1 /* Parser for C and Objective-C.
2 Copyright (C) 1987-2019 Free Software Foundation, Inc.
4 Parser actions based on the old Bison parser; structure somewhat
5 influenced by and fragments based on the C++ parser.
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
25 Make sure all relevant comments, and all relevant code from all
26 actions, brought over from old parser. Verify exact correspondence
29 Add testcases covering every input symbol in every state in old and
32 Include full syntax for GNU C, including erroneous cases accepted
33 with error messages, in syntax productions in comments.
35 Make more diagnostics in the front end generally take an explicit
36 location rather than implicitly using input_location. */
39 #define INCLUDE_UNIQUE_PTR
41 #include "coretypes.h"
46 #include "stringpool.h"
49 #include "stor-layout.h"
51 #include "trans-mem.h"
52 #include "c-family/c-pragma.h"
54 #include "c-family/c-objc.h"
56 #include "omp-general.h"
57 #include "omp-offload.h"
59 #include "gomp-constants.h"
60 #include "c-family/c-indentation.h"
61 #include "gimple-expr.h"
63 #include "gcc-rich-location.h"
65 #include "gimple-parser.h"
66 #include "read-rtl-function.h"
67 #include "run-rtl-passes.h"
69 #include "c-family/name-hint.h"
70 #include "tree-iterator.h"
73 /* We need to walk over decls with incomplete struct/union/enum types
74 after parsing the whole translation unit.
75 In finish_decl(), if the decl is static, has incomplete
76 struct/union/enum type, it is appeneded to incomplete_record_decls.
77 In c_parser_translation_unit(), we iterate over incomplete_record_decls
78 and report error if any of the decls are still incomplete. */
80 vec
<tree
> incomplete_record_decls
;
83 set_c_expr_source_range (c_expr
*expr
,
84 location_t start
, location_t finish
)
86 expr
->src_range
.m_start
= start
;
87 expr
->src_range
.m_finish
= finish
;
89 set_source_range (expr
->value
, start
, finish
);
93 set_c_expr_source_range (c_expr
*expr
,
94 source_range src_range
)
96 expr
->src_range
= src_range
;
98 set_source_range (expr
->value
, src_range
);
102 /* Initialization routine for this file. */
107 /* The only initialization required is of the reserved word
113 /* Make sure RID_MAX hasn't grown past the 8 bits used to hold the keyword in
114 the c_token structure. */
115 gcc_assert (RID_MAX
<= 255);
122 mask
|= D_ASM
| D_EXT
;
126 if (!c_dialect_objc ())
127 mask
|= D_OBJC
| D_CXX_OBJC
;
129 ridpointers
= ggc_cleared_vec_alloc
<tree
> ((int) RID_MAX
);
130 for (i
= 0; i
< num_c_common_reswords
; i
++)
132 /* If a keyword is disabled, do not enter it into the table
133 and so create a canonical spelling that isn't a keyword. */
134 if (c_common_reswords
[i
].disable
& mask
)
137 && (c_common_reswords
[i
].disable
& D_CXXWARN
))
139 id
= get_identifier (c_common_reswords
[i
].word
);
140 C_SET_RID_CODE (id
, RID_CXX_COMPAT_WARN
);
141 C_IS_RESERVED_WORD (id
) = 1;
146 id
= get_identifier (c_common_reswords
[i
].word
);
147 C_SET_RID_CODE (id
, c_common_reswords
[i
].rid
);
148 C_IS_RESERVED_WORD (id
) = 1;
149 ridpointers
[(int) c_common_reswords
[i
].rid
] = id
;
152 for (i
= 0; i
< NUM_INT_N_ENTS
; i
++)
154 /* We always create the symbols but they aren't always supported. */
156 sprintf (name
, "__int%d", int_n_data
[i
].bitsize
);
157 id
= get_identifier (name
);
158 C_SET_RID_CODE (id
, RID_FIRST_INT_N
+ i
);
159 C_IS_RESERVED_WORD (id
) = 1;
161 sprintf (name
, "__int%d__", int_n_data
[i
].bitsize
);
162 id
= get_identifier (name
);
163 C_SET_RID_CODE (id
, RID_FIRST_INT_N
+ i
);
164 C_IS_RESERVED_WORD (id
) = 1;
168 /* A parser structure recording information about the state and
169 context of parsing. Includes lexer information with up to two
170 tokens of look-ahead; more are not needed for C. */
171 struct GTY(()) c_parser
{
172 /* The look-ahead tokens. */
173 c_token
* GTY((skip
)) tokens
;
174 /* Buffer for look-ahead tokens. */
175 c_token tokens_buf
[4];
176 /* How many look-ahead tokens are available (0 - 4, or
177 more if parsing from pre-lexed tokens). */
178 unsigned int tokens_avail
;
179 /* True if a syntax error is being recovered from; false otherwise.
180 c_parser_error sets this flag. It should clear this flag when
181 enough tokens have been consumed to recover from the error. */
182 BOOL_BITFIELD error
: 1;
183 /* True if we're processing a pragma, and shouldn't automatically
184 consume CPP_PRAGMA_EOL. */
185 BOOL_BITFIELD in_pragma
: 1;
186 /* True if we're parsing the outermost block of an if statement. */
187 BOOL_BITFIELD in_if_block
: 1;
188 /* True if we want to lex a translated, joined string (for an
189 initial #pragma pch_preprocess). Otherwise the parser is
190 responsible for concatenating strings and translating to the
191 execution character set as needed. */
192 BOOL_BITFIELD lex_joined_string
: 1;
193 /* True if, when the parser is concatenating string literals, it
194 should translate them to the execution character set (false
195 inside attributes). */
196 BOOL_BITFIELD translate_strings_p
: 1;
198 /* Objective-C specific parser/lexer information. */
200 /* True if we are in a context where the Objective-C "PQ" keywords
201 are considered keywords. */
202 BOOL_BITFIELD objc_pq_context
: 1;
203 /* True if we are parsing a (potential) Objective-C foreach
204 statement. This is set to true after we parsed 'for (' and while
205 we wait for 'in' or ';' to decide if it's a standard C for loop or an
206 Objective-C foreach loop. */
207 BOOL_BITFIELD objc_could_be_foreach_context
: 1;
208 /* The following flag is needed to contextualize Objective-C lexical
209 analysis. In some cases (e.g., 'int NSObject;'), it is
210 undesirable to bind an identifier to an Objective-C class, even
211 if a class with that name exists. */
212 BOOL_BITFIELD objc_need_raw_identifier
: 1;
213 /* Nonzero if we're processing a __transaction statement. The value
214 is 1 | TM_STMT_ATTR_*. */
215 unsigned int in_transaction
: 4;
216 /* True if we are in a context where the Objective-C "Property attribute"
217 keywords are valid. */
218 BOOL_BITFIELD objc_property_attr_context
: 1;
220 /* Location of the last consumed token. */
221 location_t last_token_location
;
224 /* Return a pointer to the Nth token in PARSERs tokens_buf. */
227 c_parser_tokens_buf (c_parser
*parser
, unsigned n
)
229 return &parser
->tokens_buf
[n
];
232 /* Return the error state of PARSER. */
235 c_parser_error (c_parser
*parser
)
237 return parser
->error
;
240 /* Set the error state of PARSER to ERR. */
243 c_parser_set_error (c_parser
*parser
, bool err
)
249 /* The actual parser and external interface. ??? Does this need to be
250 garbage-collected? */
252 static GTY (()) c_parser
*the_parser
;
254 /* Read in and lex a single token, storing it in *TOKEN. */
257 c_lex_one_token (c_parser
*parser
, c_token
*token
)
259 timevar_push (TV_LEX
);
261 token
->type
= c_lex_with_flags (&token
->value
, &token
->location
,
263 (parser
->lex_joined_string
264 ? 0 : C_LEX_STRING_NO_JOIN
));
265 token
->id_kind
= C_ID_NONE
;
266 token
->keyword
= RID_MAX
;
267 token
->pragma_kind
= PRAGMA_NONE
;
275 bool objc_force_identifier
= parser
->objc_need_raw_identifier
;
276 if (c_dialect_objc ())
277 parser
->objc_need_raw_identifier
= false;
279 if (C_IS_RESERVED_WORD (token
->value
))
281 enum rid rid_code
= C_RID_CODE (token
->value
);
283 if (rid_code
== RID_CXX_COMPAT_WARN
)
285 warning_at (token
->location
,
287 "identifier %qE conflicts with C++ keyword",
290 else if (rid_code
>= RID_FIRST_ADDR_SPACE
291 && rid_code
<= RID_LAST_ADDR_SPACE
)
294 as
= (addr_space_t
) (rid_code
- RID_FIRST_ADDR_SPACE
);
295 targetm
.addr_space
.diagnose_usage (as
, token
->location
);
296 token
->id_kind
= C_ID_ADDRSPACE
;
297 token
->keyword
= rid_code
;
300 else if (c_dialect_objc () && OBJC_IS_PQ_KEYWORD (rid_code
))
302 /* We found an Objective-C "pq" keyword (in, out,
303 inout, bycopy, byref, oneway). They need special
304 care because the interpretation depends on the
306 if (parser
->objc_pq_context
)
308 token
->type
= CPP_KEYWORD
;
309 token
->keyword
= rid_code
;
312 else if (parser
->objc_could_be_foreach_context
313 && rid_code
== RID_IN
)
315 /* We are in Objective-C, inside a (potential)
316 foreach context (which means after having
317 parsed 'for (', but before having parsed ';'),
318 and we found 'in'. We consider it the keyword
319 which terminates the declaration at the
320 beginning of a foreach-statement. Note that
321 this means you can't use 'in' for anything else
322 in that context; in particular, in Objective-C
323 you can't use 'in' as the name of the running
324 variable in a C for loop. We could potentially
325 try to add code here to disambiguate, but it
326 seems a reasonable limitation. */
327 token
->type
= CPP_KEYWORD
;
328 token
->keyword
= rid_code
;
331 /* Else, "pq" keywords outside of the "pq" context are
332 not keywords, and we fall through to the code for
335 else if (c_dialect_objc () && OBJC_IS_PATTR_KEYWORD (rid_code
))
337 /* We found an Objective-C "property attribute"
338 keyword (getter, setter, readonly, etc). These are
339 only valid in the property context. */
340 if (parser
->objc_property_attr_context
)
342 token
->type
= CPP_KEYWORD
;
343 token
->keyword
= rid_code
;
346 /* Else they are not special keywords.
349 else if (c_dialect_objc ()
350 && (OBJC_IS_AT_KEYWORD (rid_code
)
351 || OBJC_IS_CXX_KEYWORD (rid_code
)))
353 /* We found one of the Objective-C "@" keywords (defs,
354 selector, synchronized, etc) or one of the
355 Objective-C "cxx" keywords (class, private,
356 protected, public, try, catch, throw) without a
357 preceding '@' sign. Do nothing and fall through to
358 the code for normal tokens (in C++ we would still
359 consider the CXX ones keywords, but not in C). */
364 token
->type
= CPP_KEYWORD
;
365 token
->keyword
= rid_code
;
370 decl
= lookup_name (token
->value
);
373 if (TREE_CODE (decl
) == TYPE_DECL
)
375 token
->id_kind
= C_ID_TYPENAME
;
379 else if (c_dialect_objc ())
381 tree objc_interface_decl
= objc_is_class_name (token
->value
);
382 /* Objective-C class names are in the same namespace as
383 variables and typedefs, and hence are shadowed by local
385 if (objc_interface_decl
386 && (!objc_force_identifier
|| global_bindings_p ()))
388 token
->value
= objc_interface_decl
;
389 token
->id_kind
= C_ID_CLASSNAME
;
393 token
->id_kind
= C_ID_ID
;
397 /* This only happens in Objective-C; it must be a keyword. */
398 token
->type
= CPP_KEYWORD
;
399 switch (C_RID_CODE (token
->value
))
401 /* Replace 'class' with '@class', 'private' with '@private',
402 etc. This prevents confusion with the C++ keyword
403 'class', and makes the tokens consistent with other
404 Objective-C 'AT' keywords. For example '@class' is
405 reported as RID_AT_CLASS which is consistent with
406 '@synchronized', which is reported as
409 case RID_CLASS
: token
->keyword
= RID_AT_CLASS
; break;
410 case RID_PRIVATE
: token
->keyword
= RID_AT_PRIVATE
; break;
411 case RID_PROTECTED
: token
->keyword
= RID_AT_PROTECTED
; break;
412 case RID_PUBLIC
: token
->keyword
= RID_AT_PUBLIC
; break;
413 case RID_THROW
: token
->keyword
= RID_AT_THROW
; break;
414 case RID_TRY
: token
->keyword
= RID_AT_TRY
; break;
415 case RID_CATCH
: token
->keyword
= RID_AT_CATCH
; break;
416 case RID_SYNCHRONIZED
: token
->keyword
= RID_AT_SYNCHRONIZED
; break;
417 default: token
->keyword
= C_RID_CODE (token
->value
);
422 case CPP_CLOSE_PAREN
:
424 /* These tokens may affect the interpretation of any identifiers
425 following, if doing Objective-C. */
426 if (c_dialect_objc ())
427 parser
->objc_need_raw_identifier
= false;
430 /* We smuggled the cpp_token->u.pragma value in an INTEGER_CST. */
431 token
->pragma_kind
= (enum pragma_kind
) TREE_INT_CST_LOW (token
->value
);
437 timevar_pop (TV_LEX
);
440 /* Return a pointer to the next token from PARSER, reading it in if
444 c_parser_peek_token (c_parser
*parser
)
446 if (parser
->tokens_avail
== 0)
448 c_lex_one_token (parser
, &parser
->tokens
[0]);
449 parser
->tokens_avail
= 1;
451 return &parser
->tokens
[0];
454 /* Return a pointer to the next-but-one token from PARSER, reading it
455 in if necessary. The next token is already read in. */
458 c_parser_peek_2nd_token (c_parser
*parser
)
460 if (parser
->tokens_avail
>= 2)
461 return &parser
->tokens
[1];
462 gcc_assert (parser
->tokens_avail
== 1);
463 gcc_assert (parser
->tokens
[0].type
!= CPP_EOF
);
464 gcc_assert (parser
->tokens
[0].type
!= CPP_PRAGMA_EOL
);
465 c_lex_one_token (parser
, &parser
->tokens
[1]);
466 parser
->tokens_avail
= 2;
467 return &parser
->tokens
[1];
470 /* Return a pointer to the Nth token from PARSER, reading it
471 in if necessary. The N-1th token is already read in. */
474 c_parser_peek_nth_token (c_parser
*parser
, unsigned int n
)
476 /* N is 1-based, not zero-based. */
479 if (parser
->tokens_avail
>= n
)
480 return &parser
->tokens
[n
- 1];
481 gcc_assert (parser
->tokens_avail
== n
- 1);
482 c_lex_one_token (parser
, &parser
->tokens
[n
- 1]);
483 parser
->tokens_avail
= n
;
484 return &parser
->tokens
[n
- 1];
488 c_keyword_starts_typename (enum rid keyword
)
523 if (keyword
>= RID_FIRST_INT_N
524 && keyword
< RID_FIRST_INT_N
+ NUM_INT_N_ENTS
525 && int_n_enabled_p
[keyword
- RID_FIRST_INT_N
])
531 /* Return true if TOKEN can start a type name,
534 c_token_starts_typename (c_token
*token
)
539 switch (token
->id_kind
)
548 gcc_assert (c_dialect_objc ());
554 return c_keyword_starts_typename (token
->keyword
);
556 if (c_dialect_objc ())
564 /* Return true if the next token from PARSER can start a type name,
565 false otherwise. LA specifies how to do lookahead in order to
566 detect unknown type names. If unsure, pick CLA_PREFER_ID. */
569 c_parser_next_tokens_start_typename (c_parser
*parser
, enum c_lookahead_kind la
)
571 c_token
*token
= c_parser_peek_token (parser
);
572 if (c_token_starts_typename (token
))
575 /* Try a bit harder to detect an unknown typename. */
576 if (la
!= cla_prefer_id
577 && token
->type
== CPP_NAME
578 && token
->id_kind
== C_ID_ID
580 /* Do not try too hard when we could have "object in array". */
581 && !parser
->objc_could_be_foreach_context
583 && (la
== cla_prefer_type
584 || c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
585 || c_parser_peek_2nd_token (parser
)->type
== CPP_MULT
)
587 /* Only unknown identifiers. */
588 && !lookup_name (token
->value
))
594 /* Return true if TOKEN is a type qualifier, false otherwise. */
596 c_token_is_qualifier (c_token
*token
)
601 switch (token
->id_kind
)
609 switch (token
->keyword
)
627 /* Return true if the next token from PARSER is a type qualifier,
630 c_parser_next_token_is_qualifier (c_parser
*parser
)
632 c_token
*token
= c_parser_peek_token (parser
);
633 return c_token_is_qualifier (token
);
636 /* Return true if TOKEN can start declaration specifiers, false
639 c_token_starts_declspecs (c_token
*token
)
644 switch (token
->id_kind
)
653 gcc_assert (c_dialect_objc ());
659 switch (token
->keyword
)
700 if (token
->keyword
>= RID_FIRST_INT_N
701 && token
->keyword
< RID_FIRST_INT_N
+ NUM_INT_N_ENTS
702 && int_n_enabled_p
[token
->keyword
- RID_FIRST_INT_N
])
707 if (c_dialect_objc ())
716 /* Return true if TOKEN can start declaration specifiers or a static
717 assertion, false otherwise. */
719 c_token_starts_declaration (c_token
*token
)
721 if (c_token_starts_declspecs (token
)
722 || token
->keyword
== RID_STATIC_ASSERT
)
728 /* Return true if the next token from PARSER can start declaration
729 specifiers, false otherwise. */
731 c_parser_next_token_starts_declspecs (c_parser
*parser
)
733 c_token
*token
= c_parser_peek_token (parser
);
735 /* In Objective-C, a classname normally starts a declspecs unless it
736 is immediately followed by a dot. In that case, it is the
737 Objective-C 2.0 "dot-syntax" for class objects, ie, calls the
738 setter/getter on the class. c_token_starts_declspecs() can't
739 differentiate between the two cases because it only checks the
740 current token, so we have a special check here. */
741 if (c_dialect_objc ()
742 && token
->type
== CPP_NAME
743 && token
->id_kind
== C_ID_CLASSNAME
744 && c_parser_peek_2nd_token (parser
)->type
== CPP_DOT
)
747 return c_token_starts_declspecs (token
);
750 /* Return true if the next tokens from PARSER can start declaration
751 specifiers or a static assertion, false otherwise. */
753 c_parser_next_tokens_start_declaration (c_parser
*parser
)
755 c_token
*token
= c_parser_peek_token (parser
);
758 if (c_dialect_objc ()
759 && token
->type
== CPP_NAME
760 && token
->id_kind
== C_ID_CLASSNAME
761 && c_parser_peek_2nd_token (parser
)->type
== CPP_DOT
)
764 /* Labels do not start declarations. */
765 if (token
->type
== CPP_NAME
766 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
769 if (c_token_starts_declaration (token
))
772 if (c_parser_next_tokens_start_typename (parser
, cla_nonabstract_decl
))
778 /* Consume the next token from PARSER. */
781 c_parser_consume_token (c_parser
*parser
)
783 gcc_assert (parser
->tokens_avail
>= 1);
784 gcc_assert (parser
->tokens
[0].type
!= CPP_EOF
);
785 gcc_assert (!parser
->in_pragma
|| parser
->tokens
[0].type
!= CPP_PRAGMA_EOL
);
786 gcc_assert (parser
->error
|| parser
->tokens
[0].type
!= CPP_PRAGMA
);
787 parser
->last_token_location
= parser
->tokens
[0].location
;
788 if (parser
->tokens
!= &parser
->tokens_buf
[0])
790 else if (parser
->tokens_avail
== 2)
791 parser
->tokens
[0] = parser
->tokens
[1];
792 parser
->tokens_avail
--;
795 /* Expect the current token to be a #pragma. Consume it and remember
796 that we've begun parsing a pragma. */
799 c_parser_consume_pragma (c_parser
*parser
)
801 gcc_assert (!parser
->in_pragma
);
802 gcc_assert (parser
->tokens_avail
>= 1);
803 gcc_assert (parser
->tokens
[0].type
== CPP_PRAGMA
);
804 if (parser
->tokens
!= &parser
->tokens_buf
[0])
806 else if (parser
->tokens_avail
== 2)
807 parser
->tokens
[0] = parser
->tokens
[1];
808 parser
->tokens_avail
--;
809 parser
->in_pragma
= true;
812 /* Update the global input_location from TOKEN. */
814 c_parser_set_source_position_from_token (c_token
*token
)
816 if (token
->type
!= CPP_EOF
)
818 input_location
= token
->location
;
822 /* Helper function for c_parser_error.
823 Having peeked a token of kind TOK1_KIND that might signify
824 a conflict marker, peek successor tokens to determine
825 if we actually do have a conflict marker.
826 Specifically, we consider a run of 7 '<', '=' or '>' characters
827 at the start of a line as a conflict marker.
828 These come through the lexer as three pairs and a single,
829 e.g. three CPP_LSHIFT ("<<") and a CPP_LESS ('<').
830 If it returns true, *OUT_LOC is written to with the location/range
834 c_parser_peek_conflict_marker (c_parser
*parser
, enum cpp_ttype tok1_kind
,
837 c_token
*token2
= c_parser_peek_2nd_token (parser
);
838 if (token2
->type
!= tok1_kind
)
840 c_token
*token3
= c_parser_peek_nth_token (parser
, 3);
841 if (token3
->type
!= tok1_kind
)
843 c_token
*token4
= c_parser_peek_nth_token (parser
, 4);
844 if (token4
->type
!= conflict_marker_get_final_tok_kind (tok1_kind
))
847 /* It must be at the start of the line. */
848 location_t start_loc
= c_parser_peek_token (parser
)->location
;
849 if (LOCATION_COLUMN (start_loc
) != 1)
852 /* We have a conflict marker. Construct a location of the form:
855 with start == caret, finishing at the end of the marker. */
856 location_t finish_loc
= get_finish (token4
->location
);
857 *out_loc
= make_location (start_loc
, start_loc
, finish_loc
);
862 /* Issue a diagnostic of the form
863 FILE:LINE: MESSAGE before TOKEN
864 where TOKEN is the next token in the input stream of PARSER.
865 MESSAGE (specified by the caller) is usually of the form "expected
868 Use RICHLOC as the location of the diagnostic.
870 Do not issue a diagnostic if still recovering from an error.
872 Return true iff an error was actually emitted.
874 ??? This is taken from the C++ parser, but building up messages in
875 this way is not i18n-friendly and some other approach should be
879 c_parser_error_richloc (c_parser
*parser
, const char *gmsgid
,
880 rich_location
*richloc
)
882 c_token
*token
= c_parser_peek_token (parser
);
885 parser
->error
= true;
889 /* If this is actually a conflict marker, report it as such. */
890 if (token
->type
== CPP_LSHIFT
891 || token
->type
== CPP_RSHIFT
892 || token
->type
== CPP_EQ_EQ
)
895 if (c_parser_peek_conflict_marker (parser
, token
->type
, &loc
))
897 error_at (loc
, "version control conflict marker in file");
902 c_parse_error (gmsgid
,
903 /* Because c_parse_error does not understand
904 CPP_KEYWORD, keywords are treated like
906 (token
->type
== CPP_KEYWORD
? CPP_NAME
: token
->type
),
907 /* ??? The C parser does not save the cpp flags of a
908 token, we need to pass 0 here and we will not get
909 the source spelling of some tokens but rather the
910 canonical spelling. */
911 token
->value
, /*flags=*/0, richloc
);
915 /* As c_parser_error_richloc, but issue the message at the
916 location of PARSER's next token, or at input_location
917 if the next token is EOF. */
920 c_parser_error (c_parser
*parser
, const char *gmsgid
)
922 c_token
*token
= c_parser_peek_token (parser
);
923 c_parser_set_source_position_from_token (token
);
924 rich_location
richloc (line_table
, input_location
);
925 return c_parser_error_richloc (parser
, gmsgid
, &richloc
);
928 /* Some tokens naturally come in pairs e.g.'(' and ')'.
929 This class is for tracking such a matching pair of symbols.
930 In particular, it tracks the location of the first token,
931 so that if the second token is missing, we can highlight the
932 location of the first token when notifying the user about the
935 template <typename traits_t
>
939 /* token_pair's ctor. */
940 token_pair () : m_open_loc (UNKNOWN_LOCATION
) {}
942 /* If the next token is the opening symbol for this pair, consume it and
944 Otherwise, issue an error and return false.
945 In either case, record the location of the opening token. */
947 bool require_open (c_parser
*parser
)
949 c_token
*token
= c_parser_peek_token (parser
);
951 m_open_loc
= token
->location
;
953 return c_parser_require (parser
, traits_t::open_token_type
,
954 traits_t::open_gmsgid
);
957 /* Consume the next token from PARSER, recording its location as
958 that of the opening token within the pair. */
960 void consume_open (c_parser
*parser
)
962 c_token
*token
= c_parser_peek_token (parser
);
963 gcc_assert (token
->type
== traits_t::open_token_type
);
964 m_open_loc
= token
->location
;
965 c_parser_consume_token (parser
);
968 /* If the next token is the closing symbol for this pair, consume it
970 Otherwise, issue an error, highlighting the location of the
971 corresponding opening token, and return false. */
973 bool require_close (c_parser
*parser
) const
975 return c_parser_require (parser
, traits_t::close_token_type
,
976 traits_t::close_gmsgid
, m_open_loc
);
979 /* Like token_pair::require_close, except that tokens will be skipped
980 until the desired token is found. An error message is still produced
981 if the next token is not as expected. */
983 void skip_until_found_close (c_parser
*parser
) const
985 c_parser_skip_until_found (parser
, traits_t::close_token_type
,
986 traits_t::close_gmsgid
, m_open_loc
);
990 location_t m_open_loc
;
993 /* Traits for token_pair<T> for tracking matching pairs of parentheses. */
995 struct matching_paren_traits
997 static const enum cpp_ttype open_token_type
= CPP_OPEN_PAREN
;
998 static const char * const open_gmsgid
;
999 static const enum cpp_ttype close_token_type
= CPP_CLOSE_PAREN
;
1000 static const char * const close_gmsgid
;
1003 const char * const matching_paren_traits::open_gmsgid
= "expected %<(%>";
1004 const char * const matching_paren_traits::close_gmsgid
= "expected %<)%>";
1006 /* "matching_parens" is a token_pair<T> class for tracking matching
1007 pairs of parentheses. */
1009 typedef token_pair
<matching_paren_traits
> matching_parens
;
1011 /* Traits for token_pair<T> for tracking matching pairs of braces. */
1013 struct matching_brace_traits
1015 static const enum cpp_ttype open_token_type
= CPP_OPEN_BRACE
;
1016 static const char * const open_gmsgid
;
1017 static const enum cpp_ttype close_token_type
= CPP_CLOSE_BRACE
;
1018 static const char * const close_gmsgid
;
1021 const char * const matching_brace_traits::open_gmsgid
= "expected %<{%>";
1022 const char * const matching_brace_traits::close_gmsgid
= "expected %<}%>";
1024 /* "matching_braces" is a token_pair<T> class for tracking matching
1027 typedef token_pair
<matching_brace_traits
> matching_braces
;
1029 /* Get a description of the matching symbol to TYPE e.g. "(" for
1033 get_matching_symbol (enum cpp_ttype type
)
1040 case CPP_CLOSE_PAREN
:
1042 case CPP_CLOSE_BRACE
:
1047 /* If the next token is of the indicated TYPE, consume it. Otherwise,
1048 issue the error MSGID. If MSGID is NULL then a message has already
1049 been produced and no message will be produced this time. Returns
1050 true if found, false otherwise.
1052 If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1053 within any error as the location of an "opening" token matching
1054 the close token TYPE (e.g. the location of the '(' when TYPE is
1057 If TYPE_IS_UNIQUE is true (the default) then msgid describes exactly
1058 one type (e.g. "expected %<)%>") and thus it may be reasonable to
1059 attempt to generate a fix-it hint for the problem.
1060 Otherwise msgid describes multiple token types (e.g.
1061 "expected %<;%>, %<,%> or %<)%>"), and thus we shouldn't attempt to
1062 generate a fix-it hint. */
1065 c_parser_require (c_parser
*parser
,
1066 enum cpp_ttype type
,
1068 location_t matching_location
,
1069 bool type_is_unique
)
1071 if (c_parser_next_token_is (parser
, type
))
1073 c_parser_consume_token (parser
);
1078 location_t next_token_loc
= c_parser_peek_token (parser
)->location
;
1079 gcc_rich_location
richloc (next_token_loc
);
1081 /* Potentially supply a fix-it hint, suggesting to add the
1082 missing token immediately after the *previous* token.
1083 This may move the primary location within richloc. */
1084 if (!parser
->error
&& type_is_unique
)
1085 maybe_suggest_missing_token_insertion (&richloc
, type
,
1086 parser
->last_token_location
);
1088 /* If matching_location != UNKNOWN_LOCATION, highlight it.
1089 Attempt to consolidate diagnostics by printing it as a
1090 secondary range within the main diagnostic. */
1091 bool added_matching_location
= false;
1092 if (matching_location
!= UNKNOWN_LOCATION
)
1093 added_matching_location
1094 = richloc
.add_location_if_nearby (matching_location
);
1096 if (c_parser_error_richloc (parser
, msgid
, &richloc
))
1097 /* If we weren't able to consolidate matching_location, then
1098 print it as a secondary diagnostic. */
1099 if (matching_location
!= UNKNOWN_LOCATION
&& !added_matching_location
)
1100 inform (matching_location
, "to match this %qs",
1101 get_matching_symbol (type
));
1107 /* If the next token is the indicated keyword, consume it. Otherwise,
1108 issue the error MSGID. Returns true if found, false otherwise. */
1111 c_parser_require_keyword (c_parser
*parser
,
1115 if (c_parser_next_token_is_keyword (parser
, keyword
))
1117 c_parser_consume_token (parser
);
1122 c_parser_error (parser
, msgid
);
1127 /* Like c_parser_require, except that tokens will be skipped until the
1128 desired token is found. An error message is still produced if the
1129 next token is not as expected. If MSGID is NULL then a message has
1130 already been produced and no message will be produced this
1133 If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1134 within any error as the location of an "opening" token matching
1135 the close token TYPE (e.g. the location of the '(' when TYPE is
1136 CPP_CLOSE_PAREN). */
1139 c_parser_skip_until_found (c_parser
*parser
,
1140 enum cpp_ttype type
,
1142 location_t matching_location
)
1144 unsigned nesting_depth
= 0;
1146 if (c_parser_require (parser
, type
, msgid
, matching_location
))
1149 /* Skip tokens until the desired token is found. */
1152 /* Peek at the next token. */
1153 c_token
*token
= c_parser_peek_token (parser
);
1154 /* If we've reached the token we want, consume it and stop. */
1155 if (token
->type
== type
&& !nesting_depth
)
1157 c_parser_consume_token (parser
);
1161 /* If we've run out of tokens, stop. */
1162 if (token
->type
== CPP_EOF
)
1164 if (token
->type
== CPP_PRAGMA_EOL
&& parser
->in_pragma
)
1166 if (token
->type
== CPP_OPEN_BRACE
1167 || token
->type
== CPP_OPEN_PAREN
1168 || token
->type
== CPP_OPEN_SQUARE
)
1170 else if (token
->type
== CPP_CLOSE_BRACE
1171 || token
->type
== CPP_CLOSE_PAREN
1172 || token
->type
== CPP_CLOSE_SQUARE
)
1174 if (nesting_depth
-- == 0)
1177 /* Consume this token. */
1178 c_parser_consume_token (parser
);
1180 parser
->error
= false;
1183 /* Skip tokens until the end of a parameter is found, but do not
1184 consume the comma, semicolon or closing delimiter. */
1187 c_parser_skip_to_end_of_parameter (c_parser
*parser
)
1189 unsigned nesting_depth
= 0;
1193 c_token
*token
= c_parser_peek_token (parser
);
1194 if ((token
->type
== CPP_COMMA
|| token
->type
== CPP_SEMICOLON
)
1197 /* If we've run out of tokens, stop. */
1198 if (token
->type
== CPP_EOF
)
1200 if (token
->type
== CPP_PRAGMA_EOL
&& parser
->in_pragma
)
1202 if (token
->type
== CPP_OPEN_BRACE
1203 || token
->type
== CPP_OPEN_PAREN
1204 || token
->type
== CPP_OPEN_SQUARE
)
1206 else if (token
->type
== CPP_CLOSE_BRACE
1207 || token
->type
== CPP_CLOSE_PAREN
1208 || token
->type
== CPP_CLOSE_SQUARE
)
1210 if (nesting_depth
-- == 0)
1213 /* Consume this token. */
1214 c_parser_consume_token (parser
);
1216 parser
->error
= false;
1219 /* Expect to be at the end of the pragma directive and consume an
1220 end of line marker. */
1223 c_parser_skip_to_pragma_eol (c_parser
*parser
, bool error_if_not_eol
= true)
1225 gcc_assert (parser
->in_pragma
);
1226 parser
->in_pragma
= false;
1228 if (error_if_not_eol
&& c_parser_peek_token (parser
)->type
!= CPP_PRAGMA_EOL
)
1229 c_parser_error (parser
, "expected end of line");
1231 cpp_ttype token_type
;
1234 c_token
*token
= c_parser_peek_token (parser
);
1235 token_type
= token
->type
;
1236 if (token_type
== CPP_EOF
)
1238 c_parser_consume_token (parser
);
1240 while (token_type
!= CPP_PRAGMA_EOL
);
1242 parser
->error
= false;
1245 /* Skip tokens until we have consumed an entire block, or until we
1246 have consumed a non-nested ';'. */
1249 c_parser_skip_to_end_of_block_or_statement (c_parser
*parser
)
1251 unsigned nesting_depth
= 0;
1252 bool save_error
= parser
->error
;
1258 /* Peek at the next token. */
1259 token
= c_parser_peek_token (parser
);
1261 switch (token
->type
)
1266 case CPP_PRAGMA_EOL
:
1267 if (parser
->in_pragma
)
1272 /* If the next token is a ';', we have reached the
1273 end of the statement. */
1276 /* Consume the ';'. */
1277 c_parser_consume_token (parser
);
1282 case CPP_CLOSE_BRACE
:
1283 /* If the next token is a non-nested '}', then we have
1284 reached the end of the current block. */
1285 if (nesting_depth
== 0 || --nesting_depth
== 0)
1287 c_parser_consume_token (parser
);
1292 case CPP_OPEN_BRACE
:
1293 /* If it the next token is a '{', then we are entering a new
1294 block. Consume the entire block. */
1299 /* If we see a pragma, consume the whole thing at once. We
1300 have some safeguards against consuming pragmas willy-nilly.
1301 Normally, we'd expect to be here with parser->error set,
1302 which disables these safeguards. But it's possible to get
1303 here for secondary error recovery, after parser->error has
1305 c_parser_consume_pragma (parser
);
1306 c_parser_skip_to_pragma_eol (parser
);
1307 parser
->error
= save_error
;
1314 c_parser_consume_token (parser
);
1318 parser
->error
= false;
1321 /* CPP's options (initialized by c-opts.c). */
1322 extern cpp_options
*cpp_opts
;
1324 /* Save the warning flags which are controlled by __extension__. */
1327 disable_extension_diagnostics (void)
1330 | (warn_pointer_arith
<< 1)
1331 | (warn_traditional
<< 2)
1333 | (warn_long_long
<< 4)
1334 | (warn_cxx_compat
<< 5)
1335 | (warn_overlength_strings
<< 6)
1336 /* warn_c90_c99_compat has three states: -1/0/1, so we must
1337 play tricks to properly restore it. */
1338 | ((warn_c90_c99_compat
== 1) << 7)
1339 | ((warn_c90_c99_compat
== -1) << 8)
1340 /* Similarly for warn_c99_c11_compat. */
1341 | ((warn_c99_c11_compat
== 1) << 9)
1342 | ((warn_c99_c11_compat
== -1) << 10)
1343 /* Similarly for warn_c11_c2x_compat. */
1344 | ((warn_c11_c2x_compat
== 1) << 11)
1345 | ((warn_c11_c2x_compat
== -1) << 12)
1347 cpp_opts
->cpp_pedantic
= pedantic
= 0;
1348 warn_pointer_arith
= 0;
1349 cpp_opts
->cpp_warn_traditional
= warn_traditional
= 0;
1351 cpp_opts
->cpp_warn_long_long
= warn_long_long
= 0;
1352 warn_cxx_compat
= 0;
1353 warn_overlength_strings
= 0;
1354 warn_c90_c99_compat
= 0;
1355 warn_c99_c11_compat
= 0;
1356 warn_c11_c2x_compat
= 0;
1360 /* Restore the warning flags which are controlled by __extension__.
1361 FLAGS is the return value from disable_extension_diagnostics. */
1364 restore_extension_diagnostics (int flags
)
1366 cpp_opts
->cpp_pedantic
= pedantic
= flags
& 1;
1367 warn_pointer_arith
= (flags
>> 1) & 1;
1368 cpp_opts
->cpp_warn_traditional
= warn_traditional
= (flags
>> 2) & 1;
1369 flag_iso
= (flags
>> 3) & 1;
1370 cpp_opts
->cpp_warn_long_long
= warn_long_long
= (flags
>> 4) & 1;
1371 warn_cxx_compat
= (flags
>> 5) & 1;
1372 warn_overlength_strings
= (flags
>> 6) & 1;
1373 /* See above for why is this needed. */
1374 warn_c90_c99_compat
= (flags
>> 7) & 1 ? 1 : ((flags
>> 8) & 1 ? -1 : 0);
1375 warn_c99_c11_compat
= (flags
>> 9) & 1 ? 1 : ((flags
>> 10) & 1 ? -1 : 0);
1376 warn_c11_c2x_compat
= (flags
>> 11) & 1 ? 1 : ((flags
>> 12) & 1 ? -1 : 0);
1379 /* Helper data structure for parsing #pragma acc routine. */
1380 struct oacc_routine_data
{
1381 bool error_seen
; /* Set if error has been reported. */
1382 bool fndecl_seen
; /* Set if one fn decl/definition has been seen already. */
1387 static void c_parser_external_declaration (c_parser
*);
1388 static void c_parser_asm_definition (c_parser
*);
1389 static void c_parser_declaration_or_fndef (c_parser
*, bool, bool, bool,
1390 bool, bool, tree
*, vec
<c_token
>,
1391 struct oacc_routine_data
* = NULL
,
1393 static void c_parser_static_assert_declaration_no_semi (c_parser
*);
1394 static void c_parser_static_assert_declaration (c_parser
*);
1395 static struct c_typespec
c_parser_enum_specifier (c_parser
*);
1396 static struct c_typespec
c_parser_struct_or_union_specifier (c_parser
*);
1397 static tree
c_parser_struct_declaration (c_parser
*);
1398 static struct c_typespec
c_parser_typeof_specifier (c_parser
*);
1399 static tree
c_parser_alignas_specifier (c_parser
*);
1400 static struct c_declarator
*c_parser_direct_declarator (c_parser
*, bool,
1402 static struct c_declarator
*c_parser_direct_declarator_inner (c_parser
*,
1404 struct c_declarator
*);
1405 static struct c_arg_info
*c_parser_parms_declarator (c_parser
*, bool, tree
);
1406 static struct c_arg_info
*c_parser_parms_list_declarator (c_parser
*, tree
,
1408 static struct c_parm
*c_parser_parameter_declaration (c_parser
*, tree
);
1409 static tree
c_parser_simple_asm_expr (c_parser
*);
1410 static tree
c_parser_gnu_attributes (c_parser
*);
1411 static struct c_expr
c_parser_initializer (c_parser
*);
1412 static struct c_expr
c_parser_braced_init (c_parser
*, tree
, bool,
1414 static void c_parser_initelt (c_parser
*, struct obstack
*);
1415 static void c_parser_initval (c_parser
*, struct c_expr
*,
1417 static tree
c_parser_compound_statement (c_parser
*);
1418 static void c_parser_compound_statement_nostart (c_parser
*);
1419 static void c_parser_label (c_parser
*);
1420 static void c_parser_statement (c_parser
*, bool *, location_t
* = NULL
);
1421 static void c_parser_statement_after_labels (c_parser
*, bool *,
1422 vec
<tree
> * = NULL
);
1423 static tree
c_parser_c99_block_statement (c_parser
*, bool *,
1424 location_t
* = NULL
);
1425 static void c_parser_if_statement (c_parser
*, bool *, vec
<tree
> *);
1426 static void c_parser_switch_statement (c_parser
*, bool *);
1427 static void c_parser_while_statement (c_parser
*, bool, unsigned short, bool *);
1428 static void c_parser_do_statement (c_parser
*, bool, unsigned short);
1429 static void c_parser_for_statement (c_parser
*, bool, unsigned short, bool *);
1430 static tree
c_parser_asm_statement (c_parser
*);
1431 static tree
c_parser_asm_operands (c_parser
*);
1432 static tree
c_parser_asm_goto_operands (c_parser
*);
1433 static tree
c_parser_asm_clobbers (c_parser
*);
1434 static struct c_expr
c_parser_expr_no_commas (c_parser
*, struct c_expr
*,
1436 static struct c_expr
c_parser_conditional_expression (c_parser
*,
1437 struct c_expr
*, tree
);
1438 static struct c_expr
c_parser_binary_expression (c_parser
*, struct c_expr
*,
1440 static struct c_expr
c_parser_cast_expression (c_parser
*, struct c_expr
*);
1441 static struct c_expr
c_parser_unary_expression (c_parser
*);
1442 static struct c_expr
c_parser_sizeof_expression (c_parser
*);
1443 static struct c_expr
c_parser_alignof_expression (c_parser
*);
1444 static struct c_expr
c_parser_postfix_expression (c_parser
*);
1445 static struct c_expr
c_parser_postfix_expression_after_paren_type (c_parser
*,
1446 struct c_type_name
*,
1448 static struct c_expr
c_parser_postfix_expression_after_primary (c_parser
*,
1451 static tree
c_parser_transaction (c_parser
*, enum rid
);
1452 static struct c_expr
c_parser_transaction_expression (c_parser
*, enum rid
);
1453 static tree
c_parser_transaction_cancel (c_parser
*);
1454 static struct c_expr
c_parser_expression (c_parser
*);
1455 static struct c_expr
c_parser_expression_conv (c_parser
*);
1456 static vec
<tree
, va_gc
> *c_parser_expr_list (c_parser
*, bool, bool,
1457 vec
<tree
, va_gc
> **, location_t
*,
1458 tree
*, vec
<location_t
> *,
1459 unsigned int * = NULL
);
1460 static struct c_expr
c_parser_has_attribute_expression (c_parser
*);
1462 static void c_parser_oacc_declare (c_parser
*);
1463 static void c_parser_oacc_enter_exit_data (c_parser
*, bool);
1464 static void c_parser_oacc_update (c_parser
*);
1465 static void c_parser_omp_construct (c_parser
*, bool *);
1466 static void c_parser_omp_threadprivate (c_parser
*);
1467 static void c_parser_omp_barrier (c_parser
*);
1468 static void c_parser_omp_depobj (c_parser
*);
1469 static void c_parser_omp_flush (c_parser
*);
1470 static tree
c_parser_omp_for_loop (location_t
, c_parser
*, enum tree_code
,
1471 tree
, tree
*, bool *);
1472 static void c_parser_omp_taskwait (c_parser
*);
1473 static void c_parser_omp_taskyield (c_parser
*);
1474 static void c_parser_omp_cancel (c_parser
*);
1476 enum pragma_context
{ pragma_external
, pragma_struct
, pragma_param
,
1477 pragma_stmt
, pragma_compound
};
1478 static bool c_parser_pragma (c_parser
*, enum pragma_context
, bool *);
1479 static void c_parser_omp_cancellation_point (c_parser
*, enum pragma_context
);
1480 static bool c_parser_omp_target (c_parser
*, enum pragma_context
, bool *);
1481 static void c_parser_omp_end_declare_target (c_parser
*);
1482 static void c_parser_omp_declare (c_parser
*, enum pragma_context
);
1483 static void c_parser_omp_requires (c_parser
*);
1484 static bool c_parser_omp_ordered (c_parser
*, enum pragma_context
, bool *);
1485 static void c_parser_oacc_routine (c_parser
*, enum pragma_context
);
1487 /* These Objective-C parser functions are only ever called when
1488 compiling Objective-C. */
1489 static void c_parser_objc_class_definition (c_parser
*, tree
);
1490 static void c_parser_objc_class_instance_variables (c_parser
*);
1491 static void c_parser_objc_class_declaration (c_parser
*);
1492 static void c_parser_objc_alias_declaration (c_parser
*);
1493 static void c_parser_objc_protocol_definition (c_parser
*, tree
);
1494 static bool c_parser_objc_method_type (c_parser
*);
1495 static void c_parser_objc_method_definition (c_parser
*);
1496 static void c_parser_objc_methodprotolist (c_parser
*);
1497 static void c_parser_objc_methodproto (c_parser
*);
1498 static tree
c_parser_objc_method_decl (c_parser
*, bool, tree
*, tree
*);
1499 static tree
c_parser_objc_type_name (c_parser
*);
1500 static tree
c_parser_objc_protocol_refs (c_parser
*);
1501 static void c_parser_objc_try_catch_finally_statement (c_parser
*);
1502 static void c_parser_objc_synchronized_statement (c_parser
*);
1503 static tree
c_parser_objc_selector (c_parser
*);
1504 static tree
c_parser_objc_selector_arg (c_parser
*);
1505 static tree
c_parser_objc_receiver (c_parser
*);
1506 static tree
c_parser_objc_message_args (c_parser
*);
1507 static tree
c_parser_objc_keywordexpr (c_parser
*);
1508 static void c_parser_objc_at_property_declaration (c_parser
*);
1509 static void c_parser_objc_at_synthesize_declaration (c_parser
*);
1510 static void c_parser_objc_at_dynamic_declaration (c_parser
*);
1511 static bool c_parser_objc_diagnose_bad_element_prefix
1512 (c_parser
*, struct c_declspecs
*);
1514 static void c_parser_parse_rtl_body (c_parser
*parser
, char *start_with_pass
);
1516 /* Parse a translation unit (C90 6.7, C99 6.9, C11 6.9).
1519 external-declarations
1521 external-declarations:
1522 external-declaration
1523 external-declarations external-declaration
1532 c_parser_translation_unit (c_parser
*parser
)
1534 if (c_parser_next_token_is (parser
, CPP_EOF
))
1536 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
1537 "ISO C forbids an empty translation unit");
1541 void *obstack_position
= obstack_alloc (&parser_obstack
, 0);
1542 mark_valid_location_for_stdc_pragma (false);
1546 c_parser_external_declaration (parser
);
1547 obstack_free (&parser_obstack
, obstack_position
);
1549 while (c_parser_next_token_is_not (parser
, CPP_EOF
));
1554 FOR_EACH_VEC_ELT (incomplete_record_decls
, i
, decl
)
1555 if (DECL_SIZE (decl
) == NULL_TREE
&& TREE_TYPE (decl
) != error_mark_node
)
1556 error ("storage size of %q+D isn%'t known", decl
);
1559 /* Parse an external declaration (C90 6.7, C99 6.9, C11 6.9).
1561 external-declaration:
1567 external-declaration:
1570 __extension__ external-declaration
1574 external-declaration:
1575 objc-class-definition
1576 objc-class-declaration
1577 objc-alias-declaration
1578 objc-protocol-definition
1579 objc-method-definition
1584 c_parser_external_declaration (c_parser
*parser
)
1587 switch (c_parser_peek_token (parser
)->type
)
1590 switch (c_parser_peek_token (parser
)->keyword
)
1593 ext
= disable_extension_diagnostics ();
1594 c_parser_consume_token (parser
);
1595 c_parser_external_declaration (parser
);
1596 restore_extension_diagnostics (ext
);
1599 c_parser_asm_definition (parser
);
1601 case RID_AT_INTERFACE
:
1602 case RID_AT_IMPLEMENTATION
:
1603 gcc_assert (c_dialect_objc ());
1604 c_parser_objc_class_definition (parser
, NULL_TREE
);
1607 gcc_assert (c_dialect_objc ());
1608 c_parser_objc_class_declaration (parser
);
1611 gcc_assert (c_dialect_objc ());
1612 c_parser_objc_alias_declaration (parser
);
1614 case RID_AT_PROTOCOL
:
1615 gcc_assert (c_dialect_objc ());
1616 c_parser_objc_protocol_definition (parser
, NULL_TREE
);
1618 case RID_AT_PROPERTY
:
1619 gcc_assert (c_dialect_objc ());
1620 c_parser_objc_at_property_declaration (parser
);
1622 case RID_AT_SYNTHESIZE
:
1623 gcc_assert (c_dialect_objc ());
1624 c_parser_objc_at_synthesize_declaration (parser
);
1626 case RID_AT_DYNAMIC
:
1627 gcc_assert (c_dialect_objc ());
1628 c_parser_objc_at_dynamic_declaration (parser
);
1631 gcc_assert (c_dialect_objc ());
1632 c_parser_consume_token (parser
);
1633 objc_finish_implementation ();
1640 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
1641 "ISO C does not allow extra %<;%> outside of a function");
1642 c_parser_consume_token (parser
);
1645 mark_valid_location_for_stdc_pragma (true);
1646 c_parser_pragma (parser
, pragma_external
, NULL
);
1647 mark_valid_location_for_stdc_pragma (false);
1651 if (c_dialect_objc ())
1653 c_parser_objc_method_definition (parser
);
1656 /* Else fall through, and yield a syntax error trying to parse
1657 as a declaration or function definition. */
1661 /* A declaration or a function definition (or, in Objective-C,
1662 an @interface or @protocol with prefix attributes). We can
1663 only tell which after parsing the declaration specifiers, if
1664 any, and the first declarator. */
1665 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
1671 static void c_finish_omp_declare_simd (c_parser
*, tree
, tree
, vec
<c_token
>);
1672 static void c_finish_oacc_routine (struct oacc_routine_data
*, tree
, bool);
1674 /* Build and add a DEBUG_BEGIN_STMT statement with location LOC. */
1677 add_debug_begin_stmt (location_t loc
)
1679 /* Don't add DEBUG_BEGIN_STMTs outside of functions, see PR84721. */
1680 if (!MAY_HAVE_DEBUG_MARKER_STMTS
|| !building_stmt_list_p ())
1683 tree stmt
= build0 (DEBUG_BEGIN_STMT
, void_type_node
);
1684 SET_EXPR_LOCATION (stmt
, loc
);
1688 /* Parse a declaration or function definition (C90 6.5, 6.7.1, C99
1689 6.7, 6.9.1, C11 6.7, 6.9.1). If FNDEF_OK is true, a function definition
1690 is accepted; otherwise (old-style parameter declarations) only other
1691 declarations are accepted. If STATIC_ASSERT_OK is true, a static
1692 assertion is accepted; otherwise (old-style parameter declarations)
1693 it is not. If NESTED is true, we are inside a function or parsing
1694 old-style parameter declarations; any functions encountered are
1695 nested functions and declaration specifiers are required; otherwise
1696 we are at top level and functions are normal functions and
1697 declaration specifiers may be optional. If EMPTY_OK is true, empty
1698 declarations are OK (subject to all other constraints); otherwise
1699 (old-style parameter declarations) they are diagnosed. If
1700 START_ATTR_OK is true, the declaration specifiers may start with
1701 attributes; otherwise they may not.
1702 OBJC_FOREACH_OBJECT_DECLARATION can be used to get back the parsed
1703 declaration when parsing an Objective-C foreach statement.
1704 FALLTHRU_ATTR_P is used to signal whether this function parsed
1705 "__attribute__((fallthrough));".
1708 declaration-specifiers init-declarator-list[opt] ;
1709 static_assert-declaration
1711 function-definition:
1712 declaration-specifiers[opt] declarator declaration-list[opt]
1717 declaration-list declaration
1719 init-declarator-list:
1721 init-declarator-list , init-declarator
1724 declarator simple-asm-expr[opt] gnu-attributes[opt]
1725 declarator simple-asm-expr[opt] gnu-attributes[opt] = initializer
1729 nested-function-definition:
1730 declaration-specifiers declarator declaration-list[opt]
1736 gnu-attributes objc-class-definition
1737 gnu-attributes objc-category-definition
1738 gnu-attributes objc-protocol-definition
1740 The simple-asm-expr and gnu-attributes are GNU extensions.
1742 This function does not handle __extension__; that is handled in its
1743 callers. ??? Following the old parser, __extension__ may start
1744 external declarations, declarations in functions and declarations
1745 at the start of "for" loops, but not old-style parameter
1748 C99 requires declaration specifiers in a function definition; the
1749 absence is diagnosed through the diagnosis of implicit int. In GNU
1750 C we also allow but diagnose declarations without declaration
1751 specifiers, but only at top level (elsewhere they conflict with
1754 In Objective-C, declarations of the looping variable in a foreach
1755 statement are exceptionally terminated by 'in' (for example, 'for
1756 (NSObject *object in array) { ... }').
1761 threadprivate-directive
1765 gimple-function-definition:
1766 declaration-specifiers[opt] __GIMPLE (gimple-or-rtl-pass-list) declarator
1767 declaration-list[opt] compound-statement
1769 rtl-function-definition:
1770 declaration-specifiers[opt] __RTL (gimple-or-rtl-pass-list) declarator
1771 declaration-list[opt] compound-statement */
1774 c_parser_declaration_or_fndef (c_parser
*parser
, bool fndef_ok
,
1775 bool static_assert_ok
, bool empty_ok
,
1776 bool nested
, bool start_attr_ok
,
1777 tree
*objc_foreach_object_declaration
,
1778 vec
<c_token
> omp_declare_simd_clauses
,
1779 struct oacc_routine_data
*oacc_routine_data
,
1780 bool *fallthru_attr_p
)
1782 struct c_declspecs
*specs
;
1784 tree all_prefix_attrs
;
1785 bool diagnosed_no_specs
= false;
1786 location_t here
= c_parser_peek_token (parser
)->location
;
1788 add_debug_begin_stmt (c_parser_peek_token (parser
)->location
);
1790 if (static_assert_ok
1791 && c_parser_next_token_is_keyword (parser
, RID_STATIC_ASSERT
))
1793 c_parser_static_assert_declaration (parser
);
1796 specs
= build_null_declspecs ();
1798 /* Try to detect an unknown type name when we have "A B" or "A *B". */
1799 if (c_parser_peek_token (parser
)->type
== CPP_NAME
1800 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
1801 && (c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
1802 || c_parser_peek_2nd_token (parser
)->type
== CPP_MULT
)
1803 && (!nested
|| !lookup_name (c_parser_peek_token (parser
)->value
)))
1805 tree name
= c_parser_peek_token (parser
)->value
;
1807 /* Issue a warning about NAME being an unknown type name, perhaps
1808 with some kind of hint.
1809 If the user forgot a "struct" etc, suggest inserting
1810 it. Otherwise, attempt to look for misspellings. */
1811 gcc_rich_location
richloc (here
);
1812 if (tag_exists_p (RECORD_TYPE
, name
))
1814 /* This is not C++ with its implicit typedef. */
1815 richloc
.add_fixit_insert_before ("struct ");
1817 "unknown type name %qE;"
1818 " use %<struct%> keyword to refer to the type",
1821 else if (tag_exists_p (UNION_TYPE
, name
))
1823 richloc
.add_fixit_insert_before ("union ");
1825 "unknown type name %qE;"
1826 " use %<union%> keyword to refer to the type",
1829 else if (tag_exists_p (ENUMERAL_TYPE
, name
))
1831 richloc
.add_fixit_insert_before ("enum ");
1833 "unknown type name %qE;"
1834 " use %<enum%> keyword to refer to the type",
1839 auto_diagnostic_group d
;
1840 name_hint hint
= lookup_name_fuzzy (name
, FUZZY_LOOKUP_TYPENAME
,
1842 if (const char *suggestion
= hint
.suggestion ())
1844 richloc
.add_fixit_replace (suggestion
);
1846 "unknown type name %qE; did you mean %qs?",
1850 error_at (here
, "unknown type name %qE", name
);
1853 /* Parse declspecs normally to get a correct pointer type, but avoid
1854 a further "fails to be a type name" error. Refuse nested functions
1855 since it is not how the user likely wants us to recover. */
1856 c_parser_peek_token (parser
)->type
= CPP_KEYWORD
;
1857 c_parser_peek_token (parser
)->keyword
= RID_VOID
;
1858 c_parser_peek_token (parser
)->value
= error_mark_node
;
1862 c_parser_declspecs (parser
, specs
, true, true, start_attr_ok
,
1863 true, true, cla_nonabstract_decl
);
1866 c_parser_skip_to_end_of_block_or_statement (parser
);
1869 if (nested
&& !specs
->declspecs_seen_p
)
1871 c_parser_error (parser
, "expected declaration specifiers");
1872 c_parser_skip_to_end_of_block_or_statement (parser
);
1876 finish_declspecs (specs
);
1877 bool auto_type_p
= specs
->typespec_word
== cts_auto_type
;
1878 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
1881 error_at (here
, "%<__auto_type%> in empty declaration");
1882 else if (specs
->typespec_kind
== ctsk_none
1883 && attribute_fallthrough_p (specs
->attrs
))
1885 if (fallthru_attr_p
!= NULL
)
1886 *fallthru_attr_p
= true;
1887 tree fn
= build_call_expr_internal_loc (here
, IFN_FALLTHROUGH
,
1895 shadow_tag_warned (specs
, 1);
1896 pedwarn (here
, 0, "empty declaration");
1898 c_parser_consume_token (parser
);
1899 if (oacc_routine_data
)
1900 c_finish_oacc_routine (oacc_routine_data
, NULL_TREE
, false);
1904 /* Provide better error recovery. Note that a type name here is usually
1905 better diagnosed as a redeclaration. */
1907 && specs
->typespec_kind
== ctsk_tagdef
1908 && c_parser_next_token_starts_declspecs (parser
)
1909 && !c_parser_next_token_is (parser
, CPP_NAME
))
1911 c_parser_error (parser
, "expected %<;%>, identifier or %<(%>");
1912 parser
->error
= false;
1913 shadow_tag_warned (specs
, 1);
1916 else if (c_dialect_objc () && !auto_type_p
)
1918 /* Prefix attributes are an error on method decls. */
1919 switch (c_parser_peek_token (parser
)->type
)
1923 if (c_parser_objc_diagnose_bad_element_prefix (parser
, specs
))
1927 warning_at (c_parser_peek_token (parser
)->location
,
1929 "prefix attributes are ignored for methods");
1930 specs
->attrs
= NULL_TREE
;
1933 c_parser_objc_method_definition (parser
);
1935 c_parser_objc_methodproto (parser
);
1941 /* This is where we parse 'attributes @interface ...',
1942 'attributes @implementation ...', 'attributes @protocol ...'
1943 (where attributes could be, for example, __attribute__
1946 switch (c_parser_peek_token (parser
)->keyword
)
1948 case RID_AT_INTERFACE
:
1950 if (c_parser_objc_diagnose_bad_element_prefix (parser
, specs
))
1952 c_parser_objc_class_definition (parser
, specs
->attrs
);
1956 case RID_AT_IMPLEMENTATION
:
1958 if (c_parser_objc_diagnose_bad_element_prefix (parser
, specs
))
1962 warning_at (c_parser_peek_token (parser
)->location
,
1964 "prefix attributes are ignored for implementations");
1965 specs
->attrs
= NULL_TREE
;
1967 c_parser_objc_class_definition (parser
, NULL_TREE
);
1971 case RID_AT_PROTOCOL
:
1973 if (c_parser_objc_diagnose_bad_element_prefix (parser
, specs
))
1975 c_parser_objc_protocol_definition (parser
, specs
->attrs
);
1982 case RID_AT_PROPERTY
:
1985 c_parser_error (parser
, "unexpected attribute");
1986 specs
->attrs
= NULL
;
1993 else if (attribute_fallthrough_p (specs
->attrs
))
1994 warning_at (here
, OPT_Wattributes
,
1995 "%<fallthrough%> attribute not followed by %<;%>");
1997 pending_xref_error ();
1998 prefix_attrs
= specs
->attrs
;
1999 all_prefix_attrs
= prefix_attrs
;
2000 specs
->attrs
= NULL_TREE
;
2003 struct c_declarator
*declarator
;
2006 tree fnbody
= NULL_TREE
;
2007 /* Declaring either one or more declarators (in which case we
2008 should diagnose if there were no declaration specifiers) or a
2009 function definition (in which case the diagnostic for
2010 implicit int suffices). */
2011 declarator
= c_parser_declarator (parser
,
2012 specs
->typespec_kind
!= ctsk_none
,
2013 C_DTR_NORMAL
, &dummy
);
2014 if (declarator
== NULL
)
2016 if (omp_declare_simd_clauses
.exists ())
2017 c_finish_omp_declare_simd (parser
, NULL_TREE
, NULL_TREE
,
2018 omp_declare_simd_clauses
);
2019 if (oacc_routine_data
)
2020 c_finish_oacc_routine (oacc_routine_data
, NULL_TREE
, false);
2021 c_parser_skip_to_end_of_block_or_statement (parser
);
2024 if (auto_type_p
&& declarator
->kind
!= cdk_id
)
2027 "%<__auto_type%> requires a plain identifier"
2029 c_parser_skip_to_end_of_block_or_statement (parser
);
2032 if (c_parser_next_token_is (parser
, CPP_EQ
)
2033 || c_parser_next_token_is (parser
, CPP_COMMA
)
2034 || c_parser_next_token_is (parser
, CPP_SEMICOLON
)
2035 || c_parser_next_token_is_keyword (parser
, RID_ASM
)
2036 || c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
)
2037 || c_parser_next_token_is_keyword (parser
, RID_IN
))
2039 tree asm_name
= NULL_TREE
;
2040 tree postfix_attrs
= NULL_TREE
;
2041 if (!diagnosed_no_specs
&& !specs
->declspecs_seen_p
)
2043 diagnosed_no_specs
= true;
2044 pedwarn (here
, 0, "data definition has no type or storage class");
2046 /* Having seen a data definition, there cannot now be a
2047 function definition. */
2049 if (c_parser_next_token_is_keyword (parser
, RID_ASM
))
2050 asm_name
= c_parser_simple_asm_expr (parser
);
2051 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
2053 postfix_attrs
= c_parser_gnu_attributes (parser
);
2054 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
2056 /* This means there is an attribute specifier after
2057 the declarator in a function definition. Provide
2058 some more information for the user. */
2059 error_at (here
, "attributes should be specified before the "
2060 "declarator in a function definition");
2061 c_parser_skip_to_end_of_block_or_statement (parser
);
2065 if (c_parser_next_token_is (parser
, CPP_EQ
))
2069 location_t init_loc
;
2070 c_parser_consume_token (parser
);
2073 init_loc
= c_parser_peek_token (parser
)->location
;
2074 rich_location
richloc (line_table
, init_loc
);
2075 start_init (NULL_TREE
, asm_name
, global_bindings_p (), &richloc
);
2076 /* A parameter is initialized, which is invalid. Don't
2077 attempt to instrument the initializer. */
2078 int flag_sanitize_save
= flag_sanitize
;
2079 if (nested
&& !empty_ok
)
2081 init
= c_parser_expr_no_commas (parser
, NULL
);
2082 flag_sanitize
= flag_sanitize_save
;
2083 if (TREE_CODE (init
.value
) == COMPONENT_REF
2084 && DECL_C_BIT_FIELD (TREE_OPERAND (init
.value
, 1)))
2086 "%<__auto_type%> used with a bit-field"
2088 init
= convert_lvalue_to_rvalue (init_loc
, init
, true, true);
2089 tree init_type
= TREE_TYPE (init
.value
);
2090 /* As with typeof, remove all qualifiers from atomic types. */
2091 if (init_type
!= error_mark_node
&& TYPE_ATOMIC (init_type
))
2093 = c_build_qualified_type (init_type
, TYPE_UNQUALIFIED
);
2094 bool vm_type
= variably_modified_type_p (init_type
,
2097 init
.value
= save_expr (init
.value
);
2099 specs
->typespec_kind
= ctsk_typeof
;
2100 specs
->locations
[cdw_typedef
] = init_loc
;
2101 specs
->typedef_p
= true;
2102 specs
->type
= init_type
;
2105 bool maybe_const
= true;
2106 tree type_expr
= c_fully_fold (init
.value
, false,
2108 specs
->expr_const_operands
&= maybe_const
;
2110 specs
->expr
= build2 (COMPOUND_EXPR
,
2111 TREE_TYPE (type_expr
),
2112 specs
->expr
, type_expr
);
2114 specs
->expr
= type_expr
;
2116 d
= start_decl (declarator
, specs
, true,
2117 chainon (postfix_attrs
, all_prefix_attrs
));
2119 d
= error_mark_node
;
2120 if (omp_declare_simd_clauses
.exists ())
2121 c_finish_omp_declare_simd (parser
, d
, NULL_TREE
,
2122 omp_declare_simd_clauses
);
2126 /* The declaration of the variable is in effect while
2127 its initializer is parsed. */
2128 d
= start_decl (declarator
, specs
, true,
2129 chainon (postfix_attrs
, all_prefix_attrs
));
2131 d
= error_mark_node
;
2132 if (omp_declare_simd_clauses
.exists ())
2133 c_finish_omp_declare_simd (parser
, d
, NULL_TREE
,
2134 omp_declare_simd_clauses
);
2135 init_loc
= c_parser_peek_token (parser
)->location
;
2136 rich_location
richloc (line_table
, init_loc
);
2137 start_init (d
, asm_name
, global_bindings_p (), &richloc
);
2138 /* A parameter is initialized, which is invalid. Don't
2139 attempt to instrument the initializer. */
2140 int flag_sanitize_save
= flag_sanitize
;
2141 if (TREE_CODE (d
) == PARM_DECL
)
2143 init
= c_parser_initializer (parser
);
2144 flag_sanitize
= flag_sanitize_save
;
2147 if (oacc_routine_data
)
2148 c_finish_oacc_routine (oacc_routine_data
, d
, false);
2149 if (d
!= error_mark_node
)
2151 maybe_warn_string_init (init_loc
, TREE_TYPE (d
), init
);
2152 finish_decl (d
, init_loc
, init
.value
,
2153 init
.original_type
, asm_name
);
2161 "%<__auto_type%> requires an initialized "
2162 "data declaration");
2163 c_parser_skip_to_end_of_block_or_statement (parser
);
2166 tree d
= start_decl (declarator
, specs
, false,
2167 chainon (postfix_attrs
,
2170 && TREE_CODE (d
) == FUNCTION_DECL
2171 && DECL_ARGUMENTS (d
) == NULL_TREE
2172 && DECL_INITIAL (d
) == NULL_TREE
)
2174 /* Find the innermost declarator that is neither cdk_id
2176 const struct c_declarator
*decl
= declarator
;
2177 const struct c_declarator
*last_non_id_attrs
= NULL
;
2185 last_non_id_attrs
= decl
;
2186 decl
= decl
->declarator
;
2190 decl
= decl
->declarator
;
2201 /* If it exists and is cdk_function, use its parameters. */
2202 if (last_non_id_attrs
2203 && last_non_id_attrs
->kind
== cdk_function
)
2204 DECL_ARGUMENTS (d
) = last_non_id_attrs
->u
.arg_info
->parms
;
2206 if (omp_declare_simd_clauses
.exists ())
2208 tree parms
= NULL_TREE
;
2209 if (d
&& TREE_CODE (d
) == FUNCTION_DECL
)
2211 struct c_declarator
*ce
= declarator
;
2213 if (ce
->kind
== cdk_function
)
2215 parms
= ce
->u
.arg_info
->parms
;
2219 ce
= ce
->declarator
;
2222 temp_store_parm_decls (d
, parms
);
2223 c_finish_omp_declare_simd (parser
, d
, parms
,
2224 omp_declare_simd_clauses
);
2226 temp_pop_parm_decls ();
2228 if (oacc_routine_data
)
2229 c_finish_oacc_routine (oacc_routine_data
, d
, false);
2231 finish_decl (d
, UNKNOWN_LOCATION
, NULL_TREE
,
2232 NULL_TREE
, asm_name
);
2234 if (c_parser_next_token_is_keyword (parser
, RID_IN
))
2237 *objc_foreach_object_declaration
= d
;
2239 *objc_foreach_object_declaration
= error_mark_node
;
2242 if (c_parser_next_token_is (parser
, CPP_COMMA
))
2247 "%<__auto_type%> may only be used with"
2248 " a single declarator");
2249 c_parser_skip_to_end_of_block_or_statement (parser
);
2252 c_parser_consume_token (parser
);
2253 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
2254 all_prefix_attrs
= chainon (c_parser_gnu_attributes (parser
),
2257 all_prefix_attrs
= prefix_attrs
;
2260 else if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
2262 c_parser_consume_token (parser
);
2265 else if (c_parser_next_token_is_keyword (parser
, RID_IN
))
2267 /* This can only happen in Objective-C: we found the
2268 'in' that terminates the declaration inside an
2269 Objective-C foreach statement. Do not consume the
2270 token, so that the caller can use it to determine
2271 that this indeed is a foreach context. */
2276 c_parser_error (parser
, "expected %<,%> or %<;%>");
2277 c_parser_skip_to_end_of_block_or_statement (parser
);
2281 else if (auto_type_p
)
2284 "%<__auto_type%> requires an initialized data declaration");
2285 c_parser_skip_to_end_of_block_or_statement (parser
);
2290 c_parser_error (parser
, "expected %<=%>, %<,%>, %<;%>, "
2291 "%<asm%> or %<__attribute__%>");
2292 c_parser_skip_to_end_of_block_or_statement (parser
);
2295 /* Function definition (nested or otherwise). */
2298 pedwarn (here
, OPT_Wpedantic
, "ISO C forbids nested functions");
2299 c_push_function_context ();
2301 if (!start_function (specs
, declarator
, all_prefix_attrs
))
2303 /* At this point we've consumed:
2304 declaration-specifiers declarator
2305 and the next token isn't CPP_EQ, CPP_COMMA, CPP_SEMICOLON,
2306 RID_ASM, RID_ATTRIBUTE, or RID_IN,
2308 declaration-specifiers declarator
2309 aren't grokkable as a function definition, so we have
2311 gcc_assert (!c_parser_next_token_is (parser
, CPP_SEMICOLON
));
2312 if (c_parser_next_token_starts_declspecs (parser
))
2315 declaration-specifiers declarator decl-specs
2316 then assume we have a missing semicolon, which would
2318 declaration-specifiers declarator decl-specs
2321 <~~~~~~~~~ declaration ~~~~~~~~~~>
2322 Use c_parser_require to get an error with a fix-it hint. */
2323 c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>");
2324 parser
->error
= false;
2328 /* This can appear in many cases looking nothing like a
2329 function definition, so we don't give a more specific
2330 error suggesting there was one. */
2331 c_parser_error (parser
, "expected %<=%>, %<,%>, %<;%>, %<asm%> "
2332 "or %<__attribute__%>");
2335 c_pop_function_context ();
2339 if (DECL_DECLARED_INLINE_P (current_function_decl
))
2340 tv
= TV_PARSE_INLINE
;
2343 auto_timevar
at (g_timer
, tv
);
2345 /* Parse old-style parameter declarations. ??? Attributes are
2346 not allowed to start declaration specifiers here because of a
2347 syntax conflict between a function declaration with attribute
2348 suffix and a function definition with an attribute prefix on
2349 first old-style parameter declaration. Following the old
2350 parser, they are not accepted on subsequent old-style
2351 parameter declarations either. However, there is no
2352 ambiguity after the first declaration, nor indeed on the
2353 first as long as we don't allow postfix attributes after a
2354 declarator with a nonempty identifier list in a definition;
2355 and postfix attributes have never been accepted here in
2356 function definitions either. */
2357 while (c_parser_next_token_is_not (parser
, CPP_EOF
)
2358 && c_parser_next_token_is_not (parser
, CPP_OPEN_BRACE
))
2359 c_parser_declaration_or_fndef (parser
, false, false, false,
2360 true, false, NULL
, vNULL
);
2361 store_parm_decls ();
2362 if (omp_declare_simd_clauses
.exists ())
2363 c_finish_omp_declare_simd (parser
, current_function_decl
, NULL_TREE
,
2364 omp_declare_simd_clauses
);
2365 if (oacc_routine_data
)
2366 c_finish_oacc_routine (oacc_routine_data
, current_function_decl
, true);
2367 DECL_STRUCT_FUNCTION (current_function_decl
)->function_start_locus
2368 = c_parser_peek_token (parser
)->location
;
2370 /* If the definition was marked with __RTL, use the RTL parser now,
2371 consuming the function body. */
2372 if (specs
->declspec_il
== cdil_rtl
)
2374 c_parser_parse_rtl_body (parser
, specs
->gimple_or_rtl_pass
);
2376 /* Normally, store_parm_decls sets next_is_function_body,
2377 anticipating a function body. We need a push_scope/pop_scope
2378 pair to flush out this state, or subsequent function parsing
2386 /* If the definition was marked with __GIMPLE then parse the
2387 function body as GIMPLE. */
2388 else if (specs
->declspec_il
!= cdil_none
)
2390 bool saved
= in_late_binary_op
;
2391 in_late_binary_op
= true;
2392 c_parser_parse_gimple_body (parser
, specs
->gimple_or_rtl_pass
,
2394 specs
->entry_bb_count
);
2395 in_late_binary_op
= saved
;
2398 fnbody
= c_parser_compound_statement (parser
);
2399 tree fndecl
= current_function_decl
;
2402 tree decl
= current_function_decl
;
2403 /* Mark nested functions as needing static-chain initially.
2404 lower_nested_functions will recompute it but the
2405 DECL_STATIC_CHAIN flag is also used before that happens,
2406 by initializer_constant_valid_p. See gcc.dg/nested-fn-2.c. */
2407 DECL_STATIC_CHAIN (decl
) = 1;
2410 c_pop_function_context ();
2411 add_stmt (build_stmt (DECL_SOURCE_LOCATION (decl
), DECL_EXPR
, decl
));
2419 /* Get rid of the empty stmt list for GIMPLE/RTL. */
2420 if (specs
->declspec_il
!= cdil_none
)
2421 DECL_SAVED_TREE (fndecl
) = NULL_TREE
;
2427 /* Parse an asm-definition (asm() outside a function body). This is a
2435 c_parser_asm_definition (c_parser
*parser
)
2437 tree asm_str
= c_parser_simple_asm_expr (parser
);
2439 symtab
->finalize_toplevel_asm (asm_str
);
2440 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
2443 /* Parse a static assertion (C11 6.7.10).
2445 static_assert-declaration:
2446 static_assert-declaration-no-semi ;
2450 c_parser_static_assert_declaration (c_parser
*parser
)
2452 c_parser_static_assert_declaration_no_semi (parser
);
2454 || !c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
2455 c_parser_skip_to_end_of_block_or_statement (parser
);
2458 /* Parse a static assertion (C11 6.7.10), without the trailing
2461 static_assert-declaration-no-semi:
2462 _Static_assert ( constant-expression , string-literal )
2465 static_assert-declaration-no-semi:
2466 _Static_assert ( constant-expression )
2470 c_parser_static_assert_declaration_no_semi (c_parser
*parser
)
2472 location_t assert_loc
, value_loc
;
2474 tree string
= NULL_TREE
;
2476 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_STATIC_ASSERT
));
2477 assert_loc
= c_parser_peek_token (parser
)->location
;
2479 pedwarn_c99 (assert_loc
, OPT_Wpedantic
,
2480 "ISO C99 does not support %<_Static_assert%>");
2482 pedwarn_c99 (assert_loc
, OPT_Wpedantic
,
2483 "ISO C90 does not support %<_Static_assert%>");
2484 c_parser_consume_token (parser
);
2485 matching_parens parens
;
2486 if (!parens
.require_open (parser
))
2488 location_t value_tok_loc
= c_parser_peek_token (parser
)->location
;
2489 value
= c_parser_expr_no_commas (parser
, NULL
).value
;
2490 value_loc
= EXPR_LOC_OR_LOC (value
, value_tok_loc
);
2491 if (c_parser_next_token_is (parser
, CPP_COMMA
))
2493 c_parser_consume_token (parser
);
2494 switch (c_parser_peek_token (parser
)->type
)
2500 case CPP_UTF8STRING
:
2501 string
= c_parser_string_literal (parser
, false, true).value
;
2504 c_parser_error (parser
, "expected string literal");
2508 else if (flag_isoc11
)
2509 /* If pedantic for pre-C11, the use of _Static_assert itself will
2510 have been diagnosed, so do not also diagnose the use of this
2511 new C2X feature of _Static_assert. */
2512 pedwarn_c11 (assert_loc
, OPT_Wpedantic
,
2513 "ISO C11 does not support omitting the string in "
2514 "%<_Static_assert%>");
2515 parens
.require_close (parser
);
2517 if (!INTEGRAL_TYPE_P (TREE_TYPE (value
)))
2519 error_at (value_loc
, "expression in static assertion is not an integer");
2522 if (TREE_CODE (value
) != INTEGER_CST
)
2524 value
= c_fully_fold (value
, false, NULL
);
2525 /* Strip no-op conversions. */
2526 STRIP_TYPE_NOPS (value
);
2527 if (TREE_CODE (value
) == INTEGER_CST
)
2528 pedwarn (value_loc
, OPT_Wpedantic
, "expression in static assertion "
2529 "is not an integer constant expression");
2531 if (TREE_CODE (value
) != INTEGER_CST
)
2533 error_at (value_loc
, "expression in static assertion is not constant");
2536 constant_expression_warning (value
);
2537 if (integer_zerop (value
))
2540 error_at (assert_loc
, "static assertion failed: %E", string
);
2542 error_at (assert_loc
, "static assertion failed");
2546 /* Parse some declaration specifiers (possibly none) (C90 6.5, C99
2547 6.7, C11 6.7), adding them to SPECS (which may already include some).
2548 Storage class specifiers are accepted iff SCSPEC_OK; type
2549 specifiers are accepted iff TYPESPEC_OK; alignment specifiers are
2550 accepted iff ALIGNSPEC_OK; gnu-attributes are accepted at the start
2551 iff START_ATTR_OK; __auto_type is accepted iff AUTO_TYPE_OK.
2553 declaration-specifiers:
2554 storage-class-specifier declaration-specifiers[opt]
2555 type-specifier declaration-specifiers[opt]
2556 type-qualifier declaration-specifiers[opt]
2557 function-specifier declaration-specifiers[opt]
2558 alignment-specifier declaration-specifiers[opt]
2560 Function specifiers (inline) are from C99, and are currently
2561 handled as storage class specifiers, as is __thread. Alignment
2562 specifiers are from C11.
2564 C90 6.5.1, C99 6.7.1, C11 6.7.1:
2565 storage-class-specifier:
2573 (_Thread_local is new in C11.)
2575 C99 6.7.4, C11 6.7.4:
2580 (_Noreturn is new in C11.)
2582 C90 6.5.2, C99 6.7.2, C11 6.7.2:
2595 [_Imaginary removed in C99 TC2]
2596 struct-or-union-specifier
2599 atomic-type-specifier
2601 (_Bool and _Complex are new in C99.)
2602 (atomic-type-specifier is new in C11.)
2604 C90 6.5.3, C99 6.7.3, C11 6.7.3:
2610 address-space-qualifier
2613 (restrict is new in C99.)
2614 (_Atomic is new in C11.)
2618 declaration-specifiers:
2619 gnu-attributes declaration-specifiers[opt]
2625 identifier recognized by the target
2627 storage-class-specifier:
2641 (_Fract, _Accum, and _Sat are new from ISO/IEC DTR 18037:
2642 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1169.pdf)
2644 atomic-type-specifier
2645 _Atomic ( type-name )
2650 class-name objc-protocol-refs[opt]
2651 typedef-name objc-protocol-refs
2656 c_parser_declspecs (c_parser
*parser
, struct c_declspecs
*specs
,
2657 bool scspec_ok
, bool typespec_ok
, bool start_attr_ok
,
2658 bool alignspec_ok
, bool auto_type_ok
,
2659 enum c_lookahead_kind la
)
2661 bool attrs_ok
= start_attr_ok
;
2662 bool seen_type
= specs
->typespec_kind
!= ctsk_none
;
2665 gcc_assert (la
== cla_prefer_id
);
2667 while (c_parser_next_token_is (parser
, CPP_NAME
)
2668 || c_parser_next_token_is (parser
, CPP_KEYWORD
)
2669 || (c_dialect_objc () && c_parser_next_token_is (parser
, CPP_LESS
)))
2671 struct c_typespec t
;
2674 location_t loc
= c_parser_peek_token (parser
)->location
;
2676 /* If we cannot accept a type, exit if the next token must start
2677 one. Also, if we already have seen a tagged definition,
2678 a typename would be an error anyway and likely the user
2679 has simply forgotten a semicolon, so we exit. */
2680 if ((!typespec_ok
|| specs
->typespec_kind
== ctsk_tagdef
)
2681 && c_parser_next_tokens_start_typename (parser
, la
)
2682 && !c_parser_next_token_is_qualifier (parser
)
2683 && !c_parser_next_token_is_keyword (parser
, RID_ALIGNAS
))
2686 if (c_parser_next_token_is (parser
, CPP_NAME
))
2688 c_token
*name_token
= c_parser_peek_token (parser
);
2689 tree value
= name_token
->value
;
2690 c_id_kind kind
= name_token
->id_kind
;
2692 if (kind
== C_ID_ADDRSPACE
)
2695 = name_token
->keyword
- RID_FIRST_ADDR_SPACE
;
2696 declspecs_add_addrspace (name_token
->location
, specs
, as
);
2697 c_parser_consume_token (parser
);
2702 gcc_assert (!c_parser_next_token_is_qualifier (parser
));
2704 /* If we cannot accept a type, and the next token must start one,
2705 exit. Do the same if we already have seen a tagged definition,
2706 since it would be an error anyway and likely the user has simply
2707 forgotten a semicolon. */
2708 if (seen_type
|| !c_parser_next_tokens_start_typename (parser
, la
))
2711 /* Now at an unknown typename (C_ID_ID), a C_ID_TYPENAME or
2712 a C_ID_CLASSNAME. */
2713 c_parser_consume_token (parser
);
2716 if (kind
== C_ID_ID
)
2718 error_at (loc
, "unknown type name %qE", value
);
2719 t
.kind
= ctsk_typedef
;
2720 t
.spec
= error_mark_node
;
2722 else if (kind
== C_ID_TYPENAME
2723 && (!c_dialect_objc ()
2724 || c_parser_next_token_is_not (parser
, CPP_LESS
)))
2726 t
.kind
= ctsk_typedef
;
2727 /* For a typedef name, record the meaning, not the name.
2728 In case of 'foo foo, bar;'. */
2729 t
.spec
= lookup_name (value
);
2733 tree proto
= NULL_TREE
;
2734 gcc_assert (c_dialect_objc ());
2736 if (c_parser_next_token_is (parser
, CPP_LESS
))
2737 proto
= c_parser_objc_protocol_refs (parser
);
2738 t
.spec
= objc_get_protocol_qualified_type (value
, proto
);
2741 t
.expr_const_operands
= true;
2742 declspecs_add_type (name_token
->location
, specs
, t
);
2745 if (c_parser_next_token_is (parser
, CPP_LESS
))
2747 /* Make "<SomeProtocol>" equivalent to "id <SomeProtocol>" -
2748 nisse@lysator.liu.se. */
2750 gcc_assert (c_dialect_objc ());
2751 if (!typespec_ok
|| seen_type
)
2753 proto
= c_parser_objc_protocol_refs (parser
);
2755 t
.spec
= objc_get_protocol_qualified_type (NULL_TREE
, proto
);
2757 t
.expr_const_operands
= true;
2758 declspecs_add_type (loc
, specs
, t
);
2761 gcc_assert (c_parser_next_token_is (parser
, CPP_KEYWORD
));
2762 switch (c_parser_peek_token (parser
)->keyword
)
2775 /* TODO: Distinguish between function specifiers (inline, noreturn)
2776 and storage class specifiers, either here or in
2777 declspecs_add_scspec. */
2778 declspecs_add_scspec (loc
, specs
,
2779 c_parser_peek_token (parser
)->value
);
2780 c_parser_consume_token (parser
);
2812 if (c_dialect_objc ())
2813 parser
->objc_need_raw_identifier
= true;
2814 t
.kind
= ctsk_resword
;
2815 t
.spec
= c_parser_peek_token (parser
)->value
;
2817 t
.expr_const_operands
= true;
2818 declspecs_add_type (loc
, specs
, t
);
2819 c_parser_consume_token (parser
);
2826 t
= c_parser_enum_specifier (parser
);
2827 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE
, t
.spec
);
2828 declspecs_add_type (loc
, specs
, t
);
2836 t
= c_parser_struct_or_union_specifier (parser
);
2837 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE
, t
.spec
);
2838 declspecs_add_type (loc
, specs
, t
);
2841 /* ??? The old parser rejected typeof after other type
2842 specifiers, but is a syntax error the best way of
2844 if (!typespec_ok
|| seen_type
)
2848 t
= c_parser_typeof_specifier (parser
);
2849 declspecs_add_type (loc
, specs
, t
);
2852 /* C parser handling of Objective-C constructs needs
2853 checking for correct lvalue-to-rvalue conversions, and
2854 the code in build_modify_expr handling various
2855 Objective-C cases, and that in build_unary_op handling
2856 Objective-C cases for increment / decrement, also needs
2857 updating; uses of TYPE_MAIN_VARIANT in objc_compare_types
2858 and objc_types_are_equivalent may also need updates. */
2859 if (c_dialect_objc ())
2860 sorry ("%<_Atomic%> in Objective-C");
2862 pedwarn_c99 (loc
, OPT_Wpedantic
,
2863 "ISO C99 does not support the %<_Atomic%> qualifier");
2865 pedwarn_c99 (loc
, OPT_Wpedantic
,
2866 "ISO C90 does not support the %<_Atomic%> qualifier");
2869 value
= c_parser_peek_token (parser
)->value
;
2870 c_parser_consume_token (parser
);
2871 if (typespec_ok
&& c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
2873 /* _Atomic ( type-name ). */
2875 c_parser_consume_token (parser
);
2876 struct c_type_name
*type
= c_parser_type_name (parser
);
2877 t
.kind
= ctsk_typeof
;
2878 t
.spec
= error_mark_node
;
2880 t
.expr_const_operands
= true;
2882 t
.spec
= groktypename (type
, &t
.expr
,
2883 &t
.expr_const_operands
);
2884 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
2886 if (t
.spec
!= error_mark_node
)
2888 if (TREE_CODE (t
.spec
) == ARRAY_TYPE
)
2889 error_at (loc
, "%<_Atomic%>-qualified array type");
2890 else if (TREE_CODE (t
.spec
) == FUNCTION_TYPE
)
2891 error_at (loc
, "%<_Atomic%>-qualified function type");
2892 else if (TYPE_QUALS (t
.spec
) != TYPE_UNQUALIFIED
)
2893 error_at (loc
, "%<_Atomic%> applied to a qualified type");
2895 t
.spec
= c_build_qualified_type (t
.spec
, TYPE_QUAL_ATOMIC
);
2897 declspecs_add_type (loc
, specs
, t
);
2900 declspecs_add_qual (loc
, specs
, value
);
2906 declspecs_add_qual (loc
, specs
, c_parser_peek_token (parser
)->value
);
2907 c_parser_consume_token (parser
);
2912 attrs
= c_parser_gnu_attributes (parser
);
2913 declspecs_add_attrs (loc
, specs
, attrs
);
2918 align
= c_parser_alignas_specifier (parser
);
2919 declspecs_add_alignas (loc
, specs
, align
);
2923 error_at (loc
, "%<__GIMPLE%> only valid with %<-fgimple%>");
2924 c_parser_consume_token (parser
);
2925 specs
->declspec_il
= cdil_gimple
;
2926 specs
->locations
[cdw_gimple
] = loc
;
2927 c_parser_gimple_or_rtl_pass_list (parser
, specs
);
2930 c_parser_consume_token (parser
);
2931 specs
->declspec_il
= cdil_rtl
;
2932 specs
->locations
[cdw_rtl
] = loc
;
2933 c_parser_gimple_or_rtl_pass_list (parser
, specs
);
2942 /* Parse an enum specifier (C90 6.5.2.2, C99 6.7.2.2, C11 6.7.2.2).
2945 enum gnu-attributes[opt] identifier[opt] { enumerator-list }
2947 enum gnu-attributes[opt] identifier[opt] { enumerator-list , }
2949 enum gnu-attributes[opt] identifier
2951 The form with trailing comma is new in C99. The forms with
2952 gnu-attributes are GNU extensions. In GNU C, we accept any expression
2953 without commas in the syntax (assignment expressions, not just
2954 conditional expressions); assignment expressions will be diagnosed
2959 enumerator-list , enumerator
2962 enumeration-constant
2963 enumeration-constant = constant-expression
2968 enumeration-constant gnu-attributes[opt]
2969 enumeration-constant gnu-attributes[opt] = constant-expression
2973 static struct c_typespec
2974 c_parser_enum_specifier (c_parser
*parser
)
2976 struct c_typespec ret
;
2978 tree ident
= NULL_TREE
;
2979 location_t enum_loc
;
2980 location_t ident_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
2981 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ENUM
));
2982 c_parser_consume_token (parser
);
2983 attrs
= c_parser_gnu_attributes (parser
);
2984 enum_loc
= c_parser_peek_token (parser
)->location
;
2985 /* Set the location in case we create a decl now. */
2986 c_parser_set_source_position_from_token (c_parser_peek_token (parser
));
2987 if (c_parser_next_token_is (parser
, CPP_NAME
))
2989 ident
= c_parser_peek_token (parser
)->value
;
2990 ident_loc
= c_parser_peek_token (parser
)->location
;
2991 enum_loc
= ident_loc
;
2992 c_parser_consume_token (parser
);
2994 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
2996 /* Parse an enum definition. */
2997 struct c_enum_contents the_enum
;
3000 /* We chain the enumerators in reverse order, then put them in
3001 forward order at the end. */
3003 timevar_push (TV_PARSE_ENUM
);
3004 type
= start_enum (enum_loc
, &the_enum
, ident
);
3006 c_parser_consume_token (parser
);
3014 location_t comma_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
3015 location_t decl_loc
, value_loc
;
3016 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
3018 /* Give a nicer error for "enum {}". */
3019 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
)
3022 error_at (c_parser_peek_token (parser
)->location
,
3023 "empty enum is invalid");
3024 parser
->error
= true;
3027 c_parser_error (parser
, "expected identifier");
3028 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
, NULL
);
3029 values
= error_mark_node
;
3032 token
= c_parser_peek_token (parser
);
3033 enum_id
= token
->value
;
3034 /* Set the location in case we create a decl now. */
3035 c_parser_set_source_position_from_token (token
);
3036 decl_loc
= value_loc
= token
->location
;
3037 c_parser_consume_token (parser
);
3038 /* Parse any specified attributes. */
3039 tree enum_attrs
= c_parser_gnu_attributes (parser
);
3040 if (c_parser_next_token_is (parser
, CPP_EQ
))
3042 c_parser_consume_token (parser
);
3043 value_loc
= c_parser_peek_token (parser
)->location
;
3044 enum_value
= c_parser_expr_no_commas (parser
, NULL
).value
;
3047 enum_value
= NULL_TREE
;
3048 enum_decl
= build_enumerator (decl_loc
, value_loc
,
3049 &the_enum
, enum_id
, enum_value
);
3051 decl_attributes (&TREE_PURPOSE (enum_decl
), enum_attrs
, 0);
3052 TREE_CHAIN (enum_decl
) = values
;
3055 if (c_parser_next_token_is (parser
, CPP_COMMA
))
3057 comma_loc
= c_parser_peek_token (parser
)->location
;
3059 c_parser_consume_token (parser
);
3061 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
3064 pedwarn_c90 (comma_loc
, OPT_Wpedantic
,
3065 "comma at end of enumerator list");
3066 c_parser_consume_token (parser
);
3071 c_parser_error (parser
, "expected %<,%> or %<}%>");
3072 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
, NULL
);
3073 values
= error_mark_node
;
3077 postfix_attrs
= c_parser_gnu_attributes (parser
);
3078 ret
.spec
= finish_enum (type
, nreverse (values
),
3079 chainon (attrs
, postfix_attrs
));
3080 ret
.kind
= ctsk_tagdef
;
3081 ret
.expr
= NULL_TREE
;
3082 ret
.expr_const_operands
= true;
3083 timevar_pop (TV_PARSE_ENUM
);
3088 c_parser_error (parser
, "expected %<{%>");
3089 ret
.spec
= error_mark_node
;
3090 ret
.kind
= ctsk_tagref
;
3091 ret
.expr
= NULL_TREE
;
3092 ret
.expr_const_operands
= true;
3095 ret
= parser_xref_tag (ident_loc
, ENUMERAL_TYPE
, ident
);
3096 /* In ISO C, enumerated types can be referred to only if already
3098 if (pedantic
&& !COMPLETE_TYPE_P (ret
.spec
))
3101 pedwarn (enum_loc
, OPT_Wpedantic
,
3102 "ISO C forbids forward references to %<enum%> types");
3107 /* Parse a struct or union specifier (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1).
3109 struct-or-union-specifier:
3110 struct-or-union gnu-attributes[opt] identifier[opt]
3111 { struct-contents } gnu-attributes[opt]
3112 struct-or-union gnu-attributes[opt] identifier
3115 struct-declaration-list
3117 struct-declaration-list:
3118 struct-declaration ;
3119 struct-declaration-list struct-declaration ;
3126 struct-declaration-list struct-declaration
3128 struct-declaration-list:
3129 struct-declaration-list ;
3132 (Note that in the syntax here, unlike that in ISO C, the semicolons
3133 are included here rather than in struct-declaration, in order to
3134 describe the syntax with extra semicolons and missing semicolon at
3139 struct-declaration-list:
3140 @defs ( class-name )
3142 (Note this does not include a trailing semicolon, but can be
3143 followed by further declarations, and gets a pedwarn-if-pedantic
3144 when followed by a semicolon.) */
3146 static struct c_typespec
3147 c_parser_struct_or_union_specifier (c_parser
*parser
)
3149 struct c_typespec ret
;
3151 tree ident
= NULL_TREE
;
3152 location_t struct_loc
;
3153 location_t ident_loc
= UNKNOWN_LOCATION
;
3154 enum tree_code code
;
3155 switch (c_parser_peek_token (parser
)->keyword
)
3166 struct_loc
= c_parser_peek_token (parser
)->location
;
3167 c_parser_consume_token (parser
);
3168 attrs
= c_parser_gnu_attributes (parser
);
3170 /* Set the location in case we create a decl now. */
3171 c_parser_set_source_position_from_token (c_parser_peek_token (parser
));
3173 if (c_parser_next_token_is (parser
, CPP_NAME
))
3175 ident
= c_parser_peek_token (parser
)->value
;
3176 ident_loc
= c_parser_peek_token (parser
)->location
;
3177 struct_loc
= ident_loc
;
3178 c_parser_consume_token (parser
);
3180 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
3182 /* Parse a struct or union definition. Start the scope of the
3183 tag before parsing components. */
3184 class c_struct_parse_info
*struct_info
;
3185 tree type
= start_struct (struct_loc
, code
, ident
, &struct_info
);
3187 /* We chain the components in reverse order, then put them in
3188 forward order at the end. Each struct-declaration may
3189 declare multiple components (comma-separated), so we must use
3190 chainon to join them, although when parsing each
3191 struct-declaration we can use TREE_CHAIN directly.
3193 The theory behind all this is that there will be more
3194 semicolon separated fields than comma separated fields, and
3195 so we'll be minimizing the number of node traversals required
3198 timevar_push (TV_PARSE_STRUCT
);
3199 contents
= NULL_TREE
;
3200 c_parser_consume_token (parser
);
3201 /* Handle the Objective-C @defs construct,
3202 e.g. foo(sizeof(struct{ @defs(ClassName) }));. */
3203 if (c_parser_next_token_is_keyword (parser
, RID_AT_DEFS
))
3206 gcc_assert (c_dialect_objc ());
3207 c_parser_consume_token (parser
);
3208 matching_parens parens
;
3209 if (!parens
.require_open (parser
))
3211 if (c_parser_next_token_is (parser
, CPP_NAME
)
3212 && c_parser_peek_token (parser
)->id_kind
== C_ID_CLASSNAME
)
3214 name
= c_parser_peek_token (parser
)->value
;
3215 c_parser_consume_token (parser
);
3219 c_parser_error (parser
, "expected class name");
3220 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
3223 parens
.skip_until_found_close (parser
);
3224 contents
= nreverse (objc_get_class_ivars (name
));
3227 /* Parse the struct-declarations and semicolons. Problems with
3228 semicolons are diagnosed here; empty structures are diagnosed
3233 /* Parse any stray semicolon. */
3234 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
3236 location_t semicolon_loc
3237 = c_parser_peek_token (parser
)->location
;
3238 gcc_rich_location
richloc (semicolon_loc
);
3239 richloc
.add_fixit_remove ();
3240 pedwarn (&richloc
, OPT_Wpedantic
,
3241 "extra semicolon in struct or union specified");
3242 c_parser_consume_token (parser
);
3245 /* Stop if at the end of the struct or union contents. */
3246 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
3248 c_parser_consume_token (parser
);
3251 /* Accept #pragmas at struct scope. */
3252 if (c_parser_next_token_is (parser
, CPP_PRAGMA
))
3254 c_parser_pragma (parser
, pragma_struct
, NULL
);
3257 /* Parse some comma-separated declarations, but not the
3258 trailing semicolon if any. */
3259 decls
= c_parser_struct_declaration (parser
);
3260 contents
= chainon (decls
, contents
);
3261 /* If no semicolon follows, either we have a parse error or
3262 are at the end of the struct or union and should
3264 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
3265 c_parser_consume_token (parser
);
3268 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
3269 pedwarn (c_parser_peek_token (parser
)->location
, 0,
3270 "no semicolon at end of struct or union");
3271 else if (parser
->error
3272 || !c_parser_next_token_starts_declspecs (parser
))
3274 c_parser_error (parser
, "expected %<;%>");
3275 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
, NULL
);
3279 /* If we come here, we have already emitted an error
3280 for an expected `;', identifier or `(', and we also
3281 recovered already. Go on with the next field. */
3284 postfix_attrs
= c_parser_gnu_attributes (parser
);
3285 ret
.spec
= finish_struct (struct_loc
, type
, nreverse (contents
),
3286 chainon (attrs
, postfix_attrs
), struct_info
);
3287 ret
.kind
= ctsk_tagdef
;
3288 ret
.expr
= NULL_TREE
;
3289 ret
.expr_const_operands
= true;
3290 timevar_pop (TV_PARSE_STRUCT
);
3295 c_parser_error (parser
, "expected %<{%>");
3296 ret
.spec
= error_mark_node
;
3297 ret
.kind
= ctsk_tagref
;
3298 ret
.expr
= NULL_TREE
;
3299 ret
.expr_const_operands
= true;
3302 ret
= parser_xref_tag (ident_loc
, code
, ident
);
3306 /* Parse a struct-declaration (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1),
3307 *without* the trailing semicolon.
3310 specifier-qualifier-list struct-declarator-list
3311 static_assert-declaration-no-semi
3313 specifier-qualifier-list:
3314 type-specifier specifier-qualifier-list[opt]
3315 type-qualifier specifier-qualifier-list[opt]
3316 alignment-specifier specifier-qualifier-list[opt]
3317 gnu-attributes specifier-qualifier-list[opt]
3319 struct-declarator-list:
3321 struct-declarator-list , gnu-attributes[opt] struct-declarator
3324 declarator gnu-attributes[opt]
3325 declarator[opt] : constant-expression gnu-attributes[opt]
3330 __extension__ struct-declaration
3331 specifier-qualifier-list
3333 Unlike the ISO C syntax, semicolons are handled elsewhere. The use
3334 of gnu-attributes where shown is a GNU extension. In GNU C, we accept
3335 any expression without commas in the syntax (assignment
3336 expressions, not just conditional expressions); assignment
3337 expressions will be diagnosed as non-constant. */
3340 c_parser_struct_declaration (c_parser
*parser
)
3342 struct c_declspecs
*specs
;
3344 tree all_prefix_attrs
;
3346 location_t decl_loc
;
3347 if (c_parser_next_token_is_keyword (parser
, RID_EXTENSION
))
3351 ext
= disable_extension_diagnostics ();
3352 c_parser_consume_token (parser
);
3353 decl
= c_parser_struct_declaration (parser
);
3354 restore_extension_diagnostics (ext
);
3357 if (c_parser_next_token_is_keyword (parser
, RID_STATIC_ASSERT
))
3359 c_parser_static_assert_declaration_no_semi (parser
);
3362 specs
= build_null_declspecs ();
3363 decl_loc
= c_parser_peek_token (parser
)->location
;
3364 /* Strictly by the standard, we shouldn't allow _Alignas here,
3365 but it appears to have been intended to allow it there, so
3366 we're keeping it as it is until WG14 reaches a conclusion
3368 <http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1731.pdf> */
3369 c_parser_declspecs (parser
, specs
, false, true, true,
3370 true, false, cla_nonabstract_decl
);
3373 if (!specs
->declspecs_seen_p
)
3375 c_parser_error (parser
, "expected specifier-qualifier-list");
3378 finish_declspecs (specs
);
3379 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
)
3380 || c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
3383 if (specs
->typespec_kind
== ctsk_none
)
3385 pedwarn (decl_loc
, OPT_Wpedantic
,
3386 "ISO C forbids member declarations with no members");
3387 shadow_tag_warned (specs
, pedantic
);
3392 /* Support for unnamed structs or unions as members of
3393 structs or unions (which is [a] useful and [b] supports
3397 ret
= grokfield (c_parser_peek_token (parser
)->location
,
3398 build_id_declarator (NULL_TREE
), specs
,
3401 decl_attributes (&ret
, attrs
, 0);
3406 /* Provide better error recovery. Note that a type name here is valid,
3407 and will be treated as a field name. */
3408 if (specs
->typespec_kind
== ctsk_tagdef
3409 && TREE_CODE (specs
->type
) != ENUMERAL_TYPE
3410 && c_parser_next_token_starts_declspecs (parser
)
3411 && !c_parser_next_token_is (parser
, CPP_NAME
))
3413 c_parser_error (parser
, "expected %<;%>, identifier or %<(%>");
3414 parser
->error
= false;
3418 pending_xref_error ();
3419 prefix_attrs
= specs
->attrs
;
3420 all_prefix_attrs
= prefix_attrs
;
3421 specs
->attrs
= NULL_TREE
;
3425 /* Declaring one or more declarators or un-named bit-fields. */
3426 struct c_declarator
*declarator
;
3428 if (c_parser_next_token_is (parser
, CPP_COLON
))
3429 declarator
= build_id_declarator (NULL_TREE
);
3431 declarator
= c_parser_declarator (parser
,
3432 specs
->typespec_kind
!= ctsk_none
,
3433 C_DTR_NORMAL
, &dummy
);
3434 if (declarator
== NULL
)
3436 c_parser_skip_to_end_of_block_or_statement (parser
);
3439 if (c_parser_next_token_is (parser
, CPP_COLON
)
3440 || c_parser_next_token_is (parser
, CPP_COMMA
)
3441 || c_parser_next_token_is (parser
, CPP_SEMICOLON
)
3442 || c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
)
3443 || c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
3445 tree postfix_attrs
= NULL_TREE
;
3446 tree width
= NULL_TREE
;
3448 if (c_parser_next_token_is (parser
, CPP_COLON
))
3450 c_parser_consume_token (parser
);
3451 width
= c_parser_expr_no_commas (parser
, NULL
).value
;
3453 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
3454 postfix_attrs
= c_parser_gnu_attributes (parser
);
3455 d
= grokfield (c_parser_peek_token (parser
)->location
,
3456 declarator
, specs
, width
, &all_prefix_attrs
);
3457 decl_attributes (&d
, chainon (postfix_attrs
,
3458 all_prefix_attrs
), 0);
3459 DECL_CHAIN (d
) = decls
;
3461 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
3462 all_prefix_attrs
= chainon (c_parser_gnu_attributes (parser
),
3465 all_prefix_attrs
= prefix_attrs
;
3466 if (c_parser_next_token_is (parser
, CPP_COMMA
))
3467 c_parser_consume_token (parser
);
3468 else if (c_parser_next_token_is (parser
, CPP_SEMICOLON
)
3469 || c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
3471 /* Semicolon consumed in caller. */
3476 c_parser_error (parser
, "expected %<,%>, %<;%> or %<}%>");
3482 c_parser_error (parser
,
3483 "expected %<:%>, %<,%>, %<;%>, %<}%> or "
3484 "%<__attribute__%>");
3491 /* Parse a typeof specifier (a GNU extension).
3494 typeof ( expression )
3495 typeof ( type-name )
3498 static struct c_typespec
3499 c_parser_typeof_specifier (c_parser
*parser
)
3501 struct c_typespec ret
;
3502 ret
.kind
= ctsk_typeof
;
3503 ret
.spec
= error_mark_node
;
3504 ret
.expr
= NULL_TREE
;
3505 ret
.expr_const_operands
= true;
3506 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_TYPEOF
));
3507 c_parser_consume_token (parser
);
3508 c_inhibit_evaluation_warnings
++;
3510 matching_parens parens
;
3511 if (!parens
.require_open (parser
))
3513 c_inhibit_evaluation_warnings
--;
3517 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_id
))
3519 struct c_type_name
*type
= c_parser_type_name (parser
);
3520 c_inhibit_evaluation_warnings
--;
3524 ret
.spec
= groktypename (type
, &ret
.expr
, &ret
.expr_const_operands
);
3525 pop_maybe_used (variably_modified_type_p (ret
.spec
, NULL_TREE
));
3531 location_t here
= c_parser_peek_token (parser
)->location
;
3532 struct c_expr expr
= c_parser_expression (parser
);
3533 c_inhibit_evaluation_warnings
--;
3535 if (TREE_CODE (expr
.value
) == COMPONENT_REF
3536 && DECL_C_BIT_FIELD (TREE_OPERAND (expr
.value
, 1)))
3537 error_at (here
, "%<typeof%> applied to a bit-field");
3538 mark_exp_read (expr
.value
);
3539 ret
.spec
= TREE_TYPE (expr
.value
);
3540 was_vm
= variably_modified_type_p (ret
.spec
, NULL_TREE
);
3541 /* This is returned with the type so that when the type is
3542 evaluated, this can be evaluated. */
3544 ret
.expr
= c_fully_fold (expr
.value
, false, &ret
.expr_const_operands
);
3545 pop_maybe_used (was_vm
);
3546 /* For use in macros such as those in <stdatomic.h>, remove all
3547 qualifiers from atomic types. (const can be an issue for more macros
3548 using typeof than just the <stdatomic.h> ones.) */
3549 if (ret
.spec
!= error_mark_node
&& TYPE_ATOMIC (ret
.spec
))
3550 ret
.spec
= c_build_qualified_type (ret
.spec
, TYPE_UNQUALIFIED
);
3552 parens
.skip_until_found_close (parser
);
3556 /* Parse an alignment-specifier.
3560 alignment-specifier:
3561 _Alignas ( type-name )
3562 _Alignas ( constant-expression )
3566 c_parser_alignas_specifier (c_parser
* parser
)
3568 tree ret
= error_mark_node
;
3569 location_t loc
= c_parser_peek_token (parser
)->location
;
3570 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ALIGNAS
));
3571 c_parser_consume_token (parser
);
3573 pedwarn_c99 (loc
, OPT_Wpedantic
,
3574 "ISO C99 does not support %<_Alignas%>");
3576 pedwarn_c99 (loc
, OPT_Wpedantic
,
3577 "ISO C90 does not support %<_Alignas%>");
3578 matching_parens parens
;
3579 if (!parens
.require_open (parser
))
3581 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_id
))
3583 struct c_type_name
*type
= c_parser_type_name (parser
);
3585 ret
= c_sizeof_or_alignof_type (loc
, groktypename (type
, NULL
, NULL
),
3589 ret
= c_parser_expr_no_commas (parser
, NULL
).value
;
3590 parens
.skip_until_found_close (parser
);
3594 /* Parse a declarator, possibly an abstract declarator (C90 6.5.4,
3595 6.5.5, C99 6.7.5, 6.7.6, C11 6.7.6, 6.7.7). If TYPE_SEEN_P then
3596 a typedef name may be redeclared; otherwise it may not. KIND
3597 indicates which kind of declarator is wanted. Returns a valid
3598 declarator except in the case of a syntax error in which case NULL is
3599 returned. *SEEN_ID is set to true if an identifier being declared is
3600 seen; this is used to diagnose bad forms of abstract array declarators
3601 and to determine whether an identifier list is syntactically permitted.
3604 pointer[opt] direct-declarator
3608 ( gnu-attributes[opt] declarator )
3609 direct-declarator array-declarator
3610 direct-declarator ( parameter-type-list )
3611 direct-declarator ( identifier-list[opt] )
3614 * type-qualifier-list[opt]
3615 * type-qualifier-list[opt] pointer
3617 type-qualifier-list:
3620 type-qualifier-list type-qualifier
3621 type-qualifier-list gnu-attributes
3624 [ type-qualifier-list[opt] assignment-expression[opt] ]
3625 [ static type-qualifier-list[opt] assignment-expression ]
3626 [ type-qualifier-list static assignment-expression ]
3627 [ type-qualifier-list[opt] * ]
3629 parameter-type-list:
3631 parameter-list , ...
3634 parameter-declaration
3635 parameter-list , parameter-declaration
3637 parameter-declaration:
3638 declaration-specifiers declarator gnu-attributes[opt]
3639 declaration-specifiers abstract-declarator[opt] gnu-attributes[opt]
3643 identifier-list , identifier
3645 abstract-declarator:
3647 pointer[opt] direct-abstract-declarator
3649 direct-abstract-declarator:
3650 ( gnu-attributes[opt] abstract-declarator )
3651 direct-abstract-declarator[opt] array-declarator
3652 direct-abstract-declarator[opt] ( parameter-type-list[opt] )
3657 direct-declarator ( parameter-forward-declarations
3658 parameter-type-list[opt] )
3660 direct-abstract-declarator:
3661 direct-abstract-declarator[opt] ( parameter-forward-declarations
3662 parameter-type-list[opt] )
3664 parameter-forward-declarations:
3666 parameter-forward-declarations parameter-list ;
3668 The uses of gnu-attributes shown above are GNU extensions.
3670 Some forms of array declarator are not included in C99 in the
3671 syntax for abstract declarators; these are disallowed elsewhere.
3672 This may be a defect (DR#289).
3674 This function also accepts an omitted abstract declarator as being
3675 an abstract declarator, although not part of the formal syntax. */
3677 struct c_declarator
*
3678 c_parser_declarator (c_parser
*parser
, bool type_seen_p
, c_dtr_syn kind
,
3681 /* Parse any initial pointer part. */
3682 if (c_parser_next_token_is (parser
, CPP_MULT
))
3684 struct c_declspecs
*quals_attrs
= build_null_declspecs ();
3685 struct c_declarator
*inner
;
3686 c_parser_consume_token (parser
);
3687 c_parser_declspecs (parser
, quals_attrs
, false, false, true,
3688 false, false, cla_prefer_id
);
3689 inner
= c_parser_declarator (parser
, type_seen_p
, kind
, seen_id
);
3693 return make_pointer_declarator (quals_attrs
, inner
);
3695 /* Now we have a direct declarator, direct abstract declarator or
3696 nothing (which counts as a direct abstract declarator here). */
3697 return c_parser_direct_declarator (parser
, type_seen_p
, kind
, seen_id
);
3700 /* Parse a direct declarator or direct abstract declarator; arguments
3701 as c_parser_declarator. */
3703 static struct c_declarator
*
3704 c_parser_direct_declarator (c_parser
*parser
, bool type_seen_p
, c_dtr_syn kind
,
3707 /* The direct declarator must start with an identifier (possibly
3708 omitted) or a parenthesized declarator (possibly abstract). In
3709 an ordinary declarator, initial parentheses must start a
3710 parenthesized declarator. In an abstract declarator or parameter
3711 declarator, they could start a parenthesized declarator or a
3712 parameter list. To tell which, the open parenthesis and any
3713 following gnu-attributes must be read. If a declaration specifier
3714 follows, then it is a parameter list; if the specifier is a
3715 typedef name, there might be an ambiguity about redeclaring it,
3716 which is resolved in the direction of treating it as a typedef
3717 name. If a close parenthesis follows, it is also an empty
3718 parameter list, as the syntax does not permit empty abstract
3719 declarators. Otherwise, it is a parenthesized declarator (in
3720 which case the analysis may be repeated inside it, recursively).
3722 ??? There is an ambiguity in a parameter declaration "int
3723 (__attribute__((foo)) x)", where x is not a typedef name: it
3724 could be an abstract declarator for a function, or declare x with
3725 parentheses. The proper resolution of this ambiguity needs
3726 documenting. At present we follow an accident of the old
3727 parser's implementation, whereby the first parameter must have
3728 some declaration specifiers other than just gnu-attributes. Thus as
3729 a parameter declaration it is treated as a parenthesized
3730 parameter named x, and as an abstract declarator it is
3733 ??? Also following the old parser, gnu-attributes inside an empty
3734 parameter list are ignored, making it a list not yielding a
3735 prototype, rather than giving an error or making it have one
3736 parameter with implicit type int.
3738 ??? Also following the old parser, typedef names may be
3739 redeclared in declarators, but not Objective-C class names. */
3741 if (kind
!= C_DTR_ABSTRACT
3742 && c_parser_next_token_is (parser
, CPP_NAME
)
3744 && (c_parser_peek_token (parser
)->id_kind
== C_ID_TYPENAME
3745 || c_parser_peek_token (parser
)->id_kind
== C_ID_CLASSNAME
))
3746 || c_parser_peek_token (parser
)->id_kind
== C_ID_ID
))
3748 struct c_declarator
*inner
3749 = build_id_declarator (c_parser_peek_token (parser
)->value
);
3751 inner
->id_loc
= c_parser_peek_token (parser
)->location
;
3752 c_parser_consume_token (parser
);
3753 return c_parser_direct_declarator_inner (parser
, *seen_id
, inner
);
3756 if (kind
!= C_DTR_NORMAL
3757 && c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
))
3759 struct c_declarator
*inner
= build_id_declarator (NULL_TREE
);
3760 inner
->id_loc
= c_parser_peek_token (parser
)->location
;
3761 return c_parser_direct_declarator_inner (parser
, *seen_id
, inner
);
3764 /* Either we are at the end of an abstract declarator, or we have
3767 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
3770 struct c_declarator
*inner
;
3771 c_parser_consume_token (parser
);
3772 attrs
= c_parser_gnu_attributes (parser
);
3773 if (kind
!= C_DTR_NORMAL
3774 && (c_parser_next_token_starts_declspecs (parser
)
3775 || c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
)))
3777 struct c_arg_info
*args
3778 = c_parser_parms_declarator (parser
, kind
== C_DTR_NORMAL
,
3785 = build_function_declarator (args
,
3786 build_id_declarator (NULL_TREE
));
3787 return c_parser_direct_declarator_inner (parser
, *seen_id
,
3791 /* A parenthesized declarator. */
3792 inner
= c_parser_declarator (parser
, type_seen_p
, kind
, seen_id
);
3793 if (inner
!= NULL
&& attrs
!= NULL
)
3794 inner
= build_attrs_declarator (attrs
, inner
);
3795 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
3797 c_parser_consume_token (parser
);
3801 return c_parser_direct_declarator_inner (parser
, *seen_id
, inner
);
3805 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
3812 if (kind
== C_DTR_NORMAL
)
3814 c_parser_error (parser
, "expected identifier or %<(%>");
3818 return build_id_declarator (NULL_TREE
);
3822 /* Parse part of a direct declarator or direct abstract declarator,
3823 given that some (in INNER) has already been parsed; ID_PRESENT is
3824 true if an identifier is present, false for an abstract
3827 static struct c_declarator
*
3828 c_parser_direct_declarator_inner (c_parser
*parser
, bool id_present
,
3829 struct c_declarator
*inner
)
3831 /* Parse a sequence of array declarators and parameter lists. */
3832 if (c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
))
3834 location_t brace_loc
= c_parser_peek_token (parser
)->location
;
3835 struct c_declarator
*declarator
;
3836 struct c_declspecs
*quals_attrs
= build_null_declspecs ();
3839 struct c_expr dimen
;
3840 dimen
.value
= NULL_TREE
;
3841 dimen
.original_code
= ERROR_MARK
;
3842 dimen
.original_type
= NULL_TREE
;
3843 c_parser_consume_token (parser
);
3844 c_parser_declspecs (parser
, quals_attrs
, false, false, true,
3845 false, false, cla_prefer_id
);
3846 static_seen
= c_parser_next_token_is_keyword (parser
, RID_STATIC
);
3848 c_parser_consume_token (parser
);
3849 if (static_seen
&& !quals_attrs
->declspecs_seen_p
)
3850 c_parser_declspecs (parser
, quals_attrs
, false, false, true,
3851 false, false, cla_prefer_id
);
3852 if (!quals_attrs
->declspecs_seen_p
)
3854 /* If "static" is present, there must be an array dimension.
3855 Otherwise, there may be a dimension, "*", or no
3860 dimen
= c_parser_expr_no_commas (parser
, NULL
);
3864 if (c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
3866 dimen
.value
= NULL_TREE
;
3869 else if (c_parser_next_token_is (parser
, CPP_MULT
))
3871 if (c_parser_peek_2nd_token (parser
)->type
== CPP_CLOSE_SQUARE
)
3873 dimen
.value
= NULL_TREE
;
3875 c_parser_consume_token (parser
);
3880 dimen
= c_parser_expr_no_commas (parser
, NULL
);
3886 dimen
= c_parser_expr_no_commas (parser
, NULL
);
3889 if (c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
3890 c_parser_consume_token (parser
);
3893 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
3898 dimen
= convert_lvalue_to_rvalue (brace_loc
, dimen
, true, true);
3899 declarator
= build_array_declarator (brace_loc
, dimen
.value
, quals_attrs
,
3900 static_seen
, star_seen
);
3901 if (declarator
== NULL
)
3903 inner
= set_array_declarator_inner (declarator
, inner
);
3904 return c_parser_direct_declarator_inner (parser
, id_present
, inner
);
3906 else if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
3909 struct c_arg_info
*args
;
3910 c_parser_consume_token (parser
);
3911 attrs
= c_parser_gnu_attributes (parser
);
3912 args
= c_parser_parms_declarator (parser
, id_present
, attrs
);
3917 inner
= build_function_declarator (args
, inner
);
3918 return c_parser_direct_declarator_inner (parser
, id_present
, inner
);
3924 /* Parse a parameter list or identifier list, including the closing
3925 parenthesis but not the opening one. ATTRS are the attributes at
3926 the start of the list. ID_LIST_OK is true if an identifier list is
3927 acceptable; such a list must not have attributes at the start. */
3929 static struct c_arg_info
*
3930 c_parser_parms_declarator (c_parser
*parser
, bool id_list_ok
, tree attrs
)
3933 declare_parm_level ();
3934 /* If the list starts with an identifier, it is an identifier list.
3935 Otherwise, it is either a prototype list or an empty list. */
3938 && c_parser_next_token_is (parser
, CPP_NAME
)
3939 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
3941 /* Look ahead to detect typos in type names. */
3942 && c_parser_peek_2nd_token (parser
)->type
!= CPP_NAME
3943 && c_parser_peek_2nd_token (parser
)->type
!= CPP_MULT
3944 && c_parser_peek_2nd_token (parser
)->type
!= CPP_OPEN_PAREN
3945 && c_parser_peek_2nd_token (parser
)->type
!= CPP_OPEN_SQUARE
3946 && c_parser_peek_2nd_token (parser
)->type
!= CPP_KEYWORD
)
3948 tree list
= NULL_TREE
, *nextp
= &list
;
3949 while (c_parser_next_token_is (parser
, CPP_NAME
)
3950 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
)
3952 *nextp
= build_tree_list (NULL_TREE
,
3953 c_parser_peek_token (parser
)->value
);
3954 nextp
= & TREE_CHAIN (*nextp
);
3955 c_parser_consume_token (parser
);
3956 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
3958 c_parser_consume_token (parser
);
3959 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
3961 c_parser_error (parser
, "expected identifier");
3965 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
3967 struct c_arg_info
*ret
= build_arg_info ();
3969 c_parser_consume_token (parser
);
3975 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
3983 struct c_arg_info
*ret
= c_parser_parms_list_declarator (parser
, attrs
,
3990 /* Parse a parameter list (possibly empty), including the closing
3991 parenthesis but not the opening one. ATTRS are the attributes at
3992 the start of the list. EXPR is NULL or an expression that needs to
3993 be evaluated for the side effects of array size expressions in the
3996 static struct c_arg_info
*
3997 c_parser_parms_list_declarator (c_parser
*parser
, tree attrs
, tree expr
)
3999 bool bad_parm
= false;
4001 /* ??? Following the old parser, forward parameter declarations may
4002 use abstract declarators, and if no real parameter declarations
4003 follow the forward declarations then this is not diagnosed. Also
4004 note as above that attributes are ignored as the only contents of
4005 the parentheses, or as the only contents after forward
4007 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4009 struct c_arg_info
*ret
= build_arg_info ();
4010 c_parser_consume_token (parser
);
4013 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
4015 struct c_arg_info
*ret
= build_arg_info ();
4017 if (flag_allow_parameterless_variadic_functions
)
4019 /* F (...) is allowed. */
4020 ret
->types
= NULL_TREE
;
4024 /* Suppress -Wold-style-definition for this case. */
4025 ret
->types
= error_mark_node
;
4026 error_at (c_parser_peek_token (parser
)->location
,
4027 "ISO C requires a named argument before %<...%>");
4029 c_parser_consume_token (parser
);
4030 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4032 c_parser_consume_token (parser
);
4037 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4042 /* Nonempty list of parameters, either terminated with semicolon
4043 (forward declarations; recurse) or with close parenthesis (normal
4044 function) or with ", ... )" (variadic function). */
4047 /* Parse a parameter. */
4048 struct c_parm
*parm
= c_parser_parameter_declaration (parser
, attrs
);
4053 push_parm_decl (parm
, &expr
);
4054 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
4057 c_parser_consume_token (parser
);
4058 mark_forward_parm_decls ();
4059 new_attrs
= c_parser_gnu_attributes (parser
);
4060 return c_parser_parms_list_declarator (parser
, new_attrs
, expr
);
4062 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4064 c_parser_consume_token (parser
);
4068 return get_parm_info (false, expr
);
4070 if (!c_parser_require (parser
, CPP_COMMA
,
4071 "expected %<;%>, %<,%> or %<)%>",
4072 UNKNOWN_LOCATION
, false))
4074 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
4077 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
4079 c_parser_consume_token (parser
);
4080 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4082 c_parser_consume_token (parser
);
4086 return get_parm_info (true, expr
);
4090 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4098 /* Parse a parameter declaration. ATTRS are the attributes at the
4099 start of the declaration if it is the first parameter. */
4101 static struct c_parm
*
4102 c_parser_parameter_declaration (c_parser
*parser
, tree attrs
)
4104 struct c_declspecs
*specs
;
4105 struct c_declarator
*declarator
;
4107 tree postfix_attrs
= NULL_TREE
;
4110 /* Accept #pragmas between parameter declarations. */
4111 while (c_parser_next_token_is (parser
, CPP_PRAGMA
))
4112 c_parser_pragma (parser
, pragma_param
, NULL
);
4114 if (!c_parser_next_token_starts_declspecs (parser
))
4116 c_token
*token
= c_parser_peek_token (parser
);
4119 c_parser_set_source_position_from_token (token
);
4120 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_type
))
4122 auto_diagnostic_group d
;
4123 name_hint hint
= lookup_name_fuzzy (token
->value
,
4124 FUZZY_LOOKUP_TYPENAME
,
4126 if (const char *suggestion
= hint
.suggestion ())
4128 gcc_rich_location
richloc (token
->location
);
4129 richloc
.add_fixit_replace (suggestion
);
4131 "unknown type name %qE; did you mean %qs?",
4132 token
->value
, suggestion
);
4135 error_at (token
->location
, "unknown type name %qE", token
->value
);
4136 parser
->error
= true;
4138 /* ??? In some Objective-C cases '...' isn't applicable so there
4139 should be a different message. */
4141 c_parser_error (parser
,
4142 "expected declaration specifiers or %<...%>");
4143 c_parser_skip_to_end_of_parameter (parser
);
4147 location_t start_loc
= c_parser_peek_token (parser
)->location
;
4149 specs
= build_null_declspecs ();
4152 declspecs_add_attrs (input_location
, specs
, attrs
);
4155 c_parser_declspecs (parser
, specs
, true, true, true, true, false,
4156 cla_nonabstract_decl
);
4157 finish_declspecs (specs
);
4158 pending_xref_error ();
4159 prefix_attrs
= specs
->attrs
;
4160 specs
->attrs
= NULL_TREE
;
4161 declarator
= c_parser_declarator (parser
,
4162 specs
->typespec_kind
!= ctsk_none
,
4163 C_DTR_PARM
, &dummy
);
4164 if (declarator
== NULL
)
4166 c_parser_skip_until_found (parser
, CPP_COMMA
, NULL
);
4169 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
4170 postfix_attrs
= c_parser_gnu_attributes (parser
);
4172 /* Generate a location for the parameter, ranging from the start of the
4173 initial token to the end of the final token.
4175 If we have a identifier, then use it for the caret location, e.g.
4177 extern int callee (int one, int (*two)(int, int), float three);
4178 ~~~~~~^~~~~~~~~~~~~~
4180 otherwise, reuse the start location for the caret location e.g.:
4182 extern int callee (int one, int (*)(int, int), float three);
4185 location_t end_loc
= parser
->last_token_location
;
4187 /* Find any cdk_id declarator; determine if we have an identifier. */
4188 c_declarator
*id_declarator
= declarator
;
4189 while (id_declarator
&& id_declarator
->kind
!= cdk_id
)
4190 id_declarator
= id_declarator
->declarator
;
4191 location_t caret_loc
= (id_declarator
->u
.id
4192 ? id_declarator
->id_loc
4194 location_t param_loc
= make_location (caret_loc
, start_loc
, end_loc
);
4196 return build_c_parm (specs
, chainon (postfix_attrs
, prefix_attrs
),
4197 declarator
, param_loc
);
4200 /* Parse a string literal in an asm expression. It should not be
4201 translated, and wide string literals are an error although
4202 permitted by the syntax. This is a GNU extension.
4209 c_parser_asm_string_literal (c_parser
*parser
)
4212 int save_flag
= warn_overlength_strings
;
4213 warn_overlength_strings
= 0;
4214 str
= c_parser_string_literal (parser
, false, false).value
;
4215 warn_overlength_strings
= save_flag
;
4219 /* Parse a simple asm expression. This is used in restricted
4220 contexts, where a full expression with inputs and outputs does not
4221 make sense. This is a GNU extension.
4224 asm ( asm-string-literal )
4228 c_parser_simple_asm_expr (c_parser
*parser
)
4231 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ASM
));
4232 c_parser_consume_token (parser
);
4233 matching_parens parens
;
4234 if (!parens
.require_open (parser
))
4236 str
= c_parser_asm_string_literal (parser
);
4237 if (!parens
.require_close (parser
))
4239 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
4246 c_parser_gnu_attribute_any_word (c_parser
*parser
)
4248 tree attr_name
= NULL_TREE
;
4250 if (c_parser_next_token_is (parser
, CPP_KEYWORD
))
4252 /* ??? See comment above about what keywords are accepted here. */
4254 switch (c_parser_peek_token (parser
)->keyword
)
4285 case RID_TRANSACTION_ATOMIC
:
4286 case RID_TRANSACTION_CANCEL
:
4302 /* Accept __attribute__((__const)) as __attribute__((const)) etc. */
4303 attr_name
= ridpointers
[(int) c_parser_peek_token (parser
)->keyword
];
4305 else if (c_parser_next_token_is (parser
, CPP_NAME
))
4306 attr_name
= c_parser_peek_token (parser
)->value
;
4311 /* Parse (possibly empty) gnu-attributes. This is a GNU extension.
4315 gnu-attributes gnu-attribute
4318 __attribute__ ( ( gnu-attribute-list ) )
4322 gnu-attribute_list , gnu-attrib
4327 any-word ( identifier )
4328 any-word ( identifier , nonempty-expr-list )
4329 any-word ( expr-list )
4331 where the "identifier" must not be declared as a type, and
4332 "any-word" may be any identifier (including one declared as a
4333 type), a reserved word storage class specifier, type specifier or
4334 type qualifier. ??? This still leaves out most reserved keywords
4335 (following the old parser), shouldn't we include them, and why not
4336 allow identifiers declared as types to start the arguments?
4337 When EXPECT_COMMA is true, expect the attribute to be preceded
4338 by a comma and fail if it isn't.
4339 When EMPTY_OK is true, allow and consume any number of consecutive
4340 commas with no attributes in between. */
4343 c_parser_gnu_attribute (c_parser
*parser
, tree attrs
,
4344 bool expect_comma
= false, bool empty_ok
= true)
4346 bool comma_first
= c_parser_next_token_is (parser
, CPP_COMMA
);
4348 && !c_parser_next_token_is (parser
, CPP_NAME
)
4349 && !c_parser_next_token_is (parser
, CPP_KEYWORD
))
4352 while (c_parser_next_token_is (parser
, CPP_COMMA
))
4354 c_parser_consume_token (parser
);
4359 tree attr_name
= c_parser_gnu_attribute_any_word (parser
);
4360 if (attr_name
== NULL_TREE
)
4363 attr_name
= canonicalize_attr_name (attr_name
);
4364 c_parser_consume_token (parser
);
4367 if (c_parser_next_token_is_not (parser
, CPP_OPEN_PAREN
))
4369 if (expect_comma
&& !comma_first
)
4371 /* A comma is missing between the last attribute on the chain
4373 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4375 return error_mark_node
;
4377 attr
= build_tree_list (attr_name
, NULL_TREE
);
4378 /* Add this attribute to the list. */
4379 attrs
= chainon (attrs
, attr
);
4382 c_parser_consume_token (parser
);
4384 vec
<tree
, va_gc
> *expr_list
;
4386 /* Parse the attribute contents. If they start with an
4387 identifier which is followed by a comma or close
4388 parenthesis, then the arguments start with that
4389 identifier; otherwise they are an expression list.
4390 In objective-c the identifier may be a classname. */
4391 if (c_parser_next_token_is (parser
, CPP_NAME
)
4392 && (c_parser_peek_token (parser
)->id_kind
== C_ID_ID
4393 || (c_dialect_objc ()
4394 && c_parser_peek_token (parser
)->id_kind
4396 && ((c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
)
4397 || (c_parser_peek_2nd_token (parser
)->type
4398 == CPP_CLOSE_PAREN
))
4399 && (attribute_takes_identifier_p (attr_name
)
4400 || (c_dialect_objc ()
4401 && c_parser_peek_token (parser
)->id_kind
4402 == C_ID_CLASSNAME
)))
4404 tree arg1
= c_parser_peek_token (parser
)->value
;
4405 c_parser_consume_token (parser
);
4406 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4407 attr_args
= build_tree_list (NULL_TREE
, arg1
);
4411 c_parser_consume_token (parser
);
4412 expr_list
= c_parser_expr_list (parser
, false, true,
4413 NULL
, NULL
, NULL
, NULL
);
4414 tree_list
= build_tree_list_vec (expr_list
);
4415 attr_args
= tree_cons (NULL_TREE
, arg1
, tree_list
);
4416 release_tree_vector (expr_list
);
4421 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4422 attr_args
= NULL_TREE
;
4425 expr_list
= c_parser_expr_list (parser
, false, true,
4426 NULL
, NULL
, NULL
, NULL
);
4427 attr_args
= build_tree_list_vec (expr_list
);
4428 release_tree_vector (expr_list
);
4432 attr
= build_tree_list (attr_name
, attr_args
);
4433 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4434 c_parser_consume_token (parser
);
4437 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4439 return error_mark_node
;
4442 if (expect_comma
&& !comma_first
)
4444 /* A comma is missing between the last attribute on the chain
4446 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4448 return error_mark_node
;
4451 /* Add this attribute to the list. */
4452 attrs
= chainon (attrs
, attr
);
4457 c_parser_gnu_attributes (c_parser
*parser
)
4459 tree attrs
= NULL_TREE
;
4460 while (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
4462 bool save_translate_strings_p
= parser
->translate_strings_p
;
4463 parser
->translate_strings_p
= false;
4464 /* Consume the `__attribute__' keyword. */
4465 c_parser_consume_token (parser
);
4466 /* Look for the two `(' tokens. */
4467 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
4469 parser
->translate_strings_p
= save_translate_strings_p
;
4472 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
4474 parser
->translate_strings_p
= save_translate_strings_p
;
4475 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
4478 /* Parse the attribute list. Require a comma between successive
4479 (possibly empty) attributes. */
4480 for (bool expect_comma
= false; ; expect_comma
= true)
4482 /* Parse a single attribute. */
4483 tree attr
= c_parser_gnu_attribute (parser
, attrs
, expect_comma
);
4484 if (attr
== error_mark_node
)
4491 /* Look for the two `)' tokens. */
4492 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4493 c_parser_consume_token (parser
);
4496 parser
->translate_strings_p
= save_translate_strings_p
;
4497 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4501 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4502 c_parser_consume_token (parser
);
4505 parser
->translate_strings_p
= save_translate_strings_p
;
4506 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4510 parser
->translate_strings_p
= save_translate_strings_p
;
4516 /* Parse a type name (C90 6.5.5, C99 6.7.6, C11 6.7.7). ALIGNAS_OK
4517 says whether alignment specifiers are OK (only in cases that might
4518 be the type name of a compound literal).
4521 specifier-qualifier-list abstract-declarator[opt]
4524 struct c_type_name
*
4525 c_parser_type_name (c_parser
*parser
, bool alignas_ok
)
4527 struct c_declspecs
*specs
= build_null_declspecs ();
4528 struct c_declarator
*declarator
;
4529 struct c_type_name
*ret
;
4531 c_parser_declspecs (parser
, specs
, false, true, true, alignas_ok
, false,
4533 if (!specs
->declspecs_seen_p
)
4535 c_parser_error (parser
, "expected specifier-qualifier-list");
4538 if (specs
->type
!= error_mark_node
)
4540 pending_xref_error ();
4541 finish_declspecs (specs
);
4543 declarator
= c_parser_declarator (parser
,
4544 specs
->typespec_kind
!= ctsk_none
,
4545 C_DTR_ABSTRACT
, &dummy
);
4546 if (declarator
== NULL
)
4548 ret
= XOBNEW (&parser_obstack
, struct c_type_name
);
4550 ret
->declarator
= declarator
;
4554 /* Parse an initializer (C90 6.5.7, C99 6.7.8, C11 6.7.9).
4557 assignment-expression
4558 { initializer-list }
4559 { initializer-list , }
4562 designation[opt] initializer
4563 initializer-list , designation[opt] initializer
4570 designator-list designator
4577 [ constant-expression ]
4589 [ constant-expression ... constant-expression ]
4591 Any expression without commas is accepted in the syntax for the
4592 constant-expressions, with non-constant expressions rejected later.
4594 This function is only used for top-level initializers; for nested
4595 ones, see c_parser_initval. */
4597 static struct c_expr
4598 c_parser_initializer (c_parser
*parser
)
4600 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
4601 return c_parser_braced_init (parser
, NULL_TREE
, false, NULL
);
4605 location_t loc
= c_parser_peek_token (parser
)->location
;
4606 ret
= c_parser_expr_no_commas (parser
, NULL
);
4607 if (TREE_CODE (ret
.value
) != STRING_CST
4608 && TREE_CODE (ret
.value
) != COMPOUND_LITERAL_EXPR
)
4609 ret
= convert_lvalue_to_rvalue (loc
, ret
, true, true);
4614 /* The location of the last comma within the current initializer list,
4615 or UNKNOWN_LOCATION if not within one. */
4617 location_t last_init_list_comma
;
4619 /* Parse a braced initializer list. TYPE is the type specified for a
4620 compound literal, and NULL_TREE for other initializers and for
4621 nested braced lists. NESTED_P is true for nested braced lists,
4622 false for the list of a compound literal or the list that is the
4623 top-level initializer in a declaration. */
4625 static struct c_expr
4626 c_parser_braced_init (c_parser
*parser
, tree type
, bool nested_p
,
4627 struct obstack
*outer_obstack
)
4630 struct obstack braced_init_obstack
;
4631 location_t brace_loc
= c_parser_peek_token (parser
)->location
;
4632 gcc_obstack_init (&braced_init_obstack
);
4633 gcc_assert (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
));
4634 matching_braces braces
;
4635 braces
.consume_open (parser
);
4638 finish_implicit_inits (brace_loc
, outer_obstack
);
4639 push_init_level (brace_loc
, 0, &braced_init_obstack
);
4642 really_start_incremental_init (type
);
4643 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
4645 pedwarn (brace_loc
, OPT_Wpedantic
, "ISO C forbids empty initializer braces");
4649 /* Parse a non-empty initializer list, possibly with a trailing
4653 c_parser_initelt (parser
, &braced_init_obstack
);
4656 if (c_parser_next_token_is (parser
, CPP_COMMA
))
4658 last_init_list_comma
= c_parser_peek_token (parser
)->location
;
4659 c_parser_consume_token (parser
);
4663 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
4667 c_token
*next_tok
= c_parser_peek_token (parser
);
4668 if (next_tok
->type
!= CPP_CLOSE_BRACE
)
4671 ret
.original_code
= ERROR_MARK
;
4672 ret
.original_type
= NULL
;
4673 braces
.skip_until_found_close (parser
);
4674 pop_init_level (brace_loc
, 0, &braced_init_obstack
, last_init_list_comma
);
4675 obstack_free (&braced_init_obstack
, NULL
);
4678 location_t close_loc
= next_tok
->location
;
4679 c_parser_consume_token (parser
);
4680 ret
= pop_init_level (brace_loc
, 0, &braced_init_obstack
, close_loc
);
4681 obstack_free (&braced_init_obstack
, NULL
);
4682 set_c_expr_source_range (&ret
, brace_loc
, close_loc
);
4686 /* Parse a nested initializer, including designators. */
4689 c_parser_initelt (c_parser
*parser
, struct obstack
* braced_init_obstack
)
4691 /* Parse any designator or designator list. A single array
4692 designator may have the subsequent "=" omitted in GNU C, but a
4693 longer list or a structure member designator may not. */
4694 if (c_parser_next_token_is (parser
, CPP_NAME
)
4695 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
4697 /* Old-style structure member designator. */
4698 set_init_label (c_parser_peek_token (parser
)->location
,
4699 c_parser_peek_token (parser
)->value
,
4700 c_parser_peek_token (parser
)->location
,
4701 braced_init_obstack
);
4702 /* Use the colon as the error location. */
4703 pedwarn (c_parser_peek_2nd_token (parser
)->location
, OPT_Wpedantic
,
4704 "obsolete use of designated initializer with %<:%>");
4705 c_parser_consume_token (parser
);
4706 c_parser_consume_token (parser
);
4710 /* des_seen is 0 if there have been no designators, 1 if there
4711 has been a single array designator and 2 otherwise. */
4713 /* Location of a designator. */
4714 location_t des_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
4715 while (c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
)
4716 || c_parser_next_token_is (parser
, CPP_DOT
))
4718 int des_prev
= des_seen
;
4720 des_loc
= c_parser_peek_token (parser
)->location
;
4723 if (c_parser_next_token_is (parser
, CPP_DOT
))
4726 c_parser_consume_token (parser
);
4727 if (c_parser_next_token_is (parser
, CPP_NAME
))
4729 set_init_label (des_loc
, c_parser_peek_token (parser
)->value
,
4730 c_parser_peek_token (parser
)->location
,
4731 braced_init_obstack
);
4732 c_parser_consume_token (parser
);
4738 init
.original_code
= ERROR_MARK
;
4739 init
.original_type
= NULL
;
4740 c_parser_error (parser
, "expected identifier");
4741 c_parser_skip_until_found (parser
, CPP_COMMA
, NULL
);
4742 process_init_element (input_location
, init
, false,
4743 braced_init_obstack
);
4750 location_t ellipsis_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
4751 location_t array_index_loc
= UNKNOWN_LOCATION
;
4752 /* ??? Following the old parser, [ objc-receiver
4753 objc-message-args ] is accepted as an initializer,
4754 being distinguished from a designator by what follows
4755 the first assignment expression inside the square
4756 brackets, but after a first array designator a
4757 subsequent square bracket is for Objective-C taken to
4758 start an expression, using the obsolete form of
4759 designated initializer without '=', rather than
4760 possibly being a second level of designation: in LALR
4761 terms, the '[' is shifted rather than reducing
4762 designator to designator-list. */
4763 if (des_prev
== 1 && c_dialect_objc ())
4765 des_seen
= des_prev
;
4768 if (des_prev
== 0 && c_dialect_objc ())
4770 /* This might be an array designator or an
4771 Objective-C message expression. If the former,
4772 continue parsing here; if the latter, parse the
4773 remainder of the initializer given the starting
4774 primary-expression. ??? It might make sense to
4775 distinguish when des_prev == 1 as well; see
4776 previous comment. */
4778 struct c_expr mexpr
;
4779 c_parser_consume_token (parser
);
4780 if (c_parser_peek_token (parser
)->type
== CPP_NAME
4781 && ((c_parser_peek_token (parser
)->id_kind
4783 || (c_parser_peek_token (parser
)->id_kind
4784 == C_ID_CLASSNAME
)))
4786 /* Type name receiver. */
4787 tree id
= c_parser_peek_token (parser
)->value
;
4788 c_parser_consume_token (parser
);
4789 rec
= objc_get_class_reference (id
);
4790 goto parse_message_args
;
4792 first
= c_parser_expr_no_commas (parser
, NULL
).value
;
4793 mark_exp_read (first
);
4794 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
)
4795 || c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
4796 goto array_desig_after_first
;
4797 /* Expression receiver. So far only one part
4798 without commas has been parsed; there might be
4799 more of the expression. */
4801 while (c_parser_next_token_is (parser
, CPP_COMMA
))
4804 location_t comma_loc
, exp_loc
;
4805 comma_loc
= c_parser_peek_token (parser
)->location
;
4806 c_parser_consume_token (parser
);
4807 exp_loc
= c_parser_peek_token (parser
)->location
;
4808 next
= c_parser_expr_no_commas (parser
, NULL
);
4809 next
= convert_lvalue_to_rvalue (exp_loc
, next
,
4811 rec
= build_compound_expr (comma_loc
, rec
, next
.value
);
4814 /* Now parse the objc-message-args. */
4815 args
= c_parser_objc_message_args (parser
);
4816 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
4819 = objc_build_message_expr (rec
, args
);
4820 mexpr
.original_code
= ERROR_MARK
;
4821 mexpr
.original_type
= NULL
;
4822 /* Now parse and process the remainder of the
4823 initializer, starting with this message
4824 expression as a primary-expression. */
4825 c_parser_initval (parser
, &mexpr
, braced_init_obstack
);
4828 c_parser_consume_token (parser
);
4829 array_index_loc
= c_parser_peek_token (parser
)->location
;
4830 first
= c_parser_expr_no_commas (parser
, NULL
).value
;
4831 mark_exp_read (first
);
4832 array_desig_after_first
:
4833 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
4835 ellipsis_loc
= c_parser_peek_token (parser
)->location
;
4836 c_parser_consume_token (parser
);
4837 second
= c_parser_expr_no_commas (parser
, NULL
).value
;
4838 mark_exp_read (second
);
4842 if (c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
4844 c_parser_consume_token (parser
);
4845 set_init_index (array_index_loc
, first
, second
,
4846 braced_init_obstack
);
4848 pedwarn (ellipsis_loc
, OPT_Wpedantic
,
4849 "ISO C forbids specifying range of elements to initialize");
4852 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
4858 if (c_parser_next_token_is (parser
, CPP_EQ
))
4860 pedwarn_c90 (des_loc
, OPT_Wpedantic
,
4861 "ISO C90 forbids specifying subobject "
4863 c_parser_consume_token (parser
);
4868 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
4869 "obsolete use of designated initializer without %<=%>");
4874 init
.original_code
= ERROR_MARK
;
4875 init
.original_type
= NULL
;
4876 c_parser_error (parser
, "expected %<=%>");
4877 c_parser_skip_until_found (parser
, CPP_COMMA
, NULL
);
4878 process_init_element (input_location
, init
, false,
4879 braced_init_obstack
);
4885 c_parser_initval (parser
, NULL
, braced_init_obstack
);
4888 /* Parse a nested initializer; as c_parser_initializer but parses
4889 initializers within braced lists, after any designators have been
4890 applied. If AFTER is not NULL then it is an Objective-C message
4891 expression which is the primary-expression starting the
4895 c_parser_initval (c_parser
*parser
, struct c_expr
*after
,
4896 struct obstack
* braced_init_obstack
)
4899 gcc_assert (!after
|| c_dialect_objc ());
4900 location_t loc
= c_parser_peek_token (parser
)->location
;
4902 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
) && !after
)
4903 init
= c_parser_braced_init (parser
, NULL_TREE
, true,
4904 braced_init_obstack
);
4907 init
= c_parser_expr_no_commas (parser
, after
);
4908 if (init
.value
!= NULL_TREE
4909 && TREE_CODE (init
.value
) != STRING_CST
4910 && TREE_CODE (init
.value
) != COMPOUND_LITERAL_EXPR
)
4911 init
= convert_lvalue_to_rvalue (loc
, init
, true, true);
4913 process_init_element (loc
, init
, false, braced_init_obstack
);
4916 /* Parse a compound statement (possibly a function body) (C90 6.6.2,
4917 C99 6.8.2, C11 6.8.2).
4920 { block-item-list[opt] }
4921 { label-declarations block-item-list }
4925 block-item-list block-item
4937 { label-declarations block-item-list }
4940 __extension__ nested-declaration
4941 nested-function-definition
4945 label-declarations label-declaration
4948 __label__ identifier-list ;
4950 Allowing the mixing of declarations and code is new in C99. The
4951 GNU syntax also permits (not shown above) labels at the end of
4952 compound statements, which yield an error. We don't allow labels
4953 on declarations; this might seem like a natural extension, but
4954 there would be a conflict between gnu-attributes on the label and
4955 prefix gnu-attributes on the declaration. ??? The syntax follows the
4956 old parser in requiring something after label declarations.
4957 Although they are erroneous if the labels declared aren't defined,
4958 is it useful for the syntax to be this way?
4979 cancellation-point-directive */
4982 c_parser_compound_statement (c_parser
*parser
)
4985 location_t brace_loc
;
4986 brace_loc
= c_parser_peek_token (parser
)->location
;
4987 if (!c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
4989 /* Ensure a scope is entered and left anyway to avoid confusion
4990 if we have just prepared to enter a function body. */
4991 stmt
= c_begin_compound_stmt (true);
4992 c_end_compound_stmt (brace_loc
, stmt
, true);
4993 return error_mark_node
;
4995 stmt
= c_begin_compound_stmt (true);
4996 c_parser_compound_statement_nostart (parser
);
4998 return c_end_compound_stmt (brace_loc
, stmt
, true);
5001 /* Parse a compound statement except for the opening brace. This is
5002 used for parsing both compound statements and statement expressions
5003 (which follow different paths to handling the opening). */
5006 c_parser_compound_statement_nostart (c_parser
*parser
)
5008 bool last_stmt
= false;
5009 bool last_label
= false;
5010 bool save_valid_for_pragma
= valid_location_for_stdc_pragma_p ();
5011 location_t label_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
5012 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
5014 add_debug_begin_stmt (c_parser_peek_token (parser
)->location
);
5015 c_parser_consume_token (parser
);
5018 mark_valid_location_for_stdc_pragma (true);
5019 if (c_parser_next_token_is_keyword (parser
, RID_LABEL
))
5021 /* Read zero or more forward-declarations for labels that nested
5022 functions can jump to. */
5023 mark_valid_location_for_stdc_pragma (false);
5024 while (c_parser_next_token_is_keyword (parser
, RID_LABEL
))
5026 label_loc
= c_parser_peek_token (parser
)->location
;
5027 c_parser_consume_token (parser
);
5028 /* Any identifiers, including those declared as type names,
5033 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
5035 c_parser_error (parser
, "expected identifier");
5039 = declare_label (c_parser_peek_token (parser
)->value
);
5040 C_DECLARED_LABEL_FLAG (label
) = 1;
5041 add_stmt (build_stmt (label_loc
, DECL_EXPR
, label
));
5042 c_parser_consume_token (parser
);
5043 if (c_parser_next_token_is (parser
, CPP_COMMA
))
5044 c_parser_consume_token (parser
);
5048 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
5050 pedwarn (label_loc
, OPT_Wpedantic
, "ISO C forbids label declarations");
5052 /* We must now have at least one statement, label or declaration. */
5053 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
5055 mark_valid_location_for_stdc_pragma (save_valid_for_pragma
);
5056 c_parser_error (parser
, "expected declaration or statement");
5057 c_parser_consume_token (parser
);
5060 while (c_parser_next_token_is_not (parser
, CPP_CLOSE_BRACE
))
5062 location_t loc
= c_parser_peek_token (parser
)->location
;
5063 loc
= expansion_point_location_if_in_system_header (loc
);
5064 if (c_parser_next_token_is_keyword (parser
, RID_CASE
)
5065 || c_parser_next_token_is_keyword (parser
, RID_DEFAULT
)
5066 || (c_parser_next_token_is (parser
, CPP_NAME
)
5067 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
))
5069 if (c_parser_next_token_is_keyword (parser
, RID_CASE
))
5070 label_loc
= c_parser_peek_2nd_token (parser
)->location
;
5072 label_loc
= c_parser_peek_token (parser
)->location
;
5075 mark_valid_location_for_stdc_pragma (false);
5076 c_parser_label (parser
);
5078 else if (!last_label
5079 && c_parser_next_tokens_start_declaration (parser
))
5082 mark_valid_location_for_stdc_pragma (false);
5083 bool fallthru_attr_p
= false;
5084 c_parser_declaration_or_fndef (parser
, true, true, true, true,
5085 true, NULL
, vNULL
, NULL
,
5087 if (last_stmt
&& !fallthru_attr_p
)
5088 pedwarn_c90 (loc
, OPT_Wdeclaration_after_statement
,
5089 "ISO C90 forbids mixed declarations and code");
5090 last_stmt
= fallthru_attr_p
;
5092 else if (!last_label
5093 && c_parser_next_token_is_keyword (parser
, RID_EXTENSION
))
5095 /* __extension__ can start a declaration, but is also an
5096 unary operator that can start an expression. Consume all
5097 but the last of a possible series of __extension__ to
5099 while (c_parser_peek_2nd_token (parser
)->type
== CPP_KEYWORD
5100 && (c_parser_peek_2nd_token (parser
)->keyword
5102 c_parser_consume_token (parser
);
5103 if (c_token_starts_declaration (c_parser_peek_2nd_token (parser
)))
5106 ext
= disable_extension_diagnostics ();
5107 c_parser_consume_token (parser
);
5109 mark_valid_location_for_stdc_pragma (false);
5110 c_parser_declaration_or_fndef (parser
, true, true, true, true,
5112 /* Following the old parser, __extension__ does not
5113 disable this diagnostic. */
5114 restore_extension_diagnostics (ext
);
5116 pedwarn_c90 (loc
, OPT_Wdeclaration_after_statement
,
5117 "ISO C90 forbids mixed declarations and code");
5123 else if (c_parser_next_token_is (parser
, CPP_PRAGMA
))
5125 /* External pragmas, and some omp pragmas, are not associated
5126 with regular c code, and so are not to be considered statements
5127 syntactically. This ensures that the user doesn't put them
5128 places that would turn into syntax errors if the directive
5130 if (c_parser_pragma (parser
,
5131 last_label
? pragma_stmt
: pragma_compound
,
5133 last_label
= false, last_stmt
= true;
5135 else if (c_parser_next_token_is (parser
, CPP_EOF
))
5137 mark_valid_location_for_stdc_pragma (save_valid_for_pragma
);
5138 c_parser_error (parser
, "expected declaration or statement");
5141 else if (c_parser_next_token_is_keyword (parser
, RID_ELSE
))
5143 if (parser
->in_if_block
)
5145 mark_valid_location_for_stdc_pragma (save_valid_for_pragma
);
5146 error_at (loc
, "expected %<}%> before %<else%>");
5151 error_at (loc
, "%<else%> without a previous %<if%>");
5152 c_parser_consume_token (parser
);
5161 mark_valid_location_for_stdc_pragma (false);
5162 c_parser_statement_after_labels (parser
, NULL
);
5165 parser
->error
= false;
5168 error_at (label_loc
, "label at end of compound statement");
5169 c_parser_consume_token (parser
);
5170 /* Restore the value we started with. */
5171 mark_valid_location_for_stdc_pragma (save_valid_for_pragma
);
5174 /* Parse all consecutive labels. */
5177 c_parser_all_labels (c_parser
*parser
)
5179 while (c_parser_next_token_is_keyword (parser
, RID_CASE
)
5180 || c_parser_next_token_is_keyword (parser
, RID_DEFAULT
)
5181 || (c_parser_next_token_is (parser
, CPP_NAME
)
5182 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
))
5183 c_parser_label (parser
);
5186 /* Parse a label (C90 6.6.1, C99 6.8.1, C11 6.8.1).
5189 identifier : gnu-attributes[opt]
5190 case constant-expression :
5196 case constant-expression ... constant-expression :
5198 The use of gnu-attributes on labels is a GNU extension. The syntax in
5199 GNU C accepts any expressions without commas, non-constant
5200 expressions being rejected later. */
5203 c_parser_label (c_parser
*parser
)
5205 location_t loc1
= c_parser_peek_token (parser
)->location
;
5206 tree label
= NULL_TREE
;
5208 /* Remember whether this case or a user-defined label is allowed to fall
5210 bool fallthrough_p
= c_parser_peek_token (parser
)->flags
& PREV_FALLTHROUGH
;
5212 if (c_parser_next_token_is_keyword (parser
, RID_CASE
))
5215 c_parser_consume_token (parser
);
5216 exp1
= c_parser_expr_no_commas (parser
, NULL
).value
;
5217 if (c_parser_next_token_is (parser
, CPP_COLON
))
5219 c_parser_consume_token (parser
);
5220 label
= do_case (loc1
, exp1
, NULL_TREE
);
5222 else if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
5224 c_parser_consume_token (parser
);
5225 exp2
= c_parser_expr_no_commas (parser
, NULL
).value
;
5226 if (c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
5227 label
= do_case (loc1
, exp1
, exp2
);
5230 c_parser_error (parser
, "expected %<:%> or %<...%>");
5232 else if (c_parser_next_token_is_keyword (parser
, RID_DEFAULT
))
5234 c_parser_consume_token (parser
);
5235 if (c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
5236 label
= do_case (loc1
, NULL_TREE
, NULL_TREE
);
5240 tree name
= c_parser_peek_token (parser
)->value
;
5243 location_t loc2
= c_parser_peek_token (parser
)->location
;
5244 gcc_assert (c_parser_next_token_is (parser
, CPP_NAME
));
5245 c_parser_consume_token (parser
);
5246 gcc_assert (c_parser_next_token_is (parser
, CPP_COLON
));
5247 c_parser_consume_token (parser
);
5248 attrs
= c_parser_gnu_attributes (parser
);
5249 tlab
= define_label (loc2
, name
);
5252 decl_attributes (&tlab
, attrs
, 0);
5253 label
= add_stmt (build_stmt (loc1
, LABEL_EXPR
, tlab
));
5258 if (TREE_CODE (label
) == LABEL_EXPR
)
5259 FALLTHROUGH_LABEL_P (LABEL_EXPR_LABEL (label
)) = fallthrough_p
;
5261 FALLTHROUGH_LABEL_P (CASE_LABEL (label
)) = fallthrough_p
;
5263 /* Allow '__attribute__((fallthrough));'. */
5264 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
5266 location_t loc
= c_parser_peek_token (parser
)->location
;
5267 tree attrs
= c_parser_gnu_attributes (parser
);
5268 if (attribute_fallthrough_p (attrs
))
5270 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
5272 tree fn
= build_call_expr_internal_loc (loc
,
5278 warning_at (loc
, OPT_Wattributes
, "%<fallthrough%> attribute "
5279 "not followed by %<;%>");
5281 else if (attrs
!= NULL_TREE
)
5282 warning_at (loc
, OPT_Wattributes
, "only attribute %<fallthrough%>"
5283 " can be applied to a null statement");
5285 if (c_parser_next_tokens_start_declaration (parser
))
5287 error_at (c_parser_peek_token (parser
)->location
,
5288 "a label can only be part of a statement and "
5289 "a declaration is not a statement");
5290 c_parser_declaration_or_fndef (parser
, /*fndef_ok*/ false,
5291 /*static_assert_ok*/ true,
5292 /*empty_ok*/ true, /*nested*/ true,
5293 /*start_attr_ok*/ true, NULL
,
5299 /* Parse a statement (C90 6.6, C99 6.8, C11 6.8).
5304 expression-statement
5312 expression-statement:
5315 selection-statement:
5319 iteration-statement:
5328 return expression[opt] ;
5338 expression-statement:
5344 objc-throw-statement
5345 objc-try-catch-statement
5346 objc-synchronized-statement
5348 objc-throw-statement:
5364 parallel-directive structured-block
5367 kernels-directive structured-block
5370 data-directive structured-block
5373 loop-directive structured-block
5387 parallel-for-construct
5388 parallel-for-simd-construct
5389 parallel-sections-construct
5396 parallel-directive structured-block
5399 for-directive iteration-statement
5402 simd-directive iteration-statements
5405 for-simd-directive iteration-statements
5408 sections-directive section-scope
5411 single-directive structured-block
5413 parallel-for-construct:
5414 parallel-for-directive iteration-statement
5416 parallel-for-simd-construct:
5417 parallel-for-simd-directive iteration-statement
5419 parallel-sections-construct:
5420 parallel-sections-directive section-scope
5423 master-directive structured-block
5426 critical-directive structured-block
5429 atomic-directive expression-statement
5432 ordered-directive structured-block
5434 Transactional Memory:
5437 transaction-statement
5438 transaction-cancel-statement
5440 IF_P is used to track whether there's a (possibly labeled) if statement
5441 which is not enclosed in braces and has an else clause. This is used to
5442 implement -Wparentheses. */
5445 c_parser_statement (c_parser
*parser
, bool *if_p
, location_t
*loc_after_labels
)
5447 c_parser_all_labels (parser
);
5448 if (loc_after_labels
)
5449 *loc_after_labels
= c_parser_peek_token (parser
)->location
;
5450 c_parser_statement_after_labels (parser
, if_p
, NULL
);
5453 /* Parse a statement, other than a labeled statement. CHAIN is a vector
5454 of if-else-if conditions.
5456 IF_P is used to track whether there's a (possibly labeled) if statement
5457 which is not enclosed in braces and has an else clause. This is used to
5458 implement -Wparentheses. */
5461 c_parser_statement_after_labels (c_parser
*parser
, bool *if_p
,
5464 location_t loc
= c_parser_peek_token (parser
)->location
;
5465 tree stmt
= NULL_TREE
;
5466 bool in_if_block
= parser
->in_if_block
;
5467 parser
->in_if_block
= false;
5471 if (c_parser_peek_token (parser
)->type
!= CPP_OPEN_BRACE
)
5472 add_debug_begin_stmt (loc
);
5474 switch (c_parser_peek_token (parser
)->type
)
5476 case CPP_OPEN_BRACE
:
5477 add_stmt (c_parser_compound_statement (parser
));
5480 switch (c_parser_peek_token (parser
)->keyword
)
5483 c_parser_if_statement (parser
, if_p
, chain
);
5486 c_parser_switch_statement (parser
, if_p
);
5489 c_parser_while_statement (parser
, false, 0, if_p
);
5492 c_parser_do_statement (parser
, 0, false);
5495 c_parser_for_statement (parser
, false, 0, if_p
);
5498 c_parser_consume_token (parser
);
5499 if (c_parser_next_token_is (parser
, CPP_NAME
))
5501 stmt
= c_finish_goto_label (loc
,
5502 c_parser_peek_token (parser
)->value
);
5503 c_parser_consume_token (parser
);
5505 else if (c_parser_next_token_is (parser
, CPP_MULT
))
5509 c_parser_consume_token (parser
);
5510 val
= c_parser_expression (parser
);
5511 val
= convert_lvalue_to_rvalue (loc
, val
, false, true);
5512 stmt
= c_finish_goto_ptr (loc
, val
.value
);
5515 c_parser_error (parser
, "expected identifier or %<*%>");
5516 goto expect_semicolon
;
5518 c_parser_consume_token (parser
);
5519 stmt
= c_finish_bc_stmt (loc
, &c_cont_label
, false);
5520 goto expect_semicolon
;
5522 c_parser_consume_token (parser
);
5523 stmt
= c_finish_bc_stmt (loc
, &c_break_label
, true);
5524 goto expect_semicolon
;
5526 c_parser_consume_token (parser
);
5527 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
5529 stmt
= c_finish_return (loc
, NULL_TREE
, NULL_TREE
);
5530 c_parser_consume_token (parser
);
5534 location_t xloc
= c_parser_peek_token (parser
)->location
;
5535 struct c_expr expr
= c_parser_expression_conv (parser
);
5536 mark_exp_read (expr
.value
);
5537 stmt
= c_finish_return (EXPR_LOC_OR_LOC (expr
.value
, xloc
),
5538 expr
.value
, expr
.original_type
);
5539 goto expect_semicolon
;
5543 stmt
= c_parser_asm_statement (parser
);
5545 case RID_TRANSACTION_ATOMIC
:
5546 case RID_TRANSACTION_RELAXED
:
5547 stmt
= c_parser_transaction (parser
,
5548 c_parser_peek_token (parser
)->keyword
);
5550 case RID_TRANSACTION_CANCEL
:
5551 stmt
= c_parser_transaction_cancel (parser
);
5552 goto expect_semicolon
;
5554 gcc_assert (c_dialect_objc ());
5555 c_parser_consume_token (parser
);
5556 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
5558 stmt
= objc_build_throw_stmt (loc
, NULL_TREE
);
5559 c_parser_consume_token (parser
);
5563 struct c_expr expr
= c_parser_expression (parser
);
5564 expr
= convert_lvalue_to_rvalue (loc
, expr
, false, false);
5565 expr
.value
= c_fully_fold (expr
.value
, false, NULL
);
5566 stmt
= objc_build_throw_stmt (loc
, expr
.value
);
5567 goto expect_semicolon
;
5571 gcc_assert (c_dialect_objc ());
5572 c_parser_objc_try_catch_finally_statement (parser
);
5574 case RID_AT_SYNCHRONIZED
:
5575 gcc_assert (c_dialect_objc ());
5576 c_parser_objc_synchronized_statement (parser
);
5580 /* Allow '__attribute__((fallthrough));'. */
5581 tree attrs
= c_parser_gnu_attributes (parser
);
5582 if (attribute_fallthrough_p (attrs
))
5584 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
5586 tree fn
= build_call_expr_internal_loc (loc
,
5591 c_parser_consume_token (parser
);
5594 warning_at (loc
, OPT_Wattributes
,
5595 "%<fallthrough%> attribute not followed "
5598 else if (attrs
!= NULL_TREE
)
5599 warning_at (loc
, OPT_Wattributes
, "only attribute %<fallthrough%>"
5600 " can be applied to a null statement");
5608 c_parser_consume_token (parser
);
5610 case CPP_CLOSE_PAREN
:
5611 case CPP_CLOSE_SQUARE
:
5612 /* Avoid infinite loop in error recovery:
5613 c_parser_skip_until_found stops at a closing nesting
5614 delimiter without consuming it, but here we need to consume
5615 it to proceed further. */
5616 c_parser_error (parser
, "expected statement");
5617 c_parser_consume_token (parser
);
5620 c_parser_pragma (parser
, pragma_stmt
, if_p
);
5624 stmt
= c_finish_expr_stmt (loc
, c_parser_expression_conv (parser
).value
);
5626 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
5629 /* Two cases cannot and do not have line numbers associated: If stmt
5630 is degenerate, such as "2;", then stmt is an INTEGER_CST, which
5631 cannot hold line numbers. But that's OK because the statement
5632 will either be changed to a MODIFY_EXPR during gimplification of
5633 the statement expr, or discarded. If stmt was compound, but
5634 without new variables, we will have skipped the creation of a
5635 BIND and will have a bare STATEMENT_LIST. But that's OK because
5636 (recursively) all of the component statements should already have
5637 line numbers assigned. ??? Can we discard no-op statements
5639 if (EXPR_LOCATION (stmt
) == UNKNOWN_LOCATION
)
5640 protected_set_expr_location (stmt
, loc
);
5642 parser
->in_if_block
= in_if_block
;
5645 /* Parse the condition from an if, do, while or for statements. */
5648 c_parser_condition (c_parser
*parser
)
5650 location_t loc
= c_parser_peek_token (parser
)->location
;
5652 cond
= c_parser_expression_conv (parser
).value
;
5653 cond
= c_objc_common_truthvalue_conversion (loc
, cond
);
5654 cond
= c_fully_fold (cond
, false, NULL
);
5655 if (warn_sequence_point
)
5656 verify_sequence_points (cond
);
5660 /* Parse a parenthesized condition from an if, do or while statement.
5666 c_parser_paren_condition (c_parser
*parser
)
5669 matching_parens parens
;
5670 if (!parens
.require_open (parser
))
5671 return error_mark_node
;
5672 cond
= c_parser_condition (parser
);
5673 parens
.skip_until_found_close (parser
);
5677 /* Parse a statement which is a block in C99.
5679 IF_P is used to track whether there's a (possibly labeled) if statement
5680 which is not enclosed in braces and has an else clause. This is used to
5681 implement -Wparentheses. */
5684 c_parser_c99_block_statement (c_parser
*parser
, bool *if_p
,
5685 location_t
*loc_after_labels
)
5687 tree block
= c_begin_compound_stmt (flag_isoc99
);
5688 location_t loc
= c_parser_peek_token (parser
)->location
;
5689 c_parser_statement (parser
, if_p
, loc_after_labels
);
5690 return c_end_compound_stmt (loc
, block
, flag_isoc99
);
5693 /* Parse the body of an if statement. This is just parsing a
5694 statement but (a) it is a block in C99, (b) we track whether the
5695 body is an if statement for the sake of -Wparentheses warnings, (c)
5696 we handle an empty body specially for the sake of -Wempty-body
5697 warnings, and (d) we call parser_compound_statement directly
5698 because c_parser_statement_after_labels resets
5699 parser->in_if_block.
5701 IF_P is used to track whether there's a (possibly labeled) if statement
5702 which is not enclosed in braces and has an else clause. This is used to
5703 implement -Wparentheses. */
5706 c_parser_if_body (c_parser
*parser
, bool *if_p
,
5707 const token_indent_info
&if_tinfo
)
5709 tree block
= c_begin_compound_stmt (flag_isoc99
);
5710 location_t body_loc
= c_parser_peek_token (parser
)->location
;
5711 location_t body_loc_after_labels
= UNKNOWN_LOCATION
;
5712 token_indent_info body_tinfo
5713 = get_token_indent_info (c_parser_peek_token (parser
));
5715 c_parser_all_labels (parser
);
5716 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
5718 location_t loc
= c_parser_peek_token (parser
)->location
;
5719 add_stmt (build_empty_stmt (loc
));
5720 c_parser_consume_token (parser
);
5721 if (!c_parser_next_token_is_keyword (parser
, RID_ELSE
))
5722 warning_at (loc
, OPT_Wempty_body
,
5723 "suggest braces around empty body in an %<if%> statement");
5725 else if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
5726 add_stmt (c_parser_compound_statement (parser
));
5729 body_loc_after_labels
= c_parser_peek_token (parser
)->location
;
5730 c_parser_statement_after_labels (parser
, if_p
);
5733 token_indent_info next_tinfo
5734 = get_token_indent_info (c_parser_peek_token (parser
));
5735 warn_for_misleading_indentation (if_tinfo
, body_tinfo
, next_tinfo
);
5736 if (body_loc_after_labels
!= UNKNOWN_LOCATION
5737 && next_tinfo
.type
!= CPP_SEMICOLON
)
5738 warn_for_multistatement_macros (body_loc_after_labels
, next_tinfo
.location
,
5739 if_tinfo
.location
, RID_IF
);
5741 return c_end_compound_stmt (body_loc
, block
, flag_isoc99
);
5744 /* Parse the else body of an if statement. This is just parsing a
5745 statement but (a) it is a block in C99, (b) we handle an empty body
5746 specially for the sake of -Wempty-body warnings. CHAIN is a vector
5747 of if-else-if conditions. */
5750 c_parser_else_body (c_parser
*parser
, const token_indent_info
&else_tinfo
,
5753 location_t body_loc
= c_parser_peek_token (parser
)->location
;
5754 tree block
= c_begin_compound_stmt (flag_isoc99
);
5755 token_indent_info body_tinfo
5756 = get_token_indent_info (c_parser_peek_token (parser
));
5757 location_t body_loc_after_labels
= UNKNOWN_LOCATION
;
5759 c_parser_all_labels (parser
);
5760 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
5762 location_t loc
= c_parser_peek_token (parser
)->location
;
5765 "suggest braces around empty body in an %<else%> statement");
5766 add_stmt (build_empty_stmt (loc
));
5767 c_parser_consume_token (parser
);
5771 if (!c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
5772 body_loc_after_labels
= c_parser_peek_token (parser
)->location
;
5773 c_parser_statement_after_labels (parser
, NULL
, chain
);
5776 token_indent_info next_tinfo
5777 = get_token_indent_info (c_parser_peek_token (parser
));
5778 warn_for_misleading_indentation (else_tinfo
, body_tinfo
, next_tinfo
);
5779 if (body_loc_after_labels
!= UNKNOWN_LOCATION
5780 && next_tinfo
.type
!= CPP_SEMICOLON
)
5781 warn_for_multistatement_macros (body_loc_after_labels
, next_tinfo
.location
,
5782 else_tinfo
.location
, RID_ELSE
);
5784 return c_end_compound_stmt (body_loc
, block
, flag_isoc99
);
5787 /* We might need to reclassify any previously-lexed identifier, e.g.
5788 when we've left a for loop with an if-statement without else in the
5789 body - we might have used a wrong scope for the token. See PR67784. */
5792 c_parser_maybe_reclassify_token (c_parser
*parser
)
5794 if (c_parser_next_token_is (parser
, CPP_NAME
))
5796 c_token
*token
= c_parser_peek_token (parser
);
5798 if (token
->id_kind
!= C_ID_CLASSNAME
)
5800 tree decl
= lookup_name (token
->value
);
5802 token
->id_kind
= C_ID_ID
;
5805 if (TREE_CODE (decl
) == TYPE_DECL
)
5806 token
->id_kind
= C_ID_TYPENAME
;
5808 else if (c_dialect_objc ())
5810 tree objc_interface_decl
= objc_is_class_name (token
->value
);
5811 /* Objective-C class names are in the same namespace as
5812 variables and typedefs, and hence are shadowed by local
5814 if (objc_interface_decl
)
5816 token
->value
= objc_interface_decl
;
5817 token
->id_kind
= C_ID_CLASSNAME
;
5824 /* Parse an if statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
5827 if ( expression ) statement
5828 if ( expression ) statement else statement
5830 CHAIN is a vector of if-else-if conditions.
5831 IF_P is used to track whether there's a (possibly labeled) if statement
5832 which is not enclosed in braces and has an else clause. This is used to
5833 implement -Wparentheses. */
5836 c_parser_if_statement (c_parser
*parser
, bool *if_p
, vec
<tree
> *chain
)
5841 bool nested_if
= false;
5842 tree first_body
, second_body
;
5845 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_IF
));
5846 token_indent_info if_tinfo
5847 = get_token_indent_info (c_parser_peek_token (parser
));
5848 c_parser_consume_token (parser
);
5849 block
= c_begin_compound_stmt (flag_isoc99
);
5850 loc
= c_parser_peek_token (parser
)->location
;
5851 cond
= c_parser_paren_condition (parser
);
5852 in_if_block
= parser
->in_if_block
;
5853 parser
->in_if_block
= true;
5854 first_body
= c_parser_if_body (parser
, &nested_if
, if_tinfo
);
5855 parser
->in_if_block
= in_if_block
;
5857 if (warn_duplicated_cond
)
5858 warn_duplicated_cond_add_or_warn (EXPR_LOCATION (cond
), cond
, &chain
);
5860 if (c_parser_next_token_is_keyword (parser
, RID_ELSE
))
5862 token_indent_info else_tinfo
5863 = get_token_indent_info (c_parser_peek_token (parser
));
5864 c_parser_consume_token (parser
);
5865 if (warn_duplicated_cond
)
5867 if (c_parser_next_token_is_keyword (parser
, RID_IF
)
5870 /* We've got "if (COND) else if (COND2)". Start the
5871 condition chain and add COND as the first element. */
5872 chain
= new vec
<tree
> ();
5873 if (!CONSTANT_CLASS_P (cond
) && !TREE_SIDE_EFFECTS (cond
))
5874 chain
->safe_push (cond
);
5876 else if (!c_parser_next_token_is_keyword (parser
, RID_IF
))
5878 /* This is if-else without subsequent if. Zap the condition
5879 chain; we would have already warned at this point. */
5884 second_body
= c_parser_else_body (parser
, else_tinfo
, chain
);
5885 /* Set IF_P to true to indicate that this if statement has an
5886 else clause. This may trigger the Wparentheses warning
5887 below when we get back up to the parent if statement. */
5893 second_body
= NULL_TREE
;
5895 /* Diagnose an ambiguous else if if-then-else is nested inside
5898 warning_at (loc
, OPT_Wdangling_else
,
5899 "suggest explicit braces to avoid ambiguous %<else%>");
5901 if (warn_duplicated_cond
)
5903 /* This if statement does not have an else clause. We don't
5904 need the condition chain anymore. */
5909 c_finish_if_stmt (loc
, cond
, first_body
, second_body
);
5910 add_stmt (c_end_compound_stmt (loc
, block
, flag_isoc99
));
5912 c_parser_maybe_reclassify_token (parser
);
5915 /* Parse a switch statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
5918 switch (expression) statement
5922 c_parser_switch_statement (c_parser
*parser
, bool *if_p
)
5925 tree block
, expr
, body
, save_break
;
5926 location_t switch_loc
= c_parser_peek_token (parser
)->location
;
5927 location_t switch_cond_loc
;
5928 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_SWITCH
));
5929 c_parser_consume_token (parser
);
5930 block
= c_begin_compound_stmt (flag_isoc99
);
5931 bool explicit_cast_p
= false;
5932 matching_parens parens
;
5933 if (parens
.require_open (parser
))
5935 switch_cond_loc
= c_parser_peek_token (parser
)->location
;
5936 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
)
5937 && c_token_starts_typename (c_parser_peek_2nd_token (parser
)))
5938 explicit_cast_p
= true;
5939 ce
= c_parser_expression (parser
);
5940 ce
= convert_lvalue_to_rvalue (switch_cond_loc
, ce
, true, false);
5942 /* ??? expr has no valid location? */
5943 parens
.skip_until_found_close (parser
);
5947 switch_cond_loc
= UNKNOWN_LOCATION
;
5948 expr
= error_mark_node
;
5949 ce
.original_type
= error_mark_node
;
5951 c_start_case (switch_loc
, switch_cond_loc
, expr
, explicit_cast_p
);
5952 save_break
= c_break_label
;
5953 c_break_label
= NULL_TREE
;
5954 location_t loc_after_labels
;
5955 bool open_brace_p
= c_parser_peek_token (parser
)->type
== CPP_OPEN_BRACE
;
5956 body
= c_parser_c99_block_statement (parser
, if_p
, &loc_after_labels
);
5957 location_t next_loc
= c_parser_peek_token (parser
)->location
;
5958 if (!open_brace_p
&& c_parser_peek_token (parser
)->type
!= CPP_SEMICOLON
)
5959 warn_for_multistatement_macros (loc_after_labels
, next_loc
, switch_loc
,
5963 location_t here
= c_parser_peek_token (parser
)->location
;
5964 tree t
= build1 (LABEL_EXPR
, void_type_node
, c_break_label
);
5965 SET_EXPR_LOCATION (t
, here
);
5966 SWITCH_BREAK_LABEL_P (c_break_label
) = 1;
5967 append_to_statement_list_force (t
, &body
);
5969 c_finish_case (body
, ce
.original_type
);
5970 c_break_label
= save_break
;
5971 add_stmt (c_end_compound_stmt (switch_loc
, block
, flag_isoc99
));
5972 c_parser_maybe_reclassify_token (parser
);
5975 /* Parse a while statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
5978 while (expression) statement
5980 IF_P is used to track whether there's a (possibly labeled) if statement
5981 which is not enclosed in braces and has an else clause. This is used to
5982 implement -Wparentheses. */
5985 c_parser_while_statement (c_parser
*parser
, bool ivdep
, unsigned short unroll
,
5988 tree block
, cond
, body
, save_break
, save_cont
;
5990 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_WHILE
));
5991 token_indent_info while_tinfo
5992 = get_token_indent_info (c_parser_peek_token (parser
));
5993 c_parser_consume_token (parser
);
5994 block
= c_begin_compound_stmt (flag_isoc99
);
5995 loc
= c_parser_peek_token (parser
)->location
;
5996 cond
= c_parser_paren_condition (parser
);
5997 if (ivdep
&& cond
!= error_mark_node
)
5998 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
5999 build_int_cst (integer_type_node
,
6000 annot_expr_ivdep_kind
),
6002 if (unroll
&& cond
!= error_mark_node
)
6003 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
6004 build_int_cst (integer_type_node
,
6005 annot_expr_unroll_kind
),
6006 build_int_cst (integer_type_node
, unroll
));
6007 save_break
= c_break_label
;
6008 c_break_label
= NULL_TREE
;
6009 save_cont
= c_cont_label
;
6010 c_cont_label
= NULL_TREE
;
6012 token_indent_info body_tinfo
6013 = get_token_indent_info (c_parser_peek_token (parser
));
6015 location_t loc_after_labels
;
6016 bool open_brace
= c_parser_next_token_is (parser
, CPP_OPEN_BRACE
);
6017 body
= c_parser_c99_block_statement (parser
, if_p
, &loc_after_labels
);
6018 c_finish_loop (loc
, loc
, cond
, UNKNOWN_LOCATION
, NULL
, body
,
6019 c_break_label
, c_cont_label
, true);
6020 add_stmt (c_end_compound_stmt (loc
, block
, flag_isoc99
));
6021 c_parser_maybe_reclassify_token (parser
);
6023 token_indent_info next_tinfo
6024 = get_token_indent_info (c_parser_peek_token (parser
));
6025 warn_for_misleading_indentation (while_tinfo
, body_tinfo
, next_tinfo
);
6027 if (next_tinfo
.type
!= CPP_SEMICOLON
&& !open_brace
)
6028 warn_for_multistatement_macros (loc_after_labels
, next_tinfo
.location
,
6029 while_tinfo
.location
, RID_WHILE
);
6031 c_break_label
= save_break
;
6032 c_cont_label
= save_cont
;
6035 /* Parse a do statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6038 do statement while ( expression ) ;
6042 c_parser_do_statement (c_parser
*parser
, bool ivdep
, unsigned short unroll
)
6044 tree block
, cond
, body
, save_break
, save_cont
, new_break
, new_cont
;
6046 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_DO
));
6047 c_parser_consume_token (parser
);
6048 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6049 warning_at (c_parser_peek_token (parser
)->location
,
6051 "suggest braces around empty body in %<do%> statement");
6052 block
= c_begin_compound_stmt (flag_isoc99
);
6053 loc
= c_parser_peek_token (parser
)->location
;
6054 save_break
= c_break_label
;
6055 c_break_label
= NULL_TREE
;
6056 save_cont
= c_cont_label
;
6057 c_cont_label
= NULL_TREE
;
6058 body
= c_parser_c99_block_statement (parser
, NULL
);
6059 c_parser_require_keyword (parser
, RID_WHILE
, "expected %<while%>");
6060 new_break
= c_break_label
;
6061 c_break_label
= save_break
;
6062 new_cont
= c_cont_label
;
6063 c_cont_label
= save_cont
;
6064 location_t cond_loc
= c_parser_peek_token (parser
)->location
;
6065 cond
= c_parser_paren_condition (parser
);
6066 if (ivdep
&& cond
!= error_mark_node
)
6067 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
6068 build_int_cst (integer_type_node
,
6069 annot_expr_ivdep_kind
),
6071 if (unroll
&& cond
!= error_mark_node
)
6072 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
6073 build_int_cst (integer_type_node
,
6074 annot_expr_unroll_kind
),
6075 build_int_cst (integer_type_node
, unroll
));
6076 if (!c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
6077 c_parser_skip_to_end_of_block_or_statement (parser
);
6078 c_finish_loop (loc
, cond_loc
, cond
, UNKNOWN_LOCATION
, NULL
, body
,
6079 new_break
, new_cont
, false);
6080 add_stmt (c_end_compound_stmt (loc
, block
, flag_isoc99
));
6083 /* Parse a for statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6086 for ( expression[opt] ; expression[opt] ; expression[opt] ) statement
6087 for ( nested-declaration expression[opt] ; expression[opt] ) statement
6089 The form with a declaration is new in C99.
6091 ??? In accordance with the old parser, the declaration may be a
6092 nested function, which is then rejected in check_for_loop_decls,
6093 but does it make any sense for this to be included in the grammar?
6094 Note in particular that the nested function does not include a
6095 trailing ';', whereas the "declaration" production includes one.
6096 Also, can we reject bad declarations earlier and cheaper than
6097 check_for_loop_decls?
6099 In Objective-C, there are two additional variants:
6102 for ( expression in expresssion ) statement
6103 for ( declaration in expression ) statement
6105 This is inconsistent with C, because the second variant is allowed
6106 even if c99 is not enabled.
6108 The rest of the comment documents these Objective-C foreach-statement.
6110 Here is the canonical example of the first variant:
6111 for (object in array) { do something with object }
6112 we call the first expression ("object") the "object_expression" and
6113 the second expression ("array") the "collection_expression".
6114 object_expression must be an lvalue of type "id" (a generic Objective-C
6115 object) because the loop works by assigning to object_expression the
6116 various objects from the collection_expression. collection_expression
6117 must evaluate to something of type "id" which responds to the method
6118 countByEnumeratingWithState:objects:count:.
6120 The canonical example of the second variant is:
6121 for (id object in array) { do something with object }
6122 which is completely equivalent to
6125 for (object in array) { do something with object }
6127 Note that initizializing 'object' in some way (eg, "for ((object =
6128 xxx) in array) { do something with object }") is possibly
6129 technically valid, but completely pointless as 'object' will be
6130 assigned to something else as soon as the loop starts. We should
6131 most likely reject it (TODO).
6133 The beginning of the Objective-C foreach-statement looks exactly
6134 like the beginning of the for-statement, and we can tell it is a
6135 foreach-statement only because the initial declaration or
6136 expression is terminated by 'in' instead of ';'.
6138 IF_P is used to track whether there's a (possibly labeled) if statement
6139 which is not enclosed in braces and has an else clause. This is used to
6140 implement -Wparentheses. */
6143 c_parser_for_statement (c_parser
*parser
, bool ivdep
, unsigned short unroll
,
6146 tree block
, cond
, incr
, save_break
, save_cont
, body
;
6147 /* The following are only used when parsing an ObjC foreach statement. */
6148 tree object_expression
;
6149 /* Silence the bogus uninitialized warning. */
6150 tree collection_expression
= NULL
;
6151 location_t loc
= c_parser_peek_token (parser
)->location
;
6152 location_t for_loc
= loc
;
6153 location_t cond_loc
= UNKNOWN_LOCATION
;
6154 location_t incr_loc
= UNKNOWN_LOCATION
;
6155 bool is_foreach_statement
= false;
6156 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_FOR
));
6157 token_indent_info for_tinfo
6158 = get_token_indent_info (c_parser_peek_token (parser
));
6159 c_parser_consume_token (parser
);
6160 /* Open a compound statement in Objective-C as well, just in case this is
6161 as foreach expression. */
6162 block
= c_begin_compound_stmt (flag_isoc99
|| c_dialect_objc ());
6163 cond
= error_mark_node
;
6164 incr
= error_mark_node
;
6165 matching_parens parens
;
6166 if (parens
.require_open (parser
))
6168 /* Parse the initialization declaration or expression. */
6169 object_expression
= error_mark_node
;
6170 parser
->objc_could_be_foreach_context
= c_dialect_objc ();
6171 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6173 parser
->objc_could_be_foreach_context
= false;
6174 c_parser_consume_token (parser
);
6175 c_finish_expr_stmt (loc
, NULL_TREE
);
6177 else if (c_parser_next_tokens_start_declaration (parser
))
6179 c_parser_declaration_or_fndef (parser
, true, true, true, true, true,
6180 &object_expression
, vNULL
);
6181 parser
->objc_could_be_foreach_context
= false;
6183 if (c_parser_next_token_is_keyword (parser
, RID_IN
))
6185 c_parser_consume_token (parser
);
6186 is_foreach_statement
= true;
6187 if (check_for_loop_decls (for_loc
, true) == NULL_TREE
)
6188 c_parser_error (parser
, "multiple iterating variables in "
6189 "fast enumeration");
6192 check_for_loop_decls (for_loc
, flag_isoc99
);
6194 else if (c_parser_next_token_is_keyword (parser
, RID_EXTENSION
))
6196 /* __extension__ can start a declaration, but is also an
6197 unary operator that can start an expression. Consume all
6198 but the last of a possible series of __extension__ to
6200 while (c_parser_peek_2nd_token (parser
)->type
== CPP_KEYWORD
6201 && (c_parser_peek_2nd_token (parser
)->keyword
6203 c_parser_consume_token (parser
);
6204 if (c_token_starts_declaration (c_parser_peek_2nd_token (parser
)))
6207 ext
= disable_extension_diagnostics ();
6208 c_parser_consume_token (parser
);
6209 c_parser_declaration_or_fndef (parser
, true, true, true, true,
6210 true, &object_expression
, vNULL
);
6211 parser
->objc_could_be_foreach_context
= false;
6213 restore_extension_diagnostics (ext
);
6214 if (c_parser_next_token_is_keyword (parser
, RID_IN
))
6216 c_parser_consume_token (parser
);
6217 is_foreach_statement
= true;
6218 if (check_for_loop_decls (for_loc
, true) == NULL_TREE
)
6219 c_parser_error (parser
, "multiple iterating variables in "
6220 "fast enumeration");
6223 check_for_loop_decls (for_loc
, flag_isoc99
);
6233 tree init_expression
;
6234 ce
= c_parser_expression (parser
);
6235 init_expression
= ce
.value
;
6236 parser
->objc_could_be_foreach_context
= false;
6237 if (c_parser_next_token_is_keyword (parser
, RID_IN
))
6239 c_parser_consume_token (parser
);
6240 is_foreach_statement
= true;
6241 if (! lvalue_p (init_expression
))
6242 c_parser_error (parser
, "invalid iterating variable in "
6243 "fast enumeration");
6245 = c_fully_fold (init_expression
, false, NULL
);
6249 ce
= convert_lvalue_to_rvalue (loc
, ce
, true, false);
6250 init_expression
= ce
.value
;
6251 c_finish_expr_stmt (loc
, init_expression
);
6252 c_parser_skip_until_found (parser
, CPP_SEMICOLON
,
6257 /* Parse the loop condition. In the case of a foreach
6258 statement, there is no loop condition. */
6259 gcc_assert (!parser
->objc_could_be_foreach_context
);
6260 if (!is_foreach_statement
)
6262 cond_loc
= c_parser_peek_token (parser
)->location
;
6263 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6267 c_parser_error (parser
, "missing loop condition in loop "
6268 "with %<GCC ivdep%> pragma");
6269 cond
= error_mark_node
;
6273 c_parser_error (parser
, "missing loop condition in loop "
6274 "with %<GCC unroll%> pragma");
6275 cond
= error_mark_node
;
6279 c_parser_consume_token (parser
);
6285 cond
= c_parser_condition (parser
);
6286 c_parser_skip_until_found (parser
, CPP_SEMICOLON
,
6289 if (ivdep
&& cond
!= error_mark_node
)
6290 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
6291 build_int_cst (integer_type_node
,
6292 annot_expr_ivdep_kind
),
6294 if (unroll
&& cond
!= error_mark_node
)
6295 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
6296 build_int_cst (integer_type_node
,
6297 annot_expr_unroll_kind
),
6298 build_int_cst (integer_type_node
, unroll
));
6300 /* Parse the increment expression (the third expression in a
6301 for-statement). In the case of a foreach-statement, this is
6302 the expression that follows the 'in'. */
6303 loc
= incr_loc
= c_parser_peek_token (parser
)->location
;
6304 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
6306 if (is_foreach_statement
)
6308 c_parser_error (parser
,
6309 "missing collection in fast enumeration");
6310 collection_expression
= error_mark_node
;
6313 incr
= c_process_expr_stmt (loc
, NULL_TREE
);
6317 if (is_foreach_statement
)
6318 collection_expression
6319 = c_fully_fold (c_parser_expression (parser
).value
, false, NULL
);
6322 struct c_expr ce
= c_parser_expression (parser
);
6323 ce
= convert_lvalue_to_rvalue (loc
, ce
, true, false);
6324 incr
= c_process_expr_stmt (loc
, ce
.value
);
6327 parens
.skip_until_found_close (parser
);
6329 save_break
= c_break_label
;
6330 c_break_label
= NULL_TREE
;
6331 save_cont
= c_cont_label
;
6332 c_cont_label
= NULL_TREE
;
6334 token_indent_info body_tinfo
6335 = get_token_indent_info (c_parser_peek_token (parser
));
6337 location_t loc_after_labels
;
6338 bool open_brace
= c_parser_next_token_is (parser
, CPP_OPEN_BRACE
);
6339 body
= c_parser_c99_block_statement (parser
, if_p
, &loc_after_labels
);
6341 if (is_foreach_statement
)
6342 objc_finish_foreach_loop (for_loc
, object_expression
,
6343 collection_expression
, body
, c_break_label
,
6346 c_finish_loop (for_loc
, cond_loc
, cond
, incr_loc
, incr
, body
,
6347 c_break_label
, c_cont_label
, true);
6348 add_stmt (c_end_compound_stmt (for_loc
, block
,
6349 flag_isoc99
|| c_dialect_objc ()));
6350 c_parser_maybe_reclassify_token (parser
);
6352 token_indent_info next_tinfo
6353 = get_token_indent_info (c_parser_peek_token (parser
));
6354 warn_for_misleading_indentation (for_tinfo
, body_tinfo
, next_tinfo
);
6356 if (next_tinfo
.type
!= CPP_SEMICOLON
&& !open_brace
)
6357 warn_for_multistatement_macros (loc_after_labels
, next_tinfo
.location
,
6358 for_tinfo
.location
, RID_FOR
);
6360 c_break_label
= save_break
;
6361 c_cont_label
= save_cont
;
6364 /* Parse an asm statement, a GNU extension. This is a full-blown asm
6365 statement with inputs, outputs, clobbers, and volatile, inline, and goto
6374 asm-qualifier-list asm-qualifier
6378 asm asm-qualifier-list[opt] ( asm-argument ) ;
6382 asm-string-literal : asm-operands[opt]
6383 asm-string-literal : asm-operands[opt] : asm-operands[opt]
6384 asm-string-literal : asm-operands[opt] : asm-operands[opt] \
6386 asm-string-literal : : asm-operands[opt] : asm-clobbers[opt] \
6389 The form with asm-goto-operands is valid if and only if the
6390 asm-qualifier-list contains goto, and is the only allowed form in that case.
6391 Duplicate asm-qualifiers are not allowed.
6393 The :: token is considered equivalent to two consecutive : tokens. */
6396 c_parser_asm_statement (c_parser
*parser
)
6398 tree str
, outputs
, inputs
, clobbers
, labels
, ret
;
6400 location_t asm_loc
= c_parser_peek_token (parser
)->location
;
6401 int section
, nsections
;
6403 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ASM
));
6404 c_parser_consume_token (parser
);
6406 /* Handle the asm-qualifier-list. */
6407 location_t volatile_loc
= UNKNOWN_LOCATION
;
6408 location_t inline_loc
= UNKNOWN_LOCATION
;
6409 location_t goto_loc
= UNKNOWN_LOCATION
;
6412 c_token
*token
= c_parser_peek_token (parser
);
6413 location_t loc
= token
->location
;
6414 switch (token
->keyword
)
6419 error_at (loc
, "duplicate %<asm%> qualifier %qE", token
->value
);
6420 inform (volatile_loc
, "first seen here");
6424 c_parser_consume_token (parser
);
6430 error_at (loc
, "duplicate %<asm%> qualifier %qE", token
->value
);
6431 inform (inline_loc
, "first seen here");
6435 c_parser_consume_token (parser
);
6441 error_at (loc
, "duplicate %<asm%> qualifier %qE", token
->value
);
6442 inform (goto_loc
, "first seen here");
6446 c_parser_consume_token (parser
);
6451 error_at (loc
, "%qE is not a valid %<asm%> qualifier", token
->value
);
6452 c_parser_consume_token (parser
);
6461 bool is_volatile
= (volatile_loc
!= UNKNOWN_LOCATION
);
6462 bool is_inline
= (inline_loc
!= UNKNOWN_LOCATION
);
6463 bool is_goto
= (goto_loc
!= UNKNOWN_LOCATION
);
6467 matching_parens parens
;
6468 if (!parens
.require_open (parser
))
6471 str
= c_parser_asm_string_literal (parser
);
6472 if (str
== NULL_TREE
)
6473 goto error_close_paren
;
6476 outputs
= NULL_TREE
;
6478 clobbers
= NULL_TREE
;
6481 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
) && !is_goto
)
6484 /* Parse each colon-delimited section of operands. */
6485 nsections
= 3 + is_goto
;
6486 for (section
= 0; section
< nsections
; ++section
)
6488 if (c_parser_next_token_is (parser
, CPP_SCOPE
))
6491 if (section
== nsections
)
6493 c_parser_error (parser
, "expected %<)%>");
6494 goto error_close_paren
;
6496 c_parser_consume_token (parser
);
6498 else if (!c_parser_require (parser
, CPP_COLON
,
6500 ? G_("expected %<:%>")
6501 : G_("expected %<:%> or %<)%>"),
6502 UNKNOWN_LOCATION
, is_goto
))
6503 goto error_close_paren
;
6505 /* Once past any colon, we're no longer a simple asm. */
6508 if ((!c_parser_next_token_is (parser
, CPP_COLON
)
6509 && !c_parser_next_token_is (parser
, CPP_SCOPE
)
6510 && !c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
6515 /* For asm goto, we don't allow output operands, but reserve
6516 the slot for a future extension that does allow them. */
6518 outputs
= c_parser_asm_operands (parser
);
6521 inputs
= c_parser_asm_operands (parser
);
6524 clobbers
= c_parser_asm_clobbers (parser
);
6527 labels
= c_parser_asm_goto_operands (parser
);
6533 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
) && !is_goto
)
6538 if (!parens
.require_close (parser
))
6540 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
6544 if (!c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
6545 c_parser_skip_to_end_of_block_or_statement (parser
);
6547 ret
= build_asm_stmt (is_volatile
,
6548 build_asm_expr (asm_loc
, str
, outputs
, inputs
,
6549 clobbers
, labels
, simple
, is_inline
));
6555 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
6559 /* Parse asm operands, a GNU extension.
6563 asm-operands , asm-operand
6566 asm-string-literal ( expression )
6567 [ identifier ] asm-string-literal ( expression )
6571 c_parser_asm_operands (c_parser
*parser
)
6573 tree list
= NULL_TREE
;
6578 if (c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
))
6580 c_parser_consume_token (parser
);
6581 if (c_parser_next_token_is (parser
, CPP_NAME
))
6583 tree id
= c_parser_peek_token (parser
)->value
;
6584 c_parser_consume_token (parser
);
6585 name
= build_string (IDENTIFIER_LENGTH (id
),
6586 IDENTIFIER_POINTER (id
));
6590 c_parser_error (parser
, "expected identifier");
6591 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
, NULL
);
6594 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
6599 str
= c_parser_asm_string_literal (parser
);
6600 if (str
== NULL_TREE
)
6602 matching_parens parens
;
6603 if (!parens
.require_open (parser
))
6605 expr
= c_parser_expression (parser
);
6606 mark_exp_read (expr
.value
);
6607 if (!parens
.require_close (parser
))
6609 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
6612 list
= chainon (list
, build_tree_list (build_tree_list (name
, str
),
6614 if (c_parser_next_token_is (parser
, CPP_COMMA
))
6615 c_parser_consume_token (parser
);
6622 /* Parse asm clobbers, a GNU extension.
6626 asm-clobbers , asm-string-literal
6630 c_parser_asm_clobbers (c_parser
*parser
)
6632 tree list
= NULL_TREE
;
6635 tree str
= c_parser_asm_string_literal (parser
);
6637 list
= tree_cons (NULL_TREE
, str
, list
);
6640 if (c_parser_next_token_is (parser
, CPP_COMMA
))
6641 c_parser_consume_token (parser
);
6648 /* Parse asm goto labels, a GNU extension.
6652 asm-goto-operands , identifier
6656 c_parser_asm_goto_operands (c_parser
*parser
)
6658 tree list
= NULL_TREE
;
6663 if (c_parser_next_token_is (parser
, CPP_NAME
))
6665 c_token
*tok
= c_parser_peek_token (parser
);
6667 label
= lookup_label_for_goto (tok
->location
, name
);
6668 c_parser_consume_token (parser
);
6669 TREE_USED (label
) = 1;
6673 c_parser_error (parser
, "expected identifier");
6677 name
= build_string (IDENTIFIER_LENGTH (name
),
6678 IDENTIFIER_POINTER (name
));
6679 list
= tree_cons (name
, label
, list
);
6680 if (c_parser_next_token_is (parser
, CPP_COMMA
))
6681 c_parser_consume_token (parser
);
6683 return nreverse (list
);
6687 /* Parse a possibly concatenated sequence of string literals.
6688 TRANSLATE says whether to translate them to the execution character
6689 set; WIDE_OK says whether any kind of prefixed string literal is
6690 permitted in this context. This code is based on that in
6694 c_parser_string_literal (c_parser
*parser
, bool translate
, bool wide_ok
)
6698 struct obstack str_ob
;
6699 struct obstack loc_ob
;
6700 cpp_string str
, istr
, *strs
;
6702 location_t loc
, last_tok_loc
;
6703 enum cpp_ttype type
;
6704 tree value
, string_tree
;
6706 tok
= c_parser_peek_token (parser
);
6707 loc
= tok
->location
;
6708 last_tok_loc
= linemap_resolve_location (line_table
, loc
,
6709 LRK_MACRO_DEFINITION_LOCATION
,
6718 case CPP_UTF8STRING
:
6719 string_tree
= tok
->value
;
6723 c_parser_error (parser
, "expected string literal");
6725 ret
.value
= NULL_TREE
;
6726 ret
.original_code
= ERROR_MARK
;
6727 ret
.original_type
= NULL_TREE
;
6731 /* Try to avoid the overhead of creating and destroying an obstack
6732 for the common case of just one string. */
6733 switch (c_parser_peek_2nd_token (parser
)->type
)
6736 c_parser_consume_token (parser
);
6737 str
.text
= (const unsigned char *) TREE_STRING_POINTER (string_tree
);
6738 str
.len
= TREE_STRING_LENGTH (string_tree
);
6747 case CPP_UTF8STRING
:
6748 gcc_obstack_init (&str_ob
);
6749 gcc_obstack_init (&loc_ob
);
6753 c_parser_consume_token (parser
);
6755 str
.text
= (const unsigned char *) TREE_STRING_POINTER (string_tree
);
6756 str
.len
= TREE_STRING_LENGTH (string_tree
);
6757 if (type
!= tok
->type
)
6759 if (type
== CPP_STRING
)
6761 else if (tok
->type
!= CPP_STRING
)
6762 error ("unsupported non-standard concatenation "
6763 "of string literals");
6765 obstack_grow (&str_ob
, &str
, sizeof (cpp_string
));
6766 obstack_grow (&loc_ob
, &last_tok_loc
, sizeof (location_t
));
6767 tok
= c_parser_peek_token (parser
);
6768 string_tree
= tok
->value
;
6770 = linemap_resolve_location (line_table
, tok
->location
,
6771 LRK_MACRO_DEFINITION_LOCATION
, NULL
);
6773 while (tok
->type
== CPP_STRING
6774 || tok
->type
== CPP_WSTRING
6775 || tok
->type
== CPP_STRING16
6776 || tok
->type
== CPP_STRING32
6777 || tok
->type
== CPP_UTF8STRING
);
6778 strs
= (cpp_string
*) obstack_finish (&str_ob
);
6781 if (count
> 1 && !in_system_header_at (input_location
))
6782 warning (OPT_Wtraditional
,
6783 "traditional C rejects string constant concatenation");
6785 if ((type
== CPP_STRING
|| wide_ok
)
6787 ? cpp_interpret_string
: cpp_interpret_string_notranslate
)
6788 (parse_in
, strs
, count
, &istr
, type
)))
6790 value
= build_string (istr
.len
, (const char *) istr
.text
);
6791 free (CONST_CAST (unsigned char *, istr
.text
));
6794 location_t
*locs
= (location_t
*) obstack_finish (&loc_ob
);
6795 gcc_assert (g_string_concat_db
);
6796 g_string_concat_db
->record_string_concatenation (count
, locs
);
6801 if (type
!= CPP_STRING
&& !wide_ok
)
6803 error_at (loc
, "a wide string is invalid in this context");
6806 /* Callers cannot generally handle error_mark_node in this
6807 context, so return the empty string instead. An error has
6808 been issued, either above or from cpp_interpret_string. */
6813 case CPP_UTF8STRING
:
6814 value
= build_string (1, "");
6817 value
= build_string (TYPE_PRECISION (char16_type_node
)
6818 / TYPE_PRECISION (char_type_node
),
6819 "\0"); /* char16_t is 16 bits */
6822 value
= build_string (TYPE_PRECISION (char32_type_node
)
6823 / TYPE_PRECISION (char_type_node
),
6824 "\0\0\0"); /* char32_t is 32 bits */
6827 value
= build_string (TYPE_PRECISION (wchar_type_node
)
6828 / TYPE_PRECISION (char_type_node
),
6829 "\0\0\0"); /* widest supported wchar_t
6839 case CPP_UTF8STRING
:
6840 TREE_TYPE (value
) = char_array_type_node
;
6843 TREE_TYPE (value
) = char16_array_type_node
;
6846 TREE_TYPE (value
) = char32_array_type_node
;
6849 TREE_TYPE (value
) = wchar_array_type_node
;
6851 value
= fix_string_type (value
);
6855 obstack_free (&str_ob
, 0);
6856 obstack_free (&loc_ob
, 0);
6860 ret
.original_code
= STRING_CST
;
6861 ret
.original_type
= NULL_TREE
;
6862 set_c_expr_source_range (&ret
, get_range_from_loc (line_table
, loc
));
6866 /* Parse an expression other than a compound expression; that is, an
6867 assignment expression (C90 6.3.16, C99 6.5.16, C11 6.5.16). If
6868 AFTER is not NULL then it is an Objective-C message expression which
6869 is the primary-expression starting the expression as an initializer.
6871 assignment-expression:
6872 conditional-expression
6873 unary-expression assignment-operator assignment-expression
6875 assignment-operator: one of
6876 = *= /= %= += -= <<= >>= &= ^= |=
6878 In GNU C we accept any conditional expression on the LHS and
6879 diagnose the invalid lvalue rather than producing a syntax
6882 static struct c_expr
6883 c_parser_expr_no_commas (c_parser
*parser
, struct c_expr
*after
,
6884 tree omp_atomic_lhs
)
6886 struct c_expr lhs
, rhs
, ret
;
6887 enum tree_code code
;
6888 location_t op_location
, exp_location
;
6889 gcc_assert (!after
|| c_dialect_objc ());
6890 lhs
= c_parser_conditional_expression (parser
, after
, omp_atomic_lhs
);
6891 op_location
= c_parser_peek_token (parser
)->location
;
6892 switch (c_parser_peek_token (parser
)->type
)
6901 code
= TRUNC_DIV_EXPR
;
6904 code
= TRUNC_MOD_EXPR
;
6919 code
= BIT_AND_EXPR
;
6922 code
= BIT_XOR_EXPR
;
6925 code
= BIT_IOR_EXPR
;
6930 c_parser_consume_token (parser
);
6931 exp_location
= c_parser_peek_token (parser
)->location
;
6932 rhs
= c_parser_expr_no_commas (parser
, NULL
);
6933 rhs
= convert_lvalue_to_rvalue (exp_location
, rhs
, true, true);
6935 ret
.value
= build_modify_expr (op_location
, lhs
.value
, lhs
.original_type
,
6936 code
, exp_location
, rhs
.value
,
6938 set_c_expr_source_range (&ret
, lhs
.get_start (), rhs
.get_finish ());
6939 if (code
== NOP_EXPR
)
6940 ret
.original_code
= MODIFY_EXPR
;
6943 TREE_NO_WARNING (ret
.value
) = 1;
6944 ret
.original_code
= ERROR_MARK
;
6946 ret
.original_type
= NULL
;
6950 /* Parse a conditional expression (C90 6.3.15, C99 6.5.15, C11 6.5.15). If
6951 AFTER is not NULL then it is an Objective-C message expression which is
6952 the primary-expression starting the expression as an initializer.
6954 conditional-expression:
6955 logical-OR-expression
6956 logical-OR-expression ? expression : conditional-expression
6960 conditional-expression:
6961 logical-OR-expression ? : conditional-expression
6964 static struct c_expr
6965 c_parser_conditional_expression (c_parser
*parser
, struct c_expr
*after
,
6966 tree omp_atomic_lhs
)
6968 struct c_expr cond
, exp1
, exp2
, ret
;
6969 location_t start
, cond_loc
, colon_loc
;
6971 gcc_assert (!after
|| c_dialect_objc ());
6973 cond
= c_parser_binary_expression (parser
, after
, omp_atomic_lhs
);
6975 if (c_parser_next_token_is_not (parser
, CPP_QUERY
))
6977 if (cond
.value
!= error_mark_node
)
6978 start
= cond
.get_start ();
6980 start
= UNKNOWN_LOCATION
;
6981 cond_loc
= c_parser_peek_token (parser
)->location
;
6982 cond
= convert_lvalue_to_rvalue (cond_loc
, cond
, true, true);
6983 c_parser_consume_token (parser
);
6984 if (c_parser_next_token_is (parser
, CPP_COLON
))
6986 tree eptype
= NULL_TREE
;
6988 location_t middle_loc
= c_parser_peek_token (parser
)->location
;
6989 pedwarn (middle_loc
, OPT_Wpedantic
,
6990 "ISO C forbids omitting the middle term of a %<?:%> expression");
6991 if (TREE_CODE (cond
.value
) == EXCESS_PRECISION_EXPR
)
6993 eptype
= TREE_TYPE (cond
.value
);
6994 cond
.value
= TREE_OPERAND (cond
.value
, 0);
6996 tree e
= cond
.value
;
6997 while (TREE_CODE (e
) == COMPOUND_EXPR
)
6998 e
= TREE_OPERAND (e
, 1);
6999 warn_for_omitted_condop (middle_loc
, e
);
7000 /* Make sure first operand is calculated only once. */
7001 exp1
.value
= save_expr (default_conversion (cond
.value
));
7003 exp1
.value
= build1 (EXCESS_PRECISION_EXPR
, eptype
, exp1
.value
);
7004 exp1
.original_type
= NULL
;
7005 exp1
.src_range
= cond
.src_range
;
7006 cond
.value
= c_objc_common_truthvalue_conversion (cond_loc
, exp1
.value
);
7007 c_inhibit_evaluation_warnings
+= cond
.value
== truthvalue_true_node
;
7012 = c_objc_common_truthvalue_conversion
7013 (cond_loc
, default_conversion (cond
.value
));
7014 c_inhibit_evaluation_warnings
+= cond
.value
== truthvalue_false_node
;
7015 exp1
= c_parser_expression_conv (parser
);
7016 mark_exp_read (exp1
.value
);
7017 c_inhibit_evaluation_warnings
+=
7018 ((cond
.value
== truthvalue_true_node
)
7019 - (cond
.value
== truthvalue_false_node
));
7022 colon_loc
= c_parser_peek_token (parser
)->location
;
7023 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
7025 c_inhibit_evaluation_warnings
-= cond
.value
== truthvalue_true_node
;
7027 ret
.original_code
= ERROR_MARK
;
7028 ret
.original_type
= NULL
;
7032 location_t exp2_loc
= c_parser_peek_token (parser
)->location
;
7033 exp2
= c_parser_conditional_expression (parser
, NULL
, NULL_TREE
);
7034 exp2
= convert_lvalue_to_rvalue (exp2_loc
, exp2
, true, true);
7036 c_inhibit_evaluation_warnings
-= cond
.value
== truthvalue_true_node
;
7037 location_t loc1
= make_location (exp1
.get_start (), exp1
.src_range
);
7038 location_t loc2
= make_location (exp2
.get_start (), exp2
.src_range
);
7039 ret
.value
= build_conditional_expr (colon_loc
, cond
.value
,
7040 cond
.original_code
== C_MAYBE_CONST_EXPR
,
7041 exp1
.value
, exp1
.original_type
, loc1
,
7042 exp2
.value
, exp2
.original_type
, loc2
);
7043 ret
.original_code
= ERROR_MARK
;
7044 if (exp1
.value
== error_mark_node
|| exp2
.value
== error_mark_node
)
7045 ret
.original_type
= NULL
;
7050 /* If both sides are enum type, the default conversion will have
7051 made the type of the result be an integer type. We want to
7052 remember the enum types we started with. */
7053 t1
= exp1
.original_type
? exp1
.original_type
: TREE_TYPE (exp1
.value
);
7054 t2
= exp2
.original_type
? exp2
.original_type
: TREE_TYPE (exp2
.value
);
7055 ret
.original_type
= ((t1
!= error_mark_node
7056 && t2
!= error_mark_node
7057 && (TYPE_MAIN_VARIANT (t1
)
7058 == TYPE_MAIN_VARIANT (t2
)))
7062 set_c_expr_source_range (&ret
, start
, exp2
.get_finish ());
7066 /* Parse a binary expression; that is, a logical-OR-expression (C90
7067 6.3.5-6.3.14, C99 6.5.5-6.5.14, C11 6.5.5-6.5.14). If AFTER is not
7068 NULL then it is an Objective-C message expression which is the
7069 primary-expression starting the expression as an initializer.
7071 OMP_ATOMIC_LHS is NULL, unless parsing OpenMP #pragma omp atomic,
7072 when it should be the unfolded lhs. In a valid OpenMP source,
7073 one of the operands of the toplevel binary expression must be equal
7074 to it. In that case, just return a build2 created binary operation
7075 rather than result of parser_build_binary_op.
7077 multiplicative-expression:
7079 multiplicative-expression * cast-expression
7080 multiplicative-expression / cast-expression
7081 multiplicative-expression % cast-expression
7083 additive-expression:
7084 multiplicative-expression
7085 additive-expression + multiplicative-expression
7086 additive-expression - multiplicative-expression
7090 shift-expression << additive-expression
7091 shift-expression >> additive-expression
7093 relational-expression:
7095 relational-expression < shift-expression
7096 relational-expression > shift-expression
7097 relational-expression <= shift-expression
7098 relational-expression >= shift-expression
7100 equality-expression:
7101 relational-expression
7102 equality-expression == relational-expression
7103 equality-expression != relational-expression
7107 AND-expression & equality-expression
7109 exclusive-OR-expression:
7111 exclusive-OR-expression ^ AND-expression
7113 inclusive-OR-expression:
7114 exclusive-OR-expression
7115 inclusive-OR-expression | exclusive-OR-expression
7117 logical-AND-expression:
7118 inclusive-OR-expression
7119 logical-AND-expression && inclusive-OR-expression
7121 logical-OR-expression:
7122 logical-AND-expression
7123 logical-OR-expression || logical-AND-expression
7126 static struct c_expr
7127 c_parser_binary_expression (c_parser
*parser
, struct c_expr
*after
,
7128 tree omp_atomic_lhs
)
7130 /* A binary expression is parsed using operator-precedence parsing,
7131 with the operands being cast expressions. All the binary
7132 operators are left-associative. Thus a binary expression is of
7135 E0 op1 E1 op2 E2 ...
7137 which we represent on a stack. On the stack, the precedence
7138 levels are strictly increasing. When a new operator is
7139 encountered of higher precedence than that at the top of the
7140 stack, it is pushed; its LHS is the top expression, and its RHS
7141 is everything parsed until it is popped. When a new operator is
7142 encountered with precedence less than or equal to that at the top
7143 of the stack, triples E[i-1] op[i] E[i] are popped and replaced
7144 by the result of the operation until the operator at the top of
7145 the stack has lower precedence than the new operator or there is
7146 only one element on the stack; then the top expression is the LHS
7147 of the new operator. In the case of logical AND and OR
7148 expressions, we also need to adjust c_inhibit_evaluation_warnings
7149 as appropriate when the operators are pushed and popped. */
7152 /* The expression at this stack level. */
7154 /* The precedence of the operator on its left, PREC_NONE at the
7155 bottom of the stack. */
7156 enum c_parser_prec prec
;
7157 /* The operation on its left. */
7159 /* The source location of this operation. */
7161 /* The sizeof argument if expr.original_code == SIZEOF_EXPR. */
7165 /* Location of the binary operator. */
7166 location_t binary_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
7169 switch (stack[sp].op) \
7171 case TRUTH_ANDIF_EXPR: \
7172 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
7173 == truthvalue_false_node); \
7175 case TRUTH_ORIF_EXPR: \
7176 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
7177 == truthvalue_true_node); \
7179 case TRUNC_DIV_EXPR: \
7180 if (stack[sp - 1].expr.original_code == SIZEOF_EXPR \
7181 && stack[sp].expr.original_code == SIZEOF_EXPR) \
7183 tree type0 = stack[sp - 1].sizeof_arg; \
7184 tree type1 = stack[sp].sizeof_arg; \
7185 tree first_arg = type0; \
7186 if (!TYPE_P (type0)) \
7187 type0 = TREE_TYPE (type0); \
7188 if (!TYPE_P (type1)) \
7189 type1 = TREE_TYPE (type1); \
7190 if (POINTER_TYPE_P (type0) \
7191 && comptypes (TREE_TYPE (type0), type1) \
7192 && !(TREE_CODE (first_arg) == PARM_DECL \
7193 && C_ARRAY_PARAMETER (first_arg) \
7194 && warn_sizeof_array_argument)) \
7196 auto_diagnostic_group d; \
7197 if (warning_at (stack[sp].loc, OPT_Wsizeof_pointer_div, \
7198 "division %<sizeof (%T) / sizeof (%T)%> " \
7199 "does not compute the number of array " \
7202 if (DECL_P (first_arg)) \
7203 inform (DECL_SOURCE_LOCATION (first_arg), \
7204 "first %<sizeof%> operand was declared here"); \
7211 stack[sp - 1].expr \
7212 = convert_lvalue_to_rvalue (stack[sp - 1].loc, \
7213 stack[sp - 1].expr, true, true); \
7215 = convert_lvalue_to_rvalue (stack[sp].loc, \
7216 stack[sp].expr, true, true); \
7217 if (__builtin_expect (omp_atomic_lhs != NULL_TREE, 0) && sp == 1 \
7218 && c_parser_peek_token (parser)->type == CPP_SEMICOLON \
7219 && ((1 << stack[sp].prec) \
7220 & ((1 << PREC_BITOR) | (1 << PREC_BITXOR) | (1 << PREC_BITAND) \
7221 | (1 << PREC_SHIFT) | (1 << PREC_ADD) | (1 << PREC_MULT))) \
7222 && stack[sp].op != TRUNC_MOD_EXPR \
7223 && stack[0].expr.value != error_mark_node \
7224 && stack[1].expr.value != error_mark_node \
7225 && (c_tree_equal (stack[0].expr.value, omp_atomic_lhs) \
7226 || c_tree_equal (stack[1].expr.value, omp_atomic_lhs))) \
7227 stack[0].expr.value \
7228 = build2 (stack[1].op, TREE_TYPE (stack[0].expr.value), \
7229 stack[0].expr.value, stack[1].expr.value); \
7231 stack[sp - 1].expr = parser_build_binary_op (stack[sp].loc, \
7233 stack[sp - 1].expr, \
7237 gcc_assert (!after
|| c_dialect_objc ());
7238 stack
[0].loc
= c_parser_peek_token (parser
)->location
;
7239 stack
[0].expr
= c_parser_cast_expression (parser
, after
);
7240 stack
[0].prec
= PREC_NONE
;
7241 stack
[0].sizeof_arg
= c_last_sizeof_arg
;
7245 enum c_parser_prec oprec
;
7246 enum tree_code ocode
;
7247 source_range src_range
;
7250 switch (c_parser_peek_token (parser
)->type
)
7258 ocode
= TRUNC_DIV_EXPR
;
7262 ocode
= TRUNC_MOD_EXPR
;
7274 ocode
= LSHIFT_EXPR
;
7278 ocode
= RSHIFT_EXPR
;
7292 case CPP_GREATER_EQ
:
7305 oprec
= PREC_BITAND
;
7306 ocode
= BIT_AND_EXPR
;
7309 oprec
= PREC_BITXOR
;
7310 ocode
= BIT_XOR_EXPR
;
7314 ocode
= BIT_IOR_EXPR
;
7317 oprec
= PREC_LOGAND
;
7318 ocode
= TRUTH_ANDIF_EXPR
;
7322 ocode
= TRUTH_ORIF_EXPR
;
7325 /* Not a binary operator, so end of the binary
7329 binary_loc
= c_parser_peek_token (parser
)->location
;
7330 while (oprec
<= stack
[sp
].prec
)
7332 c_parser_consume_token (parser
);
7335 case TRUTH_ANDIF_EXPR
:
7336 src_range
= stack
[sp
].expr
.src_range
;
7338 = convert_lvalue_to_rvalue (stack
[sp
].loc
,
7339 stack
[sp
].expr
, true, true);
7340 stack
[sp
].expr
.value
= c_objc_common_truthvalue_conversion
7341 (stack
[sp
].loc
, default_conversion (stack
[sp
].expr
.value
));
7342 c_inhibit_evaluation_warnings
+= (stack
[sp
].expr
.value
7343 == truthvalue_false_node
);
7344 set_c_expr_source_range (&stack
[sp
].expr
, src_range
);
7346 case TRUTH_ORIF_EXPR
:
7347 src_range
= stack
[sp
].expr
.src_range
;
7349 = convert_lvalue_to_rvalue (stack
[sp
].loc
,
7350 stack
[sp
].expr
, true, true);
7351 stack
[sp
].expr
.value
= c_objc_common_truthvalue_conversion
7352 (stack
[sp
].loc
, default_conversion (stack
[sp
].expr
.value
));
7353 c_inhibit_evaluation_warnings
+= (stack
[sp
].expr
.value
7354 == truthvalue_true_node
);
7355 set_c_expr_source_range (&stack
[sp
].expr
, src_range
);
7361 stack
[sp
].loc
= binary_loc
;
7362 stack
[sp
].expr
= c_parser_cast_expression (parser
, NULL
);
7363 stack
[sp
].prec
= oprec
;
7364 stack
[sp
].op
= ocode
;
7365 stack
[sp
].sizeof_arg
= c_last_sizeof_arg
;
7370 return stack
[0].expr
;
7374 /* Parse a cast expression (C90 6.3.4, C99 6.5.4, C11 6.5.4). If AFTER
7375 is not NULL then it is an Objective-C message expression which is the
7376 primary-expression starting the expression as an initializer.
7380 ( type-name ) unary-expression
7383 static struct c_expr
7384 c_parser_cast_expression (c_parser
*parser
, struct c_expr
*after
)
7386 location_t cast_loc
= c_parser_peek_token (parser
)->location
;
7387 gcc_assert (!after
|| c_dialect_objc ());
7389 return c_parser_postfix_expression_after_primary (parser
,
7391 /* If the expression begins with a parenthesized type name, it may
7392 be either a cast or a compound literal; we need to see whether
7393 the next character is '{' to tell the difference. If not, it is
7394 an unary expression. Full detection of unknown typenames here
7395 would require a 3-token lookahead. */
7396 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
)
7397 && c_token_starts_typename (c_parser_peek_2nd_token (parser
)))
7399 struct c_type_name
*type_name
;
7402 matching_parens parens
;
7403 parens
.consume_open (parser
);
7404 type_name
= c_parser_type_name (parser
, true);
7405 parens
.skip_until_found_close (parser
);
7406 if (type_name
== NULL
)
7409 ret
.original_code
= ERROR_MARK
;
7410 ret
.original_type
= NULL
;
7414 /* Save casted types in the function's used types hash table. */
7415 used_types_insert (type_name
->specs
->type
);
7417 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
7418 return c_parser_postfix_expression_after_paren_type (parser
, type_name
,
7420 if (type_name
->specs
->alignas_p
)
7421 error_at (type_name
->specs
->locations
[cdw_alignas
],
7422 "alignment specified for type name in cast");
7424 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
7425 expr
= c_parser_cast_expression (parser
, NULL
);
7426 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, true, true);
7428 ret
.value
= c_cast_expr (cast_loc
, type_name
, expr
.value
);
7429 if (ret
.value
&& expr
.value
)
7430 set_c_expr_source_range (&ret
, cast_loc
, expr
.get_finish ());
7431 ret
.original_code
= ERROR_MARK
;
7432 ret
.original_type
= NULL
;
7436 return c_parser_unary_expression (parser
);
7439 /* Parse an unary expression (C90 6.3.3, C99 6.5.3, C11 6.5.3).
7445 unary-operator cast-expression
7446 sizeof unary-expression
7447 sizeof ( type-name )
7449 unary-operator: one of
7455 __alignof__ unary-expression
7456 __alignof__ ( type-name )
7459 (C11 permits _Alignof with type names only.)
7461 unary-operator: one of
7462 __extension__ __real__ __imag__
7464 Transactional Memory:
7467 transaction-expression
7469 In addition, the GNU syntax treats ++ and -- as unary operators, so
7470 they may be applied to cast expressions with errors for non-lvalues
7473 static struct c_expr
7474 c_parser_unary_expression (c_parser
*parser
)
7477 struct c_expr ret
, op
;
7478 location_t op_loc
= c_parser_peek_token (parser
)->location
;
7481 ret
.original_code
= ERROR_MARK
;
7482 ret
.original_type
= NULL
;
7483 switch (c_parser_peek_token (parser
)->type
)
7486 c_parser_consume_token (parser
);
7487 exp_loc
= c_parser_peek_token (parser
)->location
;
7488 op
= c_parser_cast_expression (parser
, NULL
);
7490 op
= default_function_array_read_conversion (exp_loc
, op
);
7491 return parser_build_unary_op (op_loc
, PREINCREMENT_EXPR
, op
);
7492 case CPP_MINUS_MINUS
:
7493 c_parser_consume_token (parser
);
7494 exp_loc
= c_parser_peek_token (parser
)->location
;
7495 op
= c_parser_cast_expression (parser
, NULL
);
7497 op
= default_function_array_read_conversion (exp_loc
, op
);
7498 return parser_build_unary_op (op_loc
, PREDECREMENT_EXPR
, op
);
7500 c_parser_consume_token (parser
);
7501 op
= c_parser_cast_expression (parser
, NULL
);
7502 mark_exp_read (op
.value
);
7503 return parser_build_unary_op (op_loc
, ADDR_EXPR
, op
);
7506 c_parser_consume_token (parser
);
7507 exp_loc
= c_parser_peek_token (parser
)->location
;
7508 op
= c_parser_cast_expression (parser
, NULL
);
7509 finish
= op
.get_finish ();
7510 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
7511 location_t combined_loc
= make_location (op_loc
, op_loc
, finish
);
7512 ret
.value
= build_indirect_ref (combined_loc
, op
.value
, RO_UNARY_STAR
);
7513 ret
.src_range
.m_start
= op_loc
;
7514 ret
.src_range
.m_finish
= finish
;
7518 if (!c_dialect_objc () && !in_system_header_at (input_location
))
7521 "traditional C rejects the unary plus operator");
7522 c_parser_consume_token (parser
);
7523 exp_loc
= c_parser_peek_token (parser
)->location
;
7524 op
= c_parser_cast_expression (parser
, NULL
);
7525 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
7526 return parser_build_unary_op (op_loc
, CONVERT_EXPR
, op
);
7528 c_parser_consume_token (parser
);
7529 exp_loc
= c_parser_peek_token (parser
)->location
;
7530 op
= c_parser_cast_expression (parser
, NULL
);
7531 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
7532 return parser_build_unary_op (op_loc
, NEGATE_EXPR
, op
);
7534 c_parser_consume_token (parser
);
7535 exp_loc
= c_parser_peek_token (parser
)->location
;
7536 op
= c_parser_cast_expression (parser
, NULL
);
7537 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
7538 return parser_build_unary_op (op_loc
, BIT_NOT_EXPR
, op
);
7540 c_parser_consume_token (parser
);
7541 exp_loc
= c_parser_peek_token (parser
)->location
;
7542 op
= c_parser_cast_expression (parser
, NULL
);
7543 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
7544 return parser_build_unary_op (op_loc
, TRUTH_NOT_EXPR
, op
);
7546 /* Refer to the address of a label as a pointer. */
7547 c_parser_consume_token (parser
);
7548 if (c_parser_next_token_is (parser
, CPP_NAME
))
7550 ret
.value
= finish_label_address_expr
7551 (c_parser_peek_token (parser
)->value
, op_loc
);
7552 set_c_expr_source_range (&ret
, op_loc
,
7553 c_parser_peek_token (parser
)->get_finish ());
7554 c_parser_consume_token (parser
);
7558 c_parser_error (parser
, "expected identifier");
7563 switch (c_parser_peek_token (parser
)->keyword
)
7566 return c_parser_sizeof_expression (parser
);
7568 return c_parser_alignof_expression (parser
);
7569 case RID_BUILTIN_HAS_ATTRIBUTE
:
7570 return c_parser_has_attribute_expression (parser
);
7572 c_parser_consume_token (parser
);
7573 ext
= disable_extension_diagnostics ();
7574 ret
= c_parser_cast_expression (parser
, NULL
);
7575 restore_extension_diagnostics (ext
);
7578 c_parser_consume_token (parser
);
7579 exp_loc
= c_parser_peek_token (parser
)->location
;
7580 op
= c_parser_cast_expression (parser
, NULL
);
7581 op
= default_function_array_conversion (exp_loc
, op
);
7582 return parser_build_unary_op (op_loc
, REALPART_EXPR
, op
);
7584 c_parser_consume_token (parser
);
7585 exp_loc
= c_parser_peek_token (parser
)->location
;
7586 op
= c_parser_cast_expression (parser
, NULL
);
7587 op
= default_function_array_conversion (exp_loc
, op
);
7588 return parser_build_unary_op (op_loc
, IMAGPART_EXPR
, op
);
7589 case RID_TRANSACTION_ATOMIC
:
7590 case RID_TRANSACTION_RELAXED
:
7591 return c_parser_transaction_expression (parser
,
7592 c_parser_peek_token (parser
)->keyword
);
7594 return c_parser_postfix_expression (parser
);
7597 return c_parser_postfix_expression (parser
);
7601 /* Parse a sizeof expression. */
7603 static struct c_expr
7604 c_parser_sizeof_expression (c_parser
*parser
)
7607 struct c_expr result
;
7608 location_t expr_loc
;
7609 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_SIZEOF
));
7612 location_t finish
= UNKNOWN_LOCATION
;
7614 start
= c_parser_peek_token (parser
)->location
;
7616 c_parser_consume_token (parser
);
7617 c_inhibit_evaluation_warnings
++;
7619 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
)
7620 && c_token_starts_typename (c_parser_peek_2nd_token (parser
)))
7622 /* Either sizeof ( type-name ) or sizeof unary-expression
7623 starting with a compound literal. */
7624 struct c_type_name
*type_name
;
7625 matching_parens parens
;
7626 parens
.consume_open (parser
);
7627 expr_loc
= c_parser_peek_token (parser
)->location
;
7628 type_name
= c_parser_type_name (parser
, true);
7629 parens
.skip_until_found_close (parser
);
7630 finish
= parser
->tokens_buf
[0].location
;
7631 if (type_name
== NULL
)
7634 c_inhibit_evaluation_warnings
--;
7637 ret
.original_code
= ERROR_MARK
;
7638 ret
.original_type
= NULL
;
7641 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
7643 expr
= c_parser_postfix_expression_after_paren_type (parser
,
7646 finish
= expr
.get_finish ();
7649 /* sizeof ( type-name ). */
7650 if (type_name
->specs
->alignas_p
)
7651 error_at (type_name
->specs
->locations
[cdw_alignas
],
7652 "alignment specified for type name in %<sizeof%>");
7653 c_inhibit_evaluation_warnings
--;
7655 result
= c_expr_sizeof_type (expr_loc
, type_name
);
7659 expr_loc
= c_parser_peek_token (parser
)->location
;
7660 expr
= c_parser_unary_expression (parser
);
7661 finish
= expr
.get_finish ();
7663 c_inhibit_evaluation_warnings
--;
7665 mark_exp_read (expr
.value
);
7666 if (TREE_CODE (expr
.value
) == COMPONENT_REF
7667 && DECL_C_BIT_FIELD (TREE_OPERAND (expr
.value
, 1)))
7668 error_at (expr_loc
, "%<sizeof%> applied to a bit-field");
7669 result
= c_expr_sizeof_expr (expr_loc
, expr
);
7671 if (finish
== UNKNOWN_LOCATION
)
7673 set_c_expr_source_range (&result
, start
, finish
);
7677 /* Parse an alignof expression. */
7679 static struct c_expr
7680 c_parser_alignof_expression (c_parser
*parser
)
7683 location_t start_loc
= c_parser_peek_token (parser
)->location
;
7685 tree alignof_spelling
= c_parser_peek_token (parser
)->value
;
7686 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ALIGNOF
));
7687 bool is_c11_alignof
= strcmp (IDENTIFIER_POINTER (alignof_spelling
),
7689 /* A diagnostic is not required for the use of this identifier in
7690 the implementation namespace; only diagnose it for the C11
7691 spelling because of existing code using the other spellings. */
7695 pedwarn_c99 (start_loc
, OPT_Wpedantic
, "ISO C99 does not support %qE",
7698 pedwarn_c99 (start_loc
, OPT_Wpedantic
, "ISO C90 does not support %qE",
7701 c_parser_consume_token (parser
);
7702 c_inhibit_evaluation_warnings
++;
7704 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
)
7705 && c_token_starts_typename (c_parser_peek_2nd_token (parser
)))
7707 /* Either __alignof__ ( type-name ) or __alignof__
7708 unary-expression starting with a compound literal. */
7710 struct c_type_name
*type_name
;
7712 matching_parens parens
;
7713 parens
.consume_open (parser
);
7714 loc
= c_parser_peek_token (parser
)->location
;
7715 type_name
= c_parser_type_name (parser
, true);
7716 end_loc
= c_parser_peek_token (parser
)->location
;
7717 parens
.skip_until_found_close (parser
);
7718 if (type_name
== NULL
)
7721 c_inhibit_evaluation_warnings
--;
7724 ret
.original_code
= ERROR_MARK
;
7725 ret
.original_type
= NULL
;
7728 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
7730 expr
= c_parser_postfix_expression_after_paren_type (parser
,
7735 /* alignof ( type-name ). */
7736 if (type_name
->specs
->alignas_p
)
7737 error_at (type_name
->specs
->locations
[cdw_alignas
],
7738 "alignment specified for type name in %qE",
7740 c_inhibit_evaluation_warnings
--;
7742 ret
.value
= c_sizeof_or_alignof_type (loc
, groktypename (type_name
,
7744 false, is_c11_alignof
, 1);
7745 ret
.original_code
= ERROR_MARK
;
7746 ret
.original_type
= NULL
;
7747 set_c_expr_source_range (&ret
, start_loc
, end_loc
);
7753 expr
= c_parser_unary_expression (parser
);
7754 end_loc
= expr
.src_range
.m_finish
;
7756 mark_exp_read (expr
.value
);
7757 c_inhibit_evaluation_warnings
--;
7761 OPT_Wpedantic
, "ISO C does not allow %<%E (expression)%>",
7763 ret
.value
= c_alignof_expr (start_loc
, expr
.value
);
7764 ret
.original_code
= ERROR_MARK
;
7765 ret
.original_type
= NULL
;
7766 set_c_expr_source_range (&ret
, start_loc
, end_loc
);
7771 /* Parse the __builtin_has_attribute ([expr|type], attribute-spec)
7774 static struct c_expr
7775 c_parser_has_attribute_expression (c_parser
*parser
)
7777 gcc_assert (c_parser_next_token_is_keyword (parser
,
7778 RID_BUILTIN_HAS_ATTRIBUTE
));
7779 c_parser_consume_token (parser
);
7781 c_inhibit_evaluation_warnings
++;
7783 matching_parens parens
;
7784 if (!parens
.require_open (parser
))
7786 c_inhibit_evaluation_warnings
--;
7789 struct c_expr result
;
7790 result
.set_error ();
7791 result
.original_code
= ERROR_MARK
;
7792 result
.original_type
= NULL
;
7796 /* Treat the type argument the same way as in typeof for the purposes
7797 of warnings. FIXME: Generalize this so the warning refers to
7798 __builtin_has_attribute rather than typeof. */
7801 /* The first operand: one of DECL, EXPR, or TYPE. */
7802 tree oper
= NULL_TREE
;
7803 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_id
))
7805 struct c_type_name
*tname
= c_parser_type_name (parser
);
7809 oper
= groktypename (tname
, NULL
, NULL
);
7810 pop_maybe_used (variably_modified_type_p (oper
, NULL_TREE
));
7815 struct c_expr cexpr
= c_parser_expr_no_commas (parser
, NULL
);
7816 c_inhibit_evaluation_warnings
--;
7818 if (cexpr
.value
!= error_mark_node
)
7820 mark_exp_read (cexpr
.value
);
7822 tree etype
= TREE_TYPE (oper
);
7823 bool was_vm
= variably_modified_type_p (etype
, NULL_TREE
);
7824 /* This is returned with the type so that when the type is
7825 evaluated, this can be evaluated. */
7827 oper
= c_fully_fold (oper
, false, NULL
);
7828 pop_maybe_used (was_vm
);
7832 struct c_expr result
;
7833 result
.original_code
= ERROR_MARK
;
7834 result
.original_type
= NULL
;
7836 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
7838 /* Consume the closing parenthesis if that's the next token
7839 in the likely case the built-in was invoked with fewer
7840 than two arguments. */
7841 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
7842 c_parser_consume_token (parser
);
7843 c_inhibit_evaluation_warnings
--;
7844 result
.set_error ();
7848 bool save_translate_strings_p
= parser
->translate_strings_p
;
7850 location_t atloc
= c_parser_peek_token (parser
)->location
;
7851 /* Parse a single attribute. Require no leading comma and do not
7852 allow empty attributes. */
7853 tree attr
= c_parser_gnu_attribute (parser
, NULL_TREE
, false, false);
7855 parser
->translate_strings_p
= save_translate_strings_p
;
7857 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
7858 c_parser_consume_token (parser
);
7861 c_parser_error (parser
, "expected identifier");
7862 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
7864 result
.set_error ();
7870 error_at (atloc
, "expected identifier");
7871 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
7873 result
.set_error ();
7877 result
.original_code
= INTEGER_CST
;
7878 result
.original_type
= boolean_type_node
;
7880 if (has_attribute (atloc
, oper
, attr
, default_conversion
))
7881 result
.value
= boolean_true_node
;
7883 result
.value
= boolean_false_node
;
7888 /* Helper function to read arguments of builtins which are interfaces
7889 for the middle-end nodes like COMPLEX_EXPR, VEC_PERM_EXPR and
7890 others. The name of the builtin is passed using BNAME parameter.
7891 Function returns true if there were no errors while parsing and
7892 stores the arguments in CEXPR_LIST. If it returns true,
7893 *OUT_CLOSE_PAREN_LOC is written to with the location of the closing
7896 c_parser_get_builtin_args (c_parser
*parser
, const char *bname
,
7897 vec
<c_expr_t
, va_gc
> **ret_cexpr_list
,
7899 location_t
*out_close_paren_loc
)
7901 location_t loc
= c_parser_peek_token (parser
)->location
;
7902 vec
<c_expr_t
, va_gc
> *cexpr_list
;
7904 bool saved_force_folding_builtin_constant_p
;
7906 *ret_cexpr_list
= NULL
;
7907 if (c_parser_next_token_is_not (parser
, CPP_OPEN_PAREN
))
7909 error_at (loc
, "cannot take address of %qs", bname
);
7913 c_parser_consume_token (parser
);
7915 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
7917 *out_close_paren_loc
= c_parser_peek_token (parser
)->location
;
7918 c_parser_consume_token (parser
);
7922 saved_force_folding_builtin_constant_p
7923 = force_folding_builtin_constant_p
;
7924 force_folding_builtin_constant_p
|= choose_expr_p
;
7925 expr
= c_parser_expr_no_commas (parser
, NULL
);
7926 force_folding_builtin_constant_p
7927 = saved_force_folding_builtin_constant_p
;
7928 vec_alloc (cexpr_list
, 1);
7929 vec_safe_push (cexpr_list
, expr
);
7930 while (c_parser_next_token_is (parser
, CPP_COMMA
))
7932 c_parser_consume_token (parser
);
7933 expr
= c_parser_expr_no_commas (parser
, NULL
);
7934 vec_safe_push (cexpr_list
, expr
);
7937 *out_close_paren_loc
= c_parser_peek_token (parser
)->location
;
7938 if (!c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
7941 *ret_cexpr_list
= cexpr_list
;
7945 /* This represents a single generic-association. */
7947 struct c_generic_association
7949 /* The location of the starting token of the type. */
7950 location_t type_location
;
7951 /* The association's type, or NULL_TREE for 'default'. */
7953 /* The association's expression. */
7954 struct c_expr expression
;
7957 /* Parse a generic-selection. (C11 6.5.1.1).
7960 _Generic ( assignment-expression , generic-assoc-list )
7964 generic-assoc-list , generic-association
7966 generic-association:
7967 type-name : assignment-expression
7968 default : assignment-expression
7971 static struct c_expr
7972 c_parser_generic_selection (c_parser
*parser
)
7974 struct c_expr selector
, error_expr
;
7976 struct c_generic_association matched_assoc
;
7977 bool match_found
= false;
7978 location_t generic_loc
, selector_loc
;
7980 error_expr
.original_code
= ERROR_MARK
;
7981 error_expr
.original_type
= NULL
;
7982 error_expr
.set_error ();
7983 matched_assoc
.type_location
= UNKNOWN_LOCATION
;
7984 matched_assoc
.type
= NULL_TREE
;
7985 matched_assoc
.expression
= error_expr
;
7987 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_GENERIC
));
7988 generic_loc
= c_parser_peek_token (parser
)->location
;
7989 c_parser_consume_token (parser
);
7991 pedwarn_c99 (generic_loc
, OPT_Wpedantic
,
7992 "ISO C99 does not support %<_Generic%>");
7994 pedwarn_c99 (generic_loc
, OPT_Wpedantic
,
7995 "ISO C90 does not support %<_Generic%>");
7997 matching_parens parens
;
7998 if (!parens
.require_open (parser
))
8001 c_inhibit_evaluation_warnings
++;
8002 selector_loc
= c_parser_peek_token (parser
)->location
;
8003 selector
= c_parser_expr_no_commas (parser
, NULL
);
8004 selector
= default_function_array_conversion (selector_loc
, selector
);
8005 c_inhibit_evaluation_warnings
--;
8007 if (selector
.value
== error_mark_node
)
8009 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8012 selector_type
= TREE_TYPE (selector
.value
);
8013 /* In ISO C terms, rvalues (including the controlling expression of
8014 _Generic) do not have qualified types. */
8015 if (TREE_CODE (selector_type
) != ARRAY_TYPE
)
8016 selector_type
= TYPE_MAIN_VARIANT (selector_type
);
8017 /* In ISO C terms, _Noreturn is not part of the type of expressions
8018 such as &abort, but in GCC it is represented internally as a type
8020 if (FUNCTION_POINTER_TYPE_P (selector_type
)
8021 && TYPE_QUALS (TREE_TYPE (selector_type
)) != TYPE_UNQUALIFIED
)
8023 = build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (selector_type
)));
8025 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
8027 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8031 auto_vec
<c_generic_association
> associations
;
8034 struct c_generic_association assoc
, *iter
;
8036 c_token
*token
= c_parser_peek_token (parser
);
8038 assoc
.type_location
= token
->location
;
8039 if (token
->type
== CPP_KEYWORD
&& token
->keyword
== RID_DEFAULT
)
8041 c_parser_consume_token (parser
);
8042 assoc
.type
= NULL_TREE
;
8046 struct c_type_name
*type_name
;
8048 type_name
= c_parser_type_name (parser
);
8049 if (type_name
== NULL
)
8051 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8054 assoc
.type
= groktypename (type_name
, NULL
, NULL
);
8055 if (assoc
.type
== error_mark_node
)
8057 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8061 if (TREE_CODE (assoc
.type
) == FUNCTION_TYPE
)
8062 error_at (assoc
.type_location
,
8063 "%<_Generic%> association has function type");
8064 else if (!COMPLETE_TYPE_P (assoc
.type
))
8065 error_at (assoc
.type_location
,
8066 "%<_Generic%> association has incomplete type");
8068 if (variably_modified_type_p (assoc
.type
, NULL_TREE
))
8069 error_at (assoc
.type_location
,
8070 "%<_Generic%> association has "
8071 "variable length type");
8074 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
8076 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8080 assoc
.expression
= c_parser_expr_no_commas (parser
, NULL
);
8081 if (assoc
.expression
.value
== error_mark_node
)
8083 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8087 for (ix
= 0; associations
.iterate (ix
, &iter
); ++ix
)
8089 if (assoc
.type
== NULL_TREE
)
8091 if (iter
->type
== NULL_TREE
)
8093 error_at (assoc
.type_location
,
8094 "duplicate %<default%> case in %<_Generic%>");
8095 inform (iter
->type_location
, "original %<default%> is here");
8098 else if (iter
->type
!= NULL_TREE
)
8100 if (comptypes (assoc
.type
, iter
->type
))
8102 error_at (assoc
.type_location
,
8103 "%<_Generic%> specifies two compatible types");
8104 inform (iter
->type_location
, "compatible type is here");
8109 if (assoc
.type
== NULL_TREE
)
8113 matched_assoc
= assoc
;
8117 else if (comptypes (assoc
.type
, selector_type
))
8119 if (!match_found
|| matched_assoc
.type
== NULL_TREE
)
8121 matched_assoc
= assoc
;
8126 error_at (assoc
.type_location
,
8127 "%<_Generic%> selector matches multiple associations");
8128 inform (matched_assoc
.type_location
,
8129 "other match is here");
8133 associations
.safe_push (assoc
);
8135 if (c_parser_peek_token (parser
)->type
!= CPP_COMMA
)
8137 c_parser_consume_token (parser
);
8140 if (!parens
.require_close (parser
))
8142 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8148 error_at (selector_loc
, "%<_Generic%> selector of type %qT is not "
8149 "compatible with any association",
8154 return matched_assoc
.expression
;
8157 /* Check the validity of a function pointer argument *EXPR (argument
8158 position POS) to __builtin_tgmath. Return the number of function
8159 arguments if possibly valid; return 0 having reported an error if
8163 check_tgmath_function (c_expr
*expr
, unsigned int pos
)
8165 tree type
= TREE_TYPE (expr
->value
);
8166 if (!FUNCTION_POINTER_TYPE_P (type
))
8168 error_at (expr
->get_location (),
8169 "argument %u of %<__builtin_tgmath%> is not a function pointer",
8173 type
= TREE_TYPE (type
);
8174 if (!prototype_p (type
))
8176 error_at (expr
->get_location (),
8177 "argument %u of %<__builtin_tgmath%> is unprototyped", pos
);
8180 if (stdarg_p (type
))
8182 error_at (expr
->get_location (),
8183 "argument %u of %<__builtin_tgmath%> has variable arguments",
8187 unsigned int nargs
= 0;
8188 function_args_iterator iter
;
8190 FOREACH_FUNCTION_ARGS (type
, t
, iter
)
8192 if (t
== void_type_node
)
8198 error_at (expr
->get_location (),
8199 "argument %u of %<__builtin_tgmath%> has no arguments", pos
);
8205 /* Ways in which a parameter or return value of a type-generic macro
8206 may vary between the different functions the macro may call. */
8207 enum tgmath_parm_kind
8209 tgmath_fixed
, tgmath_real
, tgmath_complex
8212 /* Helper function for c_parser_postfix_expression. Parse predefined
8215 static struct c_expr
8216 c_parser_predefined_identifier (c_parser
*parser
)
8218 location_t loc
= c_parser_peek_token (parser
)->location
;
8219 switch (c_parser_peek_token (parser
)->keyword
)
8221 case RID_FUNCTION_NAME
:
8222 pedwarn (loc
, OPT_Wpedantic
, "ISO C does not support %qs predefined "
8223 "identifier", "__FUNCTION__");
8225 case RID_PRETTY_FUNCTION_NAME
:
8226 pedwarn (loc
, OPT_Wpedantic
, "ISO C does not support %qs predefined "
8227 "identifier", "__PRETTY_FUNCTION__");
8229 case RID_C99_FUNCTION_NAME
:
8230 pedwarn_c90 (loc
, OPT_Wpedantic
, "ISO C90 does not support "
8231 "%<__func__%> predefined identifier");
8238 expr
.original_code
= ERROR_MARK
;
8239 expr
.original_type
= NULL
;
8240 expr
.value
= fname_decl (loc
, c_parser_peek_token (parser
)->keyword
,
8241 c_parser_peek_token (parser
)->value
);
8242 set_c_expr_source_range (&expr
, loc
, loc
);
8243 c_parser_consume_token (parser
);
8247 /* Parse a postfix expression (C90 6.3.1-6.3.2, C99 6.5.1-6.5.2,
8248 C11 6.5.1-6.5.2). Compound literals aren't handled here; callers have to
8249 call c_parser_postfix_expression_after_paren_type on encountering them.
8253 postfix-expression [ expression ]
8254 postfix-expression ( argument-expression-list[opt] )
8255 postfix-expression . identifier
8256 postfix-expression -> identifier
8257 postfix-expression ++
8258 postfix-expression --
8259 ( type-name ) { initializer-list }
8260 ( type-name ) { initializer-list , }
8262 argument-expression-list:
8264 argument-expression-list , argument-expression
8277 (treated as a keyword in GNU C)
8280 ( compound-statement )
8281 __builtin_va_arg ( assignment-expression , type-name )
8282 __builtin_offsetof ( type-name , offsetof-member-designator )
8283 __builtin_choose_expr ( assignment-expression ,
8284 assignment-expression ,
8285 assignment-expression )
8286 __builtin_types_compatible_p ( type-name , type-name )
8287 __builtin_tgmath ( expr-list )
8288 __builtin_complex ( assignment-expression , assignment-expression )
8289 __builtin_shuffle ( assignment-expression , assignment-expression )
8290 __builtin_shuffle ( assignment-expression ,
8291 assignment-expression ,
8292 assignment-expression, )
8293 __builtin_convertvector ( assignment-expression , type-name )
8295 offsetof-member-designator:
8297 offsetof-member-designator . identifier
8298 offsetof-member-designator [ expression ]
8303 [ objc-receiver objc-message-args ]
8304 @selector ( objc-selector-arg )
8305 @protocol ( identifier )
8306 @encode ( type-name )
8308 Classname . identifier
8311 static struct c_expr
8312 c_parser_postfix_expression (c_parser
*parser
)
8314 struct c_expr expr
, e1
;
8315 struct c_type_name
*t1
, *t2
;
8316 location_t loc
= c_parser_peek_token (parser
)->location
;
8317 source_range tok_range
= c_parser_peek_token (parser
)->get_range ();
8318 expr
.original_code
= ERROR_MARK
;
8319 expr
.original_type
= NULL
;
8320 switch (c_parser_peek_token (parser
)->type
)
8323 expr
.value
= c_parser_peek_token (parser
)->value
;
8324 set_c_expr_source_range (&expr
, tok_range
);
8325 loc
= c_parser_peek_token (parser
)->location
;
8326 c_parser_consume_token (parser
);
8327 if (TREE_CODE (expr
.value
) == FIXED_CST
8328 && !targetm
.fixed_point_supported_p ())
8330 error_at (loc
, "fixed-point types not supported for this target");
8338 expr
.value
= c_parser_peek_token (parser
)->value
;
8339 /* For the purpose of warning when a pointer is compared with
8340 a zero character constant. */
8341 expr
.original_type
= char_type_node
;
8342 set_c_expr_source_range (&expr
, tok_range
);
8343 c_parser_consume_token (parser
);
8349 case CPP_UTF8STRING
:
8350 expr
= c_parser_string_literal (parser
, parser
->translate_strings_p
,
8353 case CPP_OBJC_STRING
:
8354 gcc_assert (c_dialect_objc ());
8356 = objc_build_string_object (c_parser_peek_token (parser
)->value
);
8357 set_c_expr_source_range (&expr
, tok_range
);
8358 c_parser_consume_token (parser
);
8361 switch (c_parser_peek_token (parser
)->id_kind
)
8365 tree id
= c_parser_peek_token (parser
)->value
;
8366 c_parser_consume_token (parser
);
8367 expr
.value
= build_external_ref (loc
, id
,
8368 (c_parser_peek_token (parser
)->type
8370 &expr
.original_type
);
8371 set_c_expr_source_range (&expr
, tok_range
);
8374 case C_ID_CLASSNAME
:
8376 /* Here we parse the Objective-C 2.0 Class.name dot
8378 tree class_name
= c_parser_peek_token (parser
)->value
;
8380 c_parser_consume_token (parser
);
8381 gcc_assert (c_dialect_objc ());
8382 if (!c_parser_require (parser
, CPP_DOT
, "expected %<.%>"))
8387 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
8389 c_parser_error (parser
, "expected identifier");
8393 c_token
*component_tok
= c_parser_peek_token (parser
);
8394 component
= component_tok
->value
;
8395 location_t end_loc
= component_tok
->get_finish ();
8396 c_parser_consume_token (parser
);
8397 expr
.value
= objc_build_class_component_ref (class_name
,
8399 set_c_expr_source_range (&expr
, loc
, end_loc
);
8403 c_parser_error (parser
, "expected expression");
8408 case CPP_OPEN_PAREN
:
8409 /* A parenthesized expression, statement expression or compound
8411 if (c_parser_peek_2nd_token (parser
)->type
== CPP_OPEN_BRACE
)
8413 /* A statement expression. */
8415 location_t brace_loc
;
8416 c_parser_consume_token (parser
);
8417 brace_loc
= c_parser_peek_token (parser
)->location
;
8418 c_parser_consume_token (parser
);
8419 /* If we've not yet started the current function's statement list,
8420 or we're in the parameter scope of an old-style function
8421 declaration, statement expressions are not allowed. */
8422 if (!building_stmt_list_p () || old_style_parameter_scope ())
8424 error_at (loc
, "braced-group within expression allowed "
8425 "only inside a function");
8426 parser
->error
= true;
8427 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
, NULL
);
8428 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8432 stmt
= c_begin_stmt_expr ();
8433 c_parser_compound_statement_nostart (parser
);
8434 location_t close_loc
= c_parser_peek_token (parser
)->location
;
8435 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
8437 pedwarn (loc
, OPT_Wpedantic
,
8438 "ISO C forbids braced-groups within expressions");
8439 expr
.value
= c_finish_stmt_expr (brace_loc
, stmt
);
8440 set_c_expr_source_range (&expr
, loc
, close_loc
);
8441 mark_exp_read (expr
.value
);
8445 /* A parenthesized expression. */
8446 location_t loc_open_paren
= c_parser_peek_token (parser
)->location
;
8447 c_parser_consume_token (parser
);
8448 expr
= c_parser_expression (parser
);
8449 if (TREE_CODE (expr
.value
) == MODIFY_EXPR
)
8450 TREE_NO_WARNING (expr
.value
) = 1;
8451 if (expr
.original_code
!= C_MAYBE_CONST_EXPR
8452 && expr
.original_code
!= SIZEOF_EXPR
)
8453 expr
.original_code
= ERROR_MARK
;
8454 /* Don't change EXPR.ORIGINAL_TYPE. */
8455 location_t loc_close_paren
= c_parser_peek_token (parser
)->location
;
8456 set_c_expr_source_range (&expr
, loc_open_paren
, loc_close_paren
);
8457 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
8458 "expected %<)%>", loc_open_paren
);
8462 switch (c_parser_peek_token (parser
)->keyword
)
8464 case RID_FUNCTION_NAME
:
8465 case RID_PRETTY_FUNCTION_NAME
:
8466 case RID_C99_FUNCTION_NAME
:
8467 expr
= c_parser_predefined_identifier (parser
);
8471 location_t start_loc
= loc
;
8472 c_parser_consume_token (parser
);
8473 matching_parens parens
;
8474 if (!parens
.require_open (parser
))
8479 e1
= c_parser_expr_no_commas (parser
, NULL
);
8480 mark_exp_read (e1
.value
);
8481 e1
.value
= c_fully_fold (e1
.value
, false, NULL
);
8482 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
8484 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8488 loc
= c_parser_peek_token (parser
)->location
;
8489 t1
= c_parser_type_name (parser
);
8490 location_t end_loc
= c_parser_peek_token (parser
)->get_finish ();
8491 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
8499 tree type_expr
= NULL_TREE
;
8500 expr
.value
= c_build_va_arg (start_loc
, e1
.value
, loc
,
8501 groktypename (t1
, &type_expr
, NULL
));
8504 expr
.value
= build2 (C_MAYBE_CONST_EXPR
,
8505 TREE_TYPE (expr
.value
), type_expr
,
8507 C_MAYBE_CONST_EXPR_NON_CONST (expr
.value
) = true;
8509 set_c_expr_source_range (&expr
, start_loc
, end_loc
);
8515 c_parser_consume_token (parser
);
8516 matching_parens parens
;
8517 if (!parens
.require_open (parser
))
8522 t1
= c_parser_type_name (parser
);
8524 parser
->error
= true;
8525 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
8526 gcc_assert (parser
->error
);
8529 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8533 tree type
= groktypename (t1
, NULL
, NULL
);
8535 if (type
== error_mark_node
)
8536 offsetof_ref
= error_mark_node
;
8539 offsetof_ref
= build1 (INDIRECT_REF
, type
, null_pointer_node
);
8540 SET_EXPR_LOCATION (offsetof_ref
, loc
);
8542 /* Parse the second argument to __builtin_offsetof. We
8543 must have one identifier, and beyond that we want to
8544 accept sub structure and sub array references. */
8545 if (c_parser_next_token_is (parser
, CPP_NAME
))
8547 c_token
*comp_tok
= c_parser_peek_token (parser
);
8548 offsetof_ref
= build_component_ref
8549 (loc
, offsetof_ref
, comp_tok
->value
, comp_tok
->location
);
8550 c_parser_consume_token (parser
);
8551 while (c_parser_next_token_is (parser
, CPP_DOT
)
8552 || c_parser_next_token_is (parser
,
8554 || c_parser_next_token_is (parser
,
8557 if (c_parser_next_token_is (parser
, CPP_DEREF
))
8559 loc
= c_parser_peek_token (parser
)->location
;
8560 offsetof_ref
= build_array_ref (loc
,
8565 else if (c_parser_next_token_is (parser
, CPP_DOT
))
8568 c_parser_consume_token (parser
);
8569 if (c_parser_next_token_is_not (parser
,
8572 c_parser_error (parser
, "expected identifier");
8575 c_token
*comp_tok
= c_parser_peek_token (parser
);
8576 offsetof_ref
= build_component_ref
8577 (loc
, offsetof_ref
, comp_tok
->value
,
8578 comp_tok
->location
);
8579 c_parser_consume_token (parser
);
8585 loc
= c_parser_peek_token (parser
)->location
;
8586 c_parser_consume_token (parser
);
8587 ce
= c_parser_expression (parser
);
8588 ce
= convert_lvalue_to_rvalue (loc
, ce
, false, false);
8590 idx
= c_fully_fold (idx
, false, NULL
);
8591 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
8593 offsetof_ref
= build_array_ref (loc
, offsetof_ref
, idx
);
8598 c_parser_error (parser
, "expected identifier");
8599 location_t end_loc
= c_parser_peek_token (parser
)->get_finish ();
8600 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
8602 expr
.value
= fold_offsetof (offsetof_ref
);
8603 set_c_expr_source_range (&expr
, loc
, end_loc
);
8606 case RID_CHOOSE_EXPR
:
8608 vec
<c_expr_t
, va_gc
> *cexpr_list
;
8609 c_expr_t
*e1_p
, *e2_p
, *e3_p
;
8611 location_t close_paren_loc
;
8613 c_parser_consume_token (parser
);
8614 if (!c_parser_get_builtin_args (parser
,
8615 "__builtin_choose_expr",
8623 if (vec_safe_length (cexpr_list
) != 3)
8625 error_at (loc
, "wrong number of arguments to "
8626 "%<__builtin_choose_expr%>");
8631 e1_p
= &(*cexpr_list
)[0];
8632 e2_p
= &(*cexpr_list
)[1];
8633 e3_p
= &(*cexpr_list
)[2];
8636 mark_exp_read (e2_p
->value
);
8637 mark_exp_read (e3_p
->value
);
8638 if (TREE_CODE (c
) != INTEGER_CST
8639 || !INTEGRAL_TYPE_P (TREE_TYPE (c
)))
8641 "first argument to %<__builtin_choose_expr%> not"
8643 constant_expression_warning (c
);
8644 expr
= integer_zerop (c
) ? *e3_p
: *e2_p
;
8645 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
8648 case RID_TYPES_COMPATIBLE_P
:
8650 c_parser_consume_token (parser
);
8651 matching_parens parens
;
8652 if (!parens
.require_open (parser
))
8657 t1
= c_parser_type_name (parser
);
8663 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
8665 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8669 t2
= c_parser_type_name (parser
);
8675 location_t close_paren_loc
= c_parser_peek_token (parser
)->location
;
8676 parens
.skip_until_found_close (parser
);
8678 e1
= groktypename (t1
, NULL
, NULL
);
8679 e2
= groktypename (t2
, NULL
, NULL
);
8680 if (e1
== error_mark_node
|| e2
== error_mark_node
)
8686 e1
= TYPE_MAIN_VARIANT (e1
);
8687 e2
= TYPE_MAIN_VARIANT (e2
);
8690 = comptypes (e1
, e2
) ? integer_one_node
: integer_zero_node
;
8691 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
8694 case RID_BUILTIN_TGMATH
:
8696 vec
<c_expr_t
, va_gc
> *cexpr_list
;
8697 location_t close_paren_loc
;
8699 c_parser_consume_token (parser
);
8700 if (!c_parser_get_builtin_args (parser
,
8709 if (vec_safe_length (cexpr_list
) < 3)
8711 error_at (loc
, "too few arguments to %<__builtin_tgmath%>");
8718 FOR_EACH_VEC_ELT (*cexpr_list
, i
, p
)
8719 *p
= convert_lvalue_to_rvalue (loc
, *p
, true, true);
8720 unsigned int nargs
= check_tgmath_function (&(*cexpr_list
)[0], 1);
8726 if (vec_safe_length (cexpr_list
) < nargs
)
8728 error_at (loc
, "too few arguments to %<__builtin_tgmath%>");
8732 unsigned int num_functions
= vec_safe_length (cexpr_list
) - nargs
;
8733 if (num_functions
< 2)
8735 error_at (loc
, "too few arguments to %<__builtin_tgmath%>");
8740 /* The first NUM_FUNCTIONS expressions are the function
8741 pointers. The remaining NARGS expressions are the
8742 arguments that are to be passed to one of those
8743 functions, chosen following <tgmath.h> rules. */
8744 for (unsigned int j
= 1; j
< num_functions
; j
++)
8746 unsigned int this_nargs
8747 = check_tgmath_function (&(*cexpr_list
)[j
], j
+ 1);
8748 if (this_nargs
== 0)
8753 if (this_nargs
!= nargs
)
8755 error_at ((*cexpr_list
)[j
].get_location (),
8756 "argument %u of %<__builtin_tgmath%> has "
8757 "wrong number of arguments", j
+ 1);
8763 /* The functions all have the same number of arguments.
8764 Determine whether arguments and return types vary in
8765 ways permitted for <tgmath.h> functions. */
8766 /* The first entry in each of these vectors is for the
8767 return type, subsequent entries for parameter
8769 auto_vec
<enum tgmath_parm_kind
> parm_kind (nargs
+ 1);
8770 auto_vec
<tree
> parm_first (nargs
+ 1);
8771 auto_vec
<bool> parm_complex (nargs
+ 1);
8772 auto_vec
<bool> parm_varies (nargs
+ 1);
8773 tree first_type
= TREE_TYPE (TREE_TYPE ((*cexpr_list
)[0].value
));
8774 tree first_ret
= TYPE_MAIN_VARIANT (TREE_TYPE (first_type
));
8775 parm_first
.quick_push (first_ret
);
8776 parm_complex
.quick_push (TREE_CODE (first_ret
) == COMPLEX_TYPE
);
8777 parm_varies
.quick_push (false);
8778 function_args_iterator iter
;
8780 unsigned int argpos
;
8781 FOREACH_FUNCTION_ARGS (first_type
, t
, iter
)
8783 if (t
== void_type_node
)
8785 parm_first
.quick_push (TYPE_MAIN_VARIANT (t
));
8786 parm_complex
.quick_push (TREE_CODE (t
) == COMPLEX_TYPE
);
8787 parm_varies
.quick_push (false);
8789 for (unsigned int j
= 1; j
< num_functions
; j
++)
8791 tree type
= TREE_TYPE (TREE_TYPE ((*cexpr_list
)[j
].value
));
8792 tree ret
= TYPE_MAIN_VARIANT (TREE_TYPE (type
));
8793 if (ret
!= parm_first
[0])
8795 parm_varies
[0] = true;
8796 if (!SCALAR_FLOAT_TYPE_P (parm_first
[0])
8797 && !COMPLEX_FLOAT_TYPE_P (parm_first
[0]))
8799 error_at ((*cexpr_list
)[0].get_location (),
8800 "invalid type-generic return type for "
8801 "argument %u of %<__builtin_tgmath%>",
8806 if (!SCALAR_FLOAT_TYPE_P (ret
)
8807 && !COMPLEX_FLOAT_TYPE_P (ret
))
8809 error_at ((*cexpr_list
)[j
].get_location (),
8810 "invalid type-generic return type for "
8811 "argument %u of %<__builtin_tgmath%>",
8817 if (TREE_CODE (ret
) == COMPLEX_TYPE
)
8818 parm_complex
[0] = true;
8820 FOREACH_FUNCTION_ARGS (type
, t
, iter
)
8822 if (t
== void_type_node
)
8824 t
= TYPE_MAIN_VARIANT (t
);
8825 if (t
!= parm_first
[argpos
])
8827 parm_varies
[argpos
] = true;
8828 if (!SCALAR_FLOAT_TYPE_P (parm_first
[argpos
])
8829 && !COMPLEX_FLOAT_TYPE_P (parm_first
[argpos
]))
8831 error_at ((*cexpr_list
)[0].get_location (),
8832 "invalid type-generic type for "
8833 "argument %u of argument %u of "
8834 "%<__builtin_tgmath%>", argpos
, 1);
8838 if (!SCALAR_FLOAT_TYPE_P (t
)
8839 && !COMPLEX_FLOAT_TYPE_P (t
))
8841 error_at ((*cexpr_list
)[j
].get_location (),
8842 "invalid type-generic type for "
8843 "argument %u of argument %u of "
8844 "%<__builtin_tgmath%>", argpos
, j
+ 1);
8849 if (TREE_CODE (t
) == COMPLEX_TYPE
)
8850 parm_complex
[argpos
] = true;
8854 enum tgmath_parm_kind max_variation
= tgmath_fixed
;
8855 for (unsigned int j
= 0; j
<= nargs
; j
++)
8857 enum tgmath_parm_kind this_kind
;
8860 if (parm_complex
[j
])
8861 max_variation
= this_kind
= tgmath_complex
;
8864 this_kind
= tgmath_real
;
8865 if (max_variation
!= tgmath_complex
)
8866 max_variation
= tgmath_real
;
8870 this_kind
= tgmath_fixed
;
8871 parm_kind
.quick_push (this_kind
);
8873 if (max_variation
== tgmath_fixed
)
8875 error_at (loc
, "function arguments of %<__builtin_tgmath%> "
8876 "all have the same type");
8881 /* Identify a parameter (not the return type) that varies,
8882 including with complex types if any variation includes
8883 complex types; there must be at least one such
8885 unsigned int tgarg
= 0;
8886 for (unsigned int j
= 1; j
<= nargs
; j
++)
8887 if (parm_kind
[j
] == max_variation
)
8894 error_at (loc
, "function arguments of %<__builtin_tgmath%> "
8895 "lack type-generic parameter");
8900 /* Determine the type of the relevant parameter for each
8902 auto_vec
<tree
> tg_type (num_functions
);
8903 for (unsigned int j
= 0; j
< num_functions
; j
++)
8905 tree type
= TREE_TYPE (TREE_TYPE ((*cexpr_list
)[j
].value
));
8907 FOREACH_FUNCTION_ARGS (type
, t
, iter
)
8909 if (argpos
== tgarg
)
8911 tg_type
.quick_push (TYPE_MAIN_VARIANT (t
));
8918 /* Verify that the corresponding types are different for
8919 all the listed functions. Also determine whether all
8920 the types are complex, whether all the types are
8921 standard or binary, and whether all the types are
8923 bool all_complex
= true;
8924 bool all_binary
= true;
8925 bool all_decimal
= true;
8926 hash_set
<tree
> tg_types
;
8927 FOR_EACH_VEC_ELT (tg_type
, i
, t
)
8929 if (TREE_CODE (t
) == COMPLEX_TYPE
)
8930 all_decimal
= false;
8933 all_complex
= false;
8934 if (DECIMAL_FLOAT_TYPE_P (t
))
8937 all_decimal
= false;
8939 if (tg_types
.add (t
))
8941 error_at ((*cexpr_list
)[i
].get_location (),
8942 "duplicate type-generic parameter type for "
8943 "function argument %u of %<__builtin_tgmath%>",
8950 /* Verify that other parameters and the return type whose
8951 types vary have their types varying in the correct
8953 for (unsigned int j
= 0; j
< num_functions
; j
++)
8955 tree exp_type
= tg_type
[j
];
8956 tree exp_real_type
= exp_type
;
8957 if (TREE_CODE (exp_type
) == COMPLEX_TYPE
)
8958 exp_real_type
= TREE_TYPE (exp_type
);
8959 tree type
= TREE_TYPE (TREE_TYPE ((*cexpr_list
)[j
].value
));
8960 tree ret
= TYPE_MAIN_VARIANT (TREE_TYPE (type
));
8961 if ((parm_kind
[0] == tgmath_complex
&& ret
!= exp_type
)
8962 || (parm_kind
[0] == tgmath_real
&& ret
!= exp_real_type
))
8964 error_at ((*cexpr_list
)[j
].get_location (),
8965 "bad return type for function argument %u "
8966 "of %<__builtin_tgmath%>", j
+ 1);
8971 FOREACH_FUNCTION_ARGS (type
, t
, iter
)
8973 if (t
== void_type_node
)
8975 t
= TYPE_MAIN_VARIANT (t
);
8976 if ((parm_kind
[argpos
] == tgmath_complex
8978 || (parm_kind
[argpos
] == tgmath_real
8979 && t
!= exp_real_type
))
8981 error_at ((*cexpr_list
)[j
].get_location (),
8982 "bad type for argument %u of "
8983 "function argument %u of "
8984 "%<__builtin_tgmath%>", argpos
, j
+ 1);
8992 /* The functions listed are a valid set of functions for a
8993 <tgmath.h> macro to select between. Identify the
8994 matching function, if any. First, the argument types
8995 must be combined following <tgmath.h> rules. Integer
8996 types are treated as _Decimal64 if any type-generic
8997 argument is decimal, or if the only alternatives for
8998 type-generic arguments are of decimal types, and are
8999 otherwise treated as double (or _Complex double for
9000 complex integer types, or _Float64 or _Complex _Float64
9001 if all the return types are the same _FloatN or
9002 _FloatNx type). After that adjustment, types are
9003 combined following the usual arithmetic conversions.
9004 If the function only accepts complex arguments, a
9005 complex type is produced. */
9006 bool arg_complex
= all_complex
;
9007 bool arg_binary
= all_binary
;
9008 bool arg_int_decimal
= all_decimal
;
9009 for (unsigned int j
= 1; j
<= nargs
; j
++)
9011 if (parm_kind
[j
] == tgmath_fixed
)
9013 c_expr_t
*ce
= &(*cexpr_list
)[num_functions
+ j
- 1];
9014 tree type
= TREE_TYPE (ce
->value
);
9015 if (!INTEGRAL_TYPE_P (type
)
9016 && !SCALAR_FLOAT_TYPE_P (type
)
9017 && TREE_CODE (type
) != COMPLEX_TYPE
)
9019 error_at (ce
->get_location (),
9020 "invalid type of argument %u of type-generic "
9025 if (DECIMAL_FLOAT_TYPE_P (type
))
9027 arg_int_decimal
= true;
9030 error_at (ce
->get_location (),
9031 "decimal floating-point argument %u to "
9032 "complex-only type-generic function", j
);
9036 else if (all_binary
)
9038 error_at (ce
->get_location (),
9039 "decimal floating-point argument %u to "
9040 "binary-only type-generic function", j
);
9044 else if (arg_complex
)
9046 error_at (ce
->get_location (),
9047 "both complex and decimal floating-point "
9048 "arguments to type-generic function");
9052 else if (arg_binary
)
9054 error_at (ce
->get_location (),
9055 "both binary and decimal floating-point "
9056 "arguments to type-generic function");
9061 else if (TREE_CODE (type
) == COMPLEX_TYPE
)
9064 if (COMPLEX_FLOAT_TYPE_P (type
))
9068 error_at (ce
->get_location (),
9069 "complex argument %u to "
9070 "decimal-only type-generic function", j
);
9074 else if (arg_int_decimal
)
9076 error_at (ce
->get_location (),
9077 "both complex and decimal floating-point "
9078 "arguments to type-generic function");
9083 else if (SCALAR_FLOAT_TYPE_P (type
))
9088 error_at (ce
->get_location (),
9089 "binary argument %u to "
9090 "decimal-only type-generic function", j
);
9094 else if (arg_int_decimal
)
9096 error_at (ce
->get_location (),
9097 "both binary and decimal floating-point "
9098 "arguments to type-generic function");
9104 /* For a macro rounding its result to a narrower type, map
9105 integer types to _Float64 not double if the return type
9106 is a _FloatN or _FloatNx type. */
9107 bool arg_int_float64
= false;
9108 if (parm_kind
[0] == tgmath_fixed
9109 && SCALAR_FLOAT_TYPE_P (parm_first
[0])
9110 && float64_type_node
!= NULL_TREE
)
9111 for (unsigned int j
= 0; j
< NUM_FLOATN_NX_TYPES
; j
++)
9112 if (parm_first
[0] == FLOATN_TYPE_NODE (j
))
9114 arg_int_float64
= true;
9117 tree arg_real
= NULL_TREE
;
9118 for (unsigned int j
= 1; j
<= nargs
; j
++)
9120 if (parm_kind
[j
] == tgmath_fixed
)
9122 c_expr_t
*ce
= &(*cexpr_list
)[num_functions
+ j
- 1];
9123 tree type
= TYPE_MAIN_VARIANT (TREE_TYPE (ce
->value
));
9124 if (TREE_CODE (type
) == COMPLEX_TYPE
)
9125 type
= TREE_TYPE (type
);
9126 if (INTEGRAL_TYPE_P (type
))
9127 type
= (arg_int_decimal
9128 ? dfloat64_type_node
9131 : double_type_node
);
9132 if (arg_real
== NULL_TREE
)
9135 arg_real
= common_type (arg_real
, type
);
9136 if (arg_real
== error_mark_node
)
9142 tree arg_type
= (arg_complex
9143 ? build_complex_type (arg_real
)
9146 /* Look for a function to call with type-generic parameter
9148 c_expr_t
*fn
= NULL
;
9149 for (unsigned int j
= 0; j
< num_functions
; j
++)
9151 if (tg_type
[j
] == arg_type
)
9153 fn
= &(*cexpr_list
)[j
];
9158 && parm_kind
[0] == tgmath_fixed
9159 && SCALAR_FLOAT_TYPE_P (parm_first
[0]))
9161 /* Presume this is a macro that rounds its result to a
9162 narrower type, and look for the first function with
9163 at least the range and precision of the argument
9165 for (unsigned int j
= 0; j
< num_functions
; j
++)
9168 != (TREE_CODE (tg_type
[j
]) == COMPLEX_TYPE
))
9170 tree real_tg_type
= (arg_complex
9171 ? TREE_TYPE (tg_type
[j
])
9173 if (DECIMAL_FLOAT_TYPE_P (arg_real
)
9174 != DECIMAL_FLOAT_TYPE_P (real_tg_type
))
9176 scalar_float_mode arg_mode
9177 = SCALAR_FLOAT_TYPE_MODE (arg_real
);
9178 scalar_float_mode tg_mode
9179 = SCALAR_FLOAT_TYPE_MODE (real_tg_type
);
9180 const real_format
*arg_fmt
= REAL_MODE_FORMAT (arg_mode
);
9181 const real_format
*tg_fmt
= REAL_MODE_FORMAT (tg_mode
);
9182 if (arg_fmt
->b
== tg_fmt
->b
9183 && arg_fmt
->p
<= tg_fmt
->p
9184 && arg_fmt
->emax
<= tg_fmt
->emax
9185 && (arg_fmt
->emin
- arg_fmt
->p
9186 >= tg_fmt
->emin
- tg_fmt
->p
))
9188 fn
= &(*cexpr_list
)[j
];
9195 error_at (loc
, "no matching function for type-generic call");
9200 /* Construct a call to FN. */
9201 vec
<tree
, va_gc
> *args
;
9202 vec_alloc (args
, nargs
);
9203 vec
<tree
, va_gc
> *origtypes
;
9204 vec_alloc (origtypes
, nargs
);
9205 auto_vec
<location_t
> arg_loc (nargs
);
9206 for (unsigned int j
= 0; j
< nargs
; j
++)
9208 c_expr_t
*ce
= &(*cexpr_list
)[num_functions
+ j
];
9209 args
->quick_push (ce
->value
);
9210 arg_loc
.quick_push (ce
->get_location ());
9211 origtypes
->quick_push (ce
->original_type
);
9213 expr
.value
= c_build_function_call_vec (loc
, arg_loc
, fn
->value
,
9215 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
9218 case RID_BUILTIN_CALL_WITH_STATIC_CHAIN
:
9220 vec
<c_expr_t
, va_gc
> *cexpr_list
;
9223 location_t close_paren_loc
;
9225 c_parser_consume_token (parser
);
9226 if (!c_parser_get_builtin_args (parser
,
9227 "__builtin_call_with_static_chain",
9234 if (vec_safe_length (cexpr_list
) != 2)
9236 error_at (loc
, "wrong number of arguments to "
9237 "%<__builtin_call_with_static_chain%>");
9242 expr
= (*cexpr_list
)[0];
9243 e2_p
= &(*cexpr_list
)[1];
9244 *e2_p
= convert_lvalue_to_rvalue (loc
, *e2_p
, true, true);
9245 chain_value
= e2_p
->value
;
9246 mark_exp_read (chain_value
);
9248 if (TREE_CODE (expr
.value
) != CALL_EXPR
)
9249 error_at (loc
, "first argument to "
9250 "%<__builtin_call_with_static_chain%> "
9251 "must be a call expression");
9252 else if (TREE_CODE (TREE_TYPE (chain_value
)) != POINTER_TYPE
)
9253 error_at (loc
, "second argument to "
9254 "%<__builtin_call_with_static_chain%> "
9255 "must be a pointer type");
9257 CALL_EXPR_STATIC_CHAIN (expr
.value
) = chain_value
;
9258 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
9261 case RID_BUILTIN_COMPLEX
:
9263 vec
<c_expr_t
, va_gc
> *cexpr_list
;
9264 c_expr_t
*e1_p
, *e2_p
;
9265 location_t close_paren_loc
;
9267 c_parser_consume_token (parser
);
9268 if (!c_parser_get_builtin_args (parser
,
9269 "__builtin_complex",
9277 if (vec_safe_length (cexpr_list
) != 2)
9279 error_at (loc
, "wrong number of arguments to "
9280 "%<__builtin_complex%>");
9285 e1_p
= &(*cexpr_list
)[0];
9286 e2_p
= &(*cexpr_list
)[1];
9288 *e1_p
= convert_lvalue_to_rvalue (loc
, *e1_p
, true, true);
9289 if (TREE_CODE (e1_p
->value
) == EXCESS_PRECISION_EXPR
)
9290 e1_p
->value
= convert (TREE_TYPE (e1_p
->value
),
9291 TREE_OPERAND (e1_p
->value
, 0));
9292 *e2_p
= convert_lvalue_to_rvalue (loc
, *e2_p
, true, true);
9293 if (TREE_CODE (e2_p
->value
) == EXCESS_PRECISION_EXPR
)
9294 e2_p
->value
= convert (TREE_TYPE (e2_p
->value
),
9295 TREE_OPERAND (e2_p
->value
, 0));
9296 if (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (e1_p
->value
))
9297 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e1_p
->value
))
9298 || !SCALAR_FLOAT_TYPE_P (TREE_TYPE (e2_p
->value
))
9299 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e2_p
->value
)))
9301 error_at (loc
, "%<__builtin_complex%> operand "
9302 "not of real binary floating-point type");
9306 if (TYPE_MAIN_VARIANT (TREE_TYPE (e1_p
->value
))
9307 != TYPE_MAIN_VARIANT (TREE_TYPE (e2_p
->value
)))
9310 "%<__builtin_complex%> operands of different types");
9314 pedwarn_c90 (loc
, OPT_Wpedantic
,
9315 "ISO C90 does not support complex types");
9316 expr
.value
= build2_loc (loc
, COMPLEX_EXPR
,
9319 (TREE_TYPE (e1_p
->value
))),
9320 e1_p
->value
, e2_p
->value
);
9321 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
9324 case RID_BUILTIN_SHUFFLE
:
9326 vec
<c_expr_t
, va_gc
> *cexpr_list
;
9329 location_t close_paren_loc
;
9331 c_parser_consume_token (parser
);
9332 if (!c_parser_get_builtin_args (parser
,
9333 "__builtin_shuffle",
9341 FOR_EACH_VEC_SAFE_ELT (cexpr_list
, i
, p
)
9342 *p
= convert_lvalue_to_rvalue (loc
, *p
, true, true);
9344 if (vec_safe_length (cexpr_list
) == 2)
9345 expr
.value
= c_build_vec_perm_expr (loc
, (*cexpr_list
)[0].value
,
9347 (*cexpr_list
)[1].value
);
9349 else if (vec_safe_length (cexpr_list
) == 3)
9350 expr
.value
= c_build_vec_perm_expr (loc
, (*cexpr_list
)[0].value
,
9351 (*cexpr_list
)[1].value
,
9352 (*cexpr_list
)[2].value
);
9355 error_at (loc
, "wrong number of arguments to "
9356 "%<__builtin_shuffle%>");
9359 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
9362 case RID_BUILTIN_CONVERTVECTOR
:
9364 location_t start_loc
= loc
;
9365 c_parser_consume_token (parser
);
9366 matching_parens parens
;
9367 if (!parens
.require_open (parser
))
9372 e1
= c_parser_expr_no_commas (parser
, NULL
);
9373 mark_exp_read (e1
.value
);
9374 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
9376 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
9380 loc
= c_parser_peek_token (parser
)->location
;
9381 t1
= c_parser_type_name (parser
);
9382 location_t end_loc
= c_parser_peek_token (parser
)->get_finish ();
9383 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
9389 tree type_expr
= NULL_TREE
;
9390 expr
.value
= c_build_vec_convert (start_loc
, e1
.value
, loc
,
9391 groktypename (t1
, &type_expr
,
9393 set_c_expr_source_range (&expr
, start_loc
, end_loc
);
9397 case RID_AT_SELECTOR
:
9399 gcc_assert (c_dialect_objc ());
9400 c_parser_consume_token (parser
);
9401 matching_parens parens
;
9402 if (!parens
.require_open (parser
))
9407 tree sel
= c_parser_objc_selector_arg (parser
);
9408 location_t close_loc
= c_parser_peek_token (parser
)->location
;
9409 parens
.skip_until_found_close (parser
);
9410 expr
.value
= objc_build_selector_expr (loc
, sel
);
9411 set_c_expr_source_range (&expr
, loc
, close_loc
);
9414 case RID_AT_PROTOCOL
:
9416 gcc_assert (c_dialect_objc ());
9417 c_parser_consume_token (parser
);
9418 matching_parens parens
;
9419 if (!parens
.require_open (parser
))
9424 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
9426 c_parser_error (parser
, "expected identifier");
9427 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
9431 tree id
= c_parser_peek_token (parser
)->value
;
9432 c_parser_consume_token (parser
);
9433 location_t close_loc
= c_parser_peek_token (parser
)->location
;
9434 parens
.skip_until_found_close (parser
);
9435 expr
.value
= objc_build_protocol_expr (id
);
9436 set_c_expr_source_range (&expr
, loc
, close_loc
);
9441 /* Extension to support C-structures in the archiver. */
9442 gcc_assert (c_dialect_objc ());
9443 c_parser_consume_token (parser
);
9444 matching_parens parens
;
9445 if (!parens
.require_open (parser
))
9450 t1
= c_parser_type_name (parser
);
9454 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
9457 location_t close_loc
= c_parser_peek_token (parser
)->location
;
9458 parens
.skip_until_found_close (parser
);
9459 tree type
= groktypename (t1
, NULL
, NULL
);
9460 expr
.value
= objc_build_encode_expr (type
);
9461 set_c_expr_source_range (&expr
, loc
, close_loc
);
9465 expr
= c_parser_generic_selection (parser
);
9468 c_parser_error (parser
, "expected expression");
9473 case CPP_OPEN_SQUARE
:
9474 if (c_dialect_objc ())
9476 tree receiver
, args
;
9477 c_parser_consume_token (parser
);
9478 receiver
= c_parser_objc_receiver (parser
);
9479 args
= c_parser_objc_message_args (parser
);
9480 location_t close_loc
= c_parser_peek_token (parser
)->location
;
9481 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
9483 expr
.value
= objc_build_message_expr (receiver
, args
);
9484 set_c_expr_source_range (&expr
, loc
, close_loc
);
9487 /* Else fall through to report error. */
9490 c_parser_error (parser
, "expected expression");
9495 return c_parser_postfix_expression_after_primary
9496 (parser
, EXPR_LOC_OR_LOC (expr
.value
, loc
), expr
);
9499 /* Parse a postfix expression after a parenthesized type name: the
9500 brace-enclosed initializer of a compound literal, possibly followed
9501 by some postfix operators. This is separate because it is not
9502 possible to tell until after the type name whether a cast
9503 expression has a cast or a compound literal, or whether the operand
9504 of sizeof is a parenthesized type name or starts with a compound
9505 literal. TYPE_LOC is the location where TYPE_NAME starts--the
9506 location of the first token after the parentheses around the type
9509 static struct c_expr
9510 c_parser_postfix_expression_after_paren_type (c_parser
*parser
,
9511 struct c_type_name
*type_name
,
9512 location_t type_loc
)
9518 location_t start_loc
;
9519 tree type_expr
= NULL_TREE
;
9520 bool type_expr_const
= true;
9521 check_compound_literal_type (type_loc
, type_name
);
9522 rich_location
richloc (line_table
, type_loc
);
9523 start_init (NULL_TREE
, NULL
, 0, &richloc
);
9524 type
= groktypename (type_name
, &type_expr
, &type_expr_const
);
9525 start_loc
= c_parser_peek_token (parser
)->location
;
9526 if (type
!= error_mark_node
&& C_TYPE_VARIABLE_SIZE (type
))
9528 error_at (type_loc
, "compound literal has variable size");
9529 type
= error_mark_node
;
9531 init
= c_parser_braced_init (parser
, type
, false, NULL
);
9533 maybe_warn_string_init (type_loc
, type
, init
);
9535 if (type
!= error_mark_node
9536 && !ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (type
))
9537 && current_function_decl
)
9539 error ("compound literal qualified by address-space qualifier");
9540 type
= error_mark_node
;
9543 pedwarn_c90 (start_loc
, OPT_Wpedantic
, "ISO C90 forbids compound literals");
9544 non_const
= ((init
.value
&& TREE_CODE (init
.value
) == CONSTRUCTOR
)
9545 ? CONSTRUCTOR_NON_CONST (init
.value
)
9546 : init
.original_code
== C_MAYBE_CONST_EXPR
);
9547 non_const
|= !type_expr_const
;
9548 unsigned int alignas_align
= 0;
9549 if (type
!= error_mark_node
9550 && type_name
->specs
->align_log
!= -1)
9552 alignas_align
= 1U << type_name
->specs
->align_log
;
9553 if (alignas_align
< min_align_of_type (type
))
9555 error_at (type_name
->specs
->locations
[cdw_alignas
],
9556 "%<_Alignas%> specifiers cannot reduce "
9557 "alignment of compound literal");
9561 expr
.value
= build_compound_literal (start_loc
, type
, init
.value
, non_const
,
9563 set_c_expr_source_range (&expr
, init
.src_range
);
9564 expr
.original_code
= ERROR_MARK
;
9565 expr
.original_type
= NULL
;
9566 if (type
!= error_mark_node
9567 && expr
.value
!= error_mark_node
9570 if (TREE_CODE (expr
.value
) == C_MAYBE_CONST_EXPR
)
9572 gcc_assert (C_MAYBE_CONST_EXPR_PRE (expr
.value
) == NULL_TREE
);
9573 C_MAYBE_CONST_EXPR_PRE (expr
.value
) = type_expr
;
9577 gcc_assert (!non_const
);
9578 expr
.value
= build2 (C_MAYBE_CONST_EXPR
, type
,
9579 type_expr
, expr
.value
);
9582 return c_parser_postfix_expression_after_primary (parser
, start_loc
, expr
);
9585 /* Callback function for sizeof_pointer_memaccess_warning to compare
9589 sizeof_ptr_memacc_comptypes (tree type1
, tree type2
)
9591 return comptypes (type1
, type2
) == 1;
9594 /* Warn for patterns where abs-like function appears to be used incorrectly,
9595 gracefully ignore any non-abs-like function. The warning location should
9596 be LOC. FNDECL is the declaration of called function, it must be a
9597 BUILT_IN_NORMAL function. ARG is the first and only argument of the
9601 warn_for_abs (location_t loc
, tree fndecl
, tree arg
)
9603 /* Avoid warning in unreachable subexpressions. */
9604 if (c_inhibit_evaluation_warnings
)
9607 tree atype
= TREE_TYPE (arg
);
9609 /* Casts from pointers (and thus arrays and fndecls) will generate
9610 -Wint-conversion warnings. Most other wrong types hopefully lead to type
9611 mismatch errors. TODO: Think about what to do with FIXED_POINT_TYPE_P
9612 types and possibly other exotic types. */
9613 if (!INTEGRAL_TYPE_P (atype
)
9614 && !SCALAR_FLOAT_TYPE_P (atype
)
9615 && TREE_CODE (atype
) != COMPLEX_TYPE
)
9618 enum built_in_function fcode
= DECL_FUNCTION_CODE (fndecl
);
9624 case BUILT_IN_LLABS
:
9625 case BUILT_IN_IMAXABS
:
9626 if (!INTEGRAL_TYPE_P (atype
))
9628 if (SCALAR_FLOAT_TYPE_P (atype
))
9629 warning_at (loc
, OPT_Wabsolute_value
,
9630 "using integer absolute value function %qD when "
9631 "argument is of floating-point type %qT",
9633 else if (TREE_CODE (atype
) == COMPLEX_TYPE
)
9634 warning_at (loc
, OPT_Wabsolute_value
,
9635 "using integer absolute value function %qD when "
9636 "argument is of complex type %qT", fndecl
, atype
);
9641 if (TYPE_UNSIGNED (atype
))
9642 warning_at (loc
, OPT_Wabsolute_value
,
9643 "taking the absolute value of unsigned type %qT "
9644 "has no effect", atype
);
9647 CASE_FLT_FN (BUILT_IN_FABS
):
9648 CASE_FLT_FN_FLOATN_NX (BUILT_IN_FABS
):
9649 if (!SCALAR_FLOAT_TYPE_P (atype
)
9650 || DECIMAL_FLOAT_MODE_P (TYPE_MODE (atype
)))
9652 if (INTEGRAL_TYPE_P (atype
))
9653 warning_at (loc
, OPT_Wabsolute_value
,
9654 "using floating-point absolute value function %qD "
9655 "when argument is of integer type %qT", fndecl
, atype
);
9656 else if (DECIMAL_FLOAT_TYPE_P (atype
))
9657 warning_at (loc
, OPT_Wabsolute_value
,
9658 "using floating-point absolute value function %qD "
9659 "when argument is of decimal floating-point type %qT",
9661 else if (TREE_CODE (atype
) == COMPLEX_TYPE
)
9662 warning_at (loc
, OPT_Wabsolute_value
,
9663 "using floating-point absolute value function %qD when "
9664 "argument is of complex type %qT", fndecl
, atype
);
9671 CASE_FLT_FN (BUILT_IN_CABS
):
9672 if (TREE_CODE (atype
) != COMPLEX_TYPE
)
9674 if (INTEGRAL_TYPE_P (atype
))
9675 warning_at (loc
, OPT_Wabsolute_value
,
9676 "using complex absolute value function %qD when "
9677 "argument is of integer type %qT", fndecl
, atype
);
9678 else if (SCALAR_FLOAT_TYPE_P (atype
))
9679 warning_at (loc
, OPT_Wabsolute_value
,
9680 "using complex absolute value function %qD when "
9681 "argument is of floating-point type %qT",
9690 case BUILT_IN_FABSD32
:
9691 case BUILT_IN_FABSD64
:
9692 case BUILT_IN_FABSD128
:
9693 if (!DECIMAL_FLOAT_TYPE_P (atype
))
9695 if (INTEGRAL_TYPE_P (atype
))
9696 warning_at (loc
, OPT_Wabsolute_value
,
9697 "using decimal floating-point absolute value "
9698 "function %qD when argument is of integer type %qT",
9700 else if (SCALAR_FLOAT_TYPE_P (atype
))
9701 warning_at (loc
, OPT_Wabsolute_value
,
9702 "using decimal floating-point absolute value "
9703 "function %qD when argument is of floating-point "
9704 "type %qT", fndecl
, atype
);
9705 else if (TREE_CODE (atype
) == COMPLEX_TYPE
)
9706 warning_at (loc
, OPT_Wabsolute_value
,
9707 "using decimal floating-point absolute value "
9708 "function %qD when argument is of complex type %qT",
9720 if (!TYPE_ARG_TYPES (TREE_TYPE (fndecl
)))
9723 tree ftype
= TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl
)));
9724 if (TREE_CODE (atype
) == COMPLEX_TYPE
)
9726 gcc_assert (TREE_CODE (ftype
) == COMPLEX_TYPE
);
9727 atype
= TREE_TYPE (atype
);
9728 ftype
= TREE_TYPE (ftype
);
9731 if (TYPE_PRECISION (ftype
) < TYPE_PRECISION (atype
))
9732 warning_at (loc
, OPT_Wabsolute_value
,
9733 "absolute value function %qD given an argument of type %qT "
9734 "but has parameter of type %qT which may cause truncation "
9735 "of value", fndecl
, atype
, ftype
);
9739 /* Parse a postfix expression after the initial primary or compound
9740 literal; that is, parse a series of postfix operators.
9742 EXPR_LOC is the location of the primary expression. */
9744 static struct c_expr
9745 c_parser_postfix_expression_after_primary (c_parser
*parser
,
9746 location_t expr_loc
,
9749 struct c_expr orig_expr
;
9751 location_t sizeof_arg_loc
[3], comp_loc
;
9753 unsigned int literal_zero_mask
;
9755 vec
<tree
, va_gc
> *exprlist
;
9756 vec
<tree
, va_gc
> *origtypes
= NULL
;
9757 vec
<location_t
> arg_loc
= vNULL
;
9763 location_t op_loc
= c_parser_peek_token (parser
)->location
;
9764 switch (c_parser_peek_token (parser
)->type
)
9766 case CPP_OPEN_SQUARE
:
9767 /* Array reference. */
9768 c_parser_consume_token (parser
);
9769 idx
= c_parser_expression (parser
).value
;
9770 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
9772 start
= expr
.get_start ();
9773 finish
= parser
->tokens_buf
[0].location
;
9774 expr
.value
= build_array_ref (op_loc
, expr
.value
, idx
);
9775 set_c_expr_source_range (&expr
, start
, finish
);
9776 expr
.original_code
= ERROR_MARK
;
9777 expr
.original_type
= NULL
;
9779 case CPP_OPEN_PAREN
:
9780 /* Function call. */
9781 c_parser_consume_token (parser
);
9782 for (i
= 0; i
< 3; i
++)
9784 sizeof_arg
[i
] = NULL_TREE
;
9785 sizeof_arg_loc
[i
] = UNKNOWN_LOCATION
;
9787 literal_zero_mask
= 0;
9788 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
9791 exprlist
= c_parser_expr_list (parser
, true, false, &origtypes
,
9792 sizeof_arg_loc
, sizeof_arg
,
9793 &arg_loc
, &literal_zero_mask
);
9794 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
9797 mark_exp_read (expr
.value
);
9798 if (warn_sizeof_pointer_memaccess
)
9799 sizeof_pointer_memaccess_warning (sizeof_arg_loc
,
9800 expr
.value
, exprlist
,
9802 sizeof_ptr_memacc_comptypes
);
9803 if (TREE_CODE (expr
.value
) == FUNCTION_DECL
)
9805 if (fndecl_built_in_p (expr
.value
, BUILT_IN_MEMSET
)
9806 && vec_safe_length (exprlist
) == 3)
9808 tree arg0
= (*exprlist
)[0];
9809 tree arg2
= (*exprlist
)[2];
9810 warn_for_memset (expr_loc
, arg0
, arg2
, literal_zero_mask
);
9812 if (warn_absolute_value
9813 && fndecl_built_in_p (expr
.value
, BUILT_IN_NORMAL
)
9814 && vec_safe_length (exprlist
) == 1)
9815 warn_for_abs (expr_loc
, expr
.value
, (*exprlist
)[0]);
9818 start
= expr
.get_start ();
9819 finish
= parser
->tokens_buf
[0].get_finish ();
9821 = c_build_function_call_vec (expr_loc
, arg_loc
, expr
.value
,
9822 exprlist
, origtypes
);
9823 set_c_expr_source_range (&expr
, start
, finish
);
9825 expr
.original_code
= ERROR_MARK
;
9826 if (TREE_CODE (expr
.value
) == INTEGER_CST
9827 && TREE_CODE (orig_expr
.value
) == FUNCTION_DECL
9828 && fndecl_built_in_p (orig_expr
.value
, BUILT_IN_CONSTANT_P
))
9829 expr
.original_code
= C_MAYBE_CONST_EXPR
;
9830 expr
.original_type
= NULL
;
9833 release_tree_vector (exprlist
);
9834 release_tree_vector (origtypes
);
9839 /* Structure element reference. */
9840 c_parser_consume_token (parser
);
9841 expr
= default_function_array_conversion (expr_loc
, expr
);
9842 if (c_parser_next_token_is (parser
, CPP_NAME
))
9844 c_token
*comp_tok
= c_parser_peek_token (parser
);
9845 ident
= comp_tok
->value
;
9846 comp_loc
= comp_tok
->location
;
9850 c_parser_error (parser
, "expected identifier");
9852 expr
.original_code
= ERROR_MARK
;
9853 expr
.original_type
= NULL
;
9856 start
= expr
.get_start ();
9857 finish
= c_parser_peek_token (parser
)->get_finish ();
9858 c_parser_consume_token (parser
);
9859 expr
.value
= build_component_ref (op_loc
, expr
.value
, ident
,
9861 set_c_expr_source_range (&expr
, start
, finish
);
9862 expr
.original_code
= ERROR_MARK
;
9863 if (TREE_CODE (expr
.value
) != COMPONENT_REF
)
9864 expr
.original_type
= NULL
;
9867 /* Remember the original type of a bitfield. */
9868 tree field
= TREE_OPERAND (expr
.value
, 1);
9869 if (TREE_CODE (field
) != FIELD_DECL
)
9870 expr
.original_type
= NULL
;
9872 expr
.original_type
= DECL_BIT_FIELD_TYPE (field
);
9876 /* Structure element reference. */
9877 c_parser_consume_token (parser
);
9878 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, true, false);
9879 if (c_parser_next_token_is (parser
, CPP_NAME
))
9881 c_token
*comp_tok
= c_parser_peek_token (parser
);
9882 ident
= comp_tok
->value
;
9883 comp_loc
= comp_tok
->location
;
9887 c_parser_error (parser
, "expected identifier");
9889 expr
.original_code
= ERROR_MARK
;
9890 expr
.original_type
= NULL
;
9893 start
= expr
.get_start ();
9894 finish
= c_parser_peek_token (parser
)->get_finish ();
9895 c_parser_consume_token (parser
);
9896 expr
.value
= build_component_ref (op_loc
,
9897 build_indirect_ref (op_loc
,
9901 set_c_expr_source_range (&expr
, start
, finish
);
9902 expr
.original_code
= ERROR_MARK
;
9903 if (TREE_CODE (expr
.value
) != COMPONENT_REF
)
9904 expr
.original_type
= NULL
;
9907 /* Remember the original type of a bitfield. */
9908 tree field
= TREE_OPERAND (expr
.value
, 1);
9909 if (TREE_CODE (field
) != FIELD_DECL
)
9910 expr
.original_type
= NULL
;
9912 expr
.original_type
= DECL_BIT_FIELD_TYPE (field
);
9916 /* Postincrement. */
9917 start
= expr
.get_start ();
9918 finish
= c_parser_peek_token (parser
)->get_finish ();
9919 c_parser_consume_token (parser
);
9920 expr
= default_function_array_read_conversion (expr_loc
, expr
);
9921 expr
.value
= build_unary_op (op_loc
, POSTINCREMENT_EXPR
,
9923 set_c_expr_source_range (&expr
, start
, finish
);
9924 expr
.original_code
= ERROR_MARK
;
9925 expr
.original_type
= NULL
;
9927 case CPP_MINUS_MINUS
:
9928 /* Postdecrement. */
9929 start
= expr
.get_start ();
9930 finish
= c_parser_peek_token (parser
)->get_finish ();
9931 c_parser_consume_token (parser
);
9932 expr
= default_function_array_read_conversion (expr_loc
, expr
);
9933 expr
.value
= build_unary_op (op_loc
, POSTDECREMENT_EXPR
,
9935 set_c_expr_source_range (&expr
, start
, finish
);
9936 expr
.original_code
= ERROR_MARK
;
9937 expr
.original_type
= NULL
;
9945 /* Parse an expression (C90 6.3.17, C99 6.5.17, C11 6.5.17).
9948 assignment-expression
9949 expression , assignment-expression
9952 static struct c_expr
9953 c_parser_expression (c_parser
*parser
)
9955 location_t tloc
= c_parser_peek_token (parser
)->location
;
9957 expr
= c_parser_expr_no_commas (parser
, NULL
);
9958 if (c_parser_next_token_is (parser
, CPP_COMMA
))
9959 expr
= convert_lvalue_to_rvalue (tloc
, expr
, true, false);
9960 while (c_parser_next_token_is (parser
, CPP_COMMA
))
9964 location_t loc
= c_parser_peek_token (parser
)->location
;
9965 location_t expr_loc
;
9966 c_parser_consume_token (parser
);
9967 expr_loc
= c_parser_peek_token (parser
)->location
;
9968 lhsval
= expr
.value
;
9969 while (TREE_CODE (lhsval
) == COMPOUND_EXPR
)
9970 lhsval
= TREE_OPERAND (lhsval
, 1);
9971 if (DECL_P (lhsval
) || handled_component_p (lhsval
))
9972 mark_exp_read (lhsval
);
9973 next
= c_parser_expr_no_commas (parser
, NULL
);
9974 next
= convert_lvalue_to_rvalue (expr_loc
, next
, true, false);
9975 expr
.value
= build_compound_expr (loc
, expr
.value
, next
.value
);
9976 expr
.original_code
= COMPOUND_EXPR
;
9977 expr
.original_type
= next
.original_type
;
9982 /* Parse an expression and convert functions or arrays to pointers and
9983 lvalues to rvalues. */
9985 static struct c_expr
9986 c_parser_expression_conv (c_parser
*parser
)
9989 location_t loc
= c_parser_peek_token (parser
)->location
;
9990 expr
= c_parser_expression (parser
);
9991 expr
= convert_lvalue_to_rvalue (loc
, expr
, true, false);
9995 /* Helper function of c_parser_expr_list. Check if IDXth (0 based)
9996 argument is a literal zero alone and if so, set it in literal_zero_mask. */
9999 c_parser_check_literal_zero (c_parser
*parser
, unsigned *literal_zero_mask
,
10002 if (idx
>= HOST_BITS_PER_INT
)
10005 c_token
*tok
= c_parser_peek_token (parser
);
10013 /* If a parameter is literal zero alone, remember it
10014 for -Wmemset-transposed-args warning. */
10015 if (integer_zerop (tok
->value
)
10016 && !TREE_OVERFLOW (tok
->value
)
10017 && (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
10018 || c_parser_peek_2nd_token (parser
)->type
== CPP_CLOSE_PAREN
))
10019 *literal_zero_mask
|= 1U << idx
;
10025 /* Parse a non-empty list of expressions. If CONVERT_P, convert
10026 functions and arrays to pointers and lvalues to rvalues. If
10027 FOLD_P, fold the expressions. If LOCATIONS is non-NULL, save the
10028 locations of function arguments into this vector.
10030 nonempty-expr-list:
10031 assignment-expression
10032 nonempty-expr-list , assignment-expression
10035 static vec
<tree
, va_gc
> *
10036 c_parser_expr_list (c_parser
*parser
, bool convert_p
, bool fold_p
,
10037 vec
<tree
, va_gc
> **p_orig_types
,
10038 location_t
*sizeof_arg_loc
, tree
*sizeof_arg
,
10039 vec
<location_t
> *locations
,
10040 unsigned int *literal_zero_mask
)
10042 vec
<tree
, va_gc
> *ret
;
10043 vec
<tree
, va_gc
> *orig_types
;
10044 struct c_expr expr
;
10045 unsigned int idx
= 0;
10047 ret
= make_tree_vector ();
10048 if (p_orig_types
== NULL
)
10051 orig_types
= make_tree_vector ();
10053 if (literal_zero_mask
)
10054 c_parser_check_literal_zero (parser
, literal_zero_mask
, 0);
10055 expr
= c_parser_expr_no_commas (parser
, NULL
);
10057 expr
= convert_lvalue_to_rvalue (expr
.get_location (), expr
, true, true);
10059 expr
.value
= c_fully_fold (expr
.value
, false, NULL
);
10060 ret
->quick_push (expr
.value
);
10062 orig_types
->quick_push (expr
.original_type
);
10064 locations
->safe_push (expr
.get_location ());
10065 if (sizeof_arg
!= NULL
10066 && expr
.original_code
== SIZEOF_EXPR
)
10068 sizeof_arg
[0] = c_last_sizeof_arg
;
10069 sizeof_arg_loc
[0] = c_last_sizeof_loc
;
10071 while (c_parser_next_token_is (parser
, CPP_COMMA
))
10073 c_parser_consume_token (parser
);
10074 if (literal_zero_mask
)
10075 c_parser_check_literal_zero (parser
, literal_zero_mask
, idx
+ 1);
10076 expr
= c_parser_expr_no_commas (parser
, NULL
);
10078 expr
= convert_lvalue_to_rvalue (expr
.get_location (), expr
, true,
10081 expr
.value
= c_fully_fold (expr
.value
, false, NULL
);
10082 vec_safe_push (ret
, expr
.value
);
10084 vec_safe_push (orig_types
, expr
.original_type
);
10086 locations
->safe_push (expr
.get_location ());
10088 && sizeof_arg
!= NULL
10089 && expr
.original_code
== SIZEOF_EXPR
)
10091 sizeof_arg
[idx
] = c_last_sizeof_arg
;
10092 sizeof_arg_loc
[idx
] = c_last_sizeof_loc
;
10096 *p_orig_types
= orig_types
;
10100 /* Parse Objective-C-specific constructs. */
10102 /* Parse an objc-class-definition.
10104 objc-class-definition:
10105 @interface identifier objc-superclass[opt] objc-protocol-refs[opt]
10106 objc-class-instance-variables[opt] objc-methodprotolist @end
10107 @implementation identifier objc-superclass[opt]
10108 objc-class-instance-variables[opt]
10109 @interface identifier ( identifier ) objc-protocol-refs[opt]
10110 objc-methodprotolist @end
10111 @interface identifier ( ) objc-protocol-refs[opt]
10112 objc-methodprotolist @end
10113 @implementation identifier ( identifier )
10118 "@interface identifier (" must start "@interface identifier (
10119 identifier ) ...": objc-methodprotolist in the first production may
10120 not start with a parenthesized identifier as a declarator of a data
10121 definition with no declaration specifiers if the objc-superclass,
10122 objc-protocol-refs and objc-class-instance-variables are omitted. */
10125 c_parser_objc_class_definition (c_parser
*parser
, tree attributes
)
10130 if (c_parser_next_token_is_keyword (parser
, RID_AT_INTERFACE
))
10132 else if (c_parser_next_token_is_keyword (parser
, RID_AT_IMPLEMENTATION
))
10135 gcc_unreachable ();
10137 c_parser_consume_token (parser
);
10138 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
10140 c_parser_error (parser
, "expected identifier");
10143 id1
= c_parser_peek_token (parser
)->value
;
10144 c_parser_consume_token (parser
);
10145 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
10147 /* We have a category or class extension. */
10149 tree proto
= NULL_TREE
;
10150 matching_parens parens
;
10151 parens
.consume_open (parser
);
10152 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
10154 if (iface_p
&& c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
10156 /* We have a class extension. */
10161 c_parser_error (parser
, "expected identifier or %<)%>");
10162 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10168 id2
= c_parser_peek_token (parser
)->value
;
10169 c_parser_consume_token (parser
);
10171 parens
.skip_until_found_close (parser
);
10174 objc_start_category_implementation (id1
, id2
);
10177 if (c_parser_next_token_is (parser
, CPP_LESS
))
10178 proto
= c_parser_objc_protocol_refs (parser
);
10179 objc_start_category_interface (id1
, id2
, proto
, attributes
);
10180 c_parser_objc_methodprotolist (parser
);
10181 c_parser_require_keyword (parser
, RID_AT_END
, "expected %<@end%>");
10182 objc_finish_interface ();
10185 if (c_parser_next_token_is (parser
, CPP_COLON
))
10187 c_parser_consume_token (parser
);
10188 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
10190 c_parser_error (parser
, "expected identifier");
10193 superclass
= c_parser_peek_token (parser
)->value
;
10194 c_parser_consume_token (parser
);
10197 superclass
= NULL_TREE
;
10200 tree proto
= NULL_TREE
;
10201 if (c_parser_next_token_is (parser
, CPP_LESS
))
10202 proto
= c_parser_objc_protocol_refs (parser
);
10203 objc_start_class_interface (id1
, superclass
, proto
, attributes
);
10206 objc_start_class_implementation (id1
, superclass
);
10207 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
10208 c_parser_objc_class_instance_variables (parser
);
10211 objc_continue_interface ();
10212 c_parser_objc_methodprotolist (parser
);
10213 c_parser_require_keyword (parser
, RID_AT_END
, "expected %<@end%>");
10214 objc_finish_interface ();
10218 objc_continue_implementation ();
10223 /* Parse objc-class-instance-variables.
10225 objc-class-instance-variables:
10226 { objc-instance-variable-decl-list[opt] }
10228 objc-instance-variable-decl-list:
10229 objc-visibility-spec
10230 objc-instance-variable-decl ;
10232 objc-instance-variable-decl-list objc-visibility-spec
10233 objc-instance-variable-decl-list objc-instance-variable-decl ;
10234 objc-instance-variable-decl-list ;
10236 objc-visibility-spec:
10241 objc-instance-variable-decl:
10246 c_parser_objc_class_instance_variables (c_parser
*parser
)
10248 gcc_assert (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
));
10249 c_parser_consume_token (parser
);
10250 while (c_parser_next_token_is_not (parser
, CPP_EOF
))
10253 /* Parse any stray semicolon. */
10254 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
10256 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
10257 "extra semicolon");
10258 c_parser_consume_token (parser
);
10261 /* Stop if at the end of the instance variables. */
10262 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
10264 c_parser_consume_token (parser
);
10267 /* Parse any objc-visibility-spec. */
10268 if (c_parser_next_token_is_keyword (parser
, RID_AT_PRIVATE
))
10270 c_parser_consume_token (parser
);
10271 objc_set_visibility (OBJC_IVAR_VIS_PRIVATE
);
10274 else if (c_parser_next_token_is_keyword (parser
, RID_AT_PROTECTED
))
10276 c_parser_consume_token (parser
);
10277 objc_set_visibility (OBJC_IVAR_VIS_PROTECTED
);
10280 else if (c_parser_next_token_is_keyword (parser
, RID_AT_PUBLIC
))
10282 c_parser_consume_token (parser
);
10283 objc_set_visibility (OBJC_IVAR_VIS_PUBLIC
);
10286 else if (c_parser_next_token_is_keyword (parser
, RID_AT_PACKAGE
))
10288 c_parser_consume_token (parser
);
10289 objc_set_visibility (OBJC_IVAR_VIS_PACKAGE
);
10292 else if (c_parser_next_token_is (parser
, CPP_PRAGMA
))
10294 c_parser_pragma (parser
, pragma_external
, NULL
);
10298 /* Parse some comma-separated declarations. */
10299 decls
= c_parser_struct_declaration (parser
);
10302 /* There is a syntax error. We want to skip the offending
10303 tokens up to the next ';' (included) or '}'
10306 /* First, skip manually a ')' or ']'. This is because they
10307 reduce the nesting level, so c_parser_skip_until_found()
10308 wouldn't be able to skip past them. */
10309 c_token
*token
= c_parser_peek_token (parser
);
10310 if (token
->type
== CPP_CLOSE_PAREN
|| token
->type
== CPP_CLOSE_SQUARE
)
10311 c_parser_consume_token (parser
);
10313 /* Then, do the standard skipping. */
10314 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
10316 /* We hopefully recovered. Start normal parsing again. */
10317 parser
->error
= false;
10322 /* Comma-separated instance variables are chained together
10323 in reverse order; add them one by one. */
10324 tree ivar
= nreverse (decls
);
10325 for (; ivar
; ivar
= DECL_CHAIN (ivar
))
10326 objc_add_instance_variable (copy_node (ivar
));
10328 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
10332 /* Parse an objc-class-declaration.
10334 objc-class-declaration:
10335 @class identifier-list ;
10339 c_parser_objc_class_declaration (c_parser
*parser
)
10341 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_CLASS
));
10342 c_parser_consume_token (parser
);
10343 /* Any identifiers, including those declared as type names, are OK
10348 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
10350 c_parser_error (parser
, "expected identifier");
10351 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
10352 parser
->error
= false;
10355 id
= c_parser_peek_token (parser
)->value
;
10356 objc_declare_class (id
);
10357 c_parser_consume_token (parser
);
10358 if (c_parser_next_token_is (parser
, CPP_COMMA
))
10359 c_parser_consume_token (parser
);
10363 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
10366 /* Parse an objc-alias-declaration.
10368 objc-alias-declaration:
10369 @compatibility_alias identifier identifier ;
10373 c_parser_objc_alias_declaration (c_parser
*parser
)
10376 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_ALIAS
));
10377 c_parser_consume_token (parser
);
10378 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
10380 c_parser_error (parser
, "expected identifier");
10381 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
10384 id1
= c_parser_peek_token (parser
)->value
;
10385 c_parser_consume_token (parser
);
10386 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
10388 c_parser_error (parser
, "expected identifier");
10389 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
10392 id2
= c_parser_peek_token (parser
)->value
;
10393 c_parser_consume_token (parser
);
10394 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
10395 objc_declare_alias (id1
, id2
);
10398 /* Parse an objc-protocol-definition.
10400 objc-protocol-definition:
10401 @protocol identifier objc-protocol-refs[opt] objc-methodprotolist @end
10402 @protocol identifier-list ;
10404 "@protocol identifier ;" should be resolved as "@protocol
10405 identifier-list ;": objc-methodprotolist may not start with a
10406 semicolon in the first alternative if objc-protocol-refs are
10410 c_parser_objc_protocol_definition (c_parser
*parser
, tree attributes
)
10412 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_PROTOCOL
));
10414 c_parser_consume_token (parser
);
10415 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
10417 c_parser_error (parser
, "expected identifier");
10420 if (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
10421 || c_parser_peek_2nd_token (parser
)->type
== CPP_SEMICOLON
)
10423 /* Any identifiers, including those declared as type names, are
10428 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
10430 c_parser_error (parser
, "expected identifier");
10433 id
= c_parser_peek_token (parser
)->value
;
10434 objc_declare_protocol (id
, attributes
);
10435 c_parser_consume_token (parser
);
10436 if (c_parser_next_token_is (parser
, CPP_COMMA
))
10437 c_parser_consume_token (parser
);
10441 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
10445 tree id
= c_parser_peek_token (parser
)->value
;
10446 tree proto
= NULL_TREE
;
10447 c_parser_consume_token (parser
);
10448 if (c_parser_next_token_is (parser
, CPP_LESS
))
10449 proto
= c_parser_objc_protocol_refs (parser
);
10450 parser
->objc_pq_context
= true;
10451 objc_start_protocol (id
, proto
, attributes
);
10452 c_parser_objc_methodprotolist (parser
);
10453 c_parser_require_keyword (parser
, RID_AT_END
, "expected %<@end%>");
10454 parser
->objc_pq_context
= false;
10455 objc_finish_interface ();
10459 /* Parse an objc-method-type.
10465 Return true if it is a class method (+) and false if it is
10466 an instance method (-).
10469 c_parser_objc_method_type (c_parser
*parser
)
10471 switch (c_parser_peek_token (parser
)->type
)
10474 c_parser_consume_token (parser
);
10477 c_parser_consume_token (parser
);
10480 gcc_unreachable ();
10484 /* Parse an objc-method-definition.
10486 objc-method-definition:
10487 objc-method-type objc-method-decl ;[opt] compound-statement
10491 c_parser_objc_method_definition (c_parser
*parser
)
10493 bool is_class_method
= c_parser_objc_method_type (parser
);
10494 tree decl
, attributes
= NULL_TREE
, expr
= NULL_TREE
;
10495 parser
->objc_pq_context
= true;
10496 decl
= c_parser_objc_method_decl (parser
, is_class_method
, &attributes
,
10498 if (decl
== error_mark_node
)
10499 return; /* Bail here. */
10501 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
10503 c_parser_consume_token (parser
);
10504 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
10505 "extra semicolon in method definition specified");
10508 if (!c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
10510 c_parser_error (parser
, "expected %<{%>");
10514 parser
->objc_pq_context
= false;
10515 if (objc_start_method_definition (is_class_method
, decl
, attributes
, expr
))
10517 add_stmt (c_parser_compound_statement (parser
));
10518 objc_finish_method_definition (current_function_decl
);
10522 /* This code is executed when we find a method definition
10523 outside of an @implementation context (or invalid for other
10524 reasons). Parse the method (to keep going) but do not emit
10527 c_parser_compound_statement (parser
);
10531 /* Parse an objc-methodprotolist.
10533 objc-methodprotolist:
10535 objc-methodprotolist objc-methodproto
10536 objc-methodprotolist declaration
10537 objc-methodprotolist ;
10541 The declaration is a data definition, which may be missing
10542 declaration specifiers under the same rules and diagnostics as
10543 other data definitions outside functions, and the stray semicolon
10544 is diagnosed the same way as a stray semicolon outside a
10548 c_parser_objc_methodprotolist (c_parser
*parser
)
10552 /* The list is terminated by @end. */
10553 switch (c_parser_peek_token (parser
)->type
)
10555 case CPP_SEMICOLON
:
10556 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
10557 "ISO C does not allow extra %<;%> outside of a function");
10558 c_parser_consume_token (parser
);
10562 c_parser_objc_methodproto (parser
);
10565 c_parser_pragma (parser
, pragma_external
, NULL
);
10570 if (c_parser_next_token_is_keyword (parser
, RID_AT_END
))
10572 else if (c_parser_next_token_is_keyword (parser
, RID_AT_PROPERTY
))
10573 c_parser_objc_at_property_declaration (parser
);
10574 else if (c_parser_next_token_is_keyword (parser
, RID_AT_OPTIONAL
))
10576 objc_set_method_opt (true);
10577 c_parser_consume_token (parser
);
10579 else if (c_parser_next_token_is_keyword (parser
, RID_AT_REQUIRED
))
10581 objc_set_method_opt (false);
10582 c_parser_consume_token (parser
);
10585 c_parser_declaration_or_fndef (parser
, false, false, true,
10586 false, true, NULL
, vNULL
);
10592 /* Parse an objc-methodproto.
10595 objc-method-type objc-method-decl ;
10599 c_parser_objc_methodproto (c_parser
*parser
)
10601 bool is_class_method
= c_parser_objc_method_type (parser
);
10602 tree decl
, attributes
= NULL_TREE
;
10604 /* Remember protocol qualifiers in prototypes. */
10605 parser
->objc_pq_context
= true;
10606 decl
= c_parser_objc_method_decl (parser
, is_class_method
, &attributes
,
10608 /* Forget protocol qualifiers now. */
10609 parser
->objc_pq_context
= false;
10611 /* Do not allow the presence of attributes to hide an erroneous
10612 method implementation in the interface section. */
10613 if (!c_parser_next_token_is (parser
, CPP_SEMICOLON
))
10615 c_parser_error (parser
, "expected %<;%>");
10619 if (decl
!= error_mark_node
)
10620 objc_add_method_declaration (is_class_method
, decl
, attributes
);
10622 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
10625 /* If we are at a position that method attributes may be present, check that
10626 there are not any parsed already (a syntax error) and then collect any
10627 specified at the current location. Finally, if new attributes were present,
10628 check that the next token is legal ( ';' for decls and '{' for defs). */
10631 c_parser_objc_maybe_method_attributes (c_parser
* parser
, tree
* attributes
)
10636 c_parser_error (parser
,
10637 "method attributes must be specified at the end only");
10638 *attributes
= NULL_TREE
;
10642 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
10643 *attributes
= c_parser_gnu_attributes (parser
);
10645 /* If there were no attributes here, just report any earlier error. */
10646 if (*attributes
== NULL_TREE
|| bad
)
10649 /* If the attributes are followed by a ; or {, then just report any earlier
10651 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
)
10652 || c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
10655 /* We've got attributes, but not at the end. */
10656 c_parser_error (parser
,
10657 "expected %<;%> or %<{%> after method attribute definition");
10661 /* Parse an objc-method-decl.
10664 ( objc-type-name ) objc-selector
10666 ( objc-type-name ) objc-keyword-selector objc-optparmlist
10667 objc-keyword-selector objc-optparmlist
10670 objc-keyword-selector:
10672 objc-keyword-selector objc-keyword-decl
10675 objc-selector : ( objc-type-name ) identifier
10676 objc-selector : identifier
10677 : ( objc-type-name ) identifier
10681 objc-optparms objc-optellipsis
10685 objc-opt-parms , parameter-declaration
10693 c_parser_objc_method_decl (c_parser
*parser
, bool is_class_method
,
10694 tree
*attributes
, tree
*expr
)
10696 tree type
= NULL_TREE
;
10698 tree parms
= NULL_TREE
;
10699 bool ellipsis
= false;
10700 bool attr_err
= false;
10702 *attributes
= NULL_TREE
;
10703 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
10705 matching_parens parens
;
10706 parens
.consume_open (parser
);
10707 type
= c_parser_objc_type_name (parser
);
10708 parens
.skip_until_found_close (parser
);
10710 sel
= c_parser_objc_selector (parser
);
10711 /* If there is no selector, or a colon follows, we have an
10712 objc-keyword-selector. If there is a selector, and a colon does
10713 not follow, that selector ends the objc-method-decl. */
10714 if (!sel
|| c_parser_next_token_is (parser
, CPP_COLON
))
10717 tree list
= NULL_TREE
;
10720 tree atype
= NULL_TREE
, id
, keyworddecl
;
10721 tree param_attr
= NULL_TREE
;
10722 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
10724 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
10726 c_parser_consume_token (parser
);
10727 atype
= c_parser_objc_type_name (parser
);
10728 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
10731 /* New ObjC allows attributes on method parameters. */
10732 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
10733 param_attr
= c_parser_gnu_attributes (parser
);
10734 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
10736 c_parser_error (parser
, "expected identifier");
10737 return error_mark_node
;
10739 id
= c_parser_peek_token (parser
)->value
;
10740 c_parser_consume_token (parser
);
10741 keyworddecl
= objc_build_keyword_decl (tsel
, atype
, id
, param_attr
);
10742 list
= chainon (list
, keyworddecl
);
10743 tsel
= c_parser_objc_selector (parser
);
10744 if (!tsel
&& c_parser_next_token_is_not (parser
, CPP_COLON
))
10748 attr_err
|= c_parser_objc_maybe_method_attributes (parser
, attributes
) ;
10750 /* Parse the optional parameter list. Optional Objective-C
10751 method parameters follow the C syntax, and may include '...'
10752 to denote a variable number of arguments. */
10753 parms
= make_node (TREE_LIST
);
10754 while (c_parser_next_token_is (parser
, CPP_COMMA
))
10756 struct c_parm
*parm
;
10757 c_parser_consume_token (parser
);
10758 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
10761 c_parser_consume_token (parser
);
10762 attr_err
|= c_parser_objc_maybe_method_attributes
10763 (parser
, attributes
) ;
10766 parm
= c_parser_parameter_declaration (parser
, NULL_TREE
);
10769 parms
= chainon (parms
,
10770 build_tree_list (NULL_TREE
, grokparm (parm
, expr
)));
10775 attr_err
|= c_parser_objc_maybe_method_attributes (parser
, attributes
) ;
10779 c_parser_error (parser
, "objective-c method declaration is expected");
10780 return error_mark_node
;
10784 return error_mark_node
;
10786 return objc_build_method_signature (is_class_method
, type
, sel
, parms
, ellipsis
);
10789 /* Parse an objc-type-name.
10792 objc-type-qualifiers[opt] type-name
10793 objc-type-qualifiers[opt]
10795 objc-type-qualifiers:
10796 objc-type-qualifier
10797 objc-type-qualifiers objc-type-qualifier
10799 objc-type-qualifier: one of
10800 in out inout bycopy byref oneway
10804 c_parser_objc_type_name (c_parser
*parser
)
10806 tree quals
= NULL_TREE
;
10807 struct c_type_name
*type_name
= NULL
;
10808 tree type
= NULL_TREE
;
10811 c_token
*token
= c_parser_peek_token (parser
);
10812 if (token
->type
== CPP_KEYWORD
10813 && (token
->keyword
== RID_IN
10814 || token
->keyword
== RID_OUT
10815 || token
->keyword
== RID_INOUT
10816 || token
->keyword
== RID_BYCOPY
10817 || token
->keyword
== RID_BYREF
10818 || token
->keyword
== RID_ONEWAY
))
10820 quals
= chainon (build_tree_list (NULL_TREE
, token
->value
), quals
);
10821 c_parser_consume_token (parser
);
10826 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_type
))
10827 type_name
= c_parser_type_name (parser
);
10829 type
= groktypename (type_name
, NULL
, NULL
);
10831 /* If the type is unknown, and error has already been produced and
10832 we need to recover from the error. In that case, use NULL_TREE
10833 for the type, as if no type had been specified; this will use the
10834 default type ('id') which is good for error recovery. */
10835 if (type
== error_mark_node
)
10838 return build_tree_list (quals
, type
);
10841 /* Parse objc-protocol-refs.
10843 objc-protocol-refs:
10844 < identifier-list >
10848 c_parser_objc_protocol_refs (c_parser
*parser
)
10850 tree list
= NULL_TREE
;
10851 gcc_assert (c_parser_next_token_is (parser
, CPP_LESS
));
10852 c_parser_consume_token (parser
);
10853 /* Any identifiers, including those declared as type names, are OK
10858 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
10860 c_parser_error (parser
, "expected identifier");
10863 id
= c_parser_peek_token (parser
)->value
;
10864 list
= chainon (list
, build_tree_list (NULL_TREE
, id
));
10865 c_parser_consume_token (parser
);
10866 if (c_parser_next_token_is (parser
, CPP_COMMA
))
10867 c_parser_consume_token (parser
);
10871 c_parser_require (parser
, CPP_GREATER
, "expected %<>%>");
10875 /* Parse an objc-try-catch-finally-statement.
10877 objc-try-catch-finally-statement:
10878 @try compound-statement objc-catch-list[opt]
10879 @try compound-statement objc-catch-list[opt] @finally compound-statement
10882 @catch ( objc-catch-parameter-declaration ) compound-statement
10883 objc-catch-list @catch ( objc-catch-parameter-declaration ) compound-statement
10885 objc-catch-parameter-declaration:
10886 parameter-declaration
10889 where '...' is to be interpreted literally, that is, it means CPP_ELLIPSIS.
10891 PS: This function is identical to cp_parser_objc_try_catch_finally_statement
10892 for C++. Keep them in sync. */
10895 c_parser_objc_try_catch_finally_statement (c_parser
*parser
)
10897 location_t location
;
10900 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_TRY
));
10901 c_parser_consume_token (parser
);
10902 location
= c_parser_peek_token (parser
)->location
;
10903 objc_maybe_warn_exceptions (location
);
10904 stmt
= c_parser_compound_statement (parser
);
10905 objc_begin_try_stmt (location
, stmt
);
10907 while (c_parser_next_token_is_keyword (parser
, RID_AT_CATCH
))
10909 struct c_parm
*parm
;
10910 tree parameter_declaration
= error_mark_node
;
10911 bool seen_open_paren
= false;
10913 c_parser_consume_token (parser
);
10914 matching_parens parens
;
10915 if (!parens
.require_open (parser
))
10916 seen_open_paren
= true;
10917 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
10919 /* We have "@catch (...)" (where the '...' are literally
10920 what is in the code). Skip the '...'.
10921 parameter_declaration is set to NULL_TREE, and
10922 objc_being_catch_clauses() knows that that means
10924 c_parser_consume_token (parser
);
10925 parameter_declaration
= NULL_TREE
;
10929 /* We have "@catch (NSException *exception)" or something
10930 like that. Parse the parameter declaration. */
10931 parm
= c_parser_parameter_declaration (parser
, NULL_TREE
);
10933 parameter_declaration
= error_mark_node
;
10935 parameter_declaration
= grokparm (parm
, NULL
);
10937 if (seen_open_paren
)
10938 parens
.require_close (parser
);
10941 /* If there was no open parenthesis, we are recovering from
10942 an error, and we are trying to figure out what mistake
10943 the user has made. */
10945 /* If there is an immediate closing parenthesis, the user
10946 probably forgot the opening one (ie, they typed "@catch
10947 NSException *e)". Parse the closing parenthesis and keep
10949 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
10950 c_parser_consume_token (parser
);
10952 /* If these is no immediate closing parenthesis, the user
10953 probably doesn't know that parenthesis are required at
10954 all (ie, they typed "@catch NSException *e"). So, just
10955 forget about the closing parenthesis and keep going. */
10957 objc_begin_catch_clause (parameter_declaration
);
10958 if (c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
10959 c_parser_compound_statement_nostart (parser
);
10960 objc_finish_catch_clause ();
10962 if (c_parser_next_token_is_keyword (parser
, RID_AT_FINALLY
))
10964 c_parser_consume_token (parser
);
10965 location
= c_parser_peek_token (parser
)->location
;
10966 stmt
= c_parser_compound_statement (parser
);
10967 objc_build_finally_clause (location
, stmt
);
10969 objc_finish_try_stmt ();
10972 /* Parse an objc-synchronized-statement.
10974 objc-synchronized-statement:
10975 @synchronized ( expression ) compound-statement
10979 c_parser_objc_synchronized_statement (c_parser
*parser
)
10983 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_SYNCHRONIZED
));
10984 c_parser_consume_token (parser
);
10985 loc
= c_parser_peek_token (parser
)->location
;
10986 objc_maybe_warn_exceptions (loc
);
10987 matching_parens parens
;
10988 if (parens
.require_open (parser
))
10990 struct c_expr ce
= c_parser_expression (parser
);
10991 ce
= convert_lvalue_to_rvalue (loc
, ce
, false, false);
10993 expr
= c_fully_fold (expr
, false, NULL
);
10994 parens
.skip_until_found_close (parser
);
10997 expr
= error_mark_node
;
10998 stmt
= c_parser_compound_statement (parser
);
10999 objc_build_synchronized (loc
, expr
, stmt
);
11002 /* Parse an objc-selector; return NULL_TREE without an error if the
11003 next token is not an objc-selector.
11008 enum struct union if else while do for switch case default
11009 break continue return goto asm sizeof typeof __alignof
11010 unsigned long const short volatile signed restrict _Complex
11011 in out inout bycopy byref oneway int char float double void _Bool
11014 ??? Why this selection of keywords but not, for example, storage
11015 class specifiers? */
11018 c_parser_objc_selector (c_parser
*parser
)
11020 c_token
*token
= c_parser_peek_token (parser
);
11021 tree value
= token
->value
;
11022 if (token
->type
== CPP_NAME
)
11024 c_parser_consume_token (parser
);
11027 if (token
->type
!= CPP_KEYWORD
)
11029 switch (token
->keyword
)
11068 CASE_RID_FLOATN_NX
:
11072 case RID_AUTO_TYPE
:
11077 c_parser_consume_token (parser
);
11084 /* Parse an objc-selector-arg.
11088 objc-keywordname-list
11090 objc-keywordname-list:
11092 objc-keywordname-list objc-keywordname
11100 c_parser_objc_selector_arg (c_parser
*parser
)
11102 tree sel
= c_parser_objc_selector (parser
);
11103 tree list
= NULL_TREE
;
11104 if (sel
&& c_parser_next_token_is_not (parser
, CPP_COLON
))
11108 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
11110 list
= chainon (list
, build_tree_list (sel
, NULL_TREE
));
11111 sel
= c_parser_objc_selector (parser
);
11112 if (!sel
&& c_parser_next_token_is_not (parser
, CPP_COLON
))
11118 /* Parse an objc-receiver.
11127 c_parser_objc_receiver (c_parser
*parser
)
11129 location_t loc
= c_parser_peek_token (parser
)->location
;
11131 if (c_parser_peek_token (parser
)->type
== CPP_NAME
11132 && (c_parser_peek_token (parser
)->id_kind
== C_ID_TYPENAME
11133 || c_parser_peek_token (parser
)->id_kind
== C_ID_CLASSNAME
))
11135 tree id
= c_parser_peek_token (parser
)->value
;
11136 c_parser_consume_token (parser
);
11137 return objc_get_class_reference (id
);
11139 struct c_expr ce
= c_parser_expression (parser
);
11140 ce
= convert_lvalue_to_rvalue (loc
, ce
, false, false);
11141 return c_fully_fold (ce
.value
, false, NULL
);
11144 /* Parse objc-message-args.
11148 objc-keywordarg-list
11150 objc-keywordarg-list:
11152 objc-keywordarg-list objc-keywordarg
11155 objc-selector : objc-keywordexpr
11160 c_parser_objc_message_args (c_parser
*parser
)
11162 tree sel
= c_parser_objc_selector (parser
);
11163 tree list
= NULL_TREE
;
11164 if (sel
&& c_parser_next_token_is_not (parser
, CPP_COLON
))
11169 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
11170 return error_mark_node
;
11171 keywordexpr
= c_parser_objc_keywordexpr (parser
);
11172 list
= chainon (list
, build_tree_list (sel
, keywordexpr
));
11173 sel
= c_parser_objc_selector (parser
);
11174 if (!sel
&& c_parser_next_token_is_not (parser
, CPP_COLON
))
11180 /* Parse an objc-keywordexpr.
11187 c_parser_objc_keywordexpr (c_parser
*parser
)
11190 vec
<tree
, va_gc
> *expr_list
= c_parser_expr_list (parser
, true, true,
11191 NULL
, NULL
, NULL
, NULL
);
11192 if (vec_safe_length (expr_list
) == 1)
11194 /* Just return the expression, remove a level of
11196 ret
= (*expr_list
)[0];
11200 /* We have a comma expression, we will collapse later. */
11201 ret
= build_tree_list_vec (expr_list
);
11203 release_tree_vector (expr_list
);
11207 /* A check, needed in several places, that ObjC interface, implementation or
11208 method definitions are not prefixed by incorrect items. */
11210 c_parser_objc_diagnose_bad_element_prefix (c_parser
*parser
,
11211 struct c_declspecs
*specs
)
11213 if (!specs
->declspecs_seen_p
|| specs
->non_sc_seen_p
11214 || specs
->typespec_kind
!= ctsk_none
)
11216 c_parser_error (parser
,
11217 "no type or storage class may be specified here,");
11218 c_parser_skip_to_end_of_block_or_statement (parser
);
11224 /* Parse an Objective-C @property declaration. The syntax is:
11226 objc-property-declaration:
11227 '@property' objc-property-attributes[opt] struct-declaration ;
11229 objc-property-attributes:
11230 '(' objc-property-attribute-list ')'
11232 objc-property-attribute-list:
11233 objc-property-attribute
11234 objc-property-attribute-list, objc-property-attribute
11236 objc-property-attribute
11237 'getter' = identifier
11238 'setter' = identifier
11247 @property NSString *name;
11248 @property (readonly) id object;
11249 @property (retain, nonatomic, getter=getTheName) id name;
11250 @property int a, b, c;
11252 PS: This function is identical to cp_parser_objc_at_propery_declaration
11253 for C++. Keep them in sync. */
11255 c_parser_objc_at_property_declaration (c_parser
*parser
)
11257 /* The following variables hold the attributes of the properties as
11258 parsed. They are 'false' or 'NULL_TREE' if the attribute was not
11259 seen. When we see an attribute, we set them to 'true' (if they
11260 are boolean properties) or to the identifier (if they have an
11261 argument, ie, for getter and setter). Note that here we only
11262 parse the list of attributes, check the syntax and accumulate the
11263 attributes that we find. objc_add_property_declaration() will
11264 then process the information. */
11265 bool property_assign
= false;
11266 bool property_copy
= false;
11267 tree property_getter_ident
= NULL_TREE
;
11268 bool property_nonatomic
= false;
11269 bool property_readonly
= false;
11270 bool property_readwrite
= false;
11271 bool property_retain
= false;
11272 tree property_setter_ident
= NULL_TREE
;
11274 /* 'properties' is the list of properties that we read. Usually a
11275 single one, but maybe more (eg, in "@property int a, b, c;" there
11280 loc
= c_parser_peek_token (parser
)->location
;
11281 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_PROPERTY
));
11283 c_parser_consume_token (parser
); /* Eat '@property'. */
11285 /* Parse the optional attribute list... */
11286 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
11288 matching_parens parens
;
11291 parens
.consume_open (parser
);
11293 /* Property attribute keywords are valid now. */
11294 parser
->objc_property_attr_context
= true;
11298 bool syntax_error
= false;
11299 c_token
*token
= c_parser_peek_token (parser
);
11302 if (token
->type
!= CPP_KEYWORD
)
11304 if (token
->type
== CPP_CLOSE_PAREN
)
11305 c_parser_error (parser
, "expected identifier");
11308 c_parser_consume_token (parser
);
11309 c_parser_error (parser
, "unknown property attribute");
11313 keyword
= token
->keyword
;
11314 c_parser_consume_token (parser
);
11317 case RID_ASSIGN
: property_assign
= true; break;
11318 case RID_COPY
: property_copy
= true; break;
11319 case RID_NONATOMIC
: property_nonatomic
= true; break;
11320 case RID_READONLY
: property_readonly
= true; break;
11321 case RID_READWRITE
: property_readwrite
= true; break;
11322 case RID_RETAIN
: property_retain
= true; break;
11326 if (c_parser_next_token_is_not (parser
, CPP_EQ
))
11328 if (keyword
== RID_GETTER
)
11329 c_parser_error (parser
,
11330 "missing %<=%> (after %<getter%> attribute)");
11332 c_parser_error (parser
,
11333 "missing %<=%> (after %<setter%> attribute)");
11334 syntax_error
= true;
11337 c_parser_consume_token (parser
); /* eat the = */
11338 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11340 c_parser_error (parser
, "expected identifier");
11341 syntax_error
= true;
11344 if (keyword
== RID_SETTER
)
11346 if (property_setter_ident
!= NULL_TREE
)
11347 c_parser_error (parser
, "the %<setter%> attribute may only be specified once");
11349 property_setter_ident
= c_parser_peek_token (parser
)->value
;
11350 c_parser_consume_token (parser
);
11351 if (c_parser_next_token_is_not (parser
, CPP_COLON
))
11352 c_parser_error (parser
, "setter name must terminate with %<:%>");
11354 c_parser_consume_token (parser
);
11358 if (property_getter_ident
!= NULL_TREE
)
11359 c_parser_error (parser
, "the %<getter%> attribute may only be specified once");
11361 property_getter_ident
= c_parser_peek_token (parser
)->value
;
11362 c_parser_consume_token (parser
);
11366 c_parser_error (parser
, "unknown property attribute");
11367 syntax_error
= true;
11374 if (c_parser_next_token_is (parser
, CPP_COMMA
))
11375 c_parser_consume_token (parser
);
11379 parser
->objc_property_attr_context
= false;
11380 parens
.skip_until_found_close (parser
);
11382 /* ... and the property declaration(s). */
11383 properties
= c_parser_struct_declaration (parser
);
11385 if (properties
== error_mark_node
)
11387 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
11388 parser
->error
= false;
11392 if (properties
== NULL_TREE
)
11393 c_parser_error (parser
, "expected identifier");
11396 /* Comma-separated properties are chained together in
11397 reverse order; add them one by one. */
11398 properties
= nreverse (properties
);
11400 for (; properties
; properties
= TREE_CHAIN (properties
))
11401 objc_add_property_declaration (loc
, copy_node (properties
),
11402 property_readonly
, property_readwrite
,
11403 property_assign
, property_retain
,
11404 property_copy
, property_nonatomic
,
11405 property_getter_ident
, property_setter_ident
);
11408 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
11409 parser
->error
= false;
11412 /* Parse an Objective-C @synthesize declaration. The syntax is:
11414 objc-synthesize-declaration:
11415 @synthesize objc-synthesize-identifier-list ;
11417 objc-synthesize-identifier-list:
11418 objc-synthesize-identifier
11419 objc-synthesize-identifier-list, objc-synthesize-identifier
11421 objc-synthesize-identifier
11423 identifier = identifier
11426 @synthesize MyProperty;
11427 @synthesize OneProperty, AnotherProperty=MyIvar, YetAnotherProperty;
11429 PS: This function is identical to cp_parser_objc_at_synthesize_declaration
11430 for C++. Keep them in sync.
11433 c_parser_objc_at_synthesize_declaration (c_parser
*parser
)
11435 tree list
= NULL_TREE
;
11437 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_SYNTHESIZE
));
11438 loc
= c_parser_peek_token (parser
)->location
;
11440 c_parser_consume_token (parser
);
11443 tree property
, ivar
;
11444 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11446 c_parser_error (parser
, "expected identifier");
11447 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
11448 /* Once we find the semicolon, we can resume normal parsing.
11449 We have to reset parser->error manually because
11450 c_parser_skip_until_found() won't reset it for us if the
11451 next token is precisely a semicolon. */
11452 parser
->error
= false;
11455 property
= c_parser_peek_token (parser
)->value
;
11456 c_parser_consume_token (parser
);
11457 if (c_parser_next_token_is (parser
, CPP_EQ
))
11459 c_parser_consume_token (parser
);
11460 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11462 c_parser_error (parser
, "expected identifier");
11463 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
11464 parser
->error
= false;
11467 ivar
= c_parser_peek_token (parser
)->value
;
11468 c_parser_consume_token (parser
);
11472 list
= chainon (list
, build_tree_list (ivar
, property
));
11473 if (c_parser_next_token_is (parser
, CPP_COMMA
))
11474 c_parser_consume_token (parser
);
11478 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
11479 objc_add_synthesize_declaration (loc
, list
);
11482 /* Parse an Objective-C @dynamic declaration. The syntax is:
11484 objc-dynamic-declaration:
11485 @dynamic identifier-list ;
11488 @dynamic MyProperty;
11489 @dynamic MyProperty, AnotherProperty;
11491 PS: This function is identical to cp_parser_objc_at_dynamic_declaration
11492 for C++. Keep them in sync.
11495 c_parser_objc_at_dynamic_declaration (c_parser
*parser
)
11497 tree list
= NULL_TREE
;
11499 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_DYNAMIC
));
11500 loc
= c_parser_peek_token (parser
)->location
;
11502 c_parser_consume_token (parser
);
11506 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11508 c_parser_error (parser
, "expected identifier");
11509 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
11510 parser
->error
= false;
11513 property
= c_parser_peek_token (parser
)->value
;
11514 list
= chainon (list
, build_tree_list (NULL_TREE
, property
));
11515 c_parser_consume_token (parser
);
11516 if (c_parser_next_token_is (parser
, CPP_COMMA
))
11517 c_parser_consume_token (parser
);
11521 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
11522 objc_add_dynamic_declaration (loc
, list
);
11526 /* Parse a pragma GCC ivdep. */
11529 c_parse_pragma_ivdep (c_parser
*parser
)
11531 c_parser_consume_pragma (parser
);
11532 c_parser_skip_to_pragma_eol (parser
);
11536 /* Parse a pragma GCC unroll. */
11538 static unsigned short
11539 c_parser_pragma_unroll (c_parser
*parser
)
11541 unsigned short unroll
;
11542 c_parser_consume_pragma (parser
);
11543 location_t location
= c_parser_peek_token (parser
)->location
;
11544 tree expr
= c_parser_expr_no_commas (parser
, NULL
).value
;
11545 mark_exp_read (expr
);
11546 expr
= c_fully_fold (expr
, false, NULL
);
11547 HOST_WIDE_INT lunroll
= 0;
11548 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr
))
11549 || TREE_CODE (expr
) != INTEGER_CST
11550 || (lunroll
= tree_to_shwi (expr
)) < 0
11551 || lunroll
>= USHRT_MAX
)
11553 error_at (location
, "%<#pragma GCC unroll%> requires an"
11554 " assignment-expression that evaluates to a non-negative"
11555 " integral constant less than %u", USHRT_MAX
);
11560 unroll
= (unsigned short)lunroll
;
11565 c_parser_skip_to_pragma_eol (parser
);
11569 /* Handle pragmas. Some OpenMP pragmas are associated with, and therefore
11570 should be considered, statements. ALLOW_STMT is true if we're within
11571 the context of a function and such pragmas are to be allowed. Returns
11572 true if we actually parsed such a pragma. */
11575 c_parser_pragma (c_parser
*parser
, enum pragma_context context
, bool *if_p
)
11578 const char *construct
= NULL
;
11580 id
= c_parser_peek_token (parser
)->pragma_kind
;
11581 gcc_assert (id
!= PRAGMA_NONE
);
11585 case PRAGMA_OACC_DECLARE
:
11586 c_parser_oacc_declare (parser
);
11589 case PRAGMA_OACC_ENTER_DATA
:
11590 if (context
!= pragma_compound
)
11592 construct
= "acc enter data";
11594 if (context
== pragma_stmt
)
11596 error_at (c_parser_peek_token (parser
)->location
,
11597 "%<#pragma %s%> may only be used in compound "
11598 "statements", construct
);
11599 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
11604 c_parser_oacc_enter_exit_data (parser
, true);
11607 case PRAGMA_OACC_EXIT_DATA
:
11608 if (context
!= pragma_compound
)
11610 construct
= "acc exit data";
11613 c_parser_oacc_enter_exit_data (parser
, false);
11616 case PRAGMA_OACC_ROUTINE
:
11617 if (context
!= pragma_external
)
11619 error_at (c_parser_peek_token (parser
)->location
,
11620 "%<#pragma acc routine%> must be at file scope");
11621 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
11624 c_parser_oacc_routine (parser
, context
);
11627 case PRAGMA_OACC_UPDATE
:
11628 if (context
!= pragma_compound
)
11630 construct
= "acc update";
11633 c_parser_oacc_update (parser
);
11636 case PRAGMA_OMP_BARRIER
:
11637 if (context
!= pragma_compound
)
11639 construct
= "omp barrier";
11642 c_parser_omp_barrier (parser
);
11645 case PRAGMA_OMP_DEPOBJ
:
11646 if (context
!= pragma_compound
)
11648 construct
= "omp depobj";
11651 c_parser_omp_depobj (parser
);
11654 case PRAGMA_OMP_FLUSH
:
11655 if (context
!= pragma_compound
)
11657 construct
= "omp flush";
11660 c_parser_omp_flush (parser
);
11663 case PRAGMA_OMP_TASKWAIT
:
11664 if (context
!= pragma_compound
)
11666 construct
= "omp taskwait";
11669 c_parser_omp_taskwait (parser
);
11672 case PRAGMA_OMP_TASKYIELD
:
11673 if (context
!= pragma_compound
)
11675 construct
= "omp taskyield";
11678 c_parser_omp_taskyield (parser
);
11681 case PRAGMA_OMP_CANCEL
:
11682 if (context
!= pragma_compound
)
11684 construct
= "omp cancel";
11687 c_parser_omp_cancel (parser
);
11690 case PRAGMA_OMP_CANCELLATION_POINT
:
11691 c_parser_omp_cancellation_point (parser
, context
);
11694 case PRAGMA_OMP_THREADPRIVATE
:
11695 c_parser_omp_threadprivate (parser
);
11698 case PRAGMA_OMP_TARGET
:
11699 return c_parser_omp_target (parser
, context
, if_p
);
11701 case PRAGMA_OMP_END_DECLARE_TARGET
:
11702 c_parser_omp_end_declare_target (parser
);
11705 case PRAGMA_OMP_SCAN
:
11706 error_at (c_parser_peek_token (parser
)->location
,
11707 "%<#pragma omp scan%> may only be used in "
11708 "a loop construct with %<inscan%> %<reduction%> clause");
11709 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
11712 case PRAGMA_OMP_SECTION
:
11713 error_at (c_parser_peek_token (parser
)->location
,
11714 "%<#pragma omp section%> may only be used in "
11715 "%<#pragma omp sections%> construct");
11716 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
11719 case PRAGMA_OMP_DECLARE
:
11720 c_parser_omp_declare (parser
, context
);
11723 case PRAGMA_OMP_REQUIRES
:
11724 c_parser_omp_requires (parser
);
11727 case PRAGMA_OMP_ORDERED
:
11728 return c_parser_omp_ordered (parser
, context
, if_p
);
11732 const bool ivdep
= c_parse_pragma_ivdep (parser
);
11733 unsigned short unroll
;
11734 if (c_parser_peek_token (parser
)->pragma_kind
== PRAGMA_UNROLL
)
11735 unroll
= c_parser_pragma_unroll (parser
);
11738 if (!c_parser_next_token_is_keyword (parser
, RID_FOR
)
11739 && !c_parser_next_token_is_keyword (parser
, RID_WHILE
)
11740 && !c_parser_next_token_is_keyword (parser
, RID_DO
))
11742 c_parser_error (parser
, "for, while or do statement expected");
11745 if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
11746 c_parser_for_statement (parser
, ivdep
, unroll
, if_p
);
11747 else if (c_parser_next_token_is_keyword (parser
, RID_WHILE
))
11748 c_parser_while_statement (parser
, ivdep
, unroll
, if_p
);
11750 c_parser_do_statement (parser
, ivdep
, unroll
);
11754 case PRAGMA_UNROLL
:
11756 unsigned short unroll
= c_parser_pragma_unroll (parser
);
11758 if (c_parser_peek_token (parser
)->pragma_kind
== PRAGMA_IVDEP
)
11759 ivdep
= c_parse_pragma_ivdep (parser
);
11762 if (!c_parser_next_token_is_keyword (parser
, RID_FOR
)
11763 && !c_parser_next_token_is_keyword (parser
, RID_WHILE
)
11764 && !c_parser_next_token_is_keyword (parser
, RID_DO
))
11766 c_parser_error (parser
, "for, while or do statement expected");
11769 if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
11770 c_parser_for_statement (parser
, ivdep
, unroll
, if_p
);
11771 else if (c_parser_next_token_is_keyword (parser
, RID_WHILE
))
11772 c_parser_while_statement (parser
, ivdep
, unroll
, if_p
);
11774 c_parser_do_statement (parser
, ivdep
, unroll
);
11778 case PRAGMA_GCC_PCH_PREPROCESS
:
11779 c_parser_error (parser
, "%<#pragma GCC pch_preprocess%> must be first");
11780 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
11783 case PRAGMA_OACC_WAIT
:
11784 if (context
!= pragma_compound
)
11786 construct
= "acc wait";
11789 /* FALL THROUGH. */
11792 if (id
< PRAGMA_FIRST_EXTERNAL
)
11794 if (context
!= pragma_stmt
&& context
!= pragma_compound
)
11797 c_parser_error (parser
, "expected declaration specifiers");
11798 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
11801 c_parser_omp_construct (parser
, if_p
);
11807 c_parser_consume_pragma (parser
);
11808 c_invoke_pragma_handler (id
);
11810 /* Skip to EOL, but suppress any error message. Those will have been
11811 generated by the handler routine through calling error, as opposed
11812 to calling c_parser_error. */
11813 parser
->error
= true;
11814 c_parser_skip_to_pragma_eol (parser
);
11819 /* The interface the pragma parsers have to the lexer. */
11822 pragma_lex (tree
*value
, location_t
*loc
)
11824 c_token
*tok
= c_parser_peek_token (the_parser
);
11825 enum cpp_ttype ret
= tok
->type
;
11827 *value
= tok
->value
;
11829 *loc
= tok
->location
;
11831 if (ret
== CPP_PRAGMA_EOL
|| ret
== CPP_EOF
)
11833 else if (ret
== CPP_STRING
)
11834 *value
= c_parser_string_literal (the_parser
, false, false).value
;
11837 if (ret
== CPP_KEYWORD
)
11839 c_parser_consume_token (the_parser
);
11846 c_parser_pragma_pch_preprocess (c_parser
*parser
)
11850 parser
->lex_joined_string
= true;
11851 c_parser_consume_pragma (parser
);
11852 if (c_parser_next_token_is (parser
, CPP_STRING
))
11854 name
= c_parser_peek_token (parser
)->value
;
11855 c_parser_consume_token (parser
);
11858 c_parser_error (parser
, "expected string literal");
11859 c_parser_skip_to_pragma_eol (parser
);
11860 parser
->lex_joined_string
= false;
11863 c_common_pch_pragma (parse_in
, TREE_STRING_POINTER (name
));
11866 /* OpenACC and OpenMP parsing routines. */
11868 /* Returns name of the next clause.
11869 If the clause is not recognized PRAGMA_OMP_CLAUSE_NONE is returned and
11870 the token is not consumed. Otherwise appropriate pragma_omp_clause is
11871 returned and the token is consumed. */
11873 static pragma_omp_clause
11874 c_parser_omp_clause_name (c_parser
*parser
)
11876 pragma_omp_clause result
= PRAGMA_OMP_CLAUSE_NONE
;
11878 if (c_parser_next_token_is_keyword (parser
, RID_AUTO
))
11879 result
= PRAGMA_OACC_CLAUSE_AUTO
;
11880 else if (c_parser_next_token_is_keyword (parser
, RID_IF
))
11881 result
= PRAGMA_OMP_CLAUSE_IF
;
11882 else if (c_parser_next_token_is_keyword (parser
, RID_DEFAULT
))
11883 result
= PRAGMA_OMP_CLAUSE_DEFAULT
;
11884 else if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
11885 result
= PRAGMA_OMP_CLAUSE_FOR
;
11886 else if (c_parser_next_token_is (parser
, CPP_NAME
))
11888 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
11893 if (!strcmp ("aligned", p
))
11894 result
= PRAGMA_OMP_CLAUSE_ALIGNED
;
11895 else if (!strcmp ("async", p
))
11896 result
= PRAGMA_OACC_CLAUSE_ASYNC
;
11899 if (!strcmp ("bind", p
))
11900 result
= PRAGMA_OMP_CLAUSE_BIND
;
11903 if (!strcmp ("collapse", p
))
11904 result
= PRAGMA_OMP_CLAUSE_COLLAPSE
;
11905 else if (!strcmp ("copy", p
))
11906 result
= PRAGMA_OACC_CLAUSE_COPY
;
11907 else if (!strcmp ("copyin", p
))
11908 result
= PRAGMA_OMP_CLAUSE_COPYIN
;
11909 else if (!strcmp ("copyout", p
))
11910 result
= PRAGMA_OACC_CLAUSE_COPYOUT
;
11911 else if (!strcmp ("copyprivate", p
))
11912 result
= PRAGMA_OMP_CLAUSE_COPYPRIVATE
;
11913 else if (!strcmp ("create", p
))
11914 result
= PRAGMA_OACC_CLAUSE_CREATE
;
11917 if (!strcmp ("defaultmap", p
))
11918 result
= PRAGMA_OMP_CLAUSE_DEFAULTMAP
;
11919 else if (!strcmp ("delete", p
))
11920 result
= PRAGMA_OACC_CLAUSE_DELETE
;
11921 else if (!strcmp ("depend", p
))
11922 result
= PRAGMA_OMP_CLAUSE_DEPEND
;
11923 else if (!strcmp ("device", p
))
11924 result
= PRAGMA_OMP_CLAUSE_DEVICE
;
11925 else if (!strcmp ("deviceptr", p
))
11926 result
= PRAGMA_OACC_CLAUSE_DEVICEPTR
;
11927 else if (!strcmp ("device_resident", p
))
11928 result
= PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT
;
11929 else if (!strcmp ("device_type", p
))
11930 result
= PRAGMA_OMP_CLAUSE_DEVICE_TYPE
;
11931 else if (!strcmp ("dist_schedule", p
))
11932 result
= PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
;
11935 if (!strcmp ("final", p
))
11936 result
= PRAGMA_OMP_CLAUSE_FINAL
;
11937 else if (!strcmp ("finalize", p
))
11938 result
= PRAGMA_OACC_CLAUSE_FINALIZE
;
11939 else if (!strcmp ("firstprivate", p
))
11940 result
= PRAGMA_OMP_CLAUSE_FIRSTPRIVATE
;
11941 else if (!strcmp ("from", p
))
11942 result
= PRAGMA_OMP_CLAUSE_FROM
;
11945 if (!strcmp ("gang", p
))
11946 result
= PRAGMA_OACC_CLAUSE_GANG
;
11947 else if (!strcmp ("grainsize", p
))
11948 result
= PRAGMA_OMP_CLAUSE_GRAINSIZE
;
11951 if (!strcmp ("hint", p
))
11952 result
= PRAGMA_OMP_CLAUSE_HINT
;
11953 else if (!strcmp ("host", p
))
11954 result
= PRAGMA_OACC_CLAUSE_HOST
;
11957 if (!strcmp ("if_present", p
))
11958 result
= PRAGMA_OACC_CLAUSE_IF_PRESENT
;
11959 else if (!strcmp ("in_reduction", p
))
11960 result
= PRAGMA_OMP_CLAUSE_IN_REDUCTION
;
11961 else if (!strcmp ("inbranch", p
))
11962 result
= PRAGMA_OMP_CLAUSE_INBRANCH
;
11963 else if (!strcmp ("independent", p
))
11964 result
= PRAGMA_OACC_CLAUSE_INDEPENDENT
;
11965 else if (!strcmp ("is_device_ptr", p
))
11966 result
= PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR
;
11969 if (!strcmp ("lastprivate", p
))
11970 result
= PRAGMA_OMP_CLAUSE_LASTPRIVATE
;
11971 else if (!strcmp ("linear", p
))
11972 result
= PRAGMA_OMP_CLAUSE_LINEAR
;
11973 else if (!strcmp ("link", p
))
11974 result
= PRAGMA_OMP_CLAUSE_LINK
;
11977 if (!strcmp ("map", p
))
11978 result
= PRAGMA_OMP_CLAUSE_MAP
;
11979 else if (!strcmp ("mergeable", p
))
11980 result
= PRAGMA_OMP_CLAUSE_MERGEABLE
;
11983 if (!strcmp ("nogroup", p
))
11984 result
= PRAGMA_OMP_CLAUSE_NOGROUP
;
11985 else if (!strcmp ("nontemporal", p
))
11986 result
= PRAGMA_OMP_CLAUSE_NONTEMPORAL
;
11987 else if (!strcmp ("notinbranch", p
))
11988 result
= PRAGMA_OMP_CLAUSE_NOTINBRANCH
;
11989 else if (!strcmp ("nowait", p
))
11990 result
= PRAGMA_OMP_CLAUSE_NOWAIT
;
11991 else if (!strcmp ("num_gangs", p
))
11992 result
= PRAGMA_OACC_CLAUSE_NUM_GANGS
;
11993 else if (!strcmp ("num_tasks", p
))
11994 result
= PRAGMA_OMP_CLAUSE_NUM_TASKS
;
11995 else if (!strcmp ("num_teams", p
))
11996 result
= PRAGMA_OMP_CLAUSE_NUM_TEAMS
;
11997 else if (!strcmp ("num_threads", p
))
11998 result
= PRAGMA_OMP_CLAUSE_NUM_THREADS
;
11999 else if (!strcmp ("num_workers", p
))
12000 result
= PRAGMA_OACC_CLAUSE_NUM_WORKERS
;
12003 if (!strcmp ("ordered", p
))
12004 result
= PRAGMA_OMP_CLAUSE_ORDERED
;
12005 else if (!strcmp ("order", p
))
12006 result
= PRAGMA_OMP_CLAUSE_ORDER
;
12009 if (!strcmp ("parallel", p
))
12010 result
= PRAGMA_OMP_CLAUSE_PARALLEL
;
12011 else if (!strcmp ("present", p
))
12012 result
= PRAGMA_OACC_CLAUSE_PRESENT
;
12013 /* As of OpenACC 2.5, these are now aliases of the non-present_or
12015 else if (!strcmp ("present_or_copy", p
)
12016 || !strcmp ("pcopy", p
))
12017 result
= PRAGMA_OACC_CLAUSE_COPY
;
12018 else if (!strcmp ("present_or_copyin", p
)
12019 || !strcmp ("pcopyin", p
))
12020 result
= PRAGMA_OACC_CLAUSE_COPYIN
;
12021 else if (!strcmp ("present_or_copyout", p
)
12022 || !strcmp ("pcopyout", p
))
12023 result
= PRAGMA_OACC_CLAUSE_COPYOUT
;
12024 else if (!strcmp ("present_or_create", p
)
12025 || !strcmp ("pcreate", p
))
12026 result
= PRAGMA_OACC_CLAUSE_CREATE
;
12027 else if (!strcmp ("priority", p
))
12028 result
= PRAGMA_OMP_CLAUSE_PRIORITY
;
12029 else if (!strcmp ("private", p
))
12030 result
= PRAGMA_OMP_CLAUSE_PRIVATE
;
12031 else if (!strcmp ("proc_bind", p
))
12032 result
= PRAGMA_OMP_CLAUSE_PROC_BIND
;
12035 if (!strcmp ("reduction", p
))
12036 result
= PRAGMA_OMP_CLAUSE_REDUCTION
;
12039 if (!strcmp ("safelen", p
))
12040 result
= PRAGMA_OMP_CLAUSE_SAFELEN
;
12041 else if (!strcmp ("schedule", p
))
12042 result
= PRAGMA_OMP_CLAUSE_SCHEDULE
;
12043 else if (!strcmp ("sections", p
))
12044 result
= PRAGMA_OMP_CLAUSE_SECTIONS
;
12045 else if (!strcmp ("self", p
)) /* "self" is a synonym for "host". */
12046 result
= PRAGMA_OACC_CLAUSE_HOST
;
12047 else if (!strcmp ("seq", p
))
12048 result
= PRAGMA_OACC_CLAUSE_SEQ
;
12049 else if (!strcmp ("shared", p
))
12050 result
= PRAGMA_OMP_CLAUSE_SHARED
;
12051 else if (!strcmp ("simd", p
))
12052 result
= PRAGMA_OMP_CLAUSE_SIMD
;
12053 else if (!strcmp ("simdlen", p
))
12054 result
= PRAGMA_OMP_CLAUSE_SIMDLEN
;
12057 if (!strcmp ("task_reduction", p
))
12058 result
= PRAGMA_OMP_CLAUSE_TASK_REDUCTION
;
12059 else if (!strcmp ("taskgroup", p
))
12060 result
= PRAGMA_OMP_CLAUSE_TASKGROUP
;
12061 else if (!strcmp ("thread_limit", p
))
12062 result
= PRAGMA_OMP_CLAUSE_THREAD_LIMIT
;
12063 else if (!strcmp ("threads", p
))
12064 result
= PRAGMA_OMP_CLAUSE_THREADS
;
12065 else if (!strcmp ("tile", p
))
12066 result
= PRAGMA_OACC_CLAUSE_TILE
;
12067 else if (!strcmp ("to", p
))
12068 result
= PRAGMA_OMP_CLAUSE_TO
;
12071 if (!strcmp ("uniform", p
))
12072 result
= PRAGMA_OMP_CLAUSE_UNIFORM
;
12073 else if (!strcmp ("untied", p
))
12074 result
= PRAGMA_OMP_CLAUSE_UNTIED
;
12075 else if (!strcmp ("use_device", p
))
12076 result
= PRAGMA_OACC_CLAUSE_USE_DEVICE
;
12077 else if (!strcmp ("use_device_addr", p
))
12078 result
= PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR
;
12079 else if (!strcmp ("use_device_ptr", p
))
12080 result
= PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR
;
12083 if (!strcmp ("vector", p
))
12084 result
= PRAGMA_OACC_CLAUSE_VECTOR
;
12085 else if (!strcmp ("vector_length", p
))
12086 result
= PRAGMA_OACC_CLAUSE_VECTOR_LENGTH
;
12089 if (!strcmp ("wait", p
))
12090 result
= PRAGMA_OACC_CLAUSE_WAIT
;
12091 else if (!strcmp ("worker", p
))
12092 result
= PRAGMA_OACC_CLAUSE_WORKER
;
12097 if (result
!= PRAGMA_OMP_CLAUSE_NONE
)
12098 c_parser_consume_token (parser
);
12103 /* Validate that a clause of the given type does not already exist. */
12106 check_no_duplicate_clause (tree clauses
, enum omp_clause_code code
,
12109 if (tree c
= omp_find_clause (clauses
, code
))
12110 error_at (OMP_CLAUSE_LOCATION (c
), "too many %qs clauses", name
);
12114 Parse wait clause or wait directive parameters. */
12117 c_parser_oacc_wait_list (c_parser
*parser
, location_t clause_loc
, tree list
)
12119 vec
<tree
, va_gc
> *args
;
12122 matching_parens parens
;
12123 if (!parens
.require_open (parser
))
12126 args
= c_parser_expr_list (parser
, false, true, NULL
, NULL
, NULL
, NULL
);
12127 args_tree
= build_tree_list_vec (args
);
12129 for (t
= args_tree
; t
; t
= TREE_CHAIN (t
))
12131 tree targ
= TREE_VALUE (t
);
12133 if (targ
!= error_mark_node
)
12135 if (!INTEGRAL_TYPE_P (TREE_TYPE (targ
)))
12137 c_parser_error (parser
, "expression must be integral");
12138 targ
= error_mark_node
;
12142 tree c
= build_omp_clause (clause_loc
, OMP_CLAUSE_WAIT
);
12144 OMP_CLAUSE_DECL (c
) = targ
;
12145 OMP_CLAUSE_CHAIN (c
) = list
;
12151 release_tree_vector (args
);
12152 parens
.require_close (parser
);
12156 /* OpenACC 2.0, OpenMP 2.5:
12159 variable-list , identifier
12161 If KIND is nonzero, create the appropriate node and install the
12162 decl in OMP_CLAUSE_DECL and add the node to the head of the list.
12163 If KIND is nonzero, CLAUSE_LOC is the location of the clause.
12165 If KIND is zero, create a TREE_LIST with the decl in TREE_PURPOSE;
12166 return the list created. */
12169 c_parser_omp_variable_list (c_parser
*parser
,
12170 location_t clause_loc
,
12171 enum omp_clause_code kind
, tree list
)
12173 auto_vec
<c_token
> tokens
;
12174 unsigned int tokens_avail
= 0;
12179 bool array_section_p
= false;
12180 if (kind
== OMP_CLAUSE_DEPEND
)
12182 if (c_parser_next_token_is_not (parser
, CPP_NAME
)
12183 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
12185 struct c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
12186 if (expr
.value
!= error_mark_node
)
12188 tree u
= build_omp_clause (clause_loc
, kind
);
12189 OMP_CLAUSE_DECL (u
) = expr
.value
;
12190 OMP_CLAUSE_CHAIN (u
) = list
;
12194 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
12197 c_parser_consume_token (parser
);
12202 tokens
.truncate (0);
12203 unsigned int nesting_depth
= 0;
12206 c_token
*token
= c_parser_peek_token (parser
);
12207 switch (token
->type
)
12210 case CPP_PRAGMA_EOL
:
12212 case CPP_OPEN_BRACE
:
12213 case CPP_OPEN_PAREN
:
12214 case CPP_OPEN_SQUARE
:
12217 case CPP_CLOSE_BRACE
:
12218 case CPP_CLOSE_PAREN
:
12219 case CPP_CLOSE_SQUARE
:
12220 if (nesting_depth
-- == 0)
12224 if (nesting_depth
== 0)
12229 tokens
.safe_push (*token
);
12230 c_parser_consume_token (parser
);
12236 /* Make sure nothing tries to read past the end of the tokens. */
12238 memset (&eof_token
, 0, sizeof (eof_token
));
12239 eof_token
.type
= CPP_EOF
;
12240 tokens
.safe_push (eof_token
);
12241 tokens
.safe_push (eof_token
);
12243 tokens_avail
= parser
->tokens_avail
;
12244 gcc_assert (parser
->tokens
== &parser
->tokens_buf
[0]);
12245 parser
->tokens
= tokens
.address ();
12246 parser
->tokens_avail
= tokens
.length ();
12249 tree t
= NULL_TREE
;
12251 if (c_parser_next_token_is (parser
, CPP_NAME
)
12252 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
)
12254 t
= lookup_name (c_parser_peek_token (parser
)->value
);
12256 if (t
== NULL_TREE
)
12258 undeclared_variable (c_parser_peek_token (parser
)->location
,
12259 c_parser_peek_token (parser
)->value
);
12260 t
= error_mark_node
;
12263 c_parser_consume_token (parser
);
12265 else if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
12266 && (c_parser_peek_token (parser
)->keyword
== RID_FUNCTION_NAME
12267 || (c_parser_peek_token (parser
)->keyword
12268 == RID_PRETTY_FUNCTION_NAME
)
12269 || (c_parser_peek_token (parser
)->keyword
12270 == RID_C99_FUNCTION_NAME
)))
12271 t
= c_parser_predefined_identifier (parser
).value
;
12275 c_parser_error (parser
, "expected identifier");
12279 if (t
== error_mark_node
)
12281 else if (kind
!= 0)
12285 case OMP_CLAUSE__CACHE_
:
12286 /* The OpenACC cache directive explicitly only allows "array
12287 elements or subarrays". */
12288 if (c_parser_peek_token (parser
)->type
!= CPP_OPEN_SQUARE
)
12290 c_parser_error (parser
, "expected %<[%>");
12291 t
= error_mark_node
;
12295 case OMP_CLAUSE_MAP
:
12296 case OMP_CLAUSE_FROM
:
12297 case OMP_CLAUSE_TO
:
12298 while (c_parser_next_token_is (parser
, CPP_DOT
))
12300 location_t op_loc
= c_parser_peek_token (parser
)->location
;
12301 c_parser_consume_token (parser
);
12302 if (!c_parser_next_token_is (parser
, CPP_NAME
))
12304 c_parser_error (parser
, "expected identifier");
12305 t
= error_mark_node
;
12309 c_token
*comp_tok
= c_parser_peek_token (parser
);
12310 tree ident
= comp_tok
->value
;
12311 location_t comp_loc
= comp_tok
->location
;
12312 c_parser_consume_token (parser
);
12313 t
= build_component_ref (op_loc
, t
, ident
, comp_loc
);
12316 case OMP_CLAUSE_DEPEND
:
12317 case OMP_CLAUSE_REDUCTION
:
12318 case OMP_CLAUSE_IN_REDUCTION
:
12319 case OMP_CLAUSE_TASK_REDUCTION
:
12320 while (c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
))
12322 tree low_bound
= NULL_TREE
, length
= NULL_TREE
;
12324 c_parser_consume_token (parser
);
12325 if (!c_parser_next_token_is (parser
, CPP_COLON
))
12327 location_t expr_loc
12328 = c_parser_peek_token (parser
)->location
;
12329 c_expr expr
= c_parser_expression (parser
);
12330 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
,
12332 low_bound
= expr
.value
;
12334 if (c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
12335 length
= integer_one_node
;
12338 /* Look for `:'. */
12339 if (!c_parser_require (parser
, CPP_COLON
,
12342 t
= error_mark_node
;
12345 array_section_p
= true;
12346 if (!c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
12348 location_t expr_loc
12349 = c_parser_peek_token (parser
)->location
;
12350 c_expr expr
= c_parser_expression (parser
);
12351 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
,
12353 length
= expr
.value
;
12356 /* Look for the closing `]'. */
12357 if (!c_parser_require (parser
, CPP_CLOSE_SQUARE
,
12360 t
= error_mark_node
;
12364 t
= tree_cons (low_bound
, length
, t
);
12366 if (kind
== OMP_CLAUSE_DEPEND
12367 && t
!= error_mark_node
12368 && parser
->tokens_avail
!= 2)
12370 if (array_section_p
)
12372 error_at (c_parser_peek_token (parser
)->location
,
12373 "expected %<)%> or %<,%>");
12374 t
= error_mark_node
;
12378 parser
->tokens
= tokens
.address ();
12379 parser
->tokens_avail
= tokens
.length ();
12381 t
= c_parser_expr_no_commas (parser
, NULL
).value
;
12382 if (t
!= error_mark_node
&& parser
->tokens_avail
!= 2)
12384 error_at (c_parser_peek_token (parser
)->location
,
12385 "expected %<)%> or %<,%>");
12386 t
= error_mark_node
;
12395 if (t
!= error_mark_node
)
12397 tree u
= build_omp_clause (clause_loc
, kind
);
12398 OMP_CLAUSE_DECL (u
) = t
;
12399 OMP_CLAUSE_CHAIN (u
) = list
;
12404 list
= tree_cons (t
, NULL_TREE
, list
);
12406 if (kind
== OMP_CLAUSE_DEPEND
)
12408 parser
->tokens
= &parser
->tokens_buf
[0];
12409 parser
->tokens_avail
= tokens_avail
;
12411 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
12414 c_parser_consume_token (parser
);
12421 /* Similarly, but expect leading and trailing parenthesis. This is a very
12422 common case for OpenACC and OpenMP clauses. */
12425 c_parser_omp_var_list_parens (c_parser
*parser
, enum omp_clause_code kind
,
12428 /* The clauses location. */
12429 location_t loc
= c_parser_peek_token (parser
)->location
;
12431 matching_parens parens
;
12432 if (parens
.require_open (parser
))
12434 list
= c_parser_omp_variable_list (parser
, loc
, kind
, list
);
12435 parens
.skip_until_found_close (parser
);
12441 copy ( variable-list )
12442 copyin ( variable-list )
12443 copyout ( variable-list )
12444 create ( variable-list )
12445 delete ( variable-list )
12446 present ( variable-list ) */
12449 c_parser_oacc_data_clause (c_parser
*parser
, pragma_omp_clause c_kind
,
12452 enum gomp_map_kind kind
;
12455 case PRAGMA_OACC_CLAUSE_COPY
:
12456 kind
= GOMP_MAP_TOFROM
;
12458 case PRAGMA_OACC_CLAUSE_COPYIN
:
12459 kind
= GOMP_MAP_TO
;
12461 case PRAGMA_OACC_CLAUSE_COPYOUT
:
12462 kind
= GOMP_MAP_FROM
;
12464 case PRAGMA_OACC_CLAUSE_CREATE
:
12465 kind
= GOMP_MAP_ALLOC
;
12467 case PRAGMA_OACC_CLAUSE_DELETE
:
12468 kind
= GOMP_MAP_RELEASE
;
12470 case PRAGMA_OACC_CLAUSE_DEVICE
:
12471 kind
= GOMP_MAP_FORCE_TO
;
12473 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT
:
12474 kind
= GOMP_MAP_DEVICE_RESIDENT
;
12476 case PRAGMA_OACC_CLAUSE_HOST
:
12477 kind
= GOMP_MAP_FORCE_FROM
;
12479 case PRAGMA_OACC_CLAUSE_LINK
:
12480 kind
= GOMP_MAP_LINK
;
12482 case PRAGMA_OACC_CLAUSE_PRESENT
:
12483 kind
= GOMP_MAP_FORCE_PRESENT
;
12486 gcc_unreachable ();
12489 nl
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_MAP
, list
);
12491 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
12492 OMP_CLAUSE_SET_MAP_KIND (c
, kind
);
12498 deviceptr ( variable-list ) */
12501 c_parser_oacc_data_clause_deviceptr (c_parser
*parser
, tree list
)
12503 location_t loc
= c_parser_peek_token (parser
)->location
;
12506 /* Can't use OMP_CLAUSE_MAP here (that is, can't use the generic
12507 c_parser_oacc_data_clause), as for PRAGMA_OACC_CLAUSE_DEVICEPTR,
12508 variable-list must only allow for pointer variables. */
12509 vars
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ERROR
, NULL
);
12510 for (t
= vars
; t
&& t
; t
= TREE_CHAIN (t
))
12512 tree v
= TREE_PURPOSE (t
);
12514 /* FIXME diagnostics: Ideally we should keep individual
12515 locations for all the variables in the var list to make the
12516 following errors more precise. Perhaps
12517 c_parser_omp_var_list_parens() should construct a list of
12518 locations to go along with the var list. */
12520 if (!VAR_P (v
) && TREE_CODE (v
) != PARM_DECL
)
12521 error_at (loc
, "%qD is not a variable", v
);
12522 else if (TREE_TYPE (v
) == error_mark_node
)
12524 else if (!POINTER_TYPE_P (TREE_TYPE (v
)))
12525 error_at (loc
, "%qD is not a pointer variable", v
);
12527 tree u
= build_omp_clause (loc
, OMP_CLAUSE_MAP
);
12528 OMP_CLAUSE_SET_MAP_KIND (u
, GOMP_MAP_FORCE_DEVICEPTR
);
12529 OMP_CLAUSE_DECL (u
) = v
;
12530 OMP_CLAUSE_CHAIN (u
) = list
;
12537 /* OpenACC 2.0, OpenMP 3.0:
12538 collapse ( constant-expression ) */
12541 c_parser_omp_clause_collapse (c_parser
*parser
, tree list
)
12543 tree c
, num
= error_mark_node
;
12547 check_no_duplicate_clause (list
, OMP_CLAUSE_COLLAPSE
, "collapse");
12548 check_no_duplicate_clause (list
, OMP_CLAUSE_TILE
, "tile");
12550 loc
= c_parser_peek_token (parser
)->location
;
12551 matching_parens parens
;
12552 if (parens
.require_open (parser
))
12554 num
= c_parser_expr_no_commas (parser
, NULL
).value
;
12555 parens
.skip_until_found_close (parser
);
12557 if (num
== error_mark_node
)
12559 mark_exp_read (num
);
12560 num
= c_fully_fold (num
, false, NULL
);
12561 if (!INTEGRAL_TYPE_P (TREE_TYPE (num
))
12562 || !tree_fits_shwi_p (num
)
12563 || (n
= tree_to_shwi (num
)) <= 0
12567 "collapse argument needs positive constant integer expression");
12570 c
= build_omp_clause (loc
, OMP_CLAUSE_COLLAPSE
);
12571 OMP_CLAUSE_COLLAPSE_EXPR (c
) = num
;
12572 OMP_CLAUSE_CHAIN (c
) = list
;
12577 copyin ( variable-list ) */
12580 c_parser_omp_clause_copyin (c_parser
*parser
, tree list
)
12582 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_COPYIN
, list
);
12586 copyprivate ( variable-list ) */
12589 c_parser_omp_clause_copyprivate (c_parser
*parser
, tree list
)
12591 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_COPYPRIVATE
, list
);
12595 default ( none | shared )
12598 default ( none | present ) */
12601 c_parser_omp_clause_default (c_parser
*parser
, tree list
, bool is_oacc
)
12603 enum omp_clause_default_kind kind
= OMP_CLAUSE_DEFAULT_UNSPECIFIED
;
12604 location_t loc
= c_parser_peek_token (parser
)->location
;
12607 matching_parens parens
;
12608 if (!parens
.require_open (parser
))
12610 if (c_parser_next_token_is (parser
, CPP_NAME
))
12612 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
12617 if (strcmp ("none", p
) != 0)
12619 kind
= OMP_CLAUSE_DEFAULT_NONE
;
12623 if (strcmp ("present", p
) != 0 || !is_oacc
)
12625 kind
= OMP_CLAUSE_DEFAULT_PRESENT
;
12629 if (strcmp ("shared", p
) != 0 || is_oacc
)
12631 kind
= OMP_CLAUSE_DEFAULT_SHARED
;
12638 c_parser_consume_token (parser
);
12644 c_parser_error (parser
, "expected %<none%> or %<present%>");
12646 c_parser_error (parser
, "expected %<none%> or %<shared%>");
12648 parens
.skip_until_found_close (parser
);
12650 if (kind
== OMP_CLAUSE_DEFAULT_UNSPECIFIED
)
12653 check_no_duplicate_clause (list
, OMP_CLAUSE_DEFAULT
, "default");
12654 c
= build_omp_clause (loc
, OMP_CLAUSE_DEFAULT
);
12655 OMP_CLAUSE_CHAIN (c
) = list
;
12656 OMP_CLAUSE_DEFAULT_KIND (c
) = kind
;
12662 firstprivate ( variable-list ) */
12665 c_parser_omp_clause_firstprivate (c_parser
*parser
, tree list
)
12667 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_FIRSTPRIVATE
, list
);
12671 final ( expression ) */
12674 c_parser_omp_clause_final (c_parser
*parser
, tree list
)
12676 location_t loc
= c_parser_peek_token (parser
)->location
;
12677 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
12679 matching_parens parens
;
12681 if (!parens
.require_open (parser
))
12682 t
= error_mark_node
;
12685 location_t eloc
= c_parser_peek_token (parser
)->location
;
12686 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
12687 t
= convert_lvalue_to_rvalue (eloc
, expr
, true, true).value
;
12688 t
= c_objc_common_truthvalue_conversion (eloc
, t
);
12689 t
= c_fully_fold (t
, false, NULL
);
12690 parens
.skip_until_found_close (parser
);
12693 check_no_duplicate_clause (list
, OMP_CLAUSE_FINAL
, "final");
12695 c
= build_omp_clause (loc
, OMP_CLAUSE_FINAL
);
12696 OMP_CLAUSE_FINAL_EXPR (c
) = t
;
12697 OMP_CLAUSE_CHAIN (c
) = list
;
12701 c_parser_error (parser
, "expected %<(%>");
12706 /* OpenACC, OpenMP 2.5:
12710 if ( directive-name-modifier : expression )
12712 directive-name-modifier:
12713 parallel | task | taskloop | target data | target | target update
12714 | target enter data | target exit data
12717 directive-name-modifier:
12718 ... | simd | cancel */
12721 c_parser_omp_clause_if (c_parser
*parser
, tree list
, bool is_omp
)
12723 location_t location
= c_parser_peek_token (parser
)->location
;
12724 enum tree_code if_modifier
= ERROR_MARK
;
12726 matching_parens parens
;
12727 if (!parens
.require_open (parser
))
12730 if (is_omp
&& c_parser_next_token_is (parser
, CPP_NAME
))
12732 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
12734 if (strcmp (p
, "cancel") == 0)
12735 if_modifier
= VOID_CST
;
12736 else if (strcmp (p
, "parallel") == 0)
12737 if_modifier
= OMP_PARALLEL
;
12738 else if (strcmp (p
, "simd") == 0)
12739 if_modifier
= OMP_SIMD
;
12740 else if (strcmp (p
, "task") == 0)
12741 if_modifier
= OMP_TASK
;
12742 else if (strcmp (p
, "taskloop") == 0)
12743 if_modifier
= OMP_TASKLOOP
;
12744 else if (strcmp (p
, "target") == 0)
12746 if_modifier
= OMP_TARGET
;
12747 if (c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
12749 p
= IDENTIFIER_POINTER (c_parser_peek_2nd_token (parser
)->value
);
12750 if (strcmp ("data", p
) == 0)
12751 if_modifier
= OMP_TARGET_DATA
;
12752 else if (strcmp ("update", p
) == 0)
12753 if_modifier
= OMP_TARGET_UPDATE
;
12754 else if (strcmp ("enter", p
) == 0)
12755 if_modifier
= OMP_TARGET_ENTER_DATA
;
12756 else if (strcmp ("exit", p
) == 0)
12757 if_modifier
= OMP_TARGET_EXIT_DATA
;
12758 if (if_modifier
!= OMP_TARGET
)
12761 c_parser_consume_token (parser
);
12765 location_t loc
= c_parser_peek_2nd_token (parser
)->location
;
12766 error_at (loc
, "expected %<data%>, %<update%>, %<enter%> "
12768 if_modifier
= ERROR_MARK
;
12770 if (if_modifier
== OMP_TARGET_ENTER_DATA
12771 || if_modifier
== OMP_TARGET_EXIT_DATA
)
12773 if (c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
12775 p
= IDENTIFIER_POINTER
12776 (c_parser_peek_2nd_token (parser
)->value
);
12777 if (strcmp ("data", p
) == 0)
12781 c_parser_consume_token (parser
);
12785 = c_parser_peek_2nd_token (parser
)->location
;
12786 error_at (loc
, "expected %<data%>");
12787 if_modifier
= ERROR_MARK
;
12792 if (if_modifier
!= ERROR_MARK
)
12794 if (c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
12796 c_parser_consume_token (parser
);
12797 c_parser_consume_token (parser
);
12803 location_t loc
= c_parser_peek_2nd_token (parser
)->location
;
12804 error_at (loc
, "expected %<:%>");
12806 if_modifier
= ERROR_MARK
;
12811 location_t loc
= c_parser_peek_token (parser
)->location
;
12812 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
12813 expr
= convert_lvalue_to_rvalue (loc
, expr
, true, true);
12814 tree t
= c_objc_common_truthvalue_conversion (loc
, expr
.value
), c
;
12815 t
= c_fully_fold (t
, false, NULL
);
12816 parens
.skip_until_found_close (parser
);
12818 for (c
= list
; c
; c
= OMP_CLAUSE_CHAIN (c
))
12819 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_IF
)
12821 if (if_modifier
!= ERROR_MARK
12822 && OMP_CLAUSE_IF_MODIFIER (c
) == if_modifier
)
12824 const char *p
= NULL
;
12825 switch (if_modifier
)
12827 case VOID_CST
: p
= "cancel"; break;
12828 case OMP_PARALLEL
: p
= "parallel"; break;
12829 case OMP_SIMD
: p
= "simd"; break;
12830 case OMP_TASK
: p
= "task"; break;
12831 case OMP_TASKLOOP
: p
= "taskloop"; break;
12832 case OMP_TARGET_DATA
: p
= "target data"; break;
12833 case OMP_TARGET
: p
= "target"; break;
12834 case OMP_TARGET_UPDATE
: p
= "target update"; break;
12835 case OMP_TARGET_ENTER_DATA
: p
= "target enter data"; break;
12836 case OMP_TARGET_EXIT_DATA
: p
= "target exit data"; break;
12837 default: gcc_unreachable ();
12839 error_at (location
, "too many %<if%> clauses with %qs modifier",
12843 else if (OMP_CLAUSE_IF_MODIFIER (c
) == if_modifier
)
12846 error_at (location
, "too many %<if%> clauses");
12848 error_at (location
, "too many %<if%> clauses without modifier");
12851 else if (if_modifier
== ERROR_MARK
12852 || OMP_CLAUSE_IF_MODIFIER (c
) == ERROR_MARK
)
12854 error_at (location
, "if any %<if%> clause has modifier, then all "
12855 "%<if%> clauses have to use modifier");
12860 c
= build_omp_clause (location
, OMP_CLAUSE_IF
);
12861 OMP_CLAUSE_IF_MODIFIER (c
) = if_modifier
;
12862 OMP_CLAUSE_IF_EXPR (c
) = t
;
12863 OMP_CLAUSE_CHAIN (c
) = list
;
12868 lastprivate ( variable-list )
12871 lastprivate ( [ lastprivate-modifier : ] variable-list ) */
12874 c_parser_omp_clause_lastprivate (c_parser
*parser
, tree list
)
12876 /* The clauses location. */
12877 location_t loc
= c_parser_peek_token (parser
)->location
;
12879 if (c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
12881 bool conditional
= false;
12882 if (c_parser_next_token_is (parser
, CPP_NAME
)
12883 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
12886 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
12887 if (strcmp (p
, "conditional") == 0)
12889 conditional
= true;
12890 c_parser_consume_token (parser
);
12891 c_parser_consume_token (parser
);
12894 tree nlist
= c_parser_omp_variable_list (parser
, loc
,
12895 OMP_CLAUSE_LASTPRIVATE
, list
);
12896 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, "expected %<)%>");
12898 for (tree c
= nlist
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
12899 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
) = 1;
12909 c_parser_omp_clause_mergeable (c_parser
*parser ATTRIBUTE_UNUSED
, tree list
)
12913 /* FIXME: Should we allow duplicates? */
12914 check_no_duplicate_clause (list
, OMP_CLAUSE_MERGEABLE
, "mergeable");
12916 c
= build_omp_clause (c_parser_peek_token (parser
)->location
,
12917 OMP_CLAUSE_MERGEABLE
);
12918 OMP_CLAUSE_CHAIN (c
) = list
;
12927 c_parser_omp_clause_nowait (c_parser
*parser ATTRIBUTE_UNUSED
, tree list
)
12930 location_t loc
= c_parser_peek_token (parser
)->location
;
12932 check_no_duplicate_clause (list
, OMP_CLAUSE_NOWAIT
, "nowait");
12934 c
= build_omp_clause (loc
, OMP_CLAUSE_NOWAIT
);
12935 OMP_CLAUSE_CHAIN (c
) = list
;
12940 num_threads ( expression ) */
12943 c_parser_omp_clause_num_threads (c_parser
*parser
, tree list
)
12945 location_t num_threads_loc
= c_parser_peek_token (parser
)->location
;
12946 matching_parens parens
;
12947 if (parens
.require_open (parser
))
12949 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
12950 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
12951 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
12952 tree c
, t
= expr
.value
;
12953 t
= c_fully_fold (t
, false, NULL
);
12955 parens
.skip_until_found_close (parser
);
12957 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
12959 c_parser_error (parser
, "expected integer expression");
12963 /* Attempt to statically determine when the number isn't positive. */
12964 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
12965 build_int_cst (TREE_TYPE (t
), 0));
12966 protected_set_expr_location (c
, expr_loc
);
12967 if (c
== boolean_true_node
)
12969 warning_at (expr_loc
, 0,
12970 "%<num_threads%> value must be positive");
12971 t
= integer_one_node
;
12974 check_no_duplicate_clause (list
, OMP_CLAUSE_NUM_THREADS
, "num_threads");
12976 c
= build_omp_clause (num_threads_loc
, OMP_CLAUSE_NUM_THREADS
);
12977 OMP_CLAUSE_NUM_THREADS_EXPR (c
) = t
;
12978 OMP_CLAUSE_CHAIN (c
) = list
;
12986 num_tasks ( expression ) */
12989 c_parser_omp_clause_num_tasks (c_parser
*parser
, tree list
)
12991 location_t num_tasks_loc
= c_parser_peek_token (parser
)->location
;
12992 matching_parens parens
;
12993 if (parens
.require_open (parser
))
12995 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
12996 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
12997 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
12998 tree c
, t
= expr
.value
;
12999 t
= c_fully_fold (t
, false, NULL
);
13001 parens
.skip_until_found_close (parser
);
13003 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
13005 c_parser_error (parser
, "expected integer expression");
13009 /* Attempt to statically determine when the number isn't positive. */
13010 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
13011 build_int_cst (TREE_TYPE (t
), 0));
13012 if (CAN_HAVE_LOCATION_P (c
))
13013 SET_EXPR_LOCATION (c
, expr_loc
);
13014 if (c
== boolean_true_node
)
13016 warning_at (expr_loc
, 0, "%<num_tasks%> value must be positive");
13017 t
= integer_one_node
;
13020 check_no_duplicate_clause (list
, OMP_CLAUSE_NUM_TASKS
, "num_tasks");
13022 c
= build_omp_clause (num_tasks_loc
, OMP_CLAUSE_NUM_TASKS
);
13023 OMP_CLAUSE_NUM_TASKS_EXPR (c
) = t
;
13024 OMP_CLAUSE_CHAIN (c
) = list
;
13032 grainsize ( expression ) */
13035 c_parser_omp_clause_grainsize (c_parser
*parser
, tree list
)
13037 location_t grainsize_loc
= c_parser_peek_token (parser
)->location
;
13038 matching_parens parens
;
13039 if (parens
.require_open (parser
))
13041 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
13042 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
13043 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
13044 tree c
, t
= expr
.value
;
13045 t
= c_fully_fold (t
, false, NULL
);
13047 parens
.skip_until_found_close (parser
);
13049 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
13051 c_parser_error (parser
, "expected integer expression");
13055 /* Attempt to statically determine when the number isn't positive. */
13056 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
13057 build_int_cst (TREE_TYPE (t
), 0));
13058 if (CAN_HAVE_LOCATION_P (c
))
13059 SET_EXPR_LOCATION (c
, expr_loc
);
13060 if (c
== boolean_true_node
)
13062 warning_at (expr_loc
, 0, "%<grainsize%> value must be positive");
13063 t
= integer_one_node
;
13066 check_no_duplicate_clause (list
, OMP_CLAUSE_GRAINSIZE
, "grainsize");
13068 c
= build_omp_clause (grainsize_loc
, OMP_CLAUSE_GRAINSIZE
);
13069 OMP_CLAUSE_GRAINSIZE_EXPR (c
) = t
;
13070 OMP_CLAUSE_CHAIN (c
) = list
;
13078 priority ( expression ) */
13081 c_parser_omp_clause_priority (c_parser
*parser
, tree list
)
13083 location_t priority_loc
= c_parser_peek_token (parser
)->location
;
13084 matching_parens parens
;
13085 if (parens
.require_open (parser
))
13087 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
13088 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
13089 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
13090 tree c
, t
= expr
.value
;
13091 t
= c_fully_fold (t
, false, NULL
);
13093 parens
.skip_until_found_close (parser
);
13095 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
13097 c_parser_error (parser
, "expected integer expression");
13101 /* Attempt to statically determine when the number isn't
13103 c
= fold_build2_loc (expr_loc
, LT_EXPR
, boolean_type_node
, t
,
13104 build_int_cst (TREE_TYPE (t
), 0));
13105 if (CAN_HAVE_LOCATION_P (c
))
13106 SET_EXPR_LOCATION (c
, expr_loc
);
13107 if (c
== boolean_true_node
)
13109 warning_at (expr_loc
, 0, "%<priority%> value must be non-negative");
13110 t
= integer_one_node
;
13113 check_no_duplicate_clause (list
, OMP_CLAUSE_PRIORITY
, "priority");
13115 c
= build_omp_clause (priority_loc
, OMP_CLAUSE_PRIORITY
);
13116 OMP_CLAUSE_PRIORITY_EXPR (c
) = t
;
13117 OMP_CLAUSE_CHAIN (c
) = list
;
13125 hint ( expression ) */
13128 c_parser_omp_clause_hint (c_parser
*parser
, tree list
)
13130 location_t hint_loc
= c_parser_peek_token (parser
)->location
;
13131 matching_parens parens
;
13132 if (parens
.require_open (parser
))
13134 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
13135 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
13136 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
13137 tree c
, t
= expr
.value
;
13138 t
= c_fully_fold (t
, false, NULL
);
13140 parens
.skip_until_found_close (parser
);
13142 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
))
13143 || TREE_CODE (t
) != INTEGER_CST
)
13145 c_parser_error (parser
, "expected constant integer expression");
13149 check_no_duplicate_clause (list
, OMP_CLAUSE_HINT
, "hint");
13151 c
= build_omp_clause (hint_loc
, OMP_CLAUSE_HINT
);
13152 OMP_CLAUSE_HINT_EXPR (c
) = t
;
13153 OMP_CLAUSE_CHAIN (c
) = list
;
13161 defaultmap ( tofrom : scalar )
13164 defaultmap ( implicit-behavior [ : variable-category ] ) */
13167 c_parser_omp_clause_defaultmap (c_parser
*parser
, tree list
)
13169 location_t loc
= c_parser_peek_token (parser
)->location
;
13172 enum omp_clause_defaultmap_kind behavior
= OMP_CLAUSE_DEFAULTMAP_DEFAULT
;
13173 enum omp_clause_defaultmap_kind category
13174 = OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
;
13176 matching_parens parens
;
13177 if (!parens
.require_open (parser
))
13179 if (c_parser_next_token_is_keyword (parser
, RID_DEFAULT
))
13181 else if (!c_parser_next_token_is (parser
, CPP_NAME
))
13184 c_parser_error (parser
, "expected %<alloc%>, %<to%>, %<from%>, "
13185 "%<tofrom%>, %<firstprivate%>, %<none%> "
13190 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
13195 if (strcmp ("alloc", p
) == 0)
13196 behavior
= OMP_CLAUSE_DEFAULTMAP_ALLOC
;
13198 goto invalid_behavior
;
13202 if (strcmp ("default", p
) == 0)
13203 behavior
= OMP_CLAUSE_DEFAULTMAP_DEFAULT
;
13205 goto invalid_behavior
;
13209 if (strcmp ("firstprivate", p
) == 0)
13210 behavior
= OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE
;
13211 else if (strcmp ("from", p
) == 0)
13212 behavior
= OMP_CLAUSE_DEFAULTMAP_FROM
;
13214 goto invalid_behavior
;
13218 if (strcmp ("none", p
) == 0)
13219 behavior
= OMP_CLAUSE_DEFAULTMAP_NONE
;
13221 goto invalid_behavior
;
13225 if (strcmp ("tofrom", p
) == 0)
13226 behavior
= OMP_CLAUSE_DEFAULTMAP_TOFROM
;
13227 else if (strcmp ("to", p
) == 0)
13228 behavior
= OMP_CLAUSE_DEFAULTMAP_TO
;
13230 goto invalid_behavior
;
13234 goto invalid_behavior
;
13236 c_parser_consume_token (parser
);
13238 if (!c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
13240 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
13242 if (!c_parser_next_token_is (parser
, CPP_NAME
))
13245 c_parser_error (parser
, "expected %<scalar%>, %<aggregate%> or "
13249 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
13253 if (strcmp ("aggregate", p
) == 0)
13254 category
= OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE
;
13256 goto invalid_category
;
13260 if (strcmp ("pointer", p
) == 0)
13261 category
= OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER
;
13263 goto invalid_category
;
13267 if (strcmp ("scalar", p
) == 0)
13268 category
= OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR
;
13270 goto invalid_category
;
13274 goto invalid_category
;
13277 c_parser_consume_token (parser
);
13279 parens
.skip_until_found_close (parser
);
13281 for (c
= list
; c
; c
= OMP_CLAUSE_CHAIN (c
))
13282 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEFAULTMAP
13283 && (category
== OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
13284 || OMP_CLAUSE_DEFAULTMAP_CATEGORY (c
) == category
13285 || (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c
)
13286 == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
)))
13288 enum omp_clause_defaultmap_kind cat
= category
;
13289 location_t loc
= OMP_CLAUSE_LOCATION (c
);
13290 if (cat
== OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
)
13291 cat
= OMP_CLAUSE_DEFAULTMAP_CATEGORY (c
);
13295 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
:
13298 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE
:
13301 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER
:
13304 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR
:
13308 gcc_unreachable ();
13311 error_at (loc
, "too many %<defaultmap%> clauses with %qs category",
13314 error_at (loc
, "too many %<defaultmap%> clauses with unspecified "
13319 c
= build_omp_clause (loc
, OMP_CLAUSE_DEFAULTMAP
);
13320 OMP_CLAUSE_DEFAULTMAP_SET_KIND (c
, behavior
, category
);
13321 OMP_CLAUSE_CHAIN (c
) = list
;
13325 parens
.skip_until_found_close (parser
);
13330 use_device ( variable-list )
13333 use_device_ptr ( variable-list ) */
13336 c_parser_omp_clause_use_device_ptr (c_parser
*parser
, tree list
)
13338 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_USE_DEVICE_PTR
,
13343 use_device_addr ( variable-list ) */
13346 c_parser_omp_clause_use_device_addr (c_parser
*parser
, tree list
)
13348 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_USE_DEVICE_ADDR
,
13353 is_device_ptr ( variable-list ) */
13356 c_parser_omp_clause_is_device_ptr (c_parser
*parser
, tree list
)
13358 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_IS_DEVICE_PTR
, list
);
13362 num_gangs ( expression )
13363 num_workers ( expression )
13364 vector_length ( expression ) */
13367 c_parser_oacc_single_int_clause (c_parser
*parser
, omp_clause_code code
,
13370 location_t loc
= c_parser_peek_token (parser
)->location
;
13372 matching_parens parens
;
13373 if (!parens
.require_open (parser
))
13376 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
13377 c_expr expr
= c_parser_expression (parser
);
13378 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
13379 tree c
, t
= expr
.value
;
13380 t
= c_fully_fold (t
, false, NULL
);
13382 parens
.skip_until_found_close (parser
);
13384 if (t
== error_mark_node
)
13386 else if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
13388 error_at (expr_loc
, "%qs expression must be integral",
13389 omp_clause_code_name
[code
]);
13393 /* Attempt to statically determine when the number isn't positive. */
13394 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
13395 build_int_cst (TREE_TYPE (t
), 0));
13396 protected_set_expr_location (c
, expr_loc
);
13397 if (c
== boolean_true_node
)
13399 warning_at (expr_loc
, 0,
13400 "%qs value must be positive",
13401 omp_clause_code_name
[code
]);
13402 t
= integer_one_node
;
13405 check_no_duplicate_clause (list
, code
, omp_clause_code_name
[code
]);
13407 c
= build_omp_clause (loc
, code
);
13408 OMP_CLAUSE_OPERAND (c
, 0) = t
;
13409 OMP_CLAUSE_CHAIN (c
) = list
;
13415 gang [( gang-arg-list )]
13416 worker [( [num:] int-expr )]
13417 vector [( [length:] int-expr )]
13419 where gang-arg is one of:
13424 and size-expr may be:
13431 c_parser_oacc_shape_clause (c_parser
*parser
, location_t loc
,
13432 omp_clause_code kind
,
13433 const char *str
, tree list
)
13435 const char *id
= "num";
13436 tree ops
[2] = { NULL_TREE
, NULL_TREE
}, c
;
13438 if (kind
== OMP_CLAUSE_VECTOR
)
13441 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
13443 c_parser_consume_token (parser
);
13447 c_token
*next
= c_parser_peek_token (parser
);
13450 /* Gang static argument. */
13451 if (kind
== OMP_CLAUSE_GANG
13452 && c_parser_next_token_is_keyword (parser
, RID_STATIC
))
13454 c_parser_consume_token (parser
);
13456 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
13457 goto cleanup_error
;
13460 if (ops
[idx
] != NULL_TREE
)
13462 c_parser_error (parser
, "too many %<static%> arguments");
13463 goto cleanup_error
;
13466 /* Check for the '*' argument. */
13467 if (c_parser_next_token_is (parser
, CPP_MULT
)
13468 && (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
13469 || c_parser_peek_2nd_token (parser
)->type
13470 == CPP_CLOSE_PAREN
))
13472 c_parser_consume_token (parser
);
13473 ops
[idx
] = integer_minus_one_node
;
13475 if (c_parser_next_token_is (parser
, CPP_COMMA
))
13477 c_parser_consume_token (parser
);
13484 /* Worker num: argument and vector length: arguments. */
13485 else if (c_parser_next_token_is (parser
, CPP_NAME
)
13486 && strcmp (id
, IDENTIFIER_POINTER (next
->value
)) == 0
13487 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
13489 c_parser_consume_token (parser
); /* id */
13490 c_parser_consume_token (parser
); /* ':' */
13493 /* Now collect the actual argument. */
13494 if (ops
[idx
] != NULL_TREE
)
13496 c_parser_error (parser
, "unexpected argument");
13497 goto cleanup_error
;
13500 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
13501 c_expr cexpr
= c_parser_expr_no_commas (parser
, NULL
);
13502 cexpr
= convert_lvalue_to_rvalue (expr_loc
, cexpr
, false, true);
13503 tree expr
= cexpr
.value
;
13504 if (expr
== error_mark_node
)
13505 goto cleanup_error
;
13507 expr
= c_fully_fold (expr
, false, NULL
);
13509 /* Attempt to statically determine when the number isn't a
13510 positive integer. */
13512 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr
)))
13514 c_parser_error (parser
, "expected integer expression");
13518 tree c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, expr
,
13519 build_int_cst (TREE_TYPE (expr
), 0));
13520 if (c
== boolean_true_node
)
13522 warning_at (loc
, 0,
13523 "%qs value must be positive", str
);
13524 expr
= integer_one_node
;
13529 if (kind
== OMP_CLAUSE_GANG
13530 && c_parser_next_token_is (parser
, CPP_COMMA
))
13532 c_parser_consume_token (parser
);
13539 if (!c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
13540 goto cleanup_error
;
13543 check_no_duplicate_clause (list
, kind
, str
);
13545 c
= build_omp_clause (loc
, kind
);
13548 OMP_CLAUSE_OPERAND (c
, 1) = ops
[1];
13550 OMP_CLAUSE_OPERAND (c
, 0) = ops
[0];
13551 OMP_CLAUSE_CHAIN (c
) = list
;
13556 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, 0);
13568 c_parser_oacc_simple_clause (location_t loc
, enum omp_clause_code code
,
13571 check_no_duplicate_clause (list
, code
, omp_clause_code_name
[code
]);
13573 tree c
= build_omp_clause (loc
, code
);
13574 OMP_CLAUSE_CHAIN (c
) = list
;
13580 async [( int-expr )] */
13583 c_parser_oacc_clause_async (c_parser
*parser
, tree list
)
13586 location_t loc
= c_parser_peek_token (parser
)->location
;
13588 t
= build_int_cst (integer_type_node
, GOMP_ASYNC_NOVAL
);
13590 if (c_parser_peek_token (parser
)->type
== CPP_OPEN_PAREN
)
13592 c_parser_consume_token (parser
);
13594 t
= c_parser_expression (parser
).value
;
13595 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
13596 c_parser_error (parser
, "expected integer expression");
13597 else if (t
== error_mark_node
13598 || !c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
13602 t
= c_fully_fold (t
, false, NULL
);
13604 check_no_duplicate_clause (list
, OMP_CLAUSE_ASYNC
, "async");
13606 c
= build_omp_clause (loc
, OMP_CLAUSE_ASYNC
);
13607 OMP_CLAUSE_ASYNC_EXPR (c
) = t
;
13608 OMP_CLAUSE_CHAIN (c
) = list
;
13615 tile ( size-expr-list ) */
13618 c_parser_oacc_clause_tile (c_parser
*parser
, tree list
)
13620 tree c
, expr
= error_mark_node
;
13622 tree tile
= NULL_TREE
;
13624 check_no_duplicate_clause (list
, OMP_CLAUSE_TILE
, "tile");
13625 check_no_duplicate_clause (list
, OMP_CLAUSE_COLLAPSE
, "collapse");
13627 loc
= c_parser_peek_token (parser
)->location
;
13628 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
13633 if (tile
&& !c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
13636 if (c_parser_next_token_is (parser
, CPP_MULT
)
13637 && (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
13638 || c_parser_peek_2nd_token (parser
)->type
== CPP_CLOSE_PAREN
))
13640 c_parser_consume_token (parser
);
13641 expr
= integer_zero_node
;
13645 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
13646 c_expr cexpr
= c_parser_expr_no_commas (parser
, NULL
);
13647 cexpr
= convert_lvalue_to_rvalue (expr_loc
, cexpr
, false, true);
13648 expr
= cexpr
.value
;
13650 if (expr
== error_mark_node
)
13652 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
13657 expr
= c_fully_fold (expr
, false, NULL
);
13659 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr
))
13660 || !tree_fits_shwi_p (expr
)
13661 || tree_to_shwi (expr
) <= 0)
13663 error_at (expr_loc
, "%<tile%> argument needs positive"
13664 " integral constant");
13665 expr
= integer_zero_node
;
13669 tile
= tree_cons (NULL_TREE
, expr
, tile
);
13671 while (c_parser_next_token_is_not (parser
, CPP_CLOSE_PAREN
));
13673 /* Consume the trailing ')'. */
13674 c_parser_consume_token (parser
);
13676 c
= build_omp_clause (loc
, OMP_CLAUSE_TILE
);
13677 tile
= nreverse (tile
);
13678 OMP_CLAUSE_TILE_LIST (c
) = tile
;
13679 OMP_CLAUSE_CHAIN (c
) = list
;
13684 wait [( int-expr-list )] */
13687 c_parser_oacc_clause_wait (c_parser
*parser
, tree list
)
13689 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
13691 if (c_parser_peek_token (parser
)->type
== CPP_OPEN_PAREN
)
13692 list
= c_parser_oacc_wait_list (parser
, clause_loc
, list
);
13695 tree c
= build_omp_clause (clause_loc
, OMP_CLAUSE_WAIT
);
13697 OMP_CLAUSE_DECL (c
) = build_int_cst (integer_type_node
, GOMP_ASYNC_NOVAL
);
13698 OMP_CLAUSE_CHAIN (c
) = list
;
13707 order ( concurrent ) */
13710 c_parser_omp_clause_order (c_parser
*parser
, tree list
)
13712 location_t loc
= c_parser_peek_token (parser
)->location
;
13716 matching_parens parens
;
13717 if (!parens
.require_open (parser
))
13719 if (!c_parser_next_token_is (parser
, CPP_NAME
))
13721 c_parser_error (parser
, "expected %<concurrent%>");
13724 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
13725 if (strcmp (p
, "concurrent") != 0)
13727 c_parser_error (parser
, "expected %<concurrent%>");
13730 c_parser_consume_token (parser
);
13731 parens
.skip_until_found_close (parser
);
13732 /* check_no_duplicate_clause (list, OMP_CLAUSE_ORDER, "order"); */
13733 c
= build_omp_clause (loc
, OMP_CLAUSE_ORDER
);
13734 OMP_CLAUSE_CHAIN (c
) = list
;
13738 parens
.skip_until_found_close (parser
);
13744 bind ( teams | parallel | thread ) */
13747 c_parser_omp_clause_bind (c_parser
*parser
, tree list
)
13749 location_t loc
= c_parser_peek_token (parser
)->location
;
13752 enum omp_clause_bind_kind kind
= OMP_CLAUSE_BIND_THREAD
;
13754 matching_parens parens
;
13755 if (!parens
.require_open (parser
))
13757 if (!c_parser_next_token_is (parser
, CPP_NAME
))
13760 c_parser_error (parser
,
13761 "expected %<teams%>, %<parallel%> or %<thread%>");
13762 parens
.skip_until_found_close (parser
);
13765 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
13766 if (strcmp (p
, "teams") == 0)
13767 kind
= OMP_CLAUSE_BIND_TEAMS
;
13768 else if (strcmp (p
, "parallel") == 0)
13769 kind
= OMP_CLAUSE_BIND_PARALLEL
;
13770 else if (strcmp (p
, "thread") != 0)
13772 c_parser_consume_token (parser
);
13773 parens
.skip_until_found_close (parser
);
13774 /* check_no_duplicate_clause (list, OMP_CLAUSE_BIND, "bind"); */
13775 c
= build_omp_clause (loc
, OMP_CLAUSE_BIND
);
13776 OMP_CLAUSE_BIND_KIND (c
) = kind
;
13777 OMP_CLAUSE_CHAIN (c
) = list
;
13786 ordered ( constant-expression ) */
13789 c_parser_omp_clause_ordered (c_parser
*parser
, tree list
)
13791 check_no_duplicate_clause (list
, OMP_CLAUSE_ORDERED
, "ordered");
13793 tree c
, num
= NULL_TREE
;
13795 location_t loc
= c_parser_peek_token (parser
)->location
;
13796 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
13798 matching_parens parens
;
13799 parens
.consume_open (parser
);
13800 num
= c_parser_expr_no_commas (parser
, NULL
).value
;
13801 parens
.skip_until_found_close (parser
);
13803 if (num
== error_mark_node
)
13807 mark_exp_read (num
);
13808 num
= c_fully_fold (num
, false, NULL
);
13809 if (!INTEGRAL_TYPE_P (TREE_TYPE (num
))
13810 || !tree_fits_shwi_p (num
)
13811 || (n
= tree_to_shwi (num
)) <= 0
13814 error_at (loc
, "ordered argument needs positive "
13815 "constant integer expression");
13819 c
= build_omp_clause (loc
, OMP_CLAUSE_ORDERED
);
13820 OMP_CLAUSE_ORDERED_EXPR (c
) = num
;
13821 OMP_CLAUSE_CHAIN (c
) = list
;
13826 private ( variable-list ) */
13829 c_parser_omp_clause_private (c_parser
*parser
, tree list
)
13831 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_PRIVATE
, list
);
13835 reduction ( reduction-operator : variable-list )
13837 reduction-operator:
13838 One of: + * - & ^ | && ||
13842 reduction-operator:
13843 One of: + * - & ^ | && || max min
13847 reduction-operator:
13848 One of: + * - & ^ | && ||
13852 reduction ( reduction-modifier, reduction-operator : variable-list )
13853 in_reduction ( reduction-operator : variable-list )
13854 task_reduction ( reduction-operator : variable-list ) */
13857 c_parser_omp_clause_reduction (c_parser
*parser
, enum omp_clause_code kind
,
13858 bool is_omp
, tree list
)
13860 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
13861 matching_parens parens
;
13862 if (parens
.require_open (parser
))
13865 bool inscan
= false;
13866 enum tree_code code
= ERROR_MARK
;
13867 tree reduc_id
= NULL_TREE
;
13869 if (kind
== OMP_CLAUSE_REDUCTION
&& is_omp
)
13871 if (c_parser_next_token_is_keyword (parser
, RID_DEFAULT
)
13872 && c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
)
13874 c_parser_consume_token (parser
);
13875 c_parser_consume_token (parser
);
13877 else if (c_parser_next_token_is (parser
, CPP_NAME
)
13878 && c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
)
13881 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
13882 if (strcmp (p
, "task") == 0)
13884 else if (strcmp (p
, "inscan") == 0)
13886 if (task
|| inscan
)
13888 c_parser_consume_token (parser
);
13889 c_parser_consume_token (parser
);
13894 switch (c_parser_peek_token (parser
)->type
)
13906 code
= BIT_AND_EXPR
;
13909 code
= BIT_XOR_EXPR
;
13912 code
= BIT_IOR_EXPR
;
13915 code
= TRUTH_ANDIF_EXPR
;
13918 code
= TRUTH_ORIF_EXPR
;
13923 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
13924 if (strcmp (p
, "min") == 0)
13929 if (strcmp (p
, "max") == 0)
13934 reduc_id
= c_parser_peek_token (parser
)->value
;
13938 c_parser_error (parser
,
13939 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
13940 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
13941 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, 0);
13944 c_parser_consume_token (parser
);
13945 reduc_id
= c_omp_reduction_id (code
, reduc_id
);
13946 if (c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
13950 nl
= c_parser_omp_variable_list (parser
, clause_loc
, kind
, list
);
13951 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
13953 tree d
= OMP_CLAUSE_DECL (c
), type
;
13954 if (TREE_CODE (d
) != TREE_LIST
)
13955 type
= TREE_TYPE (d
);
13960 for (t
= d
; TREE_CODE (t
) == TREE_LIST
; t
= TREE_CHAIN (t
))
13962 type
= TREE_TYPE (t
);
13965 if (TREE_CODE (type
) != POINTER_TYPE
13966 && TREE_CODE (type
) != ARRAY_TYPE
)
13968 type
= TREE_TYPE (type
);
13972 while (TREE_CODE (type
) == ARRAY_TYPE
)
13973 type
= TREE_TYPE (type
);
13974 OMP_CLAUSE_REDUCTION_CODE (c
) = code
;
13976 OMP_CLAUSE_REDUCTION_TASK (c
) = 1;
13978 OMP_CLAUSE_REDUCTION_INSCAN (c
) = 1;
13979 if (code
== ERROR_MARK
13980 || !(INTEGRAL_TYPE_P (type
)
13981 || TREE_CODE (type
) == REAL_TYPE
13982 || TREE_CODE (type
) == COMPLEX_TYPE
))
13983 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
)
13984 = c_omp_reduction_lookup (reduc_id
,
13985 TYPE_MAIN_VARIANT (type
));
13990 parens
.skip_until_found_close (parser
);
13996 schedule ( schedule-kind )
13997 schedule ( schedule-kind , expression )
14000 static | dynamic | guided | runtime | auto
14003 schedule ( schedule-modifier : schedule-kind )
14004 schedule ( schedule-modifier [ , schedule-modifier ] : schedule-kind , expression )
14012 c_parser_omp_clause_schedule (c_parser
*parser
, tree list
)
14015 location_t loc
= c_parser_peek_token (parser
)->location
;
14016 int modifiers
= 0, nmodifiers
= 0;
14018 matching_parens parens
;
14019 if (!parens
.require_open (parser
))
14022 c
= build_omp_clause (loc
, OMP_CLAUSE_SCHEDULE
);
14024 while (c_parser_next_token_is (parser
, CPP_NAME
))
14026 tree kind
= c_parser_peek_token (parser
)->value
;
14027 const char *p
= IDENTIFIER_POINTER (kind
);
14028 if (strcmp ("simd", p
) == 0)
14029 OMP_CLAUSE_SCHEDULE_SIMD (c
) = 1;
14030 else if (strcmp ("monotonic", p
) == 0)
14031 modifiers
|= OMP_CLAUSE_SCHEDULE_MONOTONIC
;
14032 else if (strcmp ("nonmonotonic", p
) == 0)
14033 modifiers
|= OMP_CLAUSE_SCHEDULE_NONMONOTONIC
;
14036 c_parser_consume_token (parser
);
14037 if (nmodifiers
++ == 0
14038 && c_parser_next_token_is (parser
, CPP_COMMA
))
14039 c_parser_consume_token (parser
);
14042 c_parser_require (parser
, CPP_COLON
, "expected %<:%>");
14047 if ((modifiers
& (OMP_CLAUSE_SCHEDULE_MONOTONIC
14048 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC
))
14049 == (OMP_CLAUSE_SCHEDULE_MONOTONIC
14050 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC
))
14052 error_at (loc
, "both %<monotonic%> and %<nonmonotonic%> modifiers "
14057 if (c_parser_next_token_is (parser
, CPP_NAME
))
14059 tree kind
= c_parser_peek_token (parser
)->value
;
14060 const char *p
= IDENTIFIER_POINTER (kind
);
14065 if (strcmp ("dynamic", p
) != 0)
14067 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_DYNAMIC
;
14071 if (strcmp ("guided", p
) != 0)
14073 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_GUIDED
;
14077 if (strcmp ("runtime", p
) != 0)
14079 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_RUNTIME
;
14086 else if (c_parser_next_token_is_keyword (parser
, RID_STATIC
))
14087 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_STATIC
;
14088 else if (c_parser_next_token_is_keyword (parser
, RID_AUTO
))
14089 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_AUTO
;
14093 c_parser_consume_token (parser
);
14094 if (c_parser_next_token_is (parser
, CPP_COMMA
))
14097 c_parser_consume_token (parser
);
14099 here
= c_parser_peek_token (parser
)->location
;
14100 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
14101 expr
= convert_lvalue_to_rvalue (here
, expr
, false, true);
14103 t
= c_fully_fold (t
, false, NULL
);
14105 if (OMP_CLAUSE_SCHEDULE_KIND (c
) == OMP_CLAUSE_SCHEDULE_RUNTIME
)
14106 error_at (here
, "schedule %<runtime%> does not take "
14107 "a %<chunk_size%> parameter");
14108 else if (OMP_CLAUSE_SCHEDULE_KIND (c
) == OMP_CLAUSE_SCHEDULE_AUTO
)
14110 "schedule %<auto%> does not take "
14111 "a %<chunk_size%> parameter");
14112 else if (TREE_CODE (TREE_TYPE (t
)) == INTEGER_TYPE
)
14114 /* Attempt to statically determine when the number isn't
14116 tree s
= fold_build2_loc (loc
, LE_EXPR
, boolean_type_node
, t
,
14117 build_int_cst (TREE_TYPE (t
), 0));
14118 protected_set_expr_location (s
, loc
);
14119 if (s
== boolean_true_node
)
14121 warning_at (loc
, 0,
14122 "chunk size value must be positive");
14123 t
= integer_one_node
;
14125 OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c
) = t
;
14128 c_parser_error (parser
, "expected integer expression");
14130 parens
.skip_until_found_close (parser
);
14133 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
14134 "expected %<,%> or %<)%>");
14136 OMP_CLAUSE_SCHEDULE_KIND (c
)
14137 = (enum omp_clause_schedule_kind
)
14138 (OMP_CLAUSE_SCHEDULE_KIND (c
) | modifiers
);
14140 check_no_duplicate_clause (list
, OMP_CLAUSE_SCHEDULE
, "schedule");
14141 OMP_CLAUSE_CHAIN (c
) = list
;
14145 c_parser_error (parser
, "invalid schedule kind");
14146 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, 0);
14151 shared ( variable-list ) */
14154 c_parser_omp_clause_shared (c_parser
*parser
, tree list
)
14156 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_SHARED
, list
);
14163 c_parser_omp_clause_untied (c_parser
*parser ATTRIBUTE_UNUSED
, tree list
)
14167 /* FIXME: Should we allow duplicates? */
14168 check_no_duplicate_clause (list
, OMP_CLAUSE_UNTIED
, "untied");
14170 c
= build_omp_clause (c_parser_peek_token (parser
)->location
,
14171 OMP_CLAUSE_UNTIED
);
14172 OMP_CLAUSE_CHAIN (c
) = list
;
14182 c_parser_omp_clause_branch (c_parser
*parser ATTRIBUTE_UNUSED
,
14183 enum omp_clause_code code
, tree list
)
14185 check_no_duplicate_clause (list
, code
, omp_clause_code_name
[code
]);
14187 tree c
= build_omp_clause (c_parser_peek_token (parser
)->location
, code
);
14188 OMP_CLAUSE_CHAIN (c
) = list
;
14200 c_parser_omp_clause_cancelkind (c_parser
*parser ATTRIBUTE_UNUSED
,
14201 enum omp_clause_code code
, tree list
)
14203 tree c
= build_omp_clause (c_parser_peek_token (parser
)->location
, code
);
14204 OMP_CLAUSE_CHAIN (c
) = list
;
14213 c_parser_omp_clause_nogroup (c_parser
*parser ATTRIBUTE_UNUSED
, tree list
)
14215 check_no_duplicate_clause (list
, OMP_CLAUSE_NOGROUP
, "nogroup");
14216 tree c
= build_omp_clause (c_parser_peek_token (parser
)->location
,
14217 OMP_CLAUSE_NOGROUP
);
14218 OMP_CLAUSE_CHAIN (c
) = list
;
14227 c_parser_omp_clause_orderedkind (c_parser
*parser ATTRIBUTE_UNUSED
,
14228 enum omp_clause_code code
, tree list
)
14230 check_no_duplicate_clause (list
, code
, omp_clause_code_name
[code
]);
14231 tree c
= build_omp_clause (c_parser_peek_token (parser
)->location
, code
);
14232 OMP_CLAUSE_CHAIN (c
) = list
;
14237 num_teams ( expression ) */
14240 c_parser_omp_clause_num_teams (c_parser
*parser
, tree list
)
14242 location_t num_teams_loc
= c_parser_peek_token (parser
)->location
;
14243 matching_parens parens
;
14244 if (parens
.require_open (parser
))
14246 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
14247 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
14248 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
14249 tree c
, t
= expr
.value
;
14250 t
= c_fully_fold (t
, false, NULL
);
14252 parens
.skip_until_found_close (parser
);
14254 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
14256 c_parser_error (parser
, "expected integer expression");
14260 /* Attempt to statically determine when the number isn't positive. */
14261 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
14262 build_int_cst (TREE_TYPE (t
), 0));
14263 protected_set_expr_location (c
, expr_loc
);
14264 if (c
== boolean_true_node
)
14266 warning_at (expr_loc
, 0, "%<num_teams%> value must be positive");
14267 t
= integer_one_node
;
14270 check_no_duplicate_clause (list
, OMP_CLAUSE_NUM_TEAMS
, "num_teams");
14272 c
= build_omp_clause (num_teams_loc
, OMP_CLAUSE_NUM_TEAMS
);
14273 OMP_CLAUSE_NUM_TEAMS_EXPR (c
) = t
;
14274 OMP_CLAUSE_CHAIN (c
) = list
;
14282 thread_limit ( expression ) */
14285 c_parser_omp_clause_thread_limit (c_parser
*parser
, tree list
)
14287 location_t num_thread_limit_loc
= c_parser_peek_token (parser
)->location
;
14288 matching_parens parens
;
14289 if (parens
.require_open (parser
))
14291 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
14292 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
14293 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
14294 tree c
, t
= expr
.value
;
14295 t
= c_fully_fold (t
, false, NULL
);
14297 parens
.skip_until_found_close (parser
);
14299 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
14301 c_parser_error (parser
, "expected integer expression");
14305 /* Attempt to statically determine when the number isn't positive. */
14306 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
14307 build_int_cst (TREE_TYPE (t
), 0));
14308 protected_set_expr_location (c
, expr_loc
);
14309 if (c
== boolean_true_node
)
14311 warning_at (expr_loc
, 0, "%<thread_limit%> value must be positive");
14312 t
= integer_one_node
;
14315 check_no_duplicate_clause (list
, OMP_CLAUSE_THREAD_LIMIT
,
14318 c
= build_omp_clause (num_thread_limit_loc
, OMP_CLAUSE_THREAD_LIMIT
);
14319 OMP_CLAUSE_THREAD_LIMIT_EXPR (c
) = t
;
14320 OMP_CLAUSE_CHAIN (c
) = list
;
14328 aligned ( variable-list )
14329 aligned ( variable-list : constant-expression ) */
14332 c_parser_omp_clause_aligned (c_parser
*parser
, tree list
)
14334 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
14337 matching_parens parens
;
14338 if (!parens
.require_open (parser
))
14341 nl
= c_parser_omp_variable_list (parser
, clause_loc
,
14342 OMP_CLAUSE_ALIGNED
, list
);
14344 if (c_parser_next_token_is (parser
, CPP_COLON
))
14346 c_parser_consume_token (parser
);
14347 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
14348 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
14349 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
14350 tree alignment
= expr
.value
;
14351 alignment
= c_fully_fold (alignment
, false, NULL
);
14352 if (TREE_CODE (alignment
) != INTEGER_CST
14353 || !INTEGRAL_TYPE_P (TREE_TYPE (alignment
))
14354 || tree_int_cst_sgn (alignment
) != 1)
14356 error_at (clause_loc
, "%<aligned%> clause alignment expression must "
14357 "be positive constant integer expression");
14358 alignment
= NULL_TREE
;
14361 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
14362 OMP_CLAUSE_ALIGNED_ALIGNMENT (c
) = alignment
;
14365 parens
.skip_until_found_close (parser
);
14370 linear ( variable-list )
14371 linear ( variable-list : expression )
14374 linear ( modifier ( variable-list ) )
14375 linear ( modifier ( variable-list ) : expression ) */
14378 c_parser_omp_clause_linear (c_parser
*parser
, tree list
)
14380 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
14382 enum omp_clause_linear_kind kind
= OMP_CLAUSE_LINEAR_DEFAULT
;
14384 matching_parens parens
;
14385 if (!parens
.require_open (parser
))
14388 if (c_parser_next_token_is (parser
, CPP_NAME
))
14390 c_token
*tok
= c_parser_peek_token (parser
);
14391 const char *p
= IDENTIFIER_POINTER (tok
->value
);
14392 if (strcmp ("val", p
) == 0)
14393 kind
= OMP_CLAUSE_LINEAR_VAL
;
14394 if (c_parser_peek_2nd_token (parser
)->type
!= CPP_OPEN_PAREN
)
14395 kind
= OMP_CLAUSE_LINEAR_DEFAULT
;
14396 if (kind
!= OMP_CLAUSE_LINEAR_DEFAULT
)
14398 c_parser_consume_token (parser
);
14399 c_parser_consume_token (parser
);
14403 nl
= c_parser_omp_variable_list (parser
, clause_loc
,
14404 OMP_CLAUSE_LINEAR
, list
);
14406 if (kind
!= OMP_CLAUSE_LINEAR_DEFAULT
)
14407 parens
.skip_until_found_close (parser
);
14409 if (c_parser_next_token_is (parser
, CPP_COLON
))
14411 c_parser_consume_token (parser
);
14412 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
14413 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
14414 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
14416 step
= c_fully_fold (step
, false, NULL
);
14417 if (!INTEGRAL_TYPE_P (TREE_TYPE (step
)))
14419 error_at (clause_loc
, "%<linear%> clause step expression must "
14421 step
= integer_one_node
;
14426 step
= integer_one_node
;
14428 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
14430 OMP_CLAUSE_LINEAR_STEP (c
) = step
;
14431 OMP_CLAUSE_LINEAR_KIND (c
) = kind
;
14434 parens
.skip_until_found_close (parser
);
14439 nontemporal ( variable-list ) */
14442 c_parser_omp_clause_nontemporal (c_parser
*parser
, tree list
)
14444 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_NONTEMPORAL
, list
);
14448 safelen ( constant-expression ) */
14451 c_parser_omp_clause_safelen (c_parser
*parser
, tree list
)
14453 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
14456 matching_parens parens
;
14457 if (!parens
.require_open (parser
))
14460 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
14461 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
14462 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
14464 t
= c_fully_fold (t
, false, NULL
);
14465 if (TREE_CODE (t
) != INTEGER_CST
14466 || !INTEGRAL_TYPE_P (TREE_TYPE (t
))
14467 || tree_int_cst_sgn (t
) != 1)
14469 error_at (clause_loc
, "%<safelen%> clause expression must "
14470 "be positive constant integer expression");
14474 parens
.skip_until_found_close (parser
);
14475 if (t
== NULL_TREE
|| t
== error_mark_node
)
14478 check_no_duplicate_clause (list
, OMP_CLAUSE_SAFELEN
, "safelen");
14480 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_SAFELEN
);
14481 OMP_CLAUSE_SAFELEN_EXPR (c
) = t
;
14482 OMP_CLAUSE_CHAIN (c
) = list
;
14487 simdlen ( constant-expression ) */
14490 c_parser_omp_clause_simdlen (c_parser
*parser
, tree list
)
14492 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
14495 matching_parens parens
;
14496 if (!parens
.require_open (parser
))
14499 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
14500 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
14501 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
14503 t
= c_fully_fold (t
, false, NULL
);
14504 if (TREE_CODE (t
) != INTEGER_CST
14505 || !INTEGRAL_TYPE_P (TREE_TYPE (t
))
14506 || tree_int_cst_sgn (t
) != 1)
14508 error_at (clause_loc
, "%<simdlen%> clause expression must "
14509 "be positive constant integer expression");
14513 parens
.skip_until_found_close (parser
);
14514 if (t
== NULL_TREE
|| t
== error_mark_node
)
14517 check_no_duplicate_clause (list
, OMP_CLAUSE_SIMDLEN
, "simdlen");
14519 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_SIMDLEN
);
14520 OMP_CLAUSE_SIMDLEN_EXPR (c
) = t
;
14521 OMP_CLAUSE_CHAIN (c
) = list
;
14527 identifier [+/- integer]
14528 vec , identifier [+/- integer]
14532 c_parser_omp_clause_depend_sink (c_parser
*parser
, location_t clause_loc
,
14536 if (c_parser_next_token_is_not (parser
, CPP_NAME
)
14537 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
14539 c_parser_error (parser
, "expected identifier");
14543 while (c_parser_next_token_is (parser
, CPP_NAME
)
14544 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
)
14546 tree t
= lookup_name (c_parser_peek_token (parser
)->value
);
14547 tree addend
= NULL
;
14549 if (t
== NULL_TREE
)
14551 undeclared_variable (c_parser_peek_token (parser
)->location
,
14552 c_parser_peek_token (parser
)->value
);
14553 t
= error_mark_node
;
14556 c_parser_consume_token (parser
);
14559 if (c_parser_next_token_is (parser
, CPP_MINUS
))
14561 else if (!c_parser_next_token_is (parser
, CPP_PLUS
))
14563 addend
= integer_zero_node
;
14565 goto add_to_vector
;
14567 c_parser_consume_token (parser
);
14569 if (c_parser_next_token_is_not (parser
, CPP_NUMBER
))
14571 c_parser_error (parser
, "expected integer");
14575 addend
= c_parser_peek_token (parser
)->value
;
14576 if (TREE_CODE (addend
) != INTEGER_CST
)
14578 c_parser_error (parser
, "expected integer");
14581 c_parser_consume_token (parser
);
14584 if (t
!= error_mark_node
)
14586 vec
= tree_cons (addend
, t
, vec
);
14588 OMP_CLAUSE_DEPEND_SINK_NEGATIVE (vec
) = 1;
14591 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
14594 c_parser_consume_token (parser
);
14597 if (vec
== NULL_TREE
)
14600 tree u
= build_omp_clause (clause_loc
, OMP_CLAUSE_DEPEND
);
14601 OMP_CLAUSE_DEPEND_KIND (u
) = OMP_CLAUSE_DEPEND_SINK
;
14602 OMP_CLAUSE_DECL (u
) = nreverse (vec
);
14603 OMP_CLAUSE_CHAIN (u
) = list
;
14608 iterators ( iterators-definition )
14610 iterators-definition:
14612 iterator-specifier , iterators-definition
14614 iterator-specifier:
14615 identifier = range-specification
14616 iterator-type identifier = range-specification
14618 range-specification:
14620 begin : end : step */
14623 c_parser_omp_iterators (c_parser
*parser
)
14625 tree ret
= NULL_TREE
, *last
= &ret
;
14626 c_parser_consume_token (parser
);
14630 matching_parens parens
;
14631 if (!parens
.require_open (parser
))
14632 return error_mark_node
;
14636 tree iter_type
= NULL_TREE
, type_expr
= NULL_TREE
;
14637 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_id
))
14639 struct c_type_name
*type
= c_parser_type_name (parser
);
14641 iter_type
= groktypename (type
, &type_expr
, NULL
);
14643 if (iter_type
== NULL_TREE
)
14644 iter_type
= integer_type_node
;
14646 location_t loc
= c_parser_peek_token (parser
)->location
;
14647 if (!c_parser_next_token_is (parser
, CPP_NAME
))
14649 c_parser_error (parser
, "expected identifier");
14653 tree id
= c_parser_peek_token (parser
)->value
;
14654 c_parser_consume_token (parser
);
14656 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
14659 location_t eloc
= c_parser_peek_token (parser
)->location
;
14660 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
14661 expr
= convert_lvalue_to_rvalue (eloc
, expr
, true, false);
14662 tree begin
= expr
.value
;
14664 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
14667 eloc
= c_parser_peek_token (parser
)->location
;
14668 expr
= c_parser_expr_no_commas (parser
, NULL
);
14669 expr
= convert_lvalue_to_rvalue (eloc
, expr
, true, false);
14670 tree end
= expr
.value
;
14672 tree step
= integer_one_node
;
14673 if (c_parser_next_token_is (parser
, CPP_COLON
))
14675 c_parser_consume_token (parser
);
14676 eloc
= c_parser_peek_token (parser
)->location
;
14677 expr
= c_parser_expr_no_commas (parser
, NULL
);
14678 expr
= convert_lvalue_to_rvalue (eloc
, expr
, true, false);
14682 tree iter_var
= build_decl (loc
, VAR_DECL
, id
, iter_type
);
14683 DECL_ARTIFICIAL (iter_var
) = 1;
14684 DECL_CONTEXT (iter_var
) = current_function_decl
;
14685 pushdecl (iter_var
);
14687 *last
= make_tree_vec (6);
14688 TREE_VEC_ELT (*last
, 0) = iter_var
;
14689 TREE_VEC_ELT (*last
, 1) = begin
;
14690 TREE_VEC_ELT (*last
, 2) = end
;
14691 TREE_VEC_ELT (*last
, 3) = step
;
14692 last
= &TREE_CHAIN (*last
);
14694 if (c_parser_next_token_is (parser
, CPP_COMMA
))
14696 c_parser_consume_token (parser
);
14703 parens
.skip_until_found_close (parser
);
14704 return ret
? ret
: error_mark_node
;
14708 depend ( depend-kind: variable-list )
14716 depend ( sink : vec )
14719 depend ( depend-modifier , depend-kind: variable-list )
14722 in | out | inout | mutexinoutset | depobj
14725 iterator ( iterators-definition ) */
14728 c_parser_omp_clause_depend (c_parser
*parser
, tree list
)
14730 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
14731 enum omp_clause_depend_kind kind
= OMP_CLAUSE_DEPEND_LAST
;
14732 tree nl
, c
, iterators
= NULL_TREE
;
14734 matching_parens parens
;
14735 if (!parens
.require_open (parser
))
14740 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
14743 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
14744 if (strcmp ("iterator", p
) == 0 && iterators
== NULL_TREE
)
14746 iterators
= c_parser_omp_iterators (parser
);
14747 c_parser_require (parser
, CPP_COMMA
, "expected %<,%>");
14750 if (strcmp ("in", p
) == 0)
14751 kind
= OMP_CLAUSE_DEPEND_IN
;
14752 else if (strcmp ("inout", p
) == 0)
14753 kind
= OMP_CLAUSE_DEPEND_INOUT
;
14754 else if (strcmp ("mutexinoutset", p
) == 0)
14755 kind
= OMP_CLAUSE_DEPEND_MUTEXINOUTSET
;
14756 else if (strcmp ("out", p
) == 0)
14757 kind
= OMP_CLAUSE_DEPEND_OUT
;
14758 else if (strcmp ("depobj", p
) == 0)
14759 kind
= OMP_CLAUSE_DEPEND_DEPOBJ
;
14760 else if (strcmp ("sink", p
) == 0)
14761 kind
= OMP_CLAUSE_DEPEND_SINK
;
14762 else if (strcmp ("source", p
) == 0)
14763 kind
= OMP_CLAUSE_DEPEND_SOURCE
;
14770 c_parser_consume_token (parser
);
14773 && (kind
== OMP_CLAUSE_DEPEND_SOURCE
|| kind
== OMP_CLAUSE_DEPEND_SINK
))
14776 error_at (clause_loc
, "%<iterator%> modifier incompatible with %qs",
14777 kind
== OMP_CLAUSE_DEPEND_SOURCE
? "source" : "sink");
14778 iterators
= NULL_TREE
;
14781 if (kind
== OMP_CLAUSE_DEPEND_SOURCE
)
14783 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_DEPEND
);
14784 OMP_CLAUSE_DEPEND_KIND (c
) = kind
;
14785 OMP_CLAUSE_DECL (c
) = NULL_TREE
;
14786 OMP_CLAUSE_CHAIN (c
) = list
;
14787 parens
.skip_until_found_close (parser
);
14791 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
14794 if (kind
== OMP_CLAUSE_DEPEND_SINK
)
14795 nl
= c_parser_omp_clause_depend_sink (parser
, clause_loc
, list
);
14798 nl
= c_parser_omp_variable_list (parser
, clause_loc
,
14799 OMP_CLAUSE_DEPEND
, list
);
14803 tree block
= pop_scope ();
14804 if (iterators
== error_mark_node
)
14805 iterators
= NULL_TREE
;
14807 TREE_VEC_ELT (iterators
, 5) = block
;
14810 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
14812 OMP_CLAUSE_DEPEND_KIND (c
) = kind
;
14814 OMP_CLAUSE_DECL (c
)
14815 = build_tree_list (iterators
, OMP_CLAUSE_DECL (c
));
14819 parens
.skip_until_found_close (parser
);
14823 c_parser_error (parser
, "invalid depend kind");
14825 parens
.skip_until_found_close (parser
);
14832 map ( map-kind: variable-list )
14833 map ( variable-list )
14836 alloc | to | from | tofrom
14840 alloc | to | from | tofrom | release | delete
14842 map ( always [,] map-kind: variable-list ) */
14845 c_parser_omp_clause_map (c_parser
*parser
, tree list
)
14847 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
14848 enum gomp_map_kind kind
= GOMP_MAP_TOFROM
;
14850 enum c_id_kind always_id_kind
= C_ID_NONE
;
14851 location_t always_loc
= UNKNOWN_LOCATION
;
14852 tree always_id
= NULL_TREE
;
14855 matching_parens parens
;
14856 if (!parens
.require_open (parser
))
14859 if (c_parser_next_token_is (parser
, CPP_NAME
))
14861 c_token
*tok
= c_parser_peek_token (parser
);
14862 const char *p
= IDENTIFIER_POINTER (tok
->value
);
14863 always_id_kind
= tok
->id_kind
;
14864 always_loc
= tok
->location
;
14865 always_id
= tok
->value
;
14866 if (strcmp ("always", p
) == 0)
14868 c_token
*sectok
= c_parser_peek_2nd_token (parser
);
14869 if (sectok
->type
== CPP_COMMA
)
14871 c_parser_consume_token (parser
);
14872 c_parser_consume_token (parser
);
14875 else if (sectok
->type
== CPP_NAME
)
14877 p
= IDENTIFIER_POINTER (sectok
->value
);
14878 if (strcmp ("alloc", p
) == 0
14879 || strcmp ("to", p
) == 0
14880 || strcmp ("from", p
) == 0
14881 || strcmp ("tofrom", p
) == 0
14882 || strcmp ("release", p
) == 0
14883 || strcmp ("delete", p
) == 0)
14885 c_parser_consume_token (parser
);
14892 if (c_parser_next_token_is (parser
, CPP_NAME
)
14893 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
14895 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
14896 if (strcmp ("alloc", p
) == 0)
14897 kind
= GOMP_MAP_ALLOC
;
14898 else if (strcmp ("to", p
) == 0)
14899 kind
= always
? GOMP_MAP_ALWAYS_TO
: GOMP_MAP_TO
;
14900 else if (strcmp ("from", p
) == 0)
14901 kind
= always
? GOMP_MAP_ALWAYS_FROM
: GOMP_MAP_FROM
;
14902 else if (strcmp ("tofrom", p
) == 0)
14903 kind
= always
? GOMP_MAP_ALWAYS_TOFROM
: GOMP_MAP_TOFROM
;
14904 else if (strcmp ("release", p
) == 0)
14905 kind
= GOMP_MAP_RELEASE
;
14906 else if (strcmp ("delete", p
) == 0)
14907 kind
= GOMP_MAP_DELETE
;
14910 c_parser_error (parser
, "invalid map kind");
14911 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
14915 c_parser_consume_token (parser
);
14916 c_parser_consume_token (parser
);
14920 if (always_id_kind
!= C_ID_ID
)
14922 c_parser_error (parser
, "expected identifier");
14923 parens
.skip_until_found_close (parser
);
14927 tree t
= lookup_name (always_id
);
14928 if (t
== NULL_TREE
)
14930 undeclared_variable (always_loc
, always_id
);
14931 t
= error_mark_node
;
14933 if (t
!= error_mark_node
)
14935 tree u
= build_omp_clause (clause_loc
, OMP_CLAUSE_MAP
);
14936 OMP_CLAUSE_DECL (u
) = t
;
14937 OMP_CLAUSE_CHAIN (u
) = list
;
14938 OMP_CLAUSE_SET_MAP_KIND (u
, kind
);
14943 parens
.skip_until_found_close (parser
);
14948 nl
= c_parser_omp_variable_list (parser
, clause_loc
, OMP_CLAUSE_MAP
, list
);
14950 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
14951 OMP_CLAUSE_SET_MAP_KIND (c
, kind
);
14953 parens
.skip_until_found_close (parser
);
14958 device ( expression ) */
14961 c_parser_omp_clause_device (c_parser
*parser
, tree list
)
14963 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
14964 matching_parens parens
;
14965 if (parens
.require_open (parser
))
14967 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
14968 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
14969 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
14970 tree c
, t
= expr
.value
;
14971 t
= c_fully_fold (t
, false, NULL
);
14973 parens
.skip_until_found_close (parser
);
14975 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
14977 c_parser_error (parser
, "expected integer expression");
14981 check_no_duplicate_clause (list
, OMP_CLAUSE_DEVICE
, "device");
14983 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_DEVICE
);
14984 OMP_CLAUSE_DEVICE_ID (c
) = t
;
14985 OMP_CLAUSE_CHAIN (c
) = list
;
14993 dist_schedule ( static )
14994 dist_schedule ( static , expression ) */
14997 c_parser_omp_clause_dist_schedule (c_parser
*parser
, tree list
)
14999 tree c
, t
= NULL_TREE
;
15000 location_t loc
= c_parser_peek_token (parser
)->location
;
15002 matching_parens parens
;
15003 if (!parens
.require_open (parser
))
15006 if (!c_parser_next_token_is_keyword (parser
, RID_STATIC
))
15008 c_parser_error (parser
, "invalid dist_schedule kind");
15009 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
15014 c_parser_consume_token (parser
);
15015 if (c_parser_next_token_is (parser
, CPP_COMMA
))
15017 c_parser_consume_token (parser
);
15019 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
15020 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15021 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
15023 t
= c_fully_fold (t
, false, NULL
);
15024 parens
.skip_until_found_close (parser
);
15027 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
15028 "expected %<,%> or %<)%>");
15030 /* check_no_duplicate_clause (list, OMP_CLAUSE_DIST_SCHEDULE,
15031 "dist_schedule"); */
15032 if (omp_find_clause (list
, OMP_CLAUSE_DIST_SCHEDULE
))
15033 warning_at (loc
, 0, "too many %qs clauses", "dist_schedule");
15034 if (t
== error_mark_node
)
15037 c
= build_omp_clause (loc
, OMP_CLAUSE_DIST_SCHEDULE
);
15038 OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c
) = t
;
15039 OMP_CLAUSE_CHAIN (c
) = list
;
15044 proc_bind ( proc-bind-kind )
15047 master | close | spread */
15050 c_parser_omp_clause_proc_bind (c_parser
*parser
, tree list
)
15052 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
15053 enum omp_clause_proc_bind_kind kind
;
15056 matching_parens parens
;
15057 if (!parens
.require_open (parser
))
15060 if (c_parser_next_token_is (parser
, CPP_NAME
))
15062 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
15063 if (strcmp ("master", p
) == 0)
15064 kind
= OMP_CLAUSE_PROC_BIND_MASTER
;
15065 else if (strcmp ("close", p
) == 0)
15066 kind
= OMP_CLAUSE_PROC_BIND_CLOSE
;
15067 else if (strcmp ("spread", p
) == 0)
15068 kind
= OMP_CLAUSE_PROC_BIND_SPREAD
;
15075 check_no_duplicate_clause (list
, OMP_CLAUSE_PROC_BIND
, "proc_bind");
15076 c_parser_consume_token (parser
);
15077 parens
.skip_until_found_close (parser
);
15078 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_PROC_BIND
);
15079 OMP_CLAUSE_PROC_BIND_KIND (c
) = kind
;
15080 OMP_CLAUSE_CHAIN (c
) = list
;
15084 c_parser_error (parser
, "invalid proc_bind kind");
15085 parens
.skip_until_found_close (parser
);
15090 device_type ( host | nohost | any ) */
15093 c_parser_omp_clause_device_type (c_parser
*parser
, tree list
)
15095 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
15096 enum omp_clause_device_type_kind kind
;
15099 matching_parens parens
;
15100 if (!parens
.require_open (parser
))
15103 if (c_parser_next_token_is (parser
, CPP_NAME
))
15105 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
15106 if (strcmp ("host", p
) == 0)
15107 kind
= OMP_CLAUSE_DEVICE_TYPE_HOST
;
15108 else if (strcmp ("nohost", p
) == 0)
15109 kind
= OMP_CLAUSE_DEVICE_TYPE_NOHOST
;
15110 else if (strcmp ("any", p
) == 0)
15111 kind
= OMP_CLAUSE_DEVICE_TYPE_ANY
;
15118 /* check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE_TYPE,
15120 c_parser_consume_token (parser
);
15121 parens
.skip_until_found_close (parser
);
15122 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_DEVICE_TYPE
);
15123 OMP_CLAUSE_DEVICE_TYPE_KIND (c
) = kind
;
15124 OMP_CLAUSE_CHAIN (c
) = list
;
15128 c_parser_error (parser
, "expected %<host%>, %<nohost%> or %<any%>");
15129 parens
.skip_until_found_close (parser
);
15134 to ( variable-list ) */
15137 c_parser_omp_clause_to (c_parser
*parser
, tree list
)
15139 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_TO
, list
);
15143 from ( variable-list ) */
15146 c_parser_omp_clause_from (c_parser
*parser
, tree list
)
15148 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_FROM
, list
);
15152 uniform ( variable-list ) */
15155 c_parser_omp_clause_uniform (c_parser
*parser
, tree list
)
15157 /* The clauses location. */
15158 location_t loc
= c_parser_peek_token (parser
)->location
;
15160 matching_parens parens
;
15161 if (parens
.require_open (parser
))
15163 list
= c_parser_omp_variable_list (parser
, loc
, OMP_CLAUSE_UNIFORM
,
15165 parens
.skip_until_found_close (parser
);
15170 /* Parse all OpenACC clauses. The set clauses allowed by the directive
15171 is a bitmask in MASK. Return the list of clauses found. */
15174 c_parser_oacc_all_clauses (c_parser
*parser
, omp_clause_mask mask
,
15175 const char *where
, bool finish_p
= true)
15177 tree clauses
= NULL
;
15180 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
15183 pragma_omp_clause c_kind
;
15184 const char *c_name
;
15185 tree prev
= clauses
;
15187 if (!first
&& c_parser_next_token_is (parser
, CPP_COMMA
))
15188 c_parser_consume_token (parser
);
15190 here
= c_parser_peek_token (parser
)->location
;
15191 c_kind
= c_parser_omp_clause_name (parser
);
15195 case PRAGMA_OACC_CLAUSE_ASYNC
:
15196 clauses
= c_parser_oacc_clause_async (parser
, clauses
);
15199 case PRAGMA_OACC_CLAUSE_AUTO
:
15200 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_AUTO
,
15204 case PRAGMA_OACC_CLAUSE_COLLAPSE
:
15205 clauses
= c_parser_omp_clause_collapse (parser
, clauses
);
15206 c_name
= "collapse";
15208 case PRAGMA_OACC_CLAUSE_COPY
:
15209 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
15212 case PRAGMA_OACC_CLAUSE_COPYIN
:
15213 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
15216 case PRAGMA_OACC_CLAUSE_COPYOUT
:
15217 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
15218 c_name
= "copyout";
15220 case PRAGMA_OACC_CLAUSE_CREATE
:
15221 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
15224 case PRAGMA_OACC_CLAUSE_DELETE
:
15225 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
15228 case PRAGMA_OMP_CLAUSE_DEFAULT
:
15229 clauses
= c_parser_omp_clause_default (parser
, clauses
, true);
15230 c_name
= "default";
15232 case PRAGMA_OACC_CLAUSE_DEVICE
:
15233 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
15236 case PRAGMA_OACC_CLAUSE_DEVICEPTR
:
15237 clauses
= c_parser_oacc_data_clause_deviceptr (parser
, clauses
);
15238 c_name
= "deviceptr";
15240 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT
:
15241 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
15242 c_name
= "device_resident";
15244 case PRAGMA_OACC_CLAUSE_FINALIZE
:
15245 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_FINALIZE
,
15247 c_name
= "finalize";
15249 case PRAGMA_OACC_CLAUSE_FIRSTPRIVATE
:
15250 clauses
= c_parser_omp_clause_firstprivate (parser
, clauses
);
15251 c_name
= "firstprivate";
15253 case PRAGMA_OACC_CLAUSE_GANG
:
15255 clauses
= c_parser_oacc_shape_clause (parser
, here
, OMP_CLAUSE_GANG
,
15258 case PRAGMA_OACC_CLAUSE_HOST
:
15259 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
15262 case PRAGMA_OACC_CLAUSE_IF
:
15263 clauses
= c_parser_omp_clause_if (parser
, clauses
, false);
15266 case PRAGMA_OACC_CLAUSE_IF_PRESENT
:
15267 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_IF_PRESENT
,
15269 c_name
= "if_present";
15271 case PRAGMA_OACC_CLAUSE_INDEPENDENT
:
15272 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_INDEPENDENT
,
15274 c_name
= "independent";
15276 case PRAGMA_OACC_CLAUSE_LINK
:
15277 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
15280 case PRAGMA_OACC_CLAUSE_NUM_GANGS
:
15281 clauses
= c_parser_oacc_single_int_clause (parser
,
15282 OMP_CLAUSE_NUM_GANGS
,
15284 c_name
= "num_gangs";
15286 case PRAGMA_OACC_CLAUSE_NUM_WORKERS
:
15287 clauses
= c_parser_oacc_single_int_clause (parser
,
15288 OMP_CLAUSE_NUM_WORKERS
,
15290 c_name
= "num_workers";
15292 case PRAGMA_OACC_CLAUSE_PRESENT
:
15293 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
15294 c_name
= "present";
15296 case PRAGMA_OACC_CLAUSE_PRIVATE
:
15297 clauses
= c_parser_omp_clause_private (parser
, clauses
);
15298 c_name
= "private";
15300 case PRAGMA_OACC_CLAUSE_REDUCTION
:
15302 = c_parser_omp_clause_reduction (parser
, OMP_CLAUSE_REDUCTION
,
15304 c_name
= "reduction";
15306 case PRAGMA_OACC_CLAUSE_SEQ
:
15307 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_SEQ
,
15311 case PRAGMA_OACC_CLAUSE_TILE
:
15312 clauses
= c_parser_oacc_clause_tile (parser
, clauses
);
15315 case PRAGMA_OACC_CLAUSE_USE_DEVICE
:
15316 clauses
= c_parser_omp_clause_use_device_ptr (parser
, clauses
);
15317 c_name
= "use_device";
15319 case PRAGMA_OACC_CLAUSE_VECTOR
:
15321 clauses
= c_parser_oacc_shape_clause (parser
, here
, OMP_CLAUSE_VECTOR
,
15324 case PRAGMA_OACC_CLAUSE_VECTOR_LENGTH
:
15325 clauses
= c_parser_oacc_single_int_clause (parser
,
15326 OMP_CLAUSE_VECTOR_LENGTH
,
15328 c_name
= "vector_length";
15330 case PRAGMA_OACC_CLAUSE_WAIT
:
15331 clauses
= c_parser_oacc_clause_wait (parser
, clauses
);
15334 case PRAGMA_OACC_CLAUSE_WORKER
:
15336 clauses
= c_parser_oacc_shape_clause (parser
, here
, OMP_CLAUSE_WORKER
,
15340 c_parser_error (parser
, "expected %<#pragma acc%> clause");
15346 if (((mask
>> c_kind
) & 1) == 0)
15348 /* Remove the invalid clause(s) from the list to avoid
15349 confusing the rest of the compiler. */
15351 error_at (here
, "%qs is not valid for %qs", c_name
, where
);
15356 c_parser_skip_to_pragma_eol (parser
);
15359 return c_finish_omp_clauses (clauses
, C_ORT_ACC
);
15364 /* Parse all OpenMP clauses. The set clauses allowed by the directive
15365 is a bitmask in MASK. Return the list of clauses found.
15366 FINISH_P set if c_finish_omp_clauses should be called.
15367 NESTED non-zero if clauses should be terminated by closing paren instead
15368 of end of pragma. If it is 2, additionally commas are required in between
15372 c_parser_omp_all_clauses (c_parser
*parser
, omp_clause_mask mask
,
15373 const char *where
, bool finish_p
= true,
15376 tree clauses
= NULL
;
15379 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
15382 pragma_omp_clause c_kind
;
15383 const char *c_name
;
15384 tree prev
= clauses
;
15386 if (nested
&& c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
15391 if (c_parser_next_token_is (parser
, CPP_COMMA
))
15392 c_parser_consume_token (parser
);
15393 else if (nested
== 2)
15394 error_at (c_parser_peek_token (parser
)->location
,
15395 "clauses in %<simd%> trait should be separated "
15399 here
= c_parser_peek_token (parser
)->location
;
15400 c_kind
= c_parser_omp_clause_name (parser
);
15404 case PRAGMA_OMP_CLAUSE_BIND
:
15405 clauses
= c_parser_omp_clause_bind (parser
, clauses
);
15408 case PRAGMA_OMP_CLAUSE_COLLAPSE
:
15409 clauses
= c_parser_omp_clause_collapse (parser
, clauses
);
15410 c_name
= "collapse";
15412 case PRAGMA_OMP_CLAUSE_COPYIN
:
15413 clauses
= c_parser_omp_clause_copyin (parser
, clauses
);
15416 case PRAGMA_OMP_CLAUSE_COPYPRIVATE
:
15417 clauses
= c_parser_omp_clause_copyprivate (parser
, clauses
);
15418 c_name
= "copyprivate";
15420 case PRAGMA_OMP_CLAUSE_DEFAULT
:
15421 clauses
= c_parser_omp_clause_default (parser
, clauses
, false);
15422 c_name
= "default";
15424 case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE
:
15425 clauses
= c_parser_omp_clause_firstprivate (parser
, clauses
);
15426 c_name
= "firstprivate";
15428 case PRAGMA_OMP_CLAUSE_FINAL
:
15429 clauses
= c_parser_omp_clause_final (parser
, clauses
);
15432 case PRAGMA_OMP_CLAUSE_GRAINSIZE
:
15433 clauses
= c_parser_omp_clause_grainsize (parser
, clauses
);
15434 c_name
= "grainsize";
15436 case PRAGMA_OMP_CLAUSE_HINT
:
15437 clauses
= c_parser_omp_clause_hint (parser
, clauses
);
15440 case PRAGMA_OMP_CLAUSE_DEFAULTMAP
:
15441 clauses
= c_parser_omp_clause_defaultmap (parser
, clauses
);
15442 c_name
= "defaultmap";
15444 case PRAGMA_OMP_CLAUSE_IF
:
15445 clauses
= c_parser_omp_clause_if (parser
, clauses
, true);
15448 case PRAGMA_OMP_CLAUSE_IN_REDUCTION
:
15450 = c_parser_omp_clause_reduction (parser
, OMP_CLAUSE_IN_REDUCTION
,
15452 c_name
= "in_reduction";
15454 case PRAGMA_OMP_CLAUSE_LASTPRIVATE
:
15455 clauses
= c_parser_omp_clause_lastprivate (parser
, clauses
);
15456 c_name
= "lastprivate";
15458 case PRAGMA_OMP_CLAUSE_MERGEABLE
:
15459 clauses
= c_parser_omp_clause_mergeable (parser
, clauses
);
15460 c_name
= "mergeable";
15462 case PRAGMA_OMP_CLAUSE_NOWAIT
:
15463 clauses
= c_parser_omp_clause_nowait (parser
, clauses
);
15466 case PRAGMA_OMP_CLAUSE_NUM_TASKS
:
15467 clauses
= c_parser_omp_clause_num_tasks (parser
, clauses
);
15468 c_name
= "num_tasks";
15470 case PRAGMA_OMP_CLAUSE_NUM_THREADS
:
15471 clauses
= c_parser_omp_clause_num_threads (parser
, clauses
);
15472 c_name
= "num_threads";
15474 case PRAGMA_OMP_CLAUSE_ORDER
:
15475 clauses
= c_parser_omp_clause_order (parser
, clauses
);
15478 case PRAGMA_OMP_CLAUSE_ORDERED
:
15479 clauses
= c_parser_omp_clause_ordered (parser
, clauses
);
15480 c_name
= "ordered";
15482 case PRAGMA_OMP_CLAUSE_PRIORITY
:
15483 clauses
= c_parser_omp_clause_priority (parser
, clauses
);
15484 c_name
= "priority";
15486 case PRAGMA_OMP_CLAUSE_PRIVATE
:
15487 clauses
= c_parser_omp_clause_private (parser
, clauses
);
15488 c_name
= "private";
15490 case PRAGMA_OMP_CLAUSE_REDUCTION
:
15492 = c_parser_omp_clause_reduction (parser
, OMP_CLAUSE_REDUCTION
,
15494 c_name
= "reduction";
15496 case PRAGMA_OMP_CLAUSE_SCHEDULE
:
15497 clauses
= c_parser_omp_clause_schedule (parser
, clauses
);
15498 c_name
= "schedule";
15500 case PRAGMA_OMP_CLAUSE_SHARED
:
15501 clauses
= c_parser_omp_clause_shared (parser
, clauses
);
15504 case PRAGMA_OMP_CLAUSE_TASK_REDUCTION
:
15506 = c_parser_omp_clause_reduction (parser
, OMP_CLAUSE_TASK_REDUCTION
,
15508 c_name
= "task_reduction";
15510 case PRAGMA_OMP_CLAUSE_UNTIED
:
15511 clauses
= c_parser_omp_clause_untied (parser
, clauses
);
15514 case PRAGMA_OMP_CLAUSE_INBRANCH
:
15515 clauses
= c_parser_omp_clause_branch (parser
, OMP_CLAUSE_INBRANCH
,
15517 c_name
= "inbranch";
15519 case PRAGMA_OMP_CLAUSE_NONTEMPORAL
:
15520 clauses
= c_parser_omp_clause_nontemporal (parser
, clauses
);
15521 c_name
= "nontemporal";
15523 case PRAGMA_OMP_CLAUSE_NOTINBRANCH
:
15524 clauses
= c_parser_omp_clause_branch (parser
, OMP_CLAUSE_NOTINBRANCH
,
15526 c_name
= "notinbranch";
15528 case PRAGMA_OMP_CLAUSE_PARALLEL
:
15530 = c_parser_omp_clause_cancelkind (parser
, OMP_CLAUSE_PARALLEL
,
15532 c_name
= "parallel";
15536 error_at (here
, "%qs must be the first clause of %qs",
15541 case PRAGMA_OMP_CLAUSE_FOR
:
15543 = c_parser_omp_clause_cancelkind (parser
, OMP_CLAUSE_FOR
,
15547 goto clause_not_first
;
15549 case PRAGMA_OMP_CLAUSE_SECTIONS
:
15551 = c_parser_omp_clause_cancelkind (parser
, OMP_CLAUSE_SECTIONS
,
15553 c_name
= "sections";
15555 goto clause_not_first
;
15557 case PRAGMA_OMP_CLAUSE_TASKGROUP
:
15559 = c_parser_omp_clause_cancelkind (parser
, OMP_CLAUSE_TASKGROUP
,
15561 c_name
= "taskgroup";
15563 goto clause_not_first
;
15565 case PRAGMA_OMP_CLAUSE_LINK
:
15567 = c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_LINK
, clauses
);
15570 case PRAGMA_OMP_CLAUSE_TO
:
15571 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_LINK
)) != 0)
15573 = c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_TO_DECLARE
,
15576 clauses
= c_parser_omp_clause_to (parser
, clauses
);
15579 case PRAGMA_OMP_CLAUSE_FROM
:
15580 clauses
= c_parser_omp_clause_from (parser
, clauses
);
15583 case PRAGMA_OMP_CLAUSE_UNIFORM
:
15584 clauses
= c_parser_omp_clause_uniform (parser
, clauses
);
15585 c_name
= "uniform";
15587 case PRAGMA_OMP_CLAUSE_NUM_TEAMS
:
15588 clauses
= c_parser_omp_clause_num_teams (parser
, clauses
);
15589 c_name
= "num_teams";
15591 case PRAGMA_OMP_CLAUSE_THREAD_LIMIT
:
15592 clauses
= c_parser_omp_clause_thread_limit (parser
, clauses
);
15593 c_name
= "thread_limit";
15595 case PRAGMA_OMP_CLAUSE_ALIGNED
:
15596 clauses
= c_parser_omp_clause_aligned (parser
, clauses
);
15597 c_name
= "aligned";
15599 case PRAGMA_OMP_CLAUSE_LINEAR
:
15600 clauses
= c_parser_omp_clause_linear (parser
, clauses
);
15603 case PRAGMA_OMP_CLAUSE_DEPEND
:
15604 clauses
= c_parser_omp_clause_depend (parser
, clauses
);
15607 case PRAGMA_OMP_CLAUSE_MAP
:
15608 clauses
= c_parser_omp_clause_map (parser
, clauses
);
15611 case PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR
:
15612 clauses
= c_parser_omp_clause_use_device_ptr (parser
, clauses
);
15613 c_name
= "use_device_ptr";
15615 case PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR
:
15616 clauses
= c_parser_omp_clause_use_device_addr (parser
, clauses
);
15617 c_name
= "use_device_addr";
15619 case PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR
:
15620 clauses
= c_parser_omp_clause_is_device_ptr (parser
, clauses
);
15621 c_name
= "is_device_ptr";
15623 case PRAGMA_OMP_CLAUSE_DEVICE
:
15624 clauses
= c_parser_omp_clause_device (parser
, clauses
);
15627 case PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
:
15628 clauses
= c_parser_omp_clause_dist_schedule (parser
, clauses
);
15629 c_name
= "dist_schedule";
15631 case PRAGMA_OMP_CLAUSE_PROC_BIND
:
15632 clauses
= c_parser_omp_clause_proc_bind (parser
, clauses
);
15633 c_name
= "proc_bind";
15635 case PRAGMA_OMP_CLAUSE_DEVICE_TYPE
:
15636 clauses
= c_parser_omp_clause_device_type (parser
, clauses
);
15637 c_name
= "device_type";
15639 case PRAGMA_OMP_CLAUSE_SAFELEN
:
15640 clauses
= c_parser_omp_clause_safelen (parser
, clauses
);
15641 c_name
= "safelen";
15643 case PRAGMA_OMP_CLAUSE_SIMDLEN
:
15644 clauses
= c_parser_omp_clause_simdlen (parser
, clauses
);
15645 c_name
= "simdlen";
15647 case PRAGMA_OMP_CLAUSE_NOGROUP
:
15648 clauses
= c_parser_omp_clause_nogroup (parser
, clauses
);
15649 c_name
= "nogroup";
15651 case PRAGMA_OMP_CLAUSE_THREADS
:
15653 = c_parser_omp_clause_orderedkind (parser
, OMP_CLAUSE_THREADS
,
15655 c_name
= "threads";
15657 case PRAGMA_OMP_CLAUSE_SIMD
:
15659 = c_parser_omp_clause_orderedkind (parser
, OMP_CLAUSE_SIMD
,
15664 c_parser_error (parser
, "expected %<#pragma omp%> clause");
15670 if (((mask
>> c_kind
) & 1) == 0)
15672 /* Remove the invalid clause(s) from the list to avoid
15673 confusing the rest of the compiler. */
15675 error_at (here
, "%qs is not valid for %qs", c_name
, where
);
15681 c_parser_skip_to_pragma_eol (parser
);
15685 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_UNIFORM
)) != 0)
15686 return c_finish_omp_clauses (clauses
, C_ORT_OMP_DECLARE_SIMD
);
15687 return c_finish_omp_clauses (clauses
, C_ORT_OMP
);
15693 /* OpenACC 2.0, OpenMP 2.5:
15697 In practice, we're also interested in adding the statement to an
15698 outer node. So it is convenient if we work around the fact that
15699 c_parser_statement calls add_stmt. */
15702 c_parser_omp_structured_block (c_parser
*parser
, bool *if_p
)
15704 tree stmt
= push_stmt_list ();
15705 c_parser_statement (parser
, if_p
);
15706 return pop_stmt_list (stmt
);
15710 # pragma acc cache (variable-list) new-line
15712 LOC is the location of the #pragma token.
15716 c_parser_oacc_cache (location_t loc
, c_parser
*parser
)
15718 tree stmt
, clauses
;
15720 clauses
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE__CACHE_
, NULL
);
15721 clauses
= c_finish_omp_clauses (clauses
, C_ORT_ACC
);
15723 c_parser_skip_to_pragma_eol (parser
);
15725 stmt
= make_node (OACC_CACHE
);
15726 TREE_TYPE (stmt
) = void_type_node
;
15727 OACC_CACHE_CLAUSES (stmt
) = clauses
;
15728 SET_EXPR_LOCATION (stmt
, loc
);
15735 # pragma acc data oacc-data-clause[optseq] new-line
15738 LOC is the location of the #pragma token.
15741 #define OACC_DATA_CLAUSE_MASK \
15742 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
15743 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
15744 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
15745 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
15746 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
15747 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
15748 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
15751 c_parser_oacc_data (location_t loc
, c_parser
*parser
, bool *if_p
)
15753 tree stmt
, clauses
, block
;
15755 clauses
= c_parser_oacc_all_clauses (parser
, OACC_DATA_CLAUSE_MASK
,
15756 "#pragma acc data");
15758 block
= c_begin_omp_parallel ();
15759 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
15761 stmt
= c_finish_oacc_data (loc
, clauses
, block
);
15767 # pragma acc declare oacc-data-clause[optseq] new-line
15770 #define OACC_DECLARE_CLAUSE_MASK \
15771 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
15772 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
15773 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
15774 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
15775 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
15776 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT) \
15777 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_LINK) \
15778 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
15781 c_parser_oacc_declare (c_parser
*parser
)
15783 location_t pragma_loc
= c_parser_peek_token (parser
)->location
;
15784 tree clauses
, stmt
, t
, decl
;
15786 bool error
= false;
15788 c_parser_consume_pragma (parser
);
15790 clauses
= c_parser_oacc_all_clauses (parser
, OACC_DECLARE_CLAUSE_MASK
,
15791 "#pragma acc declare");
15794 error_at (pragma_loc
,
15795 "no valid clauses specified in %<#pragma acc declare%>");
15799 for (t
= clauses
; t
; t
= OMP_CLAUSE_CHAIN (t
))
15801 location_t loc
= OMP_CLAUSE_LOCATION (t
);
15802 decl
= OMP_CLAUSE_DECL (t
);
15803 if (!DECL_P (decl
))
15805 error_at (loc
, "array section in %<#pragma acc declare%>");
15810 switch (OMP_CLAUSE_MAP_KIND (t
))
15812 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
15813 case GOMP_MAP_ALLOC
:
15815 case GOMP_MAP_FORCE_DEVICEPTR
:
15816 case GOMP_MAP_DEVICE_RESIDENT
:
15819 case GOMP_MAP_LINK
:
15820 if (!global_bindings_p ()
15821 && (TREE_STATIC (decl
)
15822 || !DECL_EXTERNAL (decl
)))
15825 "%qD must be a global variable in "
15826 "%<#pragma acc declare link%>",
15834 if (global_bindings_p ())
15836 error_at (loc
, "invalid OpenACC clause at file scope");
15840 if (DECL_EXTERNAL (decl
))
15843 "invalid use of %<extern%> variable %qD "
15844 "in %<#pragma acc declare%>", decl
);
15848 else if (TREE_PUBLIC (decl
))
15851 "invalid use of %<global%> variable %qD "
15852 "in %<#pragma acc declare%>", decl
);
15859 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl
))
15860 || lookup_attribute ("omp declare target link",
15861 DECL_ATTRIBUTES (decl
)))
15863 error_at (loc
, "variable %qD used more than once with "
15864 "%<#pragma acc declare%>", decl
);
15873 if (OMP_CLAUSE_MAP_KIND (t
) == GOMP_MAP_LINK
)
15874 id
= get_identifier ("omp declare target link");
15876 id
= get_identifier ("omp declare target");
15878 DECL_ATTRIBUTES (decl
)
15879 = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (decl
));
15881 if (global_bindings_p ())
15883 symtab_node
*node
= symtab_node::get (decl
);
15886 node
->offloadable
= 1;
15887 if (ENABLE_OFFLOADING
)
15889 g
->have_offload
= true;
15890 if (is_a
<varpool_node
*> (node
))
15891 vec_safe_push (offload_vars
, decl
);
15898 if (error
|| global_bindings_p ())
15901 stmt
= make_node (OACC_DECLARE
);
15902 TREE_TYPE (stmt
) = void_type_node
;
15903 OACC_DECLARE_CLAUSES (stmt
) = clauses
;
15904 SET_EXPR_LOCATION (stmt
, pragma_loc
);
15912 # pragma acc enter data oacc-enter-data-clause[optseq] new-line
15916 # pragma acc exit data oacc-exit-data-clause[optseq] new-line
15919 LOC is the location of the #pragma token.
15922 #define OACC_ENTER_DATA_CLAUSE_MASK \
15923 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
15924 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
15925 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
15926 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
15927 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
15929 #define OACC_EXIT_DATA_CLAUSE_MASK \
15930 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
15931 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
15932 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
15933 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DELETE) \
15934 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FINALIZE) \
15935 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
15938 c_parser_oacc_enter_exit_data (c_parser
*parser
, bool enter
)
15940 location_t loc
= c_parser_peek_token (parser
)->location
;
15941 tree clauses
, stmt
;
15942 const char *p
= "";
15944 c_parser_consume_pragma (parser
);
15946 if (c_parser_next_token_is (parser
, CPP_NAME
))
15948 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
15949 c_parser_consume_token (parser
);
15952 if (strcmp (p
, "data") != 0)
15954 error_at (loc
, "expected %<data%> after %<#pragma acc %s%>",
15955 enter
? "enter" : "exit");
15956 parser
->error
= true;
15957 c_parser_skip_to_pragma_eol (parser
);
15962 clauses
= c_parser_oacc_all_clauses (parser
, OACC_ENTER_DATA_CLAUSE_MASK
,
15963 "#pragma acc enter data");
15965 clauses
= c_parser_oacc_all_clauses (parser
, OACC_EXIT_DATA_CLAUSE_MASK
,
15966 "#pragma acc exit data");
15968 if (omp_find_clause (clauses
, OMP_CLAUSE_MAP
) == NULL_TREE
)
15970 error_at (loc
, "%<#pragma acc %s data%> has no data movement clause",
15971 enter
? "enter" : "exit");
15975 stmt
= enter
? make_node (OACC_ENTER_DATA
) : make_node (OACC_EXIT_DATA
);
15976 TREE_TYPE (stmt
) = void_type_node
;
15977 OMP_STANDALONE_CLAUSES (stmt
) = clauses
;
15978 SET_EXPR_LOCATION (stmt
, loc
);
15984 # pragma acc host_data oacc-data-clause[optseq] new-line
15988 #define OACC_HOST_DATA_CLAUSE_MASK \
15989 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_USE_DEVICE) )
15992 c_parser_oacc_host_data (location_t loc
, c_parser
*parser
, bool *if_p
)
15994 tree stmt
, clauses
, block
;
15996 clauses
= c_parser_oacc_all_clauses (parser
, OACC_HOST_DATA_CLAUSE_MASK
,
15997 "#pragma acc host_data");
15999 block
= c_begin_omp_parallel ();
16000 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
16001 stmt
= c_finish_oacc_host_data (loc
, clauses
, block
);
16008 # pragma acc loop oacc-loop-clause[optseq] new-line
16011 LOC is the location of the #pragma token.
16014 #define OACC_LOOP_CLAUSE_MASK \
16015 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COLLAPSE) \
16016 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
16017 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
16018 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
16019 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
16020 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
16021 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_AUTO) \
16022 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_INDEPENDENT) \
16023 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \
16024 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_TILE) )
16026 c_parser_oacc_loop (location_t loc
, c_parser
*parser
, char *p_name
,
16027 omp_clause_mask mask
, tree
*cclauses
, bool *if_p
)
16029 bool is_parallel
= ((mask
>> PRAGMA_OACC_CLAUSE_REDUCTION
) & 1) == 1;
16031 strcat (p_name
, " loop");
16032 mask
|= OACC_LOOP_CLAUSE_MASK
;
16034 tree clauses
= c_parser_oacc_all_clauses (parser
, mask
, p_name
,
16038 clauses
= c_oacc_split_loop_clauses (clauses
, cclauses
, is_parallel
);
16040 *cclauses
= c_finish_omp_clauses (*cclauses
, C_ORT_ACC
);
16042 clauses
= c_finish_omp_clauses (clauses
, C_ORT_ACC
);
16045 tree block
= c_begin_compound_stmt (true);
16046 tree stmt
= c_parser_omp_for_loop (loc
, parser
, OACC_LOOP
, clauses
, NULL
,
16048 block
= c_end_compound_stmt (loc
, block
, true);
16055 # pragma acc kernels oacc-kernels-clause[optseq] new-line
16060 # pragma acc parallel oacc-parallel-clause[optseq] new-line
16063 LOC is the location of the #pragma token.
16066 #define OACC_KERNELS_CLAUSE_MASK \
16067 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
16068 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
16069 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
16070 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
16071 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
16072 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
16073 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
16074 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
16075 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
16076 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
16077 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
16078 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
16079 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
16081 #define OACC_PARALLEL_CLAUSE_MASK \
16082 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
16083 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
16084 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
16085 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
16086 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
16087 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
16088 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
16089 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
16090 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
16091 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
16092 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
16093 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
16094 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
16095 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
16096 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
16097 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
16100 c_parser_oacc_kernels_parallel (location_t loc
, c_parser
*parser
,
16101 enum pragma_kind p_kind
, char *p_name
,
16104 omp_clause_mask mask
;
16105 enum tree_code code
;
16108 case PRAGMA_OACC_KERNELS
:
16109 strcat (p_name
, " kernels");
16110 mask
= OACC_KERNELS_CLAUSE_MASK
;
16111 code
= OACC_KERNELS
;
16113 case PRAGMA_OACC_PARALLEL
:
16114 strcat (p_name
, " parallel");
16115 mask
= OACC_PARALLEL_CLAUSE_MASK
;
16116 code
= OACC_PARALLEL
;
16119 gcc_unreachable ();
16122 if (c_parser_next_token_is (parser
, CPP_NAME
))
16124 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
16125 if (strcmp (p
, "loop") == 0)
16127 c_parser_consume_token (parser
);
16128 tree block
= c_begin_omp_parallel ();
16130 c_parser_oacc_loop (loc
, parser
, p_name
, mask
, &clauses
, if_p
);
16131 return c_finish_omp_construct (loc
, code
, block
, clauses
);
16135 tree clauses
= c_parser_oacc_all_clauses (parser
, mask
, p_name
);
16137 tree block
= c_begin_omp_parallel ();
16138 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
16140 return c_finish_omp_construct (loc
, code
, block
, clauses
);
16144 # pragma acc routine oacc-routine-clause[optseq] new-line
16145 function-definition
16147 # pragma acc routine ( name ) oacc-routine-clause[optseq] new-line
16150 #define OACC_ROUTINE_CLAUSE_MASK \
16151 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
16152 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
16153 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
16154 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) )
16156 /* Parse an OpenACC routine directive. For named directives, we apply
16157 immediately to the named function. For unnamed ones we then parse
16158 a declaration or definition, which must be for a function. */
16161 c_parser_oacc_routine (c_parser
*parser
, enum pragma_context context
)
16163 gcc_checking_assert (context
== pragma_external
);
16165 oacc_routine_data data
;
16166 data
.error_seen
= false;
16167 data
.fndecl_seen
= false;
16168 data
.clauses
= NULL_TREE
;
16169 data
.loc
= c_parser_peek_token (parser
)->location
;
16171 c_parser_consume_pragma (parser
);
16173 /* Look for optional '( name )'. */
16174 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
16176 c_parser_consume_token (parser
); /* '(' */
16178 tree decl
= NULL_TREE
;
16179 c_token
*name_token
= c_parser_peek_token (parser
);
16180 location_t name_loc
= name_token
->location
;
16181 if (name_token
->type
== CPP_NAME
16182 && (name_token
->id_kind
== C_ID_ID
16183 || name_token
->id_kind
== C_ID_TYPENAME
))
16185 decl
= lookup_name (name_token
->value
);
16187 error_at (name_loc
,
16188 "%qE has not been declared", name_token
->value
);
16189 c_parser_consume_token (parser
);
16192 c_parser_error (parser
, "expected function name");
16195 || !c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
16197 c_parser_skip_to_pragma_eol (parser
, false);
16202 = c_parser_oacc_all_clauses (parser
, OACC_ROUTINE_CLAUSE_MASK
,
16203 "#pragma acc routine");
16204 /* The clauses are in reverse order; fix that to make later diagnostic
16205 emission easier. */
16206 data
.clauses
= nreverse (data
.clauses
);
16208 if (TREE_CODE (decl
) != FUNCTION_DECL
)
16210 error_at (name_loc
, "%qD does not refer to a function", decl
);
16214 c_finish_oacc_routine (&data
, decl
, false);
16216 else /* No optional '( name )'. */
16219 = c_parser_oacc_all_clauses (parser
, OACC_ROUTINE_CLAUSE_MASK
,
16220 "#pragma acc routine");
16221 /* The clauses are in reverse order; fix that to make later diagnostic
16222 emission easier. */
16223 data
.clauses
= nreverse (data
.clauses
);
16225 /* Emit a helpful diagnostic if there's another pragma following this
16226 one. Also don't allow a static assertion declaration, as in the
16227 following we'll just parse a *single* "declaration or function
16228 definition", and the static assertion counts an one. */
16229 if (c_parser_next_token_is (parser
, CPP_PRAGMA
)
16230 || c_parser_next_token_is_keyword (parser
, RID_STATIC_ASSERT
))
16232 error_at (data
.loc
,
16233 "%<#pragma acc routine%> not immediately followed by"
16234 " function declaration or definition");
16235 /* ..., and then just keep going. */
16239 /* We only have to consider the pragma_external case here. */
16240 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
16241 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
)
16243 int ext
= disable_extension_diagnostics ();
16245 c_parser_consume_token (parser
);
16246 while (c_parser_next_token_is (parser
, CPP_KEYWORD
)
16247 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
);
16248 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
16249 NULL
, vNULL
, &data
);
16250 restore_extension_diagnostics (ext
);
16253 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
16254 NULL
, vNULL
, &data
);
16258 /* Finalize an OpenACC routine pragma, applying it to FNDECL.
16259 IS_DEFN is true if we're applying it to the definition. */
16262 c_finish_oacc_routine (struct oacc_routine_data
*data
, tree fndecl
,
16265 /* Keep going if we're in error reporting mode. */
16266 if (data
->error_seen
16267 || fndecl
== error_mark_node
)
16270 if (data
->fndecl_seen
)
16272 error_at (data
->loc
,
16273 "%<#pragma acc routine%> not immediately followed by"
16274 " a single function declaration or definition");
16275 data
->error_seen
= true;
16278 if (fndecl
== NULL_TREE
|| TREE_CODE (fndecl
) != FUNCTION_DECL
)
16280 error_at (data
->loc
,
16281 "%<#pragma acc routine%> not immediately followed by"
16282 " function declaration or definition");
16283 data
->error_seen
= true;
16288 = oacc_verify_routine_clauses (fndecl
, &data
->clauses
, data
->loc
,
16289 "#pragma acc routine");
16290 if (compatible
< 0)
16292 data
->error_seen
= true;
16295 if (compatible
> 0)
16300 if (TREE_USED (fndecl
) || (!is_defn
&& DECL_SAVED_TREE (fndecl
)))
16302 error_at (data
->loc
,
16304 ? G_("%<#pragma acc routine%> must be applied before use")
16305 : G_("%<#pragma acc routine%> must be applied before"
16307 data
->error_seen
= true;
16311 /* Set the routine's level of parallelism. */
16312 tree dims
= oacc_build_routine_dims (data
->clauses
);
16313 oacc_replace_fn_attrib (fndecl
, dims
);
16315 /* Add an "omp declare target" attribute. */
16316 DECL_ATTRIBUTES (fndecl
)
16317 = tree_cons (get_identifier ("omp declare target"),
16318 data
->clauses
, DECL_ATTRIBUTES (fndecl
));
16321 /* Remember that we've used this "#pragma acc routine". */
16322 data
->fndecl_seen
= true;
16326 # pragma acc update oacc-update-clause[optseq] new-line
16329 #define OACC_UPDATE_CLAUSE_MASK \
16330 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
16331 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE) \
16332 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_HOST) \
16333 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
16334 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) \
16335 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
16338 c_parser_oacc_update (c_parser
*parser
)
16340 location_t loc
= c_parser_peek_token (parser
)->location
;
16342 c_parser_consume_pragma (parser
);
16344 tree clauses
= c_parser_oacc_all_clauses (parser
, OACC_UPDATE_CLAUSE_MASK
,
16345 "#pragma acc update");
16346 if (omp_find_clause (clauses
, OMP_CLAUSE_MAP
) == NULL_TREE
)
16349 "%<#pragma acc update%> must contain at least one "
16350 "%<device%> or %<host%> or %<self%> clause");
16357 tree stmt
= make_node (OACC_UPDATE
);
16358 TREE_TYPE (stmt
) = void_type_node
;
16359 OACC_UPDATE_CLAUSES (stmt
) = clauses
;
16360 SET_EXPR_LOCATION (stmt
, loc
);
16365 # pragma acc wait [(intseq)] oacc-wait-clause[optseq] new-line
16367 LOC is the location of the #pragma token.
16370 #define OACC_WAIT_CLAUSE_MASK \
16371 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) )
16374 c_parser_oacc_wait (location_t loc
, c_parser
*parser
, char *p_name
)
16376 tree clauses
, list
= NULL_TREE
, stmt
= NULL_TREE
;
16378 if (c_parser_peek_token (parser
)->type
== CPP_OPEN_PAREN
)
16379 list
= c_parser_oacc_wait_list (parser
, loc
, list
);
16381 strcpy (p_name
, " wait");
16382 clauses
= c_parser_oacc_all_clauses (parser
, OACC_WAIT_CLAUSE_MASK
, p_name
);
16383 stmt
= c_finish_oacc_wait (loc
, list
, clauses
);
16390 # pragma omp atomic new-line
16394 x binop= expr | x++ | ++x | x-- | --x
16396 +, *, -, /, &, ^, |, <<, >>
16398 where x is an lvalue expression with scalar type.
16401 # pragma omp atomic new-line
16404 # pragma omp atomic read new-line
16407 # pragma omp atomic write new-line
16410 # pragma omp atomic update new-line
16413 # pragma omp atomic capture new-line
16416 # pragma omp atomic capture new-line
16424 expression-stmt | x = x binop expr
16426 v = expression-stmt
16428 { v = x; update-stmt; } | { update-stmt; v = x; }
16432 expression-stmt | x = x binop expr | x = expr binop x
16436 { v = x; update-stmt; } | { update-stmt; v = x; } | { v = x; x = expr; }
16438 where x and v are lvalue expressions with scalar type.
16440 LOC is the location of the #pragma token. */
16443 c_parser_omp_atomic (location_t loc
, c_parser
*parser
)
16445 tree lhs
= NULL_TREE
, rhs
= NULL_TREE
, v
= NULL_TREE
;
16446 tree lhs1
= NULL_TREE
, rhs1
= NULL_TREE
;
16447 tree stmt
, orig_lhs
, unfolded_lhs
= NULL_TREE
, unfolded_lhs1
= NULL_TREE
;
16448 enum tree_code code
= ERROR_MARK
, opcode
= NOP_EXPR
;
16449 enum omp_memory_order memory_order
= OMP_MEMORY_ORDER_UNSPECIFIED
;
16450 struct c_expr expr
;
16452 bool structured_block
= false;
16453 bool swapped
= false;
16456 tree clauses
= NULL_TREE
;
16458 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
16460 if (!first
&& c_parser_next_token_is (parser
, CPP_COMMA
))
16461 c_parser_consume_token (parser
);
16465 if (c_parser_next_token_is (parser
, CPP_NAME
))
16468 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
16469 location_t cloc
= c_parser_peek_token (parser
)->location
;
16470 enum tree_code new_code
= ERROR_MARK
;
16471 enum omp_memory_order new_memory_order
16472 = OMP_MEMORY_ORDER_UNSPECIFIED
;
16474 if (!strcmp (p
, "read"))
16475 new_code
= OMP_ATOMIC_READ
;
16476 else if (!strcmp (p
, "write"))
16477 new_code
= NOP_EXPR
;
16478 else if (!strcmp (p
, "update"))
16479 new_code
= OMP_ATOMIC
;
16480 else if (!strcmp (p
, "capture"))
16481 new_code
= OMP_ATOMIC_CAPTURE_NEW
;
16482 else if (!strcmp (p
, "seq_cst"))
16483 new_memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
16484 else if (!strcmp (p
, "acq_rel"))
16485 new_memory_order
= OMP_MEMORY_ORDER_ACQ_REL
;
16486 else if (!strcmp (p
, "release"))
16487 new_memory_order
= OMP_MEMORY_ORDER_RELEASE
;
16488 else if (!strcmp (p
, "acquire"))
16489 new_memory_order
= OMP_MEMORY_ORDER_ACQUIRE
;
16490 else if (!strcmp (p
, "relaxed"))
16491 new_memory_order
= OMP_MEMORY_ORDER_RELAXED
;
16492 else if (!strcmp (p
, "hint"))
16494 c_parser_consume_token (parser
);
16495 clauses
= c_parser_omp_clause_hint (parser
, clauses
);
16501 error_at (cloc
, "expected %<read%>, %<write%>, %<update%>, "
16502 "%<capture%>, %<seq_cst%>, %<acq_rel%>, "
16503 "%<release%>, %<relaxed%> or %<hint%> clause");
16507 if (new_code
!= ERROR_MARK
)
16509 if (code
!= ERROR_MARK
)
16510 error_at (cloc
, "too many atomic clauses");
16514 else if (new_memory_order
!= OMP_MEMORY_ORDER_UNSPECIFIED
)
16516 if (memory_order
!= OMP_MEMORY_ORDER_UNSPECIFIED
)
16517 error_at (cloc
, "too many memory order clauses");
16519 memory_order
= new_memory_order
;
16521 c_parser_consume_token (parser
);
16527 c_parser_skip_to_pragma_eol (parser
);
16529 if (code
== ERROR_MARK
)
16531 if (memory_order
== OMP_MEMORY_ORDER_UNSPECIFIED
)
16534 = (enum omp_requires
) (omp_requires_mask
16535 | OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED
);
16536 switch ((enum omp_memory_order
)
16537 (omp_requires_mask
& OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
))
16539 case OMP_MEMORY_ORDER_UNSPECIFIED
:
16540 case OMP_MEMORY_ORDER_RELAXED
:
16541 memory_order
= OMP_MEMORY_ORDER_RELAXED
;
16543 case OMP_MEMORY_ORDER_SEQ_CST
:
16544 memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
16546 case OMP_MEMORY_ORDER_ACQ_REL
:
16549 case OMP_ATOMIC_READ
:
16550 memory_order
= OMP_MEMORY_ORDER_ACQUIRE
;
16552 case NOP_EXPR
: /* atomic write */
16554 memory_order
= OMP_MEMORY_ORDER_RELEASE
;
16557 memory_order
= OMP_MEMORY_ORDER_ACQ_REL
;
16562 gcc_unreachable ();
16568 case OMP_ATOMIC_READ
:
16569 if (memory_order
== OMP_MEMORY_ORDER_ACQ_REL
16570 || memory_order
== OMP_MEMORY_ORDER_RELEASE
)
16572 error_at (loc
, "%<#pragma omp atomic read%> incompatible with "
16573 "%<acq_rel%> or %<release%> clauses");
16574 memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
16577 case NOP_EXPR
: /* atomic write */
16578 if (memory_order
== OMP_MEMORY_ORDER_ACQ_REL
16579 || memory_order
== OMP_MEMORY_ORDER_ACQUIRE
)
16581 error_at (loc
, "%<#pragma omp atomic write%> incompatible with "
16582 "%<acq_rel%> or %<acquire%> clauses");
16583 memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
16587 if (memory_order
== OMP_MEMORY_ORDER_ACQ_REL
16588 || memory_order
== OMP_MEMORY_ORDER_ACQUIRE
)
16590 error_at (loc
, "%<#pragma omp atomic update%> incompatible with "
16591 "%<acq_rel%> or %<acquire%> clauses");
16592 memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
16601 case OMP_ATOMIC_READ
:
16602 case NOP_EXPR
: /* atomic write */
16603 v
= c_parser_cast_expression (parser
, NULL
).value
;
16604 non_lvalue_p
= !lvalue_p (v
);
16605 v
= c_fully_fold (v
, false, NULL
, true);
16606 if (v
== error_mark_node
)
16609 v
= non_lvalue (v
);
16610 loc
= c_parser_peek_token (parser
)->location
;
16611 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
16613 if (code
== NOP_EXPR
)
16615 lhs
= c_parser_expression (parser
).value
;
16616 lhs
= c_fully_fold (lhs
, false, NULL
);
16617 if (lhs
== error_mark_node
)
16622 lhs
= c_parser_cast_expression (parser
, NULL
).value
;
16623 non_lvalue_p
= !lvalue_p (lhs
);
16624 lhs
= c_fully_fold (lhs
, false, NULL
, true);
16625 if (lhs
== error_mark_node
)
16628 lhs
= non_lvalue (lhs
);
16630 if (code
== NOP_EXPR
)
16632 /* atomic write is represented by OMP_ATOMIC with NOP_EXPR
16640 case OMP_ATOMIC_CAPTURE_NEW
:
16641 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
16643 c_parser_consume_token (parser
);
16644 structured_block
= true;
16648 v
= c_parser_cast_expression (parser
, NULL
).value
;
16649 non_lvalue_p
= !lvalue_p (v
);
16650 v
= c_fully_fold (v
, false, NULL
, true);
16651 if (v
== error_mark_node
)
16654 v
= non_lvalue (v
);
16655 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
16663 /* For structured_block case we don't know yet whether
16664 old or new x should be captured. */
16666 eloc
= c_parser_peek_token (parser
)->location
;
16667 expr
= c_parser_cast_expression (parser
, NULL
);
16669 expr
= default_function_array_conversion (eloc
, expr
);
16670 unfolded_lhs
= expr
.value
;
16671 lhs
= c_fully_fold (lhs
, false, NULL
, true);
16673 switch (TREE_CODE (lhs
))
16677 c_parser_skip_to_end_of_block_or_statement (parser
);
16678 if (structured_block
)
16680 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
16681 c_parser_consume_token (parser
);
16682 else if (code
== OMP_ATOMIC_CAPTURE_NEW
)
16684 c_parser_skip_to_end_of_block_or_statement (parser
);
16685 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
16686 c_parser_consume_token (parser
);
16691 case POSTINCREMENT_EXPR
:
16692 if (code
== OMP_ATOMIC_CAPTURE_NEW
&& !structured_block
)
16693 code
= OMP_ATOMIC_CAPTURE_OLD
;
16695 case PREINCREMENT_EXPR
:
16696 lhs
= TREE_OPERAND (lhs
, 0);
16697 unfolded_lhs
= NULL_TREE
;
16698 opcode
= PLUS_EXPR
;
16699 rhs
= integer_one_node
;
16702 case POSTDECREMENT_EXPR
:
16703 if (code
== OMP_ATOMIC_CAPTURE_NEW
&& !structured_block
)
16704 code
= OMP_ATOMIC_CAPTURE_OLD
;
16706 case PREDECREMENT_EXPR
:
16707 lhs
= TREE_OPERAND (lhs
, 0);
16708 unfolded_lhs
= NULL_TREE
;
16709 opcode
= MINUS_EXPR
;
16710 rhs
= integer_one_node
;
16713 case COMPOUND_EXPR
:
16714 if (TREE_CODE (TREE_OPERAND (lhs
, 0)) == SAVE_EXPR
16715 && TREE_CODE (TREE_OPERAND (lhs
, 1)) == COMPOUND_EXPR
16716 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (lhs
, 1), 0)) == MODIFY_EXPR
16717 && TREE_OPERAND (TREE_OPERAND (lhs
, 1), 1) == TREE_OPERAND (lhs
, 0)
16718 && TREE_CODE (TREE_TYPE (TREE_OPERAND (TREE_OPERAND
16719 (TREE_OPERAND (lhs
, 1), 0), 0)))
16721 /* Undo effects of boolean_increment for post {in,de}crement. */
16722 lhs
= TREE_OPERAND (TREE_OPERAND (lhs
, 1), 0);
16725 if (TREE_CODE (lhs
) == MODIFY_EXPR
16726 && TREE_CODE (TREE_TYPE (TREE_OPERAND (lhs
, 0))) == BOOLEAN_TYPE
)
16728 /* Undo effects of boolean_increment. */
16729 if (integer_onep (TREE_OPERAND (lhs
, 1)))
16731 /* This is pre or post increment. */
16732 rhs
= TREE_OPERAND (lhs
, 1);
16733 lhs
= TREE_OPERAND (lhs
, 0);
16734 unfolded_lhs
= NULL_TREE
;
16736 if (code
== OMP_ATOMIC_CAPTURE_NEW
16737 && !structured_block
16738 && TREE_CODE (orig_lhs
) == COMPOUND_EXPR
)
16739 code
= OMP_ATOMIC_CAPTURE_OLD
;
16742 if (TREE_CODE (TREE_OPERAND (lhs
, 1)) == TRUTH_NOT_EXPR
16743 && TREE_OPERAND (lhs
, 0)
16744 == TREE_OPERAND (TREE_OPERAND (lhs
, 1), 0))
16746 /* This is pre or post decrement. */
16747 rhs
= TREE_OPERAND (lhs
, 1);
16748 lhs
= TREE_OPERAND (lhs
, 0);
16749 unfolded_lhs
= NULL_TREE
;
16751 if (code
== OMP_ATOMIC_CAPTURE_NEW
16752 && !structured_block
16753 && TREE_CODE (orig_lhs
) == COMPOUND_EXPR
)
16754 code
= OMP_ATOMIC_CAPTURE_OLD
;
16760 if (!lvalue_p (unfolded_lhs
))
16761 lhs
= non_lvalue (lhs
);
16762 switch (c_parser_peek_token (parser
)->type
)
16765 opcode
= MULT_EXPR
;
16768 opcode
= TRUNC_DIV_EXPR
;
16771 opcode
= PLUS_EXPR
;
16774 opcode
= MINUS_EXPR
;
16776 case CPP_LSHIFT_EQ
:
16777 opcode
= LSHIFT_EXPR
;
16779 case CPP_RSHIFT_EQ
:
16780 opcode
= RSHIFT_EXPR
;
16783 opcode
= BIT_AND_EXPR
;
16786 opcode
= BIT_IOR_EXPR
;
16789 opcode
= BIT_XOR_EXPR
;
16792 c_parser_consume_token (parser
);
16793 eloc
= c_parser_peek_token (parser
)->location
;
16794 expr
= c_parser_expr_no_commas (parser
, NULL
, unfolded_lhs
);
16796 switch (TREE_CODE (rhs1
))
16799 case TRUNC_DIV_EXPR
:
16808 if (c_tree_equal (TREE_OPERAND (rhs1
, 0), unfolded_lhs
))
16810 opcode
= TREE_CODE (rhs1
);
16811 rhs
= c_fully_fold (TREE_OPERAND (rhs1
, 1), false, NULL
,
16813 rhs1
= c_fully_fold (TREE_OPERAND (rhs1
, 0), false, NULL
,
16817 if (c_tree_equal (TREE_OPERAND (rhs1
, 1), unfolded_lhs
))
16819 opcode
= TREE_CODE (rhs1
);
16820 rhs
= c_fully_fold (TREE_OPERAND (rhs1
, 0), false, NULL
,
16822 rhs1
= c_fully_fold (TREE_OPERAND (rhs1
, 1), false, NULL
,
16824 swapped
= !commutative_tree_code (opcode
);
16833 if (c_parser_peek_token (parser
)->type
== CPP_SEMICOLON
)
16835 if (structured_block
&& code
== OMP_ATOMIC_CAPTURE_NEW
)
16837 code
= OMP_ATOMIC_CAPTURE_OLD
;
16840 expr
= default_function_array_read_conversion (eloc
, expr
);
16841 unfolded_lhs1
= expr
.value
;
16842 lhs1
= c_fully_fold (unfolded_lhs1
, false, NULL
, true);
16844 c_parser_consume_token (parser
);
16847 if (structured_block
)
16850 expr
= default_function_array_read_conversion (eloc
, expr
);
16851 rhs
= c_fully_fold (expr
.value
, false, NULL
, true);
16856 c_parser_error (parser
, "invalid form of %<#pragma omp atomic%>");
16859 c_parser_error (parser
,
16860 "invalid operator for %<#pragma omp atomic%>");
16864 /* Arrange to pass the location of the assignment operator to
16865 c_finish_omp_atomic. */
16866 loc
= c_parser_peek_token (parser
)->location
;
16867 c_parser_consume_token (parser
);
16868 eloc
= c_parser_peek_token (parser
)->location
;
16869 expr
= c_parser_expression (parser
);
16870 expr
= default_function_array_read_conversion (eloc
, expr
);
16872 rhs
= c_fully_fold (rhs
, false, NULL
, true);
16876 if (structured_block
&& code
== OMP_ATOMIC_CAPTURE_NEW
)
16878 if (!c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
16880 v
= c_parser_cast_expression (parser
, NULL
).value
;
16881 non_lvalue_p
= !lvalue_p (v
);
16882 v
= c_fully_fold (v
, false, NULL
, true);
16883 if (v
== error_mark_node
)
16886 v
= non_lvalue (v
);
16887 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
16889 eloc
= c_parser_peek_token (parser
)->location
;
16890 expr
= c_parser_cast_expression (parser
, NULL
);
16892 expr
= default_function_array_read_conversion (eloc
, expr
);
16893 unfolded_lhs1
= expr
.value
;
16894 lhs1
= c_fully_fold (lhs1
, false, NULL
, true);
16895 if (lhs1
== error_mark_node
)
16897 if (!lvalue_p (unfolded_lhs1
))
16898 lhs1
= non_lvalue (lhs1
);
16900 if (structured_block
)
16902 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
16903 c_parser_require (parser
, CPP_CLOSE_BRACE
, "expected %<}%>");
16906 if (unfolded_lhs
&& unfolded_lhs1
16907 && !c_tree_equal (unfolded_lhs
, unfolded_lhs1
))
16909 error ("%<#pragma omp atomic capture%> uses two different "
16910 "expressions for memory");
16911 stmt
= error_mark_node
;
16914 stmt
= c_finish_omp_atomic (loc
, code
, opcode
, lhs
, rhs
, v
, lhs1
, rhs1
,
16915 swapped
, memory_order
);
16916 if (stmt
!= error_mark_node
)
16919 if (!structured_block
)
16920 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
16925 # pragma omp barrier new-line
16929 c_parser_omp_barrier (c_parser
*parser
)
16931 location_t loc
= c_parser_peek_token (parser
)->location
;
16932 c_parser_consume_pragma (parser
);
16933 c_parser_skip_to_pragma_eol (parser
);
16935 c_finish_omp_barrier (loc
);
16939 # pragma omp critical [(name)] new-line
16943 # pragma omp critical [(name) [hint(expression)]] new-line
16945 LOC is the location of the #pragma itself. */
16947 #define OMP_CRITICAL_CLAUSE_MASK \
16948 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HINT) )
16951 c_parser_omp_critical (location_t loc
, c_parser
*parser
, bool *if_p
)
16953 tree stmt
, name
= NULL_TREE
, clauses
= NULL_TREE
;
16955 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
16957 c_parser_consume_token (parser
);
16958 if (c_parser_next_token_is (parser
, CPP_NAME
))
16960 name
= c_parser_peek_token (parser
)->value
;
16961 c_parser_consume_token (parser
);
16962 c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>");
16965 c_parser_error (parser
, "expected identifier");
16967 if (c_parser_next_token_is (parser
, CPP_COMMA
)
16968 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
16969 c_parser_consume_token (parser
);
16971 clauses
= c_parser_omp_all_clauses (parser
,
16972 OMP_CRITICAL_CLAUSE_MASK
,
16973 "#pragma omp critical");
16977 if (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
16978 c_parser_error (parser
, "expected %<(%> or end of line");
16979 c_parser_skip_to_pragma_eol (parser
);
16982 stmt
= c_parser_omp_structured_block (parser
, if_p
);
16983 return c_finish_omp_critical (loc
, stmt
, name
, clauses
);
16987 # pragma omp depobj ( depobj ) depobj-clause new-line
16990 depend (dependence-type : locator)
16992 update (dependence-type)
17001 c_parser_omp_depobj (c_parser
*parser
)
17003 location_t loc
= c_parser_peek_token (parser
)->location
;
17004 c_parser_consume_pragma (parser
);
17005 matching_parens parens
;
17006 if (!parens
.require_open (parser
))
17008 c_parser_skip_to_pragma_eol (parser
);
17012 tree depobj
= c_parser_expr_no_commas (parser
, NULL
).value
;
17013 if (depobj
!= error_mark_node
)
17015 if (!lvalue_p (depobj
))
17017 error_at (EXPR_LOC_OR_LOC (depobj
, loc
),
17018 "%<depobj%> expression is not lvalue expression");
17019 depobj
= error_mark_node
;
17023 tree addr
= build_unary_op (EXPR_LOC_OR_LOC (depobj
, loc
), ADDR_EXPR
,
17025 if (addr
== error_mark_node
)
17026 depobj
= error_mark_node
;
17028 depobj
= build_indirect_ref (EXPR_LOC_OR_LOC (depobj
, loc
),
17029 addr
, RO_UNARY_STAR
);
17033 parens
.skip_until_found_close (parser
);
17034 tree clause
= NULL_TREE
;
17035 enum omp_clause_depend_kind kind
= OMP_CLAUSE_DEPEND_SOURCE
;
17036 location_t c_loc
= c_parser_peek_token (parser
)->location
;
17037 if (c_parser_next_token_is (parser
, CPP_NAME
))
17039 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
17041 c_parser_consume_token (parser
);
17042 if (!strcmp ("depend", p
))
17044 clause
= c_parser_omp_clause_depend (parser
, NULL_TREE
);
17045 clause
= c_finish_omp_clauses (clause
, C_ORT_OMP
);
17047 clause
= error_mark_node
;
17049 else if (!strcmp ("destroy", p
))
17050 kind
= OMP_CLAUSE_DEPEND_LAST
;
17051 else if (!strcmp ("update", p
))
17053 matching_parens c_parens
;
17054 if (c_parens
.require_open (parser
))
17056 location_t c2_loc
= c_parser_peek_token (parser
)->location
;
17057 if (c_parser_next_token_is (parser
, CPP_NAME
))
17060 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
17062 c_parser_consume_token (parser
);
17063 if (!strcmp ("in", p2
))
17064 kind
= OMP_CLAUSE_DEPEND_IN
;
17065 else if (!strcmp ("out", p2
))
17066 kind
= OMP_CLAUSE_DEPEND_OUT
;
17067 else if (!strcmp ("inout", p2
))
17068 kind
= OMP_CLAUSE_DEPEND_INOUT
;
17069 else if (!strcmp ("mutexinoutset", p2
))
17070 kind
= OMP_CLAUSE_DEPEND_MUTEXINOUTSET
;
17072 if (kind
== OMP_CLAUSE_DEPEND_SOURCE
)
17074 clause
= error_mark_node
;
17075 error_at (c2_loc
, "expected %<in%>, %<out%>, %<inout%> or "
17076 "%<mutexinoutset%>");
17078 c_parens
.skip_until_found_close (parser
);
17081 clause
= error_mark_node
;
17084 if (!clause
&& kind
== OMP_CLAUSE_DEPEND_SOURCE
)
17086 clause
= error_mark_node
;
17087 error_at (c_loc
, "expected %<depend%>, %<destroy%> or %<update%> clause");
17089 c_parser_skip_to_pragma_eol (parser
);
17091 c_finish_omp_depobj (loc
, depobj
, kind
, clause
);
17096 # pragma omp flush flush-vars[opt] new-line
17102 # pragma omp flush memory-order-clause new-line */
17105 c_parser_omp_flush (c_parser
*parser
)
17107 location_t loc
= c_parser_peek_token (parser
)->location
;
17108 c_parser_consume_pragma (parser
);
17109 enum memmodel mo
= MEMMODEL_LAST
;
17110 if (c_parser_next_token_is (parser
, CPP_NAME
))
17113 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
17115 if (!strcmp (p
, "acq_rel"))
17116 mo
= MEMMODEL_ACQ_REL
;
17117 else if (!strcmp (p
, "release"))
17118 mo
= MEMMODEL_RELEASE
;
17119 else if (!strcmp (p
, "acquire"))
17120 mo
= MEMMODEL_ACQUIRE
;
17122 error_at (c_parser_peek_token (parser
)->location
,
17123 "expected %<acq_rel%>, %<release%> or %<acquire%>");
17124 c_parser_consume_token (parser
);
17126 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
17128 if (mo
!= MEMMODEL_LAST
)
17129 error_at (c_parser_peek_token (parser
)->location
,
17130 "%<flush%> list specified together with memory order "
17132 c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ERROR
, NULL
);
17134 else if (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
17135 c_parser_error (parser
, "expected %<(%> or end of line");
17136 c_parser_skip_to_pragma_eol (parser
);
17138 c_finish_omp_flush (loc
, mo
);
17144 { structured-block scan-directive structured-block } */
17147 c_parser_omp_scan_loop_body (c_parser
*parser
, bool open_brace_parsed
)
17151 tree clauses
= NULL_TREE
;
17153 loc
= c_parser_peek_token (parser
)->location
;
17154 if (!open_brace_parsed
17155 && !c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
17157 /* Avoid skipping until the end of the block. */
17158 parser
->error
= false;
17162 substmt
= c_parser_omp_structured_block (parser
, NULL
);
17163 substmt
= build2 (OMP_SCAN
, void_type_node
, substmt
, NULL_TREE
);
17164 SET_EXPR_LOCATION (substmt
, loc
);
17165 add_stmt (substmt
);
17167 loc
= c_parser_peek_token (parser
)->location
;
17168 if (c_parser_peek_token (parser
)->pragma_kind
== PRAGMA_OMP_SCAN
)
17170 enum omp_clause_code clause
= OMP_CLAUSE_ERROR
;
17172 c_parser_consume_pragma (parser
);
17174 if (c_parser_next_token_is (parser
, CPP_NAME
))
17177 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
17178 if (strcmp (p
, "inclusive") == 0)
17179 clause
= OMP_CLAUSE_INCLUSIVE
;
17180 else if (strcmp (p
, "exclusive") == 0)
17181 clause
= OMP_CLAUSE_EXCLUSIVE
;
17183 if (clause
!= OMP_CLAUSE_ERROR
)
17185 c_parser_consume_token (parser
);
17186 clauses
= c_parser_omp_var_list_parens (parser
, clause
, NULL_TREE
);
17189 c_parser_error (parser
, "expected %<inclusive%> or "
17190 "%<exclusive%> clause");
17191 c_parser_skip_to_pragma_eol (parser
);
17194 error ("expected %<#pragma omp scan%>");
17196 clauses
= c_finish_omp_clauses (clauses
, C_ORT_OMP
);
17197 substmt
= c_parser_omp_structured_block (parser
, NULL
);
17198 substmt
= build2 (OMP_SCAN
, void_type_node
, substmt
, clauses
);
17199 SET_EXPR_LOCATION (substmt
, loc
);
17200 add_stmt (substmt
);
17202 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
,
17206 /* Parse the restricted form of loop statements allowed by OpenACC and OpenMP.
17207 The real trick here is to determine the loop control variable early
17208 so that we can push a new decl if necessary to make it private.
17209 LOC is the location of the "acc" or "omp" in "#pragma acc" or "#pragma omp",
17213 c_parser_omp_for_loop (location_t loc
, c_parser
*parser
, enum tree_code code
,
17214 tree clauses
, tree
*cclauses
, bool *if_p
)
17216 tree decl
, cond
, incr
, save_break
, save_cont
, body
, init
, stmt
, cl
;
17217 tree declv
, condv
, incrv
, initv
, ret
= NULL_TREE
;
17218 tree pre_body
= NULL_TREE
, this_pre_body
;
17219 tree ordered_cl
= NULL_TREE
;
17220 bool fail
= false, open_brace_parsed
= false;
17221 int i
, collapse
= 1, ordered
= 0, count
, nbraces
= 0;
17222 location_t for_loc
;
17223 bool tiling
= false;
17224 bool inscan
= false;
17225 vec
<tree
, va_gc
> *for_block
= make_tree_vector ();
17227 for (cl
= clauses
; cl
; cl
= OMP_CLAUSE_CHAIN (cl
))
17228 if (OMP_CLAUSE_CODE (cl
) == OMP_CLAUSE_COLLAPSE
)
17229 collapse
= tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (cl
));
17230 else if (OMP_CLAUSE_CODE (cl
) == OMP_CLAUSE_TILE
)
17233 collapse
= list_length (OMP_CLAUSE_TILE_LIST (cl
));
17235 else if (OMP_CLAUSE_CODE (cl
) == OMP_CLAUSE_ORDERED
17236 && OMP_CLAUSE_ORDERED_EXPR (cl
))
17239 ordered
= tree_to_shwi (OMP_CLAUSE_ORDERED_EXPR (cl
));
17241 else if (OMP_CLAUSE_CODE (cl
) == OMP_CLAUSE_REDUCTION
17242 && OMP_CLAUSE_REDUCTION_INSCAN (cl
)
17243 && (code
== OMP_SIMD
|| code
== OMP_FOR
))
17246 if (ordered
&& ordered
< collapse
)
17248 error_at (OMP_CLAUSE_LOCATION (ordered_cl
),
17249 "%<ordered%> clause parameter is less than %<collapse%>");
17250 OMP_CLAUSE_ORDERED_EXPR (ordered_cl
)
17251 = build_int_cst (NULL_TREE
, collapse
);
17252 ordered
= collapse
;
17256 for (tree
*pc
= &clauses
; *pc
; )
17257 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_LINEAR
)
17259 error_at (OMP_CLAUSE_LOCATION (*pc
),
17260 "%<linear%> clause may not be specified together "
17261 "with %<ordered%> clause with a parameter");
17262 *pc
= OMP_CLAUSE_CHAIN (*pc
);
17265 pc
= &OMP_CLAUSE_CHAIN (*pc
);
17268 gcc_assert (tiling
|| (collapse
>= 1 && ordered
>= 0));
17269 count
= ordered
? ordered
: collapse
;
17271 declv
= make_tree_vec (count
);
17272 initv
= make_tree_vec (count
);
17273 condv
= make_tree_vec (count
);
17274 incrv
= make_tree_vec (count
);
17276 if (!c_parser_next_token_is_keyword (parser
, RID_FOR
))
17278 c_parser_error (parser
, "for statement expected");
17281 for_loc
= c_parser_peek_token (parser
)->location
;
17282 c_parser_consume_token (parser
);
17284 for (i
= 0; i
< count
; i
++)
17286 int bracecount
= 0;
17288 matching_parens parens
;
17289 if (!parens
.require_open (parser
))
17292 /* Parse the initialization declaration or expression. */
17293 if (c_parser_next_tokens_start_declaration (parser
))
17296 vec_safe_push (for_block
, c_begin_compound_stmt (true));
17297 this_pre_body
= push_stmt_list ();
17298 c_parser_declaration_or_fndef (parser
, true, true, true, true, true,
17302 this_pre_body
= pop_stmt_list (this_pre_body
);
17306 pre_body
= push_stmt_list ();
17308 add_stmt (this_pre_body
);
17309 pre_body
= pop_stmt_list (pre_body
);
17312 pre_body
= this_pre_body
;
17314 decl
= check_for_loop_decls (for_loc
, flag_isoc99
);
17317 if (DECL_INITIAL (decl
) == error_mark_node
)
17318 decl
= error_mark_node
;
17321 else if (c_parser_next_token_is (parser
, CPP_NAME
)
17322 && c_parser_peek_2nd_token (parser
)->type
== CPP_EQ
)
17324 struct c_expr decl_exp
;
17325 struct c_expr init_exp
;
17326 location_t init_loc
;
17328 decl_exp
= c_parser_postfix_expression (parser
);
17329 decl
= decl_exp
.value
;
17331 c_parser_require (parser
, CPP_EQ
, "expected %<=%>");
17333 init_loc
= c_parser_peek_token (parser
)->location
;
17334 init_exp
= c_parser_expr_no_commas (parser
, NULL
);
17335 init_exp
= default_function_array_read_conversion (init_loc
,
17337 init
= build_modify_expr (init_loc
, decl
, decl_exp
.original_type
,
17338 NOP_EXPR
, init_loc
, init_exp
.value
,
17339 init_exp
.original_type
);
17340 init
= c_process_expr_stmt (init_loc
, init
);
17342 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
17347 c_parser_error (parser
,
17348 "expected iteration declaration or initialization");
17349 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
17355 /* Parse the loop condition. */
17357 if (c_parser_next_token_is_not (parser
, CPP_SEMICOLON
))
17359 location_t cond_loc
= c_parser_peek_token (parser
)->location
;
17360 struct c_expr cond_expr
17361 = c_parser_binary_expression (parser
, NULL
, NULL_TREE
);
17363 cond
= cond_expr
.value
;
17364 cond
= c_objc_common_truthvalue_conversion (cond_loc
, cond
);
17365 if (COMPARISON_CLASS_P (cond
))
17367 tree op0
= TREE_OPERAND (cond
, 0), op1
= TREE_OPERAND (cond
, 1);
17368 op0
= c_fully_fold (op0
, false, NULL
);
17369 op1
= c_fully_fold (op1
, false, NULL
);
17370 TREE_OPERAND (cond
, 0) = op0
;
17371 TREE_OPERAND (cond
, 1) = op1
;
17373 switch (cond_expr
.original_code
)
17381 if (code
!= OACC_LOOP
)
17385 /* Can't be cond = error_mark_node, because we want to preserve
17386 the location until c_finish_omp_for. */
17387 cond
= build1 (NOP_EXPR
, boolean_type_node
, error_mark_node
);
17390 protected_set_expr_location (cond
, cond_loc
);
17392 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
17394 /* Parse the increment expression. */
17396 if (c_parser_next_token_is_not (parser
, CPP_CLOSE_PAREN
))
17398 location_t incr_loc
= c_parser_peek_token (parser
)->location
;
17400 incr
= c_process_expr_stmt (incr_loc
,
17401 c_parser_expression (parser
).value
);
17403 parens
.skip_until_found_close (parser
);
17405 if (decl
== NULL
|| decl
== error_mark_node
|| init
== error_mark_node
)
17409 TREE_VEC_ELT (declv
, i
) = decl
;
17410 TREE_VEC_ELT (initv
, i
) = init
;
17411 TREE_VEC_ELT (condv
, i
) = cond
;
17412 TREE_VEC_ELT (incrv
, i
) = incr
;
17416 if (i
== count
- 1)
17419 /* FIXME: OpenMP 3.0 draft isn't very clear on what exactly is allowed
17420 in between the collapsed for loops to be still considered perfectly
17421 nested. Hopefully the final version clarifies this.
17422 For now handle (multiple) {'s and empty statements. */
17425 if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
17427 c_parser_consume_token (parser
);
17430 else if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
17432 c_parser_consume_token (parser
);
17435 else if (bracecount
17436 && c_parser_next_token_is (parser
, CPP_SEMICOLON
))
17437 c_parser_consume_token (parser
);
17440 c_parser_error (parser
, "not enough perfectly nested loops");
17443 open_brace_parsed
= true;
17453 nbraces
+= bracecount
;
17459 save_break
= c_break_label
;
17460 c_break_label
= size_one_node
;
17461 save_cont
= c_cont_label
;
17462 c_cont_label
= NULL_TREE
;
17463 body
= push_stmt_list ();
17466 c_parser_omp_scan_loop_body (parser
, open_brace_parsed
);
17467 else if (open_brace_parsed
)
17469 location_t here
= c_parser_peek_token (parser
)->location
;
17470 stmt
= c_begin_compound_stmt (true);
17471 c_parser_compound_statement_nostart (parser
);
17472 add_stmt (c_end_compound_stmt (here
, stmt
, true));
17475 add_stmt (c_parser_c99_block_statement (parser
, if_p
));
17478 tree t
= build1 (LABEL_EXPR
, void_type_node
, c_cont_label
);
17479 SET_EXPR_LOCATION (t
, loc
);
17483 body
= pop_stmt_list (body
);
17484 c_break_label
= save_break
;
17485 c_cont_label
= save_cont
;
17489 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
17491 c_parser_consume_token (parser
);
17494 else if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
17495 c_parser_consume_token (parser
);
17498 c_parser_error (parser
, "collapsed loops not perfectly nested");
17501 location_t here
= c_parser_peek_token (parser
)->location
;
17502 stmt
= c_begin_compound_stmt (true);
17504 c_parser_compound_statement_nostart (parser
);
17505 body
= c_end_compound_stmt (here
, stmt
, true);
17512 /* Only bother calling c_finish_omp_for if we haven't already generated
17513 an error from the initialization parsing. */
17516 stmt
= c_finish_omp_for (loc
, code
, declv
, NULL
, initv
, condv
,
17517 incrv
, body
, pre_body
, true);
17519 /* Check for iterators appearing in lb, b or incr expressions. */
17520 if (stmt
&& !c_omp_check_loop_iv (stmt
, declv
, NULL
))
17527 if (cclauses
!= NULL
17528 && cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
] != NULL
)
17531 for (c
= &cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
]; *c
; )
17532 if (OMP_CLAUSE_CODE (*c
) != OMP_CLAUSE_FIRSTPRIVATE
17533 && OMP_CLAUSE_CODE (*c
) != OMP_CLAUSE_LASTPRIVATE
)
17534 c
= &OMP_CLAUSE_CHAIN (*c
);
17537 for (i
= 0; i
< count
; i
++)
17538 if (TREE_VEC_ELT (declv
, i
) == OMP_CLAUSE_DECL (*c
))
17541 c
= &OMP_CLAUSE_CHAIN (*c
);
17542 else if (OMP_CLAUSE_CODE (*c
) == OMP_CLAUSE_FIRSTPRIVATE
)
17545 "iteration variable %qD should not be firstprivate",
17546 OMP_CLAUSE_DECL (*c
));
17547 *c
= OMP_CLAUSE_CHAIN (*c
);
17551 /* Move lastprivate (decl) clause to OMP_FOR_CLAUSES. */
17553 *c
= OMP_CLAUSE_CHAIN (*c
);
17554 if (code
== OMP_SIMD
)
17556 OMP_CLAUSE_CHAIN (l
)
17557 = cclauses
[C_OMP_CLAUSE_SPLIT_FOR
];
17558 cclauses
[C_OMP_CLAUSE_SPLIT_FOR
] = l
;
17562 OMP_CLAUSE_CHAIN (l
) = clauses
;
17568 OMP_FOR_CLAUSES (stmt
) = clauses
;
17573 while (!for_block
->is_empty ())
17575 /* FIXME diagnostics: LOC below should be the actual location of
17576 this particular for block. We need to build a list of
17577 locations to go along with FOR_BLOCK. */
17578 stmt
= c_end_compound_stmt (loc
, for_block
->pop (), true);
17581 release_tree_vector (for_block
);
17585 /* Helper function for OpenMP parsing, split clauses and call
17586 finish_omp_clauses on each of the set of clauses afterwards. */
17589 omp_split_clauses (location_t loc
, enum tree_code code
,
17590 omp_clause_mask mask
, tree clauses
, tree
*cclauses
)
17593 c_omp_split_clauses (loc
, code
, mask
, clauses
, cclauses
);
17594 for (i
= 0; i
< C_OMP_CLAUSE_SPLIT_COUNT
; i
++)
17596 cclauses
[i
] = c_finish_omp_clauses (cclauses
[i
], C_ORT_OMP
);
17600 #pragma omp loop loop-clause[optseq] new-line
17603 LOC is the location of the #pragma token.
17606 #define OMP_LOOP_CLAUSE_MASK \
17607 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
17608 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
17609 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
17610 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
17611 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_BIND) \
17612 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
17615 c_parser_omp_loop (location_t loc
, c_parser
*parser
,
17616 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
17619 tree block
, clauses
, ret
;
17621 strcat (p_name
, " loop");
17622 mask
|= OMP_LOOP_CLAUSE_MASK
;
17624 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
17627 omp_split_clauses (loc
, OMP_LOOP
, mask
, clauses
, cclauses
);
17628 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_LOOP
];
17631 block
= c_begin_compound_stmt (true);
17632 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_LOOP
, clauses
, cclauses
, if_p
);
17633 block
= c_end_compound_stmt (loc
, block
, true);
17640 #pragma omp simd simd-clause[optseq] new-line
17643 LOC is the location of the #pragma token.
17646 #define OMP_SIMD_CLAUSE_MASK \
17647 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SAFELEN) \
17648 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
17649 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
17650 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
17651 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
17652 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
17653 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
17654 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
17655 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
17656 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NONTEMPORAL) \
17657 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
17660 c_parser_omp_simd (location_t loc
, c_parser
*parser
,
17661 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
17664 tree block
, clauses
, ret
;
17666 strcat (p_name
, " simd");
17667 mask
|= OMP_SIMD_CLAUSE_MASK
;
17669 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
17672 omp_split_clauses (loc
, OMP_SIMD
, mask
, clauses
, cclauses
);
17673 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_SIMD
];
17674 tree c
= omp_find_clause (cclauses
[C_OMP_CLAUSE_SPLIT_FOR
],
17675 OMP_CLAUSE_ORDERED
);
17676 if (c
&& OMP_CLAUSE_ORDERED_EXPR (c
))
17678 error_at (OMP_CLAUSE_LOCATION (c
),
17679 "%<ordered%> clause with parameter may not be specified "
17680 "on %qs construct", p_name
);
17681 OMP_CLAUSE_ORDERED_EXPR (c
) = NULL_TREE
;
17685 block
= c_begin_compound_stmt (true);
17686 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_SIMD
, clauses
, cclauses
, if_p
);
17687 block
= c_end_compound_stmt (loc
, block
, true);
17694 #pragma omp for for-clause[optseq] new-line
17698 #pragma omp for simd for-simd-clause[optseq] new-line
17701 LOC is the location of the #pragma token.
17704 #define OMP_FOR_CLAUSE_MASK \
17705 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
17706 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
17707 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
17708 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
17709 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
17710 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED) \
17711 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE) \
17712 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
17713 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
17714 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
17717 c_parser_omp_for (location_t loc
, c_parser
*parser
,
17718 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
17721 tree block
, clauses
, ret
;
17723 strcat (p_name
, " for");
17724 mask
|= OMP_FOR_CLAUSE_MASK
;
17725 /* parallel for{, simd} disallows nowait clause, but for
17726 target {teams distribute ,}parallel for{, simd} it should be accepted. */
17727 if (cclauses
&& (mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_MAP
)) == 0)
17728 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_NOWAIT
);
17729 /* Composite distribute parallel for{, simd} disallows ordered clause. */
17730 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
)) != 0)
17731 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_ORDERED
);
17733 if (c_parser_next_token_is (parser
, CPP_NAME
))
17735 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
17737 if (strcmp (p
, "simd") == 0)
17739 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
17740 if (cclauses
== NULL
)
17741 cclauses
= cclauses_buf
;
17743 c_parser_consume_token (parser
);
17744 if (!flag_openmp
) /* flag_openmp_simd */
17745 return c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
,
17747 block
= c_begin_compound_stmt (true);
17748 ret
= c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
17749 block
= c_end_compound_stmt (loc
, block
, true);
17750 if (ret
== NULL_TREE
)
17752 ret
= make_node (OMP_FOR
);
17753 TREE_TYPE (ret
) = void_type_node
;
17754 OMP_FOR_BODY (ret
) = block
;
17755 OMP_FOR_CLAUSES (ret
) = cclauses
[C_OMP_CLAUSE_SPLIT_FOR
];
17756 SET_EXPR_LOCATION (ret
, loc
);
17761 if (!flag_openmp
) /* flag_openmp_simd */
17763 c_parser_skip_to_pragma_eol (parser
, false);
17767 /* Composite distribute parallel for disallows linear clause. */
17768 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
)) != 0)
17769 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_LINEAR
);
17771 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
17774 omp_split_clauses (loc
, OMP_FOR
, mask
, clauses
, cclauses
);
17775 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_FOR
];
17778 block
= c_begin_compound_stmt (true);
17779 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_FOR
, clauses
, cclauses
, if_p
);
17780 block
= c_end_compound_stmt (loc
, block
, true);
17786 static tree
c_parser_omp_taskloop (location_t
, c_parser
*, char *,
17787 omp_clause_mask
, tree
*, bool *);
17790 # pragma omp master new-line
17793 LOC is the location of the #pragma token.
17797 c_parser_omp_master (location_t loc
, c_parser
*parser
,
17798 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
17801 tree block
, clauses
, ret
;
17803 strcat (p_name
, " master");
17805 if (c_parser_next_token_is (parser
, CPP_NAME
))
17807 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
17809 if (strcmp (p
, "taskloop") == 0)
17811 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
17812 if (cclauses
== NULL
)
17813 cclauses
= cclauses_buf
;
17815 c_parser_consume_token (parser
);
17816 if (!flag_openmp
) /* flag_openmp_simd */
17817 return c_parser_omp_taskloop (loc
, parser
, p_name
, mask
, cclauses
,
17819 block
= c_begin_compound_stmt (true);
17820 ret
= c_parser_omp_taskloop (loc
, parser
, p_name
, mask
, cclauses
,
17822 block
= c_end_compound_stmt (loc
, block
, true);
17823 if (ret
== NULL_TREE
)
17825 ret
= c_finish_omp_master (loc
, block
);
17829 if (!flag_openmp
) /* flag_openmp_simd */
17831 c_parser_skip_to_pragma_eol (parser
, false);
17837 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, false);
17838 omp_split_clauses (loc
, OMP_MASTER
, mask
, clauses
, cclauses
);
17841 c_parser_skip_to_pragma_eol (parser
);
17843 return c_finish_omp_master (loc
, c_parser_omp_structured_block (parser
,
17848 # pragma omp ordered new-line
17852 # pragma omp ordered ordered-clauses new-line
17855 # pragma omp ordered depend-clauses new-line */
17857 #define OMP_ORDERED_CLAUSE_MASK \
17858 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREADS) \
17859 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMD))
17861 #define OMP_ORDERED_DEPEND_CLAUSE_MASK \
17862 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)
17865 c_parser_omp_ordered (c_parser
*parser
, enum pragma_context context
,
17868 location_t loc
= c_parser_peek_token (parser
)->location
;
17869 c_parser_consume_pragma (parser
);
17871 if (context
!= pragma_stmt
&& context
!= pragma_compound
)
17873 c_parser_error (parser
, "expected declaration specifiers");
17874 c_parser_skip_to_pragma_eol (parser
, false);
17878 if (c_parser_next_token_is (parser
, CPP_NAME
))
17880 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
17882 if (!strcmp ("depend", p
))
17884 if (!flag_openmp
) /* flag_openmp_simd */
17886 c_parser_skip_to_pragma_eol (parser
, false);
17889 if (context
== pragma_stmt
)
17892 "%<#pragma omp ordered%> with %<depend%> clause may "
17893 "only be used in compound statements");
17894 c_parser_skip_to_pragma_eol (parser
, false);
17899 = c_parser_omp_all_clauses (parser
,
17900 OMP_ORDERED_DEPEND_CLAUSE_MASK
,
17901 "#pragma omp ordered");
17902 c_finish_omp_ordered (loc
, clauses
, NULL_TREE
);
17907 tree clauses
= c_parser_omp_all_clauses (parser
, OMP_ORDERED_CLAUSE_MASK
,
17908 "#pragma omp ordered");
17910 if (!flag_openmp
/* flag_openmp_simd */
17911 && omp_find_clause (clauses
, OMP_CLAUSE_SIMD
) == NULL_TREE
)
17914 c_finish_omp_ordered (loc
, clauses
,
17915 c_parser_omp_structured_block (parser
, if_p
));
17922 { section-sequence }
17925 section-directive[opt] structured-block
17926 section-sequence section-directive structured-block
17928 SECTIONS_LOC is the location of the #pragma omp sections. */
17931 c_parser_omp_sections_scope (location_t sections_loc
, c_parser
*parser
)
17933 tree stmt
, substmt
;
17934 bool error_suppress
= false;
17937 loc
= c_parser_peek_token (parser
)->location
;
17938 if (!c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
17940 /* Avoid skipping until the end of the block. */
17941 parser
->error
= false;
17945 stmt
= push_stmt_list ();
17947 if (c_parser_peek_token (parser
)->pragma_kind
!= PRAGMA_OMP_SECTION
)
17949 substmt
= c_parser_omp_structured_block (parser
, NULL
);
17950 substmt
= build1 (OMP_SECTION
, void_type_node
, substmt
);
17951 SET_EXPR_LOCATION (substmt
, loc
);
17952 add_stmt (substmt
);
17957 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
17959 if (c_parser_next_token_is (parser
, CPP_EOF
))
17962 loc
= c_parser_peek_token (parser
)->location
;
17963 if (c_parser_peek_token (parser
)->pragma_kind
== PRAGMA_OMP_SECTION
)
17965 c_parser_consume_pragma (parser
);
17966 c_parser_skip_to_pragma_eol (parser
);
17967 error_suppress
= false;
17969 else if (!error_suppress
)
17971 error_at (loc
, "expected %<#pragma omp section%> or %<}%>");
17972 error_suppress
= true;
17975 substmt
= c_parser_omp_structured_block (parser
, NULL
);
17976 substmt
= build1 (OMP_SECTION
, void_type_node
, substmt
);
17977 SET_EXPR_LOCATION (substmt
, loc
);
17978 add_stmt (substmt
);
17980 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
,
17981 "expected %<#pragma omp section%> or %<}%>");
17983 substmt
= pop_stmt_list (stmt
);
17985 stmt
= make_node (OMP_SECTIONS
);
17986 SET_EXPR_LOCATION (stmt
, sections_loc
);
17987 TREE_TYPE (stmt
) = void_type_node
;
17988 OMP_SECTIONS_BODY (stmt
) = substmt
;
17990 return add_stmt (stmt
);
17994 # pragma omp sections sections-clause[optseq] newline
17997 LOC is the location of the #pragma token.
18000 #define OMP_SECTIONS_CLAUSE_MASK \
18001 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
18002 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
18003 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
18004 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
18005 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
18008 c_parser_omp_sections (location_t loc
, c_parser
*parser
,
18009 char *p_name
, omp_clause_mask mask
, tree
*cclauses
)
18011 tree block
, clauses
, ret
;
18013 strcat (p_name
, " sections");
18014 mask
|= OMP_SECTIONS_CLAUSE_MASK
;
18016 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_NOWAIT
);
18018 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
18021 omp_split_clauses (loc
, OMP_SECTIONS
, mask
, clauses
, cclauses
);
18022 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_SECTIONS
];
18025 block
= c_begin_compound_stmt (true);
18026 ret
= c_parser_omp_sections_scope (loc
, parser
);
18028 OMP_SECTIONS_CLAUSES (ret
) = clauses
;
18029 block
= c_end_compound_stmt (loc
, block
, true);
18036 # pragma omp parallel parallel-clause[optseq] new-line
18038 # pragma omp parallel for parallel-for-clause[optseq] new-line
18040 # pragma omp parallel sections parallel-sections-clause[optseq] new-line
18044 # pragma omp parallel for simd parallel-for-simd-clause[optseq] new-line
18047 LOC is the location of the #pragma token.
18050 #define OMP_PARALLEL_CLAUSE_MASK \
18051 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
18052 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
18053 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
18054 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
18055 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
18056 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN) \
18057 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
18058 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS) \
18059 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PROC_BIND))
18062 c_parser_omp_parallel (location_t loc
, c_parser
*parser
,
18063 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
18066 tree stmt
, clauses
, block
;
18068 strcat (p_name
, " parallel");
18069 mask
|= OMP_PARALLEL_CLAUSE_MASK
;
18070 /* #pragma omp target parallel{, for, for simd} disallow copyin clause. */
18071 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_MAP
)) != 0
18072 && (mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
)) == 0)
18073 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_COPYIN
);
18075 if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
18077 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
18078 if (cclauses
== NULL
)
18079 cclauses
= cclauses_buf
;
18081 c_parser_consume_token (parser
);
18082 if (!flag_openmp
) /* flag_openmp_simd */
18083 return c_parser_omp_for (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
18084 block
= c_begin_omp_parallel ();
18085 tree ret
= c_parser_omp_for (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
18087 = c_finish_omp_parallel (loc
, cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
18089 if (ret
== NULL_TREE
)
18091 OMP_PARALLEL_COMBINED (stmt
) = 1;
18094 /* When combined with distribute, parallel has to be followed by for.
18095 #pragma omp target parallel is allowed though. */
18097 && (mask
& (OMP_CLAUSE_MASK_1
18098 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
)) != 0)
18100 error_at (loc
, "expected %<for%> after %qs", p_name
);
18101 c_parser_skip_to_pragma_eol (parser
);
18104 else if (c_parser_next_token_is (parser
, CPP_NAME
))
18106 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18107 if (cclauses
== NULL
&& strcmp (p
, "master") == 0)
18109 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
18110 cclauses
= cclauses_buf
;
18112 c_parser_consume_token (parser
);
18113 if (!flag_openmp
) /* flag_openmp_simd */
18114 return c_parser_omp_master (loc
, parser
, p_name
, mask
, cclauses
,
18116 block
= c_begin_omp_parallel ();
18117 tree ret
= c_parser_omp_master (loc
, parser
, p_name
, mask
, cclauses
,
18119 stmt
= c_finish_omp_parallel (loc
,
18120 cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
18122 OMP_PARALLEL_COMBINED (stmt
) = 1;
18127 else if (strcmp (p
, "loop") == 0)
18129 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
18130 if (cclauses
== NULL
)
18131 cclauses
= cclauses_buf
;
18133 c_parser_consume_token (parser
);
18134 if (!flag_openmp
) /* flag_openmp_simd */
18135 return c_parser_omp_loop (loc
, parser
, p_name
, mask
, cclauses
,
18137 block
= c_begin_omp_parallel ();
18138 tree ret
= c_parser_omp_loop (loc
, parser
, p_name
, mask
, cclauses
,
18141 = c_finish_omp_parallel (loc
,
18142 cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
18144 if (ret
== NULL_TREE
)
18146 OMP_PARALLEL_COMBINED (stmt
) = 1;
18149 else if (!flag_openmp
) /* flag_openmp_simd */
18151 c_parser_skip_to_pragma_eol (parser
, false);
18154 else if (cclauses
== NULL
&& strcmp (p
, "sections") == 0)
18156 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
18157 cclauses
= cclauses_buf
;
18159 c_parser_consume_token (parser
);
18160 block
= c_begin_omp_parallel ();
18161 c_parser_omp_sections (loc
, parser
, p_name
, mask
, cclauses
);
18162 stmt
= c_finish_omp_parallel (loc
,
18163 cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
18165 OMP_PARALLEL_COMBINED (stmt
) = 1;
18169 else if (!flag_openmp
) /* flag_openmp_simd */
18171 c_parser_skip_to_pragma_eol (parser
, false);
18175 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
18178 omp_split_clauses (loc
, OMP_PARALLEL
, mask
, clauses
, cclauses
);
18179 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
];
18182 block
= c_begin_omp_parallel ();
18183 c_parser_statement (parser
, if_p
);
18184 stmt
= c_finish_omp_parallel (loc
, clauses
, block
);
18190 # pragma omp single single-clause[optseq] new-line
18193 LOC is the location of the #pragma.
18196 #define OMP_SINGLE_CLAUSE_MASK \
18197 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
18198 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
18199 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYPRIVATE) \
18200 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
18203 c_parser_omp_single (location_t loc
, c_parser
*parser
, bool *if_p
)
18205 tree stmt
= make_node (OMP_SINGLE
);
18206 SET_EXPR_LOCATION (stmt
, loc
);
18207 TREE_TYPE (stmt
) = void_type_node
;
18209 OMP_SINGLE_CLAUSES (stmt
)
18210 = c_parser_omp_all_clauses (parser
, OMP_SINGLE_CLAUSE_MASK
,
18211 "#pragma omp single");
18212 OMP_SINGLE_BODY (stmt
) = c_parser_omp_structured_block (parser
, if_p
);
18214 return add_stmt (stmt
);
18218 # pragma omp task task-clause[optseq] new-line
18220 LOC is the location of the #pragma.
18223 #define OMP_TASK_CLAUSE_MASK \
18224 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
18225 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
18226 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
18227 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
18228 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
18229 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
18230 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
18231 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
18232 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
18233 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
18234 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION))
18237 c_parser_omp_task (location_t loc
, c_parser
*parser
, bool *if_p
)
18239 tree clauses
, block
;
18241 clauses
= c_parser_omp_all_clauses (parser
, OMP_TASK_CLAUSE_MASK
,
18242 "#pragma omp task");
18244 block
= c_begin_omp_task ();
18245 c_parser_statement (parser
, if_p
);
18246 return c_finish_omp_task (loc
, clauses
, block
);
18250 # pragma omp taskwait new-line
18253 # pragma omp taskwait taskwait-clause[optseq] new-line
18256 #define OMP_TASKWAIT_CLAUSE_MASK \
18257 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)
18260 c_parser_omp_taskwait (c_parser
*parser
)
18262 location_t loc
= c_parser_peek_token (parser
)->location
;
18263 c_parser_consume_pragma (parser
);
18266 = c_parser_omp_all_clauses (parser
, OMP_TASKWAIT_CLAUSE_MASK
,
18267 "#pragma omp taskwait");
18271 tree stmt
= make_node (OMP_TASK
);
18272 TREE_TYPE (stmt
) = void_node
;
18273 OMP_TASK_CLAUSES (stmt
) = clauses
;
18274 OMP_TASK_BODY (stmt
) = NULL_TREE
;
18275 SET_EXPR_LOCATION (stmt
, loc
);
18279 c_finish_omp_taskwait (loc
);
18283 # pragma omp taskyield new-line
18287 c_parser_omp_taskyield (c_parser
*parser
)
18289 location_t loc
= c_parser_peek_token (parser
)->location
;
18290 c_parser_consume_pragma (parser
);
18291 c_parser_skip_to_pragma_eol (parser
);
18293 c_finish_omp_taskyield (loc
);
18297 # pragma omp taskgroup new-line
18300 # pragma omp taskgroup taskgroup-clause[optseq] new-line
18303 #define OMP_TASKGROUP_CLAUSE_MASK \
18304 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASK_REDUCTION))
18307 c_parser_omp_taskgroup (location_t loc
, c_parser
*parser
, bool *if_p
)
18309 tree clauses
= c_parser_omp_all_clauses (parser
, OMP_TASKGROUP_CLAUSE_MASK
,
18310 "#pragma omp taskgroup");
18312 tree body
= c_parser_omp_structured_block (parser
, if_p
);
18313 return c_finish_omp_taskgroup (loc
, body
, clauses
);
18317 # pragma omp cancel cancel-clause[optseq] new-line
18319 LOC is the location of the #pragma.
18322 #define OMP_CANCEL_CLAUSE_MASK \
18323 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
18324 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
18325 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
18326 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP) \
18327 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF))
18330 c_parser_omp_cancel (c_parser
*parser
)
18332 location_t loc
= c_parser_peek_token (parser
)->location
;
18334 c_parser_consume_pragma (parser
);
18335 tree clauses
= c_parser_omp_all_clauses (parser
, OMP_CANCEL_CLAUSE_MASK
,
18336 "#pragma omp cancel");
18338 c_finish_omp_cancel (loc
, clauses
);
18342 # pragma omp cancellation point cancelpt-clause[optseq] new-line
18344 LOC is the location of the #pragma.
18347 #define OMP_CANCELLATION_POINT_CLAUSE_MASK \
18348 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
18349 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
18350 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
18351 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP))
18354 c_parser_omp_cancellation_point (c_parser
*parser
, enum pragma_context context
)
18356 location_t loc
= c_parser_peek_token (parser
)->location
;
18358 bool point_seen
= false;
18360 c_parser_consume_pragma (parser
);
18361 if (c_parser_next_token_is (parser
, CPP_NAME
))
18363 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18364 if (strcmp (p
, "point") == 0)
18366 c_parser_consume_token (parser
);
18372 c_parser_error (parser
, "expected %<point%>");
18373 c_parser_skip_to_pragma_eol (parser
);
18377 if (context
!= pragma_compound
)
18379 if (context
== pragma_stmt
)
18381 "%<#pragma %s%> may only be used in compound statements",
18382 "omp cancellation point");
18384 c_parser_error (parser
, "expected declaration specifiers");
18385 c_parser_skip_to_pragma_eol (parser
, false);
18390 = c_parser_omp_all_clauses (parser
, OMP_CANCELLATION_POINT_CLAUSE_MASK
,
18391 "#pragma omp cancellation point");
18393 c_finish_omp_cancellation_point (loc
, clauses
);
18397 #pragma omp distribute distribute-clause[optseq] new-line
18400 #define OMP_DISTRIBUTE_CLAUSE_MASK \
18401 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
18402 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
18403 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
18404 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)\
18405 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE))
18408 c_parser_omp_distribute (location_t loc
, c_parser
*parser
,
18409 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
18412 tree clauses
, block
, ret
;
18414 strcat (p_name
, " distribute");
18415 mask
|= OMP_DISTRIBUTE_CLAUSE_MASK
;
18417 if (c_parser_next_token_is (parser
, CPP_NAME
))
18419 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18421 bool parallel
= false;
18423 if (strcmp (p
, "simd") == 0)
18426 parallel
= strcmp (p
, "parallel") == 0;
18427 if (parallel
|| simd
)
18429 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
18430 if (cclauses
== NULL
)
18431 cclauses
= cclauses_buf
;
18432 c_parser_consume_token (parser
);
18433 if (!flag_openmp
) /* flag_openmp_simd */
18436 return c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
,
18439 return c_parser_omp_parallel (loc
, parser
, p_name
, mask
,
18442 block
= c_begin_compound_stmt (true);
18444 ret
= c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
,
18447 ret
= c_parser_omp_parallel (loc
, parser
, p_name
, mask
, cclauses
,
18449 block
= c_end_compound_stmt (loc
, block
, true);
18452 ret
= make_node (OMP_DISTRIBUTE
);
18453 TREE_TYPE (ret
) = void_type_node
;
18454 OMP_FOR_BODY (ret
) = block
;
18455 OMP_FOR_CLAUSES (ret
) = cclauses
[C_OMP_CLAUSE_SPLIT_DISTRIBUTE
];
18456 SET_EXPR_LOCATION (ret
, loc
);
18461 if (!flag_openmp
) /* flag_openmp_simd */
18463 c_parser_skip_to_pragma_eol (parser
, false);
18467 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
18470 omp_split_clauses (loc
, OMP_DISTRIBUTE
, mask
, clauses
, cclauses
);
18471 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_DISTRIBUTE
];
18474 block
= c_begin_compound_stmt (true);
18475 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_DISTRIBUTE
, clauses
, NULL
,
18477 block
= c_end_compound_stmt (loc
, block
, true);
18484 # pragma omp teams teams-clause[optseq] new-line
18485 structured-block */
18487 #define OMP_TEAMS_CLAUSE_MASK \
18488 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
18489 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
18490 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
18491 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
18492 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS) \
18493 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \
18494 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT))
18497 c_parser_omp_teams (location_t loc
, c_parser
*parser
,
18498 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
18501 tree clauses
, block
, ret
;
18503 strcat (p_name
, " teams");
18504 mask
|= OMP_TEAMS_CLAUSE_MASK
;
18506 if (c_parser_next_token_is (parser
, CPP_NAME
))
18508 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18509 if (strcmp (p
, "distribute") == 0)
18511 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
18512 if (cclauses
== NULL
)
18513 cclauses
= cclauses_buf
;
18515 c_parser_consume_token (parser
);
18516 if (!flag_openmp
) /* flag_openmp_simd */
18517 return c_parser_omp_distribute (loc
, parser
, p_name
, mask
,
18519 block
= c_begin_omp_parallel ();
18520 ret
= c_parser_omp_distribute (loc
, parser
, p_name
, mask
, cclauses
,
18522 block
= c_end_compound_stmt (loc
, block
, true);
18525 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_TEAMS
];
18526 ret
= make_node (OMP_TEAMS
);
18527 TREE_TYPE (ret
) = void_type_node
;
18528 OMP_TEAMS_CLAUSES (ret
) = clauses
;
18529 OMP_TEAMS_BODY (ret
) = block
;
18530 OMP_TEAMS_COMBINED (ret
) = 1;
18531 SET_EXPR_LOCATION (ret
, loc
);
18532 return add_stmt (ret
);
18534 else if (strcmp (p
, "loop") == 0)
18536 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
18537 if (cclauses
== NULL
)
18538 cclauses
= cclauses_buf
;
18540 c_parser_consume_token (parser
);
18541 if (!flag_openmp
) /* flag_openmp_simd */
18542 return c_parser_omp_loop (loc
, parser
, p_name
, mask
, cclauses
,
18544 block
= c_begin_omp_parallel ();
18545 ret
= c_parser_omp_loop (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
18546 block
= c_end_compound_stmt (loc
, block
, true);
18549 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_TEAMS
];
18550 ret
= make_node (OMP_TEAMS
);
18551 TREE_TYPE (ret
) = void_type_node
;
18552 OMP_TEAMS_CLAUSES (ret
) = clauses
;
18553 OMP_TEAMS_BODY (ret
) = block
;
18554 OMP_TEAMS_COMBINED (ret
) = 1;
18555 SET_EXPR_LOCATION (ret
, loc
);
18556 return add_stmt (ret
);
18559 if (!flag_openmp
) /* flag_openmp_simd */
18561 c_parser_skip_to_pragma_eol (parser
, false);
18565 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
18568 omp_split_clauses (loc
, OMP_TEAMS
, mask
, clauses
, cclauses
);
18569 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_TEAMS
];
18572 tree stmt
= make_node (OMP_TEAMS
);
18573 TREE_TYPE (stmt
) = void_type_node
;
18574 OMP_TEAMS_CLAUSES (stmt
) = clauses
;
18575 block
= c_begin_omp_parallel ();
18576 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
18577 OMP_TEAMS_BODY (stmt
) = c_end_compound_stmt (loc
, block
, true);
18578 SET_EXPR_LOCATION (stmt
, loc
);
18580 return add_stmt (stmt
);
18584 # pragma omp target data target-data-clause[optseq] new-line
18585 structured-block */
18587 #define OMP_TARGET_DATA_CLAUSE_MASK \
18588 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
18589 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
18590 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
18591 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR) \
18592 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR))
18595 c_parser_omp_target_data (location_t loc
, c_parser
*parser
, bool *if_p
)
18598 = c_parser_omp_all_clauses (parser
, OMP_TARGET_DATA_CLAUSE_MASK
,
18599 "#pragma omp target data");
18601 for (tree
*pc
= &clauses
; *pc
;)
18603 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_MAP
)
18604 switch (OMP_CLAUSE_MAP_KIND (*pc
))
18607 case GOMP_MAP_ALWAYS_TO
:
18608 case GOMP_MAP_FROM
:
18609 case GOMP_MAP_ALWAYS_FROM
:
18610 case GOMP_MAP_TOFROM
:
18611 case GOMP_MAP_ALWAYS_TOFROM
:
18612 case GOMP_MAP_ALLOC
:
18615 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
18616 case GOMP_MAP_ALWAYS_POINTER
:
18620 error_at (OMP_CLAUSE_LOCATION (*pc
),
18621 "%<#pragma omp target data%> with map-type other "
18622 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
18623 "on %<map%> clause");
18624 *pc
= OMP_CLAUSE_CHAIN (*pc
);
18627 else if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_USE_DEVICE_PTR
18628 || OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_USE_DEVICE_ADDR
)
18630 pc
= &OMP_CLAUSE_CHAIN (*pc
);
18637 "%<#pragma omp target data%> must contain at least "
18638 "one %<map%>, %<use_device_ptr%> or %<use_device_addr%> "
18643 tree stmt
= make_node (OMP_TARGET_DATA
);
18644 TREE_TYPE (stmt
) = void_type_node
;
18645 OMP_TARGET_DATA_CLAUSES (stmt
) = clauses
;
18646 keep_next_level ();
18647 tree block
= c_begin_compound_stmt (true);
18648 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
18649 OMP_TARGET_DATA_BODY (stmt
) = c_end_compound_stmt (loc
, block
, true);
18651 SET_EXPR_LOCATION (stmt
, loc
);
18652 return add_stmt (stmt
);
18656 # pragma omp target update target-update-clause[optseq] new-line */
18658 #define OMP_TARGET_UPDATE_CLAUSE_MASK \
18659 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FROM) \
18660 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
18661 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
18662 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
18663 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
18664 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
18667 c_parser_omp_target_update (location_t loc
, c_parser
*parser
,
18668 enum pragma_context context
)
18670 if (context
== pragma_stmt
)
18672 error_at (loc
, "%<#pragma %s%> may only be used in compound statements",
18673 "omp target update");
18674 c_parser_skip_to_pragma_eol (parser
, false);
18679 = c_parser_omp_all_clauses (parser
, OMP_TARGET_UPDATE_CLAUSE_MASK
,
18680 "#pragma omp target update");
18681 if (omp_find_clause (clauses
, OMP_CLAUSE_TO
) == NULL_TREE
18682 && omp_find_clause (clauses
, OMP_CLAUSE_FROM
) == NULL_TREE
)
18685 "%<#pragma omp target update%> must contain at least one "
18686 "%<from%> or %<to%> clauses");
18690 tree stmt
= make_node (OMP_TARGET_UPDATE
);
18691 TREE_TYPE (stmt
) = void_type_node
;
18692 OMP_TARGET_UPDATE_CLAUSES (stmt
) = clauses
;
18693 SET_EXPR_LOCATION (stmt
, loc
);
18699 # pragma omp target enter data target-data-clause[optseq] new-line */
18701 #define OMP_TARGET_ENTER_DATA_CLAUSE_MASK \
18702 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
18703 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
18704 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
18705 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
18706 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
18709 c_parser_omp_target_enter_data (location_t loc
, c_parser
*parser
,
18710 enum pragma_context context
)
18712 bool data_seen
= false;
18713 if (c_parser_next_token_is (parser
, CPP_NAME
))
18715 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18716 if (strcmp (p
, "data") == 0)
18718 c_parser_consume_token (parser
);
18724 c_parser_error (parser
, "expected %<data%>");
18725 c_parser_skip_to_pragma_eol (parser
);
18729 if (context
== pragma_stmt
)
18731 error_at (loc
, "%<#pragma %s%> may only be used in compound statements",
18732 "omp target enter data");
18733 c_parser_skip_to_pragma_eol (parser
, false);
18738 = c_parser_omp_all_clauses (parser
, OMP_TARGET_ENTER_DATA_CLAUSE_MASK
,
18739 "#pragma omp target enter data");
18741 for (tree
*pc
= &clauses
; *pc
;)
18743 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_MAP
)
18744 switch (OMP_CLAUSE_MAP_KIND (*pc
))
18747 case GOMP_MAP_ALWAYS_TO
:
18748 case GOMP_MAP_ALLOC
:
18751 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
18752 case GOMP_MAP_ALWAYS_POINTER
:
18756 error_at (OMP_CLAUSE_LOCATION (*pc
),
18757 "%<#pragma omp target enter data%> with map-type other "
18758 "than %<to%> or %<alloc%> on %<map%> clause");
18759 *pc
= OMP_CLAUSE_CHAIN (*pc
);
18762 pc
= &OMP_CLAUSE_CHAIN (*pc
);
18769 "%<#pragma omp target enter data%> must contain at least "
18770 "one %<map%> clause");
18774 tree stmt
= make_node (OMP_TARGET_ENTER_DATA
);
18775 TREE_TYPE (stmt
) = void_type_node
;
18776 OMP_TARGET_ENTER_DATA_CLAUSES (stmt
) = clauses
;
18777 SET_EXPR_LOCATION (stmt
, loc
);
18783 # pragma omp target exit data target-data-clause[optseq] new-line */
18785 #define OMP_TARGET_EXIT_DATA_CLAUSE_MASK \
18786 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
18787 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
18788 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
18789 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
18790 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
18793 c_parser_omp_target_exit_data (location_t loc
, c_parser
*parser
,
18794 enum pragma_context context
)
18796 bool data_seen
= false;
18797 if (c_parser_next_token_is (parser
, CPP_NAME
))
18799 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18800 if (strcmp (p
, "data") == 0)
18802 c_parser_consume_token (parser
);
18808 c_parser_error (parser
, "expected %<data%>");
18809 c_parser_skip_to_pragma_eol (parser
);
18813 if (context
== pragma_stmt
)
18815 error_at (loc
, "%<#pragma %s%> may only be used in compound statements",
18816 "omp target exit data");
18817 c_parser_skip_to_pragma_eol (parser
, false);
18822 = c_parser_omp_all_clauses (parser
, OMP_TARGET_EXIT_DATA_CLAUSE_MASK
,
18823 "#pragma omp target exit data");
18826 for (tree
*pc
= &clauses
; *pc
;)
18828 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_MAP
)
18829 switch (OMP_CLAUSE_MAP_KIND (*pc
))
18831 case GOMP_MAP_FROM
:
18832 case GOMP_MAP_ALWAYS_FROM
:
18833 case GOMP_MAP_RELEASE
:
18834 case GOMP_MAP_DELETE
:
18837 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
18838 case GOMP_MAP_ALWAYS_POINTER
:
18842 error_at (OMP_CLAUSE_LOCATION (*pc
),
18843 "%<#pragma omp target exit data%> with map-type other "
18844 "than %<from%>, %<release%> or %<delete%> on %<map%>"
18846 *pc
= OMP_CLAUSE_CHAIN (*pc
);
18849 pc
= &OMP_CLAUSE_CHAIN (*pc
);
18856 "%<#pragma omp target exit data%> must contain at least one "
18861 tree stmt
= make_node (OMP_TARGET_EXIT_DATA
);
18862 TREE_TYPE (stmt
) = void_type_node
;
18863 OMP_TARGET_EXIT_DATA_CLAUSES (stmt
) = clauses
;
18864 SET_EXPR_LOCATION (stmt
, loc
);
18870 # pragma omp target target-clause[optseq] new-line
18871 structured-block */
18873 #define OMP_TARGET_CLAUSE_MASK \
18874 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
18875 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
18876 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
18877 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
18878 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
18879 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
18880 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
18881 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULTMAP) \
18882 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR))
18885 c_parser_omp_target (c_parser
*parser
, enum pragma_context context
, bool *if_p
)
18887 location_t loc
= c_parser_peek_token (parser
)->location
;
18888 c_parser_consume_pragma (parser
);
18889 tree
*pc
= NULL
, stmt
, block
;
18891 if (context
!= pragma_stmt
&& context
!= pragma_compound
)
18893 c_parser_error (parser
, "expected declaration specifiers");
18894 c_parser_skip_to_pragma_eol (parser
);
18900 = (enum omp_requires
) (omp_requires_mask
| OMP_REQUIRES_TARGET_USED
);
18902 if (c_parser_next_token_is (parser
, CPP_NAME
))
18904 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18905 enum tree_code ccode
= ERROR_MARK
;
18907 if (strcmp (p
, "teams") == 0)
18909 else if (strcmp (p
, "parallel") == 0)
18910 ccode
= OMP_PARALLEL
;
18911 else if (strcmp (p
, "simd") == 0)
18913 if (ccode
!= ERROR_MARK
)
18915 tree cclauses
[C_OMP_CLAUSE_SPLIT_COUNT
];
18916 char p_name
[sizeof ("#pragma omp target teams distribute "
18917 "parallel for simd")];
18919 c_parser_consume_token (parser
);
18920 strcpy (p_name
, "#pragma omp target");
18921 if (!flag_openmp
) /* flag_openmp_simd */
18927 stmt
= c_parser_omp_teams (loc
, parser
, p_name
,
18928 OMP_TARGET_CLAUSE_MASK
,
18932 stmt
= c_parser_omp_parallel (loc
, parser
, p_name
,
18933 OMP_TARGET_CLAUSE_MASK
,
18937 stmt
= c_parser_omp_simd (loc
, parser
, p_name
,
18938 OMP_TARGET_CLAUSE_MASK
,
18942 gcc_unreachable ();
18944 return stmt
!= NULL_TREE
;
18946 keep_next_level ();
18947 tree block
= c_begin_compound_stmt (true), ret
;
18951 ret
= c_parser_omp_teams (loc
, parser
, p_name
,
18952 OMP_TARGET_CLAUSE_MASK
, cclauses
,
18956 ret
= c_parser_omp_parallel (loc
, parser
, p_name
,
18957 OMP_TARGET_CLAUSE_MASK
, cclauses
,
18961 ret
= c_parser_omp_simd (loc
, parser
, p_name
,
18962 OMP_TARGET_CLAUSE_MASK
, cclauses
,
18966 gcc_unreachable ();
18968 block
= c_end_compound_stmt (loc
, block
, true);
18969 if (ret
== NULL_TREE
)
18971 if (ccode
== OMP_TEAMS
)
18973 /* For combined target teams, ensure the num_teams and
18974 thread_limit clause expressions are evaluated on the host,
18975 before entering the target construct. */
18977 for (c
= cclauses
[C_OMP_CLAUSE_SPLIT_TEAMS
];
18978 c
; c
= OMP_CLAUSE_CHAIN (c
))
18979 if ((OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_NUM_TEAMS
18980 || OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_THREAD_LIMIT
)
18981 && TREE_CODE (OMP_CLAUSE_OPERAND (c
, 0)) != INTEGER_CST
)
18983 tree expr
= OMP_CLAUSE_OPERAND (c
, 0);
18984 tree tmp
= create_tmp_var_raw (TREE_TYPE (expr
));
18985 expr
= build4 (TARGET_EXPR
, TREE_TYPE (expr
), tmp
,
18986 expr
, NULL_TREE
, NULL_TREE
);
18988 OMP_CLAUSE_OPERAND (c
, 0) = expr
;
18989 tree tc
= build_omp_clause (OMP_CLAUSE_LOCATION (c
),
18990 OMP_CLAUSE_FIRSTPRIVATE
);
18991 OMP_CLAUSE_DECL (tc
) = tmp
;
18992 OMP_CLAUSE_CHAIN (tc
)
18993 = cclauses
[C_OMP_CLAUSE_SPLIT_TARGET
];
18994 cclauses
[C_OMP_CLAUSE_SPLIT_TARGET
] = tc
;
18997 tree stmt
= make_node (OMP_TARGET
);
18998 TREE_TYPE (stmt
) = void_type_node
;
18999 OMP_TARGET_CLAUSES (stmt
) = cclauses
[C_OMP_CLAUSE_SPLIT_TARGET
];
19000 OMP_TARGET_BODY (stmt
) = block
;
19001 OMP_TARGET_COMBINED (stmt
) = 1;
19002 SET_EXPR_LOCATION (stmt
, loc
);
19004 pc
= &OMP_TARGET_CLAUSES (stmt
);
19005 goto check_clauses
;
19007 else if (!flag_openmp
) /* flag_openmp_simd */
19009 c_parser_skip_to_pragma_eol (parser
, false);
19012 else if (strcmp (p
, "data") == 0)
19014 c_parser_consume_token (parser
);
19015 c_parser_omp_target_data (loc
, parser
, if_p
);
19018 else if (strcmp (p
, "enter") == 0)
19020 c_parser_consume_token (parser
);
19021 c_parser_omp_target_enter_data (loc
, parser
, context
);
19024 else if (strcmp (p
, "exit") == 0)
19026 c_parser_consume_token (parser
);
19027 c_parser_omp_target_exit_data (loc
, parser
, context
);
19030 else if (strcmp (p
, "update") == 0)
19032 c_parser_consume_token (parser
);
19033 return c_parser_omp_target_update (loc
, parser
, context
);
19036 if (!flag_openmp
) /* flag_openmp_simd */
19038 c_parser_skip_to_pragma_eol (parser
, false);
19042 stmt
= make_node (OMP_TARGET
);
19043 TREE_TYPE (stmt
) = void_type_node
;
19045 OMP_TARGET_CLAUSES (stmt
)
19046 = c_parser_omp_all_clauses (parser
, OMP_TARGET_CLAUSE_MASK
,
19047 "#pragma omp target");
19048 pc
= &OMP_TARGET_CLAUSES (stmt
);
19049 keep_next_level ();
19050 block
= c_begin_compound_stmt (true);
19051 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
19052 OMP_TARGET_BODY (stmt
) = c_end_compound_stmt (loc
, block
, true);
19054 SET_EXPR_LOCATION (stmt
, loc
);
19060 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_MAP
)
19061 switch (OMP_CLAUSE_MAP_KIND (*pc
))
19064 case GOMP_MAP_ALWAYS_TO
:
19065 case GOMP_MAP_FROM
:
19066 case GOMP_MAP_ALWAYS_FROM
:
19067 case GOMP_MAP_TOFROM
:
19068 case GOMP_MAP_ALWAYS_TOFROM
:
19069 case GOMP_MAP_ALLOC
:
19070 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
19071 case GOMP_MAP_ALWAYS_POINTER
:
19074 error_at (OMP_CLAUSE_LOCATION (*pc
),
19075 "%<#pragma omp target%> with map-type other "
19076 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
19077 "on %<map%> clause");
19078 *pc
= OMP_CLAUSE_CHAIN (*pc
);
19081 pc
= &OMP_CLAUSE_CHAIN (*pc
);
19087 # pragma omp declare simd declare-simd-clauses[optseq] new-line
19090 # pragma omp declare variant (identifier) match(context-selector) new-line
19093 #define OMP_DECLARE_SIMD_CLAUSE_MASK \
19094 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
19095 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
19096 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
19097 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM) \
19098 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INBRANCH) \
19099 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOTINBRANCH))
19102 c_parser_omp_declare_simd (c_parser
*parser
, enum pragma_context context
)
19104 c_token
*token
= c_parser_peek_token (parser
);
19105 gcc_assert (token
->type
== CPP_NAME
);
19106 tree kind
= token
->value
;
19107 gcc_assert (strcmp (IDENTIFIER_POINTER (kind
), "simd") == 0
19108 || strcmp (IDENTIFIER_POINTER (kind
), "variant") == 0);
19110 auto_vec
<c_token
> clauses
;
19111 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
19113 c_token
*token
= c_parser_peek_token (parser
);
19114 if (token
->type
== CPP_EOF
)
19116 c_parser_skip_to_pragma_eol (parser
);
19119 clauses
.safe_push (*token
);
19120 c_parser_consume_token (parser
);
19122 clauses
.safe_push (*c_parser_peek_token (parser
));
19123 c_parser_skip_to_pragma_eol (parser
);
19125 while (c_parser_next_token_is (parser
, CPP_PRAGMA
))
19127 if (c_parser_peek_token (parser
)->pragma_kind
!= PRAGMA_OMP_DECLARE
19128 || c_parser_peek_2nd_token (parser
)->type
!= CPP_NAME
19129 || c_parser_peek_2nd_token (parser
)->value
!= kind
)
19131 error ("%<#pragma omp declare %s%> must be followed by "
19132 "function declaration or definition or another "
19133 "%<#pragma omp declare %s%>",
19134 IDENTIFIER_POINTER (kind
), IDENTIFIER_POINTER (kind
));
19137 c_parser_consume_pragma (parser
);
19138 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
19140 c_token
*token
= c_parser_peek_token (parser
);
19141 if (token
->type
== CPP_EOF
)
19143 c_parser_skip_to_pragma_eol (parser
);
19146 clauses
.safe_push (*token
);
19147 c_parser_consume_token (parser
);
19149 clauses
.safe_push (*c_parser_peek_token (parser
));
19150 c_parser_skip_to_pragma_eol (parser
);
19153 /* Make sure nothing tries to read past the end of the tokens. */
19155 memset (&eof_token
, 0, sizeof (eof_token
));
19156 eof_token
.type
= CPP_EOF
;
19157 clauses
.safe_push (eof_token
);
19158 clauses
.safe_push (eof_token
);
19162 case pragma_external
:
19163 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
19164 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
)
19166 int ext
= disable_extension_diagnostics ();
19168 c_parser_consume_token (parser
);
19169 while (c_parser_next_token_is (parser
, CPP_KEYWORD
)
19170 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
);
19171 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
19173 restore_extension_diagnostics (ext
);
19176 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
19179 case pragma_struct
:
19182 error ("%<#pragma omp declare %s%> must be followed by "
19183 "function declaration or definition",
19184 IDENTIFIER_POINTER (kind
));
19186 case pragma_compound
:
19187 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
19188 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
)
19190 int ext
= disable_extension_diagnostics ();
19192 c_parser_consume_token (parser
);
19193 while (c_parser_next_token_is (parser
, CPP_KEYWORD
)
19194 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
);
19195 if (c_parser_next_tokens_start_declaration (parser
))
19197 c_parser_declaration_or_fndef (parser
, true, true, true, true,
19198 true, NULL
, clauses
);
19199 restore_extension_diagnostics (ext
);
19202 restore_extension_diagnostics (ext
);
19204 else if (c_parser_next_tokens_start_declaration (parser
))
19206 c_parser_declaration_or_fndef (parser
, true, true, true, true, true,
19210 error ("%<#pragma omp declare %s%> must be followed by "
19211 "function declaration or definition",
19212 IDENTIFIER_POINTER (kind
));
19215 gcc_unreachable ();
19219 static const char *const omp_construct_selectors
[] = {
19220 "simd", "target", "teams", "parallel", "for", NULL
};
19221 static const char *const omp_device_selectors
[] = {
19222 "kind", "isa", "arch", NULL
};
19223 static const char *const omp_implementation_selectors
[] = {
19224 "vendor", "extension", "atomic_default_mem_order", "unified_address",
19225 "unified_shared_memory", "dynamic_allocators", "reverse_offload", NULL
};
19226 static const char *const omp_user_selectors
[] = {
19227 "condition", NULL
};
19232 trait-selector-name[([trait-score:]trait-property[,trait-property[,...]])]
19235 score(score-expression) */
19238 c_parser_omp_context_selector (c_parser
*parser
, tree set
, tree parms
)
19240 tree ret
= NULL_TREE
;
19244 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
19245 || c_parser_next_token_is (parser
, CPP_NAME
))
19246 selector
= c_parser_peek_token (parser
)->value
;
19249 c_parser_error (parser
, "expected trait selector name");
19250 return error_mark_node
;
19253 tree properties
= NULL_TREE
;
19254 const char *const *selectors
= NULL
;
19255 bool allow_score
= true;
19256 bool allow_user
= false;
19257 int property_limit
= 0;
19258 enum { CTX_PROPERTY_NONE
, CTX_PROPERTY_USER
, CTX_PROPERTY_IDLIST
,
19259 CTX_PROPERTY_EXPR
, CTX_PROPERTY_SIMD
} property_kind
19260 = CTX_PROPERTY_NONE
;
19261 switch (IDENTIFIER_POINTER (set
)[0])
19263 case 'c': /* construct */
19264 selectors
= omp_construct_selectors
;
19265 allow_score
= false;
19266 property_limit
= 1;
19267 property_kind
= CTX_PROPERTY_SIMD
;
19269 case 'd': /* device */
19270 selectors
= omp_device_selectors
;
19271 allow_score
= false;
19273 property_limit
= 3;
19274 property_kind
= CTX_PROPERTY_IDLIST
;
19276 case 'i': /* implementation */
19277 selectors
= omp_implementation_selectors
;
19279 property_limit
= 3;
19280 property_kind
= CTX_PROPERTY_IDLIST
;
19282 case 'u': /* user */
19283 selectors
= omp_user_selectors
;
19284 property_limit
= 1;
19285 property_kind
= CTX_PROPERTY_EXPR
;
19288 gcc_unreachable ();
19290 for (int i
= 0; ; i
++)
19292 if (selectors
[i
] == NULL
)
19296 property_kind
= CTX_PROPERTY_USER
;
19301 error_at (c_parser_peek_token (parser
)->location
,
19302 "selector %qs not allowed for context selector "
19303 "set %qs", IDENTIFIER_POINTER (selector
),
19304 IDENTIFIER_POINTER (set
));
19305 c_parser_consume_token (parser
);
19306 return error_mark_node
;
19309 if (i
== property_limit
)
19310 property_kind
= CTX_PROPERTY_NONE
;
19311 if (strcmp (selectors
[i
], IDENTIFIER_POINTER (selector
)) == 0)
19315 c_parser_consume_token (parser
);
19317 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
19319 if (property_kind
== CTX_PROPERTY_NONE
)
19321 error_at (c_parser_peek_token (parser
)->location
,
19322 "selector %qs does not accept any properties",
19323 IDENTIFIER_POINTER (selector
));
19324 return error_mark_node
;
19327 matching_parens parens
;
19328 parens
.require_open (parser
);
19330 c_token
*token
= c_parser_peek_token (parser
);
19332 && c_parser_next_token_is (parser
, CPP_NAME
)
19333 && strcmp (IDENTIFIER_POINTER (token
->value
), "score") == 0
19334 && c_parser_peek_2nd_token (parser
)->type
== CPP_OPEN_PAREN
)
19336 c_parser_consume_token (parser
);
19338 matching_parens parens2
;
19339 parens2
.require_open (parser
);
19340 tree score
= c_parser_expr_no_commas (parser
, NULL
).value
;
19341 parens2
.skip_until_found_close (parser
);
19342 c_parser_require (parser
, CPP_COLON
, "expected %<:%>");
19343 if (score
!= error_mark_node
)
19345 mark_exp_read (score
);
19346 score
= c_fully_fold (score
, false, NULL
);
19347 if (!INTEGRAL_TYPE_P (TREE_TYPE (score
))
19348 || !tree_fits_shwi_p (score
))
19349 error_at (token
->location
, "score argument must be "
19350 "constant integer expression");
19352 properties
= tree_cons (get_identifier (" score"),
19353 score
, properties
);
19355 token
= c_parser_peek_token (parser
);
19358 switch (property_kind
)
19361 case CTX_PROPERTY_USER
:
19364 t
= c_parser_expr_no_commas (parser
, NULL
).value
;
19365 if (TREE_CODE (t
) == STRING_CST
)
19366 properties
= tree_cons (NULL_TREE
, t
, properties
);
19367 else if (t
!= error_mark_node
)
19370 t
= c_fully_fold (t
, false, NULL
);
19371 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
))
19372 || !tree_fits_shwi_p (t
))
19373 error_at (token
->location
, "property must be "
19374 "constant integer expression or string "
19377 properties
= tree_cons (NULL_TREE
, t
, properties
);
19380 return error_mark_node
;
19382 if (c_parser_next_token_is (parser
, CPP_COMMA
))
19383 c_parser_consume_token (parser
);
19389 case CTX_PROPERTY_IDLIST
:
19393 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
19394 || c_parser_next_token_is (parser
, CPP_NAME
))
19395 prop
= c_parser_peek_token (parser
)->value
;
19398 c_parser_error (parser
, "expected identifier");
19399 return error_mark_node
;
19401 c_parser_consume_token (parser
);
19403 properties
= tree_cons (prop
, NULL_TREE
, properties
);
19405 if (c_parser_next_token_is (parser
, CPP_COMMA
))
19406 c_parser_consume_token (parser
);
19412 case CTX_PROPERTY_EXPR
:
19413 t
= c_parser_expr_no_commas (parser
, NULL
).value
;
19414 if (t
!= error_mark_node
)
19417 t
= c_fully_fold (t
, false, NULL
);
19418 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
))
19419 || !tree_fits_shwi_p (t
))
19420 error_at (token
->location
, "property must be "
19421 "constant integer expression");
19423 properties
= tree_cons (NULL_TREE
, t
, properties
);
19426 return error_mark_node
;
19428 case CTX_PROPERTY_SIMD
:
19429 if (parms
== NULL_TREE
)
19431 error_at (token
->location
, "properties for %<simd%> "
19432 "selector may not be specified in "
19433 "%<metadirective%>");
19434 return error_mark_node
;
19437 c
= c_parser_omp_all_clauses (parser
,
19438 OMP_DECLARE_SIMD_CLAUSE_MASK
,
19440 c
= c_omp_declare_simd_clauses_to_numbers (parms
19442 ? NULL_TREE
: parms
,
19447 gcc_unreachable ();
19450 parens
.skip_until_found_close (parser
);
19451 properties
= nreverse (properties
);
19453 else if (property_kind
== CTX_PROPERTY_IDLIST
19454 || property_kind
== CTX_PROPERTY_EXPR
)
19456 c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>");
19457 return error_mark_node
;
19460 ret
= tree_cons (selector
, properties
, ret
);
19462 if (c_parser_next_token_is (parser
, CPP_COMMA
))
19463 c_parser_consume_token (parser
);
19469 return nreverse (ret
);
19474 trait-set-selector[,trait-set-selector[,...]]
19476 trait-set-selector:
19477 trait-set-selector-name = { trait-selector[, trait-selector[, ...]] }
19479 trait-set-selector-name:
19486 c_parser_omp_context_selector_specification (c_parser
*parser
, tree parms
)
19488 tree ret
= NULL_TREE
;
19491 const char *setp
= "";
19492 if (c_parser_next_token_is (parser
, CPP_NAME
))
19493 setp
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
19497 if (strcmp (setp
, "construct") == 0)
19501 if (strcmp (setp
, "device") == 0)
19505 if (strcmp (setp
, "implementation") == 0)
19509 if (strcmp (setp
, "user") == 0)
19517 c_parser_error (parser
, "expected %<construct%>, %<device%>, "
19518 "%<implementation%> or %<user%>");
19519 return error_mark_node
;
19522 tree set
= c_parser_peek_token (parser
)->value
;
19523 c_parser_consume_token (parser
);
19525 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
19526 return error_mark_node
;
19528 matching_braces braces
;
19529 if (!braces
.require_open (parser
))
19530 return error_mark_node
;
19532 tree selectors
= c_parser_omp_context_selector (parser
, set
, parms
);
19533 if (selectors
== error_mark_node
)
19534 ret
= error_mark_node
;
19535 else if (ret
!= error_mark_node
)
19536 ret
= tree_cons (set
, selectors
, ret
);
19538 braces
.skip_until_found_close (parser
);
19540 if (c_parser_next_token_is (parser
, CPP_COMMA
))
19541 c_parser_consume_token (parser
);
19547 if (ret
== error_mark_node
)
19549 return nreverse (ret
);
19552 /* Finalize #pragma omp declare variant after FNDECL has been parsed, and put
19553 that into "omp declare variant base" attribute. */
19556 c_finish_omp_declare_variant (c_parser
*parser
, tree fndecl
, tree parms
)
19558 matching_parens parens
;
19559 if (!parens
.require_open (parser
))
19562 c_parser_skip_to_pragma_eol (parser
, false);
19566 if (c_parser_next_token_is_not (parser
, CPP_NAME
)
19567 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
19569 c_parser_error (parser
, "expected identifier");
19573 c_token
*token
= c_parser_peek_token (parser
);
19574 tree variant
= lookup_name (token
->value
);
19576 if (variant
== NULL_TREE
)
19578 undeclared_variable (token
->location
, token
->value
);
19579 variant
= error_mark_node
;
19582 c_parser_consume_token (parser
);
19584 parens
.require_close (parser
);
19586 const char *clause
= "";
19587 location_t match_loc
= c_parser_peek_token (parser
)->location
;
19588 if (c_parser_next_token_is (parser
, CPP_NAME
))
19589 clause
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
19590 if (strcmp (clause
, "match"))
19592 c_parser_error (parser
, "expected %<match%>");
19596 c_parser_consume_token (parser
);
19598 if (!parens
.require_open (parser
))
19601 if (parms
== NULL_TREE
)
19602 parms
= error_mark_node
;
19604 tree ctx
= c_parser_omp_context_selector_specification (parser
, parms
);
19605 if (ctx
== error_mark_node
)
19607 ctx
= c_omp_check_context_selector (match_loc
, ctx
);
19608 if (ctx
!= error_mark_node
&& variant
!= error_mark_node
)
19610 if (TREE_CODE (variant
) != FUNCTION_DECL
)
19612 error_at (token
->location
, "variant %qD is not a function", variant
);
19613 variant
= error_mark_node
;
19615 else if (omp_get_context_selector (ctx
, "construct", "simd") == NULL_TREE
19616 && !comptypes (TREE_TYPE (fndecl
), TREE_TYPE (variant
)))
19618 error_at (token
->location
, "variant %qD and base %qD have "
19619 "incompatible types", variant
, fndecl
);
19620 variant
= error_mark_node
;
19622 else if (fndecl_built_in_p (variant
)
19623 && (strncmp (IDENTIFIER_POINTER (DECL_NAME (variant
)),
19624 "__builtin_", strlen ("__builtin_")) == 0
19625 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant
)),
19626 "__sync_", strlen ("__sync_")) == 0
19627 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant
)),
19628 "__atomic_", strlen ("__atomic_")) == 0))
19630 error_at (token
->location
, "variant %qD is a built-in", variant
);
19631 variant
= error_mark_node
;
19633 if (variant
!= error_mark_node
)
19635 C_DECL_USED (variant
) = 1;
19636 tree construct
= omp_get_context_selector (ctx
, "construct", NULL
);
19637 c_omp_mark_declare_variant (match_loc
, variant
, construct
);
19638 if (omp_context_selector_matches (ctx
))
19641 = tree_cons (get_identifier ("omp declare variant base"),
19642 build_tree_list (variant
, ctx
),
19643 DECL_ATTRIBUTES (fndecl
));
19644 DECL_ATTRIBUTES (fndecl
) = attr
;
19649 parens
.require_close (parser
);
19650 c_parser_skip_to_pragma_eol (parser
);
19653 /* Finalize #pragma omp declare simd or #pragma omp declare variant
19654 clauses after FNDECL has been parsed, and put that into "omp declare simd"
19655 or "omp declare variant base" attribute. */
19658 c_finish_omp_declare_simd (c_parser
*parser
, tree fndecl
, tree parms
,
19659 vec
<c_token
> clauses
)
19661 /* Normally first token is CPP_NAME "simd" or "variant". CPP_EOF there
19662 indicates error has been reported and CPP_PRAGMA that
19663 c_finish_omp_declare_simd has already processed the tokens. */
19664 if (clauses
.exists () && clauses
[0].type
== CPP_EOF
)
19666 const char *kind
= "simd";
19667 if (clauses
.exists ()
19668 && (clauses
[0].type
== CPP_NAME
|| clauses
[0].type
== CPP_PRAGMA
))
19669 kind
= IDENTIFIER_POINTER (clauses
[0].value
);
19670 gcc_assert (strcmp (kind
, "simd") == 0 || strcmp (kind
, "variant") == 0);
19671 if (fndecl
== NULL_TREE
|| TREE_CODE (fndecl
) != FUNCTION_DECL
)
19673 error ("%<#pragma omp declare %s%> not immediately followed by "
19674 "a function declaration or definition", kind
);
19675 clauses
[0].type
= CPP_EOF
;
19678 if (clauses
.exists () && clauses
[0].type
!= CPP_NAME
)
19680 error_at (DECL_SOURCE_LOCATION (fndecl
),
19681 "%<#pragma omp declare %s%> not immediately followed by "
19682 "a single function declaration or definition", kind
);
19683 clauses
[0].type
= CPP_EOF
;
19687 if (parms
== NULL_TREE
)
19688 parms
= DECL_ARGUMENTS (fndecl
);
19690 unsigned int tokens_avail
= parser
->tokens_avail
;
19691 gcc_assert (parser
->tokens
== &parser
->tokens_buf
[0]);
19693 parser
->tokens
= clauses
.address ();
19694 parser
->tokens_avail
= clauses
.length ();
19696 /* c_parser_omp_declare_simd pushed 2 extra CPP_EOF tokens at the end. */
19697 while (parser
->tokens_avail
> 3)
19699 c_token
*token
= c_parser_peek_token (parser
);
19700 gcc_assert (token
->type
== CPP_NAME
19701 && strcmp (IDENTIFIER_POINTER (token
->value
), kind
) == 0);
19702 c_parser_consume_token (parser
);
19703 parser
->in_pragma
= true;
19705 if (strcmp (kind
, "simd") == 0)
19708 c
= c_parser_omp_all_clauses (parser
, OMP_DECLARE_SIMD_CLAUSE_MASK
,
19709 "#pragma omp declare simd");
19710 c
= c_omp_declare_simd_clauses_to_numbers (parms
, c
);
19711 if (c
!= NULL_TREE
)
19712 c
= tree_cons (NULL_TREE
, c
, NULL_TREE
);
19713 c
= build_tree_list (get_identifier ("omp declare simd"), c
);
19714 TREE_CHAIN (c
) = DECL_ATTRIBUTES (fndecl
);
19715 DECL_ATTRIBUTES (fndecl
) = c
;
19719 gcc_assert (strcmp (kind
, "variant") == 0);
19720 c_finish_omp_declare_variant (parser
, fndecl
, parms
);
19724 parser
->tokens
= &parser
->tokens_buf
[0];
19725 parser
->tokens_avail
= tokens_avail
;
19726 if (clauses
.exists ())
19727 clauses
[0].type
= CPP_PRAGMA
;
19732 # pragma omp declare target new-line
19733 declarations and definitions
19734 # pragma omp end declare target new-line
19737 # pragma omp declare target ( extended-list ) new-line
19739 # pragma omp declare target declare-target-clauses[seq] new-line */
19741 #define OMP_DECLARE_TARGET_CLAUSE_MASK \
19742 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
19743 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK) \
19744 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE))
19747 c_parser_omp_declare_target (c_parser
*parser
)
19749 tree clauses
= NULL_TREE
;
19750 int device_type
= 0;
19751 bool only_device_type
= true;
19752 if (c_parser_next_token_is (parser
, CPP_NAME
))
19753 clauses
= c_parser_omp_all_clauses (parser
, OMP_DECLARE_TARGET_CLAUSE_MASK
,
19754 "#pragma omp declare target");
19755 else if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
19757 clauses
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_TO_DECLARE
,
19759 clauses
= c_finish_omp_clauses (clauses
, C_ORT_OMP
);
19760 c_parser_skip_to_pragma_eol (parser
);
19764 c_parser_skip_to_pragma_eol (parser
);
19765 current_omp_declare_target_attribute
++;
19768 for (tree c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
19769 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEVICE_TYPE
)
19770 device_type
|= OMP_CLAUSE_DEVICE_TYPE_KIND (c
);
19771 for (tree c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
19773 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEVICE_TYPE
)
19775 tree t
= OMP_CLAUSE_DECL (c
), id
;
19776 tree at1
= lookup_attribute ("omp declare target", DECL_ATTRIBUTES (t
));
19777 tree at2
= lookup_attribute ("omp declare target link",
19778 DECL_ATTRIBUTES (t
));
19779 only_device_type
= false;
19780 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LINK
)
19782 id
= get_identifier ("omp declare target link");
19783 std::swap (at1
, at2
);
19786 id
= get_identifier ("omp declare target");
19789 error_at (OMP_CLAUSE_LOCATION (c
),
19790 "%qD specified both in declare target %<link%> and %<to%>"
19796 DECL_ATTRIBUTES (t
) = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (t
));
19797 if (TREE_CODE (t
) != FUNCTION_DECL
&& !is_global_var (t
))
19800 symtab_node
*node
= symtab_node::get (t
);
19803 node
->offloadable
= 1;
19804 if (ENABLE_OFFLOADING
)
19806 g
->have_offload
= true;
19807 if (is_a
<varpool_node
*> (node
))
19808 vec_safe_push (offload_vars
, t
);
19812 if (TREE_CODE (t
) != FUNCTION_DECL
)
19814 if ((device_type
& OMP_CLAUSE_DEVICE_TYPE_HOST
) != 0)
19816 tree at3
= lookup_attribute ("omp declare target host",
19817 DECL_ATTRIBUTES (t
));
19818 if (at3
== NULL_TREE
)
19820 id
= get_identifier ("omp declare target host");
19821 DECL_ATTRIBUTES (t
)
19822 = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (t
));
19825 if ((device_type
& OMP_CLAUSE_DEVICE_TYPE_NOHOST
) != 0)
19827 tree at3
= lookup_attribute ("omp declare target nohost",
19828 DECL_ATTRIBUTES (t
));
19829 if (at3
== NULL_TREE
)
19831 id
= get_identifier ("omp declare target nohost");
19832 DECL_ATTRIBUTES (t
)
19833 = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (t
));
19837 if (device_type
&& only_device_type
)
19838 warning_at (OMP_CLAUSE_LOCATION (clauses
), 0,
19839 "directive with only %<device_type%> clauses ignored");
19843 c_parser_omp_end_declare_target (c_parser
*parser
)
19845 location_t loc
= c_parser_peek_token (parser
)->location
;
19846 c_parser_consume_pragma (parser
);
19847 if (c_parser_next_token_is (parser
, CPP_NAME
)
19848 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
),
19851 c_parser_consume_token (parser
);
19852 if (c_parser_next_token_is (parser
, CPP_NAME
)
19853 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
),
19855 c_parser_consume_token (parser
);
19858 c_parser_error (parser
, "expected %<target%>");
19859 c_parser_skip_to_pragma_eol (parser
);
19865 c_parser_error (parser
, "expected %<declare%>");
19866 c_parser_skip_to_pragma_eol (parser
);
19869 c_parser_skip_to_pragma_eol (parser
);
19870 if (!current_omp_declare_target_attribute
)
19871 error_at (loc
, "%<#pragma omp end declare target%> without corresponding "
19872 "%<#pragma omp declare target%>");
19874 current_omp_declare_target_attribute
--;
19879 #pragma omp declare reduction (reduction-id : typename-list : expression) \
19880 initializer-clause[opt] new-line
19882 initializer-clause:
19883 initializer (omp_priv = initializer)
19884 initializer (function-name (argument-list)) */
19887 c_parser_omp_declare_reduction (c_parser
*parser
, enum pragma_context context
)
19889 unsigned int tokens_avail
= 0, i
;
19890 vec
<tree
> types
= vNULL
;
19891 vec
<c_token
> clauses
= vNULL
;
19892 enum tree_code reduc_code
= ERROR_MARK
;
19893 tree reduc_id
= NULL_TREE
;
19895 location_t rloc
= c_parser_peek_token (parser
)->location
;
19897 if (context
== pragma_struct
|| context
== pragma_param
)
19899 error ("%<#pragma omp declare reduction%> not at file or block scope");
19903 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
19906 switch (c_parser_peek_token (parser
)->type
)
19909 reduc_code
= PLUS_EXPR
;
19912 reduc_code
= MULT_EXPR
;
19915 reduc_code
= MINUS_EXPR
;
19918 reduc_code
= BIT_AND_EXPR
;
19921 reduc_code
= BIT_XOR_EXPR
;
19924 reduc_code
= BIT_IOR_EXPR
;
19927 reduc_code
= TRUTH_ANDIF_EXPR
;
19930 reduc_code
= TRUTH_ORIF_EXPR
;
19934 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
19935 if (strcmp (p
, "min") == 0)
19937 reduc_code
= MIN_EXPR
;
19940 if (strcmp (p
, "max") == 0)
19942 reduc_code
= MAX_EXPR
;
19945 reduc_id
= c_parser_peek_token (parser
)->value
;
19948 c_parser_error (parser
,
19949 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
19950 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
19954 tree orig_reduc_id
, reduc_decl
;
19955 orig_reduc_id
= reduc_id
;
19956 reduc_id
= c_omp_reduction_id (reduc_code
, reduc_id
);
19957 reduc_decl
= c_omp_reduction_decl (reduc_id
);
19958 c_parser_consume_token (parser
);
19960 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
19965 location_t loc
= c_parser_peek_token (parser
)->location
;
19966 struct c_type_name
*ctype
= c_parser_type_name (parser
);
19969 type
= groktypename (ctype
, NULL
, NULL
);
19970 if (type
== error_mark_node
)
19972 else if ((INTEGRAL_TYPE_P (type
)
19973 || TREE_CODE (type
) == REAL_TYPE
19974 || TREE_CODE (type
) == COMPLEX_TYPE
)
19975 && orig_reduc_id
== NULL_TREE
)
19976 error_at (loc
, "predeclared arithmetic type in "
19977 "%<#pragma omp declare reduction%>");
19978 else if (TREE_CODE (type
) == FUNCTION_TYPE
19979 || TREE_CODE (type
) == ARRAY_TYPE
)
19980 error_at (loc
, "function or array type in "
19981 "%<#pragma omp declare reduction%>");
19982 else if (TYPE_ATOMIC (type
))
19983 error_at (loc
, "%<_Atomic%> qualified type in "
19984 "%<#pragma omp declare reduction%>");
19985 else if (TYPE_QUALS_NO_ADDR_SPACE (type
))
19986 error_at (loc
, "const, volatile or restrict qualified type in "
19987 "%<#pragma omp declare reduction%>");
19991 for (t
= DECL_INITIAL (reduc_decl
); t
; t
= TREE_CHAIN (t
))
19992 if (comptypes (TREE_PURPOSE (t
), type
))
19994 error_at (loc
, "redeclaration of %qs "
19995 "%<#pragma omp declare reduction%> for "
19997 IDENTIFIER_POINTER (reduc_id
)
19998 + sizeof ("omp declare reduction ") - 1,
20001 = DECL_SOURCE_LOCATION (TREE_VEC_ELT (TREE_VALUE (t
),
20003 error_at (ploc
, "previous %<#pragma omp declare "
20007 if (t
== NULL_TREE
)
20008 types
.safe_push (type
);
20010 if (c_parser_next_token_is (parser
, CPP_COMMA
))
20011 c_parser_consume_token (parser
);
20019 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>")
20020 || types
.is_empty ())
20023 clauses
.release ();
20027 c_token
*token
= c_parser_peek_token (parser
);
20028 if (token
->type
== CPP_EOF
|| token
->type
== CPP_PRAGMA_EOL
)
20030 c_parser_consume_token (parser
);
20032 c_parser_skip_to_pragma_eol (parser
);
20036 if (types
.length () > 1)
20038 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
20040 c_token
*token
= c_parser_peek_token (parser
);
20041 if (token
->type
== CPP_EOF
)
20043 clauses
.safe_push (*token
);
20044 c_parser_consume_token (parser
);
20046 clauses
.safe_push (*c_parser_peek_token (parser
));
20047 c_parser_skip_to_pragma_eol (parser
);
20049 /* Make sure nothing tries to read past the end of the tokens. */
20051 memset (&eof_token
, 0, sizeof (eof_token
));
20052 eof_token
.type
= CPP_EOF
;
20053 clauses
.safe_push (eof_token
);
20054 clauses
.safe_push (eof_token
);
20057 int errs
= errorcount
;
20058 FOR_EACH_VEC_ELT (types
, i
, type
)
20060 tokens_avail
= parser
->tokens_avail
;
20061 gcc_assert (parser
->tokens
== &parser
->tokens_buf
[0]);
20062 if (!clauses
.is_empty ())
20064 parser
->tokens
= clauses
.address ();
20065 parser
->tokens_avail
= clauses
.length ();
20066 parser
->in_pragma
= true;
20069 bool nested
= current_function_decl
!= NULL_TREE
;
20071 c_push_function_context ();
20072 tree fndecl
= build_decl (BUILTINS_LOCATION
, FUNCTION_DECL
,
20073 reduc_id
, default_function_type
);
20074 current_function_decl
= fndecl
;
20075 allocate_struct_function (fndecl
, true);
20077 tree stmt
= push_stmt_list ();
20078 /* Intentionally BUILTINS_LOCATION, so that -Wshadow doesn't
20079 warn about these. */
20080 tree omp_out
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
20081 get_identifier ("omp_out"), type
);
20082 DECL_ARTIFICIAL (omp_out
) = 1;
20083 DECL_CONTEXT (omp_out
) = fndecl
;
20084 pushdecl (omp_out
);
20085 tree omp_in
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
20086 get_identifier ("omp_in"), type
);
20087 DECL_ARTIFICIAL (omp_in
) = 1;
20088 DECL_CONTEXT (omp_in
) = fndecl
;
20090 struct c_expr combiner
= c_parser_expression (parser
);
20091 struct c_expr initializer
;
20092 tree omp_priv
= NULL_TREE
, omp_orig
= NULL_TREE
;
20094 initializer
.set_error ();
20095 if (!c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
20097 else if (c_parser_next_token_is (parser
, CPP_NAME
)
20098 && strcmp (IDENTIFIER_POINTER
20099 (c_parser_peek_token (parser
)->value
),
20100 "initializer") == 0)
20102 c_parser_consume_token (parser
);
20105 omp_priv
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
20106 get_identifier ("omp_priv"), type
);
20107 DECL_ARTIFICIAL (omp_priv
) = 1;
20108 DECL_INITIAL (omp_priv
) = error_mark_node
;
20109 DECL_CONTEXT (omp_priv
) = fndecl
;
20110 pushdecl (omp_priv
);
20111 omp_orig
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
20112 get_identifier ("omp_orig"), type
);
20113 DECL_ARTIFICIAL (omp_orig
) = 1;
20114 DECL_CONTEXT (omp_orig
) = fndecl
;
20115 pushdecl (omp_orig
);
20116 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
20118 else if (!c_parser_next_token_is (parser
, CPP_NAME
))
20120 c_parser_error (parser
, "expected %<omp_priv%> or "
20124 else if (strcmp (IDENTIFIER_POINTER
20125 (c_parser_peek_token (parser
)->value
),
20128 if (c_parser_peek_2nd_token (parser
)->type
!= CPP_OPEN_PAREN
20129 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
20131 c_parser_error (parser
, "expected function-name %<(%>");
20135 initializer
= c_parser_postfix_expression (parser
);
20136 if (initializer
.value
20137 && TREE_CODE (initializer
.value
) == CALL_EXPR
)
20140 tree c
= initializer
.value
;
20141 for (j
= 0; j
< call_expr_nargs (c
); j
++)
20143 tree a
= CALL_EXPR_ARG (c
, j
);
20145 if (TREE_CODE (a
) == ADDR_EXPR
20146 && TREE_OPERAND (a
, 0) == omp_priv
)
20149 if (j
== call_expr_nargs (c
))
20150 error ("one of the initializer call arguments should be "
20156 c_parser_consume_token (parser
);
20157 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
20161 tree st
= push_stmt_list ();
20162 location_t loc
= c_parser_peek_token (parser
)->location
;
20163 rich_location
richloc (line_table
, loc
);
20164 start_init (omp_priv
, NULL_TREE
, 0, &richloc
);
20165 struct c_expr init
= c_parser_initializer (parser
);
20167 finish_decl (omp_priv
, loc
, init
.value
,
20168 init
.original_type
, NULL_TREE
);
20169 pop_stmt_list (st
);
20173 && !c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
20179 c_parser_skip_to_pragma_eol (parser
);
20181 tree t
= tree_cons (type
, make_tree_vec (omp_priv
? 6 : 3),
20182 DECL_INITIAL (reduc_decl
));
20183 DECL_INITIAL (reduc_decl
) = t
;
20184 DECL_SOURCE_LOCATION (omp_out
) = rloc
;
20185 TREE_VEC_ELT (TREE_VALUE (t
), 0) = omp_out
;
20186 TREE_VEC_ELT (TREE_VALUE (t
), 1) = omp_in
;
20187 TREE_VEC_ELT (TREE_VALUE (t
), 2) = combiner
.value
;
20188 walk_tree (&combiner
.value
, c_check_omp_declare_reduction_r
,
20189 &TREE_VEC_ELT (TREE_VALUE (t
), 0), NULL
);
20192 DECL_SOURCE_LOCATION (omp_priv
) = rloc
;
20193 TREE_VEC_ELT (TREE_VALUE (t
), 3) = omp_priv
;
20194 TREE_VEC_ELT (TREE_VALUE (t
), 4) = omp_orig
;
20195 TREE_VEC_ELT (TREE_VALUE (t
), 5) = initializer
.value
;
20196 walk_tree (&initializer
.value
, c_check_omp_declare_reduction_r
,
20197 &TREE_VEC_ELT (TREE_VALUE (t
), 3), NULL
);
20198 walk_tree (&DECL_INITIAL (omp_priv
),
20199 c_check_omp_declare_reduction_r
,
20200 &TREE_VEC_ELT (TREE_VALUE (t
), 3), NULL
);
20204 pop_stmt_list (stmt
);
20206 if (cfun
->language
!= NULL
)
20208 ggc_free (cfun
->language
);
20209 cfun
->language
= NULL
;
20212 current_function_decl
= NULL_TREE
;
20214 c_pop_function_context ();
20216 if (!clauses
.is_empty ())
20218 parser
->tokens
= &parser
->tokens_buf
[0];
20219 parser
->tokens_avail
= tokens_avail
;
20223 if (errs
!= errorcount
)
20227 clauses
.release ();
20233 #pragma omp declare simd declare-simd-clauses[optseq] new-line
20234 #pragma omp declare reduction (reduction-id : typename-list : expression) \
20235 initializer-clause[opt] new-line
20236 #pragma omp declare target new-line
20239 #pragma omp declare variant (identifier) match (context-selector) */
20242 c_parser_omp_declare (c_parser
*parser
, enum pragma_context context
)
20244 c_parser_consume_pragma (parser
);
20245 if (c_parser_next_token_is (parser
, CPP_NAME
))
20247 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
20248 if (strcmp (p
, "simd") == 0)
20250 /* c_parser_consume_token (parser); done in
20251 c_parser_omp_declare_simd. */
20252 c_parser_omp_declare_simd (parser
, context
);
20255 if (strcmp (p
, "reduction") == 0)
20257 c_parser_consume_token (parser
);
20258 c_parser_omp_declare_reduction (parser
, context
);
20261 if (!flag_openmp
) /* flag_openmp_simd */
20263 c_parser_skip_to_pragma_eol (parser
, false);
20266 if (strcmp (p
, "target") == 0)
20268 c_parser_consume_token (parser
);
20269 c_parser_omp_declare_target (parser
);
20272 if (strcmp (p
, "variant") == 0)
20274 /* c_parser_consume_token (parser); done in
20275 c_parser_omp_declare_simd. */
20276 c_parser_omp_declare_simd (parser
, context
);
20281 c_parser_error (parser
, "expected %<simd%>, %<reduction%>, "
20282 "%<target%> or %<variant%>");
20283 c_parser_skip_to_pragma_eol (parser
);
20287 #pragma omp requires clauses[optseq] new-line */
20290 c_parser_omp_requires (c_parser
*parser
)
20293 enum omp_requires new_req
= (enum omp_requires
) 0;
20295 c_parser_consume_pragma (parser
);
20297 location_t loc
= c_parser_peek_token (parser
)->location
;
20298 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
20300 if (!first
&& c_parser_next_token_is (parser
, CPP_COMMA
))
20301 c_parser_consume_token (parser
);
20305 if (c_parser_next_token_is (parser
, CPP_NAME
))
20308 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
20309 location_t cloc
= c_parser_peek_token (parser
)->location
;
20310 enum omp_requires this_req
= (enum omp_requires
) 0;
20312 if (!strcmp (p
, "unified_address"))
20313 this_req
= OMP_REQUIRES_UNIFIED_ADDRESS
;
20314 else if (!strcmp (p
, "unified_shared_memory"))
20315 this_req
= OMP_REQUIRES_UNIFIED_SHARED_MEMORY
;
20316 else if (!strcmp (p
, "dynamic_allocators"))
20317 this_req
= OMP_REQUIRES_DYNAMIC_ALLOCATORS
;
20318 else if (!strcmp (p
, "reverse_offload"))
20319 this_req
= OMP_REQUIRES_REVERSE_OFFLOAD
;
20320 else if (!strcmp (p
, "atomic_default_mem_order"))
20322 c_parser_consume_token (parser
);
20324 matching_parens parens
;
20325 if (parens
.require_open (parser
))
20327 if (c_parser_next_token_is (parser
, CPP_NAME
))
20329 tree v
= c_parser_peek_token (parser
)->value
;
20330 p
= IDENTIFIER_POINTER (v
);
20332 if (!strcmp (p
, "seq_cst"))
20334 = (enum omp_requires
) OMP_MEMORY_ORDER_SEQ_CST
;
20335 else if (!strcmp (p
, "relaxed"))
20337 = (enum omp_requires
) OMP_MEMORY_ORDER_RELAXED
;
20338 else if (!strcmp (p
, "acq_rel"))
20340 = (enum omp_requires
) OMP_MEMORY_ORDER_ACQ_REL
;
20344 error_at (c_parser_peek_token (parser
)->location
,
20345 "expected %<seq_cst%>, %<relaxed%> or "
20347 if (c_parser_peek_2nd_token (parser
)->type
20348 == CPP_CLOSE_PAREN
)
20349 c_parser_consume_token (parser
);
20352 c_parser_consume_token (parser
);
20354 parens
.skip_until_found_close (parser
);
20357 c_parser_skip_to_pragma_eol (parser
, false);
20365 error_at (cloc
, "expected %<unified_address%>, "
20366 "%<unified_shared_memory%>, "
20367 "%<dynamic_allocators%>, "
20368 "%<reverse_offload%> "
20369 "or %<atomic_default_mem_order%> clause");
20370 c_parser_skip_to_pragma_eol (parser
, false);
20374 sorry_at (cloc
, "%qs clause on %<requires%> directive not "
20375 "supported yet", p
);
20377 c_parser_consume_token (parser
);
20380 if ((this_req
& ~OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
) != 0)
20382 if ((this_req
& new_req
) != 0)
20383 error_at (cloc
, "too many %qs clauses", p
);
20384 if (this_req
!= OMP_REQUIRES_DYNAMIC_ALLOCATORS
20385 && (omp_requires_mask
& OMP_REQUIRES_TARGET_USED
) != 0)
20386 error_at (cloc
, "%qs clause used lexically after first "
20387 "target construct or offloading API", p
);
20389 else if ((new_req
& OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
) != 0)
20391 error_at (cloc
, "too many %qs clauses",
20392 "atomic_default_mem_order");
20393 this_req
= (enum omp_requires
) 0;
20395 else if ((omp_requires_mask
20396 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
) != 0)
20398 error_at (cloc
, "more than one %<atomic_default_mem_order%>"
20399 " clause in a single compilation unit");
20401 = (enum omp_requires
)
20403 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
);
20405 else if ((omp_requires_mask
20406 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED
) != 0)
20407 error_at (cloc
, "%<atomic_default_mem_order%> clause used "
20408 "lexically after first %<atomic%> construct "
20409 "without memory order clause");
20410 new_req
= (enum omp_requires
) (new_req
| this_req
);
20412 = (enum omp_requires
) (omp_requires_mask
| this_req
);
20418 c_parser_skip_to_pragma_eol (parser
);
20421 error_at (loc
, "%<pragma omp requires%> requires at least one clause");
20424 /* Helper function for c_parser_omp_taskloop.
20425 Disallow zero sized or potentially zero sized task reductions. */
20428 c_finish_taskloop_clauses (tree clauses
)
20430 tree
*pc
= &clauses
;
20431 for (tree c
= clauses
; c
; c
= *pc
)
20433 bool remove
= false;
20434 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_REDUCTION
)
20436 tree type
= strip_array_types (TREE_TYPE (OMP_CLAUSE_DECL (c
)));
20437 if (integer_zerop (TYPE_SIZE_UNIT (type
)))
20439 error_at (OMP_CLAUSE_LOCATION (c
),
20440 "zero sized type %qT in %<reduction%> clause", type
);
20443 else if (TREE_CODE (TYPE_SIZE_UNIT (type
)) != INTEGER_CST
)
20445 error_at (OMP_CLAUSE_LOCATION (c
),
20446 "variable sized type %qT in %<reduction%> clause",
20452 *pc
= OMP_CLAUSE_CHAIN (c
);
20454 pc
= &OMP_CLAUSE_CHAIN (c
);
20460 #pragma omp taskloop taskloop-clause[optseq] new-line
20463 #pragma omp taskloop simd taskloop-simd-clause[optseq] new-line
20466 #define OMP_TASKLOOP_CLAUSE_MASK \
20467 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
20468 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20469 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20470 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
20471 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
20472 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_GRAINSIZE) \
20473 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TASKS) \
20474 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
20475 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
20476 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
20477 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
20478 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
20479 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP) \
20480 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
20481 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
20482 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION))
20485 c_parser_omp_taskloop (location_t loc
, c_parser
*parser
,
20486 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
20489 tree clauses
, block
, ret
;
20491 strcat (p_name
, " taskloop");
20492 mask
|= OMP_TASKLOOP_CLAUSE_MASK
;
20493 /* #pragma omp parallel master taskloop{, simd} disallow in_reduction
20495 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_NUM_THREADS
)) != 0)
20496 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_IN_REDUCTION
);
20498 if (c_parser_next_token_is (parser
, CPP_NAME
))
20500 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
20502 if (strcmp (p
, "simd") == 0)
20504 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
20505 if (cclauses
== NULL
)
20506 cclauses
= cclauses_buf
;
20507 c_parser_consume_token (parser
);
20508 if (!flag_openmp
) /* flag_openmp_simd */
20509 return c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
,
20511 block
= c_begin_compound_stmt (true);
20512 ret
= c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
20513 block
= c_end_compound_stmt (loc
, block
, true);
20516 ret
= make_node (OMP_TASKLOOP
);
20517 TREE_TYPE (ret
) = void_type_node
;
20518 OMP_FOR_BODY (ret
) = block
;
20519 OMP_FOR_CLAUSES (ret
) = cclauses
[C_OMP_CLAUSE_SPLIT_TASKLOOP
];
20520 OMP_FOR_CLAUSES (ret
)
20521 = c_finish_taskloop_clauses (OMP_FOR_CLAUSES (ret
));
20522 SET_EXPR_LOCATION (ret
, loc
);
20527 if (!flag_openmp
) /* flag_openmp_simd */
20529 c_parser_skip_to_pragma_eol (parser
, false);
20533 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
20536 omp_split_clauses (loc
, OMP_TASKLOOP
, mask
, clauses
, cclauses
);
20537 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_TASKLOOP
];
20540 clauses
= c_finish_taskloop_clauses (clauses
);
20541 block
= c_begin_compound_stmt (true);
20542 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_TASKLOOP
, clauses
, NULL
, if_p
);
20543 block
= c_end_compound_stmt (loc
, block
, true);
20549 /* Main entry point to parsing most OpenMP pragmas. */
20552 c_parser_omp_construct (c_parser
*parser
, bool *if_p
)
20554 enum pragma_kind p_kind
;
20557 char p_name
[sizeof "#pragma omp teams distribute parallel for simd"];
20558 omp_clause_mask
mask (0);
20560 loc
= c_parser_peek_token (parser
)->location
;
20561 p_kind
= c_parser_peek_token (parser
)->pragma_kind
;
20562 c_parser_consume_pragma (parser
);
20566 case PRAGMA_OACC_ATOMIC
:
20567 c_parser_omp_atomic (loc
, parser
);
20569 case PRAGMA_OACC_CACHE
:
20570 strcpy (p_name
, "#pragma acc");
20571 stmt
= c_parser_oacc_cache (loc
, parser
);
20573 case PRAGMA_OACC_DATA
:
20574 stmt
= c_parser_oacc_data (loc
, parser
, if_p
);
20576 case PRAGMA_OACC_HOST_DATA
:
20577 stmt
= c_parser_oacc_host_data (loc
, parser
, if_p
);
20579 case PRAGMA_OACC_KERNELS
:
20580 case PRAGMA_OACC_PARALLEL
:
20581 strcpy (p_name
, "#pragma acc");
20582 stmt
= c_parser_oacc_kernels_parallel (loc
, parser
, p_kind
, p_name
,
20585 case PRAGMA_OACC_LOOP
:
20586 strcpy (p_name
, "#pragma acc");
20587 stmt
= c_parser_oacc_loop (loc
, parser
, p_name
, mask
, NULL
, if_p
);
20589 case PRAGMA_OACC_WAIT
:
20590 strcpy (p_name
, "#pragma wait");
20591 stmt
= c_parser_oacc_wait (loc
, parser
, p_name
);
20593 case PRAGMA_OMP_ATOMIC
:
20594 c_parser_omp_atomic (loc
, parser
);
20596 case PRAGMA_OMP_CRITICAL
:
20597 stmt
= c_parser_omp_critical (loc
, parser
, if_p
);
20599 case PRAGMA_OMP_DISTRIBUTE
:
20600 strcpy (p_name
, "#pragma omp");
20601 stmt
= c_parser_omp_distribute (loc
, parser
, p_name
, mask
, NULL
, if_p
);
20603 case PRAGMA_OMP_FOR
:
20604 strcpy (p_name
, "#pragma omp");
20605 stmt
= c_parser_omp_for (loc
, parser
, p_name
, mask
, NULL
, if_p
);
20607 case PRAGMA_OMP_LOOP
:
20608 strcpy (p_name
, "#pragma omp");
20609 stmt
= c_parser_omp_loop (loc
, parser
, p_name
, mask
, NULL
, if_p
);
20611 case PRAGMA_OMP_MASTER
:
20612 strcpy (p_name
, "#pragma omp");
20613 stmt
= c_parser_omp_master (loc
, parser
, p_name
, mask
, NULL
, if_p
);
20615 case PRAGMA_OMP_PARALLEL
:
20616 strcpy (p_name
, "#pragma omp");
20617 stmt
= c_parser_omp_parallel (loc
, parser
, p_name
, mask
, NULL
, if_p
);
20619 case PRAGMA_OMP_SECTIONS
:
20620 strcpy (p_name
, "#pragma omp");
20621 stmt
= c_parser_omp_sections (loc
, parser
, p_name
, mask
, NULL
);
20623 case PRAGMA_OMP_SIMD
:
20624 strcpy (p_name
, "#pragma omp");
20625 stmt
= c_parser_omp_simd (loc
, parser
, p_name
, mask
, NULL
, if_p
);
20627 case PRAGMA_OMP_SINGLE
:
20628 stmt
= c_parser_omp_single (loc
, parser
, if_p
);
20630 case PRAGMA_OMP_TASK
:
20631 stmt
= c_parser_omp_task (loc
, parser
, if_p
);
20633 case PRAGMA_OMP_TASKGROUP
:
20634 stmt
= c_parser_omp_taskgroup (loc
, parser
, if_p
);
20636 case PRAGMA_OMP_TASKLOOP
:
20637 strcpy (p_name
, "#pragma omp");
20638 stmt
= c_parser_omp_taskloop (loc
, parser
, p_name
, mask
, NULL
, if_p
);
20640 case PRAGMA_OMP_TEAMS
:
20641 strcpy (p_name
, "#pragma omp");
20642 stmt
= c_parser_omp_teams (loc
, parser
, p_name
, mask
, NULL
, if_p
);
20645 gcc_unreachable ();
20649 gcc_assert (EXPR_LOCATION (stmt
) != UNKNOWN_LOCATION
);
20654 # pragma omp threadprivate (variable-list) */
20657 c_parser_omp_threadprivate (c_parser
*parser
)
20662 c_parser_consume_pragma (parser
);
20663 loc
= c_parser_peek_token (parser
)->location
;
20664 vars
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ERROR
, NULL
);
20666 /* Mark every variable in VARS to be assigned thread local storage. */
20667 for (t
= vars
; t
; t
= TREE_CHAIN (t
))
20669 tree v
= TREE_PURPOSE (t
);
20671 /* FIXME diagnostics: Ideally we should keep individual
20672 locations for all the variables in the var list to make the
20673 following errors more precise. Perhaps
20674 c_parser_omp_var_list_parens() should construct a list of
20675 locations to go along with the var list. */
20677 /* If V had already been marked threadprivate, it doesn't matter
20678 whether it had been used prior to this point. */
20680 error_at (loc
, "%qD is not a variable", v
);
20681 else if (TREE_USED (v
) && !C_DECL_THREADPRIVATE_P (v
))
20682 error_at (loc
, "%qE declared %<threadprivate%> after first use", v
);
20683 else if (! is_global_var (v
))
20684 error_at (loc
, "automatic variable %qE cannot be %<threadprivate%>", v
);
20685 else if (TREE_TYPE (v
) == error_mark_node
)
20687 else if (! COMPLETE_TYPE_P (TREE_TYPE (v
)))
20688 error_at (loc
, "%<threadprivate%> %qE has incomplete type", v
);
20691 if (! DECL_THREAD_LOCAL_P (v
))
20693 set_decl_tls_model (v
, decl_default_tls_model (v
));
20694 /* If rtl has been already set for this var, call
20695 make_decl_rtl once again, so that encode_section_info
20696 has a chance to look at the new decl flags. */
20697 if (DECL_RTL_SET_P (v
))
20700 C_DECL_THREADPRIVATE_P (v
) = 1;
20704 c_parser_skip_to_pragma_eol (parser
);
20707 /* Parse a transaction attribute (GCC Extension).
20709 transaction-attribute:
20713 The transactional memory language description is written for C++,
20714 and uses the C++0x attribute syntax. For compatibility, allow the
20715 bracket style for transactions in C as well. */
20718 c_parser_transaction_attributes (c_parser
*parser
)
20720 tree attr_name
, attr
= NULL
;
20722 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
20723 return c_parser_gnu_attributes (parser
);
20725 if (!c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
))
20727 c_parser_consume_token (parser
);
20728 if (!c_parser_require (parser
, CPP_OPEN_SQUARE
, "expected %<[%>"))
20731 attr_name
= c_parser_gnu_attribute_any_word (parser
);
20734 c_parser_consume_token (parser
);
20735 attr
= build_tree_list (attr_name
, NULL_TREE
);
20738 c_parser_error (parser
, "expected identifier");
20740 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
, "expected %<]%>");
20742 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
, "expected %<]%>");
20746 /* Parse a __transaction_atomic or __transaction_relaxed statement
20749 transaction-statement:
20750 __transaction_atomic transaction-attribute[opt] compound-statement
20751 __transaction_relaxed compound-statement
20753 Note that the only valid attribute is: "outer".
20757 c_parser_transaction (c_parser
*parser
, enum rid keyword
)
20759 unsigned int old_in
= parser
->in_transaction
;
20760 unsigned int this_in
= 1, new_in
;
20761 location_t loc
= c_parser_peek_token (parser
)->location
;
20764 gcc_assert ((keyword
== RID_TRANSACTION_ATOMIC
20765 || keyword
== RID_TRANSACTION_RELAXED
)
20766 && c_parser_next_token_is_keyword (parser
, keyword
));
20767 c_parser_consume_token (parser
);
20769 if (keyword
== RID_TRANSACTION_RELAXED
)
20770 this_in
|= TM_STMT_ATTR_RELAXED
;
20773 attrs
= c_parser_transaction_attributes (parser
);
20775 this_in
|= parse_tm_stmt_attr (attrs
, TM_STMT_ATTR_OUTER
);
20778 /* Keep track if we're in the lexical scope of an outer transaction. */
20779 new_in
= this_in
| (old_in
& TM_STMT_ATTR_OUTER
);
20781 parser
->in_transaction
= new_in
;
20782 stmt
= c_parser_compound_statement (parser
);
20783 parser
->in_transaction
= old_in
;
20786 stmt
= c_finish_transaction (loc
, stmt
, this_in
);
20788 error_at (loc
, (keyword
== RID_TRANSACTION_ATOMIC
?
20789 "%<__transaction_atomic%> without transactional memory support enabled"
20790 : "%<__transaction_relaxed %> "
20791 "without transactional memory support enabled"));
20796 /* Parse a __transaction_atomic or __transaction_relaxed expression
20799 transaction-expression:
20800 __transaction_atomic ( expression )
20801 __transaction_relaxed ( expression )
20804 static struct c_expr
20805 c_parser_transaction_expression (c_parser
*parser
, enum rid keyword
)
20808 unsigned int old_in
= parser
->in_transaction
;
20809 unsigned int this_in
= 1;
20810 location_t loc
= c_parser_peek_token (parser
)->location
;
20813 gcc_assert ((keyword
== RID_TRANSACTION_ATOMIC
20814 || keyword
== RID_TRANSACTION_RELAXED
)
20815 && c_parser_next_token_is_keyword (parser
, keyword
));
20816 c_parser_consume_token (parser
);
20818 if (keyword
== RID_TRANSACTION_RELAXED
)
20819 this_in
|= TM_STMT_ATTR_RELAXED
;
20822 attrs
= c_parser_transaction_attributes (parser
);
20824 this_in
|= parse_tm_stmt_attr (attrs
, 0);
20827 parser
->in_transaction
= this_in
;
20828 matching_parens parens
;
20829 if (parens
.require_open (parser
))
20831 tree expr
= c_parser_expression (parser
).value
;
20832 ret
.original_type
= TREE_TYPE (expr
);
20833 ret
.value
= build1 (TRANSACTION_EXPR
, ret
.original_type
, expr
);
20834 if (this_in
& TM_STMT_ATTR_RELAXED
)
20835 TRANSACTION_EXPR_RELAXED (ret
.value
) = 1;
20836 SET_EXPR_LOCATION (ret
.value
, loc
);
20837 ret
.original_code
= TRANSACTION_EXPR
;
20838 if (!parens
.require_close (parser
))
20840 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
20848 ret
.original_code
= ERROR_MARK
;
20849 ret
.original_type
= NULL
;
20851 parser
->in_transaction
= old_in
;
20854 error_at (loc
, (keyword
== RID_TRANSACTION_ATOMIC
?
20855 "%<__transaction_atomic%> without transactional memory support enabled"
20856 : "%<__transaction_relaxed %> "
20857 "without transactional memory support enabled"));
20859 set_c_expr_source_range (&ret
, loc
, loc
);
20864 /* Parse a __transaction_cancel statement (GCC Extension).
20866 transaction-cancel-statement:
20867 __transaction_cancel transaction-attribute[opt] ;
20869 Note that the only valid attribute is "outer".
20873 c_parser_transaction_cancel (c_parser
*parser
)
20875 location_t loc
= c_parser_peek_token (parser
)->location
;
20877 bool is_outer
= false;
20879 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_TRANSACTION_CANCEL
));
20880 c_parser_consume_token (parser
);
20882 attrs
= c_parser_transaction_attributes (parser
);
20884 is_outer
= (parse_tm_stmt_attr (attrs
, TM_STMT_ATTR_OUTER
) != 0);
20888 error_at (loc
, "%<__transaction_cancel%> without "
20889 "transactional memory support enabled");
20892 else if (parser
->in_transaction
& TM_STMT_ATTR_RELAXED
)
20894 error_at (loc
, "%<__transaction_cancel%> within a "
20895 "%<__transaction_relaxed%>");
20900 if ((parser
->in_transaction
& TM_STMT_ATTR_OUTER
) == 0
20901 && !is_tm_may_cancel_outer (current_function_decl
))
20903 error_at (loc
, "outer %<__transaction_cancel%> not "
20904 "within outer %<__transaction_atomic%> or "
20905 "a %<transaction_may_cancel_outer%> function");
20909 else if (parser
->in_transaction
== 0)
20911 error_at (loc
, "%<__transaction_cancel%> not within "
20912 "%<__transaction_atomic%>");
20916 return add_stmt (build_tm_abort_call (loc
, is_outer
));
20919 return build1 (NOP_EXPR
, void_type_node
, error_mark_node
);
20922 /* Parse a single source file. */
20925 c_parse_file (void)
20927 /* Use local storage to begin. If the first token is a pragma, parse it.
20928 If it is #pragma GCC pch_preprocess, then this will load a PCH file
20929 which will cause garbage collection. */
20932 memset (&tparser
, 0, sizeof tparser
);
20933 tparser
.translate_strings_p
= true;
20934 tparser
.tokens
= &tparser
.tokens_buf
[0];
20935 the_parser
= &tparser
;
20937 if (c_parser_peek_token (&tparser
)->pragma_kind
== PRAGMA_GCC_PCH_PREPROCESS
)
20938 c_parser_pragma_pch_preprocess (&tparser
);
20940 c_common_no_more_pch ();
20942 the_parser
= ggc_alloc
<c_parser
> ();
20943 *the_parser
= tparser
;
20944 if (tparser
.tokens
== &tparser
.tokens_buf
[0])
20945 the_parser
->tokens
= &the_parser
->tokens_buf
[0];
20947 /* Initialize EH, if we've been told to do so. */
20948 if (flag_exceptions
)
20949 using_eh_for_cleanups ();
20951 c_parser_translation_unit (the_parser
);
20955 /* Parse the body of a function declaration marked with "__RTL".
20957 The RTL parser works on the level of characters read from a
20958 FILE *, whereas c_parser works at the level of tokens.
20959 Square this circle by consuming all of the tokens up to and
20960 including the closing brace, recording the start/end of the RTL
20961 fragment, and reopening the file and re-reading the relevant
20962 lines within the RTL parser.
20964 This requires the opening and closing braces of the C function
20965 to be on separate lines from the RTL they wrap.
20967 Take ownership of START_WITH_PASS, if non-NULL. */
20970 c_parser_parse_rtl_body (c_parser
*parser
, char *start_with_pass
)
20972 if (!c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
20974 free (start_with_pass
);
20978 location_t start_loc
= c_parser_peek_token (parser
)->location
;
20980 /* Consume all tokens, up to the closing brace, handling
20981 matching pairs of braces in the rtl dump. */
20982 int num_open_braces
= 1;
20985 switch (c_parser_peek_token (parser
)->type
)
20987 case CPP_OPEN_BRACE
:
20990 case CPP_CLOSE_BRACE
:
20991 if (--num_open_braces
== 0)
20992 goto found_closing_brace
;
20995 error_at (start_loc
, "no closing brace");
20996 free (start_with_pass
);
21001 c_parser_consume_token (parser
);
21004 found_closing_brace
:
21005 /* At the closing brace; record its location. */
21006 location_t end_loc
= c_parser_peek_token (parser
)->location
;
21008 /* Consume the closing brace. */
21009 c_parser_consume_token (parser
);
21011 /* Invoke the RTL parser. */
21012 if (!read_rtl_function_body_from_file_range (start_loc
, end_loc
))
21014 free (start_with_pass
);
21018 /* If a pass name was provided for START_WITH_PASS, run the backend
21019 accordingly now, on the cfun created above, transferring
21020 ownership of START_WITH_PASS. */
21021 if (start_with_pass
)
21022 run_rtl_passes (start_with_pass
);
21025 #include "gt-c-c-parser.h"