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 input_location
= c_parser_peek_token (parser
)->location
;
12401 id
= c_parser_peek_token (parser
)->pragma_kind
;
12402 gcc_assert (id
!= PRAGMA_NONE
);
12406 case PRAGMA_OACC_DECLARE
:
12407 c_parser_oacc_declare (parser
);
12410 case PRAGMA_OACC_ENTER_DATA
:
12411 if (context
!= pragma_compound
)
12413 construct
= "acc enter data";
12415 if (context
== pragma_stmt
)
12417 error_at (c_parser_peek_token (parser
)->location
,
12418 "%<#pragma %s%> may only be used in compound "
12419 "statements", construct
);
12420 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
12425 c_parser_oacc_enter_exit_data (parser
, true);
12428 case PRAGMA_OACC_EXIT_DATA
:
12429 if (context
!= pragma_compound
)
12431 construct
= "acc exit data";
12434 c_parser_oacc_enter_exit_data (parser
, false);
12437 case PRAGMA_OACC_ROUTINE
:
12438 if (context
!= pragma_external
)
12440 error_at (c_parser_peek_token (parser
)->location
,
12441 "%<#pragma acc routine%> must be at file scope");
12442 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
12445 c_parser_oacc_routine (parser
, context
);
12448 case PRAGMA_OACC_UPDATE
:
12449 if (context
!= pragma_compound
)
12451 construct
= "acc update";
12454 c_parser_oacc_update (parser
);
12457 case PRAGMA_OMP_BARRIER
:
12458 if (context
!= pragma_compound
)
12460 construct
= "omp barrier";
12463 c_parser_omp_barrier (parser
);
12466 case PRAGMA_OMP_DEPOBJ
:
12467 if (context
!= pragma_compound
)
12469 construct
= "omp depobj";
12472 c_parser_omp_depobj (parser
);
12475 case PRAGMA_OMP_FLUSH
:
12476 if (context
!= pragma_compound
)
12478 construct
= "omp flush";
12481 c_parser_omp_flush (parser
);
12484 case PRAGMA_OMP_TASKWAIT
:
12485 if (context
!= pragma_compound
)
12487 construct
= "omp taskwait";
12490 c_parser_omp_taskwait (parser
);
12493 case PRAGMA_OMP_TASKYIELD
:
12494 if (context
!= pragma_compound
)
12496 construct
= "omp taskyield";
12499 c_parser_omp_taskyield (parser
);
12502 case PRAGMA_OMP_CANCEL
:
12503 if (context
!= pragma_compound
)
12505 construct
= "omp cancel";
12508 c_parser_omp_cancel (parser
);
12511 case PRAGMA_OMP_CANCELLATION_POINT
:
12512 return c_parser_omp_cancellation_point (parser
, context
);
12514 case PRAGMA_OMP_THREADPRIVATE
:
12515 c_parser_omp_threadprivate (parser
);
12518 case PRAGMA_OMP_TARGET
:
12519 return c_parser_omp_target (parser
, context
, if_p
);
12521 case PRAGMA_OMP_END_DECLARE_TARGET
:
12522 c_parser_omp_end_declare_target (parser
);
12525 case PRAGMA_OMP_SCAN
:
12526 error_at (c_parser_peek_token (parser
)->location
,
12527 "%<#pragma omp scan%> may only be used in "
12528 "a loop construct with %<inscan%> %<reduction%> clause");
12529 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
12532 case PRAGMA_OMP_SECTION
:
12533 error_at (c_parser_peek_token (parser
)->location
,
12534 "%<#pragma omp section%> may only be used in "
12535 "%<#pragma omp sections%> construct");
12536 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
12539 case PRAGMA_OMP_DECLARE
:
12540 return c_parser_omp_declare (parser
, context
);
12542 case PRAGMA_OMP_REQUIRES
:
12543 if (context
!= pragma_external
)
12545 error_at (c_parser_peek_token (parser
)->location
,
12546 "%<#pragma omp requires%> may only be used at file scope");
12547 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
12550 c_parser_omp_requires (parser
);
12553 case PRAGMA_OMP_NOTHING
:
12554 c_parser_omp_nothing (parser
);
12557 case PRAGMA_OMP_ERROR
:
12558 return c_parser_omp_error (parser
, context
);
12560 case PRAGMA_OMP_ORDERED
:
12561 return c_parser_omp_ordered (parser
, context
, if_p
);
12565 const bool ivdep
= c_parse_pragma_ivdep (parser
);
12566 unsigned short unroll
;
12567 if (c_parser_peek_token (parser
)->pragma_kind
== PRAGMA_UNROLL
)
12568 unroll
= c_parser_pragma_unroll (parser
);
12571 if (!c_parser_next_token_is_keyword (parser
, RID_FOR
)
12572 && !c_parser_next_token_is_keyword (parser
, RID_WHILE
)
12573 && !c_parser_next_token_is_keyword (parser
, RID_DO
))
12575 c_parser_error (parser
, "for, while or do statement expected");
12578 if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
12579 c_parser_for_statement (parser
, ivdep
, unroll
, if_p
);
12580 else if (c_parser_next_token_is_keyword (parser
, RID_WHILE
))
12581 c_parser_while_statement (parser
, ivdep
, unroll
, if_p
);
12583 c_parser_do_statement (parser
, ivdep
, unroll
);
12587 case PRAGMA_UNROLL
:
12589 unsigned short unroll
= c_parser_pragma_unroll (parser
);
12591 if (c_parser_peek_token (parser
)->pragma_kind
== PRAGMA_IVDEP
)
12592 ivdep
= c_parse_pragma_ivdep (parser
);
12595 if (!c_parser_next_token_is_keyword (parser
, RID_FOR
)
12596 && !c_parser_next_token_is_keyword (parser
, RID_WHILE
)
12597 && !c_parser_next_token_is_keyword (parser
, RID_DO
))
12599 c_parser_error (parser
, "for, while or do statement expected");
12602 if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
12603 c_parser_for_statement (parser
, ivdep
, unroll
, if_p
);
12604 else if (c_parser_next_token_is_keyword (parser
, RID_WHILE
))
12605 c_parser_while_statement (parser
, ivdep
, unroll
, if_p
);
12607 c_parser_do_statement (parser
, ivdep
, unroll
);
12611 case PRAGMA_GCC_PCH_PREPROCESS
:
12612 c_parser_error (parser
, "%<#pragma GCC pch_preprocess%> must be first");
12613 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
12616 case PRAGMA_OACC_WAIT
:
12617 if (context
!= pragma_compound
)
12619 construct
= "acc wait";
12622 /* FALL THROUGH. */
12625 if (id
< PRAGMA_FIRST_EXTERNAL
)
12627 if (context
!= pragma_stmt
&& context
!= pragma_compound
)
12630 c_parser_error (parser
, "expected declaration specifiers");
12631 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
12634 c_parser_omp_construct (parser
, if_p
);
12640 c_parser_consume_pragma (parser
);
12641 c_invoke_pragma_handler (id
);
12643 /* Skip to EOL, but suppress any error message. Those will have been
12644 generated by the handler routine through calling error, as opposed
12645 to calling c_parser_error. */
12646 parser
->error
= true;
12647 c_parser_skip_to_pragma_eol (parser
);
12652 /* The interface the pragma parsers have to the lexer. */
12655 pragma_lex (tree
*value
, location_t
*loc
)
12657 c_token
*tok
= c_parser_peek_token (the_parser
);
12658 enum cpp_ttype ret
= tok
->type
;
12660 *value
= tok
->value
;
12662 *loc
= tok
->location
;
12664 if (ret
== CPP_PRAGMA_EOL
|| ret
== CPP_EOF
)
12666 else if (ret
== CPP_STRING
)
12667 *value
= c_parser_string_literal (the_parser
, false, false).value
;
12670 if (ret
== CPP_KEYWORD
)
12672 c_parser_consume_token (the_parser
);
12679 c_parser_pragma_pch_preprocess (c_parser
*parser
)
12683 parser
->lex_joined_string
= true;
12684 c_parser_consume_pragma (parser
);
12685 if (c_parser_next_token_is (parser
, CPP_STRING
))
12687 name
= c_parser_peek_token (parser
)->value
;
12688 c_parser_consume_token (parser
);
12691 c_parser_error (parser
, "expected string literal");
12692 c_parser_skip_to_pragma_eol (parser
);
12693 parser
->lex_joined_string
= false;
12696 c_common_pch_pragma (parse_in
, TREE_STRING_POINTER (name
));
12699 /* OpenACC and OpenMP parsing routines. */
12701 /* Returns name of the next clause.
12702 If the clause is not recognized PRAGMA_OMP_CLAUSE_NONE is returned and
12703 the token is not consumed. Otherwise appropriate pragma_omp_clause is
12704 returned and the token is consumed. */
12706 static pragma_omp_clause
12707 c_parser_omp_clause_name (c_parser
*parser
)
12709 pragma_omp_clause result
= PRAGMA_OMP_CLAUSE_NONE
;
12711 if (c_parser_next_token_is_keyword (parser
, RID_AUTO
))
12712 result
= PRAGMA_OACC_CLAUSE_AUTO
;
12713 else if (c_parser_next_token_is_keyword (parser
, RID_IF
))
12714 result
= PRAGMA_OMP_CLAUSE_IF
;
12715 else if (c_parser_next_token_is_keyword (parser
, RID_DEFAULT
))
12716 result
= PRAGMA_OMP_CLAUSE_DEFAULT
;
12717 else if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
12718 result
= PRAGMA_OMP_CLAUSE_FOR
;
12719 else if (c_parser_next_token_is (parser
, CPP_NAME
))
12721 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
12726 if (!strcmp ("affinity", p
))
12727 result
= PRAGMA_OMP_CLAUSE_AFFINITY
;
12728 else if (!strcmp ("aligned", p
))
12729 result
= PRAGMA_OMP_CLAUSE_ALIGNED
;
12730 else if (!strcmp ("allocate", p
))
12731 result
= PRAGMA_OMP_CLAUSE_ALLOCATE
;
12732 else if (!strcmp ("async", p
))
12733 result
= PRAGMA_OACC_CLAUSE_ASYNC
;
12734 else if (!strcmp ("attach", p
))
12735 result
= PRAGMA_OACC_CLAUSE_ATTACH
;
12738 if (!strcmp ("bind", p
))
12739 result
= PRAGMA_OMP_CLAUSE_BIND
;
12742 if (!strcmp ("collapse", p
))
12743 result
= PRAGMA_OMP_CLAUSE_COLLAPSE
;
12744 else if (!strcmp ("copy", p
))
12745 result
= PRAGMA_OACC_CLAUSE_COPY
;
12746 else if (!strcmp ("copyin", p
))
12747 result
= PRAGMA_OMP_CLAUSE_COPYIN
;
12748 else if (!strcmp ("copyout", p
))
12749 result
= PRAGMA_OACC_CLAUSE_COPYOUT
;
12750 else if (!strcmp ("copyprivate", p
))
12751 result
= PRAGMA_OMP_CLAUSE_COPYPRIVATE
;
12752 else if (!strcmp ("create", p
))
12753 result
= PRAGMA_OACC_CLAUSE_CREATE
;
12756 if (!strcmp ("defaultmap", p
))
12757 result
= PRAGMA_OMP_CLAUSE_DEFAULTMAP
;
12758 else if (!strcmp ("delete", p
))
12759 result
= PRAGMA_OACC_CLAUSE_DELETE
;
12760 else if (!strcmp ("depend", p
))
12761 result
= PRAGMA_OMP_CLAUSE_DEPEND
;
12762 else if (!strcmp ("detach", p
))
12763 result
= PRAGMA_OACC_CLAUSE_DETACH
;
12764 else if (!strcmp ("device", p
))
12765 result
= PRAGMA_OMP_CLAUSE_DEVICE
;
12766 else if (!strcmp ("deviceptr", p
))
12767 result
= PRAGMA_OACC_CLAUSE_DEVICEPTR
;
12768 else if (!strcmp ("device_resident", p
))
12769 result
= PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT
;
12770 else if (!strcmp ("device_type", p
))
12771 result
= PRAGMA_OMP_CLAUSE_DEVICE_TYPE
;
12772 else if (!strcmp ("dist_schedule", p
))
12773 result
= PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
;
12776 if (!strcmp ("enter", p
))
12777 result
= PRAGMA_OMP_CLAUSE_ENTER
;
12780 if (!strcmp ("filter", p
))
12781 result
= PRAGMA_OMP_CLAUSE_FILTER
;
12782 else if (!strcmp ("final", p
))
12783 result
= PRAGMA_OMP_CLAUSE_FINAL
;
12784 else if (!strcmp ("finalize", p
))
12785 result
= PRAGMA_OACC_CLAUSE_FINALIZE
;
12786 else if (!strcmp ("firstprivate", p
))
12787 result
= PRAGMA_OMP_CLAUSE_FIRSTPRIVATE
;
12788 else if (!strcmp ("from", p
))
12789 result
= PRAGMA_OMP_CLAUSE_FROM
;
12792 if (!strcmp ("gang", p
))
12793 result
= PRAGMA_OACC_CLAUSE_GANG
;
12794 else if (!strcmp ("grainsize", p
))
12795 result
= PRAGMA_OMP_CLAUSE_GRAINSIZE
;
12798 if (!strcmp ("has_device_addr", p
))
12799 result
= PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR
;
12800 else if (!strcmp ("hint", p
))
12801 result
= PRAGMA_OMP_CLAUSE_HINT
;
12802 else if (!strcmp ("host", p
))
12803 result
= PRAGMA_OACC_CLAUSE_HOST
;
12806 if (!strcmp ("if_present", p
))
12807 result
= PRAGMA_OACC_CLAUSE_IF_PRESENT
;
12808 else if (!strcmp ("in_reduction", p
))
12809 result
= PRAGMA_OMP_CLAUSE_IN_REDUCTION
;
12810 else if (!strcmp ("inbranch", p
))
12811 result
= PRAGMA_OMP_CLAUSE_INBRANCH
;
12812 else if (!strcmp ("independent", p
))
12813 result
= PRAGMA_OACC_CLAUSE_INDEPENDENT
;
12814 else if (!strcmp ("is_device_ptr", p
))
12815 result
= PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR
;
12818 if (!strcmp ("lastprivate", p
))
12819 result
= PRAGMA_OMP_CLAUSE_LASTPRIVATE
;
12820 else if (!strcmp ("linear", p
))
12821 result
= PRAGMA_OMP_CLAUSE_LINEAR
;
12822 else if (!strcmp ("link", p
))
12823 result
= PRAGMA_OMP_CLAUSE_LINK
;
12826 if (!strcmp ("map", p
))
12827 result
= PRAGMA_OMP_CLAUSE_MAP
;
12828 else if (!strcmp ("mergeable", p
))
12829 result
= PRAGMA_OMP_CLAUSE_MERGEABLE
;
12832 if (!strcmp ("no_create", p
))
12833 result
= PRAGMA_OACC_CLAUSE_NO_CREATE
;
12834 else if (!strcmp ("nogroup", p
))
12835 result
= PRAGMA_OMP_CLAUSE_NOGROUP
;
12836 else if (!strcmp ("nohost", p
))
12837 result
= PRAGMA_OACC_CLAUSE_NOHOST
;
12838 else if (!strcmp ("nontemporal", p
))
12839 result
= PRAGMA_OMP_CLAUSE_NONTEMPORAL
;
12840 else if (!strcmp ("notinbranch", p
))
12841 result
= PRAGMA_OMP_CLAUSE_NOTINBRANCH
;
12842 else if (!strcmp ("nowait", p
))
12843 result
= PRAGMA_OMP_CLAUSE_NOWAIT
;
12844 else if (!strcmp ("num_gangs", p
))
12845 result
= PRAGMA_OACC_CLAUSE_NUM_GANGS
;
12846 else if (!strcmp ("num_tasks", p
))
12847 result
= PRAGMA_OMP_CLAUSE_NUM_TASKS
;
12848 else if (!strcmp ("num_teams", p
))
12849 result
= PRAGMA_OMP_CLAUSE_NUM_TEAMS
;
12850 else if (!strcmp ("num_threads", p
))
12851 result
= PRAGMA_OMP_CLAUSE_NUM_THREADS
;
12852 else if (!strcmp ("num_workers", p
))
12853 result
= PRAGMA_OACC_CLAUSE_NUM_WORKERS
;
12856 if (!strcmp ("ordered", p
))
12857 result
= PRAGMA_OMP_CLAUSE_ORDERED
;
12858 else if (!strcmp ("order", p
))
12859 result
= PRAGMA_OMP_CLAUSE_ORDER
;
12862 if (!strcmp ("parallel", p
))
12863 result
= PRAGMA_OMP_CLAUSE_PARALLEL
;
12864 else if (!strcmp ("present", p
))
12865 result
= PRAGMA_OACC_CLAUSE_PRESENT
;
12866 /* As of OpenACC 2.5, these are now aliases of the non-present_or
12868 else if (!strcmp ("present_or_copy", p
)
12869 || !strcmp ("pcopy", p
))
12870 result
= PRAGMA_OACC_CLAUSE_COPY
;
12871 else if (!strcmp ("present_or_copyin", p
)
12872 || !strcmp ("pcopyin", p
))
12873 result
= PRAGMA_OACC_CLAUSE_COPYIN
;
12874 else if (!strcmp ("present_or_copyout", p
)
12875 || !strcmp ("pcopyout", p
))
12876 result
= PRAGMA_OACC_CLAUSE_COPYOUT
;
12877 else if (!strcmp ("present_or_create", p
)
12878 || !strcmp ("pcreate", p
))
12879 result
= PRAGMA_OACC_CLAUSE_CREATE
;
12880 else if (!strcmp ("priority", p
))
12881 result
= PRAGMA_OMP_CLAUSE_PRIORITY
;
12882 else if (!strcmp ("private", p
))
12883 result
= PRAGMA_OMP_CLAUSE_PRIVATE
;
12884 else if (!strcmp ("proc_bind", p
))
12885 result
= PRAGMA_OMP_CLAUSE_PROC_BIND
;
12888 if (!strcmp ("reduction", p
))
12889 result
= PRAGMA_OMP_CLAUSE_REDUCTION
;
12892 if (!strcmp ("safelen", p
))
12893 result
= PRAGMA_OMP_CLAUSE_SAFELEN
;
12894 else if (!strcmp ("schedule", p
))
12895 result
= PRAGMA_OMP_CLAUSE_SCHEDULE
;
12896 else if (!strcmp ("sections", p
))
12897 result
= PRAGMA_OMP_CLAUSE_SECTIONS
;
12898 else if (!strcmp ("self", p
)) /* "self" is a synonym for "host". */
12899 result
= PRAGMA_OACC_CLAUSE_HOST
;
12900 else if (!strcmp ("seq", p
))
12901 result
= PRAGMA_OACC_CLAUSE_SEQ
;
12902 else if (!strcmp ("shared", p
))
12903 result
= PRAGMA_OMP_CLAUSE_SHARED
;
12904 else if (!strcmp ("simd", p
))
12905 result
= PRAGMA_OMP_CLAUSE_SIMD
;
12906 else if (!strcmp ("simdlen", p
))
12907 result
= PRAGMA_OMP_CLAUSE_SIMDLEN
;
12910 if (!strcmp ("task_reduction", p
))
12911 result
= PRAGMA_OMP_CLAUSE_TASK_REDUCTION
;
12912 else if (!strcmp ("taskgroup", p
))
12913 result
= PRAGMA_OMP_CLAUSE_TASKGROUP
;
12914 else if (!strcmp ("thread_limit", p
))
12915 result
= PRAGMA_OMP_CLAUSE_THREAD_LIMIT
;
12916 else if (!strcmp ("threads", p
))
12917 result
= PRAGMA_OMP_CLAUSE_THREADS
;
12918 else if (!strcmp ("tile", p
))
12919 result
= PRAGMA_OACC_CLAUSE_TILE
;
12920 else if (!strcmp ("to", p
))
12921 result
= PRAGMA_OMP_CLAUSE_TO
;
12924 if (!strcmp ("uniform", p
))
12925 result
= PRAGMA_OMP_CLAUSE_UNIFORM
;
12926 else if (!strcmp ("untied", p
))
12927 result
= PRAGMA_OMP_CLAUSE_UNTIED
;
12928 else if (!strcmp ("use_device", p
))
12929 result
= PRAGMA_OACC_CLAUSE_USE_DEVICE
;
12930 else if (!strcmp ("use_device_addr", p
))
12931 result
= PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR
;
12932 else if (!strcmp ("use_device_ptr", p
))
12933 result
= PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR
;
12936 if (!strcmp ("vector", p
))
12937 result
= PRAGMA_OACC_CLAUSE_VECTOR
;
12938 else if (!strcmp ("vector_length", p
))
12939 result
= PRAGMA_OACC_CLAUSE_VECTOR_LENGTH
;
12942 if (!strcmp ("wait", p
))
12943 result
= PRAGMA_OACC_CLAUSE_WAIT
;
12944 else if (!strcmp ("worker", p
))
12945 result
= PRAGMA_OACC_CLAUSE_WORKER
;
12950 if (result
!= PRAGMA_OMP_CLAUSE_NONE
)
12951 c_parser_consume_token (parser
);
12956 /* Validate that a clause of the given type does not already exist. */
12959 check_no_duplicate_clause (tree clauses
, enum omp_clause_code code
,
12962 if (tree c
= omp_find_clause (clauses
, code
))
12963 error_at (OMP_CLAUSE_LOCATION (c
), "too many %qs clauses", name
);
12967 Parse wait clause or wait directive parameters. */
12970 c_parser_oacc_wait_list (c_parser
*parser
, location_t clause_loc
, tree list
)
12972 vec
<tree
, va_gc
> *args
;
12975 matching_parens parens
;
12976 if (!parens
.require_open (parser
))
12979 args
= c_parser_expr_list (parser
, false, true, NULL
, NULL
, NULL
, NULL
);
12980 args_tree
= build_tree_list_vec (args
);
12982 for (t
= args_tree
; t
; t
= TREE_CHAIN (t
))
12984 tree targ
= TREE_VALUE (t
);
12986 if (targ
!= error_mark_node
)
12988 if (!INTEGRAL_TYPE_P (TREE_TYPE (targ
)))
12990 c_parser_error (parser
, "expression must be integral");
12991 targ
= error_mark_node
;
12995 tree c
= build_omp_clause (clause_loc
, OMP_CLAUSE_WAIT
);
12997 OMP_CLAUSE_DECL (c
) = targ
;
12998 OMP_CLAUSE_CHAIN (c
) = list
;
13004 release_tree_vector (args
);
13005 parens
.require_close (parser
);
13009 /* OpenACC 2.0, OpenMP 2.5:
13012 variable-list , identifier
13014 If KIND is nonzero, create the appropriate node and install the
13015 decl in OMP_CLAUSE_DECL and add the node to the head of the list.
13016 If KIND is nonzero, CLAUSE_LOC is the location of the clause.
13018 If KIND is zero, create a TREE_LIST with the decl in TREE_PURPOSE;
13019 return the list created.
13021 The optional ALLOW_DEREF argument is true if list items can use the deref
13026 tree low_bound
, length
;
13029 omp_dim (tree lb
, tree len
, location_t lo
, bool nc
)
13030 : low_bound (lb
), length (len
), loc (lo
), no_colon (nc
) {}
13034 c_parser_omp_variable_list (c_parser
*parser
,
13035 location_t clause_loc
,
13036 enum omp_clause_code kind
, tree list
,
13037 bool allow_deref
= false)
13039 auto_vec
<omp_dim
> dims
;
13040 bool array_section_p
;
13041 auto_vec
<c_token
> tokens
;
13042 unsigned int tokens_avail
= 0;
13047 if (kind
== OMP_CLAUSE_DEPEND
|| kind
== OMP_CLAUSE_AFFINITY
)
13049 if (c_parser_next_token_is_not (parser
, CPP_NAME
)
13050 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
13052 struct c_expr expr
;
13053 if (kind
== OMP_CLAUSE_DEPEND
13054 && c_parser_next_token_is_keyword (parser
,
13055 RID_OMP_ALL_MEMORY
)
13056 && (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
13057 || (c_parser_peek_2nd_token (parser
)->type
13058 == CPP_CLOSE_PAREN
)))
13060 expr
.value
= ridpointers
[RID_OMP_ALL_MEMORY
];
13061 c_parser_consume_token (parser
);
13064 expr
= c_parser_expr_no_commas (parser
, NULL
);
13065 if (expr
.value
!= error_mark_node
)
13067 tree u
= build_omp_clause (clause_loc
, kind
);
13068 OMP_CLAUSE_DECL (u
) = expr
.value
;
13069 OMP_CLAUSE_CHAIN (u
) = list
;
13073 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
13076 c_parser_consume_token (parser
);
13081 tokens
.truncate (0);
13082 unsigned int nesting_depth
= 0;
13085 c_token
*token
= c_parser_peek_token (parser
);
13086 switch (token
->type
)
13089 case CPP_PRAGMA_EOL
:
13091 case CPP_OPEN_BRACE
:
13092 case CPP_OPEN_PAREN
:
13093 case CPP_OPEN_SQUARE
:
13096 case CPP_CLOSE_BRACE
:
13097 case CPP_CLOSE_PAREN
:
13098 case CPP_CLOSE_SQUARE
:
13099 if (nesting_depth
-- == 0)
13103 if (nesting_depth
== 0)
13108 tokens
.safe_push (*token
);
13109 c_parser_consume_token (parser
);
13115 /* Make sure nothing tries to read past the end of the tokens. */
13117 memset (&eof_token
, 0, sizeof (eof_token
));
13118 eof_token
.type
= CPP_EOF
;
13119 tokens
.safe_push (eof_token
);
13120 tokens
.safe_push (eof_token
);
13122 tokens_avail
= parser
->tokens_avail
;
13123 gcc_assert (parser
->tokens
== &parser
->tokens_buf
[0]);
13124 parser
->tokens
= tokens
.address ();
13125 parser
->tokens_avail
= tokens
.length ();
13128 tree t
= NULL_TREE
;
13130 if (c_parser_next_token_is (parser
, CPP_NAME
)
13131 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
)
13133 t
= lookup_name (c_parser_peek_token (parser
)->value
);
13135 if (t
== NULL_TREE
)
13137 undeclared_variable (c_parser_peek_token (parser
)->location
,
13138 c_parser_peek_token (parser
)->value
);
13139 t
= error_mark_node
;
13142 c_parser_consume_token (parser
);
13144 else if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
13145 && (c_parser_peek_token (parser
)->keyword
== RID_FUNCTION_NAME
13146 || (c_parser_peek_token (parser
)->keyword
13147 == RID_PRETTY_FUNCTION_NAME
)
13148 || (c_parser_peek_token (parser
)->keyword
13149 == RID_C99_FUNCTION_NAME
)))
13150 t
= c_parser_predefined_identifier (parser
).value
;
13154 c_parser_error (parser
, "expected identifier");
13158 if (t
== error_mark_node
)
13160 else if (kind
!= 0)
13164 case OMP_CLAUSE__CACHE_
:
13165 /* The OpenACC cache directive explicitly only allows "array
13166 elements or subarrays". */
13167 if (c_parser_peek_token (parser
)->type
!= CPP_OPEN_SQUARE
)
13169 c_parser_error (parser
, "expected %<[%>");
13170 t
= error_mark_node
;
13174 case OMP_CLAUSE_MAP
:
13175 case OMP_CLAUSE_FROM
:
13176 case OMP_CLAUSE_TO
:
13177 start_component_ref
:
13178 while (c_parser_next_token_is (parser
, CPP_DOT
)
13180 && c_parser_next_token_is (parser
, CPP_DEREF
)))
13182 location_t op_loc
= c_parser_peek_token (parser
)->location
;
13183 location_t arrow_loc
= UNKNOWN_LOCATION
;
13184 if (c_parser_next_token_is (parser
, CPP_DEREF
))
13188 t_expr
.original_code
= ERROR_MARK
;
13189 t_expr
.original_type
= NULL
;
13190 set_c_expr_source_range (&t_expr
, op_loc
, op_loc
);
13191 t_expr
= convert_lvalue_to_rvalue (op_loc
, t_expr
,
13193 t
= build_indirect_ref (op_loc
, t_expr
.value
, RO_ARROW
);
13194 arrow_loc
= t_expr
.get_location ();
13196 c_parser_consume_token (parser
);
13197 if (!c_parser_next_token_is (parser
, CPP_NAME
))
13199 c_parser_error (parser
, "expected identifier");
13200 t
= error_mark_node
;
13204 c_token
*comp_tok
= c_parser_peek_token (parser
);
13205 tree ident
= comp_tok
->value
;
13206 location_t comp_loc
= comp_tok
->location
;
13207 c_parser_consume_token (parser
);
13208 t
= build_component_ref (op_loc
, t
, ident
, comp_loc
,
13212 case OMP_CLAUSE_AFFINITY
:
13213 case OMP_CLAUSE_DEPEND
:
13214 case OMP_CLAUSE_REDUCTION
:
13215 case OMP_CLAUSE_IN_REDUCTION
:
13216 case OMP_CLAUSE_TASK_REDUCTION
:
13217 case OMP_CLAUSE_HAS_DEVICE_ADDR
:
13218 array_section_p
= false;
13220 while (c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
))
13222 location_t loc
= UNKNOWN_LOCATION
;
13223 tree low_bound
= NULL_TREE
, length
= NULL_TREE
;
13224 bool no_colon
= false;
13226 c_parser_consume_token (parser
);
13227 if (!c_parser_next_token_is (parser
, CPP_COLON
))
13229 location_t expr_loc
13230 = c_parser_peek_token (parser
)->location
;
13231 c_expr expr
= c_parser_expression (parser
);
13232 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
,
13234 low_bound
= expr
.value
;
13237 if (c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
13239 length
= integer_one_node
;
13244 /* Look for `:'. */
13245 if (!c_parser_require (parser
, CPP_COLON
,
13248 t
= error_mark_node
;
13251 array_section_p
= true;
13252 if (!c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
13254 location_t expr_loc
13255 = c_parser_peek_token (parser
)->location
;
13256 c_expr expr
= c_parser_expression (parser
);
13257 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
,
13259 length
= expr
.value
;
13262 /* Look for the closing `]'. */
13263 if (!c_parser_require (parser
, CPP_CLOSE_SQUARE
,
13266 t
= error_mark_node
;
13270 dims
.safe_push (omp_dim (low_bound
, length
, loc
, no_colon
));
13273 if (t
!= error_mark_node
)
13275 if ((kind
== OMP_CLAUSE_MAP
13276 || kind
== OMP_CLAUSE_FROM
13277 || kind
== OMP_CLAUSE_TO
)
13278 && !array_section_p
13279 && (c_parser_next_token_is (parser
, CPP_DOT
)
13281 && c_parser_next_token_is (parser
,
13284 for (unsigned i
= 0; i
< dims
.length (); i
++)
13286 gcc_assert (dims
[i
].length
== integer_one_node
);
13287 t
= build_array_ref (dims
[i
].loc
,
13288 t
, dims
[i
].low_bound
);
13290 goto start_component_ref
;
13293 for (unsigned i
= 0; i
< dims
.length (); i
++)
13294 t
= tree_cons (dims
[i
].low_bound
, dims
[i
].length
, t
);
13297 if ((kind
== OMP_CLAUSE_DEPEND
|| kind
== OMP_CLAUSE_AFFINITY
)
13298 && t
!= error_mark_node
13299 && parser
->tokens_avail
!= 2)
13301 if (array_section_p
)
13303 error_at (c_parser_peek_token (parser
)->location
,
13304 "expected %<)%> or %<,%>");
13305 t
= error_mark_node
;
13309 parser
->tokens
= tokens
.address ();
13310 parser
->tokens_avail
= tokens
.length ();
13312 t
= c_parser_expr_no_commas (parser
, NULL
).value
;
13313 if (t
!= error_mark_node
&& parser
->tokens_avail
!= 2)
13315 error_at (c_parser_peek_token (parser
)->location
,
13316 "expected %<)%> or %<,%>");
13317 t
= error_mark_node
;
13326 if (t
!= error_mark_node
)
13328 tree u
= build_omp_clause (clause_loc
, kind
);
13329 OMP_CLAUSE_DECL (u
) = t
;
13330 OMP_CLAUSE_CHAIN (u
) = list
;
13335 list
= tree_cons (t
, NULL_TREE
, list
);
13337 if (kind
== OMP_CLAUSE_DEPEND
|| kind
== OMP_CLAUSE_AFFINITY
)
13339 parser
->tokens
= &parser
->tokens_buf
[0];
13340 parser
->tokens_avail
= tokens_avail
;
13342 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
13345 c_parser_consume_token (parser
);
13352 /* Similarly, but expect leading and trailing parenthesis. This is a very
13353 common case for OpenACC and OpenMP clauses. The optional ALLOW_DEREF
13354 argument is true if list items can use the deref (->) operator. */
13357 c_parser_omp_var_list_parens (c_parser
*parser
, enum omp_clause_code kind
,
13358 tree list
, bool allow_deref
= false)
13360 /* The clauses location. */
13361 location_t loc
= c_parser_peek_token (parser
)->location
;
13363 matching_parens parens
;
13364 if (parens
.require_open (parser
))
13366 list
= c_parser_omp_variable_list (parser
, loc
, kind
, list
, allow_deref
);
13367 parens
.skip_until_found_close (parser
);
13373 copy ( variable-list )
13374 copyin ( variable-list )
13375 copyout ( variable-list )
13376 create ( variable-list )
13377 delete ( variable-list )
13378 present ( variable-list )
13381 no_create ( variable-list )
13382 attach ( variable-list )
13383 detach ( variable-list ) */
13386 c_parser_oacc_data_clause (c_parser
*parser
, pragma_omp_clause c_kind
,
13389 enum gomp_map_kind kind
;
13392 case PRAGMA_OACC_CLAUSE_ATTACH
:
13393 kind
= GOMP_MAP_ATTACH
;
13395 case PRAGMA_OACC_CLAUSE_COPY
:
13396 kind
= GOMP_MAP_TOFROM
;
13398 case PRAGMA_OACC_CLAUSE_COPYIN
:
13399 kind
= GOMP_MAP_TO
;
13401 case PRAGMA_OACC_CLAUSE_COPYOUT
:
13402 kind
= GOMP_MAP_FROM
;
13404 case PRAGMA_OACC_CLAUSE_CREATE
:
13405 kind
= GOMP_MAP_ALLOC
;
13407 case PRAGMA_OACC_CLAUSE_DELETE
:
13408 kind
= GOMP_MAP_RELEASE
;
13410 case PRAGMA_OACC_CLAUSE_DETACH
:
13411 kind
= GOMP_MAP_DETACH
;
13413 case PRAGMA_OACC_CLAUSE_DEVICE
:
13414 kind
= GOMP_MAP_FORCE_TO
;
13416 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT
:
13417 kind
= GOMP_MAP_DEVICE_RESIDENT
;
13419 case PRAGMA_OACC_CLAUSE_HOST
:
13420 kind
= GOMP_MAP_FORCE_FROM
;
13422 case PRAGMA_OACC_CLAUSE_LINK
:
13423 kind
= GOMP_MAP_LINK
;
13425 case PRAGMA_OACC_CLAUSE_NO_CREATE
:
13426 kind
= GOMP_MAP_IF_PRESENT
;
13428 case PRAGMA_OACC_CLAUSE_PRESENT
:
13429 kind
= GOMP_MAP_FORCE_PRESENT
;
13432 gcc_unreachable ();
13435 nl
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_MAP
, list
, true);
13437 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
13438 OMP_CLAUSE_SET_MAP_KIND (c
, kind
);
13444 deviceptr ( variable-list ) */
13447 c_parser_oacc_data_clause_deviceptr (c_parser
*parser
, tree list
)
13449 location_t loc
= c_parser_peek_token (parser
)->location
;
13452 /* Can't use OMP_CLAUSE_MAP here (that is, can't use the generic
13453 c_parser_oacc_data_clause), as for PRAGMA_OACC_CLAUSE_DEVICEPTR,
13454 variable-list must only allow for pointer variables. */
13455 vars
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ERROR
, NULL
);
13456 for (t
= vars
; t
&& t
; t
= TREE_CHAIN (t
))
13458 tree v
= TREE_PURPOSE (t
);
13460 /* FIXME diagnostics: Ideally we should keep individual
13461 locations for all the variables in the var list to make the
13462 following errors more precise. Perhaps
13463 c_parser_omp_var_list_parens() should construct a list of
13464 locations to go along with the var list. */
13466 if (!VAR_P (v
) && TREE_CODE (v
) != PARM_DECL
)
13467 error_at (loc
, "%qD is not a variable", v
);
13468 else if (TREE_TYPE (v
) == error_mark_node
)
13470 else if (!POINTER_TYPE_P (TREE_TYPE (v
)))
13471 error_at (loc
, "%qD is not a pointer variable", v
);
13473 tree u
= build_omp_clause (loc
, OMP_CLAUSE_MAP
);
13474 OMP_CLAUSE_SET_MAP_KIND (u
, GOMP_MAP_FORCE_DEVICEPTR
);
13475 OMP_CLAUSE_DECL (u
) = v
;
13476 OMP_CLAUSE_CHAIN (u
) = list
;
13483 /* OpenACC 2.0, OpenMP 3.0:
13484 collapse ( constant-expression ) */
13487 c_parser_omp_clause_collapse (c_parser
*parser
, tree list
)
13489 tree c
, num
= error_mark_node
;
13493 check_no_duplicate_clause (list
, OMP_CLAUSE_COLLAPSE
, "collapse");
13494 check_no_duplicate_clause (list
, OMP_CLAUSE_TILE
, "tile");
13496 loc
= c_parser_peek_token (parser
)->location
;
13497 matching_parens parens
;
13498 if (parens
.require_open (parser
))
13500 num
= c_parser_expr_no_commas (parser
, NULL
).value
;
13501 parens
.skip_until_found_close (parser
);
13503 if (num
== error_mark_node
)
13505 mark_exp_read (num
);
13506 num
= c_fully_fold (num
, false, NULL
);
13507 if (!INTEGRAL_TYPE_P (TREE_TYPE (num
))
13508 || !tree_fits_shwi_p (num
)
13509 || (n
= tree_to_shwi (num
)) <= 0
13513 "collapse argument needs positive constant integer expression");
13516 c
= build_omp_clause (loc
, OMP_CLAUSE_COLLAPSE
);
13517 OMP_CLAUSE_COLLAPSE_EXPR (c
) = num
;
13518 OMP_CLAUSE_CHAIN (c
) = list
;
13523 copyin ( variable-list ) */
13526 c_parser_omp_clause_copyin (c_parser
*parser
, tree list
)
13528 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_COPYIN
, list
);
13532 copyprivate ( variable-list ) */
13535 c_parser_omp_clause_copyprivate (c_parser
*parser
, tree list
)
13537 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_COPYPRIVATE
, list
);
13541 default ( none | shared )
13544 default ( private | firstprivate )
13547 default ( none | present ) */
13550 c_parser_omp_clause_default (c_parser
*parser
, tree list
, bool is_oacc
)
13552 enum omp_clause_default_kind kind
= OMP_CLAUSE_DEFAULT_UNSPECIFIED
;
13553 location_t loc
= c_parser_peek_token (parser
)->location
;
13556 matching_parens parens
;
13557 if (!parens
.require_open (parser
))
13559 if (c_parser_next_token_is (parser
, CPP_NAME
))
13561 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
13566 if (strcmp ("none", p
) != 0)
13568 kind
= OMP_CLAUSE_DEFAULT_NONE
;
13574 if (strcmp ("present", p
) != 0)
13576 kind
= OMP_CLAUSE_DEFAULT_PRESENT
;
13580 if (strcmp ("private", p
) != 0)
13582 kind
= OMP_CLAUSE_DEFAULT_PRIVATE
;
13587 if (strcmp ("firstprivate", p
) != 0 || is_oacc
)
13589 kind
= OMP_CLAUSE_DEFAULT_FIRSTPRIVATE
;
13593 if (strcmp ("shared", p
) != 0 || is_oacc
)
13595 kind
= OMP_CLAUSE_DEFAULT_SHARED
;
13602 c_parser_consume_token (parser
);
13608 c_parser_error (parser
, "expected %<none%> or %<present%>");
13610 c_parser_error (parser
, "expected %<none%>, %<shared%>, "
13611 "%<private%> or %<firstprivate%>");
13613 parens
.skip_until_found_close (parser
);
13615 if (kind
== OMP_CLAUSE_DEFAULT_UNSPECIFIED
)
13618 check_no_duplicate_clause (list
, OMP_CLAUSE_DEFAULT
, "default");
13619 c
= build_omp_clause (loc
, OMP_CLAUSE_DEFAULT
);
13620 OMP_CLAUSE_CHAIN (c
) = list
;
13621 OMP_CLAUSE_DEFAULT_KIND (c
) = kind
;
13627 firstprivate ( variable-list ) */
13630 c_parser_omp_clause_firstprivate (c_parser
*parser
, tree list
)
13632 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_FIRSTPRIVATE
, list
);
13636 final ( expression ) */
13639 c_parser_omp_clause_final (c_parser
*parser
, tree list
)
13641 location_t loc
= c_parser_peek_token (parser
)->location
;
13642 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
13644 matching_parens parens
;
13646 if (!parens
.require_open (parser
))
13647 t
= error_mark_node
;
13650 location_t eloc
= c_parser_peek_token (parser
)->location
;
13651 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
13652 t
= convert_lvalue_to_rvalue (eloc
, expr
, true, true).value
;
13653 t
= c_objc_common_truthvalue_conversion (eloc
, t
);
13654 t
= c_fully_fold (t
, false, NULL
);
13655 parens
.skip_until_found_close (parser
);
13658 check_no_duplicate_clause (list
, OMP_CLAUSE_FINAL
, "final");
13660 c
= build_omp_clause (loc
, OMP_CLAUSE_FINAL
);
13661 OMP_CLAUSE_FINAL_EXPR (c
) = t
;
13662 OMP_CLAUSE_CHAIN (c
) = list
;
13666 c_parser_error (parser
, "expected %<(%>");
13671 /* OpenACC, OpenMP 2.5:
13675 if ( directive-name-modifier : expression )
13677 directive-name-modifier:
13678 parallel | task | taskloop | target data | target | target update
13679 | target enter data | target exit data
13682 directive-name-modifier:
13683 ... | simd | cancel */
13686 c_parser_omp_clause_if (c_parser
*parser
, tree list
, bool is_omp
)
13688 location_t location
= c_parser_peek_token (parser
)->location
;
13689 enum tree_code if_modifier
= ERROR_MARK
;
13691 matching_parens parens
;
13692 if (!parens
.require_open (parser
))
13695 if (is_omp
&& c_parser_next_token_is (parser
, CPP_NAME
))
13697 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
13699 if (strcmp (p
, "cancel") == 0)
13700 if_modifier
= VOID_CST
;
13701 else if (strcmp (p
, "parallel") == 0)
13702 if_modifier
= OMP_PARALLEL
;
13703 else if (strcmp (p
, "simd") == 0)
13704 if_modifier
= OMP_SIMD
;
13705 else if (strcmp (p
, "task") == 0)
13706 if_modifier
= OMP_TASK
;
13707 else if (strcmp (p
, "taskloop") == 0)
13708 if_modifier
= OMP_TASKLOOP
;
13709 else if (strcmp (p
, "target") == 0)
13711 if_modifier
= OMP_TARGET
;
13712 if (c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
13714 p
= IDENTIFIER_POINTER (c_parser_peek_2nd_token (parser
)->value
);
13715 if (strcmp ("data", p
) == 0)
13716 if_modifier
= OMP_TARGET_DATA
;
13717 else if (strcmp ("update", p
) == 0)
13718 if_modifier
= OMP_TARGET_UPDATE
;
13719 else if (strcmp ("enter", p
) == 0)
13720 if_modifier
= OMP_TARGET_ENTER_DATA
;
13721 else if (strcmp ("exit", p
) == 0)
13722 if_modifier
= OMP_TARGET_EXIT_DATA
;
13723 if (if_modifier
!= OMP_TARGET
)
13726 c_parser_consume_token (parser
);
13730 location_t loc
= c_parser_peek_2nd_token (parser
)->location
;
13731 error_at (loc
, "expected %<data%>, %<update%>, %<enter%> "
13733 if_modifier
= ERROR_MARK
;
13735 if (if_modifier
== OMP_TARGET_ENTER_DATA
13736 || if_modifier
== OMP_TARGET_EXIT_DATA
)
13738 if (c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
13740 p
= IDENTIFIER_POINTER
13741 (c_parser_peek_2nd_token (parser
)->value
);
13742 if (strcmp ("data", p
) == 0)
13746 c_parser_consume_token (parser
);
13750 = c_parser_peek_2nd_token (parser
)->location
;
13751 error_at (loc
, "expected %<data%>");
13752 if_modifier
= ERROR_MARK
;
13757 if (if_modifier
!= ERROR_MARK
)
13759 if (c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
13761 c_parser_consume_token (parser
);
13762 c_parser_consume_token (parser
);
13768 location_t loc
= c_parser_peek_2nd_token (parser
)->location
;
13769 error_at (loc
, "expected %<:%>");
13771 if_modifier
= ERROR_MARK
;
13776 location_t loc
= c_parser_peek_token (parser
)->location
;
13777 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
13778 expr
= convert_lvalue_to_rvalue (loc
, expr
, true, true);
13779 tree t
= c_objc_common_truthvalue_conversion (loc
, expr
.value
), c
;
13780 t
= c_fully_fold (t
, false, NULL
);
13781 parens
.skip_until_found_close (parser
);
13783 for (c
= list
; c
; c
= OMP_CLAUSE_CHAIN (c
))
13784 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_IF
)
13786 if (if_modifier
!= ERROR_MARK
13787 && OMP_CLAUSE_IF_MODIFIER (c
) == if_modifier
)
13789 const char *p
= NULL
;
13790 switch (if_modifier
)
13792 case VOID_CST
: p
= "cancel"; break;
13793 case OMP_PARALLEL
: p
= "parallel"; break;
13794 case OMP_SIMD
: p
= "simd"; break;
13795 case OMP_TASK
: p
= "task"; break;
13796 case OMP_TASKLOOP
: p
= "taskloop"; break;
13797 case OMP_TARGET_DATA
: p
= "target data"; break;
13798 case OMP_TARGET
: p
= "target"; break;
13799 case OMP_TARGET_UPDATE
: p
= "target update"; break;
13800 case OMP_TARGET_ENTER_DATA
: p
= "target enter data"; break;
13801 case OMP_TARGET_EXIT_DATA
: p
= "target exit data"; break;
13802 default: gcc_unreachable ();
13804 error_at (location
, "too many %<if%> clauses with %qs modifier",
13808 else if (OMP_CLAUSE_IF_MODIFIER (c
) == if_modifier
)
13811 error_at (location
, "too many %<if%> clauses");
13813 error_at (location
, "too many %<if%> clauses without modifier");
13816 else if (if_modifier
== ERROR_MARK
13817 || OMP_CLAUSE_IF_MODIFIER (c
) == ERROR_MARK
)
13819 error_at (location
, "if any %<if%> clause has modifier, then all "
13820 "%<if%> clauses have to use modifier");
13825 c
= build_omp_clause (location
, OMP_CLAUSE_IF
);
13826 OMP_CLAUSE_IF_MODIFIER (c
) = if_modifier
;
13827 OMP_CLAUSE_IF_EXPR (c
) = t
;
13828 OMP_CLAUSE_CHAIN (c
) = list
;
13833 lastprivate ( variable-list )
13836 lastprivate ( [ lastprivate-modifier : ] variable-list ) */
13839 c_parser_omp_clause_lastprivate (c_parser
*parser
, tree list
)
13841 /* The clauses location. */
13842 location_t loc
= c_parser_peek_token (parser
)->location
;
13844 if (c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
13846 bool conditional
= false;
13847 if (c_parser_next_token_is (parser
, CPP_NAME
)
13848 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
13851 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
13852 if (strcmp (p
, "conditional") == 0)
13854 conditional
= true;
13855 c_parser_consume_token (parser
);
13856 c_parser_consume_token (parser
);
13859 tree nlist
= c_parser_omp_variable_list (parser
, loc
,
13860 OMP_CLAUSE_LASTPRIVATE
, list
);
13861 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, "expected %<)%>");
13863 for (tree c
= nlist
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
13864 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
) = 1;
13874 c_parser_omp_clause_mergeable (c_parser
*parser ATTRIBUTE_UNUSED
, tree list
)
13878 /* FIXME: Should we allow duplicates? */
13879 check_no_duplicate_clause (list
, OMP_CLAUSE_MERGEABLE
, "mergeable");
13881 c
= build_omp_clause (c_parser_peek_token (parser
)->location
,
13882 OMP_CLAUSE_MERGEABLE
);
13883 OMP_CLAUSE_CHAIN (c
) = list
;
13892 c_parser_omp_clause_nowait (c_parser
*parser ATTRIBUTE_UNUSED
, tree list
)
13895 location_t loc
= c_parser_peek_token (parser
)->location
;
13897 check_no_duplicate_clause (list
, OMP_CLAUSE_NOWAIT
, "nowait");
13899 c
= build_omp_clause (loc
, OMP_CLAUSE_NOWAIT
);
13900 OMP_CLAUSE_CHAIN (c
) = list
;
13905 num_threads ( expression ) */
13908 c_parser_omp_clause_num_threads (c_parser
*parser
, tree list
)
13910 location_t num_threads_loc
= c_parser_peek_token (parser
)->location
;
13911 matching_parens parens
;
13912 if (parens
.require_open (parser
))
13914 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
13915 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
13916 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
13917 tree c
, t
= expr
.value
;
13918 t
= c_fully_fold (t
, false, NULL
);
13920 parens
.skip_until_found_close (parser
);
13922 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
13924 c_parser_error (parser
, "expected integer expression");
13928 /* Attempt to statically determine when the number isn't positive. */
13929 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
13930 build_int_cst (TREE_TYPE (t
), 0));
13931 protected_set_expr_location (c
, expr_loc
);
13932 if (c
== boolean_true_node
)
13934 warning_at (expr_loc
, 0,
13935 "%<num_threads%> value must be positive");
13936 t
= integer_one_node
;
13939 check_no_duplicate_clause (list
, OMP_CLAUSE_NUM_THREADS
, "num_threads");
13941 c
= build_omp_clause (num_threads_loc
, OMP_CLAUSE_NUM_THREADS
);
13942 OMP_CLAUSE_NUM_THREADS_EXPR (c
) = t
;
13943 OMP_CLAUSE_CHAIN (c
) = list
;
13951 num_tasks ( expression )
13954 num_tasks ( strict : expression ) */
13957 c_parser_omp_clause_num_tasks (c_parser
*parser
, tree list
)
13959 location_t num_tasks_loc
= c_parser_peek_token (parser
)->location
;
13960 matching_parens parens
;
13961 if (parens
.require_open (parser
))
13963 bool strict
= false;
13964 if (c_parser_next_token_is (parser
, CPP_NAME
)
13965 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
13966 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
),
13970 c_parser_consume_token (parser
);
13971 c_parser_consume_token (parser
);
13974 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
13975 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
13976 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
13977 tree c
, t
= expr
.value
;
13978 t
= c_fully_fold (t
, false, NULL
);
13980 parens
.skip_until_found_close (parser
);
13982 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
13984 c_parser_error (parser
, "expected integer expression");
13988 /* Attempt to statically determine when the number isn't positive. */
13989 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
13990 build_int_cst (TREE_TYPE (t
), 0));
13991 if (CAN_HAVE_LOCATION_P (c
))
13992 SET_EXPR_LOCATION (c
, expr_loc
);
13993 if (c
== boolean_true_node
)
13995 warning_at (expr_loc
, 0, "%<num_tasks%> value must be positive");
13996 t
= integer_one_node
;
13999 check_no_duplicate_clause (list
, OMP_CLAUSE_NUM_TASKS
, "num_tasks");
14001 c
= build_omp_clause (num_tasks_loc
, OMP_CLAUSE_NUM_TASKS
);
14002 OMP_CLAUSE_NUM_TASKS_EXPR (c
) = t
;
14003 OMP_CLAUSE_NUM_TASKS_STRICT (c
) = strict
;
14004 OMP_CLAUSE_CHAIN (c
) = list
;
14012 grainsize ( expression )
14015 grainsize ( strict : expression ) */
14018 c_parser_omp_clause_grainsize (c_parser
*parser
, tree list
)
14020 location_t grainsize_loc
= c_parser_peek_token (parser
)->location
;
14021 matching_parens parens
;
14022 if (parens
.require_open (parser
))
14024 bool strict
= false;
14025 if (c_parser_next_token_is (parser
, CPP_NAME
)
14026 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
14027 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
),
14031 c_parser_consume_token (parser
);
14032 c_parser_consume_token (parser
);
14035 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
14036 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
14037 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
14038 tree c
, t
= expr
.value
;
14039 t
= c_fully_fold (t
, false, NULL
);
14041 parens
.skip_until_found_close (parser
);
14043 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
14045 c_parser_error (parser
, "expected integer expression");
14049 /* Attempt to statically determine when the number isn't positive. */
14050 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
14051 build_int_cst (TREE_TYPE (t
), 0));
14052 if (CAN_HAVE_LOCATION_P (c
))
14053 SET_EXPR_LOCATION (c
, expr_loc
);
14054 if (c
== boolean_true_node
)
14056 warning_at (expr_loc
, 0, "%<grainsize%> value must be positive");
14057 t
= integer_one_node
;
14060 check_no_duplicate_clause (list
, OMP_CLAUSE_GRAINSIZE
, "grainsize");
14062 c
= build_omp_clause (grainsize_loc
, OMP_CLAUSE_GRAINSIZE
);
14063 OMP_CLAUSE_GRAINSIZE_EXPR (c
) = t
;
14064 OMP_CLAUSE_GRAINSIZE_STRICT (c
) = strict
;
14065 OMP_CLAUSE_CHAIN (c
) = list
;
14073 priority ( expression ) */
14076 c_parser_omp_clause_priority (c_parser
*parser
, tree list
)
14078 location_t priority_loc
= c_parser_peek_token (parser
)->location
;
14079 matching_parens parens
;
14080 if (parens
.require_open (parser
))
14082 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
14083 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
14084 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
14085 tree c
, t
= expr
.value
;
14086 t
= c_fully_fold (t
, false, NULL
);
14088 parens
.skip_until_found_close (parser
);
14090 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
14092 c_parser_error (parser
, "expected integer expression");
14096 /* Attempt to statically determine when the number isn't
14098 c
= fold_build2_loc (expr_loc
, LT_EXPR
, boolean_type_node
, t
,
14099 build_int_cst (TREE_TYPE (t
), 0));
14100 if (CAN_HAVE_LOCATION_P (c
))
14101 SET_EXPR_LOCATION (c
, expr_loc
);
14102 if (c
== boolean_true_node
)
14104 warning_at (expr_loc
, 0, "%<priority%> value must be non-negative");
14105 t
= integer_one_node
;
14108 check_no_duplicate_clause (list
, OMP_CLAUSE_PRIORITY
, "priority");
14110 c
= build_omp_clause (priority_loc
, OMP_CLAUSE_PRIORITY
);
14111 OMP_CLAUSE_PRIORITY_EXPR (c
) = t
;
14112 OMP_CLAUSE_CHAIN (c
) = list
;
14120 hint ( expression ) */
14123 c_parser_omp_clause_hint (c_parser
*parser
, tree list
)
14125 location_t hint_loc
= c_parser_peek_token (parser
)->location
;
14126 matching_parens parens
;
14127 if (parens
.require_open (parser
))
14129 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
14130 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
14131 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
14132 tree c
, t
= expr
.value
;
14133 t
= c_fully_fold (t
, false, NULL
);
14134 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
))
14135 || TREE_CODE (t
) != INTEGER_CST
14136 || tree_int_cst_sgn (t
) == -1)
14138 c_parser_error (parser
, "expected constant integer expression "
14139 "with valid sync-hint value");
14142 parens
.skip_until_found_close (parser
);
14143 check_no_duplicate_clause (list
, OMP_CLAUSE_HINT
, "hint");
14145 c
= build_omp_clause (hint_loc
, OMP_CLAUSE_HINT
);
14146 OMP_CLAUSE_HINT_EXPR (c
) = t
;
14147 OMP_CLAUSE_CHAIN (c
) = list
;
14155 filter ( integer-expression ) */
14158 c_parser_omp_clause_filter (c_parser
*parser
, tree list
)
14160 location_t hint_loc
= c_parser_peek_token (parser
)->location
;
14161 matching_parens parens
;
14162 if (parens
.require_open (parser
))
14164 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
14165 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
14166 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
14167 tree c
, t
= expr
.value
;
14168 t
= c_fully_fold (t
, false, NULL
);
14169 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
14171 c_parser_error (parser
, "expected integer expression");
14174 parens
.skip_until_found_close (parser
);
14175 check_no_duplicate_clause (list
, OMP_CLAUSE_FILTER
, "filter");
14177 c
= build_omp_clause (hint_loc
, OMP_CLAUSE_FILTER
);
14178 OMP_CLAUSE_FILTER_EXPR (c
) = t
;
14179 OMP_CLAUSE_CHAIN (c
) = list
;
14187 defaultmap ( tofrom : scalar )
14190 defaultmap ( implicit-behavior [ : variable-category ] ) */
14193 c_parser_omp_clause_defaultmap (c_parser
*parser
, tree list
)
14195 location_t loc
= c_parser_peek_token (parser
)->location
;
14198 enum omp_clause_defaultmap_kind behavior
= OMP_CLAUSE_DEFAULTMAP_DEFAULT
;
14199 enum omp_clause_defaultmap_kind category
14200 = OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
;
14202 matching_parens parens
;
14203 if (!parens
.require_open (parser
))
14205 if (c_parser_next_token_is_keyword (parser
, RID_DEFAULT
))
14207 else if (!c_parser_next_token_is (parser
, CPP_NAME
))
14210 c_parser_error (parser
, "expected %<alloc%>, %<to%>, %<from%>, "
14211 "%<tofrom%>, %<firstprivate%>, %<none%> "
14216 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
14221 if (strcmp ("alloc", p
) == 0)
14222 behavior
= OMP_CLAUSE_DEFAULTMAP_ALLOC
;
14224 goto invalid_behavior
;
14228 if (strcmp ("default", p
) == 0)
14229 behavior
= OMP_CLAUSE_DEFAULTMAP_DEFAULT
;
14231 goto invalid_behavior
;
14235 if (strcmp ("firstprivate", p
) == 0)
14236 behavior
= OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE
;
14237 else if (strcmp ("from", p
) == 0)
14238 behavior
= OMP_CLAUSE_DEFAULTMAP_FROM
;
14240 goto invalid_behavior
;
14244 if (strcmp ("none", p
) == 0)
14245 behavior
= OMP_CLAUSE_DEFAULTMAP_NONE
;
14247 goto invalid_behavior
;
14251 if (strcmp ("tofrom", p
) == 0)
14252 behavior
= OMP_CLAUSE_DEFAULTMAP_TOFROM
;
14253 else if (strcmp ("to", p
) == 0)
14254 behavior
= OMP_CLAUSE_DEFAULTMAP_TO
;
14256 goto invalid_behavior
;
14260 goto invalid_behavior
;
14262 c_parser_consume_token (parser
);
14264 if (!c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
14266 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
14268 if (!c_parser_next_token_is (parser
, CPP_NAME
))
14271 c_parser_error (parser
, "expected %<scalar%>, %<aggregate%> or "
14275 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
14279 if (strcmp ("aggregate", p
) == 0)
14280 category
= OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE
;
14282 goto invalid_category
;
14286 if (strcmp ("pointer", p
) == 0)
14287 category
= OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER
;
14289 goto invalid_category
;
14293 if (strcmp ("scalar", p
) == 0)
14294 category
= OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR
;
14296 goto invalid_category
;
14300 goto invalid_category
;
14303 c_parser_consume_token (parser
);
14305 parens
.skip_until_found_close (parser
);
14307 for (c
= list
; c
; c
= OMP_CLAUSE_CHAIN (c
))
14308 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEFAULTMAP
14309 && (category
== OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
14310 || OMP_CLAUSE_DEFAULTMAP_CATEGORY (c
) == category
14311 || (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c
)
14312 == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
)))
14314 enum omp_clause_defaultmap_kind cat
= category
;
14315 location_t loc
= OMP_CLAUSE_LOCATION (c
);
14316 if (cat
== OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
)
14317 cat
= OMP_CLAUSE_DEFAULTMAP_CATEGORY (c
);
14321 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
:
14324 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE
:
14327 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER
:
14330 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR
:
14334 gcc_unreachable ();
14337 error_at (loc
, "too many %<defaultmap%> clauses with %qs category",
14340 error_at (loc
, "too many %<defaultmap%> clauses with unspecified "
14345 c
= build_omp_clause (loc
, OMP_CLAUSE_DEFAULTMAP
);
14346 OMP_CLAUSE_DEFAULTMAP_SET_KIND (c
, behavior
, category
);
14347 OMP_CLAUSE_CHAIN (c
) = list
;
14351 parens
.skip_until_found_close (parser
);
14356 use_device ( variable-list )
14359 use_device_ptr ( variable-list ) */
14362 c_parser_omp_clause_use_device_ptr (c_parser
*parser
, tree list
)
14364 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_USE_DEVICE_PTR
,
14369 use_device_addr ( variable-list ) */
14372 c_parser_omp_clause_use_device_addr (c_parser
*parser
, tree list
)
14374 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_USE_DEVICE_ADDR
,
14379 has_device_addr ( variable-list ) */
14382 c_parser_omp_clause_has_device_addr (c_parser
*parser
, tree list
)
14384 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_HAS_DEVICE_ADDR
,
14389 is_device_ptr ( variable-list ) */
14392 c_parser_omp_clause_is_device_ptr (c_parser
*parser
, tree list
)
14394 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_IS_DEVICE_PTR
, list
);
14398 num_gangs ( expression )
14399 num_workers ( expression )
14400 vector_length ( expression ) */
14403 c_parser_oacc_single_int_clause (c_parser
*parser
, omp_clause_code code
,
14406 location_t loc
= c_parser_peek_token (parser
)->location
;
14408 matching_parens parens
;
14409 if (!parens
.require_open (parser
))
14412 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
14413 c_expr expr
= c_parser_expression (parser
);
14414 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
14415 tree c
, t
= expr
.value
;
14416 t
= c_fully_fold (t
, false, NULL
);
14418 parens
.skip_until_found_close (parser
);
14420 if (t
== error_mark_node
)
14422 else if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
14424 error_at (expr_loc
, "%qs expression must be integral",
14425 omp_clause_code_name
[code
]);
14429 /* Attempt to statically determine when the number isn't positive. */
14430 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
14431 build_int_cst (TREE_TYPE (t
), 0));
14432 protected_set_expr_location (c
, expr_loc
);
14433 if (c
== boolean_true_node
)
14435 warning_at (expr_loc
, 0,
14436 "%qs value must be positive",
14437 omp_clause_code_name
[code
]);
14438 t
= integer_one_node
;
14441 check_no_duplicate_clause (list
, code
, omp_clause_code_name
[code
]);
14443 c
= build_omp_clause (loc
, code
);
14444 OMP_CLAUSE_OPERAND (c
, 0) = t
;
14445 OMP_CLAUSE_CHAIN (c
) = list
;
14451 gang [( gang-arg-list )]
14452 worker [( [num:] int-expr )]
14453 vector [( [length:] int-expr )]
14455 where gang-arg is one of:
14460 and size-expr may be:
14467 c_parser_oacc_shape_clause (c_parser
*parser
, location_t loc
,
14468 omp_clause_code kind
,
14469 const char *str
, tree list
)
14471 const char *id
= "num";
14472 tree ops
[2] = { NULL_TREE
, NULL_TREE
}, c
;
14474 if (kind
== OMP_CLAUSE_VECTOR
)
14477 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
14479 c_parser_consume_token (parser
);
14483 c_token
*next
= c_parser_peek_token (parser
);
14486 /* Gang static argument. */
14487 if (kind
== OMP_CLAUSE_GANG
14488 && c_parser_next_token_is_keyword (parser
, RID_STATIC
))
14490 c_parser_consume_token (parser
);
14492 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
14493 goto cleanup_error
;
14496 if (ops
[idx
] != NULL_TREE
)
14498 c_parser_error (parser
, "too many %<static%> arguments");
14499 goto cleanup_error
;
14502 /* Check for the '*' argument. */
14503 if (c_parser_next_token_is (parser
, CPP_MULT
)
14504 && (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
14505 || c_parser_peek_2nd_token (parser
)->type
14506 == CPP_CLOSE_PAREN
))
14508 c_parser_consume_token (parser
);
14509 ops
[idx
] = integer_minus_one_node
;
14511 if (c_parser_next_token_is (parser
, CPP_COMMA
))
14513 c_parser_consume_token (parser
);
14520 /* Worker num: argument and vector length: arguments. */
14521 else if (c_parser_next_token_is (parser
, CPP_NAME
)
14522 && strcmp (id
, IDENTIFIER_POINTER (next
->value
)) == 0
14523 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
14525 c_parser_consume_token (parser
); /* id */
14526 c_parser_consume_token (parser
); /* ':' */
14529 /* Now collect the actual argument. */
14530 if (ops
[idx
] != NULL_TREE
)
14532 c_parser_error (parser
, "unexpected argument");
14533 goto cleanup_error
;
14536 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
14537 c_expr cexpr
= c_parser_expr_no_commas (parser
, NULL
);
14538 cexpr
= convert_lvalue_to_rvalue (expr_loc
, cexpr
, false, true);
14539 tree expr
= cexpr
.value
;
14540 if (expr
== error_mark_node
)
14541 goto cleanup_error
;
14543 expr
= c_fully_fold (expr
, false, NULL
);
14545 /* Attempt to statically determine when the number isn't a
14546 positive integer. */
14548 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr
)))
14550 c_parser_error (parser
, "expected integer expression");
14554 tree c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, expr
,
14555 build_int_cst (TREE_TYPE (expr
), 0));
14556 if (c
== boolean_true_node
)
14558 warning_at (loc
, 0,
14559 "%qs value must be positive", str
);
14560 expr
= integer_one_node
;
14565 if (kind
== OMP_CLAUSE_GANG
14566 && c_parser_next_token_is (parser
, CPP_COMMA
))
14568 c_parser_consume_token (parser
);
14575 if (!c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
14576 goto cleanup_error
;
14579 check_no_duplicate_clause (list
, kind
, str
);
14581 c
= build_omp_clause (loc
, kind
);
14584 OMP_CLAUSE_OPERAND (c
, 1) = ops
[1];
14586 OMP_CLAUSE_OPERAND (c
, 0) = ops
[0];
14587 OMP_CLAUSE_CHAIN (c
) = list
;
14592 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, 0);
14604 c_parser_oacc_simple_clause (location_t loc
, enum omp_clause_code code
,
14607 check_no_duplicate_clause (list
, code
, omp_clause_code_name
[code
]);
14609 tree c
= build_omp_clause (loc
, code
);
14610 OMP_CLAUSE_CHAIN (c
) = list
;
14616 async [( int-expr )] */
14619 c_parser_oacc_clause_async (c_parser
*parser
, tree list
)
14622 location_t loc
= c_parser_peek_token (parser
)->location
;
14624 t
= build_int_cst (integer_type_node
, GOMP_ASYNC_NOVAL
);
14626 if (c_parser_peek_token (parser
)->type
== CPP_OPEN_PAREN
)
14628 c_parser_consume_token (parser
);
14630 t
= c_parser_expr_no_commas (parser
, NULL
).value
;
14631 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
14632 c_parser_error (parser
, "expected integer expression");
14633 else if (t
== error_mark_node
14634 || !c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
14638 t
= c_fully_fold (t
, false, NULL
);
14640 check_no_duplicate_clause (list
, OMP_CLAUSE_ASYNC
, "async");
14642 c
= build_omp_clause (loc
, OMP_CLAUSE_ASYNC
);
14643 OMP_CLAUSE_ASYNC_EXPR (c
) = t
;
14644 OMP_CLAUSE_CHAIN (c
) = list
;
14651 tile ( size-expr-list ) */
14654 c_parser_oacc_clause_tile (c_parser
*parser
, tree list
)
14656 tree c
, expr
= error_mark_node
;
14658 tree tile
= NULL_TREE
;
14660 check_no_duplicate_clause (list
, OMP_CLAUSE_TILE
, "tile");
14661 check_no_duplicate_clause (list
, OMP_CLAUSE_COLLAPSE
, "collapse");
14663 loc
= c_parser_peek_token (parser
)->location
;
14664 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
14669 if (tile
&& !c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
14672 if (c_parser_next_token_is (parser
, CPP_MULT
)
14673 && (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
14674 || c_parser_peek_2nd_token (parser
)->type
== CPP_CLOSE_PAREN
))
14676 c_parser_consume_token (parser
);
14677 expr
= integer_zero_node
;
14681 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
14682 c_expr cexpr
= c_parser_expr_no_commas (parser
, NULL
);
14683 cexpr
= convert_lvalue_to_rvalue (expr_loc
, cexpr
, false, true);
14684 expr
= cexpr
.value
;
14686 if (expr
== error_mark_node
)
14688 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
14693 expr
= c_fully_fold (expr
, false, NULL
);
14695 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr
))
14696 || !tree_fits_shwi_p (expr
)
14697 || tree_to_shwi (expr
) <= 0)
14699 error_at (expr_loc
, "%<tile%> argument needs positive"
14700 " integral constant");
14701 expr
= integer_zero_node
;
14705 tile
= tree_cons (NULL_TREE
, expr
, tile
);
14707 while (c_parser_next_token_is_not (parser
, CPP_CLOSE_PAREN
));
14709 /* Consume the trailing ')'. */
14710 c_parser_consume_token (parser
);
14712 c
= build_omp_clause (loc
, OMP_CLAUSE_TILE
);
14713 tile
= nreverse (tile
);
14714 OMP_CLAUSE_TILE_LIST (c
) = tile
;
14715 OMP_CLAUSE_CHAIN (c
) = list
;
14720 wait [( int-expr-list )] */
14723 c_parser_oacc_clause_wait (c_parser
*parser
, tree list
)
14725 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
14727 if (c_parser_peek_token (parser
)->type
== CPP_OPEN_PAREN
)
14728 list
= c_parser_oacc_wait_list (parser
, clause_loc
, list
);
14731 tree c
= build_omp_clause (clause_loc
, OMP_CLAUSE_WAIT
);
14733 OMP_CLAUSE_DECL (c
) = build_int_cst (integer_type_node
, GOMP_ASYNC_NOVAL
);
14734 OMP_CLAUSE_CHAIN (c
) = list
;
14743 order ( concurrent )
14746 order ( order-modifier : concurrent )
14753 c_parser_omp_clause_order (c_parser
*parser
, tree list
)
14755 location_t loc
= c_parser_peek_token (parser
)->location
;
14758 bool unconstrained
= false;
14759 bool reproducible
= false;
14761 matching_parens parens
;
14762 if (!parens
.require_open (parser
))
14764 if (c_parser_next_token_is (parser
, CPP_NAME
)
14765 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
14767 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
14768 if (strcmp (p
, "unconstrained") == 0)
14769 unconstrained
= true;
14770 else if (strcmp (p
, "reproducible") == 0)
14771 reproducible
= true;
14774 c_parser_error (parser
, "expected %<reproducible%> or "
14775 "%<unconstrained%>");
14778 c_parser_consume_token (parser
);
14779 c_parser_consume_token (parser
);
14781 if (!c_parser_next_token_is (parser
, CPP_NAME
))
14783 c_parser_error (parser
, "expected %<concurrent%>");
14786 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
14787 if (strcmp (p
, "concurrent") != 0)
14789 c_parser_error (parser
, "expected %<concurrent%>");
14792 c_parser_consume_token (parser
);
14793 parens
.skip_until_found_close (parser
);
14794 check_no_duplicate_clause (list
, OMP_CLAUSE_ORDER
, "order");
14795 c
= build_omp_clause (loc
, OMP_CLAUSE_ORDER
);
14796 OMP_CLAUSE_ORDER_UNCONSTRAINED (c
) = unconstrained
;
14797 OMP_CLAUSE_ORDER_REPRODUCIBLE (c
) = reproducible
;
14798 OMP_CLAUSE_CHAIN (c
) = list
;
14802 parens
.skip_until_found_close (parser
);
14808 bind ( teams | parallel | thread ) */
14811 c_parser_omp_clause_bind (c_parser
*parser
, tree list
)
14813 location_t loc
= c_parser_peek_token (parser
)->location
;
14816 enum omp_clause_bind_kind kind
= OMP_CLAUSE_BIND_THREAD
;
14818 matching_parens parens
;
14819 if (!parens
.require_open (parser
))
14821 if (!c_parser_next_token_is (parser
, CPP_NAME
))
14824 c_parser_error (parser
,
14825 "expected %<teams%>, %<parallel%> or %<thread%>");
14826 parens
.skip_until_found_close (parser
);
14829 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
14830 if (strcmp (p
, "teams") == 0)
14831 kind
= OMP_CLAUSE_BIND_TEAMS
;
14832 else if (strcmp (p
, "parallel") == 0)
14833 kind
= OMP_CLAUSE_BIND_PARALLEL
;
14834 else if (strcmp (p
, "thread") != 0)
14836 c_parser_consume_token (parser
);
14837 parens
.skip_until_found_close (parser
);
14838 /* check_no_duplicate_clause (list, OMP_CLAUSE_BIND, "bind"); */
14839 c
= build_omp_clause (loc
, OMP_CLAUSE_BIND
);
14840 OMP_CLAUSE_BIND_KIND (c
) = kind
;
14841 OMP_CLAUSE_CHAIN (c
) = list
;
14850 ordered ( constant-expression ) */
14853 c_parser_omp_clause_ordered (c_parser
*parser
, tree list
)
14855 check_no_duplicate_clause (list
, OMP_CLAUSE_ORDERED
, "ordered");
14857 tree c
, num
= NULL_TREE
;
14859 location_t loc
= c_parser_peek_token (parser
)->location
;
14860 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
14862 matching_parens parens
;
14863 parens
.consume_open (parser
);
14864 num
= c_parser_expr_no_commas (parser
, NULL
).value
;
14865 parens
.skip_until_found_close (parser
);
14867 if (num
== error_mark_node
)
14871 mark_exp_read (num
);
14872 num
= c_fully_fold (num
, false, NULL
);
14873 if (!INTEGRAL_TYPE_P (TREE_TYPE (num
))
14874 || !tree_fits_shwi_p (num
)
14875 || (n
= tree_to_shwi (num
)) <= 0
14878 error_at (loc
, "ordered argument needs positive "
14879 "constant integer expression");
14883 c
= build_omp_clause (loc
, OMP_CLAUSE_ORDERED
);
14884 OMP_CLAUSE_ORDERED_EXPR (c
) = num
;
14885 OMP_CLAUSE_CHAIN (c
) = list
;
14890 private ( variable-list ) */
14893 c_parser_omp_clause_private (c_parser
*parser
, tree list
)
14895 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_PRIVATE
, list
);
14899 reduction ( reduction-operator : variable-list )
14901 reduction-operator:
14902 One of: + * - & ^ | && ||
14906 reduction-operator:
14907 One of: + * - & ^ | && || max min
14911 reduction-operator:
14912 One of: + * - & ^ | && ||
14916 reduction ( reduction-modifier, reduction-operator : variable-list )
14917 in_reduction ( reduction-operator : variable-list )
14918 task_reduction ( reduction-operator : variable-list ) */
14921 c_parser_omp_clause_reduction (c_parser
*parser
, enum omp_clause_code kind
,
14922 bool is_omp
, tree list
)
14924 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
14925 matching_parens parens
;
14926 if (parens
.require_open (parser
))
14929 bool inscan
= false;
14930 enum tree_code code
= ERROR_MARK
;
14931 tree reduc_id
= NULL_TREE
;
14933 if (kind
== OMP_CLAUSE_REDUCTION
&& is_omp
)
14935 if (c_parser_next_token_is_keyword (parser
, RID_DEFAULT
)
14936 && c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
)
14938 c_parser_consume_token (parser
);
14939 c_parser_consume_token (parser
);
14941 else if (c_parser_next_token_is (parser
, CPP_NAME
)
14942 && c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
)
14945 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
14946 if (strcmp (p
, "task") == 0)
14948 else if (strcmp (p
, "inscan") == 0)
14950 if (task
|| inscan
)
14952 c_parser_consume_token (parser
);
14953 c_parser_consume_token (parser
);
14958 switch (c_parser_peek_token (parser
)->type
)
14970 code
= BIT_AND_EXPR
;
14973 code
= BIT_XOR_EXPR
;
14976 code
= BIT_IOR_EXPR
;
14979 code
= TRUTH_ANDIF_EXPR
;
14982 code
= TRUTH_ORIF_EXPR
;
14987 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
14988 if (strcmp (p
, "min") == 0)
14993 if (strcmp (p
, "max") == 0)
14998 reduc_id
= c_parser_peek_token (parser
)->value
;
15002 c_parser_error (parser
,
15003 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
15004 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
15005 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, 0);
15008 c_parser_consume_token (parser
);
15009 reduc_id
= c_omp_reduction_id (code
, reduc_id
);
15010 if (c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
15014 nl
= c_parser_omp_variable_list (parser
, clause_loc
, kind
, list
);
15015 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
15017 tree d
= OMP_CLAUSE_DECL (c
), type
;
15018 if (TREE_CODE (d
) != TREE_LIST
)
15019 type
= TREE_TYPE (d
);
15024 for (t
= d
; TREE_CODE (t
) == TREE_LIST
; t
= TREE_CHAIN (t
))
15026 type
= TREE_TYPE (t
);
15029 if (TREE_CODE (type
) != POINTER_TYPE
15030 && TREE_CODE (type
) != ARRAY_TYPE
)
15032 type
= TREE_TYPE (type
);
15036 while (TREE_CODE (type
) == ARRAY_TYPE
)
15037 type
= TREE_TYPE (type
);
15038 OMP_CLAUSE_REDUCTION_CODE (c
) = code
;
15040 OMP_CLAUSE_REDUCTION_TASK (c
) = 1;
15042 OMP_CLAUSE_REDUCTION_INSCAN (c
) = 1;
15043 if (code
== ERROR_MARK
15044 || !(INTEGRAL_TYPE_P (type
)
15045 || TREE_CODE (type
) == REAL_TYPE
15046 || TREE_CODE (type
) == COMPLEX_TYPE
))
15047 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
)
15048 = c_omp_reduction_lookup (reduc_id
,
15049 TYPE_MAIN_VARIANT (type
));
15054 parens
.skip_until_found_close (parser
);
15060 schedule ( schedule-kind )
15061 schedule ( schedule-kind , expression )
15064 static | dynamic | guided | runtime | auto
15067 schedule ( schedule-modifier : schedule-kind )
15068 schedule ( schedule-modifier [ , schedule-modifier ] : schedule-kind , expression )
15076 c_parser_omp_clause_schedule (c_parser
*parser
, tree list
)
15079 location_t loc
= c_parser_peek_token (parser
)->location
;
15080 int modifiers
= 0, nmodifiers
= 0;
15082 matching_parens parens
;
15083 if (!parens
.require_open (parser
))
15086 c
= build_omp_clause (loc
, OMP_CLAUSE_SCHEDULE
);
15088 location_t comma
= UNKNOWN_LOCATION
;
15089 while (c_parser_next_token_is (parser
, CPP_NAME
))
15091 tree kind
= c_parser_peek_token (parser
)->value
;
15092 const char *p
= IDENTIFIER_POINTER (kind
);
15093 if (strcmp ("simd", p
) == 0)
15094 OMP_CLAUSE_SCHEDULE_SIMD (c
) = 1;
15095 else if (strcmp ("monotonic", p
) == 0)
15096 modifiers
|= OMP_CLAUSE_SCHEDULE_MONOTONIC
;
15097 else if (strcmp ("nonmonotonic", p
) == 0)
15098 modifiers
|= OMP_CLAUSE_SCHEDULE_NONMONOTONIC
;
15101 comma
= UNKNOWN_LOCATION
;
15102 c_parser_consume_token (parser
);
15103 if (nmodifiers
++ == 0
15104 && c_parser_next_token_is (parser
, CPP_COMMA
))
15106 comma
= c_parser_peek_token (parser
)->location
;
15107 c_parser_consume_token (parser
);
15111 c_parser_require (parser
, CPP_COLON
, "expected %<:%>");
15115 if (comma
!= UNKNOWN_LOCATION
)
15116 error_at (comma
, "expected %<:%>");
15118 if ((modifiers
& (OMP_CLAUSE_SCHEDULE_MONOTONIC
15119 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC
))
15120 == (OMP_CLAUSE_SCHEDULE_MONOTONIC
15121 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC
))
15123 error_at (loc
, "both %<monotonic%> and %<nonmonotonic%> modifiers "
15128 if (c_parser_next_token_is (parser
, CPP_NAME
))
15130 tree kind
= c_parser_peek_token (parser
)->value
;
15131 const char *p
= IDENTIFIER_POINTER (kind
);
15136 if (strcmp ("dynamic", p
) != 0)
15138 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_DYNAMIC
;
15142 if (strcmp ("guided", p
) != 0)
15144 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_GUIDED
;
15148 if (strcmp ("runtime", p
) != 0)
15150 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_RUNTIME
;
15157 else if (c_parser_next_token_is_keyword (parser
, RID_STATIC
))
15158 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_STATIC
;
15159 else if (c_parser_next_token_is_keyword (parser
, RID_AUTO
))
15160 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_AUTO
;
15164 c_parser_consume_token (parser
);
15165 if (c_parser_next_token_is (parser
, CPP_COMMA
))
15168 c_parser_consume_token (parser
);
15170 here
= c_parser_peek_token (parser
)->location
;
15171 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15172 expr
= convert_lvalue_to_rvalue (here
, expr
, false, true);
15174 t
= c_fully_fold (t
, false, NULL
);
15176 if (OMP_CLAUSE_SCHEDULE_KIND (c
) == OMP_CLAUSE_SCHEDULE_RUNTIME
)
15177 error_at (here
, "schedule %<runtime%> does not take "
15178 "a %<chunk_size%> parameter");
15179 else if (OMP_CLAUSE_SCHEDULE_KIND (c
) == OMP_CLAUSE_SCHEDULE_AUTO
)
15181 "schedule %<auto%> does not take "
15182 "a %<chunk_size%> parameter");
15183 else if (TREE_CODE (TREE_TYPE (t
)) == INTEGER_TYPE
)
15185 /* Attempt to statically determine when the number isn't
15187 tree s
= fold_build2_loc (loc
, LE_EXPR
, boolean_type_node
, t
,
15188 build_int_cst (TREE_TYPE (t
), 0));
15189 protected_set_expr_location (s
, loc
);
15190 if (s
== boolean_true_node
)
15192 warning_at (loc
, 0,
15193 "chunk size value must be positive");
15194 t
= integer_one_node
;
15196 OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c
) = t
;
15199 c_parser_error (parser
, "expected integer expression");
15201 parens
.skip_until_found_close (parser
);
15204 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
15205 "expected %<,%> or %<)%>");
15207 OMP_CLAUSE_SCHEDULE_KIND (c
)
15208 = (enum omp_clause_schedule_kind
)
15209 (OMP_CLAUSE_SCHEDULE_KIND (c
) | modifiers
);
15211 check_no_duplicate_clause (list
, OMP_CLAUSE_SCHEDULE
, "schedule");
15212 OMP_CLAUSE_CHAIN (c
) = list
;
15216 c_parser_error (parser
, "invalid schedule kind");
15217 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, 0);
15222 shared ( variable-list ) */
15225 c_parser_omp_clause_shared (c_parser
*parser
, tree list
)
15227 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_SHARED
, list
);
15234 c_parser_omp_clause_untied (c_parser
*parser ATTRIBUTE_UNUSED
, tree list
)
15238 /* FIXME: Should we allow duplicates? */
15239 check_no_duplicate_clause (list
, OMP_CLAUSE_UNTIED
, "untied");
15241 c
= build_omp_clause (c_parser_peek_token (parser
)->location
,
15242 OMP_CLAUSE_UNTIED
);
15243 OMP_CLAUSE_CHAIN (c
) = list
;
15253 c_parser_omp_clause_branch (c_parser
*parser ATTRIBUTE_UNUSED
,
15254 enum omp_clause_code code
, tree list
)
15256 check_no_duplicate_clause (list
, code
, omp_clause_code_name
[code
]);
15258 tree c
= build_omp_clause (c_parser_peek_token (parser
)->location
, code
);
15259 OMP_CLAUSE_CHAIN (c
) = list
;
15271 c_parser_omp_clause_cancelkind (c_parser
*parser ATTRIBUTE_UNUSED
,
15272 enum omp_clause_code code
, tree list
)
15274 tree c
= build_omp_clause (c_parser_peek_token (parser
)->location
, code
);
15275 OMP_CLAUSE_CHAIN (c
) = list
;
15284 c_parser_omp_clause_nogroup (c_parser
*parser ATTRIBUTE_UNUSED
, tree list
)
15286 check_no_duplicate_clause (list
, OMP_CLAUSE_NOGROUP
, "nogroup");
15287 tree c
= build_omp_clause (c_parser_peek_token (parser
)->location
,
15288 OMP_CLAUSE_NOGROUP
);
15289 OMP_CLAUSE_CHAIN (c
) = list
;
15298 c_parser_omp_clause_orderedkind (c_parser
*parser ATTRIBUTE_UNUSED
,
15299 enum omp_clause_code code
, tree list
)
15301 check_no_duplicate_clause (list
, code
, omp_clause_code_name
[code
]);
15302 tree c
= build_omp_clause (c_parser_peek_token (parser
)->location
, code
);
15303 OMP_CLAUSE_CHAIN (c
) = list
;
15308 num_teams ( expression )
15311 num_teams ( expression : expression ) */
15314 c_parser_omp_clause_num_teams (c_parser
*parser
, tree list
)
15316 location_t num_teams_loc
= c_parser_peek_token (parser
)->location
;
15317 matching_parens parens
;
15318 if (parens
.require_open (parser
))
15320 location_t upper_loc
= c_parser_peek_token (parser
)->location
;
15321 location_t lower_loc
= UNKNOWN_LOCATION
;
15322 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15323 expr
= convert_lvalue_to_rvalue (upper_loc
, expr
, false, true);
15324 tree c
, upper
= expr
.value
, lower
= NULL_TREE
;
15325 upper
= c_fully_fold (upper
, false, NULL
);
15327 if (c_parser_next_token_is (parser
, CPP_COLON
))
15329 c_parser_consume_token (parser
);
15330 lower_loc
= upper_loc
;
15332 upper_loc
= c_parser_peek_token (parser
)->location
;
15333 expr
= c_parser_expr_no_commas (parser
, NULL
);
15334 expr
= convert_lvalue_to_rvalue (upper_loc
, expr
, false, true);
15335 upper
= expr
.value
;
15336 upper
= c_fully_fold (upper
, false, NULL
);
15339 parens
.skip_until_found_close (parser
);
15341 if (!INTEGRAL_TYPE_P (TREE_TYPE (upper
))
15342 || (lower
&& !INTEGRAL_TYPE_P (TREE_TYPE (lower
))))
15344 c_parser_error (parser
, "expected integer expression");
15348 /* Attempt to statically determine when the number isn't positive. */
15349 c
= fold_build2_loc (upper_loc
, LE_EXPR
, boolean_type_node
, upper
,
15350 build_int_cst (TREE_TYPE (upper
), 0));
15351 protected_set_expr_location (c
, upper_loc
);
15352 if (c
== boolean_true_node
)
15354 warning_at (upper_loc
, 0, "%<num_teams%> value must be positive");
15355 upper
= integer_one_node
;
15359 c
= fold_build2_loc (lower_loc
, LE_EXPR
, boolean_type_node
, lower
,
15360 build_int_cst (TREE_TYPE (lower
), 0));
15361 protected_set_expr_location (c
, lower_loc
);
15362 if (c
== boolean_true_node
)
15364 warning_at (lower_loc
, 0, "%<num_teams%> value must be positive");
15367 else if (TREE_CODE (lower
) == INTEGER_CST
15368 && TREE_CODE (upper
) == INTEGER_CST
15369 && tree_int_cst_lt (upper
, lower
))
15371 warning_at (lower_loc
, 0, "%<num_teams%> lower bound %qE bigger "
15372 "than upper bound %qE", lower
, upper
);
15377 check_no_duplicate_clause (list
, OMP_CLAUSE_NUM_TEAMS
, "num_teams");
15379 c
= build_omp_clause (num_teams_loc
, OMP_CLAUSE_NUM_TEAMS
);
15380 OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (c
) = upper
;
15381 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c
) = lower
;
15382 OMP_CLAUSE_CHAIN (c
) = list
;
15390 thread_limit ( expression ) */
15393 c_parser_omp_clause_thread_limit (c_parser
*parser
, tree list
)
15395 location_t num_thread_limit_loc
= c_parser_peek_token (parser
)->location
;
15396 matching_parens parens
;
15397 if (parens
.require_open (parser
))
15399 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
15400 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15401 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
15402 tree c
, t
= expr
.value
;
15403 t
= c_fully_fold (t
, false, NULL
);
15405 parens
.skip_until_found_close (parser
);
15407 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
15409 c_parser_error (parser
, "expected integer expression");
15413 /* Attempt to statically determine when the number isn't positive. */
15414 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
15415 build_int_cst (TREE_TYPE (t
), 0));
15416 protected_set_expr_location (c
, expr_loc
);
15417 if (c
== boolean_true_node
)
15419 warning_at (expr_loc
, 0, "%<thread_limit%> value must be positive");
15420 t
= integer_one_node
;
15423 check_no_duplicate_clause (list
, OMP_CLAUSE_THREAD_LIMIT
,
15426 c
= build_omp_clause (num_thread_limit_loc
, OMP_CLAUSE_THREAD_LIMIT
);
15427 OMP_CLAUSE_THREAD_LIMIT_EXPR (c
) = t
;
15428 OMP_CLAUSE_CHAIN (c
) = list
;
15436 aligned ( variable-list )
15437 aligned ( variable-list : constant-expression ) */
15440 c_parser_omp_clause_aligned (c_parser
*parser
, tree list
)
15442 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
15445 matching_parens parens
;
15446 if (!parens
.require_open (parser
))
15449 nl
= c_parser_omp_variable_list (parser
, clause_loc
,
15450 OMP_CLAUSE_ALIGNED
, list
);
15452 if (c_parser_next_token_is (parser
, CPP_COLON
))
15454 c_parser_consume_token (parser
);
15455 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
15456 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15457 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
15458 tree alignment
= expr
.value
;
15459 alignment
= c_fully_fold (alignment
, false, NULL
);
15460 if (TREE_CODE (alignment
) != INTEGER_CST
15461 || !INTEGRAL_TYPE_P (TREE_TYPE (alignment
))
15462 || tree_int_cst_sgn (alignment
) != 1)
15464 error_at (clause_loc
, "%<aligned%> clause alignment expression must "
15465 "be positive constant integer expression");
15466 alignment
= NULL_TREE
;
15469 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
15470 OMP_CLAUSE_ALIGNED_ALIGNMENT (c
) = alignment
;
15473 parens
.skip_until_found_close (parser
);
15478 allocate ( variable-list )
15479 allocate ( expression : variable-list )
15482 allocate ( allocator-modifier : variable-list )
15483 allocate ( allocator-modifier , allocator-modifier : variable-list )
15485 allocator-modifier:
15486 allocator ( expression )
15487 align ( expression ) */
15490 c_parser_omp_clause_allocate (c_parser
*parser
, tree list
)
15492 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
15494 tree allocator
= NULL_TREE
;
15495 tree align
= NULL_TREE
;
15497 matching_parens parens
;
15498 if (!parens
.require_open (parser
))
15501 if ((c_parser_next_token_is_not (parser
, CPP_NAME
)
15502 && c_parser_next_token_is_not (parser
, CPP_KEYWORD
))
15503 || (c_parser_peek_2nd_token (parser
)->type
!= CPP_COMMA
15504 && c_parser_peek_2nd_token (parser
)->type
!= CPP_CLOSE_PAREN
))
15506 bool has_modifiers
= false;
15507 tree orig_type
= NULL_TREE
;
15508 if (c_parser_next_token_is (parser
, CPP_NAME
)
15509 && c_parser_peek_2nd_token (parser
)->type
== CPP_OPEN_PAREN
)
15511 unsigned int n
= 3;
15513 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
15514 if ((strcmp (p
, "allocator") == 0 || strcmp (p
, "align") == 0)
15515 && c_parser_check_balanced_raw_token_sequence (parser
, &n
)
15516 && (c_parser_peek_nth_token_raw (parser
, n
)->type
15517 == CPP_CLOSE_PAREN
))
15519 if (c_parser_peek_nth_token_raw (parser
, n
+ 1)->type
15521 has_modifiers
= true;
15522 else if (c_parser_peek_nth_token_raw (parser
, n
+ 1)->type
15524 && (c_parser_peek_nth_token_raw (parser
, n
+ 2)->type
15526 && (c_parser_peek_nth_token_raw (parser
, n
+ 3)->type
15527 == CPP_OPEN_PAREN
))
15529 c_token
*tok
= c_parser_peek_nth_token_raw (parser
, n
+ 2);
15530 const char *q
= IDENTIFIER_POINTER (tok
->value
);
15532 if ((strcmp (q
, "allocator") == 0
15533 || strcmp (q
, "align") == 0)
15534 && c_parser_check_balanced_raw_token_sequence (parser
,
15536 && (c_parser_peek_nth_token_raw (parser
, n
)->type
15537 == CPP_CLOSE_PAREN
)
15538 && (c_parser_peek_nth_token_raw (parser
, n
+ 1)->type
15540 has_modifiers
= true;
15545 c_parser_consume_token (parser
);
15546 matching_parens parens2
;;
15547 parens2
.require_open (parser
);
15548 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
15549 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15550 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
15551 if (strcmp (p
, "allocator") == 0)
15553 allocator
= expr
.value
;
15554 allocator
= c_fully_fold (allocator
, false, NULL
);
15555 orig_type
= expr
.original_type
15556 ? expr
.original_type
: TREE_TYPE (allocator
);
15557 orig_type
= TYPE_MAIN_VARIANT (orig_type
);
15561 align
= expr
.value
;
15562 align
= c_fully_fold (align
, false, NULL
);
15564 parens2
.skip_until_found_close (parser
);
15565 if (c_parser_next_token_is (parser
, CPP_COMMA
))
15567 c_parser_consume_token (parser
);
15568 c_token
*tok
= c_parser_peek_token (parser
);
15569 const char *q
= "";
15570 if (c_parser_next_token_is (parser
, CPP_NAME
))
15571 q
= IDENTIFIER_POINTER (tok
->value
);
15572 if (strcmp (q
, "allocator") != 0 && strcmp (q
, "align") != 0)
15574 c_parser_error (parser
, "expected %<allocator%> or "
15576 parens
.skip_until_found_close (parser
);
15579 else if (strcmp (p
, q
) == 0)
15581 error_at (tok
->location
, "duplicate %qs modifier", p
);
15582 parens
.skip_until_found_close (parser
);
15585 c_parser_consume_token (parser
);
15586 if (!parens2
.require_open (parser
))
15588 parens
.skip_until_found_close (parser
);
15591 expr_loc
= c_parser_peek_token (parser
)->location
;
15592 expr
= c_parser_expr_no_commas (parser
, NULL
);
15593 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false,
15595 if (strcmp (q
, "allocator") == 0)
15597 allocator
= expr
.value
;
15598 allocator
= c_fully_fold (allocator
, false, NULL
);
15599 orig_type
= expr
.original_type
15600 ? expr
.original_type
: TREE_TYPE (allocator
);
15601 orig_type
= TYPE_MAIN_VARIANT (orig_type
);
15605 align
= expr
.value
;
15606 align
= c_fully_fold (align
, false, NULL
);
15608 parens2
.skip_until_found_close (parser
);
15612 if (!has_modifiers
)
15614 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
15615 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15616 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
15617 allocator
= expr
.value
;
15618 allocator
= c_fully_fold (allocator
, false, NULL
);
15619 orig_type
= expr
.original_type
15620 ? expr
.original_type
: TREE_TYPE (allocator
);
15621 orig_type
= TYPE_MAIN_VARIANT (orig_type
);
15624 && (!INTEGRAL_TYPE_P (TREE_TYPE (allocator
))
15625 || TREE_CODE (orig_type
) != ENUMERAL_TYPE
15626 || (TYPE_NAME (orig_type
)
15627 != get_identifier ("omp_allocator_handle_t"))))
15629 error_at (clause_loc
, "%<allocate%> clause allocator expression "
15630 "has type %qT rather than "
15631 "%<omp_allocator_handle_t%>",
15632 TREE_TYPE (allocator
));
15633 allocator
= NULL_TREE
;
15636 && (!INTEGRAL_TYPE_P (TREE_TYPE (align
))
15637 || !tree_fits_uhwi_p (align
)
15638 || !integer_pow2p (align
)))
15640 error_at (clause_loc
, "%<allocate%> clause %<align%> modifier "
15641 "argument needs to be positive constant "
15642 "power of two integer expression");
15645 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
15647 parens
.skip_until_found_close (parser
);
15652 nl
= c_parser_omp_variable_list (parser
, clause_loc
,
15653 OMP_CLAUSE_ALLOCATE
, list
);
15655 if (allocator
|| align
)
15656 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
15658 OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
) = allocator
;
15659 OMP_CLAUSE_ALLOCATE_ALIGN (c
) = align
;
15662 parens
.skip_until_found_close (parser
);
15667 linear ( variable-list )
15668 linear ( variable-list : expression )
15671 linear ( modifier ( variable-list ) )
15672 linear ( modifier ( variable-list ) : expression )
15678 linear ( variable-list : modifiers-list )
15682 step ( expression ) */
15685 c_parser_omp_clause_linear (c_parser
*parser
, tree list
)
15687 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
15689 enum omp_clause_linear_kind kind
= OMP_CLAUSE_LINEAR_DEFAULT
;
15690 bool old_linear_modifier
= false;
15692 matching_parens parens
;
15693 if (!parens
.require_open (parser
))
15696 if (c_parser_next_token_is (parser
, CPP_NAME
))
15698 c_token
*tok
= c_parser_peek_token (parser
);
15699 const char *p
= IDENTIFIER_POINTER (tok
->value
);
15700 if (strcmp ("val", p
) == 0)
15701 kind
= OMP_CLAUSE_LINEAR_VAL
;
15702 if (c_parser_peek_2nd_token (parser
)->type
!= CPP_OPEN_PAREN
)
15703 kind
= OMP_CLAUSE_LINEAR_DEFAULT
;
15704 if (kind
!= OMP_CLAUSE_LINEAR_DEFAULT
)
15706 old_linear_modifier
= true;
15707 c_parser_consume_token (parser
);
15708 c_parser_consume_token (parser
);
15712 nl
= c_parser_omp_variable_list (parser
, clause_loc
,
15713 OMP_CLAUSE_LINEAR
, list
);
15715 if (kind
!= OMP_CLAUSE_LINEAR_DEFAULT
)
15716 parens
.skip_until_found_close (parser
);
15718 if (c_parser_next_token_is (parser
, CPP_COLON
))
15720 c_parser_consume_token (parser
);
15721 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
15722 bool has_modifiers
= false;
15723 if (kind
== OMP_CLAUSE_LINEAR_DEFAULT
15724 && c_parser_next_token_is (parser
, CPP_NAME
))
15726 c_token
*tok
= c_parser_peek_token (parser
);
15727 const char *p
= IDENTIFIER_POINTER (tok
->value
);
15728 unsigned int pos
= 0;
15729 if (strcmp ("val", p
) == 0)
15731 else if (strcmp ("step", p
) == 0
15732 && c_parser_peek_2nd_token (parser
)->type
== CPP_OPEN_PAREN
)
15735 if (c_parser_check_balanced_raw_token_sequence (parser
, &pos
)
15736 && (c_parser_peek_nth_token_raw (parser
, pos
)->type
15737 == CPP_CLOSE_PAREN
))
15744 tok
= c_parser_peek_nth_token_raw (parser
, pos
);
15745 if (tok
->type
== CPP_COMMA
|| tok
->type
== CPP_CLOSE_PAREN
)
15746 has_modifiers
= true;
15752 while (c_parser_next_token_is (parser
, CPP_NAME
))
15754 c_token
*tok
= c_parser_peek_token (parser
);
15755 const char *p
= IDENTIFIER_POINTER (tok
->value
);
15756 if (strcmp ("val", p
) == 0)
15758 if (kind
!= OMP_CLAUSE_LINEAR_DEFAULT
)
15759 error_at (tok
->location
, "multiple linear modifiers");
15760 kind
= OMP_CLAUSE_LINEAR_DEFAULT
;
15761 c_parser_consume_token (parser
);
15763 else if (strcmp ("step", p
) == 0)
15765 c_parser_consume_token (parser
);
15766 matching_parens parens2
;
15767 if (parens2
.require_open (parser
))
15770 error_at (tok
->location
,
15771 "multiple %<step%> modifiers");
15772 expr_loc
= c_parser_peek_token (parser
)->location
;
15773 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15774 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false,
15776 step
= c_fully_fold (expr
.value
, false, NULL
);
15777 if (!INTEGRAL_TYPE_P (TREE_TYPE (step
)))
15779 error_at (clause_loc
, "%<linear%> clause step "
15780 "expression must be integral");
15781 step
= integer_one_node
;
15783 parens2
.skip_until_found_close (parser
);
15790 if (c_parser_next_token_is (parser
, CPP_COMMA
))
15792 c_parser_consume_token (parser
);
15798 step
= integer_one_node
;
15802 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15803 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
15804 step
= c_fully_fold (expr
.value
, false, NULL
);
15805 if (!INTEGRAL_TYPE_P (TREE_TYPE (step
)))
15807 error_at (clause_loc
, "%<linear%> clause step expression must "
15809 step
= integer_one_node
;
15815 step
= integer_one_node
;
15817 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
15819 OMP_CLAUSE_LINEAR_STEP (c
) = step
;
15820 OMP_CLAUSE_LINEAR_KIND (c
) = kind
;
15821 OMP_CLAUSE_LINEAR_OLD_LINEAR_MODIFIER (c
) = old_linear_modifier
;
15824 parens
.skip_until_found_close (parser
);
15829 nontemporal ( variable-list ) */
15832 c_parser_omp_clause_nontemporal (c_parser
*parser
, tree list
)
15834 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_NONTEMPORAL
, list
);
15838 safelen ( constant-expression ) */
15841 c_parser_omp_clause_safelen (c_parser
*parser
, tree list
)
15843 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
15846 matching_parens parens
;
15847 if (!parens
.require_open (parser
))
15850 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
15851 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15852 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
15854 t
= c_fully_fold (t
, false, NULL
);
15855 if (TREE_CODE (t
) != INTEGER_CST
15856 || !INTEGRAL_TYPE_P (TREE_TYPE (t
))
15857 || tree_int_cst_sgn (t
) != 1)
15859 error_at (clause_loc
, "%<safelen%> clause expression must "
15860 "be positive constant integer expression");
15864 parens
.skip_until_found_close (parser
);
15865 if (t
== NULL_TREE
|| t
== error_mark_node
)
15868 check_no_duplicate_clause (list
, OMP_CLAUSE_SAFELEN
, "safelen");
15870 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_SAFELEN
);
15871 OMP_CLAUSE_SAFELEN_EXPR (c
) = t
;
15872 OMP_CLAUSE_CHAIN (c
) = list
;
15877 simdlen ( constant-expression ) */
15880 c_parser_omp_clause_simdlen (c_parser
*parser
, tree list
)
15882 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
15885 matching_parens parens
;
15886 if (!parens
.require_open (parser
))
15889 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
15890 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15891 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
15893 t
= c_fully_fold (t
, false, NULL
);
15894 if (TREE_CODE (t
) != INTEGER_CST
15895 || !INTEGRAL_TYPE_P (TREE_TYPE (t
))
15896 || tree_int_cst_sgn (t
) != 1)
15898 error_at (clause_loc
, "%<simdlen%> clause expression must "
15899 "be positive constant integer expression");
15903 parens
.skip_until_found_close (parser
);
15904 if (t
== NULL_TREE
|| t
== error_mark_node
)
15907 check_no_duplicate_clause (list
, OMP_CLAUSE_SIMDLEN
, "simdlen");
15909 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_SIMDLEN
);
15910 OMP_CLAUSE_SIMDLEN_EXPR (c
) = t
;
15911 OMP_CLAUSE_CHAIN (c
) = list
;
15917 identifier [+/- integer]
15918 vec , identifier [+/- integer]
15922 c_parser_omp_clause_depend_sink (c_parser
*parser
, location_t clause_loc
,
15926 if (c_parser_next_token_is_not (parser
, CPP_NAME
)
15927 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
15929 c_parser_error (parser
, "expected identifier");
15933 while (c_parser_next_token_is (parser
, CPP_NAME
)
15934 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
)
15936 tree t
= lookup_name (c_parser_peek_token (parser
)->value
);
15937 tree addend
= NULL
;
15939 if (t
== NULL_TREE
)
15941 undeclared_variable (c_parser_peek_token (parser
)->location
,
15942 c_parser_peek_token (parser
)->value
);
15943 t
= error_mark_node
;
15946 c_parser_consume_token (parser
);
15949 if (c_parser_next_token_is (parser
, CPP_MINUS
))
15951 else if (!c_parser_next_token_is (parser
, CPP_PLUS
))
15953 addend
= integer_zero_node
;
15955 goto add_to_vector
;
15957 c_parser_consume_token (parser
);
15959 if (c_parser_next_token_is_not (parser
, CPP_NUMBER
))
15961 c_parser_error (parser
, "expected integer");
15965 addend
= c_parser_peek_token (parser
)->value
;
15966 if (TREE_CODE (addend
) != INTEGER_CST
)
15968 c_parser_error (parser
, "expected integer");
15971 c_parser_consume_token (parser
);
15974 if (t
!= error_mark_node
)
15976 vec
= tree_cons (addend
, t
, vec
);
15978 OMP_CLAUSE_DEPEND_SINK_NEGATIVE (vec
) = 1;
15981 if (c_parser_next_token_is_not (parser
, CPP_COMMA
)
15982 || c_parser_peek_2nd_token (parser
)->type
!= CPP_NAME
15983 || c_parser_peek_2nd_token (parser
)->id_kind
!= C_ID_ID
)
15986 c_parser_consume_token (parser
);
15989 if (vec
== NULL_TREE
)
15992 tree u
= build_omp_clause (clause_loc
, OMP_CLAUSE_DEPEND
);
15993 OMP_CLAUSE_DEPEND_KIND (u
) = OMP_CLAUSE_DEPEND_SINK
;
15994 OMP_CLAUSE_DECL (u
) = nreverse (vec
);
15995 OMP_CLAUSE_CHAIN (u
) = list
;
16000 iterators ( iterators-definition )
16002 iterators-definition:
16004 iterator-specifier , iterators-definition
16006 iterator-specifier:
16007 identifier = range-specification
16008 iterator-type identifier = range-specification
16010 range-specification:
16012 begin : end : step */
16015 c_parser_omp_iterators (c_parser
*parser
)
16017 tree ret
= NULL_TREE
, *last
= &ret
;
16018 c_parser_consume_token (parser
);
16022 matching_parens parens
;
16023 if (!parens
.require_open (parser
))
16024 return error_mark_node
;
16028 tree iter_type
= NULL_TREE
, type_expr
= NULL_TREE
;
16029 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_id
))
16031 struct c_type_name
*type
= c_parser_type_name (parser
);
16033 iter_type
= groktypename (type
, &type_expr
, NULL
);
16035 if (iter_type
== NULL_TREE
)
16036 iter_type
= integer_type_node
;
16038 location_t loc
= c_parser_peek_token (parser
)->location
;
16039 if (!c_parser_next_token_is (parser
, CPP_NAME
))
16041 c_parser_error (parser
, "expected identifier");
16045 tree id
= c_parser_peek_token (parser
)->value
;
16046 c_parser_consume_token (parser
);
16048 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
16051 location_t eloc
= c_parser_peek_token (parser
)->location
;
16052 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
16053 expr
= convert_lvalue_to_rvalue (eloc
, expr
, true, false);
16054 tree begin
= expr
.value
;
16056 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
16059 eloc
= c_parser_peek_token (parser
)->location
;
16060 expr
= c_parser_expr_no_commas (parser
, NULL
);
16061 expr
= convert_lvalue_to_rvalue (eloc
, expr
, true, false);
16062 tree end
= expr
.value
;
16064 tree step
= integer_one_node
;
16065 if (c_parser_next_token_is (parser
, CPP_COLON
))
16067 c_parser_consume_token (parser
);
16068 eloc
= c_parser_peek_token (parser
)->location
;
16069 expr
= c_parser_expr_no_commas (parser
, NULL
);
16070 expr
= convert_lvalue_to_rvalue (eloc
, expr
, true, false);
16074 tree iter_var
= build_decl (loc
, VAR_DECL
, id
, iter_type
);
16075 DECL_ARTIFICIAL (iter_var
) = 1;
16076 DECL_CONTEXT (iter_var
) = current_function_decl
;
16077 pushdecl (iter_var
);
16079 *last
= make_tree_vec (6);
16080 TREE_VEC_ELT (*last
, 0) = iter_var
;
16081 TREE_VEC_ELT (*last
, 1) = begin
;
16082 TREE_VEC_ELT (*last
, 2) = end
;
16083 TREE_VEC_ELT (*last
, 3) = step
;
16084 last
= &TREE_CHAIN (*last
);
16086 if (c_parser_next_token_is (parser
, CPP_COMMA
))
16088 c_parser_consume_token (parser
);
16095 parens
.skip_until_found_close (parser
);
16096 return ret
? ret
: error_mark_node
;
16100 affinity ( [aff-modifier :] variable-list )
16102 iterator ( iterators-definition ) */
16105 c_parser_omp_clause_affinity (c_parser
*parser
, tree list
)
16107 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
16108 tree nl
, iterators
= NULL_TREE
;
16110 matching_parens parens
;
16111 if (!parens
.require_open (parser
))
16114 if (c_parser_next_token_is (parser
, CPP_NAME
))
16116 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
16117 bool parse_iter
= ((strcmp ("iterator", p
) == 0)
16118 && (c_parser_peek_2nd_token (parser
)->type
16119 == CPP_OPEN_PAREN
));
16123 parse_iter
= (c_parser_check_balanced_raw_token_sequence (parser
, &n
)
16124 && (c_parser_peek_nth_token_raw (parser
, n
)->type
16125 == CPP_CLOSE_PAREN
)
16126 && (c_parser_peek_nth_token_raw (parser
, n
+ 1)->type
16131 iterators
= c_parser_omp_iterators (parser
);
16132 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
16136 parens
.skip_until_found_close (parser
);
16141 nl
= c_parser_omp_variable_list (parser
, clause_loc
, OMP_CLAUSE_AFFINITY
,
16145 tree block
= pop_scope ();
16146 if (iterators
!= error_mark_node
)
16148 TREE_VEC_ELT (iterators
, 5) = block
;
16149 for (tree c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
16150 OMP_CLAUSE_DECL (c
) = build_tree_list (iterators
,
16151 OMP_CLAUSE_DECL (c
));
16155 parens
.skip_until_found_close (parser
);
16161 depend ( depend-kind: variable-list )
16169 depend ( sink : vec )
16172 depend ( depend-modifier , depend-kind: variable-list )
16175 in | out | inout | mutexinoutset | depobj | inoutset
16178 iterator ( iterators-definition ) */
16181 c_parser_omp_clause_depend (c_parser
*parser
, tree list
)
16183 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
16184 enum omp_clause_depend_kind kind
= OMP_CLAUSE_DEPEND_LAST
;
16185 tree nl
, c
, iterators
= NULL_TREE
;
16187 matching_parens parens
;
16188 if (!parens
.require_open (parser
))
16193 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
16196 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
16197 if (strcmp ("iterator", p
) == 0 && iterators
== NULL_TREE
)
16199 iterators
= c_parser_omp_iterators (parser
);
16200 c_parser_require (parser
, CPP_COMMA
, "expected %<,%>");
16203 if (strcmp ("in", p
) == 0)
16204 kind
= OMP_CLAUSE_DEPEND_IN
;
16205 else if (strcmp ("inout", p
) == 0)
16206 kind
= OMP_CLAUSE_DEPEND_INOUT
;
16207 else if (strcmp ("inoutset", p
) == 0)
16208 kind
= OMP_CLAUSE_DEPEND_INOUTSET
;
16209 else if (strcmp ("mutexinoutset", p
) == 0)
16210 kind
= OMP_CLAUSE_DEPEND_MUTEXINOUTSET
;
16211 else if (strcmp ("out", p
) == 0)
16212 kind
= OMP_CLAUSE_DEPEND_OUT
;
16213 else if (strcmp ("depobj", p
) == 0)
16214 kind
= OMP_CLAUSE_DEPEND_DEPOBJ
;
16215 else if (strcmp ("sink", p
) == 0)
16216 kind
= OMP_CLAUSE_DEPEND_SINK
;
16217 else if (strcmp ("source", p
) == 0)
16218 kind
= OMP_CLAUSE_DEPEND_SOURCE
;
16225 c_parser_consume_token (parser
);
16228 && (kind
== OMP_CLAUSE_DEPEND_SOURCE
|| kind
== OMP_CLAUSE_DEPEND_SINK
))
16231 error_at (clause_loc
, "%<iterator%> modifier incompatible with %qs",
16232 kind
== OMP_CLAUSE_DEPEND_SOURCE
? "source" : "sink");
16233 iterators
= NULL_TREE
;
16236 if (kind
== OMP_CLAUSE_DEPEND_SOURCE
)
16238 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_DEPEND
);
16239 OMP_CLAUSE_DEPEND_KIND (c
) = kind
;
16240 OMP_CLAUSE_DECL (c
) = NULL_TREE
;
16241 OMP_CLAUSE_CHAIN (c
) = list
;
16242 parens
.skip_until_found_close (parser
);
16246 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
16249 if (kind
== OMP_CLAUSE_DEPEND_SINK
)
16250 nl
= c_parser_omp_clause_depend_sink (parser
, clause_loc
, list
);
16253 nl
= c_parser_omp_variable_list (parser
, clause_loc
,
16254 OMP_CLAUSE_DEPEND
, list
);
16258 tree block
= pop_scope ();
16259 if (iterators
== error_mark_node
)
16260 iterators
= NULL_TREE
;
16262 TREE_VEC_ELT (iterators
, 5) = block
;
16265 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
16267 OMP_CLAUSE_DEPEND_KIND (c
) = kind
;
16269 OMP_CLAUSE_DECL (c
)
16270 = build_tree_list (iterators
, OMP_CLAUSE_DECL (c
));
16274 parens
.skip_until_found_close (parser
);
16278 c_parser_error (parser
, "invalid depend kind");
16280 parens
.skip_until_found_close (parser
);
16287 map ( map-kind: variable-list )
16288 map ( variable-list )
16291 alloc | to | from | tofrom
16295 alloc | to | from | tofrom | release | delete
16297 map ( always [,] map-kind: variable-list )
16300 map ( [map-type-modifier[,] ...] map-kind: variable-list )
16306 c_parser_omp_clause_map (c_parser
*parser
, tree list
)
16308 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
16309 enum gomp_map_kind kind
= GOMP_MAP_TOFROM
;
16312 matching_parens parens
;
16313 if (!parens
.require_open (parser
))
16317 int map_kind_pos
= 0;
16318 while (c_parser_peek_nth_token_raw (parser
, pos
)->type
== CPP_NAME
)
16320 if (c_parser_peek_nth_token_raw (parser
, pos
+ 1)->type
== CPP_COLON
)
16322 map_kind_pos
= pos
;
16326 if (c_parser_peek_nth_token_raw (parser
, pos
+ 1)->type
== CPP_COMMA
)
16331 int always_modifier
= 0;
16332 int close_modifier
= 0;
16333 for (int pos
= 1; pos
< map_kind_pos
; ++pos
)
16335 c_token
*tok
= c_parser_peek_token (parser
);
16337 if (tok
->type
== CPP_COMMA
)
16339 c_parser_consume_token (parser
);
16343 const char *p
= IDENTIFIER_POINTER (tok
->value
);
16344 if (strcmp ("always", p
) == 0)
16346 if (always_modifier
)
16348 c_parser_error (parser
, "too many %<always%> modifiers");
16349 parens
.skip_until_found_close (parser
);
16354 else if (strcmp ("close", p
) == 0)
16356 if (close_modifier
)
16358 c_parser_error (parser
, "too many %<close%> modifiers");
16359 parens
.skip_until_found_close (parser
);
16366 c_parser_error (parser
, "%<#pragma omp target%> with "
16367 "modifier other than %<always%> or "
16368 "%<close%> on %<map%> clause");
16369 parens
.skip_until_found_close (parser
);
16373 c_parser_consume_token (parser
);
16376 if (c_parser_next_token_is (parser
, CPP_NAME
)
16377 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
16379 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
16380 if (strcmp ("alloc", p
) == 0)
16381 kind
= GOMP_MAP_ALLOC
;
16382 else if (strcmp ("to", p
) == 0)
16383 kind
= always_modifier
? GOMP_MAP_ALWAYS_TO
: GOMP_MAP_TO
;
16384 else if (strcmp ("from", p
) == 0)
16385 kind
= always_modifier
? GOMP_MAP_ALWAYS_FROM
: GOMP_MAP_FROM
;
16386 else if (strcmp ("tofrom", p
) == 0)
16387 kind
= always_modifier
? GOMP_MAP_ALWAYS_TOFROM
: GOMP_MAP_TOFROM
;
16388 else if (strcmp ("release", p
) == 0)
16389 kind
= GOMP_MAP_RELEASE
;
16390 else if (strcmp ("delete", p
) == 0)
16391 kind
= GOMP_MAP_DELETE
;
16394 c_parser_error (parser
, "invalid map kind");
16395 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
16399 c_parser_consume_token (parser
);
16400 c_parser_consume_token (parser
);
16403 nl
= c_parser_omp_variable_list (parser
, clause_loc
, OMP_CLAUSE_MAP
, list
,
16406 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
16407 OMP_CLAUSE_SET_MAP_KIND (c
, kind
);
16409 parens
.skip_until_found_close (parser
);
16414 device ( expression )
16417 device ( [device-modifier :] integer-expression )
16420 ancestor | device_num */
16423 c_parser_omp_clause_device (c_parser
*parser
, tree list
)
16425 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
16426 location_t expr_loc
;
16429 bool ancestor
= false;
16431 matching_parens parens
;
16432 if (!parens
.require_open (parser
))
16435 if (c_parser_next_token_is (parser
, CPP_NAME
)
16436 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
16438 c_token
*tok
= c_parser_peek_token (parser
);
16439 const char *p
= IDENTIFIER_POINTER (tok
->value
);
16440 if (strcmp ("ancestor", p
) == 0)
16442 /* A requires directive with the reverse_offload clause must be
16444 if ((omp_requires_mask
& OMP_REQUIRES_REVERSE_OFFLOAD
) == 0)
16446 error_at (tok
->location
, "%<ancestor%> device modifier not "
16447 "preceded by %<requires%> directive "
16448 "with %<reverse_offload%> clause");
16449 parens
.skip_until_found_close (parser
);
16454 else if (strcmp ("device_num", p
) == 0)
16458 error_at (tok
->location
, "expected %<ancestor%> or %<device_num%>");
16459 parens
.skip_until_found_close (parser
);
16462 c_parser_consume_token (parser
);
16463 c_parser_consume_token (parser
);
16466 expr_loc
= c_parser_peek_token (parser
)->location
;
16467 expr
= c_parser_expr_no_commas (parser
, NULL
);
16468 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
16470 t
= c_fully_fold (t
, false, NULL
);
16472 parens
.skip_until_found_close (parser
);
16474 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
16476 c_parser_error (parser
, "expected integer expression");
16479 if (ancestor
&& TREE_CODE (t
) == INTEGER_CST
&& !integer_onep (t
))
16481 error_at (expr_loc
, "the %<device%> clause expression must evaluate to "
16486 check_no_duplicate_clause (list
, OMP_CLAUSE_DEVICE
, "device");
16488 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_DEVICE
);
16490 OMP_CLAUSE_DEVICE_ID (c
) = t
;
16491 OMP_CLAUSE_CHAIN (c
) = list
;
16492 OMP_CLAUSE_DEVICE_ANCESTOR (c
) = ancestor
;
16499 dist_schedule ( static )
16500 dist_schedule ( static , expression ) */
16503 c_parser_omp_clause_dist_schedule (c_parser
*parser
, tree list
)
16505 tree c
, t
= NULL_TREE
;
16506 location_t loc
= c_parser_peek_token (parser
)->location
;
16508 matching_parens parens
;
16509 if (!parens
.require_open (parser
))
16512 if (!c_parser_next_token_is_keyword (parser
, RID_STATIC
))
16514 c_parser_error (parser
, "invalid dist_schedule kind");
16515 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
16520 c_parser_consume_token (parser
);
16521 if (c_parser_next_token_is (parser
, CPP_COMMA
))
16523 c_parser_consume_token (parser
);
16525 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
16526 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
16527 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
16529 t
= c_fully_fold (t
, false, NULL
);
16530 parens
.skip_until_found_close (parser
);
16533 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
16534 "expected %<,%> or %<)%>");
16536 /* check_no_duplicate_clause (list, OMP_CLAUSE_DIST_SCHEDULE,
16537 "dist_schedule"); */
16538 if (omp_find_clause (list
, OMP_CLAUSE_DIST_SCHEDULE
))
16539 warning_at (loc
, 0, "too many %qs clauses", "dist_schedule");
16540 if (t
== error_mark_node
)
16543 c
= build_omp_clause (loc
, OMP_CLAUSE_DIST_SCHEDULE
);
16544 OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c
) = t
;
16545 OMP_CLAUSE_CHAIN (c
) = list
;
16550 proc_bind ( proc-bind-kind )
16553 primary | master | close | spread
16554 where OpenMP 5.1 added 'primary' and deprecated the alias 'master'. */
16557 c_parser_omp_clause_proc_bind (c_parser
*parser
, tree list
)
16559 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
16560 enum omp_clause_proc_bind_kind kind
;
16563 matching_parens parens
;
16564 if (!parens
.require_open (parser
))
16567 if (c_parser_next_token_is (parser
, CPP_NAME
))
16569 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
16570 if (strcmp ("primary", p
) == 0)
16571 kind
= OMP_CLAUSE_PROC_BIND_PRIMARY
;
16572 else if (strcmp ("master", p
) == 0)
16573 kind
= OMP_CLAUSE_PROC_BIND_MASTER
;
16574 else if (strcmp ("close", p
) == 0)
16575 kind
= OMP_CLAUSE_PROC_BIND_CLOSE
;
16576 else if (strcmp ("spread", p
) == 0)
16577 kind
= OMP_CLAUSE_PROC_BIND_SPREAD
;
16584 check_no_duplicate_clause (list
, OMP_CLAUSE_PROC_BIND
, "proc_bind");
16585 c_parser_consume_token (parser
);
16586 parens
.skip_until_found_close (parser
);
16587 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_PROC_BIND
);
16588 OMP_CLAUSE_PROC_BIND_KIND (c
) = kind
;
16589 OMP_CLAUSE_CHAIN (c
) = list
;
16593 c_parser_error (parser
, "invalid proc_bind kind");
16594 parens
.skip_until_found_close (parser
);
16599 device_type ( host | nohost | any ) */
16602 c_parser_omp_clause_device_type (c_parser
*parser
, tree list
)
16604 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
16605 enum omp_clause_device_type_kind kind
;
16608 matching_parens parens
;
16609 if (!parens
.require_open (parser
))
16612 if (c_parser_next_token_is (parser
, CPP_NAME
))
16614 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
16615 if (strcmp ("host", p
) == 0)
16616 kind
= OMP_CLAUSE_DEVICE_TYPE_HOST
;
16617 else if (strcmp ("nohost", p
) == 0)
16618 kind
= OMP_CLAUSE_DEVICE_TYPE_NOHOST
;
16619 else if (strcmp ("any", p
) == 0)
16620 kind
= OMP_CLAUSE_DEVICE_TYPE_ANY
;
16627 /* check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE_TYPE,
16629 c_parser_consume_token (parser
);
16630 parens
.skip_until_found_close (parser
);
16631 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_DEVICE_TYPE
);
16632 OMP_CLAUSE_DEVICE_TYPE_KIND (c
) = kind
;
16633 OMP_CLAUSE_CHAIN (c
) = list
;
16637 c_parser_error (parser
, "expected %<host%>, %<nohost%> or %<any%>");
16638 parens
.skip_until_found_close (parser
);
16643 to ( variable-list ) */
16646 c_parser_omp_clause_to (c_parser
*parser
, tree list
)
16648 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_TO
, list
, true);
16652 from ( variable-list ) */
16655 c_parser_omp_clause_from (c_parser
*parser
, tree list
)
16657 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_FROM
, list
, true);
16661 uniform ( variable-list ) */
16664 c_parser_omp_clause_uniform (c_parser
*parser
, tree list
)
16666 /* The clauses location. */
16667 location_t loc
= c_parser_peek_token (parser
)->location
;
16669 matching_parens parens
;
16670 if (parens
.require_open (parser
))
16672 list
= c_parser_omp_variable_list (parser
, loc
, OMP_CLAUSE_UNIFORM
,
16674 parens
.skip_until_found_close (parser
);
16680 detach ( event-handle ) */
16683 c_parser_omp_clause_detach (c_parser
*parser
, tree list
)
16685 matching_parens parens
;
16686 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
16688 if (!parens
.require_open (parser
))
16691 if (c_parser_next_token_is_not (parser
, CPP_NAME
)
16692 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
16694 c_parser_error (parser
, "expected identifier");
16695 parens
.skip_until_found_close (parser
);
16699 tree t
= lookup_name (c_parser_peek_token (parser
)->value
);
16700 if (t
== NULL_TREE
)
16702 undeclared_variable (c_parser_peek_token (parser
)->location
,
16703 c_parser_peek_token (parser
)->value
);
16704 parens
.skip_until_found_close (parser
);
16707 c_parser_consume_token (parser
);
16709 tree type
= TYPE_MAIN_VARIANT (TREE_TYPE (t
));
16710 if (!INTEGRAL_TYPE_P (type
)
16711 || TREE_CODE (type
) != ENUMERAL_TYPE
16712 || TYPE_NAME (type
) != get_identifier ("omp_event_handle_t"))
16714 error_at (clause_loc
, "%<detach%> clause event handle "
16715 "has type %qT rather than "
16716 "%<omp_event_handle_t%>",
16718 parens
.skip_until_found_close (parser
);
16722 tree u
= build_omp_clause (clause_loc
, OMP_CLAUSE_DETACH
);
16723 OMP_CLAUSE_DECL (u
) = t
;
16724 OMP_CLAUSE_CHAIN (u
) = list
;
16725 parens
.skip_until_found_close (parser
);
16729 /* Parse all OpenACC clauses. The set clauses allowed by the directive
16730 is a bitmask in MASK. Return the list of clauses found. */
16733 c_parser_oacc_all_clauses (c_parser
*parser
, omp_clause_mask mask
,
16734 const char *where
, bool finish_p
= true)
16736 tree clauses
= NULL
;
16739 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
16742 pragma_omp_clause c_kind
;
16743 const char *c_name
;
16744 tree prev
= clauses
;
16746 if (!first
&& c_parser_next_token_is (parser
, CPP_COMMA
))
16747 c_parser_consume_token (parser
);
16749 here
= c_parser_peek_token (parser
)->location
;
16750 c_kind
= c_parser_omp_clause_name (parser
);
16754 case PRAGMA_OACC_CLAUSE_ASYNC
:
16755 clauses
= c_parser_oacc_clause_async (parser
, clauses
);
16758 case PRAGMA_OACC_CLAUSE_AUTO
:
16759 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_AUTO
,
16763 case PRAGMA_OACC_CLAUSE_ATTACH
:
16764 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16767 case PRAGMA_OACC_CLAUSE_COLLAPSE
:
16768 clauses
= c_parser_omp_clause_collapse (parser
, clauses
);
16769 c_name
= "collapse";
16771 case PRAGMA_OACC_CLAUSE_COPY
:
16772 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16775 case PRAGMA_OACC_CLAUSE_COPYIN
:
16776 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16779 case PRAGMA_OACC_CLAUSE_COPYOUT
:
16780 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16781 c_name
= "copyout";
16783 case PRAGMA_OACC_CLAUSE_CREATE
:
16784 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16787 case PRAGMA_OACC_CLAUSE_DELETE
:
16788 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16791 case PRAGMA_OMP_CLAUSE_DEFAULT
:
16792 clauses
= c_parser_omp_clause_default (parser
, clauses
, true);
16793 c_name
= "default";
16795 case PRAGMA_OACC_CLAUSE_DETACH
:
16796 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16799 case PRAGMA_OACC_CLAUSE_DEVICE
:
16800 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16803 case PRAGMA_OACC_CLAUSE_DEVICEPTR
:
16804 clauses
= c_parser_oacc_data_clause_deviceptr (parser
, clauses
);
16805 c_name
= "deviceptr";
16807 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT
:
16808 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16809 c_name
= "device_resident";
16811 case PRAGMA_OACC_CLAUSE_FINALIZE
:
16812 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_FINALIZE
,
16814 c_name
= "finalize";
16816 case PRAGMA_OACC_CLAUSE_FIRSTPRIVATE
:
16817 clauses
= c_parser_omp_clause_firstprivate (parser
, clauses
);
16818 c_name
= "firstprivate";
16820 case PRAGMA_OACC_CLAUSE_GANG
:
16822 clauses
= c_parser_oacc_shape_clause (parser
, here
, OMP_CLAUSE_GANG
,
16825 case PRAGMA_OACC_CLAUSE_HOST
:
16826 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16829 case PRAGMA_OACC_CLAUSE_IF
:
16830 clauses
= c_parser_omp_clause_if (parser
, clauses
, false);
16833 case PRAGMA_OACC_CLAUSE_IF_PRESENT
:
16834 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_IF_PRESENT
,
16836 c_name
= "if_present";
16838 case PRAGMA_OACC_CLAUSE_INDEPENDENT
:
16839 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_INDEPENDENT
,
16841 c_name
= "independent";
16843 case PRAGMA_OACC_CLAUSE_LINK
:
16844 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16847 case PRAGMA_OACC_CLAUSE_NO_CREATE
:
16848 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16849 c_name
= "no_create";
16851 case PRAGMA_OACC_CLAUSE_NOHOST
:
16852 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_NOHOST
,
16856 case PRAGMA_OACC_CLAUSE_NUM_GANGS
:
16857 clauses
= c_parser_oacc_single_int_clause (parser
,
16858 OMP_CLAUSE_NUM_GANGS
,
16860 c_name
= "num_gangs";
16862 case PRAGMA_OACC_CLAUSE_NUM_WORKERS
:
16863 clauses
= c_parser_oacc_single_int_clause (parser
,
16864 OMP_CLAUSE_NUM_WORKERS
,
16866 c_name
= "num_workers";
16868 case PRAGMA_OACC_CLAUSE_PRESENT
:
16869 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16870 c_name
= "present";
16872 case PRAGMA_OACC_CLAUSE_PRIVATE
:
16873 clauses
= c_parser_omp_clause_private (parser
, clauses
);
16874 c_name
= "private";
16876 case PRAGMA_OACC_CLAUSE_REDUCTION
:
16878 = c_parser_omp_clause_reduction (parser
, OMP_CLAUSE_REDUCTION
,
16880 c_name
= "reduction";
16882 case PRAGMA_OACC_CLAUSE_SEQ
:
16883 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_SEQ
,
16887 case PRAGMA_OACC_CLAUSE_TILE
:
16888 clauses
= c_parser_oacc_clause_tile (parser
, clauses
);
16891 case PRAGMA_OACC_CLAUSE_USE_DEVICE
:
16892 clauses
= c_parser_omp_clause_use_device_ptr (parser
, clauses
);
16893 c_name
= "use_device";
16895 case PRAGMA_OACC_CLAUSE_VECTOR
:
16897 clauses
= c_parser_oacc_shape_clause (parser
, here
, OMP_CLAUSE_VECTOR
,
16900 case PRAGMA_OACC_CLAUSE_VECTOR_LENGTH
:
16901 clauses
= c_parser_oacc_single_int_clause (parser
,
16902 OMP_CLAUSE_VECTOR_LENGTH
,
16904 c_name
= "vector_length";
16906 case PRAGMA_OACC_CLAUSE_WAIT
:
16907 clauses
= c_parser_oacc_clause_wait (parser
, clauses
);
16910 case PRAGMA_OACC_CLAUSE_WORKER
:
16912 clauses
= c_parser_oacc_shape_clause (parser
, here
, OMP_CLAUSE_WORKER
,
16916 c_parser_error (parser
, "expected %<#pragma acc%> clause");
16922 if (((mask
>> c_kind
) & 1) == 0)
16924 /* Remove the invalid clause(s) from the list to avoid
16925 confusing the rest of the compiler. */
16927 error_at (here
, "%qs is not valid for %qs", c_name
, where
);
16932 c_parser_skip_to_pragma_eol (parser
);
16935 return c_finish_omp_clauses (clauses
, C_ORT_ACC
);
16940 /* Parse all OpenMP clauses. The set clauses allowed by the directive
16941 is a bitmask in MASK. Return the list of clauses found.
16942 FINISH_P set if c_finish_omp_clauses should be called.
16943 NESTED non-zero if clauses should be terminated by closing paren instead
16944 of end of pragma. If it is 2, additionally commas are required in between
16948 c_parser_omp_all_clauses (c_parser
*parser
, omp_clause_mask mask
,
16949 const char *where
, bool finish_p
= true,
16952 tree clauses
= NULL
;
16955 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
16958 pragma_omp_clause c_kind
;
16959 const char *c_name
;
16960 tree prev
= clauses
;
16962 if (nested
&& c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
16967 if (c_parser_next_token_is (parser
, CPP_COMMA
))
16968 c_parser_consume_token (parser
);
16969 else if (nested
== 2)
16970 error_at (c_parser_peek_token (parser
)->location
,
16971 "clauses in %<simd%> trait should be separated "
16975 here
= c_parser_peek_token (parser
)->location
;
16976 c_kind
= c_parser_omp_clause_name (parser
);
16980 case PRAGMA_OMP_CLAUSE_BIND
:
16981 clauses
= c_parser_omp_clause_bind (parser
, clauses
);
16984 case PRAGMA_OMP_CLAUSE_COLLAPSE
:
16985 clauses
= c_parser_omp_clause_collapse (parser
, clauses
);
16986 c_name
= "collapse";
16988 case PRAGMA_OMP_CLAUSE_COPYIN
:
16989 clauses
= c_parser_omp_clause_copyin (parser
, clauses
);
16992 case PRAGMA_OMP_CLAUSE_COPYPRIVATE
:
16993 clauses
= c_parser_omp_clause_copyprivate (parser
, clauses
);
16994 c_name
= "copyprivate";
16996 case PRAGMA_OMP_CLAUSE_DEFAULT
:
16997 clauses
= c_parser_omp_clause_default (parser
, clauses
, false);
16998 c_name
= "default";
17000 case PRAGMA_OMP_CLAUSE_DETACH
:
17001 clauses
= c_parser_omp_clause_detach (parser
, clauses
);
17004 case PRAGMA_OMP_CLAUSE_FILTER
:
17005 clauses
= c_parser_omp_clause_filter (parser
, clauses
);
17008 case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE
:
17009 clauses
= c_parser_omp_clause_firstprivate (parser
, clauses
);
17010 c_name
= "firstprivate";
17012 case PRAGMA_OMP_CLAUSE_FINAL
:
17013 clauses
= c_parser_omp_clause_final (parser
, clauses
);
17016 case PRAGMA_OMP_CLAUSE_GRAINSIZE
:
17017 clauses
= c_parser_omp_clause_grainsize (parser
, clauses
);
17018 c_name
= "grainsize";
17020 case PRAGMA_OMP_CLAUSE_HINT
:
17021 clauses
= c_parser_omp_clause_hint (parser
, clauses
);
17024 case PRAGMA_OMP_CLAUSE_DEFAULTMAP
:
17025 clauses
= c_parser_omp_clause_defaultmap (parser
, clauses
);
17026 c_name
= "defaultmap";
17028 case PRAGMA_OMP_CLAUSE_IF
:
17029 clauses
= c_parser_omp_clause_if (parser
, clauses
, true);
17032 case PRAGMA_OMP_CLAUSE_IN_REDUCTION
:
17034 = c_parser_omp_clause_reduction (parser
, OMP_CLAUSE_IN_REDUCTION
,
17036 c_name
= "in_reduction";
17038 case PRAGMA_OMP_CLAUSE_LASTPRIVATE
:
17039 clauses
= c_parser_omp_clause_lastprivate (parser
, clauses
);
17040 c_name
= "lastprivate";
17042 case PRAGMA_OMP_CLAUSE_MERGEABLE
:
17043 clauses
= c_parser_omp_clause_mergeable (parser
, clauses
);
17044 c_name
= "mergeable";
17046 case PRAGMA_OMP_CLAUSE_NOWAIT
:
17047 clauses
= c_parser_omp_clause_nowait (parser
, clauses
);
17050 case PRAGMA_OMP_CLAUSE_NUM_TASKS
:
17051 clauses
= c_parser_omp_clause_num_tasks (parser
, clauses
);
17052 c_name
= "num_tasks";
17054 case PRAGMA_OMP_CLAUSE_NUM_THREADS
:
17055 clauses
= c_parser_omp_clause_num_threads (parser
, clauses
);
17056 c_name
= "num_threads";
17058 case PRAGMA_OMP_CLAUSE_ORDER
:
17059 clauses
= c_parser_omp_clause_order (parser
, clauses
);
17062 case PRAGMA_OMP_CLAUSE_ORDERED
:
17063 clauses
= c_parser_omp_clause_ordered (parser
, clauses
);
17064 c_name
= "ordered";
17066 case PRAGMA_OMP_CLAUSE_PRIORITY
:
17067 clauses
= c_parser_omp_clause_priority (parser
, clauses
);
17068 c_name
= "priority";
17070 case PRAGMA_OMP_CLAUSE_PRIVATE
:
17071 clauses
= c_parser_omp_clause_private (parser
, clauses
);
17072 c_name
= "private";
17074 case PRAGMA_OMP_CLAUSE_REDUCTION
:
17076 = c_parser_omp_clause_reduction (parser
, OMP_CLAUSE_REDUCTION
,
17078 c_name
= "reduction";
17080 case PRAGMA_OMP_CLAUSE_SCHEDULE
:
17081 clauses
= c_parser_omp_clause_schedule (parser
, clauses
);
17082 c_name
= "schedule";
17084 case PRAGMA_OMP_CLAUSE_SHARED
:
17085 clauses
= c_parser_omp_clause_shared (parser
, clauses
);
17088 case PRAGMA_OMP_CLAUSE_TASK_REDUCTION
:
17090 = c_parser_omp_clause_reduction (parser
, OMP_CLAUSE_TASK_REDUCTION
,
17092 c_name
= "task_reduction";
17094 case PRAGMA_OMP_CLAUSE_UNTIED
:
17095 clauses
= c_parser_omp_clause_untied (parser
, clauses
);
17098 case PRAGMA_OMP_CLAUSE_INBRANCH
:
17099 clauses
= c_parser_omp_clause_branch (parser
, OMP_CLAUSE_INBRANCH
,
17101 c_name
= "inbranch";
17103 case PRAGMA_OMP_CLAUSE_NONTEMPORAL
:
17104 clauses
= c_parser_omp_clause_nontemporal (parser
, clauses
);
17105 c_name
= "nontemporal";
17107 case PRAGMA_OMP_CLAUSE_NOTINBRANCH
:
17108 clauses
= c_parser_omp_clause_branch (parser
, OMP_CLAUSE_NOTINBRANCH
,
17110 c_name
= "notinbranch";
17112 case PRAGMA_OMP_CLAUSE_PARALLEL
:
17114 = c_parser_omp_clause_cancelkind (parser
, OMP_CLAUSE_PARALLEL
,
17116 c_name
= "parallel";
17120 error_at (here
, "%qs must be the first clause of %qs",
17125 case PRAGMA_OMP_CLAUSE_FOR
:
17127 = c_parser_omp_clause_cancelkind (parser
, OMP_CLAUSE_FOR
,
17131 goto clause_not_first
;
17133 case PRAGMA_OMP_CLAUSE_SECTIONS
:
17135 = c_parser_omp_clause_cancelkind (parser
, OMP_CLAUSE_SECTIONS
,
17137 c_name
= "sections";
17139 goto clause_not_first
;
17141 case PRAGMA_OMP_CLAUSE_TASKGROUP
:
17143 = c_parser_omp_clause_cancelkind (parser
, OMP_CLAUSE_TASKGROUP
,
17145 c_name
= "taskgroup";
17147 goto clause_not_first
;
17149 case PRAGMA_OMP_CLAUSE_LINK
:
17151 = c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_LINK
, clauses
);
17154 case PRAGMA_OMP_CLAUSE_TO
:
17155 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_LINK
)) != 0)
17157 tree nl
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ENTER
,
17159 for (tree c
= nl
; c
!= clauses
; c
= OMP_CLAUSE_CHAIN (c
))
17160 OMP_CLAUSE_ENTER_TO (c
) = 1;
17164 clauses
= c_parser_omp_clause_to (parser
, clauses
);
17167 case PRAGMA_OMP_CLAUSE_FROM
:
17168 clauses
= c_parser_omp_clause_from (parser
, clauses
);
17171 case PRAGMA_OMP_CLAUSE_UNIFORM
:
17172 clauses
= c_parser_omp_clause_uniform (parser
, clauses
);
17173 c_name
= "uniform";
17175 case PRAGMA_OMP_CLAUSE_NUM_TEAMS
:
17176 clauses
= c_parser_omp_clause_num_teams (parser
, clauses
);
17177 c_name
= "num_teams";
17179 case PRAGMA_OMP_CLAUSE_THREAD_LIMIT
:
17180 clauses
= c_parser_omp_clause_thread_limit (parser
, clauses
);
17181 c_name
= "thread_limit";
17183 case PRAGMA_OMP_CLAUSE_ALIGNED
:
17184 clauses
= c_parser_omp_clause_aligned (parser
, clauses
);
17185 c_name
= "aligned";
17187 case PRAGMA_OMP_CLAUSE_ALLOCATE
:
17188 clauses
= c_parser_omp_clause_allocate (parser
, clauses
);
17189 c_name
= "allocate";
17191 case PRAGMA_OMP_CLAUSE_LINEAR
:
17192 clauses
= c_parser_omp_clause_linear (parser
, clauses
);
17195 case PRAGMA_OMP_CLAUSE_AFFINITY
:
17196 clauses
= c_parser_omp_clause_affinity (parser
, clauses
);
17197 c_name
= "affinity";
17199 case PRAGMA_OMP_CLAUSE_DEPEND
:
17200 clauses
= c_parser_omp_clause_depend (parser
, clauses
);
17203 case PRAGMA_OMP_CLAUSE_MAP
:
17204 clauses
= c_parser_omp_clause_map (parser
, clauses
);
17207 case PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR
:
17208 clauses
= c_parser_omp_clause_use_device_ptr (parser
, clauses
);
17209 c_name
= "use_device_ptr";
17211 case PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR
:
17212 clauses
= c_parser_omp_clause_use_device_addr (parser
, clauses
);
17213 c_name
= "use_device_addr";
17215 case PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR
:
17216 clauses
= c_parser_omp_clause_has_device_addr (parser
, clauses
);
17217 c_name
= "has_device_addr";
17219 case PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR
:
17220 clauses
= c_parser_omp_clause_is_device_ptr (parser
, clauses
);
17221 c_name
= "is_device_ptr";
17223 case PRAGMA_OMP_CLAUSE_DEVICE
:
17224 clauses
= c_parser_omp_clause_device (parser
, clauses
);
17227 case PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
:
17228 clauses
= c_parser_omp_clause_dist_schedule (parser
, clauses
);
17229 c_name
= "dist_schedule";
17231 case PRAGMA_OMP_CLAUSE_PROC_BIND
:
17232 clauses
= c_parser_omp_clause_proc_bind (parser
, clauses
);
17233 c_name
= "proc_bind";
17235 case PRAGMA_OMP_CLAUSE_DEVICE_TYPE
:
17236 clauses
= c_parser_omp_clause_device_type (parser
, clauses
);
17237 c_name
= "device_type";
17239 case PRAGMA_OMP_CLAUSE_SAFELEN
:
17240 clauses
= c_parser_omp_clause_safelen (parser
, clauses
);
17241 c_name
= "safelen";
17243 case PRAGMA_OMP_CLAUSE_SIMDLEN
:
17244 clauses
= c_parser_omp_clause_simdlen (parser
, clauses
);
17245 c_name
= "simdlen";
17247 case PRAGMA_OMP_CLAUSE_NOGROUP
:
17248 clauses
= c_parser_omp_clause_nogroup (parser
, clauses
);
17249 c_name
= "nogroup";
17251 case PRAGMA_OMP_CLAUSE_THREADS
:
17253 = c_parser_omp_clause_orderedkind (parser
, OMP_CLAUSE_THREADS
,
17255 c_name
= "threads";
17257 case PRAGMA_OMP_CLAUSE_SIMD
:
17259 = c_parser_omp_clause_orderedkind (parser
, OMP_CLAUSE_SIMD
,
17263 case PRAGMA_OMP_CLAUSE_ENTER
:
17265 = c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ENTER
,
17270 c_parser_error (parser
, "expected %<#pragma omp%> clause");
17276 if (((mask
>> c_kind
) & 1) == 0)
17278 /* Remove the invalid clause(s) from the list to avoid
17279 confusing the rest of the compiler. */
17281 error_at (here
, "%qs is not valid for %qs", c_name
, where
);
17287 c_parser_skip_to_pragma_eol (parser
);
17291 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_UNIFORM
)) != 0)
17292 return c_finish_omp_clauses (clauses
, C_ORT_OMP_DECLARE_SIMD
);
17293 return c_finish_omp_clauses (clauses
, C_ORT_OMP
);
17299 /* OpenACC 2.0, OpenMP 2.5:
17303 In practice, we're also interested in adding the statement to an
17304 outer node. So it is convenient if we work around the fact that
17305 c_parser_statement calls add_stmt. */
17308 c_parser_omp_structured_block (c_parser
*parser
, bool *if_p
)
17310 tree stmt
= push_stmt_list ();
17311 c_parser_statement (parser
, if_p
);
17312 return pop_stmt_list (stmt
);
17316 # pragma acc cache (variable-list) new-line
17318 LOC is the location of the #pragma token.
17322 c_parser_oacc_cache (location_t loc
, c_parser
*parser
)
17324 tree stmt
, clauses
;
17326 clauses
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE__CACHE_
, NULL
);
17327 clauses
= c_finish_omp_clauses (clauses
, C_ORT_ACC
);
17329 c_parser_skip_to_pragma_eol (parser
);
17331 stmt
= make_node (OACC_CACHE
);
17332 TREE_TYPE (stmt
) = void_type_node
;
17333 OACC_CACHE_CLAUSES (stmt
) = clauses
;
17334 SET_EXPR_LOCATION (stmt
, loc
);
17341 # pragma acc data oacc-data-clause[optseq] new-line
17344 LOC is the location of the #pragma token.
17347 #define OACC_DATA_CLAUSE_MASK \
17348 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
17349 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
17350 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17351 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17352 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17353 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
17354 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17355 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
17356 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
17359 c_parser_oacc_data (location_t loc
, c_parser
*parser
, bool *if_p
)
17361 tree stmt
, clauses
, block
;
17363 clauses
= c_parser_oacc_all_clauses (parser
, OACC_DATA_CLAUSE_MASK
,
17364 "#pragma acc data");
17366 block
= c_begin_omp_parallel ();
17367 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
17369 stmt
= c_finish_oacc_data (loc
, clauses
, block
);
17375 # pragma acc declare oacc-data-clause[optseq] new-line
17378 #define OACC_DECLARE_CLAUSE_MASK \
17379 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
17380 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17381 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17382 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17383 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
17384 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT) \
17385 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_LINK) \
17386 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
17389 c_parser_oacc_declare (c_parser
*parser
)
17391 location_t pragma_loc
= c_parser_peek_token (parser
)->location
;
17392 tree clauses
, stmt
, t
, decl
;
17394 bool error
= false;
17396 c_parser_consume_pragma (parser
);
17398 clauses
= c_parser_oacc_all_clauses (parser
, OACC_DECLARE_CLAUSE_MASK
,
17399 "#pragma acc declare");
17402 error_at (pragma_loc
,
17403 "no valid clauses specified in %<#pragma acc declare%>");
17407 for (t
= clauses
; t
; t
= OMP_CLAUSE_CHAIN (t
))
17409 location_t loc
= OMP_CLAUSE_LOCATION (t
);
17410 decl
= OMP_CLAUSE_DECL (t
);
17411 if (!DECL_P (decl
))
17413 error_at (loc
, "array section in %<#pragma acc declare%>");
17418 switch (OMP_CLAUSE_MAP_KIND (t
))
17420 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
17421 case GOMP_MAP_ALLOC
:
17423 case GOMP_MAP_FORCE_DEVICEPTR
:
17424 case GOMP_MAP_DEVICE_RESIDENT
:
17427 case GOMP_MAP_LINK
:
17428 if (!global_bindings_p ()
17429 && (TREE_STATIC (decl
)
17430 || !DECL_EXTERNAL (decl
)))
17433 "%qD must be a global variable in "
17434 "%<#pragma acc declare link%>",
17442 if (global_bindings_p ())
17444 error_at (loc
, "invalid OpenACC clause at file scope");
17448 if (DECL_EXTERNAL (decl
))
17451 "invalid use of %<extern%> variable %qD "
17452 "in %<#pragma acc declare%>", decl
);
17456 else if (TREE_PUBLIC (decl
))
17459 "invalid use of %<global%> variable %qD "
17460 "in %<#pragma acc declare%>", decl
);
17467 if (!c_check_in_current_scope (decl
))
17470 "%qD must be a variable declared in the same scope as "
17471 "%<#pragma acc declare%>", decl
);
17476 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl
))
17477 || lookup_attribute ("omp declare target link",
17478 DECL_ATTRIBUTES (decl
)))
17480 error_at (loc
, "variable %qD used more than once with "
17481 "%<#pragma acc declare%>", decl
);
17490 if (OMP_CLAUSE_MAP_KIND (t
) == GOMP_MAP_LINK
)
17491 id
= get_identifier ("omp declare target link");
17493 id
= get_identifier ("omp declare target");
17495 DECL_ATTRIBUTES (decl
)
17496 = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (decl
));
17498 if (global_bindings_p ())
17500 symtab_node
*node
= symtab_node::get (decl
);
17503 node
->offloadable
= 1;
17504 if (ENABLE_OFFLOADING
)
17506 g
->have_offload
= true;
17507 if (is_a
<varpool_node
*> (node
))
17508 vec_safe_push (offload_vars
, decl
);
17515 if (error
|| global_bindings_p ())
17518 stmt
= make_node (OACC_DECLARE
);
17519 TREE_TYPE (stmt
) = void_type_node
;
17520 OACC_DECLARE_CLAUSES (stmt
) = clauses
;
17521 SET_EXPR_LOCATION (stmt
, pragma_loc
);
17529 # pragma acc enter data oacc-enter-data-clause[optseq] new-line
17533 # pragma acc exit data oacc-exit-data-clause[optseq] new-line
17536 LOC is the location of the #pragma token.
17539 #define OACC_ENTER_DATA_CLAUSE_MASK \
17540 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17541 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17542 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
17543 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17544 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17545 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17547 #define OACC_EXIT_DATA_CLAUSE_MASK \
17548 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17549 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17550 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17551 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DELETE) \
17552 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DETACH) \
17553 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FINALIZE) \
17554 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17557 c_parser_oacc_enter_exit_data (c_parser
*parser
, bool enter
)
17559 location_t loc
= c_parser_peek_token (parser
)->location
;
17560 tree clauses
, stmt
;
17561 const char *p
= "";
17563 c_parser_consume_pragma (parser
);
17565 if (c_parser_next_token_is (parser
, CPP_NAME
))
17567 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
17568 c_parser_consume_token (parser
);
17571 if (strcmp (p
, "data") != 0)
17573 error_at (loc
, "expected %<data%> after %<#pragma acc %s%>",
17574 enter
? "enter" : "exit");
17575 parser
->error
= true;
17576 c_parser_skip_to_pragma_eol (parser
);
17581 clauses
= c_parser_oacc_all_clauses (parser
, OACC_ENTER_DATA_CLAUSE_MASK
,
17582 "#pragma acc enter data");
17584 clauses
= c_parser_oacc_all_clauses (parser
, OACC_EXIT_DATA_CLAUSE_MASK
,
17585 "#pragma acc exit data");
17587 if (omp_find_clause (clauses
, OMP_CLAUSE_MAP
) == NULL_TREE
)
17589 error_at (loc
, "%<#pragma acc %s data%> has no data movement clause",
17590 enter
? "enter" : "exit");
17594 stmt
= enter
? make_node (OACC_ENTER_DATA
) : make_node (OACC_EXIT_DATA
);
17595 TREE_TYPE (stmt
) = void_type_node
;
17596 OMP_STANDALONE_CLAUSES (stmt
) = clauses
;
17597 SET_EXPR_LOCATION (stmt
, loc
);
17603 # pragma acc host_data oacc-data-clause[optseq] new-line
17607 #define OACC_HOST_DATA_CLAUSE_MASK \
17608 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_USE_DEVICE) \
17609 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17610 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) )
17613 c_parser_oacc_host_data (location_t loc
, c_parser
*parser
, bool *if_p
)
17615 tree stmt
, clauses
, block
;
17617 clauses
= c_parser_oacc_all_clauses (parser
, OACC_HOST_DATA_CLAUSE_MASK
,
17618 "#pragma acc host_data");
17620 block
= c_begin_omp_parallel ();
17621 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
17622 stmt
= c_finish_oacc_host_data (loc
, clauses
, block
);
17629 # pragma acc loop oacc-loop-clause[optseq] new-line
17632 LOC is the location of the #pragma token.
17635 #define OACC_LOOP_CLAUSE_MASK \
17636 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COLLAPSE) \
17637 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
17638 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
17639 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
17640 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
17641 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
17642 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_AUTO) \
17643 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_INDEPENDENT) \
17644 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \
17645 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_TILE) )
17647 c_parser_oacc_loop (location_t loc
, c_parser
*parser
, char *p_name
,
17648 omp_clause_mask mask
, tree
*cclauses
, bool *if_p
)
17650 bool is_parallel
= ((mask
>> PRAGMA_OACC_CLAUSE_REDUCTION
) & 1) == 1;
17652 strcat (p_name
, " loop");
17653 mask
|= OACC_LOOP_CLAUSE_MASK
;
17655 tree clauses
= c_parser_oacc_all_clauses (parser
, mask
, p_name
,
17659 clauses
= c_oacc_split_loop_clauses (clauses
, cclauses
, is_parallel
);
17661 *cclauses
= c_finish_omp_clauses (*cclauses
, C_ORT_ACC
);
17663 clauses
= c_finish_omp_clauses (clauses
, C_ORT_ACC
);
17666 tree block
= c_begin_compound_stmt (true);
17667 tree stmt
= c_parser_omp_for_loop (loc
, parser
, OACC_LOOP
, clauses
, NULL
,
17669 block
= c_end_compound_stmt (loc
, block
, true);
17676 # pragma acc kernels oacc-kernels-clause[optseq] new-line
17681 # pragma acc parallel oacc-parallel-clause[optseq] new-line
17686 # pragma acc serial oacc-serial-clause[optseq] new-line
17689 LOC is the location of the #pragma token.
17692 #define OACC_KERNELS_CLAUSE_MASK \
17693 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17694 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
17695 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
17696 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17697 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17698 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17699 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
17700 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
17701 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17702 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
17703 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
17704 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
17705 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
17706 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
17707 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17709 #define OACC_PARALLEL_CLAUSE_MASK \
17710 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17711 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
17712 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
17713 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17714 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17715 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17716 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
17717 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
17718 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17719 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
17720 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
17721 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
17722 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
17723 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
17724 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
17725 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
17726 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
17727 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17729 #define OACC_SERIAL_CLAUSE_MASK \
17730 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17731 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
17732 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
17733 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17734 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17735 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17736 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
17737 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
17738 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17739 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
17740 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
17741 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
17742 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
17743 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
17744 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17747 c_parser_oacc_compute (location_t loc
, c_parser
*parser
,
17748 enum pragma_kind p_kind
, char *p_name
, bool *if_p
)
17750 omp_clause_mask mask
;
17751 enum tree_code code
;
17754 case PRAGMA_OACC_KERNELS
:
17755 strcat (p_name
, " kernels");
17756 mask
= OACC_KERNELS_CLAUSE_MASK
;
17757 code
= OACC_KERNELS
;
17759 case PRAGMA_OACC_PARALLEL
:
17760 strcat (p_name
, " parallel");
17761 mask
= OACC_PARALLEL_CLAUSE_MASK
;
17762 code
= OACC_PARALLEL
;
17764 case PRAGMA_OACC_SERIAL
:
17765 strcat (p_name
, " serial");
17766 mask
= OACC_SERIAL_CLAUSE_MASK
;
17767 code
= OACC_SERIAL
;
17770 gcc_unreachable ();
17773 if (c_parser_next_token_is (parser
, CPP_NAME
))
17775 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
17776 if (strcmp (p
, "loop") == 0)
17778 c_parser_consume_token (parser
);
17779 tree block
= c_begin_omp_parallel ();
17781 c_parser_oacc_loop (loc
, parser
, p_name
, mask
, &clauses
, if_p
);
17782 return c_finish_omp_construct (loc
, code
, block
, clauses
);
17786 tree clauses
= c_parser_oacc_all_clauses (parser
, mask
, p_name
);
17788 tree block
= c_begin_omp_parallel ();
17789 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
17791 return c_finish_omp_construct (loc
, code
, block
, clauses
);
17795 # pragma acc routine oacc-routine-clause[optseq] new-line
17796 function-definition
17798 # pragma acc routine ( name ) oacc-routine-clause[optseq] new-line
17801 #define OACC_ROUTINE_CLAUSE_MASK \
17802 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
17803 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
17804 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
17805 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \
17806 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NOHOST) )
17808 /* Parse an OpenACC routine directive. For named directives, we apply
17809 immediately to the named function. For unnamed ones we then parse
17810 a declaration or definition, which must be for a function. */
17813 c_parser_oacc_routine (c_parser
*parser
, enum pragma_context context
)
17815 gcc_checking_assert (context
== pragma_external
);
17817 oacc_routine_data data
;
17818 data
.error_seen
= false;
17819 data
.fndecl_seen
= false;
17820 data
.loc
= c_parser_peek_token (parser
)->location
;
17822 c_parser_consume_pragma (parser
);
17824 /* Look for optional '( name )'. */
17825 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
17827 c_parser_consume_token (parser
); /* '(' */
17829 tree decl
= NULL_TREE
;
17830 c_token
*name_token
= c_parser_peek_token (parser
);
17831 location_t name_loc
= name_token
->location
;
17832 if (name_token
->type
== CPP_NAME
17833 && (name_token
->id_kind
== C_ID_ID
17834 || name_token
->id_kind
== C_ID_TYPENAME
))
17836 decl
= lookup_name (name_token
->value
);
17838 error_at (name_loc
,
17839 "%qE has not been declared", name_token
->value
);
17840 c_parser_consume_token (parser
);
17843 c_parser_error (parser
, "expected function name");
17846 || !c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
17848 c_parser_skip_to_pragma_eol (parser
, false);
17853 = c_parser_oacc_all_clauses (parser
, OACC_ROUTINE_CLAUSE_MASK
,
17854 "#pragma acc routine");
17855 /* The clauses are in reverse order; fix that to make later diagnostic
17856 emission easier. */
17857 data
.clauses
= nreverse (data
.clauses
);
17859 if (TREE_CODE (decl
) != FUNCTION_DECL
)
17861 error_at (name_loc
, "%qD does not refer to a function", decl
);
17865 c_finish_oacc_routine (&data
, decl
, false);
17867 else /* No optional '( name )'. */
17870 = c_parser_oacc_all_clauses (parser
, OACC_ROUTINE_CLAUSE_MASK
,
17871 "#pragma acc routine");
17872 /* The clauses are in reverse order; fix that to make later diagnostic
17873 emission easier. */
17874 data
.clauses
= nreverse (data
.clauses
);
17876 /* Emit a helpful diagnostic if there's another pragma following this
17877 one. Also don't allow a static assertion declaration, as in the
17878 following we'll just parse a *single* "declaration or function
17879 definition", and the static assertion counts an one. */
17880 if (c_parser_next_token_is (parser
, CPP_PRAGMA
)
17881 || c_parser_next_token_is_keyword (parser
, RID_STATIC_ASSERT
))
17883 error_at (data
.loc
,
17884 "%<#pragma acc routine%> not immediately followed by"
17885 " function declaration or definition");
17886 /* ..., and then just keep going. */
17890 /* We only have to consider the pragma_external case here. */
17891 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
17892 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
)
17894 int ext
= disable_extension_diagnostics ();
17896 c_parser_consume_token (parser
);
17897 while (c_parser_next_token_is (parser
, CPP_KEYWORD
)
17898 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
);
17899 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
17900 NULL
, NULL
, false, NULL
, &data
);
17901 restore_extension_diagnostics (ext
);
17904 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
17905 NULL
, NULL
, false, NULL
, &data
);
17909 /* Finalize an OpenACC routine pragma, applying it to FNDECL.
17910 IS_DEFN is true if we're applying it to the definition. */
17913 c_finish_oacc_routine (struct oacc_routine_data
*data
, tree fndecl
,
17916 /* Keep going if we're in error reporting mode. */
17917 if (data
->error_seen
17918 || fndecl
== error_mark_node
)
17921 if (data
->fndecl_seen
)
17923 error_at (data
->loc
,
17924 "%<#pragma acc routine%> not immediately followed by"
17925 " a single function declaration or definition");
17926 data
->error_seen
= true;
17929 if (fndecl
== NULL_TREE
|| TREE_CODE (fndecl
) != FUNCTION_DECL
)
17931 error_at (data
->loc
,
17932 "%<#pragma acc routine%> not immediately followed by"
17933 " function declaration or definition");
17934 data
->error_seen
= true;
17939 = oacc_verify_routine_clauses (fndecl
, &data
->clauses
, data
->loc
,
17940 "#pragma acc routine");
17941 if (compatible
< 0)
17943 data
->error_seen
= true;
17946 if (compatible
> 0)
17951 if (TREE_USED (fndecl
) || (!is_defn
&& DECL_SAVED_TREE (fndecl
)))
17953 error_at (data
->loc
,
17955 ? G_("%<#pragma acc routine%> must be applied before use")
17956 : G_("%<#pragma acc routine%> must be applied before"
17958 data
->error_seen
= true;
17962 /* Set the routine's level of parallelism. */
17963 tree dims
= oacc_build_routine_dims (data
->clauses
);
17964 oacc_replace_fn_attrib (fndecl
, dims
);
17966 /* Add an "omp declare target" attribute. */
17967 DECL_ATTRIBUTES (fndecl
)
17968 = tree_cons (get_identifier ("omp declare target"),
17969 data
->clauses
, DECL_ATTRIBUTES (fndecl
));
17972 /* Remember that we've used this "#pragma acc routine". */
17973 data
->fndecl_seen
= true;
17977 # pragma acc update oacc-update-clause[optseq] new-line
17980 #define OACC_UPDATE_CLAUSE_MASK \
17981 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17982 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE) \
17983 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_HOST) \
17984 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17985 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) \
17986 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17989 c_parser_oacc_update (c_parser
*parser
)
17991 location_t loc
= c_parser_peek_token (parser
)->location
;
17993 c_parser_consume_pragma (parser
);
17995 tree clauses
= c_parser_oacc_all_clauses (parser
, OACC_UPDATE_CLAUSE_MASK
,
17996 "#pragma acc update");
17997 if (omp_find_clause (clauses
, OMP_CLAUSE_MAP
) == NULL_TREE
)
18000 "%<#pragma acc update%> must contain at least one "
18001 "%<device%> or %<host%> or %<self%> clause");
18008 tree stmt
= make_node (OACC_UPDATE
);
18009 TREE_TYPE (stmt
) = void_type_node
;
18010 OACC_UPDATE_CLAUSES (stmt
) = clauses
;
18011 SET_EXPR_LOCATION (stmt
, loc
);
18016 # pragma acc wait [(intseq)] oacc-wait-clause[optseq] new-line
18018 LOC is the location of the #pragma token.
18021 #define OACC_WAIT_CLAUSE_MASK \
18022 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) )
18025 c_parser_oacc_wait (location_t loc
, c_parser
*parser
, char *p_name
)
18027 tree clauses
, list
= NULL_TREE
, stmt
= NULL_TREE
;
18029 if (c_parser_peek_token (parser
)->type
== CPP_OPEN_PAREN
)
18030 list
= c_parser_oacc_wait_list (parser
, loc
, list
);
18032 strcpy (p_name
, " wait");
18033 clauses
= c_parser_oacc_all_clauses (parser
, OACC_WAIT_CLAUSE_MASK
, p_name
);
18034 stmt
= c_finish_oacc_wait (loc
, list
, clauses
);
18041 # pragma omp allocate (list) [allocator(allocator)] */
18044 c_parser_omp_allocate (location_t loc
, c_parser
*parser
)
18046 tree allocator
= NULL_TREE
;
18047 tree nl
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ALLOCATE
, NULL_TREE
);
18048 if (c_parser_next_token_is (parser
, CPP_NAME
))
18050 matching_parens parens
;
18051 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18052 c_parser_consume_token (parser
);
18053 if (strcmp ("allocator", p
) != 0)
18054 error_at (c_parser_peek_token (parser
)->location
,
18055 "expected %<allocator%>");
18056 else if (parens
.require_open (parser
))
18058 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
18059 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
18060 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
18061 allocator
= expr
.value
;
18062 allocator
= c_fully_fold (allocator
, false, NULL
);
18064 = expr
.original_type
? expr
.original_type
: TREE_TYPE (allocator
);
18065 orig_type
= TYPE_MAIN_VARIANT (orig_type
);
18066 if (!INTEGRAL_TYPE_P (TREE_TYPE (allocator
))
18067 || TREE_CODE (orig_type
) != ENUMERAL_TYPE
18068 || TYPE_NAME (orig_type
)
18069 != get_identifier ("omp_allocator_handle_t"))
18071 error_at (expr_loc
, "%<allocator%> clause allocator expression "
18072 "has type %qT rather than "
18073 "%<omp_allocator_handle_t%>",
18074 TREE_TYPE (allocator
));
18075 allocator
= NULL_TREE
;
18077 parens
.skip_until_found_close (parser
);
18080 c_parser_skip_to_pragma_eol (parser
);
18083 for (tree c
= nl
; c
!= NULL_TREE
; c
= OMP_CLAUSE_CHAIN (c
))
18084 OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
) = allocator
;
18086 sorry_at (loc
, "%<#pragma omp allocate%> not yet supported");
18090 # pragma omp atomic new-line
18094 x binop= expr | x++ | ++x | x-- | --x
18096 +, *, -, /, &, ^, |, <<, >>
18098 where x is an lvalue expression with scalar type.
18101 # pragma omp atomic new-line
18104 # pragma omp atomic read new-line
18107 # pragma omp atomic write new-line
18110 # pragma omp atomic update new-line
18113 # pragma omp atomic capture new-line
18116 # pragma omp atomic capture new-line
18124 expression-stmt | x = x binop expr
18126 v = expression-stmt
18128 { v = x; update-stmt; } | { update-stmt; v = x; }
18132 expression-stmt | x = x binop expr | x = expr binop x
18136 { v = x; update-stmt; } | { update-stmt; v = x; } | { v = x; x = expr; }
18139 # pragma omp atomic compare new-line
18140 conditional-update-atomic
18142 # pragma omp atomic compare capture new-line
18143 conditional-update-capture-atomic
18145 conditional-update-atomic:
18146 cond-expr-stmt | cond-update-stmt
18148 x = expr ordop x ? expr : x;
18149 x = x ordop expr ? expr : x;
18150 x = x == e ? d : x;
18152 if (expr ordop x) { x = expr; }
18153 if (x ordop expr) { x = expr; }
18154 if (x == e) { x = d; }
18157 conditional-update-capture-atomic:
18159 { v = x; cond-expr-stmt }
18160 { cond-expr-stmt v = x; }
18161 { v = x; cond-update-stmt }
18162 { cond-update-stmt v = x; }
18163 if (x == e) { x = d; } else { v = x; }
18164 { r = x == e; if (r) { x = d; } }
18165 { r = x == e; if (r) { x = d; } else { v = x; } }
18167 where x, r and v are lvalue expressions with scalar type,
18168 expr, e and d are expressions with scalar type and e might be
18171 LOC is the location of the #pragma token. */
18174 c_parser_omp_atomic (location_t loc
, c_parser
*parser
, bool openacc
)
18176 tree lhs
= NULL_TREE
, rhs
= NULL_TREE
, v
= NULL_TREE
, r
= NULL_TREE
;
18177 tree lhs1
= NULL_TREE
, rhs1
= NULL_TREE
;
18178 tree stmt
, orig_lhs
, unfolded_lhs
= NULL_TREE
, unfolded_lhs1
= NULL_TREE
;
18179 enum tree_code code
= ERROR_MARK
, opcode
= NOP_EXPR
;
18180 enum omp_memory_order memory_order
= OMP_MEMORY_ORDER_UNSPECIFIED
;
18181 struct c_expr expr
;
18183 bool structured_block
= false;
18184 bool swapped
= false;
18187 tree clauses
= NULL_TREE
;
18188 bool capture
= false;
18189 bool compare
= false;
18191 enum omp_memory_order fail
= OMP_MEMORY_ORDER_UNSPECIFIED
;
18192 bool no_semicolon
= false;
18193 bool extra_scope
= false;
18195 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
18198 && c_parser_next_token_is (parser
, CPP_COMMA
)
18199 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
18200 c_parser_consume_token (parser
);
18204 if (c_parser_next_token_is (parser
, CPP_NAME
))
18207 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18208 location_t cloc
= c_parser_peek_token (parser
)->location
;
18209 enum tree_code new_code
= ERROR_MARK
;
18210 enum omp_memory_order new_memory_order
18211 = OMP_MEMORY_ORDER_UNSPECIFIED
;
18212 bool new_capture
= false;
18213 bool new_compare
= false;
18214 bool new_weak
= false;
18215 enum omp_memory_order new_fail
= OMP_MEMORY_ORDER_UNSPECIFIED
;
18217 if (!strcmp (p
, "read"))
18218 new_code
= OMP_ATOMIC_READ
;
18219 else if (!strcmp (p
, "write"))
18220 new_code
= NOP_EXPR
;
18221 else if (!strcmp (p
, "update"))
18222 new_code
= OMP_ATOMIC
;
18223 else if (openacc
&& !strcmp (p
, "capture"))
18224 new_code
= OMP_ATOMIC_CAPTURE_NEW
;
18228 error_at (cloc
, "expected %<read%>, %<write%>, %<update%>, "
18229 "or %<capture%> clause");
18231 else if (!strcmp (p
, "capture"))
18232 new_capture
= true;
18233 else if (!strcmp (p
, "compare"))
18234 new_compare
= true;
18235 else if (!strcmp (p
, "weak"))
18237 else if (!strcmp (p
, "fail"))
18239 matching_parens parens
;
18241 c_parser_consume_token (parser
);
18242 if (!parens
.require_open (parser
))
18245 if (c_parser_next_token_is (parser
, CPP_NAME
))
18248 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18250 if (!strcmp (q
, "seq_cst"))
18251 new_fail
= OMP_MEMORY_ORDER_SEQ_CST
;
18252 else if (!strcmp (q
, "acquire"))
18253 new_fail
= OMP_MEMORY_ORDER_ACQUIRE
;
18254 else if (!strcmp (q
, "relaxed"))
18255 new_fail
= OMP_MEMORY_ORDER_RELAXED
;
18258 if (new_fail
!= OMP_MEMORY_ORDER_UNSPECIFIED
)
18260 c_parser_consume_token (parser
);
18261 if (fail
!= OMP_MEMORY_ORDER_UNSPECIFIED
)
18262 error_at (cloc
, "too many %qs clauses", "fail");
18267 c_parser_error (parser
, "expected %<seq_cst%>, %<acquire%> "
18269 parens
.skip_until_found_close (parser
);
18272 else if (!strcmp (p
, "seq_cst"))
18273 new_memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
18274 else if (!strcmp (p
, "acq_rel"))
18275 new_memory_order
= OMP_MEMORY_ORDER_ACQ_REL
;
18276 else if (!strcmp (p
, "release"))
18277 new_memory_order
= OMP_MEMORY_ORDER_RELEASE
;
18278 else if (!strcmp (p
, "acquire"))
18279 new_memory_order
= OMP_MEMORY_ORDER_ACQUIRE
;
18280 else if (!strcmp (p
, "relaxed"))
18281 new_memory_order
= OMP_MEMORY_ORDER_RELAXED
;
18282 else if (!strcmp (p
, "hint"))
18284 c_parser_consume_token (parser
);
18285 clauses
= c_parser_omp_clause_hint (parser
, clauses
);
18291 error_at (cloc
, "expected %<read%>, %<write%>, %<update%>, "
18292 "%<capture%>, %<compare%>, %<weak%>, %<fail%>, "
18293 "%<seq_cst%>, %<acq_rel%>, %<release%>, "
18294 "%<relaxed%> or %<hint%> clause");
18298 if (new_code
!= ERROR_MARK
)
18300 /* OpenACC permits 'update capture'. */
18302 && code
== OMP_ATOMIC
18303 && new_code
== OMP_ATOMIC_CAPTURE_NEW
)
18305 else if (code
!= ERROR_MARK
)
18306 error_at (cloc
, "too many atomic clauses");
18310 else if (new_memory_order
!= OMP_MEMORY_ORDER_UNSPECIFIED
)
18312 if (memory_order
!= OMP_MEMORY_ORDER_UNSPECIFIED
)
18313 error_at (cloc
, "too many memory order clauses");
18315 memory_order
= new_memory_order
;
18317 else if (new_capture
)
18320 error_at (cloc
, "too many %qs clauses", "capture");
18324 else if (new_compare
)
18327 error_at (cloc
, "too many %qs clauses", "compare");
18334 error_at (cloc
, "too many %qs clauses", "weak");
18338 c_parser_consume_token (parser
);
18344 c_parser_skip_to_pragma_eol (parser
);
18346 if (code
== ERROR_MARK
)
18350 if (code
!= OMP_ATOMIC
)
18351 error_at (loc
, "%qs clause is incompatible with %<read%> or %<write%> "
18352 "clauses", "capture");
18354 code
= OMP_ATOMIC_CAPTURE_NEW
;
18356 if (compare
&& code
!= OMP_ATOMIC
&& code
!= OMP_ATOMIC_CAPTURE_NEW
)
18358 error_at (loc
, "%qs clause is incompatible with %<read%> or %<write%> "
18359 "clauses", "compare");
18362 if (fail
!= OMP_MEMORY_ORDER_UNSPECIFIED
&& !compare
)
18364 error_at (loc
, "%qs clause requires %qs clause", "fail", "compare");
18365 fail
= OMP_MEMORY_ORDER_UNSPECIFIED
;
18367 if (weak
&& !compare
)
18369 error_at (loc
, "%qs clause requires %qs clause", "weak", "compare");
18373 memory_order
= OMP_MEMORY_ORDER_RELAXED
;
18374 else if (memory_order
== OMP_MEMORY_ORDER_UNSPECIFIED
)
18377 = (enum omp_requires
) (omp_requires_mask
18378 | OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED
);
18379 switch ((enum omp_memory_order
)
18380 (omp_requires_mask
& OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
))
18382 case OMP_MEMORY_ORDER_UNSPECIFIED
:
18383 case OMP_MEMORY_ORDER_RELAXED
:
18384 memory_order
= OMP_MEMORY_ORDER_RELAXED
;
18386 case OMP_MEMORY_ORDER_SEQ_CST
:
18387 memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
18389 case OMP_MEMORY_ORDER_ACQ_REL
:
18392 case OMP_ATOMIC_READ
:
18393 memory_order
= OMP_MEMORY_ORDER_ACQUIRE
;
18395 case NOP_EXPR
: /* atomic write */
18396 memory_order
= OMP_MEMORY_ORDER_RELEASE
;
18399 memory_order
= OMP_MEMORY_ORDER_ACQ_REL
;
18404 gcc_unreachable ();
18410 case OMP_ATOMIC_READ
:
18411 if (memory_order
== OMP_MEMORY_ORDER_RELEASE
)
18413 error_at (loc
, "%<#pragma omp atomic read%> incompatible with "
18414 "%<release%> clause");
18415 memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
18417 else if (memory_order
== OMP_MEMORY_ORDER_ACQ_REL
)
18418 memory_order
= OMP_MEMORY_ORDER_ACQUIRE
;
18420 case NOP_EXPR
: /* atomic write */
18421 if (memory_order
== OMP_MEMORY_ORDER_ACQUIRE
)
18423 error_at (loc
, "%<#pragma omp atomic write%> incompatible with "
18424 "%<acquire%> clause");
18425 memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
18427 else if (memory_order
== OMP_MEMORY_ORDER_ACQ_REL
)
18428 memory_order
= OMP_MEMORY_ORDER_RELEASE
;
18433 if (fail
!= OMP_MEMORY_ORDER_UNSPECIFIED
)
18435 = (enum omp_memory_order
) (memory_order
18436 | (fail
<< OMP_FAIL_MEMORY_ORDER_SHIFT
));
18440 case OMP_ATOMIC_READ
:
18441 case NOP_EXPR
: /* atomic write */
18442 v
= c_parser_cast_expression (parser
, NULL
).value
;
18443 non_lvalue_p
= !lvalue_p (v
);
18444 v
= c_fully_fold (v
, false, NULL
, true);
18445 if (v
== error_mark_node
)
18448 v
= non_lvalue (v
);
18449 loc
= c_parser_peek_token (parser
)->location
;
18450 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
18452 if (code
== NOP_EXPR
)
18454 lhs
= c_parser_expression (parser
).value
;
18455 lhs
= c_fully_fold (lhs
, false, NULL
);
18456 if (lhs
== error_mark_node
)
18461 lhs
= c_parser_cast_expression (parser
, NULL
).value
;
18462 non_lvalue_p
= !lvalue_p (lhs
);
18463 lhs
= c_fully_fold (lhs
, false, NULL
, true);
18464 if (lhs
== error_mark_node
)
18467 lhs
= non_lvalue (lhs
);
18469 if (code
== NOP_EXPR
)
18471 /* atomic write is represented by OMP_ATOMIC with NOP_EXPR
18479 case OMP_ATOMIC_CAPTURE_NEW
:
18480 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
18482 c_parser_consume_token (parser
);
18483 structured_block
= true;
18486 && c_parser_next_token_is_keyword (parser
, RID_IF
))
18490 v
= c_parser_cast_expression (parser
, NULL
).value
;
18491 non_lvalue_p
= !lvalue_p (v
);
18492 v
= c_fully_fold (v
, false, NULL
, true);
18493 if (v
== error_mark_node
)
18496 v
= non_lvalue (v
);
18497 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
18499 if (compare
&& c_parser_next_token_is_keyword (parser
, RID_IF
))
18501 eloc
= c_parser_peek_token (parser
)->location
;
18502 error_at (eloc
, "expected expression");
18511 /* For structured_block case we don't know yet whether
18512 old or new x should be captured. */
18514 if (compare
&& c_parser_next_token_is_keyword (parser
, RID_IF
))
18516 c_parser_consume_token (parser
);
18518 matching_parens parens
;
18519 if (!parens
.require_open (parser
))
18521 eloc
= c_parser_peek_token (parser
)->location
;
18525 cmp_expr
= c_parser_cast_expression (parser
, NULL
);
18526 cmp_expr
= default_function_array_conversion (eloc
, cmp_expr
);
18529 cmp_expr
= c_parser_binary_expression (parser
, NULL
, void_list_node
);
18530 parens
.skip_until_found_close (parser
);
18531 if (cmp_expr
.value
== error_mark_node
)
18535 if (!c_tree_equal (cmp_expr
.value
, unfolded_lhs
))
18537 cmp_expr
.value
= rhs1
;
18539 gcc_assert (TREE_CODE (cmp_expr
.value
) == EQ_EXPR
);
18541 if (TREE_CODE (cmp_expr
.value
) == EQ_EXPR
)
18543 else if (!structured_block
&& code
== OMP_ATOMIC_CAPTURE_NEW
)
18545 error_at (EXPR_LOC_OR_LOC (cmp_expr
.value
, eloc
),
18546 "expected %<==%> comparison in %<if%> condition");
18549 else if (TREE_CODE (cmp_expr
.value
) != GT_EXPR
18550 && TREE_CODE (cmp_expr
.value
) != LT_EXPR
)
18552 error_at (EXPR_LOC_OR_LOC (cmp_expr
.value
, eloc
),
18553 "expected %<==%>, %<<%> or %<>%> comparison in %<if%> "
18557 if (!c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
18560 extra_scope
= true;
18561 eloc
= c_parser_peek_token (parser
)->location
;
18562 expr
= c_parser_cast_expression (parser
, NULL
);
18564 expr
= default_function_array_conversion (eloc
, expr
);
18565 unfolded_lhs
= expr
.value
;
18566 lhs
= c_fully_fold (lhs
, false, NULL
, true);
18568 if (lhs
== error_mark_node
)
18570 if (!lvalue_p (unfolded_lhs
))
18571 lhs
= non_lvalue (lhs
);
18572 if (!c_parser_next_token_is (parser
, CPP_EQ
))
18574 c_parser_error (parser
, "expected %<=%>");
18577 c_parser_consume_token (parser
);
18578 eloc
= c_parser_peek_token (parser
)->location
;
18579 expr
= c_parser_expr_no_commas (parser
, NULL
);
18582 if (!c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
18585 if (!c_parser_require (parser
, CPP_CLOSE_BRACE
, "expected %<}%>"))
18588 extra_scope
= false;
18589 no_semicolon
= true;
18591 if (c_tree_equal (TREE_OPERAND (cmp_expr
.value
, 0), unfolded_lhs
))
18593 if (TREE_CODE (cmp_expr
.value
) == EQ_EXPR
)
18595 opcode
= COND_EXPR
;
18596 rhs
= c_fully_fold (TREE_OPERAND (cmp_expr
.value
, 1),
18597 false, NULL
, true);
18598 rhs1
= c_fully_fold (rhs1
, false, NULL
, true);
18600 else if (c_tree_equal (TREE_OPERAND (cmp_expr
.value
, 1), rhs1
))
18602 opcode
= (TREE_CODE (cmp_expr
.value
) == GT_EXPR
18603 ? MIN_EXPR
: MAX_EXPR
);
18604 rhs
= c_fully_fold (rhs1
, false, NULL
, true);
18605 rhs1
= c_fully_fold (TREE_OPERAND (cmp_expr
.value
, 0),
18606 false, NULL
, true);
18611 else if (TREE_CODE (cmp_expr
.value
) == EQ_EXPR
)
18613 else if (c_tree_equal (TREE_OPERAND (cmp_expr
.value
, 1), unfolded_lhs
)
18614 && c_tree_equal (TREE_OPERAND (cmp_expr
.value
, 0), rhs1
))
18616 opcode
= (TREE_CODE (cmp_expr
.value
) == GT_EXPR
18617 ? MAX_EXPR
: MIN_EXPR
);
18618 rhs
= c_fully_fold (rhs1
, false, NULL
, true);
18619 rhs1
= c_fully_fold (TREE_OPERAND (cmp_expr
.value
, 1),
18620 false, NULL
, true);
18625 c_parser_error (parser
,
18626 "invalid form of %<#pragma omp atomic compare%>");
18630 if (c_parser_next_token_is_keyword (parser
, RID_ELSE
))
18632 if (code
!= OMP_ATOMIC_CAPTURE_NEW
18633 || (structured_block
&& r
== NULL_TREE
)
18634 || TREE_CODE (cmp_expr
.value
) != EQ_EXPR
)
18636 eloc
= c_parser_peek_token (parser
)->location
;
18637 error_at (eloc
, "unexpected %<else%>");
18641 c_parser_consume_token (parser
);
18643 if (!c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
18646 extra_scope
= true;
18647 v
= c_parser_cast_expression (parser
, NULL
).value
;
18648 non_lvalue_p
= !lvalue_p (v
);
18649 v
= c_fully_fold (v
, false, NULL
, true);
18650 if (v
== error_mark_node
)
18653 v
= non_lvalue (v
);
18654 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
18657 expr
= c_parser_expr_no_commas (parser
, NULL
);
18659 if (!c_tree_equal (expr
.value
, unfolded_lhs
))
18662 if (!c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
18665 if (!c_parser_require (parser
, CPP_CLOSE_BRACE
, "expected %<}%>"))
18668 extra_scope
= false;
18669 code
= OMP_ATOMIC_CAPTURE_OLD
;
18670 if (r
== NULL_TREE
)
18671 /* Signal to c_finish_omp_atomic that in
18672 if (x == e) { x = d; } else { v = x; }
18673 case the store to v should be conditional. */
18674 r
= void_list_node
;
18676 else if (code
== OMP_ATOMIC_CAPTURE_NEW
&& !structured_block
)
18678 c_parser_require_keyword (parser
, RID_ELSE
, "expected %<else%>");
18681 else if (code
== OMP_ATOMIC_CAPTURE_NEW
18687 eloc
= c_parser_peek_token (parser
)->location
;
18688 expr
= c_parser_cast_expression (parser
, NULL
);
18690 expr
= default_function_array_conversion (eloc
, expr
);
18691 unfolded_lhs
= expr
.value
;
18692 lhs
= c_fully_fold (lhs
, false, NULL
, true);
18694 switch (TREE_CODE (lhs
))
18697 error_at (eloc
, "invalid form of %<pragma omp atomic compare%>");
18701 c_parser_skip_to_end_of_block_or_statement (parser
);
18702 if (extra_scope
&& c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
18703 c_parser_consume_token (parser
);
18704 if (structured_block
)
18706 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
18707 c_parser_consume_token (parser
);
18708 else if (code
== OMP_ATOMIC_CAPTURE_NEW
)
18710 c_parser_skip_to_end_of_block_or_statement (parser
);
18711 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
18712 c_parser_consume_token (parser
);
18717 case POSTINCREMENT_EXPR
:
18718 if (code
== OMP_ATOMIC_CAPTURE_NEW
&& !structured_block
)
18719 code
= OMP_ATOMIC_CAPTURE_OLD
;
18721 case PREINCREMENT_EXPR
:
18722 lhs
= TREE_OPERAND (lhs
, 0);
18723 unfolded_lhs
= NULL_TREE
;
18724 opcode
= PLUS_EXPR
;
18725 rhs
= integer_one_node
;
18727 goto invalid_compare
;
18730 case POSTDECREMENT_EXPR
:
18731 if (code
== OMP_ATOMIC_CAPTURE_NEW
&& !structured_block
)
18732 code
= OMP_ATOMIC_CAPTURE_OLD
;
18734 case PREDECREMENT_EXPR
:
18735 lhs
= TREE_OPERAND (lhs
, 0);
18736 unfolded_lhs
= NULL_TREE
;
18737 opcode
= MINUS_EXPR
;
18738 rhs
= integer_one_node
;
18740 goto invalid_compare
;
18743 case COMPOUND_EXPR
:
18744 if (TREE_CODE (TREE_OPERAND (lhs
, 0)) == SAVE_EXPR
18745 && TREE_CODE (TREE_OPERAND (lhs
, 1)) == COMPOUND_EXPR
18746 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (lhs
, 1), 0)) == MODIFY_EXPR
18747 && TREE_OPERAND (TREE_OPERAND (lhs
, 1), 1) == TREE_OPERAND (lhs
, 0)
18748 && TREE_CODE (TREE_TYPE (TREE_OPERAND (TREE_OPERAND
18749 (TREE_OPERAND (lhs
, 1), 0), 0)))
18751 /* Undo effects of boolean_increment for post {in,de}crement. */
18752 lhs
= TREE_OPERAND (TREE_OPERAND (lhs
, 1), 0);
18755 if (TREE_CODE (lhs
) == MODIFY_EXPR
18756 && TREE_CODE (TREE_TYPE (TREE_OPERAND (lhs
, 0))) == BOOLEAN_TYPE
)
18758 /* Undo effects of boolean_increment. */
18759 if (integer_onep (TREE_OPERAND (lhs
, 1)))
18761 /* This is pre or post increment. */
18762 rhs
= TREE_OPERAND (lhs
, 1);
18763 lhs
= TREE_OPERAND (lhs
, 0);
18764 unfolded_lhs
= NULL_TREE
;
18766 if (code
== OMP_ATOMIC_CAPTURE_NEW
18767 && !structured_block
18768 && TREE_CODE (orig_lhs
) == COMPOUND_EXPR
)
18769 code
= OMP_ATOMIC_CAPTURE_OLD
;
18771 goto invalid_compare
;
18774 if (TREE_CODE (TREE_OPERAND (lhs
, 1)) == TRUTH_NOT_EXPR
18775 && TREE_OPERAND (lhs
, 0)
18776 == TREE_OPERAND (TREE_OPERAND (lhs
, 1), 0))
18778 /* This is pre or post decrement. */
18779 rhs
= TREE_OPERAND (lhs
, 1);
18780 lhs
= TREE_OPERAND (lhs
, 0);
18781 unfolded_lhs
= NULL_TREE
;
18783 if (code
== OMP_ATOMIC_CAPTURE_NEW
18784 && !structured_block
18785 && TREE_CODE (orig_lhs
) == COMPOUND_EXPR
)
18786 code
= OMP_ATOMIC_CAPTURE_OLD
;
18788 goto invalid_compare
;
18794 if (!lvalue_p (unfolded_lhs
))
18795 lhs
= non_lvalue (lhs
);
18796 if (compare
&& !c_parser_next_token_is (parser
, CPP_EQ
))
18798 c_parser_error (parser
, "expected %<=%>");
18801 switch (c_parser_peek_token (parser
)->type
)
18804 opcode
= MULT_EXPR
;
18807 opcode
= TRUNC_DIV_EXPR
;
18810 opcode
= PLUS_EXPR
;
18813 opcode
= MINUS_EXPR
;
18815 case CPP_LSHIFT_EQ
:
18816 opcode
= LSHIFT_EXPR
;
18818 case CPP_RSHIFT_EQ
:
18819 opcode
= RSHIFT_EXPR
;
18822 opcode
= BIT_AND_EXPR
;
18825 opcode
= BIT_IOR_EXPR
;
18828 opcode
= BIT_XOR_EXPR
;
18831 c_parser_consume_token (parser
);
18832 eloc
= c_parser_peek_token (parser
)->location
;
18833 expr
= c_parser_expr_no_commas (parser
, NULL
, unfolded_lhs
);
18835 switch (TREE_CODE (rhs1
))
18838 case TRUNC_DIV_EXPR
:
18849 if (c_tree_equal (TREE_OPERAND (rhs1
, 0), unfolded_lhs
))
18851 opcode
= TREE_CODE (rhs1
);
18852 rhs
= c_fully_fold (TREE_OPERAND (rhs1
, 1), false, NULL
,
18854 rhs1
= c_fully_fold (TREE_OPERAND (rhs1
, 0), false, NULL
,
18858 if (c_tree_equal (TREE_OPERAND (rhs1
, 1), unfolded_lhs
))
18860 opcode
= TREE_CODE (rhs1
);
18861 rhs
= c_fully_fold (TREE_OPERAND (rhs1
, 0), false, NULL
,
18863 rhs1
= c_fully_fold (TREE_OPERAND (rhs1
, 1), false, NULL
,
18865 swapped
= !commutative_tree_code (opcode
);
18872 if (TREE_CODE (TREE_OPERAND (rhs1
, 0)) != GT_EXPR
18873 && TREE_CODE (TREE_OPERAND (rhs1
, 0)) != LT_EXPR
18874 && TREE_CODE (TREE_OPERAND (rhs1
, 0)) != EQ_EXPR
)
18876 if (!TREE_OPERAND (rhs1
, 1))
18878 if (!c_tree_equal (TREE_OPERAND (rhs1
, 2), unfolded_lhs
))
18880 if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1
, 0), 0),
18883 if (TREE_CODE (TREE_OPERAND (rhs1
, 0)) == EQ_EXPR
)
18885 opcode
= COND_EXPR
;
18886 rhs
= c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1
,
18888 false, NULL
, true);
18889 rhs1
= c_fully_fold (TREE_OPERAND (rhs1
, 1), false,
18893 if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1
, 0), 1),
18894 TREE_OPERAND (rhs1
, 1)))
18896 opcode
= (TREE_CODE (TREE_OPERAND (rhs1
, 0)) == GT_EXPR
18897 ? MIN_EXPR
: MAX_EXPR
);
18898 rhs
= c_fully_fold (TREE_OPERAND (rhs1
, 1), false, NULL
,
18900 rhs1
= c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1
,
18902 false, NULL
, true);
18906 else if (TREE_CODE (TREE_OPERAND (rhs1
, 0)) == EQ_EXPR
)
18908 else if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1
, 0), 1),
18911 if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1
, 0), 0),
18912 TREE_OPERAND (rhs1
, 1)))
18914 opcode
= (TREE_CODE (TREE_OPERAND (rhs1
, 0)) == GT_EXPR
18915 ? MAX_EXPR
: MIN_EXPR
);
18916 rhs
= c_fully_fold (TREE_OPERAND (rhs1
, 1), false, NULL
,
18918 rhs1
= c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1
,
18920 false, NULL
, true);
18927 || code
!= OMP_ATOMIC_CAPTURE_NEW
18928 || !structured_block
18932 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
)
18933 && c_parser_peek_2nd_token (parser
)->keyword
== RID_IF
)
18937 c_parser_consume_token (parser
);
18946 if (c_parser_peek_token (parser
)->type
== CPP_SEMICOLON
)
18948 if (structured_block
&& code
== OMP_ATOMIC_CAPTURE_NEW
)
18950 code
= OMP_ATOMIC_CAPTURE_OLD
;
18953 expr
= default_function_array_read_conversion (eloc
, expr
);
18954 unfolded_lhs1
= expr
.value
;
18955 lhs1
= c_fully_fold (unfolded_lhs1
, false, NULL
, true);
18957 c_parser_consume_token (parser
);
18960 if (structured_block
&& !compare
)
18963 expr
= default_function_array_read_conversion (eloc
, expr
);
18964 rhs
= c_fully_fold (expr
.value
, false, NULL
, true);
18969 c_parser_error (parser
, "invalid form of %<#pragma omp atomic%>");
18972 c_parser_error (parser
,
18973 "invalid operator for %<#pragma omp atomic%>");
18977 /* Arrange to pass the location of the assignment operator to
18978 c_finish_omp_atomic. */
18979 loc
= c_parser_peek_token (parser
)->location
;
18980 c_parser_consume_token (parser
);
18981 eloc
= c_parser_peek_token (parser
)->location
;
18982 expr
= c_parser_expression (parser
);
18983 expr
= default_function_array_read_conversion (eloc
, expr
);
18985 rhs
= c_fully_fold (rhs
, false, NULL
, true);
18989 if (structured_block
&& code
== OMP_ATOMIC_CAPTURE_NEW
&& r
== NULL_TREE
)
18992 && !c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
18994 no_semicolon
= false;
18995 v
= c_parser_cast_expression (parser
, NULL
).value
;
18996 non_lvalue_p
= !lvalue_p (v
);
18997 v
= c_fully_fold (v
, false, NULL
, true);
18998 if (v
== error_mark_node
)
19001 v
= non_lvalue (v
);
19002 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
19004 eloc
= c_parser_peek_token (parser
)->location
;
19005 expr
= c_parser_cast_expression (parser
, NULL
);
19007 expr
= default_function_array_read_conversion (eloc
, expr
);
19008 unfolded_lhs1
= expr
.value
;
19009 lhs1
= c_fully_fold (lhs1
, false, NULL
, true);
19010 if (lhs1
== error_mark_node
)
19012 if (!lvalue_p (unfolded_lhs1
))
19013 lhs1
= non_lvalue (lhs1
);
19015 if (structured_block
)
19018 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
19019 c_parser_require (parser
, CPP_CLOSE_BRACE
, "expected %<}%>");
19022 if (weak
&& opcode
!= COND_EXPR
)
19024 error_at (loc
, "%<weak%> clause requires atomic equality comparison");
19027 if (unfolded_lhs
&& unfolded_lhs1
19028 && !c_tree_equal (unfolded_lhs
, unfolded_lhs1
))
19030 error ("%<#pragma omp atomic capture%> uses two different "
19031 "expressions for memory");
19032 stmt
= error_mark_node
;
19035 stmt
= c_finish_omp_atomic (loc
, code
, opcode
, lhs
, rhs
, v
, lhs1
, rhs1
, r
,
19036 swapped
, memory_order
, weak
);
19037 if (stmt
!= error_mark_node
)
19040 if (!structured_block
&& !no_semicolon
)
19041 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
19046 # pragma omp barrier new-line
19050 c_parser_omp_barrier (c_parser
*parser
)
19052 location_t loc
= c_parser_peek_token (parser
)->location
;
19053 c_parser_consume_pragma (parser
);
19054 c_parser_skip_to_pragma_eol (parser
);
19056 c_finish_omp_barrier (loc
);
19060 # pragma omp critical [(name)] new-line
19064 # pragma omp critical [(name) [hint(expression)]] new-line
19066 LOC is the location of the #pragma itself. */
19068 #define OMP_CRITICAL_CLAUSE_MASK \
19069 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HINT) )
19072 c_parser_omp_critical (location_t loc
, c_parser
*parser
, bool *if_p
)
19074 tree stmt
, name
= NULL_TREE
, clauses
= NULL_TREE
;
19076 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
19078 c_parser_consume_token (parser
);
19079 if (c_parser_next_token_is (parser
, CPP_NAME
))
19081 name
= c_parser_peek_token (parser
)->value
;
19082 c_parser_consume_token (parser
);
19083 c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>");
19086 c_parser_error (parser
, "expected identifier");
19088 if (c_parser_next_token_is (parser
, CPP_COMMA
)
19089 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
19090 c_parser_consume_token (parser
);
19092 clauses
= c_parser_omp_all_clauses (parser
, OMP_CRITICAL_CLAUSE_MASK
,
19093 "#pragma omp critical");
19094 stmt
= c_parser_omp_structured_block (parser
, if_p
);
19095 return c_finish_omp_critical (loc
, stmt
, name
, clauses
);
19099 # pragma omp depobj ( depobj ) depobj-clause new-line
19102 depend (dependence-type : locator)
19104 update (dependence-type)
19113 c_parser_omp_depobj (c_parser
*parser
)
19115 location_t loc
= c_parser_peek_token (parser
)->location
;
19116 c_parser_consume_pragma (parser
);
19117 matching_parens parens
;
19118 if (!parens
.require_open (parser
))
19120 c_parser_skip_to_pragma_eol (parser
);
19124 tree depobj
= c_parser_expr_no_commas (parser
, NULL
).value
;
19125 if (depobj
!= error_mark_node
)
19127 if (!lvalue_p (depobj
))
19129 error_at (EXPR_LOC_OR_LOC (depobj
, loc
),
19130 "%<depobj%> expression is not lvalue expression");
19131 depobj
= error_mark_node
;
19135 tree addr
= build_unary_op (EXPR_LOC_OR_LOC (depobj
, loc
), ADDR_EXPR
,
19137 if (addr
== error_mark_node
)
19138 depobj
= error_mark_node
;
19140 depobj
= build_indirect_ref (EXPR_LOC_OR_LOC (depobj
, loc
),
19141 addr
, RO_UNARY_STAR
);
19145 parens
.skip_until_found_close (parser
);
19146 tree clause
= NULL_TREE
;
19147 enum omp_clause_depend_kind kind
= OMP_CLAUSE_DEPEND_SOURCE
;
19148 location_t c_loc
= c_parser_peek_token (parser
)->location
;
19149 if (c_parser_next_token_is (parser
, CPP_NAME
))
19151 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
19153 c_parser_consume_token (parser
);
19154 if (!strcmp ("depend", p
))
19156 clause
= c_parser_omp_clause_depend (parser
, NULL_TREE
);
19157 clause
= c_finish_omp_clauses (clause
, C_ORT_OMP
);
19159 clause
= error_mark_node
;
19161 else if (!strcmp ("destroy", p
))
19162 kind
= OMP_CLAUSE_DEPEND_LAST
;
19163 else if (!strcmp ("update", p
))
19165 matching_parens c_parens
;
19166 if (c_parens
.require_open (parser
))
19168 location_t c2_loc
= c_parser_peek_token (parser
)->location
;
19169 if (c_parser_next_token_is (parser
, CPP_NAME
))
19172 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
19174 c_parser_consume_token (parser
);
19175 if (!strcmp ("in", p2
))
19176 kind
= OMP_CLAUSE_DEPEND_IN
;
19177 else if (!strcmp ("out", p2
))
19178 kind
= OMP_CLAUSE_DEPEND_OUT
;
19179 else if (!strcmp ("inout", p2
))
19180 kind
= OMP_CLAUSE_DEPEND_INOUT
;
19181 else if (!strcmp ("mutexinoutset", p2
))
19182 kind
= OMP_CLAUSE_DEPEND_MUTEXINOUTSET
;
19183 else if (!strcmp ("inoutset", p2
))
19184 kind
= OMP_CLAUSE_DEPEND_INOUTSET
;
19186 if (kind
== OMP_CLAUSE_DEPEND_SOURCE
)
19188 clause
= error_mark_node
;
19189 error_at (c2_loc
, "expected %<in%>, %<out%>, %<inout%>, "
19190 "%<mutexinoutset%> or %<inoutset%>");
19192 c_parens
.skip_until_found_close (parser
);
19195 clause
= error_mark_node
;
19198 if (!clause
&& kind
== OMP_CLAUSE_DEPEND_SOURCE
)
19200 clause
= error_mark_node
;
19201 error_at (c_loc
, "expected %<depend%>, %<destroy%> or %<update%> clause");
19203 c_parser_skip_to_pragma_eol (parser
);
19205 c_finish_omp_depobj (loc
, depobj
, kind
, clause
);
19210 # pragma omp flush flush-vars[opt] new-line
19216 # pragma omp flush memory-order-clause new-line */
19219 c_parser_omp_flush (c_parser
*parser
)
19221 location_t loc
= c_parser_peek_token (parser
)->location
;
19222 c_parser_consume_pragma (parser
);
19223 enum memmodel mo
= MEMMODEL_LAST
;
19224 if (c_parser_next_token_is (parser
, CPP_NAME
))
19227 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
19229 if (!strcmp (p
, "seq_cst"))
19230 mo
= MEMMODEL_SEQ_CST
;
19231 else if (!strcmp (p
, "acq_rel"))
19232 mo
= MEMMODEL_ACQ_REL
;
19233 else if (!strcmp (p
, "release"))
19234 mo
= MEMMODEL_RELEASE
;
19235 else if (!strcmp (p
, "acquire"))
19236 mo
= MEMMODEL_ACQUIRE
;
19238 error_at (c_parser_peek_token (parser
)->location
,
19239 "expected %<seq_cst%>, %<acq_rel%>, %<release%> or "
19241 c_parser_consume_token (parser
);
19243 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
19245 if (mo
!= MEMMODEL_LAST
)
19246 error_at (c_parser_peek_token (parser
)->location
,
19247 "%<flush%> list specified together with memory order "
19249 c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ERROR
, NULL
);
19251 else if (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
19252 c_parser_error (parser
, "expected %<(%> or end of line");
19253 c_parser_skip_to_pragma_eol (parser
);
19255 c_finish_omp_flush (loc
, mo
);
19258 /* Parse an OpenMP structured block sequence. KIND is the corresponding
19259 separating directive. */
19262 c_parser_omp_structured_block_sequence (c_parser
*parser
,
19263 enum pragma_kind kind
)
19265 tree stmt
= push_stmt_list ();
19266 c_parser_statement (parser
, NULL
);
19269 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
19271 if (c_parser_next_token_is (parser
, CPP_EOF
))
19274 if (kind
!= PRAGMA_NONE
19275 && c_parser_peek_token (parser
)->pragma_kind
== kind
)
19277 c_parser_statement (parser
, NULL
);
19280 return pop_stmt_list (stmt
);
19286 { structured-block scan-directive structured-block } */
19289 c_parser_omp_scan_loop_body (c_parser
*parser
, bool open_brace_parsed
)
19293 tree clauses
= NULL_TREE
;
19295 loc
= c_parser_peek_token (parser
)->location
;
19296 if (!open_brace_parsed
19297 && !c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
19299 /* Avoid skipping until the end of the block. */
19300 parser
->error
= false;
19304 substmt
= c_parser_omp_structured_block_sequence (parser
, PRAGMA_OMP_SCAN
);
19305 substmt
= build2 (OMP_SCAN
, void_type_node
, substmt
, NULL_TREE
);
19306 SET_EXPR_LOCATION (substmt
, loc
);
19307 add_stmt (substmt
);
19309 loc
= c_parser_peek_token (parser
)->location
;
19310 if (c_parser_peek_token (parser
)->pragma_kind
== PRAGMA_OMP_SCAN
)
19312 enum omp_clause_code clause
= OMP_CLAUSE_ERROR
;
19314 c_parser_consume_pragma (parser
);
19316 if (c_parser_next_token_is (parser
, CPP_NAME
))
19319 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
19320 if (strcmp (p
, "inclusive") == 0)
19321 clause
= OMP_CLAUSE_INCLUSIVE
;
19322 else if (strcmp (p
, "exclusive") == 0)
19323 clause
= OMP_CLAUSE_EXCLUSIVE
;
19325 if (clause
!= OMP_CLAUSE_ERROR
)
19327 c_parser_consume_token (parser
);
19328 clauses
= c_parser_omp_var_list_parens (parser
, clause
, NULL_TREE
);
19331 c_parser_error (parser
, "expected %<inclusive%> or "
19332 "%<exclusive%> clause");
19333 c_parser_skip_to_pragma_eol (parser
);
19336 error ("expected %<#pragma omp scan%>");
19338 clauses
= c_finish_omp_clauses (clauses
, C_ORT_OMP
);
19339 substmt
= c_parser_omp_structured_block_sequence (parser
, PRAGMA_NONE
);
19340 substmt
= build2 (OMP_SCAN
, void_type_node
, substmt
, clauses
);
19341 SET_EXPR_LOCATION (substmt
, loc
);
19342 add_stmt (substmt
);
19344 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
,
19348 /* Parse the restricted form of loop statements allowed by OpenACC and OpenMP.
19349 The real trick here is to determine the loop control variable early
19350 so that we can push a new decl if necessary to make it private.
19351 LOC is the location of the "acc" or "omp" in "#pragma acc" or "#pragma omp",
19355 c_parser_omp_for_loop (location_t loc
, c_parser
*parser
, enum tree_code code
,
19356 tree clauses
, tree
*cclauses
, bool *if_p
)
19358 tree decl
, cond
, incr
, body
, init
, stmt
, cl
;
19359 unsigned char save_in_statement
;
19360 tree declv
, condv
, incrv
, initv
, ret
= NULL_TREE
;
19361 tree pre_body
= NULL_TREE
, this_pre_body
;
19362 tree ordered_cl
= NULL_TREE
;
19363 bool fail
= false, open_brace_parsed
= false;
19364 int i
, collapse
= 1, ordered
= 0, count
, nbraces
= 0;
19365 location_t for_loc
;
19366 bool tiling
= false;
19367 bool inscan
= false;
19368 vec
<tree
, va_gc
> *for_block
= make_tree_vector ();
19370 for (cl
= clauses
; cl
; cl
= OMP_CLAUSE_CHAIN (cl
))
19371 if (OMP_CLAUSE_CODE (cl
) == OMP_CLAUSE_COLLAPSE
)
19372 collapse
= tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (cl
));
19373 else if (OMP_CLAUSE_CODE (cl
) == OMP_CLAUSE_TILE
)
19376 collapse
= list_length (OMP_CLAUSE_TILE_LIST (cl
));
19378 else if (OMP_CLAUSE_CODE (cl
) == OMP_CLAUSE_ORDERED
19379 && OMP_CLAUSE_ORDERED_EXPR (cl
))
19382 ordered
= tree_to_shwi (OMP_CLAUSE_ORDERED_EXPR (cl
));
19384 else if (OMP_CLAUSE_CODE (cl
) == OMP_CLAUSE_REDUCTION
19385 && OMP_CLAUSE_REDUCTION_INSCAN (cl
)
19386 && (code
== OMP_SIMD
|| code
== OMP_FOR
))
19389 if (ordered
&& ordered
< collapse
)
19391 error_at (OMP_CLAUSE_LOCATION (ordered_cl
),
19392 "%<ordered%> clause parameter is less than %<collapse%>");
19393 OMP_CLAUSE_ORDERED_EXPR (ordered_cl
)
19394 = build_int_cst (NULL_TREE
, collapse
);
19395 ordered
= collapse
;
19399 for (tree
*pc
= &clauses
; *pc
; )
19400 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_LINEAR
)
19402 error_at (OMP_CLAUSE_LOCATION (*pc
),
19403 "%<linear%> clause may not be specified together "
19404 "with %<ordered%> clause with a parameter");
19405 *pc
= OMP_CLAUSE_CHAIN (*pc
);
19408 pc
= &OMP_CLAUSE_CHAIN (*pc
);
19411 gcc_assert (tiling
|| (collapse
>= 1 && ordered
>= 0));
19412 count
= ordered
? ordered
: collapse
;
19414 declv
= make_tree_vec (count
);
19415 initv
= make_tree_vec (count
);
19416 condv
= make_tree_vec (count
);
19417 incrv
= make_tree_vec (count
);
19419 if (!c_parser_next_token_is_keyword (parser
, RID_FOR
))
19421 c_parser_error (parser
, "for statement expected");
19424 for_loc
= c_parser_peek_token (parser
)->location
;
19425 c_parser_consume_token (parser
);
19427 /* Forbid break/continue in the loop initializer, condition, and
19428 increment expressions. */
19429 save_in_statement
= in_statement
;
19430 in_statement
= IN_OMP_BLOCK
;
19432 for (i
= 0; i
< count
; i
++)
19434 int bracecount
= 0;
19436 matching_parens parens
;
19437 if (!parens
.require_open (parser
))
19440 /* Parse the initialization declaration or expression. */
19441 if (c_parser_next_tokens_start_declaration (parser
))
19444 vec_safe_push (for_block
, c_begin_compound_stmt (true));
19445 this_pre_body
= push_stmt_list ();
19446 c_in_omp_for
= true;
19447 c_parser_declaration_or_fndef (parser
, true, true, true, true, true);
19448 c_in_omp_for
= false;
19451 this_pre_body
= pop_stmt_list (this_pre_body
);
19455 pre_body
= push_stmt_list ();
19457 add_stmt (this_pre_body
);
19458 pre_body
= pop_stmt_list (pre_body
);
19461 pre_body
= this_pre_body
;
19463 decl
= check_for_loop_decls (for_loc
, flag_isoc99
);
19466 if (DECL_INITIAL (decl
) == error_mark_node
)
19467 decl
= error_mark_node
;
19470 else if (c_parser_next_token_is (parser
, CPP_NAME
)
19471 && c_parser_peek_2nd_token (parser
)->type
== CPP_EQ
)
19473 struct c_expr decl_exp
;
19474 struct c_expr init_exp
;
19475 location_t init_loc
;
19477 decl_exp
= c_parser_postfix_expression (parser
);
19478 decl
= decl_exp
.value
;
19480 c_parser_require (parser
, CPP_EQ
, "expected %<=%>");
19482 init_loc
= c_parser_peek_token (parser
)->location
;
19483 init_exp
= c_parser_expr_no_commas (parser
, NULL
);
19484 init_exp
= default_function_array_read_conversion (init_loc
,
19486 c_in_omp_for
= true;
19487 init
= build_modify_expr (init_loc
, decl
, decl_exp
.original_type
,
19488 NOP_EXPR
, init_loc
, init_exp
.value
,
19489 init_exp
.original_type
);
19490 c_in_omp_for
= false;
19491 init
= c_process_expr_stmt (init_loc
, init
);
19493 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
19498 c_parser_error (parser
,
19499 "expected iteration declaration or initialization");
19500 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
19506 /* Parse the loop condition. */
19508 if (c_parser_next_token_is_not (parser
, CPP_SEMICOLON
))
19510 location_t cond_loc
= c_parser_peek_token (parser
)->location
;
19511 c_in_omp_for
= true;
19512 struct c_expr cond_expr
19513 = c_parser_binary_expression (parser
, NULL
, NULL_TREE
);
19514 c_in_omp_for
= false;
19516 cond
= cond_expr
.value
;
19517 cond
= c_objc_common_truthvalue_conversion (cond_loc
, cond
);
19518 switch (cond_expr
.original_code
)
19526 if (code
!= OACC_LOOP
)
19530 /* Can't be cond = error_mark_node, because we want to preserve
19531 the location until c_finish_omp_for. */
19532 cond
= build1 (NOP_EXPR
, boolean_type_node
, error_mark_node
);
19535 protected_set_expr_location (cond
, cond_loc
);
19537 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
19539 /* Parse the increment expression. */
19541 if (c_parser_next_token_is_not (parser
, CPP_CLOSE_PAREN
))
19543 location_t incr_loc
= c_parser_peek_token (parser
)->location
;
19545 incr
= c_process_expr_stmt (incr_loc
,
19546 c_parser_expression (parser
).value
);
19548 parens
.skip_until_found_close (parser
);
19550 if (decl
== NULL
|| decl
== error_mark_node
|| init
== error_mark_node
)
19554 TREE_VEC_ELT (declv
, i
) = decl
;
19555 TREE_VEC_ELT (initv
, i
) = init
;
19556 TREE_VEC_ELT (condv
, i
) = cond
;
19557 TREE_VEC_ELT (incrv
, i
) = incr
;
19561 if (i
== count
- 1)
19564 /* FIXME: OpenMP 3.0 draft isn't very clear on what exactly is allowed
19565 in between the collapsed for loops to be still considered perfectly
19566 nested. Hopefully the final version clarifies this.
19567 For now handle (multiple) {'s and empty statements. */
19570 if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
19572 c_parser_consume_token (parser
);
19575 else if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
19577 c_parser_consume_token (parser
);
19580 else if (bracecount
19581 && c_parser_next_token_is (parser
, CPP_SEMICOLON
))
19582 c_parser_consume_token (parser
);
19585 c_parser_error (parser
, "not enough perfectly nested loops");
19588 open_brace_parsed
= true;
19598 nbraces
+= bracecount
;
19604 in_statement
= IN_OMP_FOR
;
19605 body
= push_stmt_list ();
19608 c_parser_omp_scan_loop_body (parser
, open_brace_parsed
);
19609 else if (open_brace_parsed
)
19611 location_t here
= c_parser_peek_token (parser
)->location
;
19612 stmt
= c_begin_compound_stmt (true);
19613 c_parser_compound_statement_nostart (parser
);
19614 add_stmt (c_end_compound_stmt (here
, stmt
, true));
19617 add_stmt (c_parser_c99_block_statement (parser
, if_p
));
19619 body
= pop_stmt_list (body
);
19620 in_statement
= save_in_statement
;
19624 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
19626 c_parser_consume_token (parser
);
19629 else if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
19630 c_parser_consume_token (parser
);
19633 c_parser_error (parser
, "collapsed loops not perfectly nested");
19636 location_t here
= c_parser_peek_token (parser
)->location
;
19637 stmt
= c_begin_compound_stmt (true);
19639 c_parser_compound_statement_nostart (parser
);
19640 body
= c_end_compound_stmt (here
, stmt
, true);
19647 /* Only bother calling c_finish_omp_for if we haven't already generated
19648 an error from the initialization parsing. */
19651 c_in_omp_for
= true;
19652 stmt
= c_finish_omp_for (loc
, code
, declv
, NULL
, initv
, condv
,
19653 incrv
, body
, pre_body
, true);
19654 c_in_omp_for
= false;
19656 /* Check for iterators appearing in lb, b or incr expressions. */
19657 if (stmt
&& !c_omp_check_loop_iv (stmt
, declv
, NULL
))
19664 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (stmt
)); i
++)
19666 tree init
= TREE_VEC_ELT (OMP_FOR_INIT (stmt
), i
);
19667 gcc_assert (TREE_CODE (init
) == MODIFY_EXPR
);
19668 tree decl
= TREE_OPERAND (init
, 0);
19669 tree cond
= TREE_VEC_ELT (OMP_FOR_COND (stmt
), i
);
19670 gcc_assert (COMPARISON_CLASS_P (cond
));
19671 gcc_assert (TREE_OPERAND (cond
, 0) == decl
);
19673 tree op0
= TREE_OPERAND (init
, 1);
19674 if (!OMP_FOR_NON_RECTANGULAR (stmt
)
19675 || TREE_CODE (op0
) != TREE_VEC
)
19676 TREE_OPERAND (init
, 1) = c_fully_fold (op0
, false, NULL
);
19679 TREE_VEC_ELT (op0
, 1)
19680 = c_fully_fold (TREE_VEC_ELT (op0
, 1), false, NULL
);
19681 TREE_VEC_ELT (op0
, 2)
19682 = c_fully_fold (TREE_VEC_ELT (op0
, 2), false, NULL
);
19685 tree op1
= TREE_OPERAND (cond
, 1);
19686 if (!OMP_FOR_NON_RECTANGULAR (stmt
)
19687 || TREE_CODE (op1
) != TREE_VEC
)
19688 TREE_OPERAND (cond
, 1) = c_fully_fold (op1
, false, NULL
);
19691 TREE_VEC_ELT (op1
, 1)
19692 = c_fully_fold (TREE_VEC_ELT (op1
, 1), false, NULL
);
19693 TREE_VEC_ELT (op1
, 2)
19694 = c_fully_fold (TREE_VEC_ELT (op1
, 2), false, NULL
);
19698 if (cclauses
!= NULL
19699 && cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
] != NULL
)
19702 for (c
= &cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
]; *c
; )
19703 if (OMP_CLAUSE_CODE (*c
) != OMP_CLAUSE_FIRSTPRIVATE
19704 && OMP_CLAUSE_CODE (*c
) != OMP_CLAUSE_LASTPRIVATE
)
19705 c
= &OMP_CLAUSE_CHAIN (*c
);
19708 for (i
= 0; i
< count
; i
++)
19709 if (TREE_VEC_ELT (declv
, i
) == OMP_CLAUSE_DECL (*c
))
19712 c
= &OMP_CLAUSE_CHAIN (*c
);
19713 else if (OMP_CLAUSE_CODE (*c
) == OMP_CLAUSE_FIRSTPRIVATE
)
19716 "iteration variable %qD should not be firstprivate",
19717 OMP_CLAUSE_DECL (*c
));
19718 *c
= OMP_CLAUSE_CHAIN (*c
);
19722 /* Move lastprivate (decl) clause to OMP_FOR_CLAUSES. */
19724 *c
= OMP_CLAUSE_CHAIN (*c
);
19725 if (code
== OMP_SIMD
)
19727 OMP_CLAUSE_CHAIN (l
)
19728 = cclauses
[C_OMP_CLAUSE_SPLIT_FOR
];
19729 cclauses
[C_OMP_CLAUSE_SPLIT_FOR
] = l
;
19733 OMP_CLAUSE_CHAIN (l
) = clauses
;
19739 OMP_FOR_CLAUSES (stmt
) = clauses
;
19744 while (!for_block
->is_empty ())
19746 /* FIXME diagnostics: LOC below should be the actual location of
19747 this particular for block. We need to build a list of
19748 locations to go along with FOR_BLOCK. */
19749 stmt
= c_end_compound_stmt (loc
, for_block
->pop (), true);
19752 release_tree_vector (for_block
);
19756 /* Helper function for OpenMP parsing, split clauses and call
19757 finish_omp_clauses on each of the set of clauses afterwards. */
19760 omp_split_clauses (location_t loc
, enum tree_code code
,
19761 omp_clause_mask mask
, tree clauses
, tree
*cclauses
)
19764 c_omp_split_clauses (loc
, code
, mask
, clauses
, cclauses
);
19765 for (i
= 0; i
< C_OMP_CLAUSE_SPLIT_COUNT
; i
++)
19767 cclauses
[i
] = c_finish_omp_clauses (cclauses
[i
],
19768 i
== C_OMP_CLAUSE_SPLIT_TARGET
19769 ? C_ORT_OMP_TARGET
: C_ORT_OMP
);
19773 #pragma omp loop loop-clause[optseq] new-line
19776 LOC is the location of the #pragma token.
19779 #define OMP_LOOP_CLAUSE_MASK \
19780 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19781 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
19782 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
19783 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
19784 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_BIND) \
19785 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
19788 c_parser_omp_loop (location_t loc
, c_parser
*parser
,
19789 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
19792 tree block
, clauses
, ret
;
19794 strcat (p_name
, " loop");
19795 mask
|= OMP_LOOP_CLAUSE_MASK
;
19797 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
19800 omp_split_clauses (loc
, OMP_LOOP
, mask
, clauses
, cclauses
);
19801 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_LOOP
];
19804 block
= c_begin_compound_stmt (true);
19805 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_LOOP
, clauses
, cclauses
, if_p
);
19806 block
= c_end_compound_stmt (loc
, block
, true);
19813 #pragma omp simd simd-clause[optseq] new-line
19816 LOC is the location of the #pragma token.
19819 #define OMP_SIMD_CLAUSE_MASK \
19820 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SAFELEN) \
19821 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
19822 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
19823 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
19824 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19825 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
19826 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
19827 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
19828 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
19829 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NONTEMPORAL) \
19830 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
19833 c_parser_omp_simd (location_t loc
, c_parser
*parser
,
19834 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
19837 tree block
, clauses
, ret
;
19839 strcat (p_name
, " simd");
19840 mask
|= OMP_SIMD_CLAUSE_MASK
;
19842 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
19845 omp_split_clauses (loc
, OMP_SIMD
, mask
, clauses
, cclauses
);
19846 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_SIMD
];
19847 tree c
= omp_find_clause (cclauses
[C_OMP_CLAUSE_SPLIT_FOR
],
19848 OMP_CLAUSE_ORDERED
);
19849 if (c
&& OMP_CLAUSE_ORDERED_EXPR (c
))
19851 error_at (OMP_CLAUSE_LOCATION (c
),
19852 "%<ordered%> clause with parameter may not be specified "
19853 "on %qs construct", p_name
);
19854 OMP_CLAUSE_ORDERED_EXPR (c
) = NULL_TREE
;
19858 block
= c_begin_compound_stmt (true);
19859 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_SIMD
, clauses
, cclauses
, if_p
);
19860 block
= c_end_compound_stmt (loc
, block
, true);
19867 #pragma omp for for-clause[optseq] new-line
19871 #pragma omp for simd for-simd-clause[optseq] new-line
19874 LOC is the location of the #pragma token.
19877 #define OMP_FOR_CLAUSE_MASK \
19878 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19879 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
19880 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
19881 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
19882 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
19883 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED) \
19884 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE) \
19885 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
19886 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
19887 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
19888 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
19891 c_parser_omp_for (location_t loc
, c_parser
*parser
,
19892 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
19895 tree block
, clauses
, ret
;
19897 strcat (p_name
, " for");
19898 mask
|= OMP_FOR_CLAUSE_MASK
;
19899 /* parallel for{, simd} disallows nowait clause, but for
19900 target {teams distribute ,}parallel for{, simd} it should be accepted. */
19901 if (cclauses
&& (mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_MAP
)) == 0)
19902 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_NOWAIT
);
19903 /* Composite distribute parallel for{, simd} disallows ordered clause. */
19904 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
)) != 0)
19905 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_ORDERED
);
19907 if (c_parser_next_token_is (parser
, CPP_NAME
))
19909 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
19911 if (strcmp (p
, "simd") == 0)
19913 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
19914 if (cclauses
== NULL
)
19915 cclauses
= cclauses_buf
;
19917 c_parser_consume_token (parser
);
19918 if (!flag_openmp
) /* flag_openmp_simd */
19919 return c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
,
19921 block
= c_begin_compound_stmt (true);
19922 ret
= c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
19923 block
= c_end_compound_stmt (loc
, block
, true);
19924 if (ret
== NULL_TREE
)
19926 ret
= make_node (OMP_FOR
);
19927 TREE_TYPE (ret
) = void_type_node
;
19928 OMP_FOR_BODY (ret
) = block
;
19929 OMP_FOR_CLAUSES (ret
) = cclauses
[C_OMP_CLAUSE_SPLIT_FOR
];
19930 SET_EXPR_LOCATION (ret
, loc
);
19935 if (!flag_openmp
) /* flag_openmp_simd */
19937 c_parser_skip_to_pragma_eol (parser
, false);
19941 /* Composite distribute parallel for disallows linear clause. */
19942 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
)) != 0)
19943 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_LINEAR
);
19945 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
19948 omp_split_clauses (loc
, OMP_FOR
, mask
, clauses
, cclauses
);
19949 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_FOR
];
19952 block
= c_begin_compound_stmt (true);
19953 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_FOR
, clauses
, cclauses
, if_p
);
19954 block
= c_end_compound_stmt (loc
, block
, true);
19960 static tree
c_parser_omp_taskloop (location_t
, c_parser
*, char *,
19961 omp_clause_mask
, tree
*, bool *);
19964 # pragma omp master new-line
19967 LOC is the location of the #pragma token.
19971 c_parser_omp_master (location_t loc
, c_parser
*parser
,
19972 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
19975 tree block
, clauses
, ret
;
19977 strcat (p_name
, " master");
19979 if (c_parser_next_token_is (parser
, CPP_NAME
))
19981 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
19983 if (strcmp (p
, "taskloop") == 0)
19985 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
19986 if (cclauses
== NULL
)
19987 cclauses
= cclauses_buf
;
19989 c_parser_consume_token (parser
);
19990 if (!flag_openmp
) /* flag_openmp_simd */
19991 return c_parser_omp_taskloop (loc
, parser
, p_name
, mask
, cclauses
,
19993 block
= c_begin_compound_stmt (true);
19994 ret
= c_parser_omp_taskloop (loc
, parser
, p_name
, mask
, cclauses
,
19996 block
= c_end_compound_stmt (loc
, block
, true);
19997 if (ret
== NULL_TREE
)
19999 ret
= c_finish_omp_master (loc
, block
);
20000 OMP_MASTER_COMBINED (ret
) = 1;
20004 if (!flag_openmp
) /* flag_openmp_simd */
20006 c_parser_skip_to_pragma_eol (parser
, false);
20012 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, false);
20013 omp_split_clauses (loc
, OMP_MASTER
, mask
, clauses
, cclauses
);
20016 c_parser_skip_to_pragma_eol (parser
);
20018 return c_finish_omp_master (loc
, c_parser_omp_structured_block (parser
,
20023 # pragma omp masked masked-clauses new-line
20026 LOC is the location of the #pragma token.
20029 #define OMP_MASKED_CLAUSE_MASK \
20030 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FILTER)
20033 c_parser_omp_masked (location_t loc
, c_parser
*parser
,
20034 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
20037 tree block
, clauses
, ret
;
20039 strcat (p_name
, " masked");
20040 mask
|= OMP_MASKED_CLAUSE_MASK
;
20042 if (c_parser_next_token_is (parser
, CPP_NAME
))
20044 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
20046 if (strcmp (p
, "taskloop") == 0)
20048 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
20049 if (cclauses
== NULL
)
20050 cclauses
= cclauses_buf
;
20052 c_parser_consume_token (parser
);
20053 if (!flag_openmp
) /* flag_openmp_simd */
20054 return c_parser_omp_taskloop (loc
, parser
, p_name
, mask
, cclauses
,
20056 block
= c_begin_compound_stmt (true);
20057 ret
= c_parser_omp_taskloop (loc
, parser
, p_name
, mask
, cclauses
,
20059 block
= c_end_compound_stmt (loc
, block
, true);
20060 if (ret
== NULL_TREE
)
20062 ret
= c_finish_omp_masked (loc
, block
,
20063 cclauses
[C_OMP_CLAUSE_SPLIT_MASKED
]);
20064 OMP_MASKED_COMBINED (ret
) = 1;
20068 if (!flag_openmp
) /* flag_openmp_simd */
20070 c_parser_skip_to_pragma_eol (parser
, false);
20074 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
20077 omp_split_clauses (loc
, OMP_MASKED
, mask
, clauses
, cclauses
);
20078 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_MASKED
];
20081 return c_finish_omp_masked (loc
, c_parser_omp_structured_block (parser
,
20087 # pragma omp ordered new-line
20091 # pragma omp ordered ordered-clauses new-line
20094 # pragma omp ordered depend-clauses new-line */
20096 #define OMP_ORDERED_CLAUSE_MASK \
20097 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREADS) \
20098 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMD))
20100 #define OMP_ORDERED_DEPEND_CLAUSE_MASK \
20101 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)
20104 c_parser_omp_ordered (c_parser
*parser
, enum pragma_context context
,
20107 location_t loc
= c_parser_peek_token (parser
)->location
;
20108 c_parser_consume_pragma (parser
);
20110 if (context
!= pragma_stmt
&& context
!= pragma_compound
)
20112 c_parser_error (parser
, "expected declaration specifiers");
20113 c_parser_skip_to_pragma_eol (parser
, false);
20117 if (c_parser_next_token_is (parser
, CPP_NAME
))
20119 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
20121 if (!strcmp ("depend", p
))
20123 if (!flag_openmp
) /* flag_openmp_simd */
20125 c_parser_skip_to_pragma_eol (parser
, false);
20128 if (context
== pragma_stmt
)
20131 "%<#pragma omp ordered%> with %<depend%> clause may "
20132 "only be used in compound statements");
20133 c_parser_skip_to_pragma_eol (parser
, false);
20138 = c_parser_omp_all_clauses (parser
,
20139 OMP_ORDERED_DEPEND_CLAUSE_MASK
,
20140 "#pragma omp ordered");
20141 c_finish_omp_ordered (loc
, clauses
, NULL_TREE
);
20146 tree clauses
= c_parser_omp_all_clauses (parser
, OMP_ORDERED_CLAUSE_MASK
,
20147 "#pragma omp ordered");
20149 if (!flag_openmp
/* flag_openmp_simd */
20150 && omp_find_clause (clauses
, OMP_CLAUSE_SIMD
) == NULL_TREE
)
20153 c_finish_omp_ordered (loc
, clauses
,
20154 c_parser_omp_structured_block (parser
, if_p
));
20161 { section-sequence }
20164 section-directive[opt] structured-block
20165 section-sequence section-directive structured-block
20167 OpenMP 5.1 allows structured-block-sequence instead of structured-block.
20169 SECTIONS_LOC is the location of the #pragma omp sections. */
20172 c_parser_omp_sections_scope (location_t sections_loc
, c_parser
*parser
)
20174 tree stmt
, substmt
;
20175 bool error_suppress
= false;
20178 loc
= c_parser_peek_token (parser
)->location
;
20179 if (!c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
20181 /* Avoid skipping until the end of the block. */
20182 parser
->error
= false;
20186 stmt
= push_stmt_list ();
20188 if (c_parser_peek_token (parser
)->pragma_kind
!= PRAGMA_OMP_SECTION
)
20190 substmt
= c_parser_omp_structured_block_sequence (parser
,
20191 PRAGMA_OMP_SECTION
);
20192 substmt
= build1 (OMP_SECTION
, void_type_node
, substmt
);
20193 SET_EXPR_LOCATION (substmt
, loc
);
20194 add_stmt (substmt
);
20199 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
20201 if (c_parser_next_token_is (parser
, CPP_EOF
))
20204 loc
= c_parser_peek_token (parser
)->location
;
20205 if (c_parser_peek_token (parser
)->pragma_kind
== PRAGMA_OMP_SECTION
)
20207 c_parser_consume_pragma (parser
);
20208 c_parser_skip_to_pragma_eol (parser
);
20209 error_suppress
= false;
20211 else if (!error_suppress
)
20213 error_at (loc
, "expected %<#pragma omp section%> or %<}%>");
20214 error_suppress
= true;
20217 substmt
= c_parser_omp_structured_block_sequence (parser
,
20218 PRAGMA_OMP_SECTION
);
20219 substmt
= build1 (OMP_SECTION
, void_type_node
, substmt
);
20220 SET_EXPR_LOCATION (substmt
, loc
);
20221 add_stmt (substmt
);
20223 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
,
20224 "expected %<#pragma omp section%> or %<}%>");
20226 substmt
= pop_stmt_list (stmt
);
20228 stmt
= make_node (OMP_SECTIONS
);
20229 SET_EXPR_LOCATION (stmt
, sections_loc
);
20230 TREE_TYPE (stmt
) = void_type_node
;
20231 OMP_SECTIONS_BODY (stmt
) = substmt
;
20233 return add_stmt (stmt
);
20237 # pragma omp sections sections-clause[optseq] newline
20240 LOC is the location of the #pragma token.
20243 #define OMP_SECTIONS_CLAUSE_MASK \
20244 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20245 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20246 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
20247 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
20248 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20249 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20252 c_parser_omp_sections (location_t loc
, c_parser
*parser
,
20253 char *p_name
, omp_clause_mask mask
, tree
*cclauses
)
20255 tree block
, clauses
, ret
;
20257 strcat (p_name
, " sections");
20258 mask
|= OMP_SECTIONS_CLAUSE_MASK
;
20260 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_NOWAIT
);
20262 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
20265 omp_split_clauses (loc
, OMP_SECTIONS
, mask
, clauses
, cclauses
);
20266 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_SECTIONS
];
20269 block
= c_begin_compound_stmt (true);
20270 ret
= c_parser_omp_sections_scope (loc
, parser
);
20272 OMP_SECTIONS_CLAUSES (ret
) = clauses
;
20273 block
= c_end_compound_stmt (loc
, block
, true);
20280 # pragma omp parallel parallel-clause[optseq] new-line
20282 # pragma omp parallel for parallel-for-clause[optseq] new-line
20284 # pragma omp parallel sections parallel-sections-clause[optseq] new-line
20288 # pragma omp parallel for simd parallel-for-simd-clause[optseq] new-line
20291 LOC is the location of the #pragma token.
20294 #define OMP_PARALLEL_CLAUSE_MASK \
20295 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
20296 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20297 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20298 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
20299 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
20300 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN) \
20301 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
20302 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS) \
20303 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20304 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PROC_BIND))
20307 c_parser_omp_parallel (location_t loc
, c_parser
*parser
,
20308 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
20311 tree stmt
, clauses
, block
;
20313 strcat (p_name
, " parallel");
20314 mask
|= OMP_PARALLEL_CLAUSE_MASK
;
20315 /* #pragma omp target parallel{, for, for simd} disallow copyin clause. */
20316 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_MAP
)) != 0
20317 && (mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
)) == 0)
20318 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_COPYIN
);
20320 if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
20322 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
20323 if (cclauses
== NULL
)
20324 cclauses
= cclauses_buf
;
20326 c_parser_consume_token (parser
);
20327 if (!flag_openmp
) /* flag_openmp_simd */
20328 return c_parser_omp_for (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
20329 block
= c_begin_omp_parallel ();
20330 tree ret
= c_parser_omp_for (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
20332 = c_finish_omp_parallel (loc
, cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
20334 if (ret
== NULL_TREE
)
20336 OMP_PARALLEL_COMBINED (stmt
) = 1;
20339 /* When combined with distribute, parallel has to be followed by for.
20340 #pragma omp target parallel is allowed though. */
20342 && (mask
& (OMP_CLAUSE_MASK_1
20343 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
)) != 0)
20345 error_at (loc
, "expected %<for%> after %qs", p_name
);
20346 c_parser_skip_to_pragma_eol (parser
);
20349 else if (c_parser_next_token_is (parser
, CPP_NAME
))
20351 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
20352 if (cclauses
== NULL
&& strcmp (p
, "masked") == 0)
20354 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
20355 cclauses
= cclauses_buf
;
20357 c_parser_consume_token (parser
);
20358 if (!flag_openmp
) /* flag_openmp_simd */
20359 return c_parser_omp_masked (loc
, parser
, p_name
, mask
, cclauses
,
20361 block
= c_begin_omp_parallel ();
20362 tree ret
= c_parser_omp_masked (loc
, parser
, p_name
, mask
, cclauses
,
20364 stmt
= c_finish_omp_parallel (loc
,
20365 cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
20369 /* masked does have just filter clause, but during gimplification
20370 isn't represented by a gimplification omp context, so for
20371 #pragma omp parallel masked don't set OMP_PARALLEL_COMBINED,
20373 #pragma omp parallel masked
20374 #pragma omp taskloop simd lastprivate (x)
20375 isn't confused with
20376 #pragma omp parallel masked taskloop simd lastprivate (x) */
20377 if (OMP_MASKED_COMBINED (ret
))
20378 OMP_PARALLEL_COMBINED (stmt
) = 1;
20381 else if (cclauses
== NULL
&& strcmp (p
, "master") == 0)
20383 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
20384 cclauses
= cclauses_buf
;
20386 c_parser_consume_token (parser
);
20387 if (!flag_openmp
) /* flag_openmp_simd */
20388 return c_parser_omp_master (loc
, parser
, p_name
, mask
, cclauses
,
20390 block
= c_begin_omp_parallel ();
20391 tree ret
= c_parser_omp_master (loc
, parser
, p_name
, mask
, cclauses
,
20393 stmt
= c_finish_omp_parallel (loc
,
20394 cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
20398 /* master doesn't have any clauses and during gimplification
20399 isn't represented by a gimplification omp context, so for
20400 #pragma omp parallel master don't set OMP_PARALLEL_COMBINED,
20402 #pragma omp parallel master
20403 #pragma omp taskloop simd lastprivate (x)
20404 isn't confused with
20405 #pragma omp parallel master taskloop simd lastprivate (x) */
20406 if (OMP_MASTER_COMBINED (ret
))
20407 OMP_PARALLEL_COMBINED (stmt
) = 1;
20410 else if (strcmp (p
, "loop") == 0)
20412 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
20413 if (cclauses
== NULL
)
20414 cclauses
= cclauses_buf
;
20416 c_parser_consume_token (parser
);
20417 if (!flag_openmp
) /* flag_openmp_simd */
20418 return c_parser_omp_loop (loc
, parser
, p_name
, mask
, cclauses
,
20420 block
= c_begin_omp_parallel ();
20421 tree ret
= c_parser_omp_loop (loc
, parser
, p_name
, mask
, cclauses
,
20424 = c_finish_omp_parallel (loc
,
20425 cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
20427 if (ret
== NULL_TREE
)
20429 OMP_PARALLEL_COMBINED (stmt
) = 1;
20432 else if (!flag_openmp
) /* flag_openmp_simd */
20434 c_parser_skip_to_pragma_eol (parser
, false);
20437 else if (cclauses
== NULL
&& strcmp (p
, "sections") == 0)
20439 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
20440 cclauses
= cclauses_buf
;
20442 c_parser_consume_token (parser
);
20443 block
= c_begin_omp_parallel ();
20444 c_parser_omp_sections (loc
, parser
, p_name
, mask
, cclauses
);
20445 stmt
= c_finish_omp_parallel (loc
,
20446 cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
20448 OMP_PARALLEL_COMBINED (stmt
) = 1;
20452 else if (!flag_openmp
) /* flag_openmp_simd */
20454 c_parser_skip_to_pragma_eol (parser
, false);
20458 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
20461 omp_split_clauses (loc
, OMP_PARALLEL
, mask
, clauses
, cclauses
);
20462 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
];
20465 block
= c_begin_omp_parallel ();
20466 c_parser_statement (parser
, if_p
);
20467 stmt
= c_finish_omp_parallel (loc
, clauses
, block
);
20473 # pragma omp single single-clause[optseq] new-line
20476 LOC is the location of the #pragma.
20479 #define OMP_SINGLE_CLAUSE_MASK \
20480 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20481 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20482 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYPRIVATE) \
20483 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20484 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20487 c_parser_omp_single (location_t loc
, c_parser
*parser
, bool *if_p
)
20489 tree stmt
= make_node (OMP_SINGLE
);
20490 SET_EXPR_LOCATION (stmt
, loc
);
20491 TREE_TYPE (stmt
) = void_type_node
;
20493 OMP_SINGLE_CLAUSES (stmt
)
20494 = c_parser_omp_all_clauses (parser
, OMP_SINGLE_CLAUSE_MASK
,
20495 "#pragma omp single");
20496 OMP_SINGLE_BODY (stmt
) = c_parser_omp_structured_block (parser
, if_p
);
20498 return add_stmt (stmt
);
20502 # pragma omp scope scope-clause[optseq] new-line
20505 LOC is the location of the #pragma.
20508 #define OMP_SCOPE_CLAUSE_MASK \
20509 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20510 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20511 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
20512 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20513 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20516 c_parser_omp_scope (location_t loc
, c_parser
*parser
, bool *if_p
)
20518 tree stmt
= make_node (OMP_SCOPE
);
20519 SET_EXPR_LOCATION (stmt
, loc
);
20520 TREE_TYPE (stmt
) = void_type_node
;
20522 OMP_SCOPE_CLAUSES (stmt
)
20523 = c_parser_omp_all_clauses (parser
, OMP_SCOPE_CLAUSE_MASK
,
20524 "#pragma omp scope");
20525 OMP_SCOPE_BODY (stmt
) = c_parser_omp_structured_block (parser
, if_p
);
20527 return add_stmt (stmt
);
20531 # pragma omp task task-clause[optseq] new-line
20533 LOC is the location of the #pragma.
20536 #define OMP_TASK_CLAUSE_MASK \
20537 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
20538 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
20539 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
20540 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20541 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20542 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
20543 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
20544 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
20545 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
20546 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
20547 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20548 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION) \
20549 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DETACH) \
20550 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_AFFINITY))
20553 c_parser_omp_task (location_t loc
, c_parser
*parser
, bool *if_p
)
20555 tree clauses
, block
;
20557 clauses
= c_parser_omp_all_clauses (parser
, OMP_TASK_CLAUSE_MASK
,
20558 "#pragma omp task");
20560 block
= c_begin_omp_task ();
20561 c_parser_statement (parser
, if_p
);
20562 return c_finish_omp_task (loc
, clauses
, block
);
20566 # pragma omp taskwait new-line
20569 # pragma omp taskwait taskwait-clause[optseq] new-line
20572 #define OMP_TASKWAIT_CLAUSE_MASK \
20573 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
20574 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20577 c_parser_omp_taskwait (c_parser
*parser
)
20579 location_t loc
= c_parser_peek_token (parser
)->location
;
20580 c_parser_consume_pragma (parser
);
20583 = c_parser_omp_all_clauses (parser
, OMP_TASKWAIT_CLAUSE_MASK
,
20584 "#pragma omp taskwait");
20588 tree stmt
= make_node (OMP_TASK
);
20589 TREE_TYPE (stmt
) = void_node
;
20590 OMP_TASK_CLAUSES (stmt
) = clauses
;
20591 OMP_TASK_BODY (stmt
) = NULL_TREE
;
20592 SET_EXPR_LOCATION (stmt
, loc
);
20596 c_finish_omp_taskwait (loc
);
20600 # pragma omp taskyield new-line
20604 c_parser_omp_taskyield (c_parser
*parser
)
20606 location_t loc
= c_parser_peek_token (parser
)->location
;
20607 c_parser_consume_pragma (parser
);
20608 c_parser_skip_to_pragma_eol (parser
);
20610 c_finish_omp_taskyield (loc
);
20614 # pragma omp taskgroup new-line
20617 # pragma omp taskgroup taskgroup-clause[optseq] new-line
20620 #define OMP_TASKGROUP_CLAUSE_MASK \
20621 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20622 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASK_REDUCTION))
20625 c_parser_omp_taskgroup (location_t loc
, c_parser
*parser
, bool *if_p
)
20627 tree clauses
= c_parser_omp_all_clauses (parser
, OMP_TASKGROUP_CLAUSE_MASK
,
20628 "#pragma omp taskgroup");
20630 tree body
= c_parser_omp_structured_block (parser
, if_p
);
20631 return c_finish_omp_taskgroup (loc
, body
, clauses
);
20635 # pragma omp cancel cancel-clause[optseq] new-line
20637 LOC is the location of the #pragma.
20640 #define OMP_CANCEL_CLAUSE_MASK \
20641 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
20642 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
20643 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
20644 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP) \
20645 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF))
20648 c_parser_omp_cancel (c_parser
*parser
)
20650 location_t loc
= c_parser_peek_token (parser
)->location
;
20652 c_parser_consume_pragma (parser
);
20653 tree clauses
= c_parser_omp_all_clauses (parser
, OMP_CANCEL_CLAUSE_MASK
,
20654 "#pragma omp cancel");
20656 c_finish_omp_cancel (loc
, clauses
);
20660 # pragma omp cancellation point cancelpt-clause[optseq] new-line
20662 LOC is the location of the #pragma.
20665 #define OMP_CANCELLATION_POINT_CLAUSE_MASK \
20666 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
20667 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
20668 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
20669 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP))
20672 c_parser_omp_cancellation_point (c_parser
*parser
, enum pragma_context context
)
20674 location_t loc
= c_parser_peek_token (parser
)->location
;
20676 bool point_seen
= false;
20678 c_parser_consume_pragma (parser
);
20679 if (c_parser_next_token_is (parser
, CPP_NAME
))
20681 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
20682 if (strcmp (p
, "point") == 0)
20684 c_parser_consume_token (parser
);
20690 c_parser_error (parser
, "expected %<point%>");
20691 c_parser_skip_to_pragma_eol (parser
);
20695 if (context
!= pragma_compound
)
20697 if (context
== pragma_stmt
)
20699 "%<#pragma %s%> may only be used in compound statements",
20700 "omp cancellation point");
20702 c_parser_error (parser
, "expected declaration specifiers");
20703 c_parser_skip_to_pragma_eol (parser
, false);
20708 = c_parser_omp_all_clauses (parser
, OMP_CANCELLATION_POINT_CLAUSE_MASK
,
20709 "#pragma omp cancellation point");
20711 c_finish_omp_cancellation_point (loc
, clauses
);
20716 #pragma omp distribute distribute-clause[optseq] new-line
20719 #define OMP_DISTRIBUTE_CLAUSE_MASK \
20720 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20721 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20722 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
20723 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)\
20724 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20725 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
20726 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
20729 c_parser_omp_distribute (location_t loc
, c_parser
*parser
,
20730 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
20733 tree clauses
, block
, ret
;
20735 strcat (p_name
, " distribute");
20736 mask
|= OMP_DISTRIBUTE_CLAUSE_MASK
;
20738 if (c_parser_next_token_is (parser
, CPP_NAME
))
20740 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
20742 bool parallel
= false;
20744 if (strcmp (p
, "simd") == 0)
20747 parallel
= strcmp (p
, "parallel") == 0;
20748 if (parallel
|| simd
)
20750 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
20751 if (cclauses
== NULL
)
20752 cclauses
= cclauses_buf
;
20753 c_parser_consume_token (parser
);
20754 if (!flag_openmp
) /* flag_openmp_simd */
20757 return c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
,
20760 return c_parser_omp_parallel (loc
, parser
, p_name
, mask
,
20763 block
= c_begin_compound_stmt (true);
20765 ret
= c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
,
20768 ret
= c_parser_omp_parallel (loc
, parser
, p_name
, mask
, cclauses
,
20770 block
= c_end_compound_stmt (loc
, block
, true);
20773 ret
= make_node (OMP_DISTRIBUTE
);
20774 TREE_TYPE (ret
) = void_type_node
;
20775 OMP_FOR_BODY (ret
) = block
;
20776 OMP_FOR_CLAUSES (ret
) = cclauses
[C_OMP_CLAUSE_SPLIT_DISTRIBUTE
];
20777 SET_EXPR_LOCATION (ret
, loc
);
20782 if (!flag_openmp
) /* flag_openmp_simd */
20784 c_parser_skip_to_pragma_eol (parser
, false);
20788 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
20791 omp_split_clauses (loc
, OMP_DISTRIBUTE
, mask
, clauses
, cclauses
);
20792 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_DISTRIBUTE
];
20795 block
= c_begin_compound_stmt (true);
20796 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_DISTRIBUTE
, clauses
, NULL
,
20798 block
= c_end_compound_stmt (loc
, block
, true);
20805 # pragma omp teams teams-clause[optseq] new-line
20806 structured-block */
20808 #define OMP_TEAMS_CLAUSE_MASK \
20809 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20810 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20811 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
20812 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
20813 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS) \
20814 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \
20815 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20816 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT))
20819 c_parser_omp_teams (location_t loc
, c_parser
*parser
,
20820 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
20823 tree clauses
, block
, ret
;
20825 strcat (p_name
, " teams");
20826 mask
|= OMP_TEAMS_CLAUSE_MASK
;
20828 if (c_parser_next_token_is (parser
, CPP_NAME
))
20830 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
20831 if (strcmp (p
, "distribute") == 0)
20833 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
20834 if (cclauses
== NULL
)
20835 cclauses
= cclauses_buf
;
20837 c_parser_consume_token (parser
);
20838 if (!flag_openmp
) /* flag_openmp_simd */
20839 return c_parser_omp_distribute (loc
, parser
, p_name
, mask
,
20841 block
= c_begin_omp_parallel ();
20842 ret
= c_parser_omp_distribute (loc
, parser
, p_name
, mask
, cclauses
,
20844 block
= c_end_compound_stmt (loc
, block
, true);
20847 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_TEAMS
];
20848 ret
= make_node (OMP_TEAMS
);
20849 TREE_TYPE (ret
) = void_type_node
;
20850 OMP_TEAMS_CLAUSES (ret
) = clauses
;
20851 OMP_TEAMS_BODY (ret
) = block
;
20852 OMP_TEAMS_COMBINED (ret
) = 1;
20853 SET_EXPR_LOCATION (ret
, loc
);
20854 return add_stmt (ret
);
20856 else if (strcmp (p
, "loop") == 0)
20858 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
20859 if (cclauses
== NULL
)
20860 cclauses
= cclauses_buf
;
20862 c_parser_consume_token (parser
);
20863 if (!flag_openmp
) /* flag_openmp_simd */
20864 return c_parser_omp_loop (loc
, parser
, p_name
, mask
, cclauses
,
20866 block
= c_begin_omp_parallel ();
20867 ret
= c_parser_omp_loop (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
20868 block
= c_end_compound_stmt (loc
, block
, true);
20871 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_TEAMS
];
20872 ret
= make_node (OMP_TEAMS
);
20873 TREE_TYPE (ret
) = void_type_node
;
20874 OMP_TEAMS_CLAUSES (ret
) = clauses
;
20875 OMP_TEAMS_BODY (ret
) = block
;
20876 OMP_TEAMS_COMBINED (ret
) = 1;
20877 SET_EXPR_LOCATION (ret
, loc
);
20878 return add_stmt (ret
);
20881 if (!flag_openmp
) /* flag_openmp_simd */
20883 c_parser_skip_to_pragma_eol (parser
, false);
20887 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
20890 omp_split_clauses (loc
, OMP_TEAMS
, mask
, clauses
, cclauses
);
20891 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_TEAMS
];
20894 tree stmt
= make_node (OMP_TEAMS
);
20895 TREE_TYPE (stmt
) = void_type_node
;
20896 OMP_TEAMS_CLAUSES (stmt
) = clauses
;
20897 block
= c_begin_omp_parallel ();
20898 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
20899 OMP_TEAMS_BODY (stmt
) = c_end_compound_stmt (loc
, block
, true);
20900 SET_EXPR_LOCATION (stmt
, loc
);
20902 return add_stmt (stmt
);
20906 # pragma omp target data target-data-clause[optseq] new-line
20907 structured-block */
20909 #define OMP_TARGET_DATA_CLAUSE_MASK \
20910 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
20911 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
20912 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
20913 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR) \
20914 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR))
20917 c_parser_omp_target_data (location_t loc
, c_parser
*parser
, bool *if_p
)
20921 = (enum omp_requires
) (omp_requires_mask
| OMP_REQUIRES_TARGET_USED
);
20924 = c_parser_omp_all_clauses (parser
, OMP_TARGET_DATA_CLAUSE_MASK
,
20925 "#pragma omp target data");
20926 c_omp_adjust_map_clauses (clauses
, false);
20928 for (tree
*pc
= &clauses
; *pc
;)
20930 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_MAP
)
20931 switch (OMP_CLAUSE_MAP_KIND (*pc
))
20934 case GOMP_MAP_ALWAYS_TO
:
20935 case GOMP_MAP_FROM
:
20936 case GOMP_MAP_ALWAYS_FROM
:
20937 case GOMP_MAP_TOFROM
:
20938 case GOMP_MAP_ALWAYS_TOFROM
:
20939 case GOMP_MAP_ALLOC
:
20942 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
20943 case GOMP_MAP_ALWAYS_POINTER
:
20944 case GOMP_MAP_ATTACH_DETACH
:
20948 error_at (OMP_CLAUSE_LOCATION (*pc
),
20949 "%<#pragma omp target data%> with map-type other "
20950 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
20951 "on %<map%> clause");
20952 *pc
= OMP_CLAUSE_CHAIN (*pc
);
20955 else if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_USE_DEVICE_PTR
20956 || OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_USE_DEVICE_ADDR
)
20958 pc
= &OMP_CLAUSE_CHAIN (*pc
);
20965 "%<#pragma omp target data%> must contain at least "
20966 "one %<map%>, %<use_device_ptr%> or %<use_device_addr%> "
20971 tree stmt
= make_node (OMP_TARGET_DATA
);
20972 TREE_TYPE (stmt
) = void_type_node
;
20973 OMP_TARGET_DATA_CLAUSES (stmt
) = clauses
;
20974 keep_next_level ();
20975 tree block
= c_begin_compound_stmt (true);
20976 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
20977 OMP_TARGET_DATA_BODY (stmt
) = c_end_compound_stmt (loc
, block
, true);
20979 SET_EXPR_LOCATION (stmt
, loc
);
20980 return add_stmt (stmt
);
20984 # pragma omp target update target-update-clause[optseq] new-line */
20986 #define OMP_TARGET_UPDATE_CLAUSE_MASK \
20987 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FROM) \
20988 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
20989 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
20990 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
20991 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
20992 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20995 c_parser_omp_target_update (location_t loc
, c_parser
*parser
,
20996 enum pragma_context context
)
20998 if (context
== pragma_stmt
)
21000 error_at (loc
, "%<#pragma %s%> may only be used in compound statements",
21001 "omp target update");
21002 c_parser_skip_to_pragma_eol (parser
, false);
21007 = c_parser_omp_all_clauses (parser
, OMP_TARGET_UPDATE_CLAUSE_MASK
,
21008 "#pragma omp target update");
21009 if (omp_find_clause (clauses
, OMP_CLAUSE_TO
) == NULL_TREE
21010 && omp_find_clause (clauses
, OMP_CLAUSE_FROM
) == NULL_TREE
)
21013 "%<#pragma omp target update%> must contain at least one "
21014 "%<from%> or %<to%> clauses");
21020 = (enum omp_requires
) (omp_requires_mask
| OMP_REQUIRES_TARGET_USED
);
21022 tree stmt
= make_node (OMP_TARGET_UPDATE
);
21023 TREE_TYPE (stmt
) = void_type_node
;
21024 OMP_TARGET_UPDATE_CLAUSES (stmt
) = clauses
;
21025 SET_EXPR_LOCATION (stmt
, loc
);
21031 # pragma omp target enter data target-data-clause[optseq] new-line */
21033 #define OMP_TARGET_ENTER_DATA_CLAUSE_MASK \
21034 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
21035 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
21036 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
21037 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
21038 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
21041 c_parser_omp_target_enter_data (location_t loc
, c_parser
*parser
,
21042 enum pragma_context context
)
21044 bool data_seen
= false;
21045 if (c_parser_next_token_is (parser
, CPP_NAME
))
21047 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
21048 if (strcmp (p
, "data") == 0)
21050 c_parser_consume_token (parser
);
21056 c_parser_error (parser
, "expected %<data%>");
21057 c_parser_skip_to_pragma_eol (parser
);
21061 if (context
== pragma_stmt
)
21063 error_at (loc
, "%<#pragma %s%> may only be used in compound statements",
21064 "omp target enter data");
21065 c_parser_skip_to_pragma_eol (parser
, false);
21071 = (enum omp_requires
) (omp_requires_mask
| OMP_REQUIRES_TARGET_USED
);
21074 = c_parser_omp_all_clauses (parser
, OMP_TARGET_ENTER_DATA_CLAUSE_MASK
,
21075 "#pragma omp target enter data");
21076 c_omp_adjust_map_clauses (clauses
, false);
21078 for (tree
*pc
= &clauses
; *pc
;)
21080 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_MAP
)
21081 switch (OMP_CLAUSE_MAP_KIND (*pc
))
21084 case GOMP_MAP_ALWAYS_TO
:
21085 case GOMP_MAP_ALLOC
:
21088 case GOMP_MAP_TOFROM
:
21089 OMP_CLAUSE_SET_MAP_KIND (*pc
, GOMP_MAP_TO
);
21092 case GOMP_MAP_ALWAYS_TOFROM
:
21093 OMP_CLAUSE_SET_MAP_KIND (*pc
, GOMP_MAP_ALWAYS_TO
);
21096 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
21097 case GOMP_MAP_ALWAYS_POINTER
:
21098 case GOMP_MAP_ATTACH_DETACH
:
21102 error_at (OMP_CLAUSE_LOCATION (*pc
),
21103 "%<#pragma omp target enter data%> with map-type other "
21104 "than %<to%>, %<tofrom%> or %<alloc%> on %<map%> clause");
21105 *pc
= OMP_CLAUSE_CHAIN (*pc
);
21108 pc
= &OMP_CLAUSE_CHAIN (*pc
);
21115 "%<#pragma omp target enter data%> must contain at least "
21116 "one %<map%> clause");
21120 tree stmt
= make_node (OMP_TARGET_ENTER_DATA
);
21121 TREE_TYPE (stmt
) = void_type_node
;
21122 OMP_TARGET_ENTER_DATA_CLAUSES (stmt
) = clauses
;
21123 SET_EXPR_LOCATION (stmt
, loc
);
21129 # pragma omp target exit data target-data-clause[optseq] new-line */
21131 #define OMP_TARGET_EXIT_DATA_CLAUSE_MASK \
21132 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
21133 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
21134 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
21135 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
21136 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
21139 c_parser_omp_target_exit_data (location_t loc
, c_parser
*parser
,
21140 enum pragma_context context
)
21142 bool data_seen
= false;
21143 if (c_parser_next_token_is (parser
, CPP_NAME
))
21145 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
21146 if (strcmp (p
, "data") == 0)
21148 c_parser_consume_token (parser
);
21154 c_parser_error (parser
, "expected %<data%>");
21155 c_parser_skip_to_pragma_eol (parser
);
21159 if (context
== pragma_stmt
)
21161 error_at (loc
, "%<#pragma %s%> may only be used in compound statements",
21162 "omp target exit data");
21163 c_parser_skip_to_pragma_eol (parser
, false);
21169 = (enum omp_requires
) (omp_requires_mask
| OMP_REQUIRES_TARGET_USED
);
21172 = c_parser_omp_all_clauses (parser
, OMP_TARGET_EXIT_DATA_CLAUSE_MASK
,
21173 "#pragma omp target exit data");
21174 c_omp_adjust_map_clauses (clauses
, false);
21176 for (tree
*pc
= &clauses
; *pc
;)
21178 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_MAP
)
21179 switch (OMP_CLAUSE_MAP_KIND (*pc
))
21181 case GOMP_MAP_FROM
:
21182 case GOMP_MAP_ALWAYS_FROM
:
21183 case GOMP_MAP_RELEASE
:
21184 case GOMP_MAP_DELETE
:
21187 case GOMP_MAP_TOFROM
:
21188 OMP_CLAUSE_SET_MAP_KIND (*pc
, GOMP_MAP_FROM
);
21191 case GOMP_MAP_ALWAYS_TOFROM
:
21192 OMP_CLAUSE_SET_MAP_KIND (*pc
, GOMP_MAP_ALWAYS_FROM
);
21195 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
21196 case GOMP_MAP_ALWAYS_POINTER
:
21197 case GOMP_MAP_ATTACH_DETACH
:
21201 error_at (OMP_CLAUSE_LOCATION (*pc
),
21202 "%<#pragma omp target exit data%> with map-type other "
21203 "than %<from%>, %<tofrom%>, %<release%> or %<delete%> "
21204 "on %<map%> clause");
21205 *pc
= OMP_CLAUSE_CHAIN (*pc
);
21208 pc
= &OMP_CLAUSE_CHAIN (*pc
);
21215 "%<#pragma omp target exit data%> must contain at least one "
21220 tree stmt
= make_node (OMP_TARGET_EXIT_DATA
);
21221 TREE_TYPE (stmt
) = void_type_node
;
21222 OMP_TARGET_EXIT_DATA_CLAUSES (stmt
) = clauses
;
21223 SET_EXPR_LOCATION (stmt
, loc
);
21229 # pragma omp target target-clause[optseq] new-line
21230 structured-block */
21232 #define OMP_TARGET_CLAUSE_MASK \
21233 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
21234 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
21235 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
21236 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
21237 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
21238 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
21239 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
21240 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
21241 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULTMAP) \
21242 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION) \
21243 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \
21244 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR)\
21245 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR))
21248 c_parser_omp_target (c_parser
*parser
, enum pragma_context context
, bool *if_p
)
21250 location_t loc
= c_parser_peek_token (parser
)->location
;
21251 c_parser_consume_pragma (parser
);
21252 tree
*pc
= NULL
, stmt
, block
;
21254 if (context
!= pragma_stmt
&& context
!= pragma_compound
)
21256 c_parser_error (parser
, "expected declaration specifiers");
21257 c_parser_skip_to_pragma_eol (parser
);
21263 = (enum omp_requires
) (omp_requires_mask
| OMP_REQUIRES_TARGET_USED
);
21265 if (c_parser_next_token_is (parser
, CPP_NAME
))
21267 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
21268 enum tree_code ccode
= ERROR_MARK
;
21270 if (strcmp (p
, "teams") == 0)
21272 else if (strcmp (p
, "parallel") == 0)
21273 ccode
= OMP_PARALLEL
;
21274 else if (strcmp (p
, "simd") == 0)
21276 if (ccode
!= ERROR_MARK
)
21278 tree cclauses
[C_OMP_CLAUSE_SPLIT_COUNT
];
21279 char p_name
[sizeof ("#pragma omp target teams distribute "
21280 "parallel for simd")];
21282 c_parser_consume_token (parser
);
21283 strcpy (p_name
, "#pragma omp target");
21284 if (!flag_openmp
) /* flag_openmp_simd */
21290 stmt
= c_parser_omp_teams (loc
, parser
, p_name
,
21291 OMP_TARGET_CLAUSE_MASK
,
21295 stmt
= c_parser_omp_parallel (loc
, parser
, p_name
,
21296 OMP_TARGET_CLAUSE_MASK
,
21300 stmt
= c_parser_omp_simd (loc
, parser
, p_name
,
21301 OMP_TARGET_CLAUSE_MASK
,
21305 gcc_unreachable ();
21307 return stmt
!= NULL_TREE
;
21309 keep_next_level ();
21310 tree block
= c_begin_compound_stmt (true), ret
;
21314 ret
= c_parser_omp_teams (loc
, parser
, p_name
,
21315 OMP_TARGET_CLAUSE_MASK
, cclauses
,
21319 ret
= c_parser_omp_parallel (loc
, parser
, p_name
,
21320 OMP_TARGET_CLAUSE_MASK
, cclauses
,
21324 ret
= c_parser_omp_simd (loc
, parser
, p_name
,
21325 OMP_TARGET_CLAUSE_MASK
, cclauses
,
21329 gcc_unreachable ();
21331 block
= c_end_compound_stmt (loc
, block
, true);
21332 if (ret
== NULL_TREE
)
21334 if (ccode
== OMP_TEAMS
)
21335 /* For combined target teams, ensure the num_teams and
21336 thread_limit clause expressions are evaluated on the host,
21337 before entering the target construct. */
21338 for (tree c
= cclauses
[C_OMP_CLAUSE_SPLIT_TEAMS
];
21339 c
; c
= OMP_CLAUSE_CHAIN (c
))
21340 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_NUM_TEAMS
21341 || OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_THREAD_LIMIT
)
21343 i
<= (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_NUM_TEAMS
); ++i
)
21344 if (OMP_CLAUSE_OPERAND (c
, i
)
21345 && TREE_CODE (OMP_CLAUSE_OPERAND (c
, i
)) != INTEGER_CST
)
21347 tree expr
= OMP_CLAUSE_OPERAND (c
, i
);
21348 tree tmp
= create_tmp_var_raw (TREE_TYPE (expr
));
21349 expr
= build4 (TARGET_EXPR
, TREE_TYPE (expr
), tmp
,
21350 expr
, NULL_TREE
, NULL_TREE
);
21352 OMP_CLAUSE_OPERAND (c
, i
) = expr
;
21353 tree tc
= build_omp_clause (OMP_CLAUSE_LOCATION (c
),
21354 OMP_CLAUSE_FIRSTPRIVATE
);
21355 OMP_CLAUSE_DECL (tc
) = tmp
;
21356 OMP_CLAUSE_CHAIN (tc
)
21357 = cclauses
[C_OMP_CLAUSE_SPLIT_TARGET
];
21358 cclauses
[C_OMP_CLAUSE_SPLIT_TARGET
] = tc
;
21360 tree stmt
= make_node (OMP_TARGET
);
21361 TREE_TYPE (stmt
) = void_type_node
;
21362 OMP_TARGET_CLAUSES (stmt
) = cclauses
[C_OMP_CLAUSE_SPLIT_TARGET
];
21363 c_omp_adjust_map_clauses (OMP_TARGET_CLAUSES (stmt
), true);
21364 OMP_TARGET_BODY (stmt
) = block
;
21365 OMP_TARGET_COMBINED (stmt
) = 1;
21366 SET_EXPR_LOCATION (stmt
, loc
);
21368 pc
= &OMP_TARGET_CLAUSES (stmt
);
21369 goto check_clauses
;
21371 else if (!flag_openmp
) /* flag_openmp_simd */
21373 c_parser_skip_to_pragma_eol (parser
, false);
21376 else if (strcmp (p
, "data") == 0)
21378 c_parser_consume_token (parser
);
21379 c_parser_omp_target_data (loc
, parser
, if_p
);
21382 else if (strcmp (p
, "enter") == 0)
21384 c_parser_consume_token (parser
);
21385 return c_parser_omp_target_enter_data (loc
, parser
, context
);
21387 else if (strcmp (p
, "exit") == 0)
21389 c_parser_consume_token (parser
);
21390 return c_parser_omp_target_exit_data (loc
, parser
, context
);
21392 else if (strcmp (p
, "update") == 0)
21394 c_parser_consume_token (parser
);
21395 return c_parser_omp_target_update (loc
, parser
, context
);
21398 if (!flag_openmp
) /* flag_openmp_simd */
21400 c_parser_skip_to_pragma_eol (parser
, false);
21404 stmt
= make_node (OMP_TARGET
);
21405 TREE_TYPE (stmt
) = void_type_node
;
21407 OMP_TARGET_CLAUSES (stmt
)
21408 = c_parser_omp_all_clauses (parser
, OMP_TARGET_CLAUSE_MASK
,
21409 "#pragma omp target", false);
21410 for (tree c
= OMP_TARGET_CLAUSES (stmt
); c
; c
= OMP_CLAUSE_CHAIN (c
))
21411 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_IN_REDUCTION
)
21413 tree nc
= build_omp_clause (OMP_CLAUSE_LOCATION (c
), OMP_CLAUSE_MAP
);
21414 OMP_CLAUSE_DECL (nc
) = OMP_CLAUSE_DECL (c
);
21415 OMP_CLAUSE_SET_MAP_KIND (nc
, GOMP_MAP_ALWAYS_TOFROM
);
21416 OMP_CLAUSE_CHAIN (nc
) = OMP_CLAUSE_CHAIN (c
);
21417 OMP_CLAUSE_CHAIN (c
) = nc
;
21419 OMP_TARGET_CLAUSES (stmt
)
21420 = c_finish_omp_clauses (OMP_TARGET_CLAUSES (stmt
), C_ORT_OMP_TARGET
);
21421 c_omp_adjust_map_clauses (OMP_TARGET_CLAUSES (stmt
), true);
21423 pc
= &OMP_TARGET_CLAUSES (stmt
);
21424 keep_next_level ();
21425 block
= c_begin_compound_stmt (true);
21426 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
21427 OMP_TARGET_BODY (stmt
) = c_end_compound_stmt (loc
, block
, true);
21429 SET_EXPR_LOCATION (stmt
, loc
);
21435 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_MAP
)
21436 switch (OMP_CLAUSE_MAP_KIND (*pc
))
21439 case GOMP_MAP_ALWAYS_TO
:
21440 case GOMP_MAP_FROM
:
21441 case GOMP_MAP_ALWAYS_FROM
:
21442 case GOMP_MAP_TOFROM
:
21443 case GOMP_MAP_ALWAYS_TOFROM
:
21444 case GOMP_MAP_ALLOC
:
21445 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
21446 case GOMP_MAP_ALWAYS_POINTER
:
21447 case GOMP_MAP_ATTACH_DETACH
:
21450 error_at (OMP_CLAUSE_LOCATION (*pc
),
21451 "%<#pragma omp target%> with map-type other "
21452 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
21453 "on %<map%> clause");
21454 *pc
= OMP_CLAUSE_CHAIN (*pc
);
21457 pc
= &OMP_CLAUSE_CHAIN (*pc
);
21459 cfun
->has_omp_target
= true;
21464 # pragma omp declare simd declare-simd-clauses[optseq] new-line
21467 # pragma omp declare variant (identifier) match(context-selector) new-line
21470 #define OMP_DECLARE_SIMD_CLAUSE_MASK \
21471 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
21472 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
21473 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
21474 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM) \
21475 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INBRANCH) \
21476 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOTINBRANCH))
21479 c_parser_omp_declare_simd (c_parser
*parser
, enum pragma_context context
)
21481 c_token
*token
= c_parser_peek_token (parser
);
21482 gcc_assert (token
->type
== CPP_NAME
);
21483 tree kind
= token
->value
;
21484 gcc_assert (strcmp (IDENTIFIER_POINTER (kind
), "simd") == 0
21485 || strcmp (IDENTIFIER_POINTER (kind
), "variant") == 0);
21487 auto_vec
<c_token
> clauses
;
21488 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
21490 c_token
*token
= c_parser_peek_token (parser
);
21491 if (token
->type
== CPP_EOF
)
21493 c_parser_skip_to_pragma_eol (parser
);
21496 clauses
.safe_push (*token
);
21497 c_parser_consume_token (parser
);
21499 clauses
.safe_push (*c_parser_peek_token (parser
));
21500 c_parser_skip_to_pragma_eol (parser
);
21502 while (c_parser_next_token_is (parser
, CPP_PRAGMA
))
21504 if (c_parser_peek_token (parser
)->pragma_kind
!= PRAGMA_OMP_DECLARE
21505 || c_parser_peek_2nd_token (parser
)->type
!= CPP_NAME
21506 || c_parser_peek_2nd_token (parser
)->value
!= kind
)
21508 error ("%<#pragma omp declare %s%> must be followed by "
21509 "function declaration or definition or another "
21510 "%<#pragma omp declare %s%>",
21511 IDENTIFIER_POINTER (kind
), IDENTIFIER_POINTER (kind
));
21514 c_parser_consume_pragma (parser
);
21515 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
21517 c_token
*token
= c_parser_peek_token (parser
);
21518 if (token
->type
== CPP_EOF
)
21520 c_parser_skip_to_pragma_eol (parser
);
21523 clauses
.safe_push (*token
);
21524 c_parser_consume_token (parser
);
21526 clauses
.safe_push (*c_parser_peek_token (parser
));
21527 c_parser_skip_to_pragma_eol (parser
);
21530 /* Make sure nothing tries to read past the end of the tokens. */
21532 memset (&eof_token
, 0, sizeof (eof_token
));
21533 eof_token
.type
= CPP_EOF
;
21534 clauses
.safe_push (eof_token
);
21535 clauses
.safe_push (eof_token
);
21539 case pragma_external
:
21540 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
21541 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
)
21543 int ext
= disable_extension_diagnostics ();
21545 c_parser_consume_token (parser
);
21546 while (c_parser_next_token_is (parser
, CPP_KEYWORD
)
21547 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
);
21548 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
21550 restore_extension_diagnostics (ext
);
21553 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
21556 case pragma_struct
:
21559 error ("%<#pragma omp declare %s%> must be followed by "
21560 "function declaration or definition",
21561 IDENTIFIER_POINTER (kind
));
21563 case pragma_compound
:
21564 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
21565 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
)
21567 int ext
= disable_extension_diagnostics ();
21569 c_parser_consume_token (parser
);
21570 while (c_parser_next_token_is (parser
, CPP_KEYWORD
)
21571 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
);
21572 if (c_parser_next_tokens_start_declaration (parser
))
21574 c_parser_declaration_or_fndef (parser
, true, true, true, true,
21575 true, NULL
, &clauses
);
21576 restore_extension_diagnostics (ext
);
21579 restore_extension_diagnostics (ext
);
21581 else if (c_parser_next_tokens_start_declaration (parser
))
21583 c_parser_declaration_or_fndef (parser
, true, true, true, true, true,
21587 error ("%<#pragma omp declare %s%> must be followed by "
21588 "function declaration or definition",
21589 IDENTIFIER_POINTER (kind
));
21592 gcc_unreachable ();
21596 static const char *const omp_construct_selectors
[] = {
21597 "simd", "target", "teams", "parallel", "for", NULL
};
21598 static const char *const omp_device_selectors
[] = {
21599 "kind", "isa", "arch", NULL
};
21600 static const char *const omp_implementation_selectors
[] = {
21601 "vendor", "extension", "atomic_default_mem_order", "unified_address",
21602 "unified_shared_memory", "dynamic_allocators", "reverse_offload", NULL
};
21603 static const char *const omp_user_selectors
[] = {
21604 "condition", NULL
};
21609 trait-selector-name[([trait-score:]trait-property[,trait-property[,...]])]
21612 score(score-expression) */
21615 c_parser_omp_context_selector (c_parser
*parser
, tree set
, tree parms
)
21617 tree ret
= NULL_TREE
;
21621 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
21622 || c_parser_next_token_is (parser
, CPP_NAME
))
21623 selector
= c_parser_peek_token (parser
)->value
;
21626 c_parser_error (parser
, "expected trait selector name");
21627 return error_mark_node
;
21630 tree properties
= NULL_TREE
;
21631 const char *const *selectors
= NULL
;
21632 bool allow_score
= true;
21633 bool allow_user
= false;
21634 int property_limit
= 0;
21635 enum { CTX_PROPERTY_NONE
, CTX_PROPERTY_USER
, CTX_PROPERTY_NAME_LIST
,
21636 CTX_PROPERTY_ID
, CTX_PROPERTY_EXPR
,
21637 CTX_PROPERTY_SIMD
} property_kind
= CTX_PROPERTY_NONE
;
21638 switch (IDENTIFIER_POINTER (set
)[0])
21640 case 'c': /* construct */
21641 selectors
= omp_construct_selectors
;
21642 allow_score
= false;
21643 property_limit
= 1;
21644 property_kind
= CTX_PROPERTY_SIMD
;
21646 case 'd': /* device */
21647 selectors
= omp_device_selectors
;
21648 allow_score
= false;
21650 property_limit
= 3;
21651 property_kind
= CTX_PROPERTY_NAME_LIST
;
21653 case 'i': /* implementation */
21654 selectors
= omp_implementation_selectors
;
21656 property_limit
= 3;
21657 property_kind
= CTX_PROPERTY_NAME_LIST
;
21659 case 'u': /* user */
21660 selectors
= omp_user_selectors
;
21661 property_limit
= 1;
21662 property_kind
= CTX_PROPERTY_EXPR
;
21665 gcc_unreachable ();
21667 for (int i
= 0; ; i
++)
21669 if (selectors
[i
] == NULL
)
21673 property_kind
= CTX_PROPERTY_USER
;
21678 error_at (c_parser_peek_token (parser
)->location
,
21679 "selector %qs not allowed for context selector "
21680 "set %qs", IDENTIFIER_POINTER (selector
),
21681 IDENTIFIER_POINTER (set
));
21682 c_parser_consume_token (parser
);
21683 return error_mark_node
;
21686 if (i
== property_limit
)
21687 property_kind
= CTX_PROPERTY_NONE
;
21688 if (strcmp (selectors
[i
], IDENTIFIER_POINTER (selector
)) == 0)
21691 if (property_kind
== CTX_PROPERTY_NAME_LIST
21692 && IDENTIFIER_POINTER (set
)[0] == 'i'
21693 && strcmp (IDENTIFIER_POINTER (selector
),
21694 "atomic_default_mem_order") == 0)
21695 property_kind
= CTX_PROPERTY_ID
;
21697 c_parser_consume_token (parser
);
21699 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
21701 if (property_kind
== CTX_PROPERTY_NONE
)
21703 error_at (c_parser_peek_token (parser
)->location
,
21704 "selector %qs does not accept any properties",
21705 IDENTIFIER_POINTER (selector
));
21706 return error_mark_node
;
21709 matching_parens parens
;
21710 parens
.require_open (parser
);
21712 c_token
*token
= c_parser_peek_token (parser
);
21714 && c_parser_next_token_is (parser
, CPP_NAME
)
21715 && strcmp (IDENTIFIER_POINTER (token
->value
), "score") == 0
21716 && c_parser_peek_2nd_token (parser
)->type
== CPP_OPEN_PAREN
)
21718 c_parser_consume_token (parser
);
21720 matching_parens parens2
;
21721 parens2
.require_open (parser
);
21722 tree score
= c_parser_expr_no_commas (parser
, NULL
).value
;
21723 parens2
.skip_until_found_close (parser
);
21724 c_parser_require (parser
, CPP_COLON
, "expected %<:%>");
21725 if (score
!= error_mark_node
)
21727 mark_exp_read (score
);
21728 score
= c_fully_fold (score
, false, NULL
);
21729 if (!INTEGRAL_TYPE_P (TREE_TYPE (score
))
21730 || TREE_CODE (score
) != INTEGER_CST
)
21731 error_at (token
->location
, "score argument must be "
21732 "constant integer expression");
21733 else if (tree_int_cst_sgn (score
) < 0)
21734 error_at (token
->location
, "score argument must be "
21737 properties
= tree_cons (get_identifier (" score"),
21738 score
, properties
);
21740 token
= c_parser_peek_token (parser
);
21743 switch (property_kind
)
21746 case CTX_PROPERTY_USER
:
21749 t
= c_parser_expr_no_commas (parser
, NULL
).value
;
21750 if (TREE_CODE (t
) == STRING_CST
)
21751 properties
= tree_cons (NULL_TREE
, t
, properties
);
21752 else if (t
!= error_mark_node
)
21755 t
= c_fully_fold (t
, false, NULL
);
21756 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
))
21757 || !tree_fits_shwi_p (t
))
21758 error_at (token
->location
, "property must be "
21759 "constant integer expression or string "
21762 properties
= tree_cons (NULL_TREE
, t
, properties
);
21765 return error_mark_node
;
21767 if (c_parser_next_token_is (parser
, CPP_COMMA
))
21768 c_parser_consume_token (parser
);
21774 case CTX_PROPERTY_ID
:
21775 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
21776 || c_parser_next_token_is (parser
, CPP_NAME
))
21778 tree prop
= c_parser_peek_token (parser
)->value
;
21779 c_parser_consume_token (parser
);
21780 properties
= tree_cons (prop
, NULL_TREE
, properties
);
21784 c_parser_error (parser
, "expected identifier");
21785 return error_mark_node
;
21788 case CTX_PROPERTY_NAME_LIST
:
21791 tree prop
= NULL_TREE
, value
= NULL_TREE
;
21792 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
21793 || c_parser_next_token_is (parser
, CPP_NAME
))
21795 prop
= c_parser_peek_token (parser
)->value
;
21796 c_parser_consume_token (parser
);
21798 else if (c_parser_next_token_is (parser
, CPP_STRING
))
21799 value
= c_parser_string_literal (parser
, false,
21803 c_parser_error (parser
, "expected identifier or "
21805 return error_mark_node
;
21808 properties
= tree_cons (prop
, value
, properties
);
21810 if (c_parser_next_token_is (parser
, CPP_COMMA
))
21811 c_parser_consume_token (parser
);
21817 case CTX_PROPERTY_EXPR
:
21818 t
= c_parser_expr_no_commas (parser
, NULL
).value
;
21819 if (t
!= error_mark_node
)
21822 t
= c_fully_fold (t
, false, NULL
);
21823 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
))
21824 || !tree_fits_shwi_p (t
))
21825 error_at (token
->location
, "property must be "
21826 "constant integer expression");
21828 properties
= tree_cons (NULL_TREE
, t
, properties
);
21831 return error_mark_node
;
21833 case CTX_PROPERTY_SIMD
:
21834 if (parms
== NULL_TREE
)
21836 error_at (token
->location
, "properties for %<simd%> "
21837 "selector may not be specified in "
21838 "%<metadirective%>");
21839 return error_mark_node
;
21842 c
= c_parser_omp_all_clauses (parser
,
21843 OMP_DECLARE_SIMD_CLAUSE_MASK
,
21845 c
= c_omp_declare_simd_clauses_to_numbers (parms
21847 ? NULL_TREE
: parms
,
21852 gcc_unreachable ();
21855 parens
.skip_until_found_close (parser
);
21856 properties
= nreverse (properties
);
21858 else if (property_kind
== CTX_PROPERTY_NAME_LIST
21859 || property_kind
== CTX_PROPERTY_ID
21860 || property_kind
== CTX_PROPERTY_EXPR
)
21862 c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>");
21863 return error_mark_node
;
21866 ret
= tree_cons (selector
, properties
, ret
);
21868 if (c_parser_next_token_is (parser
, CPP_COMMA
))
21869 c_parser_consume_token (parser
);
21875 return nreverse (ret
);
21880 trait-set-selector[,trait-set-selector[,...]]
21882 trait-set-selector:
21883 trait-set-selector-name = { trait-selector[, trait-selector[, ...]] }
21885 trait-set-selector-name:
21892 c_parser_omp_context_selector_specification (c_parser
*parser
, tree parms
)
21894 tree ret
= NULL_TREE
;
21897 const char *setp
= "";
21898 if (c_parser_next_token_is (parser
, CPP_NAME
))
21899 setp
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
21903 if (strcmp (setp
, "construct") == 0)
21907 if (strcmp (setp
, "device") == 0)
21911 if (strcmp (setp
, "implementation") == 0)
21915 if (strcmp (setp
, "user") == 0)
21923 c_parser_error (parser
, "expected %<construct%>, %<device%>, "
21924 "%<implementation%> or %<user%>");
21925 return error_mark_node
;
21928 tree set
= c_parser_peek_token (parser
)->value
;
21929 c_parser_consume_token (parser
);
21931 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
21932 return error_mark_node
;
21934 matching_braces braces
;
21935 if (!braces
.require_open (parser
))
21936 return error_mark_node
;
21938 tree selectors
= c_parser_omp_context_selector (parser
, set
, parms
);
21939 if (selectors
== error_mark_node
)
21940 ret
= error_mark_node
;
21941 else if (ret
!= error_mark_node
)
21942 ret
= tree_cons (set
, selectors
, ret
);
21944 braces
.skip_until_found_close (parser
);
21946 if (c_parser_next_token_is (parser
, CPP_COMMA
))
21947 c_parser_consume_token (parser
);
21953 if (ret
== error_mark_node
)
21955 return nreverse (ret
);
21958 /* Finalize #pragma omp declare variant after FNDECL has been parsed, and put
21959 that into "omp declare variant base" attribute. */
21962 c_finish_omp_declare_variant (c_parser
*parser
, tree fndecl
, tree parms
)
21964 matching_parens parens
;
21965 if (!parens
.require_open (parser
))
21968 c_parser_skip_to_pragma_eol (parser
, false);
21972 if (c_parser_next_token_is_not (parser
, CPP_NAME
)
21973 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
21975 c_parser_error (parser
, "expected identifier");
21979 c_token
*token
= c_parser_peek_token (parser
);
21980 tree variant
= lookup_name (token
->value
);
21982 if (variant
== NULL_TREE
)
21984 undeclared_variable (token
->location
, token
->value
);
21985 variant
= error_mark_node
;
21988 c_parser_consume_token (parser
);
21990 parens
.require_close (parser
);
21992 const char *clause
= "";
21993 location_t match_loc
= c_parser_peek_token (parser
)->location
;
21994 if (c_parser_next_token_is (parser
, CPP_NAME
))
21995 clause
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
21996 if (strcmp (clause
, "match"))
21998 c_parser_error (parser
, "expected %<match%>");
22002 c_parser_consume_token (parser
);
22004 if (!parens
.require_open (parser
))
22007 if (parms
== NULL_TREE
)
22008 parms
= error_mark_node
;
22010 tree ctx
= c_parser_omp_context_selector_specification (parser
, parms
);
22011 if (ctx
== error_mark_node
)
22013 ctx
= omp_check_context_selector (match_loc
, ctx
);
22014 if (ctx
!= error_mark_node
&& variant
!= error_mark_node
)
22016 if (TREE_CODE (variant
) != FUNCTION_DECL
)
22018 error_at (token
->location
, "variant %qD is not a function", variant
);
22019 variant
= error_mark_node
;
22021 else if (omp_get_context_selector (ctx
, "construct", "simd") == NULL_TREE
22022 && !comptypes (TREE_TYPE (fndecl
), TREE_TYPE (variant
)))
22024 error_at (token
->location
, "variant %qD and base %qD have "
22025 "incompatible types", variant
, fndecl
);
22026 variant
= error_mark_node
;
22028 else if (fndecl_built_in_p (variant
)
22029 && (strncmp (IDENTIFIER_POINTER (DECL_NAME (variant
)),
22030 "__builtin_", strlen ("__builtin_")) == 0
22031 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant
)),
22032 "__sync_", strlen ("__sync_")) == 0
22033 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant
)),
22034 "__atomic_", strlen ("__atomic_")) == 0))
22036 error_at (token
->location
, "variant %qD is a built-in", variant
);
22037 variant
= error_mark_node
;
22039 if (variant
!= error_mark_node
)
22041 C_DECL_USED (variant
) = 1;
22042 tree construct
= omp_get_context_selector (ctx
, "construct", NULL
);
22043 omp_mark_declare_variant (match_loc
, variant
, construct
);
22044 if (omp_context_selector_matches (ctx
))
22047 = tree_cons (get_identifier ("omp declare variant base"),
22048 build_tree_list (variant
, ctx
),
22049 DECL_ATTRIBUTES (fndecl
));
22050 DECL_ATTRIBUTES (fndecl
) = attr
;
22055 parens
.require_close (parser
);
22056 c_parser_skip_to_pragma_eol (parser
);
22059 /* Finalize #pragma omp declare simd or #pragma omp declare variant
22060 clauses after FNDECL has been parsed, and put that into "omp declare simd"
22061 or "omp declare variant base" attribute. */
22064 c_finish_omp_declare_simd (c_parser
*parser
, tree fndecl
, tree parms
,
22065 vec
<c_token
> *pclauses
)
22067 vec
<c_token
> &clauses
= *pclauses
;
22069 /* Normally first token is CPP_NAME "simd" or "variant". CPP_EOF there
22070 indicates error has been reported and CPP_PRAGMA that
22071 c_finish_omp_declare_simd has already processed the tokens. */
22072 if (clauses
.exists () && clauses
[0].type
== CPP_EOF
)
22074 const char *kind
= "simd";
22075 if (clauses
.exists ()
22076 && (clauses
[0].type
== CPP_NAME
|| clauses
[0].type
== CPP_PRAGMA
))
22077 kind
= IDENTIFIER_POINTER (clauses
[0].value
);
22078 gcc_assert (strcmp (kind
, "simd") == 0 || strcmp (kind
, "variant") == 0);
22079 if (fndecl
== NULL_TREE
|| TREE_CODE (fndecl
) != FUNCTION_DECL
)
22081 error ("%<#pragma omp declare %s%> not immediately followed by "
22082 "a function declaration or definition", kind
);
22083 clauses
[0].type
= CPP_EOF
;
22086 if (clauses
.exists () && clauses
[0].type
!= CPP_NAME
)
22088 error_at (DECL_SOURCE_LOCATION (fndecl
),
22089 "%<#pragma omp declare %s%> not immediately followed by "
22090 "a single function declaration or definition", kind
);
22091 clauses
[0].type
= CPP_EOF
;
22095 if (parms
== NULL_TREE
)
22096 parms
= DECL_ARGUMENTS (fndecl
);
22098 unsigned int tokens_avail
= parser
->tokens_avail
;
22099 gcc_assert (parser
->tokens
== &parser
->tokens_buf
[0]);
22101 parser
->tokens
= clauses
.address ();
22102 parser
->tokens_avail
= clauses
.length ();
22104 /* c_parser_omp_declare_simd pushed 2 extra CPP_EOF tokens at the end. */
22105 while (parser
->tokens_avail
> 3)
22107 c_token
*token
= c_parser_peek_token (parser
);
22108 gcc_assert (token
->type
== CPP_NAME
22109 && strcmp (IDENTIFIER_POINTER (token
->value
), kind
) == 0);
22110 c_parser_consume_token (parser
);
22111 parser
->in_pragma
= true;
22113 if (strcmp (kind
, "simd") == 0)
22116 c
= c_parser_omp_all_clauses (parser
, OMP_DECLARE_SIMD_CLAUSE_MASK
,
22117 "#pragma omp declare simd");
22118 c
= c_omp_declare_simd_clauses_to_numbers (parms
, c
);
22119 if (c
!= NULL_TREE
)
22120 c
= tree_cons (NULL_TREE
, c
, NULL_TREE
);
22121 c
= build_tree_list (get_identifier ("omp declare simd"), c
);
22122 TREE_CHAIN (c
) = DECL_ATTRIBUTES (fndecl
);
22123 DECL_ATTRIBUTES (fndecl
) = c
;
22127 gcc_assert (strcmp (kind
, "variant") == 0);
22128 c_finish_omp_declare_variant (parser
, fndecl
, parms
);
22132 parser
->tokens
= &parser
->tokens_buf
[0];
22133 parser
->tokens_avail
= tokens_avail
;
22134 if (clauses
.exists ())
22135 clauses
[0].type
= CPP_PRAGMA
;
22140 # pragma omp declare target new-line
22141 declarations and definitions
22142 # pragma omp end declare target new-line
22145 # pragma omp declare target ( extended-list ) new-line
22147 # pragma omp declare target declare-target-clauses[seq] new-line */
22149 #define OMP_DECLARE_TARGET_CLAUSE_MASK \
22150 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
22151 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ENTER) \
22152 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK) \
22153 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE))
22156 c_parser_omp_declare_target (c_parser
*parser
)
22158 tree clauses
= NULL_TREE
;
22159 int device_type
= 0;
22160 bool only_device_type
= true;
22161 if (c_parser_next_token_is (parser
, CPP_NAME
))
22162 clauses
= c_parser_omp_all_clauses (parser
, OMP_DECLARE_TARGET_CLAUSE_MASK
,
22163 "#pragma omp declare target");
22164 else if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
22166 clauses
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ENTER
,
22168 clauses
= c_finish_omp_clauses (clauses
, C_ORT_OMP
);
22169 c_parser_skip_to_pragma_eol (parser
);
22173 c_parser_skip_to_pragma_eol (parser
);
22174 current_omp_declare_target_attribute
++;
22177 for (tree c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
22178 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEVICE_TYPE
)
22179 device_type
|= OMP_CLAUSE_DEVICE_TYPE_KIND (c
);
22180 for (tree c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
22182 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEVICE_TYPE
)
22184 tree t
= OMP_CLAUSE_DECL (c
), id
;
22185 tree at1
= lookup_attribute ("omp declare target", DECL_ATTRIBUTES (t
));
22186 tree at2
= lookup_attribute ("omp declare target link",
22187 DECL_ATTRIBUTES (t
));
22188 only_device_type
= false;
22189 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LINK
)
22191 id
= get_identifier ("omp declare target link");
22192 std::swap (at1
, at2
);
22195 id
= get_identifier ("omp declare target");
22198 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_ENTER
)
22199 error_at (OMP_CLAUSE_LOCATION (c
),
22200 "%qD specified both in declare target %<link%> and %qs"
22201 " clauses", t
, OMP_CLAUSE_ENTER_TO (c
) ? "to" : "enter");
22203 error_at (OMP_CLAUSE_LOCATION (c
),
22204 "%qD specified both in declare target %<link%> and "
22205 "%<to%> or %<enter%> clauses", t
);
22210 DECL_ATTRIBUTES (t
) = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (t
));
22211 if (TREE_CODE (t
) != FUNCTION_DECL
&& !is_global_var (t
))
22214 symtab_node
*node
= symtab_node::get (t
);
22217 node
->offloadable
= 1;
22218 if (ENABLE_OFFLOADING
)
22220 g
->have_offload
= true;
22221 if (is_a
<varpool_node
*> (node
))
22222 vec_safe_push (offload_vars
, t
);
22226 if (TREE_CODE (t
) != FUNCTION_DECL
)
22228 if ((device_type
& OMP_CLAUSE_DEVICE_TYPE_HOST
) != 0)
22230 tree at3
= lookup_attribute ("omp declare target host",
22231 DECL_ATTRIBUTES (t
));
22232 if (at3
== NULL_TREE
)
22234 id
= get_identifier ("omp declare target host");
22235 DECL_ATTRIBUTES (t
)
22236 = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (t
));
22239 if ((device_type
& OMP_CLAUSE_DEVICE_TYPE_NOHOST
) != 0)
22241 tree at3
= lookup_attribute ("omp declare target nohost",
22242 DECL_ATTRIBUTES (t
));
22243 if (at3
== NULL_TREE
)
22245 id
= get_identifier ("omp declare target nohost");
22246 DECL_ATTRIBUTES (t
)
22247 = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (t
));
22251 if (device_type
&& only_device_type
)
22252 warning_at (OMP_CLAUSE_LOCATION (clauses
), 0,
22253 "directive with only %<device_type%> clauses ignored");
22257 c_parser_omp_end_declare_target (c_parser
*parser
)
22259 location_t loc
= c_parser_peek_token (parser
)->location
;
22260 c_parser_consume_pragma (parser
);
22261 if (c_parser_next_token_is (parser
, CPP_NAME
)
22262 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
),
22265 c_parser_consume_token (parser
);
22266 if (c_parser_next_token_is (parser
, CPP_NAME
)
22267 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
),
22269 c_parser_consume_token (parser
);
22272 c_parser_error (parser
, "expected %<target%>");
22273 c_parser_skip_to_pragma_eol (parser
);
22279 c_parser_error (parser
, "expected %<declare%>");
22280 c_parser_skip_to_pragma_eol (parser
);
22283 c_parser_skip_to_pragma_eol (parser
);
22284 if (!current_omp_declare_target_attribute
)
22285 error_at (loc
, "%<#pragma omp end declare target%> without corresponding "
22286 "%<#pragma omp declare target%>");
22288 current_omp_declare_target_attribute
--;
22293 #pragma omp declare reduction (reduction-id : typename-list : expression) \
22294 initializer-clause[opt] new-line
22296 initializer-clause:
22297 initializer (omp_priv = initializer)
22298 initializer (function-name (argument-list)) */
22301 c_parser_omp_declare_reduction (c_parser
*parser
, enum pragma_context context
)
22303 unsigned int tokens_avail
= 0, i
;
22304 vec
<tree
> types
= vNULL
;
22305 vec
<c_token
> clauses
= vNULL
;
22306 enum tree_code reduc_code
= ERROR_MARK
;
22307 tree reduc_id
= NULL_TREE
;
22309 location_t rloc
= c_parser_peek_token (parser
)->location
;
22311 if (context
== pragma_struct
|| context
== pragma_param
)
22313 error ("%<#pragma omp declare reduction%> not at file or block scope");
22317 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
22320 switch (c_parser_peek_token (parser
)->type
)
22323 reduc_code
= PLUS_EXPR
;
22326 reduc_code
= MULT_EXPR
;
22329 reduc_code
= MINUS_EXPR
;
22332 reduc_code
= BIT_AND_EXPR
;
22335 reduc_code
= BIT_XOR_EXPR
;
22338 reduc_code
= BIT_IOR_EXPR
;
22341 reduc_code
= TRUTH_ANDIF_EXPR
;
22344 reduc_code
= TRUTH_ORIF_EXPR
;
22348 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
22349 if (strcmp (p
, "min") == 0)
22351 reduc_code
= MIN_EXPR
;
22354 if (strcmp (p
, "max") == 0)
22356 reduc_code
= MAX_EXPR
;
22359 reduc_id
= c_parser_peek_token (parser
)->value
;
22362 c_parser_error (parser
,
22363 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
22364 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
22368 tree orig_reduc_id
, reduc_decl
;
22369 orig_reduc_id
= reduc_id
;
22370 reduc_id
= c_omp_reduction_id (reduc_code
, reduc_id
);
22371 reduc_decl
= c_omp_reduction_decl (reduc_id
);
22372 c_parser_consume_token (parser
);
22374 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
22379 location_t loc
= c_parser_peek_token (parser
)->location
;
22380 struct c_type_name
*ctype
= c_parser_type_name (parser
);
22383 type
= groktypename (ctype
, NULL
, NULL
);
22384 if (type
== error_mark_node
)
22386 else if ((INTEGRAL_TYPE_P (type
)
22387 || TREE_CODE (type
) == REAL_TYPE
22388 || TREE_CODE (type
) == COMPLEX_TYPE
)
22389 && orig_reduc_id
== NULL_TREE
)
22390 error_at (loc
, "predeclared arithmetic type in "
22391 "%<#pragma omp declare reduction%>");
22392 else if (TREE_CODE (type
) == FUNCTION_TYPE
22393 || TREE_CODE (type
) == ARRAY_TYPE
)
22394 error_at (loc
, "function or array type in "
22395 "%<#pragma omp declare reduction%>");
22396 else if (TYPE_ATOMIC (type
))
22397 error_at (loc
, "%<_Atomic%> qualified type in "
22398 "%<#pragma omp declare reduction%>");
22399 else if (TYPE_QUALS_NO_ADDR_SPACE (type
))
22400 error_at (loc
, "const, volatile or restrict qualified type in "
22401 "%<#pragma omp declare reduction%>");
22405 for (t
= DECL_INITIAL (reduc_decl
); t
; t
= TREE_CHAIN (t
))
22406 if (comptypes (TREE_PURPOSE (t
), type
))
22408 error_at (loc
, "redeclaration of %qs "
22409 "%<#pragma omp declare reduction%> for "
22411 IDENTIFIER_POINTER (reduc_id
)
22412 + sizeof ("omp declare reduction ") - 1,
22415 = DECL_SOURCE_LOCATION (TREE_VEC_ELT (TREE_VALUE (t
),
22417 error_at (ploc
, "previous %<#pragma omp declare "
22421 if (t
== NULL_TREE
)
22422 types
.safe_push (type
);
22424 if (c_parser_next_token_is (parser
, CPP_COMMA
))
22425 c_parser_consume_token (parser
);
22433 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>")
22434 || types
.is_empty ())
22437 clauses
.release ();
22441 c_token
*token
= c_parser_peek_token (parser
);
22442 if (token
->type
== CPP_EOF
|| token
->type
== CPP_PRAGMA_EOL
)
22444 c_parser_consume_token (parser
);
22446 c_parser_skip_to_pragma_eol (parser
);
22450 if (types
.length () > 1)
22452 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
22454 c_token
*token
= c_parser_peek_token (parser
);
22455 if (token
->type
== CPP_EOF
)
22457 clauses
.safe_push (*token
);
22458 c_parser_consume_token (parser
);
22460 clauses
.safe_push (*c_parser_peek_token (parser
));
22461 c_parser_skip_to_pragma_eol (parser
);
22463 /* Make sure nothing tries to read past the end of the tokens. */
22465 memset (&eof_token
, 0, sizeof (eof_token
));
22466 eof_token
.type
= CPP_EOF
;
22467 clauses
.safe_push (eof_token
);
22468 clauses
.safe_push (eof_token
);
22471 int errs
= errorcount
;
22472 FOR_EACH_VEC_ELT (types
, i
, type
)
22474 tokens_avail
= parser
->tokens_avail
;
22475 gcc_assert (parser
->tokens
== &parser
->tokens_buf
[0]);
22476 if (!clauses
.is_empty ())
22478 parser
->tokens
= clauses
.address ();
22479 parser
->tokens_avail
= clauses
.length ();
22480 parser
->in_pragma
= true;
22483 bool nested
= current_function_decl
!= NULL_TREE
;
22485 c_push_function_context ();
22486 tree fndecl
= build_decl (BUILTINS_LOCATION
, FUNCTION_DECL
,
22487 reduc_id
, default_function_type
);
22488 current_function_decl
= fndecl
;
22489 allocate_struct_function (fndecl
, true);
22491 tree stmt
= push_stmt_list ();
22492 /* Intentionally BUILTINS_LOCATION, so that -Wshadow doesn't
22493 warn about these. */
22494 tree omp_out
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
22495 get_identifier ("omp_out"), type
);
22496 DECL_ARTIFICIAL (omp_out
) = 1;
22497 DECL_CONTEXT (omp_out
) = fndecl
;
22498 pushdecl (omp_out
);
22499 tree omp_in
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
22500 get_identifier ("omp_in"), type
);
22501 DECL_ARTIFICIAL (omp_in
) = 1;
22502 DECL_CONTEXT (omp_in
) = fndecl
;
22504 struct c_expr combiner
= c_parser_expression (parser
);
22505 struct c_expr initializer
;
22506 tree omp_priv
= NULL_TREE
, omp_orig
= NULL_TREE
;
22508 initializer
.set_error ();
22509 if (!c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
22511 else if (c_parser_next_token_is (parser
, CPP_NAME
)
22512 && strcmp (IDENTIFIER_POINTER
22513 (c_parser_peek_token (parser
)->value
),
22514 "initializer") == 0)
22516 c_parser_consume_token (parser
);
22519 omp_priv
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
22520 get_identifier ("omp_priv"), type
);
22521 DECL_ARTIFICIAL (omp_priv
) = 1;
22522 DECL_INITIAL (omp_priv
) = error_mark_node
;
22523 DECL_CONTEXT (omp_priv
) = fndecl
;
22524 pushdecl (omp_priv
);
22525 omp_orig
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
22526 get_identifier ("omp_orig"), type
);
22527 DECL_ARTIFICIAL (omp_orig
) = 1;
22528 DECL_CONTEXT (omp_orig
) = fndecl
;
22529 pushdecl (omp_orig
);
22530 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
22532 else if (!c_parser_next_token_is (parser
, CPP_NAME
))
22534 c_parser_error (parser
, "expected %<omp_priv%> or "
22538 else if (strcmp (IDENTIFIER_POINTER
22539 (c_parser_peek_token (parser
)->value
),
22542 if (c_parser_peek_2nd_token (parser
)->type
!= CPP_OPEN_PAREN
22543 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
22545 c_parser_error (parser
, "expected function-name %<(%>");
22549 initializer
= c_parser_postfix_expression (parser
);
22550 if (initializer
.value
22551 && TREE_CODE (initializer
.value
) == CALL_EXPR
)
22554 tree c
= initializer
.value
;
22555 for (j
= 0; j
< call_expr_nargs (c
); j
++)
22557 tree a
= CALL_EXPR_ARG (c
, j
);
22559 if (TREE_CODE (a
) == ADDR_EXPR
22560 && TREE_OPERAND (a
, 0) == omp_priv
)
22563 if (j
== call_expr_nargs (c
))
22564 error ("one of the initializer call arguments should be "
22570 c_parser_consume_token (parser
);
22571 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
22575 tree st
= push_stmt_list ();
22576 location_t loc
= c_parser_peek_token (parser
)->location
;
22577 rich_location
richloc (line_table
, loc
);
22578 start_init (omp_priv
, NULL_TREE
, 0, &richloc
);
22579 struct c_expr init
= c_parser_initializer (parser
);
22581 finish_decl (omp_priv
, loc
, init
.value
,
22582 init
.original_type
, NULL_TREE
);
22583 pop_stmt_list (st
);
22587 && !c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
22593 c_parser_skip_to_pragma_eol (parser
);
22595 tree t
= tree_cons (type
, make_tree_vec (omp_priv
? 6 : 3),
22596 DECL_INITIAL (reduc_decl
));
22597 DECL_INITIAL (reduc_decl
) = t
;
22598 DECL_SOURCE_LOCATION (omp_out
) = rloc
;
22599 TREE_VEC_ELT (TREE_VALUE (t
), 0) = omp_out
;
22600 TREE_VEC_ELT (TREE_VALUE (t
), 1) = omp_in
;
22601 TREE_VEC_ELT (TREE_VALUE (t
), 2) = combiner
.value
;
22602 walk_tree (&combiner
.value
, c_check_omp_declare_reduction_r
,
22603 &TREE_VEC_ELT (TREE_VALUE (t
), 0), NULL
);
22606 DECL_SOURCE_LOCATION (omp_priv
) = rloc
;
22607 TREE_VEC_ELT (TREE_VALUE (t
), 3) = omp_priv
;
22608 TREE_VEC_ELT (TREE_VALUE (t
), 4) = omp_orig
;
22609 TREE_VEC_ELT (TREE_VALUE (t
), 5) = initializer
.value
;
22610 walk_tree (&initializer
.value
, c_check_omp_declare_reduction_r
,
22611 &TREE_VEC_ELT (TREE_VALUE (t
), 3), NULL
);
22612 walk_tree (&DECL_INITIAL (omp_priv
),
22613 c_check_omp_declare_reduction_r
,
22614 &TREE_VEC_ELT (TREE_VALUE (t
), 3), NULL
);
22618 pop_stmt_list (stmt
);
22620 if (cfun
->language
!= NULL
)
22622 ggc_free (cfun
->language
);
22623 cfun
->language
= NULL
;
22626 current_function_decl
= NULL_TREE
;
22628 c_pop_function_context ();
22630 if (!clauses
.is_empty ())
22632 parser
->tokens
= &parser
->tokens_buf
[0];
22633 parser
->tokens_avail
= tokens_avail
;
22637 if (errs
!= errorcount
)
22641 clauses
.release ();
22647 #pragma omp declare simd declare-simd-clauses[optseq] new-line
22648 #pragma omp declare reduction (reduction-id : typename-list : expression) \
22649 initializer-clause[opt] new-line
22650 #pragma omp declare target new-line
22653 #pragma omp declare variant (identifier) match (context-selector) */
22656 c_parser_omp_declare (c_parser
*parser
, enum pragma_context context
)
22658 c_parser_consume_pragma (parser
);
22659 if (c_parser_next_token_is (parser
, CPP_NAME
))
22661 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
22662 if (strcmp (p
, "simd") == 0)
22664 /* c_parser_consume_token (parser); done in
22665 c_parser_omp_declare_simd. */
22666 c_parser_omp_declare_simd (parser
, context
);
22669 if (strcmp (p
, "reduction") == 0)
22671 c_parser_consume_token (parser
);
22672 c_parser_omp_declare_reduction (parser
, context
);
22675 if (!flag_openmp
) /* flag_openmp_simd */
22677 c_parser_skip_to_pragma_eol (parser
, false);
22680 if (strcmp (p
, "target") == 0)
22682 c_parser_consume_token (parser
);
22683 c_parser_omp_declare_target (parser
);
22686 if (strcmp (p
, "variant") == 0)
22688 /* c_parser_consume_token (parser); done in
22689 c_parser_omp_declare_simd. */
22690 c_parser_omp_declare_simd (parser
, context
);
22695 c_parser_error (parser
, "expected %<simd%>, %<reduction%>, "
22696 "%<target%> or %<variant%>");
22697 c_parser_skip_to_pragma_eol (parser
);
22702 #pragma omp requires clauses[optseq] new-line */
22705 c_parser_omp_requires (c_parser
*parser
)
22708 enum omp_requires new_req
= (enum omp_requires
) 0;
22710 c_parser_consume_pragma (parser
);
22712 location_t loc
= c_parser_peek_token (parser
)->location
;
22713 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
22716 && c_parser_next_token_is (parser
, CPP_COMMA
)
22717 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
22718 c_parser_consume_token (parser
);
22722 if (c_parser_next_token_is (parser
, CPP_NAME
))
22725 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
22726 location_t cloc
= c_parser_peek_token (parser
)->location
;
22727 enum omp_requires this_req
= (enum omp_requires
) 0;
22729 if (!strcmp (p
, "unified_address"))
22730 this_req
= OMP_REQUIRES_UNIFIED_ADDRESS
;
22731 else if (!strcmp (p
, "unified_shared_memory"))
22732 this_req
= OMP_REQUIRES_UNIFIED_SHARED_MEMORY
;
22733 else if (!strcmp (p
, "dynamic_allocators"))
22734 this_req
= OMP_REQUIRES_DYNAMIC_ALLOCATORS
;
22735 else if (!strcmp (p
, "reverse_offload"))
22736 this_req
= OMP_REQUIRES_REVERSE_OFFLOAD
;
22737 else if (!strcmp (p
, "atomic_default_mem_order"))
22739 c_parser_consume_token (parser
);
22741 matching_parens parens
;
22742 if (parens
.require_open (parser
))
22744 if (c_parser_next_token_is (parser
, CPP_NAME
))
22746 tree v
= c_parser_peek_token (parser
)->value
;
22747 p
= IDENTIFIER_POINTER (v
);
22749 if (!strcmp (p
, "seq_cst"))
22751 = (enum omp_requires
) OMP_MEMORY_ORDER_SEQ_CST
;
22752 else if (!strcmp (p
, "relaxed"))
22754 = (enum omp_requires
) OMP_MEMORY_ORDER_RELAXED
;
22755 else if (!strcmp (p
, "acq_rel"))
22757 = (enum omp_requires
) OMP_MEMORY_ORDER_ACQ_REL
;
22761 error_at (c_parser_peek_token (parser
)->location
,
22762 "expected %<seq_cst%>, %<relaxed%> or "
22764 switch (c_parser_peek_token (parser
)->type
)
22767 case CPP_PRAGMA_EOL
:
22768 case CPP_CLOSE_PAREN
:
22771 if (c_parser_peek_2nd_token (parser
)->type
22772 == CPP_CLOSE_PAREN
)
22773 c_parser_consume_token (parser
);
22778 c_parser_consume_token (parser
);
22780 parens
.skip_until_found_close (parser
);
22783 c_parser_skip_to_pragma_eol (parser
, false);
22791 error_at (cloc
, "expected %<unified_address%>, "
22792 "%<unified_shared_memory%>, "
22793 "%<dynamic_allocators%>, "
22794 "%<reverse_offload%> "
22795 "or %<atomic_default_mem_order%> clause");
22796 c_parser_skip_to_pragma_eol (parser
, false);
22800 c_parser_consume_token (parser
);
22803 if ((this_req
& ~OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
) != 0)
22805 if ((this_req
& new_req
) != 0)
22806 error_at (cloc
, "too many %qs clauses", p
);
22807 if (this_req
!= OMP_REQUIRES_DYNAMIC_ALLOCATORS
22808 && (omp_requires_mask
& OMP_REQUIRES_TARGET_USED
) != 0)
22809 error_at (cloc
, "%qs clause used lexically after first "
22810 "target construct or offloading API", p
);
22812 else if ((new_req
& OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
) != 0)
22814 error_at (cloc
, "too many %qs clauses",
22815 "atomic_default_mem_order");
22816 this_req
= (enum omp_requires
) 0;
22818 else if ((omp_requires_mask
22819 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
) != 0)
22821 error_at (cloc
, "more than one %<atomic_default_mem_order%>"
22822 " clause in a single compilation unit");
22824 = (enum omp_requires
)
22826 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
);
22828 else if ((omp_requires_mask
22829 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED
) != 0)
22830 error_at (cloc
, "%<atomic_default_mem_order%> clause used "
22831 "lexically after first %<atomic%> construct "
22832 "without memory order clause");
22833 new_req
= (enum omp_requires
) (new_req
| this_req
);
22835 = (enum omp_requires
) (omp_requires_mask
| this_req
);
22841 c_parser_skip_to_pragma_eol (parser
);
22844 error_at (loc
, "%<pragma omp requires%> requires at least one clause");
22847 /* Helper function for c_parser_omp_taskloop.
22848 Disallow zero sized or potentially zero sized task reductions. */
22851 c_finish_taskloop_clauses (tree clauses
)
22853 tree
*pc
= &clauses
;
22854 for (tree c
= clauses
; c
; c
= *pc
)
22856 bool remove
= false;
22857 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_REDUCTION
)
22859 tree type
= strip_array_types (TREE_TYPE (OMP_CLAUSE_DECL (c
)));
22860 if (integer_zerop (TYPE_SIZE_UNIT (type
)))
22862 error_at (OMP_CLAUSE_LOCATION (c
),
22863 "zero sized type %qT in %<reduction%> clause", type
);
22866 else if (TREE_CODE (TYPE_SIZE_UNIT (type
)) != INTEGER_CST
)
22868 error_at (OMP_CLAUSE_LOCATION (c
),
22869 "variable sized type %qT in %<reduction%> clause",
22875 *pc
= OMP_CLAUSE_CHAIN (c
);
22877 pc
= &OMP_CLAUSE_CHAIN (c
);
22883 #pragma omp taskloop taskloop-clause[optseq] new-line
22886 #pragma omp taskloop simd taskloop-simd-clause[optseq] new-line
22889 #define OMP_TASKLOOP_CLAUSE_MASK \
22890 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
22891 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
22892 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
22893 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
22894 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
22895 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_GRAINSIZE) \
22896 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TASKS) \
22897 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
22898 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
22899 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
22900 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
22901 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
22902 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP) \
22903 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
22904 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
22905 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
22906 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION))
22909 c_parser_omp_taskloop (location_t loc
, c_parser
*parser
,
22910 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
22913 tree clauses
, block
, ret
;
22915 strcat (p_name
, " taskloop");
22916 mask
|= OMP_TASKLOOP_CLAUSE_MASK
;
22917 /* #pragma omp parallel master taskloop{, simd} disallow in_reduction
22919 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_NUM_THREADS
)) != 0)
22920 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_IN_REDUCTION
);
22922 if (c_parser_next_token_is (parser
, CPP_NAME
))
22924 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
22926 if (strcmp (p
, "simd") == 0)
22928 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
22929 if (cclauses
== NULL
)
22930 cclauses
= cclauses_buf
;
22931 c_parser_consume_token (parser
);
22932 if (!flag_openmp
) /* flag_openmp_simd */
22933 return c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
,
22935 block
= c_begin_compound_stmt (true);
22936 ret
= c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
22937 block
= c_end_compound_stmt (loc
, block
, true);
22940 ret
= make_node (OMP_TASKLOOP
);
22941 TREE_TYPE (ret
) = void_type_node
;
22942 OMP_FOR_BODY (ret
) = block
;
22943 OMP_FOR_CLAUSES (ret
) = cclauses
[C_OMP_CLAUSE_SPLIT_TASKLOOP
];
22944 OMP_FOR_CLAUSES (ret
)
22945 = c_finish_taskloop_clauses (OMP_FOR_CLAUSES (ret
));
22946 SET_EXPR_LOCATION (ret
, loc
);
22951 if (!flag_openmp
) /* flag_openmp_simd */
22953 c_parser_skip_to_pragma_eol (parser
, false);
22957 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
22960 omp_split_clauses (loc
, OMP_TASKLOOP
, mask
, clauses
, cclauses
);
22961 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_TASKLOOP
];
22964 clauses
= c_finish_taskloop_clauses (clauses
);
22965 block
= c_begin_compound_stmt (true);
22966 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_TASKLOOP
, clauses
, NULL
, if_p
);
22967 block
= c_end_compound_stmt (loc
, block
, true);
22974 #pragma omp nothing new-line */
22977 c_parser_omp_nothing (c_parser
*parser
)
22979 c_parser_consume_pragma (parser
);
22980 c_parser_skip_to_pragma_eol (parser
);
22984 #pragma omp error clauses[optseq] new-line */
22987 c_parser_omp_error (c_parser
*parser
, enum pragma_context context
)
22989 int at_compilation
= -1;
22990 int severity_fatal
= -1;
22991 tree message
= NULL_TREE
;
22994 location_t loc
= c_parser_peek_token (parser
)->location
;
22996 c_parser_consume_pragma (parser
);
22998 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
23001 && c_parser_next_token_is (parser
, CPP_COMMA
)
23002 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
23003 c_parser_consume_token (parser
);
23007 if (!c_parser_next_token_is (parser
, CPP_NAME
))
23011 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
23012 location_t cloc
= c_parser_peek_token (parser
)->location
;
23013 static const char *args
[] = {
23014 "execution", "compilation", "warning", "fatal"
23017 int idx
= 0, n
= -1;
23018 tree m
= NULL_TREE
;
23020 if (!strcmp (p
, "at"))
23021 v
= &at_compilation
;
23022 else if (!strcmp (p
, "severity"))
23024 v
= &severity_fatal
;
23027 else if (strcmp (p
, "message"))
23030 "expected %<at%>, %<severity%> or %<message%> clause");
23031 c_parser_skip_to_pragma_eol (parser
, false);
23035 c_parser_consume_token (parser
);
23037 matching_parens parens
;
23038 if (parens
.require_open (parser
))
23042 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
23043 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
23044 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, true, true);
23045 m
= convert (const_string_type_node
, expr
.value
);
23046 m
= c_fully_fold (m
, false, NULL
);
23050 if (c_parser_next_token_is (parser
, CPP_NAME
))
23052 tree val
= c_parser_peek_token (parser
)->value
;
23053 const char *q
= IDENTIFIER_POINTER (val
);
23055 if (!strcmp (q
, args
[idx
]))
23057 else if (!strcmp (q
, args
[idx
+ 1]))
23062 error_at (c_parser_peek_token (parser
)->location
,
23063 "expected %qs or %qs", args
[idx
], args
[idx
+ 1]);
23065 switch (c_parser_peek_token (parser
)->type
)
23068 case CPP_PRAGMA_EOL
:
23069 case CPP_CLOSE_PAREN
:
23072 if (c_parser_peek_2nd_token (parser
)->type
23073 == CPP_CLOSE_PAREN
)
23074 c_parser_consume_token (parser
);
23079 c_parser_consume_token (parser
);
23082 parens
.skip_until_found_close (parser
);
23088 error_at (cloc
, "too many %qs clauses", p
);
23098 error_at (cloc
, "too many %qs clauses", p
);
23108 c_parser_skip_to_pragma_eol (parser
);
23112 if (at_compilation
== -1)
23113 at_compilation
= 1;
23114 if (severity_fatal
== -1)
23115 severity_fatal
= 1;
23116 if (!at_compilation
)
23118 if (context
!= pragma_compound
)
23120 error_at (loc
, "%<#pragma omp error%> with %<at(execution)%> clause "
23121 "may only be used in compound statements");
23125 = builtin_decl_explicit (severity_fatal
? BUILT_IN_GOMP_ERROR
23126 : BUILT_IN_GOMP_WARNING
);
23128 message
= build_zero_cst (const_string_type_node
);
23129 tree stmt
= build_call_expr_loc (loc
, fndecl
, 2, message
,
23130 build_all_ones_cst (size_type_node
));
23134 const char *msg
= NULL
;
23137 msg
= c_getstr (message
);
23139 msg
= _("<message unknown at compile time>");
23142 emit_diagnostic (severity_fatal
? DK_ERROR
: DK_WARNING
, loc
, 0,
23143 "%<pragma omp error%> encountered: %s", msg
);
23145 emit_diagnostic (severity_fatal
? DK_ERROR
: DK_WARNING
, loc
, 0,
23146 "%<pragma omp error%> encountered");
23150 /* Main entry point to parsing most OpenMP pragmas. */
23153 c_parser_omp_construct (c_parser
*parser
, bool *if_p
)
23155 enum pragma_kind p_kind
;
23158 char p_name
[sizeof "#pragma omp teams distribute parallel for simd"];
23159 omp_clause_mask
mask (0);
23161 loc
= c_parser_peek_token (parser
)->location
;
23162 p_kind
= c_parser_peek_token (parser
)->pragma_kind
;
23163 c_parser_consume_pragma (parser
);
23167 case PRAGMA_OACC_ATOMIC
:
23168 c_parser_omp_atomic (loc
, parser
, true);
23170 case PRAGMA_OACC_CACHE
:
23171 strcpy (p_name
, "#pragma acc");
23172 stmt
= c_parser_oacc_cache (loc
, parser
);
23174 case PRAGMA_OACC_DATA
:
23175 stmt
= c_parser_oacc_data (loc
, parser
, if_p
);
23177 case PRAGMA_OACC_HOST_DATA
:
23178 stmt
= c_parser_oacc_host_data (loc
, parser
, if_p
);
23180 case PRAGMA_OACC_KERNELS
:
23181 case PRAGMA_OACC_PARALLEL
:
23182 case PRAGMA_OACC_SERIAL
:
23183 strcpy (p_name
, "#pragma acc");
23184 stmt
= c_parser_oacc_compute (loc
, parser
, p_kind
, p_name
, if_p
);
23186 case PRAGMA_OACC_LOOP
:
23187 strcpy (p_name
, "#pragma acc");
23188 stmt
= c_parser_oacc_loop (loc
, parser
, p_name
, mask
, NULL
, if_p
);
23190 case PRAGMA_OACC_WAIT
:
23191 strcpy (p_name
, "#pragma wait");
23192 stmt
= c_parser_oacc_wait (loc
, parser
, p_name
);
23194 case PRAGMA_OMP_ALLOCATE
:
23195 c_parser_omp_allocate (loc
, parser
);
23197 case PRAGMA_OMP_ATOMIC
:
23198 c_parser_omp_atomic (loc
, parser
, false);
23200 case PRAGMA_OMP_CRITICAL
:
23201 stmt
= c_parser_omp_critical (loc
, parser
, if_p
);
23203 case PRAGMA_OMP_DISTRIBUTE
:
23204 strcpy (p_name
, "#pragma omp");
23205 stmt
= c_parser_omp_distribute (loc
, parser
, p_name
, mask
, NULL
, if_p
);
23207 case PRAGMA_OMP_FOR
:
23208 strcpy (p_name
, "#pragma omp");
23209 stmt
= c_parser_omp_for (loc
, parser
, p_name
, mask
, NULL
, if_p
);
23211 case PRAGMA_OMP_LOOP
:
23212 strcpy (p_name
, "#pragma omp");
23213 stmt
= c_parser_omp_loop (loc
, parser
, p_name
, mask
, NULL
, if_p
);
23215 case PRAGMA_OMP_MASKED
:
23216 strcpy (p_name
, "#pragma omp");
23217 stmt
= c_parser_omp_masked (loc
, parser
, p_name
, mask
, NULL
, if_p
);
23219 case PRAGMA_OMP_MASTER
:
23220 strcpy (p_name
, "#pragma omp");
23221 stmt
= c_parser_omp_master (loc
, parser
, p_name
, mask
, NULL
, if_p
);
23223 case PRAGMA_OMP_PARALLEL
:
23224 strcpy (p_name
, "#pragma omp");
23225 stmt
= c_parser_omp_parallel (loc
, parser
, p_name
, mask
, NULL
, if_p
);
23227 case PRAGMA_OMP_SCOPE
:
23228 stmt
= c_parser_omp_scope (loc
, parser
, if_p
);
23230 case PRAGMA_OMP_SECTIONS
:
23231 strcpy (p_name
, "#pragma omp");
23232 stmt
= c_parser_omp_sections (loc
, parser
, p_name
, mask
, NULL
);
23234 case PRAGMA_OMP_SIMD
:
23235 strcpy (p_name
, "#pragma omp");
23236 stmt
= c_parser_omp_simd (loc
, parser
, p_name
, mask
, NULL
, if_p
);
23238 case PRAGMA_OMP_SINGLE
:
23239 stmt
= c_parser_omp_single (loc
, parser
, if_p
);
23241 case PRAGMA_OMP_TASK
:
23242 stmt
= c_parser_omp_task (loc
, parser
, if_p
);
23244 case PRAGMA_OMP_TASKGROUP
:
23245 stmt
= c_parser_omp_taskgroup (loc
, parser
, if_p
);
23247 case PRAGMA_OMP_TASKLOOP
:
23248 strcpy (p_name
, "#pragma omp");
23249 stmt
= c_parser_omp_taskloop (loc
, parser
, p_name
, mask
, NULL
, if_p
);
23251 case PRAGMA_OMP_TEAMS
:
23252 strcpy (p_name
, "#pragma omp");
23253 stmt
= c_parser_omp_teams (loc
, parser
, p_name
, mask
, NULL
, if_p
);
23256 gcc_unreachable ();
23259 if (stmt
&& stmt
!= error_mark_node
)
23260 gcc_assert (EXPR_LOCATION (stmt
) != UNKNOWN_LOCATION
);
23265 # pragma omp threadprivate (variable-list) */
23268 c_parser_omp_threadprivate (c_parser
*parser
)
23273 c_parser_consume_pragma (parser
);
23274 loc
= c_parser_peek_token (parser
)->location
;
23275 vars
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ERROR
, NULL
);
23277 /* Mark every variable in VARS to be assigned thread local storage. */
23278 for (t
= vars
; t
; t
= TREE_CHAIN (t
))
23280 tree v
= TREE_PURPOSE (t
);
23282 /* FIXME diagnostics: Ideally we should keep individual
23283 locations for all the variables in the var list to make the
23284 following errors more precise. Perhaps
23285 c_parser_omp_var_list_parens() should construct a list of
23286 locations to go along with the var list. */
23288 /* If V had already been marked threadprivate, it doesn't matter
23289 whether it had been used prior to this point. */
23291 error_at (loc
, "%qD is not a variable", v
);
23292 else if (TREE_USED (v
) && !C_DECL_THREADPRIVATE_P (v
))
23293 error_at (loc
, "%qE declared %<threadprivate%> after first use", v
);
23294 else if (! is_global_var (v
))
23295 error_at (loc
, "automatic variable %qE cannot be %<threadprivate%>", v
);
23296 else if (TREE_TYPE (v
) == error_mark_node
)
23298 else if (! COMPLETE_TYPE_P (TREE_TYPE (v
)))
23299 error_at (loc
, "%<threadprivate%> %qE has incomplete type", v
);
23302 if (! DECL_THREAD_LOCAL_P (v
))
23304 set_decl_tls_model (v
, decl_default_tls_model (v
));
23305 /* If rtl has been already set for this var, call
23306 make_decl_rtl once again, so that encode_section_info
23307 has a chance to look at the new decl flags. */
23308 if (DECL_RTL_SET_P (v
))
23311 C_DECL_THREADPRIVATE_P (v
) = 1;
23315 c_parser_skip_to_pragma_eol (parser
);
23318 /* Parse a transaction attribute (GCC Extension).
23320 transaction-attribute:
23322 attribute-specifier
23326 c_parser_transaction_attributes (c_parser
*parser
)
23328 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
23329 return c_parser_gnu_attributes (parser
);
23331 if (!c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
))
23333 return c_parser_std_attribute_specifier (parser
, true);
23336 /* Parse a __transaction_atomic or __transaction_relaxed statement
23339 transaction-statement:
23340 __transaction_atomic transaction-attribute[opt] compound-statement
23341 __transaction_relaxed compound-statement
23343 Note that the only valid attribute is: "outer".
23347 c_parser_transaction (c_parser
*parser
, enum rid keyword
)
23349 unsigned int old_in
= parser
->in_transaction
;
23350 unsigned int this_in
= 1, new_in
;
23351 location_t loc
= c_parser_peek_token (parser
)->location
;
23354 gcc_assert ((keyword
== RID_TRANSACTION_ATOMIC
23355 || keyword
== RID_TRANSACTION_RELAXED
)
23356 && c_parser_next_token_is_keyword (parser
, keyword
));
23357 c_parser_consume_token (parser
);
23359 if (keyword
== RID_TRANSACTION_RELAXED
)
23360 this_in
|= TM_STMT_ATTR_RELAXED
;
23363 attrs
= c_parser_transaction_attributes (parser
);
23365 this_in
|= parse_tm_stmt_attr (attrs
, TM_STMT_ATTR_OUTER
);
23368 /* Keep track if we're in the lexical scope of an outer transaction. */
23369 new_in
= this_in
| (old_in
& TM_STMT_ATTR_OUTER
);
23371 parser
->in_transaction
= new_in
;
23372 stmt
= c_parser_compound_statement (parser
);
23373 parser
->in_transaction
= old_in
;
23376 stmt
= c_finish_transaction (loc
, stmt
, this_in
);
23378 error_at (loc
, (keyword
== RID_TRANSACTION_ATOMIC
?
23379 "%<__transaction_atomic%> without transactional memory support enabled"
23380 : "%<__transaction_relaxed %> "
23381 "without transactional memory support enabled"));
23386 /* Parse a __transaction_atomic or __transaction_relaxed expression
23389 transaction-expression:
23390 __transaction_atomic ( expression )
23391 __transaction_relaxed ( expression )
23394 static struct c_expr
23395 c_parser_transaction_expression (c_parser
*parser
, enum rid keyword
)
23398 unsigned int old_in
= parser
->in_transaction
;
23399 unsigned int this_in
= 1;
23400 location_t loc
= c_parser_peek_token (parser
)->location
;
23403 gcc_assert ((keyword
== RID_TRANSACTION_ATOMIC
23404 || keyword
== RID_TRANSACTION_RELAXED
)
23405 && c_parser_next_token_is_keyword (parser
, keyword
));
23406 c_parser_consume_token (parser
);
23408 if (keyword
== RID_TRANSACTION_RELAXED
)
23409 this_in
|= TM_STMT_ATTR_RELAXED
;
23412 attrs
= c_parser_transaction_attributes (parser
);
23414 this_in
|= parse_tm_stmt_attr (attrs
, 0);
23417 parser
->in_transaction
= this_in
;
23418 matching_parens parens
;
23419 if (parens
.require_open (parser
))
23421 tree expr
= c_parser_expression (parser
).value
;
23422 ret
.original_type
= TREE_TYPE (expr
);
23423 ret
.value
= build1 (TRANSACTION_EXPR
, ret
.original_type
, expr
);
23424 if (this_in
& TM_STMT_ATTR_RELAXED
)
23425 TRANSACTION_EXPR_RELAXED (ret
.value
) = 1;
23426 SET_EXPR_LOCATION (ret
.value
, loc
);
23427 ret
.original_code
= TRANSACTION_EXPR
;
23428 if (!parens
.require_close (parser
))
23430 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
23438 ret
.original_code
= ERROR_MARK
;
23439 ret
.original_type
= NULL
;
23441 parser
->in_transaction
= old_in
;
23444 error_at (loc
, (keyword
== RID_TRANSACTION_ATOMIC
?
23445 "%<__transaction_atomic%> without transactional memory support enabled"
23446 : "%<__transaction_relaxed %> "
23447 "without transactional memory support enabled"));
23449 set_c_expr_source_range (&ret
, loc
, loc
);
23454 /* Parse a __transaction_cancel statement (GCC Extension).
23456 transaction-cancel-statement:
23457 __transaction_cancel transaction-attribute[opt] ;
23459 Note that the only valid attribute is "outer".
23463 c_parser_transaction_cancel (c_parser
*parser
)
23465 location_t loc
= c_parser_peek_token (parser
)->location
;
23467 bool is_outer
= false;
23469 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_TRANSACTION_CANCEL
));
23470 c_parser_consume_token (parser
);
23472 attrs
= c_parser_transaction_attributes (parser
);
23474 is_outer
= (parse_tm_stmt_attr (attrs
, TM_STMT_ATTR_OUTER
) != 0);
23478 error_at (loc
, "%<__transaction_cancel%> without "
23479 "transactional memory support enabled");
23482 else if (parser
->in_transaction
& TM_STMT_ATTR_RELAXED
)
23484 error_at (loc
, "%<__transaction_cancel%> within a "
23485 "%<__transaction_relaxed%>");
23490 if ((parser
->in_transaction
& TM_STMT_ATTR_OUTER
) == 0
23491 && !is_tm_may_cancel_outer (current_function_decl
))
23493 error_at (loc
, "outer %<__transaction_cancel%> not "
23494 "within outer %<__transaction_atomic%> or "
23495 "a %<transaction_may_cancel_outer%> function");
23499 else if (parser
->in_transaction
== 0)
23501 error_at (loc
, "%<__transaction_cancel%> not within "
23502 "%<__transaction_atomic%>");
23506 return add_stmt (build_tm_abort_call (loc
, is_outer
));
23509 return build1 (NOP_EXPR
, void_type_node
, error_mark_node
);
23512 /* Parse a single source file. */
23515 c_parse_file (void)
23517 /* Use local storage to begin. If the first token is a pragma, parse it.
23518 If it is #pragma GCC pch_preprocess, then this will load a PCH file
23519 which will cause garbage collection. */
23522 memset (&tparser
, 0, sizeof tparser
);
23523 tparser
.translate_strings_p
= true;
23524 tparser
.tokens
= &tparser
.tokens_buf
[0];
23525 the_parser
= &tparser
;
23527 if (c_parser_peek_token (&tparser
)->pragma_kind
== PRAGMA_GCC_PCH_PREPROCESS
)
23528 c_parser_pragma_pch_preprocess (&tparser
);
23530 c_common_no_more_pch ();
23532 the_parser
= ggc_alloc
<c_parser
> ();
23533 *the_parser
= tparser
;
23534 if (tparser
.tokens
== &tparser
.tokens_buf
[0])
23535 the_parser
->tokens
= &the_parser
->tokens_buf
[0];
23537 /* Initialize EH, if we've been told to do so. */
23538 if (flag_exceptions
)
23539 using_eh_for_cleanups ();
23541 c_parser_translation_unit (the_parser
);
23545 /* Parse the body of a function declaration marked with "__RTL".
23547 The RTL parser works on the level of characters read from a
23548 FILE *, whereas c_parser works at the level of tokens.
23549 Square this circle by consuming all of the tokens up to and
23550 including the closing brace, recording the start/end of the RTL
23551 fragment, and reopening the file and re-reading the relevant
23552 lines within the RTL parser.
23554 This requires the opening and closing braces of the C function
23555 to be on separate lines from the RTL they wrap.
23557 Take ownership of START_WITH_PASS, if non-NULL. */
23560 c_parser_parse_rtl_body (c_parser
*parser
, char *start_with_pass
)
23562 if (!c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
23564 free (start_with_pass
);
23565 return c_parser_peek_token (parser
)->location
;
23568 location_t start_loc
= c_parser_peek_token (parser
)->location
;
23570 /* Consume all tokens, up to the closing brace, handling
23571 matching pairs of braces in the rtl dump. */
23572 int num_open_braces
= 1;
23575 switch (c_parser_peek_token (parser
)->type
)
23577 case CPP_OPEN_BRACE
:
23580 case CPP_CLOSE_BRACE
:
23581 if (--num_open_braces
== 0)
23582 goto found_closing_brace
;
23585 error_at (start_loc
, "no closing brace");
23586 free (start_with_pass
);
23587 return c_parser_peek_token (parser
)->location
;
23591 c_parser_consume_token (parser
);
23594 found_closing_brace
:
23595 /* At the closing brace; record its location. */
23596 location_t end_loc
= c_parser_peek_token (parser
)->location
;
23598 /* Consume the closing brace. */
23599 c_parser_consume_token (parser
);
23601 /* Invoke the RTL parser. */
23602 if (!read_rtl_function_body_from_file_range (start_loc
, end_loc
))
23604 free (start_with_pass
);
23608 /* Run the backend on the cfun created above, transferring ownership of
23609 START_WITH_PASS. */
23610 run_rtl_passes (start_with_pass
);
23614 #include "gt-c-c-parser.h"