1 /* Parser for C and Objective-C.
2 Copyright (C) 1987-2021 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_UNIQUE_PTR
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
)
1136 case CPP_CLOSE_PAREN
:
1138 case CPP_CLOSE_BRACE
:
1143 /* If the next token is of the indicated TYPE, consume it. Otherwise,
1144 issue the error MSGID. If MSGID is NULL then a message has already
1145 been produced and no message will be produced this time. Returns
1146 true if found, false otherwise.
1148 If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1149 within any error as the location of an "opening" token matching
1150 the close token TYPE (e.g. the location of the '(' when TYPE is
1153 If TYPE_IS_UNIQUE is true (the default) then msgid describes exactly
1154 one type (e.g. "expected %<)%>") and thus it may be reasonable to
1155 attempt to generate a fix-it hint for the problem.
1156 Otherwise msgid describes multiple token types (e.g.
1157 "expected %<;%>, %<,%> or %<)%>"), and thus we shouldn't attempt to
1158 generate a fix-it hint. */
1161 c_parser_require (c_parser
*parser
,
1162 enum cpp_ttype type
,
1164 location_t matching_location
,
1165 bool type_is_unique
)
1167 if (c_parser_next_token_is (parser
, type
))
1169 c_parser_consume_token (parser
);
1174 location_t next_token_loc
= c_parser_peek_token (parser
)->location
;
1175 gcc_rich_location
richloc (next_token_loc
);
1177 /* Potentially supply a fix-it hint, suggesting to add the
1178 missing token immediately after the *previous* token.
1179 This may move the primary location within richloc. */
1180 if (!parser
->error
&& type_is_unique
)
1181 maybe_suggest_missing_token_insertion (&richloc
, type
,
1182 parser
->last_token_location
);
1184 /* If matching_location != UNKNOWN_LOCATION, highlight it.
1185 Attempt to consolidate diagnostics by printing it as a
1186 secondary range within the main diagnostic. */
1187 bool added_matching_location
= false;
1188 if (matching_location
!= UNKNOWN_LOCATION
)
1189 added_matching_location
1190 = richloc
.add_location_if_nearby (matching_location
);
1192 if (c_parser_error_richloc (parser
, msgid
, &richloc
))
1193 /* If we weren't able to consolidate matching_location, then
1194 print it as a secondary diagnostic. */
1195 if (matching_location
!= UNKNOWN_LOCATION
&& !added_matching_location
)
1196 inform (matching_location
, "to match this %qs",
1197 get_matching_symbol (type
));
1203 /* If the next token is the indicated keyword, consume it. Otherwise,
1204 issue the error MSGID. Returns true if found, false otherwise. */
1207 c_parser_require_keyword (c_parser
*parser
,
1211 if (c_parser_next_token_is_keyword (parser
, keyword
))
1213 c_parser_consume_token (parser
);
1218 c_parser_error (parser
, msgid
);
1223 /* Like c_parser_require, except that tokens will be skipped until the
1224 desired token is found. An error message is still produced if the
1225 next token is not as expected. If MSGID is NULL then a message has
1226 already been produced and no message will be produced this
1229 If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1230 within any error as the location of an "opening" token matching
1231 the close token TYPE (e.g. the location of the '(' when TYPE is
1232 CPP_CLOSE_PAREN). */
1235 c_parser_skip_until_found (c_parser
*parser
,
1236 enum cpp_ttype type
,
1238 location_t matching_location
)
1240 unsigned nesting_depth
= 0;
1242 if (c_parser_require (parser
, type
, msgid
, matching_location
))
1245 /* Skip tokens until the desired token is found. */
1248 /* Peek at the next token. */
1249 c_token
*token
= c_parser_peek_token (parser
);
1250 /* If we've reached the token we want, consume it and stop. */
1251 if (token
->type
== type
&& !nesting_depth
)
1253 c_parser_consume_token (parser
);
1257 /* If we've run out of tokens, stop. */
1258 if (token
->type
== CPP_EOF
)
1260 if (token
->type
== CPP_PRAGMA_EOL
&& parser
->in_pragma
)
1262 if (token
->type
== CPP_OPEN_BRACE
1263 || token
->type
== CPP_OPEN_PAREN
1264 || token
->type
== CPP_OPEN_SQUARE
)
1266 else if (token
->type
== CPP_CLOSE_BRACE
1267 || token
->type
== CPP_CLOSE_PAREN
1268 || token
->type
== CPP_CLOSE_SQUARE
)
1270 if (nesting_depth
-- == 0)
1273 /* Consume this token. */
1274 c_parser_consume_token (parser
);
1276 parser
->error
= false;
1279 /* Skip tokens until the end of a parameter is found, but do not
1280 consume the comma, semicolon or closing delimiter. */
1283 c_parser_skip_to_end_of_parameter (c_parser
*parser
)
1285 unsigned nesting_depth
= 0;
1289 c_token
*token
= c_parser_peek_token (parser
);
1290 if ((token
->type
== CPP_COMMA
|| token
->type
== CPP_SEMICOLON
)
1293 /* If we've run out of tokens, stop. */
1294 if (token
->type
== CPP_EOF
)
1296 if (token
->type
== CPP_PRAGMA_EOL
&& parser
->in_pragma
)
1298 if (token
->type
== CPP_OPEN_BRACE
1299 || token
->type
== CPP_OPEN_PAREN
1300 || token
->type
== CPP_OPEN_SQUARE
)
1302 else if (token
->type
== CPP_CLOSE_BRACE
1303 || token
->type
== CPP_CLOSE_PAREN
1304 || token
->type
== CPP_CLOSE_SQUARE
)
1306 if (nesting_depth
-- == 0)
1309 /* Consume this token. */
1310 c_parser_consume_token (parser
);
1312 parser
->error
= false;
1315 /* Expect to be at the end of the pragma directive and consume an
1316 end of line marker. */
1319 c_parser_skip_to_pragma_eol (c_parser
*parser
, bool error_if_not_eol
= true)
1321 gcc_assert (parser
->in_pragma
);
1322 parser
->in_pragma
= false;
1324 if (error_if_not_eol
&& c_parser_peek_token (parser
)->type
!= CPP_PRAGMA_EOL
)
1325 c_parser_error (parser
, "expected end of line");
1327 cpp_ttype token_type
;
1330 c_token
*token
= c_parser_peek_token (parser
);
1331 token_type
= token
->type
;
1332 if (token_type
== CPP_EOF
)
1334 c_parser_consume_token (parser
);
1336 while (token_type
!= CPP_PRAGMA_EOL
);
1338 parser
->error
= false;
1341 /* Skip tokens until we have consumed an entire block, or until we
1342 have consumed a non-nested ';'. */
1345 c_parser_skip_to_end_of_block_or_statement (c_parser
*parser
)
1347 unsigned nesting_depth
= 0;
1348 bool save_error
= parser
->error
;
1354 /* Peek at the next token. */
1355 token
= c_parser_peek_token (parser
);
1357 switch (token
->type
)
1362 case CPP_PRAGMA_EOL
:
1363 if (parser
->in_pragma
)
1368 /* If the next token is a ';', we have reached the
1369 end of the statement. */
1372 /* Consume the ';'. */
1373 c_parser_consume_token (parser
);
1378 case CPP_CLOSE_BRACE
:
1379 /* If the next token is a non-nested '}', then we have
1380 reached the end of the current block. */
1381 if (nesting_depth
== 0 || --nesting_depth
== 0)
1383 c_parser_consume_token (parser
);
1388 case CPP_OPEN_BRACE
:
1389 /* If it the next token is a '{', then we are entering a new
1390 block. Consume the entire block. */
1395 /* If we see a pragma, consume the whole thing at once. We
1396 have some safeguards against consuming pragmas willy-nilly.
1397 Normally, we'd expect to be here with parser->error set,
1398 which disables these safeguards. But it's possible to get
1399 here for secondary error recovery, after parser->error has
1401 c_parser_consume_pragma (parser
);
1402 c_parser_skip_to_pragma_eol (parser
);
1403 parser
->error
= save_error
;
1410 c_parser_consume_token (parser
);
1414 parser
->error
= false;
1417 /* CPP's options (initialized by c-opts.c). */
1418 extern cpp_options
*cpp_opts
;
1420 /* Save the warning flags which are controlled by __extension__. */
1423 disable_extension_diagnostics (void)
1426 | (warn_pointer_arith
<< 1)
1427 | (warn_traditional
<< 2)
1429 | (warn_long_long
<< 4)
1430 | (warn_cxx_compat
<< 5)
1431 | (warn_overlength_strings
<< 6)
1432 /* warn_c90_c99_compat has three states: -1/0/1, so we must
1433 play tricks to properly restore it. */
1434 | ((warn_c90_c99_compat
== 1) << 7)
1435 | ((warn_c90_c99_compat
== -1) << 8)
1436 /* Similarly for warn_c99_c11_compat. */
1437 | ((warn_c99_c11_compat
== 1) << 9)
1438 | ((warn_c99_c11_compat
== -1) << 10)
1439 /* Similarly for warn_c11_c2x_compat. */
1440 | ((warn_c11_c2x_compat
== 1) << 11)
1441 | ((warn_c11_c2x_compat
== -1) << 12)
1443 cpp_opts
->cpp_pedantic
= pedantic
= 0;
1444 warn_pointer_arith
= 0;
1445 cpp_opts
->cpp_warn_traditional
= warn_traditional
= 0;
1447 cpp_opts
->cpp_warn_long_long
= warn_long_long
= 0;
1448 warn_cxx_compat
= 0;
1449 warn_overlength_strings
= 0;
1450 warn_c90_c99_compat
= 0;
1451 warn_c99_c11_compat
= 0;
1452 warn_c11_c2x_compat
= 0;
1456 /* Restore the warning flags which are controlled by __extension__.
1457 FLAGS is the return value from disable_extension_diagnostics. */
1460 restore_extension_diagnostics (int flags
)
1462 cpp_opts
->cpp_pedantic
= pedantic
= flags
& 1;
1463 warn_pointer_arith
= (flags
>> 1) & 1;
1464 cpp_opts
->cpp_warn_traditional
= warn_traditional
= (flags
>> 2) & 1;
1465 flag_iso
= (flags
>> 3) & 1;
1466 cpp_opts
->cpp_warn_long_long
= warn_long_long
= (flags
>> 4) & 1;
1467 warn_cxx_compat
= (flags
>> 5) & 1;
1468 warn_overlength_strings
= (flags
>> 6) & 1;
1469 /* See above for why is this needed. */
1470 warn_c90_c99_compat
= (flags
>> 7) & 1 ? 1 : ((flags
>> 8) & 1 ? -1 : 0);
1471 warn_c99_c11_compat
= (flags
>> 9) & 1 ? 1 : ((flags
>> 10) & 1 ? -1 : 0);
1472 warn_c11_c2x_compat
= (flags
>> 11) & 1 ? 1 : ((flags
>> 12) & 1 ? -1 : 0);
1475 /* Helper data structure for parsing #pragma acc routine. */
1476 struct oacc_routine_data
{
1477 bool error_seen
; /* Set if error has been reported. */
1478 bool fndecl_seen
; /* Set if one fn decl/definition has been seen already. */
1483 /* Used for parsing objc foreach statements. */
1484 static tree objc_foreach_break_label
, objc_foreach_continue_label
;
1486 static bool c_parser_nth_token_starts_std_attributes (c_parser
*,
1488 static tree
c_parser_std_attribute_specifier_sequence (c_parser
*);
1489 static void c_parser_external_declaration (c_parser
*);
1490 static void c_parser_asm_definition (c_parser
*);
1491 static void c_parser_declaration_or_fndef (c_parser
*, bool, bool, bool,
1492 bool, bool, tree
* = NULL
,
1493 vec
<c_token
> * = NULL
,
1494 bool have_attrs
= false,
1496 struct oacc_routine_data
* = NULL
,
1498 static void c_parser_static_assert_declaration_no_semi (c_parser
*);
1499 static void c_parser_static_assert_declaration (c_parser
*);
1500 static struct c_typespec
c_parser_enum_specifier (c_parser
*);
1501 static struct c_typespec
c_parser_struct_or_union_specifier (c_parser
*);
1502 static tree
c_parser_struct_declaration (c_parser
*);
1503 static struct c_typespec
c_parser_typeof_specifier (c_parser
*);
1504 static tree
c_parser_alignas_specifier (c_parser
*);
1505 static struct c_declarator
*c_parser_direct_declarator (c_parser
*, bool,
1507 static struct c_declarator
*c_parser_direct_declarator_inner (c_parser
*,
1509 struct c_declarator
*);
1510 static struct c_arg_info
*c_parser_parms_declarator (c_parser
*, bool, tree
,
1512 static struct c_arg_info
*c_parser_parms_list_declarator (c_parser
*, tree
,
1514 static struct c_parm
*c_parser_parameter_declaration (c_parser
*, tree
, bool);
1515 static tree
c_parser_simple_asm_expr (c_parser
*);
1516 static tree
c_parser_gnu_attributes (c_parser
*);
1517 static struct c_expr
c_parser_initializer (c_parser
*);
1518 static struct c_expr
c_parser_braced_init (c_parser
*, tree
, bool,
1520 static void c_parser_initelt (c_parser
*, struct obstack
*);
1521 static void c_parser_initval (c_parser
*, struct c_expr
*,
1523 static tree
c_parser_compound_statement (c_parser
*, location_t
* = NULL
);
1524 static location_t
c_parser_compound_statement_nostart (c_parser
*);
1525 static void c_parser_label (c_parser
*, tree
);
1526 static void c_parser_statement (c_parser
*, bool *, location_t
* = NULL
);
1527 static void c_parser_statement_after_labels (c_parser
*, bool *,
1528 vec
<tree
> * = NULL
);
1529 static tree
c_parser_c99_block_statement (c_parser
*, bool *,
1530 location_t
* = NULL
);
1531 static void c_parser_if_statement (c_parser
*, bool *, vec
<tree
> *);
1532 static void c_parser_switch_statement (c_parser
*, bool *);
1533 static void c_parser_while_statement (c_parser
*, bool, unsigned short, bool *);
1534 static void c_parser_do_statement (c_parser
*, bool, unsigned short);
1535 static void c_parser_for_statement (c_parser
*, bool, unsigned short, bool *);
1536 static tree
c_parser_asm_statement (c_parser
*);
1537 static tree
c_parser_asm_operands (c_parser
*);
1538 static tree
c_parser_asm_goto_operands (c_parser
*);
1539 static tree
c_parser_asm_clobbers (c_parser
*);
1540 static struct c_expr
c_parser_expr_no_commas (c_parser
*, struct c_expr
*,
1542 static struct c_expr
c_parser_conditional_expression (c_parser
*,
1543 struct c_expr
*, tree
);
1544 static struct c_expr
c_parser_binary_expression (c_parser
*, struct c_expr
*,
1546 static struct c_expr
c_parser_cast_expression (c_parser
*, struct c_expr
*);
1547 static struct c_expr
c_parser_unary_expression (c_parser
*);
1548 static struct c_expr
c_parser_sizeof_expression (c_parser
*);
1549 static struct c_expr
c_parser_alignof_expression (c_parser
*);
1550 static struct c_expr
c_parser_postfix_expression (c_parser
*);
1551 static struct c_expr
c_parser_postfix_expression_after_paren_type (c_parser
*,
1552 struct c_type_name
*,
1554 static struct c_expr
c_parser_postfix_expression_after_primary (c_parser
*,
1557 static tree
c_parser_transaction (c_parser
*, enum rid
);
1558 static struct c_expr
c_parser_transaction_expression (c_parser
*, enum rid
);
1559 static tree
c_parser_transaction_cancel (c_parser
*);
1560 static struct c_expr
c_parser_expression (c_parser
*);
1561 static struct c_expr
c_parser_expression_conv (c_parser
*);
1562 static vec
<tree
, va_gc
> *c_parser_expr_list (c_parser
*, bool, bool,
1563 vec
<tree
, va_gc
> **, location_t
*,
1564 tree
*, vec
<location_t
> *,
1565 unsigned int * = NULL
);
1566 static struct c_expr
c_parser_has_attribute_expression (c_parser
*);
1568 static void c_parser_oacc_declare (c_parser
*);
1569 static void c_parser_oacc_enter_exit_data (c_parser
*, bool);
1570 static void c_parser_oacc_update (c_parser
*);
1571 static void c_parser_omp_construct (c_parser
*, bool *);
1572 static void c_parser_omp_threadprivate (c_parser
*);
1573 static void c_parser_omp_barrier (c_parser
*);
1574 static void c_parser_omp_depobj (c_parser
*);
1575 static void c_parser_omp_flush (c_parser
*);
1576 static tree
c_parser_omp_for_loop (location_t
, c_parser
*, enum tree_code
,
1577 tree
, tree
*, bool *);
1578 static void c_parser_omp_taskwait (c_parser
*);
1579 static void c_parser_omp_taskyield (c_parser
*);
1580 static void c_parser_omp_cancel (c_parser
*);
1581 static void c_parser_omp_nothing (c_parser
*);
1583 enum pragma_context
{ pragma_external
, pragma_struct
, pragma_param
,
1584 pragma_stmt
, pragma_compound
};
1585 static bool c_parser_pragma (c_parser
*, enum pragma_context
, bool *);
1586 static bool c_parser_omp_cancellation_point (c_parser
*, enum pragma_context
);
1587 static bool c_parser_omp_target (c_parser
*, enum pragma_context
, bool *);
1588 static void c_parser_omp_end_declare_target (c_parser
*);
1589 static bool c_parser_omp_declare (c_parser
*, enum pragma_context
);
1590 static void c_parser_omp_requires (c_parser
*);
1591 static bool c_parser_omp_error (c_parser
*, enum pragma_context
);
1592 static bool c_parser_omp_ordered (c_parser
*, enum pragma_context
, bool *);
1593 static void c_parser_oacc_routine (c_parser
*, enum pragma_context
);
1595 /* These Objective-C parser functions are only ever called when
1596 compiling Objective-C. */
1597 static void c_parser_objc_class_definition (c_parser
*, tree
);
1598 static void c_parser_objc_class_instance_variables (c_parser
*);
1599 static void c_parser_objc_class_declaration (c_parser
*);
1600 static void c_parser_objc_alias_declaration (c_parser
*);
1601 static void c_parser_objc_protocol_definition (c_parser
*, tree
);
1602 static bool c_parser_objc_method_type (c_parser
*);
1603 static void c_parser_objc_method_definition (c_parser
*);
1604 static void c_parser_objc_methodprotolist (c_parser
*);
1605 static void c_parser_objc_methodproto (c_parser
*);
1606 static tree
c_parser_objc_method_decl (c_parser
*, bool, tree
*, tree
*);
1607 static tree
c_parser_objc_type_name (c_parser
*);
1608 static tree
c_parser_objc_protocol_refs (c_parser
*);
1609 static void c_parser_objc_try_catch_finally_statement (c_parser
*);
1610 static void c_parser_objc_synchronized_statement (c_parser
*);
1611 static tree
c_parser_objc_selector (c_parser
*);
1612 static tree
c_parser_objc_selector_arg (c_parser
*);
1613 static tree
c_parser_objc_receiver (c_parser
*);
1614 static tree
c_parser_objc_message_args (c_parser
*);
1615 static tree
c_parser_objc_keywordexpr (c_parser
*);
1616 static void c_parser_objc_at_property_declaration (c_parser
*);
1617 static void c_parser_objc_at_synthesize_declaration (c_parser
*);
1618 static void c_parser_objc_at_dynamic_declaration (c_parser
*);
1619 static bool c_parser_objc_diagnose_bad_element_prefix
1620 (c_parser
*, struct c_declspecs
*);
1621 static location_t
c_parser_parse_rtl_body (c_parser
*, char *);
1623 /* Parse a translation unit (C90 6.7, C99 6.9, C11 6.9).
1626 external-declarations
1628 external-declarations:
1629 external-declaration
1630 external-declarations external-declaration
1639 c_parser_translation_unit (c_parser
*parser
)
1641 if (c_parser_next_token_is (parser
, CPP_EOF
))
1643 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
1644 "ISO C forbids an empty translation unit");
1648 void *obstack_position
= obstack_alloc (&parser_obstack
, 0);
1649 mark_valid_location_for_stdc_pragma (false);
1653 c_parser_external_declaration (parser
);
1654 obstack_free (&parser_obstack
, obstack_position
);
1656 while (c_parser_next_token_is_not (parser
, CPP_EOF
));
1661 FOR_EACH_VEC_ELT (incomplete_record_decls
, i
, decl
)
1662 if (DECL_SIZE (decl
) == NULL_TREE
&& TREE_TYPE (decl
) != error_mark_node
)
1663 error ("storage size of %q+D isn%'t known", decl
);
1665 if (current_omp_declare_target_attribute
)
1668 error ("%<#pragma omp declare target%> without corresponding "
1669 "%<#pragma omp end declare target%>");
1670 current_omp_declare_target_attribute
= 0;
1674 /* Parse an external declaration (C90 6.7, C99 6.9, C11 6.9).
1676 external-declaration:
1682 external-declaration:
1685 __extension__ external-declaration
1689 external-declaration:
1690 objc-class-definition
1691 objc-class-declaration
1692 objc-alias-declaration
1693 objc-protocol-definition
1694 objc-method-definition
1699 c_parser_external_declaration (c_parser
*parser
)
1702 switch (c_parser_peek_token (parser
)->type
)
1705 switch (c_parser_peek_token (parser
)->keyword
)
1708 ext
= disable_extension_diagnostics ();
1709 c_parser_consume_token (parser
);
1710 c_parser_external_declaration (parser
);
1711 restore_extension_diagnostics (ext
);
1714 c_parser_asm_definition (parser
);
1716 case RID_AT_INTERFACE
:
1717 case RID_AT_IMPLEMENTATION
:
1718 gcc_assert (c_dialect_objc ());
1719 c_parser_objc_class_definition (parser
, NULL_TREE
);
1722 gcc_assert (c_dialect_objc ());
1723 c_parser_objc_class_declaration (parser
);
1726 gcc_assert (c_dialect_objc ());
1727 c_parser_objc_alias_declaration (parser
);
1729 case RID_AT_PROTOCOL
:
1730 gcc_assert (c_dialect_objc ());
1731 c_parser_objc_protocol_definition (parser
, NULL_TREE
);
1733 case RID_AT_PROPERTY
:
1734 gcc_assert (c_dialect_objc ());
1735 c_parser_objc_at_property_declaration (parser
);
1737 case RID_AT_SYNTHESIZE
:
1738 gcc_assert (c_dialect_objc ());
1739 c_parser_objc_at_synthesize_declaration (parser
);
1741 case RID_AT_DYNAMIC
:
1742 gcc_assert (c_dialect_objc ());
1743 c_parser_objc_at_dynamic_declaration (parser
);
1746 gcc_assert (c_dialect_objc ());
1747 c_parser_consume_token (parser
);
1748 objc_finish_implementation ();
1755 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
1756 "ISO C does not allow extra %<;%> outside of a function");
1757 c_parser_consume_token (parser
);
1760 mark_valid_location_for_stdc_pragma (true);
1761 c_parser_pragma (parser
, pragma_external
, NULL
);
1762 mark_valid_location_for_stdc_pragma (false);
1766 if (c_dialect_objc ())
1768 c_parser_objc_method_definition (parser
);
1771 /* Else fall through, and yield a syntax error trying to parse
1772 as a declaration or function definition. */
1776 /* A declaration or a function definition (or, in Objective-C,
1777 an @interface or @protocol with prefix attributes). We can
1778 only tell which after parsing the declaration specifiers, if
1779 any, and the first declarator. */
1780 c_parser_declaration_or_fndef (parser
, true, true, true, false, true);
1785 static void c_finish_omp_declare_simd (c_parser
*, tree
, tree
, vec
<c_token
> *);
1786 static void c_finish_oacc_routine (struct oacc_routine_data
*, tree
, bool);
1788 /* Build and add a DEBUG_BEGIN_STMT statement with location LOC. */
1791 add_debug_begin_stmt (location_t loc
)
1793 /* Don't add DEBUG_BEGIN_STMTs outside of functions, see PR84721. */
1794 if (!MAY_HAVE_DEBUG_MARKER_STMTS
|| !building_stmt_list_p ())
1797 tree stmt
= build0 (DEBUG_BEGIN_STMT
, void_type_node
);
1798 SET_EXPR_LOCATION (stmt
, loc
);
1802 /* Parse a declaration or function definition (C90 6.5, 6.7.1, C99
1803 6.7, 6.9.1, C11 6.7, 6.9.1). If FNDEF_OK is true, a function definition
1804 is accepted; otherwise (old-style parameter declarations) only other
1805 declarations are accepted. If STATIC_ASSERT_OK is true, a static
1806 assertion is accepted; otherwise (old-style parameter declarations)
1807 it is not. If NESTED is true, we are inside a function or parsing
1808 old-style parameter declarations; any functions encountered are
1809 nested functions and declaration specifiers are required; otherwise
1810 we are at top level and functions are normal functions and
1811 declaration specifiers may be optional. If EMPTY_OK is true, empty
1812 declarations are OK (subject to all other constraints); otherwise
1813 (old-style parameter declarations) they are diagnosed. If
1814 START_ATTR_OK is true, the declaration specifiers may start with
1815 attributes (GNU or standard); otherwise they may not.
1816 OBJC_FOREACH_OBJECT_DECLARATION can be used to get back the parsed
1817 declaration when parsing an Objective-C foreach statement.
1818 FALLTHRU_ATTR_P is used to signal whether this function parsed
1819 "__attribute__((fallthrough));". ATTRS are any standard attributes
1820 parsed in the caller (in contexts where such attributes had to be
1821 parsed to determine whether what follows is a declaration or a
1822 statement); HAVE_ATTRS says whether there were any such attributes
1826 declaration-specifiers init-declarator-list[opt] ;
1827 static_assert-declaration
1829 function-definition:
1830 declaration-specifiers[opt] declarator declaration-list[opt]
1835 declaration-list declaration
1837 init-declarator-list:
1839 init-declarator-list , init-declarator
1842 declarator simple-asm-expr[opt] gnu-attributes[opt]
1843 declarator simple-asm-expr[opt] gnu-attributes[opt] = initializer
1847 nested-function-definition:
1848 declaration-specifiers declarator declaration-list[opt]
1854 gnu-attributes objc-class-definition
1855 gnu-attributes objc-category-definition
1856 gnu-attributes objc-protocol-definition
1858 The simple-asm-expr and gnu-attributes are GNU extensions.
1860 This function does not handle __extension__; that is handled in its
1861 callers. ??? Following the old parser, __extension__ may start
1862 external declarations, declarations in functions and declarations
1863 at the start of "for" loops, but not old-style parameter
1866 C99 requires declaration specifiers in a function definition; the
1867 absence is diagnosed through the diagnosis of implicit int. In GNU
1868 C we also allow but diagnose declarations without declaration
1869 specifiers, but only at top level (elsewhere they conflict with
1872 In Objective-C, declarations of the looping variable in a foreach
1873 statement are exceptionally terminated by 'in' (for example, 'for
1874 (NSObject *object in array) { ... }').
1879 threadprivate-directive
1883 gimple-function-definition:
1884 declaration-specifiers[opt] __GIMPLE (gimple-or-rtl-pass-list) declarator
1885 declaration-list[opt] compound-statement
1887 rtl-function-definition:
1888 declaration-specifiers[opt] __RTL (gimple-or-rtl-pass-list) declarator
1889 declaration-list[opt] compound-statement */
1892 c_parser_declaration_or_fndef (c_parser
*parser
, bool fndef_ok
,
1893 bool static_assert_ok
, bool empty_ok
,
1894 bool nested
, bool start_attr_ok
,
1895 tree
*objc_foreach_object_declaration
1897 vec
<c_token
> *omp_declare_simd_clauses
1899 bool have_attrs
/* = false */,
1900 tree attrs
/* = NULL_TREE */,
1901 struct oacc_routine_data
*oacc_routine_data
1903 bool *fallthru_attr_p
/* = NULL */)
1905 struct c_declspecs
*specs
;
1907 tree all_prefix_attrs
;
1908 bool diagnosed_no_specs
= false;
1909 location_t here
= c_parser_peek_token (parser
)->location
;
1911 add_debug_begin_stmt (c_parser_peek_token (parser
)->location
);
1913 if (static_assert_ok
1914 && c_parser_next_token_is_keyword (parser
, RID_STATIC_ASSERT
))
1916 c_parser_static_assert_declaration (parser
);
1919 specs
= build_null_declspecs ();
1921 /* Handle any standard attributes parsed in the caller. */
1924 declspecs_add_attrs (here
, specs
, attrs
);
1925 specs
->non_std_attrs_seen_p
= false;
1928 /* Try to detect an unknown type name when we have "A B" or "A *B". */
1929 if (c_parser_peek_token (parser
)->type
== CPP_NAME
1930 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
1931 && (c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
1932 || c_parser_peek_2nd_token (parser
)->type
== CPP_MULT
)
1933 && (!nested
|| !lookup_name (c_parser_peek_token (parser
)->value
)))
1935 tree name
= c_parser_peek_token (parser
)->value
;
1937 /* Issue a warning about NAME being an unknown type name, perhaps
1938 with some kind of hint.
1939 If the user forgot a "struct" etc, suggest inserting
1940 it. Otherwise, attempt to look for misspellings. */
1941 gcc_rich_location
richloc (here
);
1942 if (tag_exists_p (RECORD_TYPE
, name
))
1944 /* This is not C++ with its implicit typedef. */
1945 richloc
.add_fixit_insert_before ("struct ");
1947 "unknown type name %qE;"
1948 " use %<struct%> keyword to refer to the type",
1951 else if (tag_exists_p (UNION_TYPE
, name
))
1953 richloc
.add_fixit_insert_before ("union ");
1955 "unknown type name %qE;"
1956 " use %<union%> keyword to refer to the type",
1959 else if (tag_exists_p (ENUMERAL_TYPE
, name
))
1961 richloc
.add_fixit_insert_before ("enum ");
1963 "unknown type name %qE;"
1964 " use %<enum%> keyword to refer to the type",
1969 auto_diagnostic_group d
;
1970 name_hint hint
= lookup_name_fuzzy (name
, FUZZY_LOOKUP_TYPENAME
,
1972 if (const char *suggestion
= hint
.suggestion ())
1974 richloc
.add_fixit_replace (suggestion
);
1976 "unknown type name %qE; did you mean %qs?",
1980 error_at (here
, "unknown type name %qE", name
);
1983 /* Parse declspecs normally to get a correct pointer type, but avoid
1984 a further "fails to be a type name" error. Refuse nested functions
1985 since it is not how the user likely wants us to recover. */
1986 c_parser_peek_token (parser
)->type
= CPP_KEYWORD
;
1987 c_parser_peek_token (parser
)->keyword
= RID_VOID
;
1988 c_parser_peek_token (parser
)->value
= error_mark_node
;
1992 /* When there are standard attributes at the start of the
1993 declaration (to apply to the entity being declared), an
1994 init-declarator-list or function definition must be present. */
1995 if (c_parser_nth_token_starts_std_attributes (parser
, 1))
1998 c_parser_declspecs (parser
, specs
, true, true, start_attr_ok
,
1999 true, true, start_attr_ok
, true, cla_nonabstract_decl
);
2002 c_parser_skip_to_end_of_block_or_statement (parser
);
2005 if (nested
&& !specs
->declspecs_seen_p
)
2007 c_parser_error (parser
, "expected declaration specifiers");
2008 c_parser_skip_to_end_of_block_or_statement (parser
);
2012 finish_declspecs (specs
);
2013 bool auto_type_p
= specs
->typespec_word
== cts_auto_type
;
2014 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
2017 error_at (here
, "%<__auto_type%> in empty declaration");
2018 else if (specs
->typespec_kind
== ctsk_none
2019 && attribute_fallthrough_p (specs
->attrs
))
2021 if (fallthru_attr_p
!= NULL
)
2022 *fallthru_attr_p
= true;
2025 tree fn
= build_call_expr_internal_loc (here
, IFN_FALLTHROUGH
,
2030 pedwarn (here
, OPT_Wattributes
,
2031 "%<fallthrough%> attribute at top level");
2033 else if (empty_ok
&& !(have_attrs
2034 && specs
->non_std_attrs_seen_p
))
2038 shadow_tag_warned (specs
, 1);
2039 pedwarn (here
, 0, "empty declaration");
2041 c_parser_consume_token (parser
);
2042 if (oacc_routine_data
)
2043 c_finish_oacc_routine (oacc_routine_data
, NULL_TREE
, false);
2047 /* Provide better error recovery. Note that a type name here is usually
2048 better diagnosed as a redeclaration. */
2050 && specs
->typespec_kind
== ctsk_tagdef
2051 && c_parser_next_token_starts_declspecs (parser
)
2052 && !c_parser_next_token_is (parser
, CPP_NAME
))
2054 c_parser_error (parser
, "expected %<;%>, identifier or %<(%>");
2055 parser
->error
= false;
2056 shadow_tag_warned (specs
, 1);
2059 else if (c_dialect_objc () && !auto_type_p
)
2061 /* Prefix attributes are an error on method decls. */
2062 switch (c_parser_peek_token (parser
)->type
)
2066 if (c_parser_objc_diagnose_bad_element_prefix (parser
, specs
))
2070 warning_at (c_parser_peek_token (parser
)->location
,
2072 "prefix attributes are ignored for methods");
2073 specs
->attrs
= NULL_TREE
;
2076 c_parser_objc_method_definition (parser
);
2078 c_parser_objc_methodproto (parser
);
2084 /* This is where we parse 'attributes @interface ...',
2085 'attributes @implementation ...', 'attributes @protocol ...'
2086 (where attributes could be, for example, __attribute__
2089 switch (c_parser_peek_token (parser
)->keyword
)
2091 case RID_AT_INTERFACE
:
2093 if (c_parser_objc_diagnose_bad_element_prefix (parser
, specs
))
2095 c_parser_objc_class_definition (parser
, specs
->attrs
);
2099 case RID_AT_IMPLEMENTATION
:
2101 if (c_parser_objc_diagnose_bad_element_prefix (parser
, specs
))
2105 warning_at (c_parser_peek_token (parser
)->location
,
2107 "prefix attributes are ignored for implementations");
2108 specs
->attrs
= NULL_TREE
;
2110 c_parser_objc_class_definition (parser
, NULL_TREE
);
2114 case RID_AT_PROTOCOL
:
2116 if (c_parser_objc_diagnose_bad_element_prefix (parser
, specs
))
2118 c_parser_objc_protocol_definition (parser
, specs
->attrs
);
2125 case RID_AT_PROPERTY
:
2128 c_parser_error (parser
, "unexpected attribute");
2129 specs
->attrs
= NULL
;
2136 else if (attribute_fallthrough_p (specs
->attrs
))
2137 warning_at (here
, OPT_Wattributes
,
2138 "%<fallthrough%> attribute not followed by %<;%>");
2140 pending_xref_error ();
2141 prefix_attrs
= specs
->attrs
;
2142 all_prefix_attrs
= prefix_attrs
;
2143 specs
->attrs
= NULL_TREE
;
2146 struct c_declarator
*declarator
;
2149 tree fnbody
= NULL_TREE
;
2150 /* Declaring either one or more declarators (in which case we
2151 should diagnose if there were no declaration specifiers) or a
2152 function definition (in which case the diagnostic for
2153 implicit int suffices). */
2154 declarator
= c_parser_declarator (parser
,
2155 specs
->typespec_kind
!= ctsk_none
,
2156 C_DTR_NORMAL
, &dummy
);
2157 if (declarator
== NULL
)
2159 if (omp_declare_simd_clauses
)
2160 c_finish_omp_declare_simd (parser
, NULL_TREE
, NULL_TREE
,
2161 omp_declare_simd_clauses
);
2162 if (oacc_routine_data
)
2163 c_finish_oacc_routine (oacc_routine_data
, NULL_TREE
, false);
2164 c_parser_skip_to_end_of_block_or_statement (parser
);
2167 if (auto_type_p
&& declarator
->kind
!= cdk_id
)
2170 "%<__auto_type%> requires a plain identifier"
2172 c_parser_skip_to_end_of_block_or_statement (parser
);
2175 if (c_parser_next_token_is (parser
, CPP_EQ
)
2176 || c_parser_next_token_is (parser
, CPP_COMMA
)
2177 || c_parser_next_token_is (parser
, CPP_SEMICOLON
)
2178 || c_parser_next_token_is_keyword (parser
, RID_ASM
)
2179 || c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
)
2180 || c_parser_next_token_is_keyword (parser
, RID_IN
))
2182 tree asm_name
= NULL_TREE
;
2183 tree postfix_attrs
= NULL_TREE
;
2184 if (!diagnosed_no_specs
&& !specs
->declspecs_seen_p
)
2186 diagnosed_no_specs
= true;
2187 pedwarn (here
, 0, "data definition has no type or storage class");
2189 /* Having seen a data definition, there cannot now be a
2190 function definition. */
2192 if (c_parser_next_token_is_keyword (parser
, RID_ASM
))
2193 asm_name
= c_parser_simple_asm_expr (parser
);
2194 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
2196 postfix_attrs
= c_parser_gnu_attributes (parser
);
2197 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
2199 /* This means there is an attribute specifier after
2200 the declarator in a function definition. Provide
2201 some more information for the user. */
2202 error_at (here
, "attributes should be specified before the "
2203 "declarator in a function definition");
2204 c_parser_skip_to_end_of_block_or_statement (parser
);
2208 if (c_parser_next_token_is (parser
, CPP_EQ
))
2212 location_t init_loc
;
2213 c_parser_consume_token (parser
);
2216 init_loc
= c_parser_peek_token (parser
)->location
;
2217 rich_location
richloc (line_table
, init_loc
);
2218 start_init (NULL_TREE
, asm_name
, global_bindings_p (), &richloc
);
2219 /* A parameter is initialized, which is invalid. Don't
2220 attempt to instrument the initializer. */
2221 int flag_sanitize_save
= flag_sanitize
;
2222 if (nested
&& !empty_ok
)
2224 init
= c_parser_expr_no_commas (parser
, NULL
);
2225 flag_sanitize
= flag_sanitize_save
;
2226 if (TREE_CODE (init
.value
) == COMPONENT_REF
2227 && DECL_C_BIT_FIELD (TREE_OPERAND (init
.value
, 1)))
2229 "%<__auto_type%> used with a bit-field"
2231 init
= convert_lvalue_to_rvalue (init_loc
, init
, true, true);
2232 tree init_type
= TREE_TYPE (init
.value
);
2233 bool vm_type
= variably_modified_type_p (init_type
,
2236 init
.value
= save_expr (init
.value
);
2238 specs
->typespec_kind
= ctsk_typeof
;
2239 specs
->locations
[cdw_typedef
] = init_loc
;
2240 specs
->typedef_p
= true;
2241 specs
->type
= init_type
;
2244 bool maybe_const
= true;
2245 tree type_expr
= c_fully_fold (init
.value
, false,
2247 specs
->expr_const_operands
&= maybe_const
;
2249 specs
->expr
= build2 (COMPOUND_EXPR
,
2250 TREE_TYPE (type_expr
),
2251 specs
->expr
, type_expr
);
2253 specs
->expr
= type_expr
;
2255 d
= start_decl (declarator
, specs
, true,
2256 chainon (postfix_attrs
, all_prefix_attrs
));
2258 d
= error_mark_node
;
2259 if (omp_declare_simd_clauses
)
2260 c_finish_omp_declare_simd (parser
, d
, NULL_TREE
,
2261 omp_declare_simd_clauses
);
2265 /* The declaration of the variable is in effect while
2266 its initializer is parsed. */
2267 d
= start_decl (declarator
, specs
, true,
2268 chainon (postfix_attrs
, all_prefix_attrs
));
2270 d
= error_mark_node
;
2271 if (omp_declare_simd_clauses
)
2272 c_finish_omp_declare_simd (parser
, d
, NULL_TREE
,
2273 omp_declare_simd_clauses
);
2274 init_loc
= c_parser_peek_token (parser
)->location
;
2275 rich_location
richloc (line_table
, init_loc
);
2276 start_init (d
, asm_name
, global_bindings_p (), &richloc
);
2277 /* A parameter is initialized, which is invalid. Don't
2278 attempt to instrument the initializer. */
2279 int flag_sanitize_save
= flag_sanitize
;
2280 if (TREE_CODE (d
) == PARM_DECL
)
2282 init
= c_parser_initializer (parser
);
2283 flag_sanitize
= flag_sanitize_save
;
2286 if (oacc_routine_data
)
2287 c_finish_oacc_routine (oacc_routine_data
, d
, false);
2288 if (d
!= error_mark_node
)
2290 maybe_warn_string_init (init_loc
, TREE_TYPE (d
), init
);
2291 finish_decl (d
, init_loc
, init
.value
,
2292 init
.original_type
, asm_name
);
2300 "%<__auto_type%> requires an initialized "
2301 "data declaration");
2302 c_parser_skip_to_end_of_block_or_statement (parser
);
2306 location_t lastloc
= UNKNOWN_LOCATION
;
2307 tree attrs
= chainon (postfix_attrs
, all_prefix_attrs
);
2308 tree d
= start_decl (declarator
, specs
, false, attrs
, &lastloc
);
2309 if (d
&& TREE_CODE (d
) == FUNCTION_DECL
)
2311 /* Find the innermost declarator that is neither cdk_id
2313 const struct c_declarator
*decl
= declarator
;
2314 const struct c_declarator
*last_non_id_attrs
= NULL
;
2322 last_non_id_attrs
= decl
;
2323 decl
= decl
->declarator
;
2327 decl
= decl
->declarator
;
2338 /* If it exists and is cdk_function declaration whose
2339 arguments have not been set yet, use its arguments. */
2340 if (last_non_id_attrs
2341 && last_non_id_attrs
->kind
== cdk_function
)
2343 tree parms
= last_non_id_attrs
->u
.arg_info
->parms
;
2344 if (DECL_ARGUMENTS (d
) == NULL_TREE
2345 && DECL_INITIAL (d
) == NULL_TREE
)
2346 DECL_ARGUMENTS (d
) = parms
;
2348 warn_parm_array_mismatch (lastloc
, d
, parms
);
2351 if (omp_declare_simd_clauses
)
2353 tree parms
= NULL_TREE
;
2354 if (d
&& TREE_CODE (d
) == FUNCTION_DECL
)
2356 struct c_declarator
*ce
= declarator
;
2358 if (ce
->kind
== cdk_function
)
2360 parms
= ce
->u
.arg_info
->parms
;
2364 ce
= ce
->declarator
;
2367 temp_store_parm_decls (d
, parms
);
2368 c_finish_omp_declare_simd (parser
, d
, parms
,
2369 omp_declare_simd_clauses
);
2371 temp_pop_parm_decls ();
2373 if (oacc_routine_data
)
2374 c_finish_oacc_routine (oacc_routine_data
, d
, false);
2376 finish_decl (d
, UNKNOWN_LOCATION
, NULL_TREE
,
2377 NULL_TREE
, asm_name
);
2379 if (c_parser_next_token_is_keyword (parser
, RID_IN
))
2382 *objc_foreach_object_declaration
= d
;
2384 *objc_foreach_object_declaration
= error_mark_node
;
2387 if (c_parser_next_token_is (parser
, CPP_COMMA
))
2392 "%<__auto_type%> may only be used with"
2393 " a single declarator");
2394 c_parser_skip_to_end_of_block_or_statement (parser
);
2397 c_parser_consume_token (parser
);
2398 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
2399 all_prefix_attrs
= chainon (c_parser_gnu_attributes (parser
),
2402 all_prefix_attrs
= prefix_attrs
;
2405 else if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
2407 c_parser_consume_token (parser
);
2410 else if (c_parser_next_token_is_keyword (parser
, RID_IN
))
2412 /* This can only happen in Objective-C: we found the
2413 'in' that terminates the declaration inside an
2414 Objective-C foreach statement. Do not consume the
2415 token, so that the caller can use it to determine
2416 that this indeed is a foreach context. */
2421 c_parser_error (parser
, "expected %<,%> or %<;%>");
2422 c_parser_skip_to_end_of_block_or_statement (parser
);
2426 else if (auto_type_p
)
2429 "%<__auto_type%> requires an initialized data declaration");
2430 c_parser_skip_to_end_of_block_or_statement (parser
);
2435 c_parser_error (parser
, "expected %<=%>, %<,%>, %<;%>, "
2436 "%<asm%> or %<__attribute__%>");
2437 c_parser_skip_to_end_of_block_or_statement (parser
);
2440 /* Function definition (nested or otherwise). */
2443 pedwarn (here
, OPT_Wpedantic
, "ISO C forbids nested functions");
2444 c_push_function_context ();
2446 if (!start_function (specs
, declarator
, all_prefix_attrs
))
2448 /* At this point we've consumed:
2449 declaration-specifiers declarator
2450 and the next token isn't CPP_EQ, CPP_COMMA, CPP_SEMICOLON,
2451 RID_ASM, RID_ATTRIBUTE, or RID_IN,
2453 declaration-specifiers declarator
2454 aren't grokkable as a function definition, so we have
2456 gcc_assert (!c_parser_next_token_is (parser
, CPP_SEMICOLON
));
2457 if (c_parser_next_token_starts_declspecs (parser
))
2460 declaration-specifiers declarator decl-specs
2461 then assume we have a missing semicolon, which would
2463 declaration-specifiers declarator decl-specs
2466 <~~~~~~~~~ declaration ~~~~~~~~~~>
2467 Use c_parser_require to get an error with a fix-it hint. */
2468 c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>");
2469 parser
->error
= false;
2473 /* This can appear in many cases looking nothing like a
2474 function definition, so we don't give a more specific
2475 error suggesting there was one. */
2476 c_parser_error (parser
, "expected %<=%>, %<,%>, %<;%>, %<asm%> "
2477 "or %<__attribute__%>");
2480 c_pop_function_context ();
2484 if (DECL_DECLARED_INLINE_P (current_function_decl
))
2485 tv
= TV_PARSE_INLINE
;
2488 auto_timevar
at (g_timer
, tv
);
2490 /* Parse old-style parameter declarations. ??? Attributes are
2491 not allowed to start declaration specifiers here because of a
2492 syntax conflict between a function declaration with attribute
2493 suffix and a function definition with an attribute prefix on
2494 first old-style parameter declaration. Following the old
2495 parser, they are not accepted on subsequent old-style
2496 parameter declarations either. However, there is no
2497 ambiguity after the first declaration, nor indeed on the
2498 first as long as we don't allow postfix attributes after a
2499 declarator with a nonempty identifier list in a definition;
2500 and postfix attributes have never been accepted here in
2501 function definitions either. */
2502 while (c_parser_next_token_is_not (parser
, CPP_EOF
)
2503 && c_parser_next_token_is_not (parser
, CPP_OPEN_BRACE
))
2504 c_parser_declaration_or_fndef (parser
, false, false, false,
2506 store_parm_decls ();
2507 if (omp_declare_simd_clauses
)
2508 c_finish_omp_declare_simd (parser
, current_function_decl
, NULL_TREE
,
2509 omp_declare_simd_clauses
);
2510 if (oacc_routine_data
)
2511 c_finish_oacc_routine (oacc_routine_data
, current_function_decl
, true);
2512 location_t startloc
= c_parser_peek_token (parser
)->location
;
2513 DECL_STRUCT_FUNCTION (current_function_decl
)->function_start_locus
2515 location_t endloc
= startloc
;
2517 /* If the definition was marked with __RTL, use the RTL parser now,
2518 consuming the function body. */
2519 if (specs
->declspec_il
== cdil_rtl
)
2521 endloc
= c_parser_parse_rtl_body (parser
, specs
->gimple_or_rtl_pass
);
2523 /* Normally, store_parm_decls sets next_is_function_body,
2524 anticipating a function body. We need a push_scope/pop_scope
2525 pair to flush out this state, or subsequent function parsing
2530 finish_function (endloc
);
2533 /* If the definition was marked with __GIMPLE then parse the
2534 function body as GIMPLE. */
2535 else if (specs
->declspec_il
!= cdil_none
)
2537 bool saved
= in_late_binary_op
;
2538 in_late_binary_op
= true;
2539 c_parser_parse_gimple_body (parser
, specs
->gimple_or_rtl_pass
,
2541 specs
->entry_bb_count
);
2542 in_late_binary_op
= saved
;
2545 fnbody
= c_parser_compound_statement (parser
, &endloc
);
2546 tree fndecl
= current_function_decl
;
2549 tree decl
= current_function_decl
;
2550 /* Mark nested functions as needing static-chain initially.
2551 lower_nested_functions will recompute it but the
2552 DECL_STATIC_CHAIN flag is also used before that happens,
2553 by initializer_constant_valid_p. See gcc.dg/nested-fn-2.c. */
2554 DECL_STATIC_CHAIN (decl
) = 1;
2556 finish_function (endloc
);
2557 c_pop_function_context ();
2558 add_stmt (build_stmt (DECL_SOURCE_LOCATION (decl
), DECL_EXPR
, decl
));
2564 finish_function (endloc
);
2566 /* Get rid of the empty stmt list for GIMPLE/RTL. */
2567 if (specs
->declspec_il
!= cdil_none
)
2568 DECL_SAVED_TREE (fndecl
) = NULL_TREE
;
2574 /* Parse an asm-definition (asm() outside a function body). This is a
2582 c_parser_asm_definition (c_parser
*parser
)
2584 tree asm_str
= c_parser_simple_asm_expr (parser
);
2586 symtab
->finalize_toplevel_asm (asm_str
);
2587 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
2590 /* Parse a static assertion (C11 6.7.10).
2592 static_assert-declaration:
2593 static_assert-declaration-no-semi ;
2597 c_parser_static_assert_declaration (c_parser
*parser
)
2599 c_parser_static_assert_declaration_no_semi (parser
);
2601 || !c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
2602 c_parser_skip_to_end_of_block_or_statement (parser
);
2605 /* Parse a static assertion (C11 6.7.10), without the trailing
2608 static_assert-declaration-no-semi:
2609 _Static_assert ( constant-expression , string-literal )
2612 static_assert-declaration-no-semi:
2613 _Static_assert ( constant-expression )
2617 c_parser_static_assert_declaration_no_semi (c_parser
*parser
)
2619 location_t assert_loc
, value_loc
;
2621 tree string
= NULL_TREE
;
2623 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_STATIC_ASSERT
));
2624 assert_loc
= c_parser_peek_token (parser
)->location
;
2626 pedwarn_c99 (assert_loc
, OPT_Wpedantic
,
2627 "ISO C99 does not support %<_Static_assert%>");
2629 pedwarn_c99 (assert_loc
, OPT_Wpedantic
,
2630 "ISO C90 does not support %<_Static_assert%>");
2631 c_parser_consume_token (parser
);
2632 matching_parens parens
;
2633 if (!parens
.require_open (parser
))
2635 location_t value_tok_loc
= c_parser_peek_token (parser
)->location
;
2636 value
= c_parser_expr_no_commas (parser
, NULL
).value
;
2637 value_loc
= EXPR_LOC_OR_LOC (value
, value_tok_loc
);
2638 if (c_parser_next_token_is (parser
, CPP_COMMA
))
2640 c_parser_consume_token (parser
);
2641 switch (c_parser_peek_token (parser
)->type
)
2647 case CPP_UTF8STRING
:
2648 string
= c_parser_string_literal (parser
, false, true).value
;
2651 c_parser_error (parser
, "expected string literal");
2655 else if (flag_isoc11
)
2656 /* If pedantic for pre-C11, the use of _Static_assert itself will
2657 have been diagnosed, so do not also diagnose the use of this
2658 new C2X feature of _Static_assert. */
2659 pedwarn_c11 (assert_loc
, OPT_Wpedantic
,
2660 "ISO C11 does not support omitting the string in "
2661 "%<_Static_assert%>");
2662 parens
.require_close (parser
);
2664 if (!INTEGRAL_TYPE_P (TREE_TYPE (value
)))
2666 error_at (value_loc
, "expression in static assertion is not an integer");
2669 if (TREE_CODE (value
) != INTEGER_CST
)
2671 value
= c_fully_fold (value
, false, NULL
);
2672 /* Strip no-op conversions. */
2673 STRIP_TYPE_NOPS (value
);
2674 if (TREE_CODE (value
) == INTEGER_CST
)
2675 pedwarn (value_loc
, OPT_Wpedantic
, "expression in static assertion "
2676 "is not an integer constant expression");
2678 if (TREE_CODE (value
) != INTEGER_CST
)
2680 error_at (value_loc
, "expression in static assertion is not constant");
2683 constant_expression_warning (value
);
2684 if (integer_zerop (value
))
2687 error_at (assert_loc
, "static assertion failed: %E", string
);
2689 error_at (assert_loc
, "static assertion failed");
2693 /* Parse some declaration specifiers (possibly none) (C90 6.5, C99
2694 6.7, C11 6.7), adding them to SPECS (which may already include some).
2695 Storage class specifiers are accepted iff SCSPEC_OK; type
2696 specifiers are accepted iff TYPESPEC_OK; alignment specifiers are
2697 accepted iff ALIGNSPEC_OK; gnu-attributes are accepted at the start
2698 iff START_ATTR_OK; __auto_type is accepted iff AUTO_TYPE_OK. In
2699 addition to the syntax shown, standard attributes are accepted at
2700 the start iff START_STD_ATTR_OK and at the end iff END_STD_ATTR_OK;
2701 unlike gnu-attributes, they are not accepted in the middle of the
2702 list. (This combines various different syntax productions in the C
2703 standard, and in some cases gnu-attributes and standard attributes
2704 at the start may already have been parsed before this function is
2707 declaration-specifiers:
2708 storage-class-specifier declaration-specifiers[opt]
2709 type-specifier declaration-specifiers[opt]
2710 type-qualifier declaration-specifiers[opt]
2711 function-specifier declaration-specifiers[opt]
2712 alignment-specifier declaration-specifiers[opt]
2714 Function specifiers (inline) are from C99, and are currently
2715 handled as storage class specifiers, as is __thread. Alignment
2716 specifiers are from C11.
2718 C90 6.5.1, C99 6.7.1, C11 6.7.1:
2719 storage-class-specifier:
2727 (_Thread_local is new in C11.)
2729 C99 6.7.4, C11 6.7.4:
2734 (_Noreturn is new in C11.)
2736 C90 6.5.2, C99 6.7.2, C11 6.7.2:
2749 [_Imaginary removed in C99 TC2]
2750 struct-or-union-specifier
2753 atomic-type-specifier
2755 (_Bool and _Complex are new in C99.)
2756 (atomic-type-specifier is new in C11.)
2758 C90 6.5.3, C99 6.7.3, C11 6.7.3:
2764 address-space-qualifier
2767 (restrict is new in C99.)
2768 (_Atomic is new in C11.)
2772 declaration-specifiers:
2773 gnu-attributes declaration-specifiers[opt]
2779 identifier recognized by the target
2781 storage-class-specifier:
2795 (_Fract, _Accum, and _Sat are new from ISO/IEC DTR 18037:
2796 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1169.pdf)
2798 atomic-type-specifier
2799 _Atomic ( type-name )
2804 class-name objc-protocol-refs[opt]
2805 typedef-name objc-protocol-refs
2810 c_parser_declspecs (c_parser
*parser
, struct c_declspecs
*specs
,
2811 bool scspec_ok
, bool typespec_ok
, bool start_attr_ok
,
2812 bool alignspec_ok
, bool auto_type_ok
,
2813 bool start_std_attr_ok
, bool end_std_attr_ok
,
2814 enum c_lookahead_kind la
)
2816 bool attrs_ok
= start_attr_ok
;
2817 bool seen_type
= specs
->typespec_kind
!= ctsk_none
;
2820 gcc_assert (la
== cla_prefer_id
);
2822 if (start_std_attr_ok
2823 && c_parser_nth_token_starts_std_attributes (parser
, 1))
2825 gcc_assert (!specs
->non_std_attrs_seen_p
);
2826 location_t loc
= c_parser_peek_token (parser
)->location
;
2827 tree attrs
= c_parser_std_attribute_specifier_sequence (parser
);
2828 declspecs_add_attrs (loc
, specs
, attrs
);
2829 specs
->non_std_attrs_seen_p
= false;
2832 while (c_parser_next_token_is (parser
, CPP_NAME
)
2833 || c_parser_next_token_is (parser
, CPP_KEYWORD
)
2834 || (c_dialect_objc () && c_parser_next_token_is (parser
, CPP_LESS
)))
2836 struct c_typespec t
;
2839 location_t loc
= c_parser_peek_token (parser
)->location
;
2841 /* If we cannot accept a type, exit if the next token must start
2842 one. Also, if we already have seen a tagged definition,
2843 a typename would be an error anyway and likely the user
2844 has simply forgotten a semicolon, so we exit. */
2845 if ((!typespec_ok
|| specs
->typespec_kind
== ctsk_tagdef
)
2846 && c_parser_next_tokens_start_typename (parser
, la
)
2847 && !c_parser_next_token_is_qualifier (parser
)
2848 && !c_parser_next_token_is_keyword (parser
, RID_ALIGNAS
))
2851 if (c_parser_next_token_is (parser
, CPP_NAME
))
2853 c_token
*name_token
= c_parser_peek_token (parser
);
2854 tree value
= name_token
->value
;
2855 c_id_kind kind
= name_token
->id_kind
;
2857 if (kind
== C_ID_ADDRSPACE
)
2860 = name_token
->keyword
- RID_FIRST_ADDR_SPACE
;
2861 declspecs_add_addrspace (name_token
->location
, specs
, as
);
2862 c_parser_consume_token (parser
);
2867 gcc_assert (!c_parser_next_token_is_qualifier (parser
));
2869 /* If we cannot accept a type, and the next token must start one,
2870 exit. Do the same if we already have seen a tagged definition,
2871 since it would be an error anyway and likely the user has simply
2872 forgotten a semicolon. */
2873 if (seen_type
|| !c_parser_next_tokens_start_typename (parser
, la
))
2876 /* Now at an unknown typename (C_ID_ID), a C_ID_TYPENAME or
2877 a C_ID_CLASSNAME. */
2878 c_parser_consume_token (parser
);
2881 if (kind
== C_ID_ID
)
2883 error_at (loc
, "unknown type name %qE", value
);
2884 t
.kind
= ctsk_typedef
;
2885 t
.spec
= error_mark_node
;
2887 else if (kind
== C_ID_TYPENAME
2888 && (!c_dialect_objc ()
2889 || c_parser_next_token_is_not (parser
, CPP_LESS
)))
2891 t
.kind
= ctsk_typedef
;
2892 /* For a typedef name, record the meaning, not the name.
2893 In case of 'foo foo, bar;'. */
2894 t
.spec
= lookup_name (value
);
2898 tree proto
= NULL_TREE
;
2899 gcc_assert (c_dialect_objc ());
2901 if (c_parser_next_token_is (parser
, CPP_LESS
))
2902 proto
= c_parser_objc_protocol_refs (parser
);
2903 t
.spec
= objc_get_protocol_qualified_type (value
, proto
);
2906 t
.expr_const_operands
= true;
2907 declspecs_add_type (name_token
->location
, specs
, t
);
2910 if (c_parser_next_token_is (parser
, CPP_LESS
))
2912 /* Make "<SomeProtocol>" equivalent to "id <SomeProtocol>" -
2913 nisse@lysator.liu.se. */
2915 gcc_assert (c_dialect_objc ());
2916 if (!typespec_ok
|| seen_type
)
2918 proto
= c_parser_objc_protocol_refs (parser
);
2920 t
.spec
= objc_get_protocol_qualified_type (NULL_TREE
, proto
);
2922 t
.expr_const_operands
= true;
2923 declspecs_add_type (loc
, specs
, t
);
2926 gcc_assert (c_parser_next_token_is (parser
, CPP_KEYWORD
));
2927 switch (c_parser_peek_token (parser
)->keyword
)
2940 /* TODO: Distinguish between function specifiers (inline, noreturn)
2941 and storage class specifiers, either here or in
2942 declspecs_add_scspec. */
2943 declspecs_add_scspec (loc
, specs
,
2944 c_parser_peek_token (parser
)->value
);
2945 c_parser_consume_token (parser
);
2977 if (c_dialect_objc ())
2978 parser
->objc_need_raw_identifier
= true;
2979 t
.kind
= ctsk_resword
;
2980 t
.spec
= c_parser_peek_token (parser
)->value
;
2982 t
.expr_const_operands
= true;
2983 declspecs_add_type (loc
, specs
, t
);
2984 c_parser_consume_token (parser
);
2991 t
= c_parser_enum_specifier (parser
);
2992 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE
, t
.spec
);
2993 declspecs_add_type (loc
, specs
, t
);
3001 t
= c_parser_struct_or_union_specifier (parser
);
3002 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE
, t
.spec
);
3003 declspecs_add_type (loc
, specs
, t
);
3006 /* ??? The old parser rejected typeof after other type
3007 specifiers, but is a syntax error the best way of
3009 if (!typespec_ok
|| seen_type
)
3013 t
= c_parser_typeof_specifier (parser
);
3014 declspecs_add_type (loc
, specs
, t
);
3017 /* C parser handling of Objective-C constructs needs
3018 checking for correct lvalue-to-rvalue conversions, and
3019 the code in build_modify_expr handling various
3020 Objective-C cases, and that in build_unary_op handling
3021 Objective-C cases for increment / decrement, also needs
3022 updating; uses of TYPE_MAIN_VARIANT in objc_compare_types
3023 and objc_types_are_equivalent may also need updates. */
3024 if (c_dialect_objc ())
3025 sorry ("%<_Atomic%> in Objective-C");
3027 pedwarn_c99 (loc
, OPT_Wpedantic
,
3028 "ISO C99 does not support the %<_Atomic%> qualifier");
3030 pedwarn_c99 (loc
, OPT_Wpedantic
,
3031 "ISO C90 does not support the %<_Atomic%> qualifier");
3034 value
= c_parser_peek_token (parser
)->value
;
3035 c_parser_consume_token (parser
);
3036 if (typespec_ok
&& c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
3038 /* _Atomic ( type-name ). */
3040 c_parser_consume_token (parser
);
3041 struct c_type_name
*type
= c_parser_type_name (parser
);
3042 t
.kind
= ctsk_typeof
;
3043 t
.spec
= error_mark_node
;
3045 t
.expr_const_operands
= true;
3047 t
.spec
= groktypename (type
, &t
.expr
,
3048 &t
.expr_const_operands
);
3049 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
3051 if (t
.spec
!= error_mark_node
)
3053 if (TREE_CODE (t
.spec
) == ARRAY_TYPE
)
3054 error_at (loc
, "%<_Atomic%>-qualified array type");
3055 else if (TREE_CODE (t
.spec
) == FUNCTION_TYPE
)
3056 error_at (loc
, "%<_Atomic%>-qualified function type");
3057 else if (TYPE_QUALS (t
.spec
) != TYPE_UNQUALIFIED
)
3058 error_at (loc
, "%<_Atomic%> applied to a qualified type");
3060 t
.spec
= c_build_qualified_type (t
.spec
, TYPE_QUAL_ATOMIC
);
3062 declspecs_add_type (loc
, specs
, t
);
3065 declspecs_add_qual (loc
, specs
, value
);
3071 declspecs_add_qual (loc
, specs
, c_parser_peek_token (parser
)->value
);
3072 c_parser_consume_token (parser
);
3077 attrs
= c_parser_gnu_attributes (parser
);
3078 declspecs_add_attrs (loc
, specs
, attrs
);
3083 align
= c_parser_alignas_specifier (parser
);
3084 declspecs_add_alignas (loc
, specs
, align
);
3088 error_at (loc
, "%<__GIMPLE%> only valid with %<-fgimple%>");
3089 c_parser_consume_token (parser
);
3090 specs
->declspec_il
= cdil_gimple
;
3091 specs
->locations
[cdw_gimple
] = loc
;
3092 c_parser_gimple_or_rtl_pass_list (parser
, specs
);
3095 c_parser_consume_token (parser
);
3096 specs
->declspec_il
= cdil_rtl
;
3097 specs
->locations
[cdw_rtl
] = loc
;
3098 c_parser_gimple_or_rtl_pass_list (parser
, specs
);
3106 && c_parser_nth_token_starts_std_attributes (parser
, 1))
3107 specs
->postfix_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
3110 /* Parse an enum specifier (C90 6.5.2.2, C99 6.7.2.2, C11 6.7.2.2).
3113 enum gnu-attributes[opt] identifier[opt] { enumerator-list }
3115 enum gnu-attributes[opt] identifier[opt] { enumerator-list , }
3117 enum gnu-attributes[opt] identifier
3119 The form with trailing comma is new in C99. The forms with
3120 gnu-attributes are GNU extensions. In GNU C, we accept any expression
3121 without commas in the syntax (assignment expressions, not just
3122 conditional expressions); assignment expressions will be diagnosed
3127 enumerator-list , enumerator
3130 enumeration-constant attribute-specifier-sequence[opt]
3131 enumeration-constant attribute-specifier-sequence[opt]
3132 = constant-expression
3137 enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt]
3138 enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt]
3139 = constant-expression
3143 static struct c_typespec
3144 c_parser_enum_specifier (c_parser
*parser
)
3146 struct c_typespec ret
;
3147 bool have_std_attrs
;
3148 tree std_attrs
= NULL_TREE
;
3150 tree ident
= NULL_TREE
;
3151 location_t enum_loc
;
3152 location_t ident_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
3153 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ENUM
));
3154 c_parser_consume_token (parser
);
3155 have_std_attrs
= c_parser_nth_token_starts_std_attributes (parser
, 1);
3157 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
3158 attrs
= c_parser_gnu_attributes (parser
);
3159 enum_loc
= c_parser_peek_token (parser
)->location
;
3160 /* Set the location in case we create a decl now. */
3161 c_parser_set_source_position_from_token (c_parser_peek_token (parser
));
3162 if (c_parser_next_token_is (parser
, CPP_NAME
))
3164 ident
= c_parser_peek_token (parser
)->value
;
3165 ident_loc
= c_parser_peek_token (parser
)->location
;
3166 enum_loc
= ident_loc
;
3167 c_parser_consume_token (parser
);
3169 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
3171 /* Parse an enum definition. */
3172 struct c_enum_contents the_enum
;
3175 /* We chain the enumerators in reverse order, then put them in
3176 forward order at the end. */
3178 timevar_push (TV_PARSE_ENUM
);
3179 type
= start_enum (enum_loc
, &the_enum
, ident
);
3181 c_parser_consume_token (parser
);
3189 location_t comma_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
3190 location_t decl_loc
, value_loc
;
3191 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
3193 /* Give a nicer error for "enum {}". */
3194 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
)
3197 error_at (c_parser_peek_token (parser
)->location
,
3198 "empty enum is invalid");
3199 parser
->error
= true;
3202 c_parser_error (parser
, "expected identifier");
3203 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
, NULL
);
3204 values
= error_mark_node
;
3207 token
= c_parser_peek_token (parser
);
3208 enum_id
= token
->value
;
3209 /* Set the location in case we create a decl now. */
3210 c_parser_set_source_position_from_token (token
);
3211 decl_loc
= value_loc
= token
->location
;
3212 c_parser_consume_token (parser
);
3213 /* Parse any specified attributes. */
3214 tree std_attrs
= NULL_TREE
;
3215 if (c_parser_nth_token_starts_std_attributes (parser
, 1))
3216 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
3217 tree enum_attrs
= chainon (std_attrs
,
3218 c_parser_gnu_attributes (parser
));
3219 if (c_parser_next_token_is (parser
, CPP_EQ
))
3221 c_parser_consume_token (parser
);
3222 value_loc
= c_parser_peek_token (parser
)->location
;
3223 enum_value
= c_parser_expr_no_commas (parser
, NULL
).value
;
3226 enum_value
= NULL_TREE
;
3227 enum_decl
= build_enumerator (decl_loc
, value_loc
,
3228 &the_enum
, enum_id
, enum_value
);
3230 decl_attributes (&TREE_PURPOSE (enum_decl
), enum_attrs
, 0);
3231 TREE_CHAIN (enum_decl
) = values
;
3234 if (c_parser_next_token_is (parser
, CPP_COMMA
))
3236 comma_loc
= c_parser_peek_token (parser
)->location
;
3238 c_parser_consume_token (parser
);
3240 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
3243 pedwarn_c90 (comma_loc
, OPT_Wpedantic
,
3244 "comma at end of enumerator list");
3245 c_parser_consume_token (parser
);
3250 c_parser_error (parser
, "expected %<,%> or %<}%>");
3251 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
, NULL
);
3252 values
= error_mark_node
;
3256 postfix_attrs
= c_parser_gnu_attributes (parser
);
3257 ret
.spec
= finish_enum (type
, nreverse (values
),
3259 chainon (attrs
, postfix_attrs
)));
3260 ret
.kind
= ctsk_tagdef
;
3261 ret
.expr
= NULL_TREE
;
3262 ret
.expr_const_operands
= true;
3263 timevar_pop (TV_PARSE_ENUM
);
3268 c_parser_error (parser
, "expected %<{%>");
3269 ret
.spec
= error_mark_node
;
3270 ret
.kind
= ctsk_tagref
;
3271 ret
.expr
= NULL_TREE
;
3272 ret
.expr_const_operands
= true;
3275 /* Attributes may only appear when the members are defined or in
3276 certain forward declarations (treat enum forward declarations in
3277 GNU C analogously to struct and union forward declarations in
3279 if (have_std_attrs
&& c_parser_next_token_is_not (parser
, CPP_SEMICOLON
))
3280 c_parser_error (parser
, "expected %<;%>");
3281 ret
= parser_xref_tag (ident_loc
, ENUMERAL_TYPE
, ident
, have_std_attrs
,
3283 /* In ISO C, enumerated types can be referred to only if already
3285 if (pedantic
&& !COMPLETE_TYPE_P (ret
.spec
))
3288 pedwarn (enum_loc
, OPT_Wpedantic
,
3289 "ISO C forbids forward references to %<enum%> types");
3294 /* Parse a struct or union specifier (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1).
3296 struct-or-union-specifier:
3297 struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
3298 identifier[opt] { struct-contents } gnu-attributes[opt]
3299 struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
3303 struct-declaration-list
3305 struct-declaration-list:
3306 struct-declaration ;
3307 struct-declaration-list struct-declaration ;
3314 struct-declaration-list struct-declaration
3316 struct-declaration-list:
3317 struct-declaration-list ;
3320 (Note that in the syntax here, unlike that in ISO C, the semicolons
3321 are included here rather than in struct-declaration, in order to
3322 describe the syntax with extra semicolons and missing semicolon at
3327 struct-declaration-list:
3328 @defs ( class-name )
3330 (Note this does not include a trailing semicolon, but can be
3331 followed by further declarations, and gets a pedwarn-if-pedantic
3332 when followed by a semicolon.) */
3334 static struct c_typespec
3335 c_parser_struct_or_union_specifier (c_parser
*parser
)
3337 struct c_typespec ret
;
3338 bool have_std_attrs
;
3339 tree std_attrs
= NULL_TREE
;
3341 tree ident
= NULL_TREE
;
3342 location_t struct_loc
;
3343 location_t ident_loc
= UNKNOWN_LOCATION
;
3344 enum tree_code code
;
3345 switch (c_parser_peek_token (parser
)->keyword
)
3356 struct_loc
= c_parser_peek_token (parser
)->location
;
3357 c_parser_consume_token (parser
);
3358 have_std_attrs
= c_parser_nth_token_starts_std_attributes (parser
, 1);
3360 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
3361 attrs
= c_parser_gnu_attributes (parser
);
3363 /* Set the location in case we create a decl now. */
3364 c_parser_set_source_position_from_token (c_parser_peek_token (parser
));
3366 if (c_parser_next_token_is (parser
, CPP_NAME
))
3368 ident
= c_parser_peek_token (parser
)->value
;
3369 ident_loc
= c_parser_peek_token (parser
)->location
;
3370 struct_loc
= ident_loc
;
3371 c_parser_consume_token (parser
);
3373 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
3375 /* Parse a struct or union definition. Start the scope of the
3376 tag before parsing components. */
3377 class c_struct_parse_info
*struct_info
;
3378 tree type
= start_struct (struct_loc
, code
, ident
, &struct_info
);
3380 /* We chain the components in reverse order, then put them in
3381 forward order at the end. Each struct-declaration may
3382 declare multiple components (comma-separated), so we must use
3383 chainon to join them, although when parsing each
3384 struct-declaration we can use TREE_CHAIN directly.
3386 The theory behind all this is that there will be more
3387 semicolon separated fields than comma separated fields, and
3388 so we'll be minimizing the number of node traversals required
3391 timevar_push (TV_PARSE_STRUCT
);
3392 contents
= NULL_TREE
;
3393 c_parser_consume_token (parser
);
3394 /* Handle the Objective-C @defs construct,
3395 e.g. foo(sizeof(struct{ @defs(ClassName) }));. */
3396 if (c_parser_next_token_is_keyword (parser
, RID_AT_DEFS
))
3399 gcc_assert (c_dialect_objc ());
3400 c_parser_consume_token (parser
);
3401 matching_parens parens
;
3402 if (!parens
.require_open (parser
))
3404 if (c_parser_next_token_is (parser
, CPP_NAME
)
3405 && c_parser_peek_token (parser
)->id_kind
== C_ID_CLASSNAME
)
3407 name
= c_parser_peek_token (parser
)->value
;
3408 c_parser_consume_token (parser
);
3412 c_parser_error (parser
, "expected class name");
3413 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
3416 parens
.skip_until_found_close (parser
);
3417 contents
= nreverse (objc_get_class_ivars (name
));
3420 /* Parse the struct-declarations and semicolons. Problems with
3421 semicolons are diagnosed here; empty structures are diagnosed
3426 /* Parse any stray semicolon. */
3427 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
3429 location_t semicolon_loc
3430 = c_parser_peek_token (parser
)->location
;
3431 gcc_rich_location
richloc (semicolon_loc
);
3432 richloc
.add_fixit_remove ();
3433 pedwarn (&richloc
, OPT_Wpedantic
,
3434 "extra semicolon in struct or union specified");
3435 c_parser_consume_token (parser
);
3438 /* Stop if at the end of the struct or union contents. */
3439 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
3441 c_parser_consume_token (parser
);
3444 /* Accept #pragmas at struct scope. */
3445 if (c_parser_next_token_is (parser
, CPP_PRAGMA
))
3447 c_parser_pragma (parser
, pragma_struct
, NULL
);
3450 /* Parse some comma-separated declarations, but not the
3451 trailing semicolon if any. */
3452 decls
= c_parser_struct_declaration (parser
);
3453 contents
= chainon (decls
, contents
);
3454 /* If no semicolon follows, either we have a parse error or
3455 are at the end of the struct or union and should
3457 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
3458 c_parser_consume_token (parser
);
3461 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
3462 pedwarn (c_parser_peek_token (parser
)->location
, 0,
3463 "no semicolon at end of struct or union");
3464 else if (parser
->error
3465 || !c_parser_next_token_starts_declspecs (parser
))
3467 c_parser_error (parser
, "expected %<;%>");
3468 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
, NULL
);
3472 /* If we come here, we have already emitted an error
3473 for an expected `;', identifier or `(', and we also
3474 recovered already. Go on with the next field. */
3477 postfix_attrs
= c_parser_gnu_attributes (parser
);
3478 ret
.spec
= finish_struct (struct_loc
, type
, nreverse (contents
),
3480 chainon (attrs
, postfix_attrs
)),
3482 ret
.kind
= ctsk_tagdef
;
3483 ret
.expr
= NULL_TREE
;
3484 ret
.expr_const_operands
= true;
3485 timevar_pop (TV_PARSE_STRUCT
);
3490 c_parser_error (parser
, "expected %<{%>");
3491 ret
.spec
= error_mark_node
;
3492 ret
.kind
= ctsk_tagref
;
3493 ret
.expr
= NULL_TREE
;
3494 ret
.expr_const_operands
= true;
3497 /* Attributes may only appear when the members are defined or in
3498 certain forward declarations. */
3499 if (have_std_attrs
&& c_parser_next_token_is_not (parser
, CPP_SEMICOLON
))
3500 c_parser_error (parser
, "expected %<;%>");
3501 /* ??? Existing practice is that GNU attributes are ignored after
3502 the struct or union keyword when not defining the members. */
3503 ret
= parser_xref_tag (ident_loc
, code
, ident
, have_std_attrs
, std_attrs
);
3507 /* Parse a struct-declaration (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1),
3508 *without* the trailing semicolon.
3511 attribute-specifier-sequence[opt] specifier-qualifier-list
3512 attribute-specifier-sequence[opt] struct-declarator-list
3513 static_assert-declaration-no-semi
3515 specifier-qualifier-list:
3516 type-specifier specifier-qualifier-list[opt]
3517 type-qualifier specifier-qualifier-list[opt]
3518 alignment-specifier specifier-qualifier-list[opt]
3519 gnu-attributes specifier-qualifier-list[opt]
3521 struct-declarator-list:
3523 struct-declarator-list , gnu-attributes[opt] struct-declarator
3526 declarator gnu-attributes[opt]
3527 declarator[opt] : constant-expression gnu-attributes[opt]
3532 __extension__ struct-declaration
3533 specifier-qualifier-list
3535 Unlike the ISO C syntax, semicolons are handled elsewhere. The use
3536 of gnu-attributes where shown is a GNU extension. In GNU C, we accept
3537 any expression without commas in the syntax (assignment
3538 expressions, not just conditional expressions); assignment
3539 expressions will be diagnosed as non-constant. */
3542 c_parser_struct_declaration (c_parser
*parser
)
3544 struct c_declspecs
*specs
;
3546 tree all_prefix_attrs
;
3548 location_t decl_loc
;
3549 if (c_parser_next_token_is_keyword (parser
, RID_EXTENSION
))
3553 ext
= disable_extension_diagnostics ();
3554 c_parser_consume_token (parser
);
3555 decl
= c_parser_struct_declaration (parser
);
3556 restore_extension_diagnostics (ext
);
3559 if (c_parser_next_token_is_keyword (parser
, RID_STATIC_ASSERT
))
3561 c_parser_static_assert_declaration_no_semi (parser
);
3564 specs
= build_null_declspecs ();
3565 decl_loc
= c_parser_peek_token (parser
)->location
;
3566 /* Strictly by the standard, we shouldn't allow _Alignas here,
3567 but it appears to have been intended to allow it there, so
3568 we're keeping it as it is until WG14 reaches a conclusion
3570 <http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1731.pdf> */
3571 c_parser_declspecs (parser
, specs
, false, true, true,
3572 true, false, true, true, cla_nonabstract_decl
);
3575 if (!specs
->declspecs_seen_p
)
3577 c_parser_error (parser
, "expected specifier-qualifier-list");
3580 finish_declspecs (specs
);
3581 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
)
3582 || c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
3585 if (specs
->typespec_kind
== ctsk_none
)
3587 pedwarn (decl_loc
, OPT_Wpedantic
,
3588 "ISO C forbids member declarations with no members");
3589 shadow_tag_warned (specs
, pedantic
);
3594 /* Support for unnamed structs or unions as members of
3595 structs or unions (which is [a] useful and [b] supports
3599 ret
= grokfield (c_parser_peek_token (parser
)->location
,
3600 build_id_declarator (NULL_TREE
), specs
,
3603 decl_attributes (&ret
, attrs
, 0);
3608 /* Provide better error recovery. Note that a type name here is valid,
3609 and will be treated as a field name. */
3610 if (specs
->typespec_kind
== ctsk_tagdef
3611 && TREE_CODE (specs
->type
) != ENUMERAL_TYPE
3612 && c_parser_next_token_starts_declspecs (parser
)
3613 && !c_parser_next_token_is (parser
, CPP_NAME
))
3615 c_parser_error (parser
, "expected %<;%>, identifier or %<(%>");
3616 parser
->error
= false;
3620 pending_xref_error ();
3621 prefix_attrs
= specs
->attrs
;
3622 all_prefix_attrs
= prefix_attrs
;
3623 specs
->attrs
= NULL_TREE
;
3627 /* Declaring one or more declarators or un-named bit-fields. */
3628 struct c_declarator
*declarator
;
3630 if (c_parser_next_token_is (parser
, CPP_COLON
))
3631 declarator
= build_id_declarator (NULL_TREE
);
3633 declarator
= c_parser_declarator (parser
,
3634 specs
->typespec_kind
!= ctsk_none
,
3635 C_DTR_NORMAL
, &dummy
);
3636 if (declarator
== NULL
)
3638 c_parser_skip_to_end_of_block_or_statement (parser
);
3641 if (c_parser_next_token_is (parser
, CPP_COLON
)
3642 || c_parser_next_token_is (parser
, CPP_COMMA
)
3643 || c_parser_next_token_is (parser
, CPP_SEMICOLON
)
3644 || c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
)
3645 || c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
3647 tree postfix_attrs
= NULL_TREE
;
3648 tree width
= NULL_TREE
;
3650 if (c_parser_next_token_is (parser
, CPP_COLON
))
3652 c_parser_consume_token (parser
);
3653 width
= c_parser_expr_no_commas (parser
, NULL
).value
;
3655 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
3656 postfix_attrs
= c_parser_gnu_attributes (parser
);
3657 d
= grokfield (c_parser_peek_token (parser
)->location
,
3658 declarator
, specs
, width
, &all_prefix_attrs
);
3659 decl_attributes (&d
, chainon (postfix_attrs
,
3660 all_prefix_attrs
), 0);
3661 DECL_CHAIN (d
) = decls
;
3663 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
3664 all_prefix_attrs
= chainon (c_parser_gnu_attributes (parser
),
3667 all_prefix_attrs
= prefix_attrs
;
3668 if (c_parser_next_token_is (parser
, CPP_COMMA
))
3669 c_parser_consume_token (parser
);
3670 else if (c_parser_next_token_is (parser
, CPP_SEMICOLON
)
3671 || c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
3673 /* Semicolon consumed in caller. */
3678 c_parser_error (parser
, "expected %<,%>, %<;%> or %<}%>");
3684 c_parser_error (parser
,
3685 "expected %<:%>, %<,%>, %<;%>, %<}%> or "
3686 "%<__attribute__%>");
3693 /* Parse a typeof specifier (a GNU extension).
3696 typeof ( expression )
3697 typeof ( type-name )
3700 static struct c_typespec
3701 c_parser_typeof_specifier (c_parser
*parser
)
3703 struct c_typespec ret
;
3704 ret
.kind
= ctsk_typeof
;
3705 ret
.spec
= error_mark_node
;
3706 ret
.expr
= NULL_TREE
;
3707 ret
.expr_const_operands
= true;
3708 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_TYPEOF
));
3709 c_parser_consume_token (parser
);
3710 c_inhibit_evaluation_warnings
++;
3712 matching_parens parens
;
3713 if (!parens
.require_open (parser
))
3715 c_inhibit_evaluation_warnings
--;
3719 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_id
))
3721 struct c_type_name
*type
= c_parser_type_name (parser
);
3722 c_inhibit_evaluation_warnings
--;
3726 ret
.spec
= groktypename (type
, &ret
.expr
, &ret
.expr_const_operands
);
3727 pop_maybe_used (variably_modified_type_p (ret
.spec
, NULL_TREE
));
3733 location_t here
= c_parser_peek_token (parser
)->location
;
3734 struct c_expr expr
= c_parser_expression (parser
);
3735 c_inhibit_evaluation_warnings
--;
3737 if (TREE_CODE (expr
.value
) == COMPONENT_REF
3738 && DECL_C_BIT_FIELD (TREE_OPERAND (expr
.value
, 1)))
3739 error_at (here
, "%<typeof%> applied to a bit-field");
3740 mark_exp_read (expr
.value
);
3741 ret
.spec
= TREE_TYPE (expr
.value
);
3742 was_vm
= variably_modified_type_p (ret
.spec
, NULL_TREE
);
3743 /* This is returned with the type so that when the type is
3744 evaluated, this can be evaluated. */
3746 ret
.expr
= c_fully_fold (expr
.value
, false, &ret
.expr_const_operands
);
3747 pop_maybe_used (was_vm
);
3749 parens
.skip_until_found_close (parser
);
3753 /* Parse an alignment-specifier.
3757 alignment-specifier:
3758 _Alignas ( type-name )
3759 _Alignas ( constant-expression )
3763 c_parser_alignas_specifier (c_parser
* parser
)
3765 tree ret
= error_mark_node
;
3766 location_t loc
= c_parser_peek_token (parser
)->location
;
3767 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ALIGNAS
));
3768 c_parser_consume_token (parser
);
3770 pedwarn_c99 (loc
, OPT_Wpedantic
,
3771 "ISO C99 does not support %<_Alignas%>");
3773 pedwarn_c99 (loc
, OPT_Wpedantic
,
3774 "ISO C90 does not support %<_Alignas%>");
3775 matching_parens parens
;
3776 if (!parens
.require_open (parser
))
3778 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_id
))
3780 struct c_type_name
*type
= c_parser_type_name (parser
);
3782 ret
= c_sizeof_or_alignof_type (loc
, groktypename (type
, NULL
, NULL
),
3786 ret
= c_parser_expr_no_commas (parser
, NULL
).value
;
3787 parens
.skip_until_found_close (parser
);
3791 /* Parse a declarator, possibly an abstract declarator (C90 6.5.4,
3792 6.5.5, C99 6.7.5, 6.7.6, C11 6.7.6, 6.7.7). If TYPE_SEEN_P then
3793 a typedef name may be redeclared; otherwise it may not. KIND
3794 indicates which kind of declarator is wanted. Returns a valid
3795 declarator except in the case of a syntax error in which case NULL is
3796 returned. *SEEN_ID is set to true if an identifier being declared is
3797 seen; this is used to diagnose bad forms of abstract array declarators
3798 and to determine whether an identifier list is syntactically permitted.
3801 pointer[opt] direct-declarator
3805 ( gnu-attributes[opt] declarator )
3806 direct-declarator array-declarator
3807 direct-declarator ( parameter-type-list )
3808 direct-declarator ( identifier-list[opt] )
3811 * type-qualifier-list[opt]
3812 * type-qualifier-list[opt] pointer
3814 type-qualifier-list:
3817 type-qualifier-list type-qualifier
3818 type-qualifier-list gnu-attributes
3821 [ type-qualifier-list[opt] assignment-expression[opt] ]
3822 [ static type-qualifier-list[opt] assignment-expression ]
3823 [ type-qualifier-list static assignment-expression ]
3824 [ type-qualifier-list[opt] * ]
3826 parameter-type-list:
3828 parameter-list , ...
3831 parameter-declaration
3832 parameter-list , parameter-declaration
3834 parameter-declaration:
3835 declaration-specifiers declarator gnu-attributes[opt]
3836 declaration-specifiers abstract-declarator[opt] gnu-attributes[opt]
3840 identifier-list , identifier
3842 abstract-declarator:
3844 pointer[opt] direct-abstract-declarator
3846 direct-abstract-declarator:
3847 ( gnu-attributes[opt] abstract-declarator )
3848 direct-abstract-declarator[opt] array-declarator
3849 direct-abstract-declarator[opt] ( parameter-type-list[opt] )
3854 direct-declarator ( parameter-forward-declarations
3855 parameter-type-list[opt] )
3857 direct-abstract-declarator:
3858 direct-abstract-declarator[opt] ( parameter-forward-declarations
3859 parameter-type-list[opt] )
3861 parameter-forward-declarations:
3863 parameter-forward-declarations parameter-list ;
3865 The uses of gnu-attributes shown above are GNU extensions.
3867 Some forms of array declarator are not included in C99 in the
3868 syntax for abstract declarators; these are disallowed elsewhere.
3869 This may be a defect (DR#289).
3871 This function also accepts an omitted abstract declarator as being
3872 an abstract declarator, although not part of the formal syntax. */
3874 struct c_declarator
*
3875 c_parser_declarator (c_parser
*parser
, bool type_seen_p
, c_dtr_syn kind
,
3878 /* Parse any initial pointer part. */
3879 if (c_parser_next_token_is (parser
, CPP_MULT
))
3881 struct c_declspecs
*quals_attrs
= build_null_declspecs ();
3882 struct c_declarator
*inner
;
3883 c_parser_consume_token (parser
);
3884 c_parser_declspecs (parser
, quals_attrs
, false, false, true,
3885 false, false, true, false, cla_prefer_id
);
3886 inner
= c_parser_declarator (parser
, type_seen_p
, kind
, seen_id
);
3890 return make_pointer_declarator (quals_attrs
, inner
);
3892 /* Now we have a direct declarator, direct abstract declarator or
3893 nothing (which counts as a direct abstract declarator here). */
3894 return c_parser_direct_declarator (parser
, type_seen_p
, kind
, seen_id
);
3897 /* Parse a direct declarator or direct abstract declarator; arguments
3898 as c_parser_declarator. */
3900 static struct c_declarator
*
3901 c_parser_direct_declarator (c_parser
*parser
, bool type_seen_p
, c_dtr_syn kind
,
3904 /* The direct declarator must start with an identifier (possibly
3905 omitted) or a parenthesized declarator (possibly abstract). In
3906 an ordinary declarator, initial parentheses must start a
3907 parenthesized declarator. In an abstract declarator or parameter
3908 declarator, they could start a parenthesized declarator or a
3909 parameter list. To tell which, the open parenthesis and any
3910 following gnu-attributes must be read. If a declaration
3911 specifier or standard attributes follow, then it is a parameter
3912 list; if the specifier is a typedef name, there might be an
3913 ambiguity about redeclaring it, which is resolved in the
3914 direction of treating it as a typedef name. If a close
3915 parenthesis follows, it is also an empty parameter list, as the
3916 syntax does not permit empty abstract declarators. Otherwise, it
3917 is a parenthesized declarator (in which case the analysis may be
3918 repeated inside it, recursively).
3920 ??? There is an ambiguity in a parameter declaration "int
3921 (__attribute__((foo)) x)", where x is not a typedef name: it
3922 could be an abstract declarator for a function, or declare x with
3923 parentheses. The proper resolution of this ambiguity needs
3924 documenting. At present we follow an accident of the old
3925 parser's implementation, whereby the first parameter must have
3926 some declaration specifiers other than just gnu-attributes. Thus as
3927 a parameter declaration it is treated as a parenthesized
3928 parameter named x, and as an abstract declarator it is
3931 ??? Also following the old parser, gnu-attributes inside an empty
3932 parameter list are ignored, making it a list not yielding a
3933 prototype, rather than giving an error or making it have one
3934 parameter with implicit type int.
3936 ??? Also following the old parser, typedef names may be
3937 redeclared in declarators, but not Objective-C class names. */
3939 if (kind
!= C_DTR_ABSTRACT
3940 && c_parser_next_token_is (parser
, CPP_NAME
)
3942 && (c_parser_peek_token (parser
)->id_kind
== C_ID_TYPENAME
3943 || c_parser_peek_token (parser
)->id_kind
== C_ID_CLASSNAME
))
3944 || c_parser_peek_token (parser
)->id_kind
== C_ID_ID
))
3946 struct c_declarator
*inner
3947 = build_id_declarator (c_parser_peek_token (parser
)->value
);
3949 inner
->id_loc
= c_parser_peek_token (parser
)->location
;
3950 c_parser_consume_token (parser
);
3951 if (c_parser_nth_token_starts_std_attributes (parser
, 1))
3952 inner
->u
.id
.attrs
= c_parser_std_attribute_specifier_sequence (parser
);
3953 return c_parser_direct_declarator_inner (parser
, *seen_id
, inner
);
3956 if (kind
!= C_DTR_NORMAL
3957 && c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
)
3958 && !c_parser_nth_token_starts_std_attributes (parser
, 1))
3960 struct c_declarator
*inner
= build_id_declarator (NULL_TREE
);
3961 inner
->id_loc
= c_parser_peek_token (parser
)->location
;
3962 return c_parser_direct_declarator_inner (parser
, *seen_id
, inner
);
3965 /* Either we are at the end of an abstract declarator, or we have
3968 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
3971 struct c_declarator
*inner
;
3972 c_parser_consume_token (parser
);
3973 bool have_gnu_attrs
= c_parser_next_token_is_keyword (parser
,
3975 attrs
= c_parser_gnu_attributes (parser
);
3976 if (kind
!= C_DTR_NORMAL
3977 && (c_parser_next_token_starts_declspecs (parser
)
3979 && c_parser_nth_token_starts_std_attributes (parser
, 1))
3980 || c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
)))
3982 struct c_arg_info
*args
3983 = c_parser_parms_declarator (parser
, kind
== C_DTR_NORMAL
,
3984 attrs
, have_gnu_attrs
);
3989 inner
= build_id_declarator (NULL_TREE
);
3991 && args
->types
!= error_mark_node
3992 && TREE_CODE (TREE_VALUE (args
->types
)) == IDENTIFIER_NODE
)
3993 && c_parser_nth_token_starts_std_attributes (parser
, 1))
3996 = c_parser_std_attribute_specifier_sequence (parser
);
3998 inner
= build_attrs_declarator (std_attrs
, inner
);
4000 inner
= build_function_declarator (args
, inner
);
4001 return c_parser_direct_declarator_inner (parser
, *seen_id
,
4005 /* A parenthesized declarator. */
4006 inner
= c_parser_declarator (parser
, type_seen_p
, kind
, seen_id
);
4007 if (inner
!= NULL
&& attrs
!= NULL
)
4008 inner
= build_attrs_declarator (attrs
, inner
);
4009 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4011 c_parser_consume_token (parser
);
4015 return c_parser_direct_declarator_inner (parser
, *seen_id
, inner
);
4019 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4026 if (kind
== C_DTR_NORMAL
)
4028 c_parser_error (parser
, "expected identifier or %<(%>");
4032 return build_id_declarator (NULL_TREE
);
4036 /* Parse part of a direct declarator or direct abstract declarator,
4037 given that some (in INNER) has already been parsed; ID_PRESENT is
4038 true if an identifier is present, false for an abstract
4041 static struct c_declarator
*
4042 c_parser_direct_declarator_inner (c_parser
*parser
, bool id_present
,
4043 struct c_declarator
*inner
)
4045 /* Parse a sequence of array declarators and parameter lists. */
4046 if (c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
)
4047 && !c_parser_nth_token_starts_std_attributes (parser
, 1))
4049 location_t brace_loc
= c_parser_peek_token (parser
)->location
;
4050 struct c_declarator
*declarator
;
4051 struct c_declspecs
*quals_attrs
= build_null_declspecs ();
4054 struct c_expr dimen
;
4055 dimen
.value
= NULL_TREE
;
4056 dimen
.original_code
= ERROR_MARK
;
4057 dimen
.original_type
= NULL_TREE
;
4058 c_parser_consume_token (parser
);
4059 c_parser_declspecs (parser
, quals_attrs
, false, false, true,
4060 false, false, false, false, cla_prefer_id
);
4061 static_seen
= c_parser_next_token_is_keyword (parser
, RID_STATIC
);
4063 c_parser_consume_token (parser
);
4064 if (static_seen
&& !quals_attrs
->declspecs_seen_p
)
4065 c_parser_declspecs (parser
, quals_attrs
, false, false, true,
4066 false, false, false, false, cla_prefer_id
);
4067 if (!quals_attrs
->declspecs_seen_p
)
4069 /* If "static" is present, there must be an array dimension.
4070 Otherwise, there may be a dimension, "*", or no
4075 dimen
= c_parser_expr_no_commas (parser
, NULL
);
4079 if (c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
4081 dimen
.value
= NULL_TREE
;
4084 else if (c_parser_next_token_is (parser
, CPP_MULT
))
4086 if (c_parser_peek_2nd_token (parser
)->type
== CPP_CLOSE_SQUARE
)
4088 dimen
.value
= NULL_TREE
;
4090 c_parser_consume_token (parser
);
4095 dimen
= c_parser_expr_no_commas (parser
, NULL
);
4101 dimen
= c_parser_expr_no_commas (parser
, NULL
);
4104 if (c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
4105 c_parser_consume_token (parser
);
4108 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
4113 dimen
= convert_lvalue_to_rvalue (brace_loc
, dimen
, true, true);
4114 declarator
= build_array_declarator (brace_loc
, dimen
.value
, quals_attrs
,
4115 static_seen
, star_seen
);
4116 if (declarator
== NULL
)
4118 if (c_parser_nth_token_starts_std_attributes (parser
, 1))
4121 = c_parser_std_attribute_specifier_sequence (parser
);
4123 inner
= build_attrs_declarator (std_attrs
, inner
);
4125 inner
= set_array_declarator_inner (declarator
, inner
);
4126 return c_parser_direct_declarator_inner (parser
, id_present
, inner
);
4128 else if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
4131 struct c_arg_info
*args
;
4132 c_parser_consume_token (parser
);
4133 bool have_gnu_attrs
= c_parser_next_token_is_keyword (parser
,
4135 attrs
= c_parser_gnu_attributes (parser
);
4136 args
= c_parser_parms_declarator (parser
, id_present
, attrs
,
4143 && args
->types
!= error_mark_node
4144 && TREE_CODE (TREE_VALUE (args
->types
)) == IDENTIFIER_NODE
)
4145 && c_parser_nth_token_starts_std_attributes (parser
, 1))
4148 = c_parser_std_attribute_specifier_sequence (parser
);
4150 inner
= build_attrs_declarator (std_attrs
, inner
);
4152 inner
= build_function_declarator (args
, inner
);
4153 return c_parser_direct_declarator_inner (parser
, id_present
, inner
);
4159 /* Parse a parameter list or identifier list, including the closing
4160 parenthesis but not the opening one. ATTRS are the gnu-attributes
4161 at the start of the list. ID_LIST_OK is true if an identifier list
4162 is acceptable; such a list must not have attributes at the start.
4163 HAVE_GNU_ATTRS says whether any gnu-attributes (including empty
4164 attributes) were present (in which case standard attributes cannot
4167 static struct c_arg_info
*
4168 c_parser_parms_declarator (c_parser
*parser
, bool id_list_ok
, tree attrs
,
4169 bool have_gnu_attrs
)
4172 declare_parm_level ();
4173 /* If the list starts with an identifier, it is an identifier list.
4174 Otherwise, it is either a prototype list or an empty list. */
4177 && c_parser_next_token_is (parser
, CPP_NAME
)
4178 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
4180 /* Look ahead to detect typos in type names. */
4181 && c_parser_peek_2nd_token (parser
)->type
!= CPP_NAME
4182 && c_parser_peek_2nd_token (parser
)->type
!= CPP_MULT
4183 && c_parser_peek_2nd_token (parser
)->type
!= CPP_OPEN_PAREN
4184 && c_parser_peek_2nd_token (parser
)->type
!= CPP_OPEN_SQUARE
4185 && c_parser_peek_2nd_token (parser
)->type
!= CPP_KEYWORD
)
4187 tree list
= NULL_TREE
, *nextp
= &list
;
4188 while (c_parser_next_token_is (parser
, CPP_NAME
)
4189 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
)
4191 *nextp
= build_tree_list (NULL_TREE
,
4192 c_parser_peek_token (parser
)->value
);
4193 nextp
= & TREE_CHAIN (*nextp
);
4194 c_parser_consume_token (parser
);
4195 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
4197 c_parser_consume_token (parser
);
4198 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4200 c_parser_error (parser
, "expected identifier");
4204 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4206 struct c_arg_info
*ret
= build_arg_info ();
4208 c_parser_consume_token (parser
);
4214 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4222 struct c_arg_info
*ret
4223 = c_parser_parms_list_declarator (parser
, attrs
, NULL
, have_gnu_attrs
);
4229 /* Parse a parameter list (possibly empty), including the closing
4230 parenthesis but not the opening one. ATTRS are the gnu-attributes
4231 at the start of the list; if HAVE_GNU_ATTRS, there were some such
4232 attributes (possibly empty, in which case ATTRS is NULL_TREE),
4233 which means standard attributes cannot start the list. EXPR is
4234 NULL or an expression that needs to be evaluated for the side
4235 effects of array size expressions in the parameters. */
4237 static struct c_arg_info
*
4238 c_parser_parms_list_declarator (c_parser
*parser
, tree attrs
, tree expr
,
4239 bool have_gnu_attrs
)
4241 bool bad_parm
= false;
4243 /* ??? Following the old parser, forward parameter declarations may
4244 use abstract declarators, and if no real parameter declarations
4245 follow the forward declarations then this is not diagnosed. Also
4246 note as above that gnu-attributes are ignored as the only contents of
4247 the parentheses, or as the only contents after forward
4249 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4251 struct c_arg_info
*ret
= build_arg_info ();
4252 c_parser_consume_token (parser
);
4255 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
4257 struct c_arg_info
*ret
= build_arg_info ();
4259 if (flag_allow_parameterless_variadic_functions
)
4261 /* F (...) is allowed. */
4262 ret
->types
= NULL_TREE
;
4266 /* Suppress -Wold-style-definition for this case. */
4267 ret
->types
= error_mark_node
;
4268 error_at (c_parser_peek_token (parser
)->location
,
4269 "ISO C requires a named argument before %<...%>");
4271 c_parser_consume_token (parser
);
4272 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4274 c_parser_consume_token (parser
);
4279 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4284 /* Nonempty list of parameters, either terminated with semicolon
4285 (forward declarations; recurse) or with close parenthesis (normal
4286 function) or with ", ... )" (variadic function). */
4289 /* Parse a parameter. */
4290 struct c_parm
*parm
= c_parser_parameter_declaration (parser
, attrs
,
4293 have_gnu_attrs
= false;
4297 push_parm_decl (parm
, &expr
);
4298 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
4301 c_parser_consume_token (parser
);
4302 mark_forward_parm_decls ();
4303 bool new_have_gnu_attrs
4304 = c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
);
4305 new_attrs
= c_parser_gnu_attributes (parser
);
4306 return c_parser_parms_list_declarator (parser
, new_attrs
, expr
,
4307 new_have_gnu_attrs
);
4309 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4311 c_parser_consume_token (parser
);
4315 return get_parm_info (false, expr
);
4317 if (!c_parser_require (parser
, CPP_COMMA
,
4318 "expected %<;%>, %<,%> or %<)%>",
4319 UNKNOWN_LOCATION
, false))
4321 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
4324 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
4326 c_parser_consume_token (parser
);
4327 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4329 c_parser_consume_token (parser
);
4333 return get_parm_info (true, expr
);
4337 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4345 /* Parse a parameter declaration. ATTRS are the gnu-attributes at the
4346 start of the declaration if it is the first parameter;
4347 HAVE_GNU_ATTRS is true if there were any gnu-attributes there (even
4350 static struct c_parm
*
4351 c_parser_parameter_declaration (c_parser
*parser
, tree attrs
,
4352 bool have_gnu_attrs
)
4354 struct c_declspecs
*specs
;
4355 struct c_declarator
*declarator
;
4357 tree postfix_attrs
= NULL_TREE
;
4360 /* Accept #pragmas between parameter declarations. */
4361 while (c_parser_next_token_is (parser
, CPP_PRAGMA
))
4362 c_parser_pragma (parser
, pragma_param
, NULL
);
4364 if (!c_parser_next_token_starts_declspecs (parser
)
4365 && !c_parser_nth_token_starts_std_attributes (parser
, 1))
4367 c_token
*token
= c_parser_peek_token (parser
);
4370 c_parser_set_source_position_from_token (token
);
4371 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_type
))
4373 auto_diagnostic_group d
;
4374 name_hint hint
= lookup_name_fuzzy (token
->value
,
4375 FUZZY_LOOKUP_TYPENAME
,
4377 if (const char *suggestion
= hint
.suggestion ())
4379 gcc_rich_location
richloc (token
->location
);
4380 richloc
.add_fixit_replace (suggestion
);
4382 "unknown type name %qE; did you mean %qs?",
4383 token
->value
, suggestion
);
4386 error_at (token
->location
, "unknown type name %qE", token
->value
);
4387 parser
->error
= true;
4389 /* ??? In some Objective-C cases '...' isn't applicable so there
4390 should be a different message. */
4392 c_parser_error (parser
,
4393 "expected declaration specifiers or %<...%>");
4394 c_parser_skip_to_end_of_parameter (parser
);
4398 location_t start_loc
= c_parser_peek_token (parser
)->location
;
4400 specs
= build_null_declspecs ();
4403 declspecs_add_attrs (input_location
, specs
, attrs
);
4406 c_parser_declspecs (parser
, specs
, true, true, true, true, false,
4407 !have_gnu_attrs
, true, cla_nonabstract_decl
);
4408 finish_declspecs (specs
);
4409 pending_xref_error ();
4410 prefix_attrs
= specs
->attrs
;
4411 specs
->attrs
= NULL_TREE
;
4412 declarator
= c_parser_declarator (parser
,
4413 specs
->typespec_kind
!= ctsk_none
,
4414 C_DTR_PARM
, &dummy
);
4415 if (declarator
== NULL
)
4417 c_parser_skip_until_found (parser
, CPP_COMMA
, NULL
);
4420 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
4421 postfix_attrs
= c_parser_gnu_attributes (parser
);
4423 /* Generate a location for the parameter, ranging from the start of the
4424 initial token to the end of the final token.
4426 If we have a identifier, then use it for the caret location, e.g.
4428 extern int callee (int one, int (*two)(int, int), float three);
4429 ~~~~~~^~~~~~~~~~~~~~
4431 otherwise, reuse the start location for the caret location e.g.:
4433 extern int callee (int one, int (*)(int, int), float three);
4436 location_t end_loc
= parser
->last_token_location
;
4438 /* Find any cdk_id declarator; determine if we have an identifier. */
4439 c_declarator
*id_declarator
= declarator
;
4440 while (id_declarator
&& id_declarator
->kind
!= cdk_id
)
4441 id_declarator
= id_declarator
->declarator
;
4442 location_t caret_loc
= (id_declarator
->u
.id
.id
4443 ? id_declarator
->id_loc
4445 location_t param_loc
= make_location (caret_loc
, start_loc
, end_loc
);
4447 return build_c_parm (specs
, chainon (postfix_attrs
, prefix_attrs
),
4448 declarator
, param_loc
);
4451 /* Parse a string literal in an asm expression. It should not be
4452 translated, and wide string literals are an error although
4453 permitted by the syntax. This is a GNU extension.
4460 c_parser_asm_string_literal (c_parser
*parser
)
4463 int save_flag
= warn_overlength_strings
;
4464 warn_overlength_strings
= 0;
4465 str
= c_parser_string_literal (parser
, false, false).value
;
4466 warn_overlength_strings
= save_flag
;
4470 /* Parse a simple asm expression. This is used in restricted
4471 contexts, where a full expression with inputs and outputs does not
4472 make sense. This is a GNU extension.
4475 asm ( asm-string-literal )
4479 c_parser_simple_asm_expr (c_parser
*parser
)
4482 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ASM
));
4483 c_parser_consume_token (parser
);
4484 matching_parens parens
;
4485 if (!parens
.require_open (parser
))
4487 str
= c_parser_asm_string_literal (parser
);
4488 if (!parens
.require_close (parser
))
4490 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
4497 c_parser_gnu_attribute_any_word (c_parser
*parser
)
4499 tree attr_name
= NULL_TREE
;
4501 if (c_parser_next_token_is (parser
, CPP_KEYWORD
))
4503 /* ??? See comment above about what keywords are accepted here. */
4505 switch (c_parser_peek_token (parser
)->keyword
)
4536 case RID_TRANSACTION_ATOMIC
:
4537 case RID_TRANSACTION_CANCEL
:
4553 /* Accept __attribute__((__const)) as __attribute__((const)) etc. */
4554 attr_name
= ridpointers
[(int) c_parser_peek_token (parser
)->keyword
];
4556 else if (c_parser_next_token_is (parser
, CPP_NAME
))
4557 attr_name
= c_parser_peek_token (parser
)->value
;
4562 /* Parse attribute arguments. This is a common form of syntax
4563 covering all currently valid GNU and standard attributes.
4565 gnu-attribute-arguments:
4567 identifier , nonempty-expr-list
4570 where the "identifier" must not be declared as a type. ??? Why not
4571 allow identifiers declared as types to start the arguments? */
4574 c_parser_attribute_arguments (c_parser
*parser
, bool takes_identifier
,
4575 bool require_string
, bool allow_empty_args
)
4577 vec
<tree
, va_gc
> *expr_list
;
4579 /* Parse the attribute contents. If they start with an
4580 identifier which is followed by a comma or close
4581 parenthesis, then the arguments start with that
4582 identifier; otherwise they are an expression list.
4583 In objective-c the identifier may be a classname. */
4584 if (c_parser_next_token_is (parser
, CPP_NAME
)
4585 && (c_parser_peek_token (parser
)->id_kind
== C_ID_ID
4586 || (c_dialect_objc ()
4587 && c_parser_peek_token (parser
)->id_kind
4589 && ((c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
)
4590 || (c_parser_peek_2nd_token (parser
)->type
4591 == CPP_CLOSE_PAREN
))
4592 && (takes_identifier
4593 || (c_dialect_objc ()
4594 && c_parser_peek_token (parser
)->id_kind
4595 == C_ID_CLASSNAME
)))
4597 tree arg1
= c_parser_peek_token (parser
)->value
;
4598 c_parser_consume_token (parser
);
4599 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4600 attr_args
= build_tree_list (NULL_TREE
, arg1
);
4604 c_parser_consume_token (parser
);
4605 expr_list
= c_parser_expr_list (parser
, false, true,
4606 NULL
, NULL
, NULL
, NULL
);
4607 tree_list
= build_tree_list_vec (expr_list
);
4608 attr_args
= tree_cons (NULL_TREE
, arg1
, tree_list
);
4609 release_tree_vector (expr_list
);
4614 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4616 if (!allow_empty_args
)
4617 error_at (c_parser_peek_token (parser
)->location
,
4618 "parentheses must be omitted if "
4619 "attribute argument list is empty");
4620 attr_args
= NULL_TREE
;
4622 else if (require_string
)
4624 /* The only valid argument for this attribute is a string
4625 literal. Handle this specially here to avoid accepting
4626 string literals with excess parentheses. */
4627 tree string
= c_parser_string_literal (parser
, false, true).value
;
4628 attr_args
= build_tree_list (NULL_TREE
, string
);
4632 expr_list
= c_parser_expr_list (parser
, false, true,
4633 NULL
, NULL
, NULL
, NULL
);
4634 attr_args
= build_tree_list_vec (expr_list
);
4635 release_tree_vector (expr_list
);
4641 /* Parse (possibly empty) gnu-attributes. This is a GNU extension.
4645 gnu-attributes gnu-attribute
4648 __attribute__ ( ( gnu-attribute-list ) )
4652 gnu-attribute_list , gnu-attrib
4657 any-word ( gnu-attribute-arguments )
4659 where "any-word" may be any identifier (including one declared as a
4660 type), a reserved word storage class specifier, type specifier or
4661 type qualifier. ??? This still leaves out most reserved keywords
4662 (following the old parser), shouldn't we include them?
4663 When EXPECT_COMMA is true, expect the attribute to be preceded
4664 by a comma and fail if it isn't.
4665 When EMPTY_OK is true, allow and consume any number of consecutive
4666 commas with no attributes in between. */
4669 c_parser_gnu_attribute (c_parser
*parser
, tree attrs
,
4670 bool expect_comma
= false, bool empty_ok
= true)
4672 bool comma_first
= c_parser_next_token_is (parser
, CPP_COMMA
);
4674 && !c_parser_next_token_is (parser
, CPP_NAME
)
4675 && !c_parser_next_token_is (parser
, CPP_KEYWORD
))
4678 while (c_parser_next_token_is (parser
, CPP_COMMA
))
4680 c_parser_consume_token (parser
);
4685 tree attr_name
= c_parser_gnu_attribute_any_word (parser
);
4686 if (attr_name
== NULL_TREE
)
4689 attr_name
= canonicalize_attr_name (attr_name
);
4690 c_parser_consume_token (parser
);
4693 if (c_parser_next_token_is_not (parser
, CPP_OPEN_PAREN
))
4695 if (expect_comma
&& !comma_first
)
4697 /* A comma is missing between the last attribute on the chain
4699 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4701 return error_mark_node
;
4703 attr
= build_tree_list (attr_name
, NULL_TREE
);
4704 /* Add this attribute to the list. */
4705 attrs
= chainon (attrs
, attr
);
4708 c_parser_consume_token (parser
);
4711 = c_parser_attribute_arguments (parser
,
4712 attribute_takes_identifier_p (attr_name
),
4715 attr
= build_tree_list (attr_name
, attr_args
);
4716 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4717 c_parser_consume_token (parser
);
4720 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4722 return error_mark_node
;
4725 if (expect_comma
&& !comma_first
)
4727 /* A comma is missing between the last attribute on the chain
4729 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4731 return error_mark_node
;
4734 /* Add this attribute to the list. */
4735 attrs
= chainon (attrs
, attr
);
4740 c_parser_gnu_attributes (c_parser
*parser
)
4742 tree attrs
= NULL_TREE
;
4743 while (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
4745 bool save_translate_strings_p
= parser
->translate_strings_p
;
4746 parser
->translate_strings_p
= false;
4747 /* Consume the `__attribute__' keyword. */
4748 c_parser_consume_token (parser
);
4749 /* Look for the two `(' tokens. */
4750 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
4752 parser
->translate_strings_p
= save_translate_strings_p
;
4755 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
4757 parser
->translate_strings_p
= save_translate_strings_p
;
4758 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
4761 /* Parse the attribute list. Require a comma between successive
4762 (possibly empty) attributes. */
4763 for (bool expect_comma
= false; ; expect_comma
= true)
4765 /* Parse a single attribute. */
4766 tree attr
= c_parser_gnu_attribute (parser
, attrs
, expect_comma
);
4767 if (attr
== error_mark_node
)
4774 /* Look for the two `)' tokens. */
4775 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4776 c_parser_consume_token (parser
);
4779 parser
->translate_strings_p
= save_translate_strings_p
;
4780 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4784 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4785 c_parser_consume_token (parser
);
4788 parser
->translate_strings_p
= save_translate_strings_p
;
4789 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4793 parser
->translate_strings_p
= save_translate_strings_p
;
4799 /* Parse an optional balanced token sequence.
4801 balanced-token-sequence:
4803 balanced-token-sequence balanced-token
4806 ( balanced-token-sequence[opt] )
4807 [ balanced-token-sequence[opt] ]
4808 { balanced-token-sequence[opt] }
4809 any token other than ()[]{}
4813 c_parser_balanced_token_sequence (c_parser
*parser
)
4817 c_token
*token
= c_parser_peek_token (parser
);
4818 switch (token
->type
)
4820 case CPP_OPEN_BRACE
:
4822 matching_braces braces
;
4823 braces
.consume_open (parser
);
4824 c_parser_balanced_token_sequence (parser
);
4825 braces
.require_close (parser
);
4829 case CPP_OPEN_PAREN
:
4831 matching_parens parens
;
4832 parens
.consume_open (parser
);
4833 c_parser_balanced_token_sequence (parser
);
4834 parens
.require_close (parser
);
4838 case CPP_OPEN_SQUARE
:
4839 c_parser_consume_token (parser
);
4840 c_parser_balanced_token_sequence (parser
);
4841 c_parser_require (parser
, CPP_CLOSE_SQUARE
, "expected %<]%>");
4844 case CPP_CLOSE_BRACE
:
4845 case CPP_CLOSE_PAREN
:
4846 case CPP_CLOSE_SQUARE
:
4851 c_parser_consume_token (parser
);
4857 /* Parse standard (C2X) attributes (including GNU attributes in the
4860 attribute-specifier-sequence:
4861 attribute-specifier-sequence[opt] attribute-specifier
4863 attribute-specifier:
4864 [ [ attribute-list ] ]
4868 attribute-list, attribute[opt]
4871 attribute-token attribute-argument-clause[opt]
4875 attribute-prefixed-token
4880 attribute-prefixed-token:
4881 attribute-prefix :: identifier
4886 attribute-argument-clause:
4887 ( balanced-token-sequence[opt] )
4889 Keywords are accepted as identifiers for this purpose.
4893 c_parser_std_attribute (c_parser
*parser
, bool for_tm
)
4895 c_token
*token
= c_parser_peek_token (parser
);
4896 tree ns
, name
, attribute
;
4898 /* Parse the attribute-token. */
4899 if (token
->type
!= CPP_NAME
&& token
->type
!= CPP_KEYWORD
)
4901 c_parser_error (parser
, "expected identifier");
4902 return error_mark_node
;
4904 name
= canonicalize_attr_name (token
->value
);
4905 c_parser_consume_token (parser
);
4906 if (c_parser_next_token_is (parser
, CPP_SCOPE
))
4909 c_parser_consume_token (parser
);
4910 token
= c_parser_peek_token (parser
);
4911 if (token
->type
!= CPP_NAME
&& token
->type
!= CPP_KEYWORD
)
4913 c_parser_error (parser
, "expected identifier");
4914 return error_mark_node
;
4916 name
= canonicalize_attr_name (token
->value
);
4917 c_parser_consume_token (parser
);
4921 attribute
= build_tree_list (build_tree_list (ns
, name
), NULL_TREE
);
4923 /* Parse the arguments, if any. */
4924 const attribute_spec
*as
= lookup_attribute_spec (TREE_PURPOSE (attribute
));
4925 if (c_parser_next_token_is_not (parser
, CPP_OPEN_PAREN
))
4928 location_t open_loc
= c_parser_peek_token (parser
)->location
;
4929 matching_parens parens
;
4930 parens
.consume_open (parser
);
4931 if ((as
&& as
->max_length
== 0)
4932 /* Special-case the transactional-memory attribute "outer",
4933 which is specially handled but not registered as an
4934 attribute, to avoid allowing arbitrary balanced token
4935 sequences as arguments. */
4936 || is_attribute_p ("outer", name
))
4938 error_at (open_loc
, "%qE attribute does not take any arguments", name
);
4939 parens
.skip_until_found_close (parser
);
4940 return error_mark_node
;
4944 bool takes_identifier
4946 && strcmp (IDENTIFIER_POINTER (ns
), "gnu") == 0
4947 && attribute_takes_identifier_p (name
));
4950 && (strcmp (IDENTIFIER_POINTER (name
), "deprecated") == 0
4951 || strcmp (IDENTIFIER_POINTER (name
), "nodiscard") == 0));
4952 TREE_VALUE (attribute
)
4953 = c_parser_attribute_arguments (parser
, takes_identifier
,
4954 require_string
, false);
4957 c_parser_balanced_token_sequence (parser
);
4958 parens
.require_close (parser
);
4961 if (ns
== NULL_TREE
&& !for_tm
&& !as
)
4963 /* An attribute with standard syntax and no namespace specified
4964 is a constraint violation if it is not one of the known
4965 standard attributes. Diagnose it here with a pedwarn and
4966 then discard it to prevent a duplicate warning later. */
4967 pedwarn (input_location
, OPT_Wattributes
, "%qE attribute ignored",
4969 return error_mark_node
;
4975 c_parser_std_attribute_specifier (c_parser
*parser
, bool for_tm
)
4977 location_t loc
= c_parser_peek_token (parser
)->location
;
4978 if (!c_parser_require (parser
, CPP_OPEN_SQUARE
, "expected %<[%>"))
4980 if (!c_parser_require (parser
, CPP_OPEN_SQUARE
, "expected %<[%>"))
4982 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
, "expected %<]%>");
4986 pedwarn_c11 (loc
, OPT_Wpedantic
,
4987 "ISO C does not support %<[[]]%> attributes before C2X");
4988 tree attributes
= NULL_TREE
;
4991 c_token
*token
= c_parser_peek_token (parser
);
4992 if (token
->type
== CPP_CLOSE_SQUARE
)
4994 if (token
->type
== CPP_COMMA
)
4996 c_parser_consume_token (parser
);
4999 tree attribute
= c_parser_std_attribute (parser
, for_tm
);
5000 if (attribute
!= error_mark_node
)
5002 TREE_CHAIN (attribute
) = attributes
;
5003 attributes
= attribute
;
5005 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
5008 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
, "expected %<]%>");
5009 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
, "expected %<]%>");
5010 return nreverse (attributes
);
5013 /* Look past an optional balanced token sequence of raw look-ahead
5014 tokens starting with the *Nth token. *N is updated to point to the
5015 following token. Return true if such a sequence was found, false
5016 if the tokens parsed were not balanced. */
5019 c_parser_check_balanced_raw_token_sequence (c_parser
*parser
, unsigned int *n
)
5023 c_token
*token
= c_parser_peek_nth_token_raw (parser
, *n
);
5024 switch (token
->type
)
5026 case CPP_OPEN_BRACE
:
5029 if (c_parser_check_balanced_raw_token_sequence (parser
, n
))
5031 token
= c_parser_peek_nth_token_raw (parser
, *n
);
5032 if (token
->type
== CPP_CLOSE_BRACE
)
5042 case CPP_OPEN_PAREN
:
5045 if (c_parser_check_balanced_raw_token_sequence (parser
, n
))
5047 token
= c_parser_peek_nth_token_raw (parser
, *n
);
5048 if (token
->type
== CPP_CLOSE_PAREN
)
5058 case CPP_OPEN_SQUARE
:
5061 if (c_parser_check_balanced_raw_token_sequence (parser
, n
))
5063 token
= c_parser_peek_nth_token_raw (parser
, *n
);
5064 if (token
->type
== CPP_CLOSE_SQUARE
)
5074 case CPP_CLOSE_BRACE
:
5075 case CPP_CLOSE_PAREN
:
5076 case CPP_CLOSE_SQUARE
:
5087 /* Return whether standard attributes start with the Nth token. */
5090 c_parser_nth_token_starts_std_attributes (c_parser
*parser
, unsigned int n
)
5092 if (!(c_parser_peek_nth_token (parser
, n
)->type
== CPP_OPEN_SQUARE
5093 && c_parser_peek_nth_token (parser
, n
+ 1)->type
== CPP_OPEN_SQUARE
))
5095 /* In C, '[[' must start attributes. In Objective-C, we need to
5096 check whether '[[' is matched by ']]'. */
5097 if (!c_dialect_objc ())
5100 if (!c_parser_check_balanced_raw_token_sequence (parser
, &n
))
5102 c_token
*token
= c_parser_peek_nth_token_raw (parser
, n
);
5103 if (token
->type
!= CPP_CLOSE_SQUARE
)
5105 token
= c_parser_peek_nth_token_raw (parser
, n
+ 1);
5106 return token
->type
== CPP_CLOSE_SQUARE
;
5110 c_parser_std_attribute_specifier_sequence (c_parser
*parser
)
5112 tree attributes
= NULL_TREE
;
5115 tree attrs
= c_parser_std_attribute_specifier (parser
, false);
5116 attributes
= chainon (attributes
, attrs
);
5118 while (c_parser_nth_token_starts_std_attributes (parser
, 1));
5122 /* Parse a type name (C90 6.5.5, C99 6.7.6, C11 6.7.7). ALIGNAS_OK
5123 says whether alignment specifiers are OK (only in cases that might
5124 be the type name of a compound literal).
5127 specifier-qualifier-list abstract-declarator[opt]
5130 struct c_type_name
*
5131 c_parser_type_name (c_parser
*parser
, bool alignas_ok
)
5133 struct c_declspecs
*specs
= build_null_declspecs ();
5134 struct c_declarator
*declarator
;
5135 struct c_type_name
*ret
;
5137 c_parser_declspecs (parser
, specs
, false, true, true, alignas_ok
, false,
5138 false, true, cla_prefer_type
);
5139 if (!specs
->declspecs_seen_p
)
5141 c_parser_error (parser
, "expected specifier-qualifier-list");
5144 if (specs
->type
!= error_mark_node
)
5146 pending_xref_error ();
5147 finish_declspecs (specs
);
5149 declarator
= c_parser_declarator (parser
,
5150 specs
->typespec_kind
!= ctsk_none
,
5151 C_DTR_ABSTRACT
, &dummy
);
5152 if (declarator
== NULL
)
5154 ret
= XOBNEW (&parser_obstack
, struct c_type_name
);
5156 ret
->declarator
= declarator
;
5160 /* Parse an initializer (C90 6.5.7, C99 6.7.8, C11 6.7.9).
5163 assignment-expression
5164 { initializer-list }
5165 { initializer-list , }
5168 designation[opt] initializer
5169 initializer-list , designation[opt] initializer
5176 designator-list designator
5183 [ constant-expression ]
5195 [ constant-expression ... constant-expression ]
5197 Any expression without commas is accepted in the syntax for the
5198 constant-expressions, with non-constant expressions rejected later.
5200 This function is only used for top-level initializers; for nested
5201 ones, see c_parser_initval. */
5203 static struct c_expr
5204 c_parser_initializer (c_parser
*parser
)
5206 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
5207 return c_parser_braced_init (parser
, NULL_TREE
, false, NULL
);
5211 location_t loc
= c_parser_peek_token (parser
)->location
;
5212 ret
= c_parser_expr_no_commas (parser
, NULL
);
5213 if (TREE_CODE (ret
.value
) != STRING_CST
5214 && TREE_CODE (ret
.value
) != COMPOUND_LITERAL_EXPR
)
5215 ret
= convert_lvalue_to_rvalue (loc
, ret
, true, true);
5220 /* The location of the last comma within the current initializer list,
5221 or UNKNOWN_LOCATION if not within one. */
5223 location_t last_init_list_comma
;
5225 /* Parse a braced initializer list. TYPE is the type specified for a
5226 compound literal, and NULL_TREE for other initializers and for
5227 nested braced lists. NESTED_P is true for nested braced lists,
5228 false for the list of a compound literal or the list that is the
5229 top-level initializer in a declaration. */
5231 static struct c_expr
5232 c_parser_braced_init (c_parser
*parser
, tree type
, bool nested_p
,
5233 struct obstack
*outer_obstack
)
5236 struct obstack braced_init_obstack
;
5237 location_t brace_loc
= c_parser_peek_token (parser
)->location
;
5238 gcc_obstack_init (&braced_init_obstack
);
5239 gcc_assert (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
));
5240 matching_braces braces
;
5241 braces
.consume_open (parser
);
5244 finish_implicit_inits (brace_loc
, outer_obstack
);
5245 push_init_level (brace_loc
, 0, &braced_init_obstack
);
5248 really_start_incremental_init (type
);
5249 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
5251 pedwarn (brace_loc
, OPT_Wpedantic
, "ISO C forbids empty initializer braces");
5255 /* Parse a non-empty initializer list, possibly with a trailing
5259 c_parser_initelt (parser
, &braced_init_obstack
);
5262 if (c_parser_next_token_is (parser
, CPP_COMMA
))
5264 last_init_list_comma
= c_parser_peek_token (parser
)->location
;
5265 c_parser_consume_token (parser
);
5269 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
5273 c_token
*next_tok
= c_parser_peek_token (parser
);
5274 if (next_tok
->type
!= CPP_CLOSE_BRACE
)
5277 ret
.original_code
= ERROR_MARK
;
5278 ret
.original_type
= NULL
;
5279 braces
.skip_until_found_close (parser
);
5280 pop_init_level (brace_loc
, 0, &braced_init_obstack
, last_init_list_comma
);
5281 obstack_free (&braced_init_obstack
, NULL
);
5284 location_t close_loc
= next_tok
->location
;
5285 c_parser_consume_token (parser
);
5286 ret
= pop_init_level (brace_loc
, 0, &braced_init_obstack
, close_loc
);
5287 obstack_free (&braced_init_obstack
, NULL
);
5288 set_c_expr_source_range (&ret
, brace_loc
, close_loc
);
5292 /* Parse a nested initializer, including designators. */
5295 c_parser_initelt (c_parser
*parser
, struct obstack
* braced_init_obstack
)
5297 /* Parse any designator or designator list. A single array
5298 designator may have the subsequent "=" omitted in GNU C, but a
5299 longer list or a structure member designator may not. */
5300 if (c_parser_next_token_is (parser
, CPP_NAME
)
5301 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
5303 /* Old-style structure member designator. */
5304 set_init_label (c_parser_peek_token (parser
)->location
,
5305 c_parser_peek_token (parser
)->value
,
5306 c_parser_peek_token (parser
)->location
,
5307 braced_init_obstack
);
5308 /* Use the colon as the error location. */
5309 pedwarn (c_parser_peek_2nd_token (parser
)->location
, OPT_Wpedantic
,
5310 "obsolete use of designated initializer with %<:%>");
5311 c_parser_consume_token (parser
);
5312 c_parser_consume_token (parser
);
5316 /* des_seen is 0 if there have been no designators, 1 if there
5317 has been a single array designator and 2 otherwise. */
5319 /* Location of a designator. */
5320 location_t des_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
5321 while (c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
)
5322 || c_parser_next_token_is (parser
, CPP_DOT
))
5324 int des_prev
= des_seen
;
5326 des_loc
= c_parser_peek_token (parser
)->location
;
5329 if (c_parser_next_token_is (parser
, CPP_DOT
))
5332 c_parser_consume_token (parser
);
5333 if (c_parser_next_token_is (parser
, CPP_NAME
))
5335 set_init_label (des_loc
, c_parser_peek_token (parser
)->value
,
5336 c_parser_peek_token (parser
)->location
,
5337 braced_init_obstack
);
5338 c_parser_consume_token (parser
);
5344 init
.original_code
= ERROR_MARK
;
5345 init
.original_type
= NULL
;
5346 c_parser_error (parser
, "expected identifier");
5347 c_parser_skip_until_found (parser
, CPP_COMMA
, NULL
);
5348 process_init_element (input_location
, init
, false,
5349 braced_init_obstack
);
5356 location_t ellipsis_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
5357 location_t array_index_loc
= UNKNOWN_LOCATION
;
5358 /* ??? Following the old parser, [ objc-receiver
5359 objc-message-args ] is accepted as an initializer,
5360 being distinguished from a designator by what follows
5361 the first assignment expression inside the square
5362 brackets, but after a first array designator a
5363 subsequent square bracket is for Objective-C taken to
5364 start an expression, using the obsolete form of
5365 designated initializer without '=', rather than
5366 possibly being a second level of designation: in LALR
5367 terms, the '[' is shifted rather than reducing
5368 designator to designator-list. */
5369 if (des_prev
== 1 && c_dialect_objc ())
5371 des_seen
= des_prev
;
5374 if (des_prev
== 0 && c_dialect_objc ())
5376 /* This might be an array designator or an
5377 Objective-C message expression. If the former,
5378 continue parsing here; if the latter, parse the
5379 remainder of the initializer given the starting
5380 primary-expression. ??? It might make sense to
5381 distinguish when des_prev == 1 as well; see
5382 previous comment. */
5384 struct c_expr mexpr
;
5385 c_parser_consume_token (parser
);
5386 if (c_parser_peek_token (parser
)->type
== CPP_NAME
5387 && ((c_parser_peek_token (parser
)->id_kind
5389 || (c_parser_peek_token (parser
)->id_kind
5390 == C_ID_CLASSNAME
)))
5392 /* Type name receiver. */
5393 tree id
= c_parser_peek_token (parser
)->value
;
5394 c_parser_consume_token (parser
);
5395 rec
= objc_get_class_reference (id
);
5396 goto parse_message_args
;
5398 first
= c_parser_expr_no_commas (parser
, NULL
).value
;
5399 mark_exp_read (first
);
5400 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
)
5401 || c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
5402 goto array_desig_after_first
;
5403 /* Expression receiver. So far only one part
5404 without commas has been parsed; there might be
5405 more of the expression. */
5407 while (c_parser_next_token_is (parser
, CPP_COMMA
))
5410 location_t comma_loc
, exp_loc
;
5411 comma_loc
= c_parser_peek_token (parser
)->location
;
5412 c_parser_consume_token (parser
);
5413 exp_loc
= c_parser_peek_token (parser
)->location
;
5414 next
= c_parser_expr_no_commas (parser
, NULL
);
5415 next
= convert_lvalue_to_rvalue (exp_loc
, next
,
5417 rec
= build_compound_expr (comma_loc
, rec
, next
.value
);
5420 /* Now parse the objc-message-args. */
5421 args
= c_parser_objc_message_args (parser
);
5422 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
5425 = objc_build_message_expr (rec
, args
);
5426 mexpr
.original_code
= ERROR_MARK
;
5427 mexpr
.original_type
= NULL
;
5428 /* Now parse and process the remainder of the
5429 initializer, starting with this message
5430 expression as a primary-expression. */
5431 c_parser_initval (parser
, &mexpr
, braced_init_obstack
);
5434 c_parser_consume_token (parser
);
5435 array_index_loc
= c_parser_peek_token (parser
)->location
;
5436 first
= c_parser_expr_no_commas (parser
, NULL
).value
;
5437 mark_exp_read (first
);
5438 array_desig_after_first
:
5439 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
5441 ellipsis_loc
= c_parser_peek_token (parser
)->location
;
5442 c_parser_consume_token (parser
);
5443 second
= c_parser_expr_no_commas (parser
, NULL
).value
;
5444 mark_exp_read (second
);
5448 if (c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
5450 c_parser_consume_token (parser
);
5451 set_init_index (array_index_loc
, first
, second
,
5452 braced_init_obstack
);
5454 pedwarn (ellipsis_loc
, OPT_Wpedantic
,
5455 "ISO C forbids specifying range of elements to initialize");
5458 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
5464 if (c_parser_next_token_is (parser
, CPP_EQ
))
5466 pedwarn_c90 (des_loc
, OPT_Wpedantic
,
5467 "ISO C90 forbids specifying subobject "
5469 c_parser_consume_token (parser
);
5474 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
5475 "obsolete use of designated initializer without %<=%>");
5480 init
.original_code
= ERROR_MARK
;
5481 init
.original_type
= NULL
;
5482 c_parser_error (parser
, "expected %<=%>");
5483 c_parser_skip_until_found (parser
, CPP_COMMA
, NULL
);
5484 process_init_element (input_location
, init
, false,
5485 braced_init_obstack
);
5491 c_parser_initval (parser
, NULL
, braced_init_obstack
);
5494 /* Parse a nested initializer; as c_parser_initializer but parses
5495 initializers within braced lists, after any designators have been
5496 applied. If AFTER is not NULL then it is an Objective-C message
5497 expression which is the primary-expression starting the
5501 c_parser_initval (c_parser
*parser
, struct c_expr
*after
,
5502 struct obstack
* braced_init_obstack
)
5505 gcc_assert (!after
|| c_dialect_objc ());
5506 location_t loc
= c_parser_peek_token (parser
)->location
;
5508 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
) && !after
)
5509 init
= c_parser_braced_init (parser
, NULL_TREE
, true,
5510 braced_init_obstack
);
5513 init
= c_parser_expr_no_commas (parser
, after
);
5514 if (init
.value
!= NULL_TREE
5515 && TREE_CODE (init
.value
) != STRING_CST
5516 && TREE_CODE (init
.value
) != COMPOUND_LITERAL_EXPR
)
5517 init
= convert_lvalue_to_rvalue (loc
, init
, true, true);
5519 process_init_element (loc
, init
, false, braced_init_obstack
);
5522 /* Parse a compound statement (possibly a function body) (C90 6.6.2,
5523 C99 6.8.2, C11 6.8.2, C2X 6.8.2).
5526 { block-item-list[opt] }
5527 { label-declarations block-item-list }
5531 block-item-list block-item
5544 { label-declarations block-item-list }
5547 __extension__ nested-declaration
5548 nested-function-definition
5552 label-declarations label-declaration
5555 __label__ identifier-list ;
5557 Allowing the mixing of declarations and code is new in C99. The
5558 GNU syntax also permits (not shown above) labels at the end of
5559 compound statements, which yield an error. We don't allow labels
5560 on declarations; this might seem like a natural extension, but
5561 there would be a conflict between gnu-attributes on the label and
5562 prefix gnu-attributes on the declaration. ??? The syntax follows the
5563 old parser in requiring something after label declarations.
5564 Although they are erroneous if the labels declared aren't defined,
5565 is it useful for the syntax to be this way?
5586 cancellation-point-directive */
5589 c_parser_compound_statement (c_parser
*parser
, location_t
*endlocp
)
5592 location_t brace_loc
;
5593 brace_loc
= c_parser_peek_token (parser
)->location
;
5594 if (!c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
5596 /* Ensure a scope is entered and left anyway to avoid confusion
5597 if we have just prepared to enter a function body. */
5598 stmt
= c_begin_compound_stmt (true);
5599 c_end_compound_stmt (brace_loc
, stmt
, true);
5600 return error_mark_node
;
5602 stmt
= c_begin_compound_stmt (true);
5603 location_t end_loc
= c_parser_compound_statement_nostart (parser
);
5607 return c_end_compound_stmt (brace_loc
, stmt
, true);
5610 /* Parse a compound statement except for the opening brace. This is
5611 used for parsing both compound statements and statement expressions
5612 (which follow different paths to handling the opening). */
5615 c_parser_compound_statement_nostart (c_parser
*parser
)
5617 bool last_stmt
= false;
5618 bool last_label
= false;
5619 bool save_valid_for_pragma
= valid_location_for_stdc_pragma_p ();
5620 location_t label_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
5621 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
5623 location_t endloc
= c_parser_peek_token (parser
)->location
;
5624 add_debug_begin_stmt (endloc
);
5625 c_parser_consume_token (parser
);
5628 mark_valid_location_for_stdc_pragma (true);
5629 if (c_parser_next_token_is_keyword (parser
, RID_LABEL
))
5631 /* Read zero or more forward-declarations for labels that nested
5632 functions can jump to. */
5633 mark_valid_location_for_stdc_pragma (false);
5634 while (c_parser_next_token_is_keyword (parser
, RID_LABEL
))
5636 label_loc
= c_parser_peek_token (parser
)->location
;
5637 c_parser_consume_token (parser
);
5638 /* Any identifiers, including those declared as type names,
5643 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
5645 c_parser_error (parser
, "expected identifier");
5649 = declare_label (c_parser_peek_token (parser
)->value
);
5650 C_DECLARED_LABEL_FLAG (label
) = 1;
5651 add_stmt (build_stmt (label_loc
, DECL_EXPR
, label
));
5652 c_parser_consume_token (parser
);
5653 if (c_parser_next_token_is (parser
, CPP_COMMA
))
5654 c_parser_consume_token (parser
);
5658 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
5660 pedwarn (label_loc
, OPT_Wpedantic
, "ISO C forbids label declarations");
5662 /* We must now have at least one statement, label or declaration. */
5663 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
5665 mark_valid_location_for_stdc_pragma (save_valid_for_pragma
);
5666 c_parser_error (parser
, "expected declaration or statement");
5667 location_t endloc
= c_parser_peek_token (parser
)->location
;
5668 c_parser_consume_token (parser
);
5671 while (c_parser_next_token_is_not (parser
, CPP_CLOSE_BRACE
))
5673 location_t loc
= c_parser_peek_token (parser
)->location
;
5674 loc
= expansion_point_location_if_in_system_header (loc
);
5675 /* Standard attributes may start a label, statement or declaration. */
5677 = c_parser_nth_token_starts_std_attributes (parser
, 1);
5678 tree std_attrs
= NULL_TREE
;
5680 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
5681 if (c_parser_next_token_is_keyword (parser
, RID_CASE
)
5682 || c_parser_next_token_is_keyword (parser
, RID_DEFAULT
)
5683 || (c_parser_next_token_is (parser
, CPP_NAME
)
5684 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
))
5686 if (c_parser_next_token_is_keyword (parser
, RID_CASE
))
5687 label_loc
= c_parser_peek_2nd_token (parser
)->location
;
5689 label_loc
= c_parser_peek_token (parser
)->location
;
5692 mark_valid_location_for_stdc_pragma (false);
5693 c_parser_label (parser
, std_attrs
);
5695 else if (c_parser_next_tokens_start_declaration (parser
)
5697 && c_parser_next_token_is (parser
, CPP_SEMICOLON
)))
5700 pedwarn_c11 (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
5701 "a label can only be part of a statement and "
5702 "a declaration is not a statement");
5704 mark_valid_location_for_stdc_pragma (false);
5705 bool fallthru_attr_p
= false;
5706 c_parser_declaration_or_fndef (parser
, true, !have_std_attrs
,
5707 true, true, true, NULL
,
5708 NULL
, have_std_attrs
, std_attrs
,
5709 NULL
, &fallthru_attr_p
);
5711 if (last_stmt
&& !fallthru_attr_p
)
5712 pedwarn_c90 (loc
, OPT_Wdeclaration_after_statement
,
5713 "ISO C90 forbids mixed declarations and code");
5714 last_stmt
= fallthru_attr_p
;
5717 else if (c_parser_next_token_is_keyword (parser
, RID_EXTENSION
))
5719 /* __extension__ can start a declaration, but is also an
5720 unary operator that can start an expression. Consume all
5721 but the last of a possible series of __extension__ to
5722 determine which. If standard attributes have already
5723 been seen, it must start a statement, not a declaration,
5724 but standard attributes starting a declaration may appear
5725 after __extension__. */
5726 while (c_parser_peek_2nd_token (parser
)->type
== CPP_KEYWORD
5727 && (c_parser_peek_2nd_token (parser
)->keyword
5729 c_parser_consume_token (parser
);
5731 && (c_token_starts_declaration (c_parser_peek_2nd_token (parser
))
5732 || c_parser_nth_token_starts_std_attributes (parser
, 2)))
5735 ext
= disable_extension_diagnostics ();
5736 c_parser_consume_token (parser
);
5738 mark_valid_location_for_stdc_pragma (false);
5739 c_parser_declaration_or_fndef (parser
, true, true, true, true,
5741 /* Following the old parser, __extension__ does not
5742 disable this diagnostic. */
5743 restore_extension_diagnostics (ext
);
5745 pedwarn_c90 (loc
, OPT_Wdeclaration_after_statement
,
5746 "ISO C90 forbids mixed declarations and code");
5752 else if (c_parser_next_token_is (parser
, CPP_PRAGMA
))
5755 c_parser_error (parser
, "expected declaration or statement");
5756 /* External pragmas, and some omp pragmas, are not associated
5757 with regular c code, and so are not to be considered statements
5758 syntactically. This ensures that the user doesn't put them
5759 places that would turn into syntax errors if the directive
5761 if (c_parser_pragma (parser
,
5762 last_label
? pragma_stmt
: pragma_compound
,
5764 last_label
= false, last_stmt
= true;
5766 else if (c_parser_next_token_is (parser
, CPP_EOF
))
5768 mark_valid_location_for_stdc_pragma (save_valid_for_pragma
);
5769 c_parser_error (parser
, "expected declaration or statement");
5770 return c_parser_peek_token (parser
)->location
;
5772 else if (c_parser_next_token_is_keyword (parser
, RID_ELSE
))
5774 if (parser
->in_if_block
)
5776 mark_valid_location_for_stdc_pragma (save_valid_for_pragma
);
5777 error_at (loc
, "expected %<}%> before %<else%>");
5778 return c_parser_peek_token (parser
)->location
;
5782 error_at (loc
, "%<else%> without a previous %<if%>");
5783 c_parser_consume_token (parser
);
5790 c_warn_unused_attributes (std_attrs
);
5793 mark_valid_location_for_stdc_pragma (false);
5794 c_parser_statement_after_labels (parser
, NULL
);
5797 parser
->error
= false;
5800 pedwarn_c11 (label_loc
, OPT_Wpedantic
, "label at end of compound statement");
5801 location_t endloc
= c_parser_peek_token (parser
)->location
;
5802 c_parser_consume_token (parser
);
5803 /* Restore the value we started with. */
5804 mark_valid_location_for_stdc_pragma (save_valid_for_pragma
);
5808 /* Parse all consecutive labels, possibly preceded by standard
5809 attributes. In this context, a statement is required, not a
5810 declaration, so attributes must be followed by a statement that is
5811 not just a semicolon. */
5814 c_parser_all_labels (c_parser
*parser
)
5816 tree std_attrs
= NULL
;
5817 if (c_parser_nth_token_starts_std_attributes (parser
, 1))
5819 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
5820 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
5821 c_parser_error (parser
, "expected statement");
5823 while (c_parser_next_token_is_keyword (parser
, RID_CASE
)
5824 || c_parser_next_token_is_keyword (parser
, RID_DEFAULT
)
5825 || (c_parser_next_token_is (parser
, CPP_NAME
)
5826 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
))
5828 c_parser_label (parser
, std_attrs
);
5830 if (c_parser_nth_token_starts_std_attributes (parser
, 1))
5832 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
5833 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
5834 c_parser_error (parser
, "expected statement");
5838 c_warn_unused_attributes (std_attrs
);
5841 /* Parse a label (C90 6.6.1, C99 6.8.1, C11 6.8.1).
5844 identifier : gnu-attributes[opt]
5845 case constant-expression :
5851 case constant-expression ... constant-expression :
5853 The use of gnu-attributes on labels is a GNU extension. The syntax in
5854 GNU C accepts any expressions without commas, non-constant
5855 expressions being rejected later. Any standard
5856 attribute-specifier-sequence before the first label has been parsed
5857 in the caller, to distinguish statements from declarations. Any
5858 attribute-specifier-sequence after the label is parsed in this
5861 c_parser_label (c_parser
*parser
, tree std_attrs
)
5863 location_t loc1
= c_parser_peek_token (parser
)->location
;
5864 tree label
= NULL_TREE
;
5866 /* Remember whether this case or a user-defined label is allowed to fall
5868 bool fallthrough_p
= c_parser_peek_token (parser
)->flags
& PREV_FALLTHROUGH
;
5870 if (c_parser_next_token_is_keyword (parser
, RID_CASE
))
5873 c_parser_consume_token (parser
);
5874 exp1
= c_parser_expr_no_commas (parser
, NULL
).value
;
5875 if (c_parser_next_token_is (parser
, CPP_COLON
))
5877 c_parser_consume_token (parser
);
5878 label
= do_case (loc1
, exp1
, NULL_TREE
);
5880 else if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
5882 c_parser_consume_token (parser
);
5883 exp2
= c_parser_expr_no_commas (parser
, NULL
).value
;
5884 if (c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
5885 label
= do_case (loc1
, exp1
, exp2
);
5888 c_parser_error (parser
, "expected %<:%> or %<...%>");
5890 else if (c_parser_next_token_is_keyword (parser
, RID_DEFAULT
))
5892 c_parser_consume_token (parser
);
5893 if (c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
5894 label
= do_case (loc1
, NULL_TREE
, NULL_TREE
);
5898 tree name
= c_parser_peek_token (parser
)->value
;
5901 location_t loc2
= c_parser_peek_token (parser
)->location
;
5902 gcc_assert (c_parser_next_token_is (parser
, CPP_NAME
));
5903 c_parser_consume_token (parser
);
5904 gcc_assert (c_parser_next_token_is (parser
, CPP_COLON
));
5905 c_parser_consume_token (parser
);
5906 attrs
= c_parser_gnu_attributes (parser
);
5907 tlab
= define_label (loc2
, name
);
5910 decl_attributes (&tlab
, attrs
, 0);
5911 decl_attributes (&tlab
, std_attrs
, 0);
5912 label
= add_stmt (build_stmt (loc1
, LABEL_EXPR
, tlab
));
5915 && c_parser_next_tokens_start_declaration (parser
))
5916 warning_at (loc2
, OPT_Wattributes
, "GNU-style attribute between"
5917 " label and declaration appertains to the label");
5921 if (TREE_CODE (label
) == LABEL_EXPR
)
5922 FALLTHROUGH_LABEL_P (LABEL_EXPR_LABEL (label
)) = fallthrough_p
;
5924 FALLTHROUGH_LABEL_P (CASE_LABEL (label
)) = fallthrough_p
;
5928 /* Parse a statement (C90 6.6, C99 6.8, C11 6.8).
5932 attribute-specifier-sequence[opt] compound-statement
5933 expression-statement
5934 attribute-specifier-sequence[opt] selection-statement
5935 attribute-specifier-sequence[opt] iteration-statement
5936 attribute-specifier-sequence[opt] jump-statement
5939 attribute-specifier-sequence[opt] label statement
5941 expression-statement:
5943 attribute-specifier-sequence expression ;
5945 selection-statement:
5949 iteration-statement:
5958 return expression[opt] ;
5963 attribute-specifier-sequence[opt] asm-statement
5968 expression-statement:
5974 attribute-specifier-sequence[opt] objc-throw-statement
5975 attribute-specifier-sequence[opt] objc-try-catch-statement
5976 attribute-specifier-sequence[opt] objc-synchronized-statement
5978 objc-throw-statement:
5985 attribute-specifier-sequence[opt] openacc-construct
5994 parallel-directive structured-block
5997 kernels-directive structured-block
6000 data-directive structured-block
6003 loop-directive structured-block
6008 attribute-specifier-sequence[opt] openmp-construct
6017 parallel-for-construct
6018 parallel-for-simd-construct
6019 parallel-sections-construct
6026 parallel-directive structured-block
6029 for-directive iteration-statement
6032 simd-directive iteration-statements
6035 for-simd-directive iteration-statements
6038 sections-directive section-scope
6041 single-directive structured-block
6043 parallel-for-construct:
6044 parallel-for-directive iteration-statement
6046 parallel-for-simd-construct:
6047 parallel-for-simd-directive iteration-statement
6049 parallel-sections-construct:
6050 parallel-sections-directive section-scope
6053 master-directive structured-block
6056 critical-directive structured-block
6059 atomic-directive expression-statement
6062 ordered-directive structured-block
6064 Transactional Memory:
6067 attribute-specifier-sequence[opt] transaction-statement
6068 attribute-specifier-sequence[opt] transaction-cancel-statement
6070 IF_P is used to track whether there's a (possibly labeled) if statement
6071 which is not enclosed in braces and has an else clause. This is used to
6072 implement -Wparentheses. */
6075 c_parser_statement (c_parser
*parser
, bool *if_p
, location_t
*loc_after_labels
)
6077 c_parser_all_labels (parser
);
6078 if (loc_after_labels
)
6079 *loc_after_labels
= c_parser_peek_token (parser
)->location
;
6080 c_parser_statement_after_labels (parser
, if_p
, NULL
);
6083 /* Parse a statement, other than a labeled statement. CHAIN is a vector
6084 of if-else-if conditions. All labels and standard attributes have
6085 been parsed in the caller.
6087 IF_P is used to track whether there's a (possibly labeled) if statement
6088 which is not enclosed in braces and has an else clause. This is used to
6089 implement -Wparentheses. */
6092 c_parser_statement_after_labels (c_parser
*parser
, bool *if_p
,
6095 location_t loc
= c_parser_peek_token (parser
)->location
;
6096 tree stmt
= NULL_TREE
;
6097 bool in_if_block
= parser
->in_if_block
;
6098 parser
->in_if_block
= false;
6102 if (c_parser_peek_token (parser
)->type
!= CPP_OPEN_BRACE
)
6103 add_debug_begin_stmt (loc
);
6106 switch (c_parser_peek_token (parser
)->type
)
6108 case CPP_OPEN_BRACE
:
6109 add_stmt (c_parser_compound_statement (parser
));
6112 switch (c_parser_peek_token (parser
)->keyword
)
6115 c_parser_if_statement (parser
, if_p
, chain
);
6118 c_parser_switch_statement (parser
, if_p
);
6121 c_parser_while_statement (parser
, false, 0, if_p
);
6124 c_parser_do_statement (parser
, false, 0);
6127 c_parser_for_statement (parser
, false, 0, if_p
);
6130 c_parser_consume_token (parser
);
6131 if (c_parser_next_token_is (parser
, CPP_NAME
))
6133 stmt
= c_finish_goto_label (loc
,
6134 c_parser_peek_token (parser
)->value
);
6135 c_parser_consume_token (parser
);
6137 else if (c_parser_next_token_is (parser
, CPP_MULT
))
6141 c_parser_consume_token (parser
);
6142 val
= c_parser_expression (parser
);
6143 val
= convert_lvalue_to_rvalue (loc
, val
, false, true);
6144 stmt
= c_finish_goto_ptr (loc
, val
.value
);
6147 c_parser_error (parser
, "expected identifier or %<*%>");
6148 goto expect_semicolon
;
6150 c_parser_consume_token (parser
);
6151 stmt
= c_finish_bc_stmt (loc
, objc_foreach_continue_label
, false);
6152 goto expect_semicolon
;
6154 c_parser_consume_token (parser
);
6155 stmt
= c_finish_bc_stmt (loc
, objc_foreach_break_label
, true);
6156 goto expect_semicolon
;
6158 c_parser_consume_token (parser
);
6159 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6161 stmt
= c_finish_return (loc
, NULL_TREE
, NULL_TREE
);
6162 c_parser_consume_token (parser
);
6166 location_t xloc
= c_parser_peek_token (parser
)->location
;
6167 struct c_expr expr
= c_parser_expression_conv (parser
);
6168 mark_exp_read (expr
.value
);
6169 stmt
= c_finish_return (EXPR_LOC_OR_LOC (expr
.value
, xloc
),
6170 expr
.value
, expr
.original_type
);
6171 goto expect_semicolon
;
6175 stmt
= c_parser_asm_statement (parser
);
6177 case RID_TRANSACTION_ATOMIC
:
6178 case RID_TRANSACTION_RELAXED
:
6179 stmt
= c_parser_transaction (parser
,
6180 c_parser_peek_token (parser
)->keyword
);
6182 case RID_TRANSACTION_CANCEL
:
6183 stmt
= c_parser_transaction_cancel (parser
);
6184 goto expect_semicolon
;
6186 gcc_assert (c_dialect_objc ());
6187 c_parser_consume_token (parser
);
6188 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6190 stmt
= objc_build_throw_stmt (loc
, NULL_TREE
);
6191 c_parser_consume_token (parser
);
6195 struct c_expr expr
= c_parser_expression (parser
);
6196 expr
= convert_lvalue_to_rvalue (loc
, expr
, false, false);
6197 expr
.value
= c_fully_fold (expr
.value
, false, NULL
);
6198 stmt
= objc_build_throw_stmt (loc
, expr
.value
);
6199 goto expect_semicolon
;
6203 gcc_assert (c_dialect_objc ());
6204 c_parser_objc_try_catch_finally_statement (parser
);
6206 case RID_AT_SYNCHRONIZED
:
6207 gcc_assert (c_dialect_objc ());
6208 c_parser_objc_synchronized_statement (parser
);
6212 /* Allow '__attribute__((fallthrough));'. */
6213 tree attrs
= c_parser_gnu_attributes (parser
);
6214 if (attribute_fallthrough_p (attrs
))
6216 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6218 tree fn
= build_call_expr_internal_loc (loc
,
6223 c_parser_consume_token (parser
);
6226 warning_at (loc
, OPT_Wattributes
,
6227 "%<fallthrough%> attribute not followed "
6230 else if (attrs
!= NULL_TREE
)
6231 warning_at (loc
, OPT_Wattributes
, "only attribute %<fallthrough%>"
6232 " can be applied to a null statement");
6240 c_parser_consume_token (parser
);
6242 case CPP_CLOSE_PAREN
:
6243 case CPP_CLOSE_SQUARE
:
6244 /* Avoid infinite loop in error recovery:
6245 c_parser_skip_until_found stops at a closing nesting
6246 delimiter without consuming it, but here we need to consume
6247 it to proceed further. */
6248 c_parser_error (parser
, "expected statement");
6249 c_parser_consume_token (parser
);
6252 if (!c_parser_pragma (parser
, pragma_stmt
, if_p
))
6257 stmt
= c_finish_expr_stmt (loc
, c_parser_expression_conv (parser
).value
);
6259 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
6262 /* Two cases cannot and do not have line numbers associated: If stmt
6263 is degenerate, such as "2;", then stmt is an INTEGER_CST, which
6264 cannot hold line numbers. But that's OK because the statement
6265 will either be changed to a MODIFY_EXPR during gimplification of
6266 the statement expr, or discarded. If stmt was compound, but
6267 without new variables, we will have skipped the creation of a
6268 BIND and will have a bare STATEMENT_LIST. But that's OK because
6269 (recursively) all of the component statements should already have
6270 line numbers assigned. ??? Can we discard no-op statements
6272 if (EXPR_LOCATION (stmt
) == UNKNOWN_LOCATION
)
6273 protected_set_expr_location (stmt
, loc
);
6275 parser
->in_if_block
= in_if_block
;
6278 /* Parse the condition from an if, do, while or for statements. */
6281 c_parser_condition (c_parser
*parser
)
6283 location_t loc
= c_parser_peek_token (parser
)->location
;
6285 cond
= c_parser_expression_conv (parser
).value
;
6286 cond
= c_objc_common_truthvalue_conversion (loc
, cond
);
6287 cond
= c_fully_fold (cond
, false, NULL
);
6288 if (warn_sequence_point
)
6289 verify_sequence_points (cond
);
6293 /* Parse a parenthesized condition from an if, do or while statement.
6299 c_parser_paren_condition (c_parser
*parser
)
6302 matching_parens parens
;
6303 if (!parens
.require_open (parser
))
6304 return error_mark_node
;
6305 cond
= c_parser_condition (parser
);
6306 parens
.skip_until_found_close (parser
);
6310 /* Parse a statement which is a block in C99.
6312 IF_P is used to track whether there's a (possibly labeled) if statement
6313 which is not enclosed in braces and has an else clause. This is used to
6314 implement -Wparentheses. */
6317 c_parser_c99_block_statement (c_parser
*parser
, bool *if_p
,
6318 location_t
*loc_after_labels
)
6320 tree block
= c_begin_compound_stmt (flag_isoc99
);
6321 location_t loc
= c_parser_peek_token (parser
)->location
;
6322 c_parser_statement (parser
, if_p
, loc_after_labels
);
6323 return c_end_compound_stmt (loc
, block
, flag_isoc99
);
6326 /* Parse the body of an if statement. This is just parsing a
6327 statement but (a) it is a block in C99, (b) we track whether the
6328 body is an if statement for the sake of -Wparentheses warnings, (c)
6329 we handle an empty body specially for the sake of -Wempty-body
6330 warnings, and (d) we call parser_compound_statement directly
6331 because c_parser_statement_after_labels resets
6332 parser->in_if_block.
6334 IF_P is used to track whether there's a (possibly labeled) if statement
6335 which is not enclosed in braces and has an else clause. This is used to
6336 implement -Wparentheses. */
6339 c_parser_if_body (c_parser
*parser
, bool *if_p
,
6340 const token_indent_info
&if_tinfo
)
6342 tree block
= c_begin_compound_stmt (flag_isoc99
);
6343 location_t body_loc
= c_parser_peek_token (parser
)->location
;
6344 location_t body_loc_after_labels
= UNKNOWN_LOCATION
;
6345 token_indent_info body_tinfo
6346 = get_token_indent_info (c_parser_peek_token (parser
));
6348 c_parser_all_labels (parser
);
6349 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6351 location_t loc
= c_parser_peek_token (parser
)->location
;
6352 add_stmt (build_empty_stmt (loc
));
6353 c_parser_consume_token (parser
);
6354 if (!c_parser_next_token_is_keyword (parser
, RID_ELSE
))
6355 warning_at (loc
, OPT_Wempty_body
,
6356 "suggest braces around empty body in an %<if%> statement");
6358 else if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
6359 add_stmt (c_parser_compound_statement (parser
));
6362 body_loc_after_labels
= c_parser_peek_token (parser
)->location
;
6363 c_parser_statement_after_labels (parser
, if_p
);
6366 token_indent_info next_tinfo
6367 = get_token_indent_info (c_parser_peek_token (parser
));
6368 warn_for_misleading_indentation (if_tinfo
, body_tinfo
, next_tinfo
);
6369 if (body_loc_after_labels
!= UNKNOWN_LOCATION
6370 && next_tinfo
.type
!= CPP_SEMICOLON
)
6371 warn_for_multistatement_macros (body_loc_after_labels
, next_tinfo
.location
,
6372 if_tinfo
.location
, RID_IF
);
6374 return c_end_compound_stmt (body_loc
, block
, flag_isoc99
);
6377 /* Parse the else body of an if statement. This is just parsing a
6378 statement but (a) it is a block in C99, (b) we handle an empty body
6379 specially for the sake of -Wempty-body warnings. CHAIN is a vector
6380 of if-else-if conditions. */
6383 c_parser_else_body (c_parser
*parser
, const token_indent_info
&else_tinfo
,
6386 location_t body_loc
= c_parser_peek_token (parser
)->location
;
6387 tree block
= c_begin_compound_stmt (flag_isoc99
);
6388 token_indent_info body_tinfo
6389 = get_token_indent_info (c_parser_peek_token (parser
));
6390 location_t body_loc_after_labels
= UNKNOWN_LOCATION
;
6392 c_parser_all_labels (parser
);
6393 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6395 location_t loc
= c_parser_peek_token (parser
)->location
;
6398 "suggest braces around empty body in an %<else%> statement");
6399 add_stmt (build_empty_stmt (loc
));
6400 c_parser_consume_token (parser
);
6404 if (!c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
6405 body_loc_after_labels
= c_parser_peek_token (parser
)->location
;
6406 c_parser_statement_after_labels (parser
, NULL
, chain
);
6409 token_indent_info next_tinfo
6410 = get_token_indent_info (c_parser_peek_token (parser
));
6411 warn_for_misleading_indentation (else_tinfo
, body_tinfo
, next_tinfo
);
6412 if (body_loc_after_labels
!= UNKNOWN_LOCATION
6413 && next_tinfo
.type
!= CPP_SEMICOLON
)
6414 warn_for_multistatement_macros (body_loc_after_labels
, next_tinfo
.location
,
6415 else_tinfo
.location
, RID_ELSE
);
6417 return c_end_compound_stmt (body_loc
, block
, flag_isoc99
);
6420 /* We might need to reclassify any previously-lexed identifier, e.g.
6421 when we've left a for loop with an if-statement without else in the
6422 body - we might have used a wrong scope for the token. See PR67784. */
6425 c_parser_maybe_reclassify_token (c_parser
*parser
)
6427 if (c_parser_next_token_is (parser
, CPP_NAME
))
6429 c_token
*token
= c_parser_peek_token (parser
);
6431 if (token
->id_kind
!= C_ID_CLASSNAME
)
6433 tree decl
= lookup_name (token
->value
);
6435 token
->id_kind
= C_ID_ID
;
6438 if (TREE_CODE (decl
) == TYPE_DECL
)
6439 token
->id_kind
= C_ID_TYPENAME
;
6441 else if (c_dialect_objc ())
6443 tree objc_interface_decl
= objc_is_class_name (token
->value
);
6444 /* Objective-C class names are in the same namespace as
6445 variables and typedefs, and hence are shadowed by local
6447 if (objc_interface_decl
)
6449 token
->value
= objc_interface_decl
;
6450 token
->id_kind
= C_ID_CLASSNAME
;
6457 /* Parse an if statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
6460 if ( expression ) statement
6461 if ( expression ) statement else statement
6463 CHAIN is a vector of if-else-if conditions.
6464 IF_P is used to track whether there's a (possibly labeled) if statement
6465 which is not enclosed in braces and has an else clause. This is used to
6466 implement -Wparentheses. */
6469 c_parser_if_statement (c_parser
*parser
, bool *if_p
, vec
<tree
> *chain
)
6474 bool nested_if
= false;
6475 tree first_body
, second_body
;
6478 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_IF
));
6479 token_indent_info if_tinfo
6480 = get_token_indent_info (c_parser_peek_token (parser
));
6481 c_parser_consume_token (parser
);
6482 block
= c_begin_compound_stmt (flag_isoc99
);
6483 loc
= c_parser_peek_token (parser
)->location
;
6484 cond
= c_parser_paren_condition (parser
);
6485 in_if_block
= parser
->in_if_block
;
6486 parser
->in_if_block
= true;
6487 first_body
= c_parser_if_body (parser
, &nested_if
, if_tinfo
);
6488 parser
->in_if_block
= in_if_block
;
6490 if (warn_duplicated_cond
)
6491 warn_duplicated_cond_add_or_warn (EXPR_LOCATION (cond
), cond
, &chain
);
6493 if (c_parser_next_token_is_keyword (parser
, RID_ELSE
))
6495 token_indent_info else_tinfo
6496 = get_token_indent_info (c_parser_peek_token (parser
));
6497 c_parser_consume_token (parser
);
6498 if (warn_duplicated_cond
)
6500 if (c_parser_next_token_is_keyword (parser
, RID_IF
)
6503 /* We've got "if (COND) else if (COND2)". Start the
6504 condition chain and add COND as the first element. */
6505 chain
= new vec
<tree
> ();
6506 if (!CONSTANT_CLASS_P (cond
) && !TREE_SIDE_EFFECTS (cond
))
6507 chain
->safe_push (cond
);
6509 else if (!c_parser_next_token_is_keyword (parser
, RID_IF
))
6510 /* This is if-else without subsequent if. Zap the condition
6511 chain; we would have already warned at this point. */
6514 second_body
= c_parser_else_body (parser
, else_tinfo
, chain
);
6515 /* Set IF_P to true to indicate that this if statement has an
6516 else clause. This may trigger the Wparentheses warning
6517 below when we get back up to the parent if statement. */
6523 second_body
= NULL_TREE
;
6525 /* Diagnose an ambiguous else if if-then-else is nested inside
6528 warning_at (loc
, OPT_Wdangling_else
,
6529 "suggest explicit braces to avoid ambiguous %<else%>");
6531 if (warn_duplicated_cond
)
6532 /* This if statement does not have an else clause. We don't
6533 need the condition chain anymore. */
6536 c_finish_if_stmt (loc
, cond
, first_body
, second_body
);
6537 add_stmt (c_end_compound_stmt (loc
, block
, flag_isoc99
));
6539 c_parser_maybe_reclassify_token (parser
);
6542 /* Parse a switch statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
6545 switch (expression) statement
6549 c_parser_switch_statement (c_parser
*parser
, bool *if_p
)
6552 tree block
, expr
, body
;
6553 unsigned char save_in_statement
;
6554 location_t switch_loc
= c_parser_peek_token (parser
)->location
;
6555 location_t switch_cond_loc
;
6556 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_SWITCH
));
6557 c_parser_consume_token (parser
);
6558 block
= c_begin_compound_stmt (flag_isoc99
);
6559 bool explicit_cast_p
= false;
6560 matching_parens parens
;
6561 if (parens
.require_open (parser
))
6563 switch_cond_loc
= c_parser_peek_token (parser
)->location
;
6564 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
)
6565 && c_token_starts_typename (c_parser_peek_2nd_token (parser
)))
6566 explicit_cast_p
= true;
6567 ce
= c_parser_expression (parser
);
6568 ce
= convert_lvalue_to_rvalue (switch_cond_loc
, ce
, true, true);
6570 /* ??? expr has no valid location? */
6571 parens
.skip_until_found_close (parser
);
6575 switch_cond_loc
= UNKNOWN_LOCATION
;
6576 expr
= error_mark_node
;
6577 ce
.original_type
= error_mark_node
;
6579 c_start_switch (switch_loc
, switch_cond_loc
, expr
, explicit_cast_p
);
6580 save_in_statement
= in_statement
;
6581 in_statement
|= IN_SWITCH_STMT
;
6582 location_t loc_after_labels
;
6583 bool open_brace_p
= c_parser_peek_token (parser
)->type
== CPP_OPEN_BRACE
;
6584 body
= c_parser_c99_block_statement (parser
, if_p
, &loc_after_labels
);
6585 location_t next_loc
= c_parser_peek_token (parser
)->location
;
6586 if (!open_brace_p
&& c_parser_peek_token (parser
)->type
!= CPP_SEMICOLON
)
6587 warn_for_multistatement_macros (loc_after_labels
, next_loc
, switch_loc
,
6589 c_finish_switch (body
, ce
.original_type
);
6590 in_statement
= save_in_statement
;
6591 add_stmt (c_end_compound_stmt (switch_loc
, block
, flag_isoc99
));
6592 c_parser_maybe_reclassify_token (parser
);
6595 /* Parse a while statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6598 while (expression) statement
6600 IF_P is used to track whether there's a (possibly labeled) if statement
6601 which is not enclosed in braces and has an else clause. This is used to
6602 implement -Wparentheses. */
6605 c_parser_while_statement (c_parser
*parser
, bool ivdep
, unsigned short unroll
,
6608 tree block
, cond
, body
;
6609 unsigned char save_in_statement
;
6611 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_WHILE
));
6612 token_indent_info while_tinfo
6613 = get_token_indent_info (c_parser_peek_token (parser
));
6614 c_parser_consume_token (parser
);
6615 block
= c_begin_compound_stmt (flag_isoc99
);
6616 loc
= c_parser_peek_token (parser
)->location
;
6617 cond
= c_parser_paren_condition (parser
);
6618 if (ivdep
&& cond
!= error_mark_node
)
6619 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
6620 build_int_cst (integer_type_node
,
6621 annot_expr_ivdep_kind
),
6623 if (unroll
&& cond
!= error_mark_node
)
6624 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
6625 build_int_cst (integer_type_node
,
6626 annot_expr_unroll_kind
),
6627 build_int_cst (integer_type_node
, unroll
));
6628 save_in_statement
= in_statement
;
6629 in_statement
= IN_ITERATION_STMT
;
6631 token_indent_info body_tinfo
6632 = get_token_indent_info (c_parser_peek_token (parser
));
6634 location_t loc_after_labels
;
6635 bool open_brace
= c_parser_next_token_is (parser
, CPP_OPEN_BRACE
);
6636 body
= c_parser_c99_block_statement (parser
, if_p
, &loc_after_labels
);
6637 add_stmt (build_stmt (loc
, WHILE_STMT
, cond
, body
));
6638 add_stmt (c_end_compound_stmt (loc
, block
, flag_isoc99
));
6639 c_parser_maybe_reclassify_token (parser
);
6641 token_indent_info next_tinfo
6642 = get_token_indent_info (c_parser_peek_token (parser
));
6643 warn_for_misleading_indentation (while_tinfo
, body_tinfo
, next_tinfo
);
6645 if (next_tinfo
.type
!= CPP_SEMICOLON
&& !open_brace
)
6646 warn_for_multistatement_macros (loc_after_labels
, next_tinfo
.location
,
6647 while_tinfo
.location
, RID_WHILE
);
6649 in_statement
= save_in_statement
;
6652 /* Parse a do statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6655 do statement while ( expression ) ;
6659 c_parser_do_statement (c_parser
*parser
, bool ivdep
, unsigned short unroll
)
6661 tree block
, cond
, body
;
6662 unsigned char save_in_statement
;
6664 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_DO
));
6665 c_parser_consume_token (parser
);
6666 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6667 warning_at (c_parser_peek_token (parser
)->location
,
6669 "suggest braces around empty body in %<do%> statement");
6670 block
= c_begin_compound_stmt (flag_isoc99
);
6671 loc
= c_parser_peek_token (parser
)->location
;
6672 save_in_statement
= in_statement
;
6673 in_statement
= IN_ITERATION_STMT
;
6674 body
= c_parser_c99_block_statement (parser
, NULL
);
6675 c_parser_require_keyword (parser
, RID_WHILE
, "expected %<while%>");
6676 in_statement
= save_in_statement
;
6677 cond
= c_parser_paren_condition (parser
);
6678 if (ivdep
&& cond
!= error_mark_node
)
6679 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
6680 build_int_cst (integer_type_node
,
6681 annot_expr_ivdep_kind
),
6683 if (unroll
&& cond
!= error_mark_node
)
6684 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
6685 build_int_cst (integer_type_node
,
6686 annot_expr_unroll_kind
),
6687 build_int_cst (integer_type_node
, unroll
));
6688 if (!c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
6689 c_parser_skip_to_end_of_block_or_statement (parser
);
6691 add_stmt (build_stmt (loc
, DO_STMT
, cond
, body
));
6692 add_stmt (c_end_compound_stmt (loc
, block
, flag_isoc99
));
6695 /* Parse a for statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6698 for ( expression[opt] ; expression[opt] ; expression[opt] ) statement
6699 for ( nested-declaration expression[opt] ; expression[opt] ) statement
6701 The form with a declaration is new in C99.
6703 ??? In accordance with the old parser, the declaration may be a
6704 nested function, which is then rejected in check_for_loop_decls,
6705 but does it make any sense for this to be included in the grammar?
6706 Note in particular that the nested function does not include a
6707 trailing ';', whereas the "declaration" production includes one.
6708 Also, can we reject bad declarations earlier and cheaper than
6709 check_for_loop_decls?
6711 In Objective-C, there are two additional variants:
6714 for ( expression in expresssion ) statement
6715 for ( declaration in expression ) statement
6717 This is inconsistent with C, because the second variant is allowed
6718 even if c99 is not enabled.
6720 The rest of the comment documents these Objective-C foreach-statement.
6722 Here is the canonical example of the first variant:
6723 for (object in array) { do something with object }
6724 we call the first expression ("object") the "object_expression" and
6725 the second expression ("array") the "collection_expression".
6726 object_expression must be an lvalue of type "id" (a generic Objective-C
6727 object) because the loop works by assigning to object_expression the
6728 various objects from the collection_expression. collection_expression
6729 must evaluate to something of type "id" which responds to the method
6730 countByEnumeratingWithState:objects:count:.
6732 The canonical example of the second variant is:
6733 for (id object in array) { do something with object }
6734 which is completely equivalent to
6737 for (object in array) { do something with object }
6739 Note that initizializing 'object' in some way (eg, "for ((object =
6740 xxx) in array) { do something with object }") is possibly
6741 technically valid, but completely pointless as 'object' will be
6742 assigned to something else as soon as the loop starts. We should
6743 most likely reject it (TODO).
6745 The beginning of the Objective-C foreach-statement looks exactly
6746 like the beginning of the for-statement, and we can tell it is a
6747 foreach-statement only because the initial declaration or
6748 expression is terminated by 'in' instead of ';'.
6750 IF_P is used to track whether there's a (possibly labeled) if statement
6751 which is not enclosed in braces and has an else clause. This is used to
6752 implement -Wparentheses. */
6755 c_parser_for_statement (c_parser
*parser
, bool ivdep
, unsigned short unroll
,
6758 tree block
, cond
, incr
, body
;
6759 unsigned char save_in_statement
;
6760 tree save_objc_foreach_break_label
, save_objc_foreach_continue_label
;
6761 /* The following are only used when parsing an ObjC foreach statement. */
6762 tree object_expression
;
6763 /* Silence the bogus uninitialized warning. */
6764 tree collection_expression
= NULL
;
6765 location_t loc
= c_parser_peek_token (parser
)->location
;
6766 location_t for_loc
= loc
;
6767 bool is_foreach_statement
= false;
6768 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_FOR
));
6769 token_indent_info for_tinfo
6770 = get_token_indent_info (c_parser_peek_token (parser
));
6771 c_parser_consume_token (parser
);
6772 /* Open a compound statement in Objective-C as well, just in case this is
6773 as foreach expression. */
6774 block
= c_begin_compound_stmt (flag_isoc99
|| c_dialect_objc ());
6775 cond
= error_mark_node
;
6776 incr
= error_mark_node
;
6777 matching_parens parens
;
6778 if (parens
.require_open (parser
))
6780 /* Parse the initialization declaration or expression. */
6781 object_expression
= error_mark_node
;
6782 parser
->objc_could_be_foreach_context
= c_dialect_objc ();
6783 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6785 parser
->objc_could_be_foreach_context
= false;
6786 c_parser_consume_token (parser
);
6787 c_finish_expr_stmt (loc
, NULL_TREE
);
6789 else if (c_parser_next_tokens_start_declaration (parser
)
6790 || c_parser_nth_token_starts_std_attributes (parser
, 1))
6792 c_parser_declaration_or_fndef (parser
, true, true, true, true, true,
6793 &object_expression
);
6794 parser
->objc_could_be_foreach_context
= false;
6796 if (c_parser_next_token_is_keyword (parser
, RID_IN
))
6798 c_parser_consume_token (parser
);
6799 is_foreach_statement
= true;
6800 if (check_for_loop_decls (for_loc
, true) == NULL_TREE
)
6801 c_parser_error (parser
, "multiple iterating variables in "
6802 "fast enumeration");
6805 check_for_loop_decls (for_loc
, flag_isoc99
);
6807 else if (c_parser_next_token_is_keyword (parser
, RID_EXTENSION
))
6809 /* __extension__ can start a declaration, but is also an
6810 unary operator that can start an expression. Consume all
6811 but the last of a possible series of __extension__ to
6813 while (c_parser_peek_2nd_token (parser
)->type
== CPP_KEYWORD
6814 && (c_parser_peek_2nd_token (parser
)->keyword
6816 c_parser_consume_token (parser
);
6817 if (c_token_starts_declaration (c_parser_peek_2nd_token (parser
))
6818 || c_parser_nth_token_starts_std_attributes (parser
, 2))
6821 ext
= disable_extension_diagnostics ();
6822 c_parser_consume_token (parser
);
6823 c_parser_declaration_or_fndef (parser
, true, true, true, true,
6824 true, &object_expression
);
6825 parser
->objc_could_be_foreach_context
= false;
6827 restore_extension_diagnostics (ext
);
6828 if (c_parser_next_token_is_keyword (parser
, RID_IN
))
6830 c_parser_consume_token (parser
);
6831 is_foreach_statement
= true;
6832 if (check_for_loop_decls (for_loc
, true) == NULL_TREE
)
6833 c_parser_error (parser
, "multiple iterating variables in "
6834 "fast enumeration");
6837 check_for_loop_decls (for_loc
, flag_isoc99
);
6847 tree init_expression
;
6848 ce
= c_parser_expression (parser
);
6849 init_expression
= ce
.value
;
6850 parser
->objc_could_be_foreach_context
= false;
6851 if (c_parser_next_token_is_keyword (parser
, RID_IN
))
6853 c_parser_consume_token (parser
);
6854 is_foreach_statement
= true;
6855 if (! lvalue_p (init_expression
))
6856 c_parser_error (parser
, "invalid iterating variable in "
6857 "fast enumeration");
6859 = c_fully_fold (init_expression
, false, NULL
);
6863 ce
= convert_lvalue_to_rvalue (loc
, ce
, true, false);
6864 init_expression
= ce
.value
;
6865 c_finish_expr_stmt (loc
, init_expression
);
6866 c_parser_skip_until_found (parser
, CPP_SEMICOLON
,
6871 /* Parse the loop condition. In the case of a foreach
6872 statement, there is no loop condition. */
6873 gcc_assert (!parser
->objc_could_be_foreach_context
);
6874 if (!is_foreach_statement
)
6876 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6880 c_parser_error (parser
, "missing loop condition in loop "
6881 "with %<GCC ivdep%> pragma");
6882 cond
= error_mark_node
;
6886 c_parser_error (parser
, "missing loop condition in loop "
6887 "with %<GCC unroll%> pragma");
6888 cond
= error_mark_node
;
6892 c_parser_consume_token (parser
);
6898 cond
= c_parser_condition (parser
);
6899 c_parser_skip_until_found (parser
, CPP_SEMICOLON
,
6902 if (ivdep
&& cond
!= error_mark_node
)
6903 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
6904 build_int_cst (integer_type_node
,
6905 annot_expr_ivdep_kind
),
6907 if (unroll
&& cond
!= error_mark_node
)
6908 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
6909 build_int_cst (integer_type_node
,
6910 annot_expr_unroll_kind
),
6911 build_int_cst (integer_type_node
, unroll
));
6913 /* Parse the increment expression (the third expression in a
6914 for-statement). In the case of a foreach-statement, this is
6915 the expression that follows the 'in'. */
6916 loc
= c_parser_peek_token (parser
)->location
;
6917 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
6919 if (is_foreach_statement
)
6921 c_parser_error (parser
,
6922 "missing collection in fast enumeration");
6923 collection_expression
= error_mark_node
;
6926 incr
= c_process_expr_stmt (loc
, NULL_TREE
);
6930 if (is_foreach_statement
)
6931 collection_expression
6932 = c_fully_fold (c_parser_expression (parser
).value
, false, NULL
);
6935 struct c_expr ce
= c_parser_expression (parser
);
6936 ce
= convert_lvalue_to_rvalue (loc
, ce
, true, false);
6937 incr
= c_process_expr_stmt (loc
, ce
.value
);
6940 parens
.skip_until_found_close (parser
);
6942 save_in_statement
= in_statement
;
6943 if (is_foreach_statement
)
6945 in_statement
= IN_OBJC_FOREACH
;
6946 save_objc_foreach_break_label
= objc_foreach_break_label
;
6947 save_objc_foreach_continue_label
= objc_foreach_continue_label
;
6948 objc_foreach_break_label
= create_artificial_label (loc
);
6949 objc_foreach_continue_label
= create_artificial_label (loc
);
6952 in_statement
= IN_ITERATION_STMT
;
6954 token_indent_info body_tinfo
6955 = get_token_indent_info (c_parser_peek_token (parser
));
6957 location_t loc_after_labels
;
6958 bool open_brace
= c_parser_next_token_is (parser
, CPP_OPEN_BRACE
);
6959 body
= c_parser_c99_block_statement (parser
, if_p
, &loc_after_labels
);
6961 if (is_foreach_statement
)
6962 objc_finish_foreach_loop (for_loc
, object_expression
,
6963 collection_expression
, body
,
6964 objc_foreach_break_label
,
6965 objc_foreach_continue_label
);
6967 add_stmt (build_stmt (for_loc
, FOR_STMT
, NULL_TREE
, cond
, incr
,
6969 add_stmt (c_end_compound_stmt (for_loc
, block
,
6970 flag_isoc99
|| c_dialect_objc ()));
6971 c_parser_maybe_reclassify_token (parser
);
6973 token_indent_info next_tinfo
6974 = get_token_indent_info (c_parser_peek_token (parser
));
6975 warn_for_misleading_indentation (for_tinfo
, body_tinfo
, next_tinfo
);
6977 if (next_tinfo
.type
!= CPP_SEMICOLON
&& !open_brace
)
6978 warn_for_multistatement_macros (loc_after_labels
, next_tinfo
.location
,
6979 for_tinfo
.location
, RID_FOR
);
6981 in_statement
= save_in_statement
;
6982 if (is_foreach_statement
)
6984 objc_foreach_break_label
= save_objc_foreach_break_label
;
6985 objc_foreach_continue_label
= save_objc_foreach_continue_label
;
6989 /* Parse an asm statement, a GNU extension. This is a full-blown asm
6990 statement with inputs, outputs, clobbers, and volatile, inline, and goto
6999 asm-qualifier-list asm-qualifier
7003 asm asm-qualifier-list[opt] ( asm-argument ) ;
7007 asm-string-literal : asm-operands[opt]
7008 asm-string-literal : asm-operands[opt] : asm-operands[opt]
7009 asm-string-literal : asm-operands[opt] : asm-operands[opt] \
7011 asm-string-literal : : asm-operands[opt] : asm-clobbers[opt] \
7014 The form with asm-goto-operands is valid if and only if the
7015 asm-qualifier-list contains goto, and is the only allowed form in that case.
7016 Duplicate asm-qualifiers are not allowed.
7018 The :: token is considered equivalent to two consecutive : tokens. */
7021 c_parser_asm_statement (c_parser
*parser
)
7023 tree str
, outputs
, inputs
, clobbers
, labels
, ret
;
7025 location_t asm_loc
= c_parser_peek_token (parser
)->location
;
7026 int section
, nsections
;
7028 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ASM
));
7029 c_parser_consume_token (parser
);
7031 /* Handle the asm-qualifier-list. */
7032 location_t volatile_loc
= UNKNOWN_LOCATION
;
7033 location_t inline_loc
= UNKNOWN_LOCATION
;
7034 location_t goto_loc
= UNKNOWN_LOCATION
;
7037 c_token
*token
= c_parser_peek_token (parser
);
7038 location_t loc
= token
->location
;
7039 switch (token
->keyword
)
7044 error_at (loc
, "duplicate %<asm%> qualifier %qE", token
->value
);
7045 inform (volatile_loc
, "first seen here");
7049 c_parser_consume_token (parser
);
7055 error_at (loc
, "duplicate %<asm%> qualifier %qE", token
->value
);
7056 inform (inline_loc
, "first seen here");
7060 c_parser_consume_token (parser
);
7066 error_at (loc
, "duplicate %<asm%> qualifier %qE", token
->value
);
7067 inform (goto_loc
, "first seen here");
7071 c_parser_consume_token (parser
);
7076 error_at (loc
, "%qE is not a valid %<asm%> qualifier", token
->value
);
7077 c_parser_consume_token (parser
);
7086 bool is_volatile
= (volatile_loc
!= UNKNOWN_LOCATION
);
7087 bool is_inline
= (inline_loc
!= UNKNOWN_LOCATION
);
7088 bool is_goto
= (goto_loc
!= UNKNOWN_LOCATION
);
7092 matching_parens parens
;
7093 if (!parens
.require_open (parser
))
7096 str
= c_parser_asm_string_literal (parser
);
7097 if (str
== NULL_TREE
)
7098 goto error_close_paren
;
7101 outputs
= NULL_TREE
;
7103 clobbers
= NULL_TREE
;
7106 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
) && !is_goto
)
7109 /* Parse each colon-delimited section of operands. */
7110 nsections
= 3 + is_goto
;
7111 for (section
= 0; section
< nsections
; ++section
)
7113 if (c_parser_next_token_is (parser
, CPP_SCOPE
))
7116 if (section
== nsections
)
7118 c_parser_error (parser
, "expected %<)%>");
7119 goto error_close_paren
;
7121 c_parser_consume_token (parser
);
7123 else if (!c_parser_require (parser
, CPP_COLON
,
7125 ? G_("expected %<:%>")
7126 : G_("expected %<:%> or %<)%>"),
7127 UNKNOWN_LOCATION
, is_goto
))
7128 goto error_close_paren
;
7130 /* Once past any colon, we're no longer a simple asm. */
7133 if ((!c_parser_next_token_is (parser
, CPP_COLON
)
7134 && !c_parser_next_token_is (parser
, CPP_SCOPE
)
7135 && !c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
7140 outputs
= c_parser_asm_operands (parser
);
7143 inputs
= c_parser_asm_operands (parser
);
7146 clobbers
= c_parser_asm_clobbers (parser
);
7149 labels
= c_parser_asm_goto_operands (parser
);
7155 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
) && !is_goto
)
7160 if (!parens
.require_close (parser
))
7162 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
7166 if (!c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
7167 c_parser_skip_to_end_of_block_or_statement (parser
);
7169 ret
= build_asm_stmt (is_volatile
,
7170 build_asm_expr (asm_loc
, str
, outputs
, inputs
,
7171 clobbers
, labels
, simple
, is_inline
));
7177 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
7181 /* Parse asm operands, a GNU extension.
7185 asm-operands , asm-operand
7188 asm-string-literal ( expression )
7189 [ identifier ] asm-string-literal ( expression )
7193 c_parser_asm_operands (c_parser
*parser
)
7195 tree list
= NULL_TREE
;
7200 if (c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
))
7202 c_parser_consume_token (parser
);
7203 if (c_parser_next_token_is (parser
, CPP_NAME
))
7205 tree id
= c_parser_peek_token (parser
)->value
;
7206 c_parser_consume_token (parser
);
7207 name
= build_string (IDENTIFIER_LENGTH (id
),
7208 IDENTIFIER_POINTER (id
));
7212 c_parser_error (parser
, "expected identifier");
7213 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
, NULL
);
7216 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
7221 str
= c_parser_asm_string_literal (parser
);
7222 if (str
== NULL_TREE
)
7224 matching_parens parens
;
7225 if (!parens
.require_open (parser
))
7227 expr
= c_parser_expression (parser
);
7228 mark_exp_read (expr
.value
);
7229 if (!parens
.require_close (parser
))
7231 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
7234 list
= chainon (list
, build_tree_list (build_tree_list (name
, str
),
7236 if (c_parser_next_token_is (parser
, CPP_COMMA
))
7237 c_parser_consume_token (parser
);
7244 /* Parse asm clobbers, a GNU extension.
7248 asm-clobbers , asm-string-literal
7252 c_parser_asm_clobbers (c_parser
*parser
)
7254 tree list
= NULL_TREE
;
7257 tree str
= c_parser_asm_string_literal (parser
);
7259 list
= tree_cons (NULL_TREE
, str
, list
);
7262 if (c_parser_next_token_is (parser
, CPP_COMMA
))
7263 c_parser_consume_token (parser
);
7270 /* Parse asm goto labels, a GNU extension.
7274 asm-goto-operands , identifier
7278 c_parser_asm_goto_operands (c_parser
*parser
)
7280 tree list
= NULL_TREE
;
7285 if (c_parser_next_token_is (parser
, CPP_NAME
))
7287 c_token
*tok
= c_parser_peek_token (parser
);
7289 label
= lookup_label_for_goto (tok
->location
, name
);
7290 c_parser_consume_token (parser
);
7291 TREE_USED (label
) = 1;
7295 c_parser_error (parser
, "expected identifier");
7299 name
= build_string (IDENTIFIER_LENGTH (name
),
7300 IDENTIFIER_POINTER (name
));
7301 list
= tree_cons (name
, label
, list
);
7302 if (c_parser_next_token_is (parser
, CPP_COMMA
))
7303 c_parser_consume_token (parser
);
7305 return nreverse (list
);
7309 /* Parse a possibly concatenated sequence of string literals.
7310 TRANSLATE says whether to translate them to the execution character
7311 set; WIDE_OK says whether any kind of prefixed string literal is
7312 permitted in this context. This code is based on that in
7316 c_parser_string_literal (c_parser
*parser
, bool translate
, bool wide_ok
)
7320 struct obstack str_ob
;
7321 struct obstack loc_ob
;
7322 cpp_string str
, istr
, *strs
;
7324 location_t loc
, last_tok_loc
;
7325 enum cpp_ttype type
;
7326 tree value
, string_tree
;
7328 tok
= c_parser_peek_token (parser
);
7329 loc
= tok
->location
;
7330 last_tok_loc
= linemap_resolve_location (line_table
, loc
,
7331 LRK_MACRO_DEFINITION_LOCATION
,
7340 case CPP_UTF8STRING
:
7341 string_tree
= tok
->value
;
7345 c_parser_error (parser
, "expected string literal");
7347 ret
.value
= NULL_TREE
;
7348 ret
.original_code
= ERROR_MARK
;
7349 ret
.original_type
= NULL_TREE
;
7353 /* Try to avoid the overhead of creating and destroying an obstack
7354 for the common case of just one string. */
7355 switch (c_parser_peek_2nd_token (parser
)->type
)
7358 c_parser_consume_token (parser
);
7359 str
.text
= (const unsigned char *) TREE_STRING_POINTER (string_tree
);
7360 str
.len
= TREE_STRING_LENGTH (string_tree
);
7369 case CPP_UTF8STRING
:
7370 gcc_obstack_init (&str_ob
);
7371 gcc_obstack_init (&loc_ob
);
7375 c_parser_consume_token (parser
);
7377 str
.text
= (const unsigned char *) TREE_STRING_POINTER (string_tree
);
7378 str
.len
= TREE_STRING_LENGTH (string_tree
);
7379 if (type
!= tok
->type
)
7381 if (type
== CPP_STRING
)
7383 else if (tok
->type
!= CPP_STRING
)
7384 error ("unsupported non-standard concatenation "
7385 "of string literals");
7387 obstack_grow (&str_ob
, &str
, sizeof (cpp_string
));
7388 obstack_grow (&loc_ob
, &last_tok_loc
, sizeof (location_t
));
7389 tok
= c_parser_peek_token (parser
);
7390 string_tree
= tok
->value
;
7392 = linemap_resolve_location (line_table
, tok
->location
,
7393 LRK_MACRO_DEFINITION_LOCATION
, NULL
);
7395 while (tok
->type
== CPP_STRING
7396 || tok
->type
== CPP_WSTRING
7397 || tok
->type
== CPP_STRING16
7398 || tok
->type
== CPP_STRING32
7399 || tok
->type
== CPP_UTF8STRING
);
7400 strs
= (cpp_string
*) obstack_finish (&str_ob
);
7403 if (count
> 1 && !in_system_header_at (input_location
))
7404 warning (OPT_Wtraditional
,
7405 "traditional C rejects string constant concatenation");
7407 if ((type
== CPP_STRING
|| wide_ok
)
7409 ? cpp_interpret_string
: cpp_interpret_string_notranslate
)
7410 (parse_in
, strs
, count
, &istr
, type
)))
7412 value
= build_string (istr
.len
, (const char *) istr
.text
);
7413 free (CONST_CAST (unsigned char *, istr
.text
));
7416 location_t
*locs
= (location_t
*) obstack_finish (&loc_ob
);
7417 gcc_assert (g_string_concat_db
);
7418 g_string_concat_db
->record_string_concatenation (count
, locs
);
7423 if (type
!= CPP_STRING
&& !wide_ok
)
7425 error_at (loc
, "a wide string is invalid in this context");
7428 /* Callers cannot generally handle error_mark_node in this
7429 context, so return the empty string instead. An error has
7430 been issued, either above or from cpp_interpret_string. */
7435 case CPP_UTF8STRING
:
7436 value
= build_string (1, "");
7439 value
= build_string (TYPE_PRECISION (char16_type_node
)
7440 / TYPE_PRECISION (char_type_node
),
7441 "\0"); /* char16_t is 16 bits */
7444 value
= build_string (TYPE_PRECISION (char32_type_node
)
7445 / TYPE_PRECISION (char_type_node
),
7446 "\0\0\0"); /* char32_t is 32 bits */
7449 value
= build_string (TYPE_PRECISION (wchar_type_node
)
7450 / TYPE_PRECISION (char_type_node
),
7451 "\0\0\0"); /* widest supported wchar_t
7461 case CPP_UTF8STRING
:
7462 TREE_TYPE (value
) = char_array_type_node
;
7465 TREE_TYPE (value
) = char16_array_type_node
;
7468 TREE_TYPE (value
) = char32_array_type_node
;
7471 TREE_TYPE (value
) = wchar_array_type_node
;
7473 value
= fix_string_type (value
);
7477 obstack_free (&str_ob
, 0);
7478 obstack_free (&loc_ob
, 0);
7482 ret
.original_code
= STRING_CST
;
7483 ret
.original_type
= NULL_TREE
;
7484 set_c_expr_source_range (&ret
, get_range_from_loc (line_table
, loc
));
7485 parser
->seen_string_literal
= true;
7489 /* Parse an expression other than a compound expression; that is, an
7490 assignment expression (C90 6.3.16, C99 6.5.16, C11 6.5.16). If
7491 AFTER is not NULL then it is an Objective-C message expression which
7492 is the primary-expression starting the expression as an initializer.
7494 assignment-expression:
7495 conditional-expression
7496 unary-expression assignment-operator assignment-expression
7498 assignment-operator: one of
7499 = *= /= %= += -= <<= >>= &= ^= |=
7501 In GNU C we accept any conditional expression on the LHS and
7502 diagnose the invalid lvalue rather than producing a syntax
7505 static struct c_expr
7506 c_parser_expr_no_commas (c_parser
*parser
, struct c_expr
*after
,
7507 tree omp_atomic_lhs
)
7509 struct c_expr lhs
, rhs
, ret
;
7510 enum tree_code code
;
7511 location_t op_location
, exp_location
;
7512 bool save_in_omp_for
= c_in_omp_for
;
7513 c_in_omp_for
= false;
7514 gcc_assert (!after
|| c_dialect_objc ());
7515 lhs
= c_parser_conditional_expression (parser
, after
, omp_atomic_lhs
);
7516 op_location
= c_parser_peek_token (parser
)->location
;
7517 switch (c_parser_peek_token (parser
)->type
)
7526 code
= TRUNC_DIV_EXPR
;
7529 code
= TRUNC_MOD_EXPR
;
7544 code
= BIT_AND_EXPR
;
7547 code
= BIT_XOR_EXPR
;
7550 code
= BIT_IOR_EXPR
;
7553 c_in_omp_for
= save_in_omp_for
;
7556 c_parser_consume_token (parser
);
7557 exp_location
= c_parser_peek_token (parser
)->location
;
7558 rhs
= c_parser_expr_no_commas (parser
, NULL
);
7559 rhs
= convert_lvalue_to_rvalue (exp_location
, rhs
, true, true);
7561 ret
.value
= build_modify_expr (op_location
, lhs
.value
, lhs
.original_type
,
7562 code
, exp_location
, rhs
.value
,
7564 set_c_expr_source_range (&ret
, lhs
.get_start (), rhs
.get_finish ());
7565 if (code
== NOP_EXPR
)
7566 ret
.original_code
= MODIFY_EXPR
;
7569 suppress_warning (ret
.value
, OPT_Wparentheses
);
7570 ret
.original_code
= ERROR_MARK
;
7572 ret
.original_type
= NULL
;
7573 c_in_omp_for
= save_in_omp_for
;
7577 /* Parse a conditional expression (C90 6.3.15, C99 6.5.15, C11 6.5.15). If
7578 AFTER is not NULL then it is an Objective-C message expression which is
7579 the primary-expression starting the expression as an initializer.
7581 conditional-expression:
7582 logical-OR-expression
7583 logical-OR-expression ? expression : conditional-expression
7587 conditional-expression:
7588 logical-OR-expression ? : conditional-expression
7591 static struct c_expr
7592 c_parser_conditional_expression (c_parser
*parser
, struct c_expr
*after
,
7593 tree omp_atomic_lhs
)
7595 struct c_expr cond
, exp1
, exp2
, ret
;
7596 location_t start
, cond_loc
, colon_loc
;
7598 gcc_assert (!after
|| c_dialect_objc ());
7600 cond
= c_parser_binary_expression (parser
, after
, omp_atomic_lhs
);
7602 if (c_parser_next_token_is_not (parser
, CPP_QUERY
))
7604 if (cond
.value
!= error_mark_node
)
7605 start
= cond
.get_start ();
7607 start
= UNKNOWN_LOCATION
;
7608 cond_loc
= c_parser_peek_token (parser
)->location
;
7609 cond
= convert_lvalue_to_rvalue (cond_loc
, cond
, true, true);
7610 c_parser_consume_token (parser
);
7611 if (c_parser_next_token_is (parser
, CPP_COLON
))
7613 tree eptype
= NULL_TREE
;
7615 location_t middle_loc
= c_parser_peek_token (parser
)->location
;
7616 pedwarn (middle_loc
, OPT_Wpedantic
,
7617 "ISO C forbids omitting the middle term of a %<?:%> expression");
7618 if (TREE_CODE (cond
.value
) == EXCESS_PRECISION_EXPR
)
7620 eptype
= TREE_TYPE (cond
.value
);
7621 cond
.value
= TREE_OPERAND (cond
.value
, 0);
7623 tree e
= cond
.value
;
7624 while (TREE_CODE (e
) == COMPOUND_EXPR
)
7625 e
= TREE_OPERAND (e
, 1);
7626 warn_for_omitted_condop (middle_loc
, e
);
7627 /* Make sure first operand is calculated only once. */
7628 exp1
.value
= save_expr (default_conversion (cond
.value
));
7630 exp1
.value
= build1 (EXCESS_PRECISION_EXPR
, eptype
, exp1
.value
);
7631 exp1
.original_type
= NULL
;
7632 exp1
.src_range
= cond
.src_range
;
7633 cond
.value
= c_objc_common_truthvalue_conversion (cond_loc
, exp1
.value
);
7634 c_inhibit_evaluation_warnings
+= cond
.value
== truthvalue_true_node
;
7639 = c_objc_common_truthvalue_conversion
7640 (cond_loc
, default_conversion (cond
.value
));
7641 c_inhibit_evaluation_warnings
+= cond
.value
== truthvalue_false_node
;
7642 exp1
= c_parser_expression_conv (parser
);
7643 mark_exp_read (exp1
.value
);
7644 c_inhibit_evaluation_warnings
+=
7645 ((cond
.value
== truthvalue_true_node
)
7646 - (cond
.value
== truthvalue_false_node
));
7649 colon_loc
= c_parser_peek_token (parser
)->location
;
7650 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
7652 c_inhibit_evaluation_warnings
-= cond
.value
== truthvalue_true_node
;
7654 ret
.original_code
= ERROR_MARK
;
7655 ret
.original_type
= NULL
;
7659 location_t exp2_loc
= c_parser_peek_token (parser
)->location
;
7660 exp2
= c_parser_conditional_expression (parser
, NULL
, NULL_TREE
);
7661 exp2
= convert_lvalue_to_rvalue (exp2_loc
, exp2
, true, true);
7663 c_inhibit_evaluation_warnings
-= cond
.value
== truthvalue_true_node
;
7664 location_t loc1
= make_location (exp1
.get_start (), exp1
.src_range
);
7665 location_t loc2
= make_location (exp2
.get_start (), exp2
.src_range
);
7666 ret
.value
= build_conditional_expr (colon_loc
, cond
.value
,
7667 cond
.original_code
== C_MAYBE_CONST_EXPR
,
7668 exp1
.value
, exp1
.original_type
, loc1
,
7669 exp2
.value
, exp2
.original_type
, loc2
);
7670 ret
.original_code
= ERROR_MARK
;
7671 if (exp1
.value
== error_mark_node
|| exp2
.value
== error_mark_node
)
7672 ret
.original_type
= NULL
;
7677 /* If both sides are enum type, the default conversion will have
7678 made the type of the result be an integer type. We want to
7679 remember the enum types we started with. */
7680 t1
= exp1
.original_type
? exp1
.original_type
: TREE_TYPE (exp1
.value
);
7681 t2
= exp2
.original_type
? exp2
.original_type
: TREE_TYPE (exp2
.value
);
7682 ret
.original_type
= ((t1
!= error_mark_node
7683 && t2
!= error_mark_node
7684 && (TYPE_MAIN_VARIANT (t1
)
7685 == TYPE_MAIN_VARIANT (t2
)))
7689 set_c_expr_source_range (&ret
, start
, exp2
.get_finish ());
7693 /* Parse a binary expression; that is, a logical-OR-expression (C90
7694 6.3.5-6.3.14, C99 6.5.5-6.5.14, C11 6.5.5-6.5.14). If AFTER is not
7695 NULL then it is an Objective-C message expression which is the
7696 primary-expression starting the expression as an initializer.
7698 OMP_ATOMIC_LHS is NULL, unless parsing OpenMP #pragma omp atomic,
7699 when it should be the unfolded lhs. In a valid OpenMP source,
7700 one of the operands of the toplevel binary expression must be equal
7701 to it. In that case, just return a build2 created binary operation
7702 rather than result of parser_build_binary_op.
7704 multiplicative-expression:
7706 multiplicative-expression * cast-expression
7707 multiplicative-expression / cast-expression
7708 multiplicative-expression % cast-expression
7710 additive-expression:
7711 multiplicative-expression
7712 additive-expression + multiplicative-expression
7713 additive-expression - multiplicative-expression
7717 shift-expression << additive-expression
7718 shift-expression >> additive-expression
7720 relational-expression:
7722 relational-expression < shift-expression
7723 relational-expression > shift-expression
7724 relational-expression <= shift-expression
7725 relational-expression >= shift-expression
7727 equality-expression:
7728 relational-expression
7729 equality-expression == relational-expression
7730 equality-expression != relational-expression
7734 AND-expression & equality-expression
7736 exclusive-OR-expression:
7738 exclusive-OR-expression ^ AND-expression
7740 inclusive-OR-expression:
7741 exclusive-OR-expression
7742 inclusive-OR-expression | exclusive-OR-expression
7744 logical-AND-expression:
7745 inclusive-OR-expression
7746 logical-AND-expression && inclusive-OR-expression
7748 logical-OR-expression:
7749 logical-AND-expression
7750 logical-OR-expression || logical-AND-expression
7753 static struct c_expr
7754 c_parser_binary_expression (c_parser
*parser
, struct c_expr
*after
,
7755 tree omp_atomic_lhs
)
7757 /* A binary expression is parsed using operator-precedence parsing,
7758 with the operands being cast expressions. All the binary
7759 operators are left-associative. Thus a binary expression is of
7762 E0 op1 E1 op2 E2 ...
7764 which we represent on a stack. On the stack, the precedence
7765 levels are strictly increasing. When a new operator is
7766 encountered of higher precedence than that at the top of the
7767 stack, it is pushed; its LHS is the top expression, and its RHS
7768 is everything parsed until it is popped. When a new operator is
7769 encountered with precedence less than or equal to that at the top
7770 of the stack, triples E[i-1] op[i] E[i] are popped and replaced
7771 by the result of the operation until the operator at the top of
7772 the stack has lower precedence than the new operator or there is
7773 only one element on the stack; then the top expression is the LHS
7774 of the new operator. In the case of logical AND and OR
7775 expressions, we also need to adjust c_inhibit_evaluation_warnings
7776 as appropriate when the operators are pushed and popped. */
7779 /* The expression at this stack level. */
7781 /* The precedence of the operator on its left, PREC_NONE at the
7782 bottom of the stack. */
7783 enum c_parser_prec prec
;
7784 /* The operation on its left. */
7786 /* The source location of this operation. */
7788 /* The sizeof argument if expr.original_code == {PAREN_,}SIZEOF_EXPR. */
7792 /* Location of the binary operator. */
7793 location_t binary_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
7796 switch (stack[sp].op) \
7798 case TRUTH_ANDIF_EXPR: \
7799 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
7800 == truthvalue_false_node); \
7802 case TRUTH_ORIF_EXPR: \
7803 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
7804 == truthvalue_true_node); \
7806 case TRUNC_DIV_EXPR: \
7807 if ((stack[sp - 1].expr.original_code == SIZEOF_EXPR \
7808 || stack[sp - 1].expr.original_code == PAREN_SIZEOF_EXPR) \
7809 && (stack[sp].expr.original_code == SIZEOF_EXPR \
7810 || stack[sp].expr.original_code == PAREN_SIZEOF_EXPR)) \
7812 tree type0 = stack[sp - 1].sizeof_arg; \
7813 tree type1 = stack[sp].sizeof_arg; \
7814 tree first_arg = type0; \
7815 if (!TYPE_P (type0)) \
7816 type0 = TREE_TYPE (type0); \
7817 if (!TYPE_P (type1)) \
7818 type1 = TREE_TYPE (type1); \
7819 if (POINTER_TYPE_P (type0) \
7820 && comptypes (TREE_TYPE (type0), type1) \
7821 && !(TREE_CODE (first_arg) == PARM_DECL \
7822 && C_ARRAY_PARAMETER (first_arg) \
7823 && warn_sizeof_array_argument)) \
7825 auto_diagnostic_group d; \
7826 if (warning_at (stack[sp].loc, OPT_Wsizeof_pointer_div, \
7827 "division %<sizeof (%T) / sizeof (%T)%> " \
7828 "does not compute the number of array " \
7831 if (DECL_P (first_arg)) \
7832 inform (DECL_SOURCE_LOCATION (first_arg), \
7833 "first %<sizeof%> operand was declared here"); \
7835 else if (TREE_CODE (type0) == ARRAY_TYPE \
7836 && !char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type0))) \
7837 && stack[sp].expr.original_code != PAREN_SIZEOF_EXPR) \
7838 maybe_warn_sizeof_array_div (stack[sp].loc, first_arg, type0, \
7839 stack[sp].sizeof_arg, type1); \
7845 stack[sp - 1].expr \
7846 = convert_lvalue_to_rvalue (stack[sp - 1].loc, \
7847 stack[sp - 1].expr, true, true); \
7849 = convert_lvalue_to_rvalue (stack[sp].loc, \
7850 stack[sp].expr, true, true); \
7851 if (__builtin_expect (omp_atomic_lhs != NULL_TREE, 0) && sp == 1 \
7852 && c_parser_peek_token (parser)->type == CPP_SEMICOLON \
7853 && ((1 << stack[sp].prec) \
7854 & ((1 << PREC_BITOR) | (1 << PREC_BITXOR) | (1 << PREC_BITAND) \
7855 | (1 << PREC_SHIFT) | (1 << PREC_ADD) | (1 << PREC_MULT))) \
7856 && stack[sp].op != TRUNC_MOD_EXPR \
7857 && stack[0].expr.value != error_mark_node \
7858 && stack[1].expr.value != error_mark_node \
7859 && (c_tree_equal (stack[0].expr.value, omp_atomic_lhs) \
7860 || c_tree_equal (stack[1].expr.value, omp_atomic_lhs))) \
7862 tree t = make_node (stack[1].op); \
7863 TREE_TYPE (t) = TREE_TYPE (stack[0].expr.value); \
7864 TREE_OPERAND (t, 0) = stack[0].expr.value; \
7865 TREE_OPERAND (t, 1) = stack[1].expr.value; \
7866 stack[0].expr.value = t; \
7869 stack[sp - 1].expr = parser_build_binary_op (stack[sp].loc, \
7871 stack[sp - 1].expr, \
7875 gcc_assert (!after
|| c_dialect_objc ());
7876 stack
[0].loc
= c_parser_peek_token (parser
)->location
;
7877 stack
[0].expr
= c_parser_cast_expression (parser
, after
);
7878 stack
[0].prec
= PREC_NONE
;
7879 stack
[0].sizeof_arg
= c_last_sizeof_arg
;
7883 enum c_parser_prec oprec
;
7884 enum tree_code ocode
;
7885 source_range src_range
;
7888 switch (c_parser_peek_token (parser
)->type
)
7896 ocode
= TRUNC_DIV_EXPR
;
7900 ocode
= TRUNC_MOD_EXPR
;
7912 ocode
= LSHIFT_EXPR
;
7916 ocode
= RSHIFT_EXPR
;
7930 case CPP_GREATER_EQ
:
7943 oprec
= PREC_BITAND
;
7944 ocode
= BIT_AND_EXPR
;
7947 oprec
= PREC_BITXOR
;
7948 ocode
= BIT_XOR_EXPR
;
7952 ocode
= BIT_IOR_EXPR
;
7955 oprec
= PREC_LOGAND
;
7956 ocode
= TRUTH_ANDIF_EXPR
;
7960 ocode
= TRUTH_ORIF_EXPR
;
7963 /* Not a binary operator, so end of the binary
7967 binary_loc
= c_parser_peek_token (parser
)->location
;
7968 while (oprec
<= stack
[sp
].prec
)
7970 c_parser_consume_token (parser
);
7973 case TRUTH_ANDIF_EXPR
:
7974 src_range
= stack
[sp
].expr
.src_range
;
7976 = convert_lvalue_to_rvalue (stack
[sp
].loc
,
7977 stack
[sp
].expr
, true, true);
7978 stack
[sp
].expr
.value
= c_objc_common_truthvalue_conversion
7979 (stack
[sp
].loc
, default_conversion (stack
[sp
].expr
.value
));
7980 c_inhibit_evaluation_warnings
+= (stack
[sp
].expr
.value
7981 == truthvalue_false_node
);
7982 set_c_expr_source_range (&stack
[sp
].expr
, src_range
);
7984 case TRUTH_ORIF_EXPR
:
7985 src_range
= stack
[sp
].expr
.src_range
;
7987 = convert_lvalue_to_rvalue (stack
[sp
].loc
,
7988 stack
[sp
].expr
, true, true);
7989 stack
[sp
].expr
.value
= c_objc_common_truthvalue_conversion
7990 (stack
[sp
].loc
, default_conversion (stack
[sp
].expr
.value
));
7991 c_inhibit_evaluation_warnings
+= (stack
[sp
].expr
.value
7992 == truthvalue_true_node
);
7993 set_c_expr_source_range (&stack
[sp
].expr
, src_range
);
7999 stack
[sp
].loc
= binary_loc
;
8000 stack
[sp
].expr
= c_parser_cast_expression (parser
, NULL
);
8001 stack
[sp
].prec
= oprec
;
8002 stack
[sp
].op
= ocode
;
8003 stack
[sp
].sizeof_arg
= c_last_sizeof_arg
;
8008 return stack
[0].expr
;
8012 /* Parse a cast expression (C90 6.3.4, C99 6.5.4, C11 6.5.4). If AFTER
8013 is not NULL then it is an Objective-C message expression which is the
8014 primary-expression starting the expression as an initializer.
8018 ( type-name ) unary-expression
8021 static struct c_expr
8022 c_parser_cast_expression (c_parser
*parser
, struct c_expr
*after
)
8024 location_t cast_loc
= c_parser_peek_token (parser
)->location
;
8025 gcc_assert (!after
|| c_dialect_objc ());
8027 return c_parser_postfix_expression_after_primary (parser
,
8029 /* If the expression begins with a parenthesized type name, it may
8030 be either a cast or a compound literal; we need to see whether
8031 the next character is '{' to tell the difference. If not, it is
8032 an unary expression. Full detection of unknown typenames here
8033 would require a 3-token lookahead. */
8034 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
)
8035 && c_token_starts_typename (c_parser_peek_2nd_token (parser
)))
8037 struct c_type_name
*type_name
;
8040 matching_parens parens
;
8041 parens
.consume_open (parser
);
8042 type_name
= c_parser_type_name (parser
, true);
8043 parens
.skip_until_found_close (parser
);
8044 if (type_name
== NULL
)
8047 ret
.original_code
= ERROR_MARK
;
8048 ret
.original_type
= NULL
;
8052 /* Save casted types in the function's used types hash table. */
8053 used_types_insert (type_name
->specs
->type
);
8055 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
8056 return c_parser_postfix_expression_after_paren_type (parser
, type_name
,
8058 if (type_name
->specs
->alignas_p
)
8059 error_at (type_name
->specs
->locations
[cdw_alignas
],
8060 "alignment specified for type name in cast");
8062 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
8063 expr
= c_parser_cast_expression (parser
, NULL
);
8064 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, true, true);
8066 ret
.value
= c_cast_expr (cast_loc
, type_name
, expr
.value
);
8067 if (ret
.value
&& expr
.value
)
8068 set_c_expr_source_range (&ret
, cast_loc
, expr
.get_finish ());
8069 ret
.original_code
= ERROR_MARK
;
8070 ret
.original_type
= NULL
;
8074 return c_parser_unary_expression (parser
);
8077 /* Parse an unary expression (C90 6.3.3, C99 6.5.3, C11 6.5.3).
8083 unary-operator cast-expression
8084 sizeof unary-expression
8085 sizeof ( type-name )
8087 unary-operator: one of
8093 __alignof__ unary-expression
8094 __alignof__ ( type-name )
8097 (C11 permits _Alignof with type names only.)
8099 unary-operator: one of
8100 __extension__ __real__ __imag__
8102 Transactional Memory:
8105 transaction-expression
8107 In addition, the GNU syntax treats ++ and -- as unary operators, so
8108 they may be applied to cast expressions with errors for non-lvalues
8111 static struct c_expr
8112 c_parser_unary_expression (c_parser
*parser
)
8115 struct c_expr ret
, op
;
8116 location_t op_loc
= c_parser_peek_token (parser
)->location
;
8119 ret
.original_code
= ERROR_MARK
;
8120 ret
.original_type
= NULL
;
8121 switch (c_parser_peek_token (parser
)->type
)
8124 c_parser_consume_token (parser
);
8125 exp_loc
= c_parser_peek_token (parser
)->location
;
8126 op
= c_parser_cast_expression (parser
, NULL
);
8128 op
= default_function_array_read_conversion (exp_loc
, op
);
8129 return parser_build_unary_op (op_loc
, PREINCREMENT_EXPR
, op
);
8130 case CPP_MINUS_MINUS
:
8131 c_parser_consume_token (parser
);
8132 exp_loc
= c_parser_peek_token (parser
)->location
;
8133 op
= c_parser_cast_expression (parser
, NULL
);
8135 op
= default_function_array_read_conversion (exp_loc
, op
);
8136 return parser_build_unary_op (op_loc
, PREDECREMENT_EXPR
, op
);
8138 c_parser_consume_token (parser
);
8139 op
= c_parser_cast_expression (parser
, NULL
);
8140 mark_exp_read (op
.value
);
8141 return parser_build_unary_op (op_loc
, ADDR_EXPR
, op
);
8144 c_parser_consume_token (parser
);
8145 exp_loc
= c_parser_peek_token (parser
)->location
;
8146 op
= c_parser_cast_expression (parser
, NULL
);
8147 finish
= op
.get_finish ();
8148 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
8149 location_t combined_loc
= make_location (op_loc
, op_loc
, finish
);
8150 ret
.value
= build_indirect_ref (combined_loc
, op
.value
, RO_UNARY_STAR
);
8151 ret
.src_range
.m_start
= op_loc
;
8152 ret
.src_range
.m_finish
= finish
;
8156 if (!c_dialect_objc () && !in_system_header_at (input_location
))
8159 "traditional C rejects the unary plus operator");
8160 c_parser_consume_token (parser
);
8161 exp_loc
= c_parser_peek_token (parser
)->location
;
8162 op
= c_parser_cast_expression (parser
, NULL
);
8163 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
8164 return parser_build_unary_op (op_loc
, CONVERT_EXPR
, op
);
8166 c_parser_consume_token (parser
);
8167 exp_loc
= c_parser_peek_token (parser
)->location
;
8168 op
= c_parser_cast_expression (parser
, NULL
);
8169 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
8170 return parser_build_unary_op (op_loc
, NEGATE_EXPR
, op
);
8172 c_parser_consume_token (parser
);
8173 exp_loc
= c_parser_peek_token (parser
)->location
;
8174 op
= c_parser_cast_expression (parser
, NULL
);
8175 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
8176 return parser_build_unary_op (op_loc
, BIT_NOT_EXPR
, op
);
8178 c_parser_consume_token (parser
);
8179 exp_loc
= c_parser_peek_token (parser
)->location
;
8180 op
= c_parser_cast_expression (parser
, NULL
);
8181 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
8182 return parser_build_unary_op (op_loc
, TRUTH_NOT_EXPR
, op
);
8184 /* Refer to the address of a label as a pointer. */
8185 c_parser_consume_token (parser
);
8186 if (c_parser_next_token_is (parser
, CPP_NAME
))
8188 ret
.value
= finish_label_address_expr
8189 (c_parser_peek_token (parser
)->value
, op_loc
);
8190 set_c_expr_source_range (&ret
, op_loc
,
8191 c_parser_peek_token (parser
)->get_finish ());
8192 c_parser_consume_token (parser
);
8196 c_parser_error (parser
, "expected identifier");
8201 switch (c_parser_peek_token (parser
)->keyword
)
8204 return c_parser_sizeof_expression (parser
);
8206 return c_parser_alignof_expression (parser
);
8207 case RID_BUILTIN_HAS_ATTRIBUTE
:
8208 return c_parser_has_attribute_expression (parser
);
8210 c_parser_consume_token (parser
);
8211 ext
= disable_extension_diagnostics ();
8212 ret
= c_parser_cast_expression (parser
, NULL
);
8213 restore_extension_diagnostics (ext
);
8216 c_parser_consume_token (parser
);
8217 exp_loc
= c_parser_peek_token (parser
)->location
;
8218 op
= c_parser_cast_expression (parser
, NULL
);
8219 op
= default_function_array_conversion (exp_loc
, op
);
8220 return parser_build_unary_op (op_loc
, REALPART_EXPR
, op
);
8222 c_parser_consume_token (parser
);
8223 exp_loc
= c_parser_peek_token (parser
)->location
;
8224 op
= c_parser_cast_expression (parser
, NULL
);
8225 op
= default_function_array_conversion (exp_loc
, op
);
8226 return parser_build_unary_op (op_loc
, IMAGPART_EXPR
, op
);
8227 case RID_TRANSACTION_ATOMIC
:
8228 case RID_TRANSACTION_RELAXED
:
8229 return c_parser_transaction_expression (parser
,
8230 c_parser_peek_token (parser
)->keyword
);
8232 return c_parser_postfix_expression (parser
);
8235 return c_parser_postfix_expression (parser
);
8239 /* Parse a sizeof expression. */
8241 static struct c_expr
8242 c_parser_sizeof_expression (c_parser
*parser
)
8245 struct c_expr result
;
8246 location_t expr_loc
;
8247 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_SIZEOF
));
8250 location_t finish
= UNKNOWN_LOCATION
;
8252 start
= c_parser_peek_token (parser
)->location
;
8254 c_parser_consume_token (parser
);
8255 c_inhibit_evaluation_warnings
++;
8257 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
)
8258 && c_token_starts_typename (c_parser_peek_2nd_token (parser
)))
8260 /* Either sizeof ( type-name ) or sizeof unary-expression
8261 starting with a compound literal. */
8262 struct c_type_name
*type_name
;
8263 matching_parens parens
;
8264 parens
.consume_open (parser
);
8265 expr_loc
= c_parser_peek_token (parser
)->location
;
8266 type_name
= c_parser_type_name (parser
, true);
8267 parens
.skip_until_found_close (parser
);
8268 finish
= parser
->tokens_buf
[0].location
;
8269 if (type_name
== NULL
)
8272 c_inhibit_evaluation_warnings
--;
8275 ret
.original_code
= ERROR_MARK
;
8276 ret
.original_type
= NULL
;
8279 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
8281 expr
= c_parser_postfix_expression_after_paren_type (parser
,
8284 finish
= expr
.get_finish ();
8287 /* sizeof ( type-name ). */
8288 if (type_name
->specs
->alignas_p
)
8289 error_at (type_name
->specs
->locations
[cdw_alignas
],
8290 "alignment specified for type name in %<sizeof%>");
8291 c_inhibit_evaluation_warnings
--;
8293 result
= c_expr_sizeof_type (expr_loc
, type_name
);
8297 expr_loc
= c_parser_peek_token (parser
)->location
;
8298 expr
= c_parser_unary_expression (parser
);
8299 finish
= expr
.get_finish ();
8301 c_inhibit_evaluation_warnings
--;
8303 mark_exp_read (expr
.value
);
8304 if (TREE_CODE (expr
.value
) == COMPONENT_REF
8305 && DECL_C_BIT_FIELD (TREE_OPERAND (expr
.value
, 1)))
8306 error_at (expr_loc
, "%<sizeof%> applied to a bit-field");
8307 result
= c_expr_sizeof_expr (expr_loc
, expr
);
8309 if (finish
== UNKNOWN_LOCATION
)
8311 set_c_expr_source_range (&result
, start
, finish
);
8315 /* Parse an alignof expression. */
8317 static struct c_expr
8318 c_parser_alignof_expression (c_parser
*parser
)
8321 location_t start_loc
= c_parser_peek_token (parser
)->location
;
8323 tree alignof_spelling
= c_parser_peek_token (parser
)->value
;
8324 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ALIGNOF
));
8325 bool is_c11_alignof
= strcmp (IDENTIFIER_POINTER (alignof_spelling
),
8327 /* A diagnostic is not required for the use of this identifier in
8328 the implementation namespace; only diagnose it for the C11
8329 spelling because of existing code using the other spellings. */
8333 pedwarn_c99 (start_loc
, OPT_Wpedantic
, "ISO C99 does not support %qE",
8336 pedwarn_c99 (start_loc
, OPT_Wpedantic
, "ISO C90 does not support %qE",
8339 c_parser_consume_token (parser
);
8340 c_inhibit_evaluation_warnings
++;
8342 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
)
8343 && c_token_starts_typename (c_parser_peek_2nd_token (parser
)))
8345 /* Either __alignof__ ( type-name ) or __alignof__
8346 unary-expression starting with a compound literal. */
8348 struct c_type_name
*type_name
;
8350 matching_parens parens
;
8351 parens
.consume_open (parser
);
8352 loc
= c_parser_peek_token (parser
)->location
;
8353 type_name
= c_parser_type_name (parser
, true);
8354 end_loc
= c_parser_peek_token (parser
)->location
;
8355 parens
.skip_until_found_close (parser
);
8356 if (type_name
== NULL
)
8359 c_inhibit_evaluation_warnings
--;
8362 ret
.original_code
= ERROR_MARK
;
8363 ret
.original_type
= NULL
;
8366 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
8368 expr
= c_parser_postfix_expression_after_paren_type (parser
,
8373 /* alignof ( type-name ). */
8374 if (type_name
->specs
->alignas_p
)
8375 error_at (type_name
->specs
->locations
[cdw_alignas
],
8376 "alignment specified for type name in %qE",
8378 c_inhibit_evaluation_warnings
--;
8380 ret
.value
= c_sizeof_or_alignof_type (loc
, groktypename (type_name
,
8382 false, is_c11_alignof
, 1);
8383 ret
.original_code
= ERROR_MARK
;
8384 ret
.original_type
= NULL
;
8385 set_c_expr_source_range (&ret
, start_loc
, end_loc
);
8391 expr
= c_parser_unary_expression (parser
);
8392 end_loc
= expr
.src_range
.m_finish
;
8394 mark_exp_read (expr
.value
);
8395 c_inhibit_evaluation_warnings
--;
8399 OPT_Wpedantic
, "ISO C does not allow %<%E (expression)%>",
8401 ret
.value
= c_alignof_expr (start_loc
, expr
.value
);
8402 ret
.original_code
= ERROR_MARK
;
8403 ret
.original_type
= NULL
;
8404 set_c_expr_source_range (&ret
, start_loc
, end_loc
);
8409 /* Parse the __builtin_has_attribute ([expr|type], attribute-spec)
8412 static struct c_expr
8413 c_parser_has_attribute_expression (c_parser
*parser
)
8415 gcc_assert (c_parser_next_token_is_keyword (parser
,
8416 RID_BUILTIN_HAS_ATTRIBUTE
));
8417 location_t start
= c_parser_peek_token (parser
)->location
;
8418 c_parser_consume_token (parser
);
8420 c_inhibit_evaluation_warnings
++;
8422 matching_parens parens
;
8423 if (!parens
.require_open (parser
))
8425 c_inhibit_evaluation_warnings
--;
8428 struct c_expr result
;
8429 result
.set_error ();
8430 result
.original_code
= ERROR_MARK
;
8431 result
.original_type
= NULL
;
8435 /* Treat the type argument the same way as in typeof for the purposes
8436 of warnings. FIXME: Generalize this so the warning refers to
8437 __builtin_has_attribute rather than typeof. */
8440 /* The first operand: one of DECL, EXPR, or TYPE. */
8441 tree oper
= NULL_TREE
;
8442 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_id
))
8444 struct c_type_name
*tname
= c_parser_type_name (parser
);
8448 oper
= groktypename (tname
, NULL
, NULL
);
8449 pop_maybe_used (variably_modified_type_p (oper
, NULL_TREE
));
8454 struct c_expr cexpr
= c_parser_expr_no_commas (parser
, NULL
);
8455 c_inhibit_evaluation_warnings
--;
8457 if (cexpr
.value
!= error_mark_node
)
8459 mark_exp_read (cexpr
.value
);
8461 tree etype
= TREE_TYPE (oper
);
8462 bool was_vm
= variably_modified_type_p (etype
, NULL_TREE
);
8463 /* This is returned with the type so that when the type is
8464 evaluated, this can be evaluated. */
8466 oper
= c_fully_fold (oper
, false, NULL
);
8467 pop_maybe_used (was_vm
);
8471 struct c_expr result
;
8472 result
.original_code
= ERROR_MARK
;
8473 result
.original_type
= NULL
;
8475 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
8477 /* Consume the closing parenthesis if that's the next token
8478 in the likely case the built-in was invoked with fewer
8479 than two arguments. */
8480 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
8481 c_parser_consume_token (parser
);
8482 c_inhibit_evaluation_warnings
--;
8483 result
.set_error ();
8487 bool save_translate_strings_p
= parser
->translate_strings_p
;
8489 location_t atloc
= c_parser_peek_token (parser
)->location
;
8490 /* Parse a single attribute. Require no leading comma and do not
8491 allow empty attributes. */
8492 tree attr
= c_parser_gnu_attribute (parser
, NULL_TREE
, false, false);
8494 parser
->translate_strings_p
= save_translate_strings_p
;
8496 location_t finish
= c_parser_peek_token (parser
)->location
;
8497 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
8498 c_parser_consume_token (parser
);
8501 c_parser_error (parser
, "expected identifier");
8502 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8504 result
.set_error ();
8510 error_at (atloc
, "expected identifier");
8511 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
8513 result
.set_error ();
8517 result
.original_code
= INTEGER_CST
;
8518 result
.original_type
= boolean_type_node
;
8520 if (has_attribute (atloc
, oper
, attr
, default_conversion
))
8521 result
.value
= boolean_true_node
;
8523 result
.value
= boolean_false_node
;
8525 set_c_expr_source_range (&result
, start
, finish
);
8529 /* Helper function to read arguments of builtins which are interfaces
8530 for the middle-end nodes like COMPLEX_EXPR, VEC_PERM_EXPR and
8531 others. The name of the builtin is passed using BNAME parameter.
8532 Function returns true if there were no errors while parsing and
8533 stores the arguments in CEXPR_LIST. If it returns true,
8534 *OUT_CLOSE_PAREN_LOC is written to with the location of the closing
8537 c_parser_get_builtin_args (c_parser
*parser
, const char *bname
,
8538 vec
<c_expr_t
, va_gc
> **ret_cexpr_list
,
8540 location_t
*out_close_paren_loc
)
8542 location_t loc
= c_parser_peek_token (parser
)->location
;
8543 vec
<c_expr_t
, va_gc
> *cexpr_list
;
8545 bool saved_force_folding_builtin_constant_p
;
8547 *ret_cexpr_list
= NULL
;
8548 if (c_parser_next_token_is_not (parser
, CPP_OPEN_PAREN
))
8550 error_at (loc
, "cannot take address of %qs", bname
);
8554 c_parser_consume_token (parser
);
8556 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
8558 *out_close_paren_loc
= c_parser_peek_token (parser
)->location
;
8559 c_parser_consume_token (parser
);
8563 saved_force_folding_builtin_constant_p
8564 = force_folding_builtin_constant_p
;
8565 force_folding_builtin_constant_p
|= choose_expr_p
;
8566 expr
= c_parser_expr_no_commas (parser
, NULL
);
8567 force_folding_builtin_constant_p
8568 = saved_force_folding_builtin_constant_p
;
8569 vec_alloc (cexpr_list
, 1);
8570 vec_safe_push (cexpr_list
, expr
);
8571 while (c_parser_next_token_is (parser
, CPP_COMMA
))
8573 c_parser_consume_token (parser
);
8574 expr
= c_parser_expr_no_commas (parser
, NULL
);
8575 vec_safe_push (cexpr_list
, expr
);
8578 *out_close_paren_loc
= c_parser_peek_token (parser
)->location
;
8579 if (!c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
8582 *ret_cexpr_list
= cexpr_list
;
8586 /* This represents a single generic-association. */
8588 struct c_generic_association
8590 /* The location of the starting token of the type. */
8591 location_t type_location
;
8592 /* The association's type, or NULL_TREE for 'default'. */
8594 /* The association's expression. */
8595 struct c_expr expression
;
8598 /* Parse a generic-selection. (C11 6.5.1.1).
8601 _Generic ( assignment-expression , generic-assoc-list )
8605 generic-assoc-list , generic-association
8607 generic-association:
8608 type-name : assignment-expression
8609 default : assignment-expression
8612 static struct c_expr
8613 c_parser_generic_selection (c_parser
*parser
)
8615 struct c_expr selector
, error_expr
;
8617 struct c_generic_association matched_assoc
;
8618 int match_found
= -1;
8619 location_t generic_loc
, selector_loc
;
8621 error_expr
.original_code
= ERROR_MARK
;
8622 error_expr
.original_type
= NULL
;
8623 error_expr
.set_error ();
8624 matched_assoc
.type_location
= UNKNOWN_LOCATION
;
8625 matched_assoc
.type
= NULL_TREE
;
8626 matched_assoc
.expression
= error_expr
;
8628 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_GENERIC
));
8629 generic_loc
= c_parser_peek_token (parser
)->location
;
8630 c_parser_consume_token (parser
);
8632 pedwarn_c99 (generic_loc
, OPT_Wpedantic
,
8633 "ISO C99 does not support %<_Generic%>");
8635 pedwarn_c99 (generic_loc
, OPT_Wpedantic
,
8636 "ISO C90 does not support %<_Generic%>");
8638 matching_parens parens
;
8639 if (!parens
.require_open (parser
))
8642 c_inhibit_evaluation_warnings
++;
8643 selector_loc
= c_parser_peek_token (parser
)->location
;
8644 selector
= c_parser_expr_no_commas (parser
, NULL
);
8645 selector
= default_function_array_conversion (selector_loc
, selector
);
8646 c_inhibit_evaluation_warnings
--;
8648 if (selector
.value
== error_mark_node
)
8650 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8653 mark_exp_read (selector
.value
);
8654 selector_type
= TREE_TYPE (selector
.value
);
8655 /* In ISO C terms, rvalues (including the controlling expression of
8656 _Generic) do not have qualified types. */
8657 if (TREE_CODE (selector_type
) != ARRAY_TYPE
)
8658 selector_type
= TYPE_MAIN_VARIANT (selector_type
);
8659 /* In ISO C terms, _Noreturn is not part of the type of expressions
8660 such as &abort, but in GCC it is represented internally as a type
8662 if (FUNCTION_POINTER_TYPE_P (selector_type
)
8663 && TYPE_QUALS (TREE_TYPE (selector_type
)) != TYPE_UNQUALIFIED
)
8665 = build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (selector_type
)));
8667 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
8669 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8673 auto_vec
<c_generic_association
> associations
;
8676 struct c_generic_association assoc
, *iter
;
8678 c_token
*token
= c_parser_peek_token (parser
);
8680 assoc
.type_location
= token
->location
;
8681 if (token
->type
== CPP_KEYWORD
&& token
->keyword
== RID_DEFAULT
)
8683 c_parser_consume_token (parser
);
8684 assoc
.type
= NULL_TREE
;
8688 struct c_type_name
*type_name
;
8690 type_name
= c_parser_type_name (parser
);
8691 if (type_name
== NULL
)
8693 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8696 assoc
.type
= groktypename (type_name
, NULL
, NULL
);
8697 if (assoc
.type
== error_mark_node
)
8699 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8703 if (TREE_CODE (assoc
.type
) == FUNCTION_TYPE
)
8704 error_at (assoc
.type_location
,
8705 "%<_Generic%> association has function type");
8706 else if (!COMPLETE_TYPE_P (assoc
.type
))
8707 error_at (assoc
.type_location
,
8708 "%<_Generic%> association has incomplete type");
8710 if (variably_modified_type_p (assoc
.type
, NULL_TREE
))
8711 error_at (assoc
.type_location
,
8712 "%<_Generic%> association has "
8713 "variable length type");
8716 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
8718 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8722 assoc
.expression
= c_parser_expr_no_commas (parser
, NULL
);
8723 if (assoc
.expression
.value
== error_mark_node
)
8725 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8729 for (ix
= 0; associations
.iterate (ix
, &iter
); ++ix
)
8731 if (assoc
.type
== NULL_TREE
)
8733 if (iter
->type
== NULL_TREE
)
8735 error_at (assoc
.type_location
,
8736 "duplicate %<default%> case in %<_Generic%>");
8737 inform (iter
->type_location
, "original %<default%> is here");
8740 else if (iter
->type
!= NULL_TREE
)
8742 if (comptypes (assoc
.type
, iter
->type
))
8744 error_at (assoc
.type_location
,
8745 "%<_Generic%> specifies two compatible types");
8746 inform (iter
->type_location
, "compatible type is here");
8751 if (assoc
.type
== NULL_TREE
)
8753 if (match_found
< 0)
8755 matched_assoc
= assoc
;
8756 match_found
= associations
.length ();
8759 else if (comptypes (assoc
.type
, selector_type
))
8761 if (match_found
< 0 || matched_assoc
.type
== NULL_TREE
)
8763 matched_assoc
= assoc
;
8764 match_found
= associations
.length ();
8768 error_at (assoc
.type_location
,
8769 "%<_Generic%> selector matches multiple associations");
8770 inform (matched_assoc
.type_location
,
8771 "other match is here");
8775 associations
.safe_push (assoc
);
8777 if (c_parser_peek_token (parser
)->type
!= CPP_COMMA
)
8779 c_parser_consume_token (parser
);
8783 struct c_generic_association
*iter
;
8784 FOR_EACH_VEC_ELT (associations
, ix
, iter
)
8785 if (ix
!= (unsigned) match_found
)
8786 mark_exp_read (iter
->expression
.value
);
8788 if (!parens
.require_close (parser
))
8790 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8794 if (match_found
< 0)
8796 error_at (selector_loc
, "%<_Generic%> selector of type %qT is not "
8797 "compatible with any association",
8802 return matched_assoc
.expression
;
8805 /* Check the validity of a function pointer argument *EXPR (argument
8806 position POS) to __builtin_tgmath. Return the number of function
8807 arguments if possibly valid; return 0 having reported an error if
8811 check_tgmath_function (c_expr
*expr
, unsigned int pos
)
8813 tree type
= TREE_TYPE (expr
->value
);
8814 if (!FUNCTION_POINTER_TYPE_P (type
))
8816 error_at (expr
->get_location (),
8817 "argument %u of %<__builtin_tgmath%> is not a function pointer",
8821 type
= TREE_TYPE (type
);
8822 if (!prototype_p (type
))
8824 error_at (expr
->get_location (),
8825 "argument %u of %<__builtin_tgmath%> is unprototyped", pos
);
8828 if (stdarg_p (type
))
8830 error_at (expr
->get_location (),
8831 "argument %u of %<__builtin_tgmath%> has variable arguments",
8835 unsigned int nargs
= 0;
8836 function_args_iterator iter
;
8838 FOREACH_FUNCTION_ARGS (type
, t
, iter
)
8840 if (t
== void_type_node
)
8846 error_at (expr
->get_location (),
8847 "argument %u of %<__builtin_tgmath%> has no arguments", pos
);
8853 /* Ways in which a parameter or return value of a type-generic macro
8854 may vary between the different functions the macro may call. */
8855 enum tgmath_parm_kind
8857 tgmath_fixed
, tgmath_real
, tgmath_complex
8860 /* Helper function for c_parser_postfix_expression. Parse predefined
8863 static struct c_expr
8864 c_parser_predefined_identifier (c_parser
*parser
)
8866 location_t loc
= c_parser_peek_token (parser
)->location
;
8867 switch (c_parser_peek_token (parser
)->keyword
)
8869 case RID_FUNCTION_NAME
:
8870 pedwarn (loc
, OPT_Wpedantic
, "ISO C does not support %qs predefined "
8871 "identifier", "__FUNCTION__");
8873 case RID_PRETTY_FUNCTION_NAME
:
8874 pedwarn (loc
, OPT_Wpedantic
, "ISO C does not support %qs predefined "
8875 "identifier", "__PRETTY_FUNCTION__");
8877 case RID_C99_FUNCTION_NAME
:
8878 pedwarn_c90 (loc
, OPT_Wpedantic
, "ISO C90 does not support "
8879 "%<__func__%> predefined identifier");
8886 expr
.original_code
= ERROR_MARK
;
8887 expr
.original_type
= NULL
;
8888 expr
.value
= fname_decl (loc
, c_parser_peek_token (parser
)->keyword
,
8889 c_parser_peek_token (parser
)->value
);
8890 set_c_expr_source_range (&expr
, loc
, loc
);
8891 c_parser_consume_token (parser
);
8895 /* Parse a postfix expression (C90 6.3.1-6.3.2, C99 6.5.1-6.5.2,
8896 C11 6.5.1-6.5.2). Compound literals aren't handled here; callers have to
8897 call c_parser_postfix_expression_after_paren_type on encountering them.
8901 postfix-expression [ expression ]
8902 postfix-expression ( argument-expression-list[opt] )
8903 postfix-expression . identifier
8904 postfix-expression -> identifier
8905 postfix-expression ++
8906 postfix-expression --
8907 ( type-name ) { initializer-list }
8908 ( type-name ) { initializer-list , }
8910 argument-expression-list:
8912 argument-expression-list , argument-expression
8925 (treated as a keyword in GNU C)
8928 ( compound-statement )
8929 __builtin_va_arg ( assignment-expression , type-name )
8930 __builtin_offsetof ( type-name , offsetof-member-designator )
8931 __builtin_choose_expr ( assignment-expression ,
8932 assignment-expression ,
8933 assignment-expression )
8934 __builtin_types_compatible_p ( type-name , type-name )
8935 __builtin_tgmath ( expr-list )
8936 __builtin_complex ( assignment-expression , assignment-expression )
8937 __builtin_shuffle ( assignment-expression , assignment-expression )
8938 __builtin_shuffle ( assignment-expression ,
8939 assignment-expression ,
8940 assignment-expression, )
8941 __builtin_convertvector ( assignment-expression , type-name )
8943 offsetof-member-designator:
8945 offsetof-member-designator . identifier
8946 offsetof-member-designator [ expression ]
8951 [ objc-receiver objc-message-args ]
8952 @selector ( objc-selector-arg )
8953 @protocol ( identifier )
8954 @encode ( type-name )
8956 Classname . identifier
8959 static struct c_expr
8960 c_parser_postfix_expression (c_parser
*parser
)
8962 struct c_expr expr
, e1
;
8963 struct c_type_name
*t1
, *t2
;
8964 location_t loc
= c_parser_peek_token (parser
)->location
;
8965 source_range tok_range
= c_parser_peek_token (parser
)->get_range ();
8966 expr
.original_code
= ERROR_MARK
;
8967 expr
.original_type
= NULL
;
8968 switch (c_parser_peek_token (parser
)->type
)
8971 expr
.value
= c_parser_peek_token (parser
)->value
;
8972 set_c_expr_source_range (&expr
, tok_range
);
8973 loc
= c_parser_peek_token (parser
)->location
;
8974 c_parser_consume_token (parser
);
8975 if (TREE_CODE (expr
.value
) == FIXED_CST
8976 && !targetm
.fixed_point_supported_p ())
8978 error_at (loc
, "fixed-point types not supported for this target");
8987 expr
.value
= c_parser_peek_token (parser
)->value
;
8988 /* For the purpose of warning when a pointer is compared with
8989 a zero character constant. */
8990 expr
.original_type
= char_type_node
;
8991 set_c_expr_source_range (&expr
, tok_range
);
8992 c_parser_consume_token (parser
);
8998 case CPP_UTF8STRING
:
8999 expr
= c_parser_string_literal (parser
, parser
->translate_strings_p
,
9002 case CPP_OBJC_STRING
:
9003 gcc_assert (c_dialect_objc ());
9005 = objc_build_string_object (c_parser_peek_token (parser
)->value
);
9006 set_c_expr_source_range (&expr
, tok_range
);
9007 c_parser_consume_token (parser
);
9010 switch (c_parser_peek_token (parser
)->id_kind
)
9014 tree id
= c_parser_peek_token (parser
)->value
;
9015 c_parser_consume_token (parser
);
9016 expr
.value
= build_external_ref (loc
, id
,
9017 (c_parser_peek_token (parser
)->type
9019 &expr
.original_type
);
9020 set_c_expr_source_range (&expr
, tok_range
);
9023 case C_ID_CLASSNAME
:
9025 /* Here we parse the Objective-C 2.0 Class.name dot
9027 tree class_name
= c_parser_peek_token (parser
)->value
;
9029 c_parser_consume_token (parser
);
9030 gcc_assert (c_dialect_objc ());
9031 if (!c_parser_require (parser
, CPP_DOT
, "expected %<.%>"))
9036 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
9038 c_parser_error (parser
, "expected identifier");
9042 c_token
*component_tok
= c_parser_peek_token (parser
);
9043 component
= component_tok
->value
;
9044 location_t end_loc
= component_tok
->get_finish ();
9045 c_parser_consume_token (parser
);
9046 expr
.value
= objc_build_class_component_ref (class_name
,
9048 set_c_expr_source_range (&expr
, loc
, end_loc
);
9052 c_parser_error (parser
, "expected expression");
9057 case CPP_OPEN_PAREN
:
9058 /* A parenthesized expression, statement expression or compound
9060 if (c_parser_peek_2nd_token (parser
)->type
== CPP_OPEN_BRACE
)
9062 /* A statement expression. */
9064 location_t brace_loc
;
9065 c_parser_consume_token (parser
);
9066 brace_loc
= c_parser_peek_token (parser
)->location
;
9067 c_parser_consume_token (parser
);
9068 /* If we've not yet started the current function's statement list,
9069 or we're in the parameter scope of an old-style function
9070 declaration, statement expressions are not allowed. */
9071 if (!building_stmt_list_p () || old_style_parameter_scope ())
9073 error_at (loc
, "braced-group within expression allowed "
9074 "only inside a function");
9075 parser
->error
= true;
9076 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
, NULL
);
9077 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
9081 stmt
= c_begin_stmt_expr ();
9082 c_parser_compound_statement_nostart (parser
);
9083 location_t close_loc
= c_parser_peek_token (parser
)->location
;
9084 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
9086 pedwarn (loc
, OPT_Wpedantic
,
9087 "ISO C forbids braced-groups within expressions");
9088 expr
.value
= c_finish_stmt_expr (brace_loc
, stmt
);
9089 set_c_expr_source_range (&expr
, loc
, close_loc
);
9090 mark_exp_read (expr
.value
);
9094 /* A parenthesized expression. */
9095 location_t loc_open_paren
= c_parser_peek_token (parser
)->location
;
9096 c_parser_consume_token (parser
);
9097 expr
= c_parser_expression (parser
);
9098 if (TREE_CODE (expr
.value
) == MODIFY_EXPR
)
9099 suppress_warning (expr
.value
, OPT_Wparentheses
);
9100 if (expr
.original_code
!= C_MAYBE_CONST_EXPR
9101 && expr
.original_code
!= SIZEOF_EXPR
)
9102 expr
.original_code
= ERROR_MARK
;
9103 /* Remember that we saw ( ) around the sizeof. */
9104 if (expr
.original_code
== SIZEOF_EXPR
)
9105 expr
.original_code
= PAREN_SIZEOF_EXPR
;
9106 /* Don't change EXPR.ORIGINAL_TYPE. */
9107 location_t loc_close_paren
= c_parser_peek_token (parser
)->location
;
9108 set_c_expr_source_range (&expr
, loc_open_paren
, loc_close_paren
);
9109 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
9110 "expected %<)%>", loc_open_paren
);
9114 switch (c_parser_peek_token (parser
)->keyword
)
9116 case RID_FUNCTION_NAME
:
9117 case RID_PRETTY_FUNCTION_NAME
:
9118 case RID_C99_FUNCTION_NAME
:
9119 expr
= c_parser_predefined_identifier (parser
);
9123 location_t start_loc
= loc
;
9124 c_parser_consume_token (parser
);
9125 matching_parens parens
;
9126 if (!parens
.require_open (parser
))
9131 e1
= c_parser_expr_no_commas (parser
, NULL
);
9132 mark_exp_read (e1
.value
);
9133 e1
.value
= c_fully_fold (e1
.value
, false, NULL
);
9134 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
9136 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
9140 loc
= c_parser_peek_token (parser
)->location
;
9141 t1
= c_parser_type_name (parser
);
9142 location_t end_loc
= c_parser_peek_token (parser
)->get_finish ();
9143 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
9151 tree type_expr
= NULL_TREE
;
9152 expr
.value
= c_build_va_arg (start_loc
, e1
.value
, loc
,
9153 groktypename (t1
, &type_expr
, NULL
));
9156 expr
.value
= build2 (C_MAYBE_CONST_EXPR
,
9157 TREE_TYPE (expr
.value
), type_expr
,
9159 C_MAYBE_CONST_EXPR_NON_CONST (expr
.value
) = true;
9161 set_c_expr_source_range (&expr
, start_loc
, end_loc
);
9167 c_parser_consume_token (parser
);
9168 matching_parens parens
;
9169 if (!parens
.require_open (parser
))
9174 t1
= c_parser_type_name (parser
);
9176 parser
->error
= true;
9177 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
9178 gcc_assert (parser
->error
);
9181 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
9185 tree type
= groktypename (t1
, NULL
, NULL
);
9187 if (type
== error_mark_node
)
9188 offsetof_ref
= error_mark_node
;
9191 offsetof_ref
= build1 (INDIRECT_REF
, type
, null_pointer_node
);
9192 SET_EXPR_LOCATION (offsetof_ref
, loc
);
9194 /* Parse the second argument to __builtin_offsetof. We
9195 must have one identifier, and beyond that we want to
9196 accept sub structure and sub array references. */
9197 if (c_parser_next_token_is (parser
, CPP_NAME
))
9199 c_token
*comp_tok
= c_parser_peek_token (parser
);
9200 offsetof_ref
= build_component_ref
9201 (loc
, offsetof_ref
, comp_tok
->value
, comp_tok
->location
);
9202 c_parser_consume_token (parser
);
9203 while (c_parser_next_token_is (parser
, CPP_DOT
)
9204 || c_parser_next_token_is (parser
,
9206 || c_parser_next_token_is (parser
,
9209 if (c_parser_next_token_is (parser
, CPP_DEREF
))
9211 loc
= c_parser_peek_token (parser
)->location
;
9212 offsetof_ref
= build_array_ref (loc
,
9217 else if (c_parser_next_token_is (parser
, CPP_DOT
))
9220 c_parser_consume_token (parser
);
9221 if (c_parser_next_token_is_not (parser
,
9224 c_parser_error (parser
, "expected identifier");
9227 c_token
*comp_tok
= c_parser_peek_token (parser
);
9228 offsetof_ref
= build_component_ref
9229 (loc
, offsetof_ref
, comp_tok
->value
,
9230 comp_tok
->location
);
9231 c_parser_consume_token (parser
);
9237 loc
= c_parser_peek_token (parser
)->location
;
9238 c_parser_consume_token (parser
);
9239 ce
= c_parser_expression (parser
);
9240 ce
= convert_lvalue_to_rvalue (loc
, ce
, false, false);
9242 idx
= c_fully_fold (idx
, false, NULL
);
9243 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
9245 offsetof_ref
= build_array_ref (loc
, offsetof_ref
, idx
);
9250 c_parser_error (parser
, "expected identifier");
9251 location_t end_loc
= c_parser_peek_token (parser
)->get_finish ();
9252 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
9254 expr
.value
= fold_offsetof (offsetof_ref
);
9255 set_c_expr_source_range (&expr
, loc
, end_loc
);
9258 case RID_CHOOSE_EXPR
:
9260 vec
<c_expr_t
, va_gc
> *cexpr_list
;
9261 c_expr_t
*e1_p
, *e2_p
, *e3_p
;
9263 location_t close_paren_loc
;
9265 c_parser_consume_token (parser
);
9266 if (!c_parser_get_builtin_args (parser
,
9267 "__builtin_choose_expr",
9275 if (vec_safe_length (cexpr_list
) != 3)
9277 error_at (loc
, "wrong number of arguments to "
9278 "%<__builtin_choose_expr%>");
9283 e1_p
= &(*cexpr_list
)[0];
9284 e2_p
= &(*cexpr_list
)[1];
9285 e3_p
= &(*cexpr_list
)[2];
9288 mark_exp_read (e2_p
->value
);
9289 mark_exp_read (e3_p
->value
);
9290 if (TREE_CODE (c
) != INTEGER_CST
9291 || !INTEGRAL_TYPE_P (TREE_TYPE (c
)))
9293 "first argument to %<__builtin_choose_expr%> not"
9295 constant_expression_warning (c
);
9296 expr
= integer_zerop (c
) ? *e3_p
: *e2_p
;
9297 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
9300 case RID_TYPES_COMPATIBLE_P
:
9302 c_parser_consume_token (parser
);
9303 matching_parens parens
;
9304 if (!parens
.require_open (parser
))
9309 t1
= c_parser_type_name (parser
);
9315 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
9317 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
9321 t2
= c_parser_type_name (parser
);
9327 location_t close_paren_loc
= c_parser_peek_token (parser
)->location
;
9328 parens
.skip_until_found_close (parser
);
9330 e1
= groktypename (t1
, NULL
, NULL
);
9331 e2
= groktypename (t2
, NULL
, NULL
);
9332 if (e1
== error_mark_node
|| e2
== error_mark_node
)
9338 e1
= TYPE_MAIN_VARIANT (e1
);
9339 e2
= TYPE_MAIN_VARIANT (e2
);
9342 = comptypes (e1
, e2
) ? integer_one_node
: integer_zero_node
;
9343 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
9346 case RID_BUILTIN_TGMATH
:
9348 vec
<c_expr_t
, va_gc
> *cexpr_list
;
9349 location_t close_paren_loc
;
9351 c_parser_consume_token (parser
);
9352 if (!c_parser_get_builtin_args (parser
,
9361 if (vec_safe_length (cexpr_list
) < 3)
9363 error_at (loc
, "too few arguments to %<__builtin_tgmath%>");
9370 FOR_EACH_VEC_ELT (*cexpr_list
, i
, p
)
9371 *p
= convert_lvalue_to_rvalue (loc
, *p
, true, true);
9372 unsigned int nargs
= check_tgmath_function (&(*cexpr_list
)[0], 1);
9378 if (vec_safe_length (cexpr_list
) < nargs
)
9380 error_at (loc
, "too few arguments to %<__builtin_tgmath%>");
9384 unsigned int num_functions
= vec_safe_length (cexpr_list
) - nargs
;
9385 if (num_functions
< 2)
9387 error_at (loc
, "too few arguments to %<__builtin_tgmath%>");
9392 /* The first NUM_FUNCTIONS expressions are the function
9393 pointers. The remaining NARGS expressions are the
9394 arguments that are to be passed to one of those
9395 functions, chosen following <tgmath.h> rules. */
9396 for (unsigned int j
= 1; j
< num_functions
; j
++)
9398 unsigned int this_nargs
9399 = check_tgmath_function (&(*cexpr_list
)[j
], j
+ 1);
9400 if (this_nargs
== 0)
9405 if (this_nargs
!= nargs
)
9407 error_at ((*cexpr_list
)[j
].get_location (),
9408 "argument %u of %<__builtin_tgmath%> has "
9409 "wrong number of arguments", j
+ 1);
9415 /* The functions all have the same number of arguments.
9416 Determine whether arguments and return types vary in
9417 ways permitted for <tgmath.h> functions. */
9418 /* The first entry in each of these vectors is for the
9419 return type, subsequent entries for parameter
9421 auto_vec
<enum tgmath_parm_kind
> parm_kind (nargs
+ 1);
9422 auto_vec
<tree
> parm_first (nargs
+ 1);
9423 auto_vec
<bool> parm_complex (nargs
+ 1);
9424 auto_vec
<bool> parm_varies (nargs
+ 1);
9425 tree first_type
= TREE_TYPE (TREE_TYPE ((*cexpr_list
)[0].value
));
9426 tree first_ret
= TYPE_MAIN_VARIANT (TREE_TYPE (first_type
));
9427 parm_first
.quick_push (first_ret
);
9428 parm_complex
.quick_push (TREE_CODE (first_ret
) == COMPLEX_TYPE
);
9429 parm_varies
.quick_push (false);
9430 function_args_iterator iter
;
9432 unsigned int argpos
;
9433 FOREACH_FUNCTION_ARGS (first_type
, t
, iter
)
9435 if (t
== void_type_node
)
9437 parm_first
.quick_push (TYPE_MAIN_VARIANT (t
));
9438 parm_complex
.quick_push (TREE_CODE (t
) == COMPLEX_TYPE
);
9439 parm_varies
.quick_push (false);
9441 for (unsigned int j
= 1; j
< num_functions
; j
++)
9443 tree type
= TREE_TYPE (TREE_TYPE ((*cexpr_list
)[j
].value
));
9444 tree ret
= TYPE_MAIN_VARIANT (TREE_TYPE (type
));
9445 if (ret
!= parm_first
[0])
9447 parm_varies
[0] = true;
9448 if (!SCALAR_FLOAT_TYPE_P (parm_first
[0])
9449 && !COMPLEX_FLOAT_TYPE_P (parm_first
[0]))
9451 error_at ((*cexpr_list
)[0].get_location (),
9452 "invalid type-generic return type for "
9453 "argument %u of %<__builtin_tgmath%>",
9458 if (!SCALAR_FLOAT_TYPE_P (ret
)
9459 && !COMPLEX_FLOAT_TYPE_P (ret
))
9461 error_at ((*cexpr_list
)[j
].get_location (),
9462 "invalid type-generic return type for "
9463 "argument %u of %<__builtin_tgmath%>",
9469 if (TREE_CODE (ret
) == COMPLEX_TYPE
)
9470 parm_complex
[0] = true;
9472 FOREACH_FUNCTION_ARGS (type
, t
, iter
)
9474 if (t
== void_type_node
)
9476 t
= TYPE_MAIN_VARIANT (t
);
9477 if (t
!= parm_first
[argpos
])
9479 parm_varies
[argpos
] = true;
9480 if (!SCALAR_FLOAT_TYPE_P (parm_first
[argpos
])
9481 && !COMPLEX_FLOAT_TYPE_P (parm_first
[argpos
]))
9483 error_at ((*cexpr_list
)[0].get_location (),
9484 "invalid type-generic type for "
9485 "argument %u of argument %u of "
9486 "%<__builtin_tgmath%>", argpos
, 1);
9490 if (!SCALAR_FLOAT_TYPE_P (t
)
9491 && !COMPLEX_FLOAT_TYPE_P (t
))
9493 error_at ((*cexpr_list
)[j
].get_location (),
9494 "invalid type-generic type for "
9495 "argument %u of argument %u of "
9496 "%<__builtin_tgmath%>", argpos
, j
+ 1);
9501 if (TREE_CODE (t
) == COMPLEX_TYPE
)
9502 parm_complex
[argpos
] = true;
9506 enum tgmath_parm_kind max_variation
= tgmath_fixed
;
9507 for (unsigned int j
= 0; j
<= nargs
; j
++)
9509 enum tgmath_parm_kind this_kind
;
9512 if (parm_complex
[j
])
9513 max_variation
= this_kind
= tgmath_complex
;
9516 this_kind
= tgmath_real
;
9517 if (max_variation
!= tgmath_complex
)
9518 max_variation
= tgmath_real
;
9522 this_kind
= tgmath_fixed
;
9523 parm_kind
.quick_push (this_kind
);
9525 if (max_variation
== tgmath_fixed
)
9527 error_at (loc
, "function arguments of %<__builtin_tgmath%> "
9528 "all have the same type");
9533 /* Identify a parameter (not the return type) that varies,
9534 including with complex types if any variation includes
9535 complex types; there must be at least one such
9537 unsigned int tgarg
= 0;
9538 for (unsigned int j
= 1; j
<= nargs
; j
++)
9539 if (parm_kind
[j
] == max_variation
)
9546 error_at (loc
, "function arguments of %<__builtin_tgmath%> "
9547 "lack type-generic parameter");
9552 /* Determine the type of the relevant parameter for each
9554 auto_vec
<tree
> tg_type (num_functions
);
9555 for (unsigned int j
= 0; j
< num_functions
; j
++)
9557 tree type
= TREE_TYPE (TREE_TYPE ((*cexpr_list
)[j
].value
));
9559 FOREACH_FUNCTION_ARGS (type
, t
, iter
)
9561 if (argpos
== tgarg
)
9563 tg_type
.quick_push (TYPE_MAIN_VARIANT (t
));
9570 /* Verify that the corresponding types are different for
9571 all the listed functions. Also determine whether all
9572 the types are complex, whether all the types are
9573 standard or binary, and whether all the types are
9575 bool all_complex
= true;
9576 bool all_binary
= true;
9577 bool all_decimal
= true;
9578 hash_set
<tree
> tg_types
;
9579 FOR_EACH_VEC_ELT (tg_type
, i
, t
)
9581 if (TREE_CODE (t
) == COMPLEX_TYPE
)
9582 all_decimal
= false;
9585 all_complex
= false;
9586 if (DECIMAL_FLOAT_TYPE_P (t
))
9589 all_decimal
= false;
9591 if (tg_types
.add (t
))
9593 error_at ((*cexpr_list
)[i
].get_location (),
9594 "duplicate type-generic parameter type for "
9595 "function argument %u of %<__builtin_tgmath%>",
9602 /* Verify that other parameters and the return type whose
9603 types vary have their types varying in the correct
9605 for (unsigned int j
= 0; j
< num_functions
; j
++)
9607 tree exp_type
= tg_type
[j
];
9608 tree exp_real_type
= exp_type
;
9609 if (TREE_CODE (exp_type
) == COMPLEX_TYPE
)
9610 exp_real_type
= TREE_TYPE (exp_type
);
9611 tree type
= TREE_TYPE (TREE_TYPE ((*cexpr_list
)[j
].value
));
9612 tree ret
= TYPE_MAIN_VARIANT (TREE_TYPE (type
));
9613 if ((parm_kind
[0] == tgmath_complex
&& ret
!= exp_type
)
9614 || (parm_kind
[0] == tgmath_real
&& ret
!= exp_real_type
))
9616 error_at ((*cexpr_list
)[j
].get_location (),
9617 "bad return type for function argument %u "
9618 "of %<__builtin_tgmath%>", j
+ 1);
9623 FOREACH_FUNCTION_ARGS (type
, t
, iter
)
9625 if (t
== void_type_node
)
9627 t
= TYPE_MAIN_VARIANT (t
);
9628 if ((parm_kind
[argpos
] == tgmath_complex
9630 || (parm_kind
[argpos
] == tgmath_real
9631 && t
!= exp_real_type
))
9633 error_at ((*cexpr_list
)[j
].get_location (),
9634 "bad type for argument %u of "
9635 "function argument %u of "
9636 "%<__builtin_tgmath%>", argpos
, j
+ 1);
9644 /* The functions listed are a valid set of functions for a
9645 <tgmath.h> macro to select between. Identify the
9646 matching function, if any. First, the argument types
9647 must be combined following <tgmath.h> rules. Integer
9648 types are treated as _Decimal64 if any type-generic
9649 argument is decimal, or if the only alternatives for
9650 type-generic arguments are of decimal types, and are
9651 otherwise treated as double (or _Complex double for
9652 complex integer types, or _Float64 or _Complex _Float64
9653 if all the return types are the same _FloatN or
9654 _FloatNx type). After that adjustment, types are
9655 combined following the usual arithmetic conversions.
9656 If the function only accepts complex arguments, a
9657 complex type is produced. */
9658 bool arg_complex
= all_complex
;
9659 bool arg_binary
= all_binary
;
9660 bool arg_int_decimal
= all_decimal
;
9661 for (unsigned int j
= 1; j
<= nargs
; j
++)
9663 if (parm_kind
[j
] == tgmath_fixed
)
9665 c_expr_t
*ce
= &(*cexpr_list
)[num_functions
+ j
- 1];
9666 tree type
= TREE_TYPE (ce
->value
);
9667 if (!INTEGRAL_TYPE_P (type
)
9668 && !SCALAR_FLOAT_TYPE_P (type
)
9669 && TREE_CODE (type
) != COMPLEX_TYPE
)
9671 error_at (ce
->get_location (),
9672 "invalid type of argument %u of type-generic "
9677 if (DECIMAL_FLOAT_TYPE_P (type
))
9679 arg_int_decimal
= true;
9682 error_at (ce
->get_location (),
9683 "decimal floating-point argument %u to "
9684 "complex-only type-generic function", j
);
9688 else if (all_binary
)
9690 error_at (ce
->get_location (),
9691 "decimal floating-point argument %u to "
9692 "binary-only type-generic function", j
);
9696 else if (arg_complex
)
9698 error_at (ce
->get_location (),
9699 "both complex and decimal floating-point "
9700 "arguments to type-generic function");
9704 else if (arg_binary
)
9706 error_at (ce
->get_location (),
9707 "both binary and decimal floating-point "
9708 "arguments to type-generic function");
9713 else if (TREE_CODE (type
) == COMPLEX_TYPE
)
9716 if (COMPLEX_FLOAT_TYPE_P (type
))
9720 error_at (ce
->get_location (),
9721 "complex argument %u to "
9722 "decimal-only type-generic function", j
);
9726 else if (arg_int_decimal
)
9728 error_at (ce
->get_location (),
9729 "both complex and decimal floating-point "
9730 "arguments to type-generic function");
9735 else if (SCALAR_FLOAT_TYPE_P (type
))
9740 error_at (ce
->get_location (),
9741 "binary argument %u to "
9742 "decimal-only type-generic function", j
);
9746 else if (arg_int_decimal
)
9748 error_at (ce
->get_location (),
9749 "both binary and decimal floating-point "
9750 "arguments to type-generic function");
9756 /* For a macro rounding its result to a narrower type, map
9757 integer types to _Float64 not double if the return type
9758 is a _FloatN or _FloatNx type. */
9759 bool arg_int_float64
= false;
9760 if (parm_kind
[0] == tgmath_fixed
9761 && SCALAR_FLOAT_TYPE_P (parm_first
[0])
9762 && float64_type_node
!= NULL_TREE
)
9763 for (unsigned int j
= 0; j
< NUM_FLOATN_NX_TYPES
; j
++)
9764 if (parm_first
[0] == FLOATN_TYPE_NODE (j
))
9766 arg_int_float64
= true;
9769 tree arg_real
= NULL_TREE
;
9770 for (unsigned int j
= 1; j
<= nargs
; j
++)
9772 if (parm_kind
[j
] == tgmath_fixed
)
9774 c_expr_t
*ce
= &(*cexpr_list
)[num_functions
+ j
- 1];
9775 tree type
= TYPE_MAIN_VARIANT (TREE_TYPE (ce
->value
));
9776 if (TREE_CODE (type
) == COMPLEX_TYPE
)
9777 type
= TREE_TYPE (type
);
9778 if (INTEGRAL_TYPE_P (type
))
9779 type
= (arg_int_decimal
9780 ? dfloat64_type_node
9783 : double_type_node
);
9784 if (arg_real
== NULL_TREE
)
9787 arg_real
= common_type (arg_real
, type
);
9788 if (arg_real
== error_mark_node
)
9794 tree arg_type
= (arg_complex
9795 ? build_complex_type (arg_real
)
9798 /* Look for a function to call with type-generic parameter
9800 c_expr_t
*fn
= NULL
;
9801 for (unsigned int j
= 0; j
< num_functions
; j
++)
9803 if (tg_type
[j
] == arg_type
)
9805 fn
= &(*cexpr_list
)[j
];
9810 && parm_kind
[0] == tgmath_fixed
9811 && SCALAR_FLOAT_TYPE_P (parm_first
[0]))
9813 /* Presume this is a macro that rounds its result to a
9814 narrower type, and look for the first function with
9815 at least the range and precision of the argument
9817 for (unsigned int j
= 0; j
< num_functions
; j
++)
9820 != (TREE_CODE (tg_type
[j
]) == COMPLEX_TYPE
))
9822 tree real_tg_type
= (arg_complex
9823 ? TREE_TYPE (tg_type
[j
])
9825 if (DECIMAL_FLOAT_TYPE_P (arg_real
)
9826 != DECIMAL_FLOAT_TYPE_P (real_tg_type
))
9828 scalar_float_mode arg_mode
9829 = SCALAR_FLOAT_TYPE_MODE (arg_real
);
9830 scalar_float_mode tg_mode
9831 = SCALAR_FLOAT_TYPE_MODE (real_tg_type
);
9832 const real_format
*arg_fmt
= REAL_MODE_FORMAT (arg_mode
);
9833 const real_format
*tg_fmt
= REAL_MODE_FORMAT (tg_mode
);
9834 if (arg_fmt
->b
== tg_fmt
->b
9835 && arg_fmt
->p
<= tg_fmt
->p
9836 && arg_fmt
->emax
<= tg_fmt
->emax
9837 && (arg_fmt
->emin
- arg_fmt
->p
9838 >= tg_fmt
->emin
- tg_fmt
->p
))
9840 fn
= &(*cexpr_list
)[j
];
9847 error_at (loc
, "no matching function for type-generic call");
9852 /* Construct a call to FN. */
9853 vec
<tree
, va_gc
> *args
;
9854 vec_alloc (args
, nargs
);
9855 vec
<tree
, va_gc
> *origtypes
;
9856 vec_alloc (origtypes
, nargs
);
9857 auto_vec
<location_t
> arg_loc (nargs
);
9858 for (unsigned int j
= 0; j
< nargs
; j
++)
9860 c_expr_t
*ce
= &(*cexpr_list
)[num_functions
+ j
];
9861 args
->quick_push (ce
->value
);
9862 arg_loc
.quick_push (ce
->get_location ());
9863 origtypes
->quick_push (ce
->original_type
);
9865 expr
.value
= c_build_function_call_vec (loc
, arg_loc
, fn
->value
,
9867 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
9870 case RID_BUILTIN_CALL_WITH_STATIC_CHAIN
:
9872 vec
<c_expr_t
, va_gc
> *cexpr_list
;
9875 location_t close_paren_loc
;
9877 c_parser_consume_token (parser
);
9878 if (!c_parser_get_builtin_args (parser
,
9879 "__builtin_call_with_static_chain",
9886 if (vec_safe_length (cexpr_list
) != 2)
9888 error_at (loc
, "wrong number of arguments to "
9889 "%<__builtin_call_with_static_chain%>");
9894 expr
= (*cexpr_list
)[0];
9895 e2_p
= &(*cexpr_list
)[1];
9896 *e2_p
= convert_lvalue_to_rvalue (loc
, *e2_p
, true, true);
9897 chain_value
= e2_p
->value
;
9898 mark_exp_read (chain_value
);
9900 if (TREE_CODE (expr
.value
) != CALL_EXPR
)
9901 error_at (loc
, "first argument to "
9902 "%<__builtin_call_with_static_chain%> "
9903 "must be a call expression");
9904 else if (TREE_CODE (TREE_TYPE (chain_value
)) != POINTER_TYPE
)
9905 error_at (loc
, "second argument to "
9906 "%<__builtin_call_with_static_chain%> "
9907 "must be a pointer type");
9909 CALL_EXPR_STATIC_CHAIN (expr
.value
) = chain_value
;
9910 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
9913 case RID_BUILTIN_COMPLEX
:
9915 vec
<c_expr_t
, va_gc
> *cexpr_list
;
9916 c_expr_t
*e1_p
, *e2_p
;
9917 location_t close_paren_loc
;
9919 c_parser_consume_token (parser
);
9920 if (!c_parser_get_builtin_args (parser
,
9921 "__builtin_complex",
9929 if (vec_safe_length (cexpr_list
) != 2)
9931 error_at (loc
, "wrong number of arguments to "
9932 "%<__builtin_complex%>");
9937 e1_p
= &(*cexpr_list
)[0];
9938 e2_p
= &(*cexpr_list
)[1];
9940 *e1_p
= convert_lvalue_to_rvalue (loc
, *e1_p
, true, true);
9941 if (TREE_CODE (e1_p
->value
) == EXCESS_PRECISION_EXPR
)
9942 e1_p
->value
= convert (TREE_TYPE (e1_p
->value
),
9943 TREE_OPERAND (e1_p
->value
, 0));
9944 *e2_p
= convert_lvalue_to_rvalue (loc
, *e2_p
, true, true);
9945 if (TREE_CODE (e2_p
->value
) == EXCESS_PRECISION_EXPR
)
9946 e2_p
->value
= convert (TREE_TYPE (e2_p
->value
),
9947 TREE_OPERAND (e2_p
->value
, 0));
9948 if (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (e1_p
->value
))
9949 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e1_p
->value
))
9950 || !SCALAR_FLOAT_TYPE_P (TREE_TYPE (e2_p
->value
))
9951 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e2_p
->value
)))
9953 error_at (loc
, "%<__builtin_complex%> operand "
9954 "not of real binary floating-point type");
9958 if (TYPE_MAIN_VARIANT (TREE_TYPE (e1_p
->value
))
9959 != TYPE_MAIN_VARIANT (TREE_TYPE (e2_p
->value
)))
9962 "%<__builtin_complex%> operands of different types");
9966 pedwarn_c90 (loc
, OPT_Wpedantic
,
9967 "ISO C90 does not support complex types");
9968 expr
.value
= build2_loc (loc
, COMPLEX_EXPR
,
9971 (TREE_TYPE (e1_p
->value
))),
9972 e1_p
->value
, e2_p
->value
);
9973 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
9976 case RID_BUILTIN_SHUFFLE
:
9978 vec
<c_expr_t
, va_gc
> *cexpr_list
;
9981 location_t close_paren_loc
;
9983 c_parser_consume_token (parser
);
9984 if (!c_parser_get_builtin_args (parser
,
9985 "__builtin_shuffle",
9993 FOR_EACH_VEC_SAFE_ELT (cexpr_list
, i
, p
)
9994 *p
= convert_lvalue_to_rvalue (loc
, *p
, true, true);
9996 if (vec_safe_length (cexpr_list
) == 2)
9997 expr
.value
= c_build_vec_perm_expr (loc
, (*cexpr_list
)[0].value
,
9999 (*cexpr_list
)[1].value
);
10001 else if (vec_safe_length (cexpr_list
) == 3)
10002 expr
.value
= c_build_vec_perm_expr (loc
, (*cexpr_list
)[0].value
,
10003 (*cexpr_list
)[1].value
,
10004 (*cexpr_list
)[2].value
);
10007 error_at (loc
, "wrong number of arguments to "
10008 "%<__builtin_shuffle%>");
10011 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
10014 case RID_BUILTIN_SHUFFLEVECTOR
:
10016 vec
<c_expr_t
, va_gc
> *cexpr_list
;
10019 location_t close_paren_loc
;
10021 c_parser_consume_token (parser
);
10022 if (!c_parser_get_builtin_args (parser
,
10023 "__builtin_shufflevector",
10024 &cexpr_list
, false,
10031 FOR_EACH_VEC_SAFE_ELT (cexpr_list
, i
, p
)
10032 *p
= convert_lvalue_to_rvalue (loc
, *p
, true, true);
10034 if (vec_safe_length (cexpr_list
) < 3)
10036 error_at (loc
, "wrong number of arguments to "
10037 "%<__builtin_shuffle%>");
10042 auto_vec
<tree
, 16> mask
;
10043 for (i
= 2; i
< cexpr_list
->length (); ++i
)
10044 mask
.safe_push ((*cexpr_list
)[i
].value
);
10045 expr
.value
= c_build_shufflevector (loc
, (*cexpr_list
)[0].value
,
10046 (*cexpr_list
)[1].value
,
10049 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
10052 case RID_BUILTIN_CONVERTVECTOR
:
10054 location_t start_loc
= loc
;
10055 c_parser_consume_token (parser
);
10056 matching_parens parens
;
10057 if (!parens
.require_open (parser
))
10062 e1
= c_parser_expr_no_commas (parser
, NULL
);
10063 mark_exp_read (e1
.value
);
10064 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
10066 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10070 loc
= c_parser_peek_token (parser
)->location
;
10071 t1
= c_parser_type_name (parser
);
10072 location_t end_loc
= c_parser_peek_token (parser
)->get_finish ();
10073 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
10079 tree type_expr
= NULL_TREE
;
10080 expr
.value
= c_build_vec_convert (start_loc
, e1
.value
, loc
,
10081 groktypename (t1
, &type_expr
,
10083 set_c_expr_source_range (&expr
, start_loc
, end_loc
);
10087 case RID_AT_SELECTOR
:
10089 gcc_assert (c_dialect_objc ());
10090 c_parser_consume_token (parser
);
10091 matching_parens parens
;
10092 if (!parens
.require_open (parser
))
10097 tree sel
= c_parser_objc_selector_arg (parser
);
10098 location_t close_loc
= c_parser_peek_token (parser
)->location
;
10099 parens
.skip_until_found_close (parser
);
10100 expr
.value
= objc_build_selector_expr (loc
, sel
);
10101 set_c_expr_source_range (&expr
, loc
, close_loc
);
10104 case RID_AT_PROTOCOL
:
10106 gcc_assert (c_dialect_objc ());
10107 c_parser_consume_token (parser
);
10108 matching_parens parens
;
10109 if (!parens
.require_open (parser
))
10114 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
10116 c_parser_error (parser
, "expected identifier");
10117 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10121 tree id
= c_parser_peek_token (parser
)->value
;
10122 c_parser_consume_token (parser
);
10123 location_t close_loc
= c_parser_peek_token (parser
)->location
;
10124 parens
.skip_until_found_close (parser
);
10125 expr
.value
= objc_build_protocol_expr (id
);
10126 set_c_expr_source_range (&expr
, loc
, close_loc
);
10129 case RID_AT_ENCODE
:
10131 /* Extension to support C-structures in the archiver. */
10132 gcc_assert (c_dialect_objc ());
10133 c_parser_consume_token (parser
);
10134 matching_parens parens
;
10135 if (!parens
.require_open (parser
))
10140 t1
= c_parser_type_name (parser
);
10144 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10147 location_t close_loc
= c_parser_peek_token (parser
)->location
;
10148 parens
.skip_until_found_close (parser
);
10149 tree type
= groktypename (t1
, NULL
, NULL
);
10150 expr
.value
= objc_build_encode_expr (type
);
10151 set_c_expr_source_range (&expr
, loc
, close_loc
);
10155 expr
= c_parser_generic_selection (parser
);
10158 c_parser_error (parser
, "expected expression");
10163 case CPP_OPEN_SQUARE
:
10164 if (c_dialect_objc ())
10166 tree receiver
, args
;
10167 c_parser_consume_token (parser
);
10168 receiver
= c_parser_objc_receiver (parser
);
10169 args
= c_parser_objc_message_args (parser
);
10170 location_t close_loc
= c_parser_peek_token (parser
)->location
;
10171 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
10173 expr
.value
= objc_build_message_expr (receiver
, args
);
10174 set_c_expr_source_range (&expr
, loc
, close_loc
);
10177 /* Else fall through to report error. */
10180 c_parser_error (parser
, "expected expression");
10185 return c_parser_postfix_expression_after_primary
10186 (parser
, EXPR_LOC_OR_LOC (expr
.value
, loc
), expr
);
10189 /* Parse a postfix expression after a parenthesized type name: the
10190 brace-enclosed initializer of a compound literal, possibly followed
10191 by some postfix operators. This is separate because it is not
10192 possible to tell until after the type name whether a cast
10193 expression has a cast or a compound literal, or whether the operand
10194 of sizeof is a parenthesized type name or starts with a compound
10195 literal. TYPE_LOC is the location where TYPE_NAME starts--the
10196 location of the first token after the parentheses around the type
10199 static struct c_expr
10200 c_parser_postfix_expression_after_paren_type (c_parser
*parser
,
10201 struct c_type_name
*type_name
,
10202 location_t type_loc
)
10205 struct c_expr init
;
10207 struct c_expr expr
;
10208 location_t start_loc
;
10209 tree type_expr
= NULL_TREE
;
10210 bool type_expr_const
= true;
10211 check_compound_literal_type (type_loc
, type_name
);
10212 rich_location
richloc (line_table
, type_loc
);
10213 start_init (NULL_TREE
, NULL
, 0, &richloc
);
10214 type
= groktypename (type_name
, &type_expr
, &type_expr_const
);
10215 start_loc
= c_parser_peek_token (parser
)->location
;
10216 if (type
!= error_mark_node
&& C_TYPE_VARIABLE_SIZE (type
))
10218 error_at (type_loc
, "compound literal has variable size");
10219 type
= error_mark_node
;
10221 init
= c_parser_braced_init (parser
, type
, false, NULL
);
10223 maybe_warn_string_init (type_loc
, type
, init
);
10225 if (type
!= error_mark_node
10226 && !ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (type
))
10227 && current_function_decl
)
10229 error ("compound literal qualified by address-space qualifier");
10230 type
= error_mark_node
;
10233 pedwarn_c90 (start_loc
, OPT_Wpedantic
, "ISO C90 forbids compound literals");
10234 non_const
= ((init
.value
&& TREE_CODE (init
.value
) == CONSTRUCTOR
)
10235 ? CONSTRUCTOR_NON_CONST (init
.value
)
10236 : init
.original_code
== C_MAYBE_CONST_EXPR
);
10237 non_const
|= !type_expr_const
;
10238 unsigned int alignas_align
= 0;
10239 if (type
!= error_mark_node
10240 && type_name
->specs
->align_log
!= -1)
10242 alignas_align
= 1U << type_name
->specs
->align_log
;
10243 if (alignas_align
< min_align_of_type (type
))
10245 error_at (type_name
->specs
->locations
[cdw_alignas
],
10246 "%<_Alignas%> specifiers cannot reduce "
10247 "alignment of compound literal");
10251 expr
.value
= build_compound_literal (start_loc
, type
, init
.value
, non_const
,
10253 set_c_expr_source_range (&expr
, init
.src_range
);
10254 expr
.original_code
= ERROR_MARK
;
10255 expr
.original_type
= NULL
;
10256 if (type
!= error_mark_node
10257 && expr
.value
!= error_mark_node
10260 if (TREE_CODE (expr
.value
) == C_MAYBE_CONST_EXPR
)
10262 gcc_assert (C_MAYBE_CONST_EXPR_PRE (expr
.value
) == NULL_TREE
);
10263 C_MAYBE_CONST_EXPR_PRE (expr
.value
) = type_expr
;
10267 gcc_assert (!non_const
);
10268 expr
.value
= build2 (C_MAYBE_CONST_EXPR
, type
,
10269 type_expr
, expr
.value
);
10272 return c_parser_postfix_expression_after_primary (parser
, start_loc
, expr
);
10275 /* Callback function for sizeof_pointer_memaccess_warning to compare
10279 sizeof_ptr_memacc_comptypes (tree type1
, tree type2
)
10281 return comptypes (type1
, type2
) == 1;
10284 /* Warn for patterns where abs-like function appears to be used incorrectly,
10285 gracefully ignore any non-abs-like function. The warning location should
10286 be LOC. FNDECL is the declaration of called function, it must be a
10287 BUILT_IN_NORMAL function. ARG is the first and only argument of the
10291 warn_for_abs (location_t loc
, tree fndecl
, tree arg
)
10293 /* Avoid warning in unreachable subexpressions. */
10294 if (c_inhibit_evaluation_warnings
)
10297 tree atype
= TREE_TYPE (arg
);
10299 /* Casts from pointers (and thus arrays and fndecls) will generate
10300 -Wint-conversion warnings. Most other wrong types hopefully lead to type
10301 mismatch errors. TODO: Think about what to do with FIXED_POINT_TYPE_P
10302 types and possibly other exotic types. */
10303 if (!INTEGRAL_TYPE_P (atype
)
10304 && !SCALAR_FLOAT_TYPE_P (atype
)
10305 && TREE_CODE (atype
) != COMPLEX_TYPE
)
10308 enum built_in_function fcode
= DECL_FUNCTION_CODE (fndecl
);
10313 case BUILT_IN_LABS
:
10314 case BUILT_IN_LLABS
:
10315 case BUILT_IN_IMAXABS
:
10316 if (!INTEGRAL_TYPE_P (atype
))
10318 if (SCALAR_FLOAT_TYPE_P (atype
))
10319 warning_at (loc
, OPT_Wabsolute_value
,
10320 "using integer absolute value function %qD when "
10321 "argument is of floating-point type %qT",
10323 else if (TREE_CODE (atype
) == COMPLEX_TYPE
)
10324 warning_at (loc
, OPT_Wabsolute_value
,
10325 "using integer absolute value function %qD when "
10326 "argument is of complex type %qT", fndecl
, atype
);
10328 gcc_unreachable ();
10331 if (TYPE_UNSIGNED (atype
))
10332 warning_at (loc
, OPT_Wabsolute_value
,
10333 "taking the absolute value of unsigned type %qT "
10334 "has no effect", atype
);
10337 CASE_FLT_FN (BUILT_IN_FABS
):
10338 CASE_FLT_FN_FLOATN_NX (BUILT_IN_FABS
):
10339 if (!SCALAR_FLOAT_TYPE_P (atype
)
10340 || DECIMAL_FLOAT_MODE_P (TYPE_MODE (atype
)))
10342 if (INTEGRAL_TYPE_P (atype
))
10343 warning_at (loc
, OPT_Wabsolute_value
,
10344 "using floating-point absolute value function %qD "
10345 "when argument is of integer type %qT", fndecl
, atype
);
10346 else if (DECIMAL_FLOAT_TYPE_P (atype
))
10347 warning_at (loc
, OPT_Wabsolute_value
,
10348 "using floating-point absolute value function %qD "
10349 "when argument is of decimal floating-point type %qT",
10351 else if (TREE_CODE (atype
) == COMPLEX_TYPE
)
10352 warning_at (loc
, OPT_Wabsolute_value
,
10353 "using floating-point absolute value function %qD when "
10354 "argument is of complex type %qT", fndecl
, atype
);
10356 gcc_unreachable ();
10361 CASE_FLT_FN (BUILT_IN_CABS
):
10362 if (TREE_CODE (atype
) != COMPLEX_TYPE
)
10364 if (INTEGRAL_TYPE_P (atype
))
10365 warning_at (loc
, OPT_Wabsolute_value
,
10366 "using complex absolute value function %qD when "
10367 "argument is of integer type %qT", fndecl
, atype
);
10368 else if (SCALAR_FLOAT_TYPE_P (atype
))
10369 warning_at (loc
, OPT_Wabsolute_value
,
10370 "using complex absolute value function %qD when "
10371 "argument is of floating-point type %qT",
10374 gcc_unreachable ();
10380 case BUILT_IN_FABSD32
:
10381 case BUILT_IN_FABSD64
:
10382 case BUILT_IN_FABSD128
:
10383 if (!DECIMAL_FLOAT_TYPE_P (atype
))
10385 if (INTEGRAL_TYPE_P (atype
))
10386 warning_at (loc
, OPT_Wabsolute_value
,
10387 "using decimal floating-point absolute value "
10388 "function %qD when argument is of integer type %qT",
10390 else if (SCALAR_FLOAT_TYPE_P (atype
))
10391 warning_at (loc
, OPT_Wabsolute_value
,
10392 "using decimal floating-point absolute value "
10393 "function %qD when argument is of floating-point "
10394 "type %qT", fndecl
, atype
);
10395 else if (TREE_CODE (atype
) == COMPLEX_TYPE
)
10396 warning_at (loc
, OPT_Wabsolute_value
,
10397 "using decimal floating-point absolute value "
10398 "function %qD when argument is of complex type %qT",
10401 gcc_unreachable ();
10410 if (!TYPE_ARG_TYPES (TREE_TYPE (fndecl
)))
10413 tree ftype
= TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl
)));
10414 if (TREE_CODE (atype
) == COMPLEX_TYPE
)
10416 gcc_assert (TREE_CODE (ftype
) == COMPLEX_TYPE
);
10417 atype
= TREE_TYPE (atype
);
10418 ftype
= TREE_TYPE (ftype
);
10421 if (TYPE_PRECISION (ftype
) < TYPE_PRECISION (atype
))
10422 warning_at (loc
, OPT_Wabsolute_value
,
10423 "absolute value function %qD given an argument of type %qT "
10424 "but has parameter of type %qT which may cause truncation "
10425 "of value", fndecl
, atype
, ftype
);
10429 /* Parse a postfix expression after the initial primary or compound
10430 literal; that is, parse a series of postfix operators.
10432 EXPR_LOC is the location of the primary expression. */
10434 static struct c_expr
10435 c_parser_postfix_expression_after_primary (c_parser
*parser
,
10436 location_t expr_loc
,
10437 struct c_expr expr
)
10439 struct c_expr orig_expr
;
10441 location_t sizeof_arg_loc
[3], comp_loc
;
10442 tree sizeof_arg
[3];
10443 unsigned int literal_zero_mask
;
10445 vec
<tree
, va_gc
> *exprlist
;
10446 vec
<tree
, va_gc
> *origtypes
= NULL
;
10447 vec
<location_t
> arg_loc
= vNULL
;
10453 location_t op_loc
= c_parser_peek_token (parser
)->location
;
10454 switch (c_parser_peek_token (parser
)->type
)
10456 case CPP_OPEN_SQUARE
:
10457 /* Array reference. */
10458 c_parser_consume_token (parser
);
10459 idx
= c_parser_expression (parser
).value
;
10460 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
10462 start
= expr
.get_start ();
10463 finish
= parser
->tokens_buf
[0].location
;
10464 expr
.value
= build_array_ref (op_loc
, expr
.value
, idx
);
10465 set_c_expr_source_range (&expr
, start
, finish
);
10466 expr
.original_code
= ERROR_MARK
;
10467 expr
.original_type
= NULL
;
10469 case CPP_OPEN_PAREN
:
10470 /* Function call. */
10472 matching_parens parens
;
10473 parens
.consume_open (parser
);
10474 for (i
= 0; i
< 3; i
++)
10476 sizeof_arg
[i
] = NULL_TREE
;
10477 sizeof_arg_loc
[i
] = UNKNOWN_LOCATION
;
10479 literal_zero_mask
= 0;
10480 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
10483 exprlist
= c_parser_expr_list (parser
, true, false, &origtypes
,
10484 sizeof_arg_loc
, sizeof_arg
,
10485 &arg_loc
, &literal_zero_mask
);
10486 parens
.skip_until_found_close (parser
);
10489 mark_exp_read (expr
.value
);
10490 if (warn_sizeof_pointer_memaccess
)
10491 sizeof_pointer_memaccess_warning (sizeof_arg_loc
,
10492 expr
.value
, exprlist
,
10494 sizeof_ptr_memacc_comptypes
);
10495 if (TREE_CODE (expr
.value
) == FUNCTION_DECL
)
10497 if (fndecl_built_in_p (expr
.value
, BUILT_IN_MEMSET
)
10498 && vec_safe_length (exprlist
) == 3)
10500 tree arg0
= (*exprlist
)[0];
10501 tree arg2
= (*exprlist
)[2];
10502 warn_for_memset (expr_loc
, arg0
, arg2
, literal_zero_mask
);
10504 if (warn_absolute_value
10505 && fndecl_built_in_p (expr
.value
, BUILT_IN_NORMAL
)
10506 && vec_safe_length (exprlist
) == 1)
10507 warn_for_abs (expr_loc
, expr
.value
, (*exprlist
)[0]);
10510 start
= expr
.get_start ();
10511 finish
= parser
->tokens_buf
[0].get_finish ();
10513 = c_build_function_call_vec (expr_loc
, arg_loc
, expr
.value
,
10514 exprlist
, origtypes
);
10515 set_c_expr_source_range (&expr
, start
, finish
);
10517 expr
.original_code
= ERROR_MARK
;
10518 if (TREE_CODE (expr
.value
) == INTEGER_CST
10519 && TREE_CODE (orig_expr
.value
) == FUNCTION_DECL
10520 && fndecl_built_in_p (orig_expr
.value
, BUILT_IN_CONSTANT_P
))
10521 expr
.original_code
= C_MAYBE_CONST_EXPR
;
10522 expr
.original_type
= NULL
;
10525 release_tree_vector (exprlist
);
10526 release_tree_vector (origtypes
);
10528 arg_loc
.release ();
10531 /* Structure element reference. */
10532 c_parser_consume_token (parser
);
10533 expr
= default_function_array_conversion (expr_loc
, expr
);
10534 if (c_parser_next_token_is (parser
, CPP_NAME
))
10536 c_token
*comp_tok
= c_parser_peek_token (parser
);
10537 ident
= comp_tok
->value
;
10538 comp_loc
= comp_tok
->location
;
10542 c_parser_error (parser
, "expected identifier");
10544 expr
.original_code
= ERROR_MARK
;
10545 expr
.original_type
= NULL
;
10548 start
= expr
.get_start ();
10549 finish
= c_parser_peek_token (parser
)->get_finish ();
10550 c_parser_consume_token (parser
);
10551 expr
.value
= build_component_ref (op_loc
, expr
.value
, ident
,
10553 set_c_expr_source_range (&expr
, start
, finish
);
10554 expr
.original_code
= ERROR_MARK
;
10555 if (TREE_CODE (expr
.value
) != COMPONENT_REF
)
10556 expr
.original_type
= NULL
;
10559 /* Remember the original type of a bitfield. */
10560 tree field
= TREE_OPERAND (expr
.value
, 1);
10561 if (TREE_CODE (field
) != FIELD_DECL
)
10562 expr
.original_type
= NULL
;
10564 expr
.original_type
= DECL_BIT_FIELD_TYPE (field
);
10568 /* Structure element reference. */
10569 c_parser_consume_token (parser
);
10570 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, true, false);
10571 if (c_parser_next_token_is (parser
, CPP_NAME
))
10573 c_token
*comp_tok
= c_parser_peek_token (parser
);
10574 ident
= comp_tok
->value
;
10575 comp_loc
= comp_tok
->location
;
10579 c_parser_error (parser
, "expected identifier");
10581 expr
.original_code
= ERROR_MARK
;
10582 expr
.original_type
= NULL
;
10585 start
= expr
.get_start ();
10586 finish
= c_parser_peek_token (parser
)->get_finish ();
10587 c_parser_consume_token (parser
);
10588 expr
.value
= build_component_ref (op_loc
,
10589 build_indirect_ref (op_loc
,
10593 set_c_expr_source_range (&expr
, start
, finish
);
10594 expr
.original_code
= ERROR_MARK
;
10595 if (TREE_CODE (expr
.value
) != COMPONENT_REF
)
10596 expr
.original_type
= NULL
;
10599 /* Remember the original type of a bitfield. */
10600 tree field
= TREE_OPERAND (expr
.value
, 1);
10601 if (TREE_CODE (field
) != FIELD_DECL
)
10602 expr
.original_type
= NULL
;
10604 expr
.original_type
= DECL_BIT_FIELD_TYPE (field
);
10607 case CPP_PLUS_PLUS
:
10608 /* Postincrement. */
10609 start
= expr
.get_start ();
10610 finish
= c_parser_peek_token (parser
)->get_finish ();
10611 c_parser_consume_token (parser
);
10612 expr
= default_function_array_read_conversion (expr_loc
, expr
);
10613 expr
.value
= build_unary_op (op_loc
, POSTINCREMENT_EXPR
,
10614 expr
.value
, false);
10615 set_c_expr_source_range (&expr
, start
, finish
);
10616 expr
.original_code
= ERROR_MARK
;
10617 expr
.original_type
= NULL
;
10619 case CPP_MINUS_MINUS
:
10620 /* Postdecrement. */
10621 start
= expr
.get_start ();
10622 finish
= c_parser_peek_token (parser
)->get_finish ();
10623 c_parser_consume_token (parser
);
10624 expr
= default_function_array_read_conversion (expr_loc
, expr
);
10625 expr
.value
= build_unary_op (op_loc
, POSTDECREMENT_EXPR
,
10626 expr
.value
, false);
10627 set_c_expr_source_range (&expr
, start
, finish
);
10628 expr
.original_code
= ERROR_MARK
;
10629 expr
.original_type
= NULL
;
10637 /* Parse an expression (C90 6.3.17, C99 6.5.17, C11 6.5.17).
10640 assignment-expression
10641 expression , assignment-expression
10644 static struct c_expr
10645 c_parser_expression (c_parser
*parser
)
10647 location_t tloc
= c_parser_peek_token (parser
)->location
;
10648 struct c_expr expr
;
10649 expr
= c_parser_expr_no_commas (parser
, NULL
);
10650 if (c_parser_next_token_is (parser
, CPP_COMMA
))
10651 expr
= convert_lvalue_to_rvalue (tloc
, expr
, true, false);
10652 while (c_parser_next_token_is (parser
, CPP_COMMA
))
10654 struct c_expr next
;
10656 location_t loc
= c_parser_peek_token (parser
)->location
;
10657 location_t expr_loc
;
10658 c_parser_consume_token (parser
);
10659 expr_loc
= c_parser_peek_token (parser
)->location
;
10660 lhsval
= expr
.value
;
10661 while (TREE_CODE (lhsval
) == COMPOUND_EXPR
10662 || TREE_CODE (lhsval
) == NOP_EXPR
)
10664 if (TREE_CODE (lhsval
) == COMPOUND_EXPR
)
10665 lhsval
= TREE_OPERAND (lhsval
, 1);
10667 lhsval
= TREE_OPERAND (lhsval
, 0);
10669 if (DECL_P (lhsval
) || handled_component_p (lhsval
))
10670 mark_exp_read (lhsval
);
10671 next
= c_parser_expr_no_commas (parser
, NULL
);
10672 next
= convert_lvalue_to_rvalue (expr_loc
, next
, true, false);
10673 expr
.value
= build_compound_expr (loc
, expr
.value
, next
.value
);
10674 expr
.original_code
= COMPOUND_EXPR
;
10675 expr
.original_type
= next
.original_type
;
10680 /* Parse an expression and convert functions or arrays to pointers and
10681 lvalues to rvalues. */
10683 static struct c_expr
10684 c_parser_expression_conv (c_parser
*parser
)
10686 struct c_expr expr
;
10687 location_t loc
= c_parser_peek_token (parser
)->location
;
10688 expr
= c_parser_expression (parser
);
10689 expr
= convert_lvalue_to_rvalue (loc
, expr
, true, false);
10693 /* Helper function of c_parser_expr_list. Check if IDXth (0 based)
10694 argument is a literal zero alone and if so, set it in literal_zero_mask. */
10697 c_parser_check_literal_zero (c_parser
*parser
, unsigned *literal_zero_mask
,
10700 if (idx
>= HOST_BITS_PER_INT
)
10703 c_token
*tok
= c_parser_peek_token (parser
);
10712 /* If a parameter is literal zero alone, remember it
10713 for -Wmemset-transposed-args warning. */
10714 if (integer_zerop (tok
->value
)
10715 && !TREE_OVERFLOW (tok
->value
)
10716 && (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
10717 || c_parser_peek_2nd_token (parser
)->type
== CPP_CLOSE_PAREN
))
10718 *literal_zero_mask
|= 1U << idx
;
10724 /* Parse a non-empty list of expressions. If CONVERT_P, convert
10725 functions and arrays to pointers and lvalues to rvalues. If
10726 FOLD_P, fold the expressions. If LOCATIONS is non-NULL, save the
10727 locations of function arguments into this vector.
10729 nonempty-expr-list:
10730 assignment-expression
10731 nonempty-expr-list , assignment-expression
10734 static vec
<tree
, va_gc
> *
10735 c_parser_expr_list (c_parser
*parser
, bool convert_p
, bool fold_p
,
10736 vec
<tree
, va_gc
> **p_orig_types
,
10737 location_t
*sizeof_arg_loc
, tree
*sizeof_arg
,
10738 vec
<location_t
> *locations
,
10739 unsigned int *literal_zero_mask
)
10741 vec
<tree
, va_gc
> *ret
;
10742 vec
<tree
, va_gc
> *orig_types
;
10743 struct c_expr expr
;
10744 unsigned int idx
= 0;
10746 ret
= make_tree_vector ();
10747 if (p_orig_types
== NULL
)
10750 orig_types
= make_tree_vector ();
10752 if (literal_zero_mask
)
10753 c_parser_check_literal_zero (parser
, literal_zero_mask
, 0);
10754 expr
= c_parser_expr_no_commas (parser
, NULL
);
10756 expr
= convert_lvalue_to_rvalue (expr
.get_location (), expr
, true, true);
10758 expr
.value
= c_fully_fold (expr
.value
, false, NULL
);
10759 ret
->quick_push (expr
.value
);
10761 orig_types
->quick_push (expr
.original_type
);
10763 locations
->safe_push (expr
.get_location ());
10764 if (sizeof_arg
!= NULL
10765 && (expr
.original_code
== SIZEOF_EXPR
10766 || expr
.original_code
== PAREN_SIZEOF_EXPR
))
10768 sizeof_arg
[0] = c_last_sizeof_arg
;
10769 sizeof_arg_loc
[0] = c_last_sizeof_loc
;
10771 while (c_parser_next_token_is (parser
, CPP_COMMA
))
10773 c_parser_consume_token (parser
);
10774 if (literal_zero_mask
)
10775 c_parser_check_literal_zero (parser
, literal_zero_mask
, idx
+ 1);
10776 expr
= c_parser_expr_no_commas (parser
, NULL
);
10778 expr
= convert_lvalue_to_rvalue (expr
.get_location (), expr
, true,
10781 expr
.value
= c_fully_fold (expr
.value
, false, NULL
);
10782 vec_safe_push (ret
, expr
.value
);
10784 vec_safe_push (orig_types
, expr
.original_type
);
10786 locations
->safe_push (expr
.get_location ());
10788 && sizeof_arg
!= NULL
10789 && (expr
.original_code
== SIZEOF_EXPR
10790 || expr
.original_code
== PAREN_SIZEOF_EXPR
))
10792 sizeof_arg
[idx
] = c_last_sizeof_arg
;
10793 sizeof_arg_loc
[idx
] = c_last_sizeof_loc
;
10797 *p_orig_types
= orig_types
;
10801 /* Parse Objective-C-specific constructs. */
10803 /* Parse an objc-class-definition.
10805 objc-class-definition:
10806 @interface identifier objc-superclass[opt] objc-protocol-refs[opt]
10807 objc-class-instance-variables[opt] objc-methodprotolist @end
10808 @implementation identifier objc-superclass[opt]
10809 objc-class-instance-variables[opt]
10810 @interface identifier ( identifier ) objc-protocol-refs[opt]
10811 objc-methodprotolist @end
10812 @interface identifier ( ) objc-protocol-refs[opt]
10813 objc-methodprotolist @end
10814 @implementation identifier ( identifier )
10819 "@interface identifier (" must start "@interface identifier (
10820 identifier ) ...": objc-methodprotolist in the first production may
10821 not start with a parenthesized identifier as a declarator of a data
10822 definition with no declaration specifiers if the objc-superclass,
10823 objc-protocol-refs and objc-class-instance-variables are omitted. */
10826 c_parser_objc_class_definition (c_parser
*parser
, tree attributes
)
10831 if (c_parser_next_token_is_keyword (parser
, RID_AT_INTERFACE
))
10833 else if (c_parser_next_token_is_keyword (parser
, RID_AT_IMPLEMENTATION
))
10836 gcc_unreachable ();
10838 c_parser_consume_token (parser
);
10839 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
10841 c_parser_error (parser
, "expected identifier");
10844 id1
= c_parser_peek_token (parser
)->value
;
10845 location_t loc1
= c_parser_peek_token (parser
)->location
;
10846 c_parser_consume_token (parser
);
10847 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
10849 /* We have a category or class extension. */
10851 tree proto
= NULL_TREE
;
10852 matching_parens parens
;
10853 parens
.consume_open (parser
);
10854 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
10856 if (iface_p
&& c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
10858 /* We have a class extension. */
10863 c_parser_error (parser
, "expected identifier or %<)%>");
10864 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10870 id2
= c_parser_peek_token (parser
)->value
;
10871 c_parser_consume_token (parser
);
10873 parens
.skip_until_found_close (parser
);
10876 objc_start_category_implementation (id1
, id2
);
10879 if (c_parser_next_token_is (parser
, CPP_LESS
))
10880 proto
= c_parser_objc_protocol_refs (parser
);
10881 objc_start_category_interface (id1
, id2
, proto
, attributes
);
10882 c_parser_objc_methodprotolist (parser
);
10883 c_parser_require_keyword (parser
, RID_AT_END
, "expected %<@end%>");
10884 objc_finish_interface ();
10887 if (c_parser_next_token_is (parser
, CPP_COLON
))
10889 c_parser_consume_token (parser
);
10890 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
10892 c_parser_error (parser
, "expected identifier");
10895 superclass
= c_parser_peek_token (parser
)->value
;
10896 c_parser_consume_token (parser
);
10899 superclass
= NULL_TREE
;
10902 tree proto
= NULL_TREE
;
10903 if (c_parser_next_token_is (parser
, CPP_LESS
))
10904 proto
= c_parser_objc_protocol_refs (parser
);
10905 objc_start_class_interface (id1
, loc1
, superclass
, proto
, attributes
);
10908 objc_start_class_implementation (id1
, superclass
);
10909 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
10910 c_parser_objc_class_instance_variables (parser
);
10913 objc_continue_interface ();
10914 c_parser_objc_methodprotolist (parser
);
10915 c_parser_require_keyword (parser
, RID_AT_END
, "expected %<@end%>");
10916 objc_finish_interface ();
10920 objc_continue_implementation ();
10925 /* Parse objc-class-instance-variables.
10927 objc-class-instance-variables:
10928 { objc-instance-variable-decl-list[opt] }
10930 objc-instance-variable-decl-list:
10931 objc-visibility-spec
10932 objc-instance-variable-decl ;
10934 objc-instance-variable-decl-list objc-visibility-spec
10935 objc-instance-variable-decl-list objc-instance-variable-decl ;
10936 objc-instance-variable-decl-list ;
10938 objc-visibility-spec:
10943 objc-instance-variable-decl:
10948 c_parser_objc_class_instance_variables (c_parser
*parser
)
10950 gcc_assert (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
));
10951 c_parser_consume_token (parser
);
10952 while (c_parser_next_token_is_not (parser
, CPP_EOF
))
10955 /* Parse any stray semicolon. */
10956 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
10958 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
10959 "extra semicolon");
10960 c_parser_consume_token (parser
);
10963 /* Stop if at the end of the instance variables. */
10964 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
10966 c_parser_consume_token (parser
);
10969 /* Parse any objc-visibility-spec. */
10970 if (c_parser_next_token_is_keyword (parser
, RID_AT_PRIVATE
))
10972 c_parser_consume_token (parser
);
10973 objc_set_visibility (OBJC_IVAR_VIS_PRIVATE
);
10976 else if (c_parser_next_token_is_keyword (parser
, RID_AT_PROTECTED
))
10978 c_parser_consume_token (parser
);
10979 objc_set_visibility (OBJC_IVAR_VIS_PROTECTED
);
10982 else if (c_parser_next_token_is_keyword (parser
, RID_AT_PUBLIC
))
10984 c_parser_consume_token (parser
);
10985 objc_set_visibility (OBJC_IVAR_VIS_PUBLIC
);
10988 else if (c_parser_next_token_is_keyword (parser
, RID_AT_PACKAGE
))
10990 c_parser_consume_token (parser
);
10991 objc_set_visibility (OBJC_IVAR_VIS_PACKAGE
);
10994 else if (c_parser_next_token_is (parser
, CPP_PRAGMA
))
10996 c_parser_pragma (parser
, pragma_external
, NULL
);
11000 /* Parse some comma-separated declarations. */
11001 decls
= c_parser_struct_declaration (parser
);
11004 /* There is a syntax error. We want to skip the offending
11005 tokens up to the next ';' (included) or '}'
11008 /* First, skip manually a ')' or ']'. This is because they
11009 reduce the nesting level, so c_parser_skip_until_found()
11010 wouldn't be able to skip past them. */
11011 c_token
*token
= c_parser_peek_token (parser
);
11012 if (token
->type
== CPP_CLOSE_PAREN
|| token
->type
== CPP_CLOSE_SQUARE
)
11013 c_parser_consume_token (parser
);
11015 /* Then, do the standard skipping. */
11016 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
11018 /* We hopefully recovered. Start normal parsing again. */
11019 parser
->error
= false;
11024 /* Comma-separated instance variables are chained together
11025 in reverse order; add them one by one. */
11026 tree ivar
= nreverse (decls
);
11027 for (; ivar
; ivar
= DECL_CHAIN (ivar
))
11028 objc_add_instance_variable (copy_node (ivar
));
11030 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
11034 /* Parse an objc-class-declaration.
11036 objc-class-declaration:
11037 @class identifier-list ;
11041 c_parser_objc_class_declaration (c_parser
*parser
)
11043 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_CLASS
));
11044 c_parser_consume_token (parser
);
11045 /* Any identifiers, including those declared as type names, are OK
11050 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11052 c_parser_error (parser
, "expected identifier");
11053 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
11054 parser
->error
= false;
11057 id
= c_parser_peek_token (parser
)->value
;
11058 objc_declare_class (id
);
11059 c_parser_consume_token (parser
);
11060 if (c_parser_next_token_is (parser
, CPP_COMMA
))
11061 c_parser_consume_token (parser
);
11065 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
11068 /* Parse an objc-alias-declaration.
11070 objc-alias-declaration:
11071 @compatibility_alias identifier identifier ;
11075 c_parser_objc_alias_declaration (c_parser
*parser
)
11078 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_ALIAS
));
11079 c_parser_consume_token (parser
);
11080 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11082 c_parser_error (parser
, "expected identifier");
11083 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
11086 id1
= c_parser_peek_token (parser
)->value
;
11087 c_parser_consume_token (parser
);
11088 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11090 c_parser_error (parser
, "expected identifier");
11091 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
11094 id2
= c_parser_peek_token (parser
)->value
;
11095 c_parser_consume_token (parser
);
11096 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
11097 objc_declare_alias (id1
, id2
);
11100 /* Parse an objc-protocol-definition.
11102 objc-protocol-definition:
11103 @protocol identifier objc-protocol-refs[opt] objc-methodprotolist @end
11104 @protocol identifier-list ;
11106 "@protocol identifier ;" should be resolved as "@protocol
11107 identifier-list ;": objc-methodprotolist may not start with a
11108 semicolon in the first alternative if objc-protocol-refs are
11112 c_parser_objc_protocol_definition (c_parser
*parser
, tree attributes
)
11114 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_PROTOCOL
));
11116 c_parser_consume_token (parser
);
11117 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11119 c_parser_error (parser
, "expected identifier");
11122 if (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
11123 || c_parser_peek_2nd_token (parser
)->type
== CPP_SEMICOLON
)
11125 /* Any identifiers, including those declared as type names, are
11130 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11132 c_parser_error (parser
, "expected identifier");
11135 id
= c_parser_peek_token (parser
)->value
;
11136 objc_declare_protocol (id
, attributes
);
11137 c_parser_consume_token (parser
);
11138 if (c_parser_next_token_is (parser
, CPP_COMMA
))
11139 c_parser_consume_token (parser
);
11143 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
11147 tree id
= c_parser_peek_token (parser
)->value
;
11148 tree proto
= NULL_TREE
;
11149 c_parser_consume_token (parser
);
11150 if (c_parser_next_token_is (parser
, CPP_LESS
))
11151 proto
= c_parser_objc_protocol_refs (parser
);
11152 parser
->objc_pq_context
= true;
11153 objc_start_protocol (id
, proto
, attributes
);
11154 c_parser_objc_methodprotolist (parser
);
11155 c_parser_require_keyword (parser
, RID_AT_END
, "expected %<@end%>");
11156 parser
->objc_pq_context
= false;
11157 objc_finish_interface ();
11161 /* Parse an objc-method-type.
11167 Return true if it is a class method (+) and false if it is
11168 an instance method (-).
11171 c_parser_objc_method_type (c_parser
*parser
)
11173 switch (c_parser_peek_token (parser
)->type
)
11176 c_parser_consume_token (parser
);
11179 c_parser_consume_token (parser
);
11182 gcc_unreachable ();
11186 /* Parse an objc-method-definition.
11188 objc-method-definition:
11189 objc-method-type objc-method-decl ;[opt] compound-statement
11193 c_parser_objc_method_definition (c_parser
*parser
)
11195 bool is_class_method
= c_parser_objc_method_type (parser
);
11196 tree decl
, attributes
= NULL_TREE
, expr
= NULL_TREE
;
11197 parser
->objc_pq_context
= true;
11198 decl
= c_parser_objc_method_decl (parser
, is_class_method
, &attributes
,
11200 if (decl
== error_mark_node
)
11201 return; /* Bail here. */
11203 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
11205 c_parser_consume_token (parser
);
11206 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
11207 "extra semicolon in method definition specified");
11210 if (!c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
11212 c_parser_error (parser
, "expected %<{%>");
11216 parser
->objc_pq_context
= false;
11217 if (objc_start_method_definition (is_class_method
, decl
, attributes
, expr
))
11219 add_stmt (c_parser_compound_statement (parser
));
11220 objc_finish_method_definition (current_function_decl
);
11224 /* This code is executed when we find a method definition
11225 outside of an @implementation context (or invalid for other
11226 reasons). Parse the method (to keep going) but do not emit
11229 c_parser_compound_statement (parser
);
11233 /* Parse an objc-methodprotolist.
11235 objc-methodprotolist:
11237 objc-methodprotolist objc-methodproto
11238 objc-methodprotolist declaration
11239 objc-methodprotolist ;
11243 The declaration is a data definition, which may be missing
11244 declaration specifiers under the same rules and diagnostics as
11245 other data definitions outside functions, and the stray semicolon
11246 is diagnosed the same way as a stray semicolon outside a
11250 c_parser_objc_methodprotolist (c_parser
*parser
)
11254 /* The list is terminated by @end. */
11255 switch (c_parser_peek_token (parser
)->type
)
11257 case CPP_SEMICOLON
:
11258 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
11259 "ISO C does not allow extra %<;%> outside of a function");
11260 c_parser_consume_token (parser
);
11264 c_parser_objc_methodproto (parser
);
11267 c_parser_pragma (parser
, pragma_external
, NULL
);
11272 if (c_parser_next_token_is_keyword (parser
, RID_AT_END
))
11274 else if (c_parser_next_token_is_keyword (parser
, RID_AT_PROPERTY
))
11275 c_parser_objc_at_property_declaration (parser
);
11276 else if (c_parser_next_token_is_keyword (parser
, RID_AT_OPTIONAL
))
11278 objc_set_method_opt (true);
11279 c_parser_consume_token (parser
);
11281 else if (c_parser_next_token_is_keyword (parser
, RID_AT_REQUIRED
))
11283 objc_set_method_opt (false);
11284 c_parser_consume_token (parser
);
11287 c_parser_declaration_or_fndef (parser
, false, false, true,
11294 /* Parse an objc-methodproto.
11297 objc-method-type objc-method-decl ;
11301 c_parser_objc_methodproto (c_parser
*parser
)
11303 bool is_class_method
= c_parser_objc_method_type (parser
);
11304 tree decl
, attributes
= NULL_TREE
;
11306 /* Remember protocol qualifiers in prototypes. */
11307 parser
->objc_pq_context
= true;
11308 decl
= c_parser_objc_method_decl (parser
, is_class_method
, &attributes
,
11310 /* Forget protocol qualifiers now. */
11311 parser
->objc_pq_context
= false;
11313 /* Do not allow the presence of attributes to hide an erroneous
11314 method implementation in the interface section. */
11315 if (!c_parser_next_token_is (parser
, CPP_SEMICOLON
))
11317 c_parser_error (parser
, "expected %<;%>");
11321 if (decl
!= error_mark_node
)
11322 objc_add_method_declaration (is_class_method
, decl
, attributes
);
11324 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
11327 /* If we are at a position that method attributes may be present, check that
11328 there are not any parsed already (a syntax error) and then collect any
11329 specified at the current location. Finally, if new attributes were present,
11330 check that the next token is legal ( ';' for decls and '{' for defs). */
11333 c_parser_objc_maybe_method_attributes (c_parser
* parser
, tree
* attributes
)
11338 c_parser_error (parser
,
11339 "method attributes must be specified at the end only");
11340 *attributes
= NULL_TREE
;
11344 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
11345 *attributes
= c_parser_gnu_attributes (parser
);
11347 /* If there were no attributes here, just report any earlier error. */
11348 if (*attributes
== NULL_TREE
|| bad
)
11351 /* If the attributes are followed by a ; or {, then just report any earlier
11353 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
)
11354 || c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
11357 /* We've got attributes, but not at the end. */
11358 c_parser_error (parser
,
11359 "expected %<;%> or %<{%> after method attribute definition");
11363 /* Parse an objc-method-decl.
11366 ( objc-type-name ) objc-selector
11368 ( objc-type-name ) objc-keyword-selector objc-optparmlist
11369 objc-keyword-selector objc-optparmlist
11372 objc-keyword-selector:
11374 objc-keyword-selector objc-keyword-decl
11377 objc-selector : ( objc-type-name ) identifier
11378 objc-selector : identifier
11379 : ( objc-type-name ) identifier
11383 objc-optparms objc-optellipsis
11387 objc-opt-parms , parameter-declaration
11395 c_parser_objc_method_decl (c_parser
*parser
, bool is_class_method
,
11396 tree
*attributes
, tree
*expr
)
11398 tree type
= NULL_TREE
;
11400 tree parms
= NULL_TREE
;
11401 bool ellipsis
= false;
11402 bool attr_err
= false;
11404 *attributes
= NULL_TREE
;
11405 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
11407 matching_parens parens
;
11408 parens
.consume_open (parser
);
11409 type
= c_parser_objc_type_name (parser
);
11410 parens
.skip_until_found_close (parser
);
11412 sel
= c_parser_objc_selector (parser
);
11413 /* If there is no selector, or a colon follows, we have an
11414 objc-keyword-selector. If there is a selector, and a colon does
11415 not follow, that selector ends the objc-method-decl. */
11416 if (!sel
|| c_parser_next_token_is (parser
, CPP_COLON
))
11419 tree list
= NULL_TREE
;
11422 tree atype
= NULL_TREE
, id
, keyworddecl
;
11423 tree param_attr
= NULL_TREE
;
11424 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
11426 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
11428 c_parser_consume_token (parser
);
11429 atype
= c_parser_objc_type_name (parser
);
11430 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
11433 /* New ObjC allows attributes on method parameters. */
11434 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
11435 param_attr
= c_parser_gnu_attributes (parser
);
11436 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11438 c_parser_error (parser
, "expected identifier");
11439 return error_mark_node
;
11441 id
= c_parser_peek_token (parser
)->value
;
11442 c_parser_consume_token (parser
);
11443 keyworddecl
= objc_build_keyword_decl (tsel
, atype
, id
, param_attr
);
11444 list
= chainon (list
, keyworddecl
);
11445 tsel
= c_parser_objc_selector (parser
);
11446 if (!tsel
&& c_parser_next_token_is_not (parser
, CPP_COLON
))
11450 attr_err
|= c_parser_objc_maybe_method_attributes (parser
, attributes
) ;
11452 /* Parse the optional parameter list. Optional Objective-C
11453 method parameters follow the C syntax, and may include '...'
11454 to denote a variable number of arguments. */
11455 parms
= make_node (TREE_LIST
);
11456 while (c_parser_next_token_is (parser
, CPP_COMMA
))
11458 struct c_parm
*parm
;
11459 c_parser_consume_token (parser
);
11460 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
11463 c_parser_consume_token (parser
);
11464 attr_err
|= c_parser_objc_maybe_method_attributes
11465 (parser
, attributes
) ;
11468 parm
= c_parser_parameter_declaration (parser
, NULL_TREE
, false);
11471 parms
= chainon (parms
,
11472 build_tree_list (NULL_TREE
, grokparm (parm
, expr
)));
11477 attr_err
|= c_parser_objc_maybe_method_attributes (parser
, attributes
) ;
11481 c_parser_error (parser
, "objective-c method declaration is expected");
11482 return error_mark_node
;
11486 return error_mark_node
;
11488 return objc_build_method_signature (is_class_method
, type
, sel
, parms
, ellipsis
);
11491 /* Parse an objc-type-name.
11494 objc-type-qualifiers[opt] type-name
11495 objc-type-qualifiers[opt]
11497 objc-type-qualifiers:
11498 objc-type-qualifier
11499 objc-type-qualifiers objc-type-qualifier
11501 objc-type-qualifier: one of
11502 in out inout bycopy byref oneway
11506 c_parser_objc_type_name (c_parser
*parser
)
11508 tree quals
= NULL_TREE
;
11509 struct c_type_name
*type_name
= NULL
;
11510 tree type
= NULL_TREE
;
11513 c_token
*token
= c_parser_peek_token (parser
);
11514 if (token
->type
== CPP_KEYWORD
11515 && (token
->keyword
== RID_IN
11516 || token
->keyword
== RID_OUT
11517 || token
->keyword
== RID_INOUT
11518 || token
->keyword
== RID_BYCOPY
11519 || token
->keyword
== RID_BYREF
11520 || token
->keyword
== RID_ONEWAY
))
11522 quals
= chainon (build_tree_list (NULL_TREE
, token
->value
), quals
);
11523 c_parser_consume_token (parser
);
11528 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_type
))
11529 type_name
= c_parser_type_name (parser
);
11531 type
= groktypename (type_name
, NULL
, NULL
);
11533 /* If the type is unknown, and error has already been produced and
11534 we need to recover from the error. In that case, use NULL_TREE
11535 for the type, as if no type had been specified; this will use the
11536 default type ('id') which is good for error recovery. */
11537 if (type
== error_mark_node
)
11540 return build_tree_list (quals
, type
);
11543 /* Parse objc-protocol-refs.
11545 objc-protocol-refs:
11546 < identifier-list >
11550 c_parser_objc_protocol_refs (c_parser
*parser
)
11552 tree list
= NULL_TREE
;
11553 gcc_assert (c_parser_next_token_is (parser
, CPP_LESS
));
11554 c_parser_consume_token (parser
);
11555 /* Any identifiers, including those declared as type names, are OK
11560 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11562 c_parser_error (parser
, "expected identifier");
11565 id
= c_parser_peek_token (parser
)->value
;
11566 list
= chainon (list
, build_tree_list (NULL_TREE
, id
));
11567 c_parser_consume_token (parser
);
11568 if (c_parser_next_token_is (parser
, CPP_COMMA
))
11569 c_parser_consume_token (parser
);
11573 c_parser_require (parser
, CPP_GREATER
, "expected %<>%>");
11577 /* Parse an objc-try-catch-finally-statement.
11579 objc-try-catch-finally-statement:
11580 @try compound-statement objc-catch-list[opt]
11581 @try compound-statement objc-catch-list[opt] @finally compound-statement
11584 @catch ( objc-catch-parameter-declaration ) compound-statement
11585 objc-catch-list @catch ( objc-catch-parameter-declaration ) compound-statement
11587 objc-catch-parameter-declaration:
11588 parameter-declaration
11591 where '...' is to be interpreted literally, that is, it means CPP_ELLIPSIS.
11593 PS: This function is identical to cp_parser_objc_try_catch_finally_statement
11594 for C++. Keep them in sync. */
11597 c_parser_objc_try_catch_finally_statement (c_parser
*parser
)
11599 location_t location
;
11602 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_TRY
));
11603 c_parser_consume_token (parser
);
11604 location
= c_parser_peek_token (parser
)->location
;
11605 objc_maybe_warn_exceptions (location
);
11606 stmt
= c_parser_compound_statement (parser
);
11607 objc_begin_try_stmt (location
, stmt
);
11609 while (c_parser_next_token_is_keyword (parser
, RID_AT_CATCH
))
11611 struct c_parm
*parm
;
11612 tree parameter_declaration
= error_mark_node
;
11613 bool seen_open_paren
= false;
11615 c_parser_consume_token (parser
);
11616 matching_parens parens
;
11617 if (!parens
.require_open (parser
))
11618 seen_open_paren
= true;
11619 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
11621 /* We have "@catch (...)" (where the '...' are literally
11622 what is in the code). Skip the '...'.
11623 parameter_declaration is set to NULL_TREE, and
11624 objc_being_catch_clauses() knows that that means
11626 c_parser_consume_token (parser
);
11627 parameter_declaration
= NULL_TREE
;
11631 /* We have "@catch (NSException *exception)" or something
11632 like that. Parse the parameter declaration. */
11633 parm
= c_parser_parameter_declaration (parser
, NULL_TREE
, false);
11635 parameter_declaration
= error_mark_node
;
11637 parameter_declaration
= grokparm (parm
, NULL
);
11639 if (seen_open_paren
)
11640 parens
.require_close (parser
);
11643 /* If there was no open parenthesis, we are recovering from
11644 an error, and we are trying to figure out what mistake
11645 the user has made. */
11647 /* If there is an immediate closing parenthesis, the user
11648 probably forgot the opening one (ie, they typed "@catch
11649 NSException *e)". Parse the closing parenthesis and keep
11651 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
11652 c_parser_consume_token (parser
);
11654 /* If these is no immediate closing parenthesis, the user
11655 probably doesn't know that parenthesis are required at
11656 all (ie, they typed "@catch NSException *e"). So, just
11657 forget about the closing parenthesis and keep going. */
11659 objc_begin_catch_clause (parameter_declaration
);
11660 if (c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
11661 c_parser_compound_statement_nostart (parser
);
11662 objc_finish_catch_clause ();
11664 if (c_parser_next_token_is_keyword (parser
, RID_AT_FINALLY
))
11666 c_parser_consume_token (parser
);
11667 location
= c_parser_peek_token (parser
)->location
;
11668 stmt
= c_parser_compound_statement (parser
);
11669 objc_build_finally_clause (location
, stmt
);
11671 objc_finish_try_stmt ();
11674 /* Parse an objc-synchronized-statement.
11676 objc-synchronized-statement:
11677 @synchronized ( expression ) compound-statement
11681 c_parser_objc_synchronized_statement (c_parser
*parser
)
11685 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_SYNCHRONIZED
));
11686 c_parser_consume_token (parser
);
11687 loc
= c_parser_peek_token (parser
)->location
;
11688 objc_maybe_warn_exceptions (loc
);
11689 matching_parens parens
;
11690 if (parens
.require_open (parser
))
11692 struct c_expr ce
= c_parser_expression (parser
);
11693 ce
= convert_lvalue_to_rvalue (loc
, ce
, false, false);
11695 expr
= c_fully_fold (expr
, false, NULL
);
11696 parens
.skip_until_found_close (parser
);
11699 expr
= error_mark_node
;
11700 stmt
= c_parser_compound_statement (parser
);
11701 objc_build_synchronized (loc
, expr
, stmt
);
11704 /* Parse an objc-selector; return NULL_TREE without an error if the
11705 next token is not an objc-selector.
11710 enum struct union if else while do for switch case default
11711 break continue return goto asm sizeof typeof __alignof
11712 unsigned long const short volatile signed restrict _Complex
11713 in out inout bycopy byref oneway int char float double void _Bool
11716 ??? Why this selection of keywords but not, for example, storage
11717 class specifiers? */
11720 c_parser_objc_selector (c_parser
*parser
)
11722 c_token
*token
= c_parser_peek_token (parser
);
11723 tree value
= token
->value
;
11724 if (token
->type
== CPP_NAME
)
11726 c_parser_consume_token (parser
);
11729 if (token
->type
!= CPP_KEYWORD
)
11731 switch (token
->keyword
)
11770 CASE_RID_FLOATN_NX
:
11774 case RID_AUTO_TYPE
:
11779 c_parser_consume_token (parser
);
11786 /* Parse an objc-selector-arg.
11790 objc-keywordname-list
11792 objc-keywordname-list:
11794 objc-keywordname-list objc-keywordname
11802 c_parser_objc_selector_arg (c_parser
*parser
)
11804 tree sel
= c_parser_objc_selector (parser
);
11805 tree list
= NULL_TREE
;
11807 && c_parser_next_token_is_not (parser
, CPP_COLON
)
11808 && c_parser_next_token_is_not (parser
, CPP_SCOPE
))
11812 if (c_parser_next_token_is (parser
, CPP_SCOPE
))
11814 c_parser_consume_token (parser
);
11815 list
= chainon (list
, build_tree_list (sel
, NULL_TREE
));
11816 list
= chainon (list
, build_tree_list (NULL_TREE
, NULL_TREE
));
11820 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
11822 list
= chainon (list
, build_tree_list (sel
, NULL_TREE
));
11824 sel
= c_parser_objc_selector (parser
);
11826 && c_parser_next_token_is_not (parser
, CPP_COLON
)
11827 && c_parser_next_token_is_not (parser
, CPP_SCOPE
))
11833 /* Parse an objc-receiver.
11842 c_parser_objc_receiver (c_parser
*parser
)
11844 location_t loc
= c_parser_peek_token (parser
)->location
;
11846 if (c_parser_peek_token (parser
)->type
== CPP_NAME
11847 && (c_parser_peek_token (parser
)->id_kind
== C_ID_TYPENAME
11848 || c_parser_peek_token (parser
)->id_kind
== C_ID_CLASSNAME
))
11850 tree id
= c_parser_peek_token (parser
)->value
;
11851 c_parser_consume_token (parser
);
11852 return objc_get_class_reference (id
);
11854 struct c_expr ce
= c_parser_expression (parser
);
11855 ce
= convert_lvalue_to_rvalue (loc
, ce
, false, false);
11856 return c_fully_fold (ce
.value
, false, NULL
);
11859 /* Parse objc-message-args.
11863 objc-keywordarg-list
11865 objc-keywordarg-list:
11867 objc-keywordarg-list objc-keywordarg
11870 objc-selector : objc-keywordexpr
11875 c_parser_objc_message_args (c_parser
*parser
)
11877 tree sel
= c_parser_objc_selector (parser
);
11878 tree list
= NULL_TREE
;
11879 if (sel
&& c_parser_next_token_is_not (parser
, CPP_COLON
))
11884 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
11885 return error_mark_node
;
11886 keywordexpr
= c_parser_objc_keywordexpr (parser
);
11887 list
= chainon (list
, build_tree_list (sel
, keywordexpr
));
11888 sel
= c_parser_objc_selector (parser
);
11889 if (!sel
&& c_parser_next_token_is_not (parser
, CPP_COLON
))
11895 /* Parse an objc-keywordexpr.
11902 c_parser_objc_keywordexpr (c_parser
*parser
)
11905 vec
<tree
, va_gc
> *expr_list
= c_parser_expr_list (parser
, true, true,
11906 NULL
, NULL
, NULL
, NULL
);
11907 if (vec_safe_length (expr_list
) == 1)
11909 /* Just return the expression, remove a level of
11911 ret
= (*expr_list
)[0];
11915 /* We have a comma expression, we will collapse later. */
11916 ret
= build_tree_list_vec (expr_list
);
11918 release_tree_vector (expr_list
);
11922 /* A check, needed in several places, that ObjC interface, implementation or
11923 method definitions are not prefixed by incorrect items. */
11925 c_parser_objc_diagnose_bad_element_prefix (c_parser
*parser
,
11926 struct c_declspecs
*specs
)
11928 if (!specs
->declspecs_seen_p
|| specs
->non_sc_seen_p
11929 || specs
->typespec_kind
!= ctsk_none
)
11931 c_parser_error (parser
,
11932 "no type or storage class may be specified here,");
11933 c_parser_skip_to_end_of_block_or_statement (parser
);
11939 /* Parse an Objective-C @property declaration. The syntax is:
11941 objc-property-declaration:
11942 '@property' objc-property-attributes[opt] struct-declaration ;
11944 objc-property-attributes:
11945 '(' objc-property-attribute-list ')'
11947 objc-property-attribute-list:
11948 objc-property-attribute
11949 objc-property-attribute-list, objc-property-attribute
11951 objc-property-attribute
11952 'getter' = identifier
11953 'setter' = identifier
11962 @property NSString *name;
11963 @property (readonly) id object;
11964 @property (retain, nonatomic, getter=getTheName) id name;
11965 @property int a, b, c;
11967 PS: This function is identical to cp_parser_objc_at_propery_declaration
11968 for C++. Keep them in sync. */
11970 c_parser_objc_at_property_declaration (c_parser
*parser
)
11972 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_PROPERTY
));
11973 location_t loc
= c_parser_peek_token (parser
)->location
;
11974 c_parser_consume_token (parser
); /* Eat '@property'. */
11976 /* Parse the optional attribute list.
11978 A list of parsed, but not verified, attributes. */
11979 vec
<property_attribute_info
*> prop_attr_list
= vNULL
;
11981 bool syntax_error
= false;
11982 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
11984 matching_parens parens
;
11986 location_t attr_start
= c_parser_peek_token (parser
)->location
;
11988 parens
.consume_open (parser
);
11990 /* Property attribute keywords are valid now. */
11991 parser
->objc_property_attr_context
= true;
11993 /* Allow @property (), with a warning. */
11994 location_t attr_end
= c_parser_peek_token (parser
)->location
;
11996 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
11998 location_t attr_comb
= make_location (attr_end
, attr_start
, attr_end
);
11999 warning_at (attr_comb
, OPT_Wattributes
,
12000 "empty property attribute list");
12005 c_token
*token
= c_parser_peek_token (parser
);
12006 attr_start
= token
->location
;
12007 attr_end
= get_finish (token
->location
);
12008 location_t attr_comb
= make_location (attr_start
, attr_start
,
12011 if (token
->type
== CPP_CLOSE_PAREN
|| token
->type
== CPP_COMMA
)
12013 warning_at (attr_comb
, OPT_Wattributes
,
12014 "missing property attribute");
12015 if (token
->type
== CPP_CLOSE_PAREN
)
12017 c_parser_consume_token (parser
);
12021 tree attr_name
= NULL_TREE
;
12022 enum rid keyword
= RID_MAX
; /* Not a valid property attribute. */
12023 bool add_at
= false;
12024 if (token
->type
== CPP_KEYWORD
)
12026 keyword
= token
->keyword
;
12027 if (OBJC_IS_AT_KEYWORD (keyword
))
12029 /* For '@' keywords the token value has the keyword,
12030 prepend the '@' for diagnostics. */
12031 attr_name
= token
->value
;
12035 attr_name
= ridpointers
[(int)keyword
];
12037 else if (token
->type
== CPP_NAME
)
12038 attr_name
= token
->value
;
12039 c_parser_consume_token (parser
);
12041 enum objc_property_attribute_kind prop_kind
12042 = objc_prop_attr_kind_for_rid (keyword
);
12043 property_attribute_info
*prop
12044 = new property_attribute_info (attr_name
, attr_comb
, prop_kind
);
12045 prop_attr_list
.safe_push (prop
);
12048 switch (prop
->prop_kind
)
12051 case OBJC_PROPERTY_ATTR_UNKNOWN
:
12053 error_at (attr_comb
, "unknown property attribute %<%s%s%>",
12054 add_at
? "@" : "", IDENTIFIER_POINTER (attr_name
));
12056 error_at (attr_comb
, "unknown property attribute");
12057 prop
->parse_error
= syntax_error
= true;
12060 case OBJC_PROPERTY_ATTR_GETTER
:
12061 case OBJC_PROPERTY_ATTR_SETTER
:
12062 if (c_parser_next_token_is_not (parser
, CPP_EQ
))
12064 attr_comb
= make_location (attr_end
, attr_start
, attr_end
);
12065 error_at (attr_comb
, "expected %<=%> after Objective-C %qE",
12067 prop
->parse_error
= syntax_error
= true;
12070 token
= c_parser_peek_token (parser
);
12071 attr_end
= token
->location
;
12072 c_parser_consume_token (parser
); /* eat the = */
12073 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
12075 attr_comb
= make_location (attr_end
, attr_start
, attr_end
);
12076 error_at (attr_comb
, "expected %qE selector name",
12078 prop
->parse_error
= syntax_error
= true;
12081 /* Get the end of the method name, and consume the name. */
12082 token
= c_parser_peek_token (parser
);
12083 attr_end
= get_finish (token
->location
);
12084 meth_name
= token
->value
;
12085 c_parser_consume_token (parser
);
12086 if (prop
->prop_kind
== OBJC_PROPERTY_ATTR_SETTER
)
12088 if (c_parser_next_token_is_not (parser
, CPP_COLON
))
12090 attr_comb
= make_location (attr_end
, attr_start
,
12092 error_at (attr_comb
, "setter method names must"
12093 " terminate with %<:%>");
12094 prop
->parse_error
= syntax_error
= true;
12098 attr_end
= get_finish (c_parser_peek_token
12099 (parser
)->location
);
12100 c_parser_consume_token (parser
);
12102 attr_comb
= make_location (attr_start
, attr_start
,
12106 attr_comb
= make_location (attr_start
, attr_start
,
12108 prop
->ident
= meth_name
;
12109 /* Updated location including all that was successfully
12111 prop
->prop_loc
= attr_comb
;
12115 /* If we see a comma here, then keep going - even if we already
12116 saw a syntax error. For simple mistakes e.g. (asign, getter=x)
12117 this makes a more useful output and avoid spurious warnings about
12118 missing attributes that are, in fact, specified after the one with
12119 the syntax error. */
12120 if (c_parser_next_token_is (parser
, CPP_COMMA
))
12121 c_parser_consume_token (parser
);
12125 parser
->objc_property_attr_context
= false;
12127 if (syntax_error
&& c_parser_next_token_is_not (parser
, CPP_CLOSE_PAREN
))
12128 /* We don't really want to chew the whole of the file looking for a
12129 matching closing parenthesis, so we will try to read the decl and
12130 let the error handling for that close out the statement. */
12133 syntax_error
= false, parens
.skip_until_found_close (parser
);
12136 /* 'properties' is the list of properties that we read. Usually a
12137 single one, but maybe more (eg, in "@property int a, b, c;" there
12139 tree properties
= c_parser_struct_declaration (parser
);
12141 if (properties
== error_mark_node
)
12142 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
12145 if (properties
== NULL_TREE
)
12146 c_parser_error (parser
, "expected identifier");
12149 /* Comma-separated properties are chained together in reverse order;
12150 add them one by one. */
12151 properties
= nreverse (properties
);
12152 for (; properties
; properties
= TREE_CHAIN (properties
))
12153 objc_add_property_declaration (loc
, copy_node (properties
),
12156 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
12159 while (!prop_attr_list
.is_empty())
12160 delete prop_attr_list
.pop ();
12161 prop_attr_list
.release ();
12162 parser
->error
= false;
12165 /* Parse an Objective-C @synthesize declaration. The syntax is:
12167 objc-synthesize-declaration:
12168 @synthesize objc-synthesize-identifier-list ;
12170 objc-synthesize-identifier-list:
12171 objc-synthesize-identifier
12172 objc-synthesize-identifier-list, objc-synthesize-identifier
12174 objc-synthesize-identifier
12176 identifier = identifier
12179 @synthesize MyProperty;
12180 @synthesize OneProperty, AnotherProperty=MyIvar, YetAnotherProperty;
12182 PS: This function is identical to cp_parser_objc_at_synthesize_declaration
12183 for C++. Keep them in sync.
12186 c_parser_objc_at_synthesize_declaration (c_parser
*parser
)
12188 tree list
= NULL_TREE
;
12190 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_SYNTHESIZE
));
12191 loc
= c_parser_peek_token (parser
)->location
;
12193 c_parser_consume_token (parser
);
12196 tree property
, ivar
;
12197 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
12199 c_parser_error (parser
, "expected identifier");
12200 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
12201 /* Once we find the semicolon, we can resume normal parsing.
12202 We have to reset parser->error manually because
12203 c_parser_skip_until_found() won't reset it for us if the
12204 next token is precisely a semicolon. */
12205 parser
->error
= false;
12208 property
= c_parser_peek_token (parser
)->value
;
12209 c_parser_consume_token (parser
);
12210 if (c_parser_next_token_is (parser
, CPP_EQ
))
12212 c_parser_consume_token (parser
);
12213 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
12215 c_parser_error (parser
, "expected identifier");
12216 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
12217 parser
->error
= false;
12220 ivar
= c_parser_peek_token (parser
)->value
;
12221 c_parser_consume_token (parser
);
12225 list
= chainon (list
, build_tree_list (ivar
, property
));
12226 if (c_parser_next_token_is (parser
, CPP_COMMA
))
12227 c_parser_consume_token (parser
);
12231 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
12232 objc_add_synthesize_declaration (loc
, list
);
12235 /* Parse an Objective-C @dynamic declaration. The syntax is:
12237 objc-dynamic-declaration:
12238 @dynamic identifier-list ;
12241 @dynamic MyProperty;
12242 @dynamic MyProperty, AnotherProperty;
12244 PS: This function is identical to cp_parser_objc_at_dynamic_declaration
12245 for C++. Keep them in sync.
12248 c_parser_objc_at_dynamic_declaration (c_parser
*parser
)
12250 tree list
= NULL_TREE
;
12252 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_DYNAMIC
));
12253 loc
= c_parser_peek_token (parser
)->location
;
12255 c_parser_consume_token (parser
);
12259 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
12261 c_parser_error (parser
, "expected identifier");
12262 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
12263 parser
->error
= false;
12266 property
= c_parser_peek_token (parser
)->value
;
12267 list
= chainon (list
, build_tree_list (NULL_TREE
, property
));
12268 c_parser_consume_token (parser
);
12269 if (c_parser_next_token_is (parser
, CPP_COMMA
))
12270 c_parser_consume_token (parser
);
12274 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
12275 objc_add_dynamic_declaration (loc
, list
);
12279 /* Parse a pragma GCC ivdep. */
12282 c_parse_pragma_ivdep (c_parser
*parser
)
12284 c_parser_consume_pragma (parser
);
12285 c_parser_skip_to_pragma_eol (parser
);
12289 /* Parse a pragma GCC unroll. */
12291 static unsigned short
12292 c_parser_pragma_unroll (c_parser
*parser
)
12294 unsigned short unroll
;
12295 c_parser_consume_pragma (parser
);
12296 location_t location
= c_parser_peek_token (parser
)->location
;
12297 tree expr
= c_parser_expr_no_commas (parser
, NULL
).value
;
12298 mark_exp_read (expr
);
12299 expr
= c_fully_fold (expr
, false, NULL
);
12300 HOST_WIDE_INT lunroll
= 0;
12301 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr
))
12302 || TREE_CODE (expr
) != INTEGER_CST
12303 || (lunroll
= tree_to_shwi (expr
)) < 0
12304 || lunroll
>= USHRT_MAX
)
12306 error_at (location
, "%<#pragma GCC unroll%> requires an"
12307 " assignment-expression that evaluates to a non-negative"
12308 " integral constant less than %u", USHRT_MAX
);
12313 unroll
= (unsigned short)lunroll
;
12318 c_parser_skip_to_pragma_eol (parser
);
12322 /* Handle pragmas. Some OpenMP pragmas are associated with, and therefore
12323 should be considered, statements. ALLOW_STMT is true if we're within
12324 the context of a function and such pragmas are to be allowed. Returns
12325 true if we actually parsed such a pragma. */
12328 c_parser_pragma (c_parser
*parser
, enum pragma_context context
, bool *if_p
)
12331 const char *construct
= NULL
;
12333 id
= c_parser_peek_token (parser
)->pragma_kind
;
12334 gcc_assert (id
!= PRAGMA_NONE
);
12338 case PRAGMA_OACC_DECLARE
:
12339 c_parser_oacc_declare (parser
);
12342 case PRAGMA_OACC_ENTER_DATA
:
12343 if (context
!= pragma_compound
)
12345 construct
= "acc enter data";
12347 if (context
== pragma_stmt
)
12349 error_at (c_parser_peek_token (parser
)->location
,
12350 "%<#pragma %s%> may only be used in compound "
12351 "statements", construct
);
12352 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
12357 c_parser_oacc_enter_exit_data (parser
, true);
12360 case PRAGMA_OACC_EXIT_DATA
:
12361 if (context
!= pragma_compound
)
12363 construct
= "acc exit data";
12366 c_parser_oacc_enter_exit_data (parser
, false);
12369 case PRAGMA_OACC_ROUTINE
:
12370 if (context
!= pragma_external
)
12372 error_at (c_parser_peek_token (parser
)->location
,
12373 "%<#pragma acc routine%> must be at file scope");
12374 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
12377 c_parser_oacc_routine (parser
, context
);
12380 case PRAGMA_OACC_UPDATE
:
12381 if (context
!= pragma_compound
)
12383 construct
= "acc update";
12386 c_parser_oacc_update (parser
);
12389 case PRAGMA_OMP_BARRIER
:
12390 if (context
!= pragma_compound
)
12392 construct
= "omp barrier";
12395 c_parser_omp_barrier (parser
);
12398 case PRAGMA_OMP_DEPOBJ
:
12399 if (context
!= pragma_compound
)
12401 construct
= "omp depobj";
12404 c_parser_omp_depobj (parser
);
12407 case PRAGMA_OMP_FLUSH
:
12408 if (context
!= pragma_compound
)
12410 construct
= "omp flush";
12413 c_parser_omp_flush (parser
);
12416 case PRAGMA_OMP_TASKWAIT
:
12417 if (context
!= pragma_compound
)
12419 construct
= "omp taskwait";
12422 c_parser_omp_taskwait (parser
);
12425 case PRAGMA_OMP_TASKYIELD
:
12426 if (context
!= pragma_compound
)
12428 construct
= "omp taskyield";
12431 c_parser_omp_taskyield (parser
);
12434 case PRAGMA_OMP_CANCEL
:
12435 if (context
!= pragma_compound
)
12437 construct
= "omp cancel";
12440 c_parser_omp_cancel (parser
);
12443 case PRAGMA_OMP_CANCELLATION_POINT
:
12444 return c_parser_omp_cancellation_point (parser
, context
);
12446 case PRAGMA_OMP_THREADPRIVATE
:
12447 c_parser_omp_threadprivate (parser
);
12450 case PRAGMA_OMP_TARGET
:
12451 return c_parser_omp_target (parser
, context
, if_p
);
12453 case PRAGMA_OMP_END_DECLARE_TARGET
:
12454 c_parser_omp_end_declare_target (parser
);
12457 case PRAGMA_OMP_SCAN
:
12458 error_at (c_parser_peek_token (parser
)->location
,
12459 "%<#pragma omp scan%> may only be used in "
12460 "a loop construct with %<inscan%> %<reduction%> clause");
12461 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
12464 case PRAGMA_OMP_SECTION
:
12465 error_at (c_parser_peek_token (parser
)->location
,
12466 "%<#pragma omp section%> may only be used in "
12467 "%<#pragma omp sections%> construct");
12468 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
12471 case PRAGMA_OMP_DECLARE
:
12472 return c_parser_omp_declare (parser
, context
);
12474 case PRAGMA_OMP_REQUIRES
:
12475 if (context
!= pragma_external
)
12477 error_at (c_parser_peek_token (parser
)->location
,
12478 "%<#pragma omp requires%> may only be used at file scope");
12479 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
12482 c_parser_omp_requires (parser
);
12485 case PRAGMA_OMP_NOTHING
:
12486 c_parser_omp_nothing (parser
);
12489 case PRAGMA_OMP_ERROR
:
12490 return c_parser_omp_error (parser
, context
);
12492 case PRAGMA_OMP_ORDERED
:
12493 return c_parser_omp_ordered (parser
, context
, if_p
);
12497 const bool ivdep
= c_parse_pragma_ivdep (parser
);
12498 unsigned short unroll
;
12499 if (c_parser_peek_token (parser
)->pragma_kind
== PRAGMA_UNROLL
)
12500 unroll
= c_parser_pragma_unroll (parser
);
12503 if (!c_parser_next_token_is_keyword (parser
, RID_FOR
)
12504 && !c_parser_next_token_is_keyword (parser
, RID_WHILE
)
12505 && !c_parser_next_token_is_keyword (parser
, RID_DO
))
12507 c_parser_error (parser
, "for, while or do statement expected");
12510 if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
12511 c_parser_for_statement (parser
, ivdep
, unroll
, if_p
);
12512 else if (c_parser_next_token_is_keyword (parser
, RID_WHILE
))
12513 c_parser_while_statement (parser
, ivdep
, unroll
, if_p
);
12515 c_parser_do_statement (parser
, ivdep
, unroll
);
12519 case PRAGMA_UNROLL
:
12521 unsigned short unroll
= c_parser_pragma_unroll (parser
);
12523 if (c_parser_peek_token (parser
)->pragma_kind
== PRAGMA_IVDEP
)
12524 ivdep
= c_parse_pragma_ivdep (parser
);
12527 if (!c_parser_next_token_is_keyword (parser
, RID_FOR
)
12528 && !c_parser_next_token_is_keyword (parser
, RID_WHILE
)
12529 && !c_parser_next_token_is_keyword (parser
, RID_DO
))
12531 c_parser_error (parser
, "for, while or do statement expected");
12534 if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
12535 c_parser_for_statement (parser
, ivdep
, unroll
, if_p
);
12536 else if (c_parser_next_token_is_keyword (parser
, RID_WHILE
))
12537 c_parser_while_statement (parser
, ivdep
, unroll
, if_p
);
12539 c_parser_do_statement (parser
, ivdep
, unroll
);
12543 case PRAGMA_GCC_PCH_PREPROCESS
:
12544 c_parser_error (parser
, "%<#pragma GCC pch_preprocess%> must be first");
12545 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
12548 case PRAGMA_OACC_WAIT
:
12549 if (context
!= pragma_compound
)
12551 construct
= "acc wait";
12554 /* FALL THROUGH. */
12557 if (id
< PRAGMA_FIRST_EXTERNAL
)
12559 if (context
!= pragma_stmt
&& context
!= pragma_compound
)
12562 c_parser_error (parser
, "expected declaration specifiers");
12563 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
12566 c_parser_omp_construct (parser
, if_p
);
12572 c_parser_consume_pragma (parser
);
12573 c_invoke_pragma_handler (id
);
12575 /* Skip to EOL, but suppress any error message. Those will have been
12576 generated by the handler routine through calling error, as opposed
12577 to calling c_parser_error. */
12578 parser
->error
= true;
12579 c_parser_skip_to_pragma_eol (parser
);
12584 /* The interface the pragma parsers have to the lexer. */
12587 pragma_lex (tree
*value
, location_t
*loc
)
12589 c_token
*tok
= c_parser_peek_token (the_parser
);
12590 enum cpp_ttype ret
= tok
->type
;
12592 *value
= tok
->value
;
12594 *loc
= tok
->location
;
12596 if (ret
== CPP_PRAGMA_EOL
|| ret
== CPP_EOF
)
12598 else if (ret
== CPP_STRING
)
12599 *value
= c_parser_string_literal (the_parser
, false, false).value
;
12602 if (ret
== CPP_KEYWORD
)
12604 c_parser_consume_token (the_parser
);
12611 c_parser_pragma_pch_preprocess (c_parser
*parser
)
12615 parser
->lex_joined_string
= true;
12616 c_parser_consume_pragma (parser
);
12617 if (c_parser_next_token_is (parser
, CPP_STRING
))
12619 name
= c_parser_peek_token (parser
)->value
;
12620 c_parser_consume_token (parser
);
12623 c_parser_error (parser
, "expected string literal");
12624 c_parser_skip_to_pragma_eol (parser
);
12625 parser
->lex_joined_string
= false;
12628 c_common_pch_pragma (parse_in
, TREE_STRING_POINTER (name
));
12631 /* OpenACC and OpenMP parsing routines. */
12633 /* Returns name of the next clause.
12634 If the clause is not recognized PRAGMA_OMP_CLAUSE_NONE is returned and
12635 the token is not consumed. Otherwise appropriate pragma_omp_clause is
12636 returned and the token is consumed. */
12638 static pragma_omp_clause
12639 c_parser_omp_clause_name (c_parser
*parser
)
12641 pragma_omp_clause result
= PRAGMA_OMP_CLAUSE_NONE
;
12643 if (c_parser_next_token_is_keyword (parser
, RID_AUTO
))
12644 result
= PRAGMA_OACC_CLAUSE_AUTO
;
12645 else if (c_parser_next_token_is_keyword (parser
, RID_IF
))
12646 result
= PRAGMA_OMP_CLAUSE_IF
;
12647 else if (c_parser_next_token_is_keyword (parser
, RID_DEFAULT
))
12648 result
= PRAGMA_OMP_CLAUSE_DEFAULT
;
12649 else if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
12650 result
= PRAGMA_OMP_CLAUSE_FOR
;
12651 else if (c_parser_next_token_is (parser
, CPP_NAME
))
12653 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
12658 if (!strcmp ("affinity", p
))
12659 result
= PRAGMA_OMP_CLAUSE_AFFINITY
;
12660 else if (!strcmp ("aligned", p
))
12661 result
= PRAGMA_OMP_CLAUSE_ALIGNED
;
12662 else if (!strcmp ("allocate", p
))
12663 result
= PRAGMA_OMP_CLAUSE_ALLOCATE
;
12664 else if (!strcmp ("async", p
))
12665 result
= PRAGMA_OACC_CLAUSE_ASYNC
;
12666 else if (!strcmp ("attach", p
))
12667 result
= PRAGMA_OACC_CLAUSE_ATTACH
;
12670 if (!strcmp ("bind", p
))
12671 result
= PRAGMA_OMP_CLAUSE_BIND
;
12674 if (!strcmp ("collapse", p
))
12675 result
= PRAGMA_OMP_CLAUSE_COLLAPSE
;
12676 else if (!strcmp ("copy", p
))
12677 result
= PRAGMA_OACC_CLAUSE_COPY
;
12678 else if (!strcmp ("copyin", p
))
12679 result
= PRAGMA_OMP_CLAUSE_COPYIN
;
12680 else if (!strcmp ("copyout", p
))
12681 result
= PRAGMA_OACC_CLAUSE_COPYOUT
;
12682 else if (!strcmp ("copyprivate", p
))
12683 result
= PRAGMA_OMP_CLAUSE_COPYPRIVATE
;
12684 else if (!strcmp ("create", p
))
12685 result
= PRAGMA_OACC_CLAUSE_CREATE
;
12688 if (!strcmp ("defaultmap", p
))
12689 result
= PRAGMA_OMP_CLAUSE_DEFAULTMAP
;
12690 else if (!strcmp ("delete", p
))
12691 result
= PRAGMA_OACC_CLAUSE_DELETE
;
12692 else if (!strcmp ("depend", p
))
12693 result
= PRAGMA_OMP_CLAUSE_DEPEND
;
12694 else if (!strcmp ("detach", p
))
12695 result
= PRAGMA_OACC_CLAUSE_DETACH
;
12696 else if (!strcmp ("device", p
))
12697 result
= PRAGMA_OMP_CLAUSE_DEVICE
;
12698 else if (!strcmp ("deviceptr", p
))
12699 result
= PRAGMA_OACC_CLAUSE_DEVICEPTR
;
12700 else if (!strcmp ("device_resident", p
))
12701 result
= PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT
;
12702 else if (!strcmp ("device_type", p
))
12703 result
= PRAGMA_OMP_CLAUSE_DEVICE_TYPE
;
12704 else if (!strcmp ("dist_schedule", p
))
12705 result
= PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
;
12708 if (!strcmp ("filter", p
))
12709 result
= PRAGMA_OMP_CLAUSE_FILTER
;
12710 else if (!strcmp ("final", p
))
12711 result
= PRAGMA_OMP_CLAUSE_FINAL
;
12712 else if (!strcmp ("finalize", p
))
12713 result
= PRAGMA_OACC_CLAUSE_FINALIZE
;
12714 else if (!strcmp ("firstprivate", p
))
12715 result
= PRAGMA_OMP_CLAUSE_FIRSTPRIVATE
;
12716 else if (!strcmp ("from", p
))
12717 result
= PRAGMA_OMP_CLAUSE_FROM
;
12720 if (!strcmp ("gang", p
))
12721 result
= PRAGMA_OACC_CLAUSE_GANG
;
12722 else if (!strcmp ("grainsize", p
))
12723 result
= PRAGMA_OMP_CLAUSE_GRAINSIZE
;
12726 if (!strcmp ("hint", p
))
12727 result
= PRAGMA_OMP_CLAUSE_HINT
;
12728 else if (!strcmp ("host", p
))
12729 result
= PRAGMA_OACC_CLAUSE_HOST
;
12732 if (!strcmp ("if_present", p
))
12733 result
= PRAGMA_OACC_CLAUSE_IF_PRESENT
;
12734 else if (!strcmp ("in_reduction", p
))
12735 result
= PRAGMA_OMP_CLAUSE_IN_REDUCTION
;
12736 else if (!strcmp ("inbranch", p
))
12737 result
= PRAGMA_OMP_CLAUSE_INBRANCH
;
12738 else if (!strcmp ("independent", p
))
12739 result
= PRAGMA_OACC_CLAUSE_INDEPENDENT
;
12740 else if (!strcmp ("is_device_ptr", p
))
12741 result
= PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR
;
12744 if (!strcmp ("lastprivate", p
))
12745 result
= PRAGMA_OMP_CLAUSE_LASTPRIVATE
;
12746 else if (!strcmp ("linear", p
))
12747 result
= PRAGMA_OMP_CLAUSE_LINEAR
;
12748 else if (!strcmp ("link", p
))
12749 result
= PRAGMA_OMP_CLAUSE_LINK
;
12752 if (!strcmp ("map", p
))
12753 result
= PRAGMA_OMP_CLAUSE_MAP
;
12754 else if (!strcmp ("mergeable", p
))
12755 result
= PRAGMA_OMP_CLAUSE_MERGEABLE
;
12758 if (!strcmp ("no_create", p
))
12759 result
= PRAGMA_OACC_CLAUSE_NO_CREATE
;
12760 else if (!strcmp ("nogroup", p
))
12761 result
= PRAGMA_OMP_CLAUSE_NOGROUP
;
12762 else if (!strcmp ("nohost", p
))
12763 result
= PRAGMA_OACC_CLAUSE_NOHOST
;
12764 else if (!strcmp ("nontemporal", p
))
12765 result
= PRAGMA_OMP_CLAUSE_NONTEMPORAL
;
12766 else if (!strcmp ("notinbranch", p
))
12767 result
= PRAGMA_OMP_CLAUSE_NOTINBRANCH
;
12768 else if (!strcmp ("nowait", p
))
12769 result
= PRAGMA_OMP_CLAUSE_NOWAIT
;
12770 else if (!strcmp ("num_gangs", p
))
12771 result
= PRAGMA_OACC_CLAUSE_NUM_GANGS
;
12772 else if (!strcmp ("num_tasks", p
))
12773 result
= PRAGMA_OMP_CLAUSE_NUM_TASKS
;
12774 else if (!strcmp ("num_teams", p
))
12775 result
= PRAGMA_OMP_CLAUSE_NUM_TEAMS
;
12776 else if (!strcmp ("num_threads", p
))
12777 result
= PRAGMA_OMP_CLAUSE_NUM_THREADS
;
12778 else if (!strcmp ("num_workers", p
))
12779 result
= PRAGMA_OACC_CLAUSE_NUM_WORKERS
;
12782 if (!strcmp ("ordered", p
))
12783 result
= PRAGMA_OMP_CLAUSE_ORDERED
;
12784 else if (!strcmp ("order", p
))
12785 result
= PRAGMA_OMP_CLAUSE_ORDER
;
12788 if (!strcmp ("parallel", p
))
12789 result
= PRAGMA_OMP_CLAUSE_PARALLEL
;
12790 else if (!strcmp ("present", p
))
12791 result
= PRAGMA_OACC_CLAUSE_PRESENT
;
12792 /* As of OpenACC 2.5, these are now aliases of the non-present_or
12794 else if (!strcmp ("present_or_copy", p
)
12795 || !strcmp ("pcopy", p
))
12796 result
= PRAGMA_OACC_CLAUSE_COPY
;
12797 else if (!strcmp ("present_or_copyin", p
)
12798 || !strcmp ("pcopyin", p
))
12799 result
= PRAGMA_OACC_CLAUSE_COPYIN
;
12800 else if (!strcmp ("present_or_copyout", p
)
12801 || !strcmp ("pcopyout", p
))
12802 result
= PRAGMA_OACC_CLAUSE_COPYOUT
;
12803 else if (!strcmp ("present_or_create", p
)
12804 || !strcmp ("pcreate", p
))
12805 result
= PRAGMA_OACC_CLAUSE_CREATE
;
12806 else if (!strcmp ("priority", p
))
12807 result
= PRAGMA_OMP_CLAUSE_PRIORITY
;
12808 else if (!strcmp ("private", p
))
12809 result
= PRAGMA_OMP_CLAUSE_PRIVATE
;
12810 else if (!strcmp ("proc_bind", p
))
12811 result
= PRAGMA_OMP_CLAUSE_PROC_BIND
;
12814 if (!strcmp ("reduction", p
))
12815 result
= PRAGMA_OMP_CLAUSE_REDUCTION
;
12818 if (!strcmp ("safelen", p
))
12819 result
= PRAGMA_OMP_CLAUSE_SAFELEN
;
12820 else if (!strcmp ("schedule", p
))
12821 result
= PRAGMA_OMP_CLAUSE_SCHEDULE
;
12822 else if (!strcmp ("sections", p
))
12823 result
= PRAGMA_OMP_CLAUSE_SECTIONS
;
12824 else if (!strcmp ("self", p
)) /* "self" is a synonym for "host". */
12825 result
= PRAGMA_OACC_CLAUSE_HOST
;
12826 else if (!strcmp ("seq", p
))
12827 result
= PRAGMA_OACC_CLAUSE_SEQ
;
12828 else if (!strcmp ("shared", p
))
12829 result
= PRAGMA_OMP_CLAUSE_SHARED
;
12830 else if (!strcmp ("simd", p
))
12831 result
= PRAGMA_OMP_CLAUSE_SIMD
;
12832 else if (!strcmp ("simdlen", p
))
12833 result
= PRAGMA_OMP_CLAUSE_SIMDLEN
;
12836 if (!strcmp ("task_reduction", p
))
12837 result
= PRAGMA_OMP_CLAUSE_TASK_REDUCTION
;
12838 else if (!strcmp ("taskgroup", p
))
12839 result
= PRAGMA_OMP_CLAUSE_TASKGROUP
;
12840 else if (!strcmp ("thread_limit", p
))
12841 result
= PRAGMA_OMP_CLAUSE_THREAD_LIMIT
;
12842 else if (!strcmp ("threads", p
))
12843 result
= PRAGMA_OMP_CLAUSE_THREADS
;
12844 else if (!strcmp ("tile", p
))
12845 result
= PRAGMA_OACC_CLAUSE_TILE
;
12846 else if (!strcmp ("to", p
))
12847 result
= PRAGMA_OMP_CLAUSE_TO
;
12850 if (!strcmp ("uniform", p
))
12851 result
= PRAGMA_OMP_CLAUSE_UNIFORM
;
12852 else if (!strcmp ("untied", p
))
12853 result
= PRAGMA_OMP_CLAUSE_UNTIED
;
12854 else if (!strcmp ("use_device", p
))
12855 result
= PRAGMA_OACC_CLAUSE_USE_DEVICE
;
12856 else if (!strcmp ("use_device_addr", p
))
12857 result
= PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR
;
12858 else if (!strcmp ("use_device_ptr", p
))
12859 result
= PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR
;
12862 if (!strcmp ("vector", p
))
12863 result
= PRAGMA_OACC_CLAUSE_VECTOR
;
12864 else if (!strcmp ("vector_length", p
))
12865 result
= PRAGMA_OACC_CLAUSE_VECTOR_LENGTH
;
12868 if (!strcmp ("wait", p
))
12869 result
= PRAGMA_OACC_CLAUSE_WAIT
;
12870 else if (!strcmp ("worker", p
))
12871 result
= PRAGMA_OACC_CLAUSE_WORKER
;
12876 if (result
!= PRAGMA_OMP_CLAUSE_NONE
)
12877 c_parser_consume_token (parser
);
12882 /* Validate that a clause of the given type does not already exist. */
12885 check_no_duplicate_clause (tree clauses
, enum omp_clause_code code
,
12888 if (tree c
= omp_find_clause (clauses
, code
))
12889 error_at (OMP_CLAUSE_LOCATION (c
), "too many %qs clauses", name
);
12893 Parse wait clause or wait directive parameters. */
12896 c_parser_oacc_wait_list (c_parser
*parser
, location_t clause_loc
, tree list
)
12898 vec
<tree
, va_gc
> *args
;
12901 matching_parens parens
;
12902 if (!parens
.require_open (parser
))
12905 args
= c_parser_expr_list (parser
, false, true, NULL
, NULL
, NULL
, NULL
);
12906 args_tree
= build_tree_list_vec (args
);
12908 for (t
= args_tree
; t
; t
= TREE_CHAIN (t
))
12910 tree targ
= TREE_VALUE (t
);
12912 if (targ
!= error_mark_node
)
12914 if (!INTEGRAL_TYPE_P (TREE_TYPE (targ
)))
12916 c_parser_error (parser
, "expression must be integral");
12917 targ
= error_mark_node
;
12921 tree c
= build_omp_clause (clause_loc
, OMP_CLAUSE_WAIT
);
12923 OMP_CLAUSE_DECL (c
) = targ
;
12924 OMP_CLAUSE_CHAIN (c
) = list
;
12930 release_tree_vector (args
);
12931 parens
.require_close (parser
);
12935 /* OpenACC 2.0, OpenMP 2.5:
12938 variable-list , identifier
12940 If KIND is nonzero, create the appropriate node and install the
12941 decl in OMP_CLAUSE_DECL and add the node to the head of the list.
12942 If KIND is nonzero, CLAUSE_LOC is the location of the clause.
12944 If KIND is zero, create a TREE_LIST with the decl in TREE_PURPOSE;
12945 return the list created.
12947 The optional ALLOW_DEREF argument is true if list items can use the deref
12951 c_parser_omp_variable_list (c_parser
*parser
,
12952 location_t clause_loc
,
12953 enum omp_clause_code kind
, tree list
,
12954 bool allow_deref
= false)
12956 auto_vec
<c_token
> tokens
;
12957 unsigned int tokens_avail
= 0;
12962 bool array_section_p
= false;
12963 if (kind
== OMP_CLAUSE_DEPEND
|| kind
== OMP_CLAUSE_AFFINITY
)
12965 if (c_parser_next_token_is_not (parser
, CPP_NAME
)
12966 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
12968 struct c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
12969 if (expr
.value
!= error_mark_node
)
12971 tree u
= build_omp_clause (clause_loc
, kind
);
12972 OMP_CLAUSE_DECL (u
) = expr
.value
;
12973 OMP_CLAUSE_CHAIN (u
) = list
;
12977 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
12980 c_parser_consume_token (parser
);
12985 tokens
.truncate (0);
12986 unsigned int nesting_depth
= 0;
12989 c_token
*token
= c_parser_peek_token (parser
);
12990 switch (token
->type
)
12993 case CPP_PRAGMA_EOL
:
12995 case CPP_OPEN_BRACE
:
12996 case CPP_OPEN_PAREN
:
12997 case CPP_OPEN_SQUARE
:
13000 case CPP_CLOSE_BRACE
:
13001 case CPP_CLOSE_PAREN
:
13002 case CPP_CLOSE_SQUARE
:
13003 if (nesting_depth
-- == 0)
13007 if (nesting_depth
== 0)
13012 tokens
.safe_push (*token
);
13013 c_parser_consume_token (parser
);
13019 /* Make sure nothing tries to read past the end of the tokens. */
13021 memset (&eof_token
, 0, sizeof (eof_token
));
13022 eof_token
.type
= CPP_EOF
;
13023 tokens
.safe_push (eof_token
);
13024 tokens
.safe_push (eof_token
);
13026 tokens_avail
= parser
->tokens_avail
;
13027 gcc_assert (parser
->tokens
== &parser
->tokens_buf
[0]);
13028 parser
->tokens
= tokens
.address ();
13029 parser
->tokens_avail
= tokens
.length ();
13032 tree t
= NULL_TREE
;
13034 if (c_parser_next_token_is (parser
, CPP_NAME
)
13035 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
)
13037 t
= lookup_name (c_parser_peek_token (parser
)->value
);
13039 if (t
== NULL_TREE
)
13041 undeclared_variable (c_parser_peek_token (parser
)->location
,
13042 c_parser_peek_token (parser
)->value
);
13043 t
= error_mark_node
;
13046 c_parser_consume_token (parser
);
13048 else if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
13049 && (c_parser_peek_token (parser
)->keyword
== RID_FUNCTION_NAME
13050 || (c_parser_peek_token (parser
)->keyword
13051 == RID_PRETTY_FUNCTION_NAME
)
13052 || (c_parser_peek_token (parser
)->keyword
13053 == RID_C99_FUNCTION_NAME
)))
13054 t
= c_parser_predefined_identifier (parser
).value
;
13058 c_parser_error (parser
, "expected identifier");
13062 if (t
== error_mark_node
)
13064 else if (kind
!= 0)
13068 case OMP_CLAUSE__CACHE_
:
13069 /* The OpenACC cache directive explicitly only allows "array
13070 elements or subarrays". */
13071 if (c_parser_peek_token (parser
)->type
!= CPP_OPEN_SQUARE
)
13073 c_parser_error (parser
, "expected %<[%>");
13074 t
= error_mark_node
;
13078 case OMP_CLAUSE_MAP
:
13079 case OMP_CLAUSE_FROM
:
13080 case OMP_CLAUSE_TO
:
13081 while (c_parser_next_token_is (parser
, CPP_DOT
)
13083 && c_parser_next_token_is (parser
, CPP_DEREF
)))
13085 location_t op_loc
= c_parser_peek_token (parser
)->location
;
13086 if (c_parser_next_token_is (parser
, CPP_DEREF
))
13087 t
= build_simple_mem_ref (t
);
13088 c_parser_consume_token (parser
);
13089 if (!c_parser_next_token_is (parser
, CPP_NAME
))
13091 c_parser_error (parser
, "expected identifier");
13092 t
= error_mark_node
;
13096 c_token
*comp_tok
= c_parser_peek_token (parser
);
13097 tree ident
= comp_tok
->value
;
13098 location_t comp_loc
= comp_tok
->location
;
13099 c_parser_consume_token (parser
);
13100 t
= build_component_ref (op_loc
, t
, ident
, comp_loc
);
13103 case OMP_CLAUSE_AFFINITY
:
13104 case OMP_CLAUSE_DEPEND
:
13105 case OMP_CLAUSE_REDUCTION
:
13106 case OMP_CLAUSE_IN_REDUCTION
:
13107 case OMP_CLAUSE_TASK_REDUCTION
:
13108 while (c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
))
13110 tree low_bound
= NULL_TREE
, length
= NULL_TREE
;
13112 c_parser_consume_token (parser
);
13113 if (!c_parser_next_token_is (parser
, CPP_COLON
))
13115 location_t expr_loc
13116 = c_parser_peek_token (parser
)->location
;
13117 c_expr expr
= c_parser_expression (parser
);
13118 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
,
13120 low_bound
= expr
.value
;
13122 if (c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
13123 length
= integer_one_node
;
13126 /* Look for `:'. */
13127 if (!c_parser_require (parser
, CPP_COLON
,
13130 t
= error_mark_node
;
13133 array_section_p
= true;
13134 if (!c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
13136 location_t expr_loc
13137 = c_parser_peek_token (parser
)->location
;
13138 c_expr expr
= c_parser_expression (parser
);
13139 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
,
13141 length
= expr
.value
;
13144 /* Look for the closing `]'. */
13145 if (!c_parser_require (parser
, CPP_CLOSE_SQUARE
,
13148 t
= error_mark_node
;
13152 t
= tree_cons (low_bound
, length
, t
);
13154 if ((kind
== OMP_CLAUSE_DEPEND
|| kind
== OMP_CLAUSE_AFFINITY
)
13155 && t
!= error_mark_node
13156 && parser
->tokens_avail
!= 2)
13158 if (array_section_p
)
13160 error_at (c_parser_peek_token (parser
)->location
,
13161 "expected %<)%> or %<,%>");
13162 t
= error_mark_node
;
13166 parser
->tokens
= tokens
.address ();
13167 parser
->tokens_avail
= tokens
.length ();
13169 t
= c_parser_expr_no_commas (parser
, NULL
).value
;
13170 if (t
!= error_mark_node
&& parser
->tokens_avail
!= 2)
13172 error_at (c_parser_peek_token (parser
)->location
,
13173 "expected %<)%> or %<,%>");
13174 t
= error_mark_node
;
13183 if (t
!= error_mark_node
)
13185 tree u
= build_omp_clause (clause_loc
, kind
);
13186 OMP_CLAUSE_DECL (u
) = t
;
13187 OMP_CLAUSE_CHAIN (u
) = list
;
13192 list
= tree_cons (t
, NULL_TREE
, list
);
13194 if (kind
== OMP_CLAUSE_DEPEND
|| kind
== OMP_CLAUSE_AFFINITY
)
13196 parser
->tokens
= &parser
->tokens_buf
[0];
13197 parser
->tokens_avail
= tokens_avail
;
13199 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
13202 c_parser_consume_token (parser
);
13209 /* Similarly, but expect leading and trailing parenthesis. This is a very
13210 common case for OpenACC and OpenMP clauses. The optional ALLOW_DEREF
13211 argument is true if list items can use the deref (->) operator. */
13214 c_parser_omp_var_list_parens (c_parser
*parser
, enum omp_clause_code kind
,
13215 tree list
, bool allow_deref
= false)
13217 /* The clauses location. */
13218 location_t loc
= c_parser_peek_token (parser
)->location
;
13220 matching_parens parens
;
13221 if (parens
.require_open (parser
))
13223 list
= c_parser_omp_variable_list (parser
, loc
, kind
, list
, allow_deref
);
13224 parens
.skip_until_found_close (parser
);
13230 copy ( variable-list )
13231 copyin ( variable-list )
13232 copyout ( variable-list )
13233 create ( variable-list )
13234 delete ( variable-list )
13235 present ( variable-list )
13238 no_create ( variable-list )
13239 attach ( variable-list )
13240 detach ( variable-list ) */
13243 c_parser_oacc_data_clause (c_parser
*parser
, pragma_omp_clause c_kind
,
13246 enum gomp_map_kind kind
;
13249 case PRAGMA_OACC_CLAUSE_ATTACH
:
13250 kind
= GOMP_MAP_ATTACH
;
13252 case PRAGMA_OACC_CLAUSE_COPY
:
13253 kind
= GOMP_MAP_TOFROM
;
13255 case PRAGMA_OACC_CLAUSE_COPYIN
:
13256 kind
= GOMP_MAP_TO
;
13258 case PRAGMA_OACC_CLAUSE_COPYOUT
:
13259 kind
= GOMP_MAP_FROM
;
13261 case PRAGMA_OACC_CLAUSE_CREATE
:
13262 kind
= GOMP_MAP_ALLOC
;
13264 case PRAGMA_OACC_CLAUSE_DELETE
:
13265 kind
= GOMP_MAP_RELEASE
;
13267 case PRAGMA_OACC_CLAUSE_DETACH
:
13268 kind
= GOMP_MAP_DETACH
;
13270 case PRAGMA_OACC_CLAUSE_DEVICE
:
13271 kind
= GOMP_MAP_FORCE_TO
;
13273 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT
:
13274 kind
= GOMP_MAP_DEVICE_RESIDENT
;
13276 case PRAGMA_OACC_CLAUSE_HOST
:
13277 kind
= GOMP_MAP_FORCE_FROM
;
13279 case PRAGMA_OACC_CLAUSE_LINK
:
13280 kind
= GOMP_MAP_LINK
;
13282 case PRAGMA_OACC_CLAUSE_NO_CREATE
:
13283 kind
= GOMP_MAP_IF_PRESENT
;
13285 case PRAGMA_OACC_CLAUSE_PRESENT
:
13286 kind
= GOMP_MAP_FORCE_PRESENT
;
13289 gcc_unreachable ();
13292 nl
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_MAP
, list
, true);
13294 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
13295 OMP_CLAUSE_SET_MAP_KIND (c
, kind
);
13301 deviceptr ( variable-list ) */
13304 c_parser_oacc_data_clause_deviceptr (c_parser
*parser
, tree list
)
13306 location_t loc
= c_parser_peek_token (parser
)->location
;
13309 /* Can't use OMP_CLAUSE_MAP here (that is, can't use the generic
13310 c_parser_oacc_data_clause), as for PRAGMA_OACC_CLAUSE_DEVICEPTR,
13311 variable-list must only allow for pointer variables. */
13312 vars
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ERROR
, NULL
);
13313 for (t
= vars
; t
&& t
; t
= TREE_CHAIN (t
))
13315 tree v
= TREE_PURPOSE (t
);
13317 /* FIXME diagnostics: Ideally we should keep individual
13318 locations for all the variables in the var list to make the
13319 following errors more precise. Perhaps
13320 c_parser_omp_var_list_parens() should construct a list of
13321 locations to go along with the var list. */
13323 if (!VAR_P (v
) && TREE_CODE (v
) != PARM_DECL
)
13324 error_at (loc
, "%qD is not a variable", v
);
13325 else if (TREE_TYPE (v
) == error_mark_node
)
13327 else if (!POINTER_TYPE_P (TREE_TYPE (v
)))
13328 error_at (loc
, "%qD is not a pointer variable", v
);
13330 tree u
= build_omp_clause (loc
, OMP_CLAUSE_MAP
);
13331 OMP_CLAUSE_SET_MAP_KIND (u
, GOMP_MAP_FORCE_DEVICEPTR
);
13332 OMP_CLAUSE_DECL (u
) = v
;
13333 OMP_CLAUSE_CHAIN (u
) = list
;
13340 /* OpenACC 2.0, OpenMP 3.0:
13341 collapse ( constant-expression ) */
13344 c_parser_omp_clause_collapse (c_parser
*parser
, tree list
)
13346 tree c
, num
= error_mark_node
;
13350 check_no_duplicate_clause (list
, OMP_CLAUSE_COLLAPSE
, "collapse");
13351 check_no_duplicate_clause (list
, OMP_CLAUSE_TILE
, "tile");
13353 loc
= c_parser_peek_token (parser
)->location
;
13354 matching_parens parens
;
13355 if (parens
.require_open (parser
))
13357 num
= c_parser_expr_no_commas (parser
, NULL
).value
;
13358 parens
.skip_until_found_close (parser
);
13360 if (num
== error_mark_node
)
13362 mark_exp_read (num
);
13363 num
= c_fully_fold (num
, false, NULL
);
13364 if (!INTEGRAL_TYPE_P (TREE_TYPE (num
))
13365 || !tree_fits_shwi_p (num
)
13366 || (n
= tree_to_shwi (num
)) <= 0
13370 "collapse argument needs positive constant integer expression");
13373 c
= build_omp_clause (loc
, OMP_CLAUSE_COLLAPSE
);
13374 OMP_CLAUSE_COLLAPSE_EXPR (c
) = num
;
13375 OMP_CLAUSE_CHAIN (c
) = list
;
13380 copyin ( variable-list ) */
13383 c_parser_omp_clause_copyin (c_parser
*parser
, tree list
)
13385 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_COPYIN
, list
);
13389 copyprivate ( variable-list ) */
13392 c_parser_omp_clause_copyprivate (c_parser
*parser
, tree list
)
13394 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_COPYPRIVATE
, list
);
13398 default ( none | shared )
13401 default ( none | present ) */
13404 c_parser_omp_clause_default (c_parser
*parser
, tree list
, bool is_oacc
)
13406 enum omp_clause_default_kind kind
= OMP_CLAUSE_DEFAULT_UNSPECIFIED
;
13407 location_t loc
= c_parser_peek_token (parser
)->location
;
13410 matching_parens parens
;
13411 if (!parens
.require_open (parser
))
13413 if (c_parser_next_token_is (parser
, CPP_NAME
))
13415 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
13420 if (strcmp ("none", p
) != 0)
13422 kind
= OMP_CLAUSE_DEFAULT_NONE
;
13426 if (strcmp ("present", p
) != 0 || !is_oacc
)
13428 kind
= OMP_CLAUSE_DEFAULT_PRESENT
;
13432 if (strcmp ("shared", p
) != 0 || is_oacc
)
13434 kind
= OMP_CLAUSE_DEFAULT_SHARED
;
13441 c_parser_consume_token (parser
);
13447 c_parser_error (parser
, "expected %<none%> or %<present%>");
13449 c_parser_error (parser
, "expected %<none%> or %<shared%>");
13451 parens
.skip_until_found_close (parser
);
13453 if (kind
== OMP_CLAUSE_DEFAULT_UNSPECIFIED
)
13456 check_no_duplicate_clause (list
, OMP_CLAUSE_DEFAULT
, "default");
13457 c
= build_omp_clause (loc
, OMP_CLAUSE_DEFAULT
);
13458 OMP_CLAUSE_CHAIN (c
) = list
;
13459 OMP_CLAUSE_DEFAULT_KIND (c
) = kind
;
13465 firstprivate ( variable-list ) */
13468 c_parser_omp_clause_firstprivate (c_parser
*parser
, tree list
)
13470 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_FIRSTPRIVATE
, list
);
13474 final ( expression ) */
13477 c_parser_omp_clause_final (c_parser
*parser
, tree list
)
13479 location_t loc
= c_parser_peek_token (parser
)->location
;
13480 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
13482 matching_parens parens
;
13484 if (!parens
.require_open (parser
))
13485 t
= error_mark_node
;
13488 location_t eloc
= c_parser_peek_token (parser
)->location
;
13489 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
13490 t
= convert_lvalue_to_rvalue (eloc
, expr
, true, true).value
;
13491 t
= c_objc_common_truthvalue_conversion (eloc
, t
);
13492 t
= c_fully_fold (t
, false, NULL
);
13493 parens
.skip_until_found_close (parser
);
13496 check_no_duplicate_clause (list
, OMP_CLAUSE_FINAL
, "final");
13498 c
= build_omp_clause (loc
, OMP_CLAUSE_FINAL
);
13499 OMP_CLAUSE_FINAL_EXPR (c
) = t
;
13500 OMP_CLAUSE_CHAIN (c
) = list
;
13504 c_parser_error (parser
, "expected %<(%>");
13509 /* OpenACC, OpenMP 2.5:
13513 if ( directive-name-modifier : expression )
13515 directive-name-modifier:
13516 parallel | task | taskloop | target data | target | target update
13517 | target enter data | target exit data
13520 directive-name-modifier:
13521 ... | simd | cancel */
13524 c_parser_omp_clause_if (c_parser
*parser
, tree list
, bool is_omp
)
13526 location_t location
= c_parser_peek_token (parser
)->location
;
13527 enum tree_code if_modifier
= ERROR_MARK
;
13529 matching_parens parens
;
13530 if (!parens
.require_open (parser
))
13533 if (is_omp
&& c_parser_next_token_is (parser
, CPP_NAME
))
13535 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
13537 if (strcmp (p
, "cancel") == 0)
13538 if_modifier
= VOID_CST
;
13539 else if (strcmp (p
, "parallel") == 0)
13540 if_modifier
= OMP_PARALLEL
;
13541 else if (strcmp (p
, "simd") == 0)
13542 if_modifier
= OMP_SIMD
;
13543 else if (strcmp (p
, "task") == 0)
13544 if_modifier
= OMP_TASK
;
13545 else if (strcmp (p
, "taskloop") == 0)
13546 if_modifier
= OMP_TASKLOOP
;
13547 else if (strcmp (p
, "target") == 0)
13549 if_modifier
= OMP_TARGET
;
13550 if (c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
13552 p
= IDENTIFIER_POINTER (c_parser_peek_2nd_token (parser
)->value
);
13553 if (strcmp ("data", p
) == 0)
13554 if_modifier
= OMP_TARGET_DATA
;
13555 else if (strcmp ("update", p
) == 0)
13556 if_modifier
= OMP_TARGET_UPDATE
;
13557 else if (strcmp ("enter", p
) == 0)
13558 if_modifier
= OMP_TARGET_ENTER_DATA
;
13559 else if (strcmp ("exit", p
) == 0)
13560 if_modifier
= OMP_TARGET_EXIT_DATA
;
13561 if (if_modifier
!= OMP_TARGET
)
13564 c_parser_consume_token (parser
);
13568 location_t loc
= c_parser_peek_2nd_token (parser
)->location
;
13569 error_at (loc
, "expected %<data%>, %<update%>, %<enter%> "
13571 if_modifier
= ERROR_MARK
;
13573 if (if_modifier
== OMP_TARGET_ENTER_DATA
13574 || if_modifier
== OMP_TARGET_EXIT_DATA
)
13576 if (c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
13578 p
= IDENTIFIER_POINTER
13579 (c_parser_peek_2nd_token (parser
)->value
);
13580 if (strcmp ("data", p
) == 0)
13584 c_parser_consume_token (parser
);
13588 = c_parser_peek_2nd_token (parser
)->location
;
13589 error_at (loc
, "expected %<data%>");
13590 if_modifier
= ERROR_MARK
;
13595 if (if_modifier
!= ERROR_MARK
)
13597 if (c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
13599 c_parser_consume_token (parser
);
13600 c_parser_consume_token (parser
);
13606 location_t loc
= c_parser_peek_2nd_token (parser
)->location
;
13607 error_at (loc
, "expected %<:%>");
13609 if_modifier
= ERROR_MARK
;
13614 location_t loc
= c_parser_peek_token (parser
)->location
;
13615 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
13616 expr
= convert_lvalue_to_rvalue (loc
, expr
, true, true);
13617 tree t
= c_objc_common_truthvalue_conversion (loc
, expr
.value
), c
;
13618 t
= c_fully_fold (t
, false, NULL
);
13619 parens
.skip_until_found_close (parser
);
13621 for (c
= list
; c
; c
= OMP_CLAUSE_CHAIN (c
))
13622 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_IF
)
13624 if (if_modifier
!= ERROR_MARK
13625 && OMP_CLAUSE_IF_MODIFIER (c
) == if_modifier
)
13627 const char *p
= NULL
;
13628 switch (if_modifier
)
13630 case VOID_CST
: p
= "cancel"; break;
13631 case OMP_PARALLEL
: p
= "parallel"; break;
13632 case OMP_SIMD
: p
= "simd"; break;
13633 case OMP_TASK
: p
= "task"; break;
13634 case OMP_TASKLOOP
: p
= "taskloop"; break;
13635 case OMP_TARGET_DATA
: p
= "target data"; break;
13636 case OMP_TARGET
: p
= "target"; break;
13637 case OMP_TARGET_UPDATE
: p
= "target update"; break;
13638 case OMP_TARGET_ENTER_DATA
: p
= "target enter data"; break;
13639 case OMP_TARGET_EXIT_DATA
: p
= "target exit data"; break;
13640 default: gcc_unreachable ();
13642 error_at (location
, "too many %<if%> clauses with %qs modifier",
13646 else if (OMP_CLAUSE_IF_MODIFIER (c
) == if_modifier
)
13649 error_at (location
, "too many %<if%> clauses");
13651 error_at (location
, "too many %<if%> clauses without modifier");
13654 else if (if_modifier
== ERROR_MARK
13655 || OMP_CLAUSE_IF_MODIFIER (c
) == ERROR_MARK
)
13657 error_at (location
, "if any %<if%> clause has modifier, then all "
13658 "%<if%> clauses have to use modifier");
13663 c
= build_omp_clause (location
, OMP_CLAUSE_IF
);
13664 OMP_CLAUSE_IF_MODIFIER (c
) = if_modifier
;
13665 OMP_CLAUSE_IF_EXPR (c
) = t
;
13666 OMP_CLAUSE_CHAIN (c
) = list
;
13671 lastprivate ( variable-list )
13674 lastprivate ( [ lastprivate-modifier : ] variable-list ) */
13677 c_parser_omp_clause_lastprivate (c_parser
*parser
, tree list
)
13679 /* The clauses location. */
13680 location_t loc
= c_parser_peek_token (parser
)->location
;
13682 if (c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
13684 bool conditional
= false;
13685 if (c_parser_next_token_is (parser
, CPP_NAME
)
13686 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
13689 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
13690 if (strcmp (p
, "conditional") == 0)
13692 conditional
= true;
13693 c_parser_consume_token (parser
);
13694 c_parser_consume_token (parser
);
13697 tree nlist
= c_parser_omp_variable_list (parser
, loc
,
13698 OMP_CLAUSE_LASTPRIVATE
, list
);
13699 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, "expected %<)%>");
13701 for (tree c
= nlist
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
13702 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
) = 1;
13712 c_parser_omp_clause_mergeable (c_parser
*parser ATTRIBUTE_UNUSED
, tree list
)
13716 /* FIXME: Should we allow duplicates? */
13717 check_no_duplicate_clause (list
, OMP_CLAUSE_MERGEABLE
, "mergeable");
13719 c
= build_omp_clause (c_parser_peek_token (parser
)->location
,
13720 OMP_CLAUSE_MERGEABLE
);
13721 OMP_CLAUSE_CHAIN (c
) = list
;
13730 c_parser_omp_clause_nowait (c_parser
*parser ATTRIBUTE_UNUSED
, tree list
)
13733 location_t loc
= c_parser_peek_token (parser
)->location
;
13735 check_no_duplicate_clause (list
, OMP_CLAUSE_NOWAIT
, "nowait");
13737 c
= build_omp_clause (loc
, OMP_CLAUSE_NOWAIT
);
13738 OMP_CLAUSE_CHAIN (c
) = list
;
13743 num_threads ( expression ) */
13746 c_parser_omp_clause_num_threads (c_parser
*parser
, tree list
)
13748 location_t num_threads_loc
= c_parser_peek_token (parser
)->location
;
13749 matching_parens parens
;
13750 if (parens
.require_open (parser
))
13752 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
13753 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
13754 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
13755 tree c
, t
= expr
.value
;
13756 t
= c_fully_fold (t
, false, NULL
);
13758 parens
.skip_until_found_close (parser
);
13760 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
13762 c_parser_error (parser
, "expected integer expression");
13766 /* Attempt to statically determine when the number isn't positive. */
13767 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
13768 build_int_cst (TREE_TYPE (t
), 0));
13769 protected_set_expr_location (c
, expr_loc
);
13770 if (c
== boolean_true_node
)
13772 warning_at (expr_loc
, 0,
13773 "%<num_threads%> value must be positive");
13774 t
= integer_one_node
;
13777 check_no_duplicate_clause (list
, OMP_CLAUSE_NUM_THREADS
, "num_threads");
13779 c
= build_omp_clause (num_threads_loc
, OMP_CLAUSE_NUM_THREADS
);
13780 OMP_CLAUSE_NUM_THREADS_EXPR (c
) = t
;
13781 OMP_CLAUSE_CHAIN (c
) = list
;
13789 num_tasks ( expression ) */
13792 c_parser_omp_clause_num_tasks (c_parser
*parser
, tree list
)
13794 location_t num_tasks_loc
= c_parser_peek_token (parser
)->location
;
13795 matching_parens parens
;
13796 if (parens
.require_open (parser
))
13798 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
13799 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
13800 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
13801 tree c
, t
= expr
.value
;
13802 t
= c_fully_fold (t
, false, NULL
);
13804 parens
.skip_until_found_close (parser
);
13806 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
13808 c_parser_error (parser
, "expected integer expression");
13812 /* Attempt to statically determine when the number isn't positive. */
13813 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
13814 build_int_cst (TREE_TYPE (t
), 0));
13815 if (CAN_HAVE_LOCATION_P (c
))
13816 SET_EXPR_LOCATION (c
, expr_loc
);
13817 if (c
== boolean_true_node
)
13819 warning_at (expr_loc
, 0, "%<num_tasks%> value must be positive");
13820 t
= integer_one_node
;
13823 check_no_duplicate_clause (list
, OMP_CLAUSE_NUM_TASKS
, "num_tasks");
13825 c
= build_omp_clause (num_tasks_loc
, OMP_CLAUSE_NUM_TASKS
);
13826 OMP_CLAUSE_NUM_TASKS_EXPR (c
) = t
;
13827 OMP_CLAUSE_CHAIN (c
) = list
;
13835 grainsize ( expression ) */
13838 c_parser_omp_clause_grainsize (c_parser
*parser
, tree list
)
13840 location_t grainsize_loc
= c_parser_peek_token (parser
)->location
;
13841 matching_parens parens
;
13842 if (parens
.require_open (parser
))
13844 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
13845 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
13846 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
13847 tree c
, t
= expr
.value
;
13848 t
= c_fully_fold (t
, false, NULL
);
13850 parens
.skip_until_found_close (parser
);
13852 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
13854 c_parser_error (parser
, "expected integer expression");
13858 /* Attempt to statically determine when the number isn't positive. */
13859 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
13860 build_int_cst (TREE_TYPE (t
), 0));
13861 if (CAN_HAVE_LOCATION_P (c
))
13862 SET_EXPR_LOCATION (c
, expr_loc
);
13863 if (c
== boolean_true_node
)
13865 warning_at (expr_loc
, 0, "%<grainsize%> value must be positive");
13866 t
= integer_one_node
;
13869 check_no_duplicate_clause (list
, OMP_CLAUSE_GRAINSIZE
, "grainsize");
13871 c
= build_omp_clause (grainsize_loc
, OMP_CLAUSE_GRAINSIZE
);
13872 OMP_CLAUSE_GRAINSIZE_EXPR (c
) = t
;
13873 OMP_CLAUSE_CHAIN (c
) = list
;
13881 priority ( expression ) */
13884 c_parser_omp_clause_priority (c_parser
*parser
, tree list
)
13886 location_t priority_loc
= c_parser_peek_token (parser
)->location
;
13887 matching_parens parens
;
13888 if (parens
.require_open (parser
))
13890 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
13891 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
13892 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
13893 tree c
, t
= expr
.value
;
13894 t
= c_fully_fold (t
, false, NULL
);
13896 parens
.skip_until_found_close (parser
);
13898 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
13900 c_parser_error (parser
, "expected integer expression");
13904 /* Attempt to statically determine when the number isn't
13906 c
= fold_build2_loc (expr_loc
, LT_EXPR
, boolean_type_node
, t
,
13907 build_int_cst (TREE_TYPE (t
), 0));
13908 if (CAN_HAVE_LOCATION_P (c
))
13909 SET_EXPR_LOCATION (c
, expr_loc
);
13910 if (c
== boolean_true_node
)
13912 warning_at (expr_loc
, 0, "%<priority%> value must be non-negative");
13913 t
= integer_one_node
;
13916 check_no_duplicate_clause (list
, OMP_CLAUSE_PRIORITY
, "priority");
13918 c
= build_omp_clause (priority_loc
, OMP_CLAUSE_PRIORITY
);
13919 OMP_CLAUSE_PRIORITY_EXPR (c
) = t
;
13920 OMP_CLAUSE_CHAIN (c
) = list
;
13928 hint ( expression ) */
13931 c_parser_omp_clause_hint (c_parser
*parser
, tree list
)
13933 location_t hint_loc
= c_parser_peek_token (parser
)->location
;
13934 matching_parens parens
;
13935 if (parens
.require_open (parser
))
13937 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
13938 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
13939 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
13940 tree c
, t
= expr
.value
;
13941 t
= c_fully_fold (t
, false, NULL
);
13942 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
))
13943 || TREE_CODE (t
) != INTEGER_CST
13944 || tree_int_cst_sgn (t
) == -1)
13946 c_parser_error (parser
, "expected constant integer expression "
13947 "with valid sync-hint value");
13950 parens
.skip_until_found_close (parser
);
13951 check_no_duplicate_clause (list
, OMP_CLAUSE_HINT
, "hint");
13953 c
= build_omp_clause (hint_loc
, OMP_CLAUSE_HINT
);
13954 OMP_CLAUSE_HINT_EXPR (c
) = t
;
13955 OMP_CLAUSE_CHAIN (c
) = list
;
13963 filter ( integer-expression ) */
13966 c_parser_omp_clause_filter (c_parser
*parser
, tree list
)
13968 location_t hint_loc
= c_parser_peek_token (parser
)->location
;
13969 matching_parens parens
;
13970 if (parens
.require_open (parser
))
13972 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
13973 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
13974 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
13975 tree c
, t
= expr
.value
;
13976 t
= c_fully_fold (t
, false, NULL
);
13977 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
13979 c_parser_error (parser
, "expected integer expression");
13982 parens
.skip_until_found_close (parser
);
13983 check_no_duplicate_clause (list
, OMP_CLAUSE_FILTER
, "filter");
13985 c
= build_omp_clause (hint_loc
, OMP_CLAUSE_FILTER
);
13986 OMP_CLAUSE_FILTER_EXPR (c
) = t
;
13987 OMP_CLAUSE_CHAIN (c
) = list
;
13995 defaultmap ( tofrom : scalar )
13998 defaultmap ( implicit-behavior [ : variable-category ] ) */
14001 c_parser_omp_clause_defaultmap (c_parser
*parser
, tree list
)
14003 location_t loc
= c_parser_peek_token (parser
)->location
;
14006 enum omp_clause_defaultmap_kind behavior
= OMP_CLAUSE_DEFAULTMAP_DEFAULT
;
14007 enum omp_clause_defaultmap_kind category
14008 = OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
;
14010 matching_parens parens
;
14011 if (!parens
.require_open (parser
))
14013 if (c_parser_next_token_is_keyword (parser
, RID_DEFAULT
))
14015 else if (!c_parser_next_token_is (parser
, CPP_NAME
))
14018 c_parser_error (parser
, "expected %<alloc%>, %<to%>, %<from%>, "
14019 "%<tofrom%>, %<firstprivate%>, %<none%> "
14024 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
14029 if (strcmp ("alloc", p
) == 0)
14030 behavior
= OMP_CLAUSE_DEFAULTMAP_ALLOC
;
14032 goto invalid_behavior
;
14036 if (strcmp ("default", p
) == 0)
14037 behavior
= OMP_CLAUSE_DEFAULTMAP_DEFAULT
;
14039 goto invalid_behavior
;
14043 if (strcmp ("firstprivate", p
) == 0)
14044 behavior
= OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE
;
14045 else if (strcmp ("from", p
) == 0)
14046 behavior
= OMP_CLAUSE_DEFAULTMAP_FROM
;
14048 goto invalid_behavior
;
14052 if (strcmp ("none", p
) == 0)
14053 behavior
= OMP_CLAUSE_DEFAULTMAP_NONE
;
14055 goto invalid_behavior
;
14059 if (strcmp ("tofrom", p
) == 0)
14060 behavior
= OMP_CLAUSE_DEFAULTMAP_TOFROM
;
14061 else if (strcmp ("to", p
) == 0)
14062 behavior
= OMP_CLAUSE_DEFAULTMAP_TO
;
14064 goto invalid_behavior
;
14068 goto invalid_behavior
;
14070 c_parser_consume_token (parser
);
14072 if (!c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
14074 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
14076 if (!c_parser_next_token_is (parser
, CPP_NAME
))
14079 c_parser_error (parser
, "expected %<scalar%>, %<aggregate%> or "
14083 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
14087 if (strcmp ("aggregate", p
) == 0)
14088 category
= OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE
;
14090 goto invalid_category
;
14094 if (strcmp ("pointer", p
) == 0)
14095 category
= OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER
;
14097 goto invalid_category
;
14101 if (strcmp ("scalar", p
) == 0)
14102 category
= OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR
;
14104 goto invalid_category
;
14108 goto invalid_category
;
14111 c_parser_consume_token (parser
);
14113 parens
.skip_until_found_close (parser
);
14115 for (c
= list
; c
; c
= OMP_CLAUSE_CHAIN (c
))
14116 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEFAULTMAP
14117 && (category
== OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
14118 || OMP_CLAUSE_DEFAULTMAP_CATEGORY (c
) == category
14119 || (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c
)
14120 == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
)))
14122 enum omp_clause_defaultmap_kind cat
= category
;
14123 location_t loc
= OMP_CLAUSE_LOCATION (c
);
14124 if (cat
== OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
)
14125 cat
= OMP_CLAUSE_DEFAULTMAP_CATEGORY (c
);
14129 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
:
14132 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE
:
14135 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER
:
14138 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR
:
14142 gcc_unreachable ();
14145 error_at (loc
, "too many %<defaultmap%> clauses with %qs category",
14148 error_at (loc
, "too many %<defaultmap%> clauses with unspecified "
14153 c
= build_omp_clause (loc
, OMP_CLAUSE_DEFAULTMAP
);
14154 OMP_CLAUSE_DEFAULTMAP_SET_KIND (c
, behavior
, category
);
14155 OMP_CLAUSE_CHAIN (c
) = list
;
14159 parens
.skip_until_found_close (parser
);
14164 use_device ( variable-list )
14167 use_device_ptr ( variable-list ) */
14170 c_parser_omp_clause_use_device_ptr (c_parser
*parser
, tree list
)
14172 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_USE_DEVICE_PTR
,
14177 use_device_addr ( variable-list ) */
14180 c_parser_omp_clause_use_device_addr (c_parser
*parser
, tree list
)
14182 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_USE_DEVICE_ADDR
,
14187 is_device_ptr ( variable-list ) */
14190 c_parser_omp_clause_is_device_ptr (c_parser
*parser
, tree list
)
14192 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_IS_DEVICE_PTR
, list
);
14196 num_gangs ( expression )
14197 num_workers ( expression )
14198 vector_length ( expression ) */
14201 c_parser_oacc_single_int_clause (c_parser
*parser
, omp_clause_code code
,
14204 location_t loc
= c_parser_peek_token (parser
)->location
;
14206 matching_parens parens
;
14207 if (!parens
.require_open (parser
))
14210 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
14211 c_expr expr
= c_parser_expression (parser
);
14212 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
14213 tree c
, t
= expr
.value
;
14214 t
= c_fully_fold (t
, false, NULL
);
14216 parens
.skip_until_found_close (parser
);
14218 if (t
== error_mark_node
)
14220 else if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
14222 error_at (expr_loc
, "%qs expression must be integral",
14223 omp_clause_code_name
[code
]);
14227 /* Attempt to statically determine when the number isn't positive. */
14228 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
14229 build_int_cst (TREE_TYPE (t
), 0));
14230 protected_set_expr_location (c
, expr_loc
);
14231 if (c
== boolean_true_node
)
14233 warning_at (expr_loc
, 0,
14234 "%qs value must be positive",
14235 omp_clause_code_name
[code
]);
14236 t
= integer_one_node
;
14239 check_no_duplicate_clause (list
, code
, omp_clause_code_name
[code
]);
14241 c
= build_omp_clause (loc
, code
);
14242 OMP_CLAUSE_OPERAND (c
, 0) = t
;
14243 OMP_CLAUSE_CHAIN (c
) = list
;
14249 gang [( gang-arg-list )]
14250 worker [( [num:] int-expr )]
14251 vector [( [length:] int-expr )]
14253 where gang-arg is one of:
14258 and size-expr may be:
14265 c_parser_oacc_shape_clause (c_parser
*parser
, location_t loc
,
14266 omp_clause_code kind
,
14267 const char *str
, tree list
)
14269 const char *id
= "num";
14270 tree ops
[2] = { NULL_TREE
, NULL_TREE
}, c
;
14272 if (kind
== OMP_CLAUSE_VECTOR
)
14275 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
14277 c_parser_consume_token (parser
);
14281 c_token
*next
= c_parser_peek_token (parser
);
14284 /* Gang static argument. */
14285 if (kind
== OMP_CLAUSE_GANG
14286 && c_parser_next_token_is_keyword (parser
, RID_STATIC
))
14288 c_parser_consume_token (parser
);
14290 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
14291 goto cleanup_error
;
14294 if (ops
[idx
] != NULL_TREE
)
14296 c_parser_error (parser
, "too many %<static%> arguments");
14297 goto cleanup_error
;
14300 /* Check for the '*' argument. */
14301 if (c_parser_next_token_is (parser
, CPP_MULT
)
14302 && (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
14303 || c_parser_peek_2nd_token (parser
)->type
14304 == CPP_CLOSE_PAREN
))
14306 c_parser_consume_token (parser
);
14307 ops
[idx
] = integer_minus_one_node
;
14309 if (c_parser_next_token_is (parser
, CPP_COMMA
))
14311 c_parser_consume_token (parser
);
14318 /* Worker num: argument and vector length: arguments. */
14319 else if (c_parser_next_token_is (parser
, CPP_NAME
)
14320 && strcmp (id
, IDENTIFIER_POINTER (next
->value
)) == 0
14321 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
14323 c_parser_consume_token (parser
); /* id */
14324 c_parser_consume_token (parser
); /* ':' */
14327 /* Now collect the actual argument. */
14328 if (ops
[idx
] != NULL_TREE
)
14330 c_parser_error (parser
, "unexpected argument");
14331 goto cleanup_error
;
14334 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
14335 c_expr cexpr
= c_parser_expr_no_commas (parser
, NULL
);
14336 cexpr
= convert_lvalue_to_rvalue (expr_loc
, cexpr
, false, true);
14337 tree expr
= cexpr
.value
;
14338 if (expr
== error_mark_node
)
14339 goto cleanup_error
;
14341 expr
= c_fully_fold (expr
, false, NULL
);
14343 /* Attempt to statically determine when the number isn't a
14344 positive integer. */
14346 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr
)))
14348 c_parser_error (parser
, "expected integer expression");
14352 tree c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, expr
,
14353 build_int_cst (TREE_TYPE (expr
), 0));
14354 if (c
== boolean_true_node
)
14356 warning_at (loc
, 0,
14357 "%qs value must be positive", str
);
14358 expr
= integer_one_node
;
14363 if (kind
== OMP_CLAUSE_GANG
14364 && c_parser_next_token_is (parser
, CPP_COMMA
))
14366 c_parser_consume_token (parser
);
14373 if (!c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
14374 goto cleanup_error
;
14377 check_no_duplicate_clause (list
, kind
, str
);
14379 c
= build_omp_clause (loc
, kind
);
14382 OMP_CLAUSE_OPERAND (c
, 1) = ops
[1];
14384 OMP_CLAUSE_OPERAND (c
, 0) = ops
[0];
14385 OMP_CLAUSE_CHAIN (c
) = list
;
14390 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, 0);
14402 c_parser_oacc_simple_clause (location_t loc
, enum omp_clause_code code
,
14405 check_no_duplicate_clause (list
, code
, omp_clause_code_name
[code
]);
14407 tree c
= build_omp_clause (loc
, code
);
14408 OMP_CLAUSE_CHAIN (c
) = list
;
14414 async [( int-expr )] */
14417 c_parser_oacc_clause_async (c_parser
*parser
, tree list
)
14420 location_t loc
= c_parser_peek_token (parser
)->location
;
14422 t
= build_int_cst (integer_type_node
, GOMP_ASYNC_NOVAL
);
14424 if (c_parser_peek_token (parser
)->type
== CPP_OPEN_PAREN
)
14426 c_parser_consume_token (parser
);
14428 t
= c_parser_expr_no_commas (parser
, NULL
).value
;
14429 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
14430 c_parser_error (parser
, "expected integer expression");
14431 else if (t
== error_mark_node
14432 || !c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
14436 t
= c_fully_fold (t
, false, NULL
);
14438 check_no_duplicate_clause (list
, OMP_CLAUSE_ASYNC
, "async");
14440 c
= build_omp_clause (loc
, OMP_CLAUSE_ASYNC
);
14441 OMP_CLAUSE_ASYNC_EXPR (c
) = t
;
14442 OMP_CLAUSE_CHAIN (c
) = list
;
14449 tile ( size-expr-list ) */
14452 c_parser_oacc_clause_tile (c_parser
*parser
, tree list
)
14454 tree c
, expr
= error_mark_node
;
14456 tree tile
= NULL_TREE
;
14458 check_no_duplicate_clause (list
, OMP_CLAUSE_TILE
, "tile");
14459 check_no_duplicate_clause (list
, OMP_CLAUSE_COLLAPSE
, "collapse");
14461 loc
= c_parser_peek_token (parser
)->location
;
14462 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
14467 if (tile
&& !c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
14470 if (c_parser_next_token_is (parser
, CPP_MULT
)
14471 && (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
14472 || c_parser_peek_2nd_token (parser
)->type
== CPP_CLOSE_PAREN
))
14474 c_parser_consume_token (parser
);
14475 expr
= integer_zero_node
;
14479 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
14480 c_expr cexpr
= c_parser_expr_no_commas (parser
, NULL
);
14481 cexpr
= convert_lvalue_to_rvalue (expr_loc
, cexpr
, false, true);
14482 expr
= cexpr
.value
;
14484 if (expr
== error_mark_node
)
14486 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
14491 expr
= c_fully_fold (expr
, false, NULL
);
14493 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr
))
14494 || !tree_fits_shwi_p (expr
)
14495 || tree_to_shwi (expr
) <= 0)
14497 error_at (expr_loc
, "%<tile%> argument needs positive"
14498 " integral constant");
14499 expr
= integer_zero_node
;
14503 tile
= tree_cons (NULL_TREE
, expr
, tile
);
14505 while (c_parser_next_token_is_not (parser
, CPP_CLOSE_PAREN
));
14507 /* Consume the trailing ')'. */
14508 c_parser_consume_token (parser
);
14510 c
= build_omp_clause (loc
, OMP_CLAUSE_TILE
);
14511 tile
= nreverse (tile
);
14512 OMP_CLAUSE_TILE_LIST (c
) = tile
;
14513 OMP_CLAUSE_CHAIN (c
) = list
;
14518 wait [( int-expr-list )] */
14521 c_parser_oacc_clause_wait (c_parser
*parser
, tree list
)
14523 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
14525 if (c_parser_peek_token (parser
)->type
== CPP_OPEN_PAREN
)
14526 list
= c_parser_oacc_wait_list (parser
, clause_loc
, list
);
14529 tree c
= build_omp_clause (clause_loc
, OMP_CLAUSE_WAIT
);
14531 OMP_CLAUSE_DECL (c
) = build_int_cst (integer_type_node
, GOMP_ASYNC_NOVAL
);
14532 OMP_CLAUSE_CHAIN (c
) = list
;
14541 order ( concurrent ) */
14544 c_parser_omp_clause_order (c_parser
*parser
, tree list
)
14546 location_t loc
= c_parser_peek_token (parser
)->location
;
14550 matching_parens parens
;
14551 if (!parens
.require_open (parser
))
14553 if (!c_parser_next_token_is (parser
, CPP_NAME
))
14555 c_parser_error (parser
, "expected %<concurrent%>");
14558 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
14559 if (strcmp (p
, "concurrent") != 0)
14561 c_parser_error (parser
, "expected %<concurrent%>");
14564 c_parser_consume_token (parser
);
14565 parens
.skip_until_found_close (parser
);
14566 /* check_no_duplicate_clause (list, OMP_CLAUSE_ORDER, "order"); */
14567 c
= build_omp_clause (loc
, OMP_CLAUSE_ORDER
);
14568 OMP_CLAUSE_CHAIN (c
) = list
;
14572 parens
.skip_until_found_close (parser
);
14578 bind ( teams | parallel | thread ) */
14581 c_parser_omp_clause_bind (c_parser
*parser
, tree list
)
14583 location_t loc
= c_parser_peek_token (parser
)->location
;
14586 enum omp_clause_bind_kind kind
= OMP_CLAUSE_BIND_THREAD
;
14588 matching_parens parens
;
14589 if (!parens
.require_open (parser
))
14591 if (!c_parser_next_token_is (parser
, CPP_NAME
))
14594 c_parser_error (parser
,
14595 "expected %<teams%>, %<parallel%> or %<thread%>");
14596 parens
.skip_until_found_close (parser
);
14599 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
14600 if (strcmp (p
, "teams") == 0)
14601 kind
= OMP_CLAUSE_BIND_TEAMS
;
14602 else if (strcmp (p
, "parallel") == 0)
14603 kind
= OMP_CLAUSE_BIND_PARALLEL
;
14604 else if (strcmp (p
, "thread") != 0)
14606 c_parser_consume_token (parser
);
14607 parens
.skip_until_found_close (parser
);
14608 /* check_no_duplicate_clause (list, OMP_CLAUSE_BIND, "bind"); */
14609 c
= build_omp_clause (loc
, OMP_CLAUSE_BIND
);
14610 OMP_CLAUSE_BIND_KIND (c
) = kind
;
14611 OMP_CLAUSE_CHAIN (c
) = list
;
14620 ordered ( constant-expression ) */
14623 c_parser_omp_clause_ordered (c_parser
*parser
, tree list
)
14625 check_no_duplicate_clause (list
, OMP_CLAUSE_ORDERED
, "ordered");
14627 tree c
, num
= NULL_TREE
;
14629 location_t loc
= c_parser_peek_token (parser
)->location
;
14630 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
14632 matching_parens parens
;
14633 parens
.consume_open (parser
);
14634 num
= c_parser_expr_no_commas (parser
, NULL
).value
;
14635 parens
.skip_until_found_close (parser
);
14637 if (num
== error_mark_node
)
14641 mark_exp_read (num
);
14642 num
= c_fully_fold (num
, false, NULL
);
14643 if (!INTEGRAL_TYPE_P (TREE_TYPE (num
))
14644 || !tree_fits_shwi_p (num
)
14645 || (n
= tree_to_shwi (num
)) <= 0
14648 error_at (loc
, "ordered argument needs positive "
14649 "constant integer expression");
14653 c
= build_omp_clause (loc
, OMP_CLAUSE_ORDERED
);
14654 OMP_CLAUSE_ORDERED_EXPR (c
) = num
;
14655 OMP_CLAUSE_CHAIN (c
) = list
;
14660 private ( variable-list ) */
14663 c_parser_omp_clause_private (c_parser
*parser
, tree list
)
14665 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_PRIVATE
, list
);
14669 reduction ( reduction-operator : variable-list )
14671 reduction-operator:
14672 One of: + * - & ^ | && ||
14676 reduction-operator:
14677 One of: + * - & ^ | && || max min
14681 reduction-operator:
14682 One of: + * - & ^ | && ||
14686 reduction ( reduction-modifier, reduction-operator : variable-list )
14687 in_reduction ( reduction-operator : variable-list )
14688 task_reduction ( reduction-operator : variable-list ) */
14691 c_parser_omp_clause_reduction (c_parser
*parser
, enum omp_clause_code kind
,
14692 bool is_omp
, tree list
)
14694 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
14695 matching_parens parens
;
14696 if (parens
.require_open (parser
))
14699 bool inscan
= false;
14700 enum tree_code code
= ERROR_MARK
;
14701 tree reduc_id
= NULL_TREE
;
14703 if (kind
== OMP_CLAUSE_REDUCTION
&& is_omp
)
14705 if (c_parser_next_token_is_keyword (parser
, RID_DEFAULT
)
14706 && c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
)
14708 c_parser_consume_token (parser
);
14709 c_parser_consume_token (parser
);
14711 else if (c_parser_next_token_is (parser
, CPP_NAME
)
14712 && c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
)
14715 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
14716 if (strcmp (p
, "task") == 0)
14718 else if (strcmp (p
, "inscan") == 0)
14720 if (task
|| inscan
)
14722 c_parser_consume_token (parser
);
14723 c_parser_consume_token (parser
);
14728 switch (c_parser_peek_token (parser
)->type
)
14740 code
= BIT_AND_EXPR
;
14743 code
= BIT_XOR_EXPR
;
14746 code
= BIT_IOR_EXPR
;
14749 code
= TRUTH_ANDIF_EXPR
;
14752 code
= TRUTH_ORIF_EXPR
;
14757 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
14758 if (strcmp (p
, "min") == 0)
14763 if (strcmp (p
, "max") == 0)
14768 reduc_id
= c_parser_peek_token (parser
)->value
;
14772 c_parser_error (parser
,
14773 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
14774 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
14775 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, 0);
14778 c_parser_consume_token (parser
);
14779 reduc_id
= c_omp_reduction_id (code
, reduc_id
);
14780 if (c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
14784 nl
= c_parser_omp_variable_list (parser
, clause_loc
, kind
, list
);
14785 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
14787 tree d
= OMP_CLAUSE_DECL (c
), type
;
14788 if (TREE_CODE (d
) != TREE_LIST
)
14789 type
= TREE_TYPE (d
);
14794 for (t
= d
; TREE_CODE (t
) == TREE_LIST
; t
= TREE_CHAIN (t
))
14796 type
= TREE_TYPE (t
);
14799 if (TREE_CODE (type
) != POINTER_TYPE
14800 && TREE_CODE (type
) != ARRAY_TYPE
)
14802 type
= TREE_TYPE (type
);
14806 while (TREE_CODE (type
) == ARRAY_TYPE
)
14807 type
= TREE_TYPE (type
);
14808 OMP_CLAUSE_REDUCTION_CODE (c
) = code
;
14810 OMP_CLAUSE_REDUCTION_TASK (c
) = 1;
14812 OMP_CLAUSE_REDUCTION_INSCAN (c
) = 1;
14813 if (code
== ERROR_MARK
14814 || !(INTEGRAL_TYPE_P (type
)
14815 || TREE_CODE (type
) == REAL_TYPE
14816 || TREE_CODE (type
) == COMPLEX_TYPE
))
14817 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
)
14818 = c_omp_reduction_lookup (reduc_id
,
14819 TYPE_MAIN_VARIANT (type
));
14824 parens
.skip_until_found_close (parser
);
14830 schedule ( schedule-kind )
14831 schedule ( schedule-kind , expression )
14834 static | dynamic | guided | runtime | auto
14837 schedule ( schedule-modifier : schedule-kind )
14838 schedule ( schedule-modifier [ , schedule-modifier ] : schedule-kind , expression )
14846 c_parser_omp_clause_schedule (c_parser
*parser
, tree list
)
14849 location_t loc
= c_parser_peek_token (parser
)->location
;
14850 int modifiers
= 0, nmodifiers
= 0;
14852 matching_parens parens
;
14853 if (!parens
.require_open (parser
))
14856 c
= build_omp_clause (loc
, OMP_CLAUSE_SCHEDULE
);
14858 location_t comma
= UNKNOWN_LOCATION
;
14859 while (c_parser_next_token_is (parser
, CPP_NAME
))
14861 tree kind
= c_parser_peek_token (parser
)->value
;
14862 const char *p
= IDENTIFIER_POINTER (kind
);
14863 if (strcmp ("simd", p
) == 0)
14864 OMP_CLAUSE_SCHEDULE_SIMD (c
) = 1;
14865 else if (strcmp ("monotonic", p
) == 0)
14866 modifiers
|= OMP_CLAUSE_SCHEDULE_MONOTONIC
;
14867 else if (strcmp ("nonmonotonic", p
) == 0)
14868 modifiers
|= OMP_CLAUSE_SCHEDULE_NONMONOTONIC
;
14871 comma
= UNKNOWN_LOCATION
;
14872 c_parser_consume_token (parser
);
14873 if (nmodifiers
++ == 0
14874 && c_parser_next_token_is (parser
, CPP_COMMA
))
14876 comma
= c_parser_peek_token (parser
)->location
;
14877 c_parser_consume_token (parser
);
14881 c_parser_require (parser
, CPP_COLON
, "expected %<:%>");
14885 if (comma
!= UNKNOWN_LOCATION
)
14886 error_at (comma
, "expected %<:%>");
14888 if ((modifiers
& (OMP_CLAUSE_SCHEDULE_MONOTONIC
14889 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC
))
14890 == (OMP_CLAUSE_SCHEDULE_MONOTONIC
14891 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC
))
14893 error_at (loc
, "both %<monotonic%> and %<nonmonotonic%> modifiers "
14898 if (c_parser_next_token_is (parser
, CPP_NAME
))
14900 tree kind
= c_parser_peek_token (parser
)->value
;
14901 const char *p
= IDENTIFIER_POINTER (kind
);
14906 if (strcmp ("dynamic", p
) != 0)
14908 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_DYNAMIC
;
14912 if (strcmp ("guided", p
) != 0)
14914 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_GUIDED
;
14918 if (strcmp ("runtime", p
) != 0)
14920 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_RUNTIME
;
14927 else if (c_parser_next_token_is_keyword (parser
, RID_STATIC
))
14928 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_STATIC
;
14929 else if (c_parser_next_token_is_keyword (parser
, RID_AUTO
))
14930 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_AUTO
;
14934 c_parser_consume_token (parser
);
14935 if (c_parser_next_token_is (parser
, CPP_COMMA
))
14938 c_parser_consume_token (parser
);
14940 here
= c_parser_peek_token (parser
)->location
;
14941 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
14942 expr
= convert_lvalue_to_rvalue (here
, expr
, false, true);
14944 t
= c_fully_fold (t
, false, NULL
);
14946 if (OMP_CLAUSE_SCHEDULE_KIND (c
) == OMP_CLAUSE_SCHEDULE_RUNTIME
)
14947 error_at (here
, "schedule %<runtime%> does not take "
14948 "a %<chunk_size%> parameter");
14949 else if (OMP_CLAUSE_SCHEDULE_KIND (c
) == OMP_CLAUSE_SCHEDULE_AUTO
)
14951 "schedule %<auto%> does not take "
14952 "a %<chunk_size%> parameter");
14953 else if (TREE_CODE (TREE_TYPE (t
)) == INTEGER_TYPE
)
14955 /* Attempt to statically determine when the number isn't
14957 tree s
= fold_build2_loc (loc
, LE_EXPR
, boolean_type_node
, t
,
14958 build_int_cst (TREE_TYPE (t
), 0));
14959 protected_set_expr_location (s
, loc
);
14960 if (s
== boolean_true_node
)
14962 warning_at (loc
, 0,
14963 "chunk size value must be positive");
14964 t
= integer_one_node
;
14966 OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c
) = t
;
14969 c_parser_error (parser
, "expected integer expression");
14971 parens
.skip_until_found_close (parser
);
14974 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
14975 "expected %<,%> or %<)%>");
14977 OMP_CLAUSE_SCHEDULE_KIND (c
)
14978 = (enum omp_clause_schedule_kind
)
14979 (OMP_CLAUSE_SCHEDULE_KIND (c
) | modifiers
);
14981 check_no_duplicate_clause (list
, OMP_CLAUSE_SCHEDULE
, "schedule");
14982 OMP_CLAUSE_CHAIN (c
) = list
;
14986 c_parser_error (parser
, "invalid schedule kind");
14987 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, 0);
14992 shared ( variable-list ) */
14995 c_parser_omp_clause_shared (c_parser
*parser
, tree list
)
14997 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_SHARED
, list
);
15004 c_parser_omp_clause_untied (c_parser
*parser ATTRIBUTE_UNUSED
, tree list
)
15008 /* FIXME: Should we allow duplicates? */
15009 check_no_duplicate_clause (list
, OMP_CLAUSE_UNTIED
, "untied");
15011 c
= build_omp_clause (c_parser_peek_token (parser
)->location
,
15012 OMP_CLAUSE_UNTIED
);
15013 OMP_CLAUSE_CHAIN (c
) = list
;
15023 c_parser_omp_clause_branch (c_parser
*parser ATTRIBUTE_UNUSED
,
15024 enum omp_clause_code code
, tree list
)
15026 check_no_duplicate_clause (list
, code
, omp_clause_code_name
[code
]);
15028 tree c
= build_omp_clause (c_parser_peek_token (parser
)->location
, code
);
15029 OMP_CLAUSE_CHAIN (c
) = list
;
15041 c_parser_omp_clause_cancelkind (c_parser
*parser ATTRIBUTE_UNUSED
,
15042 enum omp_clause_code code
, tree list
)
15044 tree c
= build_omp_clause (c_parser_peek_token (parser
)->location
, code
);
15045 OMP_CLAUSE_CHAIN (c
) = list
;
15054 c_parser_omp_clause_nogroup (c_parser
*parser ATTRIBUTE_UNUSED
, tree list
)
15056 check_no_duplicate_clause (list
, OMP_CLAUSE_NOGROUP
, "nogroup");
15057 tree c
= build_omp_clause (c_parser_peek_token (parser
)->location
,
15058 OMP_CLAUSE_NOGROUP
);
15059 OMP_CLAUSE_CHAIN (c
) = list
;
15068 c_parser_omp_clause_orderedkind (c_parser
*parser ATTRIBUTE_UNUSED
,
15069 enum omp_clause_code code
, tree list
)
15071 check_no_duplicate_clause (list
, code
, omp_clause_code_name
[code
]);
15072 tree c
= build_omp_clause (c_parser_peek_token (parser
)->location
, code
);
15073 OMP_CLAUSE_CHAIN (c
) = list
;
15078 num_teams ( expression ) */
15081 c_parser_omp_clause_num_teams (c_parser
*parser
, tree list
)
15083 location_t num_teams_loc
= c_parser_peek_token (parser
)->location
;
15084 matching_parens parens
;
15085 if (parens
.require_open (parser
))
15087 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
15088 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15089 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
15090 tree c
, t
= expr
.value
;
15091 t
= c_fully_fold (t
, false, NULL
);
15093 parens
.skip_until_found_close (parser
);
15095 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
15097 c_parser_error (parser
, "expected integer expression");
15101 /* Attempt to statically determine when the number isn't positive. */
15102 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
15103 build_int_cst (TREE_TYPE (t
), 0));
15104 protected_set_expr_location (c
, expr_loc
);
15105 if (c
== boolean_true_node
)
15107 warning_at (expr_loc
, 0, "%<num_teams%> value must be positive");
15108 t
= integer_one_node
;
15111 check_no_duplicate_clause (list
, OMP_CLAUSE_NUM_TEAMS
, "num_teams");
15113 c
= build_omp_clause (num_teams_loc
, OMP_CLAUSE_NUM_TEAMS
);
15114 OMP_CLAUSE_NUM_TEAMS_EXPR (c
) = t
;
15115 OMP_CLAUSE_CHAIN (c
) = list
;
15123 thread_limit ( expression ) */
15126 c_parser_omp_clause_thread_limit (c_parser
*parser
, tree list
)
15128 location_t num_thread_limit_loc
= c_parser_peek_token (parser
)->location
;
15129 matching_parens parens
;
15130 if (parens
.require_open (parser
))
15132 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
15133 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15134 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
15135 tree c
, t
= expr
.value
;
15136 t
= c_fully_fold (t
, false, NULL
);
15138 parens
.skip_until_found_close (parser
);
15140 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
15142 c_parser_error (parser
, "expected integer expression");
15146 /* Attempt to statically determine when the number isn't positive. */
15147 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
15148 build_int_cst (TREE_TYPE (t
), 0));
15149 protected_set_expr_location (c
, expr_loc
);
15150 if (c
== boolean_true_node
)
15152 warning_at (expr_loc
, 0, "%<thread_limit%> value must be positive");
15153 t
= integer_one_node
;
15156 check_no_duplicate_clause (list
, OMP_CLAUSE_THREAD_LIMIT
,
15159 c
= build_omp_clause (num_thread_limit_loc
, OMP_CLAUSE_THREAD_LIMIT
);
15160 OMP_CLAUSE_THREAD_LIMIT_EXPR (c
) = t
;
15161 OMP_CLAUSE_CHAIN (c
) = list
;
15169 aligned ( variable-list )
15170 aligned ( variable-list : constant-expression ) */
15173 c_parser_omp_clause_aligned (c_parser
*parser
, tree list
)
15175 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
15178 matching_parens parens
;
15179 if (!parens
.require_open (parser
))
15182 nl
= c_parser_omp_variable_list (parser
, clause_loc
,
15183 OMP_CLAUSE_ALIGNED
, list
);
15185 if (c_parser_next_token_is (parser
, CPP_COLON
))
15187 c_parser_consume_token (parser
);
15188 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
15189 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15190 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
15191 tree alignment
= expr
.value
;
15192 alignment
= c_fully_fold (alignment
, false, NULL
);
15193 if (TREE_CODE (alignment
) != INTEGER_CST
15194 || !INTEGRAL_TYPE_P (TREE_TYPE (alignment
))
15195 || tree_int_cst_sgn (alignment
) != 1)
15197 error_at (clause_loc
, "%<aligned%> clause alignment expression must "
15198 "be positive constant integer expression");
15199 alignment
= NULL_TREE
;
15202 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
15203 OMP_CLAUSE_ALIGNED_ALIGNMENT (c
) = alignment
;
15206 parens
.skip_until_found_close (parser
);
15211 allocate ( variable-list )
15212 allocate ( expression : variable-list ) */
15215 c_parser_omp_clause_allocate (c_parser
*parser
, tree list
)
15217 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
15219 tree allocator
= NULL_TREE
;
15221 matching_parens parens
;
15222 if (!parens
.require_open (parser
))
15225 if ((c_parser_next_token_is_not (parser
, CPP_NAME
)
15226 && c_parser_next_token_is_not (parser
, CPP_KEYWORD
))
15227 || (c_parser_peek_2nd_token (parser
)->type
!= CPP_COMMA
15228 && c_parser_peek_2nd_token (parser
)->type
!= CPP_CLOSE_PAREN
))
15230 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
15231 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15232 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
15233 allocator
= expr
.value
;
15234 allocator
= c_fully_fold (allocator
, false, NULL
);
15236 = expr
.original_type
? expr
.original_type
: TREE_TYPE (allocator
);
15237 orig_type
= TYPE_MAIN_VARIANT (orig_type
);
15238 if (!INTEGRAL_TYPE_P (TREE_TYPE (allocator
))
15239 || TREE_CODE (orig_type
) != ENUMERAL_TYPE
15240 || TYPE_NAME (orig_type
) != get_identifier ("omp_allocator_handle_t"))
15242 error_at (clause_loc
, "%<allocate%> clause allocator expression "
15243 "has type %qT rather than "
15244 "%<omp_allocator_handle_t%>",
15245 TREE_TYPE (allocator
));
15246 allocator
= NULL_TREE
;
15248 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
15250 parens
.skip_until_found_close (parser
);
15255 nl
= c_parser_omp_variable_list (parser
, clause_loc
,
15256 OMP_CLAUSE_ALLOCATE
, list
);
15259 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
15260 OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
) = allocator
;
15262 parens
.skip_until_found_close (parser
);
15267 linear ( variable-list )
15268 linear ( variable-list : expression )
15271 linear ( modifier ( variable-list ) )
15272 linear ( modifier ( variable-list ) : expression ) */
15275 c_parser_omp_clause_linear (c_parser
*parser
, tree list
)
15277 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
15279 enum omp_clause_linear_kind kind
= OMP_CLAUSE_LINEAR_DEFAULT
;
15281 matching_parens parens
;
15282 if (!parens
.require_open (parser
))
15285 if (c_parser_next_token_is (parser
, CPP_NAME
))
15287 c_token
*tok
= c_parser_peek_token (parser
);
15288 const char *p
= IDENTIFIER_POINTER (tok
->value
);
15289 if (strcmp ("val", p
) == 0)
15290 kind
= OMP_CLAUSE_LINEAR_VAL
;
15291 if (c_parser_peek_2nd_token (parser
)->type
!= CPP_OPEN_PAREN
)
15292 kind
= OMP_CLAUSE_LINEAR_DEFAULT
;
15293 if (kind
!= OMP_CLAUSE_LINEAR_DEFAULT
)
15295 c_parser_consume_token (parser
);
15296 c_parser_consume_token (parser
);
15300 nl
= c_parser_omp_variable_list (parser
, clause_loc
,
15301 OMP_CLAUSE_LINEAR
, list
);
15303 if (kind
!= OMP_CLAUSE_LINEAR_DEFAULT
)
15304 parens
.skip_until_found_close (parser
);
15306 if (c_parser_next_token_is (parser
, CPP_COLON
))
15308 c_parser_consume_token (parser
);
15309 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
15310 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15311 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
15313 step
= c_fully_fold (step
, false, NULL
);
15314 if (!INTEGRAL_TYPE_P (TREE_TYPE (step
)))
15316 error_at (clause_loc
, "%<linear%> clause step expression must "
15318 step
= integer_one_node
;
15323 step
= integer_one_node
;
15325 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
15327 OMP_CLAUSE_LINEAR_STEP (c
) = step
;
15328 OMP_CLAUSE_LINEAR_KIND (c
) = kind
;
15331 parens
.skip_until_found_close (parser
);
15336 nontemporal ( variable-list ) */
15339 c_parser_omp_clause_nontemporal (c_parser
*parser
, tree list
)
15341 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_NONTEMPORAL
, list
);
15345 safelen ( constant-expression ) */
15348 c_parser_omp_clause_safelen (c_parser
*parser
, tree list
)
15350 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
15353 matching_parens parens
;
15354 if (!parens
.require_open (parser
))
15357 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
15358 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15359 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
15361 t
= c_fully_fold (t
, false, NULL
);
15362 if (TREE_CODE (t
) != INTEGER_CST
15363 || !INTEGRAL_TYPE_P (TREE_TYPE (t
))
15364 || tree_int_cst_sgn (t
) != 1)
15366 error_at (clause_loc
, "%<safelen%> clause expression must "
15367 "be positive constant integer expression");
15371 parens
.skip_until_found_close (parser
);
15372 if (t
== NULL_TREE
|| t
== error_mark_node
)
15375 check_no_duplicate_clause (list
, OMP_CLAUSE_SAFELEN
, "safelen");
15377 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_SAFELEN
);
15378 OMP_CLAUSE_SAFELEN_EXPR (c
) = t
;
15379 OMP_CLAUSE_CHAIN (c
) = list
;
15384 simdlen ( constant-expression ) */
15387 c_parser_omp_clause_simdlen (c_parser
*parser
, tree list
)
15389 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
15392 matching_parens parens
;
15393 if (!parens
.require_open (parser
))
15396 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
15397 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15398 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
15400 t
= c_fully_fold (t
, false, NULL
);
15401 if (TREE_CODE (t
) != INTEGER_CST
15402 || !INTEGRAL_TYPE_P (TREE_TYPE (t
))
15403 || tree_int_cst_sgn (t
) != 1)
15405 error_at (clause_loc
, "%<simdlen%> clause expression must "
15406 "be positive constant integer expression");
15410 parens
.skip_until_found_close (parser
);
15411 if (t
== NULL_TREE
|| t
== error_mark_node
)
15414 check_no_duplicate_clause (list
, OMP_CLAUSE_SIMDLEN
, "simdlen");
15416 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_SIMDLEN
);
15417 OMP_CLAUSE_SIMDLEN_EXPR (c
) = t
;
15418 OMP_CLAUSE_CHAIN (c
) = list
;
15424 identifier [+/- integer]
15425 vec , identifier [+/- integer]
15429 c_parser_omp_clause_depend_sink (c_parser
*parser
, location_t clause_loc
,
15433 if (c_parser_next_token_is_not (parser
, CPP_NAME
)
15434 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
15436 c_parser_error (parser
, "expected identifier");
15440 while (c_parser_next_token_is (parser
, CPP_NAME
)
15441 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
)
15443 tree t
= lookup_name (c_parser_peek_token (parser
)->value
);
15444 tree addend
= NULL
;
15446 if (t
== NULL_TREE
)
15448 undeclared_variable (c_parser_peek_token (parser
)->location
,
15449 c_parser_peek_token (parser
)->value
);
15450 t
= error_mark_node
;
15453 c_parser_consume_token (parser
);
15456 if (c_parser_next_token_is (parser
, CPP_MINUS
))
15458 else if (!c_parser_next_token_is (parser
, CPP_PLUS
))
15460 addend
= integer_zero_node
;
15462 goto add_to_vector
;
15464 c_parser_consume_token (parser
);
15466 if (c_parser_next_token_is_not (parser
, CPP_NUMBER
))
15468 c_parser_error (parser
, "expected integer");
15472 addend
= c_parser_peek_token (parser
)->value
;
15473 if (TREE_CODE (addend
) != INTEGER_CST
)
15475 c_parser_error (parser
, "expected integer");
15478 c_parser_consume_token (parser
);
15481 if (t
!= error_mark_node
)
15483 vec
= tree_cons (addend
, t
, vec
);
15485 OMP_CLAUSE_DEPEND_SINK_NEGATIVE (vec
) = 1;
15488 if (c_parser_next_token_is_not (parser
, CPP_COMMA
)
15489 || c_parser_peek_2nd_token (parser
)->type
!= CPP_NAME
15490 || c_parser_peek_2nd_token (parser
)->id_kind
!= C_ID_ID
)
15493 c_parser_consume_token (parser
);
15496 if (vec
== NULL_TREE
)
15499 tree u
= build_omp_clause (clause_loc
, OMP_CLAUSE_DEPEND
);
15500 OMP_CLAUSE_DEPEND_KIND (u
) = OMP_CLAUSE_DEPEND_SINK
;
15501 OMP_CLAUSE_DECL (u
) = nreverse (vec
);
15502 OMP_CLAUSE_CHAIN (u
) = list
;
15507 iterators ( iterators-definition )
15509 iterators-definition:
15511 iterator-specifier , iterators-definition
15513 iterator-specifier:
15514 identifier = range-specification
15515 iterator-type identifier = range-specification
15517 range-specification:
15519 begin : end : step */
15522 c_parser_omp_iterators (c_parser
*parser
)
15524 tree ret
= NULL_TREE
, *last
= &ret
;
15525 c_parser_consume_token (parser
);
15529 matching_parens parens
;
15530 if (!parens
.require_open (parser
))
15531 return error_mark_node
;
15535 tree iter_type
= NULL_TREE
, type_expr
= NULL_TREE
;
15536 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_id
))
15538 struct c_type_name
*type
= c_parser_type_name (parser
);
15540 iter_type
= groktypename (type
, &type_expr
, NULL
);
15542 if (iter_type
== NULL_TREE
)
15543 iter_type
= integer_type_node
;
15545 location_t loc
= c_parser_peek_token (parser
)->location
;
15546 if (!c_parser_next_token_is (parser
, CPP_NAME
))
15548 c_parser_error (parser
, "expected identifier");
15552 tree id
= c_parser_peek_token (parser
)->value
;
15553 c_parser_consume_token (parser
);
15555 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
15558 location_t eloc
= c_parser_peek_token (parser
)->location
;
15559 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15560 expr
= convert_lvalue_to_rvalue (eloc
, expr
, true, false);
15561 tree begin
= expr
.value
;
15563 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
15566 eloc
= c_parser_peek_token (parser
)->location
;
15567 expr
= c_parser_expr_no_commas (parser
, NULL
);
15568 expr
= convert_lvalue_to_rvalue (eloc
, expr
, true, false);
15569 tree end
= expr
.value
;
15571 tree step
= integer_one_node
;
15572 if (c_parser_next_token_is (parser
, CPP_COLON
))
15574 c_parser_consume_token (parser
);
15575 eloc
= c_parser_peek_token (parser
)->location
;
15576 expr
= c_parser_expr_no_commas (parser
, NULL
);
15577 expr
= convert_lvalue_to_rvalue (eloc
, expr
, true, false);
15581 tree iter_var
= build_decl (loc
, VAR_DECL
, id
, iter_type
);
15582 DECL_ARTIFICIAL (iter_var
) = 1;
15583 DECL_CONTEXT (iter_var
) = current_function_decl
;
15584 pushdecl (iter_var
);
15586 *last
= make_tree_vec (6);
15587 TREE_VEC_ELT (*last
, 0) = iter_var
;
15588 TREE_VEC_ELT (*last
, 1) = begin
;
15589 TREE_VEC_ELT (*last
, 2) = end
;
15590 TREE_VEC_ELT (*last
, 3) = step
;
15591 last
= &TREE_CHAIN (*last
);
15593 if (c_parser_next_token_is (parser
, CPP_COMMA
))
15595 c_parser_consume_token (parser
);
15602 parens
.skip_until_found_close (parser
);
15603 return ret
? ret
: error_mark_node
;
15607 affinity ( [aff-modifier :] variable-list )
15609 iterator ( iterators-definition ) */
15612 c_parser_omp_clause_affinity (c_parser
*parser
, tree list
)
15614 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
15615 tree nl
, iterators
= NULL_TREE
;
15617 matching_parens parens
;
15618 if (!parens
.require_open (parser
))
15621 if (c_parser_next_token_is (parser
, CPP_NAME
))
15623 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
15624 bool parse_iter
= ((strcmp ("iterator", p
) == 0)
15625 && (c_parser_peek_2nd_token (parser
)->type
15626 == CPP_OPEN_PAREN
));
15630 parse_iter
= (c_parser_check_balanced_raw_token_sequence (parser
, &n
)
15631 && (c_parser_peek_nth_token_raw (parser
, n
)->type
15632 == CPP_CLOSE_PAREN
)
15633 && (c_parser_peek_nth_token_raw (parser
, n
+ 1)->type
15638 iterators
= c_parser_omp_iterators (parser
);
15639 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
15643 parens
.skip_until_found_close (parser
);
15648 nl
= c_parser_omp_variable_list (parser
, clause_loc
, OMP_CLAUSE_AFFINITY
,
15652 tree block
= pop_scope ();
15653 if (iterators
!= error_mark_node
)
15655 TREE_VEC_ELT (iterators
, 5) = block
;
15656 for (tree c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
15657 OMP_CLAUSE_DECL (c
) = build_tree_list (iterators
,
15658 OMP_CLAUSE_DECL (c
));
15662 parens
.skip_until_found_close (parser
);
15668 depend ( depend-kind: variable-list )
15676 depend ( sink : vec )
15679 depend ( depend-modifier , depend-kind: variable-list )
15682 in | out | inout | mutexinoutset | depobj
15685 iterator ( iterators-definition ) */
15688 c_parser_omp_clause_depend (c_parser
*parser
, tree list
)
15690 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
15691 enum omp_clause_depend_kind kind
= OMP_CLAUSE_DEPEND_LAST
;
15692 tree nl
, c
, iterators
= NULL_TREE
;
15694 matching_parens parens
;
15695 if (!parens
.require_open (parser
))
15700 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
15703 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
15704 if (strcmp ("iterator", p
) == 0 && iterators
== NULL_TREE
)
15706 iterators
= c_parser_omp_iterators (parser
);
15707 c_parser_require (parser
, CPP_COMMA
, "expected %<,%>");
15710 if (strcmp ("in", p
) == 0)
15711 kind
= OMP_CLAUSE_DEPEND_IN
;
15712 else if (strcmp ("inout", p
) == 0)
15713 kind
= OMP_CLAUSE_DEPEND_INOUT
;
15714 else if (strcmp ("mutexinoutset", p
) == 0)
15715 kind
= OMP_CLAUSE_DEPEND_MUTEXINOUTSET
;
15716 else if (strcmp ("out", p
) == 0)
15717 kind
= OMP_CLAUSE_DEPEND_OUT
;
15718 else if (strcmp ("depobj", p
) == 0)
15719 kind
= OMP_CLAUSE_DEPEND_DEPOBJ
;
15720 else if (strcmp ("sink", p
) == 0)
15721 kind
= OMP_CLAUSE_DEPEND_SINK
;
15722 else if (strcmp ("source", p
) == 0)
15723 kind
= OMP_CLAUSE_DEPEND_SOURCE
;
15730 c_parser_consume_token (parser
);
15733 && (kind
== OMP_CLAUSE_DEPEND_SOURCE
|| kind
== OMP_CLAUSE_DEPEND_SINK
))
15736 error_at (clause_loc
, "%<iterator%> modifier incompatible with %qs",
15737 kind
== OMP_CLAUSE_DEPEND_SOURCE
? "source" : "sink");
15738 iterators
= NULL_TREE
;
15741 if (kind
== OMP_CLAUSE_DEPEND_SOURCE
)
15743 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_DEPEND
);
15744 OMP_CLAUSE_DEPEND_KIND (c
) = kind
;
15745 OMP_CLAUSE_DECL (c
) = NULL_TREE
;
15746 OMP_CLAUSE_CHAIN (c
) = list
;
15747 parens
.skip_until_found_close (parser
);
15751 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
15754 if (kind
== OMP_CLAUSE_DEPEND_SINK
)
15755 nl
= c_parser_omp_clause_depend_sink (parser
, clause_loc
, list
);
15758 nl
= c_parser_omp_variable_list (parser
, clause_loc
,
15759 OMP_CLAUSE_DEPEND
, list
);
15763 tree block
= pop_scope ();
15764 if (iterators
== error_mark_node
)
15765 iterators
= NULL_TREE
;
15767 TREE_VEC_ELT (iterators
, 5) = block
;
15770 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
15772 OMP_CLAUSE_DEPEND_KIND (c
) = kind
;
15774 OMP_CLAUSE_DECL (c
)
15775 = build_tree_list (iterators
, OMP_CLAUSE_DECL (c
));
15779 parens
.skip_until_found_close (parser
);
15783 c_parser_error (parser
, "invalid depend kind");
15785 parens
.skip_until_found_close (parser
);
15792 map ( map-kind: variable-list )
15793 map ( variable-list )
15796 alloc | to | from | tofrom
15800 alloc | to | from | tofrom | release | delete
15802 map ( always [,] map-kind: variable-list )
15805 map ( [map-type-modifier[,] ...] map-kind: variable-list )
15811 c_parser_omp_clause_map (c_parser
*parser
, tree list
)
15813 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
15814 enum gomp_map_kind kind
= GOMP_MAP_TOFROM
;
15817 matching_parens parens
;
15818 if (!parens
.require_open (parser
))
15822 int map_kind_pos
= 0;
15823 while (c_parser_peek_nth_token_raw (parser
, pos
)->type
== CPP_NAME
)
15825 if (c_parser_peek_nth_token_raw (parser
, pos
+ 1)->type
== CPP_COLON
)
15827 map_kind_pos
= pos
;
15831 if (c_parser_peek_nth_token_raw (parser
, pos
+ 1)->type
== CPP_COMMA
)
15836 int always_modifier
= 0;
15837 int close_modifier
= 0;
15838 for (int pos
= 1; pos
< map_kind_pos
; ++pos
)
15840 c_token
*tok
= c_parser_peek_token (parser
);
15842 if (tok
->type
== CPP_COMMA
)
15844 c_parser_consume_token (parser
);
15848 const char *p
= IDENTIFIER_POINTER (tok
->value
);
15849 if (strcmp ("always", p
) == 0)
15851 if (always_modifier
)
15853 c_parser_error (parser
, "too many %<always%> modifiers");
15854 parens
.skip_until_found_close (parser
);
15859 else if (strcmp ("close", p
) == 0)
15861 if (close_modifier
)
15863 c_parser_error (parser
, "too many %<close%> modifiers");
15864 parens
.skip_until_found_close (parser
);
15871 c_parser_error (parser
, "%<#pragma omp target%> with "
15872 "modifier other than %<always%> or %<close%>"
15873 "on %<map%> clause");
15874 parens
.skip_until_found_close (parser
);
15878 c_parser_consume_token (parser
);
15881 if (c_parser_next_token_is (parser
, CPP_NAME
)
15882 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
15884 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
15885 if (strcmp ("alloc", p
) == 0)
15886 kind
= GOMP_MAP_ALLOC
;
15887 else if (strcmp ("to", p
) == 0)
15888 kind
= always_modifier
? GOMP_MAP_ALWAYS_TO
: GOMP_MAP_TO
;
15889 else if (strcmp ("from", p
) == 0)
15890 kind
= always_modifier
? GOMP_MAP_ALWAYS_FROM
: GOMP_MAP_FROM
;
15891 else if (strcmp ("tofrom", p
) == 0)
15892 kind
= always_modifier
? GOMP_MAP_ALWAYS_TOFROM
: GOMP_MAP_TOFROM
;
15893 else if (strcmp ("release", p
) == 0)
15894 kind
= GOMP_MAP_RELEASE
;
15895 else if (strcmp ("delete", p
) == 0)
15896 kind
= GOMP_MAP_DELETE
;
15899 c_parser_error (parser
, "invalid map kind");
15900 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
15904 c_parser_consume_token (parser
);
15905 c_parser_consume_token (parser
);
15908 nl
= c_parser_omp_variable_list (parser
, clause_loc
, OMP_CLAUSE_MAP
, list
);
15910 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
15911 OMP_CLAUSE_SET_MAP_KIND (c
, kind
);
15913 parens
.skip_until_found_close (parser
);
15918 device ( expression ) */
15921 c_parser_omp_clause_device (c_parser
*parser
, tree list
)
15923 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
15924 matching_parens parens
;
15925 if (parens
.require_open (parser
))
15927 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
15928 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15929 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
15930 tree c
, t
= expr
.value
;
15931 t
= c_fully_fold (t
, false, NULL
);
15933 parens
.skip_until_found_close (parser
);
15935 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
15937 c_parser_error (parser
, "expected integer expression");
15941 check_no_duplicate_clause (list
, OMP_CLAUSE_DEVICE
, "device");
15943 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_DEVICE
);
15944 OMP_CLAUSE_DEVICE_ID (c
) = t
;
15945 OMP_CLAUSE_CHAIN (c
) = list
;
15953 dist_schedule ( static )
15954 dist_schedule ( static , expression ) */
15957 c_parser_omp_clause_dist_schedule (c_parser
*parser
, tree list
)
15959 tree c
, t
= NULL_TREE
;
15960 location_t loc
= c_parser_peek_token (parser
)->location
;
15962 matching_parens parens
;
15963 if (!parens
.require_open (parser
))
15966 if (!c_parser_next_token_is_keyword (parser
, RID_STATIC
))
15968 c_parser_error (parser
, "invalid dist_schedule kind");
15969 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
15974 c_parser_consume_token (parser
);
15975 if (c_parser_next_token_is (parser
, CPP_COMMA
))
15977 c_parser_consume_token (parser
);
15979 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
15980 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15981 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
15983 t
= c_fully_fold (t
, false, NULL
);
15984 parens
.skip_until_found_close (parser
);
15987 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
15988 "expected %<,%> or %<)%>");
15990 /* check_no_duplicate_clause (list, OMP_CLAUSE_DIST_SCHEDULE,
15991 "dist_schedule"); */
15992 if (omp_find_clause (list
, OMP_CLAUSE_DIST_SCHEDULE
))
15993 warning_at (loc
, 0, "too many %qs clauses", "dist_schedule");
15994 if (t
== error_mark_node
)
15997 c
= build_omp_clause (loc
, OMP_CLAUSE_DIST_SCHEDULE
);
15998 OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c
) = t
;
15999 OMP_CLAUSE_CHAIN (c
) = list
;
16004 proc_bind ( proc-bind-kind )
16007 primary | master | close | spread
16008 where OpenMP 5.1 added 'primary' and deprecated the alias 'master'. */
16011 c_parser_omp_clause_proc_bind (c_parser
*parser
, tree list
)
16013 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
16014 enum omp_clause_proc_bind_kind kind
;
16017 matching_parens parens
;
16018 if (!parens
.require_open (parser
))
16021 if (c_parser_next_token_is (parser
, CPP_NAME
))
16023 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
16024 if (strcmp ("primary", p
) == 0)
16025 kind
= OMP_CLAUSE_PROC_BIND_PRIMARY
;
16026 else if (strcmp ("master", p
) == 0)
16027 kind
= OMP_CLAUSE_PROC_BIND_MASTER
;
16028 else if (strcmp ("close", p
) == 0)
16029 kind
= OMP_CLAUSE_PROC_BIND_CLOSE
;
16030 else if (strcmp ("spread", p
) == 0)
16031 kind
= OMP_CLAUSE_PROC_BIND_SPREAD
;
16038 check_no_duplicate_clause (list
, OMP_CLAUSE_PROC_BIND
, "proc_bind");
16039 c_parser_consume_token (parser
);
16040 parens
.skip_until_found_close (parser
);
16041 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_PROC_BIND
);
16042 OMP_CLAUSE_PROC_BIND_KIND (c
) = kind
;
16043 OMP_CLAUSE_CHAIN (c
) = list
;
16047 c_parser_error (parser
, "invalid proc_bind kind");
16048 parens
.skip_until_found_close (parser
);
16053 device_type ( host | nohost | any ) */
16056 c_parser_omp_clause_device_type (c_parser
*parser
, tree list
)
16058 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
16059 enum omp_clause_device_type_kind kind
;
16062 matching_parens parens
;
16063 if (!parens
.require_open (parser
))
16066 if (c_parser_next_token_is (parser
, CPP_NAME
))
16068 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
16069 if (strcmp ("host", p
) == 0)
16070 kind
= OMP_CLAUSE_DEVICE_TYPE_HOST
;
16071 else if (strcmp ("nohost", p
) == 0)
16072 kind
= OMP_CLAUSE_DEVICE_TYPE_NOHOST
;
16073 else if (strcmp ("any", p
) == 0)
16074 kind
= OMP_CLAUSE_DEVICE_TYPE_ANY
;
16081 /* check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE_TYPE,
16083 c_parser_consume_token (parser
);
16084 parens
.skip_until_found_close (parser
);
16085 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_DEVICE_TYPE
);
16086 OMP_CLAUSE_DEVICE_TYPE_KIND (c
) = kind
;
16087 OMP_CLAUSE_CHAIN (c
) = list
;
16091 c_parser_error (parser
, "expected %<host%>, %<nohost%> or %<any%>");
16092 parens
.skip_until_found_close (parser
);
16097 to ( variable-list ) */
16100 c_parser_omp_clause_to (c_parser
*parser
, tree list
)
16102 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_TO
, list
);
16106 from ( variable-list ) */
16109 c_parser_omp_clause_from (c_parser
*parser
, tree list
)
16111 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_FROM
, list
);
16115 uniform ( variable-list ) */
16118 c_parser_omp_clause_uniform (c_parser
*parser
, tree list
)
16120 /* The clauses location. */
16121 location_t loc
= c_parser_peek_token (parser
)->location
;
16123 matching_parens parens
;
16124 if (parens
.require_open (parser
))
16126 list
= c_parser_omp_variable_list (parser
, loc
, OMP_CLAUSE_UNIFORM
,
16128 parens
.skip_until_found_close (parser
);
16134 detach ( event-handle ) */
16137 c_parser_omp_clause_detach (c_parser
*parser
, tree list
)
16139 matching_parens parens
;
16140 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
16142 if (!parens
.require_open (parser
))
16145 if (c_parser_next_token_is_not (parser
, CPP_NAME
)
16146 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
16148 c_parser_error (parser
, "expected identifier");
16149 parens
.skip_until_found_close (parser
);
16153 tree t
= lookup_name (c_parser_peek_token (parser
)->value
);
16154 if (t
== NULL_TREE
)
16156 undeclared_variable (c_parser_peek_token (parser
)->location
,
16157 c_parser_peek_token (parser
)->value
);
16158 parens
.skip_until_found_close (parser
);
16161 c_parser_consume_token (parser
);
16163 tree type
= TYPE_MAIN_VARIANT (TREE_TYPE (t
));
16164 if (!INTEGRAL_TYPE_P (type
)
16165 || TREE_CODE (type
) != ENUMERAL_TYPE
16166 || TYPE_NAME (type
) != get_identifier ("omp_event_handle_t"))
16168 error_at (clause_loc
, "%<detach%> clause event handle "
16169 "has type %qT rather than "
16170 "%<omp_event_handle_t%>",
16172 parens
.skip_until_found_close (parser
);
16176 tree u
= build_omp_clause (clause_loc
, OMP_CLAUSE_DETACH
);
16177 OMP_CLAUSE_DECL (u
) = t
;
16178 OMP_CLAUSE_CHAIN (u
) = list
;
16179 parens
.skip_until_found_close (parser
);
16183 /* Parse all OpenACC clauses. The set clauses allowed by the directive
16184 is a bitmask in MASK. Return the list of clauses found. */
16187 c_parser_oacc_all_clauses (c_parser
*parser
, omp_clause_mask mask
,
16188 const char *where
, bool finish_p
= true)
16190 tree clauses
= NULL
;
16193 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
16196 pragma_omp_clause c_kind
;
16197 const char *c_name
;
16198 tree prev
= clauses
;
16200 if (!first
&& c_parser_next_token_is (parser
, CPP_COMMA
))
16201 c_parser_consume_token (parser
);
16203 here
= c_parser_peek_token (parser
)->location
;
16204 c_kind
= c_parser_omp_clause_name (parser
);
16208 case PRAGMA_OACC_CLAUSE_ASYNC
:
16209 clauses
= c_parser_oacc_clause_async (parser
, clauses
);
16212 case PRAGMA_OACC_CLAUSE_AUTO
:
16213 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_AUTO
,
16217 case PRAGMA_OACC_CLAUSE_ATTACH
:
16218 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16221 case PRAGMA_OACC_CLAUSE_COLLAPSE
:
16222 clauses
= c_parser_omp_clause_collapse (parser
, clauses
);
16223 c_name
= "collapse";
16225 case PRAGMA_OACC_CLAUSE_COPY
:
16226 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16229 case PRAGMA_OACC_CLAUSE_COPYIN
:
16230 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16233 case PRAGMA_OACC_CLAUSE_COPYOUT
:
16234 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16235 c_name
= "copyout";
16237 case PRAGMA_OACC_CLAUSE_CREATE
:
16238 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16241 case PRAGMA_OACC_CLAUSE_DELETE
:
16242 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16245 case PRAGMA_OMP_CLAUSE_DEFAULT
:
16246 clauses
= c_parser_omp_clause_default (parser
, clauses
, true);
16247 c_name
= "default";
16249 case PRAGMA_OACC_CLAUSE_DETACH
:
16250 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16253 case PRAGMA_OACC_CLAUSE_DEVICE
:
16254 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16257 case PRAGMA_OACC_CLAUSE_DEVICEPTR
:
16258 clauses
= c_parser_oacc_data_clause_deviceptr (parser
, clauses
);
16259 c_name
= "deviceptr";
16261 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT
:
16262 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16263 c_name
= "device_resident";
16265 case PRAGMA_OACC_CLAUSE_FINALIZE
:
16266 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_FINALIZE
,
16268 c_name
= "finalize";
16270 case PRAGMA_OACC_CLAUSE_FIRSTPRIVATE
:
16271 clauses
= c_parser_omp_clause_firstprivate (parser
, clauses
);
16272 c_name
= "firstprivate";
16274 case PRAGMA_OACC_CLAUSE_GANG
:
16276 clauses
= c_parser_oacc_shape_clause (parser
, here
, OMP_CLAUSE_GANG
,
16279 case PRAGMA_OACC_CLAUSE_HOST
:
16280 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16283 case PRAGMA_OACC_CLAUSE_IF
:
16284 clauses
= c_parser_omp_clause_if (parser
, clauses
, false);
16287 case PRAGMA_OACC_CLAUSE_IF_PRESENT
:
16288 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_IF_PRESENT
,
16290 c_name
= "if_present";
16292 case PRAGMA_OACC_CLAUSE_INDEPENDENT
:
16293 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_INDEPENDENT
,
16295 c_name
= "independent";
16297 case PRAGMA_OACC_CLAUSE_LINK
:
16298 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16301 case PRAGMA_OACC_CLAUSE_NO_CREATE
:
16302 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16303 c_name
= "no_create";
16305 case PRAGMA_OACC_CLAUSE_NOHOST
:
16306 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_NOHOST
,
16310 case PRAGMA_OACC_CLAUSE_NUM_GANGS
:
16311 clauses
= c_parser_oacc_single_int_clause (parser
,
16312 OMP_CLAUSE_NUM_GANGS
,
16314 c_name
= "num_gangs";
16316 case PRAGMA_OACC_CLAUSE_NUM_WORKERS
:
16317 clauses
= c_parser_oacc_single_int_clause (parser
,
16318 OMP_CLAUSE_NUM_WORKERS
,
16320 c_name
= "num_workers";
16322 case PRAGMA_OACC_CLAUSE_PRESENT
:
16323 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16324 c_name
= "present";
16326 case PRAGMA_OACC_CLAUSE_PRIVATE
:
16327 clauses
= c_parser_omp_clause_private (parser
, clauses
);
16328 c_name
= "private";
16330 case PRAGMA_OACC_CLAUSE_REDUCTION
:
16332 = c_parser_omp_clause_reduction (parser
, OMP_CLAUSE_REDUCTION
,
16334 c_name
= "reduction";
16336 case PRAGMA_OACC_CLAUSE_SEQ
:
16337 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_SEQ
,
16341 case PRAGMA_OACC_CLAUSE_TILE
:
16342 clauses
= c_parser_oacc_clause_tile (parser
, clauses
);
16345 case PRAGMA_OACC_CLAUSE_USE_DEVICE
:
16346 clauses
= c_parser_omp_clause_use_device_ptr (parser
, clauses
);
16347 c_name
= "use_device";
16349 case PRAGMA_OACC_CLAUSE_VECTOR
:
16351 clauses
= c_parser_oacc_shape_clause (parser
, here
, OMP_CLAUSE_VECTOR
,
16354 case PRAGMA_OACC_CLAUSE_VECTOR_LENGTH
:
16355 clauses
= c_parser_oacc_single_int_clause (parser
,
16356 OMP_CLAUSE_VECTOR_LENGTH
,
16358 c_name
= "vector_length";
16360 case PRAGMA_OACC_CLAUSE_WAIT
:
16361 clauses
= c_parser_oacc_clause_wait (parser
, clauses
);
16364 case PRAGMA_OACC_CLAUSE_WORKER
:
16366 clauses
= c_parser_oacc_shape_clause (parser
, here
, OMP_CLAUSE_WORKER
,
16370 c_parser_error (parser
, "expected %<#pragma acc%> clause");
16376 if (((mask
>> c_kind
) & 1) == 0)
16378 /* Remove the invalid clause(s) from the list to avoid
16379 confusing the rest of the compiler. */
16381 error_at (here
, "%qs is not valid for %qs", c_name
, where
);
16386 c_parser_skip_to_pragma_eol (parser
);
16389 return c_finish_omp_clauses (clauses
, C_ORT_ACC
);
16394 /* Parse all OpenMP clauses. The set clauses allowed by the directive
16395 is a bitmask in MASK. Return the list of clauses found.
16396 FINISH_P set if c_finish_omp_clauses should be called.
16397 NESTED non-zero if clauses should be terminated by closing paren instead
16398 of end of pragma. If it is 2, additionally commas are required in between
16402 c_parser_omp_all_clauses (c_parser
*parser
, omp_clause_mask mask
,
16403 const char *where
, bool finish_p
= true,
16406 tree clauses
= NULL
;
16409 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
16412 pragma_omp_clause c_kind
;
16413 const char *c_name
;
16414 tree prev
= clauses
;
16416 if (nested
&& c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
16421 if (c_parser_next_token_is (parser
, CPP_COMMA
))
16422 c_parser_consume_token (parser
);
16423 else if (nested
== 2)
16424 error_at (c_parser_peek_token (parser
)->location
,
16425 "clauses in %<simd%> trait should be separated "
16429 here
= c_parser_peek_token (parser
)->location
;
16430 c_kind
= c_parser_omp_clause_name (parser
);
16434 case PRAGMA_OMP_CLAUSE_BIND
:
16435 clauses
= c_parser_omp_clause_bind (parser
, clauses
);
16438 case PRAGMA_OMP_CLAUSE_COLLAPSE
:
16439 clauses
= c_parser_omp_clause_collapse (parser
, clauses
);
16440 c_name
= "collapse";
16442 case PRAGMA_OMP_CLAUSE_COPYIN
:
16443 clauses
= c_parser_omp_clause_copyin (parser
, clauses
);
16446 case PRAGMA_OMP_CLAUSE_COPYPRIVATE
:
16447 clauses
= c_parser_omp_clause_copyprivate (parser
, clauses
);
16448 c_name
= "copyprivate";
16450 case PRAGMA_OMP_CLAUSE_DEFAULT
:
16451 clauses
= c_parser_omp_clause_default (parser
, clauses
, false);
16452 c_name
= "default";
16454 case PRAGMA_OMP_CLAUSE_DETACH
:
16455 clauses
= c_parser_omp_clause_detach (parser
, clauses
);
16458 case PRAGMA_OMP_CLAUSE_FILTER
:
16459 clauses
= c_parser_omp_clause_filter (parser
, clauses
);
16462 case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE
:
16463 clauses
= c_parser_omp_clause_firstprivate (parser
, clauses
);
16464 c_name
= "firstprivate";
16466 case PRAGMA_OMP_CLAUSE_FINAL
:
16467 clauses
= c_parser_omp_clause_final (parser
, clauses
);
16470 case PRAGMA_OMP_CLAUSE_GRAINSIZE
:
16471 clauses
= c_parser_omp_clause_grainsize (parser
, clauses
);
16472 c_name
= "grainsize";
16474 case PRAGMA_OMP_CLAUSE_HINT
:
16475 clauses
= c_parser_omp_clause_hint (parser
, clauses
);
16478 case PRAGMA_OMP_CLAUSE_DEFAULTMAP
:
16479 clauses
= c_parser_omp_clause_defaultmap (parser
, clauses
);
16480 c_name
= "defaultmap";
16482 case PRAGMA_OMP_CLAUSE_IF
:
16483 clauses
= c_parser_omp_clause_if (parser
, clauses
, true);
16486 case PRAGMA_OMP_CLAUSE_IN_REDUCTION
:
16488 = c_parser_omp_clause_reduction (parser
, OMP_CLAUSE_IN_REDUCTION
,
16490 c_name
= "in_reduction";
16492 case PRAGMA_OMP_CLAUSE_LASTPRIVATE
:
16493 clauses
= c_parser_omp_clause_lastprivate (parser
, clauses
);
16494 c_name
= "lastprivate";
16496 case PRAGMA_OMP_CLAUSE_MERGEABLE
:
16497 clauses
= c_parser_omp_clause_mergeable (parser
, clauses
);
16498 c_name
= "mergeable";
16500 case PRAGMA_OMP_CLAUSE_NOWAIT
:
16501 clauses
= c_parser_omp_clause_nowait (parser
, clauses
);
16504 case PRAGMA_OMP_CLAUSE_NUM_TASKS
:
16505 clauses
= c_parser_omp_clause_num_tasks (parser
, clauses
);
16506 c_name
= "num_tasks";
16508 case PRAGMA_OMP_CLAUSE_NUM_THREADS
:
16509 clauses
= c_parser_omp_clause_num_threads (parser
, clauses
);
16510 c_name
= "num_threads";
16512 case PRAGMA_OMP_CLAUSE_ORDER
:
16513 clauses
= c_parser_omp_clause_order (parser
, clauses
);
16516 case PRAGMA_OMP_CLAUSE_ORDERED
:
16517 clauses
= c_parser_omp_clause_ordered (parser
, clauses
);
16518 c_name
= "ordered";
16520 case PRAGMA_OMP_CLAUSE_PRIORITY
:
16521 clauses
= c_parser_omp_clause_priority (parser
, clauses
);
16522 c_name
= "priority";
16524 case PRAGMA_OMP_CLAUSE_PRIVATE
:
16525 clauses
= c_parser_omp_clause_private (parser
, clauses
);
16526 c_name
= "private";
16528 case PRAGMA_OMP_CLAUSE_REDUCTION
:
16530 = c_parser_omp_clause_reduction (parser
, OMP_CLAUSE_REDUCTION
,
16532 c_name
= "reduction";
16534 case PRAGMA_OMP_CLAUSE_SCHEDULE
:
16535 clauses
= c_parser_omp_clause_schedule (parser
, clauses
);
16536 c_name
= "schedule";
16538 case PRAGMA_OMP_CLAUSE_SHARED
:
16539 clauses
= c_parser_omp_clause_shared (parser
, clauses
);
16542 case PRAGMA_OMP_CLAUSE_TASK_REDUCTION
:
16544 = c_parser_omp_clause_reduction (parser
, OMP_CLAUSE_TASK_REDUCTION
,
16546 c_name
= "task_reduction";
16548 case PRAGMA_OMP_CLAUSE_UNTIED
:
16549 clauses
= c_parser_omp_clause_untied (parser
, clauses
);
16552 case PRAGMA_OMP_CLAUSE_INBRANCH
:
16553 clauses
= c_parser_omp_clause_branch (parser
, OMP_CLAUSE_INBRANCH
,
16555 c_name
= "inbranch";
16557 case PRAGMA_OMP_CLAUSE_NONTEMPORAL
:
16558 clauses
= c_parser_omp_clause_nontemporal (parser
, clauses
);
16559 c_name
= "nontemporal";
16561 case PRAGMA_OMP_CLAUSE_NOTINBRANCH
:
16562 clauses
= c_parser_omp_clause_branch (parser
, OMP_CLAUSE_NOTINBRANCH
,
16564 c_name
= "notinbranch";
16566 case PRAGMA_OMP_CLAUSE_PARALLEL
:
16568 = c_parser_omp_clause_cancelkind (parser
, OMP_CLAUSE_PARALLEL
,
16570 c_name
= "parallel";
16574 error_at (here
, "%qs must be the first clause of %qs",
16579 case PRAGMA_OMP_CLAUSE_FOR
:
16581 = c_parser_omp_clause_cancelkind (parser
, OMP_CLAUSE_FOR
,
16585 goto clause_not_first
;
16587 case PRAGMA_OMP_CLAUSE_SECTIONS
:
16589 = c_parser_omp_clause_cancelkind (parser
, OMP_CLAUSE_SECTIONS
,
16591 c_name
= "sections";
16593 goto clause_not_first
;
16595 case PRAGMA_OMP_CLAUSE_TASKGROUP
:
16597 = c_parser_omp_clause_cancelkind (parser
, OMP_CLAUSE_TASKGROUP
,
16599 c_name
= "taskgroup";
16601 goto clause_not_first
;
16603 case PRAGMA_OMP_CLAUSE_LINK
:
16605 = c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_LINK
, clauses
);
16608 case PRAGMA_OMP_CLAUSE_TO
:
16609 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_LINK
)) != 0)
16611 = c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_TO_DECLARE
,
16614 clauses
= c_parser_omp_clause_to (parser
, clauses
);
16617 case PRAGMA_OMP_CLAUSE_FROM
:
16618 clauses
= c_parser_omp_clause_from (parser
, clauses
);
16621 case PRAGMA_OMP_CLAUSE_UNIFORM
:
16622 clauses
= c_parser_omp_clause_uniform (parser
, clauses
);
16623 c_name
= "uniform";
16625 case PRAGMA_OMP_CLAUSE_NUM_TEAMS
:
16626 clauses
= c_parser_omp_clause_num_teams (parser
, clauses
);
16627 c_name
= "num_teams";
16629 case PRAGMA_OMP_CLAUSE_THREAD_LIMIT
:
16630 clauses
= c_parser_omp_clause_thread_limit (parser
, clauses
);
16631 c_name
= "thread_limit";
16633 case PRAGMA_OMP_CLAUSE_ALIGNED
:
16634 clauses
= c_parser_omp_clause_aligned (parser
, clauses
);
16635 c_name
= "aligned";
16637 case PRAGMA_OMP_CLAUSE_ALLOCATE
:
16638 clauses
= c_parser_omp_clause_allocate (parser
, clauses
);
16639 c_name
= "allocate";
16641 case PRAGMA_OMP_CLAUSE_LINEAR
:
16642 clauses
= c_parser_omp_clause_linear (parser
, clauses
);
16645 case PRAGMA_OMP_CLAUSE_AFFINITY
:
16646 clauses
= c_parser_omp_clause_affinity (parser
, clauses
);
16647 c_name
= "affinity";
16649 case PRAGMA_OMP_CLAUSE_DEPEND
:
16650 clauses
= c_parser_omp_clause_depend (parser
, clauses
);
16653 case PRAGMA_OMP_CLAUSE_MAP
:
16654 clauses
= c_parser_omp_clause_map (parser
, clauses
);
16657 case PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR
:
16658 clauses
= c_parser_omp_clause_use_device_ptr (parser
, clauses
);
16659 c_name
= "use_device_ptr";
16661 case PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR
:
16662 clauses
= c_parser_omp_clause_use_device_addr (parser
, clauses
);
16663 c_name
= "use_device_addr";
16665 case PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR
:
16666 clauses
= c_parser_omp_clause_is_device_ptr (parser
, clauses
);
16667 c_name
= "is_device_ptr";
16669 case PRAGMA_OMP_CLAUSE_DEVICE
:
16670 clauses
= c_parser_omp_clause_device (parser
, clauses
);
16673 case PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
:
16674 clauses
= c_parser_omp_clause_dist_schedule (parser
, clauses
);
16675 c_name
= "dist_schedule";
16677 case PRAGMA_OMP_CLAUSE_PROC_BIND
:
16678 clauses
= c_parser_omp_clause_proc_bind (parser
, clauses
);
16679 c_name
= "proc_bind";
16681 case PRAGMA_OMP_CLAUSE_DEVICE_TYPE
:
16682 clauses
= c_parser_omp_clause_device_type (parser
, clauses
);
16683 c_name
= "device_type";
16685 case PRAGMA_OMP_CLAUSE_SAFELEN
:
16686 clauses
= c_parser_omp_clause_safelen (parser
, clauses
);
16687 c_name
= "safelen";
16689 case PRAGMA_OMP_CLAUSE_SIMDLEN
:
16690 clauses
= c_parser_omp_clause_simdlen (parser
, clauses
);
16691 c_name
= "simdlen";
16693 case PRAGMA_OMP_CLAUSE_NOGROUP
:
16694 clauses
= c_parser_omp_clause_nogroup (parser
, clauses
);
16695 c_name
= "nogroup";
16697 case PRAGMA_OMP_CLAUSE_THREADS
:
16699 = c_parser_omp_clause_orderedkind (parser
, OMP_CLAUSE_THREADS
,
16701 c_name
= "threads";
16703 case PRAGMA_OMP_CLAUSE_SIMD
:
16705 = c_parser_omp_clause_orderedkind (parser
, OMP_CLAUSE_SIMD
,
16710 c_parser_error (parser
, "expected %<#pragma omp%> clause");
16716 if (((mask
>> c_kind
) & 1) == 0)
16718 /* Remove the invalid clause(s) from the list to avoid
16719 confusing the rest of the compiler. */
16721 error_at (here
, "%qs is not valid for %qs", c_name
, where
);
16727 c_parser_skip_to_pragma_eol (parser
);
16731 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_UNIFORM
)) != 0)
16732 return c_finish_omp_clauses (clauses
, C_ORT_OMP_DECLARE_SIMD
);
16733 return c_finish_omp_clauses (clauses
, C_ORT_OMP
);
16739 /* OpenACC 2.0, OpenMP 2.5:
16743 In practice, we're also interested in adding the statement to an
16744 outer node. So it is convenient if we work around the fact that
16745 c_parser_statement calls add_stmt. */
16748 c_parser_omp_structured_block (c_parser
*parser
, bool *if_p
)
16750 tree stmt
= push_stmt_list ();
16751 c_parser_statement (parser
, if_p
);
16752 return pop_stmt_list (stmt
);
16756 # pragma acc cache (variable-list) new-line
16758 LOC is the location of the #pragma token.
16762 c_parser_oacc_cache (location_t loc
, c_parser
*parser
)
16764 tree stmt
, clauses
;
16766 clauses
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE__CACHE_
, NULL
);
16767 clauses
= c_finish_omp_clauses (clauses
, C_ORT_ACC
);
16769 c_parser_skip_to_pragma_eol (parser
);
16771 stmt
= make_node (OACC_CACHE
);
16772 TREE_TYPE (stmt
) = void_type_node
;
16773 OACC_CACHE_CLAUSES (stmt
) = clauses
;
16774 SET_EXPR_LOCATION (stmt
, loc
);
16781 # pragma acc data oacc-data-clause[optseq] new-line
16784 LOC is the location of the #pragma token.
16787 #define OACC_DATA_CLAUSE_MASK \
16788 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
16789 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
16790 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
16791 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
16792 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
16793 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
16794 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
16795 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
16796 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
16799 c_parser_oacc_data (location_t loc
, c_parser
*parser
, bool *if_p
)
16801 tree stmt
, clauses
, block
;
16803 clauses
= c_parser_oacc_all_clauses (parser
, OACC_DATA_CLAUSE_MASK
,
16804 "#pragma acc data");
16806 block
= c_begin_omp_parallel ();
16807 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
16809 stmt
= c_finish_oacc_data (loc
, clauses
, block
);
16815 # pragma acc declare oacc-data-clause[optseq] new-line
16818 #define OACC_DECLARE_CLAUSE_MASK \
16819 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
16820 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
16821 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
16822 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
16823 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
16824 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT) \
16825 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_LINK) \
16826 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
16829 c_parser_oacc_declare (c_parser
*parser
)
16831 location_t pragma_loc
= c_parser_peek_token (parser
)->location
;
16832 tree clauses
, stmt
, t
, decl
;
16834 bool error
= false;
16836 c_parser_consume_pragma (parser
);
16838 clauses
= c_parser_oacc_all_clauses (parser
, OACC_DECLARE_CLAUSE_MASK
,
16839 "#pragma acc declare");
16842 error_at (pragma_loc
,
16843 "no valid clauses specified in %<#pragma acc declare%>");
16847 for (t
= clauses
; t
; t
= OMP_CLAUSE_CHAIN (t
))
16849 location_t loc
= OMP_CLAUSE_LOCATION (t
);
16850 decl
= OMP_CLAUSE_DECL (t
);
16851 if (!DECL_P (decl
))
16853 error_at (loc
, "array section in %<#pragma acc declare%>");
16858 switch (OMP_CLAUSE_MAP_KIND (t
))
16860 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
16861 case GOMP_MAP_ALLOC
:
16863 case GOMP_MAP_FORCE_DEVICEPTR
:
16864 case GOMP_MAP_DEVICE_RESIDENT
:
16867 case GOMP_MAP_LINK
:
16868 if (!global_bindings_p ()
16869 && (TREE_STATIC (decl
)
16870 || !DECL_EXTERNAL (decl
)))
16873 "%qD must be a global variable in "
16874 "%<#pragma acc declare link%>",
16882 if (global_bindings_p ())
16884 error_at (loc
, "invalid OpenACC clause at file scope");
16888 if (DECL_EXTERNAL (decl
))
16891 "invalid use of %<extern%> variable %qD "
16892 "in %<#pragma acc declare%>", decl
);
16896 else if (TREE_PUBLIC (decl
))
16899 "invalid use of %<global%> variable %qD "
16900 "in %<#pragma acc declare%>", decl
);
16907 if (!c_check_in_current_scope (decl
))
16910 "%qD must be a variable declared in the same scope as "
16911 "%<#pragma acc declare%>", decl
);
16916 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl
))
16917 || lookup_attribute ("omp declare target link",
16918 DECL_ATTRIBUTES (decl
)))
16920 error_at (loc
, "variable %qD used more than once with "
16921 "%<#pragma acc declare%>", decl
);
16930 if (OMP_CLAUSE_MAP_KIND (t
) == GOMP_MAP_LINK
)
16931 id
= get_identifier ("omp declare target link");
16933 id
= get_identifier ("omp declare target");
16935 DECL_ATTRIBUTES (decl
)
16936 = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (decl
));
16938 if (global_bindings_p ())
16940 symtab_node
*node
= symtab_node::get (decl
);
16943 node
->offloadable
= 1;
16944 if (ENABLE_OFFLOADING
)
16946 g
->have_offload
= true;
16947 if (is_a
<varpool_node
*> (node
))
16948 vec_safe_push (offload_vars
, decl
);
16955 if (error
|| global_bindings_p ())
16958 stmt
= make_node (OACC_DECLARE
);
16959 TREE_TYPE (stmt
) = void_type_node
;
16960 OACC_DECLARE_CLAUSES (stmt
) = clauses
;
16961 SET_EXPR_LOCATION (stmt
, pragma_loc
);
16969 # pragma acc enter data oacc-enter-data-clause[optseq] new-line
16973 # pragma acc exit data oacc-exit-data-clause[optseq] new-line
16976 LOC is the location of the #pragma token.
16979 #define OACC_ENTER_DATA_CLAUSE_MASK \
16980 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
16981 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
16982 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
16983 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
16984 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
16985 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
16987 #define OACC_EXIT_DATA_CLAUSE_MASK \
16988 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
16989 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
16990 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
16991 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DELETE) \
16992 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DETACH) \
16993 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FINALIZE) \
16994 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
16997 c_parser_oacc_enter_exit_data (c_parser
*parser
, bool enter
)
16999 location_t loc
= c_parser_peek_token (parser
)->location
;
17000 tree clauses
, stmt
;
17001 const char *p
= "";
17003 c_parser_consume_pragma (parser
);
17005 if (c_parser_next_token_is (parser
, CPP_NAME
))
17007 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
17008 c_parser_consume_token (parser
);
17011 if (strcmp (p
, "data") != 0)
17013 error_at (loc
, "expected %<data%> after %<#pragma acc %s%>",
17014 enter
? "enter" : "exit");
17015 parser
->error
= true;
17016 c_parser_skip_to_pragma_eol (parser
);
17021 clauses
= c_parser_oacc_all_clauses (parser
, OACC_ENTER_DATA_CLAUSE_MASK
,
17022 "#pragma acc enter data");
17024 clauses
= c_parser_oacc_all_clauses (parser
, OACC_EXIT_DATA_CLAUSE_MASK
,
17025 "#pragma acc exit data");
17027 if (omp_find_clause (clauses
, OMP_CLAUSE_MAP
) == NULL_TREE
)
17029 error_at (loc
, "%<#pragma acc %s data%> has no data movement clause",
17030 enter
? "enter" : "exit");
17034 stmt
= enter
? make_node (OACC_ENTER_DATA
) : make_node (OACC_EXIT_DATA
);
17035 TREE_TYPE (stmt
) = void_type_node
;
17036 OMP_STANDALONE_CLAUSES (stmt
) = clauses
;
17037 SET_EXPR_LOCATION (stmt
, loc
);
17043 # pragma acc host_data oacc-data-clause[optseq] new-line
17047 #define OACC_HOST_DATA_CLAUSE_MASK \
17048 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_USE_DEVICE) \
17049 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17050 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) )
17053 c_parser_oacc_host_data (location_t loc
, c_parser
*parser
, bool *if_p
)
17055 tree stmt
, clauses
, block
;
17057 clauses
= c_parser_oacc_all_clauses (parser
, OACC_HOST_DATA_CLAUSE_MASK
,
17058 "#pragma acc host_data");
17060 block
= c_begin_omp_parallel ();
17061 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
17062 stmt
= c_finish_oacc_host_data (loc
, clauses
, block
);
17069 # pragma acc loop oacc-loop-clause[optseq] new-line
17072 LOC is the location of the #pragma token.
17075 #define OACC_LOOP_CLAUSE_MASK \
17076 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COLLAPSE) \
17077 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
17078 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
17079 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
17080 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
17081 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
17082 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_AUTO) \
17083 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_INDEPENDENT) \
17084 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \
17085 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_TILE) )
17087 c_parser_oacc_loop (location_t loc
, c_parser
*parser
, char *p_name
,
17088 omp_clause_mask mask
, tree
*cclauses
, bool *if_p
)
17090 bool is_parallel
= ((mask
>> PRAGMA_OACC_CLAUSE_REDUCTION
) & 1) == 1;
17092 strcat (p_name
, " loop");
17093 mask
|= OACC_LOOP_CLAUSE_MASK
;
17095 tree clauses
= c_parser_oacc_all_clauses (parser
, mask
, p_name
,
17099 clauses
= c_oacc_split_loop_clauses (clauses
, cclauses
, is_parallel
);
17101 *cclauses
= c_finish_omp_clauses (*cclauses
, C_ORT_ACC
);
17103 clauses
= c_finish_omp_clauses (clauses
, C_ORT_ACC
);
17106 tree block
= c_begin_compound_stmt (true);
17107 tree stmt
= c_parser_omp_for_loop (loc
, parser
, OACC_LOOP
, clauses
, NULL
,
17109 block
= c_end_compound_stmt (loc
, block
, true);
17116 # pragma acc kernels oacc-kernels-clause[optseq] new-line
17121 # pragma acc parallel oacc-parallel-clause[optseq] new-line
17126 # pragma acc serial oacc-serial-clause[optseq] new-line
17129 LOC is the location of the #pragma token.
17132 #define OACC_KERNELS_CLAUSE_MASK \
17133 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17134 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
17135 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
17136 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17137 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17138 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17139 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
17140 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
17141 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17142 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
17143 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
17144 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
17145 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
17146 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
17147 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17149 #define OACC_PARALLEL_CLAUSE_MASK \
17150 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17151 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
17152 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
17153 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17154 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17155 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17156 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
17157 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
17158 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17159 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
17160 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
17161 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
17162 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
17163 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
17164 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
17165 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
17166 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
17167 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17169 #define OACC_SERIAL_CLAUSE_MASK \
17170 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17171 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
17172 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
17173 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17174 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17175 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17176 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
17177 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
17178 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17179 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
17180 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
17181 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
17182 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
17183 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
17184 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17187 c_parser_oacc_compute (location_t loc
, c_parser
*parser
,
17188 enum pragma_kind p_kind
, char *p_name
, bool *if_p
)
17190 omp_clause_mask mask
;
17191 enum tree_code code
;
17194 case PRAGMA_OACC_KERNELS
:
17195 strcat (p_name
, " kernels");
17196 mask
= OACC_KERNELS_CLAUSE_MASK
;
17197 code
= OACC_KERNELS
;
17199 case PRAGMA_OACC_PARALLEL
:
17200 strcat (p_name
, " parallel");
17201 mask
= OACC_PARALLEL_CLAUSE_MASK
;
17202 code
= OACC_PARALLEL
;
17204 case PRAGMA_OACC_SERIAL
:
17205 strcat (p_name
, " serial");
17206 mask
= OACC_SERIAL_CLAUSE_MASK
;
17207 code
= OACC_SERIAL
;
17210 gcc_unreachable ();
17213 if (c_parser_next_token_is (parser
, CPP_NAME
))
17215 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
17216 if (strcmp (p
, "loop") == 0)
17218 c_parser_consume_token (parser
);
17219 tree block
= c_begin_omp_parallel ();
17221 c_parser_oacc_loop (loc
, parser
, p_name
, mask
, &clauses
, if_p
);
17222 return c_finish_omp_construct (loc
, code
, block
, clauses
);
17226 tree clauses
= c_parser_oacc_all_clauses (parser
, mask
, p_name
);
17228 tree block
= c_begin_omp_parallel ();
17229 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
17231 return c_finish_omp_construct (loc
, code
, block
, clauses
);
17235 # pragma acc routine oacc-routine-clause[optseq] new-line
17236 function-definition
17238 # pragma acc routine ( name ) oacc-routine-clause[optseq] new-line
17241 #define OACC_ROUTINE_CLAUSE_MASK \
17242 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
17243 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
17244 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
17245 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \
17246 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NOHOST) )
17248 /* Parse an OpenACC routine directive. For named directives, we apply
17249 immediately to the named function. For unnamed ones we then parse
17250 a declaration or definition, which must be for a function. */
17253 c_parser_oacc_routine (c_parser
*parser
, enum pragma_context context
)
17255 gcc_checking_assert (context
== pragma_external
);
17257 oacc_routine_data data
;
17258 data
.error_seen
= false;
17259 data
.fndecl_seen
= false;
17260 data
.loc
= c_parser_peek_token (parser
)->location
;
17262 c_parser_consume_pragma (parser
);
17264 /* Look for optional '( name )'. */
17265 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
17267 c_parser_consume_token (parser
); /* '(' */
17269 tree decl
= NULL_TREE
;
17270 c_token
*name_token
= c_parser_peek_token (parser
);
17271 location_t name_loc
= name_token
->location
;
17272 if (name_token
->type
== CPP_NAME
17273 && (name_token
->id_kind
== C_ID_ID
17274 || name_token
->id_kind
== C_ID_TYPENAME
))
17276 decl
= lookup_name (name_token
->value
);
17278 error_at (name_loc
,
17279 "%qE has not been declared", name_token
->value
);
17280 c_parser_consume_token (parser
);
17283 c_parser_error (parser
, "expected function name");
17286 || !c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
17288 c_parser_skip_to_pragma_eol (parser
, false);
17293 = c_parser_oacc_all_clauses (parser
, OACC_ROUTINE_CLAUSE_MASK
,
17294 "#pragma acc routine");
17295 /* The clauses are in reverse order; fix that to make later diagnostic
17296 emission easier. */
17297 data
.clauses
= nreverse (data
.clauses
);
17299 if (TREE_CODE (decl
) != FUNCTION_DECL
)
17301 error_at (name_loc
, "%qD does not refer to a function", decl
);
17305 c_finish_oacc_routine (&data
, decl
, false);
17307 else /* No optional '( name )'. */
17310 = c_parser_oacc_all_clauses (parser
, OACC_ROUTINE_CLAUSE_MASK
,
17311 "#pragma acc routine");
17312 /* The clauses are in reverse order; fix that to make later diagnostic
17313 emission easier. */
17314 data
.clauses
= nreverse (data
.clauses
);
17316 /* Emit a helpful diagnostic if there's another pragma following this
17317 one. Also don't allow a static assertion declaration, as in the
17318 following we'll just parse a *single* "declaration or function
17319 definition", and the static assertion counts an one. */
17320 if (c_parser_next_token_is (parser
, CPP_PRAGMA
)
17321 || c_parser_next_token_is_keyword (parser
, RID_STATIC_ASSERT
))
17323 error_at (data
.loc
,
17324 "%<#pragma acc routine%> not immediately followed by"
17325 " function declaration or definition");
17326 /* ..., and then just keep going. */
17330 /* We only have to consider the pragma_external case here. */
17331 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
17332 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
)
17334 int ext
= disable_extension_diagnostics ();
17336 c_parser_consume_token (parser
);
17337 while (c_parser_next_token_is (parser
, CPP_KEYWORD
)
17338 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
);
17339 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
17340 NULL
, NULL
, false, NULL
, &data
);
17341 restore_extension_diagnostics (ext
);
17344 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
17345 NULL
, NULL
, false, NULL
, &data
);
17349 /* Finalize an OpenACC routine pragma, applying it to FNDECL.
17350 IS_DEFN is true if we're applying it to the definition. */
17353 c_finish_oacc_routine (struct oacc_routine_data
*data
, tree fndecl
,
17356 /* Keep going if we're in error reporting mode. */
17357 if (data
->error_seen
17358 || fndecl
== error_mark_node
)
17361 if (data
->fndecl_seen
)
17363 error_at (data
->loc
,
17364 "%<#pragma acc routine%> not immediately followed by"
17365 " a single function declaration or definition");
17366 data
->error_seen
= true;
17369 if (fndecl
== NULL_TREE
|| TREE_CODE (fndecl
) != FUNCTION_DECL
)
17371 error_at (data
->loc
,
17372 "%<#pragma acc routine%> not immediately followed by"
17373 " function declaration or definition");
17374 data
->error_seen
= true;
17379 = oacc_verify_routine_clauses (fndecl
, &data
->clauses
, data
->loc
,
17380 "#pragma acc routine");
17381 if (compatible
< 0)
17383 data
->error_seen
= true;
17386 if (compatible
> 0)
17391 if (TREE_USED (fndecl
) || (!is_defn
&& DECL_SAVED_TREE (fndecl
)))
17393 error_at (data
->loc
,
17395 ? G_("%<#pragma acc routine%> must be applied before use")
17396 : G_("%<#pragma acc routine%> must be applied before"
17398 data
->error_seen
= true;
17402 /* Set the routine's level of parallelism. */
17403 tree dims
= oacc_build_routine_dims (data
->clauses
);
17404 oacc_replace_fn_attrib (fndecl
, dims
);
17406 /* Add an "omp declare target" attribute. */
17407 DECL_ATTRIBUTES (fndecl
)
17408 = tree_cons (get_identifier ("omp declare target"),
17409 data
->clauses
, DECL_ATTRIBUTES (fndecl
));
17412 /* Remember that we've used this "#pragma acc routine". */
17413 data
->fndecl_seen
= true;
17417 # pragma acc update oacc-update-clause[optseq] new-line
17420 #define OACC_UPDATE_CLAUSE_MASK \
17421 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17422 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE) \
17423 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_HOST) \
17424 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17425 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) \
17426 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17429 c_parser_oacc_update (c_parser
*parser
)
17431 location_t loc
= c_parser_peek_token (parser
)->location
;
17433 c_parser_consume_pragma (parser
);
17435 tree clauses
= c_parser_oacc_all_clauses (parser
, OACC_UPDATE_CLAUSE_MASK
,
17436 "#pragma acc update");
17437 if (omp_find_clause (clauses
, OMP_CLAUSE_MAP
) == NULL_TREE
)
17440 "%<#pragma acc update%> must contain at least one "
17441 "%<device%> or %<host%> or %<self%> clause");
17448 tree stmt
= make_node (OACC_UPDATE
);
17449 TREE_TYPE (stmt
) = void_type_node
;
17450 OACC_UPDATE_CLAUSES (stmt
) = clauses
;
17451 SET_EXPR_LOCATION (stmt
, loc
);
17456 # pragma acc wait [(intseq)] oacc-wait-clause[optseq] new-line
17458 LOC is the location of the #pragma token.
17461 #define OACC_WAIT_CLAUSE_MASK \
17462 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) )
17465 c_parser_oacc_wait (location_t loc
, c_parser
*parser
, char *p_name
)
17467 tree clauses
, list
= NULL_TREE
, stmt
= NULL_TREE
;
17469 if (c_parser_peek_token (parser
)->type
== CPP_OPEN_PAREN
)
17470 list
= c_parser_oacc_wait_list (parser
, loc
, list
);
17472 strcpy (p_name
, " wait");
17473 clauses
= c_parser_oacc_all_clauses (parser
, OACC_WAIT_CLAUSE_MASK
, p_name
);
17474 stmt
= c_finish_oacc_wait (loc
, list
, clauses
);
17481 # pragma omp allocate (list) [allocator(allocator)] */
17484 c_parser_omp_allocate (location_t loc
, c_parser
*parser
)
17486 tree allocator
= NULL_TREE
;
17487 tree nl
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ALLOCATE
, NULL_TREE
);
17488 if (c_parser_next_token_is (parser
, CPP_NAME
))
17490 matching_parens parens
;
17491 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
17492 c_parser_consume_token (parser
);
17493 if (strcmp ("allocator", p
) != 0)
17494 error_at (c_parser_peek_token (parser
)->location
,
17495 "expected %<allocator%>");
17496 else if (parens
.require_open (parser
))
17498 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
17499 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
17500 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
17501 allocator
= expr
.value
;
17502 allocator
= c_fully_fold (allocator
, false, NULL
);
17504 = expr
.original_type
? expr
.original_type
: TREE_TYPE (allocator
);
17505 orig_type
= TYPE_MAIN_VARIANT (orig_type
);
17506 if (!INTEGRAL_TYPE_P (TREE_TYPE (allocator
))
17507 || TREE_CODE (orig_type
) != ENUMERAL_TYPE
17508 || TYPE_NAME (orig_type
)
17509 != get_identifier ("omp_allocator_handle_t"))
17511 error_at (expr_loc
, "%<allocator%> clause allocator expression "
17512 "has type %qT rather than "
17513 "%<omp_allocator_handle_t%>",
17514 TREE_TYPE (allocator
));
17515 allocator
= NULL_TREE
;
17517 parens
.skip_until_found_close (parser
);
17520 c_parser_skip_to_pragma_eol (parser
);
17523 for (tree c
= nl
; c
!= NULL_TREE
; c
= OMP_CLAUSE_CHAIN (c
))
17524 OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
) = allocator
;
17526 sorry_at (loc
, "%<#pragma omp allocate%> not yet supported");
17530 # pragma omp atomic new-line
17534 x binop= expr | x++ | ++x | x-- | --x
17536 +, *, -, /, &, ^, |, <<, >>
17538 where x is an lvalue expression with scalar type.
17541 # pragma omp atomic new-line
17544 # pragma omp atomic read new-line
17547 # pragma omp atomic write new-line
17550 # pragma omp atomic update new-line
17553 # pragma omp atomic capture new-line
17556 # pragma omp atomic capture new-line
17564 expression-stmt | x = x binop expr
17566 v = expression-stmt
17568 { v = x; update-stmt; } | { update-stmt; v = x; }
17572 expression-stmt | x = x binop expr | x = expr binop x
17576 { v = x; update-stmt; } | { update-stmt; v = x; } | { v = x; x = expr; }
17578 where x and v are lvalue expressions with scalar type.
17580 LOC is the location of the #pragma token. */
17583 c_parser_omp_atomic (location_t loc
, c_parser
*parser
, bool openacc
)
17585 tree lhs
= NULL_TREE
, rhs
= NULL_TREE
, v
= NULL_TREE
;
17586 tree lhs1
= NULL_TREE
, rhs1
= NULL_TREE
;
17587 tree stmt
, orig_lhs
, unfolded_lhs
= NULL_TREE
, unfolded_lhs1
= NULL_TREE
;
17588 enum tree_code code
= ERROR_MARK
, opcode
= NOP_EXPR
;
17589 enum omp_memory_order memory_order
= OMP_MEMORY_ORDER_UNSPECIFIED
;
17590 struct c_expr expr
;
17592 bool structured_block
= false;
17593 bool swapped
= false;
17596 tree clauses
= NULL_TREE
;
17598 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
17601 && c_parser_next_token_is (parser
, CPP_COMMA
)
17602 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
17603 c_parser_consume_token (parser
);
17607 if (c_parser_next_token_is (parser
, CPP_NAME
))
17610 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
17611 location_t cloc
= c_parser_peek_token (parser
)->location
;
17612 enum tree_code new_code
= ERROR_MARK
;
17613 enum omp_memory_order new_memory_order
17614 = OMP_MEMORY_ORDER_UNSPECIFIED
;
17616 if (!strcmp (p
, "read"))
17617 new_code
= OMP_ATOMIC_READ
;
17618 else if (!strcmp (p
, "write"))
17619 new_code
= NOP_EXPR
;
17620 else if (!strcmp (p
, "update"))
17621 new_code
= OMP_ATOMIC
;
17622 else if (!strcmp (p
, "capture"))
17623 new_code
= OMP_ATOMIC_CAPTURE_NEW
;
17627 error_at (cloc
, "expected %<read%>, %<write%>, %<update%>, "
17628 "or %<capture%> clause");
17630 else if (!strcmp (p
, "seq_cst"))
17631 new_memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
17632 else if (!strcmp (p
, "acq_rel"))
17633 new_memory_order
= OMP_MEMORY_ORDER_ACQ_REL
;
17634 else if (!strcmp (p
, "release"))
17635 new_memory_order
= OMP_MEMORY_ORDER_RELEASE
;
17636 else if (!strcmp (p
, "acquire"))
17637 new_memory_order
= OMP_MEMORY_ORDER_ACQUIRE
;
17638 else if (!strcmp (p
, "relaxed"))
17639 new_memory_order
= OMP_MEMORY_ORDER_RELAXED
;
17640 else if (!strcmp (p
, "hint"))
17642 c_parser_consume_token (parser
);
17643 clauses
= c_parser_omp_clause_hint (parser
, clauses
);
17649 error_at (cloc
, "expected %<read%>, %<write%>, %<update%>, "
17650 "%<capture%>, %<seq_cst%>, %<acq_rel%>, "
17651 "%<release%>, %<relaxed%> or %<hint%> clause");
17655 if (new_code
!= ERROR_MARK
)
17657 /* OpenACC permits 'update capture'. */
17659 && code
== OMP_ATOMIC
17660 && new_code
== OMP_ATOMIC_CAPTURE_NEW
)
17662 else if (code
!= ERROR_MARK
)
17663 error_at (cloc
, "too many atomic clauses");
17667 else if (new_memory_order
!= OMP_MEMORY_ORDER_UNSPECIFIED
)
17669 if (memory_order
!= OMP_MEMORY_ORDER_UNSPECIFIED
)
17670 error_at (cloc
, "too many memory order clauses");
17672 memory_order
= new_memory_order
;
17674 c_parser_consume_token (parser
);
17680 c_parser_skip_to_pragma_eol (parser
);
17682 if (code
== ERROR_MARK
)
17685 memory_order
= OMP_MEMORY_ORDER_RELAXED
;
17686 else if (memory_order
== OMP_MEMORY_ORDER_UNSPECIFIED
)
17689 = (enum omp_requires
) (omp_requires_mask
17690 | OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED
);
17691 switch ((enum omp_memory_order
)
17692 (omp_requires_mask
& OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
))
17694 case OMP_MEMORY_ORDER_UNSPECIFIED
:
17695 case OMP_MEMORY_ORDER_RELAXED
:
17696 memory_order
= OMP_MEMORY_ORDER_RELAXED
;
17698 case OMP_MEMORY_ORDER_SEQ_CST
:
17699 memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
17701 case OMP_MEMORY_ORDER_ACQ_REL
:
17704 case OMP_ATOMIC_READ
:
17705 memory_order
= OMP_MEMORY_ORDER_ACQUIRE
;
17707 case NOP_EXPR
: /* atomic write */
17709 memory_order
= OMP_MEMORY_ORDER_RELEASE
;
17712 memory_order
= OMP_MEMORY_ORDER_ACQ_REL
;
17717 gcc_unreachable ();
17723 case OMP_ATOMIC_READ
:
17724 if (memory_order
== OMP_MEMORY_ORDER_ACQ_REL
17725 || memory_order
== OMP_MEMORY_ORDER_RELEASE
)
17727 error_at (loc
, "%<#pragma omp atomic read%> incompatible with "
17728 "%<acq_rel%> or %<release%> clauses");
17729 memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
17732 case NOP_EXPR
: /* atomic write */
17733 if (memory_order
== OMP_MEMORY_ORDER_ACQ_REL
17734 || memory_order
== OMP_MEMORY_ORDER_ACQUIRE
)
17736 error_at (loc
, "%<#pragma omp atomic write%> incompatible with "
17737 "%<acq_rel%> or %<acquire%> clauses");
17738 memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
17742 /* case OMP_ATOMIC_CAPTURE_NEW: - or update to OpenMP 5.1 */
17743 if (memory_order
== OMP_MEMORY_ORDER_ACQ_REL
17744 || memory_order
== OMP_MEMORY_ORDER_ACQUIRE
)
17746 error_at (loc
, "%<#pragma omp atomic update%> incompatible with "
17747 "%<acq_rel%> or %<acquire%> clauses");
17748 memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
17757 case OMP_ATOMIC_READ
:
17758 case NOP_EXPR
: /* atomic write */
17759 v
= c_parser_cast_expression (parser
, NULL
).value
;
17760 non_lvalue_p
= !lvalue_p (v
);
17761 v
= c_fully_fold (v
, false, NULL
, true);
17762 if (v
== error_mark_node
)
17765 v
= non_lvalue (v
);
17766 loc
= c_parser_peek_token (parser
)->location
;
17767 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
17769 if (code
== NOP_EXPR
)
17771 lhs
= c_parser_expression (parser
).value
;
17772 lhs
= c_fully_fold (lhs
, false, NULL
);
17773 if (lhs
== error_mark_node
)
17778 lhs
= c_parser_cast_expression (parser
, NULL
).value
;
17779 non_lvalue_p
= !lvalue_p (lhs
);
17780 lhs
= c_fully_fold (lhs
, false, NULL
, true);
17781 if (lhs
== error_mark_node
)
17784 lhs
= non_lvalue (lhs
);
17786 if (code
== NOP_EXPR
)
17788 /* atomic write is represented by OMP_ATOMIC with NOP_EXPR
17796 case OMP_ATOMIC_CAPTURE_NEW
:
17797 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
17799 c_parser_consume_token (parser
);
17800 structured_block
= true;
17804 v
= c_parser_cast_expression (parser
, NULL
).value
;
17805 non_lvalue_p
= !lvalue_p (v
);
17806 v
= c_fully_fold (v
, false, NULL
, true);
17807 if (v
== error_mark_node
)
17810 v
= non_lvalue (v
);
17811 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
17819 /* For structured_block case we don't know yet whether
17820 old or new x should be captured. */
17822 eloc
= c_parser_peek_token (parser
)->location
;
17823 expr
= c_parser_cast_expression (parser
, NULL
);
17825 expr
= default_function_array_conversion (eloc
, expr
);
17826 unfolded_lhs
= expr
.value
;
17827 lhs
= c_fully_fold (lhs
, false, NULL
, true);
17829 switch (TREE_CODE (lhs
))
17833 c_parser_skip_to_end_of_block_or_statement (parser
);
17834 if (structured_block
)
17836 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
17837 c_parser_consume_token (parser
);
17838 else if (code
== OMP_ATOMIC_CAPTURE_NEW
)
17840 c_parser_skip_to_end_of_block_or_statement (parser
);
17841 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
17842 c_parser_consume_token (parser
);
17847 case POSTINCREMENT_EXPR
:
17848 if (code
== OMP_ATOMIC_CAPTURE_NEW
&& !structured_block
)
17849 code
= OMP_ATOMIC_CAPTURE_OLD
;
17851 case PREINCREMENT_EXPR
:
17852 lhs
= TREE_OPERAND (lhs
, 0);
17853 unfolded_lhs
= NULL_TREE
;
17854 opcode
= PLUS_EXPR
;
17855 rhs
= integer_one_node
;
17858 case POSTDECREMENT_EXPR
:
17859 if (code
== OMP_ATOMIC_CAPTURE_NEW
&& !structured_block
)
17860 code
= OMP_ATOMIC_CAPTURE_OLD
;
17862 case PREDECREMENT_EXPR
:
17863 lhs
= TREE_OPERAND (lhs
, 0);
17864 unfolded_lhs
= NULL_TREE
;
17865 opcode
= MINUS_EXPR
;
17866 rhs
= integer_one_node
;
17869 case COMPOUND_EXPR
:
17870 if (TREE_CODE (TREE_OPERAND (lhs
, 0)) == SAVE_EXPR
17871 && TREE_CODE (TREE_OPERAND (lhs
, 1)) == COMPOUND_EXPR
17872 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (lhs
, 1), 0)) == MODIFY_EXPR
17873 && TREE_OPERAND (TREE_OPERAND (lhs
, 1), 1) == TREE_OPERAND (lhs
, 0)
17874 && TREE_CODE (TREE_TYPE (TREE_OPERAND (TREE_OPERAND
17875 (TREE_OPERAND (lhs
, 1), 0), 0)))
17877 /* Undo effects of boolean_increment for post {in,de}crement. */
17878 lhs
= TREE_OPERAND (TREE_OPERAND (lhs
, 1), 0);
17881 if (TREE_CODE (lhs
) == MODIFY_EXPR
17882 && TREE_CODE (TREE_TYPE (TREE_OPERAND (lhs
, 0))) == BOOLEAN_TYPE
)
17884 /* Undo effects of boolean_increment. */
17885 if (integer_onep (TREE_OPERAND (lhs
, 1)))
17887 /* This is pre or post increment. */
17888 rhs
= TREE_OPERAND (lhs
, 1);
17889 lhs
= TREE_OPERAND (lhs
, 0);
17890 unfolded_lhs
= NULL_TREE
;
17892 if (code
== OMP_ATOMIC_CAPTURE_NEW
17893 && !structured_block
17894 && TREE_CODE (orig_lhs
) == COMPOUND_EXPR
)
17895 code
= OMP_ATOMIC_CAPTURE_OLD
;
17898 if (TREE_CODE (TREE_OPERAND (lhs
, 1)) == TRUTH_NOT_EXPR
17899 && TREE_OPERAND (lhs
, 0)
17900 == TREE_OPERAND (TREE_OPERAND (lhs
, 1), 0))
17902 /* This is pre or post decrement. */
17903 rhs
= TREE_OPERAND (lhs
, 1);
17904 lhs
= TREE_OPERAND (lhs
, 0);
17905 unfolded_lhs
= NULL_TREE
;
17907 if (code
== OMP_ATOMIC_CAPTURE_NEW
17908 && !structured_block
17909 && TREE_CODE (orig_lhs
) == COMPOUND_EXPR
)
17910 code
= OMP_ATOMIC_CAPTURE_OLD
;
17916 if (!lvalue_p (unfolded_lhs
))
17917 lhs
= non_lvalue (lhs
);
17918 switch (c_parser_peek_token (parser
)->type
)
17921 opcode
= MULT_EXPR
;
17924 opcode
= TRUNC_DIV_EXPR
;
17927 opcode
= PLUS_EXPR
;
17930 opcode
= MINUS_EXPR
;
17932 case CPP_LSHIFT_EQ
:
17933 opcode
= LSHIFT_EXPR
;
17935 case CPP_RSHIFT_EQ
:
17936 opcode
= RSHIFT_EXPR
;
17939 opcode
= BIT_AND_EXPR
;
17942 opcode
= BIT_IOR_EXPR
;
17945 opcode
= BIT_XOR_EXPR
;
17948 c_parser_consume_token (parser
);
17949 eloc
= c_parser_peek_token (parser
)->location
;
17950 expr
= c_parser_expr_no_commas (parser
, NULL
, unfolded_lhs
);
17952 switch (TREE_CODE (rhs1
))
17955 case TRUNC_DIV_EXPR
:
17964 if (c_tree_equal (TREE_OPERAND (rhs1
, 0), unfolded_lhs
))
17966 opcode
= TREE_CODE (rhs1
);
17967 rhs
= c_fully_fold (TREE_OPERAND (rhs1
, 1), false, NULL
,
17969 rhs1
= c_fully_fold (TREE_OPERAND (rhs1
, 0), false, NULL
,
17973 if (c_tree_equal (TREE_OPERAND (rhs1
, 1), unfolded_lhs
))
17975 opcode
= TREE_CODE (rhs1
);
17976 rhs
= c_fully_fold (TREE_OPERAND (rhs1
, 0), false, NULL
,
17978 rhs1
= c_fully_fold (TREE_OPERAND (rhs1
, 1), false, NULL
,
17980 swapped
= !commutative_tree_code (opcode
);
17989 if (c_parser_peek_token (parser
)->type
== CPP_SEMICOLON
)
17991 if (structured_block
&& code
== OMP_ATOMIC_CAPTURE_NEW
)
17993 code
= OMP_ATOMIC_CAPTURE_OLD
;
17996 expr
= default_function_array_read_conversion (eloc
, expr
);
17997 unfolded_lhs1
= expr
.value
;
17998 lhs1
= c_fully_fold (unfolded_lhs1
, false, NULL
, true);
18000 c_parser_consume_token (parser
);
18003 if (structured_block
)
18006 expr
= default_function_array_read_conversion (eloc
, expr
);
18007 rhs
= c_fully_fold (expr
.value
, false, NULL
, true);
18012 c_parser_error (parser
, "invalid form of %<#pragma omp atomic%>");
18015 c_parser_error (parser
,
18016 "invalid operator for %<#pragma omp atomic%>");
18020 /* Arrange to pass the location of the assignment operator to
18021 c_finish_omp_atomic. */
18022 loc
= c_parser_peek_token (parser
)->location
;
18023 c_parser_consume_token (parser
);
18024 eloc
= c_parser_peek_token (parser
)->location
;
18025 expr
= c_parser_expression (parser
);
18026 expr
= default_function_array_read_conversion (eloc
, expr
);
18028 rhs
= c_fully_fold (rhs
, false, NULL
, true);
18032 if (structured_block
&& code
== OMP_ATOMIC_CAPTURE_NEW
)
18034 if (!c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
18036 v
= c_parser_cast_expression (parser
, NULL
).value
;
18037 non_lvalue_p
= !lvalue_p (v
);
18038 v
= c_fully_fold (v
, false, NULL
, true);
18039 if (v
== error_mark_node
)
18042 v
= non_lvalue (v
);
18043 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
18045 eloc
= c_parser_peek_token (parser
)->location
;
18046 expr
= c_parser_cast_expression (parser
, NULL
);
18048 expr
= default_function_array_read_conversion (eloc
, expr
);
18049 unfolded_lhs1
= expr
.value
;
18050 lhs1
= c_fully_fold (lhs1
, false, NULL
, true);
18051 if (lhs1
== error_mark_node
)
18053 if (!lvalue_p (unfolded_lhs1
))
18054 lhs1
= non_lvalue (lhs1
);
18056 if (structured_block
)
18058 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
18059 c_parser_require (parser
, CPP_CLOSE_BRACE
, "expected %<}%>");
18062 if (unfolded_lhs
&& unfolded_lhs1
18063 && !c_tree_equal (unfolded_lhs
, unfolded_lhs1
))
18065 error ("%<#pragma omp atomic capture%> uses two different "
18066 "expressions for memory");
18067 stmt
= error_mark_node
;
18070 stmt
= c_finish_omp_atomic (loc
, code
, opcode
, lhs
, rhs
, v
, lhs1
, rhs1
,
18071 swapped
, memory_order
);
18072 if (stmt
!= error_mark_node
)
18075 if (!structured_block
)
18076 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
18081 # pragma omp barrier new-line
18085 c_parser_omp_barrier (c_parser
*parser
)
18087 location_t loc
= c_parser_peek_token (parser
)->location
;
18088 c_parser_consume_pragma (parser
);
18089 c_parser_skip_to_pragma_eol (parser
);
18091 c_finish_omp_barrier (loc
);
18095 # pragma omp critical [(name)] new-line
18099 # pragma omp critical [(name) [hint(expression)]] new-line
18101 LOC is the location of the #pragma itself. */
18103 #define OMP_CRITICAL_CLAUSE_MASK \
18104 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HINT) )
18107 c_parser_omp_critical (location_t loc
, c_parser
*parser
, bool *if_p
)
18109 tree stmt
, name
= NULL_TREE
, clauses
= NULL_TREE
;
18111 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
18113 c_parser_consume_token (parser
);
18114 if (c_parser_next_token_is (parser
, CPP_NAME
))
18116 name
= c_parser_peek_token (parser
)->value
;
18117 c_parser_consume_token (parser
);
18118 c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>");
18121 c_parser_error (parser
, "expected identifier");
18123 if (c_parser_next_token_is (parser
, CPP_COMMA
)
18124 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
18125 c_parser_consume_token (parser
);
18127 clauses
= c_parser_omp_all_clauses (parser
, OMP_CRITICAL_CLAUSE_MASK
,
18128 "#pragma omp critical");
18129 stmt
= c_parser_omp_structured_block (parser
, if_p
);
18130 return c_finish_omp_critical (loc
, stmt
, name
, clauses
);
18134 # pragma omp depobj ( depobj ) depobj-clause new-line
18137 depend (dependence-type : locator)
18139 update (dependence-type)
18148 c_parser_omp_depobj (c_parser
*parser
)
18150 location_t loc
= c_parser_peek_token (parser
)->location
;
18151 c_parser_consume_pragma (parser
);
18152 matching_parens parens
;
18153 if (!parens
.require_open (parser
))
18155 c_parser_skip_to_pragma_eol (parser
);
18159 tree depobj
= c_parser_expr_no_commas (parser
, NULL
).value
;
18160 if (depobj
!= error_mark_node
)
18162 if (!lvalue_p (depobj
))
18164 error_at (EXPR_LOC_OR_LOC (depobj
, loc
),
18165 "%<depobj%> expression is not lvalue expression");
18166 depobj
= error_mark_node
;
18170 tree addr
= build_unary_op (EXPR_LOC_OR_LOC (depobj
, loc
), ADDR_EXPR
,
18172 if (addr
== error_mark_node
)
18173 depobj
= error_mark_node
;
18175 depobj
= build_indirect_ref (EXPR_LOC_OR_LOC (depobj
, loc
),
18176 addr
, RO_UNARY_STAR
);
18180 parens
.skip_until_found_close (parser
);
18181 tree clause
= NULL_TREE
;
18182 enum omp_clause_depend_kind kind
= OMP_CLAUSE_DEPEND_SOURCE
;
18183 location_t c_loc
= c_parser_peek_token (parser
)->location
;
18184 if (c_parser_next_token_is (parser
, CPP_NAME
))
18186 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18188 c_parser_consume_token (parser
);
18189 if (!strcmp ("depend", p
))
18191 clause
= c_parser_omp_clause_depend (parser
, NULL_TREE
);
18192 clause
= c_finish_omp_clauses (clause
, C_ORT_OMP
);
18194 clause
= error_mark_node
;
18196 else if (!strcmp ("destroy", p
))
18197 kind
= OMP_CLAUSE_DEPEND_LAST
;
18198 else if (!strcmp ("update", p
))
18200 matching_parens c_parens
;
18201 if (c_parens
.require_open (parser
))
18203 location_t c2_loc
= c_parser_peek_token (parser
)->location
;
18204 if (c_parser_next_token_is (parser
, CPP_NAME
))
18207 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18209 c_parser_consume_token (parser
);
18210 if (!strcmp ("in", p2
))
18211 kind
= OMP_CLAUSE_DEPEND_IN
;
18212 else if (!strcmp ("out", p2
))
18213 kind
= OMP_CLAUSE_DEPEND_OUT
;
18214 else if (!strcmp ("inout", p2
))
18215 kind
= OMP_CLAUSE_DEPEND_INOUT
;
18216 else if (!strcmp ("mutexinoutset", p2
))
18217 kind
= OMP_CLAUSE_DEPEND_MUTEXINOUTSET
;
18219 if (kind
== OMP_CLAUSE_DEPEND_SOURCE
)
18221 clause
= error_mark_node
;
18222 error_at (c2_loc
, "expected %<in%>, %<out%>, %<inout%> or "
18223 "%<mutexinoutset%>");
18225 c_parens
.skip_until_found_close (parser
);
18228 clause
= error_mark_node
;
18231 if (!clause
&& kind
== OMP_CLAUSE_DEPEND_SOURCE
)
18233 clause
= error_mark_node
;
18234 error_at (c_loc
, "expected %<depend%>, %<destroy%> or %<update%> clause");
18236 c_parser_skip_to_pragma_eol (parser
);
18238 c_finish_omp_depobj (loc
, depobj
, kind
, clause
);
18243 # pragma omp flush flush-vars[opt] new-line
18249 # pragma omp flush memory-order-clause new-line */
18252 c_parser_omp_flush (c_parser
*parser
)
18254 location_t loc
= c_parser_peek_token (parser
)->location
;
18255 c_parser_consume_pragma (parser
);
18256 enum memmodel mo
= MEMMODEL_LAST
;
18257 if (c_parser_next_token_is (parser
, CPP_NAME
))
18260 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18262 if (!strcmp (p
, "acq_rel"))
18263 mo
= MEMMODEL_ACQ_REL
;
18264 else if (!strcmp (p
, "release"))
18265 mo
= MEMMODEL_RELEASE
;
18266 else if (!strcmp (p
, "acquire"))
18267 mo
= MEMMODEL_ACQUIRE
;
18269 error_at (c_parser_peek_token (parser
)->location
,
18270 "expected %<acq_rel%>, %<release%> or %<acquire%>");
18271 c_parser_consume_token (parser
);
18273 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
18275 if (mo
!= MEMMODEL_LAST
)
18276 error_at (c_parser_peek_token (parser
)->location
,
18277 "%<flush%> list specified together with memory order "
18279 c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ERROR
, NULL
);
18281 else if (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
18282 c_parser_error (parser
, "expected %<(%> or end of line");
18283 c_parser_skip_to_pragma_eol (parser
);
18285 c_finish_omp_flush (loc
, mo
);
18291 { structured-block scan-directive structured-block } */
18294 c_parser_omp_scan_loop_body (c_parser
*parser
, bool open_brace_parsed
)
18298 tree clauses
= NULL_TREE
;
18300 loc
= c_parser_peek_token (parser
)->location
;
18301 if (!open_brace_parsed
18302 && !c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
18304 /* Avoid skipping until the end of the block. */
18305 parser
->error
= false;
18309 substmt
= c_parser_omp_structured_block (parser
, NULL
);
18310 substmt
= build2 (OMP_SCAN
, void_type_node
, substmt
, NULL_TREE
);
18311 SET_EXPR_LOCATION (substmt
, loc
);
18312 add_stmt (substmt
);
18314 loc
= c_parser_peek_token (parser
)->location
;
18315 if (c_parser_peek_token (parser
)->pragma_kind
== PRAGMA_OMP_SCAN
)
18317 enum omp_clause_code clause
= OMP_CLAUSE_ERROR
;
18319 c_parser_consume_pragma (parser
);
18321 if (c_parser_next_token_is (parser
, CPP_NAME
))
18324 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18325 if (strcmp (p
, "inclusive") == 0)
18326 clause
= OMP_CLAUSE_INCLUSIVE
;
18327 else if (strcmp (p
, "exclusive") == 0)
18328 clause
= OMP_CLAUSE_EXCLUSIVE
;
18330 if (clause
!= OMP_CLAUSE_ERROR
)
18332 c_parser_consume_token (parser
);
18333 clauses
= c_parser_omp_var_list_parens (parser
, clause
, NULL_TREE
);
18336 c_parser_error (parser
, "expected %<inclusive%> or "
18337 "%<exclusive%> clause");
18338 c_parser_skip_to_pragma_eol (parser
);
18341 error ("expected %<#pragma omp scan%>");
18343 clauses
= c_finish_omp_clauses (clauses
, C_ORT_OMP
);
18344 substmt
= c_parser_omp_structured_block (parser
, NULL
);
18345 substmt
= build2 (OMP_SCAN
, void_type_node
, substmt
, clauses
);
18346 SET_EXPR_LOCATION (substmt
, loc
);
18347 add_stmt (substmt
);
18349 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
,
18353 /* Parse the restricted form of loop statements allowed by OpenACC and OpenMP.
18354 The real trick here is to determine the loop control variable early
18355 so that we can push a new decl if necessary to make it private.
18356 LOC is the location of the "acc" or "omp" in "#pragma acc" or "#pragma omp",
18360 c_parser_omp_for_loop (location_t loc
, c_parser
*parser
, enum tree_code code
,
18361 tree clauses
, tree
*cclauses
, bool *if_p
)
18363 tree decl
, cond
, incr
, body
, init
, stmt
, cl
;
18364 unsigned char save_in_statement
;
18365 tree declv
, condv
, incrv
, initv
, ret
= NULL_TREE
;
18366 tree pre_body
= NULL_TREE
, this_pre_body
;
18367 tree ordered_cl
= NULL_TREE
;
18368 bool fail
= false, open_brace_parsed
= false;
18369 int i
, collapse
= 1, ordered
= 0, count
, nbraces
= 0;
18370 location_t for_loc
;
18371 bool tiling
= false;
18372 bool inscan
= false;
18373 vec
<tree
, va_gc
> *for_block
= make_tree_vector ();
18375 for (cl
= clauses
; cl
; cl
= OMP_CLAUSE_CHAIN (cl
))
18376 if (OMP_CLAUSE_CODE (cl
) == OMP_CLAUSE_COLLAPSE
)
18377 collapse
= tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (cl
));
18378 else if (OMP_CLAUSE_CODE (cl
) == OMP_CLAUSE_TILE
)
18381 collapse
= list_length (OMP_CLAUSE_TILE_LIST (cl
));
18383 else if (OMP_CLAUSE_CODE (cl
) == OMP_CLAUSE_ORDERED
18384 && OMP_CLAUSE_ORDERED_EXPR (cl
))
18387 ordered
= tree_to_shwi (OMP_CLAUSE_ORDERED_EXPR (cl
));
18389 else if (OMP_CLAUSE_CODE (cl
) == OMP_CLAUSE_REDUCTION
18390 && OMP_CLAUSE_REDUCTION_INSCAN (cl
)
18391 && (code
== OMP_SIMD
|| code
== OMP_FOR
))
18394 if (ordered
&& ordered
< collapse
)
18396 error_at (OMP_CLAUSE_LOCATION (ordered_cl
),
18397 "%<ordered%> clause parameter is less than %<collapse%>");
18398 OMP_CLAUSE_ORDERED_EXPR (ordered_cl
)
18399 = build_int_cst (NULL_TREE
, collapse
);
18400 ordered
= collapse
;
18404 for (tree
*pc
= &clauses
; *pc
; )
18405 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_LINEAR
)
18407 error_at (OMP_CLAUSE_LOCATION (*pc
),
18408 "%<linear%> clause may not be specified together "
18409 "with %<ordered%> clause with a parameter");
18410 *pc
= OMP_CLAUSE_CHAIN (*pc
);
18413 pc
= &OMP_CLAUSE_CHAIN (*pc
);
18416 gcc_assert (tiling
|| (collapse
>= 1 && ordered
>= 0));
18417 count
= ordered
? ordered
: collapse
;
18419 declv
= make_tree_vec (count
);
18420 initv
= make_tree_vec (count
);
18421 condv
= make_tree_vec (count
);
18422 incrv
= make_tree_vec (count
);
18424 if (!c_parser_next_token_is_keyword (parser
, RID_FOR
))
18426 c_parser_error (parser
, "for statement expected");
18429 for_loc
= c_parser_peek_token (parser
)->location
;
18430 c_parser_consume_token (parser
);
18432 /* Forbid break/continue in the loop initializer, condition, and
18433 increment expressions. */
18434 save_in_statement
= in_statement
;
18435 in_statement
= IN_OMP_BLOCK
;
18437 for (i
= 0; i
< count
; i
++)
18439 int bracecount
= 0;
18441 matching_parens parens
;
18442 if (!parens
.require_open (parser
))
18445 /* Parse the initialization declaration or expression. */
18446 if (c_parser_next_tokens_start_declaration (parser
))
18449 vec_safe_push (for_block
, c_begin_compound_stmt (true));
18450 this_pre_body
= push_stmt_list ();
18451 c_in_omp_for
= true;
18452 c_parser_declaration_or_fndef (parser
, true, true, true, true, true);
18453 c_in_omp_for
= false;
18456 this_pre_body
= pop_stmt_list (this_pre_body
);
18460 pre_body
= push_stmt_list ();
18462 add_stmt (this_pre_body
);
18463 pre_body
= pop_stmt_list (pre_body
);
18466 pre_body
= this_pre_body
;
18468 decl
= check_for_loop_decls (for_loc
, flag_isoc99
);
18471 if (DECL_INITIAL (decl
) == error_mark_node
)
18472 decl
= error_mark_node
;
18475 else if (c_parser_next_token_is (parser
, CPP_NAME
)
18476 && c_parser_peek_2nd_token (parser
)->type
== CPP_EQ
)
18478 struct c_expr decl_exp
;
18479 struct c_expr init_exp
;
18480 location_t init_loc
;
18482 decl_exp
= c_parser_postfix_expression (parser
);
18483 decl
= decl_exp
.value
;
18485 c_parser_require (parser
, CPP_EQ
, "expected %<=%>");
18487 init_loc
= c_parser_peek_token (parser
)->location
;
18488 init_exp
= c_parser_expr_no_commas (parser
, NULL
);
18489 init_exp
= default_function_array_read_conversion (init_loc
,
18491 c_in_omp_for
= true;
18492 init
= build_modify_expr (init_loc
, decl
, decl_exp
.original_type
,
18493 NOP_EXPR
, init_loc
, init_exp
.value
,
18494 init_exp
.original_type
);
18495 c_in_omp_for
= false;
18496 init
= c_process_expr_stmt (init_loc
, init
);
18498 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
18503 c_parser_error (parser
,
18504 "expected iteration declaration or initialization");
18505 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
18511 /* Parse the loop condition. */
18513 if (c_parser_next_token_is_not (parser
, CPP_SEMICOLON
))
18515 location_t cond_loc
= c_parser_peek_token (parser
)->location
;
18516 c_in_omp_for
= true;
18517 struct c_expr cond_expr
18518 = c_parser_binary_expression (parser
, NULL
, NULL_TREE
);
18519 c_in_omp_for
= false;
18521 cond
= cond_expr
.value
;
18522 cond
= c_objc_common_truthvalue_conversion (cond_loc
, cond
);
18523 switch (cond_expr
.original_code
)
18531 if (code
!= OACC_LOOP
)
18535 /* Can't be cond = error_mark_node, because we want to preserve
18536 the location until c_finish_omp_for. */
18537 cond
= build1 (NOP_EXPR
, boolean_type_node
, error_mark_node
);
18540 protected_set_expr_location (cond
, cond_loc
);
18542 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
18544 /* Parse the increment expression. */
18546 if (c_parser_next_token_is_not (parser
, CPP_CLOSE_PAREN
))
18548 location_t incr_loc
= c_parser_peek_token (parser
)->location
;
18550 incr
= c_process_expr_stmt (incr_loc
,
18551 c_parser_expression (parser
).value
);
18553 parens
.skip_until_found_close (parser
);
18555 if (decl
== NULL
|| decl
== error_mark_node
|| init
== error_mark_node
)
18559 TREE_VEC_ELT (declv
, i
) = decl
;
18560 TREE_VEC_ELT (initv
, i
) = init
;
18561 TREE_VEC_ELT (condv
, i
) = cond
;
18562 TREE_VEC_ELT (incrv
, i
) = incr
;
18566 if (i
== count
- 1)
18569 /* FIXME: OpenMP 3.0 draft isn't very clear on what exactly is allowed
18570 in between the collapsed for loops to be still considered perfectly
18571 nested. Hopefully the final version clarifies this.
18572 For now handle (multiple) {'s and empty statements. */
18575 if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
18577 c_parser_consume_token (parser
);
18580 else if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
18582 c_parser_consume_token (parser
);
18585 else if (bracecount
18586 && c_parser_next_token_is (parser
, CPP_SEMICOLON
))
18587 c_parser_consume_token (parser
);
18590 c_parser_error (parser
, "not enough perfectly nested loops");
18593 open_brace_parsed
= true;
18603 nbraces
+= bracecount
;
18609 in_statement
= IN_OMP_FOR
;
18610 body
= push_stmt_list ();
18613 c_parser_omp_scan_loop_body (parser
, open_brace_parsed
);
18614 else if (open_brace_parsed
)
18616 location_t here
= c_parser_peek_token (parser
)->location
;
18617 stmt
= c_begin_compound_stmt (true);
18618 c_parser_compound_statement_nostart (parser
);
18619 add_stmt (c_end_compound_stmt (here
, stmt
, true));
18622 add_stmt (c_parser_c99_block_statement (parser
, if_p
));
18624 body
= pop_stmt_list (body
);
18625 in_statement
= save_in_statement
;
18629 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
18631 c_parser_consume_token (parser
);
18634 else if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
18635 c_parser_consume_token (parser
);
18638 c_parser_error (parser
, "collapsed loops not perfectly nested");
18641 location_t here
= c_parser_peek_token (parser
)->location
;
18642 stmt
= c_begin_compound_stmt (true);
18644 c_parser_compound_statement_nostart (parser
);
18645 body
= c_end_compound_stmt (here
, stmt
, true);
18652 /* Only bother calling c_finish_omp_for if we haven't already generated
18653 an error from the initialization parsing. */
18656 c_in_omp_for
= true;
18657 stmt
= c_finish_omp_for (loc
, code
, declv
, NULL
, initv
, condv
,
18658 incrv
, body
, pre_body
, true);
18659 c_in_omp_for
= false;
18661 /* Check for iterators appearing in lb, b or incr expressions. */
18662 if (stmt
&& !c_omp_check_loop_iv (stmt
, declv
, NULL
))
18669 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (stmt
)); i
++)
18671 tree init
= TREE_VEC_ELT (OMP_FOR_INIT (stmt
), i
);
18672 gcc_assert (TREE_CODE (init
) == MODIFY_EXPR
);
18673 tree decl
= TREE_OPERAND (init
, 0);
18674 tree cond
= TREE_VEC_ELT (OMP_FOR_COND (stmt
), i
);
18675 gcc_assert (COMPARISON_CLASS_P (cond
));
18676 gcc_assert (TREE_OPERAND (cond
, 0) == decl
);
18678 tree op0
= TREE_OPERAND (init
, 1);
18679 if (!OMP_FOR_NON_RECTANGULAR (stmt
)
18680 || TREE_CODE (op0
) != TREE_VEC
)
18681 TREE_OPERAND (init
, 1) = c_fully_fold (op0
, false, NULL
);
18684 TREE_VEC_ELT (op0
, 1)
18685 = c_fully_fold (TREE_VEC_ELT (op0
, 1), false, NULL
);
18686 TREE_VEC_ELT (op0
, 2)
18687 = c_fully_fold (TREE_VEC_ELT (op0
, 2), false, NULL
);
18690 tree op1
= TREE_OPERAND (cond
, 1);
18691 if (!OMP_FOR_NON_RECTANGULAR (stmt
)
18692 || TREE_CODE (op1
) != TREE_VEC
)
18693 TREE_OPERAND (cond
, 1) = c_fully_fold (op1
, false, NULL
);
18696 TREE_VEC_ELT (op1
, 1)
18697 = c_fully_fold (TREE_VEC_ELT (op1
, 1), false, NULL
);
18698 TREE_VEC_ELT (op1
, 2)
18699 = c_fully_fold (TREE_VEC_ELT (op1
, 2), false, NULL
);
18703 if (cclauses
!= NULL
18704 && cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
] != NULL
)
18707 for (c
= &cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
]; *c
; )
18708 if (OMP_CLAUSE_CODE (*c
) != OMP_CLAUSE_FIRSTPRIVATE
18709 && OMP_CLAUSE_CODE (*c
) != OMP_CLAUSE_LASTPRIVATE
)
18710 c
= &OMP_CLAUSE_CHAIN (*c
);
18713 for (i
= 0; i
< count
; i
++)
18714 if (TREE_VEC_ELT (declv
, i
) == OMP_CLAUSE_DECL (*c
))
18717 c
= &OMP_CLAUSE_CHAIN (*c
);
18718 else if (OMP_CLAUSE_CODE (*c
) == OMP_CLAUSE_FIRSTPRIVATE
)
18721 "iteration variable %qD should not be firstprivate",
18722 OMP_CLAUSE_DECL (*c
));
18723 *c
= OMP_CLAUSE_CHAIN (*c
);
18727 /* Move lastprivate (decl) clause to OMP_FOR_CLAUSES. */
18729 *c
= OMP_CLAUSE_CHAIN (*c
);
18730 if (code
== OMP_SIMD
)
18732 OMP_CLAUSE_CHAIN (l
)
18733 = cclauses
[C_OMP_CLAUSE_SPLIT_FOR
];
18734 cclauses
[C_OMP_CLAUSE_SPLIT_FOR
] = l
;
18738 OMP_CLAUSE_CHAIN (l
) = clauses
;
18744 OMP_FOR_CLAUSES (stmt
) = clauses
;
18749 while (!for_block
->is_empty ())
18751 /* FIXME diagnostics: LOC below should be the actual location of
18752 this particular for block. We need to build a list of
18753 locations to go along with FOR_BLOCK. */
18754 stmt
= c_end_compound_stmt (loc
, for_block
->pop (), true);
18757 release_tree_vector (for_block
);
18761 /* Helper function for OpenMP parsing, split clauses and call
18762 finish_omp_clauses on each of the set of clauses afterwards. */
18765 omp_split_clauses (location_t loc
, enum tree_code code
,
18766 omp_clause_mask mask
, tree clauses
, tree
*cclauses
)
18769 c_omp_split_clauses (loc
, code
, mask
, clauses
, cclauses
);
18770 for (i
= 0; i
< C_OMP_CLAUSE_SPLIT_COUNT
; i
++)
18772 cclauses
[i
] = c_finish_omp_clauses (cclauses
[i
],
18773 i
== C_OMP_CLAUSE_SPLIT_TARGET
18774 ? C_ORT_OMP_TARGET
: C_ORT_OMP
);
18778 #pragma omp loop loop-clause[optseq] new-line
18781 LOC is the location of the #pragma token.
18784 #define OMP_LOOP_CLAUSE_MASK \
18785 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
18786 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
18787 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
18788 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
18789 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_BIND) \
18790 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
18793 c_parser_omp_loop (location_t loc
, c_parser
*parser
,
18794 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
18797 tree block
, clauses
, ret
;
18799 strcat (p_name
, " loop");
18800 mask
|= OMP_LOOP_CLAUSE_MASK
;
18802 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
18805 omp_split_clauses (loc
, OMP_LOOP
, mask
, clauses
, cclauses
);
18806 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_LOOP
];
18809 block
= c_begin_compound_stmt (true);
18810 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_LOOP
, clauses
, cclauses
, if_p
);
18811 block
= c_end_compound_stmt (loc
, block
, true);
18818 #pragma omp simd simd-clause[optseq] new-line
18821 LOC is the location of the #pragma token.
18824 #define OMP_SIMD_CLAUSE_MASK \
18825 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SAFELEN) \
18826 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
18827 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
18828 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
18829 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
18830 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
18831 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
18832 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
18833 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
18834 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NONTEMPORAL) \
18835 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
18838 c_parser_omp_simd (location_t loc
, c_parser
*parser
,
18839 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
18842 tree block
, clauses
, ret
;
18844 strcat (p_name
, " simd");
18845 mask
|= OMP_SIMD_CLAUSE_MASK
;
18847 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
18850 omp_split_clauses (loc
, OMP_SIMD
, mask
, clauses
, cclauses
);
18851 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_SIMD
];
18852 tree c
= omp_find_clause (cclauses
[C_OMP_CLAUSE_SPLIT_FOR
],
18853 OMP_CLAUSE_ORDERED
);
18854 if (c
&& OMP_CLAUSE_ORDERED_EXPR (c
))
18856 error_at (OMP_CLAUSE_LOCATION (c
),
18857 "%<ordered%> clause with parameter may not be specified "
18858 "on %qs construct", p_name
);
18859 OMP_CLAUSE_ORDERED_EXPR (c
) = NULL_TREE
;
18863 block
= c_begin_compound_stmt (true);
18864 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_SIMD
, clauses
, cclauses
, if_p
);
18865 block
= c_end_compound_stmt (loc
, block
, true);
18872 #pragma omp for for-clause[optseq] new-line
18876 #pragma omp for simd for-simd-clause[optseq] new-line
18879 LOC is the location of the #pragma token.
18882 #define OMP_FOR_CLAUSE_MASK \
18883 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
18884 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
18885 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
18886 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
18887 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
18888 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED) \
18889 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE) \
18890 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
18891 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
18892 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
18893 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
18896 c_parser_omp_for (location_t loc
, c_parser
*parser
,
18897 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
18900 tree block
, clauses
, ret
;
18902 strcat (p_name
, " for");
18903 mask
|= OMP_FOR_CLAUSE_MASK
;
18904 /* parallel for{, simd} disallows nowait clause, but for
18905 target {teams distribute ,}parallel for{, simd} it should be accepted. */
18906 if (cclauses
&& (mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_MAP
)) == 0)
18907 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_NOWAIT
);
18908 /* Composite distribute parallel for{, simd} disallows ordered clause. */
18909 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
)) != 0)
18910 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_ORDERED
);
18912 if (c_parser_next_token_is (parser
, CPP_NAME
))
18914 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18916 if (strcmp (p
, "simd") == 0)
18918 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
18919 if (cclauses
== NULL
)
18920 cclauses
= cclauses_buf
;
18922 c_parser_consume_token (parser
);
18923 if (!flag_openmp
) /* flag_openmp_simd */
18924 return c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
,
18926 block
= c_begin_compound_stmt (true);
18927 ret
= c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
18928 block
= c_end_compound_stmt (loc
, block
, true);
18929 if (ret
== NULL_TREE
)
18931 ret
= make_node (OMP_FOR
);
18932 TREE_TYPE (ret
) = void_type_node
;
18933 OMP_FOR_BODY (ret
) = block
;
18934 OMP_FOR_CLAUSES (ret
) = cclauses
[C_OMP_CLAUSE_SPLIT_FOR
];
18935 SET_EXPR_LOCATION (ret
, loc
);
18940 if (!flag_openmp
) /* flag_openmp_simd */
18942 c_parser_skip_to_pragma_eol (parser
, false);
18946 /* Composite distribute parallel for disallows linear clause. */
18947 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
)) != 0)
18948 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_LINEAR
);
18950 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
18953 omp_split_clauses (loc
, OMP_FOR
, mask
, clauses
, cclauses
);
18954 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_FOR
];
18957 block
= c_begin_compound_stmt (true);
18958 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_FOR
, clauses
, cclauses
, if_p
);
18959 block
= c_end_compound_stmt (loc
, block
, true);
18965 static tree
c_parser_omp_taskloop (location_t
, c_parser
*, char *,
18966 omp_clause_mask
, tree
*, bool *);
18969 # pragma omp master new-line
18972 LOC is the location of the #pragma token.
18976 c_parser_omp_master (location_t loc
, c_parser
*parser
,
18977 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
18980 tree block
, clauses
, ret
;
18982 strcat (p_name
, " master");
18984 if (c_parser_next_token_is (parser
, CPP_NAME
))
18986 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18988 if (strcmp (p
, "taskloop") == 0)
18990 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
18991 if (cclauses
== NULL
)
18992 cclauses
= cclauses_buf
;
18994 c_parser_consume_token (parser
);
18995 if (!flag_openmp
) /* flag_openmp_simd */
18996 return c_parser_omp_taskloop (loc
, parser
, p_name
, mask
, cclauses
,
18998 block
= c_begin_compound_stmt (true);
18999 ret
= c_parser_omp_taskloop (loc
, parser
, p_name
, mask
, cclauses
,
19001 block
= c_end_compound_stmt (loc
, block
, true);
19002 if (ret
== NULL_TREE
)
19004 ret
= c_finish_omp_master (loc
, block
);
19005 OMP_MASTER_COMBINED (ret
) = 1;
19009 if (!flag_openmp
) /* flag_openmp_simd */
19011 c_parser_skip_to_pragma_eol (parser
, false);
19017 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, false);
19018 omp_split_clauses (loc
, OMP_MASTER
, mask
, clauses
, cclauses
);
19021 c_parser_skip_to_pragma_eol (parser
);
19023 return c_finish_omp_master (loc
, c_parser_omp_structured_block (parser
,
19028 # pragma omp masked masked-clauses new-line
19031 LOC is the location of the #pragma token.
19034 #define OMP_MASKED_CLAUSE_MASK \
19035 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FILTER)
19038 c_parser_omp_masked (location_t loc
, c_parser
*parser
,
19039 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
19042 tree block
, clauses
, ret
;
19044 strcat (p_name
, " masked");
19045 mask
|= OMP_MASKED_CLAUSE_MASK
;
19047 if (c_parser_next_token_is (parser
, CPP_NAME
))
19049 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
19051 if (strcmp (p
, "taskloop") == 0)
19053 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
19054 if (cclauses
== NULL
)
19055 cclauses
= cclauses_buf
;
19057 c_parser_consume_token (parser
);
19058 if (!flag_openmp
) /* flag_openmp_simd */
19059 return c_parser_omp_taskloop (loc
, parser
, p_name
, mask
, cclauses
,
19061 block
= c_begin_compound_stmt (true);
19062 ret
= c_parser_omp_taskloop (loc
, parser
, p_name
, mask
, cclauses
,
19064 block
= c_end_compound_stmt (loc
, block
, true);
19065 if (ret
== NULL_TREE
)
19067 ret
= c_finish_omp_masked (loc
, block
,
19068 cclauses
[C_OMP_CLAUSE_SPLIT_MASKED
]);
19069 OMP_MASKED_COMBINED (ret
) = 1;
19073 if (!flag_openmp
) /* flag_openmp_simd */
19075 c_parser_skip_to_pragma_eol (parser
, false);
19079 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
19082 omp_split_clauses (loc
, OMP_MASKED
, mask
, clauses
, cclauses
);
19083 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_MASKED
];
19086 return c_finish_omp_masked (loc
, c_parser_omp_structured_block (parser
,
19092 # pragma omp ordered new-line
19096 # pragma omp ordered ordered-clauses new-line
19099 # pragma omp ordered depend-clauses new-line */
19101 #define OMP_ORDERED_CLAUSE_MASK \
19102 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREADS) \
19103 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMD))
19105 #define OMP_ORDERED_DEPEND_CLAUSE_MASK \
19106 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)
19109 c_parser_omp_ordered (c_parser
*parser
, enum pragma_context context
,
19112 location_t loc
= c_parser_peek_token (parser
)->location
;
19113 c_parser_consume_pragma (parser
);
19115 if (context
!= pragma_stmt
&& context
!= pragma_compound
)
19117 c_parser_error (parser
, "expected declaration specifiers");
19118 c_parser_skip_to_pragma_eol (parser
, false);
19122 if (c_parser_next_token_is (parser
, CPP_NAME
))
19124 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
19126 if (!strcmp ("depend", p
))
19128 if (!flag_openmp
) /* flag_openmp_simd */
19130 c_parser_skip_to_pragma_eol (parser
, false);
19133 if (context
== pragma_stmt
)
19136 "%<#pragma omp ordered%> with %<depend%> clause may "
19137 "only be used in compound statements");
19138 c_parser_skip_to_pragma_eol (parser
, false);
19143 = c_parser_omp_all_clauses (parser
,
19144 OMP_ORDERED_DEPEND_CLAUSE_MASK
,
19145 "#pragma omp ordered");
19146 c_finish_omp_ordered (loc
, clauses
, NULL_TREE
);
19151 tree clauses
= c_parser_omp_all_clauses (parser
, OMP_ORDERED_CLAUSE_MASK
,
19152 "#pragma omp ordered");
19154 if (!flag_openmp
/* flag_openmp_simd */
19155 && omp_find_clause (clauses
, OMP_CLAUSE_SIMD
) == NULL_TREE
)
19158 c_finish_omp_ordered (loc
, clauses
,
19159 c_parser_omp_structured_block (parser
, if_p
));
19166 { section-sequence }
19169 section-directive[opt] structured-block
19170 section-sequence section-directive structured-block
19172 SECTIONS_LOC is the location of the #pragma omp sections. */
19175 c_parser_omp_sections_scope (location_t sections_loc
, c_parser
*parser
)
19177 tree stmt
, substmt
;
19178 bool error_suppress
= false;
19181 loc
= c_parser_peek_token (parser
)->location
;
19182 if (!c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
19184 /* Avoid skipping until the end of the block. */
19185 parser
->error
= false;
19189 stmt
= push_stmt_list ();
19191 if (c_parser_peek_token (parser
)->pragma_kind
!= PRAGMA_OMP_SECTION
)
19193 substmt
= c_parser_omp_structured_block (parser
, NULL
);
19194 substmt
= build1 (OMP_SECTION
, void_type_node
, substmt
);
19195 SET_EXPR_LOCATION (substmt
, loc
);
19196 add_stmt (substmt
);
19201 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
19203 if (c_parser_next_token_is (parser
, CPP_EOF
))
19206 loc
= c_parser_peek_token (parser
)->location
;
19207 if (c_parser_peek_token (parser
)->pragma_kind
== PRAGMA_OMP_SECTION
)
19209 c_parser_consume_pragma (parser
);
19210 c_parser_skip_to_pragma_eol (parser
);
19211 error_suppress
= false;
19213 else if (!error_suppress
)
19215 error_at (loc
, "expected %<#pragma omp section%> or %<}%>");
19216 error_suppress
= true;
19219 substmt
= c_parser_omp_structured_block (parser
, NULL
);
19220 substmt
= build1 (OMP_SECTION
, void_type_node
, substmt
);
19221 SET_EXPR_LOCATION (substmt
, loc
);
19222 add_stmt (substmt
);
19224 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
,
19225 "expected %<#pragma omp section%> or %<}%>");
19227 substmt
= pop_stmt_list (stmt
);
19229 stmt
= make_node (OMP_SECTIONS
);
19230 SET_EXPR_LOCATION (stmt
, sections_loc
);
19231 TREE_TYPE (stmt
) = void_type_node
;
19232 OMP_SECTIONS_BODY (stmt
) = substmt
;
19234 return add_stmt (stmt
);
19238 # pragma omp sections sections-clause[optseq] newline
19241 LOC is the location of the #pragma token.
19244 #define OMP_SECTIONS_CLAUSE_MASK \
19245 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19246 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
19247 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
19248 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
19249 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
19250 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
19253 c_parser_omp_sections (location_t loc
, c_parser
*parser
,
19254 char *p_name
, omp_clause_mask mask
, tree
*cclauses
)
19256 tree block
, clauses
, ret
;
19258 strcat (p_name
, " sections");
19259 mask
|= OMP_SECTIONS_CLAUSE_MASK
;
19261 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_NOWAIT
);
19263 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
19266 omp_split_clauses (loc
, OMP_SECTIONS
, mask
, clauses
, cclauses
);
19267 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_SECTIONS
];
19270 block
= c_begin_compound_stmt (true);
19271 ret
= c_parser_omp_sections_scope (loc
, parser
);
19273 OMP_SECTIONS_CLAUSES (ret
) = clauses
;
19274 block
= c_end_compound_stmt (loc
, block
, true);
19281 # pragma omp parallel parallel-clause[optseq] new-line
19283 # pragma omp parallel for parallel-for-clause[optseq] new-line
19285 # pragma omp parallel sections parallel-sections-clause[optseq] new-line
19289 # pragma omp parallel for simd parallel-for-simd-clause[optseq] new-line
19292 LOC is the location of the #pragma token.
19295 #define OMP_PARALLEL_CLAUSE_MASK \
19296 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
19297 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19298 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
19299 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
19300 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
19301 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN) \
19302 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
19303 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS) \
19304 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
19305 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PROC_BIND))
19308 c_parser_omp_parallel (location_t loc
, c_parser
*parser
,
19309 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
19312 tree stmt
, clauses
, block
;
19314 strcat (p_name
, " parallel");
19315 mask
|= OMP_PARALLEL_CLAUSE_MASK
;
19316 /* #pragma omp target parallel{, for, for simd} disallow copyin clause. */
19317 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_MAP
)) != 0
19318 && (mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
)) == 0)
19319 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_COPYIN
);
19321 if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
19323 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
19324 if (cclauses
== NULL
)
19325 cclauses
= cclauses_buf
;
19327 c_parser_consume_token (parser
);
19328 if (!flag_openmp
) /* flag_openmp_simd */
19329 return c_parser_omp_for (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
19330 block
= c_begin_omp_parallel ();
19331 tree ret
= c_parser_omp_for (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
19333 = c_finish_omp_parallel (loc
, cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
19335 if (ret
== NULL_TREE
)
19337 OMP_PARALLEL_COMBINED (stmt
) = 1;
19340 /* When combined with distribute, parallel has to be followed by for.
19341 #pragma omp target parallel is allowed though. */
19343 && (mask
& (OMP_CLAUSE_MASK_1
19344 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
)) != 0)
19346 error_at (loc
, "expected %<for%> after %qs", p_name
);
19347 c_parser_skip_to_pragma_eol (parser
);
19350 else if (c_parser_next_token_is (parser
, CPP_NAME
))
19352 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
19353 if (cclauses
== NULL
&& strcmp (p
, "masked") == 0)
19355 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
19356 cclauses
= cclauses_buf
;
19358 c_parser_consume_token (parser
);
19359 if (!flag_openmp
) /* flag_openmp_simd */
19360 return c_parser_omp_masked (loc
, parser
, p_name
, mask
, cclauses
,
19362 block
= c_begin_omp_parallel ();
19363 tree ret
= c_parser_omp_masked (loc
, parser
, p_name
, mask
, cclauses
,
19365 stmt
= c_finish_omp_parallel (loc
,
19366 cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
19370 /* masked does have just filter clause, but during gimplification
19371 isn't represented by a gimplification omp context, so for
19372 #pragma omp parallel masked don't set OMP_PARALLEL_COMBINED,
19374 #pragma omp parallel masked
19375 #pragma omp taskloop simd lastprivate (x)
19376 isn't confused with
19377 #pragma omp parallel masked taskloop simd lastprivate (x) */
19378 if (OMP_MASKED_COMBINED (ret
))
19379 OMP_PARALLEL_COMBINED (stmt
) = 1;
19382 else if (cclauses
== NULL
&& strcmp (p
, "master") == 0)
19384 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
19385 cclauses
= cclauses_buf
;
19387 c_parser_consume_token (parser
);
19388 if (!flag_openmp
) /* flag_openmp_simd */
19389 return c_parser_omp_master (loc
, parser
, p_name
, mask
, cclauses
,
19391 block
= c_begin_omp_parallel ();
19392 tree ret
= c_parser_omp_master (loc
, parser
, p_name
, mask
, cclauses
,
19394 stmt
= c_finish_omp_parallel (loc
,
19395 cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
19399 /* master doesn't have any clauses and during gimplification
19400 isn't represented by a gimplification omp context, so for
19401 #pragma omp parallel master don't set OMP_PARALLEL_COMBINED,
19403 #pragma omp parallel master
19404 #pragma omp taskloop simd lastprivate (x)
19405 isn't confused with
19406 #pragma omp parallel master taskloop simd lastprivate (x) */
19407 if (OMP_MASTER_COMBINED (ret
))
19408 OMP_PARALLEL_COMBINED (stmt
) = 1;
19411 else if (strcmp (p
, "loop") == 0)
19413 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
19414 if (cclauses
== NULL
)
19415 cclauses
= cclauses_buf
;
19417 c_parser_consume_token (parser
);
19418 if (!flag_openmp
) /* flag_openmp_simd */
19419 return c_parser_omp_loop (loc
, parser
, p_name
, mask
, cclauses
,
19421 block
= c_begin_omp_parallel ();
19422 tree ret
= c_parser_omp_loop (loc
, parser
, p_name
, mask
, cclauses
,
19425 = c_finish_omp_parallel (loc
,
19426 cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
19428 if (ret
== NULL_TREE
)
19430 OMP_PARALLEL_COMBINED (stmt
) = 1;
19433 else if (!flag_openmp
) /* flag_openmp_simd */
19435 c_parser_skip_to_pragma_eol (parser
, false);
19438 else if (cclauses
== NULL
&& strcmp (p
, "sections") == 0)
19440 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
19441 cclauses
= cclauses_buf
;
19443 c_parser_consume_token (parser
);
19444 block
= c_begin_omp_parallel ();
19445 c_parser_omp_sections (loc
, parser
, p_name
, mask
, cclauses
);
19446 stmt
= c_finish_omp_parallel (loc
,
19447 cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
19449 OMP_PARALLEL_COMBINED (stmt
) = 1;
19453 else if (!flag_openmp
) /* flag_openmp_simd */
19455 c_parser_skip_to_pragma_eol (parser
, false);
19459 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
19462 omp_split_clauses (loc
, OMP_PARALLEL
, mask
, clauses
, cclauses
);
19463 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
];
19466 block
= c_begin_omp_parallel ();
19467 c_parser_statement (parser
, if_p
);
19468 stmt
= c_finish_omp_parallel (loc
, clauses
, block
);
19474 # pragma omp single single-clause[optseq] new-line
19477 LOC is the location of the #pragma.
19480 #define OMP_SINGLE_CLAUSE_MASK \
19481 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19482 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
19483 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYPRIVATE) \
19484 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
19485 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
19488 c_parser_omp_single (location_t loc
, c_parser
*parser
, bool *if_p
)
19490 tree stmt
= make_node (OMP_SINGLE
);
19491 SET_EXPR_LOCATION (stmt
, loc
);
19492 TREE_TYPE (stmt
) = void_type_node
;
19494 OMP_SINGLE_CLAUSES (stmt
)
19495 = c_parser_omp_all_clauses (parser
, OMP_SINGLE_CLAUSE_MASK
,
19496 "#pragma omp single");
19497 OMP_SINGLE_BODY (stmt
) = c_parser_omp_structured_block (parser
, if_p
);
19499 return add_stmt (stmt
);
19503 # pragma omp scope scope-clause[optseq] new-line
19506 LOC is the location of the #pragma.
19509 #define OMP_SCOPE_CLAUSE_MASK \
19510 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19511 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
19512 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
19515 c_parser_omp_scope (location_t loc
, c_parser
*parser
, bool *if_p
)
19517 tree stmt
= make_node (OMP_SCOPE
);
19518 SET_EXPR_LOCATION (stmt
, loc
);
19519 TREE_TYPE (stmt
) = void_type_node
;
19521 OMP_SCOPE_CLAUSES (stmt
)
19522 = c_parser_omp_all_clauses (parser
, OMP_SCOPE_CLAUSE_MASK
,
19523 "#pragma omp scope");
19524 OMP_SCOPE_BODY (stmt
) = c_parser_omp_structured_block (parser
, if_p
);
19526 return add_stmt (stmt
);
19530 # pragma omp task task-clause[optseq] new-line
19532 LOC is the location of the #pragma.
19535 #define OMP_TASK_CLAUSE_MASK \
19536 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
19537 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
19538 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
19539 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19540 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
19541 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
19542 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
19543 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
19544 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
19545 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
19546 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
19547 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION) \
19548 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DETACH) \
19549 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_AFFINITY))
19552 c_parser_omp_task (location_t loc
, c_parser
*parser
, bool *if_p
)
19554 tree clauses
, block
;
19556 clauses
= c_parser_omp_all_clauses (parser
, OMP_TASK_CLAUSE_MASK
,
19557 "#pragma omp task");
19559 block
= c_begin_omp_task ();
19560 c_parser_statement (parser
, if_p
);
19561 return c_finish_omp_task (loc
, clauses
, block
);
19565 # pragma omp taskwait new-line
19568 # pragma omp taskwait taskwait-clause[optseq] new-line
19571 #define OMP_TASKWAIT_CLAUSE_MASK \
19572 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)
19575 c_parser_omp_taskwait (c_parser
*parser
)
19577 location_t loc
= c_parser_peek_token (parser
)->location
;
19578 c_parser_consume_pragma (parser
);
19581 = c_parser_omp_all_clauses (parser
, OMP_TASKWAIT_CLAUSE_MASK
,
19582 "#pragma omp taskwait");
19586 tree stmt
= make_node (OMP_TASK
);
19587 TREE_TYPE (stmt
) = void_node
;
19588 OMP_TASK_CLAUSES (stmt
) = clauses
;
19589 OMP_TASK_BODY (stmt
) = NULL_TREE
;
19590 SET_EXPR_LOCATION (stmt
, loc
);
19594 c_finish_omp_taskwait (loc
);
19598 # pragma omp taskyield new-line
19602 c_parser_omp_taskyield (c_parser
*parser
)
19604 location_t loc
= c_parser_peek_token (parser
)->location
;
19605 c_parser_consume_pragma (parser
);
19606 c_parser_skip_to_pragma_eol (parser
);
19608 c_finish_omp_taskyield (loc
);
19612 # pragma omp taskgroup new-line
19615 # pragma omp taskgroup taskgroup-clause[optseq] new-line
19618 #define OMP_TASKGROUP_CLAUSE_MASK \
19619 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
19620 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASK_REDUCTION))
19623 c_parser_omp_taskgroup (location_t loc
, c_parser
*parser
, bool *if_p
)
19625 tree clauses
= c_parser_omp_all_clauses (parser
, OMP_TASKGROUP_CLAUSE_MASK
,
19626 "#pragma omp taskgroup");
19628 tree body
= c_parser_omp_structured_block (parser
, if_p
);
19629 return c_finish_omp_taskgroup (loc
, body
, clauses
);
19633 # pragma omp cancel cancel-clause[optseq] new-line
19635 LOC is the location of the #pragma.
19638 #define OMP_CANCEL_CLAUSE_MASK \
19639 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
19640 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
19641 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
19642 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP) \
19643 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF))
19646 c_parser_omp_cancel (c_parser
*parser
)
19648 location_t loc
= c_parser_peek_token (parser
)->location
;
19650 c_parser_consume_pragma (parser
);
19651 tree clauses
= c_parser_omp_all_clauses (parser
, OMP_CANCEL_CLAUSE_MASK
,
19652 "#pragma omp cancel");
19654 c_finish_omp_cancel (loc
, clauses
);
19658 # pragma omp cancellation point cancelpt-clause[optseq] new-line
19660 LOC is the location of the #pragma.
19663 #define OMP_CANCELLATION_POINT_CLAUSE_MASK \
19664 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
19665 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
19666 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
19667 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP))
19670 c_parser_omp_cancellation_point (c_parser
*parser
, enum pragma_context context
)
19672 location_t loc
= c_parser_peek_token (parser
)->location
;
19674 bool point_seen
= false;
19676 c_parser_consume_pragma (parser
);
19677 if (c_parser_next_token_is (parser
, CPP_NAME
))
19679 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
19680 if (strcmp (p
, "point") == 0)
19682 c_parser_consume_token (parser
);
19688 c_parser_error (parser
, "expected %<point%>");
19689 c_parser_skip_to_pragma_eol (parser
);
19693 if (context
!= pragma_compound
)
19695 if (context
== pragma_stmt
)
19697 "%<#pragma %s%> may only be used in compound statements",
19698 "omp cancellation point");
19700 c_parser_error (parser
, "expected declaration specifiers");
19701 c_parser_skip_to_pragma_eol (parser
, false);
19706 = c_parser_omp_all_clauses (parser
, OMP_CANCELLATION_POINT_CLAUSE_MASK
,
19707 "#pragma omp cancellation point");
19709 c_finish_omp_cancellation_point (loc
, clauses
);
19714 #pragma omp distribute distribute-clause[optseq] new-line
19717 #define OMP_DISTRIBUTE_CLAUSE_MASK \
19718 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19719 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
19720 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
19721 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)\
19722 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
19723 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE))
19726 c_parser_omp_distribute (location_t loc
, c_parser
*parser
,
19727 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
19730 tree clauses
, block
, ret
;
19732 strcat (p_name
, " distribute");
19733 mask
|= OMP_DISTRIBUTE_CLAUSE_MASK
;
19735 if (c_parser_next_token_is (parser
, CPP_NAME
))
19737 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
19739 bool parallel
= false;
19741 if (strcmp (p
, "simd") == 0)
19744 parallel
= strcmp (p
, "parallel") == 0;
19745 if (parallel
|| simd
)
19747 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
19748 if (cclauses
== NULL
)
19749 cclauses
= cclauses_buf
;
19750 c_parser_consume_token (parser
);
19751 if (!flag_openmp
) /* flag_openmp_simd */
19754 return c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
,
19757 return c_parser_omp_parallel (loc
, parser
, p_name
, mask
,
19760 block
= c_begin_compound_stmt (true);
19762 ret
= c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
,
19765 ret
= c_parser_omp_parallel (loc
, parser
, p_name
, mask
, cclauses
,
19767 block
= c_end_compound_stmt (loc
, block
, true);
19770 ret
= make_node (OMP_DISTRIBUTE
);
19771 TREE_TYPE (ret
) = void_type_node
;
19772 OMP_FOR_BODY (ret
) = block
;
19773 OMP_FOR_CLAUSES (ret
) = cclauses
[C_OMP_CLAUSE_SPLIT_DISTRIBUTE
];
19774 SET_EXPR_LOCATION (ret
, loc
);
19779 if (!flag_openmp
) /* flag_openmp_simd */
19781 c_parser_skip_to_pragma_eol (parser
, false);
19785 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
19788 omp_split_clauses (loc
, OMP_DISTRIBUTE
, mask
, clauses
, cclauses
);
19789 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_DISTRIBUTE
];
19792 block
= c_begin_compound_stmt (true);
19793 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_DISTRIBUTE
, clauses
, NULL
,
19795 block
= c_end_compound_stmt (loc
, block
, true);
19802 # pragma omp teams teams-clause[optseq] new-line
19803 structured-block */
19805 #define OMP_TEAMS_CLAUSE_MASK \
19806 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19807 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
19808 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
19809 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
19810 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS) \
19811 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \
19812 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
19813 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT))
19816 c_parser_omp_teams (location_t loc
, c_parser
*parser
,
19817 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
19820 tree clauses
, block
, ret
;
19822 strcat (p_name
, " teams");
19823 mask
|= OMP_TEAMS_CLAUSE_MASK
;
19825 if (c_parser_next_token_is (parser
, CPP_NAME
))
19827 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
19828 if (strcmp (p
, "distribute") == 0)
19830 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
19831 if (cclauses
== NULL
)
19832 cclauses
= cclauses_buf
;
19834 c_parser_consume_token (parser
);
19835 if (!flag_openmp
) /* flag_openmp_simd */
19836 return c_parser_omp_distribute (loc
, parser
, p_name
, mask
,
19838 block
= c_begin_omp_parallel ();
19839 ret
= c_parser_omp_distribute (loc
, parser
, p_name
, mask
, cclauses
,
19841 block
= c_end_compound_stmt (loc
, block
, true);
19844 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_TEAMS
];
19845 ret
= make_node (OMP_TEAMS
);
19846 TREE_TYPE (ret
) = void_type_node
;
19847 OMP_TEAMS_CLAUSES (ret
) = clauses
;
19848 OMP_TEAMS_BODY (ret
) = block
;
19849 OMP_TEAMS_COMBINED (ret
) = 1;
19850 SET_EXPR_LOCATION (ret
, loc
);
19851 return add_stmt (ret
);
19853 else if (strcmp (p
, "loop") == 0)
19855 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
19856 if (cclauses
== NULL
)
19857 cclauses
= cclauses_buf
;
19859 c_parser_consume_token (parser
);
19860 if (!flag_openmp
) /* flag_openmp_simd */
19861 return c_parser_omp_loop (loc
, parser
, p_name
, mask
, cclauses
,
19863 block
= c_begin_omp_parallel ();
19864 ret
= c_parser_omp_loop (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
19865 block
= c_end_compound_stmt (loc
, block
, true);
19868 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_TEAMS
];
19869 ret
= make_node (OMP_TEAMS
);
19870 TREE_TYPE (ret
) = void_type_node
;
19871 OMP_TEAMS_CLAUSES (ret
) = clauses
;
19872 OMP_TEAMS_BODY (ret
) = block
;
19873 OMP_TEAMS_COMBINED (ret
) = 1;
19874 SET_EXPR_LOCATION (ret
, loc
);
19875 return add_stmt (ret
);
19878 if (!flag_openmp
) /* flag_openmp_simd */
19880 c_parser_skip_to_pragma_eol (parser
, false);
19884 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
19887 omp_split_clauses (loc
, OMP_TEAMS
, mask
, clauses
, cclauses
);
19888 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_TEAMS
];
19891 tree stmt
= make_node (OMP_TEAMS
);
19892 TREE_TYPE (stmt
) = void_type_node
;
19893 OMP_TEAMS_CLAUSES (stmt
) = clauses
;
19894 block
= c_begin_omp_parallel ();
19895 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
19896 OMP_TEAMS_BODY (stmt
) = c_end_compound_stmt (loc
, block
, true);
19897 SET_EXPR_LOCATION (stmt
, loc
);
19899 return add_stmt (stmt
);
19903 # pragma omp target data target-data-clause[optseq] new-line
19904 structured-block */
19906 #define OMP_TARGET_DATA_CLAUSE_MASK \
19907 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
19908 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
19909 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
19910 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR) \
19911 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR))
19914 c_parser_omp_target_data (location_t loc
, c_parser
*parser
, bool *if_p
)
19917 = c_parser_omp_all_clauses (parser
, OMP_TARGET_DATA_CLAUSE_MASK
,
19918 "#pragma omp target data");
19919 c_omp_adjust_map_clauses (clauses
, false);
19921 for (tree
*pc
= &clauses
; *pc
;)
19923 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_MAP
)
19924 switch (OMP_CLAUSE_MAP_KIND (*pc
))
19927 case GOMP_MAP_ALWAYS_TO
:
19928 case GOMP_MAP_FROM
:
19929 case GOMP_MAP_ALWAYS_FROM
:
19930 case GOMP_MAP_TOFROM
:
19931 case GOMP_MAP_ALWAYS_TOFROM
:
19932 case GOMP_MAP_ALLOC
:
19935 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
19936 case GOMP_MAP_ALWAYS_POINTER
:
19937 case GOMP_MAP_ATTACH_DETACH
:
19941 error_at (OMP_CLAUSE_LOCATION (*pc
),
19942 "%<#pragma omp target data%> with map-type other "
19943 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
19944 "on %<map%> clause");
19945 *pc
= OMP_CLAUSE_CHAIN (*pc
);
19948 else if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_USE_DEVICE_PTR
19949 || OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_USE_DEVICE_ADDR
)
19951 pc
= &OMP_CLAUSE_CHAIN (*pc
);
19958 "%<#pragma omp target data%> must contain at least "
19959 "one %<map%>, %<use_device_ptr%> or %<use_device_addr%> "
19964 tree stmt
= make_node (OMP_TARGET_DATA
);
19965 TREE_TYPE (stmt
) = void_type_node
;
19966 OMP_TARGET_DATA_CLAUSES (stmt
) = clauses
;
19967 keep_next_level ();
19968 tree block
= c_begin_compound_stmt (true);
19969 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
19970 OMP_TARGET_DATA_BODY (stmt
) = c_end_compound_stmt (loc
, block
, true);
19972 SET_EXPR_LOCATION (stmt
, loc
);
19973 return add_stmt (stmt
);
19977 # pragma omp target update target-update-clause[optseq] new-line */
19979 #define OMP_TARGET_UPDATE_CLAUSE_MASK \
19980 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FROM) \
19981 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
19982 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
19983 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
19984 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
19985 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
19988 c_parser_omp_target_update (location_t loc
, c_parser
*parser
,
19989 enum pragma_context context
)
19991 if (context
== pragma_stmt
)
19993 error_at (loc
, "%<#pragma %s%> may only be used in compound statements",
19994 "omp target update");
19995 c_parser_skip_to_pragma_eol (parser
, false);
20000 = c_parser_omp_all_clauses (parser
, OMP_TARGET_UPDATE_CLAUSE_MASK
,
20001 "#pragma omp target update");
20002 if (omp_find_clause (clauses
, OMP_CLAUSE_TO
) == NULL_TREE
20003 && omp_find_clause (clauses
, OMP_CLAUSE_FROM
) == NULL_TREE
)
20006 "%<#pragma omp target update%> must contain at least one "
20007 "%<from%> or %<to%> clauses");
20011 tree stmt
= make_node (OMP_TARGET_UPDATE
);
20012 TREE_TYPE (stmt
) = void_type_node
;
20013 OMP_TARGET_UPDATE_CLAUSES (stmt
) = clauses
;
20014 SET_EXPR_LOCATION (stmt
, loc
);
20020 # pragma omp target enter data target-data-clause[optseq] new-line */
20022 #define OMP_TARGET_ENTER_DATA_CLAUSE_MASK \
20023 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
20024 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
20025 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
20026 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
20027 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20030 c_parser_omp_target_enter_data (location_t loc
, c_parser
*parser
,
20031 enum pragma_context context
)
20033 bool data_seen
= false;
20034 if (c_parser_next_token_is (parser
, CPP_NAME
))
20036 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
20037 if (strcmp (p
, "data") == 0)
20039 c_parser_consume_token (parser
);
20045 c_parser_error (parser
, "expected %<data%>");
20046 c_parser_skip_to_pragma_eol (parser
);
20050 if (context
== pragma_stmt
)
20052 error_at (loc
, "%<#pragma %s%> may only be used in compound statements",
20053 "omp target enter data");
20054 c_parser_skip_to_pragma_eol (parser
, false);
20059 = c_parser_omp_all_clauses (parser
, OMP_TARGET_ENTER_DATA_CLAUSE_MASK
,
20060 "#pragma omp target enter data");
20061 c_omp_adjust_map_clauses (clauses
, false);
20063 for (tree
*pc
= &clauses
; *pc
;)
20065 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_MAP
)
20066 switch (OMP_CLAUSE_MAP_KIND (*pc
))
20069 case GOMP_MAP_ALWAYS_TO
:
20070 case GOMP_MAP_ALLOC
:
20073 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
20074 case GOMP_MAP_ALWAYS_POINTER
:
20075 case GOMP_MAP_ATTACH_DETACH
:
20079 error_at (OMP_CLAUSE_LOCATION (*pc
),
20080 "%<#pragma omp target enter data%> with map-type other "
20081 "than %<to%> or %<alloc%> on %<map%> clause");
20082 *pc
= OMP_CLAUSE_CHAIN (*pc
);
20085 pc
= &OMP_CLAUSE_CHAIN (*pc
);
20092 "%<#pragma omp target enter data%> must contain at least "
20093 "one %<map%> clause");
20097 tree stmt
= make_node (OMP_TARGET_ENTER_DATA
);
20098 TREE_TYPE (stmt
) = void_type_node
;
20099 OMP_TARGET_ENTER_DATA_CLAUSES (stmt
) = clauses
;
20100 SET_EXPR_LOCATION (stmt
, loc
);
20106 # pragma omp target exit data target-data-clause[optseq] new-line */
20108 #define OMP_TARGET_EXIT_DATA_CLAUSE_MASK \
20109 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
20110 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
20111 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
20112 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
20113 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20116 c_parser_omp_target_exit_data (location_t loc
, c_parser
*parser
,
20117 enum pragma_context context
)
20119 bool data_seen
= false;
20120 if (c_parser_next_token_is (parser
, CPP_NAME
))
20122 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
20123 if (strcmp (p
, "data") == 0)
20125 c_parser_consume_token (parser
);
20131 c_parser_error (parser
, "expected %<data%>");
20132 c_parser_skip_to_pragma_eol (parser
);
20136 if (context
== pragma_stmt
)
20138 error_at (loc
, "%<#pragma %s%> may only be used in compound statements",
20139 "omp target exit data");
20140 c_parser_skip_to_pragma_eol (parser
, false);
20145 = c_parser_omp_all_clauses (parser
, OMP_TARGET_EXIT_DATA_CLAUSE_MASK
,
20146 "#pragma omp target exit data");
20147 c_omp_adjust_map_clauses (clauses
, false);
20149 for (tree
*pc
= &clauses
; *pc
;)
20151 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_MAP
)
20152 switch (OMP_CLAUSE_MAP_KIND (*pc
))
20154 case GOMP_MAP_FROM
:
20155 case GOMP_MAP_ALWAYS_FROM
:
20156 case GOMP_MAP_RELEASE
:
20157 case GOMP_MAP_DELETE
:
20160 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
20161 case GOMP_MAP_ALWAYS_POINTER
:
20162 case GOMP_MAP_ATTACH_DETACH
:
20166 error_at (OMP_CLAUSE_LOCATION (*pc
),
20167 "%<#pragma omp target exit data%> with map-type other "
20168 "than %<from%>, %<release%> or %<delete%> on %<map%>"
20170 *pc
= OMP_CLAUSE_CHAIN (*pc
);
20173 pc
= &OMP_CLAUSE_CHAIN (*pc
);
20180 "%<#pragma omp target exit data%> must contain at least one "
20185 tree stmt
= make_node (OMP_TARGET_EXIT_DATA
);
20186 TREE_TYPE (stmt
) = void_type_node
;
20187 OMP_TARGET_EXIT_DATA_CLAUSES (stmt
) = clauses
;
20188 SET_EXPR_LOCATION (stmt
, loc
);
20194 # pragma omp target target-clause[optseq] new-line
20195 structured-block */
20197 #define OMP_TARGET_CLAUSE_MASK \
20198 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
20199 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
20200 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
20201 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
20202 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
20203 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20204 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20205 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20206 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULTMAP) \
20207 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION) \
20208 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR))
20211 c_parser_omp_target (c_parser
*parser
, enum pragma_context context
, bool *if_p
)
20213 location_t loc
= c_parser_peek_token (parser
)->location
;
20214 c_parser_consume_pragma (parser
);
20215 tree
*pc
= NULL
, stmt
, block
;
20217 if (context
!= pragma_stmt
&& context
!= pragma_compound
)
20219 c_parser_error (parser
, "expected declaration specifiers");
20220 c_parser_skip_to_pragma_eol (parser
);
20226 = (enum omp_requires
) (omp_requires_mask
| OMP_REQUIRES_TARGET_USED
);
20228 if (c_parser_next_token_is (parser
, CPP_NAME
))
20230 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
20231 enum tree_code ccode
= ERROR_MARK
;
20233 if (strcmp (p
, "teams") == 0)
20235 else if (strcmp (p
, "parallel") == 0)
20236 ccode
= OMP_PARALLEL
;
20237 else if (strcmp (p
, "simd") == 0)
20239 if (ccode
!= ERROR_MARK
)
20241 tree cclauses
[C_OMP_CLAUSE_SPLIT_COUNT
];
20242 char p_name
[sizeof ("#pragma omp target teams distribute "
20243 "parallel for simd")];
20245 c_parser_consume_token (parser
);
20246 strcpy (p_name
, "#pragma omp target");
20247 if (!flag_openmp
) /* flag_openmp_simd */
20253 stmt
= c_parser_omp_teams (loc
, parser
, p_name
,
20254 OMP_TARGET_CLAUSE_MASK
,
20258 stmt
= c_parser_omp_parallel (loc
, parser
, p_name
,
20259 OMP_TARGET_CLAUSE_MASK
,
20263 stmt
= c_parser_omp_simd (loc
, parser
, p_name
,
20264 OMP_TARGET_CLAUSE_MASK
,
20268 gcc_unreachable ();
20270 return stmt
!= NULL_TREE
;
20272 keep_next_level ();
20273 tree block
= c_begin_compound_stmt (true), ret
;
20277 ret
= c_parser_omp_teams (loc
, parser
, p_name
,
20278 OMP_TARGET_CLAUSE_MASK
, cclauses
,
20282 ret
= c_parser_omp_parallel (loc
, parser
, p_name
,
20283 OMP_TARGET_CLAUSE_MASK
, cclauses
,
20287 ret
= c_parser_omp_simd (loc
, parser
, p_name
,
20288 OMP_TARGET_CLAUSE_MASK
, cclauses
,
20292 gcc_unreachable ();
20294 block
= c_end_compound_stmt (loc
, block
, true);
20295 if (ret
== NULL_TREE
)
20297 if (ccode
== OMP_TEAMS
)
20299 /* For combined target teams, ensure the num_teams and
20300 thread_limit clause expressions are evaluated on the host,
20301 before entering the target construct. */
20303 for (c
= cclauses
[C_OMP_CLAUSE_SPLIT_TEAMS
];
20304 c
; c
= OMP_CLAUSE_CHAIN (c
))
20305 if ((OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_NUM_TEAMS
20306 || OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_THREAD_LIMIT
)
20307 && TREE_CODE (OMP_CLAUSE_OPERAND (c
, 0)) != INTEGER_CST
)
20309 tree expr
= OMP_CLAUSE_OPERAND (c
, 0);
20310 tree tmp
= create_tmp_var_raw (TREE_TYPE (expr
));
20311 expr
= build4 (TARGET_EXPR
, TREE_TYPE (expr
), tmp
,
20312 expr
, NULL_TREE
, NULL_TREE
);
20314 OMP_CLAUSE_OPERAND (c
, 0) = expr
;
20315 tree tc
= build_omp_clause (OMP_CLAUSE_LOCATION (c
),
20316 OMP_CLAUSE_FIRSTPRIVATE
);
20317 OMP_CLAUSE_DECL (tc
) = tmp
;
20318 OMP_CLAUSE_CHAIN (tc
)
20319 = cclauses
[C_OMP_CLAUSE_SPLIT_TARGET
];
20320 cclauses
[C_OMP_CLAUSE_SPLIT_TARGET
] = tc
;
20323 tree stmt
= make_node (OMP_TARGET
);
20324 TREE_TYPE (stmt
) = void_type_node
;
20325 OMP_TARGET_CLAUSES (stmt
) = cclauses
[C_OMP_CLAUSE_SPLIT_TARGET
];
20326 c_omp_adjust_map_clauses (OMP_TARGET_CLAUSES (stmt
), true);
20327 OMP_TARGET_BODY (stmt
) = block
;
20328 OMP_TARGET_COMBINED (stmt
) = 1;
20329 SET_EXPR_LOCATION (stmt
, loc
);
20331 pc
= &OMP_TARGET_CLAUSES (stmt
);
20332 goto check_clauses
;
20334 else if (!flag_openmp
) /* flag_openmp_simd */
20336 c_parser_skip_to_pragma_eol (parser
, false);
20339 else if (strcmp (p
, "data") == 0)
20341 c_parser_consume_token (parser
);
20342 c_parser_omp_target_data (loc
, parser
, if_p
);
20345 else if (strcmp (p
, "enter") == 0)
20347 c_parser_consume_token (parser
);
20348 return c_parser_omp_target_enter_data (loc
, parser
, context
);
20350 else if (strcmp (p
, "exit") == 0)
20352 c_parser_consume_token (parser
);
20353 return c_parser_omp_target_exit_data (loc
, parser
, context
);
20355 else if (strcmp (p
, "update") == 0)
20357 c_parser_consume_token (parser
);
20358 return c_parser_omp_target_update (loc
, parser
, context
);
20361 if (!flag_openmp
) /* flag_openmp_simd */
20363 c_parser_skip_to_pragma_eol (parser
, false);
20367 stmt
= make_node (OMP_TARGET
);
20368 TREE_TYPE (stmt
) = void_type_node
;
20370 OMP_TARGET_CLAUSES (stmt
)
20371 = c_parser_omp_all_clauses (parser
, OMP_TARGET_CLAUSE_MASK
,
20372 "#pragma omp target", false);
20373 for (tree c
= OMP_TARGET_CLAUSES (stmt
); c
; c
= OMP_CLAUSE_CHAIN (c
))
20374 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_IN_REDUCTION
)
20376 tree nc
= build_omp_clause (OMP_CLAUSE_LOCATION (c
), OMP_CLAUSE_MAP
);
20377 OMP_CLAUSE_DECL (nc
) = OMP_CLAUSE_DECL (c
);
20378 OMP_CLAUSE_SET_MAP_KIND (nc
, GOMP_MAP_ALWAYS_TOFROM
);
20379 OMP_CLAUSE_CHAIN (nc
) = OMP_CLAUSE_CHAIN (c
);
20380 OMP_CLAUSE_CHAIN (c
) = nc
;
20382 OMP_TARGET_CLAUSES (stmt
)
20383 = c_finish_omp_clauses (OMP_TARGET_CLAUSES (stmt
), C_ORT_OMP_TARGET
);
20384 c_omp_adjust_map_clauses (OMP_TARGET_CLAUSES (stmt
), true);
20386 pc
= &OMP_TARGET_CLAUSES (stmt
);
20387 keep_next_level ();
20388 block
= c_begin_compound_stmt (true);
20389 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
20390 OMP_TARGET_BODY (stmt
) = c_end_compound_stmt (loc
, block
, true);
20392 SET_EXPR_LOCATION (stmt
, loc
);
20398 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_MAP
)
20399 switch (OMP_CLAUSE_MAP_KIND (*pc
))
20402 case GOMP_MAP_ALWAYS_TO
:
20403 case GOMP_MAP_FROM
:
20404 case GOMP_MAP_ALWAYS_FROM
:
20405 case GOMP_MAP_TOFROM
:
20406 case GOMP_MAP_ALWAYS_TOFROM
:
20407 case GOMP_MAP_ALLOC
:
20408 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
20409 case GOMP_MAP_ALWAYS_POINTER
:
20410 case GOMP_MAP_ATTACH_DETACH
:
20413 error_at (OMP_CLAUSE_LOCATION (*pc
),
20414 "%<#pragma omp target%> with map-type other "
20415 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
20416 "on %<map%> clause");
20417 *pc
= OMP_CLAUSE_CHAIN (*pc
);
20420 pc
= &OMP_CLAUSE_CHAIN (*pc
);
20422 cfun
->has_omp_target
= true;
20427 # pragma omp declare simd declare-simd-clauses[optseq] new-line
20430 # pragma omp declare variant (identifier) match(context-selector) new-line
20433 #define OMP_DECLARE_SIMD_CLAUSE_MASK \
20434 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
20435 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
20436 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
20437 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM) \
20438 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INBRANCH) \
20439 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOTINBRANCH))
20442 c_parser_omp_declare_simd (c_parser
*parser
, enum pragma_context context
)
20444 c_token
*token
= c_parser_peek_token (parser
);
20445 gcc_assert (token
->type
== CPP_NAME
);
20446 tree kind
= token
->value
;
20447 gcc_assert (strcmp (IDENTIFIER_POINTER (kind
), "simd") == 0
20448 || strcmp (IDENTIFIER_POINTER (kind
), "variant") == 0);
20450 auto_vec
<c_token
> clauses
;
20451 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
20453 c_token
*token
= c_parser_peek_token (parser
);
20454 if (token
->type
== CPP_EOF
)
20456 c_parser_skip_to_pragma_eol (parser
);
20459 clauses
.safe_push (*token
);
20460 c_parser_consume_token (parser
);
20462 clauses
.safe_push (*c_parser_peek_token (parser
));
20463 c_parser_skip_to_pragma_eol (parser
);
20465 while (c_parser_next_token_is (parser
, CPP_PRAGMA
))
20467 if (c_parser_peek_token (parser
)->pragma_kind
!= PRAGMA_OMP_DECLARE
20468 || c_parser_peek_2nd_token (parser
)->type
!= CPP_NAME
20469 || c_parser_peek_2nd_token (parser
)->value
!= kind
)
20471 error ("%<#pragma omp declare %s%> must be followed by "
20472 "function declaration or definition or another "
20473 "%<#pragma omp declare %s%>",
20474 IDENTIFIER_POINTER (kind
), IDENTIFIER_POINTER (kind
));
20477 c_parser_consume_pragma (parser
);
20478 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
20480 c_token
*token
= c_parser_peek_token (parser
);
20481 if (token
->type
== CPP_EOF
)
20483 c_parser_skip_to_pragma_eol (parser
);
20486 clauses
.safe_push (*token
);
20487 c_parser_consume_token (parser
);
20489 clauses
.safe_push (*c_parser_peek_token (parser
));
20490 c_parser_skip_to_pragma_eol (parser
);
20493 /* Make sure nothing tries to read past the end of the tokens. */
20495 memset (&eof_token
, 0, sizeof (eof_token
));
20496 eof_token
.type
= CPP_EOF
;
20497 clauses
.safe_push (eof_token
);
20498 clauses
.safe_push (eof_token
);
20502 case pragma_external
:
20503 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
20504 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
)
20506 int ext
= disable_extension_diagnostics ();
20508 c_parser_consume_token (parser
);
20509 while (c_parser_next_token_is (parser
, CPP_KEYWORD
)
20510 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
);
20511 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
20513 restore_extension_diagnostics (ext
);
20516 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
20519 case pragma_struct
:
20522 error ("%<#pragma omp declare %s%> must be followed by "
20523 "function declaration or definition",
20524 IDENTIFIER_POINTER (kind
));
20526 case pragma_compound
:
20527 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
20528 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
)
20530 int ext
= disable_extension_diagnostics ();
20532 c_parser_consume_token (parser
);
20533 while (c_parser_next_token_is (parser
, CPP_KEYWORD
)
20534 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
);
20535 if (c_parser_next_tokens_start_declaration (parser
))
20537 c_parser_declaration_or_fndef (parser
, true, true, true, true,
20538 true, NULL
, &clauses
);
20539 restore_extension_diagnostics (ext
);
20542 restore_extension_diagnostics (ext
);
20544 else if (c_parser_next_tokens_start_declaration (parser
))
20546 c_parser_declaration_or_fndef (parser
, true, true, true, true, true,
20550 error ("%<#pragma omp declare %s%> must be followed by "
20551 "function declaration or definition",
20552 IDENTIFIER_POINTER (kind
));
20555 gcc_unreachable ();
20559 static const char *const omp_construct_selectors
[] = {
20560 "simd", "target", "teams", "parallel", "for", NULL
};
20561 static const char *const omp_device_selectors
[] = {
20562 "kind", "isa", "arch", NULL
};
20563 static const char *const omp_implementation_selectors
[] = {
20564 "vendor", "extension", "atomic_default_mem_order", "unified_address",
20565 "unified_shared_memory", "dynamic_allocators", "reverse_offload", NULL
};
20566 static const char *const omp_user_selectors
[] = {
20567 "condition", NULL
};
20572 trait-selector-name[([trait-score:]trait-property[,trait-property[,...]])]
20575 score(score-expression) */
20578 c_parser_omp_context_selector (c_parser
*parser
, tree set
, tree parms
)
20580 tree ret
= NULL_TREE
;
20584 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
20585 || c_parser_next_token_is (parser
, CPP_NAME
))
20586 selector
= c_parser_peek_token (parser
)->value
;
20589 c_parser_error (parser
, "expected trait selector name");
20590 return error_mark_node
;
20593 tree properties
= NULL_TREE
;
20594 const char *const *selectors
= NULL
;
20595 bool allow_score
= true;
20596 bool allow_user
= false;
20597 int property_limit
= 0;
20598 enum { CTX_PROPERTY_NONE
, CTX_PROPERTY_USER
, CTX_PROPERTY_NAME_LIST
,
20599 CTX_PROPERTY_ID
, CTX_PROPERTY_EXPR
,
20600 CTX_PROPERTY_SIMD
} property_kind
= CTX_PROPERTY_NONE
;
20601 switch (IDENTIFIER_POINTER (set
)[0])
20603 case 'c': /* construct */
20604 selectors
= omp_construct_selectors
;
20605 allow_score
= false;
20606 property_limit
= 1;
20607 property_kind
= CTX_PROPERTY_SIMD
;
20609 case 'd': /* device */
20610 selectors
= omp_device_selectors
;
20611 allow_score
= false;
20613 property_limit
= 3;
20614 property_kind
= CTX_PROPERTY_NAME_LIST
;
20616 case 'i': /* implementation */
20617 selectors
= omp_implementation_selectors
;
20619 property_limit
= 3;
20620 property_kind
= CTX_PROPERTY_NAME_LIST
;
20622 case 'u': /* user */
20623 selectors
= omp_user_selectors
;
20624 property_limit
= 1;
20625 property_kind
= CTX_PROPERTY_EXPR
;
20628 gcc_unreachable ();
20630 for (int i
= 0; ; i
++)
20632 if (selectors
[i
] == NULL
)
20636 property_kind
= CTX_PROPERTY_USER
;
20641 error_at (c_parser_peek_token (parser
)->location
,
20642 "selector %qs not allowed for context selector "
20643 "set %qs", IDENTIFIER_POINTER (selector
),
20644 IDENTIFIER_POINTER (set
));
20645 c_parser_consume_token (parser
);
20646 return error_mark_node
;
20649 if (i
== property_limit
)
20650 property_kind
= CTX_PROPERTY_NONE
;
20651 if (strcmp (selectors
[i
], IDENTIFIER_POINTER (selector
)) == 0)
20654 if (property_kind
== CTX_PROPERTY_NAME_LIST
20655 && IDENTIFIER_POINTER (set
)[0] == 'i'
20656 && strcmp (IDENTIFIER_POINTER (selector
),
20657 "atomic_default_mem_order") == 0)
20658 property_kind
= CTX_PROPERTY_ID
;
20660 c_parser_consume_token (parser
);
20662 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
20664 if (property_kind
== CTX_PROPERTY_NONE
)
20666 error_at (c_parser_peek_token (parser
)->location
,
20667 "selector %qs does not accept any properties",
20668 IDENTIFIER_POINTER (selector
));
20669 return error_mark_node
;
20672 matching_parens parens
;
20673 parens
.require_open (parser
);
20675 c_token
*token
= c_parser_peek_token (parser
);
20677 && c_parser_next_token_is (parser
, CPP_NAME
)
20678 && strcmp (IDENTIFIER_POINTER (token
->value
), "score") == 0
20679 && c_parser_peek_2nd_token (parser
)->type
== CPP_OPEN_PAREN
)
20681 c_parser_consume_token (parser
);
20683 matching_parens parens2
;
20684 parens2
.require_open (parser
);
20685 tree score
= c_parser_expr_no_commas (parser
, NULL
).value
;
20686 parens2
.skip_until_found_close (parser
);
20687 c_parser_require (parser
, CPP_COLON
, "expected %<:%>");
20688 if (score
!= error_mark_node
)
20690 mark_exp_read (score
);
20691 score
= c_fully_fold (score
, false, NULL
);
20692 if (!INTEGRAL_TYPE_P (TREE_TYPE (score
))
20693 || TREE_CODE (score
) != INTEGER_CST
)
20694 error_at (token
->location
, "score argument must be "
20695 "constant integer expression");
20696 else if (tree_int_cst_sgn (score
) < 0)
20697 error_at (token
->location
, "score argument must be "
20700 properties
= tree_cons (get_identifier (" score"),
20701 score
, properties
);
20703 token
= c_parser_peek_token (parser
);
20706 switch (property_kind
)
20709 case CTX_PROPERTY_USER
:
20712 t
= c_parser_expr_no_commas (parser
, NULL
).value
;
20713 if (TREE_CODE (t
) == STRING_CST
)
20714 properties
= tree_cons (NULL_TREE
, t
, properties
);
20715 else if (t
!= error_mark_node
)
20718 t
= c_fully_fold (t
, false, NULL
);
20719 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
))
20720 || !tree_fits_shwi_p (t
))
20721 error_at (token
->location
, "property must be "
20722 "constant integer expression or string "
20725 properties
= tree_cons (NULL_TREE
, t
, properties
);
20728 return error_mark_node
;
20730 if (c_parser_next_token_is (parser
, CPP_COMMA
))
20731 c_parser_consume_token (parser
);
20737 case CTX_PROPERTY_ID
:
20738 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
20739 || c_parser_next_token_is (parser
, CPP_NAME
))
20741 tree prop
= c_parser_peek_token (parser
)->value
;
20742 c_parser_consume_token (parser
);
20743 properties
= tree_cons (prop
, NULL_TREE
, properties
);
20747 c_parser_error (parser
, "expected identifier");
20748 return error_mark_node
;
20751 case CTX_PROPERTY_NAME_LIST
:
20754 tree prop
= NULL_TREE
, value
= NULL_TREE
;
20755 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
20756 || c_parser_next_token_is (parser
, CPP_NAME
))
20758 prop
= c_parser_peek_token (parser
)->value
;
20759 c_parser_consume_token (parser
);
20761 else if (c_parser_next_token_is (parser
, CPP_STRING
))
20762 value
= c_parser_string_literal (parser
, false,
20766 c_parser_error (parser
, "expected identifier or "
20768 return error_mark_node
;
20771 properties
= tree_cons (prop
, value
, properties
);
20773 if (c_parser_next_token_is (parser
, CPP_COMMA
))
20774 c_parser_consume_token (parser
);
20780 case CTX_PROPERTY_EXPR
:
20781 t
= c_parser_expr_no_commas (parser
, NULL
).value
;
20782 if (t
!= error_mark_node
)
20785 t
= c_fully_fold (t
, false, NULL
);
20786 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
))
20787 || !tree_fits_shwi_p (t
))
20788 error_at (token
->location
, "property must be "
20789 "constant integer expression");
20791 properties
= tree_cons (NULL_TREE
, t
, properties
);
20794 return error_mark_node
;
20796 case CTX_PROPERTY_SIMD
:
20797 if (parms
== NULL_TREE
)
20799 error_at (token
->location
, "properties for %<simd%> "
20800 "selector may not be specified in "
20801 "%<metadirective%>");
20802 return error_mark_node
;
20805 c
= c_parser_omp_all_clauses (parser
,
20806 OMP_DECLARE_SIMD_CLAUSE_MASK
,
20808 c
= c_omp_declare_simd_clauses_to_numbers (parms
20810 ? NULL_TREE
: parms
,
20815 gcc_unreachable ();
20818 parens
.skip_until_found_close (parser
);
20819 properties
= nreverse (properties
);
20821 else if (property_kind
== CTX_PROPERTY_NAME_LIST
20822 || property_kind
== CTX_PROPERTY_ID
20823 || property_kind
== CTX_PROPERTY_EXPR
)
20825 c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>");
20826 return error_mark_node
;
20829 ret
= tree_cons (selector
, properties
, ret
);
20831 if (c_parser_next_token_is (parser
, CPP_COMMA
))
20832 c_parser_consume_token (parser
);
20838 return nreverse (ret
);
20843 trait-set-selector[,trait-set-selector[,...]]
20845 trait-set-selector:
20846 trait-set-selector-name = { trait-selector[, trait-selector[, ...]] }
20848 trait-set-selector-name:
20855 c_parser_omp_context_selector_specification (c_parser
*parser
, tree parms
)
20857 tree ret
= NULL_TREE
;
20860 const char *setp
= "";
20861 if (c_parser_next_token_is (parser
, CPP_NAME
))
20862 setp
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
20866 if (strcmp (setp
, "construct") == 0)
20870 if (strcmp (setp
, "device") == 0)
20874 if (strcmp (setp
, "implementation") == 0)
20878 if (strcmp (setp
, "user") == 0)
20886 c_parser_error (parser
, "expected %<construct%>, %<device%>, "
20887 "%<implementation%> or %<user%>");
20888 return error_mark_node
;
20891 tree set
= c_parser_peek_token (parser
)->value
;
20892 c_parser_consume_token (parser
);
20894 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
20895 return error_mark_node
;
20897 matching_braces braces
;
20898 if (!braces
.require_open (parser
))
20899 return error_mark_node
;
20901 tree selectors
= c_parser_omp_context_selector (parser
, set
, parms
);
20902 if (selectors
== error_mark_node
)
20903 ret
= error_mark_node
;
20904 else if (ret
!= error_mark_node
)
20905 ret
= tree_cons (set
, selectors
, ret
);
20907 braces
.skip_until_found_close (parser
);
20909 if (c_parser_next_token_is (parser
, CPP_COMMA
))
20910 c_parser_consume_token (parser
);
20916 if (ret
== error_mark_node
)
20918 return nreverse (ret
);
20921 /* Finalize #pragma omp declare variant after FNDECL has been parsed, and put
20922 that into "omp declare variant base" attribute. */
20925 c_finish_omp_declare_variant (c_parser
*parser
, tree fndecl
, tree parms
)
20927 matching_parens parens
;
20928 if (!parens
.require_open (parser
))
20931 c_parser_skip_to_pragma_eol (parser
, false);
20935 if (c_parser_next_token_is_not (parser
, CPP_NAME
)
20936 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
20938 c_parser_error (parser
, "expected identifier");
20942 c_token
*token
= c_parser_peek_token (parser
);
20943 tree variant
= lookup_name (token
->value
);
20945 if (variant
== NULL_TREE
)
20947 undeclared_variable (token
->location
, token
->value
);
20948 variant
= error_mark_node
;
20951 c_parser_consume_token (parser
);
20953 parens
.require_close (parser
);
20955 const char *clause
= "";
20956 location_t match_loc
= c_parser_peek_token (parser
)->location
;
20957 if (c_parser_next_token_is (parser
, CPP_NAME
))
20958 clause
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
20959 if (strcmp (clause
, "match"))
20961 c_parser_error (parser
, "expected %<match%>");
20965 c_parser_consume_token (parser
);
20967 if (!parens
.require_open (parser
))
20970 if (parms
== NULL_TREE
)
20971 parms
= error_mark_node
;
20973 tree ctx
= c_parser_omp_context_selector_specification (parser
, parms
);
20974 if (ctx
== error_mark_node
)
20976 ctx
= c_omp_check_context_selector (match_loc
, ctx
);
20977 if (ctx
!= error_mark_node
&& variant
!= error_mark_node
)
20979 if (TREE_CODE (variant
) != FUNCTION_DECL
)
20981 error_at (token
->location
, "variant %qD is not a function", variant
);
20982 variant
= error_mark_node
;
20984 else if (omp_get_context_selector (ctx
, "construct", "simd") == NULL_TREE
20985 && !comptypes (TREE_TYPE (fndecl
), TREE_TYPE (variant
)))
20987 error_at (token
->location
, "variant %qD and base %qD have "
20988 "incompatible types", variant
, fndecl
);
20989 variant
= error_mark_node
;
20991 else if (fndecl_built_in_p (variant
)
20992 && (strncmp (IDENTIFIER_POINTER (DECL_NAME (variant
)),
20993 "__builtin_", strlen ("__builtin_")) == 0
20994 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant
)),
20995 "__sync_", strlen ("__sync_")) == 0
20996 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant
)),
20997 "__atomic_", strlen ("__atomic_")) == 0))
20999 error_at (token
->location
, "variant %qD is a built-in", variant
);
21000 variant
= error_mark_node
;
21002 if (variant
!= error_mark_node
)
21004 C_DECL_USED (variant
) = 1;
21005 tree construct
= omp_get_context_selector (ctx
, "construct", NULL
);
21006 c_omp_mark_declare_variant (match_loc
, variant
, construct
);
21007 if (omp_context_selector_matches (ctx
))
21010 = tree_cons (get_identifier ("omp declare variant base"),
21011 build_tree_list (variant
, ctx
),
21012 DECL_ATTRIBUTES (fndecl
));
21013 DECL_ATTRIBUTES (fndecl
) = attr
;
21018 parens
.require_close (parser
);
21019 c_parser_skip_to_pragma_eol (parser
);
21022 /* Finalize #pragma omp declare simd or #pragma omp declare variant
21023 clauses after FNDECL has been parsed, and put that into "omp declare simd"
21024 or "omp declare variant base" attribute. */
21027 c_finish_omp_declare_simd (c_parser
*parser
, tree fndecl
, tree parms
,
21028 vec
<c_token
> *pclauses
)
21030 vec
<c_token
> &clauses
= *pclauses
;
21032 /* Normally first token is CPP_NAME "simd" or "variant". CPP_EOF there
21033 indicates error has been reported and CPP_PRAGMA that
21034 c_finish_omp_declare_simd has already processed the tokens. */
21035 if (clauses
.exists () && clauses
[0].type
== CPP_EOF
)
21037 const char *kind
= "simd";
21038 if (clauses
.exists ()
21039 && (clauses
[0].type
== CPP_NAME
|| clauses
[0].type
== CPP_PRAGMA
))
21040 kind
= IDENTIFIER_POINTER (clauses
[0].value
);
21041 gcc_assert (strcmp (kind
, "simd") == 0 || strcmp (kind
, "variant") == 0);
21042 if (fndecl
== NULL_TREE
|| TREE_CODE (fndecl
) != FUNCTION_DECL
)
21044 error ("%<#pragma omp declare %s%> not immediately followed by "
21045 "a function declaration or definition", kind
);
21046 clauses
[0].type
= CPP_EOF
;
21049 if (clauses
.exists () && clauses
[0].type
!= CPP_NAME
)
21051 error_at (DECL_SOURCE_LOCATION (fndecl
),
21052 "%<#pragma omp declare %s%> not immediately followed by "
21053 "a single function declaration or definition", kind
);
21054 clauses
[0].type
= CPP_EOF
;
21058 if (parms
== NULL_TREE
)
21059 parms
= DECL_ARGUMENTS (fndecl
);
21061 unsigned int tokens_avail
= parser
->tokens_avail
;
21062 gcc_assert (parser
->tokens
== &parser
->tokens_buf
[0]);
21064 parser
->tokens
= clauses
.address ();
21065 parser
->tokens_avail
= clauses
.length ();
21067 /* c_parser_omp_declare_simd pushed 2 extra CPP_EOF tokens at the end. */
21068 while (parser
->tokens_avail
> 3)
21070 c_token
*token
= c_parser_peek_token (parser
);
21071 gcc_assert (token
->type
== CPP_NAME
21072 && strcmp (IDENTIFIER_POINTER (token
->value
), kind
) == 0);
21073 c_parser_consume_token (parser
);
21074 parser
->in_pragma
= true;
21076 if (strcmp (kind
, "simd") == 0)
21079 c
= c_parser_omp_all_clauses (parser
, OMP_DECLARE_SIMD_CLAUSE_MASK
,
21080 "#pragma omp declare simd");
21081 c
= c_omp_declare_simd_clauses_to_numbers (parms
, c
);
21082 if (c
!= NULL_TREE
)
21083 c
= tree_cons (NULL_TREE
, c
, NULL_TREE
);
21084 c
= build_tree_list (get_identifier ("omp declare simd"), c
);
21085 TREE_CHAIN (c
) = DECL_ATTRIBUTES (fndecl
);
21086 DECL_ATTRIBUTES (fndecl
) = c
;
21090 gcc_assert (strcmp (kind
, "variant") == 0);
21091 c_finish_omp_declare_variant (parser
, fndecl
, parms
);
21095 parser
->tokens
= &parser
->tokens_buf
[0];
21096 parser
->tokens_avail
= tokens_avail
;
21097 if (clauses
.exists ())
21098 clauses
[0].type
= CPP_PRAGMA
;
21103 # pragma omp declare target new-line
21104 declarations and definitions
21105 # pragma omp end declare target new-line
21108 # pragma omp declare target ( extended-list ) new-line
21110 # pragma omp declare target declare-target-clauses[seq] new-line */
21112 #define OMP_DECLARE_TARGET_CLAUSE_MASK \
21113 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
21114 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK) \
21115 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE))
21118 c_parser_omp_declare_target (c_parser
*parser
)
21120 tree clauses
= NULL_TREE
;
21121 int device_type
= 0;
21122 bool only_device_type
= true;
21123 if (c_parser_next_token_is (parser
, CPP_NAME
))
21124 clauses
= c_parser_omp_all_clauses (parser
, OMP_DECLARE_TARGET_CLAUSE_MASK
,
21125 "#pragma omp declare target");
21126 else if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
21128 clauses
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_TO_DECLARE
,
21130 clauses
= c_finish_omp_clauses (clauses
, C_ORT_OMP
);
21131 c_parser_skip_to_pragma_eol (parser
);
21135 c_parser_skip_to_pragma_eol (parser
);
21136 current_omp_declare_target_attribute
++;
21139 for (tree c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
21140 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEVICE_TYPE
)
21141 device_type
|= OMP_CLAUSE_DEVICE_TYPE_KIND (c
);
21142 for (tree c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
21144 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEVICE_TYPE
)
21146 tree t
= OMP_CLAUSE_DECL (c
), id
;
21147 tree at1
= lookup_attribute ("omp declare target", DECL_ATTRIBUTES (t
));
21148 tree at2
= lookup_attribute ("omp declare target link",
21149 DECL_ATTRIBUTES (t
));
21150 only_device_type
= false;
21151 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LINK
)
21153 id
= get_identifier ("omp declare target link");
21154 std::swap (at1
, at2
);
21157 id
= get_identifier ("omp declare target");
21160 error_at (OMP_CLAUSE_LOCATION (c
),
21161 "%qD specified both in declare target %<link%> and %<to%>"
21167 DECL_ATTRIBUTES (t
) = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (t
));
21168 if (TREE_CODE (t
) != FUNCTION_DECL
&& !is_global_var (t
))
21171 symtab_node
*node
= symtab_node::get (t
);
21174 node
->offloadable
= 1;
21175 if (ENABLE_OFFLOADING
)
21177 g
->have_offload
= true;
21178 if (is_a
<varpool_node
*> (node
))
21179 vec_safe_push (offload_vars
, t
);
21183 if (TREE_CODE (t
) != FUNCTION_DECL
)
21185 if ((device_type
& OMP_CLAUSE_DEVICE_TYPE_HOST
) != 0)
21187 tree at3
= lookup_attribute ("omp declare target host",
21188 DECL_ATTRIBUTES (t
));
21189 if (at3
== NULL_TREE
)
21191 id
= get_identifier ("omp declare target host");
21192 DECL_ATTRIBUTES (t
)
21193 = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (t
));
21196 if ((device_type
& OMP_CLAUSE_DEVICE_TYPE_NOHOST
) != 0)
21198 tree at3
= lookup_attribute ("omp declare target nohost",
21199 DECL_ATTRIBUTES (t
));
21200 if (at3
== NULL_TREE
)
21202 id
= get_identifier ("omp declare target nohost");
21203 DECL_ATTRIBUTES (t
)
21204 = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (t
));
21208 if (device_type
&& only_device_type
)
21209 warning_at (OMP_CLAUSE_LOCATION (clauses
), 0,
21210 "directive with only %<device_type%> clauses ignored");
21214 c_parser_omp_end_declare_target (c_parser
*parser
)
21216 location_t loc
= c_parser_peek_token (parser
)->location
;
21217 c_parser_consume_pragma (parser
);
21218 if (c_parser_next_token_is (parser
, CPP_NAME
)
21219 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
),
21222 c_parser_consume_token (parser
);
21223 if (c_parser_next_token_is (parser
, CPP_NAME
)
21224 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
),
21226 c_parser_consume_token (parser
);
21229 c_parser_error (parser
, "expected %<target%>");
21230 c_parser_skip_to_pragma_eol (parser
);
21236 c_parser_error (parser
, "expected %<declare%>");
21237 c_parser_skip_to_pragma_eol (parser
);
21240 c_parser_skip_to_pragma_eol (parser
);
21241 if (!current_omp_declare_target_attribute
)
21242 error_at (loc
, "%<#pragma omp end declare target%> without corresponding "
21243 "%<#pragma omp declare target%>");
21245 current_omp_declare_target_attribute
--;
21250 #pragma omp declare reduction (reduction-id : typename-list : expression) \
21251 initializer-clause[opt] new-line
21253 initializer-clause:
21254 initializer (omp_priv = initializer)
21255 initializer (function-name (argument-list)) */
21258 c_parser_omp_declare_reduction (c_parser
*parser
, enum pragma_context context
)
21260 unsigned int tokens_avail
= 0, i
;
21261 vec
<tree
> types
= vNULL
;
21262 vec
<c_token
> clauses
= vNULL
;
21263 enum tree_code reduc_code
= ERROR_MARK
;
21264 tree reduc_id
= NULL_TREE
;
21266 location_t rloc
= c_parser_peek_token (parser
)->location
;
21268 if (context
== pragma_struct
|| context
== pragma_param
)
21270 error ("%<#pragma omp declare reduction%> not at file or block scope");
21274 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
21277 switch (c_parser_peek_token (parser
)->type
)
21280 reduc_code
= PLUS_EXPR
;
21283 reduc_code
= MULT_EXPR
;
21286 reduc_code
= MINUS_EXPR
;
21289 reduc_code
= BIT_AND_EXPR
;
21292 reduc_code
= BIT_XOR_EXPR
;
21295 reduc_code
= BIT_IOR_EXPR
;
21298 reduc_code
= TRUTH_ANDIF_EXPR
;
21301 reduc_code
= TRUTH_ORIF_EXPR
;
21305 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
21306 if (strcmp (p
, "min") == 0)
21308 reduc_code
= MIN_EXPR
;
21311 if (strcmp (p
, "max") == 0)
21313 reduc_code
= MAX_EXPR
;
21316 reduc_id
= c_parser_peek_token (parser
)->value
;
21319 c_parser_error (parser
,
21320 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
21321 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
21325 tree orig_reduc_id
, reduc_decl
;
21326 orig_reduc_id
= reduc_id
;
21327 reduc_id
= c_omp_reduction_id (reduc_code
, reduc_id
);
21328 reduc_decl
= c_omp_reduction_decl (reduc_id
);
21329 c_parser_consume_token (parser
);
21331 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
21336 location_t loc
= c_parser_peek_token (parser
)->location
;
21337 struct c_type_name
*ctype
= c_parser_type_name (parser
);
21340 type
= groktypename (ctype
, NULL
, NULL
);
21341 if (type
== error_mark_node
)
21343 else if ((INTEGRAL_TYPE_P (type
)
21344 || TREE_CODE (type
) == REAL_TYPE
21345 || TREE_CODE (type
) == COMPLEX_TYPE
)
21346 && orig_reduc_id
== NULL_TREE
)
21347 error_at (loc
, "predeclared arithmetic type in "
21348 "%<#pragma omp declare reduction%>");
21349 else if (TREE_CODE (type
) == FUNCTION_TYPE
21350 || TREE_CODE (type
) == ARRAY_TYPE
)
21351 error_at (loc
, "function or array type in "
21352 "%<#pragma omp declare reduction%>");
21353 else if (TYPE_ATOMIC (type
))
21354 error_at (loc
, "%<_Atomic%> qualified type in "
21355 "%<#pragma omp declare reduction%>");
21356 else if (TYPE_QUALS_NO_ADDR_SPACE (type
))
21357 error_at (loc
, "const, volatile or restrict qualified type in "
21358 "%<#pragma omp declare reduction%>");
21362 for (t
= DECL_INITIAL (reduc_decl
); t
; t
= TREE_CHAIN (t
))
21363 if (comptypes (TREE_PURPOSE (t
), type
))
21365 error_at (loc
, "redeclaration of %qs "
21366 "%<#pragma omp declare reduction%> for "
21368 IDENTIFIER_POINTER (reduc_id
)
21369 + sizeof ("omp declare reduction ") - 1,
21372 = DECL_SOURCE_LOCATION (TREE_VEC_ELT (TREE_VALUE (t
),
21374 error_at (ploc
, "previous %<#pragma omp declare "
21378 if (t
== NULL_TREE
)
21379 types
.safe_push (type
);
21381 if (c_parser_next_token_is (parser
, CPP_COMMA
))
21382 c_parser_consume_token (parser
);
21390 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>")
21391 || types
.is_empty ())
21394 clauses
.release ();
21398 c_token
*token
= c_parser_peek_token (parser
);
21399 if (token
->type
== CPP_EOF
|| token
->type
== CPP_PRAGMA_EOL
)
21401 c_parser_consume_token (parser
);
21403 c_parser_skip_to_pragma_eol (parser
);
21407 if (types
.length () > 1)
21409 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
21411 c_token
*token
= c_parser_peek_token (parser
);
21412 if (token
->type
== CPP_EOF
)
21414 clauses
.safe_push (*token
);
21415 c_parser_consume_token (parser
);
21417 clauses
.safe_push (*c_parser_peek_token (parser
));
21418 c_parser_skip_to_pragma_eol (parser
);
21420 /* Make sure nothing tries to read past the end of the tokens. */
21422 memset (&eof_token
, 0, sizeof (eof_token
));
21423 eof_token
.type
= CPP_EOF
;
21424 clauses
.safe_push (eof_token
);
21425 clauses
.safe_push (eof_token
);
21428 int errs
= errorcount
;
21429 FOR_EACH_VEC_ELT (types
, i
, type
)
21431 tokens_avail
= parser
->tokens_avail
;
21432 gcc_assert (parser
->tokens
== &parser
->tokens_buf
[0]);
21433 if (!clauses
.is_empty ())
21435 parser
->tokens
= clauses
.address ();
21436 parser
->tokens_avail
= clauses
.length ();
21437 parser
->in_pragma
= true;
21440 bool nested
= current_function_decl
!= NULL_TREE
;
21442 c_push_function_context ();
21443 tree fndecl
= build_decl (BUILTINS_LOCATION
, FUNCTION_DECL
,
21444 reduc_id
, default_function_type
);
21445 current_function_decl
= fndecl
;
21446 allocate_struct_function (fndecl
, true);
21448 tree stmt
= push_stmt_list ();
21449 /* Intentionally BUILTINS_LOCATION, so that -Wshadow doesn't
21450 warn about these. */
21451 tree omp_out
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
21452 get_identifier ("omp_out"), type
);
21453 DECL_ARTIFICIAL (omp_out
) = 1;
21454 DECL_CONTEXT (omp_out
) = fndecl
;
21455 pushdecl (omp_out
);
21456 tree omp_in
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
21457 get_identifier ("omp_in"), type
);
21458 DECL_ARTIFICIAL (omp_in
) = 1;
21459 DECL_CONTEXT (omp_in
) = fndecl
;
21461 struct c_expr combiner
= c_parser_expression (parser
);
21462 struct c_expr initializer
;
21463 tree omp_priv
= NULL_TREE
, omp_orig
= NULL_TREE
;
21465 initializer
.set_error ();
21466 if (!c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
21468 else if (c_parser_next_token_is (parser
, CPP_NAME
)
21469 && strcmp (IDENTIFIER_POINTER
21470 (c_parser_peek_token (parser
)->value
),
21471 "initializer") == 0)
21473 c_parser_consume_token (parser
);
21476 omp_priv
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
21477 get_identifier ("omp_priv"), type
);
21478 DECL_ARTIFICIAL (omp_priv
) = 1;
21479 DECL_INITIAL (omp_priv
) = error_mark_node
;
21480 DECL_CONTEXT (omp_priv
) = fndecl
;
21481 pushdecl (omp_priv
);
21482 omp_orig
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
21483 get_identifier ("omp_orig"), type
);
21484 DECL_ARTIFICIAL (omp_orig
) = 1;
21485 DECL_CONTEXT (omp_orig
) = fndecl
;
21486 pushdecl (omp_orig
);
21487 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
21489 else if (!c_parser_next_token_is (parser
, CPP_NAME
))
21491 c_parser_error (parser
, "expected %<omp_priv%> or "
21495 else if (strcmp (IDENTIFIER_POINTER
21496 (c_parser_peek_token (parser
)->value
),
21499 if (c_parser_peek_2nd_token (parser
)->type
!= CPP_OPEN_PAREN
21500 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
21502 c_parser_error (parser
, "expected function-name %<(%>");
21506 initializer
= c_parser_postfix_expression (parser
);
21507 if (initializer
.value
21508 && TREE_CODE (initializer
.value
) == CALL_EXPR
)
21511 tree c
= initializer
.value
;
21512 for (j
= 0; j
< call_expr_nargs (c
); j
++)
21514 tree a
= CALL_EXPR_ARG (c
, j
);
21516 if (TREE_CODE (a
) == ADDR_EXPR
21517 && TREE_OPERAND (a
, 0) == omp_priv
)
21520 if (j
== call_expr_nargs (c
))
21521 error ("one of the initializer call arguments should be "
21527 c_parser_consume_token (parser
);
21528 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
21532 tree st
= push_stmt_list ();
21533 location_t loc
= c_parser_peek_token (parser
)->location
;
21534 rich_location
richloc (line_table
, loc
);
21535 start_init (omp_priv
, NULL_TREE
, 0, &richloc
);
21536 struct c_expr init
= c_parser_initializer (parser
);
21538 finish_decl (omp_priv
, loc
, init
.value
,
21539 init
.original_type
, NULL_TREE
);
21540 pop_stmt_list (st
);
21544 && !c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
21550 c_parser_skip_to_pragma_eol (parser
);
21552 tree t
= tree_cons (type
, make_tree_vec (omp_priv
? 6 : 3),
21553 DECL_INITIAL (reduc_decl
));
21554 DECL_INITIAL (reduc_decl
) = t
;
21555 DECL_SOURCE_LOCATION (omp_out
) = rloc
;
21556 TREE_VEC_ELT (TREE_VALUE (t
), 0) = omp_out
;
21557 TREE_VEC_ELT (TREE_VALUE (t
), 1) = omp_in
;
21558 TREE_VEC_ELT (TREE_VALUE (t
), 2) = combiner
.value
;
21559 walk_tree (&combiner
.value
, c_check_omp_declare_reduction_r
,
21560 &TREE_VEC_ELT (TREE_VALUE (t
), 0), NULL
);
21563 DECL_SOURCE_LOCATION (omp_priv
) = rloc
;
21564 TREE_VEC_ELT (TREE_VALUE (t
), 3) = omp_priv
;
21565 TREE_VEC_ELT (TREE_VALUE (t
), 4) = omp_orig
;
21566 TREE_VEC_ELT (TREE_VALUE (t
), 5) = initializer
.value
;
21567 walk_tree (&initializer
.value
, c_check_omp_declare_reduction_r
,
21568 &TREE_VEC_ELT (TREE_VALUE (t
), 3), NULL
);
21569 walk_tree (&DECL_INITIAL (omp_priv
),
21570 c_check_omp_declare_reduction_r
,
21571 &TREE_VEC_ELT (TREE_VALUE (t
), 3), NULL
);
21575 pop_stmt_list (stmt
);
21577 if (cfun
->language
!= NULL
)
21579 ggc_free (cfun
->language
);
21580 cfun
->language
= NULL
;
21583 current_function_decl
= NULL_TREE
;
21585 c_pop_function_context ();
21587 if (!clauses
.is_empty ())
21589 parser
->tokens
= &parser
->tokens_buf
[0];
21590 parser
->tokens_avail
= tokens_avail
;
21594 if (errs
!= errorcount
)
21598 clauses
.release ();
21604 #pragma omp declare simd declare-simd-clauses[optseq] new-line
21605 #pragma omp declare reduction (reduction-id : typename-list : expression) \
21606 initializer-clause[opt] new-line
21607 #pragma omp declare target new-line
21610 #pragma omp declare variant (identifier) match (context-selector) */
21613 c_parser_omp_declare (c_parser
*parser
, enum pragma_context context
)
21615 c_parser_consume_pragma (parser
);
21616 if (c_parser_next_token_is (parser
, CPP_NAME
))
21618 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
21619 if (strcmp (p
, "simd") == 0)
21621 /* c_parser_consume_token (parser); done in
21622 c_parser_omp_declare_simd. */
21623 c_parser_omp_declare_simd (parser
, context
);
21626 if (strcmp (p
, "reduction") == 0)
21628 c_parser_consume_token (parser
);
21629 c_parser_omp_declare_reduction (parser
, context
);
21632 if (!flag_openmp
) /* flag_openmp_simd */
21634 c_parser_skip_to_pragma_eol (parser
, false);
21637 if (strcmp (p
, "target") == 0)
21639 c_parser_consume_token (parser
);
21640 c_parser_omp_declare_target (parser
);
21643 if (strcmp (p
, "variant") == 0)
21645 /* c_parser_consume_token (parser); done in
21646 c_parser_omp_declare_simd. */
21647 c_parser_omp_declare_simd (parser
, context
);
21652 c_parser_error (parser
, "expected %<simd%>, %<reduction%>, "
21653 "%<target%> or %<variant%>");
21654 c_parser_skip_to_pragma_eol (parser
);
21659 #pragma omp requires clauses[optseq] new-line */
21662 c_parser_omp_requires (c_parser
*parser
)
21665 enum omp_requires new_req
= (enum omp_requires
) 0;
21667 c_parser_consume_pragma (parser
);
21669 location_t loc
= c_parser_peek_token (parser
)->location
;
21670 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
21673 && c_parser_next_token_is (parser
, CPP_COMMA
)
21674 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
21675 c_parser_consume_token (parser
);
21679 if (c_parser_next_token_is (parser
, CPP_NAME
))
21682 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
21683 location_t cloc
= c_parser_peek_token (parser
)->location
;
21684 enum omp_requires this_req
= (enum omp_requires
) 0;
21686 if (!strcmp (p
, "unified_address"))
21687 this_req
= OMP_REQUIRES_UNIFIED_ADDRESS
;
21688 else if (!strcmp (p
, "unified_shared_memory"))
21689 this_req
= OMP_REQUIRES_UNIFIED_SHARED_MEMORY
;
21690 else if (!strcmp (p
, "dynamic_allocators"))
21691 this_req
= OMP_REQUIRES_DYNAMIC_ALLOCATORS
;
21692 else if (!strcmp (p
, "reverse_offload"))
21693 this_req
= OMP_REQUIRES_REVERSE_OFFLOAD
;
21694 else if (!strcmp (p
, "atomic_default_mem_order"))
21696 c_parser_consume_token (parser
);
21698 matching_parens parens
;
21699 if (parens
.require_open (parser
))
21701 if (c_parser_next_token_is (parser
, CPP_NAME
))
21703 tree v
= c_parser_peek_token (parser
)->value
;
21704 p
= IDENTIFIER_POINTER (v
);
21706 if (!strcmp (p
, "seq_cst"))
21708 = (enum omp_requires
) OMP_MEMORY_ORDER_SEQ_CST
;
21709 else if (!strcmp (p
, "relaxed"))
21711 = (enum omp_requires
) OMP_MEMORY_ORDER_RELAXED
;
21712 else if (!strcmp (p
, "acq_rel"))
21714 = (enum omp_requires
) OMP_MEMORY_ORDER_ACQ_REL
;
21718 error_at (c_parser_peek_token (parser
)->location
,
21719 "expected %<seq_cst%>, %<relaxed%> or "
21721 switch (c_parser_peek_token (parser
)->type
)
21724 case CPP_PRAGMA_EOL
:
21725 case CPP_CLOSE_PAREN
:
21728 if (c_parser_peek_2nd_token (parser
)->type
21729 == CPP_CLOSE_PAREN
)
21730 c_parser_consume_token (parser
);
21735 c_parser_consume_token (parser
);
21737 parens
.skip_until_found_close (parser
);
21740 c_parser_skip_to_pragma_eol (parser
, false);
21748 error_at (cloc
, "expected %<unified_address%>, "
21749 "%<unified_shared_memory%>, "
21750 "%<dynamic_allocators%>, "
21751 "%<reverse_offload%> "
21752 "or %<atomic_default_mem_order%> clause");
21753 c_parser_skip_to_pragma_eol (parser
, false);
21757 sorry_at (cloc
, "%qs clause on %<requires%> directive not "
21758 "supported yet", p
);
21760 c_parser_consume_token (parser
);
21763 if ((this_req
& ~OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
) != 0)
21765 if ((this_req
& new_req
) != 0)
21766 error_at (cloc
, "too many %qs clauses", p
);
21767 if (this_req
!= OMP_REQUIRES_DYNAMIC_ALLOCATORS
21768 && (omp_requires_mask
& OMP_REQUIRES_TARGET_USED
) != 0)
21769 error_at (cloc
, "%qs clause used lexically after first "
21770 "target construct or offloading API", p
);
21772 else if ((new_req
& OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
) != 0)
21774 error_at (cloc
, "too many %qs clauses",
21775 "atomic_default_mem_order");
21776 this_req
= (enum omp_requires
) 0;
21778 else if ((omp_requires_mask
21779 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
) != 0)
21781 error_at (cloc
, "more than one %<atomic_default_mem_order%>"
21782 " clause in a single compilation unit");
21784 = (enum omp_requires
)
21786 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
);
21788 else if ((omp_requires_mask
21789 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED
) != 0)
21790 error_at (cloc
, "%<atomic_default_mem_order%> clause used "
21791 "lexically after first %<atomic%> construct "
21792 "without memory order clause");
21793 new_req
= (enum omp_requires
) (new_req
| this_req
);
21795 = (enum omp_requires
) (omp_requires_mask
| this_req
);
21801 c_parser_skip_to_pragma_eol (parser
);
21804 error_at (loc
, "%<pragma omp requires%> requires at least one clause");
21807 /* Helper function for c_parser_omp_taskloop.
21808 Disallow zero sized or potentially zero sized task reductions. */
21811 c_finish_taskloop_clauses (tree clauses
)
21813 tree
*pc
= &clauses
;
21814 for (tree c
= clauses
; c
; c
= *pc
)
21816 bool remove
= false;
21817 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_REDUCTION
)
21819 tree type
= strip_array_types (TREE_TYPE (OMP_CLAUSE_DECL (c
)));
21820 if (integer_zerop (TYPE_SIZE_UNIT (type
)))
21822 error_at (OMP_CLAUSE_LOCATION (c
),
21823 "zero sized type %qT in %<reduction%> clause", type
);
21826 else if (TREE_CODE (TYPE_SIZE_UNIT (type
)) != INTEGER_CST
)
21828 error_at (OMP_CLAUSE_LOCATION (c
),
21829 "variable sized type %qT in %<reduction%> clause",
21835 *pc
= OMP_CLAUSE_CHAIN (c
);
21837 pc
= &OMP_CLAUSE_CHAIN (c
);
21843 #pragma omp taskloop taskloop-clause[optseq] new-line
21846 #pragma omp taskloop simd taskloop-simd-clause[optseq] new-line
21849 #define OMP_TASKLOOP_CLAUSE_MASK \
21850 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
21851 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
21852 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
21853 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
21854 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
21855 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_GRAINSIZE) \
21856 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TASKS) \
21857 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
21858 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
21859 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
21860 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
21861 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
21862 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP) \
21863 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
21864 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
21865 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
21866 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION))
21869 c_parser_omp_taskloop (location_t loc
, c_parser
*parser
,
21870 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
21873 tree clauses
, block
, ret
;
21875 strcat (p_name
, " taskloop");
21876 mask
|= OMP_TASKLOOP_CLAUSE_MASK
;
21877 /* #pragma omp parallel master taskloop{, simd} disallow in_reduction
21879 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_NUM_THREADS
)) != 0)
21880 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_IN_REDUCTION
);
21882 if (c_parser_next_token_is (parser
, CPP_NAME
))
21884 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
21886 if (strcmp (p
, "simd") == 0)
21888 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
21889 if (cclauses
== NULL
)
21890 cclauses
= cclauses_buf
;
21891 c_parser_consume_token (parser
);
21892 if (!flag_openmp
) /* flag_openmp_simd */
21893 return c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
,
21895 block
= c_begin_compound_stmt (true);
21896 ret
= c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
21897 block
= c_end_compound_stmt (loc
, block
, true);
21900 ret
= make_node (OMP_TASKLOOP
);
21901 TREE_TYPE (ret
) = void_type_node
;
21902 OMP_FOR_BODY (ret
) = block
;
21903 OMP_FOR_CLAUSES (ret
) = cclauses
[C_OMP_CLAUSE_SPLIT_TASKLOOP
];
21904 OMP_FOR_CLAUSES (ret
)
21905 = c_finish_taskloop_clauses (OMP_FOR_CLAUSES (ret
));
21906 SET_EXPR_LOCATION (ret
, loc
);
21911 if (!flag_openmp
) /* flag_openmp_simd */
21913 c_parser_skip_to_pragma_eol (parser
, false);
21917 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
21920 omp_split_clauses (loc
, OMP_TASKLOOP
, mask
, clauses
, cclauses
);
21921 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_TASKLOOP
];
21924 clauses
= c_finish_taskloop_clauses (clauses
);
21925 block
= c_begin_compound_stmt (true);
21926 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_TASKLOOP
, clauses
, NULL
, if_p
);
21927 block
= c_end_compound_stmt (loc
, block
, true);
21934 #pragma omp nothing new-line */
21937 c_parser_omp_nothing (c_parser
*parser
)
21939 c_parser_consume_pragma (parser
);
21940 c_parser_skip_to_pragma_eol (parser
);
21944 #pragma omp error clauses[optseq] new-line */
21947 c_parser_omp_error (c_parser
*parser
, enum pragma_context context
)
21949 int at_compilation
= -1;
21950 int severity_fatal
= -1;
21951 tree message
= NULL_TREE
;
21954 location_t loc
= c_parser_peek_token (parser
)->location
;
21956 c_parser_consume_pragma (parser
);
21958 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
21961 && c_parser_next_token_is (parser
, CPP_COMMA
)
21962 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
21963 c_parser_consume_token (parser
);
21967 if (!c_parser_next_token_is (parser
, CPP_NAME
))
21971 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
21972 location_t cloc
= c_parser_peek_token (parser
)->location
;
21973 static const char *args
[] = {
21974 "execution", "compilation", "warning", "fatal"
21977 int idx
= 0, n
= -1;
21978 tree m
= NULL_TREE
;
21980 if (!strcmp (p
, "at"))
21981 v
= &at_compilation
;
21982 else if (!strcmp (p
, "severity"))
21984 v
= &severity_fatal
;
21987 else if (strcmp (p
, "message"))
21990 "expected %<at%>, %<severity%> or %<message%> clause");
21991 c_parser_skip_to_pragma_eol (parser
, false);
21995 c_parser_consume_token (parser
);
21997 matching_parens parens
;
21998 if (parens
.require_open (parser
))
22002 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
22003 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
22004 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, true, true);
22005 m
= convert (const_string_type_node
, expr
.value
);
22006 m
= c_fully_fold (m
, false, NULL
);
22010 if (c_parser_next_token_is (parser
, CPP_NAME
))
22012 tree val
= c_parser_peek_token (parser
)->value
;
22013 const char *q
= IDENTIFIER_POINTER (val
);
22015 if (!strcmp (q
, args
[idx
]))
22017 else if (!strcmp (q
, args
[idx
+ 1]))
22022 error_at (c_parser_peek_token (parser
)->location
,
22023 "expected %qs or %qs", args
[idx
], args
[idx
+ 1]);
22025 switch (c_parser_peek_token (parser
)->type
)
22028 case CPP_PRAGMA_EOL
:
22029 case CPP_CLOSE_PAREN
:
22032 if (c_parser_peek_2nd_token (parser
)->type
22033 == CPP_CLOSE_PAREN
)
22034 c_parser_consume_token (parser
);
22039 c_parser_consume_token (parser
);
22042 parens
.skip_until_found_close (parser
);
22048 error_at (cloc
, "too many %qs clauses", p
);
22058 error_at (cloc
, "too many %qs clauses", p
);
22068 c_parser_skip_to_pragma_eol (parser
);
22072 if (at_compilation
== -1)
22073 at_compilation
= 1;
22074 if (severity_fatal
== -1)
22075 severity_fatal
= 1;
22076 if (!at_compilation
)
22078 if (context
!= pragma_compound
)
22080 error_at (loc
, "%<#pragma omp error%> with %<at(execution)%> clause "
22081 "may only be used in compound statements");
22085 = builtin_decl_explicit (severity_fatal
? BUILT_IN_GOMP_ERROR
22086 : BUILT_IN_GOMP_WARNING
);
22088 message
= build_zero_cst (const_string_type_node
);
22089 tree stmt
= build_call_expr_loc (loc
, fndecl
, 2, message
,
22090 build_all_ones_cst (size_type_node
));
22094 const char *msg
= NULL
;
22097 msg
= c_getstr (message
);
22099 msg
= _("<message unknown at compile time>");
22102 emit_diagnostic (severity_fatal
? DK_ERROR
: DK_WARNING
, loc
, 0,
22103 "%<pragma omp error%> encountered: %s", msg
);
22105 emit_diagnostic (severity_fatal
? DK_ERROR
: DK_WARNING
, loc
, 0,
22106 "%<pragma omp error%> encountered");
22110 /* Main entry point to parsing most OpenMP pragmas. */
22113 c_parser_omp_construct (c_parser
*parser
, bool *if_p
)
22115 enum pragma_kind p_kind
;
22118 char p_name
[sizeof "#pragma omp teams distribute parallel for simd"];
22119 omp_clause_mask
mask (0);
22121 loc
= c_parser_peek_token (parser
)->location
;
22122 p_kind
= c_parser_peek_token (parser
)->pragma_kind
;
22123 c_parser_consume_pragma (parser
);
22127 case PRAGMA_OACC_ATOMIC
:
22128 c_parser_omp_atomic (loc
, parser
, true);
22130 case PRAGMA_OACC_CACHE
:
22131 strcpy (p_name
, "#pragma acc");
22132 stmt
= c_parser_oacc_cache (loc
, parser
);
22134 case PRAGMA_OACC_DATA
:
22135 stmt
= c_parser_oacc_data (loc
, parser
, if_p
);
22137 case PRAGMA_OACC_HOST_DATA
:
22138 stmt
= c_parser_oacc_host_data (loc
, parser
, if_p
);
22140 case PRAGMA_OACC_KERNELS
:
22141 case PRAGMA_OACC_PARALLEL
:
22142 case PRAGMA_OACC_SERIAL
:
22143 strcpy (p_name
, "#pragma acc");
22144 stmt
= c_parser_oacc_compute (loc
, parser
, p_kind
, p_name
, if_p
);
22146 case PRAGMA_OACC_LOOP
:
22147 strcpy (p_name
, "#pragma acc");
22148 stmt
= c_parser_oacc_loop (loc
, parser
, p_name
, mask
, NULL
, if_p
);
22150 case PRAGMA_OACC_WAIT
:
22151 strcpy (p_name
, "#pragma wait");
22152 stmt
= c_parser_oacc_wait (loc
, parser
, p_name
);
22154 case PRAGMA_OMP_ALLOCATE
:
22155 c_parser_omp_allocate (loc
, parser
);
22157 case PRAGMA_OMP_ATOMIC
:
22158 c_parser_omp_atomic (loc
, parser
, false);
22160 case PRAGMA_OMP_CRITICAL
:
22161 stmt
= c_parser_omp_critical (loc
, parser
, if_p
);
22163 case PRAGMA_OMP_DISTRIBUTE
:
22164 strcpy (p_name
, "#pragma omp");
22165 stmt
= c_parser_omp_distribute (loc
, parser
, p_name
, mask
, NULL
, if_p
);
22167 case PRAGMA_OMP_FOR
:
22168 strcpy (p_name
, "#pragma omp");
22169 stmt
= c_parser_omp_for (loc
, parser
, p_name
, mask
, NULL
, if_p
);
22171 case PRAGMA_OMP_LOOP
:
22172 strcpy (p_name
, "#pragma omp");
22173 stmt
= c_parser_omp_loop (loc
, parser
, p_name
, mask
, NULL
, if_p
);
22175 case PRAGMA_OMP_MASKED
:
22176 strcpy (p_name
, "#pragma omp");
22177 stmt
= c_parser_omp_masked (loc
, parser
, p_name
, mask
, NULL
, if_p
);
22179 case PRAGMA_OMP_MASTER
:
22180 strcpy (p_name
, "#pragma omp");
22181 stmt
= c_parser_omp_master (loc
, parser
, p_name
, mask
, NULL
, if_p
);
22183 case PRAGMA_OMP_PARALLEL
:
22184 strcpy (p_name
, "#pragma omp");
22185 stmt
= c_parser_omp_parallel (loc
, parser
, p_name
, mask
, NULL
, if_p
);
22187 case PRAGMA_OMP_SCOPE
:
22188 stmt
= c_parser_omp_scope (loc
, parser
, if_p
);
22190 case PRAGMA_OMP_SECTIONS
:
22191 strcpy (p_name
, "#pragma omp");
22192 stmt
= c_parser_omp_sections (loc
, parser
, p_name
, mask
, NULL
);
22194 case PRAGMA_OMP_SIMD
:
22195 strcpy (p_name
, "#pragma omp");
22196 stmt
= c_parser_omp_simd (loc
, parser
, p_name
, mask
, NULL
, if_p
);
22198 case PRAGMA_OMP_SINGLE
:
22199 stmt
= c_parser_omp_single (loc
, parser
, if_p
);
22201 case PRAGMA_OMP_TASK
:
22202 stmt
= c_parser_omp_task (loc
, parser
, if_p
);
22204 case PRAGMA_OMP_TASKGROUP
:
22205 stmt
= c_parser_omp_taskgroup (loc
, parser
, if_p
);
22207 case PRAGMA_OMP_TASKLOOP
:
22208 strcpy (p_name
, "#pragma omp");
22209 stmt
= c_parser_omp_taskloop (loc
, parser
, p_name
, mask
, NULL
, if_p
);
22211 case PRAGMA_OMP_TEAMS
:
22212 strcpy (p_name
, "#pragma omp");
22213 stmt
= c_parser_omp_teams (loc
, parser
, p_name
, mask
, NULL
, if_p
);
22216 gcc_unreachable ();
22219 if (stmt
&& stmt
!= error_mark_node
)
22220 gcc_assert (EXPR_LOCATION (stmt
) != UNKNOWN_LOCATION
);
22225 # pragma omp threadprivate (variable-list) */
22228 c_parser_omp_threadprivate (c_parser
*parser
)
22233 c_parser_consume_pragma (parser
);
22234 loc
= c_parser_peek_token (parser
)->location
;
22235 vars
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ERROR
, NULL
);
22237 /* Mark every variable in VARS to be assigned thread local storage. */
22238 for (t
= vars
; t
; t
= TREE_CHAIN (t
))
22240 tree v
= TREE_PURPOSE (t
);
22242 /* FIXME diagnostics: Ideally we should keep individual
22243 locations for all the variables in the var list to make the
22244 following errors more precise. Perhaps
22245 c_parser_omp_var_list_parens() should construct a list of
22246 locations to go along with the var list. */
22248 /* If V had already been marked threadprivate, it doesn't matter
22249 whether it had been used prior to this point. */
22251 error_at (loc
, "%qD is not a variable", v
);
22252 else if (TREE_USED (v
) && !C_DECL_THREADPRIVATE_P (v
))
22253 error_at (loc
, "%qE declared %<threadprivate%> after first use", v
);
22254 else if (! is_global_var (v
))
22255 error_at (loc
, "automatic variable %qE cannot be %<threadprivate%>", v
);
22256 else if (TREE_TYPE (v
) == error_mark_node
)
22258 else if (! COMPLETE_TYPE_P (TREE_TYPE (v
)))
22259 error_at (loc
, "%<threadprivate%> %qE has incomplete type", v
);
22262 if (! DECL_THREAD_LOCAL_P (v
))
22264 set_decl_tls_model (v
, decl_default_tls_model (v
));
22265 /* If rtl has been already set for this var, call
22266 make_decl_rtl once again, so that encode_section_info
22267 has a chance to look at the new decl flags. */
22268 if (DECL_RTL_SET_P (v
))
22271 C_DECL_THREADPRIVATE_P (v
) = 1;
22275 c_parser_skip_to_pragma_eol (parser
);
22278 /* Parse a transaction attribute (GCC Extension).
22280 transaction-attribute:
22282 attribute-specifier
22286 c_parser_transaction_attributes (c_parser
*parser
)
22288 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
22289 return c_parser_gnu_attributes (parser
);
22291 if (!c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
))
22293 return c_parser_std_attribute_specifier (parser
, true);
22296 /* Parse a __transaction_atomic or __transaction_relaxed statement
22299 transaction-statement:
22300 __transaction_atomic transaction-attribute[opt] compound-statement
22301 __transaction_relaxed compound-statement
22303 Note that the only valid attribute is: "outer".
22307 c_parser_transaction (c_parser
*parser
, enum rid keyword
)
22309 unsigned int old_in
= parser
->in_transaction
;
22310 unsigned int this_in
= 1, new_in
;
22311 location_t loc
= c_parser_peek_token (parser
)->location
;
22314 gcc_assert ((keyword
== RID_TRANSACTION_ATOMIC
22315 || keyword
== RID_TRANSACTION_RELAXED
)
22316 && c_parser_next_token_is_keyword (parser
, keyword
));
22317 c_parser_consume_token (parser
);
22319 if (keyword
== RID_TRANSACTION_RELAXED
)
22320 this_in
|= TM_STMT_ATTR_RELAXED
;
22323 attrs
= c_parser_transaction_attributes (parser
);
22325 this_in
|= parse_tm_stmt_attr (attrs
, TM_STMT_ATTR_OUTER
);
22328 /* Keep track if we're in the lexical scope of an outer transaction. */
22329 new_in
= this_in
| (old_in
& TM_STMT_ATTR_OUTER
);
22331 parser
->in_transaction
= new_in
;
22332 stmt
= c_parser_compound_statement (parser
);
22333 parser
->in_transaction
= old_in
;
22336 stmt
= c_finish_transaction (loc
, stmt
, this_in
);
22338 error_at (loc
, (keyword
== RID_TRANSACTION_ATOMIC
?
22339 "%<__transaction_atomic%> without transactional memory support enabled"
22340 : "%<__transaction_relaxed %> "
22341 "without transactional memory support enabled"));
22346 /* Parse a __transaction_atomic or __transaction_relaxed expression
22349 transaction-expression:
22350 __transaction_atomic ( expression )
22351 __transaction_relaxed ( expression )
22354 static struct c_expr
22355 c_parser_transaction_expression (c_parser
*parser
, enum rid keyword
)
22358 unsigned int old_in
= parser
->in_transaction
;
22359 unsigned int this_in
= 1;
22360 location_t loc
= c_parser_peek_token (parser
)->location
;
22363 gcc_assert ((keyword
== RID_TRANSACTION_ATOMIC
22364 || keyword
== RID_TRANSACTION_RELAXED
)
22365 && c_parser_next_token_is_keyword (parser
, keyword
));
22366 c_parser_consume_token (parser
);
22368 if (keyword
== RID_TRANSACTION_RELAXED
)
22369 this_in
|= TM_STMT_ATTR_RELAXED
;
22372 attrs
= c_parser_transaction_attributes (parser
);
22374 this_in
|= parse_tm_stmt_attr (attrs
, 0);
22377 parser
->in_transaction
= this_in
;
22378 matching_parens parens
;
22379 if (parens
.require_open (parser
))
22381 tree expr
= c_parser_expression (parser
).value
;
22382 ret
.original_type
= TREE_TYPE (expr
);
22383 ret
.value
= build1 (TRANSACTION_EXPR
, ret
.original_type
, expr
);
22384 if (this_in
& TM_STMT_ATTR_RELAXED
)
22385 TRANSACTION_EXPR_RELAXED (ret
.value
) = 1;
22386 SET_EXPR_LOCATION (ret
.value
, loc
);
22387 ret
.original_code
= TRANSACTION_EXPR
;
22388 if (!parens
.require_close (parser
))
22390 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
22398 ret
.original_code
= ERROR_MARK
;
22399 ret
.original_type
= NULL
;
22401 parser
->in_transaction
= old_in
;
22404 error_at (loc
, (keyword
== RID_TRANSACTION_ATOMIC
?
22405 "%<__transaction_atomic%> without transactional memory support enabled"
22406 : "%<__transaction_relaxed %> "
22407 "without transactional memory support enabled"));
22409 set_c_expr_source_range (&ret
, loc
, loc
);
22414 /* Parse a __transaction_cancel statement (GCC Extension).
22416 transaction-cancel-statement:
22417 __transaction_cancel transaction-attribute[opt] ;
22419 Note that the only valid attribute is "outer".
22423 c_parser_transaction_cancel (c_parser
*parser
)
22425 location_t loc
= c_parser_peek_token (parser
)->location
;
22427 bool is_outer
= false;
22429 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_TRANSACTION_CANCEL
));
22430 c_parser_consume_token (parser
);
22432 attrs
= c_parser_transaction_attributes (parser
);
22434 is_outer
= (parse_tm_stmt_attr (attrs
, TM_STMT_ATTR_OUTER
) != 0);
22438 error_at (loc
, "%<__transaction_cancel%> without "
22439 "transactional memory support enabled");
22442 else if (parser
->in_transaction
& TM_STMT_ATTR_RELAXED
)
22444 error_at (loc
, "%<__transaction_cancel%> within a "
22445 "%<__transaction_relaxed%>");
22450 if ((parser
->in_transaction
& TM_STMT_ATTR_OUTER
) == 0
22451 && !is_tm_may_cancel_outer (current_function_decl
))
22453 error_at (loc
, "outer %<__transaction_cancel%> not "
22454 "within outer %<__transaction_atomic%> or "
22455 "a %<transaction_may_cancel_outer%> function");
22459 else if (parser
->in_transaction
== 0)
22461 error_at (loc
, "%<__transaction_cancel%> not within "
22462 "%<__transaction_atomic%>");
22466 return add_stmt (build_tm_abort_call (loc
, is_outer
));
22469 return build1 (NOP_EXPR
, void_type_node
, error_mark_node
);
22472 /* Parse a single source file. */
22475 c_parse_file (void)
22477 /* Use local storage to begin. If the first token is a pragma, parse it.
22478 If it is #pragma GCC pch_preprocess, then this will load a PCH file
22479 which will cause garbage collection. */
22482 memset (&tparser
, 0, sizeof tparser
);
22483 tparser
.translate_strings_p
= true;
22484 tparser
.tokens
= &tparser
.tokens_buf
[0];
22485 the_parser
= &tparser
;
22487 if (c_parser_peek_token (&tparser
)->pragma_kind
== PRAGMA_GCC_PCH_PREPROCESS
)
22488 c_parser_pragma_pch_preprocess (&tparser
);
22490 c_common_no_more_pch ();
22492 the_parser
= ggc_alloc
<c_parser
> ();
22493 *the_parser
= tparser
;
22494 if (tparser
.tokens
== &tparser
.tokens_buf
[0])
22495 the_parser
->tokens
= &the_parser
->tokens_buf
[0];
22497 /* Initialize EH, if we've been told to do so. */
22498 if (flag_exceptions
)
22499 using_eh_for_cleanups ();
22501 c_parser_translation_unit (the_parser
);
22505 /* Parse the body of a function declaration marked with "__RTL".
22507 The RTL parser works on the level of characters read from a
22508 FILE *, whereas c_parser works at the level of tokens.
22509 Square this circle by consuming all of the tokens up to and
22510 including the closing brace, recording the start/end of the RTL
22511 fragment, and reopening the file and re-reading the relevant
22512 lines within the RTL parser.
22514 This requires the opening and closing braces of the C function
22515 to be on separate lines from the RTL they wrap.
22517 Take ownership of START_WITH_PASS, if non-NULL. */
22520 c_parser_parse_rtl_body (c_parser
*parser
, char *start_with_pass
)
22522 if (!c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
22524 free (start_with_pass
);
22525 return c_parser_peek_token (parser
)->location
;
22528 location_t start_loc
= c_parser_peek_token (parser
)->location
;
22530 /* Consume all tokens, up to the closing brace, handling
22531 matching pairs of braces in the rtl dump. */
22532 int num_open_braces
= 1;
22535 switch (c_parser_peek_token (parser
)->type
)
22537 case CPP_OPEN_BRACE
:
22540 case CPP_CLOSE_BRACE
:
22541 if (--num_open_braces
== 0)
22542 goto found_closing_brace
;
22545 error_at (start_loc
, "no closing brace");
22546 free (start_with_pass
);
22547 return c_parser_peek_token (parser
)->location
;
22551 c_parser_consume_token (parser
);
22554 found_closing_brace
:
22555 /* At the closing brace; record its location. */
22556 location_t end_loc
= c_parser_peek_token (parser
)->location
;
22558 /* Consume the closing brace. */
22559 c_parser_consume_token (parser
);
22561 /* Invoke the RTL parser. */
22562 if (!read_rtl_function_body_from_file_range (start_loc
, end_loc
))
22564 free (start_with_pass
);
22568 /* Run the backend on the cfun created above, transferring ownership of
22569 START_WITH_PASS. */
22570 run_rtl_passes (start_with_pass
);
22574 #include "gt-c-c-parser.h"