1 /* Parser for C and Objective-C.
2 Copyright (C) 1987-2022 Free Software Foundation, Inc.
4 Parser actions based on the old Bison parser; structure somewhat
5 influenced by and fragments based on the C++ parser.
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
25 Make sure all relevant comments, and all relevant code from all
26 actions, brought over from old parser. Verify exact correspondence
29 Add testcases covering every input symbol in every state in old and
32 Include full syntax for GNU C, including erroneous cases accepted
33 with error messages, in syntax productions in comments.
35 Make more diagnostics in the front end generally take an explicit
36 location rather than implicitly using input_location. */
39 #define INCLUDE_MEMORY
41 #include "coretypes.h"
46 #include "stringpool.h"
49 #include "stor-layout.h"
51 #include "trans-mem.h"
52 #include "c-family/c-pragma.h"
54 #include "c-family/c-objc.h"
56 #include "omp-general.h"
57 #include "omp-offload.h"
59 #include "gomp-constants.h"
60 #include "c-family/c-indentation.h"
61 #include "gimple-expr.h"
63 #include "gcc-rich-location.h"
65 #include "gimple-parser.h"
66 #include "read-rtl-function.h"
67 #include "run-rtl-passes.h"
69 #include "c-family/name-hint.h"
70 #include "tree-iterator.h"
71 #include "tree-pretty-print.h"
73 #include "c-family/known-headers.h"
75 /* We need to walk over decls with incomplete struct/union/enum types
76 after parsing the whole translation unit.
77 In finish_decl(), if the decl is static, has incomplete
78 struct/union/enum type, it is appended to incomplete_record_decls.
79 In c_parser_translation_unit(), we iterate over incomplete_record_decls
80 and report error if any of the decls are still incomplete. */
82 vec
<tree
> incomplete_record_decls
;
85 set_c_expr_source_range (c_expr
*expr
,
86 location_t start
, location_t finish
)
88 expr
->src_range
.m_start
= start
;
89 expr
->src_range
.m_finish
= finish
;
91 set_source_range (expr
->value
, start
, finish
);
95 set_c_expr_source_range (c_expr
*expr
,
96 source_range src_range
)
98 expr
->src_range
= src_range
;
100 set_source_range (expr
->value
, src_range
);
104 /* Initialization routine for this file. */
109 /* The only initialization required is of the reserved word
115 /* Make sure RID_MAX hasn't grown past the 8 bits used to hold the keyword in
116 the c_token structure. */
117 gcc_assert (RID_MAX
<= 255);
124 mask
|= D_ASM
| D_EXT
;
128 if (!c_dialect_objc ())
129 mask
|= D_OBJC
| D_CXX_OBJC
;
131 ridpointers
= ggc_cleared_vec_alloc
<tree
> ((int) RID_MAX
);
132 for (i
= 0; i
< num_c_common_reswords
; i
++)
134 /* If a keyword is disabled, do not enter it into the table
135 and so create a canonical spelling that isn't a keyword. */
136 if (c_common_reswords
[i
].disable
& mask
)
139 && (c_common_reswords
[i
].disable
& D_CXXWARN
))
141 id
= get_identifier (c_common_reswords
[i
].word
);
142 C_SET_RID_CODE (id
, RID_CXX_COMPAT_WARN
);
143 C_IS_RESERVED_WORD (id
) = 1;
148 id
= get_identifier (c_common_reswords
[i
].word
);
149 C_SET_RID_CODE (id
, c_common_reswords
[i
].rid
);
150 C_IS_RESERVED_WORD (id
) = 1;
151 ridpointers
[(int) c_common_reswords
[i
].rid
] = id
;
154 for (i
= 0; i
< NUM_INT_N_ENTS
; i
++)
156 /* We always create the symbols but they aren't always supported. */
158 sprintf (name
, "__int%d", int_n_data
[i
].bitsize
);
159 id
= get_identifier (name
);
160 C_SET_RID_CODE (id
, RID_FIRST_INT_N
+ i
);
161 C_IS_RESERVED_WORD (id
) = 1;
163 sprintf (name
, "__int%d__", int_n_data
[i
].bitsize
);
164 id
= get_identifier (name
);
165 C_SET_RID_CODE (id
, RID_FIRST_INT_N
+ i
);
166 C_IS_RESERVED_WORD (id
) = 1;
171 id
= get_identifier ("omp_all_memory");
172 C_SET_RID_CODE (id
, RID_OMP_ALL_MEMORY
);
173 C_IS_RESERVED_WORD (id
) = 1;
174 ridpointers
[RID_OMP_ALL_MEMORY
] = id
;
178 /* A parser structure recording information about the state and
179 context of parsing. Includes lexer information with up to two
180 tokens of look-ahead; more are not needed for C. */
181 struct GTY(()) c_parser
{
182 /* The look-ahead tokens. */
183 c_token
* GTY((skip
)) tokens
;
184 /* Buffer for look-ahead tokens. */
185 c_token tokens_buf
[4];
186 /* How many look-ahead tokens are available (0 - 4, or
187 more if parsing from pre-lexed tokens). */
188 unsigned int tokens_avail
;
189 /* Raw look-ahead tokens, used only for checking in Objective-C
190 whether '[[' starts attributes. */
191 vec
<c_token
, va_gc
> *raw_tokens
;
192 /* The number of raw look-ahead tokens that have since been fully
194 unsigned int raw_tokens_used
;
195 /* True if a syntax error is being recovered from; false otherwise.
196 c_parser_error sets this flag. It should clear this flag when
197 enough tokens have been consumed to recover from the error. */
198 BOOL_BITFIELD error
: 1;
199 /* True if we're processing a pragma, and shouldn't automatically
200 consume CPP_PRAGMA_EOL. */
201 BOOL_BITFIELD in_pragma
: 1;
202 /* True if we're parsing the outermost block of an if statement. */
203 BOOL_BITFIELD in_if_block
: 1;
204 /* True if we want to lex a translated, joined string (for an
205 initial #pragma pch_preprocess). Otherwise the parser is
206 responsible for concatenating strings and translating to the
207 execution character set as needed. */
208 BOOL_BITFIELD lex_joined_string
: 1;
209 /* True if, when the parser is concatenating string literals, it
210 should translate them to the execution character set (false
211 inside attributes). */
212 BOOL_BITFIELD translate_strings_p
: 1;
214 /* Objective-C specific parser/lexer information. */
216 /* True if we are in a context where the Objective-C "PQ" keywords
217 are considered keywords. */
218 BOOL_BITFIELD objc_pq_context
: 1;
219 /* True if we are parsing a (potential) Objective-C foreach
220 statement. This is set to true after we parsed 'for (' and while
221 we wait for 'in' or ';' to decide if it's a standard C for loop or an
222 Objective-C foreach loop. */
223 BOOL_BITFIELD objc_could_be_foreach_context
: 1;
224 /* The following flag is needed to contextualize Objective-C lexical
225 analysis. In some cases (e.g., 'int NSObject;'), it is
226 undesirable to bind an identifier to an Objective-C class, even
227 if a class with that name exists. */
228 BOOL_BITFIELD objc_need_raw_identifier
: 1;
229 /* Nonzero if we're processing a __transaction statement. The value
230 is 1 | TM_STMT_ATTR_*. */
231 unsigned int in_transaction
: 4;
232 /* True if we are in a context where the Objective-C "Property attribute"
233 keywords are valid. */
234 BOOL_BITFIELD objc_property_attr_context
: 1;
236 /* Whether we have just seen/constructed a string-literal. Set when
237 returning a string-literal from c_parser_string_literal. Reset
238 in consume_token. Useful when we get a parse error and see an
239 unknown token, which could have been a string-literal constant
241 BOOL_BITFIELD seen_string_literal
: 1;
243 /* Location of the last consumed token. */
244 location_t last_token_location
;
247 /* Return a pointer to the Nth token in PARSERs tokens_buf. */
250 c_parser_tokens_buf (c_parser
*parser
, unsigned n
)
252 return &parser
->tokens_buf
[n
];
255 /* Return the error state of PARSER. */
258 c_parser_error (c_parser
*parser
)
260 return parser
->error
;
263 /* Set the error state of PARSER to ERR. */
266 c_parser_set_error (c_parser
*parser
, bool err
)
272 /* The actual parser and external interface. ??? Does this need to be
273 garbage-collected? */
275 static GTY (()) c_parser
*the_parser
;
277 /* Read in and lex a single token, storing it in *TOKEN. If RAW,
278 context-sensitive postprocessing of the token is not done. */
281 c_lex_one_token (c_parser
*parser
, c_token
*token
, bool raw
= false)
283 timevar_push (TV_LEX
);
285 if (raw
|| vec_safe_length (parser
->raw_tokens
) == 0)
287 token
->type
= c_lex_with_flags (&token
->value
, &token
->location
,
289 (parser
->lex_joined_string
290 ? 0 : C_LEX_STRING_NO_JOIN
));
291 token
->id_kind
= C_ID_NONE
;
292 token
->keyword
= RID_MAX
;
293 token
->pragma_kind
= PRAGMA_NONE
;
297 /* Use a token previously lexed as a raw look-ahead token, and
298 complete the processing on it. */
299 *token
= (*parser
->raw_tokens
)[parser
->raw_tokens_used
];
300 ++parser
->raw_tokens_used
;
301 if (parser
->raw_tokens_used
== vec_safe_length (parser
->raw_tokens
))
303 vec_free (parser
->raw_tokens
);
304 parser
->raw_tokens_used
= 0;
317 bool objc_force_identifier
= parser
->objc_need_raw_identifier
;
318 if (c_dialect_objc ())
319 parser
->objc_need_raw_identifier
= false;
321 if (C_IS_RESERVED_WORD (token
->value
))
323 enum rid rid_code
= C_RID_CODE (token
->value
);
325 if (rid_code
== RID_CXX_COMPAT_WARN
)
327 warning_at (token
->location
,
329 "identifier %qE conflicts with C++ keyword",
332 else if (rid_code
>= RID_FIRST_ADDR_SPACE
333 && rid_code
<= RID_LAST_ADDR_SPACE
)
336 as
= (addr_space_t
) (rid_code
- RID_FIRST_ADDR_SPACE
);
337 targetm
.addr_space
.diagnose_usage (as
, token
->location
);
338 token
->id_kind
= C_ID_ADDRSPACE
;
339 token
->keyword
= rid_code
;
342 else if (c_dialect_objc () && OBJC_IS_PQ_KEYWORD (rid_code
))
344 /* We found an Objective-C "pq" keyword (in, out,
345 inout, bycopy, byref, oneway). They need special
346 care because the interpretation depends on the
348 if (parser
->objc_pq_context
)
350 token
->type
= CPP_KEYWORD
;
351 token
->keyword
= rid_code
;
354 else if (parser
->objc_could_be_foreach_context
355 && rid_code
== RID_IN
)
357 /* We are in Objective-C, inside a (potential)
358 foreach context (which means after having
359 parsed 'for (', but before having parsed ';'),
360 and we found 'in'. We consider it the keyword
361 which terminates the declaration at the
362 beginning of a foreach-statement. Note that
363 this means you can't use 'in' for anything else
364 in that context; in particular, in Objective-C
365 you can't use 'in' as the name of the running
366 variable in a C for loop. We could potentially
367 try to add code here to disambiguate, but it
368 seems a reasonable limitation. */
369 token
->type
= CPP_KEYWORD
;
370 token
->keyword
= rid_code
;
373 /* Else, "pq" keywords outside of the "pq" context are
374 not keywords, and we fall through to the code for
377 else if (c_dialect_objc () && OBJC_IS_PATTR_KEYWORD (rid_code
))
379 /* We found an Objective-C "property attribute"
380 keyword (getter, setter, readonly, etc). These are
381 only valid in the property context. */
382 if (parser
->objc_property_attr_context
)
384 token
->type
= CPP_KEYWORD
;
385 token
->keyword
= rid_code
;
388 /* Else they are not special keywords.
391 else if (c_dialect_objc ()
392 && (OBJC_IS_AT_KEYWORD (rid_code
)
393 || OBJC_IS_CXX_KEYWORD (rid_code
)))
395 /* We found one of the Objective-C "@" keywords (defs,
396 selector, synchronized, etc) or one of the
397 Objective-C "cxx" keywords (class, private,
398 protected, public, try, catch, throw) without a
399 preceding '@' sign. Do nothing and fall through to
400 the code for normal tokens (in C++ we would still
401 consider the CXX ones keywords, but not in C). */
406 token
->type
= CPP_KEYWORD
;
407 token
->keyword
= rid_code
;
412 decl
= lookup_name (token
->value
);
415 if (TREE_CODE (decl
) == TYPE_DECL
)
417 token
->id_kind
= C_ID_TYPENAME
;
421 else if (c_dialect_objc ())
423 tree objc_interface_decl
= objc_is_class_name (token
->value
);
424 /* Objective-C class names are in the same namespace as
425 variables and typedefs, and hence are shadowed by local
427 if (objc_interface_decl
428 && (!objc_force_identifier
|| global_bindings_p ()))
430 token
->value
= objc_interface_decl
;
431 token
->id_kind
= C_ID_CLASSNAME
;
435 token
->id_kind
= C_ID_ID
;
439 /* This only happens in Objective-C; it must be a keyword. */
440 token
->type
= CPP_KEYWORD
;
441 switch (C_RID_CODE (token
->value
))
443 /* Replace 'class' with '@class', 'private' with '@private',
444 etc. This prevents confusion with the C++ keyword
445 'class', and makes the tokens consistent with other
446 Objective-C 'AT' keywords. For example '@class' is
447 reported as RID_AT_CLASS which is consistent with
448 '@synchronized', which is reported as
451 case RID_CLASS
: token
->keyword
= RID_AT_CLASS
; break;
452 case RID_PRIVATE
: token
->keyword
= RID_AT_PRIVATE
; break;
453 case RID_PROTECTED
: token
->keyword
= RID_AT_PROTECTED
; break;
454 case RID_PUBLIC
: token
->keyword
= RID_AT_PUBLIC
; break;
455 case RID_THROW
: token
->keyword
= RID_AT_THROW
; break;
456 case RID_TRY
: token
->keyword
= RID_AT_TRY
; break;
457 case RID_CATCH
: token
->keyword
= RID_AT_CATCH
; break;
458 case RID_SYNCHRONIZED
: token
->keyword
= RID_AT_SYNCHRONIZED
; break;
459 default: token
->keyword
= C_RID_CODE (token
->value
);
464 case CPP_CLOSE_PAREN
:
466 /* These tokens may affect the interpretation of any identifiers
467 following, if doing Objective-C. */
468 if (c_dialect_objc ())
469 parser
->objc_need_raw_identifier
= false;
472 /* We smuggled the cpp_token->u.pragma value in an INTEGER_CST. */
473 token
->pragma_kind
= (enum pragma_kind
) TREE_INT_CST_LOW (token
->value
);
480 timevar_pop (TV_LEX
);
483 /* Return a pointer to the next token from PARSER, reading it in if
487 c_parser_peek_token (c_parser
*parser
)
489 if (parser
->tokens_avail
== 0)
491 c_lex_one_token (parser
, &parser
->tokens
[0]);
492 parser
->tokens_avail
= 1;
494 return &parser
->tokens
[0];
497 /* Return a pointer to the next-but-one token from PARSER, reading it
498 in if necessary. The next token is already read in. */
501 c_parser_peek_2nd_token (c_parser
*parser
)
503 if (parser
->tokens_avail
>= 2)
504 return &parser
->tokens
[1];
505 gcc_assert (parser
->tokens_avail
== 1);
506 gcc_assert (parser
->tokens
[0].type
!= CPP_EOF
);
507 gcc_assert (parser
->tokens
[0].type
!= CPP_PRAGMA_EOL
);
508 c_lex_one_token (parser
, &parser
->tokens
[1]);
509 parser
->tokens_avail
= 2;
510 return &parser
->tokens
[1];
513 /* Return a pointer to the Nth token from PARSER, reading it
514 in if necessary. The N-1th token is already read in. */
517 c_parser_peek_nth_token (c_parser
*parser
, unsigned int n
)
519 /* N is 1-based, not zero-based. */
522 if (parser
->tokens_avail
>= n
)
523 return &parser
->tokens
[n
- 1];
524 gcc_assert (parser
->tokens_avail
== n
- 1);
525 c_lex_one_token (parser
, &parser
->tokens
[n
- 1]);
526 parser
->tokens_avail
= n
;
527 return &parser
->tokens
[n
- 1];
530 /* Return a pointer to the Nth token from PARSER, reading it in as a
531 raw look-ahead token if necessary. The N-1th token is already read
532 in. Raw look-ahead tokens remain available for when the non-raw
533 functions above are called. */
536 c_parser_peek_nth_token_raw (c_parser
*parser
, unsigned int n
)
538 /* N is 1-based, not zero-based. */
541 if (parser
->tokens_avail
>= n
)
542 return &parser
->tokens
[n
- 1];
543 unsigned int raw_len
= vec_safe_length (parser
->raw_tokens
);
544 unsigned int raw_avail
545 = parser
->tokens_avail
+ raw_len
- parser
->raw_tokens_used
;
546 gcc_assert (raw_avail
>= n
- 1);
548 return &(*parser
->raw_tokens
)[parser
->raw_tokens_used
549 + n
- 1 - parser
->tokens_avail
];
550 vec_safe_reserve (parser
->raw_tokens
, 1);
551 parser
->raw_tokens
->quick_grow (raw_len
+ 1);
552 c_lex_one_token (parser
, &(*parser
->raw_tokens
)[raw_len
], true);
553 return &(*parser
->raw_tokens
)[raw_len
];
557 c_keyword_starts_typename (enum rid keyword
)
592 if (keyword
>= RID_FIRST_INT_N
593 && keyword
< RID_FIRST_INT_N
+ NUM_INT_N_ENTS
594 && int_n_enabled_p
[keyword
- RID_FIRST_INT_N
])
600 /* Return true if TOKEN can start a type name,
603 c_token_starts_typename (c_token
*token
)
608 switch (token
->id_kind
)
617 gcc_assert (c_dialect_objc ());
623 return c_keyword_starts_typename (token
->keyword
);
625 if (c_dialect_objc ())
633 /* Return true if the next token from PARSER can start a type name,
634 false otherwise. LA specifies how to do lookahead in order to
635 detect unknown type names. If unsure, pick CLA_PREFER_ID. */
638 c_parser_next_tokens_start_typename (c_parser
*parser
, enum c_lookahead_kind la
)
640 c_token
*token
= c_parser_peek_token (parser
);
641 if (c_token_starts_typename (token
))
644 /* Try a bit harder to detect an unknown typename. */
645 if (la
!= cla_prefer_id
646 && token
->type
== CPP_NAME
647 && token
->id_kind
== C_ID_ID
649 /* Do not try too hard when we could have "object in array". */
650 && !parser
->objc_could_be_foreach_context
652 && (la
== cla_prefer_type
653 || c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
654 || c_parser_peek_2nd_token (parser
)->type
== CPP_MULT
)
656 /* Only unknown identifiers. */
657 && !lookup_name (token
->value
))
663 /* Return true if TOKEN is a type qualifier, false otherwise. */
665 c_token_is_qualifier (c_token
*token
)
670 switch (token
->id_kind
)
678 switch (token
->keyword
)
696 /* Return true if the next token from PARSER is a type qualifier,
699 c_parser_next_token_is_qualifier (c_parser
*parser
)
701 c_token
*token
= c_parser_peek_token (parser
);
702 return c_token_is_qualifier (token
);
705 /* Return true if TOKEN can start declaration specifiers (not
706 including standard attributes), false otherwise. */
708 c_token_starts_declspecs (c_token
*token
)
713 switch (token
->id_kind
)
722 gcc_assert (c_dialect_objc ());
728 switch (token
->keyword
)
769 if (token
->keyword
>= RID_FIRST_INT_N
770 && token
->keyword
< RID_FIRST_INT_N
+ NUM_INT_N_ENTS
771 && int_n_enabled_p
[token
->keyword
- RID_FIRST_INT_N
])
776 if (c_dialect_objc ())
785 /* Return true if TOKEN can start declaration specifiers (not
786 including standard attributes) or a static assertion, false
789 c_token_starts_declaration (c_token
*token
)
791 if (c_token_starts_declspecs (token
)
792 || token
->keyword
== RID_STATIC_ASSERT
)
798 /* Return true if the next token from PARSER can start declaration
799 specifiers (not including standard attributes), false
802 c_parser_next_token_starts_declspecs (c_parser
*parser
)
804 c_token
*token
= c_parser_peek_token (parser
);
806 /* In Objective-C, a classname normally starts a declspecs unless it
807 is immediately followed by a dot. In that case, it is the
808 Objective-C 2.0 "dot-syntax" for class objects, ie, calls the
809 setter/getter on the class. c_token_starts_declspecs() can't
810 differentiate between the two cases because it only checks the
811 current token, so we have a special check here. */
812 if (c_dialect_objc ()
813 && token
->type
== CPP_NAME
814 && token
->id_kind
== C_ID_CLASSNAME
815 && c_parser_peek_2nd_token (parser
)->type
== CPP_DOT
)
818 return c_token_starts_declspecs (token
);
821 /* Return true if the next tokens from PARSER can start declaration
822 specifiers (not including standard attributes) or a static
823 assertion, false otherwise. */
825 c_parser_next_tokens_start_declaration (c_parser
*parser
)
827 c_token
*token
= c_parser_peek_token (parser
);
830 if (c_dialect_objc ()
831 && token
->type
== CPP_NAME
832 && token
->id_kind
== C_ID_CLASSNAME
833 && c_parser_peek_2nd_token (parser
)->type
== CPP_DOT
)
836 /* Labels do not start declarations. */
837 if (token
->type
== CPP_NAME
838 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
841 if (c_token_starts_declaration (token
))
844 if (c_parser_next_tokens_start_typename (parser
, cla_nonabstract_decl
))
850 /* Consume the next token from PARSER. */
853 c_parser_consume_token (c_parser
*parser
)
855 gcc_assert (parser
->tokens_avail
>= 1);
856 gcc_assert (parser
->tokens
[0].type
!= CPP_EOF
);
857 gcc_assert (!parser
->in_pragma
|| parser
->tokens
[0].type
!= CPP_PRAGMA_EOL
);
858 gcc_assert (parser
->error
|| parser
->tokens
[0].type
!= CPP_PRAGMA
);
859 parser
->last_token_location
= parser
->tokens
[0].location
;
860 if (parser
->tokens
!= &parser
->tokens_buf
[0])
862 else if (parser
->tokens_avail
>= 2)
864 parser
->tokens
[0] = parser
->tokens
[1];
865 if (parser
->tokens_avail
>= 3)
867 parser
->tokens
[1] = parser
->tokens
[2];
868 if (parser
->tokens_avail
>= 4)
869 parser
->tokens
[2] = parser
->tokens
[3];
872 parser
->tokens_avail
--;
873 parser
->seen_string_literal
= false;
876 /* Expect the current token to be a #pragma. Consume it and remember
877 that we've begun parsing a pragma. */
880 c_parser_consume_pragma (c_parser
*parser
)
882 gcc_assert (!parser
->in_pragma
);
883 gcc_assert (parser
->tokens_avail
>= 1);
884 gcc_assert (parser
->tokens
[0].type
== CPP_PRAGMA
);
885 if (parser
->tokens
!= &parser
->tokens_buf
[0])
887 else if (parser
->tokens_avail
>= 2)
889 parser
->tokens
[0] = parser
->tokens
[1];
890 if (parser
->tokens_avail
>= 3)
891 parser
->tokens
[1] = parser
->tokens
[2];
893 parser
->tokens_avail
--;
894 parser
->in_pragma
= true;
897 /* Update the global input_location from TOKEN. */
899 c_parser_set_source_position_from_token (c_token
*token
)
901 if (token
->type
!= CPP_EOF
)
903 input_location
= token
->location
;
907 /* Helper function for c_parser_error.
908 Having peeked a token of kind TOK1_KIND that might signify
909 a conflict marker, peek successor tokens to determine
910 if we actually do have a conflict marker.
911 Specifically, we consider a run of 7 '<', '=' or '>' characters
912 at the start of a line as a conflict marker.
913 These come through the lexer as three pairs and a single,
914 e.g. three CPP_LSHIFT ("<<") and a CPP_LESS ('<').
915 If it returns true, *OUT_LOC is written to with the location/range
919 c_parser_peek_conflict_marker (c_parser
*parser
, enum cpp_ttype tok1_kind
,
922 c_token
*token2
= c_parser_peek_2nd_token (parser
);
923 if (token2
->type
!= tok1_kind
)
925 c_token
*token3
= c_parser_peek_nth_token (parser
, 3);
926 if (token3
->type
!= tok1_kind
)
928 c_token
*token4
= c_parser_peek_nth_token (parser
, 4);
929 if (token4
->type
!= conflict_marker_get_final_tok_kind (tok1_kind
))
932 /* It must be at the start of the line. */
933 location_t start_loc
= c_parser_peek_token (parser
)->location
;
934 if (LOCATION_COLUMN (start_loc
) != 1)
937 /* We have a conflict marker. Construct a location of the form:
940 with start == caret, finishing at the end of the marker. */
941 location_t finish_loc
= get_finish (token4
->location
);
942 *out_loc
= make_location (start_loc
, start_loc
, finish_loc
);
947 /* Issue a diagnostic of the form
948 FILE:LINE: MESSAGE before TOKEN
949 where TOKEN is the next token in the input stream of PARSER.
950 MESSAGE (specified by the caller) is usually of the form "expected
953 Use RICHLOC as the location of the diagnostic.
955 Do not issue a diagnostic if still recovering from an error.
957 Return true iff an error was actually emitted.
959 ??? This is taken from the C++ parser, but building up messages in
960 this way is not i18n-friendly and some other approach should be
964 c_parser_error_richloc (c_parser
*parser
, const char *gmsgid
,
965 rich_location
*richloc
)
967 c_token
*token
= c_parser_peek_token (parser
);
970 parser
->error
= true;
974 /* If this is actually a conflict marker, report it as such. */
975 if (token
->type
== CPP_LSHIFT
976 || token
->type
== CPP_RSHIFT
977 || token
->type
== CPP_EQ_EQ
)
980 if (c_parser_peek_conflict_marker (parser
, token
->type
, &loc
))
982 error_at (loc
, "version control conflict marker in file");
987 /* If we were parsing a string-literal and there is an unknown name
988 token right after, then check to see if that could also have been
989 a literal string by checking the name against a list of known
990 standard string literal constants defined in header files. If
991 there is one, then add that as an hint to the error message. */
992 auto_diagnostic_group d
;
994 if (parser
->seen_string_literal
&& token
->type
== CPP_NAME
)
996 tree name
= token
->value
;
997 const char *token_name
= IDENTIFIER_POINTER (name
);
998 const char *header_hint
999 = get_c_stdlib_header_for_string_macro_name (token_name
);
1000 if (header_hint
!= NULL
)
1001 h
= name_hint (NULL
, new suggest_missing_header (token
->location
,
1006 c_parse_error (gmsgid
,
1007 /* Because c_parse_error does not understand
1008 CPP_KEYWORD, keywords are treated like
1010 (token
->type
== CPP_KEYWORD
? CPP_NAME
: token
->type
),
1011 /* ??? The C parser does not save the cpp flags of a
1012 token, we need to pass 0 here and we will not get
1013 the source spelling of some tokens but rather the
1014 canonical spelling. */
1015 token
->value
, /*flags=*/0, richloc
);
1019 /* As c_parser_error_richloc, but issue the message at the
1020 location of PARSER's next token, or at input_location
1021 if the next token is EOF. */
1024 c_parser_error (c_parser
*parser
, const char *gmsgid
)
1026 c_token
*token
= c_parser_peek_token (parser
);
1027 c_parser_set_source_position_from_token (token
);
1028 rich_location
richloc (line_table
, input_location
);
1029 return c_parser_error_richloc (parser
, gmsgid
, &richloc
);
1032 /* Some tokens naturally come in pairs e.g.'(' and ')'.
1033 This class is for tracking such a matching pair of symbols.
1034 In particular, it tracks the location of the first token,
1035 so that if the second token is missing, we can highlight the
1036 location of the first token when notifying the user about the
1039 template <typename traits_t
>
1043 /* token_pair's ctor. */
1044 token_pair () : m_open_loc (UNKNOWN_LOCATION
) {}
1046 /* If the next token is the opening symbol for this pair, consume it and
1048 Otherwise, issue an error and return false.
1049 In either case, record the location of the opening token. */
1051 bool require_open (c_parser
*parser
)
1053 c_token
*token
= c_parser_peek_token (parser
);
1055 m_open_loc
= token
->location
;
1057 return c_parser_require (parser
, traits_t::open_token_type
,
1058 traits_t::open_gmsgid
);
1061 /* Consume the next token from PARSER, recording its location as
1062 that of the opening token within the pair. */
1064 void consume_open (c_parser
*parser
)
1066 c_token
*token
= c_parser_peek_token (parser
);
1067 gcc_assert (token
->type
== traits_t::open_token_type
);
1068 m_open_loc
= token
->location
;
1069 c_parser_consume_token (parser
);
1072 /* If the next token is the closing symbol for this pair, consume it
1074 Otherwise, issue an error, highlighting the location of the
1075 corresponding opening token, and return false. */
1077 bool require_close (c_parser
*parser
) const
1079 return c_parser_require (parser
, traits_t::close_token_type
,
1080 traits_t::close_gmsgid
, m_open_loc
);
1083 /* Like token_pair::require_close, except that tokens will be skipped
1084 until the desired token is found. An error message is still produced
1085 if the next token is not as expected. */
1087 void skip_until_found_close (c_parser
*parser
) const
1089 c_parser_skip_until_found (parser
, traits_t::close_token_type
,
1090 traits_t::close_gmsgid
, m_open_loc
);
1094 location_t m_open_loc
;
1097 /* Traits for token_pair<T> for tracking matching pairs of parentheses. */
1099 struct matching_paren_traits
1101 static const enum cpp_ttype open_token_type
= CPP_OPEN_PAREN
;
1102 static const char * const open_gmsgid
;
1103 static const enum cpp_ttype close_token_type
= CPP_CLOSE_PAREN
;
1104 static const char * const close_gmsgid
;
1107 const char * const matching_paren_traits::open_gmsgid
= "expected %<(%>";
1108 const char * const matching_paren_traits::close_gmsgid
= "expected %<)%>";
1110 /* "matching_parens" is a token_pair<T> class for tracking matching
1111 pairs of parentheses. */
1113 typedef token_pair
<matching_paren_traits
> matching_parens
;
1115 /* Traits for token_pair<T> for tracking matching pairs of braces. */
1117 struct matching_brace_traits
1119 static const enum cpp_ttype open_token_type
= CPP_OPEN_BRACE
;
1120 static const char * const open_gmsgid
;
1121 static const enum cpp_ttype close_token_type
= CPP_CLOSE_BRACE
;
1122 static const char * const close_gmsgid
;
1125 const char * const matching_brace_traits::open_gmsgid
= "expected %<{%>";
1126 const char * const matching_brace_traits::close_gmsgid
= "expected %<}%>";
1128 /* "matching_braces" is a token_pair<T> class for tracking matching
1131 typedef token_pair
<matching_brace_traits
> matching_braces
;
1133 /* Get a description of the matching symbol to TYPE e.g. "(" for
1137 get_matching_symbol (enum cpp_ttype type
)
1143 case CPP_CLOSE_PAREN
:
1145 case CPP_CLOSE_BRACE
:
1150 /* If the next token is of the indicated TYPE, consume it. Otherwise,
1151 issue the error MSGID. If MSGID is NULL then a message has already
1152 been produced and no message will be produced this time. Returns
1153 true if found, false otherwise.
1155 If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1156 within any error as the location of an "opening" token matching
1157 the close token TYPE (e.g. the location of the '(' when TYPE is
1160 If TYPE_IS_UNIQUE is true (the default) then msgid describes exactly
1161 one type (e.g. "expected %<)%>") and thus it may be reasonable to
1162 attempt to generate a fix-it hint for the problem.
1163 Otherwise msgid describes multiple token types (e.g.
1164 "expected %<;%>, %<,%> or %<)%>"), and thus we shouldn't attempt to
1165 generate a fix-it hint. */
1168 c_parser_require (c_parser
*parser
,
1169 enum cpp_ttype type
,
1171 location_t matching_location
,
1172 bool type_is_unique
)
1174 if (c_parser_next_token_is (parser
, type
))
1176 c_parser_consume_token (parser
);
1181 location_t next_token_loc
= c_parser_peek_token (parser
)->location
;
1182 gcc_rich_location
richloc (next_token_loc
);
1184 /* Potentially supply a fix-it hint, suggesting to add the
1185 missing token immediately after the *previous* token.
1186 This may move the primary location within richloc. */
1187 if (!parser
->error
&& type_is_unique
)
1188 maybe_suggest_missing_token_insertion (&richloc
, type
,
1189 parser
->last_token_location
);
1191 /* If matching_location != UNKNOWN_LOCATION, highlight it.
1192 Attempt to consolidate diagnostics by printing it as a
1193 secondary range within the main diagnostic. */
1194 bool added_matching_location
= false;
1195 if (matching_location
!= UNKNOWN_LOCATION
)
1196 added_matching_location
1197 = richloc
.add_location_if_nearby (matching_location
);
1199 if (c_parser_error_richloc (parser
, msgid
, &richloc
))
1200 /* If we weren't able to consolidate matching_location, then
1201 print it as a secondary diagnostic. */
1202 if (matching_location
!= UNKNOWN_LOCATION
&& !added_matching_location
)
1203 inform (matching_location
, "to match this %qs",
1204 get_matching_symbol (type
));
1210 /* If the next token is the indicated keyword, consume it. Otherwise,
1211 issue the error MSGID. Returns true if found, false otherwise. */
1214 c_parser_require_keyword (c_parser
*parser
,
1218 if (c_parser_next_token_is_keyword (parser
, keyword
))
1220 c_parser_consume_token (parser
);
1225 c_parser_error (parser
, msgid
);
1230 /* Like c_parser_require, except that tokens will be skipped until the
1231 desired token is found. An error message is still produced if the
1232 next token is not as expected. If MSGID is NULL then a message has
1233 already been produced and no message will be produced this
1236 If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1237 within any error as the location of an "opening" token matching
1238 the close token TYPE (e.g. the location of the '(' when TYPE is
1239 CPP_CLOSE_PAREN). */
1242 c_parser_skip_until_found (c_parser
*parser
,
1243 enum cpp_ttype type
,
1245 location_t matching_location
)
1247 unsigned nesting_depth
= 0;
1249 if (c_parser_require (parser
, type
, msgid
, matching_location
))
1252 /* Skip tokens until the desired token is found. */
1255 /* Peek at the next token. */
1256 c_token
*token
= c_parser_peek_token (parser
);
1257 /* If we've reached the token we want, consume it and stop. */
1258 if (token
->type
== type
&& !nesting_depth
)
1260 c_parser_consume_token (parser
);
1264 /* If we've run out of tokens, stop. */
1265 if (token
->type
== CPP_EOF
)
1267 if (token
->type
== CPP_PRAGMA_EOL
&& parser
->in_pragma
)
1269 if (token
->type
== CPP_OPEN_BRACE
1270 || token
->type
== CPP_OPEN_PAREN
1271 || token
->type
== CPP_OPEN_SQUARE
)
1273 else if (token
->type
== CPP_CLOSE_BRACE
1274 || token
->type
== CPP_CLOSE_PAREN
1275 || token
->type
== CPP_CLOSE_SQUARE
)
1277 if (nesting_depth
-- == 0)
1280 /* Consume this token. */
1281 c_parser_consume_token (parser
);
1283 parser
->error
= false;
1286 /* Skip tokens until the end of a parameter is found, but do not
1287 consume the comma, semicolon or closing delimiter. */
1290 c_parser_skip_to_end_of_parameter (c_parser
*parser
)
1292 unsigned nesting_depth
= 0;
1296 c_token
*token
= c_parser_peek_token (parser
);
1297 if ((token
->type
== CPP_COMMA
|| token
->type
== CPP_SEMICOLON
)
1300 /* If we've run out of tokens, stop. */
1301 if (token
->type
== CPP_EOF
)
1303 if (token
->type
== CPP_PRAGMA_EOL
&& parser
->in_pragma
)
1305 if (token
->type
== CPP_OPEN_BRACE
1306 || token
->type
== CPP_OPEN_PAREN
1307 || token
->type
== CPP_OPEN_SQUARE
)
1309 else if (token
->type
== CPP_CLOSE_BRACE
1310 || token
->type
== CPP_CLOSE_PAREN
1311 || token
->type
== CPP_CLOSE_SQUARE
)
1313 if (nesting_depth
-- == 0)
1316 /* Consume this token. */
1317 c_parser_consume_token (parser
);
1319 parser
->error
= false;
1322 /* Expect to be at the end of the pragma directive and consume an
1323 end of line marker. */
1326 c_parser_skip_to_pragma_eol (c_parser
*parser
, bool error_if_not_eol
= true)
1328 gcc_assert (parser
->in_pragma
);
1329 parser
->in_pragma
= false;
1331 if (error_if_not_eol
&& c_parser_peek_token (parser
)->type
!= CPP_PRAGMA_EOL
)
1332 c_parser_error (parser
, "expected end of line");
1334 cpp_ttype token_type
;
1337 c_token
*token
= c_parser_peek_token (parser
);
1338 token_type
= token
->type
;
1339 if (token_type
== CPP_EOF
)
1341 c_parser_consume_token (parser
);
1343 while (token_type
!= CPP_PRAGMA_EOL
);
1345 parser
->error
= false;
1348 /* Skip tokens until we have consumed an entire block, or until we
1349 have consumed a non-nested ';'. */
1352 c_parser_skip_to_end_of_block_or_statement (c_parser
*parser
)
1354 unsigned nesting_depth
= 0;
1355 bool save_error
= parser
->error
;
1361 /* Peek at the next token. */
1362 token
= c_parser_peek_token (parser
);
1364 switch (token
->type
)
1369 case CPP_PRAGMA_EOL
:
1370 if (parser
->in_pragma
)
1375 /* If the next token is a ';', we have reached the
1376 end of the statement. */
1379 /* Consume the ';'. */
1380 c_parser_consume_token (parser
);
1385 case CPP_CLOSE_BRACE
:
1386 /* If the next token is a non-nested '}', then we have
1387 reached the end of the current block. */
1388 if (nesting_depth
== 0 || --nesting_depth
== 0)
1390 c_parser_consume_token (parser
);
1395 case CPP_OPEN_BRACE
:
1396 /* If it the next token is a '{', then we are entering a new
1397 block. Consume the entire block. */
1402 /* If we see a pragma, consume the whole thing at once. We
1403 have some safeguards against consuming pragmas willy-nilly.
1404 Normally, we'd expect to be here with parser->error set,
1405 which disables these safeguards. But it's possible to get
1406 here for secondary error recovery, after parser->error has
1408 c_parser_consume_pragma (parser
);
1409 c_parser_skip_to_pragma_eol (parser
);
1410 parser
->error
= save_error
;
1417 c_parser_consume_token (parser
);
1421 parser
->error
= false;
1424 /* CPP's options (initialized by c-opts.cc). */
1425 extern cpp_options
*cpp_opts
;
1427 /* Save the warning flags which are controlled by __extension__. */
1430 disable_extension_diagnostics (void)
1433 | (warn_pointer_arith
<< 1)
1434 | (warn_traditional
<< 2)
1436 | (warn_long_long
<< 4)
1437 | (warn_cxx_compat
<< 5)
1438 | (warn_overlength_strings
<< 6)
1439 /* warn_c90_c99_compat has three states: -1/0/1, so we must
1440 play tricks to properly restore it. */
1441 | ((warn_c90_c99_compat
== 1) << 7)
1442 | ((warn_c90_c99_compat
== -1) << 8)
1443 /* Similarly for warn_c99_c11_compat. */
1444 | ((warn_c99_c11_compat
== 1) << 9)
1445 | ((warn_c99_c11_compat
== -1) << 10)
1446 /* Similarly for warn_c11_c2x_compat. */
1447 | ((warn_c11_c2x_compat
== 1) << 11)
1448 | ((warn_c11_c2x_compat
== -1) << 12)
1450 cpp_opts
->cpp_pedantic
= pedantic
= 0;
1451 warn_pointer_arith
= 0;
1452 cpp_opts
->cpp_warn_traditional
= warn_traditional
= 0;
1454 cpp_opts
->cpp_warn_long_long
= warn_long_long
= 0;
1455 warn_cxx_compat
= 0;
1456 warn_overlength_strings
= 0;
1457 warn_c90_c99_compat
= 0;
1458 warn_c99_c11_compat
= 0;
1459 warn_c11_c2x_compat
= 0;
1463 /* Restore the warning flags which are controlled by __extension__.
1464 FLAGS is the return value from disable_extension_diagnostics. */
1467 restore_extension_diagnostics (int flags
)
1469 cpp_opts
->cpp_pedantic
= pedantic
= flags
& 1;
1470 warn_pointer_arith
= (flags
>> 1) & 1;
1471 cpp_opts
->cpp_warn_traditional
= warn_traditional
= (flags
>> 2) & 1;
1472 flag_iso
= (flags
>> 3) & 1;
1473 cpp_opts
->cpp_warn_long_long
= warn_long_long
= (flags
>> 4) & 1;
1474 warn_cxx_compat
= (flags
>> 5) & 1;
1475 warn_overlength_strings
= (flags
>> 6) & 1;
1476 /* See above for why is this needed. */
1477 warn_c90_c99_compat
= (flags
>> 7) & 1 ? 1 : ((flags
>> 8) & 1 ? -1 : 0);
1478 warn_c99_c11_compat
= (flags
>> 9) & 1 ? 1 : ((flags
>> 10) & 1 ? -1 : 0);
1479 warn_c11_c2x_compat
= (flags
>> 11) & 1 ? 1 : ((flags
>> 12) & 1 ? -1 : 0);
1482 /* Helper data structure for parsing #pragma acc routine. */
1483 struct oacc_routine_data
{
1484 bool error_seen
; /* Set if error has been reported. */
1485 bool fndecl_seen
; /* Set if one fn decl/definition has been seen already. */
1490 /* Used for parsing objc foreach statements. */
1491 static tree objc_foreach_break_label
, objc_foreach_continue_label
;
1493 static bool c_parser_nth_token_starts_std_attributes (c_parser
*,
1495 static tree
c_parser_std_attribute_specifier_sequence (c_parser
*);
1496 static void c_parser_external_declaration (c_parser
*);
1497 static void c_parser_asm_definition (c_parser
*);
1498 static void c_parser_declaration_or_fndef (c_parser
*, bool, bool, bool,
1499 bool, bool, tree
* = NULL
,
1500 vec
<c_token
> * = NULL
,
1501 bool have_attrs
= false,
1503 struct oacc_routine_data
* = NULL
,
1505 static void c_parser_static_assert_declaration_no_semi (c_parser
*);
1506 static void c_parser_static_assert_declaration (c_parser
*);
1507 static struct c_typespec
c_parser_enum_specifier (c_parser
*);
1508 static struct c_typespec
c_parser_struct_or_union_specifier (c_parser
*);
1509 static tree
c_parser_struct_declaration (c_parser
*);
1510 static struct c_typespec
c_parser_typeof_specifier (c_parser
*);
1511 static tree
c_parser_alignas_specifier (c_parser
*);
1512 static struct c_declarator
*c_parser_direct_declarator (c_parser
*, bool,
1514 static struct c_declarator
*c_parser_direct_declarator_inner (c_parser
*,
1516 struct c_declarator
*);
1517 static struct c_arg_info
*c_parser_parms_declarator (c_parser
*, bool, tree
,
1519 static struct c_arg_info
*c_parser_parms_list_declarator (c_parser
*, tree
,
1521 static struct c_parm
*c_parser_parameter_declaration (c_parser
*, tree
, bool);
1522 static tree
c_parser_simple_asm_expr (c_parser
*);
1523 static tree
c_parser_gnu_attributes (c_parser
*);
1524 static struct c_expr
c_parser_initializer (c_parser
*);
1525 static struct c_expr
c_parser_braced_init (c_parser
*, tree
, bool,
1527 static void c_parser_initelt (c_parser
*, struct obstack
*);
1528 static void c_parser_initval (c_parser
*, struct c_expr
*,
1530 static tree
c_parser_compound_statement (c_parser
*, location_t
* = NULL
);
1531 static location_t
c_parser_compound_statement_nostart (c_parser
*);
1532 static void c_parser_label (c_parser
*, tree
);
1533 static void c_parser_statement (c_parser
*, bool *, location_t
* = NULL
);
1534 static void c_parser_statement_after_labels (c_parser
*, bool *,
1535 vec
<tree
> * = NULL
);
1536 static tree
c_parser_c99_block_statement (c_parser
*, bool *,
1537 location_t
* = NULL
);
1538 static void c_parser_if_statement (c_parser
*, bool *, vec
<tree
> *);
1539 static void c_parser_switch_statement (c_parser
*, bool *);
1540 static void c_parser_while_statement (c_parser
*, bool, unsigned short, bool *);
1541 static void c_parser_do_statement (c_parser
*, bool, unsigned short);
1542 static void c_parser_for_statement (c_parser
*, bool, unsigned short, bool *);
1543 static tree
c_parser_asm_statement (c_parser
*);
1544 static tree
c_parser_asm_operands (c_parser
*);
1545 static tree
c_parser_asm_goto_operands (c_parser
*);
1546 static tree
c_parser_asm_clobbers (c_parser
*);
1547 static struct c_expr
c_parser_expr_no_commas (c_parser
*, struct c_expr
*,
1549 static struct c_expr
c_parser_conditional_expression (c_parser
*,
1550 struct c_expr
*, tree
);
1551 static struct c_expr
c_parser_binary_expression (c_parser
*, struct c_expr
*,
1553 static struct c_expr
c_parser_cast_expression (c_parser
*, struct c_expr
*);
1554 static struct c_expr
c_parser_unary_expression (c_parser
*);
1555 static struct c_expr
c_parser_sizeof_expression (c_parser
*);
1556 static struct c_expr
c_parser_alignof_expression (c_parser
*);
1557 static struct c_expr
c_parser_postfix_expression (c_parser
*);
1558 static struct c_expr
c_parser_postfix_expression_after_paren_type (c_parser
*,
1559 struct c_type_name
*,
1561 static struct c_expr
c_parser_postfix_expression_after_primary (c_parser
*,
1564 static tree
c_parser_transaction (c_parser
*, enum rid
);
1565 static struct c_expr
c_parser_transaction_expression (c_parser
*, enum rid
);
1566 static tree
c_parser_transaction_cancel (c_parser
*);
1567 static struct c_expr
c_parser_expression (c_parser
*);
1568 static struct c_expr
c_parser_expression_conv (c_parser
*);
1569 static vec
<tree
, va_gc
> *c_parser_expr_list (c_parser
*, bool, bool,
1570 vec
<tree
, va_gc
> **, location_t
*,
1571 tree
*, vec
<location_t
> *,
1572 unsigned int * = NULL
);
1573 static struct c_expr
c_parser_has_attribute_expression (c_parser
*);
1575 static void c_parser_oacc_declare (c_parser
*);
1576 static void c_parser_oacc_enter_exit_data (c_parser
*, bool);
1577 static void c_parser_oacc_update (c_parser
*);
1578 static void c_parser_omp_construct (c_parser
*, bool *);
1579 static void c_parser_omp_threadprivate (c_parser
*);
1580 static void c_parser_omp_barrier (c_parser
*);
1581 static void c_parser_omp_depobj (c_parser
*);
1582 static void c_parser_omp_flush (c_parser
*);
1583 static tree
c_parser_omp_for_loop (location_t
, c_parser
*, enum tree_code
,
1584 tree
, tree
*, bool *);
1585 static void c_parser_omp_taskwait (c_parser
*);
1586 static void c_parser_omp_taskyield (c_parser
*);
1587 static void c_parser_omp_cancel (c_parser
*);
1588 static void c_parser_omp_nothing (c_parser
*);
1590 enum pragma_context
{ pragma_external
, pragma_struct
, pragma_param
,
1591 pragma_stmt
, pragma_compound
};
1592 static bool c_parser_pragma (c_parser
*, enum pragma_context
, bool *);
1593 static bool c_parser_omp_cancellation_point (c_parser
*, enum pragma_context
);
1594 static bool c_parser_omp_target (c_parser
*, enum pragma_context
, bool *);
1595 static void c_parser_omp_end_declare_target (c_parser
*);
1596 static bool c_parser_omp_declare (c_parser
*, enum pragma_context
);
1597 static void c_parser_omp_requires (c_parser
*);
1598 static bool c_parser_omp_error (c_parser
*, enum pragma_context
);
1599 static bool c_parser_omp_ordered (c_parser
*, enum pragma_context
, bool *);
1600 static void c_parser_oacc_routine (c_parser
*, enum pragma_context
);
1602 /* These Objective-C parser functions are only ever called when
1603 compiling Objective-C. */
1604 static void c_parser_objc_class_definition (c_parser
*, tree
);
1605 static void c_parser_objc_class_instance_variables (c_parser
*);
1606 static void c_parser_objc_class_declaration (c_parser
*);
1607 static void c_parser_objc_alias_declaration (c_parser
*);
1608 static void c_parser_objc_protocol_definition (c_parser
*, tree
);
1609 static bool c_parser_objc_method_type (c_parser
*);
1610 static void c_parser_objc_method_definition (c_parser
*);
1611 static void c_parser_objc_methodprotolist (c_parser
*);
1612 static void c_parser_objc_methodproto (c_parser
*);
1613 static tree
c_parser_objc_method_decl (c_parser
*, bool, tree
*, tree
*);
1614 static tree
c_parser_objc_type_name (c_parser
*);
1615 static tree
c_parser_objc_protocol_refs (c_parser
*);
1616 static void c_parser_objc_try_catch_finally_statement (c_parser
*);
1617 static void c_parser_objc_synchronized_statement (c_parser
*);
1618 static tree
c_parser_objc_selector (c_parser
*);
1619 static tree
c_parser_objc_selector_arg (c_parser
*);
1620 static tree
c_parser_objc_receiver (c_parser
*);
1621 static tree
c_parser_objc_message_args (c_parser
*);
1622 static tree
c_parser_objc_keywordexpr (c_parser
*);
1623 static void c_parser_objc_at_property_declaration (c_parser
*);
1624 static void c_parser_objc_at_synthesize_declaration (c_parser
*);
1625 static void c_parser_objc_at_dynamic_declaration (c_parser
*);
1626 static bool c_parser_objc_diagnose_bad_element_prefix
1627 (c_parser
*, struct c_declspecs
*);
1628 static location_t
c_parser_parse_rtl_body (c_parser
*, char *);
1630 /* Parse a translation unit (C90 6.7, C99 6.9, C11 6.9).
1633 external-declarations
1635 external-declarations:
1636 external-declaration
1637 external-declarations external-declaration
1646 c_parser_translation_unit (c_parser
*parser
)
1648 if (c_parser_next_token_is (parser
, CPP_EOF
))
1650 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
1651 "ISO C forbids an empty translation unit");
1655 void *obstack_position
= obstack_alloc (&parser_obstack
, 0);
1656 mark_valid_location_for_stdc_pragma (false);
1660 c_parser_external_declaration (parser
);
1661 obstack_free (&parser_obstack
, obstack_position
);
1663 while (c_parser_next_token_is_not (parser
, CPP_EOF
));
1668 FOR_EACH_VEC_ELT (incomplete_record_decls
, i
, decl
)
1669 if (DECL_SIZE (decl
) == NULL_TREE
&& TREE_TYPE (decl
) != error_mark_node
)
1670 error ("storage size of %q+D isn%'t known", decl
);
1672 if (current_omp_declare_target_attribute
)
1675 error ("%<#pragma omp declare target%> without corresponding "
1676 "%<#pragma omp end declare target%>");
1677 current_omp_declare_target_attribute
= 0;
1681 /* Parse an external declaration (C90 6.7, C99 6.9, C11 6.9).
1683 external-declaration:
1689 external-declaration:
1692 __extension__ external-declaration
1696 external-declaration:
1697 objc-class-definition
1698 objc-class-declaration
1699 objc-alias-declaration
1700 objc-protocol-definition
1701 objc-method-definition
1706 c_parser_external_declaration (c_parser
*parser
)
1709 switch (c_parser_peek_token (parser
)->type
)
1712 switch (c_parser_peek_token (parser
)->keyword
)
1715 ext
= disable_extension_diagnostics ();
1716 c_parser_consume_token (parser
);
1717 c_parser_external_declaration (parser
);
1718 restore_extension_diagnostics (ext
);
1721 c_parser_asm_definition (parser
);
1723 case RID_AT_INTERFACE
:
1724 case RID_AT_IMPLEMENTATION
:
1725 gcc_assert (c_dialect_objc ());
1726 c_parser_objc_class_definition (parser
, NULL_TREE
);
1729 gcc_assert (c_dialect_objc ());
1730 c_parser_objc_class_declaration (parser
);
1733 gcc_assert (c_dialect_objc ());
1734 c_parser_objc_alias_declaration (parser
);
1736 case RID_AT_PROTOCOL
:
1737 gcc_assert (c_dialect_objc ());
1738 c_parser_objc_protocol_definition (parser
, NULL_TREE
);
1740 case RID_AT_PROPERTY
:
1741 gcc_assert (c_dialect_objc ());
1742 c_parser_objc_at_property_declaration (parser
);
1744 case RID_AT_SYNTHESIZE
:
1745 gcc_assert (c_dialect_objc ());
1746 c_parser_objc_at_synthesize_declaration (parser
);
1748 case RID_AT_DYNAMIC
:
1749 gcc_assert (c_dialect_objc ());
1750 c_parser_objc_at_dynamic_declaration (parser
);
1753 gcc_assert (c_dialect_objc ());
1754 c_parser_consume_token (parser
);
1755 objc_finish_implementation ();
1762 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
1763 "ISO C does not allow extra %<;%> outside of a function");
1764 c_parser_consume_token (parser
);
1767 mark_valid_location_for_stdc_pragma (true);
1768 c_parser_pragma (parser
, pragma_external
, NULL
);
1769 mark_valid_location_for_stdc_pragma (false);
1773 if (c_dialect_objc ())
1775 c_parser_objc_method_definition (parser
);
1778 /* Else fall through, and yield a syntax error trying to parse
1779 as a declaration or function definition. */
1783 /* A declaration or a function definition (or, in Objective-C,
1784 an @interface or @protocol with prefix attributes). We can
1785 only tell which after parsing the declaration specifiers, if
1786 any, and the first declarator. */
1787 c_parser_declaration_or_fndef (parser
, true, true, true, false, true);
1792 static void c_finish_omp_declare_simd (c_parser
*, tree
, tree
, vec
<c_token
> *);
1793 static void c_finish_oacc_routine (struct oacc_routine_data
*, tree
, bool);
1795 /* Build and add a DEBUG_BEGIN_STMT statement with location LOC. */
1798 add_debug_begin_stmt (location_t loc
)
1800 /* Don't add DEBUG_BEGIN_STMTs outside of functions, see PR84721. */
1801 if (!MAY_HAVE_DEBUG_MARKER_STMTS
|| !building_stmt_list_p ())
1804 tree stmt
= build0 (DEBUG_BEGIN_STMT
, void_type_node
);
1805 SET_EXPR_LOCATION (stmt
, loc
);
1809 /* Parse a declaration or function definition (C90 6.5, 6.7.1, C99
1810 6.7, 6.9.1, C11 6.7, 6.9.1). If FNDEF_OK is true, a function definition
1811 is accepted; otherwise (old-style parameter declarations) only other
1812 declarations are accepted. If STATIC_ASSERT_OK is true, a static
1813 assertion is accepted; otherwise (old-style parameter declarations)
1814 it is not. If NESTED is true, we are inside a function or parsing
1815 old-style parameter declarations; any functions encountered are
1816 nested functions and declaration specifiers are required; otherwise
1817 we are at top level and functions are normal functions and
1818 declaration specifiers may be optional. If EMPTY_OK is true, empty
1819 declarations are OK (subject to all other constraints); otherwise
1820 (old-style parameter declarations) they are diagnosed. If
1821 START_ATTR_OK is true, the declaration specifiers may start with
1822 attributes (GNU or standard); otherwise they may not.
1823 OBJC_FOREACH_OBJECT_DECLARATION can be used to get back the parsed
1824 declaration when parsing an Objective-C foreach statement.
1825 FALLTHRU_ATTR_P is used to signal whether this function parsed
1826 "__attribute__((fallthrough));". ATTRS are any standard attributes
1827 parsed in the caller (in contexts where such attributes had to be
1828 parsed to determine whether what follows is a declaration or a
1829 statement); HAVE_ATTRS says whether there were any such attributes
1833 declaration-specifiers init-declarator-list[opt] ;
1834 static_assert-declaration
1836 function-definition:
1837 declaration-specifiers[opt] declarator declaration-list[opt]
1842 declaration-list declaration
1844 init-declarator-list:
1846 init-declarator-list , init-declarator
1849 declarator simple-asm-expr[opt] gnu-attributes[opt]
1850 declarator simple-asm-expr[opt] gnu-attributes[opt] = initializer
1854 nested-function-definition:
1855 declaration-specifiers declarator declaration-list[opt]
1861 gnu-attributes objc-class-definition
1862 gnu-attributes objc-category-definition
1863 gnu-attributes objc-protocol-definition
1865 The simple-asm-expr and gnu-attributes are GNU extensions.
1867 This function does not handle __extension__; that is handled in its
1868 callers. ??? Following the old parser, __extension__ may start
1869 external declarations, declarations in functions and declarations
1870 at the start of "for" loops, but not old-style parameter
1873 C99 requires declaration specifiers in a function definition; the
1874 absence is diagnosed through the diagnosis of implicit int. In GNU
1875 C we also allow but diagnose declarations without declaration
1876 specifiers, but only at top level (elsewhere they conflict with
1879 In Objective-C, declarations of the looping variable in a foreach
1880 statement are exceptionally terminated by 'in' (for example, 'for
1881 (NSObject *object in array) { ... }').
1886 threadprivate-directive
1890 gimple-function-definition:
1891 declaration-specifiers[opt] __GIMPLE (gimple-or-rtl-pass-list) declarator
1892 declaration-list[opt] compound-statement
1894 rtl-function-definition:
1895 declaration-specifiers[opt] __RTL (gimple-or-rtl-pass-list) declarator
1896 declaration-list[opt] compound-statement */
1899 c_parser_declaration_or_fndef (c_parser
*parser
, bool fndef_ok
,
1900 bool static_assert_ok
, bool empty_ok
,
1901 bool nested
, bool start_attr_ok
,
1902 tree
*objc_foreach_object_declaration
1904 vec
<c_token
> *omp_declare_simd_clauses
1906 bool have_attrs
/* = false */,
1907 tree attrs
/* = NULL_TREE */,
1908 struct oacc_routine_data
*oacc_routine_data
1910 bool *fallthru_attr_p
/* = NULL */)
1912 struct c_declspecs
*specs
;
1914 tree all_prefix_attrs
;
1915 bool diagnosed_no_specs
= false;
1916 location_t here
= c_parser_peek_token (parser
)->location
;
1918 add_debug_begin_stmt (c_parser_peek_token (parser
)->location
);
1920 if (static_assert_ok
1921 && c_parser_next_token_is_keyword (parser
, RID_STATIC_ASSERT
))
1923 c_parser_static_assert_declaration (parser
);
1926 specs
= build_null_declspecs ();
1928 /* Handle any standard attributes parsed in the caller. */
1931 declspecs_add_attrs (here
, specs
, attrs
);
1932 specs
->non_std_attrs_seen_p
= false;
1935 /* Try to detect an unknown type name when we have "A B" or "A *B". */
1936 if (c_parser_peek_token (parser
)->type
== CPP_NAME
1937 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
1938 && (c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
1939 || c_parser_peek_2nd_token (parser
)->type
== CPP_MULT
)
1940 && (!nested
|| !lookup_name (c_parser_peek_token (parser
)->value
)))
1942 tree name
= c_parser_peek_token (parser
)->value
;
1944 /* Issue a warning about NAME being an unknown type name, perhaps
1945 with some kind of hint.
1946 If the user forgot a "struct" etc, suggest inserting
1947 it. Otherwise, attempt to look for misspellings. */
1948 gcc_rich_location
richloc (here
);
1949 if (tag_exists_p (RECORD_TYPE
, name
))
1951 /* This is not C++ with its implicit typedef. */
1952 richloc
.add_fixit_insert_before ("struct ");
1954 "unknown type name %qE;"
1955 " use %<struct%> keyword to refer to the type",
1958 else if (tag_exists_p (UNION_TYPE
, name
))
1960 richloc
.add_fixit_insert_before ("union ");
1962 "unknown type name %qE;"
1963 " use %<union%> keyword to refer to the type",
1966 else if (tag_exists_p (ENUMERAL_TYPE
, name
))
1968 richloc
.add_fixit_insert_before ("enum ");
1970 "unknown type name %qE;"
1971 " use %<enum%> keyword to refer to the type",
1976 auto_diagnostic_group d
;
1977 name_hint hint
= lookup_name_fuzzy (name
, FUZZY_LOOKUP_TYPENAME
,
1979 if (const char *suggestion
= hint
.suggestion ())
1981 richloc
.add_fixit_replace (suggestion
);
1983 "unknown type name %qE; did you mean %qs?",
1987 error_at (here
, "unknown type name %qE", name
);
1990 /* Parse declspecs normally to get a correct pointer type, but avoid
1991 a further "fails to be a type name" error. Refuse nested functions
1992 since it is not how the user likely wants us to recover. */
1993 c_parser_peek_token (parser
)->type
= CPP_KEYWORD
;
1994 c_parser_peek_token (parser
)->keyword
= RID_VOID
;
1995 c_parser_peek_token (parser
)->value
= error_mark_node
;
1999 /* When there are standard attributes at the start of the
2000 declaration (to apply to the entity being declared), an
2001 init-declarator-list or function definition must be present. */
2002 if (c_parser_nth_token_starts_std_attributes (parser
, 1))
2005 c_parser_declspecs (parser
, specs
, true, true, start_attr_ok
,
2006 true, true, start_attr_ok
, true, cla_nonabstract_decl
);
2009 c_parser_skip_to_end_of_block_or_statement (parser
);
2012 if (nested
&& !specs
->declspecs_seen_p
)
2014 c_parser_error (parser
, "expected declaration specifiers");
2015 c_parser_skip_to_end_of_block_or_statement (parser
);
2019 finish_declspecs (specs
);
2020 bool auto_type_p
= specs
->typespec_word
== cts_auto_type
;
2021 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
2024 error_at (here
, "%<__auto_type%> in empty declaration");
2025 else if (specs
->typespec_kind
== ctsk_none
2026 && attribute_fallthrough_p (specs
->attrs
))
2028 if (fallthru_attr_p
!= NULL
)
2029 *fallthru_attr_p
= true;
2032 tree fn
= build_call_expr_internal_loc (here
, IFN_FALLTHROUGH
,
2037 pedwarn (here
, OPT_Wattributes
,
2038 "%<fallthrough%> attribute at top level");
2040 else if (empty_ok
&& !(have_attrs
2041 && specs
->non_std_attrs_seen_p
))
2045 shadow_tag_warned (specs
, 1);
2046 pedwarn (here
, 0, "empty declaration");
2048 c_parser_consume_token (parser
);
2049 if (oacc_routine_data
)
2050 c_finish_oacc_routine (oacc_routine_data
, NULL_TREE
, false);
2054 /* Provide better error recovery. Note that a type name here is usually
2055 better diagnosed as a redeclaration. */
2057 && specs
->typespec_kind
== ctsk_tagdef
2058 && c_parser_next_token_starts_declspecs (parser
)
2059 && !c_parser_next_token_is (parser
, CPP_NAME
))
2061 c_parser_error (parser
, "expected %<;%>, identifier or %<(%>");
2062 parser
->error
= false;
2063 shadow_tag_warned (specs
, 1);
2066 else if (c_dialect_objc () && !auto_type_p
)
2068 /* Prefix attributes are an error on method decls. */
2069 switch (c_parser_peek_token (parser
)->type
)
2073 if (c_parser_objc_diagnose_bad_element_prefix (parser
, specs
))
2077 warning_at (c_parser_peek_token (parser
)->location
,
2079 "prefix attributes are ignored for methods");
2080 specs
->attrs
= NULL_TREE
;
2083 c_parser_objc_method_definition (parser
);
2085 c_parser_objc_methodproto (parser
);
2091 /* This is where we parse 'attributes @interface ...',
2092 'attributes @implementation ...', 'attributes @protocol ...'
2093 (where attributes could be, for example, __attribute__
2096 switch (c_parser_peek_token (parser
)->keyword
)
2098 case RID_AT_INTERFACE
:
2100 if (c_parser_objc_diagnose_bad_element_prefix (parser
, specs
))
2102 c_parser_objc_class_definition (parser
, specs
->attrs
);
2106 case RID_AT_IMPLEMENTATION
:
2108 if (c_parser_objc_diagnose_bad_element_prefix (parser
, specs
))
2112 warning_at (c_parser_peek_token (parser
)->location
,
2114 "prefix attributes are ignored for implementations");
2115 specs
->attrs
= NULL_TREE
;
2117 c_parser_objc_class_definition (parser
, NULL_TREE
);
2121 case RID_AT_PROTOCOL
:
2123 if (c_parser_objc_diagnose_bad_element_prefix (parser
, specs
))
2125 c_parser_objc_protocol_definition (parser
, specs
->attrs
);
2132 case RID_AT_PROPERTY
:
2135 c_parser_error (parser
, "unexpected attribute");
2136 specs
->attrs
= NULL
;
2143 else if (attribute_fallthrough_p (specs
->attrs
))
2144 warning_at (here
, OPT_Wattributes
,
2145 "%<fallthrough%> attribute not followed by %<;%>");
2147 pending_xref_error ();
2148 prefix_attrs
= specs
->attrs
;
2149 all_prefix_attrs
= prefix_attrs
;
2150 specs
->attrs
= NULL_TREE
;
2153 struct c_declarator
*declarator
;
2156 tree fnbody
= NULL_TREE
;
2157 /* Declaring either one or more declarators (in which case we
2158 should diagnose if there were no declaration specifiers) or a
2159 function definition (in which case the diagnostic for
2160 implicit int suffices). */
2161 declarator
= c_parser_declarator (parser
,
2162 specs
->typespec_kind
!= ctsk_none
,
2163 C_DTR_NORMAL
, &dummy
);
2164 if (declarator
== NULL
)
2166 if (omp_declare_simd_clauses
)
2167 c_finish_omp_declare_simd (parser
, NULL_TREE
, NULL_TREE
,
2168 omp_declare_simd_clauses
);
2169 if (oacc_routine_data
)
2170 c_finish_oacc_routine (oacc_routine_data
, NULL_TREE
, false);
2171 c_parser_skip_to_end_of_block_or_statement (parser
);
2174 if (auto_type_p
&& declarator
->kind
!= cdk_id
)
2177 "%<__auto_type%> requires a plain identifier"
2179 c_parser_skip_to_end_of_block_or_statement (parser
);
2182 if (c_parser_next_token_is (parser
, CPP_EQ
)
2183 || c_parser_next_token_is (parser
, CPP_COMMA
)
2184 || c_parser_next_token_is (parser
, CPP_SEMICOLON
)
2185 || c_parser_next_token_is_keyword (parser
, RID_ASM
)
2186 || c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
)
2187 || c_parser_next_token_is_keyword (parser
, RID_IN
))
2189 tree asm_name
= NULL_TREE
;
2190 tree postfix_attrs
= NULL_TREE
;
2191 if (!diagnosed_no_specs
&& !specs
->declspecs_seen_p
)
2193 diagnosed_no_specs
= true;
2194 pedwarn (here
, 0, "data definition has no type or storage class");
2196 /* Having seen a data definition, there cannot now be a
2197 function definition. */
2199 if (c_parser_next_token_is_keyword (parser
, RID_ASM
))
2200 asm_name
= c_parser_simple_asm_expr (parser
);
2201 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
2203 postfix_attrs
= c_parser_gnu_attributes (parser
);
2204 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
2206 /* This means there is an attribute specifier after
2207 the declarator in a function definition. Provide
2208 some more information for the user. */
2209 error_at (here
, "attributes should be specified before the "
2210 "declarator in a function definition");
2211 c_parser_skip_to_end_of_block_or_statement (parser
);
2215 if (c_parser_next_token_is (parser
, CPP_EQ
))
2219 location_t init_loc
;
2220 c_parser_consume_token (parser
);
2223 init_loc
= c_parser_peek_token (parser
)->location
;
2224 rich_location
richloc (line_table
, init_loc
);
2225 start_init (NULL_TREE
, asm_name
, global_bindings_p (), &richloc
);
2226 /* A parameter is initialized, which is invalid. Don't
2227 attempt to instrument the initializer. */
2228 int flag_sanitize_save
= flag_sanitize
;
2229 if (nested
&& !empty_ok
)
2231 init
= c_parser_expr_no_commas (parser
, NULL
);
2232 flag_sanitize
= flag_sanitize_save
;
2233 if (TREE_CODE (init
.value
) == COMPONENT_REF
2234 && DECL_C_BIT_FIELD (TREE_OPERAND (init
.value
, 1)))
2236 "%<__auto_type%> used with a bit-field"
2238 init
= convert_lvalue_to_rvalue (init_loc
, init
, true, true);
2239 tree init_type
= TREE_TYPE (init
.value
);
2240 bool vm_type
= variably_modified_type_p (init_type
,
2243 init
.value
= save_expr (init
.value
);
2245 specs
->typespec_kind
= ctsk_typeof
;
2246 specs
->locations
[cdw_typedef
] = init_loc
;
2247 specs
->typedef_p
= true;
2248 specs
->type
= init_type
;
2251 bool maybe_const
= true;
2252 tree type_expr
= c_fully_fold (init
.value
, false,
2254 specs
->expr_const_operands
&= maybe_const
;
2256 specs
->expr
= build2 (COMPOUND_EXPR
,
2257 TREE_TYPE (type_expr
),
2258 specs
->expr
, type_expr
);
2260 specs
->expr
= type_expr
;
2262 d
= start_decl (declarator
, specs
, true,
2263 chainon (postfix_attrs
, all_prefix_attrs
));
2265 d
= error_mark_node
;
2266 if (omp_declare_simd_clauses
)
2267 c_finish_omp_declare_simd (parser
, d
, NULL_TREE
,
2268 omp_declare_simd_clauses
);
2272 /* The declaration of the variable is in effect while
2273 its initializer is parsed. */
2274 d
= start_decl (declarator
, specs
, true,
2275 chainon (postfix_attrs
, all_prefix_attrs
));
2277 d
= error_mark_node
;
2278 if (omp_declare_simd_clauses
)
2279 c_finish_omp_declare_simd (parser
, d
, NULL_TREE
,
2280 omp_declare_simd_clauses
);
2281 init_loc
= c_parser_peek_token (parser
)->location
;
2282 rich_location
richloc (line_table
, init_loc
);
2283 start_init (d
, asm_name
, global_bindings_p (), &richloc
);
2284 /* A parameter is initialized, which is invalid. Don't
2285 attempt to instrument the initializer. */
2286 int flag_sanitize_save
= flag_sanitize
;
2287 if (TREE_CODE (d
) == PARM_DECL
)
2289 init
= c_parser_initializer (parser
);
2290 flag_sanitize
= flag_sanitize_save
;
2293 if (oacc_routine_data
)
2294 c_finish_oacc_routine (oacc_routine_data
, d
, false);
2295 if (d
!= error_mark_node
)
2297 maybe_warn_string_init (init_loc
, TREE_TYPE (d
), init
);
2298 finish_decl (d
, init_loc
, init
.value
,
2299 init
.original_type
, asm_name
);
2307 "%<__auto_type%> requires an initialized "
2308 "data declaration");
2309 c_parser_skip_to_end_of_block_or_statement (parser
);
2313 location_t lastloc
= UNKNOWN_LOCATION
;
2314 tree attrs
= chainon (postfix_attrs
, all_prefix_attrs
);
2315 tree d
= start_decl (declarator
, specs
, false, attrs
, &lastloc
);
2316 if (d
&& TREE_CODE (d
) == FUNCTION_DECL
)
2318 /* Find the innermost declarator that is neither cdk_id
2320 const struct c_declarator
*decl
= declarator
;
2321 const struct c_declarator
*last_non_id_attrs
= NULL
;
2329 last_non_id_attrs
= decl
;
2330 decl
= decl
->declarator
;
2334 decl
= decl
->declarator
;
2345 /* If it exists and is cdk_function declaration whose
2346 arguments have not been set yet, use its arguments. */
2347 if (last_non_id_attrs
2348 && last_non_id_attrs
->kind
== cdk_function
)
2350 tree parms
= last_non_id_attrs
->u
.arg_info
->parms
;
2351 if (DECL_ARGUMENTS (d
) == NULL_TREE
2352 && DECL_INITIAL (d
) == NULL_TREE
)
2353 DECL_ARGUMENTS (d
) = parms
;
2355 warn_parm_array_mismatch (lastloc
, d
, parms
);
2358 if (omp_declare_simd_clauses
)
2360 tree parms
= NULL_TREE
;
2361 if (d
&& TREE_CODE (d
) == FUNCTION_DECL
)
2363 struct c_declarator
*ce
= declarator
;
2365 if (ce
->kind
== cdk_function
)
2367 parms
= ce
->u
.arg_info
->parms
;
2371 ce
= ce
->declarator
;
2374 temp_store_parm_decls (d
, parms
);
2375 c_finish_omp_declare_simd (parser
, d
, parms
,
2376 omp_declare_simd_clauses
);
2378 temp_pop_parm_decls ();
2380 if (oacc_routine_data
)
2381 c_finish_oacc_routine (oacc_routine_data
, d
, false);
2383 finish_decl (d
, UNKNOWN_LOCATION
, NULL_TREE
,
2384 NULL_TREE
, asm_name
);
2386 if (c_parser_next_token_is_keyword (parser
, RID_IN
))
2389 *objc_foreach_object_declaration
= d
;
2391 *objc_foreach_object_declaration
= error_mark_node
;
2394 if (c_parser_next_token_is (parser
, CPP_COMMA
))
2399 "%<__auto_type%> may only be used with"
2400 " a single declarator");
2401 c_parser_skip_to_end_of_block_or_statement (parser
);
2404 c_parser_consume_token (parser
);
2405 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
2406 all_prefix_attrs
= chainon (c_parser_gnu_attributes (parser
),
2409 all_prefix_attrs
= prefix_attrs
;
2412 else if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
2414 c_parser_consume_token (parser
);
2417 else if (c_parser_next_token_is_keyword (parser
, RID_IN
))
2419 /* This can only happen in Objective-C: we found the
2420 'in' that terminates the declaration inside an
2421 Objective-C foreach statement. Do not consume the
2422 token, so that the caller can use it to determine
2423 that this indeed is a foreach context. */
2428 c_parser_error (parser
, "expected %<,%> or %<;%>");
2429 c_parser_skip_to_end_of_block_or_statement (parser
);
2433 else if (auto_type_p
)
2436 "%<__auto_type%> requires an initialized data declaration");
2437 c_parser_skip_to_end_of_block_or_statement (parser
);
2442 c_parser_error (parser
, "expected %<=%>, %<,%>, %<;%>, "
2443 "%<asm%> or %<__attribute__%>");
2444 c_parser_skip_to_end_of_block_or_statement (parser
);
2447 /* Function definition (nested or otherwise). */
2450 pedwarn (here
, OPT_Wpedantic
, "ISO C forbids nested functions");
2451 c_push_function_context ();
2453 if (!start_function (specs
, declarator
, all_prefix_attrs
))
2455 /* At this point we've consumed:
2456 declaration-specifiers declarator
2457 and the next token isn't CPP_EQ, CPP_COMMA, CPP_SEMICOLON,
2458 RID_ASM, RID_ATTRIBUTE, or RID_IN,
2460 declaration-specifiers declarator
2461 aren't grokkable as a function definition, so we have
2463 gcc_assert (!c_parser_next_token_is (parser
, CPP_SEMICOLON
));
2464 if (c_parser_next_token_starts_declspecs (parser
))
2467 declaration-specifiers declarator decl-specs
2468 then assume we have a missing semicolon, which would
2470 declaration-specifiers declarator decl-specs
2473 <~~~~~~~~~ declaration ~~~~~~~~~~>
2474 Use c_parser_require to get an error with a fix-it hint. */
2475 c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>");
2476 parser
->error
= false;
2480 /* This can appear in many cases looking nothing like a
2481 function definition, so we don't give a more specific
2482 error suggesting there was one. */
2483 c_parser_error (parser
, "expected %<=%>, %<,%>, %<;%>, %<asm%> "
2484 "or %<__attribute__%>");
2487 c_pop_function_context ();
2491 if (DECL_DECLARED_INLINE_P (current_function_decl
))
2492 tv
= TV_PARSE_INLINE
;
2495 auto_timevar
at (g_timer
, tv
);
2497 /* Parse old-style parameter declarations. ??? Attributes are
2498 not allowed to start declaration specifiers here because of a
2499 syntax conflict between a function declaration with attribute
2500 suffix and a function definition with an attribute prefix on
2501 first old-style parameter declaration. Following the old
2502 parser, they are not accepted on subsequent old-style
2503 parameter declarations either. However, there is no
2504 ambiguity after the first declaration, nor indeed on the
2505 first as long as we don't allow postfix attributes after a
2506 declarator with a nonempty identifier list in a definition;
2507 and postfix attributes have never been accepted here in
2508 function definitions either. */
2509 while (c_parser_next_token_is_not (parser
, CPP_EOF
)
2510 && c_parser_next_token_is_not (parser
, CPP_OPEN_BRACE
))
2511 c_parser_declaration_or_fndef (parser
, false, false, false,
2513 store_parm_decls ();
2514 if (omp_declare_simd_clauses
)
2515 c_finish_omp_declare_simd (parser
, current_function_decl
, NULL_TREE
,
2516 omp_declare_simd_clauses
);
2517 if (oacc_routine_data
)
2518 c_finish_oacc_routine (oacc_routine_data
, current_function_decl
, true);
2519 location_t startloc
= c_parser_peek_token (parser
)->location
;
2520 DECL_STRUCT_FUNCTION (current_function_decl
)->function_start_locus
2522 location_t endloc
= startloc
;
2524 /* If the definition was marked with __RTL, use the RTL parser now,
2525 consuming the function body. */
2526 if (specs
->declspec_il
== cdil_rtl
)
2528 endloc
= c_parser_parse_rtl_body (parser
, specs
->gimple_or_rtl_pass
);
2530 /* Normally, store_parm_decls sets next_is_function_body,
2531 anticipating a function body. We need a push_scope/pop_scope
2532 pair to flush out this state, or subsequent function parsing
2537 finish_function (endloc
);
2540 /* If the definition was marked with __GIMPLE then parse the
2541 function body as GIMPLE. */
2542 else if (specs
->declspec_il
!= cdil_none
)
2544 bool saved
= in_late_binary_op
;
2545 in_late_binary_op
= true;
2546 c_parser_parse_gimple_body (parser
, specs
->gimple_or_rtl_pass
,
2548 specs
->entry_bb_count
);
2549 in_late_binary_op
= saved
;
2552 fnbody
= c_parser_compound_statement (parser
, &endloc
);
2553 tree fndecl
= current_function_decl
;
2556 tree decl
= current_function_decl
;
2557 /* Mark nested functions as needing static-chain initially.
2558 lower_nested_functions will recompute it but the
2559 DECL_STATIC_CHAIN flag is also used before that happens,
2560 by initializer_constant_valid_p. See gcc.dg/nested-fn-2.c. */
2561 DECL_STATIC_CHAIN (decl
) = 1;
2563 finish_function (endloc
);
2564 c_pop_function_context ();
2565 add_stmt (build_stmt (DECL_SOURCE_LOCATION (decl
), DECL_EXPR
, decl
));
2571 finish_function (endloc
);
2573 /* Get rid of the empty stmt list for GIMPLE/RTL. */
2574 if (specs
->declspec_il
!= cdil_none
)
2575 DECL_SAVED_TREE (fndecl
) = NULL_TREE
;
2581 /* Parse an asm-definition (asm() outside a function body). This is a
2589 c_parser_asm_definition (c_parser
*parser
)
2591 tree asm_str
= c_parser_simple_asm_expr (parser
);
2593 symtab
->finalize_toplevel_asm (asm_str
);
2594 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
2597 /* Parse a static assertion (C11 6.7.10).
2599 static_assert-declaration:
2600 static_assert-declaration-no-semi ;
2604 c_parser_static_assert_declaration (c_parser
*parser
)
2606 c_parser_static_assert_declaration_no_semi (parser
);
2608 || !c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
2609 c_parser_skip_to_end_of_block_or_statement (parser
);
2612 /* Parse a static assertion (C11 6.7.10), without the trailing
2615 static_assert-declaration-no-semi:
2616 _Static_assert ( constant-expression , string-literal )
2619 static_assert-declaration-no-semi:
2620 _Static_assert ( constant-expression )
2624 c_parser_static_assert_declaration_no_semi (c_parser
*parser
)
2626 location_t assert_loc
, value_loc
;
2628 tree string
= NULL_TREE
;
2630 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_STATIC_ASSERT
));
2631 assert_loc
= c_parser_peek_token (parser
)->location
;
2633 pedwarn_c99 (assert_loc
, OPT_Wpedantic
,
2634 "ISO C99 does not support %<_Static_assert%>");
2636 pedwarn_c99 (assert_loc
, OPT_Wpedantic
,
2637 "ISO C90 does not support %<_Static_assert%>");
2638 c_parser_consume_token (parser
);
2639 matching_parens parens
;
2640 if (!parens
.require_open (parser
))
2642 location_t value_tok_loc
= c_parser_peek_token (parser
)->location
;
2643 value
= c_parser_expr_no_commas (parser
, NULL
).value
;
2644 value_loc
= EXPR_LOC_OR_LOC (value
, value_tok_loc
);
2645 if (c_parser_next_token_is (parser
, CPP_COMMA
))
2647 c_parser_consume_token (parser
);
2648 switch (c_parser_peek_token (parser
)->type
)
2654 case CPP_UTF8STRING
:
2655 string
= c_parser_string_literal (parser
, false, true).value
;
2658 c_parser_error (parser
, "expected string literal");
2662 else if (flag_isoc11
)
2663 /* If pedantic for pre-C11, the use of _Static_assert itself will
2664 have been diagnosed, so do not also diagnose the use of this
2665 new C2X feature of _Static_assert. */
2666 pedwarn_c11 (assert_loc
, OPT_Wpedantic
,
2667 "ISO C11 does not support omitting the string in "
2668 "%<_Static_assert%>");
2669 parens
.require_close (parser
);
2671 if (!INTEGRAL_TYPE_P (TREE_TYPE (value
)))
2673 error_at (value_loc
, "expression in static assertion is not an integer");
2676 if (TREE_CODE (value
) != INTEGER_CST
)
2678 value
= c_fully_fold (value
, false, NULL
);
2679 /* Strip no-op conversions. */
2680 STRIP_TYPE_NOPS (value
);
2681 if (TREE_CODE (value
) == INTEGER_CST
)
2682 pedwarn (value_loc
, OPT_Wpedantic
, "expression in static assertion "
2683 "is not an integer constant expression");
2685 if (TREE_CODE (value
) != INTEGER_CST
)
2687 error_at (value_loc
, "expression in static assertion is not constant");
2690 constant_expression_warning (value
);
2691 if (integer_zerop (value
))
2694 error_at (assert_loc
, "static assertion failed: %E", string
);
2696 error_at (assert_loc
, "static assertion failed");
2700 /* Parse some declaration specifiers (possibly none) (C90 6.5, C99
2701 6.7, C11 6.7), adding them to SPECS (which may already include some).
2702 Storage class specifiers are accepted iff SCSPEC_OK; type
2703 specifiers are accepted iff TYPESPEC_OK; alignment specifiers are
2704 accepted iff ALIGNSPEC_OK; gnu-attributes are accepted at the start
2705 iff START_ATTR_OK; __auto_type is accepted iff AUTO_TYPE_OK. In
2706 addition to the syntax shown, standard attributes are accepted at
2707 the start iff START_STD_ATTR_OK and at the end iff END_STD_ATTR_OK;
2708 unlike gnu-attributes, they are not accepted in the middle of the
2709 list. (This combines various different syntax productions in the C
2710 standard, and in some cases gnu-attributes and standard attributes
2711 at the start may already have been parsed before this function is
2714 declaration-specifiers:
2715 storage-class-specifier declaration-specifiers[opt]
2716 type-specifier declaration-specifiers[opt]
2717 type-qualifier declaration-specifiers[opt]
2718 function-specifier declaration-specifiers[opt]
2719 alignment-specifier declaration-specifiers[opt]
2721 Function specifiers (inline) are from C99, and are currently
2722 handled as storage class specifiers, as is __thread. Alignment
2723 specifiers are from C11.
2725 C90 6.5.1, C99 6.7.1, C11 6.7.1:
2726 storage-class-specifier:
2734 (_Thread_local is new in C11.)
2736 C99 6.7.4, C11 6.7.4:
2741 (_Noreturn is new in C11.)
2743 C90 6.5.2, C99 6.7.2, C11 6.7.2:
2756 [_Imaginary removed in C99 TC2]
2757 struct-or-union-specifier
2760 atomic-type-specifier
2762 (_Bool and _Complex are new in C99.)
2763 (atomic-type-specifier is new in C11.)
2765 C90 6.5.3, C99 6.7.3, C11 6.7.3:
2771 address-space-qualifier
2774 (restrict is new in C99.)
2775 (_Atomic is new in C11.)
2779 declaration-specifiers:
2780 gnu-attributes declaration-specifiers[opt]
2786 identifier recognized by the target
2788 storage-class-specifier:
2802 (_Fract, _Accum, and _Sat are new from ISO/IEC DTR 18037:
2803 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1169.pdf)
2805 atomic-type-specifier
2806 _Atomic ( type-name )
2811 class-name objc-protocol-refs[opt]
2812 typedef-name objc-protocol-refs
2817 c_parser_declspecs (c_parser
*parser
, struct c_declspecs
*specs
,
2818 bool scspec_ok
, bool typespec_ok
, bool start_attr_ok
,
2819 bool alignspec_ok
, bool auto_type_ok
,
2820 bool start_std_attr_ok
, bool end_std_attr_ok
,
2821 enum c_lookahead_kind la
)
2823 bool attrs_ok
= start_attr_ok
;
2824 bool seen_type
= specs
->typespec_kind
!= ctsk_none
;
2827 gcc_assert (la
== cla_prefer_id
);
2829 if (start_std_attr_ok
2830 && c_parser_nth_token_starts_std_attributes (parser
, 1))
2832 gcc_assert (!specs
->non_std_attrs_seen_p
);
2833 location_t loc
= c_parser_peek_token (parser
)->location
;
2834 tree attrs
= c_parser_std_attribute_specifier_sequence (parser
);
2835 declspecs_add_attrs (loc
, specs
, attrs
);
2836 specs
->non_std_attrs_seen_p
= false;
2839 while (c_parser_next_token_is (parser
, CPP_NAME
)
2840 || c_parser_next_token_is (parser
, CPP_KEYWORD
)
2841 || (c_dialect_objc () && c_parser_next_token_is (parser
, CPP_LESS
)))
2843 struct c_typespec t
;
2846 location_t loc
= c_parser_peek_token (parser
)->location
;
2848 /* If we cannot accept a type, exit if the next token must start
2849 one. Also, if we already have seen a tagged definition,
2850 a typename would be an error anyway and likely the user
2851 has simply forgotten a semicolon, so we exit. */
2852 if ((!typespec_ok
|| specs
->typespec_kind
== ctsk_tagdef
)
2853 && c_parser_next_tokens_start_typename (parser
, la
)
2854 && !c_parser_next_token_is_qualifier (parser
)
2855 && !c_parser_next_token_is_keyword (parser
, RID_ALIGNAS
))
2858 if (c_parser_next_token_is (parser
, CPP_NAME
))
2860 c_token
*name_token
= c_parser_peek_token (parser
);
2861 tree value
= name_token
->value
;
2862 c_id_kind kind
= name_token
->id_kind
;
2864 if (kind
== C_ID_ADDRSPACE
)
2867 = name_token
->keyword
- RID_FIRST_ADDR_SPACE
;
2868 declspecs_add_addrspace (name_token
->location
, specs
, as
);
2869 c_parser_consume_token (parser
);
2874 gcc_assert (!c_parser_next_token_is_qualifier (parser
));
2876 /* If we cannot accept a type, and the next token must start one,
2877 exit. Do the same if we already have seen a tagged definition,
2878 since it would be an error anyway and likely the user has simply
2879 forgotten a semicolon. */
2880 if (seen_type
|| !c_parser_next_tokens_start_typename (parser
, la
))
2883 /* Now at an unknown typename (C_ID_ID), a C_ID_TYPENAME or
2884 a C_ID_CLASSNAME. */
2885 c_parser_consume_token (parser
);
2888 if (kind
== C_ID_ID
)
2890 error_at (loc
, "unknown type name %qE", value
);
2891 t
.kind
= ctsk_typedef
;
2892 t
.spec
= error_mark_node
;
2894 else if (kind
== C_ID_TYPENAME
2895 && (!c_dialect_objc ()
2896 || c_parser_next_token_is_not (parser
, CPP_LESS
)))
2898 t
.kind
= ctsk_typedef
;
2899 /* For a typedef name, record the meaning, not the name.
2900 In case of 'foo foo, bar;'. */
2901 t
.spec
= lookup_name (value
);
2905 tree proto
= NULL_TREE
;
2906 gcc_assert (c_dialect_objc ());
2908 if (c_parser_next_token_is (parser
, CPP_LESS
))
2909 proto
= c_parser_objc_protocol_refs (parser
);
2910 t
.spec
= objc_get_protocol_qualified_type (value
, proto
);
2913 t
.expr_const_operands
= true;
2914 declspecs_add_type (name_token
->location
, specs
, t
);
2917 if (c_parser_next_token_is (parser
, CPP_LESS
))
2919 /* Make "<SomeProtocol>" equivalent to "id <SomeProtocol>" -
2920 nisse@lysator.liu.se. */
2922 gcc_assert (c_dialect_objc ());
2923 if (!typespec_ok
|| seen_type
)
2925 proto
= c_parser_objc_protocol_refs (parser
);
2927 t
.spec
= objc_get_protocol_qualified_type (NULL_TREE
, proto
);
2929 t
.expr_const_operands
= true;
2930 declspecs_add_type (loc
, specs
, t
);
2933 gcc_assert (c_parser_next_token_is (parser
, CPP_KEYWORD
));
2934 switch (c_parser_peek_token (parser
)->keyword
)
2947 /* TODO: Distinguish between function specifiers (inline, noreturn)
2948 and storage class specifiers, either here or in
2949 declspecs_add_scspec. */
2950 declspecs_add_scspec (loc
, specs
,
2951 c_parser_peek_token (parser
)->value
);
2952 c_parser_consume_token (parser
);
2984 if (c_dialect_objc ())
2985 parser
->objc_need_raw_identifier
= true;
2986 t
.kind
= ctsk_resword
;
2987 t
.spec
= c_parser_peek_token (parser
)->value
;
2989 t
.expr_const_operands
= true;
2990 declspecs_add_type (loc
, specs
, t
);
2991 c_parser_consume_token (parser
);
2998 t
= c_parser_enum_specifier (parser
);
2999 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE
, t
.spec
);
3000 declspecs_add_type (loc
, specs
, t
);
3008 t
= c_parser_struct_or_union_specifier (parser
);
3009 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE
, t
.spec
);
3010 declspecs_add_type (loc
, specs
, t
);
3013 /* ??? The old parser rejected typeof after other type
3014 specifiers, but is a syntax error the best way of
3016 if (!typespec_ok
|| seen_type
)
3020 t
= c_parser_typeof_specifier (parser
);
3021 declspecs_add_type (loc
, specs
, t
);
3024 /* C parser handling of Objective-C constructs needs
3025 checking for correct lvalue-to-rvalue conversions, and
3026 the code in build_modify_expr handling various
3027 Objective-C cases, and that in build_unary_op handling
3028 Objective-C cases for increment / decrement, also needs
3029 updating; uses of TYPE_MAIN_VARIANT in objc_compare_types
3030 and objc_types_are_equivalent may also need updates. */
3031 if (c_dialect_objc ())
3032 sorry ("%<_Atomic%> in Objective-C");
3034 pedwarn_c99 (loc
, OPT_Wpedantic
,
3035 "ISO C99 does not support the %<_Atomic%> qualifier");
3037 pedwarn_c99 (loc
, OPT_Wpedantic
,
3038 "ISO C90 does not support the %<_Atomic%> qualifier");
3041 value
= c_parser_peek_token (parser
)->value
;
3042 c_parser_consume_token (parser
);
3043 if (typespec_ok
&& c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
3045 /* _Atomic ( type-name ). */
3047 c_parser_consume_token (parser
);
3048 struct c_type_name
*type
= c_parser_type_name (parser
);
3049 t
.kind
= ctsk_typeof
;
3050 t
.spec
= error_mark_node
;
3052 t
.expr_const_operands
= true;
3054 t
.spec
= groktypename (type
, &t
.expr
,
3055 &t
.expr_const_operands
);
3056 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
3058 if (t
.spec
!= error_mark_node
)
3060 if (TREE_CODE (t
.spec
) == ARRAY_TYPE
)
3061 error_at (loc
, "%<_Atomic%>-qualified array type");
3062 else if (TREE_CODE (t
.spec
) == FUNCTION_TYPE
)
3063 error_at (loc
, "%<_Atomic%>-qualified function type");
3064 else if (TYPE_QUALS (t
.spec
) != TYPE_UNQUALIFIED
)
3065 error_at (loc
, "%<_Atomic%> applied to a qualified type");
3067 t
.spec
= c_build_qualified_type (t
.spec
, TYPE_QUAL_ATOMIC
);
3069 declspecs_add_type (loc
, specs
, t
);
3072 declspecs_add_qual (loc
, specs
, value
);
3078 declspecs_add_qual (loc
, specs
, c_parser_peek_token (parser
)->value
);
3079 c_parser_consume_token (parser
);
3084 attrs
= c_parser_gnu_attributes (parser
);
3085 declspecs_add_attrs (loc
, specs
, attrs
);
3090 align
= c_parser_alignas_specifier (parser
);
3091 declspecs_add_alignas (loc
, specs
, align
);
3095 error_at (loc
, "%<__GIMPLE%> only valid with %<-fgimple%>");
3096 c_parser_consume_token (parser
);
3097 specs
->declspec_il
= cdil_gimple
;
3098 specs
->locations
[cdw_gimple
] = loc
;
3099 c_parser_gimple_or_rtl_pass_list (parser
, specs
);
3102 c_parser_consume_token (parser
);
3103 specs
->declspec_il
= cdil_rtl
;
3104 specs
->locations
[cdw_rtl
] = loc
;
3105 c_parser_gimple_or_rtl_pass_list (parser
, specs
);
3113 && c_parser_nth_token_starts_std_attributes (parser
, 1))
3114 specs
->postfix_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
3117 /* Parse an enum specifier (C90 6.5.2.2, C99 6.7.2.2, C11 6.7.2.2).
3120 enum gnu-attributes[opt] identifier[opt] { enumerator-list }
3122 enum gnu-attributes[opt] identifier[opt] { enumerator-list , }
3124 enum gnu-attributes[opt] identifier
3126 The form with trailing comma is new in C99. The forms with
3127 gnu-attributes are GNU extensions. In GNU C, we accept any expression
3128 without commas in the syntax (assignment expressions, not just
3129 conditional expressions); assignment expressions will be diagnosed
3134 enumerator-list , enumerator
3137 enumeration-constant attribute-specifier-sequence[opt]
3138 enumeration-constant attribute-specifier-sequence[opt]
3139 = constant-expression
3144 enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt]
3145 enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt]
3146 = constant-expression
3150 static struct c_typespec
3151 c_parser_enum_specifier (c_parser
*parser
)
3153 struct c_typespec ret
;
3154 bool have_std_attrs
;
3155 tree std_attrs
= NULL_TREE
;
3157 tree ident
= NULL_TREE
;
3158 location_t enum_loc
;
3159 location_t ident_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
3160 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ENUM
));
3161 c_parser_consume_token (parser
);
3162 have_std_attrs
= c_parser_nth_token_starts_std_attributes (parser
, 1);
3164 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
3165 attrs
= c_parser_gnu_attributes (parser
);
3166 enum_loc
= c_parser_peek_token (parser
)->location
;
3167 /* Set the location in case we create a decl now. */
3168 c_parser_set_source_position_from_token (c_parser_peek_token (parser
));
3169 if (c_parser_next_token_is (parser
, CPP_NAME
))
3171 ident
= c_parser_peek_token (parser
)->value
;
3172 ident_loc
= c_parser_peek_token (parser
)->location
;
3173 enum_loc
= ident_loc
;
3174 c_parser_consume_token (parser
);
3176 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
3178 /* Parse an enum definition. */
3179 struct c_enum_contents the_enum
;
3182 /* We chain the enumerators in reverse order, then put them in
3183 forward order at the end. */
3185 timevar_push (TV_PARSE_ENUM
);
3186 type
= start_enum (enum_loc
, &the_enum
, ident
);
3188 c_parser_consume_token (parser
);
3196 location_t comma_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
3197 location_t decl_loc
, value_loc
;
3198 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
3200 /* Give a nicer error for "enum {}". */
3201 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
)
3204 error_at (c_parser_peek_token (parser
)->location
,
3205 "empty enum is invalid");
3206 parser
->error
= true;
3209 c_parser_error (parser
, "expected identifier");
3210 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
, NULL
);
3211 values
= error_mark_node
;
3214 token
= c_parser_peek_token (parser
);
3215 enum_id
= token
->value
;
3216 /* Set the location in case we create a decl now. */
3217 c_parser_set_source_position_from_token (token
);
3218 decl_loc
= value_loc
= token
->location
;
3219 c_parser_consume_token (parser
);
3220 /* Parse any specified attributes. */
3221 tree std_attrs
= NULL_TREE
;
3222 if (c_parser_nth_token_starts_std_attributes (parser
, 1))
3223 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
3224 tree enum_attrs
= chainon (std_attrs
,
3225 c_parser_gnu_attributes (parser
));
3226 if (c_parser_next_token_is (parser
, CPP_EQ
))
3228 c_parser_consume_token (parser
);
3229 value_loc
= c_parser_peek_token (parser
)->location
;
3230 enum_value
= c_parser_expr_no_commas (parser
, NULL
).value
;
3233 enum_value
= NULL_TREE
;
3234 enum_decl
= build_enumerator (decl_loc
, value_loc
,
3235 &the_enum
, enum_id
, enum_value
);
3237 decl_attributes (&TREE_PURPOSE (enum_decl
), enum_attrs
, 0);
3238 TREE_CHAIN (enum_decl
) = values
;
3241 if (c_parser_next_token_is (parser
, CPP_COMMA
))
3243 comma_loc
= c_parser_peek_token (parser
)->location
;
3245 c_parser_consume_token (parser
);
3247 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
3250 pedwarn_c90 (comma_loc
, OPT_Wpedantic
,
3251 "comma at end of enumerator list");
3252 c_parser_consume_token (parser
);
3257 c_parser_error (parser
, "expected %<,%> or %<}%>");
3258 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
, NULL
);
3259 values
= error_mark_node
;
3263 postfix_attrs
= c_parser_gnu_attributes (parser
);
3264 ret
.spec
= finish_enum (type
, nreverse (values
),
3266 chainon (attrs
, postfix_attrs
)));
3267 ret
.kind
= ctsk_tagdef
;
3268 ret
.expr
= NULL_TREE
;
3269 ret
.expr_const_operands
= true;
3270 timevar_pop (TV_PARSE_ENUM
);
3275 c_parser_error (parser
, "expected %<{%>");
3276 ret
.spec
= error_mark_node
;
3277 ret
.kind
= ctsk_tagref
;
3278 ret
.expr
= NULL_TREE
;
3279 ret
.expr_const_operands
= true;
3282 /* Attributes may only appear when the members are defined or in
3283 certain forward declarations (treat enum forward declarations in
3284 GNU C analogously to struct and union forward declarations in
3286 if (have_std_attrs
&& c_parser_next_token_is_not (parser
, CPP_SEMICOLON
))
3287 c_parser_error (parser
, "expected %<;%>");
3288 ret
= parser_xref_tag (ident_loc
, ENUMERAL_TYPE
, ident
, have_std_attrs
,
3290 /* In ISO C, enumerated types can be referred to only if already
3292 if (pedantic
&& !COMPLETE_TYPE_P (ret
.spec
))
3295 pedwarn (enum_loc
, OPT_Wpedantic
,
3296 "ISO C forbids forward references to %<enum%> types");
3301 /* Parse a struct or union specifier (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1).
3303 struct-or-union-specifier:
3304 struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
3305 identifier[opt] { struct-contents } gnu-attributes[opt]
3306 struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
3310 struct-declaration-list
3312 struct-declaration-list:
3313 struct-declaration ;
3314 struct-declaration-list struct-declaration ;
3321 struct-declaration-list struct-declaration
3323 struct-declaration-list:
3324 struct-declaration-list ;
3327 (Note that in the syntax here, unlike that in ISO C, the semicolons
3328 are included here rather than in struct-declaration, in order to
3329 describe the syntax with extra semicolons and missing semicolon at
3334 struct-declaration-list:
3335 @defs ( class-name )
3337 (Note this does not include a trailing semicolon, but can be
3338 followed by further declarations, and gets a pedwarn-if-pedantic
3339 when followed by a semicolon.) */
3341 static struct c_typespec
3342 c_parser_struct_or_union_specifier (c_parser
*parser
)
3344 struct c_typespec ret
;
3345 bool have_std_attrs
;
3346 tree std_attrs
= NULL_TREE
;
3348 tree ident
= NULL_TREE
;
3349 location_t struct_loc
;
3350 location_t ident_loc
= UNKNOWN_LOCATION
;
3351 enum tree_code code
;
3352 switch (c_parser_peek_token (parser
)->keyword
)
3363 struct_loc
= c_parser_peek_token (parser
)->location
;
3364 c_parser_consume_token (parser
);
3365 have_std_attrs
= c_parser_nth_token_starts_std_attributes (parser
, 1);
3367 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
3368 attrs
= c_parser_gnu_attributes (parser
);
3370 /* Set the location in case we create a decl now. */
3371 c_parser_set_source_position_from_token (c_parser_peek_token (parser
));
3373 if (c_parser_next_token_is (parser
, CPP_NAME
))
3375 ident
= c_parser_peek_token (parser
)->value
;
3376 ident_loc
= c_parser_peek_token (parser
)->location
;
3377 struct_loc
= ident_loc
;
3378 c_parser_consume_token (parser
);
3380 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
3382 /* Parse a struct or union definition. Start the scope of the
3383 tag before parsing components. */
3384 class c_struct_parse_info
*struct_info
;
3385 tree type
= start_struct (struct_loc
, code
, ident
, &struct_info
);
3387 /* We chain the components in reverse order, then put them in
3388 forward order at the end. Each struct-declaration may
3389 declare multiple components (comma-separated), so we must use
3390 chainon to join them, although when parsing each
3391 struct-declaration we can use TREE_CHAIN directly.
3393 The theory behind all this is that there will be more
3394 semicolon separated fields than comma separated fields, and
3395 so we'll be minimizing the number of node traversals required
3398 timevar_push (TV_PARSE_STRUCT
);
3399 contents
= NULL_TREE
;
3400 c_parser_consume_token (parser
);
3401 /* Handle the Objective-C @defs construct,
3402 e.g. foo(sizeof(struct{ @defs(ClassName) }));. */
3403 if (c_parser_next_token_is_keyword (parser
, RID_AT_DEFS
))
3406 gcc_assert (c_dialect_objc ());
3407 c_parser_consume_token (parser
);
3408 matching_parens parens
;
3409 if (!parens
.require_open (parser
))
3411 if (c_parser_next_token_is (parser
, CPP_NAME
)
3412 && c_parser_peek_token (parser
)->id_kind
== C_ID_CLASSNAME
)
3414 name
= c_parser_peek_token (parser
)->value
;
3415 c_parser_consume_token (parser
);
3419 c_parser_error (parser
, "expected class name");
3420 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
3423 parens
.skip_until_found_close (parser
);
3424 contents
= nreverse (objc_get_class_ivars (name
));
3427 /* Parse the struct-declarations and semicolons. Problems with
3428 semicolons are diagnosed here; empty structures are diagnosed
3433 /* Parse any stray semicolon. */
3434 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
3436 location_t semicolon_loc
3437 = c_parser_peek_token (parser
)->location
;
3438 gcc_rich_location
richloc (semicolon_loc
);
3439 richloc
.add_fixit_remove ();
3440 pedwarn (&richloc
, OPT_Wpedantic
,
3441 "extra semicolon in struct or union specified");
3442 c_parser_consume_token (parser
);
3445 /* Stop if at the end of the struct or union contents. */
3446 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
3448 c_parser_consume_token (parser
);
3451 /* Accept #pragmas at struct scope. */
3452 if (c_parser_next_token_is (parser
, CPP_PRAGMA
))
3454 c_parser_pragma (parser
, pragma_struct
, NULL
);
3457 /* Parse some comma-separated declarations, but not the
3458 trailing semicolon if any. */
3459 decls
= c_parser_struct_declaration (parser
);
3460 contents
= chainon (decls
, contents
);
3461 /* If no semicolon follows, either we have a parse error or
3462 are at the end of the struct or union and should
3464 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
3465 c_parser_consume_token (parser
);
3468 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
3469 pedwarn (c_parser_peek_token (parser
)->location
, 0,
3470 "no semicolon at end of struct or union");
3471 else if (parser
->error
3472 || !c_parser_next_token_starts_declspecs (parser
))
3474 c_parser_error (parser
, "expected %<;%>");
3475 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
, NULL
);
3479 /* If we come here, we have already emitted an error
3480 for an expected `;', identifier or `(', and we also
3481 recovered already. Go on with the next field. */
3484 postfix_attrs
= c_parser_gnu_attributes (parser
);
3485 ret
.spec
= finish_struct (struct_loc
, type
, nreverse (contents
),
3487 chainon (attrs
, postfix_attrs
)),
3489 ret
.kind
= ctsk_tagdef
;
3490 ret
.expr
= NULL_TREE
;
3491 ret
.expr_const_operands
= true;
3492 timevar_pop (TV_PARSE_STRUCT
);
3497 c_parser_error (parser
, "expected %<{%>");
3498 ret
.spec
= error_mark_node
;
3499 ret
.kind
= ctsk_tagref
;
3500 ret
.expr
= NULL_TREE
;
3501 ret
.expr_const_operands
= true;
3504 /* Attributes may only appear when the members are defined or in
3505 certain forward declarations. */
3506 if (have_std_attrs
&& c_parser_next_token_is_not (parser
, CPP_SEMICOLON
))
3507 c_parser_error (parser
, "expected %<;%>");
3508 /* ??? Existing practice is that GNU attributes are ignored after
3509 the struct or union keyword when not defining the members. */
3510 ret
= parser_xref_tag (ident_loc
, code
, ident
, have_std_attrs
, std_attrs
);
3514 /* Parse a struct-declaration (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1),
3515 *without* the trailing semicolon.
3518 attribute-specifier-sequence[opt] specifier-qualifier-list
3519 attribute-specifier-sequence[opt] struct-declarator-list
3520 static_assert-declaration-no-semi
3522 specifier-qualifier-list:
3523 type-specifier specifier-qualifier-list[opt]
3524 type-qualifier specifier-qualifier-list[opt]
3525 alignment-specifier specifier-qualifier-list[opt]
3526 gnu-attributes specifier-qualifier-list[opt]
3528 struct-declarator-list:
3530 struct-declarator-list , gnu-attributes[opt] struct-declarator
3533 declarator gnu-attributes[opt]
3534 declarator[opt] : constant-expression gnu-attributes[opt]
3539 __extension__ struct-declaration
3540 specifier-qualifier-list
3542 Unlike the ISO C syntax, semicolons are handled elsewhere. The use
3543 of gnu-attributes where shown is a GNU extension. In GNU C, we accept
3544 any expression without commas in the syntax (assignment
3545 expressions, not just conditional expressions); assignment
3546 expressions will be diagnosed as non-constant. */
3549 c_parser_struct_declaration (c_parser
*parser
)
3551 struct c_declspecs
*specs
;
3553 tree all_prefix_attrs
;
3555 location_t decl_loc
;
3556 if (c_parser_next_token_is_keyword (parser
, RID_EXTENSION
))
3560 ext
= disable_extension_diagnostics ();
3561 c_parser_consume_token (parser
);
3562 decl
= c_parser_struct_declaration (parser
);
3563 restore_extension_diagnostics (ext
);
3566 if (c_parser_next_token_is_keyword (parser
, RID_STATIC_ASSERT
))
3568 c_parser_static_assert_declaration_no_semi (parser
);
3571 specs
= build_null_declspecs ();
3572 decl_loc
= c_parser_peek_token (parser
)->location
;
3573 /* Strictly by the standard, we shouldn't allow _Alignas here,
3574 but it appears to have been intended to allow it there, so
3575 we're keeping it as it is until WG14 reaches a conclusion
3577 <http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1731.pdf> */
3578 c_parser_declspecs (parser
, specs
, false, true, true,
3579 true, false, true, true, cla_nonabstract_decl
);
3582 if (!specs
->declspecs_seen_p
)
3584 c_parser_error (parser
, "expected specifier-qualifier-list");
3587 finish_declspecs (specs
);
3588 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
)
3589 || c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
3592 if (specs
->typespec_kind
== ctsk_none
)
3594 pedwarn (decl_loc
, OPT_Wpedantic
,
3595 "ISO C forbids member declarations with no members");
3596 shadow_tag_warned (specs
, pedantic
);
3601 /* Support for unnamed structs or unions as members of
3602 structs or unions (which is [a] useful and [b] supports
3606 ret
= grokfield (c_parser_peek_token (parser
)->location
,
3607 build_id_declarator (NULL_TREE
), specs
,
3610 decl_attributes (&ret
, attrs
, 0);
3615 /* Provide better error recovery. Note that a type name here is valid,
3616 and will be treated as a field name. */
3617 if (specs
->typespec_kind
== ctsk_tagdef
3618 && TREE_CODE (specs
->type
) != ENUMERAL_TYPE
3619 && c_parser_next_token_starts_declspecs (parser
)
3620 && !c_parser_next_token_is (parser
, CPP_NAME
))
3622 c_parser_error (parser
, "expected %<;%>, identifier or %<(%>");
3623 parser
->error
= false;
3627 pending_xref_error ();
3628 prefix_attrs
= specs
->attrs
;
3629 all_prefix_attrs
= prefix_attrs
;
3630 specs
->attrs
= NULL_TREE
;
3634 /* Declaring one or more declarators or un-named bit-fields. */
3635 struct c_declarator
*declarator
;
3637 if (c_parser_next_token_is (parser
, CPP_COLON
))
3638 declarator
= build_id_declarator (NULL_TREE
);
3640 declarator
= c_parser_declarator (parser
,
3641 specs
->typespec_kind
!= ctsk_none
,
3642 C_DTR_NORMAL
, &dummy
);
3643 if (declarator
== NULL
)
3645 c_parser_skip_to_end_of_block_or_statement (parser
);
3648 if (c_parser_next_token_is (parser
, CPP_COLON
)
3649 || c_parser_next_token_is (parser
, CPP_COMMA
)
3650 || c_parser_next_token_is (parser
, CPP_SEMICOLON
)
3651 || c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
)
3652 || c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
3654 tree postfix_attrs
= NULL_TREE
;
3655 tree width
= NULL_TREE
;
3657 if (c_parser_next_token_is (parser
, CPP_COLON
))
3659 c_parser_consume_token (parser
);
3660 width
= c_parser_expr_no_commas (parser
, NULL
).value
;
3662 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
3663 postfix_attrs
= c_parser_gnu_attributes (parser
);
3664 d
= grokfield (c_parser_peek_token (parser
)->location
,
3665 declarator
, specs
, width
, &all_prefix_attrs
);
3666 decl_attributes (&d
, chainon (postfix_attrs
,
3667 all_prefix_attrs
), 0);
3668 DECL_CHAIN (d
) = decls
;
3670 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
3671 all_prefix_attrs
= chainon (c_parser_gnu_attributes (parser
),
3674 all_prefix_attrs
= prefix_attrs
;
3675 if (c_parser_next_token_is (parser
, CPP_COMMA
))
3676 c_parser_consume_token (parser
);
3677 else if (c_parser_next_token_is (parser
, CPP_SEMICOLON
)
3678 || c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
3680 /* Semicolon consumed in caller. */
3685 c_parser_error (parser
, "expected %<,%>, %<;%> or %<}%>");
3691 c_parser_error (parser
,
3692 "expected %<:%>, %<,%>, %<;%>, %<}%> or "
3693 "%<__attribute__%>");
3700 /* Parse a typeof specifier (a GNU extension).
3703 typeof ( expression )
3704 typeof ( type-name )
3707 static struct c_typespec
3708 c_parser_typeof_specifier (c_parser
*parser
)
3710 struct c_typespec ret
;
3711 ret
.kind
= ctsk_typeof
;
3712 ret
.spec
= error_mark_node
;
3713 ret
.expr
= NULL_TREE
;
3714 ret
.expr_const_operands
= true;
3715 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_TYPEOF
));
3716 c_parser_consume_token (parser
);
3717 c_inhibit_evaluation_warnings
++;
3719 matching_parens parens
;
3720 if (!parens
.require_open (parser
))
3722 c_inhibit_evaluation_warnings
--;
3726 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_id
))
3728 struct c_type_name
*type
= c_parser_type_name (parser
);
3729 c_inhibit_evaluation_warnings
--;
3733 ret
.spec
= groktypename (type
, &ret
.expr
, &ret
.expr_const_operands
);
3734 pop_maybe_used (variably_modified_type_p (ret
.spec
, NULL_TREE
));
3740 location_t here
= c_parser_peek_token (parser
)->location
;
3741 struct c_expr expr
= c_parser_expression (parser
);
3742 c_inhibit_evaluation_warnings
--;
3744 if (TREE_CODE (expr
.value
) == COMPONENT_REF
3745 && DECL_C_BIT_FIELD (TREE_OPERAND (expr
.value
, 1)))
3746 error_at (here
, "%<typeof%> applied to a bit-field");
3747 mark_exp_read (expr
.value
);
3748 ret
.spec
= TREE_TYPE (expr
.value
);
3749 was_vm
= variably_modified_type_p (ret
.spec
, NULL_TREE
);
3750 /* This is returned with the type so that when the type is
3751 evaluated, this can be evaluated. */
3753 ret
.expr
= c_fully_fold (expr
.value
, false, &ret
.expr_const_operands
);
3754 pop_maybe_used (was_vm
);
3756 parens
.skip_until_found_close (parser
);
3760 /* Parse an alignment-specifier.
3764 alignment-specifier:
3765 _Alignas ( type-name )
3766 _Alignas ( constant-expression )
3770 c_parser_alignas_specifier (c_parser
* parser
)
3772 tree ret
= error_mark_node
;
3773 location_t loc
= c_parser_peek_token (parser
)->location
;
3774 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ALIGNAS
));
3775 c_parser_consume_token (parser
);
3777 pedwarn_c99 (loc
, OPT_Wpedantic
,
3778 "ISO C99 does not support %<_Alignas%>");
3780 pedwarn_c99 (loc
, OPT_Wpedantic
,
3781 "ISO C90 does not support %<_Alignas%>");
3782 matching_parens parens
;
3783 if (!parens
.require_open (parser
))
3785 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_id
))
3787 struct c_type_name
*type
= c_parser_type_name (parser
);
3789 ret
= c_sizeof_or_alignof_type (loc
, groktypename (type
, NULL
, NULL
),
3793 ret
= c_parser_expr_no_commas (parser
, NULL
).value
;
3794 parens
.skip_until_found_close (parser
);
3798 /* Parse a declarator, possibly an abstract declarator (C90 6.5.4,
3799 6.5.5, C99 6.7.5, 6.7.6, C11 6.7.6, 6.7.7). If TYPE_SEEN_P then
3800 a typedef name may be redeclared; otherwise it may not. KIND
3801 indicates which kind of declarator is wanted. Returns a valid
3802 declarator except in the case of a syntax error in which case NULL is
3803 returned. *SEEN_ID is set to true if an identifier being declared is
3804 seen; this is used to diagnose bad forms of abstract array declarators
3805 and to determine whether an identifier list is syntactically permitted.
3808 pointer[opt] direct-declarator
3812 ( gnu-attributes[opt] declarator )
3813 direct-declarator array-declarator
3814 direct-declarator ( parameter-type-list )
3815 direct-declarator ( identifier-list[opt] )
3818 * type-qualifier-list[opt]
3819 * type-qualifier-list[opt] pointer
3821 type-qualifier-list:
3824 type-qualifier-list type-qualifier
3825 type-qualifier-list gnu-attributes
3828 [ type-qualifier-list[opt] assignment-expression[opt] ]
3829 [ static type-qualifier-list[opt] assignment-expression ]
3830 [ type-qualifier-list static assignment-expression ]
3831 [ type-qualifier-list[opt] * ]
3833 parameter-type-list:
3835 parameter-list , ...
3838 parameter-declaration
3839 parameter-list , parameter-declaration
3841 parameter-declaration:
3842 declaration-specifiers declarator gnu-attributes[opt]
3843 declaration-specifiers abstract-declarator[opt] gnu-attributes[opt]
3847 identifier-list , identifier
3849 abstract-declarator:
3851 pointer[opt] direct-abstract-declarator
3853 direct-abstract-declarator:
3854 ( gnu-attributes[opt] abstract-declarator )
3855 direct-abstract-declarator[opt] array-declarator
3856 direct-abstract-declarator[opt] ( parameter-type-list[opt] )
3861 direct-declarator ( parameter-forward-declarations
3862 parameter-type-list[opt] )
3864 direct-abstract-declarator:
3865 direct-abstract-declarator[opt] ( parameter-forward-declarations
3866 parameter-type-list[opt] )
3868 parameter-forward-declarations:
3870 parameter-forward-declarations parameter-list ;
3872 The uses of gnu-attributes shown above are GNU extensions.
3874 Some forms of array declarator are not included in C99 in the
3875 syntax for abstract declarators; these are disallowed elsewhere.
3876 This may be a defect (DR#289).
3878 This function also accepts an omitted abstract declarator as being
3879 an abstract declarator, although not part of the formal syntax. */
3881 struct c_declarator
*
3882 c_parser_declarator (c_parser
*parser
, bool type_seen_p
, c_dtr_syn kind
,
3885 /* Parse any initial pointer part. */
3886 if (c_parser_next_token_is (parser
, CPP_MULT
))
3888 struct c_declspecs
*quals_attrs
= build_null_declspecs ();
3889 struct c_declarator
*inner
;
3890 c_parser_consume_token (parser
);
3891 c_parser_declspecs (parser
, quals_attrs
, false, false, true,
3892 false, false, true, false, cla_prefer_id
);
3893 inner
= c_parser_declarator (parser
, type_seen_p
, kind
, seen_id
);
3897 return make_pointer_declarator (quals_attrs
, inner
);
3899 /* Now we have a direct declarator, direct abstract declarator or
3900 nothing (which counts as a direct abstract declarator here). */
3901 return c_parser_direct_declarator (parser
, type_seen_p
, kind
, seen_id
);
3904 /* Parse a direct declarator or direct abstract declarator; arguments
3905 as c_parser_declarator. */
3907 static struct c_declarator
*
3908 c_parser_direct_declarator (c_parser
*parser
, bool type_seen_p
, c_dtr_syn kind
,
3911 /* The direct declarator must start with an identifier (possibly
3912 omitted) or a parenthesized declarator (possibly abstract). In
3913 an ordinary declarator, initial parentheses must start a
3914 parenthesized declarator. In an abstract declarator or parameter
3915 declarator, they could start a parenthesized declarator or a
3916 parameter list. To tell which, the open parenthesis and any
3917 following gnu-attributes must be read. If a declaration
3918 specifier or standard attributes follow, then it is a parameter
3919 list; if the specifier is a typedef name, there might be an
3920 ambiguity about redeclaring it, which is resolved in the
3921 direction of treating it as a typedef name. If a close
3922 parenthesis follows, it is also an empty parameter list, as the
3923 syntax does not permit empty abstract declarators. Otherwise, it
3924 is a parenthesized declarator (in which case the analysis may be
3925 repeated inside it, recursively).
3927 ??? There is an ambiguity in a parameter declaration "int
3928 (__attribute__((foo)) x)", where x is not a typedef name: it
3929 could be an abstract declarator for a function, or declare x with
3930 parentheses. The proper resolution of this ambiguity needs
3931 documenting. At present we follow an accident of the old
3932 parser's implementation, whereby the first parameter must have
3933 some declaration specifiers other than just gnu-attributes. Thus as
3934 a parameter declaration it is treated as a parenthesized
3935 parameter named x, and as an abstract declarator it is
3938 ??? Also following the old parser, gnu-attributes inside an empty
3939 parameter list are ignored, making it a list not yielding a
3940 prototype, rather than giving an error or making it have one
3941 parameter with implicit type int.
3943 ??? Also following the old parser, typedef names may be
3944 redeclared in declarators, but not Objective-C class names. */
3946 if (kind
!= C_DTR_ABSTRACT
3947 && c_parser_next_token_is (parser
, CPP_NAME
)
3949 && (c_parser_peek_token (parser
)->id_kind
== C_ID_TYPENAME
3950 || c_parser_peek_token (parser
)->id_kind
== C_ID_CLASSNAME
))
3951 || c_parser_peek_token (parser
)->id_kind
== C_ID_ID
))
3953 struct c_declarator
*inner
3954 = build_id_declarator (c_parser_peek_token (parser
)->value
);
3956 inner
->id_loc
= c_parser_peek_token (parser
)->location
;
3957 c_parser_consume_token (parser
);
3958 if (c_parser_nth_token_starts_std_attributes (parser
, 1))
3959 inner
->u
.id
.attrs
= c_parser_std_attribute_specifier_sequence (parser
);
3960 return c_parser_direct_declarator_inner (parser
, *seen_id
, inner
);
3963 if (kind
!= C_DTR_NORMAL
3964 && c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
)
3965 && !c_parser_nth_token_starts_std_attributes (parser
, 1))
3967 struct c_declarator
*inner
= build_id_declarator (NULL_TREE
);
3968 inner
->id_loc
= c_parser_peek_token (parser
)->location
;
3969 return c_parser_direct_declarator_inner (parser
, *seen_id
, inner
);
3972 /* Either we are at the end of an abstract declarator, or we have
3975 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
3978 struct c_declarator
*inner
;
3979 c_parser_consume_token (parser
);
3980 bool have_gnu_attrs
= c_parser_next_token_is_keyword (parser
,
3982 attrs
= c_parser_gnu_attributes (parser
);
3983 if (kind
!= C_DTR_NORMAL
3984 && (c_parser_next_token_starts_declspecs (parser
)
3986 && c_parser_nth_token_starts_std_attributes (parser
, 1))
3987 || c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
)))
3989 struct c_arg_info
*args
3990 = c_parser_parms_declarator (parser
, kind
== C_DTR_NORMAL
,
3991 attrs
, have_gnu_attrs
);
3996 inner
= build_id_declarator (NULL_TREE
);
3998 && args
->types
!= error_mark_node
3999 && TREE_CODE (TREE_VALUE (args
->types
)) == IDENTIFIER_NODE
)
4000 && c_parser_nth_token_starts_std_attributes (parser
, 1))
4003 = c_parser_std_attribute_specifier_sequence (parser
);
4005 inner
= build_attrs_declarator (std_attrs
, inner
);
4007 inner
= build_function_declarator (args
, inner
);
4008 return c_parser_direct_declarator_inner (parser
, *seen_id
,
4012 /* A parenthesized declarator. */
4013 inner
= c_parser_declarator (parser
, type_seen_p
, kind
, seen_id
);
4014 if (inner
!= NULL
&& attrs
!= NULL
)
4015 inner
= build_attrs_declarator (attrs
, inner
);
4016 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4018 c_parser_consume_token (parser
);
4022 return c_parser_direct_declarator_inner (parser
, *seen_id
, inner
);
4026 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4033 if (kind
== C_DTR_NORMAL
)
4035 c_parser_error (parser
, "expected identifier or %<(%>");
4039 return build_id_declarator (NULL_TREE
);
4043 /* Parse part of a direct declarator or direct abstract declarator,
4044 given that some (in INNER) has already been parsed; ID_PRESENT is
4045 true if an identifier is present, false for an abstract
4048 static struct c_declarator
*
4049 c_parser_direct_declarator_inner (c_parser
*parser
, bool id_present
,
4050 struct c_declarator
*inner
)
4052 /* Parse a sequence of array declarators and parameter lists. */
4053 if (c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
)
4054 && !c_parser_nth_token_starts_std_attributes (parser
, 1))
4056 location_t brace_loc
= c_parser_peek_token (parser
)->location
;
4057 struct c_declarator
*declarator
;
4058 struct c_declspecs
*quals_attrs
= build_null_declspecs ();
4061 struct c_expr dimen
;
4062 dimen
.value
= NULL_TREE
;
4063 dimen
.original_code
= ERROR_MARK
;
4064 dimen
.original_type
= NULL_TREE
;
4065 c_parser_consume_token (parser
);
4066 c_parser_declspecs (parser
, quals_attrs
, false, false, true,
4067 false, false, false, false, cla_prefer_id
);
4068 static_seen
= c_parser_next_token_is_keyword (parser
, RID_STATIC
);
4070 c_parser_consume_token (parser
);
4071 if (static_seen
&& !quals_attrs
->declspecs_seen_p
)
4072 c_parser_declspecs (parser
, quals_attrs
, false, false, true,
4073 false, false, false, false, cla_prefer_id
);
4074 if (!quals_attrs
->declspecs_seen_p
)
4076 /* If "static" is present, there must be an array dimension.
4077 Otherwise, there may be a dimension, "*", or no
4082 dimen
= c_parser_expr_no_commas (parser
, NULL
);
4086 if (c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
4088 dimen
.value
= NULL_TREE
;
4091 else if (c_parser_next_token_is (parser
, CPP_MULT
))
4093 if (c_parser_peek_2nd_token (parser
)->type
== CPP_CLOSE_SQUARE
)
4095 dimen
.value
= NULL_TREE
;
4097 c_parser_consume_token (parser
);
4102 dimen
= c_parser_expr_no_commas (parser
, NULL
);
4108 dimen
= c_parser_expr_no_commas (parser
, NULL
);
4111 if (c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
4112 c_parser_consume_token (parser
);
4115 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
4120 dimen
= convert_lvalue_to_rvalue (brace_loc
, dimen
, true, true);
4121 declarator
= build_array_declarator (brace_loc
, dimen
.value
, quals_attrs
,
4122 static_seen
, star_seen
);
4123 if (declarator
== NULL
)
4125 if (c_parser_nth_token_starts_std_attributes (parser
, 1))
4128 = c_parser_std_attribute_specifier_sequence (parser
);
4130 inner
= build_attrs_declarator (std_attrs
, inner
);
4132 inner
= set_array_declarator_inner (declarator
, inner
);
4133 return c_parser_direct_declarator_inner (parser
, id_present
, inner
);
4135 else if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
4138 struct c_arg_info
*args
;
4139 c_parser_consume_token (parser
);
4140 bool have_gnu_attrs
= c_parser_next_token_is_keyword (parser
,
4142 attrs
= c_parser_gnu_attributes (parser
);
4143 args
= c_parser_parms_declarator (parser
, id_present
, attrs
,
4150 && args
->types
!= error_mark_node
4151 && TREE_CODE (TREE_VALUE (args
->types
)) == IDENTIFIER_NODE
)
4152 && c_parser_nth_token_starts_std_attributes (parser
, 1))
4155 = c_parser_std_attribute_specifier_sequence (parser
);
4157 inner
= build_attrs_declarator (std_attrs
, inner
);
4159 inner
= build_function_declarator (args
, inner
);
4160 return c_parser_direct_declarator_inner (parser
, id_present
, inner
);
4166 /* Parse a parameter list or identifier list, including the closing
4167 parenthesis but not the opening one. ATTRS are the gnu-attributes
4168 at the start of the list. ID_LIST_OK is true if an identifier list
4169 is acceptable; such a list must not have attributes at the start.
4170 HAVE_GNU_ATTRS says whether any gnu-attributes (including empty
4171 attributes) were present (in which case standard attributes cannot
4174 static struct c_arg_info
*
4175 c_parser_parms_declarator (c_parser
*parser
, bool id_list_ok
, tree attrs
,
4176 bool have_gnu_attrs
)
4179 declare_parm_level ();
4180 /* If the list starts with an identifier, it is an identifier list.
4181 Otherwise, it is either a prototype list or an empty list. */
4184 && c_parser_next_token_is (parser
, CPP_NAME
)
4185 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
4187 /* Look ahead to detect typos in type names. */
4188 && c_parser_peek_2nd_token (parser
)->type
!= CPP_NAME
4189 && c_parser_peek_2nd_token (parser
)->type
!= CPP_MULT
4190 && c_parser_peek_2nd_token (parser
)->type
!= CPP_OPEN_PAREN
4191 && c_parser_peek_2nd_token (parser
)->type
!= CPP_OPEN_SQUARE
4192 && c_parser_peek_2nd_token (parser
)->type
!= CPP_KEYWORD
)
4194 tree list
= NULL_TREE
, *nextp
= &list
;
4195 while (c_parser_next_token_is (parser
, CPP_NAME
)
4196 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
)
4198 *nextp
= build_tree_list (NULL_TREE
,
4199 c_parser_peek_token (parser
)->value
);
4200 nextp
= & TREE_CHAIN (*nextp
);
4201 c_parser_consume_token (parser
);
4202 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
4204 c_parser_consume_token (parser
);
4205 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4207 c_parser_error (parser
, "expected identifier");
4211 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4213 struct c_arg_info
*ret
= build_arg_info ();
4215 c_parser_consume_token (parser
);
4221 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4229 struct c_arg_info
*ret
4230 = c_parser_parms_list_declarator (parser
, attrs
, NULL
, have_gnu_attrs
);
4236 /* Parse a parameter list (possibly empty), including the closing
4237 parenthesis but not the opening one. ATTRS are the gnu-attributes
4238 at the start of the list; if HAVE_GNU_ATTRS, there were some such
4239 attributes (possibly empty, in which case ATTRS is NULL_TREE),
4240 which means standard attributes cannot start the list. EXPR is
4241 NULL or an expression that needs to be evaluated for the side
4242 effects of array size expressions in the parameters. */
4244 static struct c_arg_info
*
4245 c_parser_parms_list_declarator (c_parser
*parser
, tree attrs
, tree expr
,
4246 bool have_gnu_attrs
)
4248 bool bad_parm
= false;
4250 /* ??? Following the old parser, forward parameter declarations may
4251 use abstract declarators, and if no real parameter declarations
4252 follow the forward declarations then this is not diagnosed. Also
4253 note as above that gnu-attributes are ignored as the only contents of
4254 the parentheses, or as the only contents after forward
4256 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4258 struct c_arg_info
*ret
= build_arg_info ();
4259 c_parser_consume_token (parser
);
4262 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
4264 struct c_arg_info
*ret
= build_arg_info ();
4266 if (flag_allow_parameterless_variadic_functions
)
4268 /* F (...) is allowed. */
4269 ret
->types
= NULL_TREE
;
4273 /* Suppress -Wold-style-definition for this case. */
4274 ret
->types
= error_mark_node
;
4275 error_at (c_parser_peek_token (parser
)->location
,
4276 "ISO C requires a named argument before %<...%>");
4278 c_parser_consume_token (parser
);
4279 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4281 c_parser_consume_token (parser
);
4286 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4291 /* Nonempty list of parameters, either terminated with semicolon
4292 (forward declarations; recurse) or with close parenthesis (normal
4293 function) or with ", ... )" (variadic function). */
4296 /* Parse a parameter. */
4297 struct c_parm
*parm
= c_parser_parameter_declaration (parser
, attrs
,
4300 have_gnu_attrs
= false;
4304 push_parm_decl (parm
, &expr
);
4305 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
4308 c_parser_consume_token (parser
);
4309 mark_forward_parm_decls ();
4310 bool new_have_gnu_attrs
4311 = c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
);
4312 new_attrs
= c_parser_gnu_attributes (parser
);
4313 return c_parser_parms_list_declarator (parser
, new_attrs
, expr
,
4314 new_have_gnu_attrs
);
4316 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4318 c_parser_consume_token (parser
);
4322 return get_parm_info (false, expr
);
4324 if (!c_parser_require (parser
, CPP_COMMA
,
4325 "expected %<;%>, %<,%> or %<)%>",
4326 UNKNOWN_LOCATION
, false))
4328 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
4331 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
4333 c_parser_consume_token (parser
);
4334 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4336 c_parser_consume_token (parser
);
4340 return get_parm_info (true, expr
);
4344 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4352 /* Parse a parameter declaration. ATTRS are the gnu-attributes at the
4353 start of the declaration if it is the first parameter;
4354 HAVE_GNU_ATTRS is true if there were any gnu-attributes there (even
4357 static struct c_parm
*
4358 c_parser_parameter_declaration (c_parser
*parser
, tree attrs
,
4359 bool have_gnu_attrs
)
4361 struct c_declspecs
*specs
;
4362 struct c_declarator
*declarator
;
4364 tree postfix_attrs
= NULL_TREE
;
4367 /* Accept #pragmas between parameter declarations. */
4368 while (c_parser_next_token_is (parser
, CPP_PRAGMA
))
4369 c_parser_pragma (parser
, pragma_param
, NULL
);
4371 if (!c_parser_next_token_starts_declspecs (parser
)
4372 && !c_parser_nth_token_starts_std_attributes (parser
, 1))
4374 c_token
*token
= c_parser_peek_token (parser
);
4377 c_parser_set_source_position_from_token (token
);
4378 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_type
))
4380 auto_diagnostic_group d
;
4381 name_hint hint
= lookup_name_fuzzy (token
->value
,
4382 FUZZY_LOOKUP_TYPENAME
,
4384 if (const char *suggestion
= hint
.suggestion ())
4386 gcc_rich_location
richloc (token
->location
);
4387 richloc
.add_fixit_replace (suggestion
);
4389 "unknown type name %qE; did you mean %qs?",
4390 token
->value
, suggestion
);
4393 error_at (token
->location
, "unknown type name %qE", token
->value
);
4394 parser
->error
= true;
4396 /* ??? In some Objective-C cases '...' isn't applicable so there
4397 should be a different message. */
4399 c_parser_error (parser
,
4400 "expected declaration specifiers or %<...%>");
4401 c_parser_skip_to_end_of_parameter (parser
);
4405 location_t start_loc
= c_parser_peek_token (parser
)->location
;
4407 specs
= build_null_declspecs ();
4410 declspecs_add_attrs (input_location
, specs
, attrs
);
4413 c_parser_declspecs (parser
, specs
, true, true, true, true, false,
4414 !have_gnu_attrs
, true, cla_nonabstract_decl
);
4415 finish_declspecs (specs
);
4416 pending_xref_error ();
4417 prefix_attrs
= specs
->attrs
;
4418 specs
->attrs
= NULL_TREE
;
4419 declarator
= c_parser_declarator (parser
,
4420 specs
->typespec_kind
!= ctsk_none
,
4421 C_DTR_PARM
, &dummy
);
4422 if (declarator
== NULL
)
4424 c_parser_skip_until_found (parser
, CPP_COMMA
, NULL
);
4427 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
4428 postfix_attrs
= c_parser_gnu_attributes (parser
);
4430 /* Generate a location for the parameter, ranging from the start of the
4431 initial token to the end of the final token.
4433 If we have a identifier, then use it for the caret location, e.g.
4435 extern int callee (int one, int (*two)(int, int), float three);
4436 ~~~~~~^~~~~~~~~~~~~~
4438 otherwise, reuse the start location for the caret location e.g.:
4440 extern int callee (int one, int (*)(int, int), float three);
4443 location_t end_loc
= parser
->last_token_location
;
4445 /* Find any cdk_id declarator; determine if we have an identifier. */
4446 c_declarator
*id_declarator
= declarator
;
4447 while (id_declarator
&& id_declarator
->kind
!= cdk_id
)
4448 id_declarator
= id_declarator
->declarator
;
4449 location_t caret_loc
= (id_declarator
->u
.id
.id
4450 ? id_declarator
->id_loc
4452 location_t param_loc
= make_location (caret_loc
, start_loc
, end_loc
);
4454 return build_c_parm (specs
, chainon (postfix_attrs
, prefix_attrs
),
4455 declarator
, param_loc
);
4458 /* Parse a string literal in an asm expression. It should not be
4459 translated, and wide string literals are an error although
4460 permitted by the syntax. This is a GNU extension.
4467 c_parser_asm_string_literal (c_parser
*parser
)
4470 int save_flag
= warn_overlength_strings
;
4471 warn_overlength_strings
= 0;
4472 str
= c_parser_string_literal (parser
, false, false).value
;
4473 warn_overlength_strings
= save_flag
;
4477 /* Parse a simple asm expression. This is used in restricted
4478 contexts, where a full expression with inputs and outputs does not
4479 make sense. This is a GNU extension.
4482 asm ( asm-string-literal )
4486 c_parser_simple_asm_expr (c_parser
*parser
)
4489 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ASM
));
4490 c_parser_consume_token (parser
);
4491 matching_parens parens
;
4492 if (!parens
.require_open (parser
))
4494 str
= c_parser_asm_string_literal (parser
);
4495 if (!parens
.require_close (parser
))
4497 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
4504 c_parser_gnu_attribute_any_word (c_parser
*parser
)
4506 tree attr_name
= NULL_TREE
;
4508 if (c_parser_next_token_is (parser
, CPP_KEYWORD
))
4510 /* ??? See comment above about what keywords are accepted here. */
4512 switch (c_parser_peek_token (parser
)->keyword
)
4543 case RID_TRANSACTION_ATOMIC
:
4544 case RID_TRANSACTION_CANCEL
:
4560 /* Accept __attribute__((__const)) as __attribute__((const)) etc. */
4561 attr_name
= ridpointers
[(int) c_parser_peek_token (parser
)->keyword
];
4563 else if (c_parser_next_token_is (parser
, CPP_NAME
))
4564 attr_name
= c_parser_peek_token (parser
)->value
;
4569 /* Parse attribute arguments. This is a common form of syntax
4570 covering all currently valid GNU and standard attributes.
4572 gnu-attribute-arguments:
4574 identifier , nonempty-expr-list
4577 where the "identifier" must not be declared as a type. ??? Why not
4578 allow identifiers declared as types to start the arguments? */
4581 c_parser_attribute_arguments (c_parser
*parser
, bool takes_identifier
,
4582 bool require_string
, bool allow_empty_args
)
4584 vec
<tree
, va_gc
> *expr_list
;
4586 /* Parse the attribute contents. If they start with an
4587 identifier which is followed by a comma or close
4588 parenthesis, then the arguments start with that
4589 identifier; otherwise they are an expression list.
4590 In objective-c the identifier may be a classname. */
4591 if (c_parser_next_token_is (parser
, CPP_NAME
)
4592 && (c_parser_peek_token (parser
)->id_kind
== C_ID_ID
4593 || (c_dialect_objc ()
4594 && c_parser_peek_token (parser
)->id_kind
4596 && ((c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
)
4597 || (c_parser_peek_2nd_token (parser
)->type
4598 == CPP_CLOSE_PAREN
))
4599 && (takes_identifier
4600 || (c_dialect_objc ()
4601 && c_parser_peek_token (parser
)->id_kind
4602 == C_ID_CLASSNAME
)))
4604 tree arg1
= c_parser_peek_token (parser
)->value
;
4605 c_parser_consume_token (parser
);
4606 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4607 attr_args
= build_tree_list (NULL_TREE
, arg1
);
4611 c_parser_consume_token (parser
);
4612 expr_list
= c_parser_expr_list (parser
, false, true,
4613 NULL
, NULL
, NULL
, NULL
);
4614 tree_list
= build_tree_list_vec (expr_list
);
4615 attr_args
= tree_cons (NULL_TREE
, arg1
, tree_list
);
4616 release_tree_vector (expr_list
);
4621 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4623 if (!allow_empty_args
)
4624 error_at (c_parser_peek_token (parser
)->location
,
4625 "parentheses must be omitted if "
4626 "attribute argument list is empty");
4627 attr_args
= NULL_TREE
;
4629 else if (require_string
)
4631 /* The only valid argument for this attribute is a string
4632 literal. Handle this specially here to avoid accepting
4633 string literals with excess parentheses. */
4634 tree string
= c_parser_string_literal (parser
, false, true).value
;
4635 attr_args
= build_tree_list (NULL_TREE
, string
);
4639 expr_list
= c_parser_expr_list (parser
, false, true,
4640 NULL
, NULL
, NULL
, NULL
);
4641 attr_args
= build_tree_list_vec (expr_list
);
4642 release_tree_vector (expr_list
);
4648 /* Parse (possibly empty) gnu-attributes. This is a GNU extension.
4652 gnu-attributes gnu-attribute
4655 __attribute__ ( ( gnu-attribute-list ) )
4659 gnu-attribute_list , gnu-attrib
4664 any-word ( gnu-attribute-arguments )
4666 where "any-word" may be any identifier (including one declared as a
4667 type), a reserved word storage class specifier, type specifier or
4668 type qualifier. ??? This still leaves out most reserved keywords
4669 (following the old parser), shouldn't we include them?
4670 When EXPECT_COMMA is true, expect the attribute to be preceded
4671 by a comma and fail if it isn't.
4672 When EMPTY_OK is true, allow and consume any number of consecutive
4673 commas with no attributes in between. */
4676 c_parser_gnu_attribute (c_parser
*parser
, tree attrs
,
4677 bool expect_comma
= false, bool empty_ok
= true)
4679 bool comma_first
= c_parser_next_token_is (parser
, CPP_COMMA
);
4681 && !c_parser_next_token_is (parser
, CPP_NAME
)
4682 && !c_parser_next_token_is (parser
, CPP_KEYWORD
))
4685 while (c_parser_next_token_is (parser
, CPP_COMMA
))
4687 c_parser_consume_token (parser
);
4692 tree attr_name
= c_parser_gnu_attribute_any_word (parser
);
4693 if (attr_name
== NULL_TREE
)
4696 attr_name
= canonicalize_attr_name (attr_name
);
4697 c_parser_consume_token (parser
);
4700 if (c_parser_next_token_is_not (parser
, CPP_OPEN_PAREN
))
4702 if (expect_comma
&& !comma_first
)
4704 /* A comma is missing between the last attribute on the chain
4706 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4708 return error_mark_node
;
4710 attr
= build_tree_list (attr_name
, NULL_TREE
);
4711 /* Add this attribute to the list. */
4712 attrs
= chainon (attrs
, attr
);
4715 c_parser_consume_token (parser
);
4718 = c_parser_attribute_arguments (parser
,
4719 attribute_takes_identifier_p (attr_name
),
4722 attr
= build_tree_list (attr_name
, attr_args
);
4723 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4724 c_parser_consume_token (parser
);
4727 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4729 return error_mark_node
;
4732 if (expect_comma
&& !comma_first
)
4734 /* A comma is missing between the last attribute on the chain
4736 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4738 return error_mark_node
;
4741 /* Add this attribute to the list. */
4742 attrs
= chainon (attrs
, attr
);
4747 c_parser_gnu_attributes (c_parser
*parser
)
4749 tree attrs
= NULL_TREE
;
4750 while (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
4752 bool save_translate_strings_p
= parser
->translate_strings_p
;
4753 parser
->translate_strings_p
= false;
4754 /* Consume the `__attribute__' keyword. */
4755 c_parser_consume_token (parser
);
4756 /* Look for the two `(' tokens. */
4757 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
4759 parser
->translate_strings_p
= save_translate_strings_p
;
4762 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
4764 parser
->translate_strings_p
= save_translate_strings_p
;
4765 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
4768 /* Parse the attribute list. Require a comma between successive
4769 (possibly empty) attributes. */
4770 for (bool expect_comma
= false; ; expect_comma
= true)
4772 /* Parse a single attribute. */
4773 tree attr
= c_parser_gnu_attribute (parser
, attrs
, expect_comma
);
4774 if (attr
== error_mark_node
)
4781 /* Look for the two `)' tokens. */
4782 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4783 c_parser_consume_token (parser
);
4786 parser
->translate_strings_p
= save_translate_strings_p
;
4787 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4791 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4792 c_parser_consume_token (parser
);
4795 parser
->translate_strings_p
= save_translate_strings_p
;
4796 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4800 parser
->translate_strings_p
= save_translate_strings_p
;
4806 /* Parse an optional balanced token sequence.
4808 balanced-token-sequence:
4810 balanced-token-sequence balanced-token
4813 ( balanced-token-sequence[opt] )
4814 [ balanced-token-sequence[opt] ]
4815 { balanced-token-sequence[opt] }
4816 any token other than ()[]{}
4820 c_parser_balanced_token_sequence (c_parser
*parser
)
4824 c_token
*token
= c_parser_peek_token (parser
);
4825 switch (token
->type
)
4827 case CPP_OPEN_BRACE
:
4829 matching_braces braces
;
4830 braces
.consume_open (parser
);
4831 c_parser_balanced_token_sequence (parser
);
4832 braces
.require_close (parser
);
4836 case CPP_OPEN_PAREN
:
4838 matching_parens parens
;
4839 parens
.consume_open (parser
);
4840 c_parser_balanced_token_sequence (parser
);
4841 parens
.require_close (parser
);
4845 case CPP_OPEN_SQUARE
:
4846 c_parser_consume_token (parser
);
4847 c_parser_balanced_token_sequence (parser
);
4848 c_parser_require (parser
, CPP_CLOSE_SQUARE
, "expected %<]%>");
4851 case CPP_CLOSE_BRACE
:
4852 case CPP_CLOSE_PAREN
:
4853 case CPP_CLOSE_SQUARE
:
4858 c_parser_consume_pragma (parser
);
4859 c_parser_skip_to_pragma_eol (parser
, false);
4863 c_parser_consume_token (parser
);
4869 /* Parse standard (C2X) attributes (including GNU attributes in the
4872 attribute-specifier-sequence:
4873 attribute-specifier-sequence[opt] attribute-specifier
4875 attribute-specifier:
4876 [ [ attribute-list ] ]
4880 attribute-list, attribute[opt]
4883 attribute-token attribute-argument-clause[opt]
4887 attribute-prefixed-token
4892 attribute-prefixed-token:
4893 attribute-prefix :: identifier
4898 attribute-argument-clause:
4899 ( balanced-token-sequence[opt] )
4901 Keywords are accepted as identifiers for this purpose.
4905 c_parser_std_attribute (c_parser
*parser
, bool for_tm
)
4907 c_token
*token
= c_parser_peek_token (parser
);
4908 tree ns
, name
, attribute
;
4910 /* Parse the attribute-token. */
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
);
4918 if (c_parser_next_token_is (parser
, CPP_SCOPE
))
4921 c_parser_consume_token (parser
);
4922 token
= c_parser_peek_token (parser
);
4923 if (token
->type
!= CPP_NAME
&& token
->type
!= CPP_KEYWORD
)
4925 c_parser_error (parser
, "expected identifier");
4926 return error_mark_node
;
4928 name
= canonicalize_attr_name (token
->value
);
4929 c_parser_consume_token (parser
);
4933 attribute
= build_tree_list (build_tree_list (ns
, name
), NULL_TREE
);
4935 /* Parse the arguments, if any. */
4936 const attribute_spec
*as
= lookup_attribute_spec (TREE_PURPOSE (attribute
));
4937 if (c_parser_next_token_is_not (parser
, CPP_OPEN_PAREN
))
4940 location_t open_loc
= c_parser_peek_token (parser
)->location
;
4941 matching_parens parens
;
4942 parens
.consume_open (parser
);
4943 if ((as
&& as
->max_length
== 0)
4944 /* Special-case the transactional-memory attribute "outer",
4945 which is specially handled but not registered as an
4946 attribute, to avoid allowing arbitrary balanced token
4947 sequences as arguments. */
4948 || is_attribute_p ("outer", name
))
4950 error_at (open_loc
, "%qE attribute does not take any arguments", name
);
4951 parens
.skip_until_found_close (parser
);
4952 return error_mark_node
;
4954 /* If this is a fake attribute created to handle -Wno-attributes,
4955 we must skip parsing the arguments. */
4956 if (as
&& !attribute_ignored_p (as
))
4958 bool takes_identifier
4960 && strcmp (IDENTIFIER_POINTER (ns
), "gnu") == 0
4961 && attribute_takes_identifier_p (name
));
4964 && (strcmp (IDENTIFIER_POINTER (name
), "deprecated") == 0
4965 || strcmp (IDENTIFIER_POINTER (name
), "nodiscard") == 0));
4966 TREE_VALUE (attribute
)
4967 = c_parser_attribute_arguments (parser
, takes_identifier
,
4968 require_string
, false);
4971 c_parser_balanced_token_sequence (parser
);
4972 parens
.require_close (parser
);
4975 if (ns
== NULL_TREE
&& !for_tm
&& !as
)
4977 /* An attribute with standard syntax and no namespace specified
4978 is a constraint violation if it is not one of the known
4979 standard attributes. Diagnose it here with a pedwarn and
4980 then discard it to prevent a duplicate warning later. */
4981 pedwarn (input_location
, OPT_Wattributes
, "%qE attribute ignored",
4983 return error_mark_node
;
4989 c_parser_std_attribute_specifier (c_parser
*parser
, bool for_tm
)
4991 location_t loc
= c_parser_peek_token (parser
)->location
;
4992 if (!c_parser_require (parser
, CPP_OPEN_SQUARE
, "expected %<[%>"))
4994 if (!c_parser_require (parser
, CPP_OPEN_SQUARE
, "expected %<[%>"))
4996 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
, "expected %<]%>");
5000 pedwarn_c11 (loc
, OPT_Wpedantic
,
5001 "ISO C does not support %<[[]]%> attributes before C2X");
5002 tree attributes
= NULL_TREE
;
5005 c_token
*token
= c_parser_peek_token (parser
);
5006 if (token
->type
== CPP_CLOSE_SQUARE
)
5008 if (token
->type
== CPP_COMMA
)
5010 c_parser_consume_token (parser
);
5013 tree attribute
= c_parser_std_attribute (parser
, for_tm
);
5014 if (attribute
!= error_mark_node
)
5016 TREE_CHAIN (attribute
) = attributes
;
5017 attributes
= attribute
;
5019 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
5022 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
, "expected %<]%>");
5023 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
, "expected %<]%>");
5024 return nreverse (attributes
);
5027 /* Look past an optional balanced token sequence of raw look-ahead
5028 tokens starting with the *Nth token. *N is updated to point to the
5029 following token. Return true if such a sequence was found, false
5030 if the tokens parsed were not balanced. */
5033 c_parser_check_balanced_raw_token_sequence (c_parser
*parser
, unsigned int *n
)
5037 c_token
*token
= c_parser_peek_nth_token_raw (parser
, *n
);
5038 switch (token
->type
)
5040 case CPP_OPEN_BRACE
:
5043 if (c_parser_check_balanced_raw_token_sequence (parser
, n
))
5045 token
= c_parser_peek_nth_token_raw (parser
, *n
);
5046 if (token
->type
== CPP_CLOSE_BRACE
)
5056 case CPP_OPEN_PAREN
:
5059 if (c_parser_check_balanced_raw_token_sequence (parser
, n
))
5061 token
= c_parser_peek_nth_token_raw (parser
, *n
);
5062 if (token
->type
== CPP_CLOSE_PAREN
)
5072 case CPP_OPEN_SQUARE
:
5075 if (c_parser_check_balanced_raw_token_sequence (parser
, n
))
5077 token
= c_parser_peek_nth_token_raw (parser
, *n
);
5078 if (token
->type
== CPP_CLOSE_SQUARE
)
5088 case CPP_CLOSE_BRACE
:
5089 case CPP_CLOSE_PAREN
:
5090 case CPP_CLOSE_SQUARE
:
5101 /* Return whether standard attributes start with the Nth token. */
5104 c_parser_nth_token_starts_std_attributes (c_parser
*parser
, unsigned int n
)
5106 if (!(c_parser_peek_nth_token (parser
, n
)->type
== CPP_OPEN_SQUARE
5107 && c_parser_peek_nth_token (parser
, n
+ 1)->type
== CPP_OPEN_SQUARE
))
5109 /* In C, '[[' must start attributes. In Objective-C, we need to
5110 check whether '[[' is matched by ']]'. */
5111 if (!c_dialect_objc ())
5114 if (!c_parser_check_balanced_raw_token_sequence (parser
, &n
))
5116 c_token
*token
= c_parser_peek_nth_token_raw (parser
, n
);
5117 if (token
->type
!= CPP_CLOSE_SQUARE
)
5119 token
= c_parser_peek_nth_token_raw (parser
, n
+ 1);
5120 return token
->type
== CPP_CLOSE_SQUARE
;
5124 c_parser_std_attribute_specifier_sequence (c_parser
*parser
)
5126 tree attributes
= NULL_TREE
;
5129 tree attrs
= c_parser_std_attribute_specifier (parser
, false);
5130 attributes
= chainon (attributes
, attrs
);
5132 while (c_parser_nth_token_starts_std_attributes (parser
, 1));
5136 /* Parse a type name (C90 6.5.5, C99 6.7.6, C11 6.7.7). ALIGNAS_OK
5137 says whether alignment specifiers are OK (only in cases that might
5138 be the type name of a compound literal).
5141 specifier-qualifier-list abstract-declarator[opt]
5144 struct c_type_name
*
5145 c_parser_type_name (c_parser
*parser
, bool alignas_ok
)
5147 struct c_declspecs
*specs
= build_null_declspecs ();
5148 struct c_declarator
*declarator
;
5149 struct c_type_name
*ret
;
5151 c_parser_declspecs (parser
, specs
, false, true, true, alignas_ok
, false,
5152 false, true, cla_prefer_type
);
5153 if (!specs
->declspecs_seen_p
)
5155 c_parser_error (parser
, "expected specifier-qualifier-list");
5158 if (specs
->type
!= error_mark_node
)
5160 pending_xref_error ();
5161 finish_declspecs (specs
);
5163 declarator
= c_parser_declarator (parser
,
5164 specs
->typespec_kind
!= ctsk_none
,
5165 C_DTR_ABSTRACT
, &dummy
);
5166 if (declarator
== NULL
)
5168 ret
= XOBNEW (&parser_obstack
, struct c_type_name
);
5170 ret
->declarator
= declarator
;
5174 /* Parse an initializer (C90 6.5.7, C99 6.7.8, C11 6.7.9).
5177 assignment-expression
5178 { initializer-list }
5179 { initializer-list , }
5182 designation[opt] initializer
5183 initializer-list , designation[opt] initializer
5190 designator-list designator
5197 [ constant-expression ]
5209 [ constant-expression ... constant-expression ]
5211 Any expression without commas is accepted in the syntax for the
5212 constant-expressions, with non-constant expressions rejected later.
5214 This function is only used for top-level initializers; for nested
5215 ones, see c_parser_initval. */
5217 static struct c_expr
5218 c_parser_initializer (c_parser
*parser
)
5220 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
5221 return c_parser_braced_init (parser
, NULL_TREE
, false, NULL
);
5225 location_t loc
= c_parser_peek_token (parser
)->location
;
5226 ret
= c_parser_expr_no_commas (parser
, NULL
);
5227 if (TREE_CODE (ret
.value
) != STRING_CST
5228 && TREE_CODE (ret
.value
) != COMPOUND_LITERAL_EXPR
)
5229 ret
= convert_lvalue_to_rvalue (loc
, ret
, true, true);
5234 /* The location of the last comma within the current initializer list,
5235 or UNKNOWN_LOCATION if not within one. */
5237 location_t last_init_list_comma
;
5239 /* Parse a braced initializer list. TYPE is the type specified for a
5240 compound literal, and NULL_TREE for other initializers and for
5241 nested braced lists. NESTED_P is true for nested braced lists,
5242 false for the list of a compound literal or the list that is the
5243 top-level initializer in a declaration. */
5245 static struct c_expr
5246 c_parser_braced_init (c_parser
*parser
, tree type
, bool nested_p
,
5247 struct obstack
*outer_obstack
)
5250 struct obstack braced_init_obstack
;
5251 location_t brace_loc
= c_parser_peek_token (parser
)->location
;
5252 gcc_obstack_init (&braced_init_obstack
);
5253 gcc_assert (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
));
5254 matching_braces braces
;
5255 braces
.consume_open (parser
);
5258 finish_implicit_inits (brace_loc
, outer_obstack
);
5259 push_init_level (brace_loc
, 0, &braced_init_obstack
);
5262 really_start_incremental_init (type
);
5263 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
5265 pedwarn (brace_loc
, OPT_Wpedantic
, "ISO C forbids empty initializer braces");
5269 /* Parse a non-empty initializer list, possibly with a trailing
5273 c_parser_initelt (parser
, &braced_init_obstack
);
5276 if (c_parser_next_token_is (parser
, CPP_COMMA
))
5278 last_init_list_comma
= c_parser_peek_token (parser
)->location
;
5279 c_parser_consume_token (parser
);
5283 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
5287 c_token
*next_tok
= c_parser_peek_token (parser
);
5288 if (next_tok
->type
!= CPP_CLOSE_BRACE
)
5291 ret
.original_code
= ERROR_MARK
;
5292 ret
.original_type
= NULL
;
5293 braces
.skip_until_found_close (parser
);
5294 pop_init_level (brace_loc
, 0, &braced_init_obstack
, last_init_list_comma
);
5295 obstack_free (&braced_init_obstack
, NULL
);
5298 location_t close_loc
= next_tok
->location
;
5299 c_parser_consume_token (parser
);
5300 ret
= pop_init_level (brace_loc
, 0, &braced_init_obstack
, close_loc
);
5301 obstack_free (&braced_init_obstack
, NULL
);
5302 set_c_expr_source_range (&ret
, brace_loc
, close_loc
);
5306 /* Parse a nested initializer, including designators. */
5309 c_parser_initelt (c_parser
*parser
, struct obstack
* braced_init_obstack
)
5311 /* Parse any designator or designator list. A single array
5312 designator may have the subsequent "=" omitted in GNU C, but a
5313 longer list or a structure member designator may not. */
5314 if (c_parser_next_token_is (parser
, CPP_NAME
)
5315 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
5317 /* Old-style structure member designator. */
5318 set_init_label (c_parser_peek_token (parser
)->location
,
5319 c_parser_peek_token (parser
)->value
,
5320 c_parser_peek_token (parser
)->location
,
5321 braced_init_obstack
);
5322 /* Use the colon as the error location. */
5323 pedwarn (c_parser_peek_2nd_token (parser
)->location
, OPT_Wpedantic
,
5324 "obsolete use of designated initializer with %<:%>");
5325 c_parser_consume_token (parser
);
5326 c_parser_consume_token (parser
);
5330 /* des_seen is 0 if there have been no designators, 1 if there
5331 has been a single array designator and 2 otherwise. */
5333 /* Location of a designator. */
5334 location_t des_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
5335 while (c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
)
5336 || c_parser_next_token_is (parser
, CPP_DOT
))
5338 int des_prev
= des_seen
;
5340 des_loc
= c_parser_peek_token (parser
)->location
;
5343 if (c_parser_next_token_is (parser
, CPP_DOT
))
5346 c_parser_consume_token (parser
);
5347 if (c_parser_next_token_is (parser
, CPP_NAME
))
5349 set_init_label (des_loc
, c_parser_peek_token (parser
)->value
,
5350 c_parser_peek_token (parser
)->location
,
5351 braced_init_obstack
);
5352 c_parser_consume_token (parser
);
5358 init
.original_code
= ERROR_MARK
;
5359 init
.original_type
= NULL
;
5360 c_parser_error (parser
, "expected identifier");
5361 c_parser_skip_until_found (parser
, CPP_COMMA
, NULL
);
5362 process_init_element (input_location
, init
, false,
5363 braced_init_obstack
);
5370 location_t ellipsis_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
5371 location_t array_index_loc
= UNKNOWN_LOCATION
;
5372 /* ??? Following the old parser, [ objc-receiver
5373 objc-message-args ] is accepted as an initializer,
5374 being distinguished from a designator by what follows
5375 the first assignment expression inside the square
5376 brackets, but after a first array designator a
5377 subsequent square bracket is for Objective-C taken to
5378 start an expression, using the obsolete form of
5379 designated initializer without '=', rather than
5380 possibly being a second level of designation: in LALR
5381 terms, the '[' is shifted rather than reducing
5382 designator to designator-list. */
5383 if (des_prev
== 1 && c_dialect_objc ())
5385 des_seen
= des_prev
;
5388 if (des_prev
== 0 && c_dialect_objc ())
5390 /* This might be an array designator or an
5391 Objective-C message expression. If the former,
5392 continue parsing here; if the latter, parse the
5393 remainder of the initializer given the starting
5394 primary-expression. ??? It might make sense to
5395 distinguish when des_prev == 1 as well; see
5396 previous comment. */
5398 struct c_expr mexpr
;
5399 c_parser_consume_token (parser
);
5400 if (c_parser_peek_token (parser
)->type
== CPP_NAME
5401 && ((c_parser_peek_token (parser
)->id_kind
5403 || (c_parser_peek_token (parser
)->id_kind
5404 == C_ID_CLASSNAME
)))
5406 /* Type name receiver. */
5407 tree id
= c_parser_peek_token (parser
)->value
;
5408 c_parser_consume_token (parser
);
5409 rec
= objc_get_class_reference (id
);
5410 goto parse_message_args
;
5412 first
= c_parser_expr_no_commas (parser
, NULL
).value
;
5413 mark_exp_read (first
);
5414 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
)
5415 || c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
5416 goto array_desig_after_first
;
5417 /* Expression receiver. So far only one part
5418 without commas has been parsed; there might be
5419 more of the expression. */
5421 while (c_parser_next_token_is (parser
, CPP_COMMA
))
5424 location_t comma_loc
, exp_loc
;
5425 comma_loc
= c_parser_peek_token (parser
)->location
;
5426 c_parser_consume_token (parser
);
5427 exp_loc
= c_parser_peek_token (parser
)->location
;
5428 next
= c_parser_expr_no_commas (parser
, NULL
);
5429 next
= convert_lvalue_to_rvalue (exp_loc
, next
,
5431 rec
= build_compound_expr (comma_loc
, rec
, next
.value
);
5434 /* Now parse the objc-message-args. */
5435 args
= c_parser_objc_message_args (parser
);
5436 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
5439 = objc_build_message_expr (rec
, args
);
5440 mexpr
.original_code
= ERROR_MARK
;
5441 mexpr
.original_type
= NULL
;
5442 /* Now parse and process the remainder of the
5443 initializer, starting with this message
5444 expression as a primary-expression. */
5445 c_parser_initval (parser
, &mexpr
, braced_init_obstack
);
5448 c_parser_consume_token (parser
);
5449 array_index_loc
= c_parser_peek_token (parser
)->location
;
5450 first
= c_parser_expr_no_commas (parser
, NULL
).value
;
5451 mark_exp_read (first
);
5452 array_desig_after_first
:
5453 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
5455 ellipsis_loc
= c_parser_peek_token (parser
)->location
;
5456 c_parser_consume_token (parser
);
5457 second
= c_parser_expr_no_commas (parser
, NULL
).value
;
5458 mark_exp_read (second
);
5462 if (c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
5464 c_parser_consume_token (parser
);
5465 set_init_index (array_index_loc
, first
, second
,
5466 braced_init_obstack
);
5468 pedwarn (ellipsis_loc
, OPT_Wpedantic
,
5469 "ISO C forbids specifying range of elements to initialize");
5472 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
5478 if (c_parser_next_token_is (parser
, CPP_EQ
))
5480 pedwarn_c90 (des_loc
, OPT_Wpedantic
,
5481 "ISO C90 forbids specifying subobject "
5483 c_parser_consume_token (parser
);
5488 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
5489 "obsolete use of designated initializer without %<=%>");
5494 init
.original_code
= ERROR_MARK
;
5495 init
.original_type
= NULL
;
5496 c_parser_error (parser
, "expected %<=%>");
5497 c_parser_skip_until_found (parser
, CPP_COMMA
, NULL
);
5498 process_init_element (input_location
, init
, false,
5499 braced_init_obstack
);
5505 c_parser_initval (parser
, NULL
, braced_init_obstack
);
5508 /* Parse a nested initializer; as c_parser_initializer but parses
5509 initializers within braced lists, after any designators have been
5510 applied. If AFTER is not NULL then it is an Objective-C message
5511 expression which is the primary-expression starting the
5515 c_parser_initval (c_parser
*parser
, struct c_expr
*after
,
5516 struct obstack
* braced_init_obstack
)
5519 gcc_assert (!after
|| c_dialect_objc ());
5520 location_t loc
= c_parser_peek_token (parser
)->location
;
5522 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
) && !after
)
5523 init
= c_parser_braced_init (parser
, NULL_TREE
, true,
5524 braced_init_obstack
);
5527 init
= c_parser_expr_no_commas (parser
, after
);
5528 if (init
.value
!= NULL_TREE
5529 && TREE_CODE (init
.value
) != STRING_CST
5530 && TREE_CODE (init
.value
) != COMPOUND_LITERAL_EXPR
)
5531 init
= convert_lvalue_to_rvalue (loc
, init
, true, true);
5533 process_init_element (loc
, init
, false, braced_init_obstack
);
5536 /* Parse a compound statement (possibly a function body) (C90 6.6.2,
5537 C99 6.8.2, C11 6.8.2, C2X 6.8.2).
5540 { block-item-list[opt] }
5541 { label-declarations block-item-list }
5545 block-item-list block-item
5558 { label-declarations block-item-list }
5561 __extension__ nested-declaration
5562 nested-function-definition
5566 label-declarations label-declaration
5569 __label__ identifier-list ;
5571 Allowing the mixing of declarations and code is new in C99. The
5572 GNU syntax also permits (not shown above) labels at the end of
5573 compound statements, which yield an error. We don't allow labels
5574 on declarations; this might seem like a natural extension, but
5575 there would be a conflict between gnu-attributes on the label and
5576 prefix gnu-attributes on the declaration. ??? The syntax follows the
5577 old parser in requiring something after label declarations.
5578 Although they are erroneous if the labels declared aren't defined,
5579 is it useful for the syntax to be this way?
5600 cancellation-point-directive */
5603 c_parser_compound_statement (c_parser
*parser
, location_t
*endlocp
)
5606 location_t brace_loc
;
5607 brace_loc
= c_parser_peek_token (parser
)->location
;
5608 if (!c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
5610 /* Ensure a scope is entered and left anyway to avoid confusion
5611 if we have just prepared to enter a function body. */
5612 stmt
= c_begin_compound_stmt (true);
5613 c_end_compound_stmt (brace_loc
, stmt
, true);
5614 return error_mark_node
;
5616 stmt
= c_begin_compound_stmt (true);
5617 location_t end_loc
= c_parser_compound_statement_nostart (parser
);
5621 return c_end_compound_stmt (brace_loc
, stmt
, true);
5624 /* Parse a compound statement except for the opening brace. This is
5625 used for parsing both compound statements and statement expressions
5626 (which follow different paths to handling the opening). */
5629 c_parser_compound_statement_nostart (c_parser
*parser
)
5631 bool last_stmt
= false;
5632 bool last_label
= false;
5633 bool save_valid_for_pragma
= valid_location_for_stdc_pragma_p ();
5634 location_t label_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
5635 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
5637 location_t endloc
= c_parser_peek_token (parser
)->location
;
5638 add_debug_begin_stmt (endloc
);
5639 c_parser_consume_token (parser
);
5642 mark_valid_location_for_stdc_pragma (true);
5643 if (c_parser_next_token_is_keyword (parser
, RID_LABEL
))
5645 /* Read zero or more forward-declarations for labels that nested
5646 functions can jump to. */
5647 mark_valid_location_for_stdc_pragma (false);
5648 while (c_parser_next_token_is_keyword (parser
, RID_LABEL
))
5650 label_loc
= c_parser_peek_token (parser
)->location
;
5651 c_parser_consume_token (parser
);
5652 /* Any identifiers, including those declared as type names,
5657 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
5659 c_parser_error (parser
, "expected identifier");
5663 = declare_label (c_parser_peek_token (parser
)->value
);
5664 C_DECLARED_LABEL_FLAG (label
) = 1;
5665 add_stmt (build_stmt (label_loc
, DECL_EXPR
, label
));
5666 c_parser_consume_token (parser
);
5667 if (c_parser_next_token_is (parser
, CPP_COMMA
))
5668 c_parser_consume_token (parser
);
5672 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
5674 pedwarn (label_loc
, OPT_Wpedantic
, "ISO C forbids label declarations");
5676 /* We must now have at least one statement, label or declaration. */
5677 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
5679 mark_valid_location_for_stdc_pragma (save_valid_for_pragma
);
5680 c_parser_error (parser
, "expected declaration or statement");
5681 location_t endloc
= c_parser_peek_token (parser
)->location
;
5682 c_parser_consume_token (parser
);
5685 while (c_parser_next_token_is_not (parser
, CPP_CLOSE_BRACE
))
5687 location_t loc
= c_parser_peek_token (parser
)->location
;
5688 loc
= expansion_point_location_if_in_system_header (loc
);
5689 /* Standard attributes may start a label, statement or declaration. */
5691 = c_parser_nth_token_starts_std_attributes (parser
, 1);
5692 tree std_attrs
= NULL_TREE
;
5694 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
5695 if (c_parser_next_token_is_keyword (parser
, RID_CASE
)
5696 || c_parser_next_token_is_keyword (parser
, RID_DEFAULT
)
5697 || (c_parser_next_token_is (parser
, CPP_NAME
)
5698 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
))
5700 if (c_parser_next_token_is_keyword (parser
, RID_CASE
))
5701 label_loc
= c_parser_peek_2nd_token (parser
)->location
;
5703 label_loc
= c_parser_peek_token (parser
)->location
;
5706 mark_valid_location_for_stdc_pragma (false);
5707 c_parser_label (parser
, std_attrs
);
5709 else if (c_parser_next_tokens_start_declaration (parser
)
5711 && c_parser_next_token_is (parser
, CPP_SEMICOLON
)))
5714 pedwarn_c11 (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
5715 "a label can only be part of a statement and "
5716 "a declaration is not a statement");
5718 mark_valid_location_for_stdc_pragma (false);
5719 bool fallthru_attr_p
= false;
5720 c_parser_declaration_or_fndef (parser
, true, !have_std_attrs
,
5721 true, true, true, NULL
,
5722 NULL
, have_std_attrs
, std_attrs
,
5723 NULL
, &fallthru_attr_p
);
5725 if (last_stmt
&& !fallthru_attr_p
)
5726 pedwarn_c90 (loc
, OPT_Wdeclaration_after_statement
,
5727 "ISO C90 forbids mixed declarations and code");
5728 last_stmt
= fallthru_attr_p
;
5731 else if (c_parser_next_token_is_keyword (parser
, RID_EXTENSION
))
5733 /* __extension__ can start a declaration, but is also an
5734 unary operator that can start an expression. Consume all
5735 but the last of a possible series of __extension__ to
5736 determine which. If standard attributes have already
5737 been seen, it must start a statement, not a declaration,
5738 but standard attributes starting a declaration may appear
5739 after __extension__. */
5740 while (c_parser_peek_2nd_token (parser
)->type
== CPP_KEYWORD
5741 && (c_parser_peek_2nd_token (parser
)->keyword
5743 c_parser_consume_token (parser
);
5745 && (c_token_starts_declaration (c_parser_peek_2nd_token (parser
))
5746 || c_parser_nth_token_starts_std_attributes (parser
, 2)))
5749 ext
= disable_extension_diagnostics ();
5750 c_parser_consume_token (parser
);
5752 mark_valid_location_for_stdc_pragma (false);
5753 c_parser_declaration_or_fndef (parser
, true, true, true, true,
5755 /* Following the old parser, __extension__ does not
5756 disable this diagnostic. */
5757 restore_extension_diagnostics (ext
);
5759 pedwarn_c90 (loc
, OPT_Wdeclaration_after_statement
,
5760 "ISO C90 forbids mixed declarations and code");
5766 else if (c_parser_next_token_is (parser
, CPP_PRAGMA
))
5769 c_parser_error (parser
, "expected declaration or statement");
5770 /* External pragmas, and some omp pragmas, are not associated
5771 with regular c code, and so are not to be considered statements
5772 syntactically. This ensures that the user doesn't put them
5773 places that would turn into syntax errors if the directive
5775 if (c_parser_pragma (parser
,
5776 last_label
? pragma_stmt
: pragma_compound
,
5778 last_label
= false, last_stmt
= true;
5780 else if (c_parser_next_token_is (parser
, CPP_EOF
))
5782 mark_valid_location_for_stdc_pragma (save_valid_for_pragma
);
5783 c_parser_error (parser
, "expected declaration or statement");
5784 return c_parser_peek_token (parser
)->location
;
5786 else if (c_parser_next_token_is_keyword (parser
, RID_ELSE
))
5788 if (parser
->in_if_block
)
5790 mark_valid_location_for_stdc_pragma (save_valid_for_pragma
);
5791 error_at (loc
, "expected %<}%> before %<else%>");
5792 return c_parser_peek_token (parser
)->location
;
5796 error_at (loc
, "%<else%> without a previous %<if%>");
5797 c_parser_consume_token (parser
);
5804 c_warn_unused_attributes (std_attrs
);
5807 mark_valid_location_for_stdc_pragma (false);
5808 c_parser_statement_after_labels (parser
, NULL
);
5811 parser
->error
= false;
5814 pedwarn_c11 (label_loc
, OPT_Wpedantic
, "label at end of compound statement");
5815 location_t endloc
= c_parser_peek_token (parser
)->location
;
5816 c_parser_consume_token (parser
);
5817 /* Restore the value we started with. */
5818 mark_valid_location_for_stdc_pragma (save_valid_for_pragma
);
5822 /* Parse all consecutive labels, possibly preceded by standard
5823 attributes. In this context, a statement is required, not a
5824 declaration, so attributes must be followed by a statement that is
5825 not just a semicolon. */
5828 c_parser_all_labels (c_parser
*parser
)
5830 tree std_attrs
= NULL
;
5831 if (c_parser_nth_token_starts_std_attributes (parser
, 1))
5833 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
5834 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
5835 c_parser_error (parser
, "expected statement");
5837 while (c_parser_next_token_is_keyword (parser
, RID_CASE
)
5838 || c_parser_next_token_is_keyword (parser
, RID_DEFAULT
)
5839 || (c_parser_next_token_is (parser
, CPP_NAME
)
5840 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
))
5842 c_parser_label (parser
, std_attrs
);
5844 if (c_parser_nth_token_starts_std_attributes (parser
, 1))
5846 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
5847 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
5848 c_parser_error (parser
, "expected statement");
5852 c_warn_unused_attributes (std_attrs
);
5855 /* Parse a label (C90 6.6.1, C99 6.8.1, C11 6.8.1).
5858 identifier : gnu-attributes[opt]
5859 case constant-expression :
5865 case constant-expression ... constant-expression :
5867 The use of gnu-attributes on labels is a GNU extension. The syntax in
5868 GNU C accepts any expressions without commas, non-constant
5869 expressions being rejected later. Any standard
5870 attribute-specifier-sequence before the first label has been parsed
5871 in the caller, to distinguish statements from declarations. Any
5872 attribute-specifier-sequence after the label is parsed in this
5875 c_parser_label (c_parser
*parser
, tree std_attrs
)
5877 location_t loc1
= c_parser_peek_token (parser
)->location
;
5878 tree label
= NULL_TREE
;
5880 /* Remember whether this case or a user-defined label is allowed to fall
5882 bool fallthrough_p
= c_parser_peek_token (parser
)->flags
& PREV_FALLTHROUGH
;
5884 if (c_parser_next_token_is_keyword (parser
, RID_CASE
))
5887 c_parser_consume_token (parser
);
5888 exp1
= c_parser_expr_no_commas (parser
, NULL
).value
;
5889 if (c_parser_next_token_is (parser
, CPP_COLON
))
5891 c_parser_consume_token (parser
);
5892 label
= do_case (loc1
, exp1
, NULL_TREE
);
5894 else if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
5896 c_parser_consume_token (parser
);
5897 exp2
= c_parser_expr_no_commas (parser
, NULL
).value
;
5898 if (c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
5899 label
= do_case (loc1
, exp1
, exp2
);
5902 c_parser_error (parser
, "expected %<:%> or %<...%>");
5904 else if (c_parser_next_token_is_keyword (parser
, RID_DEFAULT
))
5906 c_parser_consume_token (parser
);
5907 if (c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
5908 label
= do_case (loc1
, NULL_TREE
, NULL_TREE
);
5912 tree name
= c_parser_peek_token (parser
)->value
;
5915 location_t loc2
= c_parser_peek_token (parser
)->location
;
5916 gcc_assert (c_parser_next_token_is (parser
, CPP_NAME
));
5917 c_parser_consume_token (parser
);
5918 gcc_assert (c_parser_next_token_is (parser
, CPP_COLON
));
5919 c_parser_consume_token (parser
);
5920 attrs
= c_parser_gnu_attributes (parser
);
5921 tlab
= define_label (loc2
, name
);
5924 decl_attributes (&tlab
, attrs
, 0);
5925 decl_attributes (&tlab
, std_attrs
, 0);
5926 label
= add_stmt (build_stmt (loc1
, LABEL_EXPR
, tlab
));
5929 && c_parser_next_tokens_start_declaration (parser
))
5930 warning_at (loc2
, OPT_Wattributes
, "GNU-style attribute between"
5931 " label and declaration appertains to the label");
5935 if (TREE_CODE (label
) == LABEL_EXPR
)
5936 FALLTHROUGH_LABEL_P (LABEL_EXPR_LABEL (label
)) = fallthrough_p
;
5938 FALLTHROUGH_LABEL_P (CASE_LABEL (label
)) = fallthrough_p
;
5942 /* Parse a statement (C90 6.6, C99 6.8, C11 6.8).
5946 attribute-specifier-sequence[opt] compound-statement
5947 expression-statement
5948 attribute-specifier-sequence[opt] selection-statement
5949 attribute-specifier-sequence[opt] iteration-statement
5950 attribute-specifier-sequence[opt] jump-statement
5953 attribute-specifier-sequence[opt] label statement
5955 expression-statement:
5957 attribute-specifier-sequence expression ;
5959 selection-statement:
5963 iteration-statement:
5972 return expression[opt] ;
5977 attribute-specifier-sequence[opt] asm-statement
5982 expression-statement:
5988 attribute-specifier-sequence[opt] objc-throw-statement
5989 attribute-specifier-sequence[opt] objc-try-catch-statement
5990 attribute-specifier-sequence[opt] objc-synchronized-statement
5992 objc-throw-statement:
5999 attribute-specifier-sequence[opt] openacc-construct
6008 parallel-directive structured-block
6011 kernels-directive structured-block
6014 data-directive structured-block
6017 loop-directive structured-block
6022 attribute-specifier-sequence[opt] openmp-construct
6031 parallel-for-construct
6032 parallel-for-simd-construct
6033 parallel-sections-construct
6040 parallel-directive structured-block
6043 for-directive iteration-statement
6046 simd-directive iteration-statements
6049 for-simd-directive iteration-statements
6052 sections-directive section-scope
6055 single-directive structured-block
6057 parallel-for-construct:
6058 parallel-for-directive iteration-statement
6060 parallel-for-simd-construct:
6061 parallel-for-simd-directive iteration-statement
6063 parallel-sections-construct:
6064 parallel-sections-directive section-scope
6067 master-directive structured-block
6070 critical-directive structured-block
6073 atomic-directive expression-statement
6076 ordered-directive structured-block
6078 Transactional Memory:
6081 attribute-specifier-sequence[opt] transaction-statement
6082 attribute-specifier-sequence[opt] transaction-cancel-statement
6084 IF_P is used to track whether there's a (possibly labeled) if statement
6085 which is not enclosed in braces and has an else clause. This is used to
6086 implement -Wparentheses. */
6089 c_parser_statement (c_parser
*parser
, bool *if_p
, location_t
*loc_after_labels
)
6091 c_parser_all_labels (parser
);
6092 if (loc_after_labels
)
6093 *loc_after_labels
= c_parser_peek_token (parser
)->location
;
6094 c_parser_statement_after_labels (parser
, if_p
, NULL
);
6097 /* Parse a statement, other than a labeled statement. CHAIN is a vector
6098 of if-else-if conditions. All labels and standard attributes have
6099 been parsed in the caller.
6101 IF_P is used to track whether there's a (possibly labeled) if statement
6102 which is not enclosed in braces and has an else clause. This is used to
6103 implement -Wparentheses. */
6106 c_parser_statement_after_labels (c_parser
*parser
, bool *if_p
,
6109 location_t loc
= c_parser_peek_token (parser
)->location
;
6110 tree stmt
= NULL_TREE
;
6111 bool in_if_block
= parser
->in_if_block
;
6112 parser
->in_if_block
= false;
6116 if (c_parser_peek_token (parser
)->type
!= CPP_OPEN_BRACE
)
6117 add_debug_begin_stmt (loc
);
6120 switch (c_parser_peek_token (parser
)->type
)
6122 case CPP_OPEN_BRACE
:
6123 add_stmt (c_parser_compound_statement (parser
));
6126 switch (c_parser_peek_token (parser
)->keyword
)
6129 c_parser_if_statement (parser
, if_p
, chain
);
6132 c_parser_switch_statement (parser
, if_p
);
6135 c_parser_while_statement (parser
, false, 0, if_p
);
6138 c_parser_do_statement (parser
, false, 0);
6141 c_parser_for_statement (parser
, false, 0, if_p
);
6144 c_parser_consume_token (parser
);
6145 if (c_parser_next_token_is (parser
, CPP_NAME
))
6147 stmt
= c_finish_goto_label (loc
,
6148 c_parser_peek_token (parser
)->value
);
6149 c_parser_consume_token (parser
);
6151 else if (c_parser_next_token_is (parser
, CPP_MULT
))
6155 c_parser_consume_token (parser
);
6156 val
= c_parser_expression (parser
);
6157 val
= convert_lvalue_to_rvalue (loc
, val
, false, true);
6158 stmt
= c_finish_goto_ptr (loc
, val
);
6161 c_parser_error (parser
, "expected identifier or %<*%>");
6162 goto expect_semicolon
;
6164 c_parser_consume_token (parser
);
6165 stmt
= c_finish_bc_stmt (loc
, objc_foreach_continue_label
, false);
6166 goto expect_semicolon
;
6168 c_parser_consume_token (parser
);
6169 stmt
= c_finish_bc_stmt (loc
, objc_foreach_break_label
, true);
6170 goto expect_semicolon
;
6172 c_parser_consume_token (parser
);
6173 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6175 stmt
= c_finish_return (loc
, NULL_TREE
, NULL_TREE
);
6176 c_parser_consume_token (parser
);
6180 location_t xloc
= c_parser_peek_token (parser
)->location
;
6181 struct c_expr expr
= c_parser_expression_conv (parser
);
6182 mark_exp_read (expr
.value
);
6183 stmt
= c_finish_return (EXPR_LOC_OR_LOC (expr
.value
, xloc
),
6184 expr
.value
, expr
.original_type
);
6185 goto expect_semicolon
;
6189 stmt
= c_parser_asm_statement (parser
);
6191 case RID_TRANSACTION_ATOMIC
:
6192 case RID_TRANSACTION_RELAXED
:
6193 stmt
= c_parser_transaction (parser
,
6194 c_parser_peek_token (parser
)->keyword
);
6196 case RID_TRANSACTION_CANCEL
:
6197 stmt
= c_parser_transaction_cancel (parser
);
6198 goto expect_semicolon
;
6200 gcc_assert (c_dialect_objc ());
6201 c_parser_consume_token (parser
);
6202 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6204 stmt
= objc_build_throw_stmt (loc
, NULL_TREE
);
6205 c_parser_consume_token (parser
);
6209 struct c_expr expr
= c_parser_expression (parser
);
6210 expr
= convert_lvalue_to_rvalue (loc
, expr
, false, false);
6211 expr
.value
= c_fully_fold (expr
.value
, false, NULL
);
6212 stmt
= objc_build_throw_stmt (loc
, expr
.value
);
6213 goto expect_semicolon
;
6217 gcc_assert (c_dialect_objc ());
6218 c_parser_objc_try_catch_finally_statement (parser
);
6220 case RID_AT_SYNCHRONIZED
:
6221 gcc_assert (c_dialect_objc ());
6222 c_parser_objc_synchronized_statement (parser
);
6226 /* Allow '__attribute__((fallthrough));'. */
6227 tree attrs
= c_parser_gnu_attributes (parser
);
6228 if (attribute_fallthrough_p (attrs
))
6230 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6232 tree fn
= build_call_expr_internal_loc (loc
,
6237 c_parser_consume_token (parser
);
6240 warning_at (loc
, OPT_Wattributes
,
6241 "%<fallthrough%> attribute not followed "
6244 else if (attrs
!= NULL_TREE
)
6245 warning_at (loc
, OPT_Wattributes
, "only attribute %<fallthrough%>"
6246 " can be applied to a null statement");
6254 c_parser_consume_token (parser
);
6256 case CPP_CLOSE_PAREN
:
6257 case CPP_CLOSE_SQUARE
:
6258 /* Avoid infinite loop in error recovery:
6259 c_parser_skip_until_found stops at a closing nesting
6260 delimiter without consuming it, but here we need to consume
6261 it to proceed further. */
6262 c_parser_error (parser
, "expected statement");
6263 c_parser_consume_token (parser
);
6266 if (!c_parser_pragma (parser
, pragma_stmt
, if_p
))
6271 stmt
= c_finish_expr_stmt (loc
, c_parser_expression_conv (parser
).value
);
6273 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
6276 /* Two cases cannot and do not have line numbers associated: If stmt
6277 is degenerate, such as "2;", then stmt is an INTEGER_CST, which
6278 cannot hold line numbers. But that's OK because the statement
6279 will either be changed to a MODIFY_EXPR during gimplification of
6280 the statement expr, or discarded. If stmt was compound, but
6281 without new variables, we will have skipped the creation of a
6282 BIND and will have a bare STATEMENT_LIST. But that's OK because
6283 (recursively) all of the component statements should already have
6284 line numbers assigned. ??? Can we discard no-op statements
6286 if (EXPR_LOCATION (stmt
) == UNKNOWN_LOCATION
)
6287 protected_set_expr_location (stmt
, loc
);
6289 parser
->in_if_block
= in_if_block
;
6292 /* Parse the condition from an if, do, while or for statements. */
6295 c_parser_condition (c_parser
*parser
)
6297 location_t loc
= c_parser_peek_token (parser
)->location
;
6299 cond
= c_parser_expression_conv (parser
).value
;
6300 cond
= c_objc_common_truthvalue_conversion (loc
, cond
);
6301 cond
= c_fully_fold (cond
, false, NULL
);
6302 if (warn_sequence_point
)
6303 verify_sequence_points (cond
);
6307 /* Parse a parenthesized condition from an if, do or while statement.
6313 c_parser_paren_condition (c_parser
*parser
)
6316 matching_parens parens
;
6317 if (!parens
.require_open (parser
))
6318 return error_mark_node
;
6319 cond
= c_parser_condition (parser
);
6320 parens
.skip_until_found_close (parser
);
6324 /* Parse a statement which is a block in C99.
6326 IF_P is used to track whether there's a (possibly labeled) if statement
6327 which is not enclosed in braces and has an else clause. This is used to
6328 implement -Wparentheses. */
6331 c_parser_c99_block_statement (c_parser
*parser
, bool *if_p
,
6332 location_t
*loc_after_labels
)
6334 tree block
= c_begin_compound_stmt (flag_isoc99
);
6335 location_t loc
= c_parser_peek_token (parser
)->location
;
6336 c_parser_statement (parser
, if_p
, loc_after_labels
);
6337 return c_end_compound_stmt (loc
, block
, flag_isoc99
);
6340 /* Parse the body of an if statement. This is just parsing a
6341 statement but (a) it is a block in C99, (b) we track whether the
6342 body is an if statement for the sake of -Wparentheses warnings, (c)
6343 we handle an empty body specially for the sake of -Wempty-body
6344 warnings, and (d) we call parser_compound_statement directly
6345 because c_parser_statement_after_labels resets
6346 parser->in_if_block.
6348 IF_P is used to track whether there's a (possibly labeled) if statement
6349 which is not enclosed in braces and has an else clause. This is used to
6350 implement -Wparentheses. */
6353 c_parser_if_body (c_parser
*parser
, bool *if_p
,
6354 const token_indent_info
&if_tinfo
)
6356 tree block
= c_begin_compound_stmt (flag_isoc99
);
6357 location_t body_loc
= c_parser_peek_token (parser
)->location
;
6358 location_t body_loc_after_labels
= UNKNOWN_LOCATION
;
6359 token_indent_info body_tinfo
6360 = get_token_indent_info (c_parser_peek_token (parser
));
6362 c_parser_all_labels (parser
);
6363 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6365 location_t loc
= c_parser_peek_token (parser
)->location
;
6366 add_stmt (build_empty_stmt (loc
));
6367 c_parser_consume_token (parser
);
6368 if (!c_parser_next_token_is_keyword (parser
, RID_ELSE
))
6369 warning_at (loc
, OPT_Wempty_body
,
6370 "suggest braces around empty body in an %<if%> statement");
6372 else if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
6373 add_stmt (c_parser_compound_statement (parser
));
6376 body_loc_after_labels
= c_parser_peek_token (parser
)->location
;
6377 c_parser_statement_after_labels (parser
, if_p
);
6380 token_indent_info next_tinfo
6381 = get_token_indent_info (c_parser_peek_token (parser
));
6382 warn_for_misleading_indentation (if_tinfo
, body_tinfo
, next_tinfo
);
6383 if (body_loc_after_labels
!= UNKNOWN_LOCATION
6384 && next_tinfo
.type
!= CPP_SEMICOLON
)
6385 warn_for_multistatement_macros (body_loc_after_labels
, next_tinfo
.location
,
6386 if_tinfo
.location
, RID_IF
);
6388 return c_end_compound_stmt (body_loc
, block
, flag_isoc99
);
6391 /* Parse the else body of an if statement. This is just parsing a
6392 statement but (a) it is a block in C99, (b) we handle an empty body
6393 specially for the sake of -Wempty-body warnings. CHAIN is a vector
6394 of if-else-if conditions. */
6397 c_parser_else_body (c_parser
*parser
, const token_indent_info
&else_tinfo
,
6400 location_t body_loc
= c_parser_peek_token (parser
)->location
;
6401 tree block
= c_begin_compound_stmt (flag_isoc99
);
6402 token_indent_info body_tinfo
6403 = get_token_indent_info (c_parser_peek_token (parser
));
6404 location_t body_loc_after_labels
= UNKNOWN_LOCATION
;
6406 c_parser_all_labels (parser
);
6407 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6409 location_t loc
= c_parser_peek_token (parser
)->location
;
6412 "suggest braces around empty body in an %<else%> statement");
6413 add_stmt (build_empty_stmt (loc
));
6414 c_parser_consume_token (parser
);
6418 if (!c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
6419 body_loc_after_labels
= c_parser_peek_token (parser
)->location
;
6420 c_parser_statement_after_labels (parser
, NULL
, chain
);
6423 token_indent_info next_tinfo
6424 = get_token_indent_info (c_parser_peek_token (parser
));
6425 warn_for_misleading_indentation (else_tinfo
, body_tinfo
, next_tinfo
);
6426 if (body_loc_after_labels
!= UNKNOWN_LOCATION
6427 && next_tinfo
.type
!= CPP_SEMICOLON
)
6428 warn_for_multistatement_macros (body_loc_after_labels
, next_tinfo
.location
,
6429 else_tinfo
.location
, RID_ELSE
);
6431 return c_end_compound_stmt (body_loc
, block
, flag_isoc99
);
6434 /* We might need to reclassify any previously-lexed identifier, e.g.
6435 when we've left a for loop with an if-statement without else in the
6436 body - we might have used a wrong scope for the token. See PR67784. */
6439 c_parser_maybe_reclassify_token (c_parser
*parser
)
6441 if (c_parser_next_token_is (parser
, CPP_NAME
))
6443 c_token
*token
= c_parser_peek_token (parser
);
6445 if (token
->id_kind
!= C_ID_CLASSNAME
)
6447 tree decl
= lookup_name (token
->value
);
6449 token
->id_kind
= C_ID_ID
;
6452 if (TREE_CODE (decl
) == TYPE_DECL
)
6453 token
->id_kind
= C_ID_TYPENAME
;
6455 else if (c_dialect_objc ())
6457 tree objc_interface_decl
= objc_is_class_name (token
->value
);
6458 /* Objective-C class names are in the same namespace as
6459 variables and typedefs, and hence are shadowed by local
6461 if (objc_interface_decl
)
6463 token
->value
= objc_interface_decl
;
6464 token
->id_kind
= C_ID_CLASSNAME
;
6471 /* Parse an if statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
6474 if ( expression ) statement
6475 if ( expression ) statement else statement
6477 CHAIN is a vector of if-else-if conditions.
6478 IF_P is used to track whether there's a (possibly labeled) if statement
6479 which is not enclosed in braces and has an else clause. This is used to
6480 implement -Wparentheses. */
6483 c_parser_if_statement (c_parser
*parser
, bool *if_p
, vec
<tree
> *chain
)
6488 bool nested_if
= false;
6489 tree first_body
, second_body
;
6492 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_IF
));
6493 token_indent_info if_tinfo
6494 = get_token_indent_info (c_parser_peek_token (parser
));
6495 c_parser_consume_token (parser
);
6496 block
= c_begin_compound_stmt (flag_isoc99
);
6497 loc
= c_parser_peek_token (parser
)->location
;
6498 cond
= c_parser_paren_condition (parser
);
6499 in_if_block
= parser
->in_if_block
;
6500 parser
->in_if_block
= true;
6501 first_body
= c_parser_if_body (parser
, &nested_if
, if_tinfo
);
6502 parser
->in_if_block
= in_if_block
;
6504 if (warn_duplicated_cond
)
6505 warn_duplicated_cond_add_or_warn (EXPR_LOCATION (cond
), cond
, &chain
);
6507 if (c_parser_next_token_is_keyword (parser
, RID_ELSE
))
6509 token_indent_info else_tinfo
6510 = get_token_indent_info (c_parser_peek_token (parser
));
6511 c_parser_consume_token (parser
);
6512 if (warn_duplicated_cond
)
6514 if (c_parser_next_token_is_keyword (parser
, RID_IF
)
6517 /* We've got "if (COND) else if (COND2)". Start the
6518 condition chain and add COND as the first element. */
6519 chain
= new vec
<tree
> ();
6520 if (!CONSTANT_CLASS_P (cond
) && !TREE_SIDE_EFFECTS (cond
))
6521 chain
->safe_push (cond
);
6523 else if (!c_parser_next_token_is_keyword (parser
, RID_IF
))
6524 /* This is if-else without subsequent if. Zap the condition
6525 chain; we would have already warned at this point. */
6528 second_body
= c_parser_else_body (parser
, else_tinfo
, chain
);
6529 /* Set IF_P to true to indicate that this if statement has an
6530 else clause. This may trigger the Wparentheses warning
6531 below when we get back up to the parent if statement. */
6537 second_body
= NULL_TREE
;
6539 /* Diagnose an ambiguous else if if-then-else is nested inside
6542 warning_at (loc
, OPT_Wdangling_else
,
6543 "suggest explicit braces to avoid ambiguous %<else%>");
6545 if (warn_duplicated_cond
)
6546 /* This if statement does not have an else clause. We don't
6547 need the condition chain anymore. */
6550 c_finish_if_stmt (loc
, cond
, first_body
, second_body
);
6551 add_stmt (c_end_compound_stmt (loc
, block
, flag_isoc99
));
6553 c_parser_maybe_reclassify_token (parser
);
6556 /* Parse a switch statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
6559 switch (expression) statement
6563 c_parser_switch_statement (c_parser
*parser
, bool *if_p
)
6566 tree block
, expr
, body
;
6567 unsigned char save_in_statement
;
6568 location_t switch_loc
= c_parser_peek_token (parser
)->location
;
6569 location_t switch_cond_loc
;
6570 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_SWITCH
));
6571 c_parser_consume_token (parser
);
6572 block
= c_begin_compound_stmt (flag_isoc99
);
6573 bool explicit_cast_p
= false;
6574 matching_parens parens
;
6575 if (parens
.require_open (parser
))
6577 switch_cond_loc
= c_parser_peek_token (parser
)->location
;
6578 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
)
6579 && c_token_starts_typename (c_parser_peek_2nd_token (parser
)))
6580 explicit_cast_p
= true;
6581 ce
= c_parser_expression (parser
);
6582 ce
= convert_lvalue_to_rvalue (switch_cond_loc
, ce
, true, true);
6584 /* ??? expr has no valid location? */
6585 parens
.skip_until_found_close (parser
);
6589 switch_cond_loc
= UNKNOWN_LOCATION
;
6590 expr
= error_mark_node
;
6591 ce
.original_type
= error_mark_node
;
6593 c_start_switch (switch_loc
, switch_cond_loc
, expr
, explicit_cast_p
);
6594 save_in_statement
= in_statement
;
6595 in_statement
|= IN_SWITCH_STMT
;
6596 location_t loc_after_labels
;
6597 bool open_brace_p
= c_parser_peek_token (parser
)->type
== CPP_OPEN_BRACE
;
6598 body
= c_parser_c99_block_statement (parser
, if_p
, &loc_after_labels
);
6599 location_t next_loc
= c_parser_peek_token (parser
)->location
;
6600 if (!open_brace_p
&& c_parser_peek_token (parser
)->type
!= CPP_SEMICOLON
)
6601 warn_for_multistatement_macros (loc_after_labels
, next_loc
, switch_loc
,
6603 c_finish_switch (body
, ce
.original_type
);
6604 in_statement
= save_in_statement
;
6605 add_stmt (c_end_compound_stmt (switch_loc
, block
, flag_isoc99
));
6606 c_parser_maybe_reclassify_token (parser
);
6609 /* Parse a while statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6612 while (expression) statement
6614 IF_P is used to track whether there's a (possibly labeled) if statement
6615 which is not enclosed in braces and has an else clause. This is used to
6616 implement -Wparentheses. */
6619 c_parser_while_statement (c_parser
*parser
, bool ivdep
, unsigned short unroll
,
6622 tree block
, cond
, body
;
6623 unsigned char save_in_statement
;
6625 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_WHILE
));
6626 token_indent_info while_tinfo
6627 = get_token_indent_info (c_parser_peek_token (parser
));
6628 c_parser_consume_token (parser
);
6629 block
= c_begin_compound_stmt (flag_isoc99
);
6630 loc
= c_parser_peek_token (parser
)->location
;
6631 cond
= c_parser_paren_condition (parser
);
6632 if (ivdep
&& cond
!= error_mark_node
)
6633 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
6634 build_int_cst (integer_type_node
,
6635 annot_expr_ivdep_kind
),
6637 if (unroll
&& cond
!= error_mark_node
)
6638 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
6639 build_int_cst (integer_type_node
,
6640 annot_expr_unroll_kind
),
6641 build_int_cst (integer_type_node
, unroll
));
6642 save_in_statement
= in_statement
;
6643 in_statement
= IN_ITERATION_STMT
;
6645 token_indent_info body_tinfo
6646 = get_token_indent_info (c_parser_peek_token (parser
));
6648 location_t loc_after_labels
;
6649 bool open_brace
= c_parser_next_token_is (parser
, CPP_OPEN_BRACE
);
6650 body
= c_parser_c99_block_statement (parser
, if_p
, &loc_after_labels
);
6651 add_stmt (build_stmt (loc
, WHILE_STMT
, cond
, body
));
6652 add_stmt (c_end_compound_stmt (loc
, block
, flag_isoc99
));
6653 c_parser_maybe_reclassify_token (parser
);
6655 token_indent_info next_tinfo
6656 = get_token_indent_info (c_parser_peek_token (parser
));
6657 warn_for_misleading_indentation (while_tinfo
, body_tinfo
, next_tinfo
);
6659 if (next_tinfo
.type
!= CPP_SEMICOLON
&& !open_brace
)
6660 warn_for_multistatement_macros (loc_after_labels
, next_tinfo
.location
,
6661 while_tinfo
.location
, RID_WHILE
);
6663 in_statement
= save_in_statement
;
6666 /* Parse a do statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6669 do statement while ( expression ) ;
6673 c_parser_do_statement (c_parser
*parser
, bool ivdep
, unsigned short unroll
)
6675 tree block
, cond
, body
;
6676 unsigned char save_in_statement
;
6678 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_DO
));
6679 c_parser_consume_token (parser
);
6680 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6681 warning_at (c_parser_peek_token (parser
)->location
,
6683 "suggest braces around empty body in %<do%> statement");
6684 block
= c_begin_compound_stmt (flag_isoc99
);
6685 loc
= c_parser_peek_token (parser
)->location
;
6686 save_in_statement
= in_statement
;
6687 in_statement
= IN_ITERATION_STMT
;
6688 body
= c_parser_c99_block_statement (parser
, NULL
);
6689 c_parser_require_keyword (parser
, RID_WHILE
, "expected %<while%>");
6690 in_statement
= save_in_statement
;
6691 cond
= c_parser_paren_condition (parser
);
6692 if (ivdep
&& cond
!= error_mark_node
)
6693 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
6694 build_int_cst (integer_type_node
,
6695 annot_expr_ivdep_kind
),
6697 if (unroll
&& cond
!= error_mark_node
)
6698 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
6699 build_int_cst (integer_type_node
,
6700 annot_expr_unroll_kind
),
6701 build_int_cst (integer_type_node
, unroll
));
6702 if (!c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
6703 c_parser_skip_to_end_of_block_or_statement (parser
);
6705 add_stmt (build_stmt (loc
, DO_STMT
, cond
, body
));
6706 add_stmt (c_end_compound_stmt (loc
, block
, flag_isoc99
));
6709 /* Parse a for statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6712 for ( expression[opt] ; expression[opt] ; expression[opt] ) statement
6713 for ( nested-declaration expression[opt] ; expression[opt] ) statement
6715 The form with a declaration is new in C99.
6717 ??? In accordance with the old parser, the declaration may be a
6718 nested function, which is then rejected in check_for_loop_decls,
6719 but does it make any sense for this to be included in the grammar?
6720 Note in particular that the nested function does not include a
6721 trailing ';', whereas the "declaration" production includes one.
6722 Also, can we reject bad declarations earlier and cheaper than
6723 check_for_loop_decls?
6725 In Objective-C, there are two additional variants:
6728 for ( expression in expresssion ) statement
6729 for ( declaration in expression ) statement
6731 This is inconsistent with C, because the second variant is allowed
6732 even if c99 is not enabled.
6734 The rest of the comment documents these Objective-C foreach-statement.
6736 Here is the canonical example of the first variant:
6737 for (object in array) { do something with object }
6738 we call the first expression ("object") the "object_expression" and
6739 the second expression ("array") the "collection_expression".
6740 object_expression must be an lvalue of type "id" (a generic Objective-C
6741 object) because the loop works by assigning to object_expression the
6742 various objects from the collection_expression. collection_expression
6743 must evaluate to something of type "id" which responds to the method
6744 countByEnumeratingWithState:objects:count:.
6746 The canonical example of the second variant is:
6747 for (id object in array) { do something with object }
6748 which is completely equivalent to
6751 for (object in array) { do something with object }
6753 Note that initizializing 'object' in some way (eg, "for ((object =
6754 xxx) in array) { do something with object }") is possibly
6755 technically valid, but completely pointless as 'object' will be
6756 assigned to something else as soon as the loop starts. We should
6757 most likely reject it (TODO).
6759 The beginning of the Objective-C foreach-statement looks exactly
6760 like the beginning of the for-statement, and we can tell it is a
6761 foreach-statement only because the initial declaration or
6762 expression is terminated by 'in' instead of ';'.
6764 IF_P is used to track whether there's a (possibly labeled) if statement
6765 which is not enclosed in braces and has an else clause. This is used to
6766 implement -Wparentheses. */
6769 c_parser_for_statement (c_parser
*parser
, bool ivdep
, unsigned short unroll
,
6772 tree block
, cond
, incr
, body
;
6773 unsigned char save_in_statement
;
6774 tree save_objc_foreach_break_label
, save_objc_foreach_continue_label
;
6775 /* The following are only used when parsing an ObjC foreach statement. */
6776 tree object_expression
;
6777 /* Silence the bogus uninitialized warning. */
6778 tree collection_expression
= NULL
;
6779 location_t loc
= c_parser_peek_token (parser
)->location
;
6780 location_t for_loc
= loc
;
6781 bool is_foreach_statement
= false;
6782 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_FOR
));
6783 token_indent_info for_tinfo
6784 = get_token_indent_info (c_parser_peek_token (parser
));
6785 c_parser_consume_token (parser
);
6786 /* Open a compound statement in Objective-C as well, just in case this is
6787 as foreach expression. */
6788 block
= c_begin_compound_stmt (flag_isoc99
|| c_dialect_objc ());
6789 cond
= error_mark_node
;
6790 incr
= error_mark_node
;
6791 matching_parens parens
;
6792 if (parens
.require_open (parser
))
6794 /* Parse the initialization declaration or expression. */
6795 object_expression
= error_mark_node
;
6796 parser
->objc_could_be_foreach_context
= c_dialect_objc ();
6797 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6799 parser
->objc_could_be_foreach_context
= false;
6800 c_parser_consume_token (parser
);
6801 c_finish_expr_stmt (loc
, NULL_TREE
);
6803 else if (c_parser_next_tokens_start_declaration (parser
)
6804 || c_parser_nth_token_starts_std_attributes (parser
, 1))
6806 c_parser_declaration_or_fndef (parser
, true, true, true, true, true,
6807 &object_expression
);
6808 parser
->objc_could_be_foreach_context
= false;
6810 if (c_parser_next_token_is_keyword (parser
, RID_IN
))
6812 c_parser_consume_token (parser
);
6813 is_foreach_statement
= true;
6814 if (check_for_loop_decls (for_loc
, true) == NULL_TREE
)
6815 c_parser_error (parser
, "multiple iterating variables in "
6816 "fast enumeration");
6819 check_for_loop_decls (for_loc
, flag_isoc99
);
6821 else if (c_parser_next_token_is_keyword (parser
, RID_EXTENSION
))
6823 /* __extension__ can start a declaration, but is also an
6824 unary operator that can start an expression. Consume all
6825 but the last of a possible series of __extension__ to
6827 while (c_parser_peek_2nd_token (parser
)->type
== CPP_KEYWORD
6828 && (c_parser_peek_2nd_token (parser
)->keyword
6830 c_parser_consume_token (parser
);
6831 if (c_token_starts_declaration (c_parser_peek_2nd_token (parser
))
6832 || c_parser_nth_token_starts_std_attributes (parser
, 2))
6835 ext
= disable_extension_diagnostics ();
6836 c_parser_consume_token (parser
);
6837 c_parser_declaration_or_fndef (parser
, true, true, true, true,
6838 true, &object_expression
);
6839 parser
->objc_could_be_foreach_context
= false;
6841 restore_extension_diagnostics (ext
);
6842 if (c_parser_next_token_is_keyword (parser
, RID_IN
))
6844 c_parser_consume_token (parser
);
6845 is_foreach_statement
= true;
6846 if (check_for_loop_decls (for_loc
, true) == NULL_TREE
)
6847 c_parser_error (parser
, "multiple iterating variables in "
6848 "fast enumeration");
6851 check_for_loop_decls (for_loc
, flag_isoc99
);
6861 tree init_expression
;
6862 ce
= c_parser_expression (parser
);
6863 init_expression
= ce
.value
;
6864 parser
->objc_could_be_foreach_context
= false;
6865 if (c_parser_next_token_is_keyword (parser
, RID_IN
))
6867 c_parser_consume_token (parser
);
6868 is_foreach_statement
= true;
6869 if (! lvalue_p (init_expression
))
6870 c_parser_error (parser
, "invalid iterating variable in "
6871 "fast enumeration");
6873 = c_fully_fold (init_expression
, false, NULL
);
6877 ce
= convert_lvalue_to_rvalue (loc
, ce
, true, false);
6878 init_expression
= ce
.value
;
6879 c_finish_expr_stmt (loc
, init_expression
);
6880 c_parser_skip_until_found (parser
, CPP_SEMICOLON
,
6885 /* Parse the loop condition. In the case of a foreach
6886 statement, there is no loop condition. */
6887 gcc_assert (!parser
->objc_could_be_foreach_context
);
6888 if (!is_foreach_statement
)
6890 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6894 c_parser_error (parser
, "missing loop condition in loop "
6895 "with %<GCC ivdep%> pragma");
6896 cond
= error_mark_node
;
6900 c_parser_error (parser
, "missing loop condition in loop "
6901 "with %<GCC unroll%> pragma");
6902 cond
= error_mark_node
;
6906 c_parser_consume_token (parser
);
6912 cond
= c_parser_condition (parser
);
6913 c_parser_skip_until_found (parser
, CPP_SEMICOLON
,
6916 if (ivdep
&& cond
!= error_mark_node
)
6917 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
6918 build_int_cst (integer_type_node
,
6919 annot_expr_ivdep_kind
),
6921 if (unroll
&& cond
!= error_mark_node
)
6922 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
6923 build_int_cst (integer_type_node
,
6924 annot_expr_unroll_kind
),
6925 build_int_cst (integer_type_node
, unroll
));
6927 /* Parse the increment expression (the third expression in a
6928 for-statement). In the case of a foreach-statement, this is
6929 the expression that follows the 'in'. */
6930 loc
= c_parser_peek_token (parser
)->location
;
6931 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
6933 if (is_foreach_statement
)
6935 c_parser_error (parser
,
6936 "missing collection in fast enumeration");
6937 collection_expression
= error_mark_node
;
6940 incr
= c_process_expr_stmt (loc
, NULL_TREE
);
6944 if (is_foreach_statement
)
6945 collection_expression
6946 = c_fully_fold (c_parser_expression (parser
).value
, false, NULL
);
6949 struct c_expr ce
= c_parser_expression (parser
);
6950 ce
= convert_lvalue_to_rvalue (loc
, ce
, true, false);
6951 incr
= c_process_expr_stmt (loc
, ce
.value
);
6954 parens
.skip_until_found_close (parser
);
6956 save_in_statement
= in_statement
;
6957 if (is_foreach_statement
)
6959 in_statement
= IN_OBJC_FOREACH
;
6960 save_objc_foreach_break_label
= objc_foreach_break_label
;
6961 save_objc_foreach_continue_label
= objc_foreach_continue_label
;
6962 objc_foreach_break_label
= create_artificial_label (loc
);
6963 objc_foreach_continue_label
= create_artificial_label (loc
);
6966 in_statement
= IN_ITERATION_STMT
;
6968 token_indent_info body_tinfo
6969 = get_token_indent_info (c_parser_peek_token (parser
));
6971 location_t loc_after_labels
;
6972 bool open_brace
= c_parser_next_token_is (parser
, CPP_OPEN_BRACE
);
6973 body
= c_parser_c99_block_statement (parser
, if_p
, &loc_after_labels
);
6975 if (is_foreach_statement
)
6976 objc_finish_foreach_loop (for_loc
, object_expression
,
6977 collection_expression
, body
,
6978 objc_foreach_break_label
,
6979 objc_foreach_continue_label
);
6981 add_stmt (build_stmt (for_loc
, FOR_STMT
, NULL_TREE
, cond
, incr
,
6983 add_stmt (c_end_compound_stmt (for_loc
, block
,
6984 flag_isoc99
|| c_dialect_objc ()));
6985 c_parser_maybe_reclassify_token (parser
);
6987 token_indent_info next_tinfo
6988 = get_token_indent_info (c_parser_peek_token (parser
));
6989 warn_for_misleading_indentation (for_tinfo
, body_tinfo
, next_tinfo
);
6991 if (next_tinfo
.type
!= CPP_SEMICOLON
&& !open_brace
)
6992 warn_for_multistatement_macros (loc_after_labels
, next_tinfo
.location
,
6993 for_tinfo
.location
, RID_FOR
);
6995 in_statement
= save_in_statement
;
6996 if (is_foreach_statement
)
6998 objc_foreach_break_label
= save_objc_foreach_break_label
;
6999 objc_foreach_continue_label
= save_objc_foreach_continue_label
;
7003 /* Parse an asm statement, a GNU extension. This is a full-blown asm
7004 statement with inputs, outputs, clobbers, and volatile, inline, and goto
7013 asm-qualifier-list asm-qualifier
7017 asm asm-qualifier-list[opt] ( asm-argument ) ;
7021 asm-string-literal : asm-operands[opt]
7022 asm-string-literal : asm-operands[opt] : asm-operands[opt]
7023 asm-string-literal : asm-operands[opt] : asm-operands[opt] \
7025 asm-string-literal : : asm-operands[opt] : asm-clobbers[opt] \
7028 The form with asm-goto-operands is valid if and only if the
7029 asm-qualifier-list contains goto, and is the only allowed form in that case.
7030 Duplicate asm-qualifiers are not allowed.
7032 The :: token is considered equivalent to two consecutive : tokens. */
7035 c_parser_asm_statement (c_parser
*parser
)
7037 tree str
, outputs
, inputs
, clobbers
, labels
, ret
;
7039 location_t asm_loc
= c_parser_peek_token (parser
)->location
;
7040 int section
, nsections
;
7042 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ASM
));
7043 c_parser_consume_token (parser
);
7045 /* Handle the asm-qualifier-list. */
7046 location_t volatile_loc
= UNKNOWN_LOCATION
;
7047 location_t inline_loc
= UNKNOWN_LOCATION
;
7048 location_t goto_loc
= UNKNOWN_LOCATION
;
7051 c_token
*token
= c_parser_peek_token (parser
);
7052 location_t loc
= token
->location
;
7053 switch (token
->keyword
)
7058 error_at (loc
, "duplicate %<asm%> qualifier %qE", token
->value
);
7059 inform (volatile_loc
, "first seen here");
7063 c_parser_consume_token (parser
);
7069 error_at (loc
, "duplicate %<asm%> qualifier %qE", token
->value
);
7070 inform (inline_loc
, "first seen here");
7074 c_parser_consume_token (parser
);
7080 error_at (loc
, "duplicate %<asm%> qualifier %qE", token
->value
);
7081 inform (goto_loc
, "first seen here");
7085 c_parser_consume_token (parser
);
7090 error_at (loc
, "%qE is not a valid %<asm%> qualifier", token
->value
);
7091 c_parser_consume_token (parser
);
7100 bool is_volatile
= (volatile_loc
!= UNKNOWN_LOCATION
);
7101 bool is_inline
= (inline_loc
!= UNKNOWN_LOCATION
);
7102 bool is_goto
= (goto_loc
!= UNKNOWN_LOCATION
);
7106 matching_parens parens
;
7107 if (!parens
.require_open (parser
))
7110 str
= c_parser_asm_string_literal (parser
);
7111 if (str
== NULL_TREE
)
7112 goto error_close_paren
;
7115 outputs
= NULL_TREE
;
7117 clobbers
= NULL_TREE
;
7120 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
) && !is_goto
)
7123 /* Parse each colon-delimited section of operands. */
7124 nsections
= 3 + is_goto
;
7125 for (section
= 0; section
< nsections
; ++section
)
7127 if (c_parser_next_token_is (parser
, CPP_SCOPE
))
7130 if (section
== nsections
)
7132 c_parser_error (parser
, "expected %<)%>");
7133 goto error_close_paren
;
7135 c_parser_consume_token (parser
);
7137 else if (!c_parser_require (parser
, CPP_COLON
,
7139 ? G_("expected %<:%>")
7140 : G_("expected %<:%> or %<)%>"),
7141 UNKNOWN_LOCATION
, is_goto
))
7142 goto error_close_paren
;
7144 /* Once past any colon, we're no longer a simple asm. */
7147 if ((!c_parser_next_token_is (parser
, CPP_COLON
)
7148 && !c_parser_next_token_is (parser
, CPP_SCOPE
)
7149 && !c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
7154 outputs
= c_parser_asm_operands (parser
);
7157 inputs
= c_parser_asm_operands (parser
);
7160 clobbers
= c_parser_asm_clobbers (parser
);
7163 labels
= c_parser_asm_goto_operands (parser
);
7169 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
) && !is_goto
)
7174 if (!parens
.require_close (parser
))
7176 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
7180 if (!c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
7181 c_parser_skip_to_end_of_block_or_statement (parser
);
7183 ret
= build_asm_stmt (is_volatile
,
7184 build_asm_expr (asm_loc
, str
, outputs
, inputs
,
7185 clobbers
, labels
, simple
, is_inline
));
7191 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
7195 /* Parse asm operands, a GNU extension.
7199 asm-operands , asm-operand
7202 asm-string-literal ( expression )
7203 [ identifier ] asm-string-literal ( expression )
7207 c_parser_asm_operands (c_parser
*parser
)
7209 tree list
= NULL_TREE
;
7214 if (c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
))
7216 c_parser_consume_token (parser
);
7217 if (c_parser_next_token_is (parser
, CPP_NAME
))
7219 tree id
= c_parser_peek_token (parser
)->value
;
7220 c_parser_consume_token (parser
);
7221 name
= build_string (IDENTIFIER_LENGTH (id
),
7222 IDENTIFIER_POINTER (id
));
7226 c_parser_error (parser
, "expected identifier");
7227 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
, NULL
);
7230 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
7235 str
= c_parser_asm_string_literal (parser
);
7236 if (str
== NULL_TREE
)
7238 matching_parens parens
;
7239 if (!parens
.require_open (parser
))
7241 expr
= c_parser_expression (parser
);
7242 mark_exp_read (expr
.value
);
7243 if (!parens
.require_close (parser
))
7245 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
7248 list
= chainon (list
, build_tree_list (build_tree_list (name
, str
),
7250 if (c_parser_next_token_is (parser
, CPP_COMMA
))
7251 c_parser_consume_token (parser
);
7258 /* Parse asm clobbers, a GNU extension.
7262 asm-clobbers , asm-string-literal
7266 c_parser_asm_clobbers (c_parser
*parser
)
7268 tree list
= NULL_TREE
;
7271 tree str
= c_parser_asm_string_literal (parser
);
7273 list
= tree_cons (NULL_TREE
, str
, list
);
7276 if (c_parser_next_token_is (parser
, CPP_COMMA
))
7277 c_parser_consume_token (parser
);
7284 /* Parse asm goto labels, a GNU extension.
7288 asm-goto-operands , identifier
7292 c_parser_asm_goto_operands (c_parser
*parser
)
7294 tree list
= NULL_TREE
;
7299 if (c_parser_next_token_is (parser
, CPP_NAME
))
7301 c_token
*tok
= c_parser_peek_token (parser
);
7303 label
= lookup_label_for_goto (tok
->location
, name
);
7304 c_parser_consume_token (parser
);
7305 TREE_USED (label
) = 1;
7309 c_parser_error (parser
, "expected identifier");
7313 name
= build_string (IDENTIFIER_LENGTH (name
),
7314 IDENTIFIER_POINTER (name
));
7315 list
= tree_cons (name
, label
, list
);
7316 if (c_parser_next_token_is (parser
, CPP_COMMA
))
7317 c_parser_consume_token (parser
);
7319 return nreverse (list
);
7323 /* Parse a possibly concatenated sequence of string literals.
7324 TRANSLATE says whether to translate them to the execution character
7325 set; WIDE_OK says whether any kind of prefixed string literal is
7326 permitted in this context. This code is based on that in
7330 c_parser_string_literal (c_parser
*parser
, bool translate
, bool wide_ok
)
7334 struct obstack str_ob
;
7335 struct obstack loc_ob
;
7336 cpp_string str
, istr
, *strs
;
7338 location_t loc
, last_tok_loc
;
7339 enum cpp_ttype type
;
7340 tree value
, string_tree
;
7342 tok
= c_parser_peek_token (parser
);
7343 loc
= tok
->location
;
7344 last_tok_loc
= linemap_resolve_location (line_table
, loc
,
7345 LRK_MACRO_DEFINITION_LOCATION
,
7354 case CPP_UTF8STRING
:
7355 string_tree
= tok
->value
;
7359 c_parser_error (parser
, "expected string literal");
7361 ret
.value
= NULL_TREE
;
7362 ret
.original_code
= ERROR_MARK
;
7363 ret
.original_type
= NULL_TREE
;
7367 /* Try to avoid the overhead of creating and destroying an obstack
7368 for the common case of just one string. */
7369 switch (c_parser_peek_2nd_token (parser
)->type
)
7372 c_parser_consume_token (parser
);
7373 str
.text
= (const unsigned char *) TREE_STRING_POINTER (string_tree
);
7374 str
.len
= TREE_STRING_LENGTH (string_tree
);
7383 case CPP_UTF8STRING
:
7384 gcc_obstack_init (&str_ob
);
7385 gcc_obstack_init (&loc_ob
);
7389 c_parser_consume_token (parser
);
7391 str
.text
= (const unsigned char *) TREE_STRING_POINTER (string_tree
);
7392 str
.len
= TREE_STRING_LENGTH (string_tree
);
7393 if (type
!= tok
->type
)
7395 if (type
== CPP_STRING
)
7397 else if (tok
->type
!= CPP_STRING
)
7398 error ("unsupported non-standard concatenation "
7399 "of string literals");
7401 obstack_grow (&str_ob
, &str
, sizeof (cpp_string
));
7402 obstack_grow (&loc_ob
, &last_tok_loc
, sizeof (location_t
));
7403 tok
= c_parser_peek_token (parser
);
7404 string_tree
= tok
->value
;
7406 = linemap_resolve_location (line_table
, tok
->location
,
7407 LRK_MACRO_DEFINITION_LOCATION
, NULL
);
7409 while (tok
->type
== CPP_STRING
7410 || tok
->type
== CPP_WSTRING
7411 || tok
->type
== CPP_STRING16
7412 || tok
->type
== CPP_STRING32
7413 || tok
->type
== CPP_UTF8STRING
);
7414 strs
= (cpp_string
*) obstack_finish (&str_ob
);
7417 if (count
> 1 && !in_system_header_at (input_location
))
7418 warning (OPT_Wtraditional
,
7419 "traditional C rejects string constant concatenation");
7421 if ((type
== CPP_STRING
|| wide_ok
)
7423 ? cpp_interpret_string
: cpp_interpret_string_notranslate
)
7424 (parse_in
, strs
, count
, &istr
, type
)))
7426 value
= build_string (istr
.len
, (const char *) istr
.text
);
7427 free (CONST_CAST (unsigned char *, istr
.text
));
7430 location_t
*locs
= (location_t
*) obstack_finish (&loc_ob
);
7431 gcc_assert (g_string_concat_db
);
7432 g_string_concat_db
->record_string_concatenation (count
, locs
);
7437 if (type
!= CPP_STRING
&& !wide_ok
)
7439 error_at (loc
, "a wide string is invalid in this context");
7442 /* Callers cannot generally handle error_mark_node in this
7443 context, so return the empty string instead. An error has
7444 been issued, either above or from cpp_interpret_string. */
7449 case CPP_UTF8STRING
:
7450 value
= build_string (1, "");
7453 value
= build_string (TYPE_PRECISION (char16_type_node
)
7454 / TYPE_PRECISION (char_type_node
),
7455 "\0"); /* char16_t is 16 bits */
7458 value
= build_string (TYPE_PRECISION (char32_type_node
)
7459 / TYPE_PRECISION (char_type_node
),
7460 "\0\0\0"); /* char32_t is 32 bits */
7463 value
= build_string (TYPE_PRECISION (wchar_type_node
)
7464 / TYPE_PRECISION (char_type_node
),
7465 "\0\0\0"); /* widest supported wchar_t
7475 case CPP_UTF8STRING
:
7476 TREE_TYPE (value
) = char_array_type_node
;
7479 TREE_TYPE (value
) = char16_array_type_node
;
7482 TREE_TYPE (value
) = char32_array_type_node
;
7485 TREE_TYPE (value
) = wchar_array_type_node
;
7487 value
= fix_string_type (value
);
7491 obstack_free (&str_ob
, 0);
7492 obstack_free (&loc_ob
, 0);
7496 ret
.original_code
= STRING_CST
;
7497 ret
.original_type
= NULL_TREE
;
7498 set_c_expr_source_range (&ret
, get_range_from_loc (line_table
, loc
));
7499 parser
->seen_string_literal
= true;
7503 /* Parse an expression other than a compound expression; that is, an
7504 assignment expression (C90 6.3.16, C99 6.5.16, C11 6.5.16). If
7505 AFTER is not NULL then it is an Objective-C message expression which
7506 is the primary-expression starting the expression as an initializer.
7508 assignment-expression:
7509 conditional-expression
7510 unary-expression assignment-operator assignment-expression
7512 assignment-operator: one of
7513 = *= /= %= += -= <<= >>= &= ^= |=
7515 In GNU C we accept any conditional expression on the LHS and
7516 diagnose the invalid lvalue rather than producing a syntax
7519 static struct c_expr
7520 c_parser_expr_no_commas (c_parser
*parser
, struct c_expr
*after
,
7521 tree omp_atomic_lhs
)
7523 struct c_expr lhs
, rhs
, ret
;
7524 enum tree_code code
;
7525 location_t op_location
, exp_location
;
7526 bool save_in_omp_for
= c_in_omp_for
;
7527 c_in_omp_for
= false;
7528 gcc_assert (!after
|| c_dialect_objc ());
7529 lhs
= c_parser_conditional_expression (parser
, after
, omp_atomic_lhs
);
7530 op_location
= c_parser_peek_token (parser
)->location
;
7531 switch (c_parser_peek_token (parser
)->type
)
7540 code
= TRUNC_DIV_EXPR
;
7543 code
= TRUNC_MOD_EXPR
;
7558 code
= BIT_AND_EXPR
;
7561 code
= BIT_XOR_EXPR
;
7564 code
= BIT_IOR_EXPR
;
7567 c_in_omp_for
= save_in_omp_for
;
7570 c_parser_consume_token (parser
);
7571 exp_location
= c_parser_peek_token (parser
)->location
;
7572 rhs
= c_parser_expr_no_commas (parser
, NULL
);
7573 rhs
= convert_lvalue_to_rvalue (exp_location
, rhs
, true, true);
7575 ret
.value
= build_modify_expr (op_location
, lhs
.value
, lhs
.original_type
,
7576 code
, exp_location
, rhs
.value
,
7578 set_c_expr_source_range (&ret
, lhs
.get_start (), rhs
.get_finish ());
7579 if (code
== NOP_EXPR
)
7580 ret
.original_code
= MODIFY_EXPR
;
7583 suppress_warning (ret
.value
, OPT_Wparentheses
);
7584 ret
.original_code
= ERROR_MARK
;
7586 ret
.original_type
= NULL
;
7587 c_in_omp_for
= save_in_omp_for
;
7591 /* Parse a conditional expression (C90 6.3.15, C99 6.5.15, C11 6.5.15). If
7592 AFTER is not NULL then it is an Objective-C message expression which is
7593 the primary-expression starting the expression as an initializer.
7595 conditional-expression:
7596 logical-OR-expression
7597 logical-OR-expression ? expression : conditional-expression
7601 conditional-expression:
7602 logical-OR-expression ? : conditional-expression
7605 static struct c_expr
7606 c_parser_conditional_expression (c_parser
*parser
, struct c_expr
*after
,
7607 tree omp_atomic_lhs
)
7609 struct c_expr cond
, exp1
, exp2
, ret
;
7610 location_t start
, cond_loc
, colon_loc
;
7612 gcc_assert (!after
|| c_dialect_objc ());
7614 cond
= c_parser_binary_expression (parser
, after
, omp_atomic_lhs
);
7616 if (c_parser_next_token_is_not (parser
, CPP_QUERY
))
7618 if (cond
.value
!= error_mark_node
)
7619 start
= cond
.get_start ();
7621 start
= UNKNOWN_LOCATION
;
7622 cond_loc
= c_parser_peek_token (parser
)->location
;
7623 cond
= convert_lvalue_to_rvalue (cond_loc
, cond
, true, true);
7624 c_parser_consume_token (parser
);
7625 if (c_parser_next_token_is (parser
, CPP_COLON
))
7627 tree eptype
= NULL_TREE
;
7629 location_t middle_loc
= c_parser_peek_token (parser
)->location
;
7630 pedwarn (middle_loc
, OPT_Wpedantic
,
7631 "ISO C forbids omitting the middle term of a %<?:%> expression");
7632 if (TREE_CODE (cond
.value
) == EXCESS_PRECISION_EXPR
)
7634 eptype
= TREE_TYPE (cond
.value
);
7635 cond
.value
= TREE_OPERAND (cond
.value
, 0);
7637 tree e
= cond
.value
;
7638 while (TREE_CODE (e
) == COMPOUND_EXPR
)
7639 e
= TREE_OPERAND (e
, 1);
7640 warn_for_omitted_condop (middle_loc
, e
);
7641 /* Make sure first operand is calculated only once. */
7642 exp1
.value
= save_expr (default_conversion (cond
.value
));
7644 exp1
.value
= build1 (EXCESS_PRECISION_EXPR
, eptype
, exp1
.value
);
7645 exp1
.original_type
= NULL
;
7646 exp1
.src_range
= cond
.src_range
;
7647 cond
.value
= c_objc_common_truthvalue_conversion (cond_loc
, exp1
.value
);
7648 c_inhibit_evaluation_warnings
+= cond
.value
== truthvalue_true_node
;
7653 = c_objc_common_truthvalue_conversion
7654 (cond_loc
, default_conversion (cond
.value
));
7655 c_inhibit_evaluation_warnings
+= cond
.value
== truthvalue_false_node
;
7656 exp1
= c_parser_expression_conv (parser
);
7657 mark_exp_read (exp1
.value
);
7658 c_inhibit_evaluation_warnings
+=
7659 ((cond
.value
== truthvalue_true_node
)
7660 - (cond
.value
== truthvalue_false_node
));
7663 colon_loc
= c_parser_peek_token (parser
)->location
;
7664 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
7666 c_inhibit_evaluation_warnings
-= cond
.value
== truthvalue_true_node
;
7668 ret
.original_code
= ERROR_MARK
;
7669 ret
.original_type
= NULL
;
7673 location_t exp2_loc
= c_parser_peek_token (parser
)->location
;
7674 exp2
= c_parser_conditional_expression (parser
, NULL
, NULL_TREE
);
7675 exp2
= convert_lvalue_to_rvalue (exp2_loc
, exp2
, true, true);
7677 c_inhibit_evaluation_warnings
-= cond
.value
== truthvalue_true_node
;
7678 location_t loc1
= make_location (exp1
.get_start (), exp1
.src_range
);
7679 location_t loc2
= make_location (exp2
.get_start (), exp2
.src_range
);
7680 if (UNLIKELY (omp_atomic_lhs
!= NULL
)
7681 && (TREE_CODE (cond
.value
) == GT_EXPR
7682 || TREE_CODE (cond
.value
) == LT_EXPR
7683 || TREE_CODE (cond
.value
) == EQ_EXPR
)
7684 && c_tree_equal (exp2
.value
, omp_atomic_lhs
)
7685 && (c_tree_equal (TREE_OPERAND (cond
.value
, 0), omp_atomic_lhs
)
7686 || c_tree_equal (TREE_OPERAND (cond
.value
, 1), omp_atomic_lhs
)))
7687 ret
.value
= build3_loc (colon_loc
, COND_EXPR
, TREE_TYPE (omp_atomic_lhs
),
7688 cond
.value
, exp1
.value
, exp2
.value
);
7691 = build_conditional_expr (colon_loc
, cond
.value
,
7692 cond
.original_code
== C_MAYBE_CONST_EXPR
,
7693 exp1
.value
, exp1
.original_type
, loc1
,
7694 exp2
.value
, exp2
.original_type
, loc2
);
7695 ret
.original_code
= ERROR_MARK
;
7696 if (exp1
.value
== error_mark_node
|| exp2
.value
== error_mark_node
)
7697 ret
.original_type
= NULL
;
7702 /* If both sides are enum type, the default conversion will have
7703 made the type of the result be an integer type. We want to
7704 remember the enum types we started with. */
7705 t1
= exp1
.original_type
? exp1
.original_type
: TREE_TYPE (exp1
.value
);
7706 t2
= exp2
.original_type
? exp2
.original_type
: TREE_TYPE (exp2
.value
);
7707 ret
.original_type
= ((t1
!= error_mark_node
7708 && t2
!= error_mark_node
7709 && (TYPE_MAIN_VARIANT (t1
)
7710 == TYPE_MAIN_VARIANT (t2
)))
7714 set_c_expr_source_range (&ret
, start
, exp2
.get_finish ());
7718 /* Parse a binary expression; that is, a logical-OR-expression (C90
7719 6.3.5-6.3.14, C99 6.5.5-6.5.14, C11 6.5.5-6.5.14). If AFTER is not
7720 NULL then it is an Objective-C message expression which is the
7721 primary-expression starting the expression as an initializer.
7723 OMP_ATOMIC_LHS is NULL, unless parsing OpenMP #pragma omp atomic,
7724 when it should be the unfolded lhs. In a valid OpenMP source,
7725 one of the operands of the toplevel binary expression must be equal
7726 to it. In that case, just return a build2 created binary operation
7727 rather than result of parser_build_binary_op.
7729 multiplicative-expression:
7731 multiplicative-expression * cast-expression
7732 multiplicative-expression / cast-expression
7733 multiplicative-expression % cast-expression
7735 additive-expression:
7736 multiplicative-expression
7737 additive-expression + multiplicative-expression
7738 additive-expression - multiplicative-expression
7742 shift-expression << additive-expression
7743 shift-expression >> additive-expression
7745 relational-expression:
7747 relational-expression < shift-expression
7748 relational-expression > shift-expression
7749 relational-expression <= shift-expression
7750 relational-expression >= shift-expression
7752 equality-expression:
7753 relational-expression
7754 equality-expression == relational-expression
7755 equality-expression != relational-expression
7759 AND-expression & equality-expression
7761 exclusive-OR-expression:
7763 exclusive-OR-expression ^ AND-expression
7765 inclusive-OR-expression:
7766 exclusive-OR-expression
7767 inclusive-OR-expression | exclusive-OR-expression
7769 logical-AND-expression:
7770 inclusive-OR-expression
7771 logical-AND-expression && inclusive-OR-expression
7773 logical-OR-expression:
7774 logical-AND-expression
7775 logical-OR-expression || logical-AND-expression
7778 static struct c_expr
7779 c_parser_binary_expression (c_parser
*parser
, struct c_expr
*after
,
7780 tree omp_atomic_lhs
)
7782 /* A binary expression is parsed using operator-precedence parsing,
7783 with the operands being cast expressions. All the binary
7784 operators are left-associative. Thus a binary expression is of
7787 E0 op1 E1 op2 E2 ...
7789 which we represent on a stack. On the stack, the precedence
7790 levels are strictly increasing. When a new operator is
7791 encountered of higher precedence than that at the top of the
7792 stack, it is pushed; its LHS is the top expression, and its RHS
7793 is everything parsed until it is popped. When a new operator is
7794 encountered with precedence less than or equal to that at the top
7795 of the stack, triples E[i-1] op[i] E[i] are popped and replaced
7796 by the result of the operation until the operator at the top of
7797 the stack has lower precedence than the new operator or there is
7798 only one element on the stack; then the top expression is the LHS
7799 of the new operator. In the case of logical AND and OR
7800 expressions, we also need to adjust c_inhibit_evaluation_warnings
7801 as appropriate when the operators are pushed and popped. */
7804 /* The expression at this stack level. */
7806 /* The precedence of the operator on its left, PREC_NONE at the
7807 bottom of the stack. */
7808 enum c_parser_prec prec
;
7809 /* The operation on its left. */
7811 /* The source location of this operation. */
7813 /* The sizeof argument if expr.original_code == {PAREN_,}SIZEOF_EXPR. */
7817 /* Location of the binary operator. */
7818 location_t binary_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
7821 switch (stack[sp].op) \
7823 case TRUTH_ANDIF_EXPR: \
7824 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
7825 == truthvalue_false_node); \
7827 case TRUTH_ORIF_EXPR: \
7828 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
7829 == truthvalue_true_node); \
7831 case TRUNC_DIV_EXPR: \
7832 if ((stack[sp - 1].expr.original_code == SIZEOF_EXPR \
7833 || stack[sp - 1].expr.original_code == PAREN_SIZEOF_EXPR) \
7834 && (stack[sp].expr.original_code == SIZEOF_EXPR \
7835 || stack[sp].expr.original_code == PAREN_SIZEOF_EXPR)) \
7837 tree type0 = stack[sp - 1].sizeof_arg; \
7838 tree type1 = stack[sp].sizeof_arg; \
7839 tree first_arg = type0; \
7840 if (!TYPE_P (type0)) \
7841 type0 = TREE_TYPE (type0); \
7842 if (!TYPE_P (type1)) \
7843 type1 = TREE_TYPE (type1); \
7844 if (POINTER_TYPE_P (type0) \
7845 && comptypes (TREE_TYPE (type0), type1) \
7846 && !(TREE_CODE (first_arg) == PARM_DECL \
7847 && C_ARRAY_PARAMETER (first_arg) \
7848 && warn_sizeof_array_argument)) \
7850 auto_diagnostic_group d; \
7851 if (warning_at (stack[sp].loc, OPT_Wsizeof_pointer_div, \
7852 "division %<sizeof (%T) / sizeof (%T)%> " \
7853 "does not compute the number of array " \
7856 if (DECL_P (first_arg)) \
7857 inform (DECL_SOURCE_LOCATION (first_arg), \
7858 "first %<sizeof%> operand was declared here"); \
7860 else if (TREE_CODE (type0) == ARRAY_TYPE \
7861 && !char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type0))) \
7862 && stack[sp].expr.original_code != PAREN_SIZEOF_EXPR) \
7863 maybe_warn_sizeof_array_div (stack[sp].loc, first_arg, type0, \
7864 stack[sp].sizeof_arg, type1); \
7870 stack[sp - 1].expr \
7871 = convert_lvalue_to_rvalue (stack[sp - 1].loc, \
7872 stack[sp - 1].expr, true, true); \
7874 = convert_lvalue_to_rvalue (stack[sp].loc, \
7875 stack[sp].expr, true, true); \
7876 if (UNLIKELY (omp_atomic_lhs != NULL_TREE) && sp == 1 \
7877 && ((c_parser_next_token_is (parser, CPP_SEMICOLON) \
7878 && ((1 << stack[sp].prec) \
7879 & ((1 << PREC_BITOR) | (1 << PREC_BITXOR) \
7880 | (1 << PREC_BITAND) | (1 << PREC_SHIFT) \
7881 | (1 << PREC_ADD) | (1 << PREC_MULT) \
7882 | (1 << PREC_EQ)))) \
7883 || ((c_parser_next_token_is (parser, CPP_QUERY) \
7884 || (omp_atomic_lhs == void_list_node \
7885 && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))) \
7886 && (stack[sp].prec == PREC_REL || stack[sp].prec == PREC_EQ)))\
7887 && stack[sp].op != TRUNC_MOD_EXPR \
7888 && stack[sp].op != GE_EXPR \
7889 && stack[sp].op != LE_EXPR \
7890 && stack[sp].op != NE_EXPR \
7891 && stack[0].expr.value != error_mark_node \
7892 && stack[1].expr.value != error_mark_node \
7893 && (omp_atomic_lhs == void_list_node \
7894 || c_tree_equal (stack[0].expr.value, omp_atomic_lhs) \
7895 || c_tree_equal (stack[1].expr.value, omp_atomic_lhs) \
7896 || (stack[sp].op == EQ_EXPR \
7897 && c_parser_peek_2nd_token (parser)->keyword == RID_IF))) \
7899 tree t = make_node (stack[1].op); \
7900 TREE_TYPE (t) = TREE_TYPE (stack[0].expr.value); \
7901 TREE_OPERAND (t, 0) = stack[0].expr.value; \
7902 TREE_OPERAND (t, 1) = stack[1].expr.value; \
7903 stack[0].expr.value = t; \
7906 stack[sp - 1].expr = parser_build_binary_op (stack[sp].loc, \
7908 stack[sp - 1].expr, \
7912 gcc_assert (!after
|| c_dialect_objc ());
7913 stack
[0].loc
= c_parser_peek_token (parser
)->location
;
7914 stack
[0].expr
= c_parser_cast_expression (parser
, after
);
7915 stack
[0].prec
= PREC_NONE
;
7916 stack
[0].sizeof_arg
= c_last_sizeof_arg
;
7920 enum c_parser_prec oprec
;
7921 enum tree_code ocode
;
7922 source_range src_range
;
7925 switch (c_parser_peek_token (parser
)->type
)
7933 ocode
= TRUNC_DIV_EXPR
;
7937 ocode
= TRUNC_MOD_EXPR
;
7949 ocode
= LSHIFT_EXPR
;
7953 ocode
= RSHIFT_EXPR
;
7967 case CPP_GREATER_EQ
:
7980 oprec
= PREC_BITAND
;
7981 ocode
= BIT_AND_EXPR
;
7984 oprec
= PREC_BITXOR
;
7985 ocode
= BIT_XOR_EXPR
;
7989 ocode
= BIT_IOR_EXPR
;
7992 oprec
= PREC_LOGAND
;
7993 ocode
= TRUTH_ANDIF_EXPR
;
7997 ocode
= TRUTH_ORIF_EXPR
;
8000 /* Not a binary operator, so end of the binary
8004 binary_loc
= c_parser_peek_token (parser
)->location
;
8005 while (oprec
<= stack
[sp
].prec
)
8007 c_parser_consume_token (parser
);
8010 case TRUTH_ANDIF_EXPR
:
8011 src_range
= stack
[sp
].expr
.src_range
;
8013 = convert_lvalue_to_rvalue (stack
[sp
].loc
,
8014 stack
[sp
].expr
, true, true);
8015 stack
[sp
].expr
.value
= c_objc_common_truthvalue_conversion
8016 (stack
[sp
].loc
, default_conversion (stack
[sp
].expr
.value
));
8017 c_inhibit_evaluation_warnings
+= (stack
[sp
].expr
.value
8018 == truthvalue_false_node
);
8019 set_c_expr_source_range (&stack
[sp
].expr
, src_range
);
8021 case TRUTH_ORIF_EXPR
:
8022 src_range
= stack
[sp
].expr
.src_range
;
8024 = convert_lvalue_to_rvalue (stack
[sp
].loc
,
8025 stack
[sp
].expr
, true, true);
8026 stack
[sp
].expr
.value
= c_objc_common_truthvalue_conversion
8027 (stack
[sp
].loc
, default_conversion (stack
[sp
].expr
.value
));
8028 c_inhibit_evaluation_warnings
+= (stack
[sp
].expr
.value
8029 == truthvalue_true_node
);
8030 set_c_expr_source_range (&stack
[sp
].expr
, src_range
);
8036 stack
[sp
].loc
= binary_loc
;
8037 stack
[sp
].expr
= c_parser_cast_expression (parser
, NULL
);
8038 stack
[sp
].prec
= oprec
;
8039 stack
[sp
].op
= ocode
;
8040 stack
[sp
].sizeof_arg
= c_last_sizeof_arg
;
8045 return stack
[0].expr
;
8049 /* Parse a cast expression (C90 6.3.4, C99 6.5.4, C11 6.5.4). If AFTER
8050 is not NULL then it is an Objective-C message expression which is the
8051 primary-expression starting the expression as an initializer.
8055 ( type-name ) unary-expression
8058 static struct c_expr
8059 c_parser_cast_expression (c_parser
*parser
, struct c_expr
*after
)
8061 location_t cast_loc
= c_parser_peek_token (parser
)->location
;
8062 gcc_assert (!after
|| c_dialect_objc ());
8064 return c_parser_postfix_expression_after_primary (parser
,
8066 /* If the expression begins with a parenthesized type name, it may
8067 be either a cast or a compound literal; we need to see whether
8068 the next character is '{' to tell the difference. If not, it is
8069 an unary expression. Full detection of unknown typenames here
8070 would require a 3-token lookahead. */
8071 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
)
8072 && c_token_starts_typename (c_parser_peek_2nd_token (parser
)))
8074 struct c_type_name
*type_name
;
8077 matching_parens parens
;
8078 parens
.consume_open (parser
);
8079 type_name
= c_parser_type_name (parser
, true);
8080 parens
.skip_until_found_close (parser
);
8081 if (type_name
== NULL
)
8084 ret
.original_code
= ERROR_MARK
;
8085 ret
.original_type
= NULL
;
8089 /* Save casted types in the function's used types hash table. */
8090 used_types_insert (type_name
->specs
->type
);
8092 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
8093 return c_parser_postfix_expression_after_paren_type (parser
, type_name
,
8095 if (type_name
->specs
->alignas_p
)
8096 error_at (type_name
->specs
->locations
[cdw_alignas
],
8097 "alignment specified for type name in cast");
8099 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
8100 expr
= c_parser_cast_expression (parser
, NULL
);
8101 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, true, true);
8103 ret
.value
= c_cast_expr (cast_loc
, type_name
, expr
.value
);
8104 if (ret
.value
&& expr
.value
)
8105 set_c_expr_source_range (&ret
, cast_loc
, expr
.get_finish ());
8106 ret
.original_code
= ERROR_MARK
;
8107 ret
.original_type
= NULL
;
8111 return c_parser_unary_expression (parser
);
8114 /* Parse an unary expression (C90 6.3.3, C99 6.5.3, C11 6.5.3).
8120 unary-operator cast-expression
8121 sizeof unary-expression
8122 sizeof ( type-name )
8124 unary-operator: one of
8130 __alignof__ unary-expression
8131 __alignof__ ( type-name )
8134 (C11 permits _Alignof with type names only.)
8136 unary-operator: one of
8137 __extension__ __real__ __imag__
8139 Transactional Memory:
8142 transaction-expression
8144 In addition, the GNU syntax treats ++ and -- as unary operators, so
8145 they may be applied to cast expressions with errors for non-lvalues
8148 static struct c_expr
8149 c_parser_unary_expression (c_parser
*parser
)
8152 struct c_expr ret
, op
;
8153 location_t op_loc
= c_parser_peek_token (parser
)->location
;
8156 ret
.original_code
= ERROR_MARK
;
8157 ret
.original_type
= NULL
;
8158 switch (c_parser_peek_token (parser
)->type
)
8161 c_parser_consume_token (parser
);
8162 exp_loc
= c_parser_peek_token (parser
)->location
;
8163 op
= c_parser_cast_expression (parser
, NULL
);
8165 op
= default_function_array_read_conversion (exp_loc
, op
);
8166 return parser_build_unary_op (op_loc
, PREINCREMENT_EXPR
, op
);
8167 case CPP_MINUS_MINUS
:
8168 c_parser_consume_token (parser
);
8169 exp_loc
= c_parser_peek_token (parser
)->location
;
8170 op
= c_parser_cast_expression (parser
, NULL
);
8172 op
= default_function_array_read_conversion (exp_loc
, op
);
8173 return parser_build_unary_op (op_loc
, PREDECREMENT_EXPR
, op
);
8175 c_parser_consume_token (parser
);
8176 op
= c_parser_cast_expression (parser
, NULL
);
8177 mark_exp_read (op
.value
);
8178 return parser_build_unary_op (op_loc
, ADDR_EXPR
, op
);
8181 c_parser_consume_token (parser
);
8182 exp_loc
= c_parser_peek_token (parser
)->location
;
8183 op
= c_parser_cast_expression (parser
, NULL
);
8184 finish
= op
.get_finish ();
8185 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
8186 location_t combined_loc
= make_location (op_loc
, op_loc
, finish
);
8187 ret
.value
= build_indirect_ref (combined_loc
, op
.value
, RO_UNARY_STAR
);
8188 ret
.src_range
.m_start
= op_loc
;
8189 ret
.src_range
.m_finish
= finish
;
8193 if (!c_dialect_objc () && !in_system_header_at (input_location
))
8196 "traditional C rejects the unary plus operator");
8197 c_parser_consume_token (parser
);
8198 exp_loc
= c_parser_peek_token (parser
)->location
;
8199 op
= c_parser_cast_expression (parser
, NULL
);
8200 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
8201 return parser_build_unary_op (op_loc
, CONVERT_EXPR
, op
);
8203 c_parser_consume_token (parser
);
8204 exp_loc
= c_parser_peek_token (parser
)->location
;
8205 op
= c_parser_cast_expression (parser
, NULL
);
8206 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
8207 return parser_build_unary_op (op_loc
, NEGATE_EXPR
, op
);
8209 c_parser_consume_token (parser
);
8210 exp_loc
= c_parser_peek_token (parser
)->location
;
8211 op
= c_parser_cast_expression (parser
, NULL
);
8212 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
8213 return parser_build_unary_op (op_loc
, BIT_NOT_EXPR
, op
);
8215 c_parser_consume_token (parser
);
8216 exp_loc
= c_parser_peek_token (parser
)->location
;
8217 op
= c_parser_cast_expression (parser
, NULL
);
8218 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
8219 return parser_build_unary_op (op_loc
, TRUTH_NOT_EXPR
, op
);
8221 /* Refer to the address of a label as a pointer. */
8222 c_parser_consume_token (parser
);
8223 if (c_parser_next_token_is (parser
, CPP_NAME
))
8225 ret
.value
= finish_label_address_expr
8226 (c_parser_peek_token (parser
)->value
, op_loc
);
8227 set_c_expr_source_range (&ret
, op_loc
,
8228 c_parser_peek_token (parser
)->get_finish ());
8229 c_parser_consume_token (parser
);
8233 c_parser_error (parser
, "expected identifier");
8238 switch (c_parser_peek_token (parser
)->keyword
)
8241 return c_parser_sizeof_expression (parser
);
8243 return c_parser_alignof_expression (parser
);
8244 case RID_BUILTIN_HAS_ATTRIBUTE
:
8245 return c_parser_has_attribute_expression (parser
);
8247 c_parser_consume_token (parser
);
8248 ext
= disable_extension_diagnostics ();
8249 ret
= c_parser_cast_expression (parser
, NULL
);
8250 restore_extension_diagnostics (ext
);
8253 c_parser_consume_token (parser
);
8254 exp_loc
= c_parser_peek_token (parser
)->location
;
8255 op
= c_parser_cast_expression (parser
, NULL
);
8256 op
= default_function_array_conversion (exp_loc
, op
);
8257 return parser_build_unary_op (op_loc
, REALPART_EXPR
, op
);
8259 c_parser_consume_token (parser
);
8260 exp_loc
= c_parser_peek_token (parser
)->location
;
8261 op
= c_parser_cast_expression (parser
, NULL
);
8262 op
= default_function_array_conversion (exp_loc
, op
);
8263 return parser_build_unary_op (op_loc
, IMAGPART_EXPR
, op
);
8264 case RID_TRANSACTION_ATOMIC
:
8265 case RID_TRANSACTION_RELAXED
:
8266 return c_parser_transaction_expression (parser
,
8267 c_parser_peek_token (parser
)->keyword
);
8269 return c_parser_postfix_expression (parser
);
8272 return c_parser_postfix_expression (parser
);
8276 /* Parse a sizeof expression. */
8278 static struct c_expr
8279 c_parser_sizeof_expression (c_parser
*parser
)
8282 struct c_expr result
;
8283 location_t expr_loc
;
8284 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_SIZEOF
));
8287 location_t finish
= UNKNOWN_LOCATION
;
8289 start
= c_parser_peek_token (parser
)->location
;
8291 c_parser_consume_token (parser
);
8292 c_inhibit_evaluation_warnings
++;
8294 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
)
8295 && c_token_starts_typename (c_parser_peek_2nd_token (parser
)))
8297 /* Either sizeof ( type-name ) or sizeof unary-expression
8298 starting with a compound literal. */
8299 struct c_type_name
*type_name
;
8300 matching_parens parens
;
8301 parens
.consume_open (parser
);
8302 expr_loc
= c_parser_peek_token (parser
)->location
;
8303 type_name
= c_parser_type_name (parser
, true);
8304 parens
.skip_until_found_close (parser
);
8305 finish
= parser
->tokens_buf
[0].location
;
8306 if (type_name
== NULL
)
8309 c_inhibit_evaluation_warnings
--;
8312 ret
.original_code
= ERROR_MARK
;
8313 ret
.original_type
= NULL
;
8316 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
8318 expr
= c_parser_postfix_expression_after_paren_type (parser
,
8321 finish
= expr
.get_finish ();
8324 /* sizeof ( type-name ). */
8325 if (type_name
->specs
->alignas_p
)
8326 error_at (type_name
->specs
->locations
[cdw_alignas
],
8327 "alignment specified for type name in %<sizeof%>");
8328 c_inhibit_evaluation_warnings
--;
8330 result
= c_expr_sizeof_type (expr_loc
, type_name
);
8334 expr_loc
= c_parser_peek_token (parser
)->location
;
8335 expr
= c_parser_unary_expression (parser
);
8336 finish
= expr
.get_finish ();
8338 c_inhibit_evaluation_warnings
--;
8340 mark_exp_read (expr
.value
);
8341 if (TREE_CODE (expr
.value
) == COMPONENT_REF
8342 && DECL_C_BIT_FIELD (TREE_OPERAND (expr
.value
, 1)))
8343 error_at (expr_loc
, "%<sizeof%> applied to a bit-field");
8344 result
= c_expr_sizeof_expr (expr_loc
, expr
);
8346 if (finish
== UNKNOWN_LOCATION
)
8348 set_c_expr_source_range (&result
, start
, finish
);
8352 /* Parse an alignof expression. */
8354 static struct c_expr
8355 c_parser_alignof_expression (c_parser
*parser
)
8358 location_t start_loc
= c_parser_peek_token (parser
)->location
;
8360 tree alignof_spelling
= c_parser_peek_token (parser
)->value
;
8361 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ALIGNOF
));
8362 bool is_c11_alignof
= strcmp (IDENTIFIER_POINTER (alignof_spelling
),
8364 /* A diagnostic is not required for the use of this identifier in
8365 the implementation namespace; only diagnose it for the C11
8366 spelling because of existing code using the other spellings. */
8370 pedwarn_c99 (start_loc
, OPT_Wpedantic
, "ISO C99 does not support %qE",
8373 pedwarn_c99 (start_loc
, OPT_Wpedantic
, "ISO C90 does not support %qE",
8376 c_parser_consume_token (parser
);
8377 c_inhibit_evaluation_warnings
++;
8379 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
)
8380 && c_token_starts_typename (c_parser_peek_2nd_token (parser
)))
8382 /* Either __alignof__ ( type-name ) or __alignof__
8383 unary-expression starting with a compound literal. */
8385 struct c_type_name
*type_name
;
8387 matching_parens parens
;
8388 parens
.consume_open (parser
);
8389 loc
= c_parser_peek_token (parser
)->location
;
8390 type_name
= c_parser_type_name (parser
, true);
8391 end_loc
= c_parser_peek_token (parser
)->location
;
8392 parens
.skip_until_found_close (parser
);
8393 if (type_name
== NULL
)
8396 c_inhibit_evaluation_warnings
--;
8399 ret
.original_code
= ERROR_MARK
;
8400 ret
.original_type
= NULL
;
8403 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
8405 expr
= c_parser_postfix_expression_after_paren_type (parser
,
8410 /* alignof ( type-name ). */
8411 if (type_name
->specs
->alignas_p
)
8412 error_at (type_name
->specs
->locations
[cdw_alignas
],
8413 "alignment specified for type name in %qE",
8415 c_inhibit_evaluation_warnings
--;
8417 ret
.value
= c_sizeof_or_alignof_type (loc
, groktypename (type_name
,
8419 false, is_c11_alignof
, 1);
8420 ret
.original_code
= ERROR_MARK
;
8421 ret
.original_type
= NULL
;
8422 set_c_expr_source_range (&ret
, start_loc
, end_loc
);
8428 expr
= c_parser_unary_expression (parser
);
8429 end_loc
= expr
.src_range
.m_finish
;
8431 mark_exp_read (expr
.value
);
8432 c_inhibit_evaluation_warnings
--;
8436 OPT_Wpedantic
, "ISO C does not allow %<%E (expression)%>",
8438 ret
.value
= c_alignof_expr (start_loc
, expr
.value
);
8439 ret
.original_code
= ERROR_MARK
;
8440 ret
.original_type
= NULL
;
8441 set_c_expr_source_range (&ret
, start_loc
, end_loc
);
8446 /* Parse the __builtin_has_attribute ([expr|type], attribute-spec)
8449 static struct c_expr
8450 c_parser_has_attribute_expression (c_parser
*parser
)
8452 gcc_assert (c_parser_next_token_is_keyword (parser
,
8453 RID_BUILTIN_HAS_ATTRIBUTE
));
8454 location_t start
= c_parser_peek_token (parser
)->location
;
8455 c_parser_consume_token (parser
);
8457 c_inhibit_evaluation_warnings
++;
8459 matching_parens parens
;
8460 if (!parens
.require_open (parser
))
8462 c_inhibit_evaluation_warnings
--;
8465 struct c_expr result
;
8466 result
.set_error ();
8467 result
.original_code
= ERROR_MARK
;
8468 result
.original_type
= NULL
;
8472 /* Treat the type argument the same way as in typeof for the purposes
8473 of warnings. FIXME: Generalize this so the warning refers to
8474 __builtin_has_attribute rather than typeof. */
8477 /* The first operand: one of DECL, EXPR, or TYPE. */
8478 tree oper
= NULL_TREE
;
8479 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_id
))
8481 struct c_type_name
*tname
= c_parser_type_name (parser
);
8485 oper
= groktypename (tname
, NULL
, NULL
);
8486 pop_maybe_used (variably_modified_type_p (oper
, NULL_TREE
));
8491 struct c_expr cexpr
= c_parser_expr_no_commas (parser
, NULL
);
8492 c_inhibit_evaluation_warnings
--;
8494 if (cexpr
.value
!= error_mark_node
)
8496 mark_exp_read (cexpr
.value
);
8498 tree etype
= TREE_TYPE (oper
);
8499 bool was_vm
= variably_modified_type_p (etype
, NULL_TREE
);
8500 /* This is returned with the type so that when the type is
8501 evaluated, this can be evaluated. */
8503 oper
= c_fully_fold (oper
, false, NULL
);
8504 pop_maybe_used (was_vm
);
8508 struct c_expr result
;
8509 result
.original_code
= ERROR_MARK
;
8510 result
.original_type
= NULL
;
8512 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
8514 /* Consume the closing parenthesis if that's the next token
8515 in the likely case the built-in was invoked with fewer
8516 than two arguments. */
8517 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
8518 c_parser_consume_token (parser
);
8519 c_inhibit_evaluation_warnings
--;
8520 result
.set_error ();
8524 bool save_translate_strings_p
= parser
->translate_strings_p
;
8526 location_t atloc
= c_parser_peek_token (parser
)->location
;
8527 /* Parse a single attribute. Require no leading comma and do not
8528 allow empty attributes. */
8529 tree attr
= c_parser_gnu_attribute (parser
, NULL_TREE
, false, false);
8531 parser
->translate_strings_p
= save_translate_strings_p
;
8533 location_t finish
= c_parser_peek_token (parser
)->location
;
8534 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
8535 c_parser_consume_token (parser
);
8538 c_parser_error (parser
, "expected identifier");
8539 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8541 result
.set_error ();
8547 error_at (atloc
, "expected identifier");
8548 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
8550 result
.set_error ();
8554 result
.original_code
= INTEGER_CST
;
8555 result
.original_type
= boolean_type_node
;
8557 if (has_attribute (atloc
, oper
, attr
, default_conversion
))
8558 result
.value
= boolean_true_node
;
8560 result
.value
= boolean_false_node
;
8562 set_c_expr_source_range (&result
, start
, finish
);
8566 /* Helper function to read arguments of builtins which are interfaces
8567 for the middle-end nodes like COMPLEX_EXPR, VEC_PERM_EXPR and
8568 others. The name of the builtin is passed using BNAME parameter.
8569 Function returns true if there were no errors while parsing and
8570 stores the arguments in CEXPR_LIST. If it returns true,
8571 *OUT_CLOSE_PAREN_LOC is written to with the location of the closing
8574 c_parser_get_builtin_args (c_parser
*parser
, const char *bname
,
8575 vec
<c_expr_t
, va_gc
> **ret_cexpr_list
,
8577 location_t
*out_close_paren_loc
)
8579 location_t loc
= c_parser_peek_token (parser
)->location
;
8580 vec
<c_expr_t
, va_gc
> *cexpr_list
;
8582 bool saved_force_folding_builtin_constant_p
;
8584 *ret_cexpr_list
= NULL
;
8585 if (c_parser_next_token_is_not (parser
, CPP_OPEN_PAREN
))
8587 error_at (loc
, "cannot take address of %qs", bname
);
8591 c_parser_consume_token (parser
);
8593 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
8595 *out_close_paren_loc
= c_parser_peek_token (parser
)->location
;
8596 c_parser_consume_token (parser
);
8600 saved_force_folding_builtin_constant_p
8601 = force_folding_builtin_constant_p
;
8602 force_folding_builtin_constant_p
|= choose_expr_p
;
8603 expr
= c_parser_expr_no_commas (parser
, NULL
);
8604 force_folding_builtin_constant_p
8605 = saved_force_folding_builtin_constant_p
;
8606 vec_alloc (cexpr_list
, 1);
8607 vec_safe_push (cexpr_list
, expr
);
8608 while (c_parser_next_token_is (parser
, CPP_COMMA
))
8610 c_parser_consume_token (parser
);
8611 expr
= c_parser_expr_no_commas (parser
, NULL
);
8612 vec_safe_push (cexpr_list
, expr
);
8615 *out_close_paren_loc
= c_parser_peek_token (parser
)->location
;
8616 if (!c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
8619 *ret_cexpr_list
= cexpr_list
;
8623 /* This represents a single generic-association. */
8625 struct c_generic_association
8627 /* The location of the starting token of the type. */
8628 location_t type_location
;
8629 /* The association's type, or NULL_TREE for 'default'. */
8631 /* The association's expression. */
8632 struct c_expr expression
;
8635 /* Parse a generic-selection. (C11 6.5.1.1).
8638 _Generic ( assignment-expression , generic-assoc-list )
8642 generic-assoc-list , generic-association
8644 generic-association:
8645 type-name : assignment-expression
8646 default : assignment-expression
8649 static struct c_expr
8650 c_parser_generic_selection (c_parser
*parser
)
8652 struct c_expr selector
, error_expr
;
8654 struct c_generic_association matched_assoc
;
8655 int match_found
= -1;
8656 location_t generic_loc
, selector_loc
;
8658 error_expr
.original_code
= ERROR_MARK
;
8659 error_expr
.original_type
= NULL
;
8660 error_expr
.set_error ();
8661 matched_assoc
.type_location
= UNKNOWN_LOCATION
;
8662 matched_assoc
.type
= NULL_TREE
;
8663 matched_assoc
.expression
= error_expr
;
8665 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_GENERIC
));
8666 generic_loc
= c_parser_peek_token (parser
)->location
;
8667 c_parser_consume_token (parser
);
8669 pedwarn_c99 (generic_loc
, OPT_Wpedantic
,
8670 "ISO C99 does not support %<_Generic%>");
8672 pedwarn_c99 (generic_loc
, OPT_Wpedantic
,
8673 "ISO C90 does not support %<_Generic%>");
8675 matching_parens parens
;
8676 if (!parens
.require_open (parser
))
8679 c_inhibit_evaluation_warnings
++;
8680 selector_loc
= c_parser_peek_token (parser
)->location
;
8681 selector
= c_parser_expr_no_commas (parser
, NULL
);
8682 selector
= default_function_array_conversion (selector_loc
, selector
);
8683 c_inhibit_evaluation_warnings
--;
8685 if (selector
.value
== error_mark_node
)
8687 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8690 mark_exp_read (selector
.value
);
8691 selector_type
= TREE_TYPE (selector
.value
);
8692 /* In ISO C terms, rvalues (including the controlling expression of
8693 _Generic) do not have qualified types. */
8694 if (TREE_CODE (selector_type
) != ARRAY_TYPE
)
8695 selector_type
= TYPE_MAIN_VARIANT (selector_type
);
8696 /* In ISO C terms, _Noreturn is not part of the type of expressions
8697 such as &abort, but in GCC it is represented internally as a type
8699 if (FUNCTION_POINTER_TYPE_P (selector_type
)
8700 && TYPE_QUALS (TREE_TYPE (selector_type
)) != TYPE_UNQUALIFIED
)
8702 = build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (selector_type
)));
8704 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
8706 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8710 auto_vec
<c_generic_association
> associations
;
8713 struct c_generic_association assoc
, *iter
;
8715 c_token
*token
= c_parser_peek_token (parser
);
8717 assoc
.type_location
= token
->location
;
8718 if (token
->type
== CPP_KEYWORD
&& token
->keyword
== RID_DEFAULT
)
8720 c_parser_consume_token (parser
);
8721 assoc
.type
= NULL_TREE
;
8725 struct c_type_name
*type_name
;
8727 type_name
= c_parser_type_name (parser
);
8728 if (type_name
== NULL
)
8730 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8733 assoc
.type
= groktypename (type_name
, NULL
, NULL
);
8734 if (assoc
.type
== error_mark_node
)
8736 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8740 if (TREE_CODE (assoc
.type
) == FUNCTION_TYPE
)
8741 error_at (assoc
.type_location
,
8742 "%<_Generic%> association has function type");
8743 else if (!COMPLETE_TYPE_P (assoc
.type
))
8744 error_at (assoc
.type_location
,
8745 "%<_Generic%> association has incomplete type");
8747 if (variably_modified_type_p (assoc
.type
, NULL_TREE
))
8748 error_at (assoc
.type_location
,
8749 "%<_Generic%> association has "
8750 "variable length type");
8753 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
8755 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8759 assoc
.expression
= c_parser_expr_no_commas (parser
, NULL
);
8760 if (assoc
.expression
.value
== error_mark_node
)
8762 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8766 for (ix
= 0; associations
.iterate (ix
, &iter
); ++ix
)
8768 if (assoc
.type
== NULL_TREE
)
8770 if (iter
->type
== NULL_TREE
)
8772 error_at (assoc
.type_location
,
8773 "duplicate %<default%> case in %<_Generic%>");
8774 inform (iter
->type_location
, "original %<default%> is here");
8777 else if (iter
->type
!= NULL_TREE
)
8779 if (comptypes (assoc
.type
, iter
->type
))
8781 error_at (assoc
.type_location
,
8782 "%<_Generic%> specifies two compatible types");
8783 inform (iter
->type_location
, "compatible type is here");
8788 if (assoc
.type
== NULL_TREE
)
8790 if (match_found
< 0)
8792 matched_assoc
= assoc
;
8793 match_found
= associations
.length ();
8796 else if (comptypes (assoc
.type
, selector_type
))
8798 if (match_found
< 0 || matched_assoc
.type
== NULL_TREE
)
8800 matched_assoc
= assoc
;
8801 match_found
= associations
.length ();
8805 error_at (assoc
.type_location
,
8806 "%<_Generic%> selector matches multiple associations");
8807 inform (matched_assoc
.type_location
,
8808 "other match is here");
8812 associations
.safe_push (assoc
);
8814 if (c_parser_peek_token (parser
)->type
!= CPP_COMMA
)
8816 c_parser_consume_token (parser
);
8820 struct c_generic_association
*iter
;
8821 FOR_EACH_VEC_ELT (associations
, ix
, iter
)
8822 if (ix
!= (unsigned) match_found
)
8823 mark_exp_read (iter
->expression
.value
);
8825 if (!parens
.require_close (parser
))
8827 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8831 if (match_found
< 0)
8833 error_at (selector_loc
, "%<_Generic%> selector of type %qT is not "
8834 "compatible with any association",
8839 return matched_assoc
.expression
;
8842 /* Check the validity of a function pointer argument *EXPR (argument
8843 position POS) to __builtin_tgmath. Return the number of function
8844 arguments if possibly valid; return 0 having reported an error if
8848 check_tgmath_function (c_expr
*expr
, unsigned int pos
)
8850 tree type
= TREE_TYPE (expr
->value
);
8851 if (!FUNCTION_POINTER_TYPE_P (type
))
8853 error_at (expr
->get_location (),
8854 "argument %u of %<__builtin_tgmath%> is not a function pointer",
8858 type
= TREE_TYPE (type
);
8859 if (!prototype_p (type
))
8861 error_at (expr
->get_location (),
8862 "argument %u of %<__builtin_tgmath%> is unprototyped", pos
);
8865 if (stdarg_p (type
))
8867 error_at (expr
->get_location (),
8868 "argument %u of %<__builtin_tgmath%> has variable arguments",
8872 unsigned int nargs
= 0;
8873 function_args_iterator iter
;
8875 FOREACH_FUNCTION_ARGS (type
, t
, iter
)
8877 if (t
== void_type_node
)
8883 error_at (expr
->get_location (),
8884 "argument %u of %<__builtin_tgmath%> has no arguments", pos
);
8890 /* Ways in which a parameter or return value of a type-generic macro
8891 may vary between the different functions the macro may call. */
8892 enum tgmath_parm_kind
8894 tgmath_fixed
, tgmath_real
, tgmath_complex
8897 /* Helper function for c_parser_postfix_expression. Parse predefined
8900 static struct c_expr
8901 c_parser_predefined_identifier (c_parser
*parser
)
8903 location_t loc
= c_parser_peek_token (parser
)->location
;
8904 switch (c_parser_peek_token (parser
)->keyword
)
8906 case RID_FUNCTION_NAME
:
8907 pedwarn (loc
, OPT_Wpedantic
, "ISO C does not support %qs predefined "
8908 "identifier", "__FUNCTION__");
8910 case RID_PRETTY_FUNCTION_NAME
:
8911 pedwarn (loc
, OPT_Wpedantic
, "ISO C does not support %qs predefined "
8912 "identifier", "__PRETTY_FUNCTION__");
8914 case RID_C99_FUNCTION_NAME
:
8915 pedwarn_c90 (loc
, OPT_Wpedantic
, "ISO C90 does not support "
8916 "%<__func__%> predefined identifier");
8923 expr
.original_code
= ERROR_MARK
;
8924 expr
.original_type
= NULL
;
8925 expr
.value
= fname_decl (loc
, c_parser_peek_token (parser
)->keyword
,
8926 c_parser_peek_token (parser
)->value
);
8927 set_c_expr_source_range (&expr
, loc
, loc
);
8928 c_parser_consume_token (parser
);
8932 /* Parse a postfix expression (C90 6.3.1-6.3.2, C99 6.5.1-6.5.2,
8933 C11 6.5.1-6.5.2). Compound literals aren't handled here; callers have to
8934 call c_parser_postfix_expression_after_paren_type on encountering them.
8938 postfix-expression [ expression ]
8939 postfix-expression ( argument-expression-list[opt] )
8940 postfix-expression . identifier
8941 postfix-expression -> identifier
8942 postfix-expression ++
8943 postfix-expression --
8944 ( type-name ) { initializer-list }
8945 ( type-name ) { initializer-list , }
8947 argument-expression-list:
8949 argument-expression-list , argument-expression
8962 (treated as a keyword in GNU C)
8965 ( compound-statement )
8966 __builtin_va_arg ( assignment-expression , type-name )
8967 __builtin_offsetof ( type-name , offsetof-member-designator )
8968 __builtin_choose_expr ( assignment-expression ,
8969 assignment-expression ,
8970 assignment-expression )
8971 __builtin_types_compatible_p ( type-name , type-name )
8972 __builtin_tgmath ( expr-list )
8973 __builtin_complex ( assignment-expression , assignment-expression )
8974 __builtin_shuffle ( assignment-expression , assignment-expression )
8975 __builtin_shuffle ( assignment-expression ,
8976 assignment-expression ,
8977 assignment-expression, )
8978 __builtin_convertvector ( assignment-expression , type-name )
8979 __builtin_assoc_barrier ( assignment-expression )
8981 offsetof-member-designator:
8983 offsetof-member-designator . identifier
8984 offsetof-member-designator [ expression ]
8989 [ objc-receiver objc-message-args ]
8990 @selector ( objc-selector-arg )
8991 @protocol ( identifier )
8992 @encode ( type-name )
8994 Classname . identifier
8997 static struct c_expr
8998 c_parser_postfix_expression (c_parser
*parser
)
9000 struct c_expr expr
, e1
;
9001 struct c_type_name
*t1
, *t2
;
9002 location_t loc
= c_parser_peek_token (parser
)->location
;
9003 source_range tok_range
= c_parser_peek_token (parser
)->get_range ();
9004 expr
.original_code
= ERROR_MARK
;
9005 expr
.original_type
= NULL
;
9006 switch (c_parser_peek_token (parser
)->type
)
9009 expr
.value
= c_parser_peek_token (parser
)->value
;
9010 set_c_expr_source_range (&expr
, tok_range
);
9011 loc
= c_parser_peek_token (parser
)->location
;
9012 c_parser_consume_token (parser
);
9013 if (TREE_CODE (expr
.value
) == FIXED_CST
9014 && !targetm
.fixed_point_supported_p ())
9016 error_at (loc
, "fixed-point types not supported for this target");
9025 expr
.value
= c_parser_peek_token (parser
)->value
;
9026 /* For the purpose of warning when a pointer is compared with
9027 a zero character constant. */
9028 expr
.original_type
= char_type_node
;
9029 set_c_expr_source_range (&expr
, tok_range
);
9030 c_parser_consume_token (parser
);
9036 case CPP_UTF8STRING
:
9037 expr
= c_parser_string_literal (parser
, parser
->translate_strings_p
,
9040 case CPP_OBJC_STRING
:
9041 gcc_assert (c_dialect_objc ());
9043 = objc_build_string_object (c_parser_peek_token (parser
)->value
);
9044 set_c_expr_source_range (&expr
, tok_range
);
9045 c_parser_consume_token (parser
);
9048 switch (c_parser_peek_token (parser
)->id_kind
)
9052 tree id
= c_parser_peek_token (parser
)->value
;
9053 c_parser_consume_token (parser
);
9054 expr
.value
= build_external_ref (loc
, id
,
9055 (c_parser_peek_token (parser
)->type
9057 &expr
.original_type
);
9058 set_c_expr_source_range (&expr
, tok_range
);
9061 case C_ID_CLASSNAME
:
9063 /* Here we parse the Objective-C 2.0 Class.name dot
9065 tree class_name
= c_parser_peek_token (parser
)->value
;
9067 c_parser_consume_token (parser
);
9068 gcc_assert (c_dialect_objc ());
9069 if (!c_parser_require (parser
, CPP_DOT
, "expected %<.%>"))
9074 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
9076 c_parser_error (parser
, "expected identifier");
9080 c_token
*component_tok
= c_parser_peek_token (parser
);
9081 component
= component_tok
->value
;
9082 location_t end_loc
= component_tok
->get_finish ();
9083 c_parser_consume_token (parser
);
9084 expr
.value
= objc_build_class_component_ref (class_name
,
9086 set_c_expr_source_range (&expr
, loc
, end_loc
);
9090 c_parser_error (parser
, "expected expression");
9095 case CPP_OPEN_PAREN
:
9096 /* A parenthesized expression, statement expression or compound
9098 if (c_parser_peek_2nd_token (parser
)->type
== CPP_OPEN_BRACE
)
9100 /* A statement expression. */
9102 location_t brace_loc
;
9103 c_parser_consume_token (parser
);
9104 brace_loc
= c_parser_peek_token (parser
)->location
;
9105 c_parser_consume_token (parser
);
9106 /* If we've not yet started the current function's statement list,
9107 or we're in the parameter scope of an old-style function
9108 declaration, statement expressions are not allowed. */
9109 if (!building_stmt_list_p () || old_style_parameter_scope ())
9111 error_at (loc
, "braced-group within expression allowed "
9112 "only inside a function");
9113 parser
->error
= true;
9114 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
, NULL
);
9115 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
9119 stmt
= c_begin_stmt_expr ();
9120 c_parser_compound_statement_nostart (parser
);
9121 location_t close_loc
= c_parser_peek_token (parser
)->location
;
9122 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
9124 pedwarn (loc
, OPT_Wpedantic
,
9125 "ISO C forbids braced-groups within expressions");
9126 expr
.value
= c_finish_stmt_expr (brace_loc
, stmt
);
9127 set_c_expr_source_range (&expr
, loc
, close_loc
);
9128 mark_exp_read (expr
.value
);
9132 /* A parenthesized expression. */
9133 location_t loc_open_paren
= c_parser_peek_token (parser
)->location
;
9134 c_parser_consume_token (parser
);
9135 expr
= c_parser_expression (parser
);
9136 if (TREE_CODE (expr
.value
) == MODIFY_EXPR
)
9137 suppress_warning (expr
.value
, OPT_Wparentheses
);
9138 if (expr
.original_code
!= C_MAYBE_CONST_EXPR
9139 && expr
.original_code
!= SIZEOF_EXPR
)
9140 expr
.original_code
= ERROR_MARK
;
9141 /* Remember that we saw ( ) around the sizeof. */
9142 if (expr
.original_code
== SIZEOF_EXPR
)
9143 expr
.original_code
= PAREN_SIZEOF_EXPR
;
9144 /* Don't change EXPR.ORIGINAL_TYPE. */
9145 location_t loc_close_paren
= c_parser_peek_token (parser
)->location
;
9146 set_c_expr_source_range (&expr
, loc_open_paren
, loc_close_paren
);
9147 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
9148 "expected %<)%>", loc_open_paren
);
9152 switch (c_parser_peek_token (parser
)->keyword
)
9154 case RID_FUNCTION_NAME
:
9155 case RID_PRETTY_FUNCTION_NAME
:
9156 case RID_C99_FUNCTION_NAME
:
9157 expr
= c_parser_predefined_identifier (parser
);
9161 location_t start_loc
= loc
;
9162 c_parser_consume_token (parser
);
9163 matching_parens parens
;
9164 if (!parens
.require_open (parser
))
9169 e1
= c_parser_expr_no_commas (parser
, NULL
);
9170 mark_exp_read (e1
.value
);
9171 e1
.value
= c_fully_fold (e1
.value
, false, NULL
);
9172 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
9174 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
9178 loc
= c_parser_peek_token (parser
)->location
;
9179 t1
= c_parser_type_name (parser
);
9180 location_t end_loc
= c_parser_peek_token (parser
)->get_finish ();
9181 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
9189 tree type_expr
= NULL_TREE
;
9190 expr
.value
= c_build_va_arg (start_loc
, e1
.value
, loc
,
9191 groktypename (t1
, &type_expr
, NULL
));
9194 expr
.value
= build2 (C_MAYBE_CONST_EXPR
,
9195 TREE_TYPE (expr
.value
), type_expr
,
9197 C_MAYBE_CONST_EXPR_NON_CONST (expr
.value
) = true;
9199 set_c_expr_source_range (&expr
, start_loc
, end_loc
);
9205 c_parser_consume_token (parser
);
9206 matching_parens parens
;
9207 if (!parens
.require_open (parser
))
9212 t1
= c_parser_type_name (parser
);
9214 parser
->error
= true;
9215 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
9216 gcc_assert (parser
->error
);
9219 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
9223 tree type
= groktypename (t1
, NULL
, NULL
);
9225 if (type
== error_mark_node
)
9226 offsetof_ref
= error_mark_node
;
9229 offsetof_ref
= build1 (INDIRECT_REF
, type
, null_pointer_node
);
9230 SET_EXPR_LOCATION (offsetof_ref
, loc
);
9232 /* Parse the second argument to __builtin_offsetof. We
9233 must have one identifier, and beyond that we want to
9234 accept sub structure and sub array references. */
9235 if (c_parser_next_token_is (parser
, CPP_NAME
))
9237 c_token
*comp_tok
= c_parser_peek_token (parser
);
9239 = build_component_ref (loc
, offsetof_ref
, comp_tok
->value
,
9240 comp_tok
->location
, UNKNOWN_LOCATION
);
9241 c_parser_consume_token (parser
);
9242 while (c_parser_next_token_is (parser
, CPP_DOT
)
9243 || c_parser_next_token_is (parser
,
9245 || c_parser_next_token_is (parser
,
9248 if (c_parser_next_token_is (parser
, CPP_DEREF
))
9250 loc
= c_parser_peek_token (parser
)->location
;
9251 offsetof_ref
= build_array_ref (loc
,
9256 else if (c_parser_next_token_is (parser
, CPP_DOT
))
9259 c_parser_consume_token (parser
);
9260 if (c_parser_next_token_is_not (parser
,
9263 c_parser_error (parser
, "expected identifier");
9266 c_token
*comp_tok
= c_parser_peek_token (parser
);
9268 = build_component_ref (loc
, offsetof_ref
,
9272 c_parser_consume_token (parser
);
9278 loc
= c_parser_peek_token (parser
)->location
;
9279 c_parser_consume_token (parser
);
9280 ce
= c_parser_expression (parser
);
9281 ce
= convert_lvalue_to_rvalue (loc
, ce
, false, false);
9283 idx
= c_fully_fold (idx
, false, NULL
);
9284 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
9286 offsetof_ref
= build_array_ref (loc
, offsetof_ref
, idx
);
9291 c_parser_error (parser
, "expected identifier");
9292 location_t end_loc
= c_parser_peek_token (parser
)->get_finish ();
9293 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
9295 expr
.value
= fold_offsetof (offsetof_ref
);
9296 set_c_expr_source_range (&expr
, loc
, end_loc
);
9299 case RID_CHOOSE_EXPR
:
9301 vec
<c_expr_t
, va_gc
> *cexpr_list
;
9302 c_expr_t
*e1_p
, *e2_p
, *e3_p
;
9304 location_t close_paren_loc
;
9306 c_parser_consume_token (parser
);
9307 if (!c_parser_get_builtin_args (parser
,
9308 "__builtin_choose_expr",
9316 if (vec_safe_length (cexpr_list
) != 3)
9318 error_at (loc
, "wrong number of arguments to "
9319 "%<__builtin_choose_expr%>");
9324 e1_p
= &(*cexpr_list
)[0];
9325 e2_p
= &(*cexpr_list
)[1];
9326 e3_p
= &(*cexpr_list
)[2];
9329 mark_exp_read (e2_p
->value
);
9330 mark_exp_read (e3_p
->value
);
9331 if (TREE_CODE (c
) != INTEGER_CST
9332 || !INTEGRAL_TYPE_P (TREE_TYPE (c
)))
9334 "first argument to %<__builtin_choose_expr%> not"
9336 constant_expression_warning (c
);
9337 expr
= integer_zerop (c
) ? *e3_p
: *e2_p
;
9338 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
9341 case RID_TYPES_COMPATIBLE_P
:
9343 c_parser_consume_token (parser
);
9344 matching_parens parens
;
9345 if (!parens
.require_open (parser
))
9350 t1
= c_parser_type_name (parser
);
9356 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
9358 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
9362 t2
= c_parser_type_name (parser
);
9368 location_t close_paren_loc
= c_parser_peek_token (parser
)->location
;
9369 parens
.skip_until_found_close (parser
);
9371 e1
= groktypename (t1
, NULL
, NULL
);
9372 e2
= groktypename (t2
, NULL
, NULL
);
9373 if (e1
== error_mark_node
|| e2
== error_mark_node
)
9379 e1
= TYPE_MAIN_VARIANT (e1
);
9380 e2
= TYPE_MAIN_VARIANT (e2
);
9383 = comptypes (e1
, e2
) ? integer_one_node
: integer_zero_node
;
9384 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
9387 case RID_BUILTIN_TGMATH
:
9389 vec
<c_expr_t
, va_gc
> *cexpr_list
;
9390 location_t close_paren_loc
;
9392 c_parser_consume_token (parser
);
9393 if (!c_parser_get_builtin_args (parser
,
9402 if (vec_safe_length (cexpr_list
) < 3)
9404 error_at (loc
, "too few arguments to %<__builtin_tgmath%>");
9411 FOR_EACH_VEC_ELT (*cexpr_list
, i
, p
)
9412 *p
= convert_lvalue_to_rvalue (loc
, *p
, true, true);
9413 unsigned int nargs
= check_tgmath_function (&(*cexpr_list
)[0], 1);
9419 if (vec_safe_length (cexpr_list
) < nargs
)
9421 error_at (loc
, "too few arguments to %<__builtin_tgmath%>");
9425 unsigned int num_functions
= vec_safe_length (cexpr_list
) - nargs
;
9426 if (num_functions
< 2)
9428 error_at (loc
, "too few arguments to %<__builtin_tgmath%>");
9433 /* The first NUM_FUNCTIONS expressions are the function
9434 pointers. The remaining NARGS expressions are the
9435 arguments that are to be passed to one of those
9436 functions, chosen following <tgmath.h> rules. */
9437 for (unsigned int j
= 1; j
< num_functions
; j
++)
9439 unsigned int this_nargs
9440 = check_tgmath_function (&(*cexpr_list
)[j
], j
+ 1);
9441 if (this_nargs
== 0)
9446 if (this_nargs
!= nargs
)
9448 error_at ((*cexpr_list
)[j
].get_location (),
9449 "argument %u of %<__builtin_tgmath%> has "
9450 "wrong number of arguments", j
+ 1);
9456 /* The functions all have the same number of arguments.
9457 Determine whether arguments and return types vary in
9458 ways permitted for <tgmath.h> functions. */
9459 /* The first entry in each of these vectors is for the
9460 return type, subsequent entries for parameter
9462 auto_vec
<enum tgmath_parm_kind
> parm_kind (nargs
+ 1);
9463 auto_vec
<tree
> parm_first (nargs
+ 1);
9464 auto_vec
<bool> parm_complex (nargs
+ 1);
9465 auto_vec
<bool> parm_varies (nargs
+ 1);
9466 tree first_type
= TREE_TYPE (TREE_TYPE ((*cexpr_list
)[0].value
));
9467 tree first_ret
= TYPE_MAIN_VARIANT (TREE_TYPE (first_type
));
9468 parm_first
.quick_push (first_ret
);
9469 parm_complex
.quick_push (TREE_CODE (first_ret
) == COMPLEX_TYPE
);
9470 parm_varies
.quick_push (false);
9471 function_args_iterator iter
;
9473 unsigned int argpos
;
9474 FOREACH_FUNCTION_ARGS (first_type
, t
, iter
)
9476 if (t
== void_type_node
)
9478 parm_first
.quick_push (TYPE_MAIN_VARIANT (t
));
9479 parm_complex
.quick_push (TREE_CODE (t
) == COMPLEX_TYPE
);
9480 parm_varies
.quick_push (false);
9482 for (unsigned int j
= 1; j
< num_functions
; j
++)
9484 tree type
= TREE_TYPE (TREE_TYPE ((*cexpr_list
)[j
].value
));
9485 tree ret
= TYPE_MAIN_VARIANT (TREE_TYPE (type
));
9486 if (ret
!= parm_first
[0])
9488 parm_varies
[0] = true;
9489 if (!SCALAR_FLOAT_TYPE_P (parm_first
[0])
9490 && !COMPLEX_FLOAT_TYPE_P (parm_first
[0]))
9492 error_at ((*cexpr_list
)[0].get_location (),
9493 "invalid type-generic return type for "
9494 "argument %u of %<__builtin_tgmath%>",
9499 if (!SCALAR_FLOAT_TYPE_P (ret
)
9500 && !COMPLEX_FLOAT_TYPE_P (ret
))
9502 error_at ((*cexpr_list
)[j
].get_location (),
9503 "invalid type-generic return type for "
9504 "argument %u of %<__builtin_tgmath%>",
9510 if (TREE_CODE (ret
) == COMPLEX_TYPE
)
9511 parm_complex
[0] = true;
9513 FOREACH_FUNCTION_ARGS (type
, t
, iter
)
9515 if (t
== void_type_node
)
9517 t
= TYPE_MAIN_VARIANT (t
);
9518 if (t
!= parm_first
[argpos
])
9520 parm_varies
[argpos
] = true;
9521 if (!SCALAR_FLOAT_TYPE_P (parm_first
[argpos
])
9522 && !COMPLEX_FLOAT_TYPE_P (parm_first
[argpos
]))
9524 error_at ((*cexpr_list
)[0].get_location (),
9525 "invalid type-generic type for "
9526 "argument %u of argument %u of "
9527 "%<__builtin_tgmath%>", argpos
, 1);
9531 if (!SCALAR_FLOAT_TYPE_P (t
)
9532 && !COMPLEX_FLOAT_TYPE_P (t
))
9534 error_at ((*cexpr_list
)[j
].get_location (),
9535 "invalid type-generic type for "
9536 "argument %u of argument %u of "
9537 "%<__builtin_tgmath%>", argpos
, j
+ 1);
9542 if (TREE_CODE (t
) == COMPLEX_TYPE
)
9543 parm_complex
[argpos
] = true;
9547 enum tgmath_parm_kind max_variation
= tgmath_fixed
;
9548 for (unsigned int j
= 0; j
<= nargs
; j
++)
9550 enum tgmath_parm_kind this_kind
;
9553 if (parm_complex
[j
])
9554 max_variation
= this_kind
= tgmath_complex
;
9557 this_kind
= tgmath_real
;
9558 if (max_variation
!= tgmath_complex
)
9559 max_variation
= tgmath_real
;
9563 this_kind
= tgmath_fixed
;
9564 parm_kind
.quick_push (this_kind
);
9566 if (max_variation
== tgmath_fixed
)
9568 error_at (loc
, "function arguments of %<__builtin_tgmath%> "
9569 "all have the same type");
9574 /* Identify a parameter (not the return type) that varies,
9575 including with complex types if any variation includes
9576 complex types; there must be at least one such
9578 unsigned int tgarg
= 0;
9579 for (unsigned int j
= 1; j
<= nargs
; j
++)
9580 if (parm_kind
[j
] == max_variation
)
9587 error_at (loc
, "function arguments of %<__builtin_tgmath%> "
9588 "lack type-generic parameter");
9593 /* Determine the type of the relevant parameter for each
9595 auto_vec
<tree
> tg_type (num_functions
);
9596 for (unsigned int j
= 0; j
< num_functions
; j
++)
9598 tree type
= TREE_TYPE (TREE_TYPE ((*cexpr_list
)[j
].value
));
9600 FOREACH_FUNCTION_ARGS (type
, t
, iter
)
9602 if (argpos
== tgarg
)
9604 tg_type
.quick_push (TYPE_MAIN_VARIANT (t
));
9611 /* Verify that the corresponding types are different for
9612 all the listed functions. Also determine whether all
9613 the types are complex, whether all the types are
9614 standard or binary, and whether all the types are
9616 bool all_complex
= true;
9617 bool all_binary
= true;
9618 bool all_decimal
= true;
9619 hash_set
<tree
> tg_types
;
9620 FOR_EACH_VEC_ELT (tg_type
, i
, t
)
9622 if (TREE_CODE (t
) == COMPLEX_TYPE
)
9623 all_decimal
= false;
9626 all_complex
= false;
9627 if (DECIMAL_FLOAT_TYPE_P (t
))
9630 all_decimal
= false;
9632 if (tg_types
.add (t
))
9634 error_at ((*cexpr_list
)[i
].get_location (),
9635 "duplicate type-generic parameter type for "
9636 "function argument %u of %<__builtin_tgmath%>",
9643 /* Verify that other parameters and the return type whose
9644 types vary have their types varying in the correct
9646 for (unsigned int j
= 0; j
< num_functions
; j
++)
9648 tree exp_type
= tg_type
[j
];
9649 tree exp_real_type
= exp_type
;
9650 if (TREE_CODE (exp_type
) == COMPLEX_TYPE
)
9651 exp_real_type
= TREE_TYPE (exp_type
);
9652 tree type
= TREE_TYPE (TREE_TYPE ((*cexpr_list
)[j
].value
));
9653 tree ret
= TYPE_MAIN_VARIANT (TREE_TYPE (type
));
9654 if ((parm_kind
[0] == tgmath_complex
&& ret
!= exp_type
)
9655 || (parm_kind
[0] == tgmath_real
&& ret
!= exp_real_type
))
9657 error_at ((*cexpr_list
)[j
].get_location (),
9658 "bad return type for function argument %u "
9659 "of %<__builtin_tgmath%>", j
+ 1);
9664 FOREACH_FUNCTION_ARGS (type
, t
, iter
)
9666 if (t
== void_type_node
)
9668 t
= TYPE_MAIN_VARIANT (t
);
9669 if ((parm_kind
[argpos
] == tgmath_complex
9671 || (parm_kind
[argpos
] == tgmath_real
9672 && t
!= exp_real_type
))
9674 error_at ((*cexpr_list
)[j
].get_location (),
9675 "bad type for argument %u of "
9676 "function argument %u of "
9677 "%<__builtin_tgmath%>", argpos
, j
+ 1);
9685 /* The functions listed are a valid set of functions for a
9686 <tgmath.h> macro to select between. Identify the
9687 matching function, if any. First, the argument types
9688 must be combined following <tgmath.h> rules. Integer
9689 types are treated as _Decimal64 if any type-generic
9690 argument is decimal, or if the only alternatives for
9691 type-generic arguments are of decimal types, and are
9692 otherwise treated as double (or _Complex double for
9693 complex integer types, or _Float64 or _Complex _Float64
9694 if all the return types are the same _FloatN or
9695 _FloatNx type). After that adjustment, types are
9696 combined following the usual arithmetic conversions.
9697 If the function only accepts complex arguments, a
9698 complex type is produced. */
9699 bool arg_complex
= all_complex
;
9700 bool arg_binary
= all_binary
;
9701 bool arg_int_decimal
= all_decimal
;
9702 for (unsigned int j
= 1; j
<= nargs
; j
++)
9704 if (parm_kind
[j
] == tgmath_fixed
)
9706 c_expr_t
*ce
= &(*cexpr_list
)[num_functions
+ j
- 1];
9707 tree type
= TREE_TYPE (ce
->value
);
9708 if (!INTEGRAL_TYPE_P (type
)
9709 && !SCALAR_FLOAT_TYPE_P (type
)
9710 && TREE_CODE (type
) != COMPLEX_TYPE
)
9712 error_at (ce
->get_location (),
9713 "invalid type of argument %u of type-generic "
9718 if (DECIMAL_FLOAT_TYPE_P (type
))
9720 arg_int_decimal
= true;
9723 error_at (ce
->get_location (),
9724 "decimal floating-point argument %u to "
9725 "complex-only type-generic function", j
);
9729 else if (all_binary
)
9731 error_at (ce
->get_location (),
9732 "decimal floating-point argument %u to "
9733 "binary-only type-generic function", j
);
9737 else if (arg_complex
)
9739 error_at (ce
->get_location (),
9740 "both complex and decimal floating-point "
9741 "arguments to type-generic function");
9745 else if (arg_binary
)
9747 error_at (ce
->get_location (),
9748 "both binary and decimal floating-point "
9749 "arguments to type-generic function");
9754 else if (TREE_CODE (type
) == COMPLEX_TYPE
)
9757 if (COMPLEX_FLOAT_TYPE_P (type
))
9761 error_at (ce
->get_location (),
9762 "complex argument %u to "
9763 "decimal-only type-generic function", j
);
9767 else if (arg_int_decimal
)
9769 error_at (ce
->get_location (),
9770 "both complex and decimal floating-point "
9771 "arguments to type-generic function");
9776 else if (SCALAR_FLOAT_TYPE_P (type
))
9781 error_at (ce
->get_location (),
9782 "binary argument %u to "
9783 "decimal-only type-generic function", j
);
9787 else if (arg_int_decimal
)
9789 error_at (ce
->get_location (),
9790 "both binary and decimal floating-point "
9791 "arguments to type-generic function");
9797 /* For a macro rounding its result to a narrower type, map
9798 integer types to _Float64 not double if the return type
9799 is a _FloatN or _FloatNx type. */
9800 bool arg_int_float64
= false;
9801 if (parm_kind
[0] == tgmath_fixed
9802 && SCALAR_FLOAT_TYPE_P (parm_first
[0])
9803 && float64_type_node
!= NULL_TREE
)
9804 for (unsigned int j
= 0; j
< NUM_FLOATN_NX_TYPES
; j
++)
9805 if (parm_first
[0] == FLOATN_TYPE_NODE (j
))
9807 arg_int_float64
= true;
9810 tree arg_real
= NULL_TREE
;
9811 for (unsigned int j
= 1; j
<= nargs
; j
++)
9813 if (parm_kind
[j
] == tgmath_fixed
)
9815 c_expr_t
*ce
= &(*cexpr_list
)[num_functions
+ j
- 1];
9816 tree type
= TYPE_MAIN_VARIANT (TREE_TYPE (ce
->value
));
9817 if (TREE_CODE (type
) == COMPLEX_TYPE
)
9818 type
= TREE_TYPE (type
);
9819 if (INTEGRAL_TYPE_P (type
))
9820 type
= (arg_int_decimal
9821 ? dfloat64_type_node
9824 : double_type_node
);
9825 if (arg_real
== NULL_TREE
)
9828 arg_real
= common_type (arg_real
, type
);
9829 if (arg_real
== error_mark_node
)
9835 tree arg_type
= (arg_complex
9836 ? build_complex_type (arg_real
)
9839 /* Look for a function to call with type-generic parameter
9841 c_expr_t
*fn
= NULL
;
9842 for (unsigned int j
= 0; j
< num_functions
; j
++)
9844 if (tg_type
[j
] == arg_type
)
9846 fn
= &(*cexpr_list
)[j
];
9851 && parm_kind
[0] == tgmath_fixed
9852 && SCALAR_FLOAT_TYPE_P (parm_first
[0]))
9854 /* Presume this is a macro that rounds its result to a
9855 narrower type, and look for the first function with
9856 at least the range and precision of the argument
9858 for (unsigned int j
= 0; j
< num_functions
; j
++)
9861 != (TREE_CODE (tg_type
[j
]) == COMPLEX_TYPE
))
9863 tree real_tg_type
= (arg_complex
9864 ? TREE_TYPE (tg_type
[j
])
9866 if (DECIMAL_FLOAT_TYPE_P (arg_real
)
9867 != DECIMAL_FLOAT_TYPE_P (real_tg_type
))
9869 scalar_float_mode arg_mode
9870 = SCALAR_FLOAT_TYPE_MODE (arg_real
);
9871 scalar_float_mode tg_mode
9872 = SCALAR_FLOAT_TYPE_MODE (real_tg_type
);
9873 const real_format
*arg_fmt
= REAL_MODE_FORMAT (arg_mode
);
9874 const real_format
*tg_fmt
= REAL_MODE_FORMAT (tg_mode
);
9875 if (arg_fmt
->b
== tg_fmt
->b
9876 && arg_fmt
->p
<= tg_fmt
->p
9877 && arg_fmt
->emax
<= tg_fmt
->emax
9878 && (arg_fmt
->emin
- arg_fmt
->p
9879 >= tg_fmt
->emin
- tg_fmt
->p
))
9881 fn
= &(*cexpr_list
)[j
];
9888 error_at (loc
, "no matching function for type-generic call");
9893 /* Construct a call to FN. */
9894 vec
<tree
, va_gc
> *args
;
9895 vec_alloc (args
, nargs
);
9896 vec
<tree
, va_gc
> *origtypes
;
9897 vec_alloc (origtypes
, nargs
);
9898 auto_vec
<location_t
> arg_loc (nargs
);
9899 for (unsigned int j
= 0; j
< nargs
; j
++)
9901 c_expr_t
*ce
= &(*cexpr_list
)[num_functions
+ j
];
9902 args
->quick_push (ce
->value
);
9903 arg_loc
.quick_push (ce
->get_location ());
9904 origtypes
->quick_push (ce
->original_type
);
9906 expr
.value
= c_build_function_call_vec (loc
, arg_loc
, fn
->value
,
9908 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
9911 case RID_BUILTIN_CALL_WITH_STATIC_CHAIN
:
9913 vec
<c_expr_t
, va_gc
> *cexpr_list
;
9916 location_t close_paren_loc
;
9918 c_parser_consume_token (parser
);
9919 if (!c_parser_get_builtin_args (parser
,
9920 "__builtin_call_with_static_chain",
9927 if (vec_safe_length (cexpr_list
) != 2)
9929 error_at (loc
, "wrong number of arguments to "
9930 "%<__builtin_call_with_static_chain%>");
9935 expr
= (*cexpr_list
)[0];
9936 e2_p
= &(*cexpr_list
)[1];
9937 *e2_p
= convert_lvalue_to_rvalue (loc
, *e2_p
, true, true);
9938 chain_value
= e2_p
->value
;
9939 mark_exp_read (chain_value
);
9941 if (TREE_CODE (expr
.value
) != CALL_EXPR
)
9942 error_at (loc
, "first argument to "
9943 "%<__builtin_call_with_static_chain%> "
9944 "must be a call expression");
9945 else if (TREE_CODE (TREE_TYPE (chain_value
)) != POINTER_TYPE
)
9946 error_at (loc
, "second argument to "
9947 "%<__builtin_call_with_static_chain%> "
9948 "must be a pointer type");
9950 CALL_EXPR_STATIC_CHAIN (expr
.value
) = chain_value
;
9951 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
9954 case RID_BUILTIN_COMPLEX
:
9956 vec
<c_expr_t
, va_gc
> *cexpr_list
;
9957 c_expr_t
*e1_p
, *e2_p
;
9958 location_t close_paren_loc
;
9960 c_parser_consume_token (parser
);
9961 if (!c_parser_get_builtin_args (parser
,
9962 "__builtin_complex",
9970 if (vec_safe_length (cexpr_list
) != 2)
9972 error_at (loc
, "wrong number of arguments to "
9973 "%<__builtin_complex%>");
9978 e1_p
= &(*cexpr_list
)[0];
9979 e2_p
= &(*cexpr_list
)[1];
9981 *e1_p
= convert_lvalue_to_rvalue (loc
, *e1_p
, true, true);
9982 if (TREE_CODE (e1_p
->value
) == EXCESS_PRECISION_EXPR
)
9983 e1_p
->value
= convert (TREE_TYPE (e1_p
->value
),
9984 TREE_OPERAND (e1_p
->value
, 0));
9985 *e2_p
= convert_lvalue_to_rvalue (loc
, *e2_p
, true, true);
9986 if (TREE_CODE (e2_p
->value
) == EXCESS_PRECISION_EXPR
)
9987 e2_p
->value
= convert (TREE_TYPE (e2_p
->value
),
9988 TREE_OPERAND (e2_p
->value
, 0));
9989 if (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (e1_p
->value
))
9990 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e1_p
->value
))
9991 || !SCALAR_FLOAT_TYPE_P (TREE_TYPE (e2_p
->value
))
9992 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e2_p
->value
)))
9994 error_at (loc
, "%<__builtin_complex%> operand "
9995 "not of real binary floating-point type");
9999 if (TYPE_MAIN_VARIANT (TREE_TYPE (e1_p
->value
))
10000 != TYPE_MAIN_VARIANT (TREE_TYPE (e2_p
->value
)))
10003 "%<__builtin_complex%> operands of different types");
10007 pedwarn_c90 (loc
, OPT_Wpedantic
,
10008 "ISO C90 does not support complex types");
10009 expr
.value
= build2_loc (loc
, COMPLEX_EXPR
,
10012 (TREE_TYPE (e1_p
->value
))),
10013 e1_p
->value
, e2_p
->value
);
10014 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
10017 case RID_BUILTIN_SHUFFLE
:
10019 vec
<c_expr_t
, va_gc
> *cexpr_list
;
10022 location_t close_paren_loc
;
10024 c_parser_consume_token (parser
);
10025 if (!c_parser_get_builtin_args (parser
,
10026 "__builtin_shuffle",
10027 &cexpr_list
, false,
10034 FOR_EACH_VEC_SAFE_ELT (cexpr_list
, i
, p
)
10035 *p
= convert_lvalue_to_rvalue (loc
, *p
, true, true);
10037 if (vec_safe_length (cexpr_list
) == 2)
10038 expr
.value
= c_build_vec_perm_expr (loc
, (*cexpr_list
)[0].value
,
10040 (*cexpr_list
)[1].value
);
10042 else if (vec_safe_length (cexpr_list
) == 3)
10043 expr
.value
= c_build_vec_perm_expr (loc
, (*cexpr_list
)[0].value
,
10044 (*cexpr_list
)[1].value
,
10045 (*cexpr_list
)[2].value
);
10048 error_at (loc
, "wrong number of arguments to "
10049 "%<__builtin_shuffle%>");
10052 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
10055 case RID_BUILTIN_SHUFFLEVECTOR
:
10057 vec
<c_expr_t
, va_gc
> *cexpr_list
;
10060 location_t close_paren_loc
;
10062 c_parser_consume_token (parser
);
10063 if (!c_parser_get_builtin_args (parser
,
10064 "__builtin_shufflevector",
10065 &cexpr_list
, false,
10072 FOR_EACH_VEC_SAFE_ELT (cexpr_list
, i
, p
)
10073 *p
= convert_lvalue_to_rvalue (loc
, *p
, true, true);
10075 if (vec_safe_length (cexpr_list
) < 3)
10077 error_at (loc
, "wrong number of arguments to "
10078 "%<__builtin_shuffle%>");
10083 auto_vec
<tree
, 16> mask
;
10084 for (i
= 2; i
< cexpr_list
->length (); ++i
)
10085 mask
.safe_push ((*cexpr_list
)[i
].value
);
10086 expr
.value
= c_build_shufflevector (loc
, (*cexpr_list
)[0].value
,
10087 (*cexpr_list
)[1].value
,
10090 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
10093 case RID_BUILTIN_CONVERTVECTOR
:
10095 location_t start_loc
= loc
;
10096 c_parser_consume_token (parser
);
10097 matching_parens parens
;
10098 if (!parens
.require_open (parser
))
10103 e1
= c_parser_expr_no_commas (parser
, NULL
);
10104 mark_exp_read (e1
.value
);
10105 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
10107 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10111 loc
= c_parser_peek_token (parser
)->location
;
10112 t1
= c_parser_type_name (parser
);
10113 location_t end_loc
= c_parser_peek_token (parser
)->get_finish ();
10114 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
10120 tree type_expr
= NULL_TREE
;
10121 expr
.value
= c_build_vec_convert (start_loc
, e1
.value
, loc
,
10122 groktypename (t1
, &type_expr
,
10124 set_c_expr_source_range (&expr
, start_loc
, end_loc
);
10128 case RID_BUILTIN_ASSOC_BARRIER
:
10130 location_t start_loc
= loc
;
10131 c_parser_consume_token (parser
);
10132 matching_parens parens
;
10133 if (!parens
.require_open (parser
))
10138 e1
= c_parser_expr_no_commas (parser
, NULL
);
10139 mark_exp_read (e1
.value
);
10140 location_t end_loc
= c_parser_peek_token (parser
)->get_finish ();
10141 parens
.skip_until_found_close (parser
);
10142 expr
= parser_build_unary_op (loc
, PAREN_EXPR
, e1
);
10143 set_c_expr_source_range (&expr
, start_loc
, end_loc
);
10146 case RID_AT_SELECTOR
:
10148 gcc_assert (c_dialect_objc ());
10149 c_parser_consume_token (parser
);
10150 matching_parens parens
;
10151 if (!parens
.require_open (parser
))
10156 tree sel
= c_parser_objc_selector_arg (parser
);
10157 location_t close_loc
= c_parser_peek_token (parser
)->location
;
10158 parens
.skip_until_found_close (parser
);
10159 expr
.value
= objc_build_selector_expr (loc
, sel
);
10160 set_c_expr_source_range (&expr
, loc
, close_loc
);
10163 case RID_AT_PROTOCOL
:
10165 gcc_assert (c_dialect_objc ());
10166 c_parser_consume_token (parser
);
10167 matching_parens parens
;
10168 if (!parens
.require_open (parser
))
10173 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
10175 c_parser_error (parser
, "expected identifier");
10176 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10180 tree id
= c_parser_peek_token (parser
)->value
;
10181 c_parser_consume_token (parser
);
10182 location_t close_loc
= c_parser_peek_token (parser
)->location
;
10183 parens
.skip_until_found_close (parser
);
10184 expr
.value
= objc_build_protocol_expr (id
);
10185 set_c_expr_source_range (&expr
, loc
, close_loc
);
10188 case RID_AT_ENCODE
:
10190 /* Extension to support C-structures in the archiver. */
10191 gcc_assert (c_dialect_objc ());
10192 c_parser_consume_token (parser
);
10193 matching_parens parens
;
10194 if (!parens
.require_open (parser
))
10199 t1
= c_parser_type_name (parser
);
10203 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10206 location_t close_loc
= c_parser_peek_token (parser
)->location
;
10207 parens
.skip_until_found_close (parser
);
10208 tree type
= groktypename (t1
, NULL
, NULL
);
10209 expr
.value
= objc_build_encode_expr (type
);
10210 set_c_expr_source_range (&expr
, loc
, close_loc
);
10214 expr
= c_parser_generic_selection (parser
);
10216 case RID_OMP_ALL_MEMORY
:
10217 gcc_assert (flag_openmp
);
10218 c_parser_consume_token (parser
);
10219 error_at (loc
, "%<omp_all_memory%> may only be used in OpenMP "
10220 "%<depend%> clause");
10224 c_parser_error (parser
, "expected expression");
10229 case CPP_OPEN_SQUARE
:
10230 if (c_dialect_objc ())
10232 tree receiver
, args
;
10233 c_parser_consume_token (parser
);
10234 receiver
= c_parser_objc_receiver (parser
);
10235 args
= c_parser_objc_message_args (parser
);
10236 location_t close_loc
= c_parser_peek_token (parser
)->location
;
10237 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
10239 expr
.value
= objc_build_message_expr (receiver
, args
);
10240 set_c_expr_source_range (&expr
, loc
, close_loc
);
10243 /* Else fall through to report error. */
10246 c_parser_error (parser
, "expected expression");
10251 return c_parser_postfix_expression_after_primary
10252 (parser
, EXPR_LOC_OR_LOC (expr
.value
, loc
), expr
);
10255 /* Parse a postfix expression after a parenthesized type name: the
10256 brace-enclosed initializer of a compound literal, possibly followed
10257 by some postfix operators. This is separate because it is not
10258 possible to tell until after the type name whether a cast
10259 expression has a cast or a compound literal, or whether the operand
10260 of sizeof is a parenthesized type name or starts with a compound
10261 literal. TYPE_LOC is the location where TYPE_NAME starts--the
10262 location of the first token after the parentheses around the type
10265 static struct c_expr
10266 c_parser_postfix_expression_after_paren_type (c_parser
*parser
,
10267 struct c_type_name
*type_name
,
10268 location_t type_loc
)
10271 struct c_expr init
;
10273 struct c_expr expr
;
10274 location_t start_loc
;
10275 tree type_expr
= NULL_TREE
;
10276 bool type_expr_const
= true;
10277 check_compound_literal_type (type_loc
, type_name
);
10278 rich_location
richloc (line_table
, type_loc
);
10279 start_init (NULL_TREE
, NULL
, 0, &richloc
);
10280 type
= groktypename (type_name
, &type_expr
, &type_expr_const
);
10281 start_loc
= c_parser_peek_token (parser
)->location
;
10282 if (type
!= error_mark_node
&& C_TYPE_VARIABLE_SIZE (type
))
10284 error_at (type_loc
, "compound literal has variable size");
10285 type
= error_mark_node
;
10287 init
= c_parser_braced_init (parser
, type
, false, NULL
);
10289 maybe_warn_string_init (type_loc
, type
, init
);
10291 if (type
!= error_mark_node
10292 && !ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (type
))
10293 && current_function_decl
)
10295 error ("compound literal qualified by address-space qualifier");
10296 type
= error_mark_node
;
10299 pedwarn_c90 (start_loc
, OPT_Wpedantic
, "ISO C90 forbids compound literals");
10300 non_const
= ((init
.value
&& TREE_CODE (init
.value
) == CONSTRUCTOR
)
10301 ? CONSTRUCTOR_NON_CONST (init
.value
)
10302 : init
.original_code
== C_MAYBE_CONST_EXPR
);
10303 non_const
|= !type_expr_const
;
10304 unsigned int alignas_align
= 0;
10305 if (type
!= error_mark_node
10306 && type_name
->specs
->align_log
!= -1)
10308 alignas_align
= 1U << type_name
->specs
->align_log
;
10309 if (alignas_align
< min_align_of_type (type
))
10311 error_at (type_name
->specs
->locations
[cdw_alignas
],
10312 "%<_Alignas%> specifiers cannot reduce "
10313 "alignment of compound literal");
10317 expr
.value
= build_compound_literal (start_loc
, type
, init
.value
, non_const
,
10319 set_c_expr_source_range (&expr
, init
.src_range
);
10320 expr
.original_code
= ERROR_MARK
;
10321 expr
.original_type
= NULL
;
10322 if (type
!= error_mark_node
10323 && expr
.value
!= error_mark_node
10326 if (TREE_CODE (expr
.value
) == C_MAYBE_CONST_EXPR
)
10328 gcc_assert (C_MAYBE_CONST_EXPR_PRE (expr
.value
) == NULL_TREE
);
10329 C_MAYBE_CONST_EXPR_PRE (expr
.value
) = type_expr
;
10333 gcc_assert (!non_const
);
10334 expr
.value
= build2 (C_MAYBE_CONST_EXPR
, type
,
10335 type_expr
, expr
.value
);
10338 return c_parser_postfix_expression_after_primary (parser
, start_loc
, expr
);
10341 /* Callback function for sizeof_pointer_memaccess_warning to compare
10345 sizeof_ptr_memacc_comptypes (tree type1
, tree type2
)
10347 return comptypes (type1
, type2
) == 1;
10350 /* Warn for patterns where abs-like function appears to be used incorrectly,
10351 gracefully ignore any non-abs-like function. The warning location should
10352 be LOC. FNDECL is the declaration of called function, it must be a
10353 BUILT_IN_NORMAL function. ARG is the first and only argument of the
10357 warn_for_abs (location_t loc
, tree fndecl
, tree arg
)
10359 /* Avoid warning in unreachable subexpressions. */
10360 if (c_inhibit_evaluation_warnings
)
10363 tree atype
= TREE_TYPE (arg
);
10365 /* Casts from pointers (and thus arrays and fndecls) will generate
10366 -Wint-conversion warnings. Most other wrong types hopefully lead to type
10367 mismatch errors. TODO: Think about what to do with FIXED_POINT_TYPE_P
10368 types and possibly other exotic types. */
10369 if (!INTEGRAL_TYPE_P (atype
)
10370 && !SCALAR_FLOAT_TYPE_P (atype
)
10371 && TREE_CODE (atype
) != COMPLEX_TYPE
)
10374 enum built_in_function fcode
= DECL_FUNCTION_CODE (fndecl
);
10379 case BUILT_IN_LABS
:
10380 case BUILT_IN_LLABS
:
10381 case BUILT_IN_IMAXABS
:
10382 if (!INTEGRAL_TYPE_P (atype
))
10384 if (SCALAR_FLOAT_TYPE_P (atype
))
10385 warning_at (loc
, OPT_Wabsolute_value
,
10386 "using integer absolute value function %qD when "
10387 "argument is of floating-point type %qT",
10389 else if (TREE_CODE (atype
) == COMPLEX_TYPE
)
10390 warning_at (loc
, OPT_Wabsolute_value
,
10391 "using integer absolute value function %qD when "
10392 "argument is of complex type %qT", fndecl
, atype
);
10394 gcc_unreachable ();
10397 if (TYPE_UNSIGNED (atype
))
10398 warning_at (loc
, OPT_Wabsolute_value
,
10399 "taking the absolute value of unsigned type %qT "
10400 "has no effect", atype
);
10403 CASE_FLT_FN (BUILT_IN_FABS
):
10404 CASE_FLT_FN_FLOATN_NX (BUILT_IN_FABS
):
10405 if (!SCALAR_FLOAT_TYPE_P (atype
)
10406 || DECIMAL_FLOAT_MODE_P (TYPE_MODE (atype
)))
10408 if (INTEGRAL_TYPE_P (atype
))
10409 warning_at (loc
, OPT_Wabsolute_value
,
10410 "using floating-point absolute value function %qD "
10411 "when argument is of integer type %qT", fndecl
, atype
);
10412 else if (DECIMAL_FLOAT_TYPE_P (atype
))
10413 warning_at (loc
, OPT_Wabsolute_value
,
10414 "using floating-point absolute value function %qD "
10415 "when argument is of decimal floating-point type %qT",
10417 else if (TREE_CODE (atype
) == COMPLEX_TYPE
)
10418 warning_at (loc
, OPT_Wabsolute_value
,
10419 "using floating-point absolute value function %qD when "
10420 "argument is of complex type %qT", fndecl
, atype
);
10422 gcc_unreachable ();
10427 CASE_FLT_FN (BUILT_IN_CABS
):
10428 if (TREE_CODE (atype
) != COMPLEX_TYPE
)
10430 if (INTEGRAL_TYPE_P (atype
))
10431 warning_at (loc
, OPT_Wabsolute_value
,
10432 "using complex absolute value function %qD when "
10433 "argument is of integer type %qT", fndecl
, atype
);
10434 else if (SCALAR_FLOAT_TYPE_P (atype
))
10435 warning_at (loc
, OPT_Wabsolute_value
,
10436 "using complex absolute value function %qD when "
10437 "argument is of floating-point type %qT",
10440 gcc_unreachable ();
10446 case BUILT_IN_FABSD32
:
10447 case BUILT_IN_FABSD64
:
10448 case BUILT_IN_FABSD128
:
10449 if (!DECIMAL_FLOAT_TYPE_P (atype
))
10451 if (INTEGRAL_TYPE_P (atype
))
10452 warning_at (loc
, OPT_Wabsolute_value
,
10453 "using decimal floating-point absolute value "
10454 "function %qD when argument is of integer type %qT",
10456 else if (SCALAR_FLOAT_TYPE_P (atype
))
10457 warning_at (loc
, OPT_Wabsolute_value
,
10458 "using decimal floating-point absolute value "
10459 "function %qD when argument is of floating-point "
10460 "type %qT", fndecl
, atype
);
10461 else if (TREE_CODE (atype
) == COMPLEX_TYPE
)
10462 warning_at (loc
, OPT_Wabsolute_value
,
10463 "using decimal floating-point absolute value "
10464 "function %qD when argument is of complex type %qT",
10467 gcc_unreachable ();
10476 if (!TYPE_ARG_TYPES (TREE_TYPE (fndecl
)))
10479 tree ftype
= TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl
)));
10480 if (TREE_CODE (atype
) == COMPLEX_TYPE
)
10482 gcc_assert (TREE_CODE (ftype
) == COMPLEX_TYPE
);
10483 atype
= TREE_TYPE (atype
);
10484 ftype
= TREE_TYPE (ftype
);
10487 if (TYPE_PRECISION (ftype
) < TYPE_PRECISION (atype
))
10488 warning_at (loc
, OPT_Wabsolute_value
,
10489 "absolute value function %qD given an argument of type %qT "
10490 "but has parameter of type %qT which may cause truncation "
10491 "of value", fndecl
, atype
, ftype
);
10495 /* Parse a postfix expression after the initial primary or compound
10496 literal; that is, parse a series of postfix operators.
10498 EXPR_LOC is the location of the primary expression. */
10500 static struct c_expr
10501 c_parser_postfix_expression_after_primary (c_parser
*parser
,
10502 location_t expr_loc
,
10503 struct c_expr expr
)
10505 struct c_expr orig_expr
;
10507 location_t sizeof_arg_loc
[3], comp_loc
;
10508 tree sizeof_arg
[3];
10509 unsigned int literal_zero_mask
;
10511 vec
<tree
, va_gc
> *exprlist
;
10512 vec
<tree
, va_gc
> *origtypes
= NULL
;
10513 vec
<location_t
> arg_loc
= vNULL
;
10519 location_t op_loc
= c_parser_peek_token (parser
)->location
;
10520 switch (c_parser_peek_token (parser
)->type
)
10522 case CPP_OPEN_SQUARE
:
10523 /* Array reference. */
10524 c_parser_consume_token (parser
);
10525 idx
= c_parser_expression (parser
).value
;
10526 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
10528 start
= expr
.get_start ();
10529 finish
= parser
->tokens_buf
[0].location
;
10530 expr
.value
= build_array_ref (op_loc
, expr
.value
, idx
);
10531 set_c_expr_source_range (&expr
, start
, finish
);
10532 expr
.original_code
= ERROR_MARK
;
10533 expr
.original_type
= NULL
;
10535 case CPP_OPEN_PAREN
:
10536 /* Function call. */
10538 matching_parens parens
;
10539 parens
.consume_open (parser
);
10540 for (i
= 0; i
< 3; i
++)
10542 sizeof_arg
[i
] = NULL_TREE
;
10543 sizeof_arg_loc
[i
] = UNKNOWN_LOCATION
;
10545 literal_zero_mask
= 0;
10546 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
10549 exprlist
= c_parser_expr_list (parser
, true, false, &origtypes
,
10550 sizeof_arg_loc
, sizeof_arg
,
10551 &arg_loc
, &literal_zero_mask
);
10552 parens
.skip_until_found_close (parser
);
10555 mark_exp_read (expr
.value
);
10556 if (warn_sizeof_pointer_memaccess
)
10557 sizeof_pointer_memaccess_warning (sizeof_arg_loc
,
10558 expr
.value
, exprlist
,
10560 sizeof_ptr_memacc_comptypes
);
10561 if (TREE_CODE (expr
.value
) == FUNCTION_DECL
)
10563 if (fndecl_built_in_p (expr
.value
, BUILT_IN_MEMSET
)
10564 && vec_safe_length (exprlist
) == 3)
10566 tree arg0
= (*exprlist
)[0];
10567 tree arg2
= (*exprlist
)[2];
10568 warn_for_memset (expr_loc
, arg0
, arg2
, literal_zero_mask
);
10570 if (warn_absolute_value
10571 && fndecl_built_in_p (expr
.value
, BUILT_IN_NORMAL
)
10572 && vec_safe_length (exprlist
) == 1)
10573 warn_for_abs (expr_loc
, expr
.value
, (*exprlist
)[0]);
10576 start
= expr
.get_start ();
10577 finish
= parser
->tokens_buf
[0].get_finish ();
10579 = c_build_function_call_vec (expr_loc
, arg_loc
, expr
.value
,
10580 exprlist
, origtypes
);
10581 set_c_expr_source_range (&expr
, start
, finish
);
10583 expr
.original_code
= ERROR_MARK
;
10584 if (TREE_CODE (expr
.value
) == INTEGER_CST
10585 && TREE_CODE (orig_expr
.value
) == FUNCTION_DECL
10586 && fndecl_built_in_p (orig_expr
.value
, BUILT_IN_CONSTANT_P
))
10587 expr
.original_code
= C_MAYBE_CONST_EXPR
;
10588 expr
.original_type
= NULL
;
10591 release_tree_vector (exprlist
);
10592 release_tree_vector (origtypes
);
10594 arg_loc
.release ();
10597 /* Structure element reference. */
10598 c_parser_consume_token (parser
);
10599 expr
= default_function_array_conversion (expr_loc
, expr
);
10600 if (c_parser_next_token_is (parser
, CPP_NAME
))
10602 c_token
*comp_tok
= c_parser_peek_token (parser
);
10603 ident
= comp_tok
->value
;
10604 comp_loc
= comp_tok
->location
;
10608 c_parser_error (parser
, "expected identifier");
10610 expr
.original_code
= ERROR_MARK
;
10611 expr
.original_type
= NULL
;
10614 start
= expr
.get_start ();
10615 finish
= c_parser_peek_token (parser
)->get_finish ();
10616 c_parser_consume_token (parser
);
10617 expr
.value
= build_component_ref (op_loc
, expr
.value
, ident
,
10618 comp_loc
, UNKNOWN_LOCATION
);
10619 set_c_expr_source_range (&expr
, start
, finish
);
10620 expr
.original_code
= ERROR_MARK
;
10621 if (TREE_CODE (expr
.value
) != COMPONENT_REF
)
10622 expr
.original_type
= NULL
;
10625 /* Remember the original type of a bitfield. */
10626 tree field
= TREE_OPERAND (expr
.value
, 1);
10627 if (TREE_CODE (field
) != FIELD_DECL
)
10628 expr
.original_type
= NULL
;
10630 expr
.original_type
= DECL_BIT_FIELD_TYPE (field
);
10634 /* Structure element reference. */
10635 c_parser_consume_token (parser
);
10636 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, true, false);
10637 if (c_parser_next_token_is (parser
, CPP_NAME
))
10639 c_token
*comp_tok
= c_parser_peek_token (parser
);
10640 ident
= comp_tok
->value
;
10641 comp_loc
= comp_tok
->location
;
10645 c_parser_error (parser
, "expected identifier");
10647 expr
.original_code
= ERROR_MARK
;
10648 expr
.original_type
= NULL
;
10651 start
= expr
.get_start ();
10652 finish
= c_parser_peek_token (parser
)->get_finish ();
10653 c_parser_consume_token (parser
);
10654 expr
.value
= build_component_ref (op_loc
,
10655 build_indirect_ref (op_loc
,
10659 expr
.get_location ());
10660 set_c_expr_source_range (&expr
, start
, finish
);
10661 expr
.original_code
= ERROR_MARK
;
10662 if (TREE_CODE (expr
.value
) != COMPONENT_REF
)
10663 expr
.original_type
= NULL
;
10666 /* Remember the original type of a bitfield. */
10667 tree field
= TREE_OPERAND (expr
.value
, 1);
10668 if (TREE_CODE (field
) != FIELD_DECL
)
10669 expr
.original_type
= NULL
;
10671 expr
.original_type
= DECL_BIT_FIELD_TYPE (field
);
10674 case CPP_PLUS_PLUS
:
10675 /* Postincrement. */
10676 start
= expr
.get_start ();
10677 finish
= c_parser_peek_token (parser
)->get_finish ();
10678 c_parser_consume_token (parser
);
10679 expr
= default_function_array_read_conversion (expr_loc
, expr
);
10680 expr
.value
= build_unary_op (op_loc
, POSTINCREMENT_EXPR
,
10681 expr
.value
, false);
10682 set_c_expr_source_range (&expr
, start
, finish
);
10683 expr
.original_code
= ERROR_MARK
;
10684 expr
.original_type
= NULL
;
10686 case CPP_MINUS_MINUS
:
10687 /* Postdecrement. */
10688 start
= expr
.get_start ();
10689 finish
= c_parser_peek_token (parser
)->get_finish ();
10690 c_parser_consume_token (parser
);
10691 expr
= default_function_array_read_conversion (expr_loc
, expr
);
10692 expr
.value
= build_unary_op (op_loc
, POSTDECREMENT_EXPR
,
10693 expr
.value
, false);
10694 set_c_expr_source_range (&expr
, start
, finish
);
10695 expr
.original_code
= ERROR_MARK
;
10696 expr
.original_type
= NULL
;
10704 /* Parse an expression (C90 6.3.17, C99 6.5.17, C11 6.5.17).
10707 assignment-expression
10708 expression , assignment-expression
10711 static struct c_expr
10712 c_parser_expression (c_parser
*parser
)
10714 location_t tloc
= c_parser_peek_token (parser
)->location
;
10715 struct c_expr expr
;
10716 expr
= c_parser_expr_no_commas (parser
, NULL
);
10717 if (c_parser_next_token_is (parser
, CPP_COMMA
))
10718 expr
= convert_lvalue_to_rvalue (tloc
, expr
, true, false);
10719 while (c_parser_next_token_is (parser
, CPP_COMMA
))
10721 struct c_expr next
;
10723 location_t loc
= c_parser_peek_token (parser
)->location
;
10724 location_t expr_loc
;
10725 c_parser_consume_token (parser
);
10726 expr_loc
= c_parser_peek_token (parser
)->location
;
10727 lhsval
= expr
.value
;
10728 while (TREE_CODE (lhsval
) == COMPOUND_EXPR
10729 || TREE_CODE (lhsval
) == NOP_EXPR
)
10731 if (TREE_CODE (lhsval
) == COMPOUND_EXPR
)
10732 lhsval
= TREE_OPERAND (lhsval
, 1);
10734 lhsval
= TREE_OPERAND (lhsval
, 0);
10736 if (DECL_P (lhsval
) || handled_component_p (lhsval
))
10737 mark_exp_read (lhsval
);
10738 next
= c_parser_expr_no_commas (parser
, NULL
);
10739 next
= convert_lvalue_to_rvalue (expr_loc
, next
, true, false);
10740 expr
.value
= build_compound_expr (loc
, expr
.value
, next
.value
);
10741 expr
.original_code
= COMPOUND_EXPR
;
10742 expr
.original_type
= next
.original_type
;
10747 /* Parse an expression and convert functions or arrays to pointers and
10748 lvalues to rvalues. */
10750 static struct c_expr
10751 c_parser_expression_conv (c_parser
*parser
)
10753 struct c_expr expr
;
10754 location_t loc
= c_parser_peek_token (parser
)->location
;
10755 expr
= c_parser_expression (parser
);
10756 expr
= convert_lvalue_to_rvalue (loc
, expr
, true, false);
10760 /* Helper function of c_parser_expr_list. Check if IDXth (0 based)
10761 argument is a literal zero alone and if so, set it in literal_zero_mask. */
10764 c_parser_check_literal_zero (c_parser
*parser
, unsigned *literal_zero_mask
,
10767 if (idx
>= HOST_BITS_PER_INT
)
10770 c_token
*tok
= c_parser_peek_token (parser
);
10779 /* If a parameter is literal zero alone, remember it
10780 for -Wmemset-transposed-args warning. */
10781 if (integer_zerop (tok
->value
)
10782 && !TREE_OVERFLOW (tok
->value
)
10783 && (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
10784 || c_parser_peek_2nd_token (parser
)->type
== CPP_CLOSE_PAREN
))
10785 *literal_zero_mask
|= 1U << idx
;
10791 /* Parse a non-empty list of expressions. If CONVERT_P, convert
10792 functions and arrays to pointers and lvalues to rvalues. If
10793 FOLD_P, fold the expressions. If LOCATIONS is non-NULL, save the
10794 locations of function arguments into this vector.
10796 nonempty-expr-list:
10797 assignment-expression
10798 nonempty-expr-list , assignment-expression
10801 static vec
<tree
, va_gc
> *
10802 c_parser_expr_list (c_parser
*parser
, bool convert_p
, bool fold_p
,
10803 vec
<tree
, va_gc
> **p_orig_types
,
10804 location_t
*sizeof_arg_loc
, tree
*sizeof_arg
,
10805 vec
<location_t
> *locations
,
10806 unsigned int *literal_zero_mask
)
10808 vec
<tree
, va_gc
> *ret
;
10809 vec
<tree
, va_gc
> *orig_types
;
10810 struct c_expr expr
;
10811 unsigned int idx
= 0;
10813 ret
= make_tree_vector ();
10814 if (p_orig_types
== NULL
)
10817 orig_types
= make_tree_vector ();
10819 if (literal_zero_mask
)
10820 c_parser_check_literal_zero (parser
, literal_zero_mask
, 0);
10821 expr
= c_parser_expr_no_commas (parser
, NULL
);
10823 expr
= convert_lvalue_to_rvalue (expr
.get_location (), expr
, true, true);
10825 expr
.value
= c_fully_fold (expr
.value
, false, NULL
);
10826 ret
->quick_push (expr
.value
);
10828 orig_types
->quick_push (expr
.original_type
);
10830 locations
->safe_push (expr
.get_location ());
10831 if (sizeof_arg
!= NULL
10832 && (expr
.original_code
== SIZEOF_EXPR
10833 || expr
.original_code
== PAREN_SIZEOF_EXPR
))
10835 sizeof_arg
[0] = c_last_sizeof_arg
;
10836 sizeof_arg_loc
[0] = c_last_sizeof_loc
;
10838 while (c_parser_next_token_is (parser
, CPP_COMMA
))
10840 c_parser_consume_token (parser
);
10841 if (literal_zero_mask
)
10842 c_parser_check_literal_zero (parser
, literal_zero_mask
, idx
+ 1);
10843 expr
= c_parser_expr_no_commas (parser
, NULL
);
10845 expr
= convert_lvalue_to_rvalue (expr
.get_location (), expr
, true,
10848 expr
.value
= c_fully_fold (expr
.value
, false, NULL
);
10849 vec_safe_push (ret
, expr
.value
);
10851 vec_safe_push (orig_types
, expr
.original_type
);
10853 locations
->safe_push (expr
.get_location ());
10855 && sizeof_arg
!= NULL
10856 && (expr
.original_code
== SIZEOF_EXPR
10857 || expr
.original_code
== PAREN_SIZEOF_EXPR
))
10859 sizeof_arg
[idx
] = c_last_sizeof_arg
;
10860 sizeof_arg_loc
[idx
] = c_last_sizeof_loc
;
10864 *p_orig_types
= orig_types
;
10868 /* Parse Objective-C-specific constructs. */
10870 /* Parse an objc-class-definition.
10872 objc-class-definition:
10873 @interface identifier objc-superclass[opt] objc-protocol-refs[opt]
10874 objc-class-instance-variables[opt] objc-methodprotolist @end
10875 @implementation identifier objc-superclass[opt]
10876 objc-class-instance-variables[opt]
10877 @interface identifier ( identifier ) objc-protocol-refs[opt]
10878 objc-methodprotolist @end
10879 @interface identifier ( ) objc-protocol-refs[opt]
10880 objc-methodprotolist @end
10881 @implementation identifier ( identifier )
10886 "@interface identifier (" must start "@interface identifier (
10887 identifier ) ...": objc-methodprotolist in the first production may
10888 not start with a parenthesized identifier as a declarator of a data
10889 definition with no declaration specifiers if the objc-superclass,
10890 objc-protocol-refs and objc-class-instance-variables are omitted. */
10893 c_parser_objc_class_definition (c_parser
*parser
, tree attributes
)
10898 if (c_parser_next_token_is_keyword (parser
, RID_AT_INTERFACE
))
10900 else if (c_parser_next_token_is_keyword (parser
, RID_AT_IMPLEMENTATION
))
10903 gcc_unreachable ();
10905 c_parser_consume_token (parser
);
10906 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
10908 c_parser_error (parser
, "expected identifier");
10911 id1
= c_parser_peek_token (parser
)->value
;
10912 location_t loc1
= c_parser_peek_token (parser
)->location
;
10913 c_parser_consume_token (parser
);
10914 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
10916 /* We have a category or class extension. */
10918 tree proto
= NULL_TREE
;
10919 matching_parens parens
;
10920 parens
.consume_open (parser
);
10921 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
10923 if (iface_p
&& c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
10925 /* We have a class extension. */
10930 c_parser_error (parser
, "expected identifier or %<)%>");
10931 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10937 id2
= c_parser_peek_token (parser
)->value
;
10938 c_parser_consume_token (parser
);
10940 parens
.skip_until_found_close (parser
);
10943 objc_start_category_implementation (id1
, id2
);
10946 if (c_parser_next_token_is (parser
, CPP_LESS
))
10947 proto
= c_parser_objc_protocol_refs (parser
);
10948 objc_start_category_interface (id1
, id2
, proto
, attributes
);
10949 c_parser_objc_methodprotolist (parser
);
10950 c_parser_require_keyword (parser
, RID_AT_END
, "expected %<@end%>");
10951 objc_finish_interface ();
10954 if (c_parser_next_token_is (parser
, CPP_COLON
))
10956 c_parser_consume_token (parser
);
10957 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
10959 c_parser_error (parser
, "expected identifier");
10962 superclass
= c_parser_peek_token (parser
)->value
;
10963 c_parser_consume_token (parser
);
10966 superclass
= NULL_TREE
;
10969 tree proto
= NULL_TREE
;
10970 if (c_parser_next_token_is (parser
, CPP_LESS
))
10971 proto
= c_parser_objc_protocol_refs (parser
);
10972 objc_start_class_interface (id1
, loc1
, superclass
, proto
, attributes
);
10975 objc_start_class_implementation (id1
, superclass
);
10976 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
10977 c_parser_objc_class_instance_variables (parser
);
10980 objc_continue_interface ();
10981 c_parser_objc_methodprotolist (parser
);
10982 c_parser_require_keyword (parser
, RID_AT_END
, "expected %<@end%>");
10983 objc_finish_interface ();
10987 objc_continue_implementation ();
10992 /* Parse objc-class-instance-variables.
10994 objc-class-instance-variables:
10995 { objc-instance-variable-decl-list[opt] }
10997 objc-instance-variable-decl-list:
10998 objc-visibility-spec
10999 objc-instance-variable-decl ;
11001 objc-instance-variable-decl-list objc-visibility-spec
11002 objc-instance-variable-decl-list objc-instance-variable-decl ;
11003 objc-instance-variable-decl-list ;
11005 objc-visibility-spec:
11010 objc-instance-variable-decl:
11015 c_parser_objc_class_instance_variables (c_parser
*parser
)
11017 gcc_assert (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
));
11018 c_parser_consume_token (parser
);
11019 while (c_parser_next_token_is_not (parser
, CPP_EOF
))
11022 /* Parse any stray semicolon. */
11023 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
11025 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
11026 "extra semicolon");
11027 c_parser_consume_token (parser
);
11030 /* Stop if at the end of the instance variables. */
11031 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
11033 c_parser_consume_token (parser
);
11036 /* Parse any objc-visibility-spec. */
11037 if (c_parser_next_token_is_keyword (parser
, RID_AT_PRIVATE
))
11039 c_parser_consume_token (parser
);
11040 objc_set_visibility (OBJC_IVAR_VIS_PRIVATE
);
11043 else if (c_parser_next_token_is_keyword (parser
, RID_AT_PROTECTED
))
11045 c_parser_consume_token (parser
);
11046 objc_set_visibility (OBJC_IVAR_VIS_PROTECTED
);
11049 else if (c_parser_next_token_is_keyword (parser
, RID_AT_PUBLIC
))
11051 c_parser_consume_token (parser
);
11052 objc_set_visibility (OBJC_IVAR_VIS_PUBLIC
);
11055 else if (c_parser_next_token_is_keyword (parser
, RID_AT_PACKAGE
))
11057 c_parser_consume_token (parser
);
11058 objc_set_visibility (OBJC_IVAR_VIS_PACKAGE
);
11061 else if (c_parser_next_token_is (parser
, CPP_PRAGMA
))
11063 c_parser_pragma (parser
, pragma_external
, NULL
);
11067 /* Parse some comma-separated declarations. */
11068 decls
= c_parser_struct_declaration (parser
);
11071 /* There is a syntax error. We want to skip the offending
11072 tokens up to the next ';' (included) or '}'
11075 /* First, skip manually a ')' or ']'. This is because they
11076 reduce the nesting level, so c_parser_skip_until_found()
11077 wouldn't be able to skip past them. */
11078 c_token
*token
= c_parser_peek_token (parser
);
11079 if (token
->type
== CPP_CLOSE_PAREN
|| token
->type
== CPP_CLOSE_SQUARE
)
11080 c_parser_consume_token (parser
);
11082 /* Then, do the standard skipping. */
11083 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
11085 /* We hopefully recovered. Start normal parsing again. */
11086 parser
->error
= false;
11091 /* Comma-separated instance variables are chained together
11092 in reverse order; add them one by one. */
11093 tree ivar
= nreverse (decls
);
11094 for (; ivar
; ivar
= DECL_CHAIN (ivar
))
11095 objc_add_instance_variable (copy_node (ivar
));
11097 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
11101 /* Parse an objc-class-declaration.
11103 objc-class-declaration:
11104 @class identifier-list ;
11108 c_parser_objc_class_declaration (c_parser
*parser
)
11110 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_CLASS
));
11111 c_parser_consume_token (parser
);
11112 /* Any identifiers, including those declared as type names, are OK
11117 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11119 c_parser_error (parser
, "expected identifier");
11120 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
11121 parser
->error
= false;
11124 id
= c_parser_peek_token (parser
)->value
;
11125 objc_declare_class (id
);
11126 c_parser_consume_token (parser
);
11127 if (c_parser_next_token_is (parser
, CPP_COMMA
))
11128 c_parser_consume_token (parser
);
11132 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
11135 /* Parse an objc-alias-declaration.
11137 objc-alias-declaration:
11138 @compatibility_alias identifier identifier ;
11142 c_parser_objc_alias_declaration (c_parser
*parser
)
11145 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_ALIAS
));
11146 c_parser_consume_token (parser
);
11147 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11149 c_parser_error (parser
, "expected identifier");
11150 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
11153 id1
= c_parser_peek_token (parser
)->value
;
11154 c_parser_consume_token (parser
);
11155 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11157 c_parser_error (parser
, "expected identifier");
11158 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
11161 id2
= c_parser_peek_token (parser
)->value
;
11162 c_parser_consume_token (parser
);
11163 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
11164 objc_declare_alias (id1
, id2
);
11167 /* Parse an objc-protocol-definition.
11169 objc-protocol-definition:
11170 @protocol identifier objc-protocol-refs[opt] objc-methodprotolist @end
11171 @protocol identifier-list ;
11173 "@protocol identifier ;" should be resolved as "@protocol
11174 identifier-list ;": objc-methodprotolist may not start with a
11175 semicolon in the first alternative if objc-protocol-refs are
11179 c_parser_objc_protocol_definition (c_parser
*parser
, tree attributes
)
11181 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_PROTOCOL
));
11183 c_parser_consume_token (parser
);
11184 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11186 c_parser_error (parser
, "expected identifier");
11189 if (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
11190 || c_parser_peek_2nd_token (parser
)->type
== CPP_SEMICOLON
)
11192 /* Any identifiers, including those declared as type names, are
11197 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11199 c_parser_error (parser
, "expected identifier");
11202 id
= c_parser_peek_token (parser
)->value
;
11203 objc_declare_protocol (id
, attributes
);
11204 c_parser_consume_token (parser
);
11205 if (c_parser_next_token_is (parser
, CPP_COMMA
))
11206 c_parser_consume_token (parser
);
11210 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
11214 tree id
= c_parser_peek_token (parser
)->value
;
11215 tree proto
= NULL_TREE
;
11216 c_parser_consume_token (parser
);
11217 if (c_parser_next_token_is (parser
, CPP_LESS
))
11218 proto
= c_parser_objc_protocol_refs (parser
);
11219 parser
->objc_pq_context
= true;
11220 objc_start_protocol (id
, proto
, attributes
);
11221 c_parser_objc_methodprotolist (parser
);
11222 c_parser_require_keyword (parser
, RID_AT_END
, "expected %<@end%>");
11223 parser
->objc_pq_context
= false;
11224 objc_finish_interface ();
11228 /* Parse an objc-method-type.
11234 Return true if it is a class method (+) and false if it is
11235 an instance method (-).
11238 c_parser_objc_method_type (c_parser
*parser
)
11240 switch (c_parser_peek_token (parser
)->type
)
11243 c_parser_consume_token (parser
);
11246 c_parser_consume_token (parser
);
11249 gcc_unreachable ();
11253 /* Parse an objc-method-definition.
11255 objc-method-definition:
11256 objc-method-type objc-method-decl ;[opt] compound-statement
11260 c_parser_objc_method_definition (c_parser
*parser
)
11262 bool is_class_method
= c_parser_objc_method_type (parser
);
11263 tree decl
, attributes
= NULL_TREE
, expr
= NULL_TREE
;
11264 parser
->objc_pq_context
= true;
11265 decl
= c_parser_objc_method_decl (parser
, is_class_method
, &attributes
,
11267 if (decl
== error_mark_node
)
11268 return; /* Bail here. */
11270 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
11272 c_parser_consume_token (parser
);
11273 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
11274 "extra semicolon in method definition specified");
11277 if (!c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
11279 c_parser_error (parser
, "expected %<{%>");
11283 parser
->objc_pq_context
= false;
11284 if (objc_start_method_definition (is_class_method
, decl
, attributes
, expr
))
11286 add_stmt (c_parser_compound_statement (parser
));
11287 objc_finish_method_definition (current_function_decl
);
11291 /* This code is executed when we find a method definition
11292 outside of an @implementation context (or invalid for other
11293 reasons). Parse the method (to keep going) but do not emit
11296 c_parser_compound_statement (parser
);
11300 /* Parse an objc-methodprotolist.
11302 objc-methodprotolist:
11304 objc-methodprotolist objc-methodproto
11305 objc-methodprotolist declaration
11306 objc-methodprotolist ;
11310 The declaration is a data definition, which may be missing
11311 declaration specifiers under the same rules and diagnostics as
11312 other data definitions outside functions, and the stray semicolon
11313 is diagnosed the same way as a stray semicolon outside a
11317 c_parser_objc_methodprotolist (c_parser
*parser
)
11321 /* The list is terminated by @end. */
11322 switch (c_parser_peek_token (parser
)->type
)
11324 case CPP_SEMICOLON
:
11325 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
11326 "ISO C does not allow extra %<;%> outside of a function");
11327 c_parser_consume_token (parser
);
11331 c_parser_objc_methodproto (parser
);
11334 c_parser_pragma (parser
, pragma_external
, NULL
);
11339 if (c_parser_next_token_is_keyword (parser
, RID_AT_END
))
11341 else if (c_parser_next_token_is_keyword (parser
, RID_AT_PROPERTY
))
11342 c_parser_objc_at_property_declaration (parser
);
11343 else if (c_parser_next_token_is_keyword (parser
, RID_AT_OPTIONAL
))
11345 objc_set_method_opt (true);
11346 c_parser_consume_token (parser
);
11348 else if (c_parser_next_token_is_keyword (parser
, RID_AT_REQUIRED
))
11350 objc_set_method_opt (false);
11351 c_parser_consume_token (parser
);
11354 c_parser_declaration_or_fndef (parser
, false, false, true,
11361 /* Parse an objc-methodproto.
11364 objc-method-type objc-method-decl ;
11368 c_parser_objc_methodproto (c_parser
*parser
)
11370 bool is_class_method
= c_parser_objc_method_type (parser
);
11371 tree decl
, attributes
= NULL_TREE
;
11373 /* Remember protocol qualifiers in prototypes. */
11374 parser
->objc_pq_context
= true;
11375 decl
= c_parser_objc_method_decl (parser
, is_class_method
, &attributes
,
11377 /* Forget protocol qualifiers now. */
11378 parser
->objc_pq_context
= false;
11380 /* Do not allow the presence of attributes to hide an erroneous
11381 method implementation in the interface section. */
11382 if (!c_parser_next_token_is (parser
, CPP_SEMICOLON
))
11384 c_parser_error (parser
, "expected %<;%>");
11388 if (decl
!= error_mark_node
)
11389 objc_add_method_declaration (is_class_method
, decl
, attributes
);
11391 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
11394 /* If we are at a position that method attributes may be present, check that
11395 there are not any parsed already (a syntax error) and then collect any
11396 specified at the current location. Finally, if new attributes were present,
11397 check that the next token is legal ( ';' for decls and '{' for defs). */
11400 c_parser_objc_maybe_method_attributes (c_parser
* parser
, tree
* attributes
)
11405 c_parser_error (parser
,
11406 "method attributes must be specified at the end only");
11407 *attributes
= NULL_TREE
;
11411 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
11412 *attributes
= c_parser_gnu_attributes (parser
);
11414 /* If there were no attributes here, just report any earlier error. */
11415 if (*attributes
== NULL_TREE
|| bad
)
11418 /* If the attributes are followed by a ; or {, then just report any earlier
11420 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
)
11421 || c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
11424 /* We've got attributes, but not at the end. */
11425 c_parser_error (parser
,
11426 "expected %<;%> or %<{%> after method attribute definition");
11430 /* Parse an objc-method-decl.
11433 ( objc-type-name ) objc-selector
11435 ( objc-type-name ) objc-keyword-selector objc-optparmlist
11436 objc-keyword-selector objc-optparmlist
11439 objc-keyword-selector:
11441 objc-keyword-selector objc-keyword-decl
11444 objc-selector : ( objc-type-name ) identifier
11445 objc-selector : identifier
11446 : ( objc-type-name ) identifier
11450 objc-optparms objc-optellipsis
11454 objc-opt-parms , parameter-declaration
11462 c_parser_objc_method_decl (c_parser
*parser
, bool is_class_method
,
11463 tree
*attributes
, tree
*expr
)
11465 tree type
= NULL_TREE
;
11467 tree parms
= NULL_TREE
;
11468 bool ellipsis
= false;
11469 bool attr_err
= false;
11471 *attributes
= NULL_TREE
;
11472 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
11474 matching_parens parens
;
11475 parens
.consume_open (parser
);
11476 type
= c_parser_objc_type_name (parser
);
11477 parens
.skip_until_found_close (parser
);
11479 sel
= c_parser_objc_selector (parser
);
11480 /* If there is no selector, or a colon follows, we have an
11481 objc-keyword-selector. If there is a selector, and a colon does
11482 not follow, that selector ends the objc-method-decl. */
11483 if (!sel
|| c_parser_next_token_is (parser
, CPP_COLON
))
11486 tree list
= NULL_TREE
;
11489 tree atype
= NULL_TREE
, id
, keyworddecl
;
11490 tree param_attr
= NULL_TREE
;
11491 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
11493 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
11495 c_parser_consume_token (parser
);
11496 atype
= c_parser_objc_type_name (parser
);
11497 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
11500 /* New ObjC allows attributes on method parameters. */
11501 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
11502 param_attr
= c_parser_gnu_attributes (parser
);
11503 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11505 c_parser_error (parser
, "expected identifier");
11506 return error_mark_node
;
11508 id
= c_parser_peek_token (parser
)->value
;
11509 c_parser_consume_token (parser
);
11510 keyworddecl
= objc_build_keyword_decl (tsel
, atype
, id
, param_attr
);
11511 list
= chainon (list
, keyworddecl
);
11512 tsel
= c_parser_objc_selector (parser
);
11513 if (!tsel
&& c_parser_next_token_is_not (parser
, CPP_COLON
))
11517 attr_err
|= c_parser_objc_maybe_method_attributes (parser
, attributes
) ;
11519 /* Parse the optional parameter list. Optional Objective-C
11520 method parameters follow the C syntax, and may include '...'
11521 to denote a variable number of arguments. */
11522 parms
= make_node (TREE_LIST
);
11523 while (c_parser_next_token_is (parser
, CPP_COMMA
))
11525 struct c_parm
*parm
;
11526 c_parser_consume_token (parser
);
11527 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
11530 c_parser_consume_token (parser
);
11531 attr_err
|= c_parser_objc_maybe_method_attributes
11532 (parser
, attributes
) ;
11535 parm
= c_parser_parameter_declaration (parser
, NULL_TREE
, false);
11538 parms
= chainon (parms
,
11539 build_tree_list (NULL_TREE
, grokparm (parm
, expr
)));
11544 attr_err
|= c_parser_objc_maybe_method_attributes (parser
, attributes
) ;
11548 c_parser_error (parser
, "objective-c method declaration is expected");
11549 return error_mark_node
;
11553 return error_mark_node
;
11555 return objc_build_method_signature (is_class_method
, type
, sel
, parms
, ellipsis
);
11558 /* Parse an objc-type-name.
11561 objc-type-qualifiers[opt] type-name
11562 objc-type-qualifiers[opt]
11564 objc-type-qualifiers:
11565 objc-type-qualifier
11566 objc-type-qualifiers objc-type-qualifier
11568 objc-type-qualifier: one of
11569 in out inout bycopy byref oneway
11573 c_parser_objc_type_name (c_parser
*parser
)
11575 tree quals
= NULL_TREE
;
11576 struct c_type_name
*type_name
= NULL
;
11577 tree type
= NULL_TREE
;
11580 c_token
*token
= c_parser_peek_token (parser
);
11581 if (token
->type
== CPP_KEYWORD
11582 && (token
->keyword
== RID_IN
11583 || token
->keyword
== RID_OUT
11584 || token
->keyword
== RID_INOUT
11585 || token
->keyword
== RID_BYCOPY
11586 || token
->keyword
== RID_BYREF
11587 || token
->keyword
== RID_ONEWAY
))
11589 quals
= chainon (build_tree_list (NULL_TREE
, token
->value
), quals
);
11590 c_parser_consume_token (parser
);
11595 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_type
))
11596 type_name
= c_parser_type_name (parser
);
11598 type
= groktypename (type_name
, NULL
, NULL
);
11600 /* If the type is unknown, and error has already been produced and
11601 we need to recover from the error. In that case, use NULL_TREE
11602 for the type, as if no type had been specified; this will use the
11603 default type ('id') which is good for error recovery. */
11604 if (type
== error_mark_node
)
11607 return build_tree_list (quals
, type
);
11610 /* Parse objc-protocol-refs.
11612 objc-protocol-refs:
11613 < identifier-list >
11617 c_parser_objc_protocol_refs (c_parser
*parser
)
11619 tree list
= NULL_TREE
;
11620 gcc_assert (c_parser_next_token_is (parser
, CPP_LESS
));
11621 c_parser_consume_token (parser
);
11622 /* Any identifiers, including those declared as type names, are OK
11627 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11629 c_parser_error (parser
, "expected identifier");
11632 id
= c_parser_peek_token (parser
)->value
;
11633 list
= chainon (list
, build_tree_list (NULL_TREE
, id
));
11634 c_parser_consume_token (parser
);
11635 if (c_parser_next_token_is (parser
, CPP_COMMA
))
11636 c_parser_consume_token (parser
);
11640 c_parser_require (parser
, CPP_GREATER
, "expected %<>%>");
11644 /* Parse an objc-try-catch-finally-statement.
11646 objc-try-catch-finally-statement:
11647 @try compound-statement objc-catch-list[opt]
11648 @try compound-statement objc-catch-list[opt] @finally compound-statement
11651 @catch ( objc-catch-parameter-declaration ) compound-statement
11652 objc-catch-list @catch ( objc-catch-parameter-declaration ) compound-statement
11654 objc-catch-parameter-declaration:
11655 parameter-declaration
11658 where '...' is to be interpreted literally, that is, it means CPP_ELLIPSIS.
11660 PS: This function is identical to cp_parser_objc_try_catch_finally_statement
11661 for C++. Keep them in sync. */
11664 c_parser_objc_try_catch_finally_statement (c_parser
*parser
)
11666 location_t location
;
11669 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_TRY
));
11670 c_parser_consume_token (parser
);
11671 location
= c_parser_peek_token (parser
)->location
;
11672 objc_maybe_warn_exceptions (location
);
11673 stmt
= c_parser_compound_statement (parser
);
11674 objc_begin_try_stmt (location
, stmt
);
11676 while (c_parser_next_token_is_keyword (parser
, RID_AT_CATCH
))
11678 struct c_parm
*parm
;
11679 tree parameter_declaration
= error_mark_node
;
11680 bool seen_open_paren
= false;
11682 c_parser_consume_token (parser
);
11683 matching_parens parens
;
11684 if (!parens
.require_open (parser
))
11685 seen_open_paren
= true;
11686 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
11688 /* We have "@catch (...)" (where the '...' are literally
11689 what is in the code). Skip the '...'.
11690 parameter_declaration is set to NULL_TREE, and
11691 objc_being_catch_clauses() knows that that means
11693 c_parser_consume_token (parser
);
11694 parameter_declaration
= NULL_TREE
;
11698 /* We have "@catch (NSException *exception)" or something
11699 like that. Parse the parameter declaration. */
11700 parm
= c_parser_parameter_declaration (parser
, NULL_TREE
, false);
11702 parameter_declaration
= error_mark_node
;
11704 parameter_declaration
= grokparm (parm
, NULL
);
11706 if (seen_open_paren
)
11707 parens
.require_close (parser
);
11710 /* If there was no open parenthesis, we are recovering from
11711 an error, and we are trying to figure out what mistake
11712 the user has made. */
11714 /* If there is an immediate closing parenthesis, the user
11715 probably forgot the opening one (ie, they typed "@catch
11716 NSException *e)". Parse the closing parenthesis and keep
11718 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
11719 c_parser_consume_token (parser
);
11721 /* If these is no immediate closing parenthesis, the user
11722 probably doesn't know that parenthesis are required at
11723 all (ie, they typed "@catch NSException *e"). So, just
11724 forget about the closing parenthesis and keep going. */
11726 objc_begin_catch_clause (parameter_declaration
);
11727 if (c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
11728 c_parser_compound_statement_nostart (parser
);
11729 objc_finish_catch_clause ();
11731 if (c_parser_next_token_is_keyword (parser
, RID_AT_FINALLY
))
11733 c_parser_consume_token (parser
);
11734 location
= c_parser_peek_token (parser
)->location
;
11735 stmt
= c_parser_compound_statement (parser
);
11736 objc_build_finally_clause (location
, stmt
);
11738 objc_finish_try_stmt ();
11741 /* Parse an objc-synchronized-statement.
11743 objc-synchronized-statement:
11744 @synchronized ( expression ) compound-statement
11748 c_parser_objc_synchronized_statement (c_parser
*parser
)
11752 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_SYNCHRONIZED
));
11753 c_parser_consume_token (parser
);
11754 loc
= c_parser_peek_token (parser
)->location
;
11755 objc_maybe_warn_exceptions (loc
);
11756 matching_parens parens
;
11757 if (parens
.require_open (parser
))
11759 struct c_expr ce
= c_parser_expression (parser
);
11760 ce
= convert_lvalue_to_rvalue (loc
, ce
, false, false);
11762 expr
= c_fully_fold (expr
, false, NULL
);
11763 parens
.skip_until_found_close (parser
);
11766 expr
= error_mark_node
;
11767 stmt
= c_parser_compound_statement (parser
);
11768 objc_build_synchronized (loc
, expr
, stmt
);
11771 /* Parse an objc-selector; return NULL_TREE without an error if the
11772 next token is not an objc-selector.
11777 enum struct union if else while do for switch case default
11778 break continue return goto asm sizeof typeof __alignof
11779 unsigned long const short volatile signed restrict _Complex
11780 in out inout bycopy byref oneway int char float double void _Bool
11783 ??? Why this selection of keywords but not, for example, storage
11784 class specifiers? */
11787 c_parser_objc_selector (c_parser
*parser
)
11789 c_token
*token
= c_parser_peek_token (parser
);
11790 tree value
= token
->value
;
11791 if (token
->type
== CPP_NAME
)
11793 c_parser_consume_token (parser
);
11796 if (token
->type
!= CPP_KEYWORD
)
11798 switch (token
->keyword
)
11837 CASE_RID_FLOATN_NX
:
11841 case RID_AUTO_TYPE
:
11846 c_parser_consume_token (parser
);
11853 /* Parse an objc-selector-arg.
11857 objc-keywordname-list
11859 objc-keywordname-list:
11861 objc-keywordname-list objc-keywordname
11869 c_parser_objc_selector_arg (c_parser
*parser
)
11871 tree sel
= c_parser_objc_selector (parser
);
11872 tree list
= NULL_TREE
;
11874 && c_parser_next_token_is_not (parser
, CPP_COLON
)
11875 && c_parser_next_token_is_not (parser
, CPP_SCOPE
))
11879 if (c_parser_next_token_is (parser
, CPP_SCOPE
))
11881 c_parser_consume_token (parser
);
11882 list
= chainon (list
, build_tree_list (sel
, NULL_TREE
));
11883 list
= chainon (list
, build_tree_list (NULL_TREE
, NULL_TREE
));
11887 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
11889 list
= chainon (list
, build_tree_list (sel
, NULL_TREE
));
11891 sel
= c_parser_objc_selector (parser
);
11893 && c_parser_next_token_is_not (parser
, CPP_COLON
)
11894 && c_parser_next_token_is_not (parser
, CPP_SCOPE
))
11900 /* Parse an objc-receiver.
11909 c_parser_objc_receiver (c_parser
*parser
)
11911 location_t loc
= c_parser_peek_token (parser
)->location
;
11913 if (c_parser_peek_token (parser
)->type
== CPP_NAME
11914 && (c_parser_peek_token (parser
)->id_kind
== C_ID_TYPENAME
11915 || c_parser_peek_token (parser
)->id_kind
== C_ID_CLASSNAME
))
11917 tree id
= c_parser_peek_token (parser
)->value
;
11918 c_parser_consume_token (parser
);
11919 return objc_get_class_reference (id
);
11921 struct c_expr ce
= c_parser_expression (parser
);
11922 ce
= convert_lvalue_to_rvalue (loc
, ce
, false, false);
11923 return c_fully_fold (ce
.value
, false, NULL
);
11926 /* Parse objc-message-args.
11930 objc-keywordarg-list
11932 objc-keywordarg-list:
11934 objc-keywordarg-list objc-keywordarg
11937 objc-selector : objc-keywordexpr
11942 c_parser_objc_message_args (c_parser
*parser
)
11944 tree sel
= c_parser_objc_selector (parser
);
11945 tree list
= NULL_TREE
;
11946 if (sel
&& c_parser_next_token_is_not (parser
, CPP_COLON
))
11951 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
11952 return error_mark_node
;
11953 keywordexpr
= c_parser_objc_keywordexpr (parser
);
11954 list
= chainon (list
, build_tree_list (sel
, keywordexpr
));
11955 sel
= c_parser_objc_selector (parser
);
11956 if (!sel
&& c_parser_next_token_is_not (parser
, CPP_COLON
))
11962 /* Parse an objc-keywordexpr.
11969 c_parser_objc_keywordexpr (c_parser
*parser
)
11972 vec
<tree
, va_gc
> *expr_list
= c_parser_expr_list (parser
, true, true,
11973 NULL
, NULL
, NULL
, NULL
);
11974 if (vec_safe_length (expr_list
) == 1)
11976 /* Just return the expression, remove a level of
11978 ret
= (*expr_list
)[0];
11982 /* We have a comma expression, we will collapse later. */
11983 ret
= build_tree_list_vec (expr_list
);
11985 release_tree_vector (expr_list
);
11989 /* A check, needed in several places, that ObjC interface, implementation or
11990 method definitions are not prefixed by incorrect items. */
11992 c_parser_objc_diagnose_bad_element_prefix (c_parser
*parser
,
11993 struct c_declspecs
*specs
)
11995 if (!specs
->declspecs_seen_p
|| specs
->non_sc_seen_p
11996 || specs
->typespec_kind
!= ctsk_none
)
11998 c_parser_error (parser
,
11999 "no type or storage class may be specified here,");
12000 c_parser_skip_to_end_of_block_or_statement (parser
);
12006 /* Parse an Objective-C @property declaration. The syntax is:
12008 objc-property-declaration:
12009 '@property' objc-property-attributes[opt] struct-declaration ;
12011 objc-property-attributes:
12012 '(' objc-property-attribute-list ')'
12014 objc-property-attribute-list:
12015 objc-property-attribute
12016 objc-property-attribute-list, objc-property-attribute
12018 objc-property-attribute
12019 'getter' = identifier
12020 'setter' = identifier
12029 @property NSString *name;
12030 @property (readonly) id object;
12031 @property (retain, nonatomic, getter=getTheName) id name;
12032 @property int a, b, c;
12034 PS: This function is identical to cp_parser_objc_at_propery_declaration
12035 for C++. Keep them in sync. */
12037 c_parser_objc_at_property_declaration (c_parser
*parser
)
12039 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_PROPERTY
));
12040 location_t loc
= c_parser_peek_token (parser
)->location
;
12041 c_parser_consume_token (parser
); /* Eat '@property'. */
12043 /* Parse the optional attribute list.
12045 A list of parsed, but not verified, attributes. */
12046 vec
<property_attribute_info
*> prop_attr_list
= vNULL
;
12048 bool syntax_error
= false;
12049 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
12051 matching_parens parens
;
12053 location_t attr_start
= c_parser_peek_token (parser
)->location
;
12055 parens
.consume_open (parser
);
12057 /* Property attribute keywords are valid now. */
12058 parser
->objc_property_attr_context
= true;
12060 /* Allow @property (), with a warning. */
12061 location_t attr_end
= c_parser_peek_token (parser
)->location
;
12063 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
12065 location_t attr_comb
= make_location (attr_end
, attr_start
, attr_end
);
12066 warning_at (attr_comb
, OPT_Wattributes
,
12067 "empty property attribute list");
12072 c_token
*token
= c_parser_peek_token (parser
);
12073 attr_start
= token
->location
;
12074 attr_end
= get_finish (token
->location
);
12075 location_t attr_comb
= make_location (attr_start
, attr_start
,
12078 if (token
->type
== CPP_CLOSE_PAREN
|| token
->type
== CPP_COMMA
)
12080 warning_at (attr_comb
, OPT_Wattributes
,
12081 "missing property attribute");
12082 if (token
->type
== CPP_CLOSE_PAREN
)
12084 c_parser_consume_token (parser
);
12088 tree attr_name
= NULL_TREE
;
12089 enum rid keyword
= RID_MAX
; /* Not a valid property attribute. */
12090 bool add_at
= false;
12091 if (token
->type
== CPP_KEYWORD
)
12093 keyword
= token
->keyword
;
12094 if (OBJC_IS_AT_KEYWORD (keyword
))
12096 /* For '@' keywords the token value has the keyword,
12097 prepend the '@' for diagnostics. */
12098 attr_name
= token
->value
;
12102 attr_name
= ridpointers
[(int)keyword
];
12104 else if (token
->type
== CPP_NAME
)
12105 attr_name
= token
->value
;
12106 c_parser_consume_token (parser
);
12108 enum objc_property_attribute_kind prop_kind
12109 = objc_prop_attr_kind_for_rid (keyword
);
12110 property_attribute_info
*prop
12111 = new property_attribute_info (attr_name
, attr_comb
, prop_kind
);
12112 prop_attr_list
.safe_push (prop
);
12115 switch (prop
->prop_kind
)
12118 case OBJC_PROPERTY_ATTR_UNKNOWN
:
12120 error_at (attr_comb
, "unknown property attribute %<%s%s%>",
12121 add_at
? "@" : "", IDENTIFIER_POINTER (attr_name
));
12123 error_at (attr_comb
, "unknown property attribute");
12124 prop
->parse_error
= syntax_error
= true;
12127 case OBJC_PROPERTY_ATTR_GETTER
:
12128 case OBJC_PROPERTY_ATTR_SETTER
:
12129 if (c_parser_next_token_is_not (parser
, CPP_EQ
))
12131 attr_comb
= make_location (attr_end
, attr_start
, attr_end
);
12132 error_at (attr_comb
, "expected %<=%> after Objective-C %qE",
12134 prop
->parse_error
= syntax_error
= true;
12137 token
= c_parser_peek_token (parser
);
12138 attr_end
= token
->location
;
12139 c_parser_consume_token (parser
); /* eat the = */
12140 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
12142 attr_comb
= make_location (attr_end
, attr_start
, attr_end
);
12143 error_at (attr_comb
, "expected %qE selector name",
12145 prop
->parse_error
= syntax_error
= true;
12148 /* Get the end of the method name, and consume the name. */
12149 token
= c_parser_peek_token (parser
);
12150 attr_end
= get_finish (token
->location
);
12151 meth_name
= token
->value
;
12152 c_parser_consume_token (parser
);
12153 if (prop
->prop_kind
== OBJC_PROPERTY_ATTR_SETTER
)
12155 if (c_parser_next_token_is_not (parser
, CPP_COLON
))
12157 attr_comb
= make_location (attr_end
, attr_start
,
12159 error_at (attr_comb
, "setter method names must"
12160 " terminate with %<:%>");
12161 prop
->parse_error
= syntax_error
= true;
12165 attr_end
= get_finish (c_parser_peek_token
12166 (parser
)->location
);
12167 c_parser_consume_token (parser
);
12169 attr_comb
= make_location (attr_start
, attr_start
,
12173 attr_comb
= make_location (attr_start
, attr_start
,
12175 prop
->ident
= meth_name
;
12176 /* Updated location including all that was successfully
12178 prop
->prop_loc
= attr_comb
;
12182 /* If we see a comma here, then keep going - even if we already
12183 saw a syntax error. For simple mistakes e.g. (asign, getter=x)
12184 this makes a more useful output and avoid spurious warnings about
12185 missing attributes that are, in fact, specified after the one with
12186 the syntax error. */
12187 if (c_parser_next_token_is (parser
, CPP_COMMA
))
12188 c_parser_consume_token (parser
);
12192 parser
->objc_property_attr_context
= false;
12194 if (syntax_error
&& c_parser_next_token_is_not (parser
, CPP_CLOSE_PAREN
))
12195 /* We don't really want to chew the whole of the file looking for a
12196 matching closing parenthesis, so we will try to read the decl and
12197 let the error handling for that close out the statement. */
12200 syntax_error
= false, parens
.skip_until_found_close (parser
);
12203 /* 'properties' is the list of properties that we read. Usually a
12204 single one, but maybe more (eg, in "@property int a, b, c;" there
12206 tree properties
= c_parser_struct_declaration (parser
);
12208 if (properties
== error_mark_node
)
12209 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
12212 if (properties
== NULL_TREE
)
12213 c_parser_error (parser
, "expected identifier");
12216 /* Comma-separated properties are chained together in reverse order;
12217 add them one by one. */
12218 properties
= nreverse (properties
);
12219 for (; properties
; properties
= TREE_CHAIN (properties
))
12220 objc_add_property_declaration (loc
, copy_node (properties
),
12223 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
12226 while (!prop_attr_list
.is_empty())
12227 delete prop_attr_list
.pop ();
12228 prop_attr_list
.release ();
12229 parser
->error
= false;
12232 /* Parse an Objective-C @synthesize declaration. The syntax is:
12234 objc-synthesize-declaration:
12235 @synthesize objc-synthesize-identifier-list ;
12237 objc-synthesize-identifier-list:
12238 objc-synthesize-identifier
12239 objc-synthesize-identifier-list, objc-synthesize-identifier
12241 objc-synthesize-identifier
12243 identifier = identifier
12246 @synthesize MyProperty;
12247 @synthesize OneProperty, AnotherProperty=MyIvar, YetAnotherProperty;
12249 PS: This function is identical to cp_parser_objc_at_synthesize_declaration
12250 for C++. Keep them in sync.
12253 c_parser_objc_at_synthesize_declaration (c_parser
*parser
)
12255 tree list
= NULL_TREE
;
12257 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_SYNTHESIZE
));
12258 loc
= c_parser_peek_token (parser
)->location
;
12260 c_parser_consume_token (parser
);
12263 tree property
, ivar
;
12264 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
12266 c_parser_error (parser
, "expected identifier");
12267 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
12268 /* Once we find the semicolon, we can resume normal parsing.
12269 We have to reset parser->error manually because
12270 c_parser_skip_until_found() won't reset it for us if the
12271 next token is precisely a semicolon. */
12272 parser
->error
= false;
12275 property
= c_parser_peek_token (parser
)->value
;
12276 c_parser_consume_token (parser
);
12277 if (c_parser_next_token_is (parser
, CPP_EQ
))
12279 c_parser_consume_token (parser
);
12280 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
12282 c_parser_error (parser
, "expected identifier");
12283 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
12284 parser
->error
= false;
12287 ivar
= c_parser_peek_token (parser
)->value
;
12288 c_parser_consume_token (parser
);
12292 list
= chainon (list
, build_tree_list (ivar
, property
));
12293 if (c_parser_next_token_is (parser
, CPP_COMMA
))
12294 c_parser_consume_token (parser
);
12298 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
12299 objc_add_synthesize_declaration (loc
, list
);
12302 /* Parse an Objective-C @dynamic declaration. The syntax is:
12304 objc-dynamic-declaration:
12305 @dynamic identifier-list ;
12308 @dynamic MyProperty;
12309 @dynamic MyProperty, AnotherProperty;
12311 PS: This function is identical to cp_parser_objc_at_dynamic_declaration
12312 for C++. Keep them in sync.
12315 c_parser_objc_at_dynamic_declaration (c_parser
*parser
)
12317 tree list
= NULL_TREE
;
12319 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_DYNAMIC
));
12320 loc
= c_parser_peek_token (parser
)->location
;
12322 c_parser_consume_token (parser
);
12326 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
12328 c_parser_error (parser
, "expected identifier");
12329 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
12330 parser
->error
= false;
12333 property
= c_parser_peek_token (parser
)->value
;
12334 list
= chainon (list
, build_tree_list (NULL_TREE
, property
));
12335 c_parser_consume_token (parser
);
12336 if (c_parser_next_token_is (parser
, CPP_COMMA
))
12337 c_parser_consume_token (parser
);
12341 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
12342 objc_add_dynamic_declaration (loc
, list
);
12346 /* Parse a pragma GCC ivdep. */
12349 c_parse_pragma_ivdep (c_parser
*parser
)
12351 c_parser_consume_pragma (parser
);
12352 c_parser_skip_to_pragma_eol (parser
);
12356 /* Parse a pragma GCC unroll. */
12358 static unsigned short
12359 c_parser_pragma_unroll (c_parser
*parser
)
12361 unsigned short unroll
;
12362 c_parser_consume_pragma (parser
);
12363 location_t location
= c_parser_peek_token (parser
)->location
;
12364 tree expr
= c_parser_expr_no_commas (parser
, NULL
).value
;
12365 mark_exp_read (expr
);
12366 expr
= c_fully_fold (expr
, false, NULL
);
12367 HOST_WIDE_INT lunroll
= 0;
12368 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr
))
12369 || TREE_CODE (expr
) != INTEGER_CST
12370 || (lunroll
= tree_to_shwi (expr
)) < 0
12371 || lunroll
>= USHRT_MAX
)
12373 error_at (location
, "%<#pragma GCC unroll%> requires an"
12374 " assignment-expression that evaluates to a non-negative"
12375 " integral constant less than %u", USHRT_MAX
);
12380 unroll
= (unsigned short)lunroll
;
12385 c_parser_skip_to_pragma_eol (parser
);
12389 /* Handle pragmas. Some OpenMP pragmas are associated with, and therefore
12390 should be considered, statements. ALLOW_STMT is true if we're within
12391 the context of a function and such pragmas are to be allowed. Returns
12392 true if we actually parsed such a pragma. */
12395 c_parser_pragma (c_parser
*parser
, enum pragma_context context
, bool *if_p
)
12398 const char *construct
= NULL
;
12400 id
= c_parser_peek_token (parser
)->pragma_kind
;
12401 gcc_assert (id
!= PRAGMA_NONE
);
12405 case PRAGMA_OACC_DECLARE
:
12406 c_parser_oacc_declare (parser
);
12409 case PRAGMA_OACC_ENTER_DATA
:
12410 if (context
!= pragma_compound
)
12412 construct
= "acc enter data";
12414 if (context
== pragma_stmt
)
12416 error_at (c_parser_peek_token (parser
)->location
,
12417 "%<#pragma %s%> may only be used in compound "
12418 "statements", construct
);
12419 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
12424 c_parser_oacc_enter_exit_data (parser
, true);
12427 case PRAGMA_OACC_EXIT_DATA
:
12428 if (context
!= pragma_compound
)
12430 construct
= "acc exit data";
12433 c_parser_oacc_enter_exit_data (parser
, false);
12436 case PRAGMA_OACC_ROUTINE
:
12437 if (context
!= pragma_external
)
12439 error_at (c_parser_peek_token (parser
)->location
,
12440 "%<#pragma acc routine%> must be at file scope");
12441 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
12444 c_parser_oacc_routine (parser
, context
);
12447 case PRAGMA_OACC_UPDATE
:
12448 if (context
!= pragma_compound
)
12450 construct
= "acc update";
12453 c_parser_oacc_update (parser
);
12456 case PRAGMA_OMP_BARRIER
:
12457 if (context
!= pragma_compound
)
12459 construct
= "omp barrier";
12462 c_parser_omp_barrier (parser
);
12465 case PRAGMA_OMP_DEPOBJ
:
12466 if (context
!= pragma_compound
)
12468 construct
= "omp depobj";
12471 c_parser_omp_depobj (parser
);
12474 case PRAGMA_OMP_FLUSH
:
12475 if (context
!= pragma_compound
)
12477 construct
= "omp flush";
12480 c_parser_omp_flush (parser
);
12483 case PRAGMA_OMP_TASKWAIT
:
12484 if (context
!= pragma_compound
)
12486 construct
= "omp taskwait";
12489 c_parser_omp_taskwait (parser
);
12492 case PRAGMA_OMP_TASKYIELD
:
12493 if (context
!= pragma_compound
)
12495 construct
= "omp taskyield";
12498 c_parser_omp_taskyield (parser
);
12501 case PRAGMA_OMP_CANCEL
:
12502 if (context
!= pragma_compound
)
12504 construct
= "omp cancel";
12507 c_parser_omp_cancel (parser
);
12510 case PRAGMA_OMP_CANCELLATION_POINT
:
12511 return c_parser_omp_cancellation_point (parser
, context
);
12513 case PRAGMA_OMP_THREADPRIVATE
:
12514 c_parser_omp_threadprivate (parser
);
12517 case PRAGMA_OMP_TARGET
:
12518 return c_parser_omp_target (parser
, context
, if_p
);
12520 case PRAGMA_OMP_END_DECLARE_TARGET
:
12521 c_parser_omp_end_declare_target (parser
);
12524 case PRAGMA_OMP_SCAN
:
12525 error_at (c_parser_peek_token (parser
)->location
,
12526 "%<#pragma omp scan%> may only be used in "
12527 "a loop construct with %<inscan%> %<reduction%> clause");
12528 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
12531 case PRAGMA_OMP_SECTION
:
12532 error_at (c_parser_peek_token (parser
)->location
,
12533 "%<#pragma omp section%> may only be used in "
12534 "%<#pragma omp sections%> construct");
12535 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
12538 case PRAGMA_OMP_DECLARE
:
12539 return c_parser_omp_declare (parser
, context
);
12541 case PRAGMA_OMP_REQUIRES
:
12542 if (context
!= pragma_external
)
12544 error_at (c_parser_peek_token (parser
)->location
,
12545 "%<#pragma omp requires%> may only be used at file scope");
12546 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
12549 c_parser_omp_requires (parser
);
12552 case PRAGMA_OMP_NOTHING
:
12553 c_parser_omp_nothing (parser
);
12556 case PRAGMA_OMP_ERROR
:
12557 return c_parser_omp_error (parser
, context
);
12559 case PRAGMA_OMP_ORDERED
:
12560 return c_parser_omp_ordered (parser
, context
, if_p
);
12564 const bool ivdep
= c_parse_pragma_ivdep (parser
);
12565 unsigned short unroll
;
12566 if (c_parser_peek_token (parser
)->pragma_kind
== PRAGMA_UNROLL
)
12567 unroll
= c_parser_pragma_unroll (parser
);
12570 if (!c_parser_next_token_is_keyword (parser
, RID_FOR
)
12571 && !c_parser_next_token_is_keyword (parser
, RID_WHILE
)
12572 && !c_parser_next_token_is_keyword (parser
, RID_DO
))
12574 c_parser_error (parser
, "for, while or do statement expected");
12577 if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
12578 c_parser_for_statement (parser
, ivdep
, unroll
, if_p
);
12579 else if (c_parser_next_token_is_keyword (parser
, RID_WHILE
))
12580 c_parser_while_statement (parser
, ivdep
, unroll
, if_p
);
12582 c_parser_do_statement (parser
, ivdep
, unroll
);
12586 case PRAGMA_UNROLL
:
12588 unsigned short unroll
= c_parser_pragma_unroll (parser
);
12590 if (c_parser_peek_token (parser
)->pragma_kind
== PRAGMA_IVDEP
)
12591 ivdep
= c_parse_pragma_ivdep (parser
);
12594 if (!c_parser_next_token_is_keyword (parser
, RID_FOR
)
12595 && !c_parser_next_token_is_keyword (parser
, RID_WHILE
)
12596 && !c_parser_next_token_is_keyword (parser
, RID_DO
))
12598 c_parser_error (parser
, "for, while or do statement expected");
12601 if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
12602 c_parser_for_statement (parser
, ivdep
, unroll
, if_p
);
12603 else if (c_parser_next_token_is_keyword (parser
, RID_WHILE
))
12604 c_parser_while_statement (parser
, ivdep
, unroll
, if_p
);
12606 c_parser_do_statement (parser
, ivdep
, unroll
);
12610 case PRAGMA_GCC_PCH_PREPROCESS
:
12611 c_parser_error (parser
, "%<#pragma GCC pch_preprocess%> must be first");
12612 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
12615 case PRAGMA_OACC_WAIT
:
12616 if (context
!= pragma_compound
)
12618 construct
= "acc wait";
12621 /* FALL THROUGH. */
12624 if (id
< PRAGMA_FIRST_EXTERNAL
)
12626 if (context
!= pragma_stmt
&& context
!= pragma_compound
)
12629 c_parser_error (parser
, "expected declaration specifiers");
12630 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
12633 c_parser_omp_construct (parser
, if_p
);
12639 c_parser_consume_pragma (parser
);
12640 c_invoke_pragma_handler (id
);
12642 /* Skip to EOL, but suppress any error message. Those will have been
12643 generated by the handler routine through calling error, as opposed
12644 to calling c_parser_error. */
12645 parser
->error
= true;
12646 c_parser_skip_to_pragma_eol (parser
);
12651 /* The interface the pragma parsers have to the lexer. */
12654 pragma_lex (tree
*value
, location_t
*loc
)
12656 c_token
*tok
= c_parser_peek_token (the_parser
);
12657 enum cpp_ttype ret
= tok
->type
;
12659 *value
= tok
->value
;
12661 *loc
= tok
->location
;
12663 if (ret
== CPP_PRAGMA_EOL
|| ret
== CPP_EOF
)
12665 else if (ret
== CPP_STRING
)
12666 *value
= c_parser_string_literal (the_parser
, false, false).value
;
12669 if (ret
== CPP_KEYWORD
)
12671 c_parser_consume_token (the_parser
);
12678 c_parser_pragma_pch_preprocess (c_parser
*parser
)
12682 parser
->lex_joined_string
= true;
12683 c_parser_consume_pragma (parser
);
12684 if (c_parser_next_token_is (parser
, CPP_STRING
))
12686 name
= c_parser_peek_token (parser
)->value
;
12687 c_parser_consume_token (parser
);
12690 c_parser_error (parser
, "expected string literal");
12691 c_parser_skip_to_pragma_eol (parser
);
12692 parser
->lex_joined_string
= false;
12695 c_common_pch_pragma (parse_in
, TREE_STRING_POINTER (name
));
12698 /* OpenACC and OpenMP parsing routines. */
12700 /* Returns name of the next clause.
12701 If the clause is not recognized PRAGMA_OMP_CLAUSE_NONE is returned and
12702 the token is not consumed. Otherwise appropriate pragma_omp_clause is
12703 returned and the token is consumed. */
12705 static pragma_omp_clause
12706 c_parser_omp_clause_name (c_parser
*parser
)
12708 pragma_omp_clause result
= PRAGMA_OMP_CLAUSE_NONE
;
12710 if (c_parser_next_token_is_keyword (parser
, RID_AUTO
))
12711 result
= PRAGMA_OACC_CLAUSE_AUTO
;
12712 else if (c_parser_next_token_is_keyword (parser
, RID_IF
))
12713 result
= PRAGMA_OMP_CLAUSE_IF
;
12714 else if (c_parser_next_token_is_keyword (parser
, RID_DEFAULT
))
12715 result
= PRAGMA_OMP_CLAUSE_DEFAULT
;
12716 else if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
12717 result
= PRAGMA_OMP_CLAUSE_FOR
;
12718 else if (c_parser_next_token_is (parser
, CPP_NAME
))
12720 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
12725 if (!strcmp ("affinity", p
))
12726 result
= PRAGMA_OMP_CLAUSE_AFFINITY
;
12727 else if (!strcmp ("aligned", p
))
12728 result
= PRAGMA_OMP_CLAUSE_ALIGNED
;
12729 else if (!strcmp ("allocate", p
))
12730 result
= PRAGMA_OMP_CLAUSE_ALLOCATE
;
12731 else if (!strcmp ("async", p
))
12732 result
= PRAGMA_OACC_CLAUSE_ASYNC
;
12733 else if (!strcmp ("attach", p
))
12734 result
= PRAGMA_OACC_CLAUSE_ATTACH
;
12737 if (!strcmp ("bind", p
))
12738 result
= PRAGMA_OMP_CLAUSE_BIND
;
12741 if (!strcmp ("collapse", p
))
12742 result
= PRAGMA_OMP_CLAUSE_COLLAPSE
;
12743 else if (!strcmp ("copy", p
))
12744 result
= PRAGMA_OACC_CLAUSE_COPY
;
12745 else if (!strcmp ("copyin", p
))
12746 result
= PRAGMA_OMP_CLAUSE_COPYIN
;
12747 else if (!strcmp ("copyout", p
))
12748 result
= PRAGMA_OACC_CLAUSE_COPYOUT
;
12749 else if (!strcmp ("copyprivate", p
))
12750 result
= PRAGMA_OMP_CLAUSE_COPYPRIVATE
;
12751 else if (!strcmp ("create", p
))
12752 result
= PRAGMA_OACC_CLAUSE_CREATE
;
12755 if (!strcmp ("defaultmap", p
))
12756 result
= PRAGMA_OMP_CLAUSE_DEFAULTMAP
;
12757 else if (!strcmp ("delete", p
))
12758 result
= PRAGMA_OACC_CLAUSE_DELETE
;
12759 else if (!strcmp ("depend", p
))
12760 result
= PRAGMA_OMP_CLAUSE_DEPEND
;
12761 else if (!strcmp ("detach", p
))
12762 result
= PRAGMA_OACC_CLAUSE_DETACH
;
12763 else if (!strcmp ("device", p
))
12764 result
= PRAGMA_OMP_CLAUSE_DEVICE
;
12765 else if (!strcmp ("deviceptr", p
))
12766 result
= PRAGMA_OACC_CLAUSE_DEVICEPTR
;
12767 else if (!strcmp ("device_resident", p
))
12768 result
= PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT
;
12769 else if (!strcmp ("device_type", p
))
12770 result
= PRAGMA_OMP_CLAUSE_DEVICE_TYPE
;
12771 else if (!strcmp ("dist_schedule", p
))
12772 result
= PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
;
12775 if (!strcmp ("enter", p
))
12776 result
= PRAGMA_OMP_CLAUSE_ENTER
;
12779 if (!strcmp ("filter", p
))
12780 result
= PRAGMA_OMP_CLAUSE_FILTER
;
12781 else if (!strcmp ("final", p
))
12782 result
= PRAGMA_OMP_CLAUSE_FINAL
;
12783 else if (!strcmp ("finalize", p
))
12784 result
= PRAGMA_OACC_CLAUSE_FINALIZE
;
12785 else if (!strcmp ("firstprivate", p
))
12786 result
= PRAGMA_OMP_CLAUSE_FIRSTPRIVATE
;
12787 else if (!strcmp ("from", p
))
12788 result
= PRAGMA_OMP_CLAUSE_FROM
;
12791 if (!strcmp ("gang", p
))
12792 result
= PRAGMA_OACC_CLAUSE_GANG
;
12793 else if (!strcmp ("grainsize", p
))
12794 result
= PRAGMA_OMP_CLAUSE_GRAINSIZE
;
12797 if (!strcmp ("has_device_addr", p
))
12798 result
= PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR
;
12799 else if (!strcmp ("hint", p
))
12800 result
= PRAGMA_OMP_CLAUSE_HINT
;
12801 else if (!strcmp ("host", p
))
12802 result
= PRAGMA_OACC_CLAUSE_HOST
;
12805 if (!strcmp ("if_present", p
))
12806 result
= PRAGMA_OACC_CLAUSE_IF_PRESENT
;
12807 else if (!strcmp ("in_reduction", p
))
12808 result
= PRAGMA_OMP_CLAUSE_IN_REDUCTION
;
12809 else if (!strcmp ("inbranch", p
))
12810 result
= PRAGMA_OMP_CLAUSE_INBRANCH
;
12811 else if (!strcmp ("independent", p
))
12812 result
= PRAGMA_OACC_CLAUSE_INDEPENDENT
;
12813 else if (!strcmp ("is_device_ptr", p
))
12814 result
= PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR
;
12817 if (!strcmp ("lastprivate", p
))
12818 result
= PRAGMA_OMP_CLAUSE_LASTPRIVATE
;
12819 else if (!strcmp ("linear", p
))
12820 result
= PRAGMA_OMP_CLAUSE_LINEAR
;
12821 else if (!strcmp ("link", p
))
12822 result
= PRAGMA_OMP_CLAUSE_LINK
;
12825 if (!strcmp ("map", p
))
12826 result
= PRAGMA_OMP_CLAUSE_MAP
;
12827 else if (!strcmp ("mergeable", p
))
12828 result
= PRAGMA_OMP_CLAUSE_MERGEABLE
;
12831 if (!strcmp ("no_create", p
))
12832 result
= PRAGMA_OACC_CLAUSE_NO_CREATE
;
12833 else if (!strcmp ("nogroup", p
))
12834 result
= PRAGMA_OMP_CLAUSE_NOGROUP
;
12835 else if (!strcmp ("nohost", p
))
12836 result
= PRAGMA_OACC_CLAUSE_NOHOST
;
12837 else if (!strcmp ("nontemporal", p
))
12838 result
= PRAGMA_OMP_CLAUSE_NONTEMPORAL
;
12839 else if (!strcmp ("notinbranch", p
))
12840 result
= PRAGMA_OMP_CLAUSE_NOTINBRANCH
;
12841 else if (!strcmp ("nowait", p
))
12842 result
= PRAGMA_OMP_CLAUSE_NOWAIT
;
12843 else if (!strcmp ("num_gangs", p
))
12844 result
= PRAGMA_OACC_CLAUSE_NUM_GANGS
;
12845 else if (!strcmp ("num_tasks", p
))
12846 result
= PRAGMA_OMP_CLAUSE_NUM_TASKS
;
12847 else if (!strcmp ("num_teams", p
))
12848 result
= PRAGMA_OMP_CLAUSE_NUM_TEAMS
;
12849 else if (!strcmp ("num_threads", p
))
12850 result
= PRAGMA_OMP_CLAUSE_NUM_THREADS
;
12851 else if (!strcmp ("num_workers", p
))
12852 result
= PRAGMA_OACC_CLAUSE_NUM_WORKERS
;
12855 if (!strcmp ("ordered", p
))
12856 result
= PRAGMA_OMP_CLAUSE_ORDERED
;
12857 else if (!strcmp ("order", p
))
12858 result
= PRAGMA_OMP_CLAUSE_ORDER
;
12861 if (!strcmp ("parallel", p
))
12862 result
= PRAGMA_OMP_CLAUSE_PARALLEL
;
12863 else if (!strcmp ("present", p
))
12864 result
= PRAGMA_OACC_CLAUSE_PRESENT
;
12865 /* As of OpenACC 2.5, these are now aliases of the non-present_or
12867 else if (!strcmp ("present_or_copy", p
)
12868 || !strcmp ("pcopy", p
))
12869 result
= PRAGMA_OACC_CLAUSE_COPY
;
12870 else if (!strcmp ("present_or_copyin", p
)
12871 || !strcmp ("pcopyin", p
))
12872 result
= PRAGMA_OACC_CLAUSE_COPYIN
;
12873 else if (!strcmp ("present_or_copyout", p
)
12874 || !strcmp ("pcopyout", p
))
12875 result
= PRAGMA_OACC_CLAUSE_COPYOUT
;
12876 else if (!strcmp ("present_or_create", p
)
12877 || !strcmp ("pcreate", p
))
12878 result
= PRAGMA_OACC_CLAUSE_CREATE
;
12879 else if (!strcmp ("priority", p
))
12880 result
= PRAGMA_OMP_CLAUSE_PRIORITY
;
12881 else if (!strcmp ("private", p
))
12882 result
= PRAGMA_OMP_CLAUSE_PRIVATE
;
12883 else if (!strcmp ("proc_bind", p
))
12884 result
= PRAGMA_OMP_CLAUSE_PROC_BIND
;
12887 if (!strcmp ("reduction", p
))
12888 result
= PRAGMA_OMP_CLAUSE_REDUCTION
;
12891 if (!strcmp ("safelen", p
))
12892 result
= PRAGMA_OMP_CLAUSE_SAFELEN
;
12893 else if (!strcmp ("schedule", p
))
12894 result
= PRAGMA_OMP_CLAUSE_SCHEDULE
;
12895 else if (!strcmp ("sections", p
))
12896 result
= PRAGMA_OMP_CLAUSE_SECTIONS
;
12897 else if (!strcmp ("self", p
)) /* "self" is a synonym for "host". */
12898 result
= PRAGMA_OACC_CLAUSE_HOST
;
12899 else if (!strcmp ("seq", p
))
12900 result
= PRAGMA_OACC_CLAUSE_SEQ
;
12901 else if (!strcmp ("shared", p
))
12902 result
= PRAGMA_OMP_CLAUSE_SHARED
;
12903 else if (!strcmp ("simd", p
))
12904 result
= PRAGMA_OMP_CLAUSE_SIMD
;
12905 else if (!strcmp ("simdlen", p
))
12906 result
= PRAGMA_OMP_CLAUSE_SIMDLEN
;
12909 if (!strcmp ("task_reduction", p
))
12910 result
= PRAGMA_OMP_CLAUSE_TASK_REDUCTION
;
12911 else if (!strcmp ("taskgroup", p
))
12912 result
= PRAGMA_OMP_CLAUSE_TASKGROUP
;
12913 else if (!strcmp ("thread_limit", p
))
12914 result
= PRAGMA_OMP_CLAUSE_THREAD_LIMIT
;
12915 else if (!strcmp ("threads", p
))
12916 result
= PRAGMA_OMP_CLAUSE_THREADS
;
12917 else if (!strcmp ("tile", p
))
12918 result
= PRAGMA_OACC_CLAUSE_TILE
;
12919 else if (!strcmp ("to", p
))
12920 result
= PRAGMA_OMP_CLAUSE_TO
;
12923 if (!strcmp ("uniform", p
))
12924 result
= PRAGMA_OMP_CLAUSE_UNIFORM
;
12925 else if (!strcmp ("untied", p
))
12926 result
= PRAGMA_OMP_CLAUSE_UNTIED
;
12927 else if (!strcmp ("use_device", p
))
12928 result
= PRAGMA_OACC_CLAUSE_USE_DEVICE
;
12929 else if (!strcmp ("use_device_addr", p
))
12930 result
= PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR
;
12931 else if (!strcmp ("use_device_ptr", p
))
12932 result
= PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR
;
12935 if (!strcmp ("vector", p
))
12936 result
= PRAGMA_OACC_CLAUSE_VECTOR
;
12937 else if (!strcmp ("vector_length", p
))
12938 result
= PRAGMA_OACC_CLAUSE_VECTOR_LENGTH
;
12941 if (!strcmp ("wait", p
))
12942 result
= PRAGMA_OACC_CLAUSE_WAIT
;
12943 else if (!strcmp ("worker", p
))
12944 result
= PRAGMA_OACC_CLAUSE_WORKER
;
12949 if (result
!= PRAGMA_OMP_CLAUSE_NONE
)
12950 c_parser_consume_token (parser
);
12955 /* Validate that a clause of the given type does not already exist. */
12958 check_no_duplicate_clause (tree clauses
, enum omp_clause_code code
,
12961 if (tree c
= omp_find_clause (clauses
, code
))
12962 error_at (OMP_CLAUSE_LOCATION (c
), "too many %qs clauses", name
);
12966 Parse wait clause or wait directive parameters. */
12969 c_parser_oacc_wait_list (c_parser
*parser
, location_t clause_loc
, tree list
)
12971 vec
<tree
, va_gc
> *args
;
12974 matching_parens parens
;
12975 if (!parens
.require_open (parser
))
12978 args
= c_parser_expr_list (parser
, false, true, NULL
, NULL
, NULL
, NULL
);
12979 args_tree
= build_tree_list_vec (args
);
12981 for (t
= args_tree
; t
; t
= TREE_CHAIN (t
))
12983 tree targ
= TREE_VALUE (t
);
12985 if (targ
!= error_mark_node
)
12987 if (!INTEGRAL_TYPE_P (TREE_TYPE (targ
)))
12989 c_parser_error (parser
, "expression must be integral");
12990 targ
= error_mark_node
;
12994 tree c
= build_omp_clause (clause_loc
, OMP_CLAUSE_WAIT
);
12996 OMP_CLAUSE_DECL (c
) = targ
;
12997 OMP_CLAUSE_CHAIN (c
) = list
;
13003 release_tree_vector (args
);
13004 parens
.require_close (parser
);
13008 /* OpenACC 2.0, OpenMP 2.5:
13011 variable-list , identifier
13013 If KIND is nonzero, create the appropriate node and install the
13014 decl in OMP_CLAUSE_DECL and add the node to the head of the list.
13015 If KIND is nonzero, CLAUSE_LOC is the location of the clause.
13017 If KIND is zero, create a TREE_LIST with the decl in TREE_PURPOSE;
13018 return the list created.
13020 The optional ALLOW_DEREF argument is true if list items can use the deref
13025 tree low_bound
, length
;
13028 omp_dim (tree lb
, tree len
, location_t lo
, bool nc
)
13029 : low_bound (lb
), length (len
), loc (lo
), no_colon (nc
) {}
13033 c_parser_omp_variable_list (c_parser
*parser
,
13034 location_t clause_loc
,
13035 enum omp_clause_code kind
, tree list
,
13036 bool allow_deref
= false)
13038 auto_vec
<omp_dim
> dims
;
13039 bool array_section_p
;
13040 auto_vec
<c_token
> tokens
;
13041 unsigned int tokens_avail
= 0;
13046 if (kind
== OMP_CLAUSE_DEPEND
|| kind
== OMP_CLAUSE_AFFINITY
)
13048 if (c_parser_next_token_is_not (parser
, CPP_NAME
)
13049 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
13051 struct c_expr expr
;
13052 if (kind
== OMP_CLAUSE_DEPEND
13053 && c_parser_next_token_is_keyword (parser
,
13054 RID_OMP_ALL_MEMORY
)
13055 && (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
13056 || (c_parser_peek_2nd_token (parser
)->type
13057 == CPP_CLOSE_PAREN
)))
13059 expr
.value
= ridpointers
[RID_OMP_ALL_MEMORY
];
13060 c_parser_consume_token (parser
);
13063 expr
= c_parser_expr_no_commas (parser
, NULL
);
13064 if (expr
.value
!= error_mark_node
)
13066 tree u
= build_omp_clause (clause_loc
, kind
);
13067 OMP_CLAUSE_DECL (u
) = expr
.value
;
13068 OMP_CLAUSE_CHAIN (u
) = list
;
13072 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
13075 c_parser_consume_token (parser
);
13080 tokens
.truncate (0);
13081 unsigned int nesting_depth
= 0;
13084 c_token
*token
= c_parser_peek_token (parser
);
13085 switch (token
->type
)
13088 case CPP_PRAGMA_EOL
:
13090 case CPP_OPEN_BRACE
:
13091 case CPP_OPEN_PAREN
:
13092 case CPP_OPEN_SQUARE
:
13095 case CPP_CLOSE_BRACE
:
13096 case CPP_CLOSE_PAREN
:
13097 case CPP_CLOSE_SQUARE
:
13098 if (nesting_depth
-- == 0)
13102 if (nesting_depth
== 0)
13107 tokens
.safe_push (*token
);
13108 c_parser_consume_token (parser
);
13114 /* Make sure nothing tries to read past the end of the tokens. */
13116 memset (&eof_token
, 0, sizeof (eof_token
));
13117 eof_token
.type
= CPP_EOF
;
13118 tokens
.safe_push (eof_token
);
13119 tokens
.safe_push (eof_token
);
13121 tokens_avail
= parser
->tokens_avail
;
13122 gcc_assert (parser
->tokens
== &parser
->tokens_buf
[0]);
13123 parser
->tokens
= tokens
.address ();
13124 parser
->tokens_avail
= tokens
.length ();
13127 tree t
= NULL_TREE
;
13129 if (c_parser_next_token_is (parser
, CPP_NAME
)
13130 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
)
13132 t
= lookup_name (c_parser_peek_token (parser
)->value
);
13134 if (t
== NULL_TREE
)
13136 undeclared_variable (c_parser_peek_token (parser
)->location
,
13137 c_parser_peek_token (parser
)->value
);
13138 t
= error_mark_node
;
13141 c_parser_consume_token (parser
);
13143 else if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
13144 && (c_parser_peek_token (parser
)->keyword
== RID_FUNCTION_NAME
13145 || (c_parser_peek_token (parser
)->keyword
13146 == RID_PRETTY_FUNCTION_NAME
)
13147 || (c_parser_peek_token (parser
)->keyword
13148 == RID_C99_FUNCTION_NAME
)))
13149 t
= c_parser_predefined_identifier (parser
).value
;
13153 c_parser_error (parser
, "expected identifier");
13157 if (t
== error_mark_node
)
13159 else if (kind
!= 0)
13163 case OMP_CLAUSE__CACHE_
:
13164 /* The OpenACC cache directive explicitly only allows "array
13165 elements or subarrays". */
13166 if (c_parser_peek_token (parser
)->type
!= CPP_OPEN_SQUARE
)
13168 c_parser_error (parser
, "expected %<[%>");
13169 t
= error_mark_node
;
13173 case OMP_CLAUSE_MAP
:
13174 case OMP_CLAUSE_FROM
:
13175 case OMP_CLAUSE_TO
:
13176 start_component_ref
:
13177 while (c_parser_next_token_is (parser
, CPP_DOT
)
13179 && c_parser_next_token_is (parser
, CPP_DEREF
)))
13181 location_t op_loc
= c_parser_peek_token (parser
)->location
;
13182 location_t arrow_loc
= UNKNOWN_LOCATION
;
13183 if (c_parser_next_token_is (parser
, CPP_DEREF
))
13187 t_expr
.original_code
= ERROR_MARK
;
13188 t_expr
.original_type
= NULL
;
13189 set_c_expr_source_range (&t_expr
, op_loc
, op_loc
);
13190 t_expr
= convert_lvalue_to_rvalue (op_loc
, t_expr
,
13192 t
= build_indirect_ref (op_loc
, t_expr
.value
, RO_ARROW
);
13193 arrow_loc
= t_expr
.get_location ();
13195 c_parser_consume_token (parser
);
13196 if (!c_parser_next_token_is (parser
, CPP_NAME
))
13198 c_parser_error (parser
, "expected identifier");
13199 t
= error_mark_node
;
13203 c_token
*comp_tok
= c_parser_peek_token (parser
);
13204 tree ident
= comp_tok
->value
;
13205 location_t comp_loc
= comp_tok
->location
;
13206 c_parser_consume_token (parser
);
13207 t
= build_component_ref (op_loc
, t
, ident
, comp_loc
,
13211 case OMP_CLAUSE_AFFINITY
:
13212 case OMP_CLAUSE_DEPEND
:
13213 case OMP_CLAUSE_REDUCTION
:
13214 case OMP_CLAUSE_IN_REDUCTION
:
13215 case OMP_CLAUSE_TASK_REDUCTION
:
13216 case OMP_CLAUSE_HAS_DEVICE_ADDR
:
13217 array_section_p
= false;
13219 while (c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
))
13221 location_t loc
= UNKNOWN_LOCATION
;
13222 tree low_bound
= NULL_TREE
, length
= NULL_TREE
;
13223 bool no_colon
= false;
13225 c_parser_consume_token (parser
);
13226 if (!c_parser_next_token_is (parser
, CPP_COLON
))
13228 location_t expr_loc
13229 = c_parser_peek_token (parser
)->location
;
13230 c_expr expr
= c_parser_expression (parser
);
13231 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
,
13233 low_bound
= expr
.value
;
13236 if (c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
13238 length
= integer_one_node
;
13243 /* Look for `:'. */
13244 if (!c_parser_require (parser
, CPP_COLON
,
13247 t
= error_mark_node
;
13250 array_section_p
= true;
13251 if (!c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
13253 location_t expr_loc
13254 = c_parser_peek_token (parser
)->location
;
13255 c_expr expr
= c_parser_expression (parser
);
13256 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
,
13258 length
= expr
.value
;
13261 /* Look for the closing `]'. */
13262 if (!c_parser_require (parser
, CPP_CLOSE_SQUARE
,
13265 t
= error_mark_node
;
13269 dims
.safe_push (omp_dim (low_bound
, length
, loc
, no_colon
));
13272 if (t
!= error_mark_node
)
13274 if ((kind
== OMP_CLAUSE_MAP
13275 || kind
== OMP_CLAUSE_FROM
13276 || kind
== OMP_CLAUSE_TO
)
13277 && !array_section_p
13278 && (c_parser_next_token_is (parser
, CPP_DOT
)
13280 && c_parser_next_token_is (parser
,
13283 for (unsigned i
= 0; i
< dims
.length (); i
++)
13285 gcc_assert (dims
[i
].length
== integer_one_node
);
13286 t
= build_array_ref (dims
[i
].loc
,
13287 t
, dims
[i
].low_bound
);
13289 goto start_component_ref
;
13292 for (unsigned i
= 0; i
< dims
.length (); i
++)
13293 t
= tree_cons (dims
[i
].low_bound
, dims
[i
].length
, t
);
13296 if ((kind
== OMP_CLAUSE_DEPEND
|| kind
== OMP_CLAUSE_AFFINITY
)
13297 && t
!= error_mark_node
13298 && parser
->tokens_avail
!= 2)
13300 if (array_section_p
)
13302 error_at (c_parser_peek_token (parser
)->location
,
13303 "expected %<)%> or %<,%>");
13304 t
= error_mark_node
;
13308 parser
->tokens
= tokens
.address ();
13309 parser
->tokens_avail
= tokens
.length ();
13311 t
= c_parser_expr_no_commas (parser
, NULL
).value
;
13312 if (t
!= error_mark_node
&& parser
->tokens_avail
!= 2)
13314 error_at (c_parser_peek_token (parser
)->location
,
13315 "expected %<)%> or %<,%>");
13316 t
= error_mark_node
;
13325 if (t
!= error_mark_node
)
13327 tree u
= build_omp_clause (clause_loc
, kind
);
13328 OMP_CLAUSE_DECL (u
) = t
;
13329 OMP_CLAUSE_CHAIN (u
) = list
;
13334 list
= tree_cons (t
, NULL_TREE
, list
);
13336 if (kind
== OMP_CLAUSE_DEPEND
|| kind
== OMP_CLAUSE_AFFINITY
)
13338 parser
->tokens
= &parser
->tokens_buf
[0];
13339 parser
->tokens_avail
= tokens_avail
;
13341 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
13344 c_parser_consume_token (parser
);
13351 /* Similarly, but expect leading and trailing parenthesis. This is a very
13352 common case for OpenACC and OpenMP clauses. The optional ALLOW_DEREF
13353 argument is true if list items can use the deref (->) operator. */
13356 c_parser_omp_var_list_parens (c_parser
*parser
, enum omp_clause_code kind
,
13357 tree list
, bool allow_deref
= false)
13359 /* The clauses location. */
13360 location_t loc
= c_parser_peek_token (parser
)->location
;
13362 matching_parens parens
;
13363 if (parens
.require_open (parser
))
13365 list
= c_parser_omp_variable_list (parser
, loc
, kind
, list
, allow_deref
);
13366 parens
.skip_until_found_close (parser
);
13372 copy ( variable-list )
13373 copyin ( variable-list )
13374 copyout ( variable-list )
13375 create ( variable-list )
13376 delete ( variable-list )
13377 present ( variable-list )
13380 no_create ( variable-list )
13381 attach ( variable-list )
13382 detach ( variable-list ) */
13385 c_parser_oacc_data_clause (c_parser
*parser
, pragma_omp_clause c_kind
,
13388 enum gomp_map_kind kind
;
13391 case PRAGMA_OACC_CLAUSE_ATTACH
:
13392 kind
= GOMP_MAP_ATTACH
;
13394 case PRAGMA_OACC_CLAUSE_COPY
:
13395 kind
= GOMP_MAP_TOFROM
;
13397 case PRAGMA_OACC_CLAUSE_COPYIN
:
13398 kind
= GOMP_MAP_TO
;
13400 case PRAGMA_OACC_CLAUSE_COPYOUT
:
13401 kind
= GOMP_MAP_FROM
;
13403 case PRAGMA_OACC_CLAUSE_CREATE
:
13404 kind
= GOMP_MAP_ALLOC
;
13406 case PRAGMA_OACC_CLAUSE_DELETE
:
13407 kind
= GOMP_MAP_RELEASE
;
13409 case PRAGMA_OACC_CLAUSE_DETACH
:
13410 kind
= GOMP_MAP_DETACH
;
13412 case PRAGMA_OACC_CLAUSE_DEVICE
:
13413 kind
= GOMP_MAP_FORCE_TO
;
13415 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT
:
13416 kind
= GOMP_MAP_DEVICE_RESIDENT
;
13418 case PRAGMA_OACC_CLAUSE_HOST
:
13419 kind
= GOMP_MAP_FORCE_FROM
;
13421 case PRAGMA_OACC_CLAUSE_LINK
:
13422 kind
= GOMP_MAP_LINK
;
13424 case PRAGMA_OACC_CLAUSE_NO_CREATE
:
13425 kind
= GOMP_MAP_IF_PRESENT
;
13427 case PRAGMA_OACC_CLAUSE_PRESENT
:
13428 kind
= GOMP_MAP_FORCE_PRESENT
;
13431 gcc_unreachable ();
13434 nl
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_MAP
, list
, true);
13436 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
13437 OMP_CLAUSE_SET_MAP_KIND (c
, kind
);
13443 deviceptr ( variable-list ) */
13446 c_parser_oacc_data_clause_deviceptr (c_parser
*parser
, tree list
)
13448 location_t loc
= c_parser_peek_token (parser
)->location
;
13451 /* Can't use OMP_CLAUSE_MAP here (that is, can't use the generic
13452 c_parser_oacc_data_clause), as for PRAGMA_OACC_CLAUSE_DEVICEPTR,
13453 variable-list must only allow for pointer variables. */
13454 vars
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ERROR
, NULL
);
13455 for (t
= vars
; t
&& t
; t
= TREE_CHAIN (t
))
13457 tree v
= TREE_PURPOSE (t
);
13459 /* FIXME diagnostics: Ideally we should keep individual
13460 locations for all the variables in the var list to make the
13461 following errors more precise. Perhaps
13462 c_parser_omp_var_list_parens() should construct a list of
13463 locations to go along with the var list. */
13465 if (!VAR_P (v
) && TREE_CODE (v
) != PARM_DECL
)
13466 error_at (loc
, "%qD is not a variable", v
);
13467 else if (TREE_TYPE (v
) == error_mark_node
)
13469 else if (!POINTER_TYPE_P (TREE_TYPE (v
)))
13470 error_at (loc
, "%qD is not a pointer variable", v
);
13472 tree u
= build_omp_clause (loc
, OMP_CLAUSE_MAP
);
13473 OMP_CLAUSE_SET_MAP_KIND (u
, GOMP_MAP_FORCE_DEVICEPTR
);
13474 OMP_CLAUSE_DECL (u
) = v
;
13475 OMP_CLAUSE_CHAIN (u
) = list
;
13482 /* OpenACC 2.0, OpenMP 3.0:
13483 collapse ( constant-expression ) */
13486 c_parser_omp_clause_collapse (c_parser
*parser
, tree list
)
13488 tree c
, num
= error_mark_node
;
13492 check_no_duplicate_clause (list
, OMP_CLAUSE_COLLAPSE
, "collapse");
13493 check_no_duplicate_clause (list
, OMP_CLAUSE_TILE
, "tile");
13495 loc
= c_parser_peek_token (parser
)->location
;
13496 matching_parens parens
;
13497 if (parens
.require_open (parser
))
13499 num
= c_parser_expr_no_commas (parser
, NULL
).value
;
13500 parens
.skip_until_found_close (parser
);
13502 if (num
== error_mark_node
)
13504 mark_exp_read (num
);
13505 num
= c_fully_fold (num
, false, NULL
);
13506 if (!INTEGRAL_TYPE_P (TREE_TYPE (num
))
13507 || !tree_fits_shwi_p (num
)
13508 || (n
= tree_to_shwi (num
)) <= 0
13512 "collapse argument needs positive constant integer expression");
13515 c
= build_omp_clause (loc
, OMP_CLAUSE_COLLAPSE
);
13516 OMP_CLAUSE_COLLAPSE_EXPR (c
) = num
;
13517 OMP_CLAUSE_CHAIN (c
) = list
;
13522 copyin ( variable-list ) */
13525 c_parser_omp_clause_copyin (c_parser
*parser
, tree list
)
13527 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_COPYIN
, list
);
13531 copyprivate ( variable-list ) */
13534 c_parser_omp_clause_copyprivate (c_parser
*parser
, tree list
)
13536 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_COPYPRIVATE
, list
);
13540 default ( none | shared )
13543 default ( private | firstprivate )
13546 default ( none | present ) */
13549 c_parser_omp_clause_default (c_parser
*parser
, tree list
, bool is_oacc
)
13551 enum omp_clause_default_kind kind
= OMP_CLAUSE_DEFAULT_UNSPECIFIED
;
13552 location_t loc
= c_parser_peek_token (parser
)->location
;
13555 matching_parens parens
;
13556 if (!parens
.require_open (parser
))
13558 if (c_parser_next_token_is (parser
, CPP_NAME
))
13560 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
13565 if (strcmp ("none", p
) != 0)
13567 kind
= OMP_CLAUSE_DEFAULT_NONE
;
13573 if (strcmp ("present", p
) != 0)
13575 kind
= OMP_CLAUSE_DEFAULT_PRESENT
;
13579 if (strcmp ("private", p
) != 0)
13581 kind
= OMP_CLAUSE_DEFAULT_PRIVATE
;
13586 if (strcmp ("firstprivate", p
) != 0 || is_oacc
)
13588 kind
= OMP_CLAUSE_DEFAULT_FIRSTPRIVATE
;
13592 if (strcmp ("shared", p
) != 0 || is_oacc
)
13594 kind
= OMP_CLAUSE_DEFAULT_SHARED
;
13601 c_parser_consume_token (parser
);
13607 c_parser_error (parser
, "expected %<none%> or %<present%>");
13609 c_parser_error (parser
, "expected %<none%>, %<shared%>, "
13610 "%<private%> or %<firstprivate%>");
13612 parens
.skip_until_found_close (parser
);
13614 if (kind
== OMP_CLAUSE_DEFAULT_UNSPECIFIED
)
13617 check_no_duplicate_clause (list
, OMP_CLAUSE_DEFAULT
, "default");
13618 c
= build_omp_clause (loc
, OMP_CLAUSE_DEFAULT
);
13619 OMP_CLAUSE_CHAIN (c
) = list
;
13620 OMP_CLAUSE_DEFAULT_KIND (c
) = kind
;
13626 firstprivate ( variable-list ) */
13629 c_parser_omp_clause_firstprivate (c_parser
*parser
, tree list
)
13631 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_FIRSTPRIVATE
, list
);
13635 final ( expression ) */
13638 c_parser_omp_clause_final (c_parser
*parser
, tree list
)
13640 location_t loc
= c_parser_peek_token (parser
)->location
;
13641 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
13643 matching_parens parens
;
13645 if (!parens
.require_open (parser
))
13646 t
= error_mark_node
;
13649 location_t eloc
= c_parser_peek_token (parser
)->location
;
13650 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
13651 t
= convert_lvalue_to_rvalue (eloc
, expr
, true, true).value
;
13652 t
= c_objc_common_truthvalue_conversion (eloc
, t
);
13653 t
= c_fully_fold (t
, false, NULL
);
13654 parens
.skip_until_found_close (parser
);
13657 check_no_duplicate_clause (list
, OMP_CLAUSE_FINAL
, "final");
13659 c
= build_omp_clause (loc
, OMP_CLAUSE_FINAL
);
13660 OMP_CLAUSE_FINAL_EXPR (c
) = t
;
13661 OMP_CLAUSE_CHAIN (c
) = list
;
13665 c_parser_error (parser
, "expected %<(%>");
13670 /* OpenACC, OpenMP 2.5:
13674 if ( directive-name-modifier : expression )
13676 directive-name-modifier:
13677 parallel | task | taskloop | target data | target | target update
13678 | target enter data | target exit data
13681 directive-name-modifier:
13682 ... | simd | cancel */
13685 c_parser_omp_clause_if (c_parser
*parser
, tree list
, bool is_omp
)
13687 location_t location
= c_parser_peek_token (parser
)->location
;
13688 enum tree_code if_modifier
= ERROR_MARK
;
13690 matching_parens parens
;
13691 if (!parens
.require_open (parser
))
13694 if (is_omp
&& c_parser_next_token_is (parser
, CPP_NAME
))
13696 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
13698 if (strcmp (p
, "cancel") == 0)
13699 if_modifier
= VOID_CST
;
13700 else if (strcmp (p
, "parallel") == 0)
13701 if_modifier
= OMP_PARALLEL
;
13702 else if (strcmp (p
, "simd") == 0)
13703 if_modifier
= OMP_SIMD
;
13704 else if (strcmp (p
, "task") == 0)
13705 if_modifier
= OMP_TASK
;
13706 else if (strcmp (p
, "taskloop") == 0)
13707 if_modifier
= OMP_TASKLOOP
;
13708 else if (strcmp (p
, "target") == 0)
13710 if_modifier
= OMP_TARGET
;
13711 if (c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
13713 p
= IDENTIFIER_POINTER (c_parser_peek_2nd_token (parser
)->value
);
13714 if (strcmp ("data", p
) == 0)
13715 if_modifier
= OMP_TARGET_DATA
;
13716 else if (strcmp ("update", p
) == 0)
13717 if_modifier
= OMP_TARGET_UPDATE
;
13718 else if (strcmp ("enter", p
) == 0)
13719 if_modifier
= OMP_TARGET_ENTER_DATA
;
13720 else if (strcmp ("exit", p
) == 0)
13721 if_modifier
= OMP_TARGET_EXIT_DATA
;
13722 if (if_modifier
!= OMP_TARGET
)
13725 c_parser_consume_token (parser
);
13729 location_t loc
= c_parser_peek_2nd_token (parser
)->location
;
13730 error_at (loc
, "expected %<data%>, %<update%>, %<enter%> "
13732 if_modifier
= ERROR_MARK
;
13734 if (if_modifier
== OMP_TARGET_ENTER_DATA
13735 || if_modifier
== OMP_TARGET_EXIT_DATA
)
13737 if (c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
13739 p
= IDENTIFIER_POINTER
13740 (c_parser_peek_2nd_token (parser
)->value
);
13741 if (strcmp ("data", p
) == 0)
13745 c_parser_consume_token (parser
);
13749 = c_parser_peek_2nd_token (parser
)->location
;
13750 error_at (loc
, "expected %<data%>");
13751 if_modifier
= ERROR_MARK
;
13756 if (if_modifier
!= ERROR_MARK
)
13758 if (c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
13760 c_parser_consume_token (parser
);
13761 c_parser_consume_token (parser
);
13767 location_t loc
= c_parser_peek_2nd_token (parser
)->location
;
13768 error_at (loc
, "expected %<:%>");
13770 if_modifier
= ERROR_MARK
;
13775 location_t loc
= c_parser_peek_token (parser
)->location
;
13776 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
13777 expr
= convert_lvalue_to_rvalue (loc
, expr
, true, true);
13778 tree t
= c_objc_common_truthvalue_conversion (loc
, expr
.value
), c
;
13779 t
= c_fully_fold (t
, false, NULL
);
13780 parens
.skip_until_found_close (parser
);
13782 for (c
= list
; c
; c
= OMP_CLAUSE_CHAIN (c
))
13783 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_IF
)
13785 if (if_modifier
!= ERROR_MARK
13786 && OMP_CLAUSE_IF_MODIFIER (c
) == if_modifier
)
13788 const char *p
= NULL
;
13789 switch (if_modifier
)
13791 case VOID_CST
: p
= "cancel"; break;
13792 case OMP_PARALLEL
: p
= "parallel"; break;
13793 case OMP_SIMD
: p
= "simd"; break;
13794 case OMP_TASK
: p
= "task"; break;
13795 case OMP_TASKLOOP
: p
= "taskloop"; break;
13796 case OMP_TARGET_DATA
: p
= "target data"; break;
13797 case OMP_TARGET
: p
= "target"; break;
13798 case OMP_TARGET_UPDATE
: p
= "target update"; break;
13799 case OMP_TARGET_ENTER_DATA
: p
= "target enter data"; break;
13800 case OMP_TARGET_EXIT_DATA
: p
= "target exit data"; break;
13801 default: gcc_unreachable ();
13803 error_at (location
, "too many %<if%> clauses with %qs modifier",
13807 else if (OMP_CLAUSE_IF_MODIFIER (c
) == if_modifier
)
13810 error_at (location
, "too many %<if%> clauses");
13812 error_at (location
, "too many %<if%> clauses without modifier");
13815 else if (if_modifier
== ERROR_MARK
13816 || OMP_CLAUSE_IF_MODIFIER (c
) == ERROR_MARK
)
13818 error_at (location
, "if any %<if%> clause has modifier, then all "
13819 "%<if%> clauses have to use modifier");
13824 c
= build_omp_clause (location
, OMP_CLAUSE_IF
);
13825 OMP_CLAUSE_IF_MODIFIER (c
) = if_modifier
;
13826 OMP_CLAUSE_IF_EXPR (c
) = t
;
13827 OMP_CLAUSE_CHAIN (c
) = list
;
13832 lastprivate ( variable-list )
13835 lastprivate ( [ lastprivate-modifier : ] variable-list ) */
13838 c_parser_omp_clause_lastprivate (c_parser
*parser
, tree list
)
13840 /* The clauses location. */
13841 location_t loc
= c_parser_peek_token (parser
)->location
;
13843 if (c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
13845 bool conditional
= false;
13846 if (c_parser_next_token_is (parser
, CPP_NAME
)
13847 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
13850 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
13851 if (strcmp (p
, "conditional") == 0)
13853 conditional
= true;
13854 c_parser_consume_token (parser
);
13855 c_parser_consume_token (parser
);
13858 tree nlist
= c_parser_omp_variable_list (parser
, loc
,
13859 OMP_CLAUSE_LASTPRIVATE
, list
);
13860 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, "expected %<)%>");
13862 for (tree c
= nlist
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
13863 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
) = 1;
13873 c_parser_omp_clause_mergeable (c_parser
*parser ATTRIBUTE_UNUSED
, tree list
)
13877 /* FIXME: Should we allow duplicates? */
13878 check_no_duplicate_clause (list
, OMP_CLAUSE_MERGEABLE
, "mergeable");
13880 c
= build_omp_clause (c_parser_peek_token (parser
)->location
,
13881 OMP_CLAUSE_MERGEABLE
);
13882 OMP_CLAUSE_CHAIN (c
) = list
;
13891 c_parser_omp_clause_nowait (c_parser
*parser ATTRIBUTE_UNUSED
, tree list
)
13894 location_t loc
= c_parser_peek_token (parser
)->location
;
13896 check_no_duplicate_clause (list
, OMP_CLAUSE_NOWAIT
, "nowait");
13898 c
= build_omp_clause (loc
, OMP_CLAUSE_NOWAIT
);
13899 OMP_CLAUSE_CHAIN (c
) = list
;
13904 num_threads ( expression ) */
13907 c_parser_omp_clause_num_threads (c_parser
*parser
, tree list
)
13909 location_t num_threads_loc
= c_parser_peek_token (parser
)->location
;
13910 matching_parens parens
;
13911 if (parens
.require_open (parser
))
13913 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
13914 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
13915 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
13916 tree c
, t
= expr
.value
;
13917 t
= c_fully_fold (t
, false, NULL
);
13919 parens
.skip_until_found_close (parser
);
13921 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
13923 c_parser_error (parser
, "expected integer expression");
13927 /* Attempt to statically determine when the number isn't positive. */
13928 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
13929 build_int_cst (TREE_TYPE (t
), 0));
13930 protected_set_expr_location (c
, expr_loc
);
13931 if (c
== boolean_true_node
)
13933 warning_at (expr_loc
, 0,
13934 "%<num_threads%> value must be positive");
13935 t
= integer_one_node
;
13938 check_no_duplicate_clause (list
, OMP_CLAUSE_NUM_THREADS
, "num_threads");
13940 c
= build_omp_clause (num_threads_loc
, OMP_CLAUSE_NUM_THREADS
);
13941 OMP_CLAUSE_NUM_THREADS_EXPR (c
) = t
;
13942 OMP_CLAUSE_CHAIN (c
) = list
;
13950 num_tasks ( expression )
13953 num_tasks ( strict : expression ) */
13956 c_parser_omp_clause_num_tasks (c_parser
*parser
, tree list
)
13958 location_t num_tasks_loc
= c_parser_peek_token (parser
)->location
;
13959 matching_parens parens
;
13960 if (parens
.require_open (parser
))
13962 bool strict
= false;
13963 if (c_parser_next_token_is (parser
, CPP_NAME
)
13964 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
13965 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
),
13969 c_parser_consume_token (parser
);
13970 c_parser_consume_token (parser
);
13973 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
13974 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
13975 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
13976 tree c
, t
= expr
.value
;
13977 t
= c_fully_fold (t
, false, NULL
);
13979 parens
.skip_until_found_close (parser
);
13981 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
13983 c_parser_error (parser
, "expected integer expression");
13987 /* Attempt to statically determine when the number isn't positive. */
13988 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
13989 build_int_cst (TREE_TYPE (t
), 0));
13990 if (CAN_HAVE_LOCATION_P (c
))
13991 SET_EXPR_LOCATION (c
, expr_loc
);
13992 if (c
== boolean_true_node
)
13994 warning_at (expr_loc
, 0, "%<num_tasks%> value must be positive");
13995 t
= integer_one_node
;
13998 check_no_duplicate_clause (list
, OMP_CLAUSE_NUM_TASKS
, "num_tasks");
14000 c
= build_omp_clause (num_tasks_loc
, OMP_CLAUSE_NUM_TASKS
);
14001 OMP_CLAUSE_NUM_TASKS_EXPR (c
) = t
;
14002 OMP_CLAUSE_NUM_TASKS_STRICT (c
) = strict
;
14003 OMP_CLAUSE_CHAIN (c
) = list
;
14011 grainsize ( expression )
14014 grainsize ( strict : expression ) */
14017 c_parser_omp_clause_grainsize (c_parser
*parser
, tree list
)
14019 location_t grainsize_loc
= c_parser_peek_token (parser
)->location
;
14020 matching_parens parens
;
14021 if (parens
.require_open (parser
))
14023 bool strict
= false;
14024 if (c_parser_next_token_is (parser
, CPP_NAME
)
14025 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
14026 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
),
14030 c_parser_consume_token (parser
);
14031 c_parser_consume_token (parser
);
14034 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
14035 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
14036 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
14037 tree c
, t
= expr
.value
;
14038 t
= c_fully_fold (t
, false, NULL
);
14040 parens
.skip_until_found_close (parser
);
14042 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
14044 c_parser_error (parser
, "expected integer expression");
14048 /* Attempt to statically determine when the number isn't positive. */
14049 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
14050 build_int_cst (TREE_TYPE (t
), 0));
14051 if (CAN_HAVE_LOCATION_P (c
))
14052 SET_EXPR_LOCATION (c
, expr_loc
);
14053 if (c
== boolean_true_node
)
14055 warning_at (expr_loc
, 0, "%<grainsize%> value must be positive");
14056 t
= integer_one_node
;
14059 check_no_duplicate_clause (list
, OMP_CLAUSE_GRAINSIZE
, "grainsize");
14061 c
= build_omp_clause (grainsize_loc
, OMP_CLAUSE_GRAINSIZE
);
14062 OMP_CLAUSE_GRAINSIZE_EXPR (c
) = t
;
14063 OMP_CLAUSE_GRAINSIZE_STRICT (c
) = strict
;
14064 OMP_CLAUSE_CHAIN (c
) = list
;
14072 priority ( expression ) */
14075 c_parser_omp_clause_priority (c_parser
*parser
, tree list
)
14077 location_t priority_loc
= c_parser_peek_token (parser
)->location
;
14078 matching_parens parens
;
14079 if (parens
.require_open (parser
))
14081 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
14082 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
14083 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
14084 tree c
, t
= expr
.value
;
14085 t
= c_fully_fold (t
, false, NULL
);
14087 parens
.skip_until_found_close (parser
);
14089 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
14091 c_parser_error (parser
, "expected integer expression");
14095 /* Attempt to statically determine when the number isn't
14097 c
= fold_build2_loc (expr_loc
, LT_EXPR
, boolean_type_node
, t
,
14098 build_int_cst (TREE_TYPE (t
), 0));
14099 if (CAN_HAVE_LOCATION_P (c
))
14100 SET_EXPR_LOCATION (c
, expr_loc
);
14101 if (c
== boolean_true_node
)
14103 warning_at (expr_loc
, 0, "%<priority%> value must be non-negative");
14104 t
= integer_one_node
;
14107 check_no_duplicate_clause (list
, OMP_CLAUSE_PRIORITY
, "priority");
14109 c
= build_omp_clause (priority_loc
, OMP_CLAUSE_PRIORITY
);
14110 OMP_CLAUSE_PRIORITY_EXPR (c
) = t
;
14111 OMP_CLAUSE_CHAIN (c
) = list
;
14119 hint ( expression ) */
14122 c_parser_omp_clause_hint (c_parser
*parser
, tree list
)
14124 location_t hint_loc
= c_parser_peek_token (parser
)->location
;
14125 matching_parens parens
;
14126 if (parens
.require_open (parser
))
14128 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
14129 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
14130 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
14131 tree c
, t
= expr
.value
;
14132 t
= c_fully_fold (t
, false, NULL
);
14133 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
))
14134 || TREE_CODE (t
) != INTEGER_CST
14135 || tree_int_cst_sgn (t
) == -1)
14137 c_parser_error (parser
, "expected constant integer expression "
14138 "with valid sync-hint value");
14141 parens
.skip_until_found_close (parser
);
14142 check_no_duplicate_clause (list
, OMP_CLAUSE_HINT
, "hint");
14144 c
= build_omp_clause (hint_loc
, OMP_CLAUSE_HINT
);
14145 OMP_CLAUSE_HINT_EXPR (c
) = t
;
14146 OMP_CLAUSE_CHAIN (c
) = list
;
14154 filter ( integer-expression ) */
14157 c_parser_omp_clause_filter (c_parser
*parser
, tree list
)
14159 location_t hint_loc
= c_parser_peek_token (parser
)->location
;
14160 matching_parens parens
;
14161 if (parens
.require_open (parser
))
14163 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
14164 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
14165 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
14166 tree c
, t
= expr
.value
;
14167 t
= c_fully_fold (t
, false, NULL
);
14168 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
14170 c_parser_error (parser
, "expected integer expression");
14173 parens
.skip_until_found_close (parser
);
14174 check_no_duplicate_clause (list
, OMP_CLAUSE_FILTER
, "filter");
14176 c
= build_omp_clause (hint_loc
, OMP_CLAUSE_FILTER
);
14177 OMP_CLAUSE_FILTER_EXPR (c
) = t
;
14178 OMP_CLAUSE_CHAIN (c
) = list
;
14186 defaultmap ( tofrom : scalar )
14189 defaultmap ( implicit-behavior [ : variable-category ] ) */
14192 c_parser_omp_clause_defaultmap (c_parser
*parser
, tree list
)
14194 location_t loc
= c_parser_peek_token (parser
)->location
;
14197 enum omp_clause_defaultmap_kind behavior
= OMP_CLAUSE_DEFAULTMAP_DEFAULT
;
14198 enum omp_clause_defaultmap_kind category
14199 = OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
;
14201 matching_parens parens
;
14202 if (!parens
.require_open (parser
))
14204 if (c_parser_next_token_is_keyword (parser
, RID_DEFAULT
))
14206 else if (!c_parser_next_token_is (parser
, CPP_NAME
))
14209 c_parser_error (parser
, "expected %<alloc%>, %<to%>, %<from%>, "
14210 "%<tofrom%>, %<firstprivate%>, %<none%> "
14215 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
14220 if (strcmp ("alloc", p
) == 0)
14221 behavior
= OMP_CLAUSE_DEFAULTMAP_ALLOC
;
14223 goto invalid_behavior
;
14227 if (strcmp ("default", p
) == 0)
14228 behavior
= OMP_CLAUSE_DEFAULTMAP_DEFAULT
;
14230 goto invalid_behavior
;
14234 if (strcmp ("firstprivate", p
) == 0)
14235 behavior
= OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE
;
14236 else if (strcmp ("from", p
) == 0)
14237 behavior
= OMP_CLAUSE_DEFAULTMAP_FROM
;
14239 goto invalid_behavior
;
14243 if (strcmp ("none", p
) == 0)
14244 behavior
= OMP_CLAUSE_DEFAULTMAP_NONE
;
14246 goto invalid_behavior
;
14250 if (strcmp ("tofrom", p
) == 0)
14251 behavior
= OMP_CLAUSE_DEFAULTMAP_TOFROM
;
14252 else if (strcmp ("to", p
) == 0)
14253 behavior
= OMP_CLAUSE_DEFAULTMAP_TO
;
14255 goto invalid_behavior
;
14259 goto invalid_behavior
;
14261 c_parser_consume_token (parser
);
14263 if (!c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
14265 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
14267 if (!c_parser_next_token_is (parser
, CPP_NAME
))
14270 c_parser_error (parser
, "expected %<scalar%>, %<aggregate%> or "
14274 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
14278 if (strcmp ("aggregate", p
) == 0)
14279 category
= OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE
;
14281 goto invalid_category
;
14285 if (strcmp ("pointer", p
) == 0)
14286 category
= OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER
;
14288 goto invalid_category
;
14292 if (strcmp ("scalar", p
) == 0)
14293 category
= OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR
;
14295 goto invalid_category
;
14299 goto invalid_category
;
14302 c_parser_consume_token (parser
);
14304 parens
.skip_until_found_close (parser
);
14306 for (c
= list
; c
; c
= OMP_CLAUSE_CHAIN (c
))
14307 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEFAULTMAP
14308 && (category
== OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
14309 || OMP_CLAUSE_DEFAULTMAP_CATEGORY (c
) == category
14310 || (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c
)
14311 == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
)))
14313 enum omp_clause_defaultmap_kind cat
= category
;
14314 location_t loc
= OMP_CLAUSE_LOCATION (c
);
14315 if (cat
== OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
)
14316 cat
= OMP_CLAUSE_DEFAULTMAP_CATEGORY (c
);
14320 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
:
14323 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE
:
14326 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER
:
14329 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR
:
14333 gcc_unreachable ();
14336 error_at (loc
, "too many %<defaultmap%> clauses with %qs category",
14339 error_at (loc
, "too many %<defaultmap%> clauses with unspecified "
14344 c
= build_omp_clause (loc
, OMP_CLAUSE_DEFAULTMAP
);
14345 OMP_CLAUSE_DEFAULTMAP_SET_KIND (c
, behavior
, category
);
14346 OMP_CLAUSE_CHAIN (c
) = list
;
14350 parens
.skip_until_found_close (parser
);
14355 use_device ( variable-list )
14358 use_device_ptr ( variable-list ) */
14361 c_parser_omp_clause_use_device_ptr (c_parser
*parser
, tree list
)
14363 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_USE_DEVICE_PTR
,
14368 use_device_addr ( variable-list ) */
14371 c_parser_omp_clause_use_device_addr (c_parser
*parser
, tree list
)
14373 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_USE_DEVICE_ADDR
,
14378 has_device_addr ( variable-list ) */
14381 c_parser_omp_clause_has_device_addr (c_parser
*parser
, tree list
)
14383 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_HAS_DEVICE_ADDR
,
14388 is_device_ptr ( variable-list ) */
14391 c_parser_omp_clause_is_device_ptr (c_parser
*parser
, tree list
)
14393 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_IS_DEVICE_PTR
, list
);
14397 num_gangs ( expression )
14398 num_workers ( expression )
14399 vector_length ( expression ) */
14402 c_parser_oacc_single_int_clause (c_parser
*parser
, omp_clause_code code
,
14405 location_t loc
= c_parser_peek_token (parser
)->location
;
14407 matching_parens parens
;
14408 if (!parens
.require_open (parser
))
14411 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
14412 c_expr expr
= c_parser_expression (parser
);
14413 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
14414 tree c
, t
= expr
.value
;
14415 t
= c_fully_fold (t
, false, NULL
);
14417 parens
.skip_until_found_close (parser
);
14419 if (t
== error_mark_node
)
14421 else if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
14423 error_at (expr_loc
, "%qs expression must be integral",
14424 omp_clause_code_name
[code
]);
14428 /* Attempt to statically determine when the number isn't positive. */
14429 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
14430 build_int_cst (TREE_TYPE (t
), 0));
14431 protected_set_expr_location (c
, expr_loc
);
14432 if (c
== boolean_true_node
)
14434 warning_at (expr_loc
, 0,
14435 "%qs value must be positive",
14436 omp_clause_code_name
[code
]);
14437 t
= integer_one_node
;
14440 check_no_duplicate_clause (list
, code
, omp_clause_code_name
[code
]);
14442 c
= build_omp_clause (loc
, code
);
14443 OMP_CLAUSE_OPERAND (c
, 0) = t
;
14444 OMP_CLAUSE_CHAIN (c
) = list
;
14450 gang [( gang-arg-list )]
14451 worker [( [num:] int-expr )]
14452 vector [( [length:] int-expr )]
14454 where gang-arg is one of:
14459 and size-expr may be:
14466 c_parser_oacc_shape_clause (c_parser
*parser
, location_t loc
,
14467 omp_clause_code kind
,
14468 const char *str
, tree list
)
14470 const char *id
= "num";
14471 tree ops
[2] = { NULL_TREE
, NULL_TREE
}, c
;
14473 if (kind
== OMP_CLAUSE_VECTOR
)
14476 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
14478 c_parser_consume_token (parser
);
14482 c_token
*next
= c_parser_peek_token (parser
);
14485 /* Gang static argument. */
14486 if (kind
== OMP_CLAUSE_GANG
14487 && c_parser_next_token_is_keyword (parser
, RID_STATIC
))
14489 c_parser_consume_token (parser
);
14491 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
14492 goto cleanup_error
;
14495 if (ops
[idx
] != NULL_TREE
)
14497 c_parser_error (parser
, "too many %<static%> arguments");
14498 goto cleanup_error
;
14501 /* Check for the '*' argument. */
14502 if (c_parser_next_token_is (parser
, CPP_MULT
)
14503 && (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
14504 || c_parser_peek_2nd_token (parser
)->type
14505 == CPP_CLOSE_PAREN
))
14507 c_parser_consume_token (parser
);
14508 ops
[idx
] = integer_minus_one_node
;
14510 if (c_parser_next_token_is (parser
, CPP_COMMA
))
14512 c_parser_consume_token (parser
);
14519 /* Worker num: argument and vector length: arguments. */
14520 else if (c_parser_next_token_is (parser
, CPP_NAME
)
14521 && strcmp (id
, IDENTIFIER_POINTER (next
->value
)) == 0
14522 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
14524 c_parser_consume_token (parser
); /* id */
14525 c_parser_consume_token (parser
); /* ':' */
14528 /* Now collect the actual argument. */
14529 if (ops
[idx
] != NULL_TREE
)
14531 c_parser_error (parser
, "unexpected argument");
14532 goto cleanup_error
;
14535 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
14536 c_expr cexpr
= c_parser_expr_no_commas (parser
, NULL
);
14537 cexpr
= convert_lvalue_to_rvalue (expr_loc
, cexpr
, false, true);
14538 tree expr
= cexpr
.value
;
14539 if (expr
== error_mark_node
)
14540 goto cleanup_error
;
14542 expr
= c_fully_fold (expr
, false, NULL
);
14544 /* Attempt to statically determine when the number isn't a
14545 positive integer. */
14547 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr
)))
14549 c_parser_error (parser
, "expected integer expression");
14553 tree c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, expr
,
14554 build_int_cst (TREE_TYPE (expr
), 0));
14555 if (c
== boolean_true_node
)
14557 warning_at (loc
, 0,
14558 "%qs value must be positive", str
);
14559 expr
= integer_one_node
;
14564 if (kind
== OMP_CLAUSE_GANG
14565 && c_parser_next_token_is (parser
, CPP_COMMA
))
14567 c_parser_consume_token (parser
);
14574 if (!c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
14575 goto cleanup_error
;
14578 check_no_duplicate_clause (list
, kind
, str
);
14580 c
= build_omp_clause (loc
, kind
);
14583 OMP_CLAUSE_OPERAND (c
, 1) = ops
[1];
14585 OMP_CLAUSE_OPERAND (c
, 0) = ops
[0];
14586 OMP_CLAUSE_CHAIN (c
) = list
;
14591 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, 0);
14603 c_parser_oacc_simple_clause (location_t loc
, enum omp_clause_code code
,
14606 check_no_duplicate_clause (list
, code
, omp_clause_code_name
[code
]);
14608 tree c
= build_omp_clause (loc
, code
);
14609 OMP_CLAUSE_CHAIN (c
) = list
;
14615 async [( int-expr )] */
14618 c_parser_oacc_clause_async (c_parser
*parser
, tree list
)
14621 location_t loc
= c_parser_peek_token (parser
)->location
;
14623 t
= build_int_cst (integer_type_node
, GOMP_ASYNC_NOVAL
);
14625 if (c_parser_peek_token (parser
)->type
== CPP_OPEN_PAREN
)
14627 c_parser_consume_token (parser
);
14629 t
= c_parser_expr_no_commas (parser
, NULL
).value
;
14630 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
14631 c_parser_error (parser
, "expected integer expression");
14632 else if (t
== error_mark_node
14633 || !c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
14637 t
= c_fully_fold (t
, false, NULL
);
14639 check_no_duplicate_clause (list
, OMP_CLAUSE_ASYNC
, "async");
14641 c
= build_omp_clause (loc
, OMP_CLAUSE_ASYNC
);
14642 OMP_CLAUSE_ASYNC_EXPR (c
) = t
;
14643 OMP_CLAUSE_CHAIN (c
) = list
;
14650 tile ( size-expr-list ) */
14653 c_parser_oacc_clause_tile (c_parser
*parser
, tree list
)
14655 tree c
, expr
= error_mark_node
;
14657 tree tile
= NULL_TREE
;
14659 check_no_duplicate_clause (list
, OMP_CLAUSE_TILE
, "tile");
14660 check_no_duplicate_clause (list
, OMP_CLAUSE_COLLAPSE
, "collapse");
14662 loc
= c_parser_peek_token (parser
)->location
;
14663 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
14668 if (tile
&& !c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
14671 if (c_parser_next_token_is (parser
, CPP_MULT
)
14672 && (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
14673 || c_parser_peek_2nd_token (parser
)->type
== CPP_CLOSE_PAREN
))
14675 c_parser_consume_token (parser
);
14676 expr
= integer_zero_node
;
14680 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
14681 c_expr cexpr
= c_parser_expr_no_commas (parser
, NULL
);
14682 cexpr
= convert_lvalue_to_rvalue (expr_loc
, cexpr
, false, true);
14683 expr
= cexpr
.value
;
14685 if (expr
== error_mark_node
)
14687 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
14692 expr
= c_fully_fold (expr
, false, NULL
);
14694 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr
))
14695 || !tree_fits_shwi_p (expr
)
14696 || tree_to_shwi (expr
) <= 0)
14698 error_at (expr_loc
, "%<tile%> argument needs positive"
14699 " integral constant");
14700 expr
= integer_zero_node
;
14704 tile
= tree_cons (NULL_TREE
, expr
, tile
);
14706 while (c_parser_next_token_is_not (parser
, CPP_CLOSE_PAREN
));
14708 /* Consume the trailing ')'. */
14709 c_parser_consume_token (parser
);
14711 c
= build_omp_clause (loc
, OMP_CLAUSE_TILE
);
14712 tile
= nreverse (tile
);
14713 OMP_CLAUSE_TILE_LIST (c
) = tile
;
14714 OMP_CLAUSE_CHAIN (c
) = list
;
14719 wait [( int-expr-list )] */
14722 c_parser_oacc_clause_wait (c_parser
*parser
, tree list
)
14724 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
14726 if (c_parser_peek_token (parser
)->type
== CPP_OPEN_PAREN
)
14727 list
= c_parser_oacc_wait_list (parser
, clause_loc
, list
);
14730 tree c
= build_omp_clause (clause_loc
, OMP_CLAUSE_WAIT
);
14732 OMP_CLAUSE_DECL (c
) = build_int_cst (integer_type_node
, GOMP_ASYNC_NOVAL
);
14733 OMP_CLAUSE_CHAIN (c
) = list
;
14742 order ( concurrent )
14745 order ( order-modifier : concurrent )
14752 c_parser_omp_clause_order (c_parser
*parser
, tree list
)
14754 location_t loc
= c_parser_peek_token (parser
)->location
;
14757 bool unconstrained
= false;
14758 bool reproducible
= false;
14760 matching_parens parens
;
14761 if (!parens
.require_open (parser
))
14763 if (c_parser_next_token_is (parser
, CPP_NAME
)
14764 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
14766 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
14767 if (strcmp (p
, "unconstrained") == 0)
14768 unconstrained
= true;
14769 else if (strcmp (p
, "reproducible") == 0)
14770 reproducible
= true;
14773 c_parser_error (parser
, "expected %<reproducible%> or "
14774 "%<unconstrained%>");
14777 c_parser_consume_token (parser
);
14778 c_parser_consume_token (parser
);
14780 if (!c_parser_next_token_is (parser
, CPP_NAME
))
14782 c_parser_error (parser
, "expected %<concurrent%>");
14785 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
14786 if (strcmp (p
, "concurrent") != 0)
14788 c_parser_error (parser
, "expected %<concurrent%>");
14791 c_parser_consume_token (parser
);
14792 parens
.skip_until_found_close (parser
);
14793 check_no_duplicate_clause (list
, OMP_CLAUSE_ORDER
, "order");
14794 c
= build_omp_clause (loc
, OMP_CLAUSE_ORDER
);
14795 OMP_CLAUSE_ORDER_UNCONSTRAINED (c
) = unconstrained
;
14796 OMP_CLAUSE_ORDER_REPRODUCIBLE (c
) = reproducible
;
14797 OMP_CLAUSE_CHAIN (c
) = list
;
14801 parens
.skip_until_found_close (parser
);
14807 bind ( teams | parallel | thread ) */
14810 c_parser_omp_clause_bind (c_parser
*parser
, tree list
)
14812 location_t loc
= c_parser_peek_token (parser
)->location
;
14815 enum omp_clause_bind_kind kind
= OMP_CLAUSE_BIND_THREAD
;
14817 matching_parens parens
;
14818 if (!parens
.require_open (parser
))
14820 if (!c_parser_next_token_is (parser
, CPP_NAME
))
14823 c_parser_error (parser
,
14824 "expected %<teams%>, %<parallel%> or %<thread%>");
14825 parens
.skip_until_found_close (parser
);
14828 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
14829 if (strcmp (p
, "teams") == 0)
14830 kind
= OMP_CLAUSE_BIND_TEAMS
;
14831 else if (strcmp (p
, "parallel") == 0)
14832 kind
= OMP_CLAUSE_BIND_PARALLEL
;
14833 else if (strcmp (p
, "thread") != 0)
14835 c_parser_consume_token (parser
);
14836 parens
.skip_until_found_close (parser
);
14837 /* check_no_duplicate_clause (list, OMP_CLAUSE_BIND, "bind"); */
14838 c
= build_omp_clause (loc
, OMP_CLAUSE_BIND
);
14839 OMP_CLAUSE_BIND_KIND (c
) = kind
;
14840 OMP_CLAUSE_CHAIN (c
) = list
;
14849 ordered ( constant-expression ) */
14852 c_parser_omp_clause_ordered (c_parser
*parser
, tree list
)
14854 check_no_duplicate_clause (list
, OMP_CLAUSE_ORDERED
, "ordered");
14856 tree c
, num
= NULL_TREE
;
14858 location_t loc
= c_parser_peek_token (parser
)->location
;
14859 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
14861 matching_parens parens
;
14862 parens
.consume_open (parser
);
14863 num
= c_parser_expr_no_commas (parser
, NULL
).value
;
14864 parens
.skip_until_found_close (parser
);
14866 if (num
== error_mark_node
)
14870 mark_exp_read (num
);
14871 num
= c_fully_fold (num
, false, NULL
);
14872 if (!INTEGRAL_TYPE_P (TREE_TYPE (num
))
14873 || !tree_fits_shwi_p (num
)
14874 || (n
= tree_to_shwi (num
)) <= 0
14877 error_at (loc
, "ordered argument needs positive "
14878 "constant integer expression");
14882 c
= build_omp_clause (loc
, OMP_CLAUSE_ORDERED
);
14883 OMP_CLAUSE_ORDERED_EXPR (c
) = num
;
14884 OMP_CLAUSE_CHAIN (c
) = list
;
14889 private ( variable-list ) */
14892 c_parser_omp_clause_private (c_parser
*parser
, tree list
)
14894 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_PRIVATE
, list
);
14898 reduction ( reduction-operator : variable-list )
14900 reduction-operator:
14901 One of: + * - & ^ | && ||
14905 reduction-operator:
14906 One of: + * - & ^ | && || max min
14910 reduction-operator:
14911 One of: + * - & ^ | && ||
14915 reduction ( reduction-modifier, reduction-operator : variable-list )
14916 in_reduction ( reduction-operator : variable-list )
14917 task_reduction ( reduction-operator : variable-list ) */
14920 c_parser_omp_clause_reduction (c_parser
*parser
, enum omp_clause_code kind
,
14921 bool is_omp
, tree list
)
14923 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
14924 matching_parens parens
;
14925 if (parens
.require_open (parser
))
14928 bool inscan
= false;
14929 enum tree_code code
= ERROR_MARK
;
14930 tree reduc_id
= NULL_TREE
;
14932 if (kind
== OMP_CLAUSE_REDUCTION
&& is_omp
)
14934 if (c_parser_next_token_is_keyword (parser
, RID_DEFAULT
)
14935 && c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
)
14937 c_parser_consume_token (parser
);
14938 c_parser_consume_token (parser
);
14940 else if (c_parser_next_token_is (parser
, CPP_NAME
)
14941 && c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
)
14944 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
14945 if (strcmp (p
, "task") == 0)
14947 else if (strcmp (p
, "inscan") == 0)
14949 if (task
|| inscan
)
14951 c_parser_consume_token (parser
);
14952 c_parser_consume_token (parser
);
14957 switch (c_parser_peek_token (parser
)->type
)
14969 code
= BIT_AND_EXPR
;
14972 code
= BIT_XOR_EXPR
;
14975 code
= BIT_IOR_EXPR
;
14978 code
= TRUTH_ANDIF_EXPR
;
14981 code
= TRUTH_ORIF_EXPR
;
14986 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
14987 if (strcmp (p
, "min") == 0)
14992 if (strcmp (p
, "max") == 0)
14997 reduc_id
= c_parser_peek_token (parser
)->value
;
15001 c_parser_error (parser
,
15002 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
15003 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
15004 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, 0);
15007 c_parser_consume_token (parser
);
15008 reduc_id
= c_omp_reduction_id (code
, reduc_id
);
15009 if (c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
15013 nl
= c_parser_omp_variable_list (parser
, clause_loc
, kind
, list
);
15014 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
15016 tree d
= OMP_CLAUSE_DECL (c
), type
;
15017 if (TREE_CODE (d
) != TREE_LIST
)
15018 type
= TREE_TYPE (d
);
15023 for (t
= d
; TREE_CODE (t
) == TREE_LIST
; t
= TREE_CHAIN (t
))
15025 type
= TREE_TYPE (t
);
15028 if (TREE_CODE (type
) != POINTER_TYPE
15029 && TREE_CODE (type
) != ARRAY_TYPE
)
15031 type
= TREE_TYPE (type
);
15035 while (TREE_CODE (type
) == ARRAY_TYPE
)
15036 type
= TREE_TYPE (type
);
15037 OMP_CLAUSE_REDUCTION_CODE (c
) = code
;
15039 OMP_CLAUSE_REDUCTION_TASK (c
) = 1;
15041 OMP_CLAUSE_REDUCTION_INSCAN (c
) = 1;
15042 if (code
== ERROR_MARK
15043 || !(INTEGRAL_TYPE_P (type
)
15044 || TREE_CODE (type
) == REAL_TYPE
15045 || TREE_CODE (type
) == COMPLEX_TYPE
))
15046 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
)
15047 = c_omp_reduction_lookup (reduc_id
,
15048 TYPE_MAIN_VARIANT (type
));
15053 parens
.skip_until_found_close (parser
);
15059 schedule ( schedule-kind )
15060 schedule ( schedule-kind , expression )
15063 static | dynamic | guided | runtime | auto
15066 schedule ( schedule-modifier : schedule-kind )
15067 schedule ( schedule-modifier [ , schedule-modifier ] : schedule-kind , expression )
15075 c_parser_omp_clause_schedule (c_parser
*parser
, tree list
)
15078 location_t loc
= c_parser_peek_token (parser
)->location
;
15079 int modifiers
= 0, nmodifiers
= 0;
15081 matching_parens parens
;
15082 if (!parens
.require_open (parser
))
15085 c
= build_omp_clause (loc
, OMP_CLAUSE_SCHEDULE
);
15087 location_t comma
= UNKNOWN_LOCATION
;
15088 while (c_parser_next_token_is (parser
, CPP_NAME
))
15090 tree kind
= c_parser_peek_token (parser
)->value
;
15091 const char *p
= IDENTIFIER_POINTER (kind
);
15092 if (strcmp ("simd", p
) == 0)
15093 OMP_CLAUSE_SCHEDULE_SIMD (c
) = 1;
15094 else if (strcmp ("monotonic", p
) == 0)
15095 modifiers
|= OMP_CLAUSE_SCHEDULE_MONOTONIC
;
15096 else if (strcmp ("nonmonotonic", p
) == 0)
15097 modifiers
|= OMP_CLAUSE_SCHEDULE_NONMONOTONIC
;
15100 comma
= UNKNOWN_LOCATION
;
15101 c_parser_consume_token (parser
);
15102 if (nmodifiers
++ == 0
15103 && c_parser_next_token_is (parser
, CPP_COMMA
))
15105 comma
= c_parser_peek_token (parser
)->location
;
15106 c_parser_consume_token (parser
);
15110 c_parser_require (parser
, CPP_COLON
, "expected %<:%>");
15114 if (comma
!= UNKNOWN_LOCATION
)
15115 error_at (comma
, "expected %<:%>");
15117 if ((modifiers
& (OMP_CLAUSE_SCHEDULE_MONOTONIC
15118 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC
))
15119 == (OMP_CLAUSE_SCHEDULE_MONOTONIC
15120 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC
))
15122 error_at (loc
, "both %<monotonic%> and %<nonmonotonic%> modifiers "
15127 if (c_parser_next_token_is (parser
, CPP_NAME
))
15129 tree kind
= c_parser_peek_token (parser
)->value
;
15130 const char *p
= IDENTIFIER_POINTER (kind
);
15135 if (strcmp ("dynamic", p
) != 0)
15137 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_DYNAMIC
;
15141 if (strcmp ("guided", p
) != 0)
15143 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_GUIDED
;
15147 if (strcmp ("runtime", p
) != 0)
15149 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_RUNTIME
;
15156 else if (c_parser_next_token_is_keyword (parser
, RID_STATIC
))
15157 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_STATIC
;
15158 else if (c_parser_next_token_is_keyword (parser
, RID_AUTO
))
15159 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_AUTO
;
15163 c_parser_consume_token (parser
);
15164 if (c_parser_next_token_is (parser
, CPP_COMMA
))
15167 c_parser_consume_token (parser
);
15169 here
= c_parser_peek_token (parser
)->location
;
15170 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15171 expr
= convert_lvalue_to_rvalue (here
, expr
, false, true);
15173 t
= c_fully_fold (t
, false, NULL
);
15175 if (OMP_CLAUSE_SCHEDULE_KIND (c
) == OMP_CLAUSE_SCHEDULE_RUNTIME
)
15176 error_at (here
, "schedule %<runtime%> does not take "
15177 "a %<chunk_size%> parameter");
15178 else if (OMP_CLAUSE_SCHEDULE_KIND (c
) == OMP_CLAUSE_SCHEDULE_AUTO
)
15180 "schedule %<auto%> does not take "
15181 "a %<chunk_size%> parameter");
15182 else if (TREE_CODE (TREE_TYPE (t
)) == INTEGER_TYPE
)
15184 /* Attempt to statically determine when the number isn't
15186 tree s
= fold_build2_loc (loc
, LE_EXPR
, boolean_type_node
, t
,
15187 build_int_cst (TREE_TYPE (t
), 0));
15188 protected_set_expr_location (s
, loc
);
15189 if (s
== boolean_true_node
)
15191 warning_at (loc
, 0,
15192 "chunk size value must be positive");
15193 t
= integer_one_node
;
15195 OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c
) = t
;
15198 c_parser_error (parser
, "expected integer expression");
15200 parens
.skip_until_found_close (parser
);
15203 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
15204 "expected %<,%> or %<)%>");
15206 OMP_CLAUSE_SCHEDULE_KIND (c
)
15207 = (enum omp_clause_schedule_kind
)
15208 (OMP_CLAUSE_SCHEDULE_KIND (c
) | modifiers
);
15210 check_no_duplicate_clause (list
, OMP_CLAUSE_SCHEDULE
, "schedule");
15211 OMP_CLAUSE_CHAIN (c
) = list
;
15215 c_parser_error (parser
, "invalid schedule kind");
15216 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, 0);
15221 shared ( variable-list ) */
15224 c_parser_omp_clause_shared (c_parser
*parser
, tree list
)
15226 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_SHARED
, list
);
15233 c_parser_omp_clause_untied (c_parser
*parser ATTRIBUTE_UNUSED
, tree list
)
15237 /* FIXME: Should we allow duplicates? */
15238 check_no_duplicate_clause (list
, OMP_CLAUSE_UNTIED
, "untied");
15240 c
= build_omp_clause (c_parser_peek_token (parser
)->location
,
15241 OMP_CLAUSE_UNTIED
);
15242 OMP_CLAUSE_CHAIN (c
) = list
;
15252 c_parser_omp_clause_branch (c_parser
*parser ATTRIBUTE_UNUSED
,
15253 enum omp_clause_code code
, tree list
)
15255 check_no_duplicate_clause (list
, code
, omp_clause_code_name
[code
]);
15257 tree c
= build_omp_clause (c_parser_peek_token (parser
)->location
, code
);
15258 OMP_CLAUSE_CHAIN (c
) = list
;
15270 c_parser_omp_clause_cancelkind (c_parser
*parser ATTRIBUTE_UNUSED
,
15271 enum omp_clause_code code
, tree list
)
15273 tree c
= build_omp_clause (c_parser_peek_token (parser
)->location
, code
);
15274 OMP_CLAUSE_CHAIN (c
) = list
;
15283 c_parser_omp_clause_nogroup (c_parser
*parser ATTRIBUTE_UNUSED
, tree list
)
15285 check_no_duplicate_clause (list
, OMP_CLAUSE_NOGROUP
, "nogroup");
15286 tree c
= build_omp_clause (c_parser_peek_token (parser
)->location
,
15287 OMP_CLAUSE_NOGROUP
);
15288 OMP_CLAUSE_CHAIN (c
) = list
;
15297 c_parser_omp_clause_orderedkind (c_parser
*parser ATTRIBUTE_UNUSED
,
15298 enum omp_clause_code code
, tree list
)
15300 check_no_duplicate_clause (list
, code
, omp_clause_code_name
[code
]);
15301 tree c
= build_omp_clause (c_parser_peek_token (parser
)->location
, code
);
15302 OMP_CLAUSE_CHAIN (c
) = list
;
15307 num_teams ( expression )
15310 num_teams ( expression : expression ) */
15313 c_parser_omp_clause_num_teams (c_parser
*parser
, tree list
)
15315 location_t num_teams_loc
= c_parser_peek_token (parser
)->location
;
15316 matching_parens parens
;
15317 if (parens
.require_open (parser
))
15319 location_t upper_loc
= c_parser_peek_token (parser
)->location
;
15320 location_t lower_loc
= UNKNOWN_LOCATION
;
15321 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15322 expr
= convert_lvalue_to_rvalue (upper_loc
, expr
, false, true);
15323 tree c
, upper
= expr
.value
, lower
= NULL_TREE
;
15324 upper
= c_fully_fold (upper
, false, NULL
);
15326 if (c_parser_next_token_is (parser
, CPP_COLON
))
15328 c_parser_consume_token (parser
);
15329 lower_loc
= upper_loc
;
15331 upper_loc
= c_parser_peek_token (parser
)->location
;
15332 expr
= c_parser_expr_no_commas (parser
, NULL
);
15333 expr
= convert_lvalue_to_rvalue (upper_loc
, expr
, false, true);
15334 upper
= expr
.value
;
15335 upper
= c_fully_fold (upper
, false, NULL
);
15338 parens
.skip_until_found_close (parser
);
15340 if (!INTEGRAL_TYPE_P (TREE_TYPE (upper
))
15341 || (lower
&& !INTEGRAL_TYPE_P (TREE_TYPE (lower
))))
15343 c_parser_error (parser
, "expected integer expression");
15347 /* Attempt to statically determine when the number isn't positive. */
15348 c
= fold_build2_loc (upper_loc
, LE_EXPR
, boolean_type_node
, upper
,
15349 build_int_cst (TREE_TYPE (upper
), 0));
15350 protected_set_expr_location (c
, upper_loc
);
15351 if (c
== boolean_true_node
)
15353 warning_at (upper_loc
, 0, "%<num_teams%> value must be positive");
15354 upper
= integer_one_node
;
15358 c
= fold_build2_loc (lower_loc
, LE_EXPR
, boolean_type_node
, lower
,
15359 build_int_cst (TREE_TYPE (lower
), 0));
15360 protected_set_expr_location (c
, lower_loc
);
15361 if (c
== boolean_true_node
)
15363 warning_at (lower_loc
, 0, "%<num_teams%> value must be positive");
15366 else if (TREE_CODE (lower
) == INTEGER_CST
15367 && TREE_CODE (upper
) == INTEGER_CST
15368 && tree_int_cst_lt (upper
, lower
))
15370 warning_at (lower_loc
, 0, "%<num_teams%> lower bound %qE bigger "
15371 "than upper bound %qE", lower
, upper
);
15376 check_no_duplicate_clause (list
, OMP_CLAUSE_NUM_TEAMS
, "num_teams");
15378 c
= build_omp_clause (num_teams_loc
, OMP_CLAUSE_NUM_TEAMS
);
15379 OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (c
) = upper
;
15380 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c
) = lower
;
15381 OMP_CLAUSE_CHAIN (c
) = list
;
15389 thread_limit ( expression ) */
15392 c_parser_omp_clause_thread_limit (c_parser
*parser
, tree list
)
15394 location_t num_thread_limit_loc
= c_parser_peek_token (parser
)->location
;
15395 matching_parens parens
;
15396 if (parens
.require_open (parser
))
15398 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
15399 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15400 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
15401 tree c
, t
= expr
.value
;
15402 t
= c_fully_fold (t
, false, NULL
);
15404 parens
.skip_until_found_close (parser
);
15406 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
15408 c_parser_error (parser
, "expected integer expression");
15412 /* Attempt to statically determine when the number isn't positive. */
15413 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
15414 build_int_cst (TREE_TYPE (t
), 0));
15415 protected_set_expr_location (c
, expr_loc
);
15416 if (c
== boolean_true_node
)
15418 warning_at (expr_loc
, 0, "%<thread_limit%> value must be positive");
15419 t
= integer_one_node
;
15422 check_no_duplicate_clause (list
, OMP_CLAUSE_THREAD_LIMIT
,
15425 c
= build_omp_clause (num_thread_limit_loc
, OMP_CLAUSE_THREAD_LIMIT
);
15426 OMP_CLAUSE_THREAD_LIMIT_EXPR (c
) = t
;
15427 OMP_CLAUSE_CHAIN (c
) = list
;
15435 aligned ( variable-list )
15436 aligned ( variable-list : constant-expression ) */
15439 c_parser_omp_clause_aligned (c_parser
*parser
, tree list
)
15441 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
15444 matching_parens parens
;
15445 if (!parens
.require_open (parser
))
15448 nl
= c_parser_omp_variable_list (parser
, clause_loc
,
15449 OMP_CLAUSE_ALIGNED
, list
);
15451 if (c_parser_next_token_is (parser
, CPP_COLON
))
15453 c_parser_consume_token (parser
);
15454 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
15455 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15456 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
15457 tree alignment
= expr
.value
;
15458 alignment
= c_fully_fold (alignment
, false, NULL
);
15459 if (TREE_CODE (alignment
) != INTEGER_CST
15460 || !INTEGRAL_TYPE_P (TREE_TYPE (alignment
))
15461 || tree_int_cst_sgn (alignment
) != 1)
15463 error_at (clause_loc
, "%<aligned%> clause alignment expression must "
15464 "be positive constant integer expression");
15465 alignment
= NULL_TREE
;
15468 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
15469 OMP_CLAUSE_ALIGNED_ALIGNMENT (c
) = alignment
;
15472 parens
.skip_until_found_close (parser
);
15477 allocate ( variable-list )
15478 allocate ( expression : variable-list )
15481 allocate ( allocator-modifier : variable-list )
15482 allocate ( allocator-modifier , allocator-modifier : variable-list )
15484 allocator-modifier:
15485 allocator ( expression )
15486 align ( expression ) */
15489 c_parser_omp_clause_allocate (c_parser
*parser
, tree list
)
15491 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
15493 tree allocator
= NULL_TREE
;
15494 tree align
= NULL_TREE
;
15496 matching_parens parens
;
15497 if (!parens
.require_open (parser
))
15500 if ((c_parser_next_token_is_not (parser
, CPP_NAME
)
15501 && c_parser_next_token_is_not (parser
, CPP_KEYWORD
))
15502 || (c_parser_peek_2nd_token (parser
)->type
!= CPP_COMMA
15503 && c_parser_peek_2nd_token (parser
)->type
!= CPP_CLOSE_PAREN
))
15505 bool has_modifiers
= false;
15506 tree orig_type
= NULL_TREE
;
15507 if (c_parser_next_token_is (parser
, CPP_NAME
)
15508 && c_parser_peek_2nd_token (parser
)->type
== CPP_OPEN_PAREN
)
15510 unsigned int n
= 3;
15512 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
15513 if ((strcmp (p
, "allocator") == 0 || strcmp (p
, "align") == 0)
15514 && c_parser_check_balanced_raw_token_sequence (parser
, &n
)
15515 && (c_parser_peek_nth_token_raw (parser
, n
)->type
15516 == CPP_CLOSE_PAREN
))
15518 if (c_parser_peek_nth_token_raw (parser
, n
+ 1)->type
15520 has_modifiers
= true;
15521 else if (c_parser_peek_nth_token_raw (parser
, n
+ 1)->type
15523 && (c_parser_peek_nth_token_raw (parser
, n
+ 2)->type
15525 && (c_parser_peek_nth_token_raw (parser
, n
+ 3)->type
15526 == CPP_OPEN_PAREN
))
15528 c_token
*tok
= c_parser_peek_nth_token_raw (parser
, n
+ 2);
15529 const char *q
= IDENTIFIER_POINTER (tok
->value
);
15531 if ((strcmp (q
, "allocator") == 0
15532 || strcmp (q
, "align") == 0)
15533 && c_parser_check_balanced_raw_token_sequence (parser
,
15535 && (c_parser_peek_nth_token_raw (parser
, n
)->type
15536 == CPP_CLOSE_PAREN
)
15537 && (c_parser_peek_nth_token_raw (parser
, n
+ 1)->type
15539 has_modifiers
= true;
15544 c_parser_consume_token (parser
);
15545 matching_parens parens2
;;
15546 parens2
.require_open (parser
);
15547 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
15548 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15549 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
15550 if (strcmp (p
, "allocator") == 0)
15552 allocator
= expr
.value
;
15553 allocator
= c_fully_fold (allocator
, false, NULL
);
15554 orig_type
= expr
.original_type
15555 ? expr
.original_type
: TREE_TYPE (allocator
);
15556 orig_type
= TYPE_MAIN_VARIANT (orig_type
);
15560 align
= expr
.value
;
15561 align
= c_fully_fold (align
, false, NULL
);
15563 parens2
.skip_until_found_close (parser
);
15564 if (c_parser_next_token_is (parser
, CPP_COMMA
))
15566 c_parser_consume_token (parser
);
15567 c_token
*tok
= c_parser_peek_token (parser
);
15568 const char *q
= "";
15569 if (c_parser_next_token_is (parser
, CPP_NAME
))
15570 q
= IDENTIFIER_POINTER (tok
->value
);
15571 if (strcmp (q
, "allocator") != 0 && strcmp (q
, "align") != 0)
15573 c_parser_error (parser
, "expected %<allocator%> or "
15575 parens
.skip_until_found_close (parser
);
15578 else if (strcmp (p
, q
) == 0)
15580 error_at (tok
->location
, "duplicate %qs modifier", p
);
15581 parens
.skip_until_found_close (parser
);
15584 c_parser_consume_token (parser
);
15585 if (!parens2
.require_open (parser
))
15587 parens
.skip_until_found_close (parser
);
15590 expr_loc
= c_parser_peek_token (parser
)->location
;
15591 expr
= c_parser_expr_no_commas (parser
, NULL
);
15592 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false,
15594 if (strcmp (q
, "allocator") == 0)
15596 allocator
= expr
.value
;
15597 allocator
= c_fully_fold (allocator
, false, NULL
);
15598 orig_type
= expr
.original_type
15599 ? expr
.original_type
: TREE_TYPE (allocator
);
15600 orig_type
= TYPE_MAIN_VARIANT (orig_type
);
15604 align
= expr
.value
;
15605 align
= c_fully_fold (align
, false, NULL
);
15607 parens2
.skip_until_found_close (parser
);
15611 if (!has_modifiers
)
15613 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
15614 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15615 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
15616 allocator
= expr
.value
;
15617 allocator
= c_fully_fold (allocator
, false, NULL
);
15618 orig_type
= expr
.original_type
15619 ? expr
.original_type
: TREE_TYPE (allocator
);
15620 orig_type
= TYPE_MAIN_VARIANT (orig_type
);
15623 && (!INTEGRAL_TYPE_P (TREE_TYPE (allocator
))
15624 || TREE_CODE (orig_type
) != ENUMERAL_TYPE
15625 || (TYPE_NAME (orig_type
)
15626 != get_identifier ("omp_allocator_handle_t"))))
15628 error_at (clause_loc
, "%<allocate%> clause allocator expression "
15629 "has type %qT rather than "
15630 "%<omp_allocator_handle_t%>",
15631 TREE_TYPE (allocator
));
15632 allocator
= NULL_TREE
;
15635 && (!INTEGRAL_TYPE_P (TREE_TYPE (align
))
15636 || !tree_fits_uhwi_p (align
)
15637 || !integer_pow2p (align
)))
15639 error_at (clause_loc
, "%<allocate%> clause %<align%> modifier "
15640 "argument needs to be positive constant "
15641 "power of two integer expression");
15644 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
15646 parens
.skip_until_found_close (parser
);
15651 nl
= c_parser_omp_variable_list (parser
, clause_loc
,
15652 OMP_CLAUSE_ALLOCATE
, list
);
15654 if (allocator
|| align
)
15655 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
15657 OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
) = allocator
;
15658 OMP_CLAUSE_ALLOCATE_ALIGN (c
) = align
;
15661 parens
.skip_until_found_close (parser
);
15666 linear ( variable-list )
15667 linear ( variable-list : expression )
15670 linear ( modifier ( variable-list ) )
15671 linear ( modifier ( variable-list ) : expression )
15677 linear ( variable-list : modifiers-list )
15681 step ( expression ) */
15684 c_parser_omp_clause_linear (c_parser
*parser
, tree list
)
15686 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
15688 enum omp_clause_linear_kind kind
= OMP_CLAUSE_LINEAR_DEFAULT
;
15689 bool old_linear_modifier
= false;
15691 matching_parens parens
;
15692 if (!parens
.require_open (parser
))
15695 if (c_parser_next_token_is (parser
, CPP_NAME
))
15697 c_token
*tok
= c_parser_peek_token (parser
);
15698 const char *p
= IDENTIFIER_POINTER (tok
->value
);
15699 if (strcmp ("val", p
) == 0)
15700 kind
= OMP_CLAUSE_LINEAR_VAL
;
15701 if (c_parser_peek_2nd_token (parser
)->type
!= CPP_OPEN_PAREN
)
15702 kind
= OMP_CLAUSE_LINEAR_DEFAULT
;
15703 if (kind
!= OMP_CLAUSE_LINEAR_DEFAULT
)
15705 old_linear_modifier
= true;
15706 c_parser_consume_token (parser
);
15707 c_parser_consume_token (parser
);
15711 nl
= c_parser_omp_variable_list (parser
, clause_loc
,
15712 OMP_CLAUSE_LINEAR
, list
);
15714 if (kind
!= OMP_CLAUSE_LINEAR_DEFAULT
)
15715 parens
.skip_until_found_close (parser
);
15717 if (c_parser_next_token_is (parser
, CPP_COLON
))
15719 c_parser_consume_token (parser
);
15720 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
15721 bool has_modifiers
= false;
15722 if (kind
== OMP_CLAUSE_LINEAR_DEFAULT
15723 && c_parser_next_token_is (parser
, CPP_NAME
))
15725 c_token
*tok
= c_parser_peek_token (parser
);
15726 const char *p
= IDENTIFIER_POINTER (tok
->value
);
15727 unsigned int pos
= 0;
15728 if (strcmp ("val", p
) == 0)
15730 else if (strcmp ("step", p
) == 0
15731 && c_parser_peek_2nd_token (parser
)->type
== CPP_OPEN_PAREN
)
15734 if (c_parser_check_balanced_raw_token_sequence (parser
, &pos
)
15735 && (c_parser_peek_nth_token_raw (parser
, pos
)->type
15736 == CPP_CLOSE_PAREN
))
15743 tok
= c_parser_peek_nth_token_raw (parser
, pos
);
15744 if (tok
->type
== CPP_COMMA
|| tok
->type
== CPP_CLOSE_PAREN
)
15745 has_modifiers
= true;
15751 while (c_parser_next_token_is (parser
, CPP_NAME
))
15753 c_token
*tok
= c_parser_peek_token (parser
);
15754 const char *p
= IDENTIFIER_POINTER (tok
->value
);
15755 if (strcmp ("val", p
) == 0)
15757 if (kind
!= OMP_CLAUSE_LINEAR_DEFAULT
)
15758 error_at (tok
->location
, "multiple linear modifiers");
15759 kind
= OMP_CLAUSE_LINEAR_DEFAULT
;
15760 c_parser_consume_token (parser
);
15762 else if (strcmp ("step", p
) == 0)
15764 c_parser_consume_token (parser
);
15765 matching_parens parens2
;
15766 if (parens2
.require_open (parser
))
15769 error_at (tok
->location
,
15770 "multiple %<step%> modifiers");
15771 expr_loc
= c_parser_peek_token (parser
)->location
;
15772 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15773 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false,
15775 step
= c_fully_fold (expr
.value
, false, NULL
);
15776 if (!INTEGRAL_TYPE_P (TREE_TYPE (step
)))
15778 error_at (clause_loc
, "%<linear%> clause step "
15779 "expression must be integral");
15780 step
= integer_one_node
;
15782 parens2
.skip_until_found_close (parser
);
15789 if (c_parser_next_token_is (parser
, CPP_COMMA
))
15791 c_parser_consume_token (parser
);
15797 step
= integer_one_node
;
15801 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15802 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
15803 step
= c_fully_fold (expr
.value
, false, NULL
);
15804 if (!INTEGRAL_TYPE_P (TREE_TYPE (step
)))
15806 error_at (clause_loc
, "%<linear%> clause step expression must "
15808 step
= integer_one_node
;
15814 step
= integer_one_node
;
15816 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
15818 OMP_CLAUSE_LINEAR_STEP (c
) = step
;
15819 OMP_CLAUSE_LINEAR_KIND (c
) = kind
;
15820 OMP_CLAUSE_LINEAR_OLD_LINEAR_MODIFIER (c
) = old_linear_modifier
;
15823 parens
.skip_until_found_close (parser
);
15828 nontemporal ( variable-list ) */
15831 c_parser_omp_clause_nontemporal (c_parser
*parser
, tree list
)
15833 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_NONTEMPORAL
, list
);
15837 safelen ( constant-expression ) */
15840 c_parser_omp_clause_safelen (c_parser
*parser
, tree list
)
15842 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
15845 matching_parens parens
;
15846 if (!parens
.require_open (parser
))
15849 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
15850 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15851 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
15853 t
= c_fully_fold (t
, false, NULL
);
15854 if (TREE_CODE (t
) != INTEGER_CST
15855 || !INTEGRAL_TYPE_P (TREE_TYPE (t
))
15856 || tree_int_cst_sgn (t
) != 1)
15858 error_at (clause_loc
, "%<safelen%> clause expression must "
15859 "be positive constant integer expression");
15863 parens
.skip_until_found_close (parser
);
15864 if (t
== NULL_TREE
|| t
== error_mark_node
)
15867 check_no_duplicate_clause (list
, OMP_CLAUSE_SAFELEN
, "safelen");
15869 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_SAFELEN
);
15870 OMP_CLAUSE_SAFELEN_EXPR (c
) = t
;
15871 OMP_CLAUSE_CHAIN (c
) = list
;
15876 simdlen ( constant-expression ) */
15879 c_parser_omp_clause_simdlen (c_parser
*parser
, tree list
)
15881 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
15884 matching_parens parens
;
15885 if (!parens
.require_open (parser
))
15888 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
15889 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15890 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
15892 t
= c_fully_fold (t
, false, NULL
);
15893 if (TREE_CODE (t
) != INTEGER_CST
15894 || !INTEGRAL_TYPE_P (TREE_TYPE (t
))
15895 || tree_int_cst_sgn (t
) != 1)
15897 error_at (clause_loc
, "%<simdlen%> clause expression must "
15898 "be positive constant integer expression");
15902 parens
.skip_until_found_close (parser
);
15903 if (t
== NULL_TREE
|| t
== error_mark_node
)
15906 check_no_duplicate_clause (list
, OMP_CLAUSE_SIMDLEN
, "simdlen");
15908 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_SIMDLEN
);
15909 OMP_CLAUSE_SIMDLEN_EXPR (c
) = t
;
15910 OMP_CLAUSE_CHAIN (c
) = list
;
15916 identifier [+/- integer]
15917 vec , identifier [+/- integer]
15921 c_parser_omp_clause_depend_sink (c_parser
*parser
, location_t clause_loc
,
15925 if (c_parser_next_token_is_not (parser
, CPP_NAME
)
15926 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
15928 c_parser_error (parser
, "expected identifier");
15932 while (c_parser_next_token_is (parser
, CPP_NAME
)
15933 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
)
15935 tree t
= lookup_name (c_parser_peek_token (parser
)->value
);
15936 tree addend
= NULL
;
15938 if (t
== NULL_TREE
)
15940 undeclared_variable (c_parser_peek_token (parser
)->location
,
15941 c_parser_peek_token (parser
)->value
);
15942 t
= error_mark_node
;
15945 c_parser_consume_token (parser
);
15948 if (c_parser_next_token_is (parser
, CPP_MINUS
))
15950 else if (!c_parser_next_token_is (parser
, CPP_PLUS
))
15952 addend
= integer_zero_node
;
15954 goto add_to_vector
;
15956 c_parser_consume_token (parser
);
15958 if (c_parser_next_token_is_not (parser
, CPP_NUMBER
))
15960 c_parser_error (parser
, "expected integer");
15964 addend
= c_parser_peek_token (parser
)->value
;
15965 if (TREE_CODE (addend
) != INTEGER_CST
)
15967 c_parser_error (parser
, "expected integer");
15970 c_parser_consume_token (parser
);
15973 if (t
!= error_mark_node
)
15975 vec
= tree_cons (addend
, t
, vec
);
15977 OMP_CLAUSE_DEPEND_SINK_NEGATIVE (vec
) = 1;
15980 if (c_parser_next_token_is_not (parser
, CPP_COMMA
)
15981 || c_parser_peek_2nd_token (parser
)->type
!= CPP_NAME
15982 || c_parser_peek_2nd_token (parser
)->id_kind
!= C_ID_ID
)
15985 c_parser_consume_token (parser
);
15988 if (vec
== NULL_TREE
)
15991 tree u
= build_omp_clause (clause_loc
, OMP_CLAUSE_DEPEND
);
15992 OMP_CLAUSE_DEPEND_KIND (u
) = OMP_CLAUSE_DEPEND_SINK
;
15993 OMP_CLAUSE_DECL (u
) = nreverse (vec
);
15994 OMP_CLAUSE_CHAIN (u
) = list
;
15999 iterators ( iterators-definition )
16001 iterators-definition:
16003 iterator-specifier , iterators-definition
16005 iterator-specifier:
16006 identifier = range-specification
16007 iterator-type identifier = range-specification
16009 range-specification:
16011 begin : end : step */
16014 c_parser_omp_iterators (c_parser
*parser
)
16016 tree ret
= NULL_TREE
, *last
= &ret
;
16017 c_parser_consume_token (parser
);
16021 matching_parens parens
;
16022 if (!parens
.require_open (parser
))
16023 return error_mark_node
;
16027 tree iter_type
= NULL_TREE
, type_expr
= NULL_TREE
;
16028 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_id
))
16030 struct c_type_name
*type
= c_parser_type_name (parser
);
16032 iter_type
= groktypename (type
, &type_expr
, NULL
);
16034 if (iter_type
== NULL_TREE
)
16035 iter_type
= integer_type_node
;
16037 location_t loc
= c_parser_peek_token (parser
)->location
;
16038 if (!c_parser_next_token_is (parser
, CPP_NAME
))
16040 c_parser_error (parser
, "expected identifier");
16044 tree id
= c_parser_peek_token (parser
)->value
;
16045 c_parser_consume_token (parser
);
16047 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
16050 location_t eloc
= c_parser_peek_token (parser
)->location
;
16051 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
16052 expr
= convert_lvalue_to_rvalue (eloc
, expr
, true, false);
16053 tree begin
= expr
.value
;
16055 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
16058 eloc
= c_parser_peek_token (parser
)->location
;
16059 expr
= c_parser_expr_no_commas (parser
, NULL
);
16060 expr
= convert_lvalue_to_rvalue (eloc
, expr
, true, false);
16061 tree end
= expr
.value
;
16063 tree step
= integer_one_node
;
16064 if (c_parser_next_token_is (parser
, CPP_COLON
))
16066 c_parser_consume_token (parser
);
16067 eloc
= c_parser_peek_token (parser
)->location
;
16068 expr
= c_parser_expr_no_commas (parser
, NULL
);
16069 expr
= convert_lvalue_to_rvalue (eloc
, expr
, true, false);
16073 tree iter_var
= build_decl (loc
, VAR_DECL
, id
, iter_type
);
16074 DECL_ARTIFICIAL (iter_var
) = 1;
16075 DECL_CONTEXT (iter_var
) = current_function_decl
;
16076 pushdecl (iter_var
);
16078 *last
= make_tree_vec (6);
16079 TREE_VEC_ELT (*last
, 0) = iter_var
;
16080 TREE_VEC_ELT (*last
, 1) = begin
;
16081 TREE_VEC_ELT (*last
, 2) = end
;
16082 TREE_VEC_ELT (*last
, 3) = step
;
16083 last
= &TREE_CHAIN (*last
);
16085 if (c_parser_next_token_is (parser
, CPP_COMMA
))
16087 c_parser_consume_token (parser
);
16094 parens
.skip_until_found_close (parser
);
16095 return ret
? ret
: error_mark_node
;
16099 affinity ( [aff-modifier :] variable-list )
16101 iterator ( iterators-definition ) */
16104 c_parser_omp_clause_affinity (c_parser
*parser
, tree list
)
16106 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
16107 tree nl
, iterators
= NULL_TREE
;
16109 matching_parens parens
;
16110 if (!parens
.require_open (parser
))
16113 if (c_parser_next_token_is (parser
, CPP_NAME
))
16115 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
16116 bool parse_iter
= ((strcmp ("iterator", p
) == 0)
16117 && (c_parser_peek_2nd_token (parser
)->type
16118 == CPP_OPEN_PAREN
));
16122 parse_iter
= (c_parser_check_balanced_raw_token_sequence (parser
, &n
)
16123 && (c_parser_peek_nth_token_raw (parser
, n
)->type
16124 == CPP_CLOSE_PAREN
)
16125 && (c_parser_peek_nth_token_raw (parser
, n
+ 1)->type
16130 iterators
= c_parser_omp_iterators (parser
);
16131 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
16135 parens
.skip_until_found_close (parser
);
16140 nl
= c_parser_omp_variable_list (parser
, clause_loc
, OMP_CLAUSE_AFFINITY
,
16144 tree block
= pop_scope ();
16145 if (iterators
!= error_mark_node
)
16147 TREE_VEC_ELT (iterators
, 5) = block
;
16148 for (tree c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
16149 OMP_CLAUSE_DECL (c
) = build_tree_list (iterators
,
16150 OMP_CLAUSE_DECL (c
));
16154 parens
.skip_until_found_close (parser
);
16160 depend ( depend-kind: variable-list )
16168 depend ( sink : vec )
16171 depend ( depend-modifier , depend-kind: variable-list )
16174 in | out | inout | mutexinoutset | depobj | inoutset
16177 iterator ( iterators-definition ) */
16180 c_parser_omp_clause_depend (c_parser
*parser
, tree list
)
16182 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
16183 enum omp_clause_depend_kind kind
= OMP_CLAUSE_DEPEND_LAST
;
16184 tree nl
, c
, iterators
= NULL_TREE
;
16186 matching_parens parens
;
16187 if (!parens
.require_open (parser
))
16192 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
16195 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
16196 if (strcmp ("iterator", p
) == 0 && iterators
== NULL_TREE
)
16198 iterators
= c_parser_omp_iterators (parser
);
16199 c_parser_require (parser
, CPP_COMMA
, "expected %<,%>");
16202 if (strcmp ("in", p
) == 0)
16203 kind
= OMP_CLAUSE_DEPEND_IN
;
16204 else if (strcmp ("inout", p
) == 0)
16205 kind
= OMP_CLAUSE_DEPEND_INOUT
;
16206 else if (strcmp ("inoutset", p
) == 0)
16207 kind
= OMP_CLAUSE_DEPEND_INOUTSET
;
16208 else if (strcmp ("mutexinoutset", p
) == 0)
16209 kind
= OMP_CLAUSE_DEPEND_MUTEXINOUTSET
;
16210 else if (strcmp ("out", p
) == 0)
16211 kind
= OMP_CLAUSE_DEPEND_OUT
;
16212 else if (strcmp ("depobj", p
) == 0)
16213 kind
= OMP_CLAUSE_DEPEND_DEPOBJ
;
16214 else if (strcmp ("sink", p
) == 0)
16215 kind
= OMP_CLAUSE_DEPEND_SINK
;
16216 else if (strcmp ("source", p
) == 0)
16217 kind
= OMP_CLAUSE_DEPEND_SOURCE
;
16224 c_parser_consume_token (parser
);
16227 && (kind
== OMP_CLAUSE_DEPEND_SOURCE
|| kind
== OMP_CLAUSE_DEPEND_SINK
))
16230 error_at (clause_loc
, "%<iterator%> modifier incompatible with %qs",
16231 kind
== OMP_CLAUSE_DEPEND_SOURCE
? "source" : "sink");
16232 iterators
= NULL_TREE
;
16235 if (kind
== OMP_CLAUSE_DEPEND_SOURCE
)
16237 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_DEPEND
);
16238 OMP_CLAUSE_DEPEND_KIND (c
) = kind
;
16239 OMP_CLAUSE_DECL (c
) = NULL_TREE
;
16240 OMP_CLAUSE_CHAIN (c
) = list
;
16241 parens
.skip_until_found_close (parser
);
16245 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
16248 if (kind
== OMP_CLAUSE_DEPEND_SINK
)
16249 nl
= c_parser_omp_clause_depend_sink (parser
, clause_loc
, list
);
16252 nl
= c_parser_omp_variable_list (parser
, clause_loc
,
16253 OMP_CLAUSE_DEPEND
, list
);
16257 tree block
= pop_scope ();
16258 if (iterators
== error_mark_node
)
16259 iterators
= NULL_TREE
;
16261 TREE_VEC_ELT (iterators
, 5) = block
;
16264 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
16266 OMP_CLAUSE_DEPEND_KIND (c
) = kind
;
16268 OMP_CLAUSE_DECL (c
)
16269 = build_tree_list (iterators
, OMP_CLAUSE_DECL (c
));
16273 parens
.skip_until_found_close (parser
);
16277 c_parser_error (parser
, "invalid depend kind");
16279 parens
.skip_until_found_close (parser
);
16286 map ( map-kind: variable-list )
16287 map ( variable-list )
16290 alloc | to | from | tofrom
16294 alloc | to | from | tofrom | release | delete
16296 map ( always [,] map-kind: variable-list )
16299 map ( [map-type-modifier[,] ...] map-kind: variable-list )
16305 c_parser_omp_clause_map (c_parser
*parser
, tree list
)
16307 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
16308 enum gomp_map_kind kind
= GOMP_MAP_TOFROM
;
16311 matching_parens parens
;
16312 if (!parens
.require_open (parser
))
16316 int map_kind_pos
= 0;
16317 while (c_parser_peek_nth_token_raw (parser
, pos
)->type
== CPP_NAME
)
16319 if (c_parser_peek_nth_token_raw (parser
, pos
+ 1)->type
== CPP_COLON
)
16321 map_kind_pos
= pos
;
16325 if (c_parser_peek_nth_token_raw (parser
, pos
+ 1)->type
== CPP_COMMA
)
16330 int always_modifier
= 0;
16331 int close_modifier
= 0;
16332 for (int pos
= 1; pos
< map_kind_pos
; ++pos
)
16334 c_token
*tok
= c_parser_peek_token (parser
);
16336 if (tok
->type
== CPP_COMMA
)
16338 c_parser_consume_token (parser
);
16342 const char *p
= IDENTIFIER_POINTER (tok
->value
);
16343 if (strcmp ("always", p
) == 0)
16345 if (always_modifier
)
16347 c_parser_error (parser
, "too many %<always%> modifiers");
16348 parens
.skip_until_found_close (parser
);
16353 else if (strcmp ("close", p
) == 0)
16355 if (close_modifier
)
16357 c_parser_error (parser
, "too many %<close%> modifiers");
16358 parens
.skip_until_found_close (parser
);
16365 c_parser_error (parser
, "%<#pragma omp target%> with "
16366 "modifier other than %<always%> or "
16367 "%<close%> on %<map%> clause");
16368 parens
.skip_until_found_close (parser
);
16372 c_parser_consume_token (parser
);
16375 if (c_parser_next_token_is (parser
, CPP_NAME
)
16376 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
16378 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
16379 if (strcmp ("alloc", p
) == 0)
16380 kind
= GOMP_MAP_ALLOC
;
16381 else if (strcmp ("to", p
) == 0)
16382 kind
= always_modifier
? GOMP_MAP_ALWAYS_TO
: GOMP_MAP_TO
;
16383 else if (strcmp ("from", p
) == 0)
16384 kind
= always_modifier
? GOMP_MAP_ALWAYS_FROM
: GOMP_MAP_FROM
;
16385 else if (strcmp ("tofrom", p
) == 0)
16386 kind
= always_modifier
? GOMP_MAP_ALWAYS_TOFROM
: GOMP_MAP_TOFROM
;
16387 else if (strcmp ("release", p
) == 0)
16388 kind
= GOMP_MAP_RELEASE
;
16389 else if (strcmp ("delete", p
) == 0)
16390 kind
= GOMP_MAP_DELETE
;
16393 c_parser_error (parser
, "invalid map kind");
16394 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
16398 c_parser_consume_token (parser
);
16399 c_parser_consume_token (parser
);
16402 nl
= c_parser_omp_variable_list (parser
, clause_loc
, OMP_CLAUSE_MAP
, list
,
16405 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
16406 OMP_CLAUSE_SET_MAP_KIND (c
, kind
);
16408 parens
.skip_until_found_close (parser
);
16413 device ( expression )
16416 device ( [device-modifier :] integer-expression )
16419 ancestor | device_num */
16422 c_parser_omp_clause_device (c_parser
*parser
, tree list
)
16424 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
16425 location_t expr_loc
;
16428 bool ancestor
= false;
16430 matching_parens parens
;
16431 if (!parens
.require_open (parser
))
16434 if (c_parser_next_token_is (parser
, CPP_NAME
)
16435 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
16437 c_token
*tok
= c_parser_peek_token (parser
);
16438 const char *p
= IDENTIFIER_POINTER (tok
->value
);
16439 if (strcmp ("ancestor", p
) == 0)
16441 /* A requires directive with the reverse_offload clause must be
16443 if ((omp_requires_mask
& OMP_REQUIRES_REVERSE_OFFLOAD
) == 0)
16445 error_at (tok
->location
, "%<ancestor%> device modifier not "
16446 "preceded by %<requires%> directive "
16447 "with %<reverse_offload%> clause");
16448 parens
.skip_until_found_close (parser
);
16453 else if (strcmp ("device_num", p
) == 0)
16457 error_at (tok
->location
, "expected %<ancestor%> or %<device_num%>");
16458 parens
.skip_until_found_close (parser
);
16461 c_parser_consume_token (parser
);
16462 c_parser_consume_token (parser
);
16465 expr_loc
= c_parser_peek_token (parser
)->location
;
16466 expr
= c_parser_expr_no_commas (parser
, NULL
);
16467 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
16469 t
= c_fully_fold (t
, false, NULL
);
16471 parens
.skip_until_found_close (parser
);
16473 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
16475 c_parser_error (parser
, "expected integer expression");
16478 if (ancestor
&& TREE_CODE (t
) == INTEGER_CST
&& !integer_onep (t
))
16480 error_at (expr_loc
, "the %<device%> clause expression must evaluate to "
16485 check_no_duplicate_clause (list
, OMP_CLAUSE_DEVICE
, "device");
16487 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_DEVICE
);
16489 OMP_CLAUSE_DEVICE_ID (c
) = t
;
16490 OMP_CLAUSE_CHAIN (c
) = list
;
16491 OMP_CLAUSE_DEVICE_ANCESTOR (c
) = ancestor
;
16498 dist_schedule ( static )
16499 dist_schedule ( static , expression ) */
16502 c_parser_omp_clause_dist_schedule (c_parser
*parser
, tree list
)
16504 tree c
, t
= NULL_TREE
;
16505 location_t loc
= c_parser_peek_token (parser
)->location
;
16507 matching_parens parens
;
16508 if (!parens
.require_open (parser
))
16511 if (!c_parser_next_token_is_keyword (parser
, RID_STATIC
))
16513 c_parser_error (parser
, "invalid dist_schedule kind");
16514 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
16519 c_parser_consume_token (parser
);
16520 if (c_parser_next_token_is (parser
, CPP_COMMA
))
16522 c_parser_consume_token (parser
);
16524 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
16525 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
16526 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
16528 t
= c_fully_fold (t
, false, NULL
);
16529 parens
.skip_until_found_close (parser
);
16532 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
16533 "expected %<,%> or %<)%>");
16535 /* check_no_duplicate_clause (list, OMP_CLAUSE_DIST_SCHEDULE,
16536 "dist_schedule"); */
16537 if (omp_find_clause (list
, OMP_CLAUSE_DIST_SCHEDULE
))
16538 warning_at (loc
, 0, "too many %qs clauses", "dist_schedule");
16539 if (t
== error_mark_node
)
16542 c
= build_omp_clause (loc
, OMP_CLAUSE_DIST_SCHEDULE
);
16543 OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c
) = t
;
16544 OMP_CLAUSE_CHAIN (c
) = list
;
16549 proc_bind ( proc-bind-kind )
16552 primary | master | close | spread
16553 where OpenMP 5.1 added 'primary' and deprecated the alias 'master'. */
16556 c_parser_omp_clause_proc_bind (c_parser
*parser
, tree list
)
16558 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
16559 enum omp_clause_proc_bind_kind kind
;
16562 matching_parens parens
;
16563 if (!parens
.require_open (parser
))
16566 if (c_parser_next_token_is (parser
, CPP_NAME
))
16568 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
16569 if (strcmp ("primary", p
) == 0)
16570 kind
= OMP_CLAUSE_PROC_BIND_PRIMARY
;
16571 else if (strcmp ("master", p
) == 0)
16572 kind
= OMP_CLAUSE_PROC_BIND_MASTER
;
16573 else if (strcmp ("close", p
) == 0)
16574 kind
= OMP_CLAUSE_PROC_BIND_CLOSE
;
16575 else if (strcmp ("spread", p
) == 0)
16576 kind
= OMP_CLAUSE_PROC_BIND_SPREAD
;
16583 check_no_duplicate_clause (list
, OMP_CLAUSE_PROC_BIND
, "proc_bind");
16584 c_parser_consume_token (parser
);
16585 parens
.skip_until_found_close (parser
);
16586 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_PROC_BIND
);
16587 OMP_CLAUSE_PROC_BIND_KIND (c
) = kind
;
16588 OMP_CLAUSE_CHAIN (c
) = list
;
16592 c_parser_error (parser
, "invalid proc_bind kind");
16593 parens
.skip_until_found_close (parser
);
16598 device_type ( host | nohost | any ) */
16601 c_parser_omp_clause_device_type (c_parser
*parser
, tree list
)
16603 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
16604 enum omp_clause_device_type_kind kind
;
16607 matching_parens parens
;
16608 if (!parens
.require_open (parser
))
16611 if (c_parser_next_token_is (parser
, CPP_NAME
))
16613 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
16614 if (strcmp ("host", p
) == 0)
16615 kind
= OMP_CLAUSE_DEVICE_TYPE_HOST
;
16616 else if (strcmp ("nohost", p
) == 0)
16617 kind
= OMP_CLAUSE_DEVICE_TYPE_NOHOST
;
16618 else if (strcmp ("any", p
) == 0)
16619 kind
= OMP_CLAUSE_DEVICE_TYPE_ANY
;
16626 /* check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE_TYPE,
16628 c_parser_consume_token (parser
);
16629 parens
.skip_until_found_close (parser
);
16630 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_DEVICE_TYPE
);
16631 OMP_CLAUSE_DEVICE_TYPE_KIND (c
) = kind
;
16632 OMP_CLAUSE_CHAIN (c
) = list
;
16636 c_parser_error (parser
, "expected %<host%>, %<nohost%> or %<any%>");
16637 parens
.skip_until_found_close (parser
);
16642 to ( variable-list ) */
16645 c_parser_omp_clause_to (c_parser
*parser
, tree list
)
16647 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_TO
, list
, true);
16651 from ( variable-list ) */
16654 c_parser_omp_clause_from (c_parser
*parser
, tree list
)
16656 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_FROM
, list
, true);
16660 uniform ( variable-list ) */
16663 c_parser_omp_clause_uniform (c_parser
*parser
, tree list
)
16665 /* The clauses location. */
16666 location_t loc
= c_parser_peek_token (parser
)->location
;
16668 matching_parens parens
;
16669 if (parens
.require_open (parser
))
16671 list
= c_parser_omp_variable_list (parser
, loc
, OMP_CLAUSE_UNIFORM
,
16673 parens
.skip_until_found_close (parser
);
16679 detach ( event-handle ) */
16682 c_parser_omp_clause_detach (c_parser
*parser
, tree list
)
16684 matching_parens parens
;
16685 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
16687 if (!parens
.require_open (parser
))
16690 if (c_parser_next_token_is_not (parser
, CPP_NAME
)
16691 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
16693 c_parser_error (parser
, "expected identifier");
16694 parens
.skip_until_found_close (parser
);
16698 tree t
= lookup_name (c_parser_peek_token (parser
)->value
);
16699 if (t
== NULL_TREE
)
16701 undeclared_variable (c_parser_peek_token (parser
)->location
,
16702 c_parser_peek_token (parser
)->value
);
16703 parens
.skip_until_found_close (parser
);
16706 c_parser_consume_token (parser
);
16708 tree type
= TYPE_MAIN_VARIANT (TREE_TYPE (t
));
16709 if (!INTEGRAL_TYPE_P (type
)
16710 || TREE_CODE (type
) != ENUMERAL_TYPE
16711 || TYPE_NAME (type
) != get_identifier ("omp_event_handle_t"))
16713 error_at (clause_loc
, "%<detach%> clause event handle "
16714 "has type %qT rather than "
16715 "%<omp_event_handle_t%>",
16717 parens
.skip_until_found_close (parser
);
16721 tree u
= build_omp_clause (clause_loc
, OMP_CLAUSE_DETACH
);
16722 OMP_CLAUSE_DECL (u
) = t
;
16723 OMP_CLAUSE_CHAIN (u
) = list
;
16724 parens
.skip_until_found_close (parser
);
16728 /* Parse all OpenACC clauses. The set clauses allowed by the directive
16729 is a bitmask in MASK. Return the list of clauses found. */
16732 c_parser_oacc_all_clauses (c_parser
*parser
, omp_clause_mask mask
,
16733 const char *where
, bool finish_p
= true)
16735 tree clauses
= NULL
;
16738 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
16741 pragma_omp_clause c_kind
;
16742 const char *c_name
;
16743 tree prev
= clauses
;
16745 if (!first
&& c_parser_next_token_is (parser
, CPP_COMMA
))
16746 c_parser_consume_token (parser
);
16748 here
= c_parser_peek_token (parser
)->location
;
16749 c_kind
= c_parser_omp_clause_name (parser
);
16753 case PRAGMA_OACC_CLAUSE_ASYNC
:
16754 clauses
= c_parser_oacc_clause_async (parser
, clauses
);
16757 case PRAGMA_OACC_CLAUSE_AUTO
:
16758 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_AUTO
,
16762 case PRAGMA_OACC_CLAUSE_ATTACH
:
16763 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16766 case PRAGMA_OACC_CLAUSE_COLLAPSE
:
16767 clauses
= c_parser_omp_clause_collapse (parser
, clauses
);
16768 c_name
= "collapse";
16770 case PRAGMA_OACC_CLAUSE_COPY
:
16771 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16774 case PRAGMA_OACC_CLAUSE_COPYIN
:
16775 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16778 case PRAGMA_OACC_CLAUSE_COPYOUT
:
16779 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16780 c_name
= "copyout";
16782 case PRAGMA_OACC_CLAUSE_CREATE
:
16783 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16786 case PRAGMA_OACC_CLAUSE_DELETE
:
16787 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16790 case PRAGMA_OMP_CLAUSE_DEFAULT
:
16791 clauses
= c_parser_omp_clause_default (parser
, clauses
, true);
16792 c_name
= "default";
16794 case PRAGMA_OACC_CLAUSE_DETACH
:
16795 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16798 case PRAGMA_OACC_CLAUSE_DEVICE
:
16799 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16802 case PRAGMA_OACC_CLAUSE_DEVICEPTR
:
16803 clauses
= c_parser_oacc_data_clause_deviceptr (parser
, clauses
);
16804 c_name
= "deviceptr";
16806 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT
:
16807 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16808 c_name
= "device_resident";
16810 case PRAGMA_OACC_CLAUSE_FINALIZE
:
16811 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_FINALIZE
,
16813 c_name
= "finalize";
16815 case PRAGMA_OACC_CLAUSE_FIRSTPRIVATE
:
16816 clauses
= c_parser_omp_clause_firstprivate (parser
, clauses
);
16817 c_name
= "firstprivate";
16819 case PRAGMA_OACC_CLAUSE_GANG
:
16821 clauses
= c_parser_oacc_shape_clause (parser
, here
, OMP_CLAUSE_GANG
,
16824 case PRAGMA_OACC_CLAUSE_HOST
:
16825 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16828 case PRAGMA_OACC_CLAUSE_IF
:
16829 clauses
= c_parser_omp_clause_if (parser
, clauses
, false);
16832 case PRAGMA_OACC_CLAUSE_IF_PRESENT
:
16833 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_IF_PRESENT
,
16835 c_name
= "if_present";
16837 case PRAGMA_OACC_CLAUSE_INDEPENDENT
:
16838 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_INDEPENDENT
,
16840 c_name
= "independent";
16842 case PRAGMA_OACC_CLAUSE_LINK
:
16843 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16846 case PRAGMA_OACC_CLAUSE_NO_CREATE
:
16847 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16848 c_name
= "no_create";
16850 case PRAGMA_OACC_CLAUSE_NOHOST
:
16851 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_NOHOST
,
16855 case PRAGMA_OACC_CLAUSE_NUM_GANGS
:
16856 clauses
= c_parser_oacc_single_int_clause (parser
,
16857 OMP_CLAUSE_NUM_GANGS
,
16859 c_name
= "num_gangs";
16861 case PRAGMA_OACC_CLAUSE_NUM_WORKERS
:
16862 clauses
= c_parser_oacc_single_int_clause (parser
,
16863 OMP_CLAUSE_NUM_WORKERS
,
16865 c_name
= "num_workers";
16867 case PRAGMA_OACC_CLAUSE_PRESENT
:
16868 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16869 c_name
= "present";
16871 case PRAGMA_OACC_CLAUSE_PRIVATE
:
16872 clauses
= c_parser_omp_clause_private (parser
, clauses
);
16873 c_name
= "private";
16875 case PRAGMA_OACC_CLAUSE_REDUCTION
:
16877 = c_parser_omp_clause_reduction (parser
, OMP_CLAUSE_REDUCTION
,
16879 c_name
= "reduction";
16881 case PRAGMA_OACC_CLAUSE_SEQ
:
16882 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_SEQ
,
16886 case PRAGMA_OACC_CLAUSE_TILE
:
16887 clauses
= c_parser_oacc_clause_tile (parser
, clauses
);
16890 case PRAGMA_OACC_CLAUSE_USE_DEVICE
:
16891 clauses
= c_parser_omp_clause_use_device_ptr (parser
, clauses
);
16892 c_name
= "use_device";
16894 case PRAGMA_OACC_CLAUSE_VECTOR
:
16896 clauses
= c_parser_oacc_shape_clause (parser
, here
, OMP_CLAUSE_VECTOR
,
16899 case PRAGMA_OACC_CLAUSE_VECTOR_LENGTH
:
16900 clauses
= c_parser_oacc_single_int_clause (parser
,
16901 OMP_CLAUSE_VECTOR_LENGTH
,
16903 c_name
= "vector_length";
16905 case PRAGMA_OACC_CLAUSE_WAIT
:
16906 clauses
= c_parser_oacc_clause_wait (parser
, clauses
);
16909 case PRAGMA_OACC_CLAUSE_WORKER
:
16911 clauses
= c_parser_oacc_shape_clause (parser
, here
, OMP_CLAUSE_WORKER
,
16915 c_parser_error (parser
, "expected %<#pragma acc%> clause");
16921 if (((mask
>> c_kind
) & 1) == 0)
16923 /* Remove the invalid clause(s) from the list to avoid
16924 confusing the rest of the compiler. */
16926 error_at (here
, "%qs is not valid for %qs", c_name
, where
);
16931 c_parser_skip_to_pragma_eol (parser
);
16934 return c_finish_omp_clauses (clauses
, C_ORT_ACC
);
16939 /* Parse all OpenMP clauses. The set clauses allowed by the directive
16940 is a bitmask in MASK. Return the list of clauses found.
16941 FINISH_P set if c_finish_omp_clauses should be called.
16942 NESTED non-zero if clauses should be terminated by closing paren instead
16943 of end of pragma. If it is 2, additionally commas are required in between
16947 c_parser_omp_all_clauses (c_parser
*parser
, omp_clause_mask mask
,
16948 const char *where
, bool finish_p
= true,
16951 tree clauses
= NULL
;
16954 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
16957 pragma_omp_clause c_kind
;
16958 const char *c_name
;
16959 tree prev
= clauses
;
16961 if (nested
&& c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
16966 if (c_parser_next_token_is (parser
, CPP_COMMA
))
16967 c_parser_consume_token (parser
);
16968 else if (nested
== 2)
16969 error_at (c_parser_peek_token (parser
)->location
,
16970 "clauses in %<simd%> trait should be separated "
16974 here
= c_parser_peek_token (parser
)->location
;
16975 c_kind
= c_parser_omp_clause_name (parser
);
16979 case PRAGMA_OMP_CLAUSE_BIND
:
16980 clauses
= c_parser_omp_clause_bind (parser
, clauses
);
16983 case PRAGMA_OMP_CLAUSE_COLLAPSE
:
16984 clauses
= c_parser_omp_clause_collapse (parser
, clauses
);
16985 c_name
= "collapse";
16987 case PRAGMA_OMP_CLAUSE_COPYIN
:
16988 clauses
= c_parser_omp_clause_copyin (parser
, clauses
);
16991 case PRAGMA_OMP_CLAUSE_COPYPRIVATE
:
16992 clauses
= c_parser_omp_clause_copyprivate (parser
, clauses
);
16993 c_name
= "copyprivate";
16995 case PRAGMA_OMP_CLAUSE_DEFAULT
:
16996 clauses
= c_parser_omp_clause_default (parser
, clauses
, false);
16997 c_name
= "default";
16999 case PRAGMA_OMP_CLAUSE_DETACH
:
17000 clauses
= c_parser_omp_clause_detach (parser
, clauses
);
17003 case PRAGMA_OMP_CLAUSE_FILTER
:
17004 clauses
= c_parser_omp_clause_filter (parser
, clauses
);
17007 case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE
:
17008 clauses
= c_parser_omp_clause_firstprivate (parser
, clauses
);
17009 c_name
= "firstprivate";
17011 case PRAGMA_OMP_CLAUSE_FINAL
:
17012 clauses
= c_parser_omp_clause_final (parser
, clauses
);
17015 case PRAGMA_OMP_CLAUSE_GRAINSIZE
:
17016 clauses
= c_parser_omp_clause_grainsize (parser
, clauses
);
17017 c_name
= "grainsize";
17019 case PRAGMA_OMP_CLAUSE_HINT
:
17020 clauses
= c_parser_omp_clause_hint (parser
, clauses
);
17023 case PRAGMA_OMP_CLAUSE_DEFAULTMAP
:
17024 clauses
= c_parser_omp_clause_defaultmap (parser
, clauses
);
17025 c_name
= "defaultmap";
17027 case PRAGMA_OMP_CLAUSE_IF
:
17028 clauses
= c_parser_omp_clause_if (parser
, clauses
, true);
17031 case PRAGMA_OMP_CLAUSE_IN_REDUCTION
:
17033 = c_parser_omp_clause_reduction (parser
, OMP_CLAUSE_IN_REDUCTION
,
17035 c_name
= "in_reduction";
17037 case PRAGMA_OMP_CLAUSE_LASTPRIVATE
:
17038 clauses
= c_parser_omp_clause_lastprivate (parser
, clauses
);
17039 c_name
= "lastprivate";
17041 case PRAGMA_OMP_CLAUSE_MERGEABLE
:
17042 clauses
= c_parser_omp_clause_mergeable (parser
, clauses
);
17043 c_name
= "mergeable";
17045 case PRAGMA_OMP_CLAUSE_NOWAIT
:
17046 clauses
= c_parser_omp_clause_nowait (parser
, clauses
);
17049 case PRAGMA_OMP_CLAUSE_NUM_TASKS
:
17050 clauses
= c_parser_omp_clause_num_tasks (parser
, clauses
);
17051 c_name
= "num_tasks";
17053 case PRAGMA_OMP_CLAUSE_NUM_THREADS
:
17054 clauses
= c_parser_omp_clause_num_threads (parser
, clauses
);
17055 c_name
= "num_threads";
17057 case PRAGMA_OMP_CLAUSE_ORDER
:
17058 clauses
= c_parser_omp_clause_order (parser
, clauses
);
17061 case PRAGMA_OMP_CLAUSE_ORDERED
:
17062 clauses
= c_parser_omp_clause_ordered (parser
, clauses
);
17063 c_name
= "ordered";
17065 case PRAGMA_OMP_CLAUSE_PRIORITY
:
17066 clauses
= c_parser_omp_clause_priority (parser
, clauses
);
17067 c_name
= "priority";
17069 case PRAGMA_OMP_CLAUSE_PRIVATE
:
17070 clauses
= c_parser_omp_clause_private (parser
, clauses
);
17071 c_name
= "private";
17073 case PRAGMA_OMP_CLAUSE_REDUCTION
:
17075 = c_parser_omp_clause_reduction (parser
, OMP_CLAUSE_REDUCTION
,
17077 c_name
= "reduction";
17079 case PRAGMA_OMP_CLAUSE_SCHEDULE
:
17080 clauses
= c_parser_omp_clause_schedule (parser
, clauses
);
17081 c_name
= "schedule";
17083 case PRAGMA_OMP_CLAUSE_SHARED
:
17084 clauses
= c_parser_omp_clause_shared (parser
, clauses
);
17087 case PRAGMA_OMP_CLAUSE_TASK_REDUCTION
:
17089 = c_parser_omp_clause_reduction (parser
, OMP_CLAUSE_TASK_REDUCTION
,
17091 c_name
= "task_reduction";
17093 case PRAGMA_OMP_CLAUSE_UNTIED
:
17094 clauses
= c_parser_omp_clause_untied (parser
, clauses
);
17097 case PRAGMA_OMP_CLAUSE_INBRANCH
:
17098 clauses
= c_parser_omp_clause_branch (parser
, OMP_CLAUSE_INBRANCH
,
17100 c_name
= "inbranch";
17102 case PRAGMA_OMP_CLAUSE_NONTEMPORAL
:
17103 clauses
= c_parser_omp_clause_nontemporal (parser
, clauses
);
17104 c_name
= "nontemporal";
17106 case PRAGMA_OMP_CLAUSE_NOTINBRANCH
:
17107 clauses
= c_parser_omp_clause_branch (parser
, OMP_CLAUSE_NOTINBRANCH
,
17109 c_name
= "notinbranch";
17111 case PRAGMA_OMP_CLAUSE_PARALLEL
:
17113 = c_parser_omp_clause_cancelkind (parser
, OMP_CLAUSE_PARALLEL
,
17115 c_name
= "parallel";
17119 error_at (here
, "%qs must be the first clause of %qs",
17124 case PRAGMA_OMP_CLAUSE_FOR
:
17126 = c_parser_omp_clause_cancelkind (parser
, OMP_CLAUSE_FOR
,
17130 goto clause_not_first
;
17132 case PRAGMA_OMP_CLAUSE_SECTIONS
:
17134 = c_parser_omp_clause_cancelkind (parser
, OMP_CLAUSE_SECTIONS
,
17136 c_name
= "sections";
17138 goto clause_not_first
;
17140 case PRAGMA_OMP_CLAUSE_TASKGROUP
:
17142 = c_parser_omp_clause_cancelkind (parser
, OMP_CLAUSE_TASKGROUP
,
17144 c_name
= "taskgroup";
17146 goto clause_not_first
;
17148 case PRAGMA_OMP_CLAUSE_LINK
:
17150 = c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_LINK
, clauses
);
17153 case PRAGMA_OMP_CLAUSE_TO
:
17154 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_LINK
)) != 0)
17156 tree nl
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ENTER
,
17158 for (tree c
= nl
; c
!= clauses
; c
= OMP_CLAUSE_CHAIN (c
))
17159 OMP_CLAUSE_ENTER_TO (c
) = 1;
17163 clauses
= c_parser_omp_clause_to (parser
, clauses
);
17166 case PRAGMA_OMP_CLAUSE_FROM
:
17167 clauses
= c_parser_omp_clause_from (parser
, clauses
);
17170 case PRAGMA_OMP_CLAUSE_UNIFORM
:
17171 clauses
= c_parser_omp_clause_uniform (parser
, clauses
);
17172 c_name
= "uniform";
17174 case PRAGMA_OMP_CLAUSE_NUM_TEAMS
:
17175 clauses
= c_parser_omp_clause_num_teams (parser
, clauses
);
17176 c_name
= "num_teams";
17178 case PRAGMA_OMP_CLAUSE_THREAD_LIMIT
:
17179 clauses
= c_parser_omp_clause_thread_limit (parser
, clauses
);
17180 c_name
= "thread_limit";
17182 case PRAGMA_OMP_CLAUSE_ALIGNED
:
17183 clauses
= c_parser_omp_clause_aligned (parser
, clauses
);
17184 c_name
= "aligned";
17186 case PRAGMA_OMP_CLAUSE_ALLOCATE
:
17187 clauses
= c_parser_omp_clause_allocate (parser
, clauses
);
17188 c_name
= "allocate";
17190 case PRAGMA_OMP_CLAUSE_LINEAR
:
17191 clauses
= c_parser_omp_clause_linear (parser
, clauses
);
17194 case PRAGMA_OMP_CLAUSE_AFFINITY
:
17195 clauses
= c_parser_omp_clause_affinity (parser
, clauses
);
17196 c_name
= "affinity";
17198 case PRAGMA_OMP_CLAUSE_DEPEND
:
17199 clauses
= c_parser_omp_clause_depend (parser
, clauses
);
17202 case PRAGMA_OMP_CLAUSE_MAP
:
17203 clauses
= c_parser_omp_clause_map (parser
, clauses
);
17206 case PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR
:
17207 clauses
= c_parser_omp_clause_use_device_ptr (parser
, clauses
);
17208 c_name
= "use_device_ptr";
17210 case PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR
:
17211 clauses
= c_parser_omp_clause_use_device_addr (parser
, clauses
);
17212 c_name
= "use_device_addr";
17214 case PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR
:
17215 clauses
= c_parser_omp_clause_has_device_addr (parser
, clauses
);
17216 c_name
= "has_device_addr";
17218 case PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR
:
17219 clauses
= c_parser_omp_clause_is_device_ptr (parser
, clauses
);
17220 c_name
= "is_device_ptr";
17222 case PRAGMA_OMP_CLAUSE_DEVICE
:
17223 clauses
= c_parser_omp_clause_device (parser
, clauses
);
17226 case PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
:
17227 clauses
= c_parser_omp_clause_dist_schedule (parser
, clauses
);
17228 c_name
= "dist_schedule";
17230 case PRAGMA_OMP_CLAUSE_PROC_BIND
:
17231 clauses
= c_parser_omp_clause_proc_bind (parser
, clauses
);
17232 c_name
= "proc_bind";
17234 case PRAGMA_OMP_CLAUSE_DEVICE_TYPE
:
17235 clauses
= c_parser_omp_clause_device_type (parser
, clauses
);
17236 c_name
= "device_type";
17238 case PRAGMA_OMP_CLAUSE_SAFELEN
:
17239 clauses
= c_parser_omp_clause_safelen (parser
, clauses
);
17240 c_name
= "safelen";
17242 case PRAGMA_OMP_CLAUSE_SIMDLEN
:
17243 clauses
= c_parser_omp_clause_simdlen (parser
, clauses
);
17244 c_name
= "simdlen";
17246 case PRAGMA_OMP_CLAUSE_NOGROUP
:
17247 clauses
= c_parser_omp_clause_nogroup (parser
, clauses
);
17248 c_name
= "nogroup";
17250 case PRAGMA_OMP_CLAUSE_THREADS
:
17252 = c_parser_omp_clause_orderedkind (parser
, OMP_CLAUSE_THREADS
,
17254 c_name
= "threads";
17256 case PRAGMA_OMP_CLAUSE_SIMD
:
17258 = c_parser_omp_clause_orderedkind (parser
, OMP_CLAUSE_SIMD
,
17262 case PRAGMA_OMP_CLAUSE_ENTER
:
17264 = c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ENTER
,
17269 c_parser_error (parser
, "expected %<#pragma omp%> clause");
17275 if (((mask
>> c_kind
) & 1) == 0)
17277 /* Remove the invalid clause(s) from the list to avoid
17278 confusing the rest of the compiler. */
17280 error_at (here
, "%qs is not valid for %qs", c_name
, where
);
17286 c_parser_skip_to_pragma_eol (parser
);
17290 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_UNIFORM
)) != 0)
17291 return c_finish_omp_clauses (clauses
, C_ORT_OMP_DECLARE_SIMD
);
17292 return c_finish_omp_clauses (clauses
, C_ORT_OMP
);
17298 /* OpenACC 2.0, OpenMP 2.5:
17302 In practice, we're also interested in adding the statement to an
17303 outer node. So it is convenient if we work around the fact that
17304 c_parser_statement calls add_stmt. */
17307 c_parser_omp_structured_block (c_parser
*parser
, bool *if_p
)
17309 tree stmt
= push_stmt_list ();
17310 c_parser_statement (parser
, if_p
);
17311 return pop_stmt_list (stmt
);
17315 # pragma acc cache (variable-list) new-line
17317 LOC is the location of the #pragma token.
17321 c_parser_oacc_cache (location_t loc
, c_parser
*parser
)
17323 tree stmt
, clauses
;
17325 clauses
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE__CACHE_
, NULL
);
17326 clauses
= c_finish_omp_clauses (clauses
, C_ORT_ACC
);
17328 c_parser_skip_to_pragma_eol (parser
);
17330 stmt
= make_node (OACC_CACHE
);
17331 TREE_TYPE (stmt
) = void_type_node
;
17332 OACC_CACHE_CLAUSES (stmt
) = clauses
;
17333 SET_EXPR_LOCATION (stmt
, loc
);
17340 # pragma acc data oacc-data-clause[optseq] new-line
17343 LOC is the location of the #pragma token.
17346 #define OACC_DATA_CLAUSE_MASK \
17347 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
17348 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
17349 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17350 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17351 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17352 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
17353 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17354 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
17355 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
17358 c_parser_oacc_data (location_t loc
, c_parser
*parser
, bool *if_p
)
17360 tree stmt
, clauses
, block
;
17362 clauses
= c_parser_oacc_all_clauses (parser
, OACC_DATA_CLAUSE_MASK
,
17363 "#pragma acc data");
17365 block
= c_begin_omp_parallel ();
17366 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
17368 stmt
= c_finish_oacc_data (loc
, clauses
, block
);
17374 # pragma acc declare oacc-data-clause[optseq] new-line
17377 #define OACC_DECLARE_CLAUSE_MASK \
17378 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
17379 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17380 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17381 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17382 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
17383 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT) \
17384 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_LINK) \
17385 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
17388 c_parser_oacc_declare (c_parser
*parser
)
17390 location_t pragma_loc
= c_parser_peek_token (parser
)->location
;
17391 tree clauses
, stmt
, t
, decl
;
17393 bool error
= false;
17395 c_parser_consume_pragma (parser
);
17397 clauses
= c_parser_oacc_all_clauses (parser
, OACC_DECLARE_CLAUSE_MASK
,
17398 "#pragma acc declare");
17401 error_at (pragma_loc
,
17402 "no valid clauses specified in %<#pragma acc declare%>");
17406 for (t
= clauses
; t
; t
= OMP_CLAUSE_CHAIN (t
))
17408 location_t loc
= OMP_CLAUSE_LOCATION (t
);
17409 decl
= OMP_CLAUSE_DECL (t
);
17410 if (!DECL_P (decl
))
17412 error_at (loc
, "array section in %<#pragma acc declare%>");
17417 switch (OMP_CLAUSE_MAP_KIND (t
))
17419 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
17420 case GOMP_MAP_ALLOC
:
17422 case GOMP_MAP_FORCE_DEVICEPTR
:
17423 case GOMP_MAP_DEVICE_RESIDENT
:
17426 case GOMP_MAP_LINK
:
17427 if (!global_bindings_p ()
17428 && (TREE_STATIC (decl
)
17429 || !DECL_EXTERNAL (decl
)))
17432 "%qD must be a global variable in "
17433 "%<#pragma acc declare link%>",
17441 if (global_bindings_p ())
17443 error_at (loc
, "invalid OpenACC clause at file scope");
17447 if (DECL_EXTERNAL (decl
))
17450 "invalid use of %<extern%> variable %qD "
17451 "in %<#pragma acc declare%>", decl
);
17455 else if (TREE_PUBLIC (decl
))
17458 "invalid use of %<global%> variable %qD "
17459 "in %<#pragma acc declare%>", decl
);
17466 if (!c_check_in_current_scope (decl
))
17469 "%qD must be a variable declared in the same scope as "
17470 "%<#pragma acc declare%>", decl
);
17475 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl
))
17476 || lookup_attribute ("omp declare target link",
17477 DECL_ATTRIBUTES (decl
)))
17479 error_at (loc
, "variable %qD used more than once with "
17480 "%<#pragma acc declare%>", decl
);
17489 if (OMP_CLAUSE_MAP_KIND (t
) == GOMP_MAP_LINK
)
17490 id
= get_identifier ("omp declare target link");
17492 id
= get_identifier ("omp declare target");
17494 DECL_ATTRIBUTES (decl
)
17495 = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (decl
));
17497 if (global_bindings_p ())
17499 symtab_node
*node
= symtab_node::get (decl
);
17502 node
->offloadable
= 1;
17503 if (ENABLE_OFFLOADING
)
17505 g
->have_offload
= true;
17506 if (is_a
<varpool_node
*> (node
))
17507 vec_safe_push (offload_vars
, decl
);
17514 if (error
|| global_bindings_p ())
17517 stmt
= make_node (OACC_DECLARE
);
17518 TREE_TYPE (stmt
) = void_type_node
;
17519 OACC_DECLARE_CLAUSES (stmt
) = clauses
;
17520 SET_EXPR_LOCATION (stmt
, pragma_loc
);
17528 # pragma acc enter data oacc-enter-data-clause[optseq] new-line
17532 # pragma acc exit data oacc-exit-data-clause[optseq] new-line
17535 LOC is the location of the #pragma token.
17538 #define OACC_ENTER_DATA_CLAUSE_MASK \
17539 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17540 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17541 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
17542 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17543 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17544 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17546 #define OACC_EXIT_DATA_CLAUSE_MASK \
17547 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17548 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17549 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17550 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DELETE) \
17551 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DETACH) \
17552 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FINALIZE) \
17553 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17556 c_parser_oacc_enter_exit_data (c_parser
*parser
, bool enter
)
17558 location_t loc
= c_parser_peek_token (parser
)->location
;
17559 tree clauses
, stmt
;
17560 const char *p
= "";
17562 c_parser_consume_pragma (parser
);
17564 if (c_parser_next_token_is (parser
, CPP_NAME
))
17566 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
17567 c_parser_consume_token (parser
);
17570 if (strcmp (p
, "data") != 0)
17572 error_at (loc
, "expected %<data%> after %<#pragma acc %s%>",
17573 enter
? "enter" : "exit");
17574 parser
->error
= true;
17575 c_parser_skip_to_pragma_eol (parser
);
17580 clauses
= c_parser_oacc_all_clauses (parser
, OACC_ENTER_DATA_CLAUSE_MASK
,
17581 "#pragma acc enter data");
17583 clauses
= c_parser_oacc_all_clauses (parser
, OACC_EXIT_DATA_CLAUSE_MASK
,
17584 "#pragma acc exit data");
17586 if (omp_find_clause (clauses
, OMP_CLAUSE_MAP
) == NULL_TREE
)
17588 error_at (loc
, "%<#pragma acc %s data%> has no data movement clause",
17589 enter
? "enter" : "exit");
17593 stmt
= enter
? make_node (OACC_ENTER_DATA
) : make_node (OACC_EXIT_DATA
);
17594 TREE_TYPE (stmt
) = void_type_node
;
17595 OMP_STANDALONE_CLAUSES (stmt
) = clauses
;
17596 SET_EXPR_LOCATION (stmt
, loc
);
17602 # pragma acc host_data oacc-data-clause[optseq] new-line
17606 #define OACC_HOST_DATA_CLAUSE_MASK \
17607 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_USE_DEVICE) \
17608 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17609 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) )
17612 c_parser_oacc_host_data (location_t loc
, c_parser
*parser
, bool *if_p
)
17614 tree stmt
, clauses
, block
;
17616 clauses
= c_parser_oacc_all_clauses (parser
, OACC_HOST_DATA_CLAUSE_MASK
,
17617 "#pragma acc host_data");
17619 block
= c_begin_omp_parallel ();
17620 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
17621 stmt
= c_finish_oacc_host_data (loc
, clauses
, block
);
17628 # pragma acc loop oacc-loop-clause[optseq] new-line
17631 LOC is the location of the #pragma token.
17634 #define OACC_LOOP_CLAUSE_MASK \
17635 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COLLAPSE) \
17636 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
17637 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
17638 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
17639 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
17640 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
17641 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_AUTO) \
17642 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_INDEPENDENT) \
17643 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \
17644 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_TILE) )
17646 c_parser_oacc_loop (location_t loc
, c_parser
*parser
, char *p_name
,
17647 omp_clause_mask mask
, tree
*cclauses
, bool *if_p
)
17649 bool is_parallel
= ((mask
>> PRAGMA_OACC_CLAUSE_REDUCTION
) & 1) == 1;
17651 strcat (p_name
, " loop");
17652 mask
|= OACC_LOOP_CLAUSE_MASK
;
17654 tree clauses
= c_parser_oacc_all_clauses (parser
, mask
, p_name
,
17658 clauses
= c_oacc_split_loop_clauses (clauses
, cclauses
, is_parallel
);
17660 *cclauses
= c_finish_omp_clauses (*cclauses
, C_ORT_ACC
);
17662 clauses
= c_finish_omp_clauses (clauses
, C_ORT_ACC
);
17665 tree block
= c_begin_compound_stmt (true);
17666 tree stmt
= c_parser_omp_for_loop (loc
, parser
, OACC_LOOP
, clauses
, NULL
,
17668 block
= c_end_compound_stmt (loc
, block
, true);
17675 # pragma acc kernels oacc-kernels-clause[optseq] new-line
17680 # pragma acc parallel oacc-parallel-clause[optseq] new-line
17685 # pragma acc serial oacc-serial-clause[optseq] new-line
17688 LOC is the location of the #pragma token.
17691 #define OACC_KERNELS_CLAUSE_MASK \
17692 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17693 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
17694 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
17695 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17696 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17697 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17698 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
17699 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
17700 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17701 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
17702 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
17703 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
17704 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
17705 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
17706 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17708 #define OACC_PARALLEL_CLAUSE_MASK \
17709 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17710 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
17711 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
17712 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17713 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17714 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17715 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
17716 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
17717 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17718 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
17719 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
17720 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
17721 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
17722 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
17723 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
17724 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
17725 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
17726 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17728 #define OACC_SERIAL_CLAUSE_MASK \
17729 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17730 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
17731 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
17732 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17733 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17734 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17735 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
17736 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
17737 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17738 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
17739 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
17740 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
17741 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
17742 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
17743 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17746 c_parser_oacc_compute (location_t loc
, c_parser
*parser
,
17747 enum pragma_kind p_kind
, char *p_name
, bool *if_p
)
17749 omp_clause_mask mask
;
17750 enum tree_code code
;
17753 case PRAGMA_OACC_KERNELS
:
17754 strcat (p_name
, " kernels");
17755 mask
= OACC_KERNELS_CLAUSE_MASK
;
17756 code
= OACC_KERNELS
;
17758 case PRAGMA_OACC_PARALLEL
:
17759 strcat (p_name
, " parallel");
17760 mask
= OACC_PARALLEL_CLAUSE_MASK
;
17761 code
= OACC_PARALLEL
;
17763 case PRAGMA_OACC_SERIAL
:
17764 strcat (p_name
, " serial");
17765 mask
= OACC_SERIAL_CLAUSE_MASK
;
17766 code
= OACC_SERIAL
;
17769 gcc_unreachable ();
17772 if (c_parser_next_token_is (parser
, CPP_NAME
))
17774 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
17775 if (strcmp (p
, "loop") == 0)
17777 c_parser_consume_token (parser
);
17778 tree block
= c_begin_omp_parallel ();
17780 c_parser_oacc_loop (loc
, parser
, p_name
, mask
, &clauses
, if_p
);
17781 return c_finish_omp_construct (loc
, code
, block
, clauses
);
17785 tree clauses
= c_parser_oacc_all_clauses (parser
, mask
, p_name
);
17787 tree block
= c_begin_omp_parallel ();
17788 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
17790 return c_finish_omp_construct (loc
, code
, block
, clauses
);
17794 # pragma acc routine oacc-routine-clause[optseq] new-line
17795 function-definition
17797 # pragma acc routine ( name ) oacc-routine-clause[optseq] new-line
17800 #define OACC_ROUTINE_CLAUSE_MASK \
17801 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
17802 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
17803 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
17804 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \
17805 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NOHOST) )
17807 /* Parse an OpenACC routine directive. For named directives, we apply
17808 immediately to the named function. For unnamed ones we then parse
17809 a declaration or definition, which must be for a function. */
17812 c_parser_oacc_routine (c_parser
*parser
, enum pragma_context context
)
17814 gcc_checking_assert (context
== pragma_external
);
17816 oacc_routine_data data
;
17817 data
.error_seen
= false;
17818 data
.fndecl_seen
= false;
17819 data
.loc
= c_parser_peek_token (parser
)->location
;
17821 c_parser_consume_pragma (parser
);
17823 /* Look for optional '( name )'. */
17824 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
17826 c_parser_consume_token (parser
); /* '(' */
17828 tree decl
= NULL_TREE
;
17829 c_token
*name_token
= c_parser_peek_token (parser
);
17830 location_t name_loc
= name_token
->location
;
17831 if (name_token
->type
== CPP_NAME
17832 && (name_token
->id_kind
== C_ID_ID
17833 || name_token
->id_kind
== C_ID_TYPENAME
))
17835 decl
= lookup_name (name_token
->value
);
17837 error_at (name_loc
,
17838 "%qE has not been declared", name_token
->value
);
17839 c_parser_consume_token (parser
);
17842 c_parser_error (parser
, "expected function name");
17845 || !c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
17847 c_parser_skip_to_pragma_eol (parser
, false);
17852 = c_parser_oacc_all_clauses (parser
, OACC_ROUTINE_CLAUSE_MASK
,
17853 "#pragma acc routine");
17854 /* The clauses are in reverse order; fix that to make later diagnostic
17855 emission easier. */
17856 data
.clauses
= nreverse (data
.clauses
);
17858 if (TREE_CODE (decl
) != FUNCTION_DECL
)
17860 error_at (name_loc
, "%qD does not refer to a function", decl
);
17864 c_finish_oacc_routine (&data
, decl
, false);
17866 else /* No optional '( name )'. */
17869 = c_parser_oacc_all_clauses (parser
, OACC_ROUTINE_CLAUSE_MASK
,
17870 "#pragma acc routine");
17871 /* The clauses are in reverse order; fix that to make later diagnostic
17872 emission easier. */
17873 data
.clauses
= nreverse (data
.clauses
);
17875 /* Emit a helpful diagnostic if there's another pragma following this
17876 one. Also don't allow a static assertion declaration, as in the
17877 following we'll just parse a *single* "declaration or function
17878 definition", and the static assertion counts an one. */
17879 if (c_parser_next_token_is (parser
, CPP_PRAGMA
)
17880 || c_parser_next_token_is_keyword (parser
, RID_STATIC_ASSERT
))
17882 error_at (data
.loc
,
17883 "%<#pragma acc routine%> not immediately followed by"
17884 " function declaration or definition");
17885 /* ..., and then just keep going. */
17889 /* We only have to consider the pragma_external case here. */
17890 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
17891 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
)
17893 int ext
= disable_extension_diagnostics ();
17895 c_parser_consume_token (parser
);
17896 while (c_parser_next_token_is (parser
, CPP_KEYWORD
)
17897 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
);
17898 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
17899 NULL
, NULL
, false, NULL
, &data
);
17900 restore_extension_diagnostics (ext
);
17903 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
17904 NULL
, NULL
, false, NULL
, &data
);
17908 /* Finalize an OpenACC routine pragma, applying it to FNDECL.
17909 IS_DEFN is true if we're applying it to the definition. */
17912 c_finish_oacc_routine (struct oacc_routine_data
*data
, tree fndecl
,
17915 /* Keep going if we're in error reporting mode. */
17916 if (data
->error_seen
17917 || fndecl
== error_mark_node
)
17920 if (data
->fndecl_seen
)
17922 error_at (data
->loc
,
17923 "%<#pragma acc routine%> not immediately followed by"
17924 " a single function declaration or definition");
17925 data
->error_seen
= true;
17928 if (fndecl
== NULL_TREE
|| TREE_CODE (fndecl
) != FUNCTION_DECL
)
17930 error_at (data
->loc
,
17931 "%<#pragma acc routine%> not immediately followed by"
17932 " function declaration or definition");
17933 data
->error_seen
= true;
17938 = oacc_verify_routine_clauses (fndecl
, &data
->clauses
, data
->loc
,
17939 "#pragma acc routine");
17940 if (compatible
< 0)
17942 data
->error_seen
= true;
17945 if (compatible
> 0)
17950 if (TREE_USED (fndecl
) || (!is_defn
&& DECL_SAVED_TREE (fndecl
)))
17952 error_at (data
->loc
,
17954 ? G_("%<#pragma acc routine%> must be applied before use")
17955 : G_("%<#pragma acc routine%> must be applied before"
17957 data
->error_seen
= true;
17961 /* Set the routine's level of parallelism. */
17962 tree dims
= oacc_build_routine_dims (data
->clauses
);
17963 oacc_replace_fn_attrib (fndecl
, dims
);
17965 /* Add an "omp declare target" attribute. */
17966 DECL_ATTRIBUTES (fndecl
)
17967 = tree_cons (get_identifier ("omp declare target"),
17968 data
->clauses
, DECL_ATTRIBUTES (fndecl
));
17971 /* Remember that we've used this "#pragma acc routine". */
17972 data
->fndecl_seen
= true;
17976 # pragma acc update oacc-update-clause[optseq] new-line
17979 #define OACC_UPDATE_CLAUSE_MASK \
17980 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17981 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE) \
17982 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_HOST) \
17983 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17984 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) \
17985 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17988 c_parser_oacc_update (c_parser
*parser
)
17990 location_t loc
= c_parser_peek_token (parser
)->location
;
17992 c_parser_consume_pragma (parser
);
17994 tree clauses
= c_parser_oacc_all_clauses (parser
, OACC_UPDATE_CLAUSE_MASK
,
17995 "#pragma acc update");
17996 if (omp_find_clause (clauses
, OMP_CLAUSE_MAP
) == NULL_TREE
)
17999 "%<#pragma acc update%> must contain at least one "
18000 "%<device%> or %<host%> or %<self%> clause");
18007 tree stmt
= make_node (OACC_UPDATE
);
18008 TREE_TYPE (stmt
) = void_type_node
;
18009 OACC_UPDATE_CLAUSES (stmt
) = clauses
;
18010 SET_EXPR_LOCATION (stmt
, loc
);
18015 # pragma acc wait [(intseq)] oacc-wait-clause[optseq] new-line
18017 LOC is the location of the #pragma token.
18020 #define OACC_WAIT_CLAUSE_MASK \
18021 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) )
18024 c_parser_oacc_wait (location_t loc
, c_parser
*parser
, char *p_name
)
18026 tree clauses
, list
= NULL_TREE
, stmt
= NULL_TREE
;
18028 if (c_parser_peek_token (parser
)->type
== CPP_OPEN_PAREN
)
18029 list
= c_parser_oacc_wait_list (parser
, loc
, list
);
18031 strcpy (p_name
, " wait");
18032 clauses
= c_parser_oacc_all_clauses (parser
, OACC_WAIT_CLAUSE_MASK
, p_name
);
18033 stmt
= c_finish_oacc_wait (loc
, list
, clauses
);
18040 # pragma omp allocate (list) [allocator(allocator)] */
18043 c_parser_omp_allocate (location_t loc
, c_parser
*parser
)
18045 tree allocator
= NULL_TREE
;
18046 tree nl
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ALLOCATE
, NULL_TREE
);
18047 if (c_parser_next_token_is (parser
, CPP_NAME
))
18049 matching_parens parens
;
18050 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18051 c_parser_consume_token (parser
);
18052 if (strcmp ("allocator", p
) != 0)
18053 error_at (c_parser_peek_token (parser
)->location
,
18054 "expected %<allocator%>");
18055 else if (parens
.require_open (parser
))
18057 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
18058 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
18059 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
18060 allocator
= expr
.value
;
18061 allocator
= c_fully_fold (allocator
, false, NULL
);
18063 = expr
.original_type
? expr
.original_type
: TREE_TYPE (allocator
);
18064 orig_type
= TYPE_MAIN_VARIANT (orig_type
);
18065 if (!INTEGRAL_TYPE_P (TREE_TYPE (allocator
))
18066 || TREE_CODE (orig_type
) != ENUMERAL_TYPE
18067 || TYPE_NAME (orig_type
)
18068 != get_identifier ("omp_allocator_handle_t"))
18070 error_at (expr_loc
, "%<allocator%> clause allocator expression "
18071 "has type %qT rather than "
18072 "%<omp_allocator_handle_t%>",
18073 TREE_TYPE (allocator
));
18074 allocator
= NULL_TREE
;
18076 parens
.skip_until_found_close (parser
);
18079 c_parser_skip_to_pragma_eol (parser
);
18082 for (tree c
= nl
; c
!= NULL_TREE
; c
= OMP_CLAUSE_CHAIN (c
))
18083 OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
) = allocator
;
18085 sorry_at (loc
, "%<#pragma omp allocate%> not yet supported");
18089 # pragma omp atomic new-line
18093 x binop= expr | x++ | ++x | x-- | --x
18095 +, *, -, /, &, ^, |, <<, >>
18097 where x is an lvalue expression with scalar type.
18100 # pragma omp atomic new-line
18103 # pragma omp atomic read new-line
18106 # pragma omp atomic write new-line
18109 # pragma omp atomic update new-line
18112 # pragma omp atomic capture new-line
18115 # pragma omp atomic capture new-line
18123 expression-stmt | x = x binop expr
18125 v = expression-stmt
18127 { v = x; update-stmt; } | { update-stmt; v = x; }
18131 expression-stmt | x = x binop expr | x = expr binop x
18135 { v = x; update-stmt; } | { update-stmt; v = x; } | { v = x; x = expr; }
18138 # pragma omp atomic compare new-line
18139 conditional-update-atomic
18141 # pragma omp atomic compare capture new-line
18142 conditional-update-capture-atomic
18144 conditional-update-atomic:
18145 cond-expr-stmt | cond-update-stmt
18147 x = expr ordop x ? expr : x;
18148 x = x ordop expr ? expr : x;
18149 x = x == e ? d : x;
18151 if (expr ordop x) { x = expr; }
18152 if (x ordop expr) { x = expr; }
18153 if (x == e) { x = d; }
18156 conditional-update-capture-atomic:
18158 { v = x; cond-expr-stmt }
18159 { cond-expr-stmt v = x; }
18160 { v = x; cond-update-stmt }
18161 { cond-update-stmt v = x; }
18162 if (x == e) { x = d; } else { v = x; }
18163 { r = x == e; if (r) { x = d; } }
18164 { r = x == e; if (r) { x = d; } else { v = x; } }
18166 where x, r and v are lvalue expressions with scalar type,
18167 expr, e and d are expressions with scalar type and e might be
18170 LOC is the location of the #pragma token. */
18173 c_parser_omp_atomic (location_t loc
, c_parser
*parser
, bool openacc
)
18175 tree lhs
= NULL_TREE
, rhs
= NULL_TREE
, v
= NULL_TREE
, r
= NULL_TREE
;
18176 tree lhs1
= NULL_TREE
, rhs1
= NULL_TREE
;
18177 tree stmt
, orig_lhs
, unfolded_lhs
= NULL_TREE
, unfolded_lhs1
= NULL_TREE
;
18178 enum tree_code code
= ERROR_MARK
, opcode
= NOP_EXPR
;
18179 enum omp_memory_order memory_order
= OMP_MEMORY_ORDER_UNSPECIFIED
;
18180 struct c_expr expr
;
18182 bool structured_block
= false;
18183 bool swapped
= false;
18186 tree clauses
= NULL_TREE
;
18187 bool capture
= false;
18188 bool compare
= false;
18190 enum omp_memory_order fail
= OMP_MEMORY_ORDER_UNSPECIFIED
;
18191 bool no_semicolon
= false;
18192 bool extra_scope
= false;
18194 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
18197 && c_parser_next_token_is (parser
, CPP_COMMA
)
18198 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
18199 c_parser_consume_token (parser
);
18203 if (c_parser_next_token_is (parser
, CPP_NAME
))
18206 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18207 location_t cloc
= c_parser_peek_token (parser
)->location
;
18208 enum tree_code new_code
= ERROR_MARK
;
18209 enum omp_memory_order new_memory_order
18210 = OMP_MEMORY_ORDER_UNSPECIFIED
;
18211 bool new_capture
= false;
18212 bool new_compare
= false;
18213 bool new_weak
= false;
18214 enum omp_memory_order new_fail
= OMP_MEMORY_ORDER_UNSPECIFIED
;
18216 if (!strcmp (p
, "read"))
18217 new_code
= OMP_ATOMIC_READ
;
18218 else if (!strcmp (p
, "write"))
18219 new_code
= NOP_EXPR
;
18220 else if (!strcmp (p
, "update"))
18221 new_code
= OMP_ATOMIC
;
18222 else if (openacc
&& !strcmp (p
, "capture"))
18223 new_code
= OMP_ATOMIC_CAPTURE_NEW
;
18227 error_at (cloc
, "expected %<read%>, %<write%>, %<update%>, "
18228 "or %<capture%> clause");
18230 else if (!strcmp (p
, "capture"))
18231 new_capture
= true;
18232 else if (!strcmp (p
, "compare"))
18233 new_compare
= true;
18234 else if (!strcmp (p
, "weak"))
18236 else if (!strcmp (p
, "fail"))
18238 matching_parens parens
;
18240 c_parser_consume_token (parser
);
18241 if (!parens
.require_open (parser
))
18244 if (c_parser_next_token_is (parser
, CPP_NAME
))
18247 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18249 if (!strcmp (q
, "seq_cst"))
18250 new_fail
= OMP_MEMORY_ORDER_SEQ_CST
;
18251 else if (!strcmp (q
, "acquire"))
18252 new_fail
= OMP_MEMORY_ORDER_ACQUIRE
;
18253 else if (!strcmp (q
, "relaxed"))
18254 new_fail
= OMP_MEMORY_ORDER_RELAXED
;
18257 if (new_fail
!= OMP_MEMORY_ORDER_UNSPECIFIED
)
18259 c_parser_consume_token (parser
);
18260 if (fail
!= OMP_MEMORY_ORDER_UNSPECIFIED
)
18261 error_at (cloc
, "too many %qs clauses", "fail");
18266 c_parser_error (parser
, "expected %<seq_cst%>, %<acquire%> "
18268 parens
.skip_until_found_close (parser
);
18271 else if (!strcmp (p
, "seq_cst"))
18272 new_memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
18273 else if (!strcmp (p
, "acq_rel"))
18274 new_memory_order
= OMP_MEMORY_ORDER_ACQ_REL
;
18275 else if (!strcmp (p
, "release"))
18276 new_memory_order
= OMP_MEMORY_ORDER_RELEASE
;
18277 else if (!strcmp (p
, "acquire"))
18278 new_memory_order
= OMP_MEMORY_ORDER_ACQUIRE
;
18279 else if (!strcmp (p
, "relaxed"))
18280 new_memory_order
= OMP_MEMORY_ORDER_RELAXED
;
18281 else if (!strcmp (p
, "hint"))
18283 c_parser_consume_token (parser
);
18284 clauses
= c_parser_omp_clause_hint (parser
, clauses
);
18290 error_at (cloc
, "expected %<read%>, %<write%>, %<update%>, "
18291 "%<capture%>, %<compare%>, %<weak%>, %<fail%>, "
18292 "%<seq_cst%>, %<acq_rel%>, %<release%>, "
18293 "%<relaxed%> or %<hint%> clause");
18297 if (new_code
!= ERROR_MARK
)
18299 /* OpenACC permits 'update capture'. */
18301 && code
== OMP_ATOMIC
18302 && new_code
== OMP_ATOMIC_CAPTURE_NEW
)
18304 else if (code
!= ERROR_MARK
)
18305 error_at (cloc
, "too many atomic clauses");
18309 else if (new_memory_order
!= OMP_MEMORY_ORDER_UNSPECIFIED
)
18311 if (memory_order
!= OMP_MEMORY_ORDER_UNSPECIFIED
)
18312 error_at (cloc
, "too many memory order clauses");
18314 memory_order
= new_memory_order
;
18316 else if (new_capture
)
18319 error_at (cloc
, "too many %qs clauses", "capture");
18323 else if (new_compare
)
18326 error_at (cloc
, "too many %qs clauses", "compare");
18333 error_at (cloc
, "too many %qs clauses", "weak");
18337 c_parser_consume_token (parser
);
18343 c_parser_skip_to_pragma_eol (parser
);
18345 if (code
== ERROR_MARK
)
18349 if (code
!= OMP_ATOMIC
)
18350 error_at (loc
, "%qs clause is incompatible with %<read%> or %<write%> "
18351 "clauses", "capture");
18353 code
= OMP_ATOMIC_CAPTURE_NEW
;
18355 if (compare
&& code
!= OMP_ATOMIC
&& code
!= OMP_ATOMIC_CAPTURE_NEW
)
18357 error_at (loc
, "%qs clause is incompatible with %<read%> or %<write%> "
18358 "clauses", "compare");
18361 if (fail
!= OMP_MEMORY_ORDER_UNSPECIFIED
&& !compare
)
18363 error_at (loc
, "%qs clause requires %qs clause", "fail", "compare");
18364 fail
= OMP_MEMORY_ORDER_UNSPECIFIED
;
18366 if (weak
&& !compare
)
18368 error_at (loc
, "%qs clause requires %qs clause", "weak", "compare");
18372 memory_order
= OMP_MEMORY_ORDER_RELAXED
;
18373 else if (memory_order
== OMP_MEMORY_ORDER_UNSPECIFIED
)
18376 = (enum omp_requires
) (omp_requires_mask
18377 | OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED
);
18378 switch ((enum omp_memory_order
)
18379 (omp_requires_mask
& OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
))
18381 case OMP_MEMORY_ORDER_UNSPECIFIED
:
18382 case OMP_MEMORY_ORDER_RELAXED
:
18383 memory_order
= OMP_MEMORY_ORDER_RELAXED
;
18385 case OMP_MEMORY_ORDER_SEQ_CST
:
18386 memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
18388 case OMP_MEMORY_ORDER_ACQ_REL
:
18391 case OMP_ATOMIC_READ
:
18392 memory_order
= OMP_MEMORY_ORDER_ACQUIRE
;
18394 case NOP_EXPR
: /* atomic write */
18395 memory_order
= OMP_MEMORY_ORDER_RELEASE
;
18398 memory_order
= OMP_MEMORY_ORDER_ACQ_REL
;
18403 gcc_unreachable ();
18409 case OMP_ATOMIC_READ
:
18410 if (memory_order
== OMP_MEMORY_ORDER_RELEASE
)
18412 error_at (loc
, "%<#pragma omp atomic read%> incompatible with "
18413 "%<release%> clause");
18414 memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
18416 else if (memory_order
== OMP_MEMORY_ORDER_ACQ_REL
)
18417 memory_order
= OMP_MEMORY_ORDER_ACQUIRE
;
18419 case NOP_EXPR
: /* atomic write */
18420 if (memory_order
== OMP_MEMORY_ORDER_ACQUIRE
)
18422 error_at (loc
, "%<#pragma omp atomic write%> incompatible with "
18423 "%<acquire%> clause");
18424 memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
18426 else if (memory_order
== OMP_MEMORY_ORDER_ACQ_REL
)
18427 memory_order
= OMP_MEMORY_ORDER_RELEASE
;
18432 if (fail
!= OMP_MEMORY_ORDER_UNSPECIFIED
)
18434 = (enum omp_memory_order
) (memory_order
18435 | (fail
<< OMP_FAIL_MEMORY_ORDER_SHIFT
));
18439 case OMP_ATOMIC_READ
:
18440 case NOP_EXPR
: /* atomic write */
18441 v
= c_parser_cast_expression (parser
, NULL
).value
;
18442 non_lvalue_p
= !lvalue_p (v
);
18443 v
= c_fully_fold (v
, false, NULL
, true);
18444 if (v
== error_mark_node
)
18447 v
= non_lvalue (v
);
18448 loc
= c_parser_peek_token (parser
)->location
;
18449 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
18451 if (code
== NOP_EXPR
)
18453 lhs
= c_parser_expression (parser
).value
;
18454 lhs
= c_fully_fold (lhs
, false, NULL
);
18455 if (lhs
== error_mark_node
)
18460 lhs
= c_parser_cast_expression (parser
, NULL
).value
;
18461 non_lvalue_p
= !lvalue_p (lhs
);
18462 lhs
= c_fully_fold (lhs
, false, NULL
, true);
18463 if (lhs
== error_mark_node
)
18466 lhs
= non_lvalue (lhs
);
18468 if (code
== NOP_EXPR
)
18470 /* atomic write is represented by OMP_ATOMIC with NOP_EXPR
18478 case OMP_ATOMIC_CAPTURE_NEW
:
18479 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
18481 c_parser_consume_token (parser
);
18482 structured_block
= true;
18485 && c_parser_next_token_is_keyword (parser
, RID_IF
))
18489 v
= c_parser_cast_expression (parser
, NULL
).value
;
18490 non_lvalue_p
= !lvalue_p (v
);
18491 v
= c_fully_fold (v
, false, NULL
, true);
18492 if (v
== error_mark_node
)
18495 v
= non_lvalue (v
);
18496 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
18498 if (compare
&& c_parser_next_token_is_keyword (parser
, RID_IF
))
18500 eloc
= c_parser_peek_token (parser
)->location
;
18501 error_at (eloc
, "expected expression");
18510 /* For structured_block case we don't know yet whether
18511 old or new x should be captured. */
18513 if (compare
&& c_parser_next_token_is_keyword (parser
, RID_IF
))
18515 c_parser_consume_token (parser
);
18517 matching_parens parens
;
18518 if (!parens
.require_open (parser
))
18520 eloc
= c_parser_peek_token (parser
)->location
;
18524 cmp_expr
= c_parser_cast_expression (parser
, NULL
);
18525 cmp_expr
= default_function_array_conversion (eloc
, cmp_expr
);
18528 cmp_expr
= c_parser_binary_expression (parser
, NULL
, void_list_node
);
18529 parens
.skip_until_found_close (parser
);
18530 if (cmp_expr
.value
== error_mark_node
)
18534 if (!c_tree_equal (cmp_expr
.value
, unfolded_lhs
))
18536 cmp_expr
.value
= rhs1
;
18538 gcc_assert (TREE_CODE (cmp_expr
.value
) == EQ_EXPR
);
18540 if (TREE_CODE (cmp_expr
.value
) == EQ_EXPR
)
18542 else if (!structured_block
&& code
== OMP_ATOMIC_CAPTURE_NEW
)
18544 error_at (EXPR_LOC_OR_LOC (cmp_expr
.value
, eloc
),
18545 "expected %<==%> comparison in %<if%> condition");
18548 else if (TREE_CODE (cmp_expr
.value
) != GT_EXPR
18549 && TREE_CODE (cmp_expr
.value
) != LT_EXPR
)
18551 error_at (EXPR_LOC_OR_LOC (cmp_expr
.value
, eloc
),
18552 "expected %<==%>, %<<%> or %<>%> comparison in %<if%> "
18556 if (!c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
18559 extra_scope
= true;
18560 eloc
= c_parser_peek_token (parser
)->location
;
18561 expr
= c_parser_cast_expression (parser
, NULL
);
18563 expr
= default_function_array_conversion (eloc
, expr
);
18564 unfolded_lhs
= expr
.value
;
18565 lhs
= c_fully_fold (lhs
, false, NULL
, true);
18567 if (lhs
== error_mark_node
)
18569 if (!lvalue_p (unfolded_lhs
))
18570 lhs
= non_lvalue (lhs
);
18571 if (!c_parser_next_token_is (parser
, CPP_EQ
))
18573 c_parser_error (parser
, "expected %<=%>");
18576 c_parser_consume_token (parser
);
18577 eloc
= c_parser_peek_token (parser
)->location
;
18578 expr
= c_parser_expr_no_commas (parser
, NULL
);
18581 if (!c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
18584 if (!c_parser_require (parser
, CPP_CLOSE_BRACE
, "expected %<}%>"))
18587 extra_scope
= false;
18588 no_semicolon
= true;
18590 if (c_tree_equal (TREE_OPERAND (cmp_expr
.value
, 0), unfolded_lhs
))
18592 if (TREE_CODE (cmp_expr
.value
) == EQ_EXPR
)
18594 opcode
= COND_EXPR
;
18595 rhs
= c_fully_fold (TREE_OPERAND (cmp_expr
.value
, 1),
18596 false, NULL
, true);
18597 rhs1
= c_fully_fold (rhs1
, false, NULL
, true);
18599 else if (c_tree_equal (TREE_OPERAND (cmp_expr
.value
, 1), rhs1
))
18601 opcode
= (TREE_CODE (cmp_expr
.value
) == GT_EXPR
18602 ? MIN_EXPR
: MAX_EXPR
);
18603 rhs
= c_fully_fold (rhs1
, false, NULL
, true);
18604 rhs1
= c_fully_fold (TREE_OPERAND (cmp_expr
.value
, 0),
18605 false, NULL
, true);
18610 else if (TREE_CODE (cmp_expr
.value
) == EQ_EXPR
)
18612 else if (c_tree_equal (TREE_OPERAND (cmp_expr
.value
, 1), unfolded_lhs
)
18613 && c_tree_equal (TREE_OPERAND (cmp_expr
.value
, 0), rhs1
))
18615 opcode
= (TREE_CODE (cmp_expr
.value
) == GT_EXPR
18616 ? MAX_EXPR
: MIN_EXPR
);
18617 rhs
= c_fully_fold (rhs1
, false, NULL
, true);
18618 rhs1
= c_fully_fold (TREE_OPERAND (cmp_expr
.value
, 1),
18619 false, NULL
, true);
18624 c_parser_error (parser
,
18625 "invalid form of %<#pragma omp atomic compare%>");
18629 if (c_parser_next_token_is_keyword (parser
, RID_ELSE
))
18631 if (code
!= OMP_ATOMIC_CAPTURE_NEW
18632 || (structured_block
&& r
== NULL_TREE
)
18633 || TREE_CODE (cmp_expr
.value
) != EQ_EXPR
)
18635 eloc
= c_parser_peek_token (parser
)->location
;
18636 error_at (eloc
, "unexpected %<else%>");
18640 c_parser_consume_token (parser
);
18642 if (!c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
18645 extra_scope
= true;
18646 v
= c_parser_cast_expression (parser
, NULL
).value
;
18647 non_lvalue_p
= !lvalue_p (v
);
18648 v
= c_fully_fold (v
, false, NULL
, true);
18649 if (v
== error_mark_node
)
18652 v
= non_lvalue (v
);
18653 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
18656 expr
= c_parser_expr_no_commas (parser
, NULL
);
18658 if (!c_tree_equal (expr
.value
, unfolded_lhs
))
18661 if (!c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
18664 if (!c_parser_require (parser
, CPP_CLOSE_BRACE
, "expected %<}%>"))
18667 extra_scope
= false;
18668 code
= OMP_ATOMIC_CAPTURE_OLD
;
18669 if (r
== NULL_TREE
)
18670 /* Signal to c_finish_omp_atomic that in
18671 if (x == e) { x = d; } else { v = x; }
18672 case the store to v should be conditional. */
18673 r
= void_list_node
;
18675 else if (code
== OMP_ATOMIC_CAPTURE_NEW
&& !structured_block
)
18677 c_parser_require_keyword (parser
, RID_ELSE
, "expected %<else%>");
18680 else if (code
== OMP_ATOMIC_CAPTURE_NEW
18686 eloc
= c_parser_peek_token (parser
)->location
;
18687 expr
= c_parser_cast_expression (parser
, NULL
);
18689 expr
= default_function_array_conversion (eloc
, expr
);
18690 unfolded_lhs
= expr
.value
;
18691 lhs
= c_fully_fold (lhs
, false, NULL
, true);
18693 switch (TREE_CODE (lhs
))
18696 error_at (eloc
, "invalid form of %<pragma omp atomic compare%>");
18700 c_parser_skip_to_end_of_block_or_statement (parser
);
18701 if (extra_scope
&& c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
18702 c_parser_consume_token (parser
);
18703 if (structured_block
)
18705 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
18706 c_parser_consume_token (parser
);
18707 else if (code
== OMP_ATOMIC_CAPTURE_NEW
)
18709 c_parser_skip_to_end_of_block_or_statement (parser
);
18710 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
18711 c_parser_consume_token (parser
);
18716 case POSTINCREMENT_EXPR
:
18717 if (code
== OMP_ATOMIC_CAPTURE_NEW
&& !structured_block
)
18718 code
= OMP_ATOMIC_CAPTURE_OLD
;
18720 case PREINCREMENT_EXPR
:
18721 lhs
= TREE_OPERAND (lhs
, 0);
18722 unfolded_lhs
= NULL_TREE
;
18723 opcode
= PLUS_EXPR
;
18724 rhs
= integer_one_node
;
18726 goto invalid_compare
;
18729 case POSTDECREMENT_EXPR
:
18730 if (code
== OMP_ATOMIC_CAPTURE_NEW
&& !structured_block
)
18731 code
= OMP_ATOMIC_CAPTURE_OLD
;
18733 case PREDECREMENT_EXPR
:
18734 lhs
= TREE_OPERAND (lhs
, 0);
18735 unfolded_lhs
= NULL_TREE
;
18736 opcode
= MINUS_EXPR
;
18737 rhs
= integer_one_node
;
18739 goto invalid_compare
;
18742 case COMPOUND_EXPR
:
18743 if (TREE_CODE (TREE_OPERAND (lhs
, 0)) == SAVE_EXPR
18744 && TREE_CODE (TREE_OPERAND (lhs
, 1)) == COMPOUND_EXPR
18745 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (lhs
, 1), 0)) == MODIFY_EXPR
18746 && TREE_OPERAND (TREE_OPERAND (lhs
, 1), 1) == TREE_OPERAND (lhs
, 0)
18747 && TREE_CODE (TREE_TYPE (TREE_OPERAND (TREE_OPERAND
18748 (TREE_OPERAND (lhs
, 1), 0), 0)))
18750 /* Undo effects of boolean_increment for post {in,de}crement. */
18751 lhs
= TREE_OPERAND (TREE_OPERAND (lhs
, 1), 0);
18754 if (TREE_CODE (lhs
) == MODIFY_EXPR
18755 && TREE_CODE (TREE_TYPE (TREE_OPERAND (lhs
, 0))) == BOOLEAN_TYPE
)
18757 /* Undo effects of boolean_increment. */
18758 if (integer_onep (TREE_OPERAND (lhs
, 1)))
18760 /* This is pre or post increment. */
18761 rhs
= TREE_OPERAND (lhs
, 1);
18762 lhs
= TREE_OPERAND (lhs
, 0);
18763 unfolded_lhs
= NULL_TREE
;
18765 if (code
== OMP_ATOMIC_CAPTURE_NEW
18766 && !structured_block
18767 && TREE_CODE (orig_lhs
) == COMPOUND_EXPR
)
18768 code
= OMP_ATOMIC_CAPTURE_OLD
;
18770 goto invalid_compare
;
18773 if (TREE_CODE (TREE_OPERAND (lhs
, 1)) == TRUTH_NOT_EXPR
18774 && TREE_OPERAND (lhs
, 0)
18775 == TREE_OPERAND (TREE_OPERAND (lhs
, 1), 0))
18777 /* This is pre or post decrement. */
18778 rhs
= TREE_OPERAND (lhs
, 1);
18779 lhs
= TREE_OPERAND (lhs
, 0);
18780 unfolded_lhs
= NULL_TREE
;
18782 if (code
== OMP_ATOMIC_CAPTURE_NEW
18783 && !structured_block
18784 && TREE_CODE (orig_lhs
) == COMPOUND_EXPR
)
18785 code
= OMP_ATOMIC_CAPTURE_OLD
;
18787 goto invalid_compare
;
18793 if (!lvalue_p (unfolded_lhs
))
18794 lhs
= non_lvalue (lhs
);
18795 if (compare
&& !c_parser_next_token_is (parser
, CPP_EQ
))
18797 c_parser_error (parser
, "expected %<=%>");
18800 switch (c_parser_peek_token (parser
)->type
)
18803 opcode
= MULT_EXPR
;
18806 opcode
= TRUNC_DIV_EXPR
;
18809 opcode
= PLUS_EXPR
;
18812 opcode
= MINUS_EXPR
;
18814 case CPP_LSHIFT_EQ
:
18815 opcode
= LSHIFT_EXPR
;
18817 case CPP_RSHIFT_EQ
:
18818 opcode
= RSHIFT_EXPR
;
18821 opcode
= BIT_AND_EXPR
;
18824 opcode
= BIT_IOR_EXPR
;
18827 opcode
= BIT_XOR_EXPR
;
18830 c_parser_consume_token (parser
);
18831 eloc
= c_parser_peek_token (parser
)->location
;
18832 expr
= c_parser_expr_no_commas (parser
, NULL
, unfolded_lhs
);
18834 switch (TREE_CODE (rhs1
))
18837 case TRUNC_DIV_EXPR
:
18848 if (c_tree_equal (TREE_OPERAND (rhs1
, 0), unfolded_lhs
))
18850 opcode
= TREE_CODE (rhs1
);
18851 rhs
= c_fully_fold (TREE_OPERAND (rhs1
, 1), false, NULL
,
18853 rhs1
= c_fully_fold (TREE_OPERAND (rhs1
, 0), false, NULL
,
18857 if (c_tree_equal (TREE_OPERAND (rhs1
, 1), unfolded_lhs
))
18859 opcode
= TREE_CODE (rhs1
);
18860 rhs
= c_fully_fold (TREE_OPERAND (rhs1
, 0), false, NULL
,
18862 rhs1
= c_fully_fold (TREE_OPERAND (rhs1
, 1), false, NULL
,
18864 swapped
= !commutative_tree_code (opcode
);
18871 if (TREE_CODE (TREE_OPERAND (rhs1
, 0)) != GT_EXPR
18872 && TREE_CODE (TREE_OPERAND (rhs1
, 0)) != LT_EXPR
18873 && TREE_CODE (TREE_OPERAND (rhs1
, 0)) != EQ_EXPR
)
18875 if (!TREE_OPERAND (rhs1
, 1))
18877 if (!c_tree_equal (TREE_OPERAND (rhs1
, 2), unfolded_lhs
))
18879 if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1
, 0), 0),
18882 if (TREE_CODE (TREE_OPERAND (rhs1
, 0)) == EQ_EXPR
)
18884 opcode
= COND_EXPR
;
18885 rhs
= c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1
,
18887 false, NULL
, true);
18888 rhs1
= c_fully_fold (TREE_OPERAND (rhs1
, 1), false,
18892 if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1
, 0), 1),
18893 TREE_OPERAND (rhs1
, 1)))
18895 opcode
= (TREE_CODE (TREE_OPERAND (rhs1
, 0)) == GT_EXPR
18896 ? MIN_EXPR
: MAX_EXPR
);
18897 rhs
= c_fully_fold (TREE_OPERAND (rhs1
, 1), false, NULL
,
18899 rhs1
= c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1
,
18901 false, NULL
, true);
18905 else if (TREE_CODE (TREE_OPERAND (rhs1
, 0)) == EQ_EXPR
)
18907 else if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1
, 0), 1),
18910 if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1
, 0), 0),
18911 TREE_OPERAND (rhs1
, 1)))
18913 opcode
= (TREE_CODE (TREE_OPERAND (rhs1
, 0)) == GT_EXPR
18914 ? MAX_EXPR
: MIN_EXPR
);
18915 rhs
= c_fully_fold (TREE_OPERAND (rhs1
, 1), false, NULL
,
18917 rhs1
= c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1
,
18919 false, NULL
, true);
18926 || code
!= OMP_ATOMIC_CAPTURE_NEW
18927 || !structured_block
18931 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
)
18932 && c_parser_peek_2nd_token (parser
)->keyword
== RID_IF
)
18936 c_parser_consume_token (parser
);
18945 if (c_parser_peek_token (parser
)->type
== CPP_SEMICOLON
)
18947 if (structured_block
&& code
== OMP_ATOMIC_CAPTURE_NEW
)
18949 code
= OMP_ATOMIC_CAPTURE_OLD
;
18952 expr
= default_function_array_read_conversion (eloc
, expr
);
18953 unfolded_lhs1
= expr
.value
;
18954 lhs1
= c_fully_fold (unfolded_lhs1
, false, NULL
, true);
18956 c_parser_consume_token (parser
);
18959 if (structured_block
&& !compare
)
18962 expr
= default_function_array_read_conversion (eloc
, expr
);
18963 rhs
= c_fully_fold (expr
.value
, false, NULL
, true);
18968 c_parser_error (parser
, "invalid form of %<#pragma omp atomic%>");
18971 c_parser_error (parser
,
18972 "invalid operator for %<#pragma omp atomic%>");
18976 /* Arrange to pass the location of the assignment operator to
18977 c_finish_omp_atomic. */
18978 loc
= c_parser_peek_token (parser
)->location
;
18979 c_parser_consume_token (parser
);
18980 eloc
= c_parser_peek_token (parser
)->location
;
18981 expr
= c_parser_expression (parser
);
18982 expr
= default_function_array_read_conversion (eloc
, expr
);
18984 rhs
= c_fully_fold (rhs
, false, NULL
, true);
18988 if (structured_block
&& code
== OMP_ATOMIC_CAPTURE_NEW
&& r
== NULL_TREE
)
18991 && !c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
18993 no_semicolon
= false;
18994 v
= c_parser_cast_expression (parser
, NULL
).value
;
18995 non_lvalue_p
= !lvalue_p (v
);
18996 v
= c_fully_fold (v
, false, NULL
, true);
18997 if (v
== error_mark_node
)
19000 v
= non_lvalue (v
);
19001 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
19003 eloc
= c_parser_peek_token (parser
)->location
;
19004 expr
= c_parser_cast_expression (parser
, NULL
);
19006 expr
= default_function_array_read_conversion (eloc
, expr
);
19007 unfolded_lhs1
= expr
.value
;
19008 lhs1
= c_fully_fold (lhs1
, false, NULL
, true);
19009 if (lhs1
== error_mark_node
)
19011 if (!lvalue_p (unfolded_lhs1
))
19012 lhs1
= non_lvalue (lhs1
);
19014 if (structured_block
)
19017 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
19018 c_parser_require (parser
, CPP_CLOSE_BRACE
, "expected %<}%>");
19021 if (weak
&& opcode
!= COND_EXPR
)
19023 error_at (loc
, "%<weak%> clause requires atomic equality comparison");
19026 if (unfolded_lhs
&& unfolded_lhs1
19027 && !c_tree_equal (unfolded_lhs
, unfolded_lhs1
))
19029 error ("%<#pragma omp atomic capture%> uses two different "
19030 "expressions for memory");
19031 stmt
= error_mark_node
;
19034 stmt
= c_finish_omp_atomic (loc
, code
, opcode
, lhs
, rhs
, v
, lhs1
, rhs1
, r
,
19035 swapped
, memory_order
, weak
);
19036 if (stmt
!= error_mark_node
)
19039 if (!structured_block
&& !no_semicolon
)
19040 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
19045 # pragma omp barrier new-line
19049 c_parser_omp_barrier (c_parser
*parser
)
19051 location_t loc
= c_parser_peek_token (parser
)->location
;
19052 c_parser_consume_pragma (parser
);
19053 c_parser_skip_to_pragma_eol (parser
);
19055 c_finish_omp_barrier (loc
);
19059 # pragma omp critical [(name)] new-line
19063 # pragma omp critical [(name) [hint(expression)]] new-line
19065 LOC is the location of the #pragma itself. */
19067 #define OMP_CRITICAL_CLAUSE_MASK \
19068 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HINT) )
19071 c_parser_omp_critical (location_t loc
, c_parser
*parser
, bool *if_p
)
19073 tree stmt
, name
= NULL_TREE
, clauses
= NULL_TREE
;
19075 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
19077 c_parser_consume_token (parser
);
19078 if (c_parser_next_token_is (parser
, CPP_NAME
))
19080 name
= c_parser_peek_token (parser
)->value
;
19081 c_parser_consume_token (parser
);
19082 c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>");
19085 c_parser_error (parser
, "expected identifier");
19087 if (c_parser_next_token_is (parser
, CPP_COMMA
)
19088 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
19089 c_parser_consume_token (parser
);
19091 clauses
= c_parser_omp_all_clauses (parser
, OMP_CRITICAL_CLAUSE_MASK
,
19092 "#pragma omp critical");
19093 stmt
= c_parser_omp_structured_block (parser
, if_p
);
19094 return c_finish_omp_critical (loc
, stmt
, name
, clauses
);
19098 # pragma omp depobj ( depobj ) depobj-clause new-line
19101 depend (dependence-type : locator)
19103 update (dependence-type)
19112 c_parser_omp_depobj (c_parser
*parser
)
19114 location_t loc
= c_parser_peek_token (parser
)->location
;
19115 c_parser_consume_pragma (parser
);
19116 matching_parens parens
;
19117 if (!parens
.require_open (parser
))
19119 c_parser_skip_to_pragma_eol (parser
);
19123 tree depobj
= c_parser_expr_no_commas (parser
, NULL
).value
;
19124 if (depobj
!= error_mark_node
)
19126 if (!lvalue_p (depobj
))
19128 error_at (EXPR_LOC_OR_LOC (depobj
, loc
),
19129 "%<depobj%> expression is not lvalue expression");
19130 depobj
= error_mark_node
;
19134 tree addr
= build_unary_op (EXPR_LOC_OR_LOC (depobj
, loc
), ADDR_EXPR
,
19136 if (addr
== error_mark_node
)
19137 depobj
= error_mark_node
;
19139 depobj
= build_indirect_ref (EXPR_LOC_OR_LOC (depobj
, loc
),
19140 addr
, RO_UNARY_STAR
);
19144 parens
.skip_until_found_close (parser
);
19145 tree clause
= NULL_TREE
;
19146 enum omp_clause_depend_kind kind
= OMP_CLAUSE_DEPEND_SOURCE
;
19147 location_t c_loc
= c_parser_peek_token (parser
)->location
;
19148 if (c_parser_next_token_is (parser
, CPP_NAME
))
19150 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
19152 c_parser_consume_token (parser
);
19153 if (!strcmp ("depend", p
))
19155 clause
= c_parser_omp_clause_depend (parser
, NULL_TREE
);
19156 clause
= c_finish_omp_clauses (clause
, C_ORT_OMP
);
19158 clause
= error_mark_node
;
19160 else if (!strcmp ("destroy", p
))
19161 kind
= OMP_CLAUSE_DEPEND_LAST
;
19162 else if (!strcmp ("update", p
))
19164 matching_parens c_parens
;
19165 if (c_parens
.require_open (parser
))
19167 location_t c2_loc
= c_parser_peek_token (parser
)->location
;
19168 if (c_parser_next_token_is (parser
, CPP_NAME
))
19171 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
19173 c_parser_consume_token (parser
);
19174 if (!strcmp ("in", p2
))
19175 kind
= OMP_CLAUSE_DEPEND_IN
;
19176 else if (!strcmp ("out", p2
))
19177 kind
= OMP_CLAUSE_DEPEND_OUT
;
19178 else if (!strcmp ("inout", p2
))
19179 kind
= OMP_CLAUSE_DEPEND_INOUT
;
19180 else if (!strcmp ("mutexinoutset", p2
))
19181 kind
= OMP_CLAUSE_DEPEND_MUTEXINOUTSET
;
19182 else if (!strcmp ("inoutset", p2
))
19183 kind
= OMP_CLAUSE_DEPEND_INOUTSET
;
19185 if (kind
== OMP_CLAUSE_DEPEND_SOURCE
)
19187 clause
= error_mark_node
;
19188 error_at (c2_loc
, "expected %<in%>, %<out%>, %<inout%>, "
19189 "%<mutexinoutset%> or %<inoutset%>");
19191 c_parens
.skip_until_found_close (parser
);
19194 clause
= error_mark_node
;
19197 if (!clause
&& kind
== OMP_CLAUSE_DEPEND_SOURCE
)
19199 clause
= error_mark_node
;
19200 error_at (c_loc
, "expected %<depend%>, %<destroy%> or %<update%> clause");
19202 c_parser_skip_to_pragma_eol (parser
);
19204 c_finish_omp_depobj (loc
, depobj
, kind
, clause
);
19209 # pragma omp flush flush-vars[opt] new-line
19215 # pragma omp flush memory-order-clause new-line */
19218 c_parser_omp_flush (c_parser
*parser
)
19220 location_t loc
= c_parser_peek_token (parser
)->location
;
19221 c_parser_consume_pragma (parser
);
19222 enum memmodel mo
= MEMMODEL_LAST
;
19223 if (c_parser_next_token_is (parser
, CPP_NAME
))
19226 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
19228 if (!strcmp (p
, "seq_cst"))
19229 mo
= MEMMODEL_SEQ_CST
;
19230 else if (!strcmp (p
, "acq_rel"))
19231 mo
= MEMMODEL_ACQ_REL
;
19232 else if (!strcmp (p
, "release"))
19233 mo
= MEMMODEL_RELEASE
;
19234 else if (!strcmp (p
, "acquire"))
19235 mo
= MEMMODEL_ACQUIRE
;
19237 error_at (c_parser_peek_token (parser
)->location
,
19238 "expected %<seq_cst%>, %<acq_rel%>, %<release%> or "
19240 c_parser_consume_token (parser
);
19242 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
19244 if (mo
!= MEMMODEL_LAST
)
19245 error_at (c_parser_peek_token (parser
)->location
,
19246 "%<flush%> list specified together with memory order "
19248 c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ERROR
, NULL
);
19250 else if (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
19251 c_parser_error (parser
, "expected %<(%> or end of line");
19252 c_parser_skip_to_pragma_eol (parser
);
19254 c_finish_omp_flush (loc
, mo
);
19257 /* Parse an OpenMP structured block sequence. KIND is the corresponding
19258 separating directive. */
19261 c_parser_omp_structured_block_sequence (c_parser
*parser
,
19262 enum pragma_kind kind
)
19264 tree stmt
= push_stmt_list ();
19265 c_parser_statement (parser
, NULL
);
19268 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
19270 if (c_parser_next_token_is (parser
, CPP_EOF
))
19273 if (kind
!= PRAGMA_NONE
19274 && c_parser_peek_token (parser
)->pragma_kind
== kind
)
19276 c_parser_statement (parser
, NULL
);
19279 return pop_stmt_list (stmt
);
19285 { structured-block scan-directive structured-block } */
19288 c_parser_omp_scan_loop_body (c_parser
*parser
, bool open_brace_parsed
)
19292 tree clauses
= NULL_TREE
;
19294 loc
= c_parser_peek_token (parser
)->location
;
19295 if (!open_brace_parsed
19296 && !c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
19298 /* Avoid skipping until the end of the block. */
19299 parser
->error
= false;
19303 substmt
= c_parser_omp_structured_block_sequence (parser
, PRAGMA_OMP_SCAN
);
19304 substmt
= build2 (OMP_SCAN
, void_type_node
, substmt
, NULL_TREE
);
19305 SET_EXPR_LOCATION (substmt
, loc
);
19306 add_stmt (substmt
);
19308 loc
= c_parser_peek_token (parser
)->location
;
19309 if (c_parser_peek_token (parser
)->pragma_kind
== PRAGMA_OMP_SCAN
)
19311 enum omp_clause_code clause
= OMP_CLAUSE_ERROR
;
19313 c_parser_consume_pragma (parser
);
19315 if (c_parser_next_token_is (parser
, CPP_NAME
))
19318 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
19319 if (strcmp (p
, "inclusive") == 0)
19320 clause
= OMP_CLAUSE_INCLUSIVE
;
19321 else if (strcmp (p
, "exclusive") == 0)
19322 clause
= OMP_CLAUSE_EXCLUSIVE
;
19324 if (clause
!= OMP_CLAUSE_ERROR
)
19326 c_parser_consume_token (parser
);
19327 clauses
= c_parser_omp_var_list_parens (parser
, clause
, NULL_TREE
);
19330 c_parser_error (parser
, "expected %<inclusive%> or "
19331 "%<exclusive%> clause");
19332 c_parser_skip_to_pragma_eol (parser
);
19335 error ("expected %<#pragma omp scan%>");
19337 clauses
= c_finish_omp_clauses (clauses
, C_ORT_OMP
);
19338 substmt
= c_parser_omp_structured_block_sequence (parser
, PRAGMA_NONE
);
19339 substmt
= build2 (OMP_SCAN
, void_type_node
, substmt
, clauses
);
19340 SET_EXPR_LOCATION (substmt
, loc
);
19341 add_stmt (substmt
);
19343 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
,
19347 /* Parse the restricted form of loop statements allowed by OpenACC and OpenMP.
19348 The real trick here is to determine the loop control variable early
19349 so that we can push a new decl if necessary to make it private.
19350 LOC is the location of the "acc" or "omp" in "#pragma acc" or "#pragma omp",
19354 c_parser_omp_for_loop (location_t loc
, c_parser
*parser
, enum tree_code code
,
19355 tree clauses
, tree
*cclauses
, bool *if_p
)
19357 tree decl
, cond
, incr
, body
, init
, stmt
, cl
;
19358 unsigned char save_in_statement
;
19359 tree declv
, condv
, incrv
, initv
, ret
= NULL_TREE
;
19360 tree pre_body
= NULL_TREE
, this_pre_body
;
19361 tree ordered_cl
= NULL_TREE
;
19362 bool fail
= false, open_brace_parsed
= false;
19363 int i
, collapse
= 1, ordered
= 0, count
, nbraces
= 0;
19364 location_t for_loc
;
19365 bool tiling
= false;
19366 bool inscan
= false;
19367 vec
<tree
, va_gc
> *for_block
= make_tree_vector ();
19369 for (cl
= clauses
; cl
; cl
= OMP_CLAUSE_CHAIN (cl
))
19370 if (OMP_CLAUSE_CODE (cl
) == OMP_CLAUSE_COLLAPSE
)
19371 collapse
= tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (cl
));
19372 else if (OMP_CLAUSE_CODE (cl
) == OMP_CLAUSE_TILE
)
19375 collapse
= list_length (OMP_CLAUSE_TILE_LIST (cl
));
19377 else if (OMP_CLAUSE_CODE (cl
) == OMP_CLAUSE_ORDERED
19378 && OMP_CLAUSE_ORDERED_EXPR (cl
))
19381 ordered
= tree_to_shwi (OMP_CLAUSE_ORDERED_EXPR (cl
));
19383 else if (OMP_CLAUSE_CODE (cl
) == OMP_CLAUSE_REDUCTION
19384 && OMP_CLAUSE_REDUCTION_INSCAN (cl
)
19385 && (code
== OMP_SIMD
|| code
== OMP_FOR
))
19388 if (ordered
&& ordered
< collapse
)
19390 error_at (OMP_CLAUSE_LOCATION (ordered_cl
),
19391 "%<ordered%> clause parameter is less than %<collapse%>");
19392 OMP_CLAUSE_ORDERED_EXPR (ordered_cl
)
19393 = build_int_cst (NULL_TREE
, collapse
);
19394 ordered
= collapse
;
19398 for (tree
*pc
= &clauses
; *pc
; )
19399 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_LINEAR
)
19401 error_at (OMP_CLAUSE_LOCATION (*pc
),
19402 "%<linear%> clause may not be specified together "
19403 "with %<ordered%> clause with a parameter");
19404 *pc
= OMP_CLAUSE_CHAIN (*pc
);
19407 pc
= &OMP_CLAUSE_CHAIN (*pc
);
19410 gcc_assert (tiling
|| (collapse
>= 1 && ordered
>= 0));
19411 count
= ordered
? ordered
: collapse
;
19413 declv
= make_tree_vec (count
);
19414 initv
= make_tree_vec (count
);
19415 condv
= make_tree_vec (count
);
19416 incrv
= make_tree_vec (count
);
19418 if (!c_parser_next_token_is_keyword (parser
, RID_FOR
))
19420 c_parser_error (parser
, "for statement expected");
19423 for_loc
= c_parser_peek_token (parser
)->location
;
19424 c_parser_consume_token (parser
);
19426 /* Forbid break/continue in the loop initializer, condition, and
19427 increment expressions. */
19428 save_in_statement
= in_statement
;
19429 in_statement
= IN_OMP_BLOCK
;
19431 for (i
= 0; i
< count
; i
++)
19433 int bracecount
= 0;
19435 matching_parens parens
;
19436 if (!parens
.require_open (parser
))
19439 /* Parse the initialization declaration or expression. */
19440 if (c_parser_next_tokens_start_declaration (parser
))
19443 vec_safe_push (for_block
, c_begin_compound_stmt (true));
19444 this_pre_body
= push_stmt_list ();
19445 c_in_omp_for
= true;
19446 c_parser_declaration_or_fndef (parser
, true, true, true, true, true);
19447 c_in_omp_for
= false;
19450 this_pre_body
= pop_stmt_list (this_pre_body
);
19454 pre_body
= push_stmt_list ();
19456 add_stmt (this_pre_body
);
19457 pre_body
= pop_stmt_list (pre_body
);
19460 pre_body
= this_pre_body
;
19462 decl
= check_for_loop_decls (for_loc
, flag_isoc99
);
19465 if (DECL_INITIAL (decl
) == error_mark_node
)
19466 decl
= error_mark_node
;
19469 else if (c_parser_next_token_is (parser
, CPP_NAME
)
19470 && c_parser_peek_2nd_token (parser
)->type
== CPP_EQ
)
19472 struct c_expr decl_exp
;
19473 struct c_expr init_exp
;
19474 location_t init_loc
;
19476 decl_exp
= c_parser_postfix_expression (parser
);
19477 decl
= decl_exp
.value
;
19479 c_parser_require (parser
, CPP_EQ
, "expected %<=%>");
19481 init_loc
= c_parser_peek_token (parser
)->location
;
19482 init_exp
= c_parser_expr_no_commas (parser
, NULL
);
19483 init_exp
= default_function_array_read_conversion (init_loc
,
19485 c_in_omp_for
= true;
19486 init
= build_modify_expr (init_loc
, decl
, decl_exp
.original_type
,
19487 NOP_EXPR
, init_loc
, init_exp
.value
,
19488 init_exp
.original_type
);
19489 c_in_omp_for
= false;
19490 init
= c_process_expr_stmt (init_loc
, init
);
19492 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
19497 c_parser_error (parser
,
19498 "expected iteration declaration or initialization");
19499 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
19505 /* Parse the loop condition. */
19507 if (c_parser_next_token_is_not (parser
, CPP_SEMICOLON
))
19509 location_t cond_loc
= c_parser_peek_token (parser
)->location
;
19510 c_in_omp_for
= true;
19511 struct c_expr cond_expr
19512 = c_parser_binary_expression (parser
, NULL
, NULL_TREE
);
19513 c_in_omp_for
= false;
19515 cond
= cond_expr
.value
;
19516 cond
= c_objc_common_truthvalue_conversion (cond_loc
, cond
);
19517 switch (cond_expr
.original_code
)
19525 if (code
!= OACC_LOOP
)
19529 /* Can't be cond = error_mark_node, because we want to preserve
19530 the location until c_finish_omp_for. */
19531 cond
= build1 (NOP_EXPR
, boolean_type_node
, error_mark_node
);
19534 protected_set_expr_location (cond
, cond_loc
);
19536 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
19538 /* Parse the increment expression. */
19540 if (c_parser_next_token_is_not (parser
, CPP_CLOSE_PAREN
))
19542 location_t incr_loc
= c_parser_peek_token (parser
)->location
;
19544 incr
= c_process_expr_stmt (incr_loc
,
19545 c_parser_expression (parser
).value
);
19547 parens
.skip_until_found_close (parser
);
19549 if (decl
== NULL
|| decl
== error_mark_node
|| init
== error_mark_node
)
19553 TREE_VEC_ELT (declv
, i
) = decl
;
19554 TREE_VEC_ELT (initv
, i
) = init
;
19555 TREE_VEC_ELT (condv
, i
) = cond
;
19556 TREE_VEC_ELT (incrv
, i
) = incr
;
19560 if (i
== count
- 1)
19563 /* FIXME: OpenMP 3.0 draft isn't very clear on what exactly is allowed
19564 in between the collapsed for loops to be still considered perfectly
19565 nested. Hopefully the final version clarifies this.
19566 For now handle (multiple) {'s and empty statements. */
19569 if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
19571 c_parser_consume_token (parser
);
19574 else if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
19576 c_parser_consume_token (parser
);
19579 else if (bracecount
19580 && c_parser_next_token_is (parser
, CPP_SEMICOLON
))
19581 c_parser_consume_token (parser
);
19584 c_parser_error (parser
, "not enough perfectly nested loops");
19587 open_brace_parsed
= true;
19597 nbraces
+= bracecount
;
19603 in_statement
= IN_OMP_FOR
;
19604 body
= push_stmt_list ();
19607 c_parser_omp_scan_loop_body (parser
, open_brace_parsed
);
19608 else if (open_brace_parsed
)
19610 location_t here
= c_parser_peek_token (parser
)->location
;
19611 stmt
= c_begin_compound_stmt (true);
19612 c_parser_compound_statement_nostart (parser
);
19613 add_stmt (c_end_compound_stmt (here
, stmt
, true));
19616 add_stmt (c_parser_c99_block_statement (parser
, if_p
));
19618 body
= pop_stmt_list (body
);
19619 in_statement
= save_in_statement
;
19623 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
19625 c_parser_consume_token (parser
);
19628 else if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
19629 c_parser_consume_token (parser
);
19632 c_parser_error (parser
, "collapsed loops not perfectly nested");
19635 location_t here
= c_parser_peek_token (parser
)->location
;
19636 stmt
= c_begin_compound_stmt (true);
19638 c_parser_compound_statement_nostart (parser
);
19639 body
= c_end_compound_stmt (here
, stmt
, true);
19646 /* Only bother calling c_finish_omp_for if we haven't already generated
19647 an error from the initialization parsing. */
19650 c_in_omp_for
= true;
19651 stmt
= c_finish_omp_for (loc
, code
, declv
, NULL
, initv
, condv
,
19652 incrv
, body
, pre_body
, true);
19653 c_in_omp_for
= false;
19655 /* Check for iterators appearing in lb, b or incr expressions. */
19656 if (stmt
&& !c_omp_check_loop_iv (stmt
, declv
, NULL
))
19663 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (stmt
)); i
++)
19665 tree init
= TREE_VEC_ELT (OMP_FOR_INIT (stmt
), i
);
19666 gcc_assert (TREE_CODE (init
) == MODIFY_EXPR
);
19667 tree decl
= TREE_OPERAND (init
, 0);
19668 tree cond
= TREE_VEC_ELT (OMP_FOR_COND (stmt
), i
);
19669 gcc_assert (COMPARISON_CLASS_P (cond
));
19670 gcc_assert (TREE_OPERAND (cond
, 0) == decl
);
19672 tree op0
= TREE_OPERAND (init
, 1);
19673 if (!OMP_FOR_NON_RECTANGULAR (stmt
)
19674 || TREE_CODE (op0
) != TREE_VEC
)
19675 TREE_OPERAND (init
, 1) = c_fully_fold (op0
, false, NULL
);
19678 TREE_VEC_ELT (op0
, 1)
19679 = c_fully_fold (TREE_VEC_ELT (op0
, 1), false, NULL
);
19680 TREE_VEC_ELT (op0
, 2)
19681 = c_fully_fold (TREE_VEC_ELT (op0
, 2), false, NULL
);
19684 tree op1
= TREE_OPERAND (cond
, 1);
19685 if (!OMP_FOR_NON_RECTANGULAR (stmt
)
19686 || TREE_CODE (op1
) != TREE_VEC
)
19687 TREE_OPERAND (cond
, 1) = c_fully_fold (op1
, false, NULL
);
19690 TREE_VEC_ELT (op1
, 1)
19691 = c_fully_fold (TREE_VEC_ELT (op1
, 1), false, NULL
);
19692 TREE_VEC_ELT (op1
, 2)
19693 = c_fully_fold (TREE_VEC_ELT (op1
, 2), false, NULL
);
19697 if (cclauses
!= NULL
19698 && cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
] != NULL
)
19701 for (c
= &cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
]; *c
; )
19702 if (OMP_CLAUSE_CODE (*c
) != OMP_CLAUSE_FIRSTPRIVATE
19703 && OMP_CLAUSE_CODE (*c
) != OMP_CLAUSE_LASTPRIVATE
)
19704 c
= &OMP_CLAUSE_CHAIN (*c
);
19707 for (i
= 0; i
< count
; i
++)
19708 if (TREE_VEC_ELT (declv
, i
) == OMP_CLAUSE_DECL (*c
))
19711 c
= &OMP_CLAUSE_CHAIN (*c
);
19712 else if (OMP_CLAUSE_CODE (*c
) == OMP_CLAUSE_FIRSTPRIVATE
)
19715 "iteration variable %qD should not be firstprivate",
19716 OMP_CLAUSE_DECL (*c
));
19717 *c
= OMP_CLAUSE_CHAIN (*c
);
19721 /* Move lastprivate (decl) clause to OMP_FOR_CLAUSES. */
19723 *c
= OMP_CLAUSE_CHAIN (*c
);
19724 if (code
== OMP_SIMD
)
19726 OMP_CLAUSE_CHAIN (l
)
19727 = cclauses
[C_OMP_CLAUSE_SPLIT_FOR
];
19728 cclauses
[C_OMP_CLAUSE_SPLIT_FOR
] = l
;
19732 OMP_CLAUSE_CHAIN (l
) = clauses
;
19738 OMP_FOR_CLAUSES (stmt
) = clauses
;
19743 while (!for_block
->is_empty ())
19745 /* FIXME diagnostics: LOC below should be the actual location of
19746 this particular for block. We need to build a list of
19747 locations to go along with FOR_BLOCK. */
19748 stmt
= c_end_compound_stmt (loc
, for_block
->pop (), true);
19751 release_tree_vector (for_block
);
19755 /* Helper function for OpenMP parsing, split clauses and call
19756 finish_omp_clauses on each of the set of clauses afterwards. */
19759 omp_split_clauses (location_t loc
, enum tree_code code
,
19760 omp_clause_mask mask
, tree clauses
, tree
*cclauses
)
19763 c_omp_split_clauses (loc
, code
, mask
, clauses
, cclauses
);
19764 for (i
= 0; i
< C_OMP_CLAUSE_SPLIT_COUNT
; i
++)
19766 cclauses
[i
] = c_finish_omp_clauses (cclauses
[i
],
19767 i
== C_OMP_CLAUSE_SPLIT_TARGET
19768 ? C_ORT_OMP_TARGET
: C_ORT_OMP
);
19772 #pragma omp loop loop-clause[optseq] new-line
19775 LOC is the location of the #pragma token.
19778 #define OMP_LOOP_CLAUSE_MASK \
19779 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19780 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
19781 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
19782 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
19783 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_BIND) \
19784 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
19787 c_parser_omp_loop (location_t loc
, c_parser
*parser
,
19788 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
19791 tree block
, clauses
, ret
;
19793 strcat (p_name
, " loop");
19794 mask
|= OMP_LOOP_CLAUSE_MASK
;
19796 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
19799 omp_split_clauses (loc
, OMP_LOOP
, mask
, clauses
, cclauses
);
19800 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_LOOP
];
19803 block
= c_begin_compound_stmt (true);
19804 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_LOOP
, clauses
, cclauses
, if_p
);
19805 block
= c_end_compound_stmt (loc
, block
, true);
19812 #pragma omp simd simd-clause[optseq] new-line
19815 LOC is the location of the #pragma token.
19818 #define OMP_SIMD_CLAUSE_MASK \
19819 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SAFELEN) \
19820 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
19821 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
19822 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
19823 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19824 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
19825 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
19826 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
19827 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
19828 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NONTEMPORAL) \
19829 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
19832 c_parser_omp_simd (location_t loc
, c_parser
*parser
,
19833 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
19836 tree block
, clauses
, ret
;
19838 strcat (p_name
, " simd");
19839 mask
|= OMP_SIMD_CLAUSE_MASK
;
19841 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
19844 omp_split_clauses (loc
, OMP_SIMD
, mask
, clauses
, cclauses
);
19845 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_SIMD
];
19846 tree c
= omp_find_clause (cclauses
[C_OMP_CLAUSE_SPLIT_FOR
],
19847 OMP_CLAUSE_ORDERED
);
19848 if (c
&& OMP_CLAUSE_ORDERED_EXPR (c
))
19850 error_at (OMP_CLAUSE_LOCATION (c
),
19851 "%<ordered%> clause with parameter may not be specified "
19852 "on %qs construct", p_name
);
19853 OMP_CLAUSE_ORDERED_EXPR (c
) = NULL_TREE
;
19857 block
= c_begin_compound_stmt (true);
19858 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_SIMD
, clauses
, cclauses
, if_p
);
19859 block
= c_end_compound_stmt (loc
, block
, true);
19866 #pragma omp for for-clause[optseq] new-line
19870 #pragma omp for simd for-simd-clause[optseq] new-line
19873 LOC is the location of the #pragma token.
19876 #define OMP_FOR_CLAUSE_MASK \
19877 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19878 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
19879 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
19880 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
19881 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
19882 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED) \
19883 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE) \
19884 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
19885 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
19886 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
19887 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
19890 c_parser_omp_for (location_t loc
, c_parser
*parser
,
19891 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
19894 tree block
, clauses
, ret
;
19896 strcat (p_name
, " for");
19897 mask
|= OMP_FOR_CLAUSE_MASK
;
19898 /* parallel for{, simd} disallows nowait clause, but for
19899 target {teams distribute ,}parallel for{, simd} it should be accepted. */
19900 if (cclauses
&& (mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_MAP
)) == 0)
19901 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_NOWAIT
);
19902 /* Composite distribute parallel for{, simd} disallows ordered clause. */
19903 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
)) != 0)
19904 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_ORDERED
);
19906 if (c_parser_next_token_is (parser
, CPP_NAME
))
19908 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
19910 if (strcmp (p
, "simd") == 0)
19912 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
19913 if (cclauses
== NULL
)
19914 cclauses
= cclauses_buf
;
19916 c_parser_consume_token (parser
);
19917 if (!flag_openmp
) /* flag_openmp_simd */
19918 return c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
,
19920 block
= c_begin_compound_stmt (true);
19921 ret
= c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
19922 block
= c_end_compound_stmt (loc
, block
, true);
19923 if (ret
== NULL_TREE
)
19925 ret
= make_node (OMP_FOR
);
19926 TREE_TYPE (ret
) = void_type_node
;
19927 OMP_FOR_BODY (ret
) = block
;
19928 OMP_FOR_CLAUSES (ret
) = cclauses
[C_OMP_CLAUSE_SPLIT_FOR
];
19929 SET_EXPR_LOCATION (ret
, loc
);
19934 if (!flag_openmp
) /* flag_openmp_simd */
19936 c_parser_skip_to_pragma_eol (parser
, false);
19940 /* Composite distribute parallel for disallows linear clause. */
19941 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
)) != 0)
19942 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_LINEAR
);
19944 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
19947 omp_split_clauses (loc
, OMP_FOR
, mask
, clauses
, cclauses
);
19948 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_FOR
];
19951 block
= c_begin_compound_stmt (true);
19952 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_FOR
, clauses
, cclauses
, if_p
);
19953 block
= c_end_compound_stmt (loc
, block
, true);
19959 static tree
c_parser_omp_taskloop (location_t
, c_parser
*, char *,
19960 omp_clause_mask
, tree
*, bool *);
19963 # pragma omp master new-line
19966 LOC is the location of the #pragma token.
19970 c_parser_omp_master (location_t loc
, c_parser
*parser
,
19971 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
19974 tree block
, clauses
, ret
;
19976 strcat (p_name
, " master");
19978 if (c_parser_next_token_is (parser
, CPP_NAME
))
19980 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
19982 if (strcmp (p
, "taskloop") == 0)
19984 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
19985 if (cclauses
== NULL
)
19986 cclauses
= cclauses_buf
;
19988 c_parser_consume_token (parser
);
19989 if (!flag_openmp
) /* flag_openmp_simd */
19990 return c_parser_omp_taskloop (loc
, parser
, p_name
, mask
, cclauses
,
19992 block
= c_begin_compound_stmt (true);
19993 ret
= c_parser_omp_taskloop (loc
, parser
, p_name
, mask
, cclauses
,
19995 block
= c_end_compound_stmt (loc
, block
, true);
19996 if (ret
== NULL_TREE
)
19998 ret
= c_finish_omp_master (loc
, block
);
19999 OMP_MASTER_COMBINED (ret
) = 1;
20003 if (!flag_openmp
) /* flag_openmp_simd */
20005 c_parser_skip_to_pragma_eol (parser
, false);
20011 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, false);
20012 omp_split_clauses (loc
, OMP_MASTER
, mask
, clauses
, cclauses
);
20015 c_parser_skip_to_pragma_eol (parser
);
20017 return c_finish_omp_master (loc
, c_parser_omp_structured_block (parser
,
20022 # pragma omp masked masked-clauses new-line
20025 LOC is the location of the #pragma token.
20028 #define OMP_MASKED_CLAUSE_MASK \
20029 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FILTER)
20032 c_parser_omp_masked (location_t loc
, c_parser
*parser
,
20033 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
20036 tree block
, clauses
, ret
;
20038 strcat (p_name
, " masked");
20039 mask
|= OMP_MASKED_CLAUSE_MASK
;
20041 if (c_parser_next_token_is (parser
, CPP_NAME
))
20043 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
20045 if (strcmp (p
, "taskloop") == 0)
20047 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
20048 if (cclauses
== NULL
)
20049 cclauses
= cclauses_buf
;
20051 c_parser_consume_token (parser
);
20052 if (!flag_openmp
) /* flag_openmp_simd */
20053 return c_parser_omp_taskloop (loc
, parser
, p_name
, mask
, cclauses
,
20055 block
= c_begin_compound_stmt (true);
20056 ret
= c_parser_omp_taskloop (loc
, parser
, p_name
, mask
, cclauses
,
20058 block
= c_end_compound_stmt (loc
, block
, true);
20059 if (ret
== NULL_TREE
)
20061 ret
= c_finish_omp_masked (loc
, block
,
20062 cclauses
[C_OMP_CLAUSE_SPLIT_MASKED
]);
20063 OMP_MASKED_COMBINED (ret
) = 1;
20067 if (!flag_openmp
) /* flag_openmp_simd */
20069 c_parser_skip_to_pragma_eol (parser
, false);
20073 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
20076 omp_split_clauses (loc
, OMP_MASKED
, mask
, clauses
, cclauses
);
20077 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_MASKED
];
20080 return c_finish_omp_masked (loc
, c_parser_omp_structured_block (parser
,
20086 # pragma omp ordered new-line
20090 # pragma omp ordered ordered-clauses new-line
20093 # pragma omp ordered depend-clauses new-line */
20095 #define OMP_ORDERED_CLAUSE_MASK \
20096 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREADS) \
20097 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMD))
20099 #define OMP_ORDERED_DEPEND_CLAUSE_MASK \
20100 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)
20103 c_parser_omp_ordered (c_parser
*parser
, enum pragma_context context
,
20106 location_t loc
= c_parser_peek_token (parser
)->location
;
20107 c_parser_consume_pragma (parser
);
20109 if (context
!= pragma_stmt
&& context
!= pragma_compound
)
20111 c_parser_error (parser
, "expected declaration specifiers");
20112 c_parser_skip_to_pragma_eol (parser
, false);
20116 if (c_parser_next_token_is (parser
, CPP_NAME
))
20118 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
20120 if (!strcmp ("depend", p
))
20122 if (!flag_openmp
) /* flag_openmp_simd */
20124 c_parser_skip_to_pragma_eol (parser
, false);
20127 if (context
== pragma_stmt
)
20130 "%<#pragma omp ordered%> with %<depend%> clause may "
20131 "only be used in compound statements");
20132 c_parser_skip_to_pragma_eol (parser
, false);
20137 = c_parser_omp_all_clauses (parser
,
20138 OMP_ORDERED_DEPEND_CLAUSE_MASK
,
20139 "#pragma omp ordered");
20140 c_finish_omp_ordered (loc
, clauses
, NULL_TREE
);
20145 tree clauses
= c_parser_omp_all_clauses (parser
, OMP_ORDERED_CLAUSE_MASK
,
20146 "#pragma omp ordered");
20148 if (!flag_openmp
/* flag_openmp_simd */
20149 && omp_find_clause (clauses
, OMP_CLAUSE_SIMD
) == NULL_TREE
)
20152 c_finish_omp_ordered (loc
, clauses
,
20153 c_parser_omp_structured_block (parser
, if_p
));
20160 { section-sequence }
20163 section-directive[opt] structured-block
20164 section-sequence section-directive structured-block
20166 OpenMP 5.1 allows structured-block-sequence instead of structured-block.
20168 SECTIONS_LOC is the location of the #pragma omp sections. */
20171 c_parser_omp_sections_scope (location_t sections_loc
, c_parser
*parser
)
20173 tree stmt
, substmt
;
20174 bool error_suppress
= false;
20177 loc
= c_parser_peek_token (parser
)->location
;
20178 if (!c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
20180 /* Avoid skipping until the end of the block. */
20181 parser
->error
= false;
20185 stmt
= push_stmt_list ();
20187 if (c_parser_peek_token (parser
)->pragma_kind
!= PRAGMA_OMP_SECTION
)
20189 substmt
= c_parser_omp_structured_block_sequence (parser
,
20190 PRAGMA_OMP_SECTION
);
20191 substmt
= build1 (OMP_SECTION
, void_type_node
, substmt
);
20192 SET_EXPR_LOCATION (substmt
, loc
);
20193 add_stmt (substmt
);
20198 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
20200 if (c_parser_next_token_is (parser
, CPP_EOF
))
20203 loc
= c_parser_peek_token (parser
)->location
;
20204 if (c_parser_peek_token (parser
)->pragma_kind
== PRAGMA_OMP_SECTION
)
20206 c_parser_consume_pragma (parser
);
20207 c_parser_skip_to_pragma_eol (parser
);
20208 error_suppress
= false;
20210 else if (!error_suppress
)
20212 error_at (loc
, "expected %<#pragma omp section%> or %<}%>");
20213 error_suppress
= true;
20216 substmt
= c_parser_omp_structured_block_sequence (parser
,
20217 PRAGMA_OMP_SECTION
);
20218 substmt
= build1 (OMP_SECTION
, void_type_node
, substmt
);
20219 SET_EXPR_LOCATION (substmt
, loc
);
20220 add_stmt (substmt
);
20222 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
,
20223 "expected %<#pragma omp section%> or %<}%>");
20225 substmt
= pop_stmt_list (stmt
);
20227 stmt
= make_node (OMP_SECTIONS
);
20228 SET_EXPR_LOCATION (stmt
, sections_loc
);
20229 TREE_TYPE (stmt
) = void_type_node
;
20230 OMP_SECTIONS_BODY (stmt
) = substmt
;
20232 return add_stmt (stmt
);
20236 # pragma omp sections sections-clause[optseq] newline
20239 LOC is the location of the #pragma token.
20242 #define OMP_SECTIONS_CLAUSE_MASK \
20243 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20244 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20245 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
20246 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
20247 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20248 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20251 c_parser_omp_sections (location_t loc
, c_parser
*parser
,
20252 char *p_name
, omp_clause_mask mask
, tree
*cclauses
)
20254 tree block
, clauses
, ret
;
20256 strcat (p_name
, " sections");
20257 mask
|= OMP_SECTIONS_CLAUSE_MASK
;
20259 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_NOWAIT
);
20261 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
20264 omp_split_clauses (loc
, OMP_SECTIONS
, mask
, clauses
, cclauses
);
20265 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_SECTIONS
];
20268 block
= c_begin_compound_stmt (true);
20269 ret
= c_parser_omp_sections_scope (loc
, parser
);
20271 OMP_SECTIONS_CLAUSES (ret
) = clauses
;
20272 block
= c_end_compound_stmt (loc
, block
, true);
20279 # pragma omp parallel parallel-clause[optseq] new-line
20281 # pragma omp parallel for parallel-for-clause[optseq] new-line
20283 # pragma omp parallel sections parallel-sections-clause[optseq] new-line
20287 # pragma omp parallel for simd parallel-for-simd-clause[optseq] new-line
20290 LOC is the location of the #pragma token.
20293 #define OMP_PARALLEL_CLAUSE_MASK \
20294 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
20295 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20296 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20297 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
20298 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
20299 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN) \
20300 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
20301 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS) \
20302 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20303 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PROC_BIND))
20306 c_parser_omp_parallel (location_t loc
, c_parser
*parser
,
20307 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
20310 tree stmt
, clauses
, block
;
20312 strcat (p_name
, " parallel");
20313 mask
|= OMP_PARALLEL_CLAUSE_MASK
;
20314 /* #pragma omp target parallel{, for, for simd} disallow copyin clause. */
20315 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_MAP
)) != 0
20316 && (mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
)) == 0)
20317 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_COPYIN
);
20319 if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
20321 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
20322 if (cclauses
== NULL
)
20323 cclauses
= cclauses_buf
;
20325 c_parser_consume_token (parser
);
20326 if (!flag_openmp
) /* flag_openmp_simd */
20327 return c_parser_omp_for (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
20328 block
= c_begin_omp_parallel ();
20329 tree ret
= c_parser_omp_for (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
20331 = c_finish_omp_parallel (loc
, cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
20333 if (ret
== NULL_TREE
)
20335 OMP_PARALLEL_COMBINED (stmt
) = 1;
20338 /* When combined with distribute, parallel has to be followed by for.
20339 #pragma omp target parallel is allowed though. */
20341 && (mask
& (OMP_CLAUSE_MASK_1
20342 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
)) != 0)
20344 error_at (loc
, "expected %<for%> after %qs", p_name
);
20345 c_parser_skip_to_pragma_eol (parser
);
20348 else if (c_parser_next_token_is (parser
, CPP_NAME
))
20350 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
20351 if (cclauses
== NULL
&& strcmp (p
, "masked") == 0)
20353 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
20354 cclauses
= cclauses_buf
;
20356 c_parser_consume_token (parser
);
20357 if (!flag_openmp
) /* flag_openmp_simd */
20358 return c_parser_omp_masked (loc
, parser
, p_name
, mask
, cclauses
,
20360 block
= c_begin_omp_parallel ();
20361 tree ret
= c_parser_omp_masked (loc
, parser
, p_name
, mask
, cclauses
,
20363 stmt
= c_finish_omp_parallel (loc
,
20364 cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
20368 /* masked does have just filter clause, but during gimplification
20369 isn't represented by a gimplification omp context, so for
20370 #pragma omp parallel masked don't set OMP_PARALLEL_COMBINED,
20372 #pragma omp parallel masked
20373 #pragma omp taskloop simd lastprivate (x)
20374 isn't confused with
20375 #pragma omp parallel masked taskloop simd lastprivate (x) */
20376 if (OMP_MASKED_COMBINED (ret
))
20377 OMP_PARALLEL_COMBINED (stmt
) = 1;
20380 else if (cclauses
== NULL
&& strcmp (p
, "master") == 0)
20382 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
20383 cclauses
= cclauses_buf
;
20385 c_parser_consume_token (parser
);
20386 if (!flag_openmp
) /* flag_openmp_simd */
20387 return c_parser_omp_master (loc
, parser
, p_name
, mask
, cclauses
,
20389 block
= c_begin_omp_parallel ();
20390 tree ret
= c_parser_omp_master (loc
, parser
, p_name
, mask
, cclauses
,
20392 stmt
= c_finish_omp_parallel (loc
,
20393 cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
20397 /* master doesn't have any clauses and during gimplification
20398 isn't represented by a gimplification omp context, so for
20399 #pragma omp parallel master don't set OMP_PARALLEL_COMBINED,
20401 #pragma omp parallel master
20402 #pragma omp taskloop simd lastprivate (x)
20403 isn't confused with
20404 #pragma omp parallel master taskloop simd lastprivate (x) */
20405 if (OMP_MASTER_COMBINED (ret
))
20406 OMP_PARALLEL_COMBINED (stmt
) = 1;
20409 else if (strcmp (p
, "loop") == 0)
20411 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
20412 if (cclauses
== NULL
)
20413 cclauses
= cclauses_buf
;
20415 c_parser_consume_token (parser
);
20416 if (!flag_openmp
) /* flag_openmp_simd */
20417 return c_parser_omp_loop (loc
, parser
, p_name
, mask
, cclauses
,
20419 block
= c_begin_omp_parallel ();
20420 tree ret
= c_parser_omp_loop (loc
, parser
, p_name
, mask
, cclauses
,
20423 = c_finish_omp_parallel (loc
,
20424 cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
20426 if (ret
== NULL_TREE
)
20428 OMP_PARALLEL_COMBINED (stmt
) = 1;
20431 else if (!flag_openmp
) /* flag_openmp_simd */
20433 c_parser_skip_to_pragma_eol (parser
, false);
20436 else if (cclauses
== NULL
&& strcmp (p
, "sections") == 0)
20438 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
20439 cclauses
= cclauses_buf
;
20441 c_parser_consume_token (parser
);
20442 block
= c_begin_omp_parallel ();
20443 c_parser_omp_sections (loc
, parser
, p_name
, mask
, cclauses
);
20444 stmt
= c_finish_omp_parallel (loc
,
20445 cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
20447 OMP_PARALLEL_COMBINED (stmt
) = 1;
20451 else if (!flag_openmp
) /* flag_openmp_simd */
20453 c_parser_skip_to_pragma_eol (parser
, false);
20457 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
20460 omp_split_clauses (loc
, OMP_PARALLEL
, mask
, clauses
, cclauses
);
20461 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
];
20464 block
= c_begin_omp_parallel ();
20465 c_parser_statement (parser
, if_p
);
20466 stmt
= c_finish_omp_parallel (loc
, clauses
, block
);
20472 # pragma omp single single-clause[optseq] new-line
20475 LOC is the location of the #pragma.
20478 #define OMP_SINGLE_CLAUSE_MASK \
20479 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20480 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20481 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYPRIVATE) \
20482 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20483 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20486 c_parser_omp_single (location_t loc
, c_parser
*parser
, bool *if_p
)
20488 tree stmt
= make_node (OMP_SINGLE
);
20489 SET_EXPR_LOCATION (stmt
, loc
);
20490 TREE_TYPE (stmt
) = void_type_node
;
20492 OMP_SINGLE_CLAUSES (stmt
)
20493 = c_parser_omp_all_clauses (parser
, OMP_SINGLE_CLAUSE_MASK
,
20494 "#pragma omp single");
20495 OMP_SINGLE_BODY (stmt
) = c_parser_omp_structured_block (parser
, if_p
);
20497 return add_stmt (stmt
);
20501 # pragma omp scope scope-clause[optseq] new-line
20504 LOC is the location of the #pragma.
20507 #define OMP_SCOPE_CLAUSE_MASK \
20508 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20509 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20510 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
20511 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20512 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20515 c_parser_omp_scope (location_t loc
, c_parser
*parser
, bool *if_p
)
20517 tree stmt
= make_node (OMP_SCOPE
);
20518 SET_EXPR_LOCATION (stmt
, loc
);
20519 TREE_TYPE (stmt
) = void_type_node
;
20521 OMP_SCOPE_CLAUSES (stmt
)
20522 = c_parser_omp_all_clauses (parser
, OMP_SCOPE_CLAUSE_MASK
,
20523 "#pragma omp scope");
20524 OMP_SCOPE_BODY (stmt
) = c_parser_omp_structured_block (parser
, if_p
);
20526 return add_stmt (stmt
);
20530 # pragma omp task task-clause[optseq] new-line
20532 LOC is the location of the #pragma.
20535 #define OMP_TASK_CLAUSE_MASK \
20536 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
20537 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
20538 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
20539 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20540 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20541 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
20542 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
20543 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
20544 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
20545 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
20546 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20547 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION) \
20548 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DETACH) \
20549 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_AFFINITY))
20552 c_parser_omp_task (location_t loc
, c_parser
*parser
, bool *if_p
)
20554 tree clauses
, block
;
20556 clauses
= c_parser_omp_all_clauses (parser
, OMP_TASK_CLAUSE_MASK
,
20557 "#pragma omp task");
20559 block
= c_begin_omp_task ();
20560 c_parser_statement (parser
, if_p
);
20561 return c_finish_omp_task (loc
, clauses
, block
);
20565 # pragma omp taskwait new-line
20568 # pragma omp taskwait taskwait-clause[optseq] new-line
20571 #define OMP_TASKWAIT_CLAUSE_MASK \
20572 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
20573 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20576 c_parser_omp_taskwait (c_parser
*parser
)
20578 location_t loc
= c_parser_peek_token (parser
)->location
;
20579 c_parser_consume_pragma (parser
);
20582 = c_parser_omp_all_clauses (parser
, OMP_TASKWAIT_CLAUSE_MASK
,
20583 "#pragma omp taskwait");
20587 tree stmt
= make_node (OMP_TASK
);
20588 TREE_TYPE (stmt
) = void_node
;
20589 OMP_TASK_CLAUSES (stmt
) = clauses
;
20590 OMP_TASK_BODY (stmt
) = NULL_TREE
;
20591 SET_EXPR_LOCATION (stmt
, loc
);
20595 c_finish_omp_taskwait (loc
);
20599 # pragma omp taskyield new-line
20603 c_parser_omp_taskyield (c_parser
*parser
)
20605 location_t loc
= c_parser_peek_token (parser
)->location
;
20606 c_parser_consume_pragma (parser
);
20607 c_parser_skip_to_pragma_eol (parser
);
20609 c_finish_omp_taskyield (loc
);
20613 # pragma omp taskgroup new-line
20616 # pragma omp taskgroup taskgroup-clause[optseq] new-line
20619 #define OMP_TASKGROUP_CLAUSE_MASK \
20620 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20621 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASK_REDUCTION))
20624 c_parser_omp_taskgroup (location_t loc
, c_parser
*parser
, bool *if_p
)
20626 tree clauses
= c_parser_omp_all_clauses (parser
, OMP_TASKGROUP_CLAUSE_MASK
,
20627 "#pragma omp taskgroup");
20629 tree body
= c_parser_omp_structured_block (parser
, if_p
);
20630 return c_finish_omp_taskgroup (loc
, body
, clauses
);
20634 # pragma omp cancel cancel-clause[optseq] new-line
20636 LOC is the location of the #pragma.
20639 #define OMP_CANCEL_CLAUSE_MASK \
20640 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
20641 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
20642 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
20643 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP) \
20644 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF))
20647 c_parser_omp_cancel (c_parser
*parser
)
20649 location_t loc
= c_parser_peek_token (parser
)->location
;
20651 c_parser_consume_pragma (parser
);
20652 tree clauses
= c_parser_omp_all_clauses (parser
, OMP_CANCEL_CLAUSE_MASK
,
20653 "#pragma omp cancel");
20655 c_finish_omp_cancel (loc
, clauses
);
20659 # pragma omp cancellation point cancelpt-clause[optseq] new-line
20661 LOC is the location of the #pragma.
20664 #define OMP_CANCELLATION_POINT_CLAUSE_MASK \
20665 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
20666 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
20667 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
20668 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP))
20671 c_parser_omp_cancellation_point (c_parser
*parser
, enum pragma_context context
)
20673 location_t loc
= c_parser_peek_token (parser
)->location
;
20675 bool point_seen
= false;
20677 c_parser_consume_pragma (parser
);
20678 if (c_parser_next_token_is (parser
, CPP_NAME
))
20680 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
20681 if (strcmp (p
, "point") == 0)
20683 c_parser_consume_token (parser
);
20689 c_parser_error (parser
, "expected %<point%>");
20690 c_parser_skip_to_pragma_eol (parser
);
20694 if (context
!= pragma_compound
)
20696 if (context
== pragma_stmt
)
20698 "%<#pragma %s%> may only be used in compound statements",
20699 "omp cancellation point");
20701 c_parser_error (parser
, "expected declaration specifiers");
20702 c_parser_skip_to_pragma_eol (parser
, false);
20707 = c_parser_omp_all_clauses (parser
, OMP_CANCELLATION_POINT_CLAUSE_MASK
,
20708 "#pragma omp cancellation point");
20710 c_finish_omp_cancellation_point (loc
, clauses
);
20715 #pragma omp distribute distribute-clause[optseq] new-line
20718 #define OMP_DISTRIBUTE_CLAUSE_MASK \
20719 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20720 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20721 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
20722 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)\
20723 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20724 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
20725 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
20728 c_parser_omp_distribute (location_t loc
, c_parser
*parser
,
20729 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
20732 tree clauses
, block
, ret
;
20734 strcat (p_name
, " distribute");
20735 mask
|= OMP_DISTRIBUTE_CLAUSE_MASK
;
20737 if (c_parser_next_token_is (parser
, CPP_NAME
))
20739 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
20741 bool parallel
= false;
20743 if (strcmp (p
, "simd") == 0)
20746 parallel
= strcmp (p
, "parallel") == 0;
20747 if (parallel
|| simd
)
20749 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
20750 if (cclauses
== NULL
)
20751 cclauses
= cclauses_buf
;
20752 c_parser_consume_token (parser
);
20753 if (!flag_openmp
) /* flag_openmp_simd */
20756 return c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
,
20759 return c_parser_omp_parallel (loc
, parser
, p_name
, mask
,
20762 block
= c_begin_compound_stmt (true);
20764 ret
= c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
,
20767 ret
= c_parser_omp_parallel (loc
, parser
, p_name
, mask
, cclauses
,
20769 block
= c_end_compound_stmt (loc
, block
, true);
20772 ret
= make_node (OMP_DISTRIBUTE
);
20773 TREE_TYPE (ret
) = void_type_node
;
20774 OMP_FOR_BODY (ret
) = block
;
20775 OMP_FOR_CLAUSES (ret
) = cclauses
[C_OMP_CLAUSE_SPLIT_DISTRIBUTE
];
20776 SET_EXPR_LOCATION (ret
, loc
);
20781 if (!flag_openmp
) /* flag_openmp_simd */
20783 c_parser_skip_to_pragma_eol (parser
, false);
20787 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
20790 omp_split_clauses (loc
, OMP_DISTRIBUTE
, mask
, clauses
, cclauses
);
20791 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_DISTRIBUTE
];
20794 block
= c_begin_compound_stmt (true);
20795 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_DISTRIBUTE
, clauses
, NULL
,
20797 block
= c_end_compound_stmt (loc
, block
, true);
20804 # pragma omp teams teams-clause[optseq] new-line
20805 structured-block */
20807 #define OMP_TEAMS_CLAUSE_MASK \
20808 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20809 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20810 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
20811 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
20812 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS) \
20813 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \
20814 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20815 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT))
20818 c_parser_omp_teams (location_t loc
, c_parser
*parser
,
20819 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
20822 tree clauses
, block
, ret
;
20824 strcat (p_name
, " teams");
20825 mask
|= OMP_TEAMS_CLAUSE_MASK
;
20827 if (c_parser_next_token_is (parser
, CPP_NAME
))
20829 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
20830 if (strcmp (p
, "distribute") == 0)
20832 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
20833 if (cclauses
== NULL
)
20834 cclauses
= cclauses_buf
;
20836 c_parser_consume_token (parser
);
20837 if (!flag_openmp
) /* flag_openmp_simd */
20838 return c_parser_omp_distribute (loc
, parser
, p_name
, mask
,
20840 block
= c_begin_omp_parallel ();
20841 ret
= c_parser_omp_distribute (loc
, parser
, p_name
, mask
, cclauses
,
20843 block
= c_end_compound_stmt (loc
, block
, true);
20846 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_TEAMS
];
20847 ret
= make_node (OMP_TEAMS
);
20848 TREE_TYPE (ret
) = void_type_node
;
20849 OMP_TEAMS_CLAUSES (ret
) = clauses
;
20850 OMP_TEAMS_BODY (ret
) = block
;
20851 OMP_TEAMS_COMBINED (ret
) = 1;
20852 SET_EXPR_LOCATION (ret
, loc
);
20853 return add_stmt (ret
);
20855 else if (strcmp (p
, "loop") == 0)
20857 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
20858 if (cclauses
== NULL
)
20859 cclauses
= cclauses_buf
;
20861 c_parser_consume_token (parser
);
20862 if (!flag_openmp
) /* flag_openmp_simd */
20863 return c_parser_omp_loop (loc
, parser
, p_name
, mask
, cclauses
,
20865 block
= c_begin_omp_parallel ();
20866 ret
= c_parser_omp_loop (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
20867 block
= c_end_compound_stmt (loc
, block
, true);
20870 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_TEAMS
];
20871 ret
= make_node (OMP_TEAMS
);
20872 TREE_TYPE (ret
) = void_type_node
;
20873 OMP_TEAMS_CLAUSES (ret
) = clauses
;
20874 OMP_TEAMS_BODY (ret
) = block
;
20875 OMP_TEAMS_COMBINED (ret
) = 1;
20876 SET_EXPR_LOCATION (ret
, loc
);
20877 return add_stmt (ret
);
20880 if (!flag_openmp
) /* flag_openmp_simd */
20882 c_parser_skip_to_pragma_eol (parser
, false);
20886 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
20889 omp_split_clauses (loc
, OMP_TEAMS
, mask
, clauses
, cclauses
);
20890 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_TEAMS
];
20893 tree stmt
= make_node (OMP_TEAMS
);
20894 TREE_TYPE (stmt
) = void_type_node
;
20895 OMP_TEAMS_CLAUSES (stmt
) = clauses
;
20896 block
= c_begin_omp_parallel ();
20897 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
20898 OMP_TEAMS_BODY (stmt
) = c_end_compound_stmt (loc
, block
, true);
20899 SET_EXPR_LOCATION (stmt
, loc
);
20901 return add_stmt (stmt
);
20905 # pragma omp target data target-data-clause[optseq] new-line
20906 structured-block */
20908 #define OMP_TARGET_DATA_CLAUSE_MASK \
20909 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
20910 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
20911 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
20912 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR) \
20913 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR))
20916 c_parser_omp_target_data (location_t loc
, c_parser
*parser
, bool *if_p
)
20920 = (enum omp_requires
) (omp_requires_mask
| OMP_REQUIRES_TARGET_USED
);
20923 = c_parser_omp_all_clauses (parser
, OMP_TARGET_DATA_CLAUSE_MASK
,
20924 "#pragma omp target data");
20925 c_omp_adjust_map_clauses (clauses
, false);
20927 for (tree
*pc
= &clauses
; *pc
;)
20929 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_MAP
)
20930 switch (OMP_CLAUSE_MAP_KIND (*pc
))
20933 case GOMP_MAP_ALWAYS_TO
:
20934 case GOMP_MAP_FROM
:
20935 case GOMP_MAP_ALWAYS_FROM
:
20936 case GOMP_MAP_TOFROM
:
20937 case GOMP_MAP_ALWAYS_TOFROM
:
20938 case GOMP_MAP_ALLOC
:
20941 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
20942 case GOMP_MAP_ALWAYS_POINTER
:
20943 case GOMP_MAP_ATTACH_DETACH
:
20947 error_at (OMP_CLAUSE_LOCATION (*pc
),
20948 "%<#pragma omp target data%> with map-type other "
20949 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
20950 "on %<map%> clause");
20951 *pc
= OMP_CLAUSE_CHAIN (*pc
);
20954 else if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_USE_DEVICE_PTR
20955 || OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_USE_DEVICE_ADDR
)
20957 pc
= &OMP_CLAUSE_CHAIN (*pc
);
20964 "%<#pragma omp target data%> must contain at least "
20965 "one %<map%>, %<use_device_ptr%> or %<use_device_addr%> "
20970 tree stmt
= make_node (OMP_TARGET_DATA
);
20971 TREE_TYPE (stmt
) = void_type_node
;
20972 OMP_TARGET_DATA_CLAUSES (stmt
) = clauses
;
20973 keep_next_level ();
20974 tree block
= c_begin_compound_stmt (true);
20975 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
20976 OMP_TARGET_DATA_BODY (stmt
) = c_end_compound_stmt (loc
, block
, true);
20978 SET_EXPR_LOCATION (stmt
, loc
);
20979 return add_stmt (stmt
);
20983 # pragma omp target update target-update-clause[optseq] new-line */
20985 #define OMP_TARGET_UPDATE_CLAUSE_MASK \
20986 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FROM) \
20987 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
20988 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
20989 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
20990 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
20991 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20994 c_parser_omp_target_update (location_t loc
, c_parser
*parser
,
20995 enum pragma_context context
)
20997 if (context
== pragma_stmt
)
20999 error_at (loc
, "%<#pragma %s%> may only be used in compound statements",
21000 "omp target update");
21001 c_parser_skip_to_pragma_eol (parser
, false);
21006 = c_parser_omp_all_clauses (parser
, OMP_TARGET_UPDATE_CLAUSE_MASK
,
21007 "#pragma omp target update");
21008 if (omp_find_clause (clauses
, OMP_CLAUSE_TO
) == NULL_TREE
21009 && omp_find_clause (clauses
, OMP_CLAUSE_FROM
) == NULL_TREE
)
21012 "%<#pragma omp target update%> must contain at least one "
21013 "%<from%> or %<to%> clauses");
21019 = (enum omp_requires
) (omp_requires_mask
| OMP_REQUIRES_TARGET_USED
);
21021 tree stmt
= make_node (OMP_TARGET_UPDATE
);
21022 TREE_TYPE (stmt
) = void_type_node
;
21023 OMP_TARGET_UPDATE_CLAUSES (stmt
) = clauses
;
21024 SET_EXPR_LOCATION (stmt
, loc
);
21030 # pragma omp target enter data target-data-clause[optseq] new-line */
21032 #define OMP_TARGET_ENTER_DATA_CLAUSE_MASK \
21033 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
21034 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
21035 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
21036 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
21037 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
21040 c_parser_omp_target_enter_data (location_t loc
, c_parser
*parser
,
21041 enum pragma_context context
)
21043 bool data_seen
= false;
21044 if (c_parser_next_token_is (parser
, CPP_NAME
))
21046 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
21047 if (strcmp (p
, "data") == 0)
21049 c_parser_consume_token (parser
);
21055 c_parser_error (parser
, "expected %<data%>");
21056 c_parser_skip_to_pragma_eol (parser
);
21060 if (context
== pragma_stmt
)
21062 error_at (loc
, "%<#pragma %s%> may only be used in compound statements",
21063 "omp target enter data");
21064 c_parser_skip_to_pragma_eol (parser
, false);
21070 = (enum omp_requires
) (omp_requires_mask
| OMP_REQUIRES_TARGET_USED
);
21073 = c_parser_omp_all_clauses (parser
, OMP_TARGET_ENTER_DATA_CLAUSE_MASK
,
21074 "#pragma omp target enter data");
21075 c_omp_adjust_map_clauses (clauses
, false);
21077 for (tree
*pc
= &clauses
; *pc
;)
21079 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_MAP
)
21080 switch (OMP_CLAUSE_MAP_KIND (*pc
))
21083 case GOMP_MAP_ALWAYS_TO
:
21084 case GOMP_MAP_ALLOC
:
21087 case GOMP_MAP_TOFROM
:
21088 OMP_CLAUSE_SET_MAP_KIND (*pc
, GOMP_MAP_TO
);
21091 case GOMP_MAP_ALWAYS_TOFROM
:
21092 OMP_CLAUSE_SET_MAP_KIND (*pc
, GOMP_MAP_ALWAYS_TO
);
21095 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
21096 case GOMP_MAP_ALWAYS_POINTER
:
21097 case GOMP_MAP_ATTACH_DETACH
:
21101 error_at (OMP_CLAUSE_LOCATION (*pc
),
21102 "%<#pragma omp target enter data%> with map-type other "
21103 "than %<to%>, %<tofrom%> or %<alloc%> on %<map%> clause");
21104 *pc
= OMP_CLAUSE_CHAIN (*pc
);
21107 pc
= &OMP_CLAUSE_CHAIN (*pc
);
21114 "%<#pragma omp target enter data%> must contain at least "
21115 "one %<map%> clause");
21119 tree stmt
= make_node (OMP_TARGET_ENTER_DATA
);
21120 TREE_TYPE (stmt
) = void_type_node
;
21121 OMP_TARGET_ENTER_DATA_CLAUSES (stmt
) = clauses
;
21122 SET_EXPR_LOCATION (stmt
, loc
);
21128 # pragma omp target exit data target-data-clause[optseq] new-line */
21130 #define OMP_TARGET_EXIT_DATA_CLAUSE_MASK \
21131 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
21132 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
21133 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
21134 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
21135 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
21138 c_parser_omp_target_exit_data (location_t loc
, c_parser
*parser
,
21139 enum pragma_context context
)
21141 bool data_seen
= false;
21142 if (c_parser_next_token_is (parser
, CPP_NAME
))
21144 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
21145 if (strcmp (p
, "data") == 0)
21147 c_parser_consume_token (parser
);
21153 c_parser_error (parser
, "expected %<data%>");
21154 c_parser_skip_to_pragma_eol (parser
);
21158 if (context
== pragma_stmt
)
21160 error_at (loc
, "%<#pragma %s%> may only be used in compound statements",
21161 "omp target exit data");
21162 c_parser_skip_to_pragma_eol (parser
, false);
21168 = (enum omp_requires
) (omp_requires_mask
| OMP_REQUIRES_TARGET_USED
);
21171 = c_parser_omp_all_clauses (parser
, OMP_TARGET_EXIT_DATA_CLAUSE_MASK
,
21172 "#pragma omp target exit data");
21173 c_omp_adjust_map_clauses (clauses
, false);
21175 for (tree
*pc
= &clauses
; *pc
;)
21177 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_MAP
)
21178 switch (OMP_CLAUSE_MAP_KIND (*pc
))
21180 case GOMP_MAP_FROM
:
21181 case GOMP_MAP_ALWAYS_FROM
:
21182 case GOMP_MAP_RELEASE
:
21183 case GOMP_MAP_DELETE
:
21186 case GOMP_MAP_TOFROM
:
21187 OMP_CLAUSE_SET_MAP_KIND (*pc
, GOMP_MAP_FROM
);
21190 case GOMP_MAP_ALWAYS_TOFROM
:
21191 OMP_CLAUSE_SET_MAP_KIND (*pc
, GOMP_MAP_ALWAYS_FROM
);
21194 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
21195 case GOMP_MAP_ALWAYS_POINTER
:
21196 case GOMP_MAP_ATTACH_DETACH
:
21200 error_at (OMP_CLAUSE_LOCATION (*pc
),
21201 "%<#pragma omp target exit data%> with map-type other "
21202 "than %<from%>, %<tofrom%>, %<release%> or %<delete%> "
21203 "on %<map%> clause");
21204 *pc
= OMP_CLAUSE_CHAIN (*pc
);
21207 pc
= &OMP_CLAUSE_CHAIN (*pc
);
21214 "%<#pragma omp target exit data%> must contain at least one "
21219 tree stmt
= make_node (OMP_TARGET_EXIT_DATA
);
21220 TREE_TYPE (stmt
) = void_type_node
;
21221 OMP_TARGET_EXIT_DATA_CLAUSES (stmt
) = clauses
;
21222 SET_EXPR_LOCATION (stmt
, loc
);
21228 # pragma omp target target-clause[optseq] new-line
21229 structured-block */
21231 #define OMP_TARGET_CLAUSE_MASK \
21232 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
21233 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
21234 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
21235 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
21236 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
21237 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
21238 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
21239 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
21240 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULTMAP) \
21241 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION) \
21242 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \
21243 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR)\
21244 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR))
21247 c_parser_omp_target (c_parser
*parser
, enum pragma_context context
, bool *if_p
)
21249 location_t loc
= c_parser_peek_token (parser
)->location
;
21250 c_parser_consume_pragma (parser
);
21251 tree
*pc
= NULL
, stmt
, block
;
21253 if (context
!= pragma_stmt
&& context
!= pragma_compound
)
21255 c_parser_error (parser
, "expected declaration specifiers");
21256 c_parser_skip_to_pragma_eol (parser
);
21262 = (enum omp_requires
) (omp_requires_mask
| OMP_REQUIRES_TARGET_USED
);
21264 if (c_parser_next_token_is (parser
, CPP_NAME
))
21266 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
21267 enum tree_code ccode
= ERROR_MARK
;
21269 if (strcmp (p
, "teams") == 0)
21271 else if (strcmp (p
, "parallel") == 0)
21272 ccode
= OMP_PARALLEL
;
21273 else if (strcmp (p
, "simd") == 0)
21275 if (ccode
!= ERROR_MARK
)
21277 tree cclauses
[C_OMP_CLAUSE_SPLIT_COUNT
];
21278 char p_name
[sizeof ("#pragma omp target teams distribute "
21279 "parallel for simd")];
21281 c_parser_consume_token (parser
);
21282 strcpy (p_name
, "#pragma omp target");
21283 if (!flag_openmp
) /* flag_openmp_simd */
21289 stmt
= c_parser_omp_teams (loc
, parser
, p_name
,
21290 OMP_TARGET_CLAUSE_MASK
,
21294 stmt
= c_parser_omp_parallel (loc
, parser
, p_name
,
21295 OMP_TARGET_CLAUSE_MASK
,
21299 stmt
= c_parser_omp_simd (loc
, parser
, p_name
,
21300 OMP_TARGET_CLAUSE_MASK
,
21304 gcc_unreachable ();
21306 return stmt
!= NULL_TREE
;
21308 keep_next_level ();
21309 tree block
= c_begin_compound_stmt (true), ret
;
21313 ret
= c_parser_omp_teams (loc
, parser
, p_name
,
21314 OMP_TARGET_CLAUSE_MASK
, cclauses
,
21318 ret
= c_parser_omp_parallel (loc
, parser
, p_name
,
21319 OMP_TARGET_CLAUSE_MASK
, cclauses
,
21323 ret
= c_parser_omp_simd (loc
, parser
, p_name
,
21324 OMP_TARGET_CLAUSE_MASK
, cclauses
,
21328 gcc_unreachable ();
21330 block
= c_end_compound_stmt (loc
, block
, true);
21331 if (ret
== NULL_TREE
)
21333 if (ccode
== OMP_TEAMS
)
21334 /* For combined target teams, ensure the num_teams and
21335 thread_limit clause expressions are evaluated on the host,
21336 before entering the target construct. */
21337 for (tree c
= cclauses
[C_OMP_CLAUSE_SPLIT_TEAMS
];
21338 c
; c
= OMP_CLAUSE_CHAIN (c
))
21339 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_NUM_TEAMS
21340 || OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_THREAD_LIMIT
)
21342 i
<= (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_NUM_TEAMS
); ++i
)
21343 if (OMP_CLAUSE_OPERAND (c
, i
)
21344 && TREE_CODE (OMP_CLAUSE_OPERAND (c
, i
)) != INTEGER_CST
)
21346 tree expr
= OMP_CLAUSE_OPERAND (c
, i
);
21347 tree tmp
= create_tmp_var_raw (TREE_TYPE (expr
));
21348 expr
= build4 (TARGET_EXPR
, TREE_TYPE (expr
), tmp
,
21349 expr
, NULL_TREE
, NULL_TREE
);
21351 OMP_CLAUSE_OPERAND (c
, i
) = expr
;
21352 tree tc
= build_omp_clause (OMP_CLAUSE_LOCATION (c
),
21353 OMP_CLAUSE_FIRSTPRIVATE
);
21354 OMP_CLAUSE_DECL (tc
) = tmp
;
21355 OMP_CLAUSE_CHAIN (tc
)
21356 = cclauses
[C_OMP_CLAUSE_SPLIT_TARGET
];
21357 cclauses
[C_OMP_CLAUSE_SPLIT_TARGET
] = tc
;
21359 tree stmt
= make_node (OMP_TARGET
);
21360 TREE_TYPE (stmt
) = void_type_node
;
21361 OMP_TARGET_CLAUSES (stmt
) = cclauses
[C_OMP_CLAUSE_SPLIT_TARGET
];
21362 c_omp_adjust_map_clauses (OMP_TARGET_CLAUSES (stmt
), true);
21363 OMP_TARGET_BODY (stmt
) = block
;
21364 OMP_TARGET_COMBINED (stmt
) = 1;
21365 SET_EXPR_LOCATION (stmt
, loc
);
21367 pc
= &OMP_TARGET_CLAUSES (stmt
);
21368 goto check_clauses
;
21370 else if (!flag_openmp
) /* flag_openmp_simd */
21372 c_parser_skip_to_pragma_eol (parser
, false);
21375 else if (strcmp (p
, "data") == 0)
21377 c_parser_consume_token (parser
);
21378 c_parser_omp_target_data (loc
, parser
, if_p
);
21381 else if (strcmp (p
, "enter") == 0)
21383 c_parser_consume_token (parser
);
21384 return c_parser_omp_target_enter_data (loc
, parser
, context
);
21386 else if (strcmp (p
, "exit") == 0)
21388 c_parser_consume_token (parser
);
21389 return c_parser_omp_target_exit_data (loc
, parser
, context
);
21391 else if (strcmp (p
, "update") == 0)
21393 c_parser_consume_token (parser
);
21394 return c_parser_omp_target_update (loc
, parser
, context
);
21397 if (!flag_openmp
) /* flag_openmp_simd */
21399 c_parser_skip_to_pragma_eol (parser
, false);
21403 stmt
= make_node (OMP_TARGET
);
21404 TREE_TYPE (stmt
) = void_type_node
;
21406 OMP_TARGET_CLAUSES (stmt
)
21407 = c_parser_omp_all_clauses (parser
, OMP_TARGET_CLAUSE_MASK
,
21408 "#pragma omp target", false);
21409 for (tree c
= OMP_TARGET_CLAUSES (stmt
); c
; c
= OMP_CLAUSE_CHAIN (c
))
21410 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_IN_REDUCTION
)
21412 tree nc
= build_omp_clause (OMP_CLAUSE_LOCATION (c
), OMP_CLAUSE_MAP
);
21413 OMP_CLAUSE_DECL (nc
) = OMP_CLAUSE_DECL (c
);
21414 OMP_CLAUSE_SET_MAP_KIND (nc
, GOMP_MAP_ALWAYS_TOFROM
);
21415 OMP_CLAUSE_CHAIN (nc
) = OMP_CLAUSE_CHAIN (c
);
21416 OMP_CLAUSE_CHAIN (c
) = nc
;
21418 OMP_TARGET_CLAUSES (stmt
)
21419 = c_finish_omp_clauses (OMP_TARGET_CLAUSES (stmt
), C_ORT_OMP_TARGET
);
21420 c_omp_adjust_map_clauses (OMP_TARGET_CLAUSES (stmt
), true);
21422 pc
= &OMP_TARGET_CLAUSES (stmt
);
21423 keep_next_level ();
21424 block
= c_begin_compound_stmt (true);
21425 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
21426 OMP_TARGET_BODY (stmt
) = c_end_compound_stmt (loc
, block
, true);
21428 SET_EXPR_LOCATION (stmt
, loc
);
21434 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_MAP
)
21435 switch (OMP_CLAUSE_MAP_KIND (*pc
))
21438 case GOMP_MAP_ALWAYS_TO
:
21439 case GOMP_MAP_FROM
:
21440 case GOMP_MAP_ALWAYS_FROM
:
21441 case GOMP_MAP_TOFROM
:
21442 case GOMP_MAP_ALWAYS_TOFROM
:
21443 case GOMP_MAP_ALLOC
:
21444 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
21445 case GOMP_MAP_ALWAYS_POINTER
:
21446 case GOMP_MAP_ATTACH_DETACH
:
21449 error_at (OMP_CLAUSE_LOCATION (*pc
),
21450 "%<#pragma omp target%> with map-type other "
21451 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
21452 "on %<map%> clause");
21453 *pc
= OMP_CLAUSE_CHAIN (*pc
);
21456 pc
= &OMP_CLAUSE_CHAIN (*pc
);
21458 cfun
->has_omp_target
= true;
21463 # pragma omp declare simd declare-simd-clauses[optseq] new-line
21466 # pragma omp declare variant (identifier) match(context-selector) new-line
21469 #define OMP_DECLARE_SIMD_CLAUSE_MASK \
21470 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
21471 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
21472 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
21473 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM) \
21474 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INBRANCH) \
21475 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOTINBRANCH))
21478 c_parser_omp_declare_simd (c_parser
*parser
, enum pragma_context context
)
21480 c_token
*token
= c_parser_peek_token (parser
);
21481 gcc_assert (token
->type
== CPP_NAME
);
21482 tree kind
= token
->value
;
21483 gcc_assert (strcmp (IDENTIFIER_POINTER (kind
), "simd") == 0
21484 || strcmp (IDENTIFIER_POINTER (kind
), "variant") == 0);
21486 auto_vec
<c_token
> clauses
;
21487 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
21489 c_token
*token
= c_parser_peek_token (parser
);
21490 if (token
->type
== CPP_EOF
)
21492 c_parser_skip_to_pragma_eol (parser
);
21495 clauses
.safe_push (*token
);
21496 c_parser_consume_token (parser
);
21498 clauses
.safe_push (*c_parser_peek_token (parser
));
21499 c_parser_skip_to_pragma_eol (parser
);
21501 while (c_parser_next_token_is (parser
, CPP_PRAGMA
))
21503 if (c_parser_peek_token (parser
)->pragma_kind
!= PRAGMA_OMP_DECLARE
21504 || c_parser_peek_2nd_token (parser
)->type
!= CPP_NAME
21505 || c_parser_peek_2nd_token (parser
)->value
!= kind
)
21507 error ("%<#pragma omp declare %s%> must be followed by "
21508 "function declaration or definition or another "
21509 "%<#pragma omp declare %s%>",
21510 IDENTIFIER_POINTER (kind
), IDENTIFIER_POINTER (kind
));
21513 c_parser_consume_pragma (parser
);
21514 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
21516 c_token
*token
= c_parser_peek_token (parser
);
21517 if (token
->type
== CPP_EOF
)
21519 c_parser_skip_to_pragma_eol (parser
);
21522 clauses
.safe_push (*token
);
21523 c_parser_consume_token (parser
);
21525 clauses
.safe_push (*c_parser_peek_token (parser
));
21526 c_parser_skip_to_pragma_eol (parser
);
21529 /* Make sure nothing tries to read past the end of the tokens. */
21531 memset (&eof_token
, 0, sizeof (eof_token
));
21532 eof_token
.type
= CPP_EOF
;
21533 clauses
.safe_push (eof_token
);
21534 clauses
.safe_push (eof_token
);
21538 case pragma_external
:
21539 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
21540 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
)
21542 int ext
= disable_extension_diagnostics ();
21544 c_parser_consume_token (parser
);
21545 while (c_parser_next_token_is (parser
, CPP_KEYWORD
)
21546 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
);
21547 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
21549 restore_extension_diagnostics (ext
);
21552 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
21555 case pragma_struct
:
21558 error ("%<#pragma omp declare %s%> must be followed by "
21559 "function declaration or definition",
21560 IDENTIFIER_POINTER (kind
));
21562 case pragma_compound
:
21563 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
21564 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
)
21566 int ext
= disable_extension_diagnostics ();
21568 c_parser_consume_token (parser
);
21569 while (c_parser_next_token_is (parser
, CPP_KEYWORD
)
21570 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
);
21571 if (c_parser_next_tokens_start_declaration (parser
))
21573 c_parser_declaration_or_fndef (parser
, true, true, true, true,
21574 true, NULL
, &clauses
);
21575 restore_extension_diagnostics (ext
);
21578 restore_extension_diagnostics (ext
);
21580 else if (c_parser_next_tokens_start_declaration (parser
))
21582 c_parser_declaration_or_fndef (parser
, true, true, true, true, true,
21586 error ("%<#pragma omp declare %s%> must be followed by "
21587 "function declaration or definition",
21588 IDENTIFIER_POINTER (kind
));
21591 gcc_unreachable ();
21595 static const char *const omp_construct_selectors
[] = {
21596 "simd", "target", "teams", "parallel", "for", NULL
};
21597 static const char *const omp_device_selectors
[] = {
21598 "kind", "isa", "arch", NULL
};
21599 static const char *const omp_implementation_selectors
[] = {
21600 "vendor", "extension", "atomic_default_mem_order", "unified_address",
21601 "unified_shared_memory", "dynamic_allocators", "reverse_offload", NULL
};
21602 static const char *const omp_user_selectors
[] = {
21603 "condition", NULL
};
21608 trait-selector-name[([trait-score:]trait-property[,trait-property[,...]])]
21611 score(score-expression) */
21614 c_parser_omp_context_selector (c_parser
*parser
, tree set
, tree parms
)
21616 tree ret
= NULL_TREE
;
21620 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
21621 || c_parser_next_token_is (parser
, CPP_NAME
))
21622 selector
= c_parser_peek_token (parser
)->value
;
21625 c_parser_error (parser
, "expected trait selector name");
21626 return error_mark_node
;
21629 tree properties
= NULL_TREE
;
21630 const char *const *selectors
= NULL
;
21631 bool allow_score
= true;
21632 bool allow_user
= false;
21633 int property_limit
= 0;
21634 enum { CTX_PROPERTY_NONE
, CTX_PROPERTY_USER
, CTX_PROPERTY_NAME_LIST
,
21635 CTX_PROPERTY_ID
, CTX_PROPERTY_EXPR
,
21636 CTX_PROPERTY_SIMD
} property_kind
= CTX_PROPERTY_NONE
;
21637 switch (IDENTIFIER_POINTER (set
)[0])
21639 case 'c': /* construct */
21640 selectors
= omp_construct_selectors
;
21641 allow_score
= false;
21642 property_limit
= 1;
21643 property_kind
= CTX_PROPERTY_SIMD
;
21645 case 'd': /* device */
21646 selectors
= omp_device_selectors
;
21647 allow_score
= false;
21649 property_limit
= 3;
21650 property_kind
= CTX_PROPERTY_NAME_LIST
;
21652 case 'i': /* implementation */
21653 selectors
= omp_implementation_selectors
;
21655 property_limit
= 3;
21656 property_kind
= CTX_PROPERTY_NAME_LIST
;
21658 case 'u': /* user */
21659 selectors
= omp_user_selectors
;
21660 property_limit
= 1;
21661 property_kind
= CTX_PROPERTY_EXPR
;
21664 gcc_unreachable ();
21666 for (int i
= 0; ; i
++)
21668 if (selectors
[i
] == NULL
)
21672 property_kind
= CTX_PROPERTY_USER
;
21677 error_at (c_parser_peek_token (parser
)->location
,
21678 "selector %qs not allowed for context selector "
21679 "set %qs", IDENTIFIER_POINTER (selector
),
21680 IDENTIFIER_POINTER (set
));
21681 c_parser_consume_token (parser
);
21682 return error_mark_node
;
21685 if (i
== property_limit
)
21686 property_kind
= CTX_PROPERTY_NONE
;
21687 if (strcmp (selectors
[i
], IDENTIFIER_POINTER (selector
)) == 0)
21690 if (property_kind
== CTX_PROPERTY_NAME_LIST
21691 && IDENTIFIER_POINTER (set
)[0] == 'i'
21692 && strcmp (IDENTIFIER_POINTER (selector
),
21693 "atomic_default_mem_order") == 0)
21694 property_kind
= CTX_PROPERTY_ID
;
21696 c_parser_consume_token (parser
);
21698 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
21700 if (property_kind
== CTX_PROPERTY_NONE
)
21702 error_at (c_parser_peek_token (parser
)->location
,
21703 "selector %qs does not accept any properties",
21704 IDENTIFIER_POINTER (selector
));
21705 return error_mark_node
;
21708 matching_parens parens
;
21709 parens
.require_open (parser
);
21711 c_token
*token
= c_parser_peek_token (parser
);
21713 && c_parser_next_token_is (parser
, CPP_NAME
)
21714 && strcmp (IDENTIFIER_POINTER (token
->value
), "score") == 0
21715 && c_parser_peek_2nd_token (parser
)->type
== CPP_OPEN_PAREN
)
21717 c_parser_consume_token (parser
);
21719 matching_parens parens2
;
21720 parens2
.require_open (parser
);
21721 tree score
= c_parser_expr_no_commas (parser
, NULL
).value
;
21722 parens2
.skip_until_found_close (parser
);
21723 c_parser_require (parser
, CPP_COLON
, "expected %<:%>");
21724 if (score
!= error_mark_node
)
21726 mark_exp_read (score
);
21727 score
= c_fully_fold (score
, false, NULL
);
21728 if (!INTEGRAL_TYPE_P (TREE_TYPE (score
))
21729 || TREE_CODE (score
) != INTEGER_CST
)
21730 error_at (token
->location
, "score argument must be "
21731 "constant integer expression");
21732 else if (tree_int_cst_sgn (score
) < 0)
21733 error_at (token
->location
, "score argument must be "
21736 properties
= tree_cons (get_identifier (" score"),
21737 score
, properties
);
21739 token
= c_parser_peek_token (parser
);
21742 switch (property_kind
)
21745 case CTX_PROPERTY_USER
:
21748 t
= c_parser_expr_no_commas (parser
, NULL
).value
;
21749 if (TREE_CODE (t
) == STRING_CST
)
21750 properties
= tree_cons (NULL_TREE
, t
, properties
);
21751 else if (t
!= error_mark_node
)
21754 t
= c_fully_fold (t
, false, NULL
);
21755 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
))
21756 || !tree_fits_shwi_p (t
))
21757 error_at (token
->location
, "property must be "
21758 "constant integer expression or string "
21761 properties
= tree_cons (NULL_TREE
, t
, properties
);
21764 return error_mark_node
;
21766 if (c_parser_next_token_is (parser
, CPP_COMMA
))
21767 c_parser_consume_token (parser
);
21773 case CTX_PROPERTY_ID
:
21774 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
21775 || c_parser_next_token_is (parser
, CPP_NAME
))
21777 tree prop
= c_parser_peek_token (parser
)->value
;
21778 c_parser_consume_token (parser
);
21779 properties
= tree_cons (prop
, NULL_TREE
, properties
);
21783 c_parser_error (parser
, "expected identifier");
21784 return error_mark_node
;
21787 case CTX_PROPERTY_NAME_LIST
:
21790 tree prop
= NULL_TREE
, value
= NULL_TREE
;
21791 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
21792 || c_parser_next_token_is (parser
, CPP_NAME
))
21794 prop
= c_parser_peek_token (parser
)->value
;
21795 c_parser_consume_token (parser
);
21797 else if (c_parser_next_token_is (parser
, CPP_STRING
))
21798 value
= c_parser_string_literal (parser
, false,
21802 c_parser_error (parser
, "expected identifier or "
21804 return error_mark_node
;
21807 properties
= tree_cons (prop
, value
, properties
);
21809 if (c_parser_next_token_is (parser
, CPP_COMMA
))
21810 c_parser_consume_token (parser
);
21816 case CTX_PROPERTY_EXPR
:
21817 t
= c_parser_expr_no_commas (parser
, NULL
).value
;
21818 if (t
!= error_mark_node
)
21821 t
= c_fully_fold (t
, false, NULL
);
21822 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
))
21823 || !tree_fits_shwi_p (t
))
21824 error_at (token
->location
, "property must be "
21825 "constant integer expression");
21827 properties
= tree_cons (NULL_TREE
, t
, properties
);
21830 return error_mark_node
;
21832 case CTX_PROPERTY_SIMD
:
21833 if (parms
== NULL_TREE
)
21835 error_at (token
->location
, "properties for %<simd%> "
21836 "selector may not be specified in "
21837 "%<metadirective%>");
21838 return error_mark_node
;
21841 c
= c_parser_omp_all_clauses (parser
,
21842 OMP_DECLARE_SIMD_CLAUSE_MASK
,
21844 c
= c_omp_declare_simd_clauses_to_numbers (parms
21846 ? NULL_TREE
: parms
,
21851 gcc_unreachable ();
21854 parens
.skip_until_found_close (parser
);
21855 properties
= nreverse (properties
);
21857 else if (property_kind
== CTX_PROPERTY_NAME_LIST
21858 || property_kind
== CTX_PROPERTY_ID
21859 || property_kind
== CTX_PROPERTY_EXPR
)
21861 c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>");
21862 return error_mark_node
;
21865 ret
= tree_cons (selector
, properties
, ret
);
21867 if (c_parser_next_token_is (parser
, CPP_COMMA
))
21868 c_parser_consume_token (parser
);
21874 return nreverse (ret
);
21879 trait-set-selector[,trait-set-selector[,...]]
21881 trait-set-selector:
21882 trait-set-selector-name = { trait-selector[, trait-selector[, ...]] }
21884 trait-set-selector-name:
21891 c_parser_omp_context_selector_specification (c_parser
*parser
, tree parms
)
21893 tree ret
= NULL_TREE
;
21896 const char *setp
= "";
21897 if (c_parser_next_token_is (parser
, CPP_NAME
))
21898 setp
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
21902 if (strcmp (setp
, "construct") == 0)
21906 if (strcmp (setp
, "device") == 0)
21910 if (strcmp (setp
, "implementation") == 0)
21914 if (strcmp (setp
, "user") == 0)
21922 c_parser_error (parser
, "expected %<construct%>, %<device%>, "
21923 "%<implementation%> or %<user%>");
21924 return error_mark_node
;
21927 tree set
= c_parser_peek_token (parser
)->value
;
21928 c_parser_consume_token (parser
);
21930 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
21931 return error_mark_node
;
21933 matching_braces braces
;
21934 if (!braces
.require_open (parser
))
21935 return error_mark_node
;
21937 tree selectors
= c_parser_omp_context_selector (parser
, set
, parms
);
21938 if (selectors
== error_mark_node
)
21939 ret
= error_mark_node
;
21940 else if (ret
!= error_mark_node
)
21941 ret
= tree_cons (set
, selectors
, ret
);
21943 braces
.skip_until_found_close (parser
);
21945 if (c_parser_next_token_is (parser
, CPP_COMMA
))
21946 c_parser_consume_token (parser
);
21952 if (ret
== error_mark_node
)
21954 return nreverse (ret
);
21957 /* Finalize #pragma omp declare variant after FNDECL has been parsed, and put
21958 that into "omp declare variant base" attribute. */
21961 c_finish_omp_declare_variant (c_parser
*parser
, tree fndecl
, tree parms
)
21963 matching_parens parens
;
21964 if (!parens
.require_open (parser
))
21967 c_parser_skip_to_pragma_eol (parser
, false);
21971 if (c_parser_next_token_is_not (parser
, CPP_NAME
)
21972 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
21974 c_parser_error (parser
, "expected identifier");
21978 c_token
*token
= c_parser_peek_token (parser
);
21979 tree variant
= lookup_name (token
->value
);
21981 if (variant
== NULL_TREE
)
21983 undeclared_variable (token
->location
, token
->value
);
21984 variant
= error_mark_node
;
21987 c_parser_consume_token (parser
);
21989 parens
.require_close (parser
);
21991 const char *clause
= "";
21992 location_t match_loc
= c_parser_peek_token (parser
)->location
;
21993 if (c_parser_next_token_is (parser
, CPP_NAME
))
21994 clause
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
21995 if (strcmp (clause
, "match"))
21997 c_parser_error (parser
, "expected %<match%>");
22001 c_parser_consume_token (parser
);
22003 if (!parens
.require_open (parser
))
22006 if (parms
== NULL_TREE
)
22007 parms
= error_mark_node
;
22009 tree ctx
= c_parser_omp_context_selector_specification (parser
, parms
);
22010 if (ctx
== error_mark_node
)
22012 ctx
= omp_check_context_selector (match_loc
, ctx
);
22013 if (ctx
!= error_mark_node
&& variant
!= error_mark_node
)
22015 if (TREE_CODE (variant
) != FUNCTION_DECL
)
22017 error_at (token
->location
, "variant %qD is not a function", variant
);
22018 variant
= error_mark_node
;
22020 else if (omp_get_context_selector (ctx
, "construct", "simd") == NULL_TREE
22021 && !comptypes (TREE_TYPE (fndecl
), TREE_TYPE (variant
)))
22023 error_at (token
->location
, "variant %qD and base %qD have "
22024 "incompatible types", variant
, fndecl
);
22025 variant
= error_mark_node
;
22027 else if (fndecl_built_in_p (variant
)
22028 && (strncmp (IDENTIFIER_POINTER (DECL_NAME (variant
)),
22029 "__builtin_", strlen ("__builtin_")) == 0
22030 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant
)),
22031 "__sync_", strlen ("__sync_")) == 0
22032 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant
)),
22033 "__atomic_", strlen ("__atomic_")) == 0))
22035 error_at (token
->location
, "variant %qD is a built-in", variant
);
22036 variant
= error_mark_node
;
22038 if (variant
!= error_mark_node
)
22040 C_DECL_USED (variant
) = 1;
22041 tree construct
= omp_get_context_selector (ctx
, "construct", NULL
);
22042 omp_mark_declare_variant (match_loc
, variant
, construct
);
22043 if (omp_context_selector_matches (ctx
))
22046 = tree_cons (get_identifier ("omp declare variant base"),
22047 build_tree_list (variant
, ctx
),
22048 DECL_ATTRIBUTES (fndecl
));
22049 DECL_ATTRIBUTES (fndecl
) = attr
;
22054 parens
.require_close (parser
);
22055 c_parser_skip_to_pragma_eol (parser
);
22058 /* Finalize #pragma omp declare simd or #pragma omp declare variant
22059 clauses after FNDECL has been parsed, and put that into "omp declare simd"
22060 or "omp declare variant base" attribute. */
22063 c_finish_omp_declare_simd (c_parser
*parser
, tree fndecl
, tree parms
,
22064 vec
<c_token
> *pclauses
)
22066 vec
<c_token
> &clauses
= *pclauses
;
22068 /* Normally first token is CPP_NAME "simd" or "variant". CPP_EOF there
22069 indicates error has been reported and CPP_PRAGMA that
22070 c_finish_omp_declare_simd has already processed the tokens. */
22071 if (clauses
.exists () && clauses
[0].type
== CPP_EOF
)
22073 const char *kind
= "simd";
22074 if (clauses
.exists ()
22075 && (clauses
[0].type
== CPP_NAME
|| clauses
[0].type
== CPP_PRAGMA
))
22076 kind
= IDENTIFIER_POINTER (clauses
[0].value
);
22077 gcc_assert (strcmp (kind
, "simd") == 0 || strcmp (kind
, "variant") == 0);
22078 if (fndecl
== NULL_TREE
|| TREE_CODE (fndecl
) != FUNCTION_DECL
)
22080 error ("%<#pragma omp declare %s%> not immediately followed by "
22081 "a function declaration or definition", kind
);
22082 clauses
[0].type
= CPP_EOF
;
22085 if (clauses
.exists () && clauses
[0].type
!= CPP_NAME
)
22087 error_at (DECL_SOURCE_LOCATION (fndecl
),
22088 "%<#pragma omp declare %s%> not immediately followed by "
22089 "a single function declaration or definition", kind
);
22090 clauses
[0].type
= CPP_EOF
;
22094 if (parms
== NULL_TREE
)
22095 parms
= DECL_ARGUMENTS (fndecl
);
22097 unsigned int tokens_avail
= parser
->tokens_avail
;
22098 gcc_assert (parser
->tokens
== &parser
->tokens_buf
[0]);
22100 parser
->tokens
= clauses
.address ();
22101 parser
->tokens_avail
= clauses
.length ();
22103 /* c_parser_omp_declare_simd pushed 2 extra CPP_EOF tokens at the end. */
22104 while (parser
->tokens_avail
> 3)
22106 c_token
*token
= c_parser_peek_token (parser
);
22107 gcc_assert (token
->type
== CPP_NAME
22108 && strcmp (IDENTIFIER_POINTER (token
->value
), kind
) == 0);
22109 c_parser_consume_token (parser
);
22110 parser
->in_pragma
= true;
22112 if (strcmp (kind
, "simd") == 0)
22115 c
= c_parser_omp_all_clauses (parser
, OMP_DECLARE_SIMD_CLAUSE_MASK
,
22116 "#pragma omp declare simd");
22117 c
= c_omp_declare_simd_clauses_to_numbers (parms
, c
);
22118 if (c
!= NULL_TREE
)
22119 c
= tree_cons (NULL_TREE
, c
, NULL_TREE
);
22120 c
= build_tree_list (get_identifier ("omp declare simd"), c
);
22121 TREE_CHAIN (c
) = DECL_ATTRIBUTES (fndecl
);
22122 DECL_ATTRIBUTES (fndecl
) = c
;
22126 gcc_assert (strcmp (kind
, "variant") == 0);
22127 c_finish_omp_declare_variant (parser
, fndecl
, parms
);
22131 parser
->tokens
= &parser
->tokens_buf
[0];
22132 parser
->tokens_avail
= tokens_avail
;
22133 if (clauses
.exists ())
22134 clauses
[0].type
= CPP_PRAGMA
;
22139 # pragma omp declare target new-line
22140 declarations and definitions
22141 # pragma omp end declare target new-line
22144 # pragma omp declare target ( extended-list ) new-line
22146 # pragma omp declare target declare-target-clauses[seq] new-line */
22148 #define OMP_DECLARE_TARGET_CLAUSE_MASK \
22149 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
22150 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ENTER) \
22151 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK) \
22152 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE))
22155 c_parser_omp_declare_target (c_parser
*parser
)
22157 tree clauses
= NULL_TREE
;
22158 int device_type
= 0;
22159 bool only_device_type
= true;
22160 if (c_parser_next_token_is (parser
, CPP_NAME
))
22161 clauses
= c_parser_omp_all_clauses (parser
, OMP_DECLARE_TARGET_CLAUSE_MASK
,
22162 "#pragma omp declare target");
22163 else if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
22165 clauses
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ENTER
,
22167 clauses
= c_finish_omp_clauses (clauses
, C_ORT_OMP
);
22168 c_parser_skip_to_pragma_eol (parser
);
22172 c_parser_skip_to_pragma_eol (parser
);
22173 current_omp_declare_target_attribute
++;
22176 for (tree c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
22177 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEVICE_TYPE
)
22178 device_type
|= OMP_CLAUSE_DEVICE_TYPE_KIND (c
);
22179 for (tree c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
22181 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEVICE_TYPE
)
22183 tree t
= OMP_CLAUSE_DECL (c
), id
;
22184 tree at1
= lookup_attribute ("omp declare target", DECL_ATTRIBUTES (t
));
22185 tree at2
= lookup_attribute ("omp declare target link",
22186 DECL_ATTRIBUTES (t
));
22187 only_device_type
= false;
22188 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LINK
)
22190 id
= get_identifier ("omp declare target link");
22191 std::swap (at1
, at2
);
22194 id
= get_identifier ("omp declare target");
22197 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_ENTER
)
22198 error_at (OMP_CLAUSE_LOCATION (c
),
22199 "%qD specified both in declare target %<link%> and %qs"
22200 " clauses", t
, OMP_CLAUSE_ENTER_TO (c
) ? "to" : "enter");
22202 error_at (OMP_CLAUSE_LOCATION (c
),
22203 "%qD specified both in declare target %<link%> and "
22204 "%<to%> or %<enter%> clauses", t
);
22209 DECL_ATTRIBUTES (t
) = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (t
));
22210 if (TREE_CODE (t
) != FUNCTION_DECL
&& !is_global_var (t
))
22213 symtab_node
*node
= symtab_node::get (t
);
22216 node
->offloadable
= 1;
22217 if (ENABLE_OFFLOADING
)
22219 g
->have_offload
= true;
22220 if (is_a
<varpool_node
*> (node
))
22221 vec_safe_push (offload_vars
, t
);
22225 if (TREE_CODE (t
) != FUNCTION_DECL
)
22227 if ((device_type
& OMP_CLAUSE_DEVICE_TYPE_HOST
) != 0)
22229 tree at3
= lookup_attribute ("omp declare target host",
22230 DECL_ATTRIBUTES (t
));
22231 if (at3
== NULL_TREE
)
22233 id
= get_identifier ("omp declare target host");
22234 DECL_ATTRIBUTES (t
)
22235 = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (t
));
22238 if ((device_type
& OMP_CLAUSE_DEVICE_TYPE_NOHOST
) != 0)
22240 tree at3
= lookup_attribute ("omp declare target nohost",
22241 DECL_ATTRIBUTES (t
));
22242 if (at3
== NULL_TREE
)
22244 id
= get_identifier ("omp declare target nohost");
22245 DECL_ATTRIBUTES (t
)
22246 = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (t
));
22250 if (device_type
&& only_device_type
)
22251 warning_at (OMP_CLAUSE_LOCATION (clauses
), 0,
22252 "directive with only %<device_type%> clauses ignored");
22256 c_parser_omp_end_declare_target (c_parser
*parser
)
22258 location_t loc
= c_parser_peek_token (parser
)->location
;
22259 c_parser_consume_pragma (parser
);
22260 if (c_parser_next_token_is (parser
, CPP_NAME
)
22261 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
),
22264 c_parser_consume_token (parser
);
22265 if (c_parser_next_token_is (parser
, CPP_NAME
)
22266 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
),
22268 c_parser_consume_token (parser
);
22271 c_parser_error (parser
, "expected %<target%>");
22272 c_parser_skip_to_pragma_eol (parser
);
22278 c_parser_error (parser
, "expected %<declare%>");
22279 c_parser_skip_to_pragma_eol (parser
);
22282 c_parser_skip_to_pragma_eol (parser
);
22283 if (!current_omp_declare_target_attribute
)
22284 error_at (loc
, "%<#pragma omp end declare target%> without corresponding "
22285 "%<#pragma omp declare target%>");
22287 current_omp_declare_target_attribute
--;
22292 #pragma omp declare reduction (reduction-id : typename-list : expression) \
22293 initializer-clause[opt] new-line
22295 initializer-clause:
22296 initializer (omp_priv = initializer)
22297 initializer (function-name (argument-list)) */
22300 c_parser_omp_declare_reduction (c_parser
*parser
, enum pragma_context context
)
22302 unsigned int tokens_avail
= 0, i
;
22303 vec
<tree
> types
= vNULL
;
22304 vec
<c_token
> clauses
= vNULL
;
22305 enum tree_code reduc_code
= ERROR_MARK
;
22306 tree reduc_id
= NULL_TREE
;
22308 location_t rloc
= c_parser_peek_token (parser
)->location
;
22310 if (context
== pragma_struct
|| context
== pragma_param
)
22312 error ("%<#pragma omp declare reduction%> not at file or block scope");
22316 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
22319 switch (c_parser_peek_token (parser
)->type
)
22322 reduc_code
= PLUS_EXPR
;
22325 reduc_code
= MULT_EXPR
;
22328 reduc_code
= MINUS_EXPR
;
22331 reduc_code
= BIT_AND_EXPR
;
22334 reduc_code
= BIT_XOR_EXPR
;
22337 reduc_code
= BIT_IOR_EXPR
;
22340 reduc_code
= TRUTH_ANDIF_EXPR
;
22343 reduc_code
= TRUTH_ORIF_EXPR
;
22347 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
22348 if (strcmp (p
, "min") == 0)
22350 reduc_code
= MIN_EXPR
;
22353 if (strcmp (p
, "max") == 0)
22355 reduc_code
= MAX_EXPR
;
22358 reduc_id
= c_parser_peek_token (parser
)->value
;
22361 c_parser_error (parser
,
22362 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
22363 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
22367 tree orig_reduc_id
, reduc_decl
;
22368 orig_reduc_id
= reduc_id
;
22369 reduc_id
= c_omp_reduction_id (reduc_code
, reduc_id
);
22370 reduc_decl
= c_omp_reduction_decl (reduc_id
);
22371 c_parser_consume_token (parser
);
22373 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
22378 location_t loc
= c_parser_peek_token (parser
)->location
;
22379 struct c_type_name
*ctype
= c_parser_type_name (parser
);
22382 type
= groktypename (ctype
, NULL
, NULL
);
22383 if (type
== error_mark_node
)
22385 else if ((INTEGRAL_TYPE_P (type
)
22386 || TREE_CODE (type
) == REAL_TYPE
22387 || TREE_CODE (type
) == COMPLEX_TYPE
)
22388 && orig_reduc_id
== NULL_TREE
)
22389 error_at (loc
, "predeclared arithmetic type in "
22390 "%<#pragma omp declare reduction%>");
22391 else if (TREE_CODE (type
) == FUNCTION_TYPE
22392 || TREE_CODE (type
) == ARRAY_TYPE
)
22393 error_at (loc
, "function or array type in "
22394 "%<#pragma omp declare reduction%>");
22395 else if (TYPE_ATOMIC (type
))
22396 error_at (loc
, "%<_Atomic%> qualified type in "
22397 "%<#pragma omp declare reduction%>");
22398 else if (TYPE_QUALS_NO_ADDR_SPACE (type
))
22399 error_at (loc
, "const, volatile or restrict qualified type in "
22400 "%<#pragma omp declare reduction%>");
22404 for (t
= DECL_INITIAL (reduc_decl
); t
; t
= TREE_CHAIN (t
))
22405 if (comptypes (TREE_PURPOSE (t
), type
))
22407 error_at (loc
, "redeclaration of %qs "
22408 "%<#pragma omp declare reduction%> for "
22410 IDENTIFIER_POINTER (reduc_id
)
22411 + sizeof ("omp declare reduction ") - 1,
22414 = DECL_SOURCE_LOCATION (TREE_VEC_ELT (TREE_VALUE (t
),
22416 error_at (ploc
, "previous %<#pragma omp declare "
22420 if (t
== NULL_TREE
)
22421 types
.safe_push (type
);
22423 if (c_parser_next_token_is (parser
, CPP_COMMA
))
22424 c_parser_consume_token (parser
);
22432 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>")
22433 || types
.is_empty ())
22436 clauses
.release ();
22440 c_token
*token
= c_parser_peek_token (parser
);
22441 if (token
->type
== CPP_EOF
|| token
->type
== CPP_PRAGMA_EOL
)
22443 c_parser_consume_token (parser
);
22445 c_parser_skip_to_pragma_eol (parser
);
22449 if (types
.length () > 1)
22451 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
22453 c_token
*token
= c_parser_peek_token (parser
);
22454 if (token
->type
== CPP_EOF
)
22456 clauses
.safe_push (*token
);
22457 c_parser_consume_token (parser
);
22459 clauses
.safe_push (*c_parser_peek_token (parser
));
22460 c_parser_skip_to_pragma_eol (parser
);
22462 /* Make sure nothing tries to read past the end of the tokens. */
22464 memset (&eof_token
, 0, sizeof (eof_token
));
22465 eof_token
.type
= CPP_EOF
;
22466 clauses
.safe_push (eof_token
);
22467 clauses
.safe_push (eof_token
);
22470 int errs
= errorcount
;
22471 FOR_EACH_VEC_ELT (types
, i
, type
)
22473 tokens_avail
= parser
->tokens_avail
;
22474 gcc_assert (parser
->tokens
== &parser
->tokens_buf
[0]);
22475 if (!clauses
.is_empty ())
22477 parser
->tokens
= clauses
.address ();
22478 parser
->tokens_avail
= clauses
.length ();
22479 parser
->in_pragma
= true;
22482 bool nested
= current_function_decl
!= NULL_TREE
;
22484 c_push_function_context ();
22485 tree fndecl
= build_decl (BUILTINS_LOCATION
, FUNCTION_DECL
,
22486 reduc_id
, default_function_type
);
22487 current_function_decl
= fndecl
;
22488 allocate_struct_function (fndecl
, true);
22490 tree stmt
= push_stmt_list ();
22491 /* Intentionally BUILTINS_LOCATION, so that -Wshadow doesn't
22492 warn about these. */
22493 tree omp_out
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
22494 get_identifier ("omp_out"), type
);
22495 DECL_ARTIFICIAL (omp_out
) = 1;
22496 DECL_CONTEXT (omp_out
) = fndecl
;
22497 pushdecl (omp_out
);
22498 tree omp_in
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
22499 get_identifier ("omp_in"), type
);
22500 DECL_ARTIFICIAL (omp_in
) = 1;
22501 DECL_CONTEXT (omp_in
) = fndecl
;
22503 struct c_expr combiner
= c_parser_expression (parser
);
22504 struct c_expr initializer
;
22505 tree omp_priv
= NULL_TREE
, omp_orig
= NULL_TREE
;
22507 initializer
.set_error ();
22508 if (!c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
22510 else if (c_parser_next_token_is (parser
, CPP_NAME
)
22511 && strcmp (IDENTIFIER_POINTER
22512 (c_parser_peek_token (parser
)->value
),
22513 "initializer") == 0)
22515 c_parser_consume_token (parser
);
22518 omp_priv
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
22519 get_identifier ("omp_priv"), type
);
22520 DECL_ARTIFICIAL (omp_priv
) = 1;
22521 DECL_INITIAL (omp_priv
) = error_mark_node
;
22522 DECL_CONTEXT (omp_priv
) = fndecl
;
22523 pushdecl (omp_priv
);
22524 omp_orig
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
22525 get_identifier ("omp_orig"), type
);
22526 DECL_ARTIFICIAL (omp_orig
) = 1;
22527 DECL_CONTEXT (omp_orig
) = fndecl
;
22528 pushdecl (omp_orig
);
22529 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
22531 else if (!c_parser_next_token_is (parser
, CPP_NAME
))
22533 c_parser_error (parser
, "expected %<omp_priv%> or "
22537 else if (strcmp (IDENTIFIER_POINTER
22538 (c_parser_peek_token (parser
)->value
),
22541 if (c_parser_peek_2nd_token (parser
)->type
!= CPP_OPEN_PAREN
22542 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
22544 c_parser_error (parser
, "expected function-name %<(%>");
22548 initializer
= c_parser_postfix_expression (parser
);
22549 if (initializer
.value
22550 && TREE_CODE (initializer
.value
) == CALL_EXPR
)
22553 tree c
= initializer
.value
;
22554 for (j
= 0; j
< call_expr_nargs (c
); j
++)
22556 tree a
= CALL_EXPR_ARG (c
, j
);
22558 if (TREE_CODE (a
) == ADDR_EXPR
22559 && TREE_OPERAND (a
, 0) == omp_priv
)
22562 if (j
== call_expr_nargs (c
))
22563 error ("one of the initializer call arguments should be "
22569 c_parser_consume_token (parser
);
22570 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
22574 tree st
= push_stmt_list ();
22575 location_t loc
= c_parser_peek_token (parser
)->location
;
22576 rich_location
richloc (line_table
, loc
);
22577 start_init (omp_priv
, NULL_TREE
, 0, &richloc
);
22578 struct c_expr init
= c_parser_initializer (parser
);
22580 finish_decl (omp_priv
, loc
, init
.value
,
22581 init
.original_type
, NULL_TREE
);
22582 pop_stmt_list (st
);
22586 && !c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
22592 c_parser_skip_to_pragma_eol (parser
);
22594 tree t
= tree_cons (type
, make_tree_vec (omp_priv
? 6 : 3),
22595 DECL_INITIAL (reduc_decl
));
22596 DECL_INITIAL (reduc_decl
) = t
;
22597 DECL_SOURCE_LOCATION (omp_out
) = rloc
;
22598 TREE_VEC_ELT (TREE_VALUE (t
), 0) = omp_out
;
22599 TREE_VEC_ELT (TREE_VALUE (t
), 1) = omp_in
;
22600 TREE_VEC_ELT (TREE_VALUE (t
), 2) = combiner
.value
;
22601 walk_tree (&combiner
.value
, c_check_omp_declare_reduction_r
,
22602 &TREE_VEC_ELT (TREE_VALUE (t
), 0), NULL
);
22605 DECL_SOURCE_LOCATION (omp_priv
) = rloc
;
22606 TREE_VEC_ELT (TREE_VALUE (t
), 3) = omp_priv
;
22607 TREE_VEC_ELT (TREE_VALUE (t
), 4) = omp_orig
;
22608 TREE_VEC_ELT (TREE_VALUE (t
), 5) = initializer
.value
;
22609 walk_tree (&initializer
.value
, c_check_omp_declare_reduction_r
,
22610 &TREE_VEC_ELT (TREE_VALUE (t
), 3), NULL
);
22611 walk_tree (&DECL_INITIAL (omp_priv
),
22612 c_check_omp_declare_reduction_r
,
22613 &TREE_VEC_ELT (TREE_VALUE (t
), 3), NULL
);
22617 pop_stmt_list (stmt
);
22619 if (cfun
->language
!= NULL
)
22621 ggc_free (cfun
->language
);
22622 cfun
->language
= NULL
;
22625 current_function_decl
= NULL_TREE
;
22627 c_pop_function_context ();
22629 if (!clauses
.is_empty ())
22631 parser
->tokens
= &parser
->tokens_buf
[0];
22632 parser
->tokens_avail
= tokens_avail
;
22636 if (errs
!= errorcount
)
22640 clauses
.release ();
22646 #pragma omp declare simd declare-simd-clauses[optseq] new-line
22647 #pragma omp declare reduction (reduction-id : typename-list : expression) \
22648 initializer-clause[opt] new-line
22649 #pragma omp declare target new-line
22652 #pragma omp declare variant (identifier) match (context-selector) */
22655 c_parser_omp_declare (c_parser
*parser
, enum pragma_context context
)
22657 c_parser_consume_pragma (parser
);
22658 if (c_parser_next_token_is (parser
, CPP_NAME
))
22660 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
22661 if (strcmp (p
, "simd") == 0)
22663 /* c_parser_consume_token (parser); done in
22664 c_parser_omp_declare_simd. */
22665 c_parser_omp_declare_simd (parser
, context
);
22668 if (strcmp (p
, "reduction") == 0)
22670 c_parser_consume_token (parser
);
22671 c_parser_omp_declare_reduction (parser
, context
);
22674 if (!flag_openmp
) /* flag_openmp_simd */
22676 c_parser_skip_to_pragma_eol (parser
, false);
22679 if (strcmp (p
, "target") == 0)
22681 c_parser_consume_token (parser
);
22682 c_parser_omp_declare_target (parser
);
22685 if (strcmp (p
, "variant") == 0)
22687 /* c_parser_consume_token (parser); done in
22688 c_parser_omp_declare_simd. */
22689 c_parser_omp_declare_simd (parser
, context
);
22694 c_parser_error (parser
, "expected %<simd%>, %<reduction%>, "
22695 "%<target%> or %<variant%>");
22696 c_parser_skip_to_pragma_eol (parser
);
22701 #pragma omp requires clauses[optseq] new-line */
22704 c_parser_omp_requires (c_parser
*parser
)
22707 enum omp_requires new_req
= (enum omp_requires
) 0;
22709 c_parser_consume_pragma (parser
);
22711 location_t loc
= c_parser_peek_token (parser
)->location
;
22712 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
22715 && c_parser_next_token_is (parser
, CPP_COMMA
)
22716 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
22717 c_parser_consume_token (parser
);
22721 if (c_parser_next_token_is (parser
, CPP_NAME
))
22724 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
22725 location_t cloc
= c_parser_peek_token (parser
)->location
;
22726 enum omp_requires this_req
= (enum omp_requires
) 0;
22728 if (!strcmp (p
, "unified_address"))
22729 this_req
= OMP_REQUIRES_UNIFIED_ADDRESS
;
22730 else if (!strcmp (p
, "unified_shared_memory"))
22731 this_req
= OMP_REQUIRES_UNIFIED_SHARED_MEMORY
;
22732 else if (!strcmp (p
, "dynamic_allocators"))
22733 this_req
= OMP_REQUIRES_DYNAMIC_ALLOCATORS
;
22734 else if (!strcmp (p
, "reverse_offload"))
22735 this_req
= OMP_REQUIRES_REVERSE_OFFLOAD
;
22736 else if (!strcmp (p
, "atomic_default_mem_order"))
22738 c_parser_consume_token (parser
);
22740 matching_parens parens
;
22741 if (parens
.require_open (parser
))
22743 if (c_parser_next_token_is (parser
, CPP_NAME
))
22745 tree v
= c_parser_peek_token (parser
)->value
;
22746 p
= IDENTIFIER_POINTER (v
);
22748 if (!strcmp (p
, "seq_cst"))
22750 = (enum omp_requires
) OMP_MEMORY_ORDER_SEQ_CST
;
22751 else if (!strcmp (p
, "relaxed"))
22753 = (enum omp_requires
) OMP_MEMORY_ORDER_RELAXED
;
22754 else if (!strcmp (p
, "acq_rel"))
22756 = (enum omp_requires
) OMP_MEMORY_ORDER_ACQ_REL
;
22760 error_at (c_parser_peek_token (parser
)->location
,
22761 "expected %<seq_cst%>, %<relaxed%> or "
22763 switch (c_parser_peek_token (parser
)->type
)
22766 case CPP_PRAGMA_EOL
:
22767 case CPP_CLOSE_PAREN
:
22770 if (c_parser_peek_2nd_token (parser
)->type
22771 == CPP_CLOSE_PAREN
)
22772 c_parser_consume_token (parser
);
22777 c_parser_consume_token (parser
);
22779 parens
.skip_until_found_close (parser
);
22782 c_parser_skip_to_pragma_eol (parser
, false);
22790 error_at (cloc
, "expected %<unified_address%>, "
22791 "%<unified_shared_memory%>, "
22792 "%<dynamic_allocators%>, "
22793 "%<reverse_offload%> "
22794 "or %<atomic_default_mem_order%> clause");
22795 c_parser_skip_to_pragma_eol (parser
, false);
22799 c_parser_consume_token (parser
);
22802 if ((this_req
& ~OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
) != 0)
22804 if ((this_req
& new_req
) != 0)
22805 error_at (cloc
, "too many %qs clauses", p
);
22806 if (this_req
!= OMP_REQUIRES_DYNAMIC_ALLOCATORS
22807 && (omp_requires_mask
& OMP_REQUIRES_TARGET_USED
) != 0)
22808 error_at (cloc
, "%qs clause used lexically after first "
22809 "target construct or offloading API", p
);
22811 else if ((new_req
& OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
) != 0)
22813 error_at (cloc
, "too many %qs clauses",
22814 "atomic_default_mem_order");
22815 this_req
= (enum omp_requires
) 0;
22817 else if ((omp_requires_mask
22818 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
) != 0)
22820 error_at (cloc
, "more than one %<atomic_default_mem_order%>"
22821 " clause in a single compilation unit");
22823 = (enum omp_requires
)
22825 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
);
22827 else if ((omp_requires_mask
22828 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED
) != 0)
22829 error_at (cloc
, "%<atomic_default_mem_order%> clause used "
22830 "lexically after first %<atomic%> construct "
22831 "without memory order clause");
22832 new_req
= (enum omp_requires
) (new_req
| this_req
);
22834 = (enum omp_requires
) (omp_requires_mask
| this_req
);
22840 c_parser_skip_to_pragma_eol (parser
);
22843 error_at (loc
, "%<pragma omp requires%> requires at least one clause");
22846 /* Helper function for c_parser_omp_taskloop.
22847 Disallow zero sized or potentially zero sized task reductions. */
22850 c_finish_taskloop_clauses (tree clauses
)
22852 tree
*pc
= &clauses
;
22853 for (tree c
= clauses
; c
; c
= *pc
)
22855 bool remove
= false;
22856 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_REDUCTION
)
22858 tree type
= strip_array_types (TREE_TYPE (OMP_CLAUSE_DECL (c
)));
22859 if (integer_zerop (TYPE_SIZE_UNIT (type
)))
22861 error_at (OMP_CLAUSE_LOCATION (c
),
22862 "zero sized type %qT in %<reduction%> clause", type
);
22865 else if (TREE_CODE (TYPE_SIZE_UNIT (type
)) != INTEGER_CST
)
22867 error_at (OMP_CLAUSE_LOCATION (c
),
22868 "variable sized type %qT in %<reduction%> clause",
22874 *pc
= OMP_CLAUSE_CHAIN (c
);
22876 pc
= &OMP_CLAUSE_CHAIN (c
);
22882 #pragma omp taskloop taskloop-clause[optseq] new-line
22885 #pragma omp taskloop simd taskloop-simd-clause[optseq] new-line
22888 #define OMP_TASKLOOP_CLAUSE_MASK \
22889 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
22890 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
22891 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
22892 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
22893 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
22894 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_GRAINSIZE) \
22895 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TASKS) \
22896 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
22897 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
22898 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
22899 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
22900 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
22901 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP) \
22902 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
22903 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
22904 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
22905 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION))
22908 c_parser_omp_taskloop (location_t loc
, c_parser
*parser
,
22909 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
22912 tree clauses
, block
, ret
;
22914 strcat (p_name
, " taskloop");
22915 mask
|= OMP_TASKLOOP_CLAUSE_MASK
;
22916 /* #pragma omp parallel master taskloop{, simd} disallow in_reduction
22918 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_NUM_THREADS
)) != 0)
22919 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_IN_REDUCTION
);
22921 if (c_parser_next_token_is (parser
, CPP_NAME
))
22923 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
22925 if (strcmp (p
, "simd") == 0)
22927 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
22928 if (cclauses
== NULL
)
22929 cclauses
= cclauses_buf
;
22930 c_parser_consume_token (parser
);
22931 if (!flag_openmp
) /* flag_openmp_simd */
22932 return c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
,
22934 block
= c_begin_compound_stmt (true);
22935 ret
= c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
22936 block
= c_end_compound_stmt (loc
, block
, true);
22939 ret
= make_node (OMP_TASKLOOP
);
22940 TREE_TYPE (ret
) = void_type_node
;
22941 OMP_FOR_BODY (ret
) = block
;
22942 OMP_FOR_CLAUSES (ret
) = cclauses
[C_OMP_CLAUSE_SPLIT_TASKLOOP
];
22943 OMP_FOR_CLAUSES (ret
)
22944 = c_finish_taskloop_clauses (OMP_FOR_CLAUSES (ret
));
22945 SET_EXPR_LOCATION (ret
, loc
);
22950 if (!flag_openmp
) /* flag_openmp_simd */
22952 c_parser_skip_to_pragma_eol (parser
, false);
22956 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
22959 omp_split_clauses (loc
, OMP_TASKLOOP
, mask
, clauses
, cclauses
);
22960 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_TASKLOOP
];
22963 clauses
= c_finish_taskloop_clauses (clauses
);
22964 block
= c_begin_compound_stmt (true);
22965 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_TASKLOOP
, clauses
, NULL
, if_p
);
22966 block
= c_end_compound_stmt (loc
, block
, true);
22973 #pragma omp nothing new-line */
22976 c_parser_omp_nothing (c_parser
*parser
)
22978 c_parser_consume_pragma (parser
);
22979 c_parser_skip_to_pragma_eol (parser
);
22983 #pragma omp error clauses[optseq] new-line */
22986 c_parser_omp_error (c_parser
*parser
, enum pragma_context context
)
22988 int at_compilation
= -1;
22989 int severity_fatal
= -1;
22990 tree message
= NULL_TREE
;
22993 location_t loc
= c_parser_peek_token (parser
)->location
;
22995 c_parser_consume_pragma (parser
);
22997 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
23000 && c_parser_next_token_is (parser
, CPP_COMMA
)
23001 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
23002 c_parser_consume_token (parser
);
23006 if (!c_parser_next_token_is (parser
, CPP_NAME
))
23010 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
23011 location_t cloc
= c_parser_peek_token (parser
)->location
;
23012 static const char *args
[] = {
23013 "execution", "compilation", "warning", "fatal"
23016 int idx
= 0, n
= -1;
23017 tree m
= NULL_TREE
;
23019 if (!strcmp (p
, "at"))
23020 v
= &at_compilation
;
23021 else if (!strcmp (p
, "severity"))
23023 v
= &severity_fatal
;
23026 else if (strcmp (p
, "message"))
23029 "expected %<at%>, %<severity%> or %<message%> clause");
23030 c_parser_skip_to_pragma_eol (parser
, false);
23034 c_parser_consume_token (parser
);
23036 matching_parens parens
;
23037 if (parens
.require_open (parser
))
23041 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
23042 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
23043 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, true, true);
23044 m
= convert (const_string_type_node
, expr
.value
);
23045 m
= c_fully_fold (m
, false, NULL
);
23049 if (c_parser_next_token_is (parser
, CPP_NAME
))
23051 tree val
= c_parser_peek_token (parser
)->value
;
23052 const char *q
= IDENTIFIER_POINTER (val
);
23054 if (!strcmp (q
, args
[idx
]))
23056 else if (!strcmp (q
, args
[idx
+ 1]))
23061 error_at (c_parser_peek_token (parser
)->location
,
23062 "expected %qs or %qs", args
[idx
], args
[idx
+ 1]);
23064 switch (c_parser_peek_token (parser
)->type
)
23067 case CPP_PRAGMA_EOL
:
23068 case CPP_CLOSE_PAREN
:
23071 if (c_parser_peek_2nd_token (parser
)->type
23072 == CPP_CLOSE_PAREN
)
23073 c_parser_consume_token (parser
);
23078 c_parser_consume_token (parser
);
23081 parens
.skip_until_found_close (parser
);
23087 error_at (cloc
, "too many %qs clauses", p
);
23097 error_at (cloc
, "too many %qs clauses", p
);
23107 c_parser_skip_to_pragma_eol (parser
);
23111 if (at_compilation
== -1)
23112 at_compilation
= 1;
23113 if (severity_fatal
== -1)
23114 severity_fatal
= 1;
23115 if (!at_compilation
)
23117 if (context
!= pragma_compound
)
23119 error_at (loc
, "%<#pragma omp error%> with %<at(execution)%> clause "
23120 "may only be used in compound statements");
23124 = builtin_decl_explicit (severity_fatal
? BUILT_IN_GOMP_ERROR
23125 : BUILT_IN_GOMP_WARNING
);
23127 message
= build_zero_cst (const_string_type_node
);
23128 tree stmt
= build_call_expr_loc (loc
, fndecl
, 2, message
,
23129 build_all_ones_cst (size_type_node
));
23133 const char *msg
= NULL
;
23136 msg
= c_getstr (message
);
23138 msg
= _("<message unknown at compile time>");
23141 emit_diagnostic (severity_fatal
? DK_ERROR
: DK_WARNING
, loc
, 0,
23142 "%<pragma omp error%> encountered: %s", msg
);
23144 emit_diagnostic (severity_fatal
? DK_ERROR
: DK_WARNING
, loc
, 0,
23145 "%<pragma omp error%> encountered");
23149 /* Main entry point to parsing most OpenMP pragmas. */
23152 c_parser_omp_construct (c_parser
*parser
, bool *if_p
)
23154 enum pragma_kind p_kind
;
23157 char p_name
[sizeof "#pragma omp teams distribute parallel for simd"];
23158 omp_clause_mask
mask (0);
23160 loc
= c_parser_peek_token (parser
)->location
;
23161 p_kind
= c_parser_peek_token (parser
)->pragma_kind
;
23162 c_parser_consume_pragma (parser
);
23166 case PRAGMA_OACC_ATOMIC
:
23167 c_parser_omp_atomic (loc
, parser
, true);
23169 case PRAGMA_OACC_CACHE
:
23170 strcpy (p_name
, "#pragma acc");
23171 stmt
= c_parser_oacc_cache (loc
, parser
);
23173 case PRAGMA_OACC_DATA
:
23174 stmt
= c_parser_oacc_data (loc
, parser
, if_p
);
23176 case PRAGMA_OACC_HOST_DATA
:
23177 stmt
= c_parser_oacc_host_data (loc
, parser
, if_p
);
23179 case PRAGMA_OACC_KERNELS
:
23180 case PRAGMA_OACC_PARALLEL
:
23181 case PRAGMA_OACC_SERIAL
:
23182 strcpy (p_name
, "#pragma acc");
23183 stmt
= c_parser_oacc_compute (loc
, parser
, p_kind
, p_name
, if_p
);
23185 case PRAGMA_OACC_LOOP
:
23186 strcpy (p_name
, "#pragma acc");
23187 stmt
= c_parser_oacc_loop (loc
, parser
, p_name
, mask
, NULL
, if_p
);
23189 case PRAGMA_OACC_WAIT
:
23190 strcpy (p_name
, "#pragma wait");
23191 stmt
= c_parser_oacc_wait (loc
, parser
, p_name
);
23193 case PRAGMA_OMP_ALLOCATE
:
23194 c_parser_omp_allocate (loc
, parser
);
23196 case PRAGMA_OMP_ATOMIC
:
23197 c_parser_omp_atomic (loc
, parser
, false);
23199 case PRAGMA_OMP_CRITICAL
:
23200 stmt
= c_parser_omp_critical (loc
, parser
, if_p
);
23202 case PRAGMA_OMP_DISTRIBUTE
:
23203 strcpy (p_name
, "#pragma omp");
23204 stmt
= c_parser_omp_distribute (loc
, parser
, p_name
, mask
, NULL
, if_p
);
23206 case PRAGMA_OMP_FOR
:
23207 strcpy (p_name
, "#pragma omp");
23208 stmt
= c_parser_omp_for (loc
, parser
, p_name
, mask
, NULL
, if_p
);
23210 case PRAGMA_OMP_LOOP
:
23211 strcpy (p_name
, "#pragma omp");
23212 stmt
= c_parser_omp_loop (loc
, parser
, p_name
, mask
, NULL
, if_p
);
23214 case PRAGMA_OMP_MASKED
:
23215 strcpy (p_name
, "#pragma omp");
23216 stmt
= c_parser_omp_masked (loc
, parser
, p_name
, mask
, NULL
, if_p
);
23218 case PRAGMA_OMP_MASTER
:
23219 strcpy (p_name
, "#pragma omp");
23220 stmt
= c_parser_omp_master (loc
, parser
, p_name
, mask
, NULL
, if_p
);
23222 case PRAGMA_OMP_PARALLEL
:
23223 strcpy (p_name
, "#pragma omp");
23224 stmt
= c_parser_omp_parallel (loc
, parser
, p_name
, mask
, NULL
, if_p
);
23226 case PRAGMA_OMP_SCOPE
:
23227 stmt
= c_parser_omp_scope (loc
, parser
, if_p
);
23229 case PRAGMA_OMP_SECTIONS
:
23230 strcpy (p_name
, "#pragma omp");
23231 stmt
= c_parser_omp_sections (loc
, parser
, p_name
, mask
, NULL
);
23233 case PRAGMA_OMP_SIMD
:
23234 strcpy (p_name
, "#pragma omp");
23235 stmt
= c_parser_omp_simd (loc
, parser
, p_name
, mask
, NULL
, if_p
);
23237 case PRAGMA_OMP_SINGLE
:
23238 stmt
= c_parser_omp_single (loc
, parser
, if_p
);
23240 case PRAGMA_OMP_TASK
:
23241 stmt
= c_parser_omp_task (loc
, parser
, if_p
);
23243 case PRAGMA_OMP_TASKGROUP
:
23244 stmt
= c_parser_omp_taskgroup (loc
, parser
, if_p
);
23246 case PRAGMA_OMP_TASKLOOP
:
23247 strcpy (p_name
, "#pragma omp");
23248 stmt
= c_parser_omp_taskloop (loc
, parser
, p_name
, mask
, NULL
, if_p
);
23250 case PRAGMA_OMP_TEAMS
:
23251 strcpy (p_name
, "#pragma omp");
23252 stmt
= c_parser_omp_teams (loc
, parser
, p_name
, mask
, NULL
, if_p
);
23255 gcc_unreachable ();
23258 if (stmt
&& stmt
!= error_mark_node
)
23259 gcc_assert (EXPR_LOCATION (stmt
) != UNKNOWN_LOCATION
);
23264 # pragma omp threadprivate (variable-list) */
23267 c_parser_omp_threadprivate (c_parser
*parser
)
23272 c_parser_consume_pragma (parser
);
23273 loc
= c_parser_peek_token (parser
)->location
;
23274 vars
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ERROR
, NULL
);
23276 /* Mark every variable in VARS to be assigned thread local storage. */
23277 for (t
= vars
; t
; t
= TREE_CHAIN (t
))
23279 tree v
= TREE_PURPOSE (t
);
23281 /* FIXME diagnostics: Ideally we should keep individual
23282 locations for all the variables in the var list to make the
23283 following errors more precise. Perhaps
23284 c_parser_omp_var_list_parens() should construct a list of
23285 locations to go along with the var list. */
23287 /* If V had already been marked threadprivate, it doesn't matter
23288 whether it had been used prior to this point. */
23290 error_at (loc
, "%qD is not a variable", v
);
23291 else if (TREE_USED (v
) && !C_DECL_THREADPRIVATE_P (v
))
23292 error_at (loc
, "%qE declared %<threadprivate%> after first use", v
);
23293 else if (! is_global_var (v
))
23294 error_at (loc
, "automatic variable %qE cannot be %<threadprivate%>", v
);
23295 else if (TREE_TYPE (v
) == error_mark_node
)
23297 else if (! COMPLETE_TYPE_P (TREE_TYPE (v
)))
23298 error_at (loc
, "%<threadprivate%> %qE has incomplete type", v
);
23301 if (! DECL_THREAD_LOCAL_P (v
))
23303 set_decl_tls_model (v
, decl_default_tls_model (v
));
23304 /* If rtl has been already set for this var, call
23305 make_decl_rtl once again, so that encode_section_info
23306 has a chance to look at the new decl flags. */
23307 if (DECL_RTL_SET_P (v
))
23310 C_DECL_THREADPRIVATE_P (v
) = 1;
23314 c_parser_skip_to_pragma_eol (parser
);
23317 /* Parse a transaction attribute (GCC Extension).
23319 transaction-attribute:
23321 attribute-specifier
23325 c_parser_transaction_attributes (c_parser
*parser
)
23327 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
23328 return c_parser_gnu_attributes (parser
);
23330 if (!c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
))
23332 return c_parser_std_attribute_specifier (parser
, true);
23335 /* Parse a __transaction_atomic or __transaction_relaxed statement
23338 transaction-statement:
23339 __transaction_atomic transaction-attribute[opt] compound-statement
23340 __transaction_relaxed compound-statement
23342 Note that the only valid attribute is: "outer".
23346 c_parser_transaction (c_parser
*parser
, enum rid keyword
)
23348 unsigned int old_in
= parser
->in_transaction
;
23349 unsigned int this_in
= 1, new_in
;
23350 location_t loc
= c_parser_peek_token (parser
)->location
;
23353 gcc_assert ((keyword
== RID_TRANSACTION_ATOMIC
23354 || keyword
== RID_TRANSACTION_RELAXED
)
23355 && c_parser_next_token_is_keyword (parser
, keyword
));
23356 c_parser_consume_token (parser
);
23358 if (keyword
== RID_TRANSACTION_RELAXED
)
23359 this_in
|= TM_STMT_ATTR_RELAXED
;
23362 attrs
= c_parser_transaction_attributes (parser
);
23364 this_in
|= parse_tm_stmt_attr (attrs
, TM_STMT_ATTR_OUTER
);
23367 /* Keep track if we're in the lexical scope of an outer transaction. */
23368 new_in
= this_in
| (old_in
& TM_STMT_ATTR_OUTER
);
23370 parser
->in_transaction
= new_in
;
23371 stmt
= c_parser_compound_statement (parser
);
23372 parser
->in_transaction
= old_in
;
23375 stmt
= c_finish_transaction (loc
, stmt
, this_in
);
23377 error_at (loc
, (keyword
== RID_TRANSACTION_ATOMIC
?
23378 "%<__transaction_atomic%> without transactional memory support enabled"
23379 : "%<__transaction_relaxed %> "
23380 "without transactional memory support enabled"));
23385 /* Parse a __transaction_atomic or __transaction_relaxed expression
23388 transaction-expression:
23389 __transaction_atomic ( expression )
23390 __transaction_relaxed ( expression )
23393 static struct c_expr
23394 c_parser_transaction_expression (c_parser
*parser
, enum rid keyword
)
23397 unsigned int old_in
= parser
->in_transaction
;
23398 unsigned int this_in
= 1;
23399 location_t loc
= c_parser_peek_token (parser
)->location
;
23402 gcc_assert ((keyword
== RID_TRANSACTION_ATOMIC
23403 || keyword
== RID_TRANSACTION_RELAXED
)
23404 && c_parser_next_token_is_keyword (parser
, keyword
));
23405 c_parser_consume_token (parser
);
23407 if (keyword
== RID_TRANSACTION_RELAXED
)
23408 this_in
|= TM_STMT_ATTR_RELAXED
;
23411 attrs
= c_parser_transaction_attributes (parser
);
23413 this_in
|= parse_tm_stmt_attr (attrs
, 0);
23416 parser
->in_transaction
= this_in
;
23417 matching_parens parens
;
23418 if (parens
.require_open (parser
))
23420 tree expr
= c_parser_expression (parser
).value
;
23421 ret
.original_type
= TREE_TYPE (expr
);
23422 ret
.value
= build1 (TRANSACTION_EXPR
, ret
.original_type
, expr
);
23423 if (this_in
& TM_STMT_ATTR_RELAXED
)
23424 TRANSACTION_EXPR_RELAXED (ret
.value
) = 1;
23425 SET_EXPR_LOCATION (ret
.value
, loc
);
23426 ret
.original_code
= TRANSACTION_EXPR
;
23427 if (!parens
.require_close (parser
))
23429 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
23437 ret
.original_code
= ERROR_MARK
;
23438 ret
.original_type
= NULL
;
23440 parser
->in_transaction
= old_in
;
23443 error_at (loc
, (keyword
== RID_TRANSACTION_ATOMIC
?
23444 "%<__transaction_atomic%> without transactional memory support enabled"
23445 : "%<__transaction_relaxed %> "
23446 "without transactional memory support enabled"));
23448 set_c_expr_source_range (&ret
, loc
, loc
);
23453 /* Parse a __transaction_cancel statement (GCC Extension).
23455 transaction-cancel-statement:
23456 __transaction_cancel transaction-attribute[opt] ;
23458 Note that the only valid attribute is "outer".
23462 c_parser_transaction_cancel (c_parser
*parser
)
23464 location_t loc
= c_parser_peek_token (parser
)->location
;
23466 bool is_outer
= false;
23468 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_TRANSACTION_CANCEL
));
23469 c_parser_consume_token (parser
);
23471 attrs
= c_parser_transaction_attributes (parser
);
23473 is_outer
= (parse_tm_stmt_attr (attrs
, TM_STMT_ATTR_OUTER
) != 0);
23477 error_at (loc
, "%<__transaction_cancel%> without "
23478 "transactional memory support enabled");
23481 else if (parser
->in_transaction
& TM_STMT_ATTR_RELAXED
)
23483 error_at (loc
, "%<__transaction_cancel%> within a "
23484 "%<__transaction_relaxed%>");
23489 if ((parser
->in_transaction
& TM_STMT_ATTR_OUTER
) == 0
23490 && !is_tm_may_cancel_outer (current_function_decl
))
23492 error_at (loc
, "outer %<__transaction_cancel%> not "
23493 "within outer %<__transaction_atomic%> or "
23494 "a %<transaction_may_cancel_outer%> function");
23498 else if (parser
->in_transaction
== 0)
23500 error_at (loc
, "%<__transaction_cancel%> not within "
23501 "%<__transaction_atomic%>");
23505 return add_stmt (build_tm_abort_call (loc
, is_outer
));
23508 return build1 (NOP_EXPR
, void_type_node
, error_mark_node
);
23511 /* Parse a single source file. */
23514 c_parse_file (void)
23516 /* Use local storage to begin. If the first token is a pragma, parse it.
23517 If it is #pragma GCC pch_preprocess, then this will load a PCH file
23518 which will cause garbage collection. */
23521 memset (&tparser
, 0, sizeof tparser
);
23522 tparser
.translate_strings_p
= true;
23523 tparser
.tokens
= &tparser
.tokens_buf
[0];
23524 the_parser
= &tparser
;
23526 if (c_parser_peek_token (&tparser
)->pragma_kind
== PRAGMA_GCC_PCH_PREPROCESS
)
23527 c_parser_pragma_pch_preprocess (&tparser
);
23529 c_common_no_more_pch ();
23531 the_parser
= ggc_alloc
<c_parser
> ();
23532 *the_parser
= tparser
;
23533 if (tparser
.tokens
== &tparser
.tokens_buf
[0])
23534 the_parser
->tokens
= &the_parser
->tokens_buf
[0];
23536 /* Initialize EH, if we've been told to do so. */
23537 if (flag_exceptions
)
23538 using_eh_for_cleanups ();
23540 c_parser_translation_unit (the_parser
);
23544 /* Parse the body of a function declaration marked with "__RTL".
23546 The RTL parser works on the level of characters read from a
23547 FILE *, whereas c_parser works at the level of tokens.
23548 Square this circle by consuming all of the tokens up to and
23549 including the closing brace, recording the start/end of the RTL
23550 fragment, and reopening the file and re-reading the relevant
23551 lines within the RTL parser.
23553 This requires the opening and closing braces of the C function
23554 to be on separate lines from the RTL they wrap.
23556 Take ownership of START_WITH_PASS, if non-NULL. */
23559 c_parser_parse_rtl_body (c_parser
*parser
, char *start_with_pass
)
23561 if (!c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
23563 free (start_with_pass
);
23564 return c_parser_peek_token (parser
)->location
;
23567 location_t start_loc
= c_parser_peek_token (parser
)->location
;
23569 /* Consume all tokens, up to the closing brace, handling
23570 matching pairs of braces in the rtl dump. */
23571 int num_open_braces
= 1;
23574 switch (c_parser_peek_token (parser
)->type
)
23576 case CPP_OPEN_BRACE
:
23579 case CPP_CLOSE_BRACE
:
23580 if (--num_open_braces
== 0)
23581 goto found_closing_brace
;
23584 error_at (start_loc
, "no closing brace");
23585 free (start_with_pass
);
23586 return c_parser_peek_token (parser
)->location
;
23590 c_parser_consume_token (parser
);
23593 found_closing_brace
:
23594 /* At the closing brace; record its location. */
23595 location_t end_loc
= c_parser_peek_token (parser
)->location
;
23597 /* Consume the closing brace. */
23598 c_parser_consume_token (parser
);
23600 /* Invoke the RTL parser. */
23601 if (!read_rtl_function_body_from_file_range (start_loc
, end_loc
))
23603 free (start_with_pass
);
23607 /* Run the backend on the cfun created above, transferring ownership of
23608 START_WITH_PASS. */
23609 run_rtl_passes (start_with_pass
);
23613 #include "gt-c-c-parser.h"