1 /* Parser for C and Objective-C.
2 Copyright (C) 1987-2017 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"
71 /* We need to walk over decls with incomplete struct/union/enum types
72 after parsing the whole translation unit.
73 In finish_decl(), if the decl is static, has incomplete
74 struct/union/enum type, it is appeneded to incomplete_record_decls.
75 In c_parser_translation_unit(), we iterate over incomplete_record_decls
76 and report error if any of the decls are still incomplete. */
78 vec
<tree
> incomplete_record_decls
;
81 set_c_expr_source_range (c_expr
*expr
,
82 location_t start
, location_t finish
)
84 expr
->src_range
.m_start
= start
;
85 expr
->src_range
.m_finish
= finish
;
87 set_source_range (expr
->value
, start
, finish
);
91 set_c_expr_source_range (c_expr
*expr
,
92 source_range src_range
)
94 expr
->src_range
= src_range
;
96 set_source_range (expr
->value
, src_range
);
100 /* Initialization routine for this file. */
105 /* The only initialization required is of the reserved word
111 /* Make sure RID_MAX hasn't grown past the 8 bits used to hold the keyword in
112 the c_token structure. */
113 gcc_assert (RID_MAX
<= 255);
120 mask
|= D_ASM
| D_EXT
;
124 if (!c_dialect_objc ())
125 mask
|= D_OBJC
| D_CXX_OBJC
;
127 ridpointers
= ggc_cleared_vec_alloc
<tree
> ((int) RID_MAX
);
128 for (i
= 0; i
< num_c_common_reswords
; i
++)
130 /* If a keyword is disabled, do not enter it into the table
131 and so create a canonical spelling that isn't a keyword. */
132 if (c_common_reswords
[i
].disable
& mask
)
135 && (c_common_reswords
[i
].disable
& D_CXXWARN
))
137 id
= get_identifier (c_common_reswords
[i
].word
);
138 C_SET_RID_CODE (id
, RID_CXX_COMPAT_WARN
);
139 C_IS_RESERVED_WORD (id
) = 1;
144 id
= get_identifier (c_common_reswords
[i
].word
);
145 C_SET_RID_CODE (id
, c_common_reswords
[i
].rid
);
146 C_IS_RESERVED_WORD (id
) = 1;
147 ridpointers
[(int) c_common_reswords
[i
].rid
] = id
;
150 for (i
= 0; i
< NUM_INT_N_ENTS
; i
++)
152 /* We always create the symbols but they aren't always supported. */
154 sprintf (name
, "__int%d", int_n_data
[i
].bitsize
);
155 id
= get_identifier (name
);
156 C_SET_RID_CODE (id
, RID_FIRST_INT_N
+ i
);
157 C_IS_RESERVED_WORD (id
) = 1;
161 /* A parser structure recording information about the state and
162 context of parsing. Includes lexer information with up to two
163 tokens of look-ahead; more are not needed for C. */
164 struct GTY(()) c_parser
{
165 /* The look-ahead tokens. */
166 c_token
* GTY((skip
)) tokens
;
167 /* Buffer for look-ahead tokens. */
168 c_token tokens_buf
[4];
169 /* How many look-ahead tokens are available (0 - 4, or
170 more if parsing from pre-lexed tokens). */
171 unsigned int tokens_avail
;
172 /* True if a syntax error is being recovered from; false otherwise.
173 c_parser_error sets this flag. It should clear this flag when
174 enough tokens have been consumed to recover from the error. */
175 BOOL_BITFIELD error
: 1;
176 /* True if we're processing a pragma, and shouldn't automatically
177 consume CPP_PRAGMA_EOL. */
178 BOOL_BITFIELD in_pragma
: 1;
179 /* True if we're parsing the outermost block of an if statement. */
180 BOOL_BITFIELD in_if_block
: 1;
181 /* True if we want to lex an untranslated string. */
182 BOOL_BITFIELD lex_untranslated_string
: 1;
184 /* Objective-C specific parser/lexer information. */
186 /* True if we are in a context where the Objective-C "PQ" keywords
187 are considered keywords. */
188 BOOL_BITFIELD objc_pq_context
: 1;
189 /* True if we are parsing a (potential) Objective-C foreach
190 statement. This is set to true after we parsed 'for (' and while
191 we wait for 'in' or ';' to decide if it's a standard C for loop or an
192 Objective-C foreach loop. */
193 BOOL_BITFIELD objc_could_be_foreach_context
: 1;
194 /* The following flag is needed to contextualize Objective-C lexical
195 analysis. In some cases (e.g., 'int NSObject;'), it is
196 undesirable to bind an identifier to an Objective-C class, even
197 if a class with that name exists. */
198 BOOL_BITFIELD objc_need_raw_identifier
: 1;
199 /* Nonzero if we're processing a __transaction statement. The value
200 is 1 | TM_STMT_ATTR_*. */
201 unsigned int in_transaction
: 4;
202 /* True if we are in a context where the Objective-C "Property attribute"
203 keywords are valid. */
204 BOOL_BITFIELD objc_property_attr_context
: 1;
206 /* Cilk Plus specific parser/lexer information. */
208 /* Buffer to hold all the tokens from parsing the vector attribute for the
209 SIMD-enabled functions (formerly known as elemental functions). */
210 vec
<c_token
, va_gc
> *cilk_simd_fn_tokens
;
212 /* Location of the last consumed token. */
213 location_t last_token_location
;
216 /* Return a pointer to the Nth token in PARSERs tokens_buf. */
219 c_parser_tokens_buf (c_parser
*parser
, unsigned n
)
221 return &parser
->tokens_buf
[n
];
224 /* Return the error state of PARSER. */
227 c_parser_error (c_parser
*parser
)
229 return parser
->error
;
232 /* Set the error state of PARSER to ERR. */
235 c_parser_set_error (c_parser
*parser
, bool err
)
241 /* The actual parser and external interface. ??? Does this need to be
242 garbage-collected? */
244 static GTY (()) c_parser
*the_parser
;
246 /* Read in and lex a single token, storing it in *TOKEN. */
249 c_lex_one_token (c_parser
*parser
, c_token
*token
)
251 timevar_push (TV_LEX
);
253 token
->type
= c_lex_with_flags (&token
->value
, &token
->location
,
255 (parser
->lex_untranslated_string
256 ? C_LEX_STRING_NO_TRANSLATE
: 0));
257 token
->id_kind
= C_ID_NONE
;
258 token
->keyword
= RID_MAX
;
259 token
->pragma_kind
= PRAGMA_NONE
;
267 bool objc_force_identifier
= parser
->objc_need_raw_identifier
;
268 if (c_dialect_objc ())
269 parser
->objc_need_raw_identifier
= false;
271 if (C_IS_RESERVED_WORD (token
->value
))
273 enum rid rid_code
= C_RID_CODE (token
->value
);
275 if (rid_code
== RID_CXX_COMPAT_WARN
)
277 warning_at (token
->location
,
279 "identifier %qE conflicts with C++ keyword",
282 else if (rid_code
>= RID_FIRST_ADDR_SPACE
283 && rid_code
<= RID_LAST_ADDR_SPACE
)
286 as
= (addr_space_t
) (rid_code
- RID_FIRST_ADDR_SPACE
);
287 targetm
.addr_space
.diagnose_usage (as
, token
->location
);
288 token
->id_kind
= C_ID_ADDRSPACE
;
289 token
->keyword
= rid_code
;
292 else if (c_dialect_objc () && OBJC_IS_PQ_KEYWORD (rid_code
))
294 /* We found an Objective-C "pq" keyword (in, out,
295 inout, bycopy, byref, oneway). They need special
296 care because the interpretation depends on the
298 if (parser
->objc_pq_context
)
300 token
->type
= CPP_KEYWORD
;
301 token
->keyword
= rid_code
;
304 else if (parser
->objc_could_be_foreach_context
305 && rid_code
== RID_IN
)
307 /* We are in Objective-C, inside a (potential)
308 foreach context (which means after having
309 parsed 'for (', but before having parsed ';'),
310 and we found 'in'. We consider it the keyword
311 which terminates the declaration at the
312 beginning of a foreach-statement. Note that
313 this means you can't use 'in' for anything else
314 in that context; in particular, in Objective-C
315 you can't use 'in' as the name of the running
316 variable in a C for loop. We could potentially
317 try to add code here to disambiguate, but it
318 seems a reasonable limitation. */
319 token
->type
= CPP_KEYWORD
;
320 token
->keyword
= rid_code
;
323 /* Else, "pq" keywords outside of the "pq" context are
324 not keywords, and we fall through to the code for
327 else if (c_dialect_objc () && OBJC_IS_PATTR_KEYWORD (rid_code
))
329 /* We found an Objective-C "property attribute"
330 keyword (getter, setter, readonly, etc). These are
331 only valid in the property context. */
332 if (parser
->objc_property_attr_context
)
334 token
->type
= CPP_KEYWORD
;
335 token
->keyword
= rid_code
;
338 /* Else they are not special keywords.
341 else if (c_dialect_objc ()
342 && (OBJC_IS_AT_KEYWORD (rid_code
)
343 || OBJC_IS_CXX_KEYWORD (rid_code
)))
345 /* We found one of the Objective-C "@" keywords (defs,
346 selector, synchronized, etc) or one of the
347 Objective-C "cxx" keywords (class, private,
348 protected, public, try, catch, throw) without a
349 preceding '@' sign. Do nothing and fall through to
350 the code for normal tokens (in C++ we would still
351 consider the CXX ones keywords, but not in C). */
356 token
->type
= CPP_KEYWORD
;
357 token
->keyword
= rid_code
;
362 decl
= lookup_name (token
->value
);
365 if (TREE_CODE (decl
) == TYPE_DECL
)
367 token
->id_kind
= C_ID_TYPENAME
;
371 else if (c_dialect_objc ())
373 tree objc_interface_decl
= objc_is_class_name (token
->value
);
374 /* Objective-C class names are in the same namespace as
375 variables and typedefs, and hence are shadowed by local
377 if (objc_interface_decl
378 && (!objc_force_identifier
|| global_bindings_p ()))
380 token
->value
= objc_interface_decl
;
381 token
->id_kind
= C_ID_CLASSNAME
;
385 token
->id_kind
= C_ID_ID
;
389 /* This only happens in Objective-C; it must be a keyword. */
390 token
->type
= CPP_KEYWORD
;
391 switch (C_RID_CODE (token
->value
))
393 /* Replace 'class' with '@class', 'private' with '@private',
394 etc. This prevents confusion with the C++ keyword
395 'class', and makes the tokens consistent with other
396 Objective-C 'AT' keywords. For example '@class' is
397 reported as RID_AT_CLASS which is consistent with
398 '@synchronized', which is reported as
401 case RID_CLASS
: token
->keyword
= RID_AT_CLASS
; break;
402 case RID_PRIVATE
: token
->keyword
= RID_AT_PRIVATE
; break;
403 case RID_PROTECTED
: token
->keyword
= RID_AT_PROTECTED
; break;
404 case RID_PUBLIC
: token
->keyword
= RID_AT_PUBLIC
; break;
405 case RID_THROW
: token
->keyword
= RID_AT_THROW
; break;
406 case RID_TRY
: token
->keyword
= RID_AT_TRY
; break;
407 case RID_CATCH
: token
->keyword
= RID_AT_CATCH
; break;
408 case RID_SYNCHRONIZED
: token
->keyword
= RID_AT_SYNCHRONIZED
; break;
409 default: token
->keyword
= C_RID_CODE (token
->value
);
414 case CPP_CLOSE_PAREN
:
416 /* These tokens may affect the interpretation of any identifiers
417 following, if doing Objective-C. */
418 if (c_dialect_objc ())
419 parser
->objc_need_raw_identifier
= false;
422 /* We smuggled the cpp_token->u.pragma value in an INTEGER_CST. */
423 token
->pragma_kind
= (enum pragma_kind
) TREE_INT_CST_LOW (token
->value
);
429 timevar_pop (TV_LEX
);
432 /* Return a pointer to the next token from PARSER, reading it in if
436 c_parser_peek_token (c_parser
*parser
)
438 if (parser
->tokens_avail
== 0)
440 c_lex_one_token (parser
, &parser
->tokens
[0]);
441 parser
->tokens_avail
= 1;
443 return &parser
->tokens
[0];
446 /* Return a pointer to the next-but-one token from PARSER, reading it
447 in if necessary. The next token is already read in. */
450 c_parser_peek_2nd_token (c_parser
*parser
)
452 if (parser
->tokens_avail
>= 2)
453 return &parser
->tokens
[1];
454 gcc_assert (parser
->tokens_avail
== 1);
455 gcc_assert (parser
->tokens
[0].type
!= CPP_EOF
);
456 gcc_assert (parser
->tokens
[0].type
!= CPP_PRAGMA_EOL
);
457 c_lex_one_token (parser
, &parser
->tokens
[1]);
458 parser
->tokens_avail
= 2;
459 return &parser
->tokens
[1];
462 /* Return a pointer to the Nth token from PARSER, reading it
463 in if necessary. The N-1th token is already read in. */
466 c_parser_peek_nth_token (c_parser
*parser
, unsigned int n
)
468 /* N is 1-based, not zero-based. */
471 if (parser
->tokens_avail
>= n
)
472 return &parser
->tokens
[n
- 1];
473 gcc_assert (parser
->tokens_avail
== n
- 1);
474 c_lex_one_token (parser
, &parser
->tokens
[n
- 1]);
475 parser
->tokens_avail
= n
;
476 return &parser
->tokens
[n
- 1];
480 c_keyword_starts_typename (enum rid keyword
)
514 if (keyword
>= RID_FIRST_INT_N
515 && keyword
< RID_FIRST_INT_N
+ NUM_INT_N_ENTS
516 && int_n_enabled_p
[keyword
- RID_FIRST_INT_N
])
522 /* Return true if TOKEN can start a type name,
525 c_token_starts_typename (c_token
*token
)
530 switch (token
->id_kind
)
539 gcc_assert (c_dialect_objc ());
545 return c_keyword_starts_typename (token
->keyword
);
547 if (c_dialect_objc ())
555 /* Return true if the next token from PARSER can start a type name,
556 false otherwise. LA specifies how to do lookahead in order to
557 detect unknown type names. If unsure, pick CLA_PREFER_ID. */
560 c_parser_next_tokens_start_typename (c_parser
*parser
, enum c_lookahead_kind la
)
562 c_token
*token
= c_parser_peek_token (parser
);
563 if (c_token_starts_typename (token
))
566 /* Try a bit harder to detect an unknown typename. */
567 if (la
!= cla_prefer_id
568 && token
->type
== CPP_NAME
569 && token
->id_kind
== C_ID_ID
571 /* Do not try too hard when we could have "object in array". */
572 && !parser
->objc_could_be_foreach_context
574 && (la
== cla_prefer_type
575 || c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
576 || c_parser_peek_2nd_token (parser
)->type
== CPP_MULT
)
578 /* Only unknown identifiers. */
579 && !lookup_name (token
->value
))
585 /* Return true if TOKEN is a type qualifier, false otherwise. */
587 c_token_is_qualifier (c_token
*token
)
592 switch (token
->id_kind
)
600 switch (token
->keyword
)
618 /* Return true if the next token from PARSER is a type qualifier,
621 c_parser_next_token_is_qualifier (c_parser
*parser
)
623 c_token
*token
= c_parser_peek_token (parser
);
624 return c_token_is_qualifier (token
);
627 /* Return true if TOKEN can start declaration specifiers, false
630 c_token_starts_declspecs (c_token
*token
)
635 switch (token
->id_kind
)
644 gcc_assert (c_dialect_objc ());
650 switch (token
->keyword
)
691 if (token
->keyword
>= RID_FIRST_INT_N
692 && token
->keyword
< RID_FIRST_INT_N
+ NUM_INT_N_ENTS
693 && int_n_enabled_p
[token
->keyword
- RID_FIRST_INT_N
])
698 if (c_dialect_objc ())
707 /* Return true if TOKEN can start declaration specifiers or a static
708 assertion, false otherwise. */
710 c_token_starts_declaration (c_token
*token
)
712 if (c_token_starts_declspecs (token
)
713 || token
->keyword
== RID_STATIC_ASSERT
)
719 /* Return true if the next token from PARSER can start declaration
720 specifiers, false otherwise. */
722 c_parser_next_token_starts_declspecs (c_parser
*parser
)
724 c_token
*token
= c_parser_peek_token (parser
);
726 /* In Objective-C, a classname normally starts a declspecs unless it
727 is immediately followed by a dot. In that case, it is the
728 Objective-C 2.0 "dot-syntax" for class objects, ie, calls the
729 setter/getter on the class. c_token_starts_declspecs() can't
730 differentiate between the two cases because it only checks the
731 current token, so we have a special check here. */
732 if (c_dialect_objc ()
733 && token
->type
== CPP_NAME
734 && token
->id_kind
== C_ID_CLASSNAME
735 && c_parser_peek_2nd_token (parser
)->type
== CPP_DOT
)
738 return c_token_starts_declspecs (token
);
741 /* Return true if the next tokens from PARSER can start declaration
742 specifiers or a static assertion, false otherwise. */
744 c_parser_next_tokens_start_declaration (c_parser
*parser
)
746 c_token
*token
= c_parser_peek_token (parser
);
749 if (c_dialect_objc ()
750 && token
->type
== CPP_NAME
751 && token
->id_kind
== C_ID_CLASSNAME
752 && c_parser_peek_2nd_token (parser
)->type
== CPP_DOT
)
755 /* Labels do not start declarations. */
756 if (token
->type
== CPP_NAME
757 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
760 if (c_token_starts_declaration (token
))
763 if (c_parser_next_tokens_start_typename (parser
, cla_nonabstract_decl
))
769 /* Consume the next token from PARSER. */
772 c_parser_consume_token (c_parser
*parser
)
774 gcc_assert (parser
->tokens_avail
>= 1);
775 gcc_assert (parser
->tokens
[0].type
!= CPP_EOF
);
776 gcc_assert (!parser
->in_pragma
|| parser
->tokens
[0].type
!= CPP_PRAGMA_EOL
);
777 gcc_assert (parser
->error
|| parser
->tokens
[0].type
!= CPP_PRAGMA
);
778 parser
->last_token_location
= parser
->tokens
[0].location
;
779 if (parser
->tokens
!= &parser
->tokens_buf
[0])
781 else if (parser
->tokens_avail
== 2)
782 parser
->tokens
[0] = parser
->tokens
[1];
783 parser
->tokens_avail
--;
786 /* Expect the current token to be a #pragma. Consume it and remember
787 that we've begun parsing a pragma. */
790 c_parser_consume_pragma (c_parser
*parser
)
792 gcc_assert (!parser
->in_pragma
);
793 gcc_assert (parser
->tokens_avail
>= 1);
794 gcc_assert (parser
->tokens
[0].type
== CPP_PRAGMA
);
795 if (parser
->tokens
!= &parser
->tokens_buf
[0])
797 else if (parser
->tokens_avail
== 2)
798 parser
->tokens
[0] = parser
->tokens
[1];
799 parser
->tokens_avail
--;
800 parser
->in_pragma
= true;
803 /* Update the global input_location from TOKEN. */
805 c_parser_set_source_position_from_token (c_token
*token
)
807 if (token
->type
!= CPP_EOF
)
809 input_location
= token
->location
;
813 /* Helper function for c_parser_error.
814 Having peeked a token of kind TOK1_KIND that might signify
815 a conflict marker, peek successor tokens to determine
816 if we actually do have a conflict marker.
817 Specifically, we consider a run of 7 '<', '=' or '>' characters
818 at the start of a line as a conflict marker.
819 These come through the lexer as three pairs and a single,
820 e.g. three CPP_LSHIFT ("<<") and a CPP_LESS ('<').
821 If it returns true, *OUT_LOC is written to with the location/range
825 c_parser_peek_conflict_marker (c_parser
*parser
, enum cpp_ttype tok1_kind
,
828 c_token
*token2
= c_parser_peek_2nd_token (parser
);
829 if (token2
->type
!= tok1_kind
)
831 c_token
*token3
= c_parser_peek_nth_token (parser
, 3);
832 if (token3
->type
!= tok1_kind
)
834 c_token
*token4
= c_parser_peek_nth_token (parser
, 4);
835 if (token4
->type
!= conflict_marker_get_final_tok_kind (tok1_kind
))
838 /* It must be at the start of the line. */
839 location_t start_loc
= c_parser_peek_token (parser
)->location
;
840 if (LOCATION_COLUMN (start_loc
) != 1)
843 /* We have a conflict marker. Construct a location of the form:
846 with start == caret, finishing at the end of the marker. */
847 location_t finish_loc
= get_finish (token4
->location
);
848 *out_loc
= make_location (start_loc
, start_loc
, finish_loc
);
853 /* Issue a diagnostic of the form
854 FILE:LINE: MESSAGE before TOKEN
855 where TOKEN is the next token in the input stream of PARSER.
856 MESSAGE (specified by the caller) is usually of the form "expected
859 Use RICHLOC as the location of the diagnostic.
861 Do not issue a diagnostic if still recovering from an error.
863 Return true iff an error was actually emitted.
865 ??? This is taken from the C++ parser, but building up messages in
866 this way is not i18n-friendly and some other approach should be
870 c_parser_error_richloc (c_parser
*parser
, const char *gmsgid
,
871 rich_location
*richloc
)
873 c_token
*token
= c_parser_peek_token (parser
);
876 parser
->error
= true;
880 /* If this is actually a conflict marker, report it as such. */
881 if (token
->type
== CPP_LSHIFT
882 || token
->type
== CPP_RSHIFT
883 || token
->type
== CPP_EQ_EQ
)
886 if (c_parser_peek_conflict_marker (parser
, token
->type
, &loc
))
888 error_at (loc
, "version control conflict marker in file");
893 c_parse_error (gmsgid
,
894 /* Because c_parse_error does not understand
895 CPP_KEYWORD, keywords are treated like
897 (token
->type
== CPP_KEYWORD
? CPP_NAME
: token
->type
),
898 /* ??? The C parser does not save the cpp flags of a
899 token, we need to pass 0 here and we will not get
900 the source spelling of some tokens but rather the
901 canonical spelling. */
902 token
->value
, /*flags=*/0, richloc
);
906 /* As c_parser_error_richloc, but issue the message at the
907 location of PARSER's next token, or at input_location
908 if the next token is EOF. */
911 c_parser_error (c_parser
*parser
, const char *gmsgid
)
913 c_token
*token
= c_parser_peek_token (parser
);
914 c_parser_set_source_position_from_token (token
);
915 rich_location
richloc (line_table
, input_location
);
916 return c_parser_error_richloc (parser
, gmsgid
, &richloc
);
919 /* Some tokens naturally come in pairs e.g.'(' and ')'.
920 This class is for tracking such a matching pair of symbols.
921 In particular, it tracks the location of the first token,
922 so that if the second token is missing, we can highlight the
923 location of the first token when notifying the user about the
926 template <typename traits_t
>
930 /* token_pair's ctor. */
931 token_pair () : m_open_loc (UNKNOWN_LOCATION
) {}
933 /* If the next token is the opening symbol for this pair, consume it and
935 Otherwise, issue an error and return false.
936 In either case, record the location of the opening token. */
938 bool require_open (c_parser
*parser
)
940 c_token
*token
= c_parser_peek_token (parser
);
942 m_open_loc
= token
->location
;
944 return c_parser_require (parser
, traits_t::open_token_type
,
945 traits_t::open_gmsgid
);
948 /* Consume the next token from PARSER, recording its location as
949 that of the opening token within the pair. */
951 void consume_open (c_parser
*parser
)
953 c_token
*token
= c_parser_peek_token (parser
);
954 gcc_assert (token
->type
== traits_t::open_token_type
);
955 m_open_loc
= token
->location
;
956 c_parser_consume_token (parser
);
959 /* If the next token is the closing symbol for this pair, consume it
961 Otherwise, issue an error, highlighting the location of the
962 corresponding opening token, and return false. */
964 bool require_close (c_parser
*parser
) const
966 return c_parser_require (parser
, traits_t::close_token_type
,
967 traits_t::close_gmsgid
, m_open_loc
);
970 /* Like token_pair::require_close, except that tokens will be skipped
971 until the desired token is found. An error message is still produced
972 if the next token is not as expected. */
974 void skip_until_found_close (c_parser
*parser
) const
976 c_parser_skip_until_found (parser
, traits_t::close_token_type
,
977 traits_t::close_gmsgid
, m_open_loc
);
981 location_t m_open_loc
;
984 /* Traits for token_pair<T> for tracking matching pairs of parentheses. */
986 struct matching_paren_traits
988 static const enum cpp_ttype open_token_type
= CPP_OPEN_PAREN
;
989 static const char * const open_gmsgid
;
990 static const enum cpp_ttype close_token_type
= CPP_CLOSE_PAREN
;
991 static const char * const close_gmsgid
;
994 const char * const matching_paren_traits::open_gmsgid
= "expected %<(%>";
995 const char * const matching_paren_traits::close_gmsgid
= "expected %<)%>";
997 /* "matching_parens" is a token_pair<T> class for tracking matching
998 pairs of parentheses. */
1000 typedef token_pair
<matching_paren_traits
> matching_parens
;
1002 /* Traits for token_pair<T> for tracking matching pairs of braces. */
1004 struct matching_brace_traits
1006 static const enum cpp_ttype open_token_type
= CPP_OPEN_BRACE
;
1007 static const char * const open_gmsgid
;
1008 static const enum cpp_ttype close_token_type
= CPP_CLOSE_BRACE
;
1009 static const char * const close_gmsgid
;
1012 const char * const matching_brace_traits::open_gmsgid
= "expected %<{%>";
1013 const char * const matching_brace_traits::close_gmsgid
= "expected %<}%>";
1015 /* "matching_braces" is a token_pair<T> class for tracking matching
1018 typedef token_pair
<matching_brace_traits
> matching_braces
;
1020 /* Get a description of the matching symbol to TYPE e.g. "(" for
1024 get_matching_symbol (enum cpp_ttype type
)
1031 case CPP_CLOSE_PAREN
:
1033 case CPP_CLOSE_BRACE
:
1038 /* If the next token is of the indicated TYPE, consume it. Otherwise,
1039 issue the error MSGID. If MSGID is NULL then a message has already
1040 been produced and no message will be produced this time. Returns
1041 true if found, false otherwise.
1043 If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1044 within any error as the location of an "opening" token matching
1045 the close token TYPE (e.g. the location of the '(' when TYPE is
1048 If TYPE_IS_UNIQUE is true (the default) then msgid describes exactly
1049 one type (e.g. "expected %<)%>") and thus it may be reasonable to
1050 attempt to generate a fix-it hint for the problem.
1051 Otherwise msgid describes multiple token types (e.g.
1052 "expected %<;%>, %<,%> or %<)%>"), and thus we shouldn't attempt to
1053 generate a fix-it hint. */
1056 c_parser_require (c_parser
*parser
,
1057 enum cpp_ttype type
,
1059 location_t matching_location
,
1060 bool type_is_unique
)
1062 if (c_parser_next_token_is (parser
, type
))
1064 c_parser_consume_token (parser
);
1069 location_t next_token_loc
= c_parser_peek_token (parser
)->location
;
1070 gcc_rich_location
richloc (next_token_loc
);
1072 /* Potentially supply a fix-it hint, suggesting to add the
1073 missing token immediately after the *previous* token.
1074 This may move the primary location within richloc. */
1075 if (!parser
->error
&& type_is_unique
)
1076 maybe_suggest_missing_token_insertion (&richloc
, type
,
1077 parser
->last_token_location
);
1079 /* If matching_location != UNKNOWN_LOCATION, highlight it.
1080 Attempt to consolidate diagnostics by printing it as a
1081 secondary range within the main diagnostic. */
1082 bool added_matching_location
= false;
1083 if (matching_location
!= UNKNOWN_LOCATION
)
1084 added_matching_location
1085 = richloc
.add_location_if_nearby (matching_location
);
1087 if (c_parser_error_richloc (parser
, msgid
, &richloc
))
1088 /* If we weren't able to consolidate matching_location, then
1089 print it as a secondary diagnostic. */
1090 if (matching_location
!= UNKNOWN_LOCATION
&& !added_matching_location
)
1091 inform (matching_location
, "to match this %qs",
1092 get_matching_symbol (type
));
1098 /* If the next token is the indicated keyword, consume it. Otherwise,
1099 issue the error MSGID. Returns true if found, false otherwise. */
1102 c_parser_require_keyword (c_parser
*parser
,
1106 if (c_parser_next_token_is_keyword (parser
, keyword
))
1108 c_parser_consume_token (parser
);
1113 c_parser_error (parser
, msgid
);
1118 /* Like c_parser_require, except that tokens will be skipped until the
1119 desired token is found. An error message is still produced if the
1120 next token is not as expected. If MSGID is NULL then a message has
1121 already been produced and no message will be produced this
1124 If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1125 within any error as the location of an "opening" token matching
1126 the close token TYPE (e.g. the location of the '(' when TYPE is
1127 CPP_CLOSE_PAREN). */
1130 c_parser_skip_until_found (c_parser
*parser
,
1131 enum cpp_ttype type
,
1133 location_t matching_location
)
1135 unsigned nesting_depth
= 0;
1137 if (c_parser_require (parser
, type
, msgid
, matching_location
))
1140 /* Skip tokens until the desired token is found. */
1143 /* Peek at the next token. */
1144 c_token
*token
= c_parser_peek_token (parser
);
1145 /* If we've reached the token we want, consume it and stop. */
1146 if (token
->type
== type
&& !nesting_depth
)
1148 c_parser_consume_token (parser
);
1152 /* If we've run out of tokens, stop. */
1153 if (token
->type
== CPP_EOF
)
1155 if (token
->type
== CPP_PRAGMA_EOL
&& parser
->in_pragma
)
1157 if (token
->type
== CPP_OPEN_BRACE
1158 || token
->type
== CPP_OPEN_PAREN
1159 || token
->type
== CPP_OPEN_SQUARE
)
1161 else if (token
->type
== CPP_CLOSE_BRACE
1162 || token
->type
== CPP_CLOSE_PAREN
1163 || token
->type
== CPP_CLOSE_SQUARE
)
1165 if (nesting_depth
-- == 0)
1168 /* Consume this token. */
1169 c_parser_consume_token (parser
);
1171 parser
->error
= false;
1174 /* Skip tokens until the end of a parameter is found, but do not
1175 consume the comma, semicolon or closing delimiter. */
1178 c_parser_skip_to_end_of_parameter (c_parser
*parser
)
1180 unsigned nesting_depth
= 0;
1184 c_token
*token
= c_parser_peek_token (parser
);
1185 if ((token
->type
== CPP_COMMA
|| token
->type
== CPP_SEMICOLON
)
1188 /* If we've run out of tokens, stop. */
1189 if (token
->type
== CPP_EOF
)
1191 if (token
->type
== CPP_PRAGMA_EOL
&& parser
->in_pragma
)
1193 if (token
->type
== CPP_OPEN_BRACE
1194 || token
->type
== CPP_OPEN_PAREN
1195 || token
->type
== CPP_OPEN_SQUARE
)
1197 else if (token
->type
== CPP_CLOSE_BRACE
1198 || token
->type
== CPP_CLOSE_PAREN
1199 || token
->type
== CPP_CLOSE_SQUARE
)
1201 if (nesting_depth
-- == 0)
1204 /* Consume this token. */
1205 c_parser_consume_token (parser
);
1207 parser
->error
= false;
1210 /* Expect to be at the end of the pragma directive and consume an
1211 end of line marker. */
1214 c_parser_skip_to_pragma_eol (c_parser
*parser
, bool error_if_not_eol
= true)
1216 gcc_assert (parser
->in_pragma
);
1217 parser
->in_pragma
= false;
1219 if (error_if_not_eol
&& c_parser_peek_token (parser
)->type
!= CPP_PRAGMA_EOL
)
1220 c_parser_error (parser
, "expected end of line");
1222 cpp_ttype token_type
;
1225 c_token
*token
= c_parser_peek_token (parser
);
1226 token_type
= token
->type
;
1227 if (token_type
== CPP_EOF
)
1229 c_parser_consume_token (parser
);
1231 while (token_type
!= CPP_PRAGMA_EOL
);
1233 parser
->error
= false;
1236 /* Skip tokens until we have consumed an entire block, or until we
1237 have consumed a non-nested ';'. */
1240 c_parser_skip_to_end_of_block_or_statement (c_parser
*parser
)
1242 unsigned nesting_depth
= 0;
1243 bool save_error
= parser
->error
;
1249 /* Peek at the next token. */
1250 token
= c_parser_peek_token (parser
);
1252 switch (token
->type
)
1257 case CPP_PRAGMA_EOL
:
1258 if (parser
->in_pragma
)
1263 /* If the next token is a ';', we have reached the
1264 end of the statement. */
1267 /* Consume the ';'. */
1268 c_parser_consume_token (parser
);
1273 case CPP_CLOSE_BRACE
:
1274 /* If the next token is a non-nested '}', then we have
1275 reached the end of the current block. */
1276 if (nesting_depth
== 0 || --nesting_depth
== 0)
1278 c_parser_consume_token (parser
);
1283 case CPP_OPEN_BRACE
:
1284 /* If it the next token is a '{', then we are entering a new
1285 block. Consume the entire block. */
1290 /* If we see a pragma, consume the whole thing at once. We
1291 have some safeguards against consuming pragmas willy-nilly.
1292 Normally, we'd expect to be here with parser->error set,
1293 which disables these safeguards. But it's possible to get
1294 here for secondary error recovery, after parser->error has
1296 c_parser_consume_pragma (parser
);
1297 c_parser_skip_to_pragma_eol (parser
);
1298 parser
->error
= save_error
;
1305 c_parser_consume_token (parser
);
1309 parser
->error
= false;
1312 /* CPP's options (initialized by c-opts.c). */
1313 extern cpp_options
*cpp_opts
;
1315 /* Save the warning flags which are controlled by __extension__. */
1318 disable_extension_diagnostics (void)
1321 | (warn_pointer_arith
<< 1)
1322 | (warn_traditional
<< 2)
1324 | (warn_long_long
<< 4)
1325 | (warn_cxx_compat
<< 5)
1326 | (warn_overlength_strings
<< 6)
1327 /* warn_c90_c99_compat has three states: -1/0/1, so we must
1328 play tricks to properly restore it. */
1329 | ((warn_c90_c99_compat
== 1) << 7)
1330 | ((warn_c90_c99_compat
== -1) << 8)
1331 /* Similarly for warn_c99_c11_compat. */
1332 | ((warn_c99_c11_compat
== 1) << 9)
1333 | ((warn_c99_c11_compat
== -1) << 10)
1335 cpp_opts
->cpp_pedantic
= pedantic
= 0;
1336 warn_pointer_arith
= 0;
1337 cpp_opts
->cpp_warn_traditional
= warn_traditional
= 0;
1339 cpp_opts
->cpp_warn_long_long
= warn_long_long
= 0;
1340 warn_cxx_compat
= 0;
1341 warn_overlength_strings
= 0;
1342 warn_c90_c99_compat
= 0;
1343 warn_c99_c11_compat
= 0;
1347 /* Restore the warning flags which are controlled by __extension__.
1348 FLAGS is the return value from disable_extension_diagnostics. */
1351 restore_extension_diagnostics (int flags
)
1353 cpp_opts
->cpp_pedantic
= pedantic
= flags
& 1;
1354 warn_pointer_arith
= (flags
>> 1) & 1;
1355 cpp_opts
->cpp_warn_traditional
= warn_traditional
= (flags
>> 2) & 1;
1356 flag_iso
= (flags
>> 3) & 1;
1357 cpp_opts
->cpp_warn_long_long
= warn_long_long
= (flags
>> 4) & 1;
1358 warn_cxx_compat
= (flags
>> 5) & 1;
1359 warn_overlength_strings
= (flags
>> 6) & 1;
1360 /* See above for why is this needed. */
1361 warn_c90_c99_compat
= (flags
>> 7) & 1 ? 1 : ((flags
>> 8) & 1 ? -1 : 0);
1362 warn_c99_c11_compat
= (flags
>> 9) & 1 ? 1 : ((flags
>> 10) & 1 ? -1 : 0);
1365 /* Helper data structure for parsing #pragma acc routine. */
1366 struct oacc_routine_data
{
1367 bool error_seen
; /* Set if error has been reported. */
1368 bool fndecl_seen
; /* Set if one fn decl/definition has been seen already. */
1373 static void c_parser_external_declaration (c_parser
*);
1374 static void c_parser_asm_definition (c_parser
*);
1375 static void c_parser_declaration_or_fndef (c_parser
*, bool, bool, bool,
1376 bool, bool, tree
*, vec
<c_token
>,
1377 struct oacc_routine_data
* = NULL
,
1379 static void c_parser_static_assert_declaration_no_semi (c_parser
*);
1380 static void c_parser_static_assert_declaration (c_parser
*);
1381 static struct c_typespec
c_parser_enum_specifier (c_parser
*);
1382 static struct c_typespec
c_parser_struct_or_union_specifier (c_parser
*);
1383 static tree
c_parser_struct_declaration (c_parser
*);
1384 static struct c_typespec
c_parser_typeof_specifier (c_parser
*);
1385 static tree
c_parser_alignas_specifier (c_parser
*);
1386 static struct c_declarator
*c_parser_direct_declarator (c_parser
*, bool,
1388 static struct c_declarator
*c_parser_direct_declarator_inner (c_parser
*,
1390 struct c_declarator
*);
1391 static struct c_arg_info
*c_parser_parms_declarator (c_parser
*, bool, tree
);
1392 static struct c_arg_info
*c_parser_parms_list_declarator (c_parser
*, tree
,
1394 static struct c_parm
*c_parser_parameter_declaration (c_parser
*, tree
);
1395 static tree
c_parser_simple_asm_expr (c_parser
*);
1396 static tree
c_parser_attributes (c_parser
*);
1397 static struct c_expr
c_parser_initializer (c_parser
*);
1398 static struct c_expr
c_parser_braced_init (c_parser
*, tree
, bool,
1400 static void c_parser_initelt (c_parser
*, struct obstack
*);
1401 static void c_parser_initval (c_parser
*, struct c_expr
*,
1403 static tree
c_parser_compound_statement (c_parser
*);
1404 static void c_parser_compound_statement_nostart (c_parser
*);
1405 static void c_parser_label (c_parser
*);
1406 static void c_parser_statement (c_parser
*, bool *, location_t
* = NULL
);
1407 static void c_parser_statement_after_labels (c_parser
*, bool *,
1408 vec
<tree
> * = NULL
);
1409 static tree
c_parser_c99_block_statement (c_parser
*, bool *,
1410 location_t
* = NULL
);
1411 static void c_parser_if_statement (c_parser
*, bool *, vec
<tree
> *);
1412 static void c_parser_switch_statement (c_parser
*, bool *);
1413 static void c_parser_while_statement (c_parser
*, bool, bool *);
1414 static void c_parser_do_statement (c_parser
*, bool);
1415 static void c_parser_for_statement (c_parser
*, bool, bool *);
1416 static tree
c_parser_asm_statement (c_parser
*);
1417 static tree
c_parser_asm_operands (c_parser
*);
1418 static tree
c_parser_asm_goto_operands (c_parser
*);
1419 static tree
c_parser_asm_clobbers (c_parser
*);
1420 static struct c_expr
c_parser_expr_no_commas (c_parser
*, struct c_expr
*,
1422 static struct c_expr
c_parser_conditional_expression (c_parser
*,
1423 struct c_expr
*, tree
);
1424 static struct c_expr
c_parser_binary_expression (c_parser
*, struct c_expr
*,
1426 static struct c_expr
c_parser_cast_expression (c_parser
*, struct c_expr
*);
1427 static struct c_expr
c_parser_unary_expression (c_parser
*);
1428 static struct c_expr
c_parser_sizeof_expression (c_parser
*);
1429 static struct c_expr
c_parser_alignof_expression (c_parser
*);
1430 static struct c_expr
c_parser_postfix_expression (c_parser
*);
1431 static struct c_expr
c_parser_postfix_expression_after_paren_type (c_parser
*,
1432 struct c_type_name
*,
1434 static struct c_expr
c_parser_postfix_expression_after_primary (c_parser
*,
1437 static tree
c_parser_transaction (c_parser
*, enum rid
);
1438 static struct c_expr
c_parser_transaction_expression (c_parser
*, enum rid
);
1439 static tree
c_parser_transaction_cancel (c_parser
*);
1440 static struct c_expr
c_parser_expression (c_parser
*);
1441 static struct c_expr
c_parser_expression_conv (c_parser
*);
1442 static vec
<tree
, va_gc
> *c_parser_expr_list (c_parser
*, bool, bool,
1443 vec
<tree
, va_gc
> **, location_t
*,
1444 tree
*, vec
<location_t
> *,
1445 unsigned int * = NULL
);
1446 static void c_parser_oacc_declare (c_parser
*);
1447 static void c_parser_oacc_enter_exit_data (c_parser
*, bool);
1448 static void c_parser_oacc_update (c_parser
*);
1449 static void c_parser_omp_construct (c_parser
*, bool *);
1450 static void c_parser_omp_threadprivate (c_parser
*);
1451 static void c_parser_omp_barrier (c_parser
*);
1452 static void c_parser_omp_flush (c_parser
*);
1453 static tree
c_parser_omp_for_loop (location_t
, c_parser
*, enum tree_code
,
1454 tree
, tree
*, bool *);
1455 static void c_parser_omp_taskwait (c_parser
*);
1456 static void c_parser_omp_taskyield (c_parser
*);
1457 static void c_parser_omp_cancel (c_parser
*);
1459 enum pragma_context
{ pragma_external
, pragma_struct
, pragma_param
,
1460 pragma_stmt
, pragma_compound
};
1461 static bool c_parser_pragma (c_parser
*, enum pragma_context
, bool *);
1462 static void c_parser_omp_cancellation_point (c_parser
*, enum pragma_context
);
1463 static bool c_parser_omp_target (c_parser
*, enum pragma_context
, bool *);
1464 static void c_parser_omp_end_declare_target (c_parser
*);
1465 static void c_parser_omp_declare (c_parser
*, enum pragma_context
);
1466 static bool c_parser_omp_ordered (c_parser
*, enum pragma_context
, bool *);
1467 static void c_parser_oacc_routine (c_parser
*, enum pragma_context
);
1469 /* These Objective-C parser functions are only ever called when
1470 compiling Objective-C. */
1471 static void c_parser_objc_class_definition (c_parser
*, tree
);
1472 static void c_parser_objc_class_instance_variables (c_parser
*);
1473 static void c_parser_objc_class_declaration (c_parser
*);
1474 static void c_parser_objc_alias_declaration (c_parser
*);
1475 static void c_parser_objc_protocol_definition (c_parser
*, tree
);
1476 static bool c_parser_objc_method_type (c_parser
*);
1477 static void c_parser_objc_method_definition (c_parser
*);
1478 static void c_parser_objc_methodprotolist (c_parser
*);
1479 static void c_parser_objc_methodproto (c_parser
*);
1480 static tree
c_parser_objc_method_decl (c_parser
*, bool, tree
*, tree
*);
1481 static tree
c_parser_objc_type_name (c_parser
*);
1482 static tree
c_parser_objc_protocol_refs (c_parser
*);
1483 static void c_parser_objc_try_catch_finally_statement (c_parser
*);
1484 static void c_parser_objc_synchronized_statement (c_parser
*);
1485 static tree
c_parser_objc_selector (c_parser
*);
1486 static tree
c_parser_objc_selector_arg (c_parser
*);
1487 static tree
c_parser_objc_receiver (c_parser
*);
1488 static tree
c_parser_objc_message_args (c_parser
*);
1489 static tree
c_parser_objc_keywordexpr (c_parser
*);
1490 static void c_parser_objc_at_property_declaration (c_parser
*);
1491 static void c_parser_objc_at_synthesize_declaration (c_parser
*);
1492 static void c_parser_objc_at_dynamic_declaration (c_parser
*);
1493 static bool c_parser_objc_diagnose_bad_element_prefix
1494 (c_parser
*, struct c_declspecs
*);
1496 /* Cilk Plus supporting routines. */
1497 static void c_parser_cilk_simd (c_parser
*, bool *);
1498 static void c_parser_cilk_for (c_parser
*, tree
, bool *);
1499 static bool c_parser_cilk_verify_simd (c_parser
*, enum pragma_context
);
1500 static tree
c_parser_array_notation (location_t
, c_parser
*, tree
, tree
);
1501 static tree
c_parser_cilk_clause_vectorlength (c_parser
*, tree
, bool);
1502 static void c_parser_cilk_grainsize (c_parser
*, bool *);
1504 static void c_parser_parse_rtl_body (c_parser
*parser
, char *start_with_pass
);
1506 /* Parse a translation unit (C90 6.7, C99 6.9, C11 6.9).
1509 external-declarations
1511 external-declarations:
1512 external-declaration
1513 external-declarations external-declaration
1522 c_parser_translation_unit (c_parser
*parser
)
1524 if (c_parser_next_token_is (parser
, CPP_EOF
))
1526 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
1527 "ISO C forbids an empty translation unit");
1531 void *obstack_position
= obstack_alloc (&parser_obstack
, 0);
1532 mark_valid_location_for_stdc_pragma (false);
1536 c_parser_external_declaration (parser
);
1537 obstack_free (&parser_obstack
, obstack_position
);
1539 while (c_parser_next_token_is_not (parser
, CPP_EOF
));
1544 FOR_EACH_VEC_ELT (incomplete_record_decls
, i
, decl
)
1545 if (DECL_SIZE (decl
) == NULL_TREE
&& TREE_TYPE (decl
) != error_mark_node
)
1546 error ("storage size of %q+D isn%'t known", decl
);
1549 /* Parse an external declaration (C90 6.7, C99 6.9, C11 6.9).
1551 external-declaration:
1557 external-declaration:
1560 __extension__ external-declaration
1564 external-declaration:
1565 objc-class-definition
1566 objc-class-declaration
1567 objc-alias-declaration
1568 objc-protocol-definition
1569 objc-method-definition
1574 c_parser_external_declaration (c_parser
*parser
)
1577 switch (c_parser_peek_token (parser
)->type
)
1580 switch (c_parser_peek_token (parser
)->keyword
)
1583 ext
= disable_extension_diagnostics ();
1584 c_parser_consume_token (parser
);
1585 c_parser_external_declaration (parser
);
1586 restore_extension_diagnostics (ext
);
1589 c_parser_asm_definition (parser
);
1591 case RID_AT_INTERFACE
:
1592 case RID_AT_IMPLEMENTATION
:
1593 gcc_assert (c_dialect_objc ());
1594 c_parser_objc_class_definition (parser
, NULL_TREE
);
1597 gcc_assert (c_dialect_objc ());
1598 c_parser_objc_class_declaration (parser
);
1601 gcc_assert (c_dialect_objc ());
1602 c_parser_objc_alias_declaration (parser
);
1604 case RID_AT_PROTOCOL
:
1605 gcc_assert (c_dialect_objc ());
1606 c_parser_objc_protocol_definition (parser
, NULL_TREE
);
1608 case RID_AT_PROPERTY
:
1609 gcc_assert (c_dialect_objc ());
1610 c_parser_objc_at_property_declaration (parser
);
1612 case RID_AT_SYNTHESIZE
:
1613 gcc_assert (c_dialect_objc ());
1614 c_parser_objc_at_synthesize_declaration (parser
);
1616 case RID_AT_DYNAMIC
:
1617 gcc_assert (c_dialect_objc ());
1618 c_parser_objc_at_dynamic_declaration (parser
);
1621 gcc_assert (c_dialect_objc ());
1622 c_parser_consume_token (parser
);
1623 objc_finish_implementation ();
1630 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
1631 "ISO C does not allow extra %<;%> outside of a function");
1632 c_parser_consume_token (parser
);
1635 mark_valid_location_for_stdc_pragma (true);
1636 c_parser_pragma (parser
, pragma_external
, NULL
);
1637 mark_valid_location_for_stdc_pragma (false);
1641 if (c_dialect_objc ())
1643 c_parser_objc_method_definition (parser
);
1646 /* Else fall through, and yield a syntax error trying to parse
1647 as a declaration or function definition. */
1651 /* A declaration or a function definition (or, in Objective-C,
1652 an @interface or @protocol with prefix attributes). We can
1653 only tell which after parsing the declaration specifiers, if
1654 any, and the first declarator. */
1655 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
1661 static void c_finish_omp_declare_simd (c_parser
*, tree
, tree
, vec
<c_token
>);
1662 static void c_finish_oacc_routine (struct oacc_routine_data
*, tree
, bool);
1664 /* Parse a declaration or function definition (C90 6.5, 6.7.1, C99
1665 6.7, 6.9.1, C11 6.7, 6.9.1). If FNDEF_OK is true, a function definition
1666 is accepted; otherwise (old-style parameter declarations) only other
1667 declarations are accepted. If STATIC_ASSERT_OK is true, a static
1668 assertion is accepted; otherwise (old-style parameter declarations)
1669 it is not. If NESTED is true, we are inside a function or parsing
1670 old-style parameter declarations; any functions encountered are
1671 nested functions and declaration specifiers are required; otherwise
1672 we are at top level and functions are normal functions and
1673 declaration specifiers may be optional. If EMPTY_OK is true, empty
1674 declarations are OK (subject to all other constraints); otherwise
1675 (old-style parameter declarations) they are diagnosed. If
1676 START_ATTR_OK is true, the declaration specifiers may start with
1677 attributes; otherwise they may not.
1678 OBJC_FOREACH_OBJECT_DECLARATION can be used to get back the parsed
1679 declaration when parsing an Objective-C foreach statement.
1680 FALLTHRU_ATTR_P is used to signal whether this function parsed
1681 "__attribute__((fallthrough));".
1684 declaration-specifiers init-declarator-list[opt] ;
1685 static_assert-declaration
1687 function-definition:
1688 declaration-specifiers[opt] declarator declaration-list[opt]
1693 declaration-list declaration
1695 init-declarator-list:
1697 init-declarator-list , init-declarator
1700 declarator simple-asm-expr[opt] attributes[opt]
1701 declarator simple-asm-expr[opt] attributes[opt] = initializer
1705 nested-function-definition:
1706 declaration-specifiers declarator declaration-list[opt]
1712 attributes objc-class-definition
1713 attributes objc-category-definition
1714 attributes objc-protocol-definition
1716 The simple-asm-expr and attributes are GNU extensions.
1718 This function does not handle __extension__; that is handled in its
1719 callers. ??? Following the old parser, __extension__ may start
1720 external declarations, declarations in functions and declarations
1721 at the start of "for" loops, but not old-style parameter
1724 C99 requires declaration specifiers in a function definition; the
1725 absence is diagnosed through the diagnosis of implicit int. In GNU
1726 C we also allow but diagnose declarations without declaration
1727 specifiers, but only at top level (elsewhere they conflict with
1730 In Objective-C, declarations of the looping variable in a foreach
1731 statement are exceptionally terminated by 'in' (for example, 'for
1732 (NSObject *object in array) { ... }').
1737 threadprivate-directive
1741 gimple-function-definition:
1742 declaration-specifiers[opt] __GIMPLE (gimple-or-rtl-pass-list) declarator
1743 declaration-list[opt] compound-statement
1745 rtl-function-definition:
1746 declaration-specifiers[opt] __RTL (gimple-or-rtl-pass-list) declarator
1747 declaration-list[opt] compound-statement */
1750 c_parser_declaration_or_fndef (c_parser
*parser
, bool fndef_ok
,
1751 bool static_assert_ok
, bool empty_ok
,
1752 bool nested
, bool start_attr_ok
,
1753 tree
*objc_foreach_object_declaration
,
1754 vec
<c_token
> omp_declare_simd_clauses
,
1755 struct oacc_routine_data
*oacc_routine_data
,
1756 bool *fallthru_attr_p
)
1758 struct c_declspecs
*specs
;
1760 tree all_prefix_attrs
;
1761 bool diagnosed_no_specs
= false;
1762 location_t here
= c_parser_peek_token (parser
)->location
;
1764 if (static_assert_ok
1765 && c_parser_next_token_is_keyword (parser
, RID_STATIC_ASSERT
))
1767 c_parser_static_assert_declaration (parser
);
1770 specs
= build_null_declspecs ();
1772 /* Try to detect an unknown type name when we have "A B" or "A *B". */
1773 if (c_parser_peek_token (parser
)->type
== CPP_NAME
1774 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
1775 && (c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
1776 || c_parser_peek_2nd_token (parser
)->type
== CPP_MULT
)
1777 && (!nested
|| !lookup_name (c_parser_peek_token (parser
)->value
)))
1779 tree name
= c_parser_peek_token (parser
)->value
;
1781 /* Issue a warning about NAME being an unknown type name, perhaps
1782 with some kind of hint.
1783 If the user forgot a "struct" etc, suggest inserting
1784 it. Otherwise, attempt to look for misspellings. */
1785 gcc_rich_location
richloc (here
);
1786 if (tag_exists_p (RECORD_TYPE
, name
))
1788 /* This is not C++ with its implicit typedef. */
1789 richloc
.add_fixit_insert_before ("struct ");
1791 "unknown type name %qE;"
1792 " use %<struct%> keyword to refer to the type",
1795 else if (tag_exists_p (UNION_TYPE
, name
))
1797 richloc
.add_fixit_insert_before ("union ");
1799 "unknown type name %qE;"
1800 " use %<union%> keyword to refer to the type",
1803 else if (tag_exists_p (ENUMERAL_TYPE
, name
))
1805 richloc
.add_fixit_insert_before ("enum ");
1807 "unknown type name %qE;"
1808 " use %<enum%> keyword to refer to the type",
1813 name_hint hint
= lookup_name_fuzzy (name
, FUZZY_LOOKUP_TYPENAME
,
1817 richloc
.add_fixit_replace (hint
.suggestion ());
1819 "unknown type name %qE; did you mean %qs?",
1820 name
, hint
.suggestion ());
1823 error_at (here
, "unknown type name %qE", name
);
1826 /* Parse declspecs normally to get a correct pointer type, but avoid
1827 a further "fails to be a type name" error. Refuse nested functions
1828 since it is not how the user likely wants us to recover. */
1829 c_parser_peek_token (parser
)->type
= CPP_KEYWORD
;
1830 c_parser_peek_token (parser
)->keyword
= RID_VOID
;
1831 c_parser_peek_token (parser
)->value
= error_mark_node
;
1835 c_parser_declspecs (parser
, specs
, true, true, start_attr_ok
,
1836 true, true, cla_nonabstract_decl
);
1839 c_parser_skip_to_end_of_block_or_statement (parser
);
1842 if (nested
&& !specs
->declspecs_seen_p
)
1844 c_parser_error (parser
, "expected declaration specifiers");
1845 c_parser_skip_to_end_of_block_or_statement (parser
);
1849 finish_declspecs (specs
);
1850 bool auto_type_p
= specs
->typespec_word
== cts_auto_type
;
1851 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
1854 error_at (here
, "%<__auto_type%> in empty declaration");
1855 else if (specs
->typespec_kind
== ctsk_none
1856 && attribute_fallthrough_p (specs
->attrs
))
1858 if (fallthru_attr_p
!= NULL
)
1859 *fallthru_attr_p
= true;
1860 tree fn
= build_call_expr_internal_loc (here
, IFN_FALLTHROUGH
,
1868 shadow_tag_warned (specs
, 1);
1869 pedwarn (here
, 0, "empty declaration");
1871 c_parser_consume_token (parser
);
1872 if (oacc_routine_data
)
1873 c_finish_oacc_routine (oacc_routine_data
, NULL_TREE
, false);
1877 /* Provide better error recovery. Note that a type name here is usually
1878 better diagnosed as a redeclaration. */
1880 && specs
->typespec_kind
== ctsk_tagdef
1881 && c_parser_next_token_starts_declspecs (parser
)
1882 && !c_parser_next_token_is (parser
, CPP_NAME
))
1884 c_parser_error (parser
, "expected %<;%>, identifier or %<(%>");
1885 parser
->error
= false;
1886 shadow_tag_warned (specs
, 1);
1889 else if (c_dialect_objc () && !auto_type_p
)
1891 /* Prefix attributes are an error on method decls. */
1892 switch (c_parser_peek_token (parser
)->type
)
1896 if (c_parser_objc_diagnose_bad_element_prefix (parser
, specs
))
1900 warning_at (c_parser_peek_token (parser
)->location
,
1902 "prefix attributes are ignored for methods");
1903 specs
->attrs
= NULL_TREE
;
1906 c_parser_objc_method_definition (parser
);
1908 c_parser_objc_methodproto (parser
);
1914 /* This is where we parse 'attributes @interface ...',
1915 'attributes @implementation ...', 'attributes @protocol ...'
1916 (where attributes could be, for example, __attribute__
1919 switch (c_parser_peek_token (parser
)->keyword
)
1921 case RID_AT_INTERFACE
:
1923 if (c_parser_objc_diagnose_bad_element_prefix (parser
, specs
))
1925 c_parser_objc_class_definition (parser
, specs
->attrs
);
1929 case RID_AT_IMPLEMENTATION
:
1931 if (c_parser_objc_diagnose_bad_element_prefix (parser
, specs
))
1935 warning_at (c_parser_peek_token (parser
)->location
,
1937 "prefix attributes are ignored for implementations");
1938 specs
->attrs
= NULL_TREE
;
1940 c_parser_objc_class_definition (parser
, NULL_TREE
);
1944 case RID_AT_PROTOCOL
:
1946 if (c_parser_objc_diagnose_bad_element_prefix (parser
, specs
))
1948 c_parser_objc_protocol_definition (parser
, specs
->attrs
);
1955 case RID_AT_PROPERTY
:
1958 c_parser_error (parser
, "unexpected attribute");
1959 specs
->attrs
= NULL
;
1966 else if (attribute_fallthrough_p (specs
->attrs
))
1967 warning_at (here
, OPT_Wattributes
,
1968 "%<fallthrough%> attribute not followed by %<;%>");
1970 pending_xref_error ();
1971 prefix_attrs
= specs
->attrs
;
1972 all_prefix_attrs
= prefix_attrs
;
1973 specs
->attrs
= NULL_TREE
;
1976 struct c_declarator
*declarator
;
1979 tree fnbody
= NULL_TREE
;
1980 /* Declaring either one or more declarators (in which case we
1981 should diagnose if there were no declaration specifiers) or a
1982 function definition (in which case the diagnostic for
1983 implicit int suffices). */
1984 declarator
= c_parser_declarator (parser
,
1985 specs
->typespec_kind
!= ctsk_none
,
1986 C_DTR_NORMAL
, &dummy
);
1987 if (declarator
== NULL
)
1989 if (omp_declare_simd_clauses
.exists ()
1990 || !vec_safe_is_empty (parser
->cilk_simd_fn_tokens
))
1991 c_finish_omp_declare_simd (parser
, NULL_TREE
, NULL_TREE
,
1992 omp_declare_simd_clauses
);
1993 if (oacc_routine_data
)
1994 c_finish_oacc_routine (oacc_routine_data
, NULL_TREE
, false);
1995 c_parser_skip_to_end_of_block_or_statement (parser
);
1998 if (auto_type_p
&& declarator
->kind
!= cdk_id
)
2001 "%<__auto_type%> requires a plain identifier"
2003 c_parser_skip_to_end_of_block_or_statement (parser
);
2006 if (c_parser_next_token_is (parser
, CPP_EQ
)
2007 || c_parser_next_token_is (parser
, CPP_COMMA
)
2008 || c_parser_next_token_is (parser
, CPP_SEMICOLON
)
2009 || c_parser_next_token_is_keyword (parser
, RID_ASM
)
2010 || c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
)
2011 || c_parser_next_token_is_keyword (parser
, RID_IN
))
2013 tree asm_name
= NULL_TREE
;
2014 tree postfix_attrs
= NULL_TREE
;
2015 if (!diagnosed_no_specs
&& !specs
->declspecs_seen_p
)
2017 diagnosed_no_specs
= true;
2018 pedwarn (here
, 0, "data definition has no type or storage class");
2020 /* Having seen a data definition, there cannot now be a
2021 function definition. */
2023 if (c_parser_next_token_is_keyword (parser
, RID_ASM
))
2024 asm_name
= c_parser_simple_asm_expr (parser
);
2025 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
2027 postfix_attrs
= c_parser_attributes (parser
);
2028 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
2030 /* This means there is an attribute specifier after
2031 the declarator in a function definition. Provide
2032 some more information for the user. */
2033 error_at (here
, "attributes should be specified before the "
2034 "declarator in a function definition");
2035 c_parser_skip_to_end_of_block_or_statement (parser
);
2039 if (c_parser_next_token_is (parser
, CPP_EQ
))
2043 location_t init_loc
;
2044 c_parser_consume_token (parser
);
2047 init_loc
= c_parser_peek_token (parser
)->location
;
2048 rich_location
richloc (line_table
, init_loc
);
2049 start_init (NULL_TREE
, asm_name
, global_bindings_p (), &richloc
);
2050 /* A parameter is initialized, which is invalid. Don't
2051 attempt to instrument the initializer. */
2052 int flag_sanitize_save
= flag_sanitize
;
2053 if (nested
&& !empty_ok
)
2055 init
= c_parser_expr_no_commas (parser
, NULL
);
2056 flag_sanitize
= flag_sanitize_save
;
2057 if (TREE_CODE (init
.value
) == COMPONENT_REF
2058 && DECL_C_BIT_FIELD (TREE_OPERAND (init
.value
, 1)))
2060 "%<__auto_type%> used with a bit-field"
2062 init
= convert_lvalue_to_rvalue (init_loc
, init
, true, true);
2063 tree init_type
= TREE_TYPE (init
.value
);
2064 /* As with typeof, remove all qualifiers from atomic types. */
2065 if (init_type
!= error_mark_node
&& TYPE_ATOMIC (init_type
))
2067 = c_build_qualified_type (init_type
, TYPE_UNQUALIFIED
);
2068 bool vm_type
= variably_modified_type_p (init_type
,
2071 init
.value
= save_expr (init
.value
);
2073 specs
->typespec_kind
= ctsk_typeof
;
2074 specs
->locations
[cdw_typedef
] = init_loc
;
2075 specs
->typedef_p
= true;
2076 specs
->type
= init_type
;
2079 bool maybe_const
= true;
2080 tree type_expr
= c_fully_fold (init
.value
, false,
2082 specs
->expr_const_operands
&= maybe_const
;
2084 specs
->expr
= build2 (COMPOUND_EXPR
,
2085 TREE_TYPE (type_expr
),
2086 specs
->expr
, type_expr
);
2088 specs
->expr
= type_expr
;
2090 d
= start_decl (declarator
, specs
, true,
2091 chainon (postfix_attrs
, all_prefix_attrs
));
2093 d
= error_mark_node
;
2094 if (omp_declare_simd_clauses
.exists ()
2095 || !vec_safe_is_empty (parser
->cilk_simd_fn_tokens
))
2096 c_finish_omp_declare_simd (parser
, d
, NULL_TREE
,
2097 omp_declare_simd_clauses
);
2101 /* The declaration of the variable is in effect while
2102 its initializer is parsed. */
2103 d
= start_decl (declarator
, specs
, true,
2104 chainon (postfix_attrs
, all_prefix_attrs
));
2106 d
= error_mark_node
;
2107 if (omp_declare_simd_clauses
.exists ()
2108 || !vec_safe_is_empty (parser
->cilk_simd_fn_tokens
))
2109 c_finish_omp_declare_simd (parser
, d
, NULL_TREE
,
2110 omp_declare_simd_clauses
);
2111 init_loc
= c_parser_peek_token (parser
)->location
;
2112 rich_location
richloc (line_table
, init_loc
);
2113 start_init (d
, asm_name
, global_bindings_p (), &richloc
);
2114 /* A parameter is initialized, which is invalid. Don't
2115 attempt to instrument the initializer. */
2116 int flag_sanitize_save
= flag_sanitize
;
2117 if (TREE_CODE (d
) == PARM_DECL
)
2119 init
= c_parser_initializer (parser
);
2120 flag_sanitize
= flag_sanitize_save
;
2123 if (oacc_routine_data
)
2124 c_finish_oacc_routine (oacc_routine_data
, d
, false);
2125 if (d
!= error_mark_node
)
2127 maybe_warn_string_init (init_loc
, TREE_TYPE (d
), init
);
2128 finish_decl (d
, init_loc
, init
.value
,
2129 init
.original_type
, asm_name
);
2137 "%<__auto_type%> requires an initialized "
2138 "data declaration");
2139 c_parser_skip_to_end_of_block_or_statement (parser
);
2142 tree d
= start_decl (declarator
, specs
, false,
2143 chainon (postfix_attrs
,
2145 if (d
&& TREE_CODE (d
) == FUNCTION_DECL
)
2146 if (declarator
->kind
== cdk_function
)
2147 if (DECL_ARGUMENTS (d
) == NULL_TREE
)
2148 DECL_ARGUMENTS (d
) = declarator
->u
.arg_info
->parms
;
2149 if (omp_declare_simd_clauses
.exists ()
2150 || !vec_safe_is_empty (parser
->cilk_simd_fn_tokens
))
2152 tree parms
= NULL_TREE
;
2153 if (d
&& TREE_CODE (d
) == FUNCTION_DECL
)
2155 struct c_declarator
*ce
= declarator
;
2157 if (ce
->kind
== cdk_function
)
2159 parms
= ce
->u
.arg_info
->parms
;
2163 ce
= ce
->declarator
;
2166 temp_store_parm_decls (d
, parms
);
2167 c_finish_omp_declare_simd (parser
, d
, parms
,
2168 omp_declare_simd_clauses
);
2170 temp_pop_parm_decls ();
2172 if (oacc_routine_data
)
2173 c_finish_oacc_routine (oacc_routine_data
, d
, false);
2175 finish_decl (d
, UNKNOWN_LOCATION
, NULL_TREE
,
2176 NULL_TREE
, asm_name
);
2178 if (c_parser_next_token_is_keyword (parser
, RID_IN
))
2181 *objc_foreach_object_declaration
= d
;
2183 *objc_foreach_object_declaration
= error_mark_node
;
2186 if (c_parser_next_token_is (parser
, CPP_COMMA
))
2191 "%<__auto_type%> may only be used with"
2192 " a single declarator");
2193 c_parser_skip_to_end_of_block_or_statement (parser
);
2196 c_parser_consume_token (parser
);
2197 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
2198 all_prefix_attrs
= chainon (c_parser_attributes (parser
),
2201 all_prefix_attrs
= prefix_attrs
;
2204 else if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
2206 c_parser_consume_token (parser
);
2209 else if (c_parser_next_token_is_keyword (parser
, RID_IN
))
2211 /* This can only happen in Objective-C: we found the
2212 'in' that terminates the declaration inside an
2213 Objective-C foreach statement. Do not consume the
2214 token, so that the caller can use it to determine
2215 that this indeed is a foreach context. */
2220 c_parser_error (parser
, "expected %<,%> or %<;%>");
2221 c_parser_skip_to_end_of_block_or_statement (parser
);
2225 else if (auto_type_p
)
2228 "%<__auto_type%> requires an initialized data declaration");
2229 c_parser_skip_to_end_of_block_or_statement (parser
);
2234 c_parser_error (parser
, "expected %<=%>, %<,%>, %<;%>, "
2235 "%<asm%> or %<__attribute__%>");
2236 c_parser_skip_to_end_of_block_or_statement (parser
);
2239 /* Function definition (nested or otherwise). */
2242 pedwarn (here
, OPT_Wpedantic
, "ISO C forbids nested functions");
2243 c_push_function_context ();
2245 if (!start_function (specs
, declarator
, all_prefix_attrs
))
2247 /* At this point we've consumed:
2248 declaration-specifiers declarator
2249 and the next token isn't CPP_EQ, CPP_COMMA, CPP_SEMICOLON,
2250 RID_ASM, RID_ATTRIBUTE, or RID_IN,
2252 declaration-specifiers declarator
2253 aren't grokkable as a function definition, so we have
2255 gcc_assert (!c_parser_next_token_is (parser
, CPP_SEMICOLON
));
2256 if (c_parser_next_token_starts_declspecs (parser
))
2259 declaration-specifiers declarator decl-specs
2260 then assume we have a missing semicolon, which would
2262 declaration-specifiers declarator decl-specs
2265 <~~~~~~~~~ declaration ~~~~~~~~~~>
2266 Use c_parser_require to get an error with a fix-it hint. */
2267 c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>");
2268 parser
->error
= false;
2272 /* This can appear in many cases looking nothing like a
2273 function definition, so we don't give a more specific
2274 error suggesting there was one. */
2275 c_parser_error (parser
, "expected %<=%>, %<,%>, %<;%>, %<asm%> "
2276 "or %<__attribute__%>");
2279 c_pop_function_context ();
2283 if (DECL_DECLARED_INLINE_P (current_function_decl
))
2284 tv
= TV_PARSE_INLINE
;
2287 auto_timevar
at (g_timer
, tv
);
2289 /* Parse old-style parameter declarations. ??? Attributes are
2290 not allowed to start declaration specifiers here because of a
2291 syntax conflict between a function declaration with attribute
2292 suffix and a function definition with an attribute prefix on
2293 first old-style parameter declaration. Following the old
2294 parser, they are not accepted on subsequent old-style
2295 parameter declarations either. However, there is no
2296 ambiguity after the first declaration, nor indeed on the
2297 first as long as we don't allow postfix attributes after a
2298 declarator with a nonempty identifier list in a definition;
2299 and postfix attributes have never been accepted here in
2300 function definitions either. */
2301 while (c_parser_next_token_is_not (parser
, CPP_EOF
)
2302 && c_parser_next_token_is_not (parser
, CPP_OPEN_BRACE
))
2303 c_parser_declaration_or_fndef (parser
, false, false, false,
2304 true, false, NULL
, vNULL
);
2305 store_parm_decls ();
2306 if (omp_declare_simd_clauses
.exists ()
2307 || !vec_safe_is_empty (parser
->cilk_simd_fn_tokens
))
2308 c_finish_omp_declare_simd (parser
, current_function_decl
, NULL_TREE
,
2309 omp_declare_simd_clauses
);
2310 if (oacc_routine_data
)
2311 c_finish_oacc_routine (oacc_routine_data
, current_function_decl
, true);
2312 DECL_STRUCT_FUNCTION (current_function_decl
)->function_start_locus
2313 = c_parser_peek_token (parser
)->location
;
2315 /* If the definition was marked with __GIMPLE then parse the
2316 function body as GIMPLE. */
2317 if (specs
->gimple_p
)
2319 cfun
->pass_startwith
= specs
->gimple_or_rtl_pass
;
2320 bool saved
= in_late_binary_op
;
2321 in_late_binary_op
= true;
2322 c_parser_parse_gimple_body (parser
);
2323 in_late_binary_op
= saved
;
2325 /* Similarly, if it was marked with __RTL, use the RTL parser now,
2326 consuming the function body. */
2327 else if (specs
->rtl_p
)
2329 c_parser_parse_rtl_body (parser
, specs
->gimple_or_rtl_pass
);
2331 /* Normally, store_parm_decls sets next_is_function_body,
2332 anticipating a function body. We need a push_scope/pop_scope
2333 pair to flush out this state, or subsequent function parsing
2343 fnbody
= c_parser_compound_statement (parser
);
2344 if (flag_cilkplus
&& contains_array_notation_expr (fnbody
))
2345 fnbody
= expand_array_notation_exprs (fnbody
);
2347 tree fndecl
= current_function_decl
;
2350 tree decl
= current_function_decl
;
2351 /* Mark nested functions as needing static-chain initially.
2352 lower_nested_functions will recompute it but the
2353 DECL_STATIC_CHAIN flag is also used before that happens,
2354 by initializer_constant_valid_p. See gcc.dg/nested-fn-2.c. */
2355 DECL_STATIC_CHAIN (decl
) = 1;
2358 c_pop_function_context ();
2359 add_stmt (build_stmt (DECL_SOURCE_LOCATION (decl
), DECL_EXPR
, decl
));
2367 /* Get rid of the empty stmt list for GIMPLE. */
2368 if (specs
->gimple_p
)
2369 DECL_SAVED_TREE (fndecl
) = NULL_TREE
;
2375 /* Parse an asm-definition (asm() outside a function body). This is a
2383 c_parser_asm_definition (c_parser
*parser
)
2385 tree asm_str
= c_parser_simple_asm_expr (parser
);
2387 symtab
->finalize_toplevel_asm (asm_str
);
2388 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
2391 /* Parse a static assertion (C11 6.7.10).
2393 static_assert-declaration:
2394 static_assert-declaration-no-semi ;
2398 c_parser_static_assert_declaration (c_parser
*parser
)
2400 c_parser_static_assert_declaration_no_semi (parser
);
2402 || !c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
2403 c_parser_skip_to_end_of_block_or_statement (parser
);
2406 /* Parse a static assertion (C11 6.7.10), without the trailing
2409 static_assert-declaration-no-semi:
2410 _Static_assert ( constant-expression , string-literal )
2414 c_parser_static_assert_declaration_no_semi (c_parser
*parser
)
2416 location_t assert_loc
, value_loc
;
2420 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_STATIC_ASSERT
));
2421 assert_loc
= c_parser_peek_token (parser
)->location
;
2423 pedwarn_c99 (assert_loc
, OPT_Wpedantic
,
2424 "ISO C99 does not support %<_Static_assert%>");
2426 pedwarn_c99 (assert_loc
, OPT_Wpedantic
,
2427 "ISO C90 does not support %<_Static_assert%>");
2428 c_parser_consume_token (parser
);
2429 matching_parens parens
;
2430 if (!parens
.require_open (parser
))
2432 location_t value_tok_loc
= c_parser_peek_token (parser
)->location
;
2433 value
= c_parser_expr_no_commas (parser
, NULL
).value
;
2434 value_loc
= EXPR_LOC_OR_LOC (value
, value_tok_loc
);
2435 parser
->lex_untranslated_string
= true;
2436 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
2438 parser
->lex_untranslated_string
= false;
2441 switch (c_parser_peek_token (parser
)->type
)
2447 case CPP_UTF8STRING
:
2448 string
= c_parser_peek_token (parser
)->value
;
2449 c_parser_consume_token (parser
);
2450 parser
->lex_untranslated_string
= false;
2453 c_parser_error (parser
, "expected string literal");
2454 parser
->lex_untranslated_string
= false;
2457 parens
.require_close (parser
);
2459 if (!INTEGRAL_TYPE_P (TREE_TYPE (value
)))
2461 error_at (value_loc
, "expression in static assertion is not an integer");
2464 if (TREE_CODE (value
) != INTEGER_CST
)
2466 value
= c_fully_fold (value
, false, NULL
);
2467 /* Strip no-op conversions. */
2468 STRIP_TYPE_NOPS (value
);
2469 if (TREE_CODE (value
) == INTEGER_CST
)
2470 pedwarn (value_loc
, OPT_Wpedantic
, "expression in static assertion "
2471 "is not an integer constant expression");
2473 if (TREE_CODE (value
) != INTEGER_CST
)
2475 error_at (value_loc
, "expression in static assertion is not constant");
2478 constant_expression_warning (value
);
2479 if (integer_zerop (value
))
2480 error_at (assert_loc
, "static assertion failed: %E", string
);
2483 /* Parse some declaration specifiers (possibly none) (C90 6.5, C99
2484 6.7, C11 6.7), adding them to SPECS (which may already include some).
2485 Storage class specifiers are accepted iff SCSPEC_OK; type
2486 specifiers are accepted iff TYPESPEC_OK; alignment specifiers are
2487 accepted iff ALIGNSPEC_OK; attributes are accepted at the start
2488 iff START_ATTR_OK; __auto_type is accepted iff AUTO_TYPE_OK.
2490 declaration-specifiers:
2491 storage-class-specifier declaration-specifiers[opt]
2492 type-specifier declaration-specifiers[opt]
2493 type-qualifier declaration-specifiers[opt]
2494 function-specifier declaration-specifiers[opt]
2495 alignment-specifier declaration-specifiers[opt]
2497 Function specifiers (inline) are from C99, and are currently
2498 handled as storage class specifiers, as is __thread. Alignment
2499 specifiers are from C11.
2501 C90 6.5.1, C99 6.7.1, C11 6.7.1:
2502 storage-class-specifier:
2510 (_Thread_local is new in C11.)
2512 C99 6.7.4, C11 6.7.4:
2517 (_Noreturn is new in C11.)
2519 C90 6.5.2, C99 6.7.2, C11 6.7.2:
2532 [_Imaginary removed in C99 TC2]
2533 struct-or-union-specifier
2536 atomic-type-specifier
2538 (_Bool and _Complex are new in C99.)
2539 (atomic-type-specifier is new in C11.)
2541 C90 6.5.3, C99 6.7.3, C11 6.7.3:
2547 address-space-qualifier
2550 (restrict is new in C99.)
2551 (_Atomic is new in C11.)
2555 declaration-specifiers:
2556 attributes declaration-specifiers[opt]
2562 identifier recognized by the target
2564 storage-class-specifier:
2578 (_Fract, _Accum, and _Sat are new from ISO/IEC DTR 18037:
2579 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1169.pdf)
2581 atomic-type-specifier
2582 _Atomic ( type-name )
2587 class-name objc-protocol-refs[opt]
2588 typedef-name objc-protocol-refs
2593 c_parser_declspecs (c_parser
*parser
, struct c_declspecs
*specs
,
2594 bool scspec_ok
, bool typespec_ok
, bool start_attr_ok
,
2595 bool alignspec_ok
, bool auto_type_ok
,
2596 enum c_lookahead_kind la
)
2598 bool attrs_ok
= start_attr_ok
;
2599 bool seen_type
= specs
->typespec_kind
!= ctsk_none
;
2602 gcc_assert (la
== cla_prefer_id
);
2604 while (c_parser_next_token_is (parser
, CPP_NAME
)
2605 || c_parser_next_token_is (parser
, CPP_KEYWORD
)
2606 || (c_dialect_objc () && c_parser_next_token_is (parser
, CPP_LESS
)))
2608 struct c_typespec t
;
2611 location_t loc
= c_parser_peek_token (parser
)->location
;
2613 /* If we cannot accept a type, exit if the next token must start
2614 one. Also, if we already have seen a tagged definition,
2615 a typename would be an error anyway and likely the user
2616 has simply forgotten a semicolon, so we exit. */
2617 if ((!typespec_ok
|| specs
->typespec_kind
== ctsk_tagdef
)
2618 && c_parser_next_tokens_start_typename (parser
, la
)
2619 && !c_parser_next_token_is_qualifier (parser
))
2622 if (c_parser_next_token_is (parser
, CPP_NAME
))
2624 c_token
*name_token
= c_parser_peek_token (parser
);
2625 tree value
= name_token
->value
;
2626 c_id_kind kind
= name_token
->id_kind
;
2628 if (kind
== C_ID_ADDRSPACE
)
2631 = name_token
->keyword
- RID_FIRST_ADDR_SPACE
;
2632 declspecs_add_addrspace (name_token
->location
, specs
, as
);
2633 c_parser_consume_token (parser
);
2638 gcc_assert (!c_parser_next_token_is_qualifier (parser
));
2640 /* If we cannot accept a type, and the next token must start one,
2641 exit. Do the same if we already have seen a tagged definition,
2642 since it would be an error anyway and likely the user has simply
2643 forgotten a semicolon. */
2644 if (seen_type
|| !c_parser_next_tokens_start_typename (parser
, la
))
2647 /* Now at an unknown typename (C_ID_ID), a C_ID_TYPENAME or
2648 a C_ID_CLASSNAME. */
2649 c_parser_consume_token (parser
);
2652 if (kind
== C_ID_ID
)
2654 error_at (loc
, "unknown type name %qE", value
);
2655 t
.kind
= ctsk_typedef
;
2656 t
.spec
= error_mark_node
;
2658 else if (kind
== C_ID_TYPENAME
2659 && (!c_dialect_objc ()
2660 || c_parser_next_token_is_not (parser
, CPP_LESS
)))
2662 t
.kind
= ctsk_typedef
;
2663 /* For a typedef name, record the meaning, not the name.
2664 In case of 'foo foo, bar;'. */
2665 t
.spec
= lookup_name (value
);
2669 tree proto
= NULL_TREE
;
2670 gcc_assert (c_dialect_objc ());
2672 if (c_parser_next_token_is (parser
, CPP_LESS
))
2673 proto
= c_parser_objc_protocol_refs (parser
);
2674 t
.spec
= objc_get_protocol_qualified_type (value
, proto
);
2677 t
.expr_const_operands
= true;
2678 declspecs_add_type (name_token
->location
, specs
, t
);
2681 if (c_parser_next_token_is (parser
, CPP_LESS
))
2683 /* Make "<SomeProtocol>" equivalent to "id <SomeProtocol>" -
2684 nisse@lysator.liu.se. */
2686 gcc_assert (c_dialect_objc ());
2687 if (!typespec_ok
|| seen_type
)
2689 proto
= c_parser_objc_protocol_refs (parser
);
2691 t
.spec
= objc_get_protocol_qualified_type (NULL_TREE
, proto
);
2693 t
.expr_const_operands
= true;
2694 declspecs_add_type (loc
, specs
, t
);
2697 gcc_assert (c_parser_next_token_is (parser
, CPP_KEYWORD
));
2698 switch (c_parser_peek_token (parser
)->keyword
)
2711 /* TODO: Distinguish between function specifiers (inline, noreturn)
2712 and storage class specifiers, either here or in
2713 declspecs_add_scspec. */
2714 declspecs_add_scspec (loc
, specs
,
2715 c_parser_peek_token (parser
)->value
);
2716 c_parser_consume_token (parser
);
2748 if (c_dialect_objc ())
2749 parser
->objc_need_raw_identifier
= true;
2750 t
.kind
= ctsk_resword
;
2751 t
.spec
= c_parser_peek_token (parser
)->value
;
2753 t
.expr_const_operands
= true;
2754 declspecs_add_type (loc
, specs
, t
);
2755 c_parser_consume_token (parser
);
2762 t
= c_parser_enum_specifier (parser
);
2763 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE
, t
.spec
);
2764 declspecs_add_type (loc
, specs
, t
);
2772 t
= c_parser_struct_or_union_specifier (parser
);
2773 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE
, t
.spec
);
2774 declspecs_add_type (loc
, specs
, t
);
2777 /* ??? The old parser rejected typeof after other type
2778 specifiers, but is a syntax error the best way of
2780 if (!typespec_ok
|| seen_type
)
2784 t
= c_parser_typeof_specifier (parser
);
2785 declspecs_add_type (loc
, specs
, t
);
2788 /* C parser handling of Objective-C constructs needs
2789 checking for correct lvalue-to-rvalue conversions, and
2790 the code in build_modify_expr handling various
2791 Objective-C cases, and that in build_unary_op handling
2792 Objective-C cases for increment / decrement, also needs
2793 updating; uses of TYPE_MAIN_VARIANT in objc_compare_types
2794 and objc_types_are_equivalent may also need updates. */
2795 if (c_dialect_objc ())
2796 sorry ("%<_Atomic%> in Objective-C");
2798 pedwarn_c99 (loc
, OPT_Wpedantic
,
2799 "ISO C99 does not support the %<_Atomic%> qualifier");
2801 pedwarn_c99 (loc
, OPT_Wpedantic
,
2802 "ISO C90 does not support the %<_Atomic%> qualifier");
2805 value
= c_parser_peek_token (parser
)->value
;
2806 c_parser_consume_token (parser
);
2807 if (typespec_ok
&& c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
2809 /* _Atomic ( type-name ). */
2811 c_parser_consume_token (parser
);
2812 struct c_type_name
*type
= c_parser_type_name (parser
);
2813 t
.kind
= ctsk_typeof
;
2814 t
.spec
= error_mark_node
;
2816 t
.expr_const_operands
= true;
2818 t
.spec
= groktypename (type
, &t
.expr
,
2819 &t
.expr_const_operands
);
2820 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
2822 if (t
.spec
!= error_mark_node
)
2824 if (TREE_CODE (t
.spec
) == ARRAY_TYPE
)
2825 error_at (loc
, "%<_Atomic%>-qualified array type");
2826 else if (TREE_CODE (t
.spec
) == FUNCTION_TYPE
)
2827 error_at (loc
, "%<_Atomic%>-qualified function type");
2828 else if (TYPE_QUALS (t
.spec
) != TYPE_UNQUALIFIED
)
2829 error_at (loc
, "%<_Atomic%> applied to a qualified type");
2831 t
.spec
= c_build_qualified_type (t
.spec
, TYPE_QUAL_ATOMIC
);
2833 declspecs_add_type (loc
, specs
, t
);
2836 declspecs_add_qual (loc
, specs
, value
);
2842 declspecs_add_qual (loc
, specs
, c_parser_peek_token (parser
)->value
);
2843 c_parser_consume_token (parser
);
2848 attrs
= c_parser_attributes (parser
);
2849 declspecs_add_attrs (loc
, specs
, attrs
);
2854 align
= c_parser_alignas_specifier (parser
);
2855 declspecs_add_alignas (loc
, specs
, align
);
2859 error_at (loc
, "%<__GIMPLE%> only valid with -fgimple");
2860 c_parser_consume_token (parser
);
2861 specs
->gimple_p
= true;
2862 specs
->locations
[cdw_gimple
] = loc
;
2863 specs
->gimple_or_rtl_pass
= c_parser_gimple_or_rtl_pass_list (parser
);
2866 c_parser_consume_token (parser
);
2867 specs
->rtl_p
= true;
2868 specs
->locations
[cdw_rtl
] = loc
;
2869 specs
->gimple_or_rtl_pass
= c_parser_gimple_or_rtl_pass_list (parser
);
2878 /* Parse an enum specifier (C90 6.5.2.2, C99 6.7.2.2, C11 6.7.2.2).
2881 enum attributes[opt] identifier[opt] { enumerator-list } attributes[opt]
2882 enum attributes[opt] identifier[opt] { enumerator-list , } attributes[opt]
2883 enum attributes[opt] identifier
2885 The form with trailing comma is new in C99. The forms with
2886 attributes are GNU extensions. In GNU C, we accept any expression
2887 without commas in the syntax (assignment expressions, not just
2888 conditional expressions); assignment expressions will be diagnosed
2893 enumerator-list , enumerator
2896 enumeration-constant
2897 enumeration-constant = constant-expression
2902 enumeration-constant attributes[opt]
2903 enumeration-constant attributes[opt] = constant-expression
2907 static struct c_typespec
2908 c_parser_enum_specifier (c_parser
*parser
)
2910 struct c_typespec ret
;
2912 tree ident
= NULL_TREE
;
2913 location_t enum_loc
;
2914 location_t ident_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
2915 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ENUM
));
2916 c_parser_consume_token (parser
);
2917 attrs
= c_parser_attributes (parser
);
2918 enum_loc
= c_parser_peek_token (parser
)->location
;
2919 /* Set the location in case we create a decl now. */
2920 c_parser_set_source_position_from_token (c_parser_peek_token (parser
));
2921 if (c_parser_next_token_is (parser
, CPP_NAME
))
2923 ident
= c_parser_peek_token (parser
)->value
;
2924 ident_loc
= c_parser_peek_token (parser
)->location
;
2925 enum_loc
= ident_loc
;
2926 c_parser_consume_token (parser
);
2928 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
2930 /* Parse an enum definition. */
2931 struct c_enum_contents the_enum
;
2934 /* We chain the enumerators in reverse order, then put them in
2935 forward order at the end. */
2937 timevar_push (TV_PARSE_ENUM
);
2938 type
= start_enum (enum_loc
, &the_enum
, ident
);
2940 c_parser_consume_token (parser
);
2948 location_t comma_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
2949 location_t decl_loc
, value_loc
;
2950 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
2952 /* Give a nicer error for "enum {}". */
2953 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
)
2956 error_at (c_parser_peek_token (parser
)->location
,
2957 "empty enum is invalid");
2958 parser
->error
= true;
2961 c_parser_error (parser
, "expected identifier");
2962 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
, NULL
);
2963 values
= error_mark_node
;
2966 token
= c_parser_peek_token (parser
);
2967 enum_id
= token
->value
;
2968 /* Set the location in case we create a decl now. */
2969 c_parser_set_source_position_from_token (token
);
2970 decl_loc
= value_loc
= token
->location
;
2971 c_parser_consume_token (parser
);
2972 /* Parse any specified attributes. */
2973 tree enum_attrs
= c_parser_attributes (parser
);
2974 if (c_parser_next_token_is (parser
, CPP_EQ
))
2976 c_parser_consume_token (parser
);
2977 value_loc
= c_parser_peek_token (parser
)->location
;
2978 enum_value
= c_parser_expr_no_commas (parser
, NULL
).value
;
2981 enum_value
= NULL_TREE
;
2982 enum_decl
= build_enumerator (decl_loc
, value_loc
,
2983 &the_enum
, enum_id
, enum_value
);
2985 decl_attributes (&TREE_PURPOSE (enum_decl
), enum_attrs
, 0);
2986 TREE_CHAIN (enum_decl
) = values
;
2989 if (c_parser_next_token_is (parser
, CPP_COMMA
))
2991 comma_loc
= c_parser_peek_token (parser
)->location
;
2993 c_parser_consume_token (parser
);
2995 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
2998 pedwarn_c90 (comma_loc
, OPT_Wpedantic
,
2999 "comma at end of enumerator list");
3000 c_parser_consume_token (parser
);
3005 c_parser_error (parser
, "expected %<,%> or %<}%>");
3006 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
, NULL
);
3007 values
= error_mark_node
;
3011 postfix_attrs
= c_parser_attributes (parser
);
3012 ret
.spec
= finish_enum (type
, nreverse (values
),
3013 chainon (attrs
, postfix_attrs
));
3014 ret
.kind
= ctsk_tagdef
;
3015 ret
.expr
= NULL_TREE
;
3016 ret
.expr_const_operands
= true;
3017 timevar_pop (TV_PARSE_ENUM
);
3022 c_parser_error (parser
, "expected %<{%>");
3023 ret
.spec
= error_mark_node
;
3024 ret
.kind
= ctsk_tagref
;
3025 ret
.expr
= NULL_TREE
;
3026 ret
.expr_const_operands
= true;
3029 ret
= parser_xref_tag (ident_loc
, ENUMERAL_TYPE
, ident
);
3030 /* In ISO C, enumerated types can be referred to only if already
3032 if (pedantic
&& !COMPLETE_TYPE_P (ret
.spec
))
3035 pedwarn (enum_loc
, OPT_Wpedantic
,
3036 "ISO C forbids forward references to %<enum%> types");
3041 /* Parse a struct or union specifier (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1).
3043 struct-or-union-specifier:
3044 struct-or-union attributes[opt] identifier[opt]
3045 { struct-contents } attributes[opt]
3046 struct-or-union attributes[opt] identifier
3049 struct-declaration-list
3051 struct-declaration-list:
3052 struct-declaration ;
3053 struct-declaration-list struct-declaration ;
3060 struct-declaration-list struct-declaration
3062 struct-declaration-list:
3063 struct-declaration-list ;
3066 (Note that in the syntax here, unlike that in ISO C, the semicolons
3067 are included here rather than in struct-declaration, in order to
3068 describe the syntax with extra semicolons and missing semicolon at
3073 struct-declaration-list:
3074 @defs ( class-name )
3076 (Note this does not include a trailing semicolon, but can be
3077 followed by further declarations, and gets a pedwarn-if-pedantic
3078 when followed by a semicolon.) */
3080 static struct c_typespec
3081 c_parser_struct_or_union_specifier (c_parser
*parser
)
3083 struct c_typespec ret
;
3085 tree ident
= NULL_TREE
;
3086 location_t struct_loc
;
3087 location_t ident_loc
= UNKNOWN_LOCATION
;
3088 enum tree_code code
;
3089 switch (c_parser_peek_token (parser
)->keyword
)
3100 struct_loc
= c_parser_peek_token (parser
)->location
;
3101 c_parser_consume_token (parser
);
3102 attrs
= c_parser_attributes (parser
);
3104 /* Set the location in case we create a decl now. */
3105 c_parser_set_source_position_from_token (c_parser_peek_token (parser
));
3107 if (c_parser_next_token_is (parser
, CPP_NAME
))
3109 ident
= c_parser_peek_token (parser
)->value
;
3110 ident_loc
= c_parser_peek_token (parser
)->location
;
3111 struct_loc
= ident_loc
;
3112 c_parser_consume_token (parser
);
3114 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
3116 /* Parse a struct or union definition. Start the scope of the
3117 tag before parsing components. */
3118 struct c_struct_parse_info
*struct_info
;
3119 tree type
= start_struct (struct_loc
, code
, ident
, &struct_info
);
3121 /* We chain the components in reverse order, then put them in
3122 forward order at the end. Each struct-declaration may
3123 declare multiple components (comma-separated), so we must use
3124 chainon to join them, although when parsing each
3125 struct-declaration we can use TREE_CHAIN directly.
3127 The theory behind all this is that there will be more
3128 semicolon separated fields than comma separated fields, and
3129 so we'll be minimizing the number of node traversals required
3132 timevar_push (TV_PARSE_STRUCT
);
3133 contents
= NULL_TREE
;
3134 c_parser_consume_token (parser
);
3135 /* Handle the Objective-C @defs construct,
3136 e.g. foo(sizeof(struct{ @defs(ClassName) }));. */
3137 if (c_parser_next_token_is_keyword (parser
, RID_AT_DEFS
))
3140 gcc_assert (c_dialect_objc ());
3141 c_parser_consume_token (parser
);
3142 matching_parens parens
;
3143 if (!parens
.require_open (parser
))
3145 if (c_parser_next_token_is (parser
, CPP_NAME
)
3146 && c_parser_peek_token (parser
)->id_kind
== C_ID_CLASSNAME
)
3148 name
= c_parser_peek_token (parser
)->value
;
3149 c_parser_consume_token (parser
);
3153 c_parser_error (parser
, "expected class name");
3154 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
3157 parens
.skip_until_found_close (parser
);
3158 contents
= nreverse (objc_get_class_ivars (name
));
3161 /* Parse the struct-declarations and semicolons. Problems with
3162 semicolons are diagnosed here; empty structures are diagnosed
3167 /* Parse any stray semicolon. */
3168 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
3170 location_t semicolon_loc
3171 = c_parser_peek_token (parser
)->location
;
3172 gcc_rich_location
richloc (semicolon_loc
);
3173 richloc
.add_fixit_remove ();
3174 pedwarn (&richloc
, OPT_Wpedantic
,
3175 "extra semicolon in struct or union specified");
3176 c_parser_consume_token (parser
);
3179 /* Stop if at the end of the struct or union contents. */
3180 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
3182 c_parser_consume_token (parser
);
3185 /* Accept #pragmas at struct scope. */
3186 if (c_parser_next_token_is (parser
, CPP_PRAGMA
))
3188 c_parser_pragma (parser
, pragma_struct
, NULL
);
3191 /* Parse some comma-separated declarations, but not the
3192 trailing semicolon if any. */
3193 decls
= c_parser_struct_declaration (parser
);
3194 contents
= chainon (decls
, contents
);
3195 /* If no semicolon follows, either we have a parse error or
3196 are at the end of the struct or union and should
3198 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
3199 c_parser_consume_token (parser
);
3202 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
3203 pedwarn (c_parser_peek_token (parser
)->location
, 0,
3204 "no semicolon at end of struct or union");
3205 else if (parser
->error
3206 || !c_parser_next_token_starts_declspecs (parser
))
3208 c_parser_error (parser
, "expected %<;%>");
3209 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
, NULL
);
3213 /* If we come here, we have already emitted an error
3214 for an expected `;', identifier or `(', and we also
3215 recovered already. Go on with the next field. */
3218 postfix_attrs
= c_parser_attributes (parser
);
3219 ret
.spec
= finish_struct (struct_loc
, type
, nreverse (contents
),
3220 chainon (attrs
, postfix_attrs
), struct_info
);
3221 ret
.kind
= ctsk_tagdef
;
3222 ret
.expr
= NULL_TREE
;
3223 ret
.expr_const_operands
= true;
3224 timevar_pop (TV_PARSE_STRUCT
);
3229 c_parser_error (parser
, "expected %<{%>");
3230 ret
.spec
= error_mark_node
;
3231 ret
.kind
= ctsk_tagref
;
3232 ret
.expr
= NULL_TREE
;
3233 ret
.expr_const_operands
= true;
3236 ret
= parser_xref_tag (ident_loc
, code
, ident
);
3240 /* Parse a struct-declaration (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1),
3241 *without* the trailing semicolon.
3244 specifier-qualifier-list struct-declarator-list
3245 static_assert-declaration-no-semi
3247 specifier-qualifier-list:
3248 type-specifier specifier-qualifier-list[opt]
3249 type-qualifier specifier-qualifier-list[opt]
3250 attributes specifier-qualifier-list[opt]
3252 struct-declarator-list:
3254 struct-declarator-list , attributes[opt] struct-declarator
3257 declarator attributes[opt]
3258 declarator[opt] : constant-expression attributes[opt]
3263 __extension__ struct-declaration
3264 specifier-qualifier-list
3266 Unlike the ISO C syntax, semicolons are handled elsewhere. The use
3267 of attributes where shown is a GNU extension. In GNU C, we accept
3268 any expression without commas in the syntax (assignment
3269 expressions, not just conditional expressions); assignment
3270 expressions will be diagnosed as non-constant. */
3273 c_parser_struct_declaration (c_parser
*parser
)
3275 struct c_declspecs
*specs
;
3277 tree all_prefix_attrs
;
3279 location_t decl_loc
;
3280 if (c_parser_next_token_is_keyword (parser
, RID_EXTENSION
))
3284 ext
= disable_extension_diagnostics ();
3285 c_parser_consume_token (parser
);
3286 decl
= c_parser_struct_declaration (parser
);
3287 restore_extension_diagnostics (ext
);
3290 if (c_parser_next_token_is_keyword (parser
, RID_STATIC_ASSERT
))
3292 c_parser_static_assert_declaration_no_semi (parser
);
3295 specs
= build_null_declspecs ();
3296 decl_loc
= c_parser_peek_token (parser
)->location
;
3297 /* Strictly by the standard, we shouldn't allow _Alignas here,
3298 but it appears to have been intended to allow it there, so
3299 we're keeping it as it is until WG14 reaches a conclusion
3301 <http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1731.pdf> */
3302 c_parser_declspecs (parser
, specs
, false, true, true,
3303 true, false, cla_nonabstract_decl
);
3306 if (!specs
->declspecs_seen_p
)
3308 c_parser_error (parser
, "expected specifier-qualifier-list");
3311 finish_declspecs (specs
);
3312 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
)
3313 || c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
3316 if (specs
->typespec_kind
== ctsk_none
)
3318 pedwarn (decl_loc
, OPT_Wpedantic
,
3319 "ISO C forbids member declarations with no members");
3320 shadow_tag_warned (specs
, pedantic
);
3325 /* Support for unnamed structs or unions as members of
3326 structs or unions (which is [a] useful and [b] supports
3330 ret
= grokfield (c_parser_peek_token (parser
)->location
,
3331 build_id_declarator (NULL_TREE
), specs
,
3334 decl_attributes (&ret
, attrs
, 0);
3339 /* Provide better error recovery. Note that a type name here is valid,
3340 and will be treated as a field name. */
3341 if (specs
->typespec_kind
== ctsk_tagdef
3342 && TREE_CODE (specs
->type
) != ENUMERAL_TYPE
3343 && c_parser_next_token_starts_declspecs (parser
)
3344 && !c_parser_next_token_is (parser
, CPP_NAME
))
3346 c_parser_error (parser
, "expected %<;%>, identifier or %<(%>");
3347 parser
->error
= false;
3351 pending_xref_error ();
3352 prefix_attrs
= specs
->attrs
;
3353 all_prefix_attrs
= prefix_attrs
;
3354 specs
->attrs
= NULL_TREE
;
3358 /* Declaring one or more declarators or un-named bit-fields. */
3359 struct c_declarator
*declarator
;
3361 if (c_parser_next_token_is (parser
, CPP_COLON
))
3362 declarator
= build_id_declarator (NULL_TREE
);
3364 declarator
= c_parser_declarator (parser
,
3365 specs
->typespec_kind
!= ctsk_none
,
3366 C_DTR_NORMAL
, &dummy
);
3367 if (declarator
== NULL
)
3369 c_parser_skip_to_end_of_block_or_statement (parser
);
3372 if (c_parser_next_token_is (parser
, CPP_COLON
)
3373 || c_parser_next_token_is (parser
, CPP_COMMA
)
3374 || c_parser_next_token_is (parser
, CPP_SEMICOLON
)
3375 || c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
)
3376 || c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
3378 tree postfix_attrs
= NULL_TREE
;
3379 tree width
= NULL_TREE
;
3381 if (c_parser_next_token_is (parser
, CPP_COLON
))
3383 c_parser_consume_token (parser
);
3384 width
= c_parser_expr_no_commas (parser
, NULL
).value
;
3386 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
3387 postfix_attrs
= c_parser_attributes (parser
);
3388 d
= grokfield (c_parser_peek_token (parser
)->location
,
3389 declarator
, specs
, width
, &all_prefix_attrs
);
3390 decl_attributes (&d
, chainon (postfix_attrs
,
3391 all_prefix_attrs
), 0);
3392 DECL_CHAIN (d
) = decls
;
3394 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
3395 all_prefix_attrs
= chainon (c_parser_attributes (parser
),
3398 all_prefix_attrs
= prefix_attrs
;
3399 if (c_parser_next_token_is (parser
, CPP_COMMA
))
3400 c_parser_consume_token (parser
);
3401 else if (c_parser_next_token_is (parser
, CPP_SEMICOLON
)
3402 || c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
3404 /* Semicolon consumed in caller. */
3409 c_parser_error (parser
, "expected %<,%>, %<;%> or %<}%>");
3415 c_parser_error (parser
,
3416 "expected %<:%>, %<,%>, %<;%>, %<}%> or "
3417 "%<__attribute__%>");
3424 /* Parse a typeof specifier (a GNU extension).
3427 typeof ( expression )
3428 typeof ( type-name )
3431 static struct c_typespec
3432 c_parser_typeof_specifier (c_parser
*parser
)
3434 struct c_typespec ret
;
3435 ret
.kind
= ctsk_typeof
;
3436 ret
.spec
= error_mark_node
;
3437 ret
.expr
= NULL_TREE
;
3438 ret
.expr_const_operands
= true;
3439 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_TYPEOF
));
3440 c_parser_consume_token (parser
);
3441 c_inhibit_evaluation_warnings
++;
3443 matching_parens parens
;
3444 if (!parens
.require_open (parser
))
3446 c_inhibit_evaluation_warnings
--;
3450 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_id
))
3452 struct c_type_name
*type
= c_parser_type_name (parser
);
3453 c_inhibit_evaluation_warnings
--;
3457 ret
.spec
= groktypename (type
, &ret
.expr
, &ret
.expr_const_operands
);
3458 pop_maybe_used (variably_modified_type_p (ret
.spec
, NULL_TREE
));
3464 location_t here
= c_parser_peek_token (parser
)->location
;
3465 struct c_expr expr
= c_parser_expression (parser
);
3466 c_inhibit_evaluation_warnings
--;
3468 if (TREE_CODE (expr
.value
) == COMPONENT_REF
3469 && DECL_C_BIT_FIELD (TREE_OPERAND (expr
.value
, 1)))
3470 error_at (here
, "%<typeof%> applied to a bit-field");
3471 mark_exp_read (expr
.value
);
3472 ret
.spec
= TREE_TYPE (expr
.value
);
3473 was_vm
= variably_modified_type_p (ret
.spec
, NULL_TREE
);
3474 /* This is returned with the type so that when the type is
3475 evaluated, this can be evaluated. */
3477 ret
.expr
= c_fully_fold (expr
.value
, false, &ret
.expr_const_operands
);
3478 pop_maybe_used (was_vm
);
3479 /* For use in macros such as those in <stdatomic.h>, remove all
3480 qualifiers from atomic types. (const can be an issue for more macros
3481 using typeof than just the <stdatomic.h> ones.) */
3482 if (ret
.spec
!= error_mark_node
&& TYPE_ATOMIC (ret
.spec
))
3483 ret
.spec
= c_build_qualified_type (ret
.spec
, TYPE_UNQUALIFIED
);
3485 parens
.skip_until_found_close (parser
);
3489 /* Parse an alignment-specifier.
3493 alignment-specifier:
3494 _Alignas ( type-name )
3495 _Alignas ( constant-expression )
3499 c_parser_alignas_specifier (c_parser
* parser
)
3501 tree ret
= error_mark_node
;
3502 location_t loc
= c_parser_peek_token (parser
)->location
;
3503 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ALIGNAS
));
3504 c_parser_consume_token (parser
);
3506 pedwarn_c99 (loc
, OPT_Wpedantic
,
3507 "ISO C99 does not support %<_Alignas%>");
3509 pedwarn_c99 (loc
, OPT_Wpedantic
,
3510 "ISO C90 does not support %<_Alignas%>");
3511 matching_parens parens
;
3512 if (!parens
.require_open (parser
))
3514 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_id
))
3516 struct c_type_name
*type
= c_parser_type_name (parser
);
3518 ret
= c_sizeof_or_alignof_type (loc
, groktypename (type
, NULL
, NULL
),
3522 ret
= c_parser_expr_no_commas (parser
, NULL
).value
;
3523 parens
.skip_until_found_close (parser
);
3527 /* Parse a declarator, possibly an abstract declarator (C90 6.5.4,
3528 6.5.5, C99 6.7.5, 6.7.6, C11 6.7.6, 6.7.7). If TYPE_SEEN_P then
3529 a typedef name may be redeclared; otherwise it may not. KIND
3530 indicates which kind of declarator is wanted. Returns a valid
3531 declarator except in the case of a syntax error in which case NULL is
3532 returned. *SEEN_ID is set to true if an identifier being declared is
3533 seen; this is used to diagnose bad forms of abstract array declarators
3534 and to determine whether an identifier list is syntactically permitted.
3537 pointer[opt] direct-declarator
3541 ( attributes[opt] declarator )
3542 direct-declarator array-declarator
3543 direct-declarator ( parameter-type-list )
3544 direct-declarator ( identifier-list[opt] )
3547 * type-qualifier-list[opt]
3548 * type-qualifier-list[opt] pointer
3550 type-qualifier-list:
3553 type-qualifier-list type-qualifier
3554 type-qualifier-list attributes
3557 [ type-qualifier-list[opt] assignment-expression[opt] ]
3558 [ static type-qualifier-list[opt] assignment-expression ]
3559 [ type-qualifier-list static assignment-expression ]
3560 [ type-qualifier-list[opt] * ]
3562 parameter-type-list:
3564 parameter-list , ...
3567 parameter-declaration
3568 parameter-list , parameter-declaration
3570 parameter-declaration:
3571 declaration-specifiers declarator attributes[opt]
3572 declaration-specifiers abstract-declarator[opt] attributes[opt]
3576 identifier-list , identifier
3578 abstract-declarator:
3580 pointer[opt] direct-abstract-declarator
3582 direct-abstract-declarator:
3583 ( attributes[opt] abstract-declarator )
3584 direct-abstract-declarator[opt] array-declarator
3585 direct-abstract-declarator[opt] ( parameter-type-list[opt] )
3590 direct-declarator ( parameter-forward-declarations
3591 parameter-type-list[opt] )
3593 direct-abstract-declarator:
3594 direct-abstract-declarator[opt] ( parameter-forward-declarations
3595 parameter-type-list[opt] )
3597 parameter-forward-declarations:
3599 parameter-forward-declarations parameter-list ;
3601 The uses of attributes shown above are GNU extensions.
3603 Some forms of array declarator are not included in C99 in the
3604 syntax for abstract declarators; these are disallowed elsewhere.
3605 This may be a defect (DR#289).
3607 This function also accepts an omitted abstract declarator as being
3608 an abstract declarator, although not part of the formal syntax. */
3610 struct c_declarator
*
3611 c_parser_declarator (c_parser
*parser
, bool type_seen_p
, c_dtr_syn kind
,
3614 /* Parse any initial pointer part. */
3615 if (c_parser_next_token_is (parser
, CPP_MULT
))
3617 struct c_declspecs
*quals_attrs
= build_null_declspecs ();
3618 struct c_declarator
*inner
;
3619 c_parser_consume_token (parser
);
3620 c_parser_declspecs (parser
, quals_attrs
, false, false, true,
3621 false, false, cla_prefer_id
);
3622 inner
= c_parser_declarator (parser
, type_seen_p
, kind
, seen_id
);
3626 return make_pointer_declarator (quals_attrs
, inner
);
3628 /* Now we have a direct declarator, direct abstract declarator or
3629 nothing (which counts as a direct abstract declarator here). */
3630 return c_parser_direct_declarator (parser
, type_seen_p
, kind
, seen_id
);
3633 /* Parse a direct declarator or direct abstract declarator; arguments
3634 as c_parser_declarator. */
3636 static struct c_declarator
*
3637 c_parser_direct_declarator (c_parser
*parser
, bool type_seen_p
, c_dtr_syn kind
,
3640 /* The direct declarator must start with an identifier (possibly
3641 omitted) or a parenthesized declarator (possibly abstract). In
3642 an ordinary declarator, initial parentheses must start a
3643 parenthesized declarator. In an abstract declarator or parameter
3644 declarator, they could start a parenthesized declarator or a
3645 parameter list. To tell which, the open parenthesis and any
3646 following attributes must be read. If a declaration specifier
3647 follows, then it is a parameter list; if the specifier is a
3648 typedef name, there might be an ambiguity about redeclaring it,
3649 which is resolved in the direction of treating it as a typedef
3650 name. If a close parenthesis follows, it is also an empty
3651 parameter list, as the syntax does not permit empty abstract
3652 declarators. Otherwise, it is a parenthesized declarator (in
3653 which case the analysis may be repeated inside it, recursively).
3655 ??? There is an ambiguity in a parameter declaration "int
3656 (__attribute__((foo)) x)", where x is not a typedef name: it
3657 could be an abstract declarator for a function, or declare x with
3658 parentheses. The proper resolution of this ambiguity needs
3659 documenting. At present we follow an accident of the old
3660 parser's implementation, whereby the first parameter must have
3661 some declaration specifiers other than just attributes. Thus as
3662 a parameter declaration it is treated as a parenthesized
3663 parameter named x, and as an abstract declarator it is
3666 ??? Also following the old parser, attributes inside an empty
3667 parameter list are ignored, making it a list not yielding a
3668 prototype, rather than giving an error or making it have one
3669 parameter with implicit type int.
3671 ??? Also following the old parser, typedef names may be
3672 redeclared in declarators, but not Objective-C class names. */
3674 if (kind
!= C_DTR_ABSTRACT
3675 && c_parser_next_token_is (parser
, CPP_NAME
)
3677 && (c_parser_peek_token (parser
)->id_kind
== C_ID_TYPENAME
3678 || c_parser_peek_token (parser
)->id_kind
== C_ID_CLASSNAME
))
3679 || c_parser_peek_token (parser
)->id_kind
== C_ID_ID
))
3681 struct c_declarator
*inner
3682 = build_id_declarator (c_parser_peek_token (parser
)->value
);
3684 inner
->id_loc
= c_parser_peek_token (parser
)->location
;
3685 c_parser_consume_token (parser
);
3686 return c_parser_direct_declarator_inner (parser
, *seen_id
, inner
);
3689 if (kind
!= C_DTR_NORMAL
3690 && c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
))
3692 struct c_declarator
*inner
= build_id_declarator (NULL_TREE
);
3693 inner
->id_loc
= c_parser_peek_token (parser
)->location
;
3694 return c_parser_direct_declarator_inner (parser
, *seen_id
, inner
);
3697 /* Either we are at the end of an abstract declarator, or we have
3700 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
3703 struct c_declarator
*inner
;
3704 c_parser_consume_token (parser
);
3705 attrs
= c_parser_attributes (parser
);
3706 if (kind
!= C_DTR_NORMAL
3707 && (c_parser_next_token_starts_declspecs (parser
)
3708 || c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
)))
3710 struct c_arg_info
*args
3711 = c_parser_parms_declarator (parser
, kind
== C_DTR_NORMAL
,
3718 = build_function_declarator (args
,
3719 build_id_declarator (NULL_TREE
));
3720 return c_parser_direct_declarator_inner (parser
, *seen_id
,
3724 /* A parenthesized declarator. */
3725 inner
= c_parser_declarator (parser
, type_seen_p
, kind
, seen_id
);
3726 if (inner
!= NULL
&& attrs
!= NULL
)
3727 inner
= build_attrs_declarator (attrs
, inner
);
3728 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
3730 c_parser_consume_token (parser
);
3734 return c_parser_direct_declarator_inner (parser
, *seen_id
, inner
);
3738 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
3745 if (kind
== C_DTR_NORMAL
)
3747 c_parser_error (parser
, "expected identifier or %<(%>");
3751 return build_id_declarator (NULL_TREE
);
3755 /* Parse part of a direct declarator or direct abstract declarator,
3756 given that some (in INNER) has already been parsed; ID_PRESENT is
3757 true if an identifier is present, false for an abstract
3760 static struct c_declarator
*
3761 c_parser_direct_declarator_inner (c_parser
*parser
, bool id_present
,
3762 struct c_declarator
*inner
)
3764 /* Parse a sequence of array declarators and parameter lists. */
3765 if (c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
))
3767 location_t brace_loc
= c_parser_peek_token (parser
)->location
;
3768 struct c_declarator
*declarator
;
3769 struct c_declspecs
*quals_attrs
= build_null_declspecs ();
3772 struct c_expr dimen
;
3773 dimen
.value
= NULL_TREE
;
3774 dimen
.original_code
= ERROR_MARK
;
3775 dimen
.original_type
= NULL_TREE
;
3776 c_parser_consume_token (parser
);
3777 c_parser_declspecs (parser
, quals_attrs
, false, false, true,
3778 false, false, cla_prefer_id
);
3779 static_seen
= c_parser_next_token_is_keyword (parser
, RID_STATIC
);
3781 c_parser_consume_token (parser
);
3782 if (static_seen
&& !quals_attrs
->declspecs_seen_p
)
3783 c_parser_declspecs (parser
, quals_attrs
, false, false, true,
3784 false, false, cla_prefer_id
);
3785 if (!quals_attrs
->declspecs_seen_p
)
3787 /* If "static" is present, there must be an array dimension.
3788 Otherwise, there may be a dimension, "*", or no
3793 dimen
= c_parser_expr_no_commas (parser
, NULL
);
3797 if (c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
3799 dimen
.value
= NULL_TREE
;
3802 else if (flag_cilkplus
3803 && c_parser_next_token_is (parser
, CPP_COLON
))
3805 dimen
.value
= error_mark_node
;
3807 error_at (c_parser_peek_token (parser
)->location
,
3808 "array notations cannot be used in declaration");
3809 c_parser_consume_token (parser
);
3811 else if (c_parser_next_token_is (parser
, CPP_MULT
))
3813 if (c_parser_peek_2nd_token (parser
)->type
== CPP_CLOSE_SQUARE
)
3815 dimen
.value
= NULL_TREE
;
3817 c_parser_consume_token (parser
);
3822 dimen
= c_parser_expr_no_commas (parser
, NULL
);
3828 dimen
= c_parser_expr_no_commas (parser
, NULL
);
3831 if (c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
3832 c_parser_consume_token (parser
);
3833 else if (flag_cilkplus
3834 && c_parser_next_token_is (parser
, CPP_COLON
))
3836 error_at (c_parser_peek_token (parser
)->location
,
3837 "array notations cannot be used in declaration");
3838 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
, NULL
);
3843 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
3848 dimen
= convert_lvalue_to_rvalue (brace_loc
, dimen
, true, true);
3849 declarator
= build_array_declarator (brace_loc
, dimen
.value
, quals_attrs
,
3850 static_seen
, star_seen
);
3851 if (declarator
== NULL
)
3853 inner
= set_array_declarator_inner (declarator
, inner
);
3854 return c_parser_direct_declarator_inner (parser
, id_present
, inner
);
3856 else if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
3859 struct c_arg_info
*args
;
3860 c_parser_consume_token (parser
);
3861 attrs
= c_parser_attributes (parser
);
3862 args
= c_parser_parms_declarator (parser
, id_present
, attrs
);
3867 inner
= build_function_declarator (args
, inner
);
3868 return c_parser_direct_declarator_inner (parser
, id_present
, inner
);
3874 /* Parse a parameter list or identifier list, including the closing
3875 parenthesis but not the opening one. ATTRS are the attributes at
3876 the start of the list. ID_LIST_OK is true if an identifier list is
3877 acceptable; such a list must not have attributes at the start. */
3879 static struct c_arg_info
*
3880 c_parser_parms_declarator (c_parser
*parser
, bool id_list_ok
, tree attrs
)
3883 declare_parm_level ();
3884 /* If the list starts with an identifier, it is an identifier list.
3885 Otherwise, it is either a prototype list or an empty list. */
3888 && c_parser_next_token_is (parser
, CPP_NAME
)
3889 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
3891 /* Look ahead to detect typos in type names. */
3892 && c_parser_peek_2nd_token (parser
)->type
!= CPP_NAME
3893 && c_parser_peek_2nd_token (parser
)->type
!= CPP_MULT
3894 && c_parser_peek_2nd_token (parser
)->type
!= CPP_OPEN_PAREN
3895 && c_parser_peek_2nd_token (parser
)->type
!= CPP_OPEN_SQUARE
3896 && c_parser_peek_2nd_token (parser
)->type
!= CPP_KEYWORD
)
3898 tree list
= NULL_TREE
, *nextp
= &list
;
3899 while (c_parser_next_token_is (parser
, CPP_NAME
)
3900 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
)
3902 *nextp
= build_tree_list (NULL_TREE
,
3903 c_parser_peek_token (parser
)->value
);
3904 nextp
= & TREE_CHAIN (*nextp
);
3905 c_parser_consume_token (parser
);
3906 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
3908 c_parser_consume_token (parser
);
3909 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
3911 c_parser_error (parser
, "expected identifier");
3915 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
3917 struct c_arg_info
*ret
= build_arg_info ();
3919 c_parser_consume_token (parser
);
3925 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
3933 struct c_arg_info
*ret
= c_parser_parms_list_declarator (parser
, attrs
,
3940 /* Parse a parameter list (possibly empty), including the closing
3941 parenthesis but not the opening one. ATTRS are the attributes at
3942 the start of the list. EXPR is NULL or an expression that needs to
3943 be evaluated for the side effects of array size expressions in the
3946 static struct c_arg_info
*
3947 c_parser_parms_list_declarator (c_parser
*parser
, tree attrs
, tree expr
)
3949 bool bad_parm
= false;
3951 /* ??? Following the old parser, forward parameter declarations may
3952 use abstract declarators, and if no real parameter declarations
3953 follow the forward declarations then this is not diagnosed. Also
3954 note as above that attributes are ignored as the only contents of
3955 the parentheses, or as the only contents after forward
3957 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
3959 struct c_arg_info
*ret
= build_arg_info ();
3960 c_parser_consume_token (parser
);
3963 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
3965 struct c_arg_info
*ret
= build_arg_info ();
3967 if (flag_allow_parameterless_variadic_functions
)
3969 /* F (...) is allowed. */
3970 ret
->types
= NULL_TREE
;
3974 /* Suppress -Wold-style-definition for this case. */
3975 ret
->types
= error_mark_node
;
3976 error_at (c_parser_peek_token (parser
)->location
,
3977 "ISO C requires a named argument before %<...%>");
3979 c_parser_consume_token (parser
);
3980 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
3982 c_parser_consume_token (parser
);
3987 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
3992 /* Nonempty list of parameters, either terminated with semicolon
3993 (forward declarations; recurse) or with close parenthesis (normal
3994 function) or with ", ... )" (variadic function). */
3997 /* Parse a parameter. */
3998 struct c_parm
*parm
= c_parser_parameter_declaration (parser
, attrs
);
4003 push_parm_decl (parm
, &expr
);
4004 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
4007 c_parser_consume_token (parser
);
4008 mark_forward_parm_decls ();
4009 new_attrs
= c_parser_attributes (parser
);
4010 return c_parser_parms_list_declarator (parser
, new_attrs
, expr
);
4012 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4014 c_parser_consume_token (parser
);
4018 return get_parm_info (false, expr
);
4020 if (!c_parser_require (parser
, CPP_COMMA
,
4021 "expected %<;%>, %<,%> or %<)%>",
4022 UNKNOWN_LOCATION
, false))
4024 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
4027 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
4029 c_parser_consume_token (parser
);
4030 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4032 c_parser_consume_token (parser
);
4036 return get_parm_info (true, expr
);
4040 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4048 /* Parse a parameter declaration. ATTRS are the attributes at the
4049 start of the declaration if it is the first parameter. */
4051 static struct c_parm
*
4052 c_parser_parameter_declaration (c_parser
*parser
, tree attrs
)
4054 struct c_declspecs
*specs
;
4055 struct c_declarator
*declarator
;
4057 tree postfix_attrs
= NULL_TREE
;
4060 /* Accept #pragmas between parameter declarations. */
4061 while (c_parser_next_token_is (parser
, CPP_PRAGMA
))
4062 c_parser_pragma (parser
, pragma_param
, NULL
);
4064 if (!c_parser_next_token_starts_declspecs (parser
))
4066 c_token
*token
= c_parser_peek_token (parser
);
4069 c_parser_set_source_position_from_token (token
);
4070 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_type
))
4072 name_hint hint
= lookup_name_fuzzy (token
->value
,
4073 FUZZY_LOOKUP_TYPENAME
,
4077 gcc_rich_location
richloc (token
->location
);
4078 richloc
.add_fixit_replace (hint
.suggestion ());
4080 "unknown type name %qE; did you mean %qs?",
4081 token
->value
, hint
.suggestion ());
4084 error_at (token
->location
, "unknown type name %qE", token
->value
);
4085 parser
->error
= true;
4087 /* ??? In some Objective-C cases '...' isn't applicable so there
4088 should be a different message. */
4090 c_parser_error (parser
,
4091 "expected declaration specifiers or %<...%>");
4092 c_parser_skip_to_end_of_parameter (parser
);
4096 location_t start_loc
= c_parser_peek_token (parser
)->location
;
4098 specs
= build_null_declspecs ();
4101 declspecs_add_attrs (input_location
, specs
, attrs
);
4104 c_parser_declspecs (parser
, specs
, true, true, true, true, false,
4105 cla_nonabstract_decl
);
4106 finish_declspecs (specs
);
4107 pending_xref_error ();
4108 prefix_attrs
= specs
->attrs
;
4109 specs
->attrs
= NULL_TREE
;
4110 declarator
= c_parser_declarator (parser
,
4111 specs
->typespec_kind
!= ctsk_none
,
4112 C_DTR_PARM
, &dummy
);
4113 if (declarator
== NULL
)
4115 c_parser_skip_until_found (parser
, CPP_COMMA
, NULL
);
4118 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
4119 postfix_attrs
= c_parser_attributes (parser
);
4121 /* Generate a location for the parameter, ranging from the start of the
4122 initial token to the end of the final token.
4124 If we have a identifier, then use it for the caret location, e.g.
4126 extern int callee (int one, int (*two)(int, int), float three);
4127 ~~~~~~^~~~~~~~~~~~~~
4129 otherwise, reuse the start location for the caret location e.g.:
4131 extern int callee (int one, int (*)(int, int), float three);
4134 location_t end_loc
= parser
->last_token_location
;
4136 /* Find any cdk_id declarator; determine if we have an identifier. */
4137 c_declarator
*id_declarator
= declarator
;
4138 while (id_declarator
&& id_declarator
->kind
!= cdk_id
)
4139 id_declarator
= id_declarator
->declarator
;
4140 location_t caret_loc
= (id_declarator
->u
.id
4141 ? id_declarator
->id_loc
4143 location_t param_loc
= make_location (caret_loc
, start_loc
, end_loc
);
4145 return build_c_parm (specs
, chainon (postfix_attrs
, prefix_attrs
),
4146 declarator
, param_loc
);
4149 /* Parse a string literal in an asm expression. It should not be
4150 translated, and wide string literals are an error although
4151 permitted by the syntax. This is a GNU extension.
4156 ??? At present, following the old parser, the caller needs to have
4157 set lex_untranslated_string to 1. It would be better to follow the
4158 C++ parser rather than using this kludge. */
4161 c_parser_asm_string_literal (c_parser
*parser
)
4164 int save_flag
= warn_overlength_strings
;
4165 warn_overlength_strings
= 0;
4166 if (c_parser_next_token_is (parser
, CPP_STRING
))
4168 str
= c_parser_peek_token (parser
)->value
;
4169 c_parser_consume_token (parser
);
4171 else if (c_parser_next_token_is (parser
, CPP_WSTRING
))
4173 error_at (c_parser_peek_token (parser
)->location
,
4174 "wide string literal in %<asm%>");
4175 str
= build_string (1, "");
4176 c_parser_consume_token (parser
);
4180 c_parser_error (parser
, "expected string literal");
4183 warn_overlength_strings
= save_flag
;
4187 /* Parse a simple asm expression. This is used in restricted
4188 contexts, where a full expression with inputs and outputs does not
4189 make sense. This is a GNU extension.
4192 asm ( asm-string-literal )
4196 c_parser_simple_asm_expr (c_parser
*parser
)
4199 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ASM
));
4200 /* ??? Follow the C++ parser rather than using the
4201 lex_untranslated_string kludge. */
4202 parser
->lex_untranslated_string
= true;
4203 c_parser_consume_token (parser
);
4204 matching_parens parens
;
4205 if (!parens
.require_open (parser
))
4207 parser
->lex_untranslated_string
= false;
4210 str
= c_parser_asm_string_literal (parser
);
4211 parser
->lex_untranslated_string
= false;
4212 if (!parens
.require_close (parser
))
4214 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
4221 c_parser_attribute_any_word (c_parser
*parser
)
4223 tree attr_name
= NULL_TREE
;
4225 if (c_parser_next_token_is (parser
, CPP_KEYWORD
))
4227 /* ??? See comment above about what keywords are accepted here. */
4229 switch (c_parser_peek_token (parser
)->keyword
)
4260 case RID_TRANSACTION_ATOMIC
:
4261 case RID_TRANSACTION_CANCEL
:
4277 /* Accept __attribute__((__const)) as __attribute__((const)) etc. */
4278 attr_name
= ridpointers
[(int) c_parser_peek_token (parser
)->keyword
];
4280 else if (c_parser_next_token_is (parser
, CPP_NAME
))
4281 attr_name
= c_parser_peek_token (parser
)->value
;
4286 #define CILK_SIMD_FN_CLAUSE_MASK \
4287 ((OMP_CLAUSE_MASK_1 << PRAGMA_CILK_CLAUSE_VECTORLENGTH) \
4288 | (OMP_CLAUSE_MASK_1 << PRAGMA_CILK_CLAUSE_LINEAR) \
4289 | (OMP_CLAUSE_MASK_1 << PRAGMA_CILK_CLAUSE_UNIFORM) \
4290 | (OMP_CLAUSE_MASK_1 << PRAGMA_CILK_CLAUSE_MASK) \
4291 | (OMP_CLAUSE_MASK_1 << PRAGMA_CILK_CLAUSE_NOMASK))
4293 /* Parses the vector attribute of SIMD enabled functions in Cilk Plus.
4294 VEC_TOKEN is the "vector" token that is replaced with "simd" and
4295 pushed into the token list.
4298 vector (<vector attributes>). */
4301 c_parser_cilk_simd_fn_vector_attrs (c_parser
*parser
, c_token vec_token
)
4303 gcc_assert (is_cilkplus_vector_p (vec_token
.value
));
4305 int paren_scope
= 0;
4306 vec_safe_push (parser
->cilk_simd_fn_tokens
, vec_token
);
4307 /* Consume the "vector" token. */
4308 c_parser_consume_token (parser
);
4310 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
4312 c_parser_consume_token (parser
);
4315 while (paren_scope
> 0)
4317 c_token
*token
= c_parser_peek_token (parser
);
4318 if (token
->type
== CPP_OPEN_PAREN
)
4320 else if (token
->type
== CPP_CLOSE_PAREN
)
4322 /* Do not push the last ')' since we are not pushing the '('. */
4323 if (!(token
->type
== CPP_CLOSE_PAREN
&& paren_scope
== 0))
4324 vec_safe_push (parser
->cilk_simd_fn_tokens
, *token
);
4325 c_parser_consume_token (parser
);
4328 /* Since we are converting an attribute to a pragma, we need to end the
4329 attribute with PRAGMA_EOL. */
4331 memset (&eol_token
, 0, sizeof (eol_token
));
4332 eol_token
.type
= CPP_PRAGMA_EOL
;
4333 vec_safe_push (parser
->cilk_simd_fn_tokens
, eol_token
);
4336 /* Add 2 CPP_EOF at the end of PARSER->ELEM_FN_TOKENS vector. */
4339 c_finish_cilk_simd_fn_tokens (c_parser
*parser
)
4341 c_token last_token
= parser
->cilk_simd_fn_tokens
->last ();
4343 /* c_parser_attributes is called in several places, so if these EOF
4344 tokens are already inserted, then don't do them again. */
4345 if (last_token
.type
== CPP_EOF
)
4348 /* Two CPP_EOF token are added as a safety net since the normal C
4349 front-end has two token look-ahead. */
4351 eof_token
.type
= CPP_EOF
;
4352 vec_safe_push (parser
->cilk_simd_fn_tokens
, eof_token
);
4353 vec_safe_push (parser
->cilk_simd_fn_tokens
, eof_token
);
4356 /* Parse (possibly empty) attributes. This is a GNU extension.
4360 attributes attribute
4363 __attribute__ ( ( attribute-list ) )
4367 attribute_list , attrib
4372 any-word ( identifier )
4373 any-word ( identifier , nonempty-expr-list )
4374 any-word ( expr-list )
4376 where the "identifier" must not be declared as a type, and
4377 "any-word" may be any identifier (including one declared as a
4378 type), a reserved word storage class specifier, type specifier or
4379 type qualifier. ??? This still leaves out most reserved keywords
4380 (following the old parser), shouldn't we include them, and why not
4381 allow identifiers declared as types to start the arguments? */
4384 c_parser_attributes (c_parser
*parser
)
4386 tree attrs
= NULL_TREE
;
4387 while (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
4389 /* ??? Follow the C++ parser rather than using the
4390 lex_untranslated_string kludge. */
4391 parser
->lex_untranslated_string
= true;
4392 /* Consume the `__attribute__' keyword. */
4393 c_parser_consume_token (parser
);
4394 /* Look for the two `(' tokens. */
4395 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
4397 parser
->lex_untranslated_string
= false;
4400 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
4402 parser
->lex_untranslated_string
= false;
4403 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
4406 /* Parse the attribute list. */
4407 while (c_parser_next_token_is (parser
, CPP_COMMA
)
4408 || c_parser_next_token_is (parser
, CPP_NAME
)
4409 || c_parser_next_token_is (parser
, CPP_KEYWORD
))
4411 tree attr
, attr_name
, attr_args
;
4412 vec
<tree
, va_gc
> *expr_list
;
4413 if (c_parser_next_token_is (parser
, CPP_COMMA
))
4415 c_parser_consume_token (parser
);
4419 attr_name
= c_parser_attribute_any_word (parser
);
4420 if (attr_name
== NULL
)
4422 attr_name
= canonicalize_attr_name (attr_name
);
4423 if (is_cilkplus_vector_p (attr_name
))
4425 c_token
*v_token
= c_parser_peek_token (parser
);
4426 v_token
->value
= canonicalize_attr_name (v_token
->value
);
4427 c_parser_cilk_simd_fn_vector_attrs (parser
, *v_token
);
4428 /* If the next token isn't a comma, we're done. */
4429 if (!c_parser_next_token_is (parser
, CPP_COMMA
))
4433 c_parser_consume_token (parser
);
4434 if (c_parser_next_token_is_not (parser
, CPP_OPEN_PAREN
))
4436 attr
= build_tree_list (attr_name
, NULL_TREE
);
4437 /* Add this attribute to the list. */
4438 attrs
= chainon (attrs
, attr
);
4439 /* If the next token isn't a comma, we're done. */
4440 if (!c_parser_next_token_is (parser
, CPP_COMMA
))
4444 c_parser_consume_token (parser
);
4445 /* Parse the attribute contents. If they start with an
4446 identifier which is followed by a comma or close
4447 parenthesis, then the arguments start with that
4448 identifier; otherwise they are an expression list.
4449 In objective-c the identifier may be a classname. */
4450 if (c_parser_next_token_is (parser
, CPP_NAME
)
4451 && (c_parser_peek_token (parser
)->id_kind
== C_ID_ID
4452 || (c_dialect_objc ()
4453 && c_parser_peek_token (parser
)->id_kind
4455 && ((c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
)
4456 || (c_parser_peek_2nd_token (parser
)->type
4457 == CPP_CLOSE_PAREN
))
4458 && (attribute_takes_identifier_p (attr_name
)
4459 || (c_dialect_objc ()
4460 && c_parser_peek_token (parser
)->id_kind
4461 == C_ID_CLASSNAME
)))
4463 tree arg1
= c_parser_peek_token (parser
)->value
;
4464 c_parser_consume_token (parser
);
4465 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4466 attr_args
= build_tree_list (NULL_TREE
, arg1
);
4470 c_parser_consume_token (parser
);
4471 expr_list
= c_parser_expr_list (parser
, false, true,
4472 NULL
, NULL
, NULL
, NULL
);
4473 tree_list
= build_tree_list_vec (expr_list
);
4474 attr_args
= tree_cons (NULL_TREE
, arg1
, tree_list
);
4475 release_tree_vector (expr_list
);
4480 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4481 attr_args
= NULL_TREE
;
4484 expr_list
= c_parser_expr_list (parser
, false, true,
4485 NULL
, NULL
, NULL
, NULL
);
4486 attr_args
= build_tree_list_vec (expr_list
);
4487 release_tree_vector (expr_list
);
4491 attr
= build_tree_list (attr_name
, attr_args
);
4492 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4493 c_parser_consume_token (parser
);
4496 parser
->lex_untranslated_string
= false;
4497 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4501 /* Add this attribute to the list. */
4502 attrs
= chainon (attrs
, attr
);
4503 /* If the next token isn't a comma, we're done. */
4504 if (!c_parser_next_token_is (parser
, CPP_COMMA
))
4507 /* Look for the two `)' tokens. */
4508 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4509 c_parser_consume_token (parser
);
4512 parser
->lex_untranslated_string
= false;
4513 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4517 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4518 c_parser_consume_token (parser
);
4521 parser
->lex_untranslated_string
= false;
4522 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4526 parser
->lex_untranslated_string
= false;
4529 if (flag_cilkplus
&& !vec_safe_is_empty (parser
->cilk_simd_fn_tokens
))
4530 c_finish_cilk_simd_fn_tokens (parser
);
4534 /* Parse a type name (C90 6.5.5, C99 6.7.6, C11 6.7.7).
4537 specifier-qualifier-list abstract-declarator[opt]
4540 struct c_type_name
*
4541 c_parser_type_name (c_parser
*parser
)
4543 struct c_declspecs
*specs
= build_null_declspecs ();
4544 struct c_declarator
*declarator
;
4545 struct c_type_name
*ret
;
4547 c_parser_declspecs (parser
, specs
, false, true, true, false, false,
4549 if (!specs
->declspecs_seen_p
)
4551 c_parser_error (parser
, "expected specifier-qualifier-list");
4554 if (specs
->type
!= error_mark_node
)
4556 pending_xref_error ();
4557 finish_declspecs (specs
);
4559 declarator
= c_parser_declarator (parser
,
4560 specs
->typespec_kind
!= ctsk_none
,
4561 C_DTR_ABSTRACT
, &dummy
);
4562 if (declarator
== NULL
)
4564 ret
= XOBNEW (&parser_obstack
, struct c_type_name
);
4566 ret
->declarator
= declarator
;
4570 /* Parse an initializer (C90 6.5.7, C99 6.7.8, C11 6.7.9).
4573 assignment-expression
4574 { initializer-list }
4575 { initializer-list , }
4578 designation[opt] initializer
4579 initializer-list , designation[opt] initializer
4586 designator-list designator
4593 [ constant-expression ]
4605 [ constant-expression ... constant-expression ]
4607 Any expression without commas is accepted in the syntax for the
4608 constant-expressions, with non-constant expressions rejected later.
4610 This function is only used for top-level initializers; for nested
4611 ones, see c_parser_initval. */
4613 static struct c_expr
4614 c_parser_initializer (c_parser
*parser
)
4616 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
4617 return c_parser_braced_init (parser
, NULL_TREE
, false, NULL
);
4621 location_t loc
= c_parser_peek_token (parser
)->location
;
4622 ret
= c_parser_expr_no_commas (parser
, NULL
);
4623 if (TREE_CODE (ret
.value
) != STRING_CST
4624 && TREE_CODE (ret
.value
) != COMPOUND_LITERAL_EXPR
)
4625 ret
= convert_lvalue_to_rvalue (loc
, ret
, true, true);
4630 /* The location of the last comma within the current initializer list,
4631 or UNKNOWN_LOCATION if not within one. */
4633 location_t last_init_list_comma
;
4635 /* Parse a braced initializer list. TYPE is the type specified for a
4636 compound literal, and NULL_TREE for other initializers and for
4637 nested braced lists. NESTED_P is true for nested braced lists,
4638 false for the list of a compound literal or the list that is the
4639 top-level initializer in a declaration. */
4641 static struct c_expr
4642 c_parser_braced_init (c_parser
*parser
, tree type
, bool nested_p
,
4643 struct obstack
*outer_obstack
)
4646 struct obstack braced_init_obstack
;
4647 location_t brace_loc
= c_parser_peek_token (parser
)->location
;
4648 gcc_obstack_init (&braced_init_obstack
);
4649 gcc_assert (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
));
4650 matching_braces braces
;
4651 braces
.consume_open (parser
);
4654 finish_implicit_inits (brace_loc
, outer_obstack
);
4655 push_init_level (brace_loc
, 0, &braced_init_obstack
);
4658 really_start_incremental_init (type
);
4659 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
4661 pedwarn (brace_loc
, OPT_Wpedantic
, "ISO C forbids empty initializer braces");
4665 /* Parse a non-empty initializer list, possibly with a trailing
4669 c_parser_initelt (parser
, &braced_init_obstack
);
4672 if (c_parser_next_token_is (parser
, CPP_COMMA
))
4674 last_init_list_comma
= c_parser_peek_token (parser
)->location
;
4675 c_parser_consume_token (parser
);
4679 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
4683 c_token
*next_tok
= c_parser_peek_token (parser
);
4684 if (next_tok
->type
!= CPP_CLOSE_BRACE
)
4686 ret
.value
= error_mark_node
;
4687 ret
.original_code
= ERROR_MARK
;
4688 ret
.original_type
= NULL
;
4689 braces
.skip_until_found_close (parser
);
4690 pop_init_level (brace_loc
, 0, &braced_init_obstack
, last_init_list_comma
);
4691 obstack_free (&braced_init_obstack
, NULL
);
4694 location_t close_loc
= next_tok
->location
;
4695 c_parser_consume_token (parser
);
4696 ret
= pop_init_level (brace_loc
, 0, &braced_init_obstack
, close_loc
);
4697 obstack_free (&braced_init_obstack
, NULL
);
4698 set_c_expr_source_range (&ret
, brace_loc
, close_loc
);
4702 /* Parse a nested initializer, including designators. */
4705 c_parser_initelt (c_parser
*parser
, struct obstack
* braced_init_obstack
)
4707 /* Parse any designator or designator list. A single array
4708 designator may have the subsequent "=" omitted in GNU C, but a
4709 longer list or a structure member designator may not. */
4710 if (c_parser_next_token_is (parser
, CPP_NAME
)
4711 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
4713 /* Old-style structure member designator. */
4714 set_init_label (c_parser_peek_token (parser
)->location
,
4715 c_parser_peek_token (parser
)->value
,
4716 c_parser_peek_token (parser
)->location
,
4717 braced_init_obstack
);
4718 /* Use the colon as the error location. */
4719 pedwarn (c_parser_peek_2nd_token (parser
)->location
, OPT_Wpedantic
,
4720 "obsolete use of designated initializer with %<:%>");
4721 c_parser_consume_token (parser
);
4722 c_parser_consume_token (parser
);
4726 /* des_seen is 0 if there have been no designators, 1 if there
4727 has been a single array designator and 2 otherwise. */
4729 /* Location of a designator. */
4730 location_t des_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
4731 while (c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
)
4732 || c_parser_next_token_is (parser
, CPP_DOT
))
4734 int des_prev
= des_seen
;
4736 des_loc
= c_parser_peek_token (parser
)->location
;
4739 if (c_parser_next_token_is (parser
, CPP_DOT
))
4742 c_parser_consume_token (parser
);
4743 if (c_parser_next_token_is (parser
, CPP_NAME
))
4745 set_init_label (des_loc
, c_parser_peek_token (parser
)->value
,
4746 c_parser_peek_token (parser
)->location
,
4747 braced_init_obstack
);
4748 c_parser_consume_token (parser
);
4753 init
.value
= error_mark_node
;
4754 init
.original_code
= ERROR_MARK
;
4755 init
.original_type
= NULL
;
4756 c_parser_error (parser
, "expected identifier");
4757 c_parser_skip_until_found (parser
, CPP_COMMA
, NULL
);
4758 process_init_element (input_location
, init
, false,
4759 braced_init_obstack
);
4766 location_t ellipsis_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
4767 location_t array_index_loc
= UNKNOWN_LOCATION
;
4768 /* ??? Following the old parser, [ objc-receiver
4769 objc-message-args ] is accepted as an initializer,
4770 being distinguished from a designator by what follows
4771 the first assignment expression inside the square
4772 brackets, but after a first array designator a
4773 subsequent square bracket is for Objective-C taken to
4774 start an expression, using the obsolete form of
4775 designated initializer without '=', rather than
4776 possibly being a second level of designation: in LALR
4777 terms, the '[' is shifted rather than reducing
4778 designator to designator-list. */
4779 if (des_prev
== 1 && c_dialect_objc ())
4781 des_seen
= des_prev
;
4784 if (des_prev
== 0 && c_dialect_objc ())
4786 /* This might be an array designator or an
4787 Objective-C message expression. If the former,
4788 continue parsing here; if the latter, parse the
4789 remainder of the initializer given the starting
4790 primary-expression. ??? It might make sense to
4791 distinguish when des_prev == 1 as well; see
4792 previous comment. */
4794 struct c_expr mexpr
;
4795 c_parser_consume_token (parser
);
4796 if (c_parser_peek_token (parser
)->type
== CPP_NAME
4797 && ((c_parser_peek_token (parser
)->id_kind
4799 || (c_parser_peek_token (parser
)->id_kind
4800 == C_ID_CLASSNAME
)))
4802 /* Type name receiver. */
4803 tree id
= c_parser_peek_token (parser
)->value
;
4804 c_parser_consume_token (parser
);
4805 rec
= objc_get_class_reference (id
);
4806 goto parse_message_args
;
4808 first
= c_parser_expr_no_commas (parser
, NULL
).value
;
4809 mark_exp_read (first
);
4810 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
)
4811 || c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
4812 goto array_desig_after_first
;
4813 /* Expression receiver. So far only one part
4814 without commas has been parsed; there might be
4815 more of the expression. */
4817 while (c_parser_next_token_is (parser
, CPP_COMMA
))
4820 location_t comma_loc
, exp_loc
;
4821 comma_loc
= c_parser_peek_token (parser
)->location
;
4822 c_parser_consume_token (parser
);
4823 exp_loc
= c_parser_peek_token (parser
)->location
;
4824 next
= c_parser_expr_no_commas (parser
, NULL
);
4825 next
= convert_lvalue_to_rvalue (exp_loc
, next
,
4827 rec
= build_compound_expr (comma_loc
, rec
, next
.value
);
4830 /* Now parse the objc-message-args. */
4831 args
= c_parser_objc_message_args (parser
);
4832 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
4835 = objc_build_message_expr (rec
, args
);
4836 mexpr
.original_code
= ERROR_MARK
;
4837 mexpr
.original_type
= NULL
;
4838 /* Now parse and process the remainder of the
4839 initializer, starting with this message
4840 expression as a primary-expression. */
4841 c_parser_initval (parser
, &mexpr
, braced_init_obstack
);
4844 c_parser_consume_token (parser
);
4845 array_index_loc
= c_parser_peek_token (parser
)->location
;
4846 first
= c_parser_expr_no_commas (parser
, NULL
).value
;
4847 mark_exp_read (first
);
4848 array_desig_after_first
:
4849 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
4851 ellipsis_loc
= c_parser_peek_token (parser
)->location
;
4852 c_parser_consume_token (parser
);
4853 second
= c_parser_expr_no_commas (parser
, NULL
).value
;
4854 mark_exp_read (second
);
4858 if (c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
4860 c_parser_consume_token (parser
);
4861 set_init_index (array_index_loc
, first
, second
,
4862 braced_init_obstack
);
4864 pedwarn (ellipsis_loc
, OPT_Wpedantic
,
4865 "ISO C forbids specifying range of elements to initialize");
4868 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
4874 if (c_parser_next_token_is (parser
, CPP_EQ
))
4876 pedwarn_c90 (des_loc
, OPT_Wpedantic
,
4877 "ISO C90 forbids specifying subobject "
4879 c_parser_consume_token (parser
);
4884 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
4885 "obsolete use of designated initializer without %<=%>");
4889 init
.value
= error_mark_node
;
4890 init
.original_code
= ERROR_MARK
;
4891 init
.original_type
= NULL
;
4892 c_parser_error (parser
, "expected %<=%>");
4893 c_parser_skip_until_found (parser
, CPP_COMMA
, NULL
);
4894 process_init_element (input_location
, init
, false,
4895 braced_init_obstack
);
4901 c_parser_initval (parser
, NULL
, braced_init_obstack
);
4904 /* Parse a nested initializer; as c_parser_initializer but parses
4905 initializers within braced lists, after any designators have been
4906 applied. If AFTER is not NULL then it is an Objective-C message
4907 expression which is the primary-expression starting the
4911 c_parser_initval (c_parser
*parser
, struct c_expr
*after
,
4912 struct obstack
* braced_init_obstack
)
4915 gcc_assert (!after
|| c_dialect_objc ());
4916 location_t loc
= c_parser_peek_token (parser
)->location
;
4918 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
) && !after
)
4919 init
= c_parser_braced_init (parser
, NULL_TREE
, true,
4920 braced_init_obstack
);
4923 init
= c_parser_expr_no_commas (parser
, after
);
4924 if (init
.value
!= NULL_TREE
4925 && TREE_CODE (init
.value
) != STRING_CST
4926 && TREE_CODE (init
.value
) != COMPOUND_LITERAL_EXPR
)
4927 init
= convert_lvalue_to_rvalue (loc
, init
, true, true);
4929 process_init_element (loc
, init
, false, braced_init_obstack
);
4932 /* Parse a compound statement (possibly a function body) (C90 6.6.2,
4933 C99 6.8.2, C11 6.8.2).
4936 { block-item-list[opt] }
4937 { label-declarations block-item-list }
4941 block-item-list block-item
4953 { label-declarations block-item-list }
4956 __extension__ nested-declaration
4957 nested-function-definition
4961 label-declarations label-declaration
4964 __label__ identifier-list ;
4966 Allowing the mixing of declarations and code is new in C99. The
4967 GNU syntax also permits (not shown above) labels at the end of
4968 compound statements, which yield an error. We don't allow labels
4969 on declarations; this might seem like a natural extension, but
4970 there would be a conflict between attributes on the label and
4971 prefix attributes on the declaration. ??? The syntax follows the
4972 old parser in requiring something after label declarations.
4973 Although they are erroneous if the labels declared aren't defined,
4974 is it useful for the syntax to be this way?
4995 cancellation-point-directive */
4998 c_parser_compound_statement (c_parser
*parser
)
5001 location_t brace_loc
;
5002 brace_loc
= c_parser_peek_token (parser
)->location
;
5003 if (!c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
5005 /* Ensure a scope is entered and left anyway to avoid confusion
5006 if we have just prepared to enter a function body. */
5007 stmt
= c_begin_compound_stmt (true);
5008 c_end_compound_stmt (brace_loc
, stmt
, true);
5009 return error_mark_node
;
5011 stmt
= c_begin_compound_stmt (true);
5012 c_parser_compound_statement_nostart (parser
);
5014 /* If the compound stmt contains array notations, then we expand them. */
5015 if (flag_cilkplus
&& contains_array_notation_expr (stmt
))
5016 stmt
= expand_array_notation_exprs (stmt
);
5017 return c_end_compound_stmt (brace_loc
, stmt
, true);
5020 /* Parse a compound statement except for the opening brace. This is
5021 used for parsing both compound statements and statement expressions
5022 (which follow different paths to handling the opening). */
5025 c_parser_compound_statement_nostart (c_parser
*parser
)
5027 bool last_stmt
= false;
5028 bool last_label
= false;
5029 bool save_valid_for_pragma
= valid_location_for_stdc_pragma_p ();
5030 location_t label_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
5031 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
5033 c_parser_consume_token (parser
);
5036 mark_valid_location_for_stdc_pragma (true);
5037 if (c_parser_next_token_is_keyword (parser
, RID_LABEL
))
5039 /* Read zero or more forward-declarations for labels that nested
5040 functions can jump to. */
5041 mark_valid_location_for_stdc_pragma (false);
5042 while (c_parser_next_token_is_keyword (parser
, RID_LABEL
))
5044 label_loc
= c_parser_peek_token (parser
)->location
;
5045 c_parser_consume_token (parser
);
5046 /* Any identifiers, including those declared as type names,
5051 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
5053 c_parser_error (parser
, "expected identifier");
5057 = declare_label (c_parser_peek_token (parser
)->value
);
5058 C_DECLARED_LABEL_FLAG (label
) = 1;
5059 add_stmt (build_stmt (label_loc
, DECL_EXPR
, label
));
5060 c_parser_consume_token (parser
);
5061 if (c_parser_next_token_is (parser
, CPP_COMMA
))
5062 c_parser_consume_token (parser
);
5066 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
5068 pedwarn (label_loc
, OPT_Wpedantic
, "ISO C forbids label declarations");
5070 /* We must now have at least one statement, label or declaration. */
5071 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
5073 mark_valid_location_for_stdc_pragma (save_valid_for_pragma
);
5074 c_parser_error (parser
, "expected declaration or statement");
5075 c_parser_consume_token (parser
);
5078 while (c_parser_next_token_is_not (parser
, CPP_CLOSE_BRACE
))
5080 location_t loc
= c_parser_peek_token (parser
)->location
;
5081 if (c_parser_next_token_is_keyword (parser
, RID_CASE
)
5082 || c_parser_next_token_is_keyword (parser
, RID_DEFAULT
)
5083 || (c_parser_next_token_is (parser
, CPP_NAME
)
5084 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
))
5086 if (c_parser_next_token_is_keyword (parser
, RID_CASE
))
5087 label_loc
= c_parser_peek_2nd_token (parser
)->location
;
5089 label_loc
= c_parser_peek_token (parser
)->location
;
5092 mark_valid_location_for_stdc_pragma (false);
5093 c_parser_label (parser
);
5095 else if (!last_label
5096 && c_parser_next_tokens_start_declaration (parser
))
5099 mark_valid_location_for_stdc_pragma (false);
5100 bool fallthru_attr_p
= false;
5101 c_parser_declaration_or_fndef (parser
, true, true, true, true,
5102 true, NULL
, vNULL
, NULL
,
5104 if (last_stmt
&& !fallthru_attr_p
)
5105 pedwarn_c90 (loc
, OPT_Wdeclaration_after_statement
,
5106 "ISO C90 forbids mixed declarations and code");
5107 last_stmt
= fallthru_attr_p
;
5109 else if (!last_label
5110 && c_parser_next_token_is_keyword (parser
, RID_EXTENSION
))
5112 /* __extension__ can start a declaration, but is also an
5113 unary operator that can start an expression. Consume all
5114 but the last of a possible series of __extension__ to
5116 while (c_parser_peek_2nd_token (parser
)->type
== CPP_KEYWORD
5117 && (c_parser_peek_2nd_token (parser
)->keyword
5119 c_parser_consume_token (parser
);
5120 if (c_token_starts_declaration (c_parser_peek_2nd_token (parser
)))
5123 ext
= disable_extension_diagnostics ();
5124 c_parser_consume_token (parser
);
5126 mark_valid_location_for_stdc_pragma (false);
5127 c_parser_declaration_or_fndef (parser
, true, true, true, true,
5129 /* Following the old parser, __extension__ does not
5130 disable this diagnostic. */
5131 restore_extension_diagnostics (ext
);
5133 pedwarn_c90 (loc
, OPT_Wdeclaration_after_statement
,
5134 "ISO C90 forbids mixed declarations and code");
5140 else if (c_parser_next_token_is (parser
, CPP_PRAGMA
))
5142 /* External pragmas, and some omp pragmas, are not associated
5143 with regular c code, and so are not to be considered statements
5144 syntactically. This ensures that the user doesn't put them
5145 places that would turn into syntax errors if the directive
5147 if (c_parser_pragma (parser
,
5148 last_label
? pragma_stmt
: pragma_compound
,
5150 last_label
= false, last_stmt
= true;
5152 else if (c_parser_next_token_is (parser
, CPP_EOF
))
5154 mark_valid_location_for_stdc_pragma (save_valid_for_pragma
);
5155 c_parser_error (parser
, "expected declaration or statement");
5158 else if (c_parser_next_token_is_keyword (parser
, RID_ELSE
))
5160 if (parser
->in_if_block
)
5162 mark_valid_location_for_stdc_pragma (save_valid_for_pragma
);
5163 error_at (loc
, "expected %<}%> before %<else%>");
5168 error_at (loc
, "%<else%> without a previous %<if%>");
5169 c_parser_consume_token (parser
);
5178 mark_valid_location_for_stdc_pragma (false);
5179 c_parser_statement_after_labels (parser
, NULL
);
5182 parser
->error
= false;
5185 error_at (label_loc
, "label at end of compound statement");
5186 c_parser_consume_token (parser
);
5187 /* Restore the value we started with. */
5188 mark_valid_location_for_stdc_pragma (save_valid_for_pragma
);
5191 /* Parse all consecutive labels. */
5194 c_parser_all_labels (c_parser
*parser
)
5196 while (c_parser_next_token_is_keyword (parser
, RID_CASE
)
5197 || c_parser_next_token_is_keyword (parser
, RID_DEFAULT
)
5198 || (c_parser_next_token_is (parser
, CPP_NAME
)
5199 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
))
5200 c_parser_label (parser
);
5203 /* Parse a label (C90 6.6.1, C99 6.8.1, C11 6.8.1).
5206 identifier : attributes[opt]
5207 case constant-expression :
5213 case constant-expression ... constant-expression :
5215 The use of attributes on labels is a GNU extension. The syntax in
5216 GNU C accepts any expressions without commas, non-constant
5217 expressions being rejected later. */
5220 c_parser_label (c_parser
*parser
)
5222 location_t loc1
= c_parser_peek_token (parser
)->location
;
5223 tree label
= NULL_TREE
;
5225 /* Remember whether this case or a user-defined label is allowed to fall
5227 bool fallthrough_p
= c_parser_peek_token (parser
)->flags
& PREV_FALLTHROUGH
;
5229 if (c_parser_next_token_is_keyword (parser
, RID_CASE
))
5232 c_parser_consume_token (parser
);
5233 exp1
= c_parser_expr_no_commas (parser
, NULL
).value
;
5234 if (c_parser_next_token_is (parser
, CPP_COLON
))
5236 c_parser_consume_token (parser
);
5237 label
= do_case (loc1
, exp1
, NULL_TREE
);
5239 else if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
5241 c_parser_consume_token (parser
);
5242 exp2
= c_parser_expr_no_commas (parser
, NULL
).value
;
5243 if (c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
5244 label
= do_case (loc1
, exp1
, exp2
);
5247 c_parser_error (parser
, "expected %<:%> or %<...%>");
5249 else if (c_parser_next_token_is_keyword (parser
, RID_DEFAULT
))
5251 c_parser_consume_token (parser
);
5252 if (c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
5253 label
= do_case (loc1
, NULL_TREE
, NULL_TREE
);
5257 tree name
= c_parser_peek_token (parser
)->value
;
5260 location_t loc2
= c_parser_peek_token (parser
)->location
;
5261 gcc_assert (c_parser_next_token_is (parser
, CPP_NAME
));
5262 c_parser_consume_token (parser
);
5263 gcc_assert (c_parser_next_token_is (parser
, CPP_COLON
));
5264 c_parser_consume_token (parser
);
5265 attrs
= c_parser_attributes (parser
);
5266 tlab
= define_label (loc2
, name
);
5269 decl_attributes (&tlab
, attrs
, 0);
5270 label
= add_stmt (build_stmt (loc1
, LABEL_EXPR
, tlab
));
5275 if (TREE_CODE (label
) == LABEL_EXPR
)
5276 FALLTHROUGH_LABEL_P (LABEL_EXPR_LABEL (label
)) = fallthrough_p
;
5278 FALLTHROUGH_LABEL_P (CASE_LABEL (label
)) = fallthrough_p
;
5280 /* Allow '__attribute__((fallthrough));'. */
5281 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
5283 location_t loc
= c_parser_peek_token (parser
)->location
;
5284 tree attrs
= c_parser_attributes (parser
);
5285 if (attribute_fallthrough_p (attrs
))
5287 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
5289 tree fn
= build_call_expr_internal_loc (loc
,
5295 warning_at (loc
, OPT_Wattributes
, "%<fallthrough%> attribute "
5296 "not followed by %<;%>");
5298 else if (attrs
!= NULL_TREE
)
5299 warning_at (loc
, OPT_Wattributes
, "only attribute %<fallthrough%>"
5300 " can be applied to a null statement");
5302 if (c_parser_next_tokens_start_declaration (parser
))
5304 error_at (c_parser_peek_token (parser
)->location
,
5305 "a label can only be part of a statement and "
5306 "a declaration is not a statement");
5307 c_parser_declaration_or_fndef (parser
, /*fndef_ok*/ false,
5308 /*static_assert_ok*/ true,
5309 /*empty_ok*/ true, /*nested*/ true,
5310 /*start_attr_ok*/ true, NULL
,
5316 /* Parse a statement (C90 6.6, C99 6.8, C11 6.8).
5321 expression-statement
5329 expression-statement:
5332 selection-statement:
5336 iteration-statement:
5345 return expression[opt] ;
5355 expression-statement:
5361 objc-throw-statement
5362 objc-try-catch-statement
5363 objc-synchronized-statement
5365 objc-throw-statement:
5381 parallel-directive structured-block
5384 kernels-directive structured-block
5387 data-directive structured-block
5390 loop-directive structured-block
5404 parallel-for-construct
5405 parallel-for-simd-construct
5406 parallel-sections-construct
5413 parallel-directive structured-block
5416 for-directive iteration-statement
5419 simd-directive iteration-statements
5422 for-simd-directive iteration-statements
5425 sections-directive section-scope
5428 single-directive structured-block
5430 parallel-for-construct:
5431 parallel-for-directive iteration-statement
5433 parallel-for-simd-construct:
5434 parallel-for-simd-directive iteration-statement
5436 parallel-sections-construct:
5437 parallel-sections-directive section-scope
5440 master-directive structured-block
5443 critical-directive structured-block
5446 atomic-directive expression-statement
5449 ordered-directive structured-block
5451 Transactional Memory:
5454 transaction-statement
5455 transaction-cancel-statement
5457 IF_P is used to track whether there's a (possibly labeled) if statement
5458 which is not enclosed in braces and has an else clause. This is used to
5459 implement -Wparentheses. */
5462 c_parser_statement (c_parser
*parser
, bool *if_p
, location_t
*loc_after_labels
)
5464 c_parser_all_labels (parser
);
5465 if (loc_after_labels
)
5466 *loc_after_labels
= c_parser_peek_token (parser
)->location
;
5467 c_parser_statement_after_labels (parser
, if_p
, NULL
);
5470 /* Parse a statement, other than a labeled statement. CHAIN is a vector
5471 of if-else-if conditions.
5473 IF_P is used to track whether there's a (possibly labeled) if statement
5474 which is not enclosed in braces and has an else clause. This is used to
5475 implement -Wparentheses. */
5478 c_parser_statement_after_labels (c_parser
*parser
, bool *if_p
,
5481 location_t loc
= c_parser_peek_token (parser
)->location
;
5482 tree stmt
= NULL_TREE
;
5483 bool in_if_block
= parser
->in_if_block
;
5484 parser
->in_if_block
= false;
5487 switch (c_parser_peek_token (parser
)->type
)
5489 case CPP_OPEN_BRACE
:
5490 add_stmt (c_parser_compound_statement (parser
));
5493 switch (c_parser_peek_token (parser
)->keyword
)
5496 c_parser_if_statement (parser
, if_p
, chain
);
5499 c_parser_switch_statement (parser
, if_p
);
5502 c_parser_while_statement (parser
, false, if_p
);
5505 c_parser_do_statement (parser
, false);
5508 c_parser_for_statement (parser
, false, if_p
);
5513 error_at (c_parser_peek_token (parser
)->location
,
5514 "-fcilkplus must be enabled to use %<_Cilk_for%>");
5515 c_parser_skip_to_end_of_block_or_statement (parser
);
5518 c_parser_cilk_for (parser
, integer_zero_node
, if_p
);
5521 c_parser_consume_token (parser
);
5522 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
5524 error_at (loc
, "-fcilkplus must be enabled to use %<_Cilk_sync%>");
5526 add_stmt (build_cilk_sync ());
5529 c_parser_consume_token (parser
);
5530 if (c_parser_next_token_is (parser
, CPP_NAME
))
5532 stmt
= c_finish_goto_label (loc
,
5533 c_parser_peek_token (parser
)->value
);
5534 c_parser_consume_token (parser
);
5536 else if (c_parser_next_token_is (parser
, CPP_MULT
))
5540 c_parser_consume_token (parser
);
5541 val
= c_parser_expression (parser
);
5542 if (check_no_cilk (val
.value
,
5543 "Cilk array notation cannot be used as a computed goto expression",
5544 "%<_Cilk_spawn%> statement cannot be used as a computed goto expression",
5546 val
.value
= error_mark_node
;
5547 val
= convert_lvalue_to_rvalue (loc
, val
, false, true);
5548 stmt
= c_finish_goto_ptr (loc
, val
.value
);
5551 c_parser_error (parser
, "expected identifier or %<*%>");
5552 goto expect_semicolon
;
5554 c_parser_consume_token (parser
);
5555 stmt
= c_finish_bc_stmt (loc
, &c_cont_label
, false);
5556 goto expect_semicolon
;
5558 c_parser_consume_token (parser
);
5559 stmt
= c_finish_bc_stmt (loc
, &c_break_label
, true);
5560 goto expect_semicolon
;
5562 c_parser_consume_token (parser
);
5563 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
5565 stmt
= c_finish_return (loc
, NULL_TREE
, NULL_TREE
);
5566 c_parser_consume_token (parser
);
5570 location_t xloc
= c_parser_peek_token (parser
)->location
;
5571 struct c_expr expr
= c_parser_expression_conv (parser
);
5572 mark_exp_read (expr
.value
);
5573 stmt
= c_finish_return (EXPR_LOC_OR_LOC (expr
.value
, xloc
),
5574 expr
.value
, expr
.original_type
);
5575 goto expect_semicolon
;
5579 stmt
= c_parser_asm_statement (parser
);
5581 case RID_TRANSACTION_ATOMIC
:
5582 case RID_TRANSACTION_RELAXED
:
5583 stmt
= c_parser_transaction (parser
,
5584 c_parser_peek_token (parser
)->keyword
);
5586 case RID_TRANSACTION_CANCEL
:
5587 stmt
= c_parser_transaction_cancel (parser
);
5588 goto expect_semicolon
;
5590 gcc_assert (c_dialect_objc ());
5591 c_parser_consume_token (parser
);
5592 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
5594 stmt
= objc_build_throw_stmt (loc
, NULL_TREE
);
5595 c_parser_consume_token (parser
);
5599 struct c_expr expr
= c_parser_expression (parser
);
5600 expr
= convert_lvalue_to_rvalue (loc
, expr
, false, false);
5601 if (check_no_cilk (expr
.value
,
5602 "Cilk array notation cannot be used for a throw expression",
5603 "%<_Cilk_spawn%> statement cannot be used for a throw expression"))
5604 expr
.value
= error_mark_node
;
5607 expr
.value
= c_fully_fold (expr
.value
, false, NULL
);
5608 stmt
= objc_build_throw_stmt (loc
, expr
.value
);
5610 goto expect_semicolon
;
5614 gcc_assert (c_dialect_objc ());
5615 c_parser_objc_try_catch_finally_statement (parser
);
5617 case RID_AT_SYNCHRONIZED
:
5618 gcc_assert (c_dialect_objc ());
5619 c_parser_objc_synchronized_statement (parser
);
5623 /* Allow '__attribute__((fallthrough));'. */
5624 tree attrs
= c_parser_attributes (parser
);
5625 if (attribute_fallthrough_p (attrs
))
5627 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
5629 tree fn
= build_call_expr_internal_loc (loc
,
5634 c_parser_consume_token (parser
);
5637 warning_at (loc
, OPT_Wattributes
,
5638 "%<fallthrough%> attribute not followed "
5641 else if (attrs
!= NULL_TREE
)
5642 warning_at (loc
, OPT_Wattributes
, "only attribute %<fallthrough%>"
5643 " can be applied to a null statement");
5651 c_parser_consume_token (parser
);
5653 case CPP_CLOSE_PAREN
:
5654 case CPP_CLOSE_SQUARE
:
5655 /* Avoid infinite loop in error recovery:
5656 c_parser_skip_until_found stops at a closing nesting
5657 delimiter without consuming it, but here we need to consume
5658 it to proceed further. */
5659 c_parser_error (parser
, "expected statement");
5660 c_parser_consume_token (parser
);
5663 c_parser_pragma (parser
, pragma_stmt
, if_p
);
5667 stmt
= c_finish_expr_stmt (loc
, c_parser_expression_conv (parser
).value
);
5669 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
5672 /* Two cases cannot and do not have line numbers associated: If stmt
5673 is degenerate, such as "2;", then stmt is an INTEGER_CST, which
5674 cannot hold line numbers. But that's OK because the statement
5675 will either be changed to a MODIFY_EXPR during gimplification of
5676 the statement expr, or discarded. If stmt was compound, but
5677 without new variables, we will have skipped the creation of a
5678 BIND and will have a bare STATEMENT_LIST. But that's OK because
5679 (recursively) all of the component statements should already have
5680 line numbers assigned. ??? Can we discard no-op statements
5682 if (EXPR_LOCATION (stmt
) == UNKNOWN_LOCATION
)
5683 protected_set_expr_location (stmt
, loc
);
5685 parser
->in_if_block
= in_if_block
;
5688 /* Parse the condition from an if, do, while or for statements. */
5691 c_parser_condition (c_parser
*parser
)
5693 location_t loc
= c_parser_peek_token (parser
)->location
;
5695 cond
= c_parser_expression_conv (parser
).value
;
5696 cond
= c_objc_common_truthvalue_conversion (loc
, cond
);
5697 cond
= c_fully_fold (cond
, false, NULL
);
5698 if (warn_sequence_point
)
5699 verify_sequence_points (cond
);
5703 /* Parse a parenthesized condition from an if, do or while statement.
5709 c_parser_paren_condition (c_parser
*parser
)
5712 matching_parens parens
;
5713 if (!parens
.require_open (parser
))
5714 return error_mark_node
;
5715 cond
= c_parser_condition (parser
);
5716 parens
.skip_until_found_close (parser
);
5720 /* Parse a statement which is a block in C99.
5722 IF_P is used to track whether there's a (possibly labeled) if statement
5723 which is not enclosed in braces and has an else clause. This is used to
5724 implement -Wparentheses. */
5727 c_parser_c99_block_statement (c_parser
*parser
, bool *if_p
,
5728 location_t
*loc_after_labels
)
5730 tree block
= c_begin_compound_stmt (flag_isoc99
);
5731 location_t loc
= c_parser_peek_token (parser
)->location
;
5732 c_parser_statement (parser
, if_p
, loc_after_labels
);
5733 return c_end_compound_stmt (loc
, block
, flag_isoc99
);
5736 /* Parse the body of an if statement. This is just parsing a
5737 statement but (a) it is a block in C99, (b) we track whether the
5738 body is an if statement for the sake of -Wparentheses warnings, (c)
5739 we handle an empty body specially for the sake of -Wempty-body
5740 warnings, and (d) we call parser_compound_statement directly
5741 because c_parser_statement_after_labels resets
5742 parser->in_if_block.
5744 IF_P is used to track whether there's a (possibly labeled) if statement
5745 which is not enclosed in braces and has an else clause. This is used to
5746 implement -Wparentheses. */
5749 c_parser_if_body (c_parser
*parser
, bool *if_p
,
5750 const token_indent_info
&if_tinfo
)
5752 tree block
= c_begin_compound_stmt (flag_isoc99
);
5753 location_t body_loc
= c_parser_peek_token (parser
)->location
;
5754 location_t body_loc_after_labels
= UNKNOWN_LOCATION
;
5755 token_indent_info body_tinfo
5756 = get_token_indent_info (c_parser_peek_token (parser
));
5758 c_parser_all_labels (parser
);
5759 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
5761 location_t loc
= c_parser_peek_token (parser
)->location
;
5762 add_stmt (build_empty_stmt (loc
));
5763 c_parser_consume_token (parser
);
5764 if (!c_parser_next_token_is_keyword (parser
, RID_ELSE
))
5765 warning_at (loc
, OPT_Wempty_body
,
5766 "suggest braces around empty body in an %<if%> statement");
5768 else if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
5769 add_stmt (c_parser_compound_statement (parser
));
5772 body_loc_after_labels
= c_parser_peek_token (parser
)->location
;
5773 c_parser_statement_after_labels (parser
, if_p
);
5776 token_indent_info next_tinfo
5777 = get_token_indent_info (c_parser_peek_token (parser
));
5778 warn_for_misleading_indentation (if_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 if_tinfo
.location
, RID_IF
);
5784 return c_end_compound_stmt (body_loc
, block
, flag_isoc99
);
5787 /* Parse the else body of an if statement. This is just parsing a
5788 statement but (a) it is a block in C99, (b) we handle an empty body
5789 specially for the sake of -Wempty-body warnings. CHAIN is a vector
5790 of if-else-if conditions. */
5793 c_parser_else_body (c_parser
*parser
, const token_indent_info
&else_tinfo
,
5796 location_t body_loc
= c_parser_peek_token (parser
)->location
;
5797 tree block
= c_begin_compound_stmt (flag_isoc99
);
5798 token_indent_info body_tinfo
5799 = get_token_indent_info (c_parser_peek_token (parser
));
5800 location_t body_loc_after_labels
= UNKNOWN_LOCATION
;
5802 c_parser_all_labels (parser
);
5803 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
5805 location_t loc
= c_parser_peek_token (parser
)->location
;
5808 "suggest braces around empty body in an %<else%> statement");
5809 add_stmt (build_empty_stmt (loc
));
5810 c_parser_consume_token (parser
);
5814 if (!c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
5815 body_loc_after_labels
= c_parser_peek_token (parser
)->location
;
5816 c_parser_statement_after_labels (parser
, NULL
, chain
);
5819 token_indent_info next_tinfo
5820 = get_token_indent_info (c_parser_peek_token (parser
));
5821 warn_for_misleading_indentation (else_tinfo
, body_tinfo
, next_tinfo
);
5822 if (body_loc_after_labels
!= UNKNOWN_LOCATION
5823 && next_tinfo
.type
!= CPP_SEMICOLON
)
5824 warn_for_multistatement_macros (body_loc_after_labels
, next_tinfo
.location
,
5825 else_tinfo
.location
, RID_ELSE
);
5827 return c_end_compound_stmt (body_loc
, block
, flag_isoc99
);
5830 /* We might need to reclassify any previously-lexed identifier, e.g.
5831 when we've left a for loop with an if-statement without else in the
5832 body - we might have used a wrong scope for the token. See PR67784. */
5835 c_parser_maybe_reclassify_token (c_parser
*parser
)
5837 if (c_parser_next_token_is (parser
, CPP_NAME
))
5839 c_token
*token
= c_parser_peek_token (parser
);
5841 if (token
->id_kind
!= C_ID_CLASSNAME
)
5843 tree decl
= lookup_name (token
->value
);
5845 token
->id_kind
= C_ID_ID
;
5848 if (TREE_CODE (decl
) == TYPE_DECL
)
5849 token
->id_kind
= C_ID_TYPENAME
;
5851 else if (c_dialect_objc ())
5853 tree objc_interface_decl
= objc_is_class_name (token
->value
);
5854 /* Objective-C class names are in the same namespace as
5855 variables and typedefs, and hence are shadowed by local
5857 if (objc_interface_decl
)
5859 token
->value
= objc_interface_decl
;
5860 token
->id_kind
= C_ID_CLASSNAME
;
5867 /* Parse an if statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
5870 if ( expression ) statement
5871 if ( expression ) statement else statement
5873 CHAIN is a vector of if-else-if conditions.
5874 IF_P is used to track whether there's a (possibly labeled) if statement
5875 which is not enclosed in braces and has an else clause. This is used to
5876 implement -Wparentheses. */
5879 c_parser_if_statement (c_parser
*parser
, bool *if_p
, vec
<tree
> *chain
)
5884 bool nested_if
= false;
5885 tree first_body
, second_body
;
5889 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_IF
));
5890 token_indent_info if_tinfo
5891 = get_token_indent_info (c_parser_peek_token (parser
));
5892 c_parser_consume_token (parser
);
5893 block
= c_begin_compound_stmt (flag_isoc99
);
5894 loc
= c_parser_peek_token (parser
)->location
;
5895 cond
= c_parser_paren_condition (parser
);
5896 if (flag_cilkplus
&& contains_cilk_spawn_stmt (cond
))
5898 error_at (loc
, "if statement cannot contain %<Cilk_spawn%>");
5899 cond
= error_mark_node
;
5901 in_if_block
= parser
->in_if_block
;
5902 parser
->in_if_block
= true;
5903 first_body
= c_parser_if_body (parser
, &nested_if
, if_tinfo
);
5904 parser
->in_if_block
= in_if_block
;
5906 if (warn_duplicated_cond
)
5907 warn_duplicated_cond_add_or_warn (EXPR_LOCATION (cond
), cond
, &chain
);
5909 if (c_parser_next_token_is_keyword (parser
, RID_ELSE
))
5911 token_indent_info else_tinfo
5912 = get_token_indent_info (c_parser_peek_token (parser
));
5913 c_parser_consume_token (parser
);
5914 if (warn_duplicated_cond
)
5916 if (c_parser_next_token_is_keyword (parser
, RID_IF
)
5919 /* We've got "if (COND) else if (COND2)". Start the
5920 condition chain and add COND as the first element. */
5921 chain
= new vec
<tree
> ();
5922 if (!CONSTANT_CLASS_P (cond
) && !TREE_SIDE_EFFECTS (cond
))
5923 chain
->safe_push (cond
);
5925 else if (!c_parser_next_token_is_keyword (parser
, RID_IF
))
5927 /* This is if-else without subsequent if. Zap the condition
5928 chain; we would have already warned at this point. */
5933 second_body
= c_parser_else_body (parser
, else_tinfo
, chain
);
5934 /* Set IF_P to true to indicate that this if statement has an
5935 else clause. This may trigger the Wparentheses warning
5936 below when we get back up to the parent if statement. */
5942 second_body
= NULL_TREE
;
5944 /* Diagnose an ambiguous else if if-then-else is nested inside
5947 warning_at (loc
, OPT_Wdangling_else
,
5948 "suggest explicit braces to avoid ambiguous %<else%>");
5950 if (warn_duplicated_cond
)
5952 /* This if statement does not have an else clause. We don't
5953 need the condition chain anymore. */
5958 c_finish_if_stmt (loc
, cond
, first_body
, second_body
);
5959 if_stmt
= c_end_compound_stmt (loc
, block
, flag_isoc99
);
5961 /* If the if statement contains array notations, then we expand them. */
5962 if (flag_cilkplus
&& contains_array_notation_expr (if_stmt
))
5963 if_stmt
= fix_conditional_array_notations (if_stmt
);
5965 c_parser_maybe_reclassify_token (parser
);
5968 /* Parse a switch statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
5971 switch (expression) statement
5975 c_parser_switch_statement (c_parser
*parser
, bool *if_p
)
5978 tree block
, expr
, body
, save_break
;
5979 location_t switch_loc
= c_parser_peek_token (parser
)->location
;
5980 location_t switch_cond_loc
;
5981 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_SWITCH
));
5982 c_parser_consume_token (parser
);
5983 block
= c_begin_compound_stmt (flag_isoc99
);
5984 bool explicit_cast_p
= false;
5985 matching_parens parens
;
5986 if (parens
.require_open (parser
))
5988 switch_cond_loc
= c_parser_peek_token (parser
)->location
;
5989 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
)
5990 && c_token_starts_typename (c_parser_peek_2nd_token (parser
)))
5991 explicit_cast_p
= true;
5992 ce
= c_parser_expression (parser
);
5993 ce
= convert_lvalue_to_rvalue (switch_cond_loc
, ce
, true, false);
5995 /* ??? expr has no valid location? */
5996 if (check_no_cilk (expr
,
5997 "Cilk array notation cannot be used as a condition for switch statement",
5998 "%<_Cilk_spawn%> statement cannot be used as a condition for switch statement",
6000 expr
= error_mark_node
;
6001 parens
.skip_until_found_close (parser
);
6005 switch_cond_loc
= UNKNOWN_LOCATION
;
6006 expr
= error_mark_node
;
6007 ce
.original_type
= error_mark_node
;
6009 c_start_case (switch_loc
, switch_cond_loc
, expr
, explicit_cast_p
);
6010 save_break
= c_break_label
;
6011 c_break_label
= NULL_TREE
;
6012 location_t loc_after_labels
;
6013 bool open_brace_p
= c_parser_peek_token (parser
)->type
== CPP_OPEN_BRACE
;
6014 body
= c_parser_c99_block_statement (parser
, if_p
, &loc_after_labels
);
6015 location_t next_loc
= c_parser_peek_token (parser
)->location
;
6016 if (!open_brace_p
&& c_parser_peek_token (parser
)->type
!= CPP_SEMICOLON
)
6017 warn_for_multistatement_macros (loc_after_labels
, next_loc
, switch_loc
,
6019 c_finish_case (body
, ce
.original_type
);
6022 location_t here
= c_parser_peek_token (parser
)->location
;
6023 tree t
= build1 (LABEL_EXPR
, void_type_node
, c_break_label
);
6024 SET_EXPR_LOCATION (t
, here
);
6027 c_break_label
= save_break
;
6028 add_stmt (c_end_compound_stmt (switch_loc
, block
, flag_isoc99
));
6029 c_parser_maybe_reclassify_token (parser
);
6032 /* Parse a while statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6035 while (expression) statement
6037 IF_P is used to track whether there's a (possibly labeled) if statement
6038 which is not enclosed in braces and has an else clause. This is used to
6039 implement -Wparentheses. */
6042 c_parser_while_statement (c_parser
*parser
, bool ivdep
, bool *if_p
)
6044 tree block
, cond
, body
, save_break
, save_cont
;
6046 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_WHILE
));
6047 token_indent_info while_tinfo
6048 = get_token_indent_info (c_parser_peek_token (parser
));
6049 c_parser_consume_token (parser
);
6050 block
= c_begin_compound_stmt (flag_isoc99
);
6051 loc
= c_parser_peek_token (parser
)->location
;
6052 cond
= c_parser_paren_condition (parser
);
6053 if (check_no_cilk (cond
,
6054 "Cilk array notation cannot be used as a condition for while statement",
6055 "%<_Cilk_spawn%> statement cannot be used as a condition for while statement"))
6056 cond
= error_mark_node
;
6057 if (ivdep
&& cond
!= error_mark_node
)
6058 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
6059 build_int_cst (integer_type_node
,
6060 annot_expr_ivdep_kind
),
6062 save_break
= c_break_label
;
6063 c_break_label
= NULL_TREE
;
6064 save_cont
= c_cont_label
;
6065 c_cont_label
= NULL_TREE
;
6067 token_indent_info body_tinfo
6068 = get_token_indent_info (c_parser_peek_token (parser
));
6070 location_t loc_after_labels
;
6071 bool open_brace
= c_parser_next_token_is (parser
, CPP_OPEN_BRACE
);
6072 body
= c_parser_c99_block_statement (parser
, if_p
, &loc_after_labels
);
6073 c_finish_loop (loc
, cond
, NULL
, body
, c_break_label
, c_cont_label
, true);
6074 add_stmt (c_end_compound_stmt (loc
, block
, flag_isoc99
));
6075 c_parser_maybe_reclassify_token (parser
);
6077 token_indent_info next_tinfo
6078 = get_token_indent_info (c_parser_peek_token (parser
));
6079 warn_for_misleading_indentation (while_tinfo
, body_tinfo
, next_tinfo
);
6081 if (next_tinfo
.type
!= CPP_SEMICOLON
&& !open_brace
)
6082 warn_for_multistatement_macros (loc_after_labels
, next_tinfo
.location
,
6083 while_tinfo
.location
, RID_WHILE
);
6085 c_break_label
= save_break
;
6086 c_cont_label
= save_cont
;
6089 /* Parse a do statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6092 do statement while ( expression ) ;
6096 c_parser_do_statement (c_parser
*parser
, bool ivdep
)
6098 tree block
, cond
, body
, save_break
, save_cont
, new_break
, new_cont
;
6100 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_DO
));
6101 c_parser_consume_token (parser
);
6102 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6103 warning_at (c_parser_peek_token (parser
)->location
,
6105 "suggest braces around empty body in %<do%> statement");
6106 block
= c_begin_compound_stmt (flag_isoc99
);
6107 loc
= c_parser_peek_token (parser
)->location
;
6108 save_break
= c_break_label
;
6109 c_break_label
= NULL_TREE
;
6110 save_cont
= c_cont_label
;
6111 c_cont_label
= NULL_TREE
;
6112 body
= c_parser_c99_block_statement (parser
, NULL
);
6113 c_parser_require_keyword (parser
, RID_WHILE
, "expected %<while%>");
6114 new_break
= c_break_label
;
6115 c_break_label
= save_break
;
6116 new_cont
= c_cont_label
;
6117 c_cont_label
= save_cont
;
6118 cond
= c_parser_paren_condition (parser
);
6119 if (check_no_cilk (cond
,
6120 "Cilk array notation cannot be used as a condition for a do-while statement",
6121 "%<_Cilk_spawn%> statement cannot be used as a condition for a do-while statement"))
6122 cond
= error_mark_node
;
6123 if (ivdep
&& cond
!= error_mark_node
)
6124 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
6125 build_int_cst (integer_type_node
,
6126 annot_expr_ivdep_kind
),
6128 if (!c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
6129 c_parser_skip_to_end_of_block_or_statement (parser
);
6130 c_finish_loop (loc
, cond
, NULL
, body
, new_break
, new_cont
, false);
6131 add_stmt (c_end_compound_stmt (loc
, block
, flag_isoc99
));
6134 /* Parse a for statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6137 for ( expression[opt] ; expression[opt] ; expression[opt] ) statement
6138 for ( nested-declaration expression[opt] ; expression[opt] ) statement
6140 The form with a declaration is new in C99.
6142 ??? In accordance with the old parser, the declaration may be a
6143 nested function, which is then rejected in check_for_loop_decls,
6144 but does it make any sense for this to be included in the grammar?
6145 Note in particular that the nested function does not include a
6146 trailing ';', whereas the "declaration" production includes one.
6147 Also, can we reject bad declarations earlier and cheaper than
6148 check_for_loop_decls?
6150 In Objective-C, there are two additional variants:
6153 for ( expression in expresssion ) statement
6154 for ( declaration in expression ) statement
6156 This is inconsistent with C, because the second variant is allowed
6157 even if c99 is not enabled.
6159 The rest of the comment documents these Objective-C foreach-statement.
6161 Here is the canonical example of the first variant:
6162 for (object in array) { do something with object }
6163 we call the first expression ("object") the "object_expression" and
6164 the second expression ("array") the "collection_expression".
6165 object_expression must be an lvalue of type "id" (a generic Objective-C
6166 object) because the loop works by assigning to object_expression the
6167 various objects from the collection_expression. collection_expression
6168 must evaluate to something of type "id" which responds to the method
6169 countByEnumeratingWithState:objects:count:.
6171 The canonical example of the second variant is:
6172 for (id object in array) { do something with object }
6173 which is completely equivalent to
6176 for (object in array) { do something with object }
6178 Note that initizializing 'object' in some way (eg, "for ((object =
6179 xxx) in array) { do something with object }") is possibly
6180 technically valid, but completely pointless as 'object' will be
6181 assigned to something else as soon as the loop starts. We should
6182 most likely reject it (TODO).
6184 The beginning of the Objective-C foreach-statement looks exactly
6185 like the beginning of the for-statement, and we can tell it is a
6186 foreach-statement only because the initial declaration or
6187 expression is terminated by 'in' instead of ';'.
6189 IF_P is used to track whether there's a (possibly labeled) if statement
6190 which is not enclosed in braces and has an else clause. This is used to
6191 implement -Wparentheses. */
6194 c_parser_for_statement (c_parser
*parser
, bool ivdep
, bool *if_p
)
6196 tree block
, cond
, incr
, save_break
, save_cont
, body
;
6197 /* The following are only used when parsing an ObjC foreach statement. */
6198 tree object_expression
;
6199 /* Silence the bogus uninitialized warning. */
6200 tree collection_expression
= NULL
;
6201 location_t loc
= c_parser_peek_token (parser
)->location
;
6202 location_t for_loc
= c_parser_peek_token (parser
)->location
;
6203 bool is_foreach_statement
= false;
6204 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_FOR
));
6205 token_indent_info for_tinfo
6206 = get_token_indent_info (c_parser_peek_token (parser
));
6207 c_parser_consume_token (parser
);
6208 /* Open a compound statement in Objective-C as well, just in case this is
6209 as foreach expression. */
6210 block
= c_begin_compound_stmt (flag_isoc99
|| c_dialect_objc ());
6211 cond
= error_mark_node
;
6212 incr
= error_mark_node
;
6213 matching_parens parens
;
6214 if (parens
.require_open (parser
))
6216 /* Parse the initialization declaration or expression. */
6217 object_expression
= error_mark_node
;
6218 parser
->objc_could_be_foreach_context
= c_dialect_objc ();
6219 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6221 parser
->objc_could_be_foreach_context
= false;
6222 c_parser_consume_token (parser
);
6223 c_finish_expr_stmt (loc
, NULL_TREE
);
6225 else if (c_parser_next_tokens_start_declaration (parser
))
6227 c_parser_declaration_or_fndef (parser
, true, true, true, true, true,
6228 &object_expression
, vNULL
);
6229 parser
->objc_could_be_foreach_context
= false;
6231 if (c_parser_next_token_is_keyword (parser
, RID_IN
))
6233 c_parser_consume_token (parser
);
6234 is_foreach_statement
= true;
6235 if (check_for_loop_decls (for_loc
, true) == NULL_TREE
)
6236 c_parser_error (parser
, "multiple iterating variables in fast enumeration");
6239 check_for_loop_decls (for_loc
, flag_isoc99
);
6241 else if (c_parser_next_token_is_keyword (parser
, RID_EXTENSION
))
6243 /* __extension__ can start a declaration, but is also an
6244 unary operator that can start an expression. Consume all
6245 but the last of a possible series of __extension__ to
6247 while (c_parser_peek_2nd_token (parser
)->type
== CPP_KEYWORD
6248 && (c_parser_peek_2nd_token (parser
)->keyword
6250 c_parser_consume_token (parser
);
6251 if (c_token_starts_declaration (c_parser_peek_2nd_token (parser
)))
6254 ext
= disable_extension_diagnostics ();
6255 c_parser_consume_token (parser
);
6256 c_parser_declaration_or_fndef (parser
, true, true, true, true,
6257 true, &object_expression
, vNULL
);
6258 parser
->objc_could_be_foreach_context
= false;
6260 restore_extension_diagnostics (ext
);
6261 if (c_parser_next_token_is_keyword (parser
, RID_IN
))
6263 c_parser_consume_token (parser
);
6264 is_foreach_statement
= true;
6265 if (check_for_loop_decls (for_loc
, true) == NULL_TREE
)
6266 c_parser_error (parser
, "multiple iterating variables in fast enumeration");
6269 check_for_loop_decls (for_loc
, flag_isoc99
);
6279 tree init_expression
;
6280 ce
= c_parser_expression (parser
);
6281 /* In theory we could forbid _Cilk_spawn here, as the spec says "only in top
6282 level statement", but it works just fine, so allow it. */
6283 init_expression
= ce
.value
;
6284 parser
->objc_could_be_foreach_context
= false;
6285 if (c_parser_next_token_is_keyword (parser
, RID_IN
))
6287 c_parser_consume_token (parser
);
6288 is_foreach_statement
= true;
6289 if (! lvalue_p (init_expression
))
6290 c_parser_error (parser
, "invalid iterating variable in fast enumeration");
6291 object_expression
= c_fully_fold (init_expression
, false, NULL
);
6295 ce
= convert_lvalue_to_rvalue (loc
, ce
, true, false);
6296 init_expression
= ce
.value
;
6297 c_finish_expr_stmt (loc
, init_expression
);
6298 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
6302 /* Parse the loop condition. In the case of a foreach
6303 statement, there is no loop condition. */
6304 gcc_assert (!parser
->objc_could_be_foreach_context
);
6305 if (!is_foreach_statement
)
6307 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6311 c_parser_error (parser
, "missing loop condition in loop with "
6312 "%<GCC ivdep%> pragma");
6313 cond
= error_mark_node
;
6317 c_parser_consume_token (parser
);
6323 cond
= c_parser_condition (parser
);
6324 if (check_no_cilk (cond
,
6325 "Cilk array notation cannot be used in a condition for a for-loop",
6326 "%<_Cilk_spawn%> statement cannot be used in a condition for a for-loop"))
6327 cond
= error_mark_node
;
6328 c_parser_skip_until_found (parser
, CPP_SEMICOLON
,
6331 if (ivdep
&& cond
!= error_mark_node
)
6332 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
6333 build_int_cst (integer_type_node
,
6334 annot_expr_ivdep_kind
),
6337 /* Parse the increment expression (the third expression in a
6338 for-statement). In the case of a foreach-statement, this is
6339 the expression that follows the 'in'. */
6340 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
6342 if (is_foreach_statement
)
6344 c_parser_error (parser
, "missing collection in fast enumeration");
6345 collection_expression
= error_mark_node
;
6348 incr
= c_process_expr_stmt (loc
, NULL_TREE
);
6352 if (is_foreach_statement
)
6353 collection_expression
= c_fully_fold (c_parser_expression (parser
).value
,
6357 struct c_expr ce
= c_parser_expression (parser
);
6358 ce
= convert_lvalue_to_rvalue (loc
, ce
, true, false);
6359 incr
= c_process_expr_stmt (loc
, ce
.value
);
6362 parens
.skip_until_found_close (parser
);
6364 save_break
= c_break_label
;
6365 c_break_label
= NULL_TREE
;
6366 save_cont
= c_cont_label
;
6367 c_cont_label
= NULL_TREE
;
6369 token_indent_info body_tinfo
6370 = get_token_indent_info (c_parser_peek_token (parser
));
6372 location_t loc_after_labels
;
6373 bool open_brace
= c_parser_next_token_is (parser
, CPP_OPEN_BRACE
);
6374 body
= c_parser_c99_block_statement (parser
, if_p
, &loc_after_labels
);
6376 if (is_foreach_statement
)
6377 objc_finish_foreach_loop (loc
, object_expression
, collection_expression
, body
, c_break_label
, c_cont_label
);
6379 c_finish_loop (loc
, cond
, incr
, body
, c_break_label
, c_cont_label
, true);
6380 add_stmt (c_end_compound_stmt (loc
, block
, flag_isoc99
|| c_dialect_objc ()));
6381 c_parser_maybe_reclassify_token (parser
);
6383 token_indent_info next_tinfo
6384 = get_token_indent_info (c_parser_peek_token (parser
));
6385 warn_for_misleading_indentation (for_tinfo
, body_tinfo
, next_tinfo
);
6387 if (next_tinfo
.type
!= CPP_SEMICOLON
&& !open_brace
)
6388 warn_for_multistatement_macros (loc_after_labels
, next_tinfo
.location
,
6389 for_tinfo
.location
, RID_FOR
);
6391 c_break_label
= save_break
;
6392 c_cont_label
= save_cont
;
6395 /* Parse an asm statement, a GNU extension. This is a full-blown asm
6396 statement with inputs, outputs, clobbers, and volatile tag
6400 asm type-qualifier[opt] ( asm-argument ) ;
6401 asm type-qualifier[opt] goto ( asm-goto-argument ) ;
6405 asm-string-literal : asm-operands[opt]
6406 asm-string-literal : asm-operands[opt] : asm-operands[opt]
6407 asm-string-literal : asm-operands[opt] : asm-operands[opt] : asm-clobbers[opt]
6410 asm-string-literal : : asm-operands[opt] : asm-clobbers[opt] \
6413 Qualifiers other than volatile are accepted in the syntax but
6417 c_parser_asm_statement (c_parser
*parser
)
6419 tree quals
, str
, outputs
, inputs
, clobbers
, labels
, ret
;
6420 bool simple
, is_goto
;
6421 location_t asm_loc
= c_parser_peek_token (parser
)->location
;
6422 int section
, nsections
;
6424 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ASM
));
6425 c_parser_consume_token (parser
);
6426 if (c_parser_next_token_is_keyword (parser
, RID_VOLATILE
))
6428 quals
= c_parser_peek_token (parser
)->value
;
6429 c_parser_consume_token (parser
);
6431 else if (c_parser_next_token_is_keyword (parser
, RID_CONST
)
6432 || c_parser_next_token_is_keyword (parser
, RID_RESTRICT
))
6434 warning_at (c_parser_peek_token (parser
)->location
,
6436 "%E qualifier ignored on asm",
6437 c_parser_peek_token (parser
)->value
);
6439 c_parser_consume_token (parser
);
6445 if (c_parser_next_token_is_keyword (parser
, RID_GOTO
))
6447 c_parser_consume_token (parser
);
6451 /* ??? Follow the C++ parser rather than using the
6452 lex_untranslated_string kludge. */
6453 parser
->lex_untranslated_string
= true;
6456 matching_parens parens
;
6457 if (!parens
.require_open (parser
))
6460 str
= c_parser_asm_string_literal (parser
);
6461 if (str
== NULL_TREE
)
6462 goto error_close_paren
;
6465 outputs
= NULL_TREE
;
6467 clobbers
= NULL_TREE
;
6470 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
) && !is_goto
)
6473 /* Parse each colon-delimited section of operands. */
6474 nsections
= 3 + is_goto
;
6475 for (section
= 0; section
< nsections
; ++section
)
6477 if (!c_parser_require (parser
, CPP_COLON
,
6479 ? G_("expected %<:%>")
6480 : G_("expected %<:%> or %<)%>"),
6481 UNKNOWN_LOCATION
, is_goto
))
6482 goto error_close_paren
;
6484 /* Once past any colon, we're no longer a simple asm. */
6487 if ((!c_parser_next_token_is (parser
, CPP_COLON
)
6488 && !c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
6493 /* For asm goto, we don't allow output operands, but reserve
6494 the slot for a future extension that does allow them. */
6496 outputs
= c_parser_asm_operands (parser
);
6499 inputs
= c_parser_asm_operands (parser
);
6502 clobbers
= c_parser_asm_clobbers (parser
);
6505 labels
= c_parser_asm_goto_operands (parser
);
6511 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
) && !is_goto
)
6516 if (!parens
.require_close (parser
))
6518 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
6522 if (!c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
6523 c_parser_skip_to_end_of_block_or_statement (parser
);
6525 ret
= build_asm_stmt (quals
, build_asm_expr (asm_loc
, str
, outputs
, inputs
,
6526 clobbers
, labels
, simple
));
6529 parser
->lex_untranslated_string
= false;
6533 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
6537 /* Parse asm operands, a GNU extension.
6541 asm-operands , asm-operand
6544 asm-string-literal ( expression )
6545 [ identifier ] asm-string-literal ( expression )
6549 c_parser_asm_operands (c_parser
*parser
)
6551 tree list
= NULL_TREE
;
6556 if (c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
))
6558 c_parser_consume_token (parser
);
6559 if (c_parser_next_token_is (parser
, CPP_NAME
))
6561 tree id
= c_parser_peek_token (parser
)->value
;
6562 c_parser_consume_token (parser
);
6563 name
= build_string (IDENTIFIER_LENGTH (id
),
6564 IDENTIFIER_POINTER (id
));
6568 c_parser_error (parser
, "expected identifier");
6569 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
, NULL
);
6572 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
6577 str
= c_parser_asm_string_literal (parser
);
6578 if (str
== NULL_TREE
)
6580 parser
->lex_untranslated_string
= false;
6581 matching_parens parens
;
6582 if (!parens
.require_open (parser
))
6584 parser
->lex_untranslated_string
= true;
6587 expr
= c_parser_expression (parser
);
6588 mark_exp_read (expr
.value
);
6589 parser
->lex_untranslated_string
= true;
6590 if (!parens
.require_close (parser
))
6592 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
6595 list
= chainon (list
, build_tree_list (build_tree_list (name
, str
),
6597 if (c_parser_next_token_is (parser
, CPP_COMMA
))
6598 c_parser_consume_token (parser
);
6605 /* Parse asm clobbers, a GNU extension.
6609 asm-clobbers , asm-string-literal
6613 c_parser_asm_clobbers (c_parser
*parser
)
6615 tree list
= NULL_TREE
;
6618 tree str
= c_parser_asm_string_literal (parser
);
6620 list
= tree_cons (NULL_TREE
, str
, list
);
6623 if (c_parser_next_token_is (parser
, CPP_COMMA
))
6624 c_parser_consume_token (parser
);
6631 /* Parse asm goto labels, a GNU extension.
6635 asm-goto-operands , identifier
6639 c_parser_asm_goto_operands (c_parser
*parser
)
6641 tree list
= NULL_TREE
;
6646 if (c_parser_next_token_is (parser
, CPP_NAME
))
6648 c_token
*tok
= c_parser_peek_token (parser
);
6650 label
= lookup_label_for_goto (tok
->location
, name
);
6651 c_parser_consume_token (parser
);
6652 TREE_USED (label
) = 1;
6656 c_parser_error (parser
, "expected identifier");
6660 name
= build_string (IDENTIFIER_LENGTH (name
),
6661 IDENTIFIER_POINTER (name
));
6662 list
= tree_cons (name
, label
, list
);
6663 if (c_parser_next_token_is (parser
, CPP_COMMA
))
6664 c_parser_consume_token (parser
);
6666 return nreverse (list
);
6670 /* Parse an expression other than a compound expression; that is, an
6671 assignment expression (C90 6.3.16, C99 6.5.16, C11 6.5.16). If
6672 AFTER is not NULL then it is an Objective-C message expression which
6673 is the primary-expression starting the expression as an initializer.
6675 assignment-expression:
6676 conditional-expression
6677 unary-expression assignment-operator assignment-expression
6679 assignment-operator: one of
6680 = *= /= %= += -= <<= >>= &= ^= |=
6682 In GNU C we accept any conditional expression on the LHS and
6683 diagnose the invalid lvalue rather than producing a syntax
6686 static struct c_expr
6687 c_parser_expr_no_commas (c_parser
*parser
, struct c_expr
*after
,
6688 tree omp_atomic_lhs
)
6690 struct c_expr lhs
, rhs
, ret
;
6691 enum tree_code code
;
6692 location_t op_location
, exp_location
;
6693 gcc_assert (!after
|| c_dialect_objc ());
6694 lhs
= c_parser_conditional_expression (parser
, after
, omp_atomic_lhs
);
6695 op_location
= c_parser_peek_token (parser
)->location
;
6696 switch (c_parser_peek_token (parser
)->type
)
6705 code
= TRUNC_DIV_EXPR
;
6708 code
= TRUNC_MOD_EXPR
;
6723 code
= BIT_AND_EXPR
;
6726 code
= BIT_XOR_EXPR
;
6729 code
= BIT_IOR_EXPR
;
6734 c_parser_consume_token (parser
);
6735 exp_location
= c_parser_peek_token (parser
)->location
;
6736 rhs
= c_parser_expr_no_commas (parser
, NULL
);
6737 rhs
= convert_lvalue_to_rvalue (exp_location
, rhs
, true, true);
6739 ret
.value
= build_modify_expr (op_location
, lhs
.value
, lhs
.original_type
,
6740 code
, exp_location
, rhs
.value
,
6742 set_c_expr_source_range (&ret
, lhs
.get_start (), rhs
.get_finish ());
6743 if (code
== NOP_EXPR
)
6744 ret
.original_code
= MODIFY_EXPR
;
6747 TREE_NO_WARNING (ret
.value
) = 1;
6748 ret
.original_code
= ERROR_MARK
;
6750 ret
.original_type
= NULL
;
6754 /* Parse a conditional expression (C90 6.3.15, C99 6.5.15, C11 6.5.15). If
6755 AFTER is not NULL then it is an Objective-C message expression which is
6756 the primary-expression starting the expression as an initializer.
6758 conditional-expression:
6759 logical-OR-expression
6760 logical-OR-expression ? expression : conditional-expression
6764 conditional-expression:
6765 logical-OR-expression ? : conditional-expression
6768 static struct c_expr
6769 c_parser_conditional_expression (c_parser
*parser
, struct c_expr
*after
,
6770 tree omp_atomic_lhs
)
6772 struct c_expr cond
, exp1
, exp2
, ret
;
6773 location_t start
, cond_loc
, colon_loc
;
6775 gcc_assert (!after
|| c_dialect_objc ());
6777 cond
= c_parser_binary_expression (parser
, after
, omp_atomic_lhs
);
6779 if (c_parser_next_token_is_not (parser
, CPP_QUERY
))
6781 if (cond
.value
!= error_mark_node
)
6782 start
= cond
.get_start ();
6784 start
= UNKNOWN_LOCATION
;
6785 cond_loc
= c_parser_peek_token (parser
)->location
;
6786 cond
= convert_lvalue_to_rvalue (cond_loc
, cond
, true, true);
6787 c_parser_consume_token (parser
);
6788 if (c_parser_next_token_is (parser
, CPP_COLON
))
6790 tree eptype
= NULL_TREE
;
6792 location_t middle_loc
= c_parser_peek_token (parser
)->location
;
6793 pedwarn (middle_loc
, OPT_Wpedantic
,
6794 "ISO C forbids omitting the middle term of a ?: expression");
6795 if (TREE_CODE (cond
.value
) == EXCESS_PRECISION_EXPR
)
6797 eptype
= TREE_TYPE (cond
.value
);
6798 cond
.value
= TREE_OPERAND (cond
.value
, 0);
6800 tree e
= cond
.value
;
6801 while (TREE_CODE (e
) == COMPOUND_EXPR
)
6802 e
= TREE_OPERAND (e
, 1);
6803 warn_for_omitted_condop (middle_loc
, e
);
6804 /* Make sure first operand is calculated only once. */
6805 exp1
.value
= save_expr (default_conversion (cond
.value
));
6807 exp1
.value
= build1 (EXCESS_PRECISION_EXPR
, eptype
, exp1
.value
);
6808 exp1
.original_type
= NULL
;
6809 exp1
.src_range
= cond
.src_range
;
6810 cond
.value
= c_objc_common_truthvalue_conversion (cond_loc
, exp1
.value
);
6811 c_inhibit_evaluation_warnings
+= cond
.value
== truthvalue_true_node
;
6816 = c_objc_common_truthvalue_conversion
6817 (cond_loc
, default_conversion (cond
.value
));
6818 c_inhibit_evaluation_warnings
+= cond
.value
== truthvalue_false_node
;
6819 exp1
= c_parser_expression_conv (parser
);
6820 mark_exp_read (exp1
.value
);
6821 c_inhibit_evaluation_warnings
+=
6822 ((cond
.value
== truthvalue_true_node
)
6823 - (cond
.value
== truthvalue_false_node
));
6826 colon_loc
= c_parser_peek_token (parser
)->location
;
6827 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
6829 c_inhibit_evaluation_warnings
-= cond
.value
== truthvalue_true_node
;
6830 ret
.value
= error_mark_node
;
6831 ret
.original_code
= ERROR_MARK
;
6832 ret
.original_type
= NULL
;
6836 location_t exp2_loc
= c_parser_peek_token (parser
)->location
;
6837 exp2
= c_parser_conditional_expression (parser
, NULL
, NULL_TREE
);
6838 exp2
= convert_lvalue_to_rvalue (exp2_loc
, exp2
, true, true);
6840 c_inhibit_evaluation_warnings
-= cond
.value
== truthvalue_true_node
;
6841 location_t loc1
= make_location (exp1
.get_start (), exp1
.src_range
);
6842 location_t loc2
= make_location (exp2
.get_start (), exp2
.src_range
);
6843 ret
.value
= build_conditional_expr (colon_loc
, cond
.value
,
6844 cond
.original_code
== C_MAYBE_CONST_EXPR
,
6845 exp1
.value
, exp1
.original_type
, loc1
,
6846 exp2
.value
, exp2
.original_type
, loc2
);
6847 ret
.original_code
= ERROR_MARK
;
6848 if (exp1
.value
== error_mark_node
|| exp2
.value
== error_mark_node
)
6849 ret
.original_type
= NULL
;
6854 /* If both sides are enum type, the default conversion will have
6855 made the type of the result be an integer type. We want to
6856 remember the enum types we started with. */
6857 t1
= exp1
.original_type
? exp1
.original_type
: TREE_TYPE (exp1
.value
);
6858 t2
= exp2
.original_type
? exp2
.original_type
: TREE_TYPE (exp2
.value
);
6859 ret
.original_type
= ((t1
!= error_mark_node
6860 && t2
!= error_mark_node
6861 && (TYPE_MAIN_VARIANT (t1
)
6862 == TYPE_MAIN_VARIANT (t2
)))
6866 set_c_expr_source_range (&ret
, start
, exp2
.get_finish ());
6870 /* Parse a binary expression; that is, a logical-OR-expression (C90
6871 6.3.5-6.3.14, C99 6.5.5-6.5.14, C11 6.5.5-6.5.14). If AFTER is not
6872 NULL then it is an Objective-C message expression which is the
6873 primary-expression starting the expression as an initializer.
6875 OMP_ATOMIC_LHS is NULL, unless parsing OpenMP #pragma omp atomic,
6876 when it should be the unfolded lhs. In a valid OpenMP source,
6877 one of the operands of the toplevel binary expression must be equal
6878 to it. In that case, just return a build2 created binary operation
6879 rather than result of parser_build_binary_op.
6881 multiplicative-expression:
6883 multiplicative-expression * cast-expression
6884 multiplicative-expression / cast-expression
6885 multiplicative-expression % cast-expression
6887 additive-expression:
6888 multiplicative-expression
6889 additive-expression + multiplicative-expression
6890 additive-expression - multiplicative-expression
6894 shift-expression << additive-expression
6895 shift-expression >> additive-expression
6897 relational-expression:
6899 relational-expression < shift-expression
6900 relational-expression > shift-expression
6901 relational-expression <= shift-expression
6902 relational-expression >= shift-expression
6904 equality-expression:
6905 relational-expression
6906 equality-expression == relational-expression
6907 equality-expression != relational-expression
6911 AND-expression & equality-expression
6913 exclusive-OR-expression:
6915 exclusive-OR-expression ^ AND-expression
6917 inclusive-OR-expression:
6918 exclusive-OR-expression
6919 inclusive-OR-expression | exclusive-OR-expression
6921 logical-AND-expression:
6922 inclusive-OR-expression
6923 logical-AND-expression && inclusive-OR-expression
6925 logical-OR-expression:
6926 logical-AND-expression
6927 logical-OR-expression || logical-AND-expression
6930 static struct c_expr
6931 c_parser_binary_expression (c_parser
*parser
, struct c_expr
*after
,
6932 tree omp_atomic_lhs
)
6934 /* A binary expression is parsed using operator-precedence parsing,
6935 with the operands being cast expressions. All the binary
6936 operators are left-associative. Thus a binary expression is of
6939 E0 op1 E1 op2 E2 ...
6941 which we represent on a stack. On the stack, the precedence
6942 levels are strictly increasing. When a new operator is
6943 encountered of higher precedence than that at the top of the
6944 stack, it is pushed; its LHS is the top expression, and its RHS
6945 is everything parsed until it is popped. When a new operator is
6946 encountered with precedence less than or equal to that at the top
6947 of the stack, triples E[i-1] op[i] E[i] are popped and replaced
6948 by the result of the operation until the operator at the top of
6949 the stack has lower precedence than the new operator or there is
6950 only one element on the stack; then the top expression is the LHS
6951 of the new operator. In the case of logical AND and OR
6952 expressions, we also need to adjust c_inhibit_evaluation_warnings
6953 as appropriate when the operators are pushed and popped. */
6956 /* The expression at this stack level. */
6958 /* The precedence of the operator on its left, PREC_NONE at the
6959 bottom of the stack. */
6960 enum c_parser_prec prec
;
6961 /* The operation on its left. */
6963 /* The source location of this operation. */
6965 /* The sizeof argument if expr.original_code == SIZEOF_EXPR. */
6969 /* Location of the binary operator. */
6970 location_t binary_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
6973 switch (stack[sp].op) \
6975 case TRUTH_ANDIF_EXPR: \
6976 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
6977 == truthvalue_false_node); \
6979 case TRUTH_ORIF_EXPR: \
6980 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
6981 == truthvalue_true_node); \
6983 case TRUNC_DIV_EXPR: \
6984 if (stack[sp - 1].expr.original_code == SIZEOF_EXPR \
6985 && stack[sp].expr.original_code == SIZEOF_EXPR) \
6987 tree type0 = stack[sp - 1].sizeof_arg; \
6988 tree type1 = stack[sp].sizeof_arg; \
6989 tree first_arg = type0; \
6990 if (!TYPE_P (type0)) \
6991 type0 = TREE_TYPE (type0); \
6992 if (!TYPE_P (type1)) \
6993 type1 = TREE_TYPE (type1); \
6994 if (POINTER_TYPE_P (type0) \
6995 && comptypes (TREE_TYPE (type0), type1) \
6996 && !(TREE_CODE (first_arg) == PARM_DECL \
6997 && C_ARRAY_PARAMETER (first_arg) \
6998 && warn_sizeof_array_argument)) \
6999 if (warning_at (stack[sp].loc, OPT_Wsizeof_pointer_div, \
7000 "division %<sizeof (%T) / sizeof (%T)%> does " \
7001 "not compute the number of array elements", \
7003 if (DECL_P (first_arg)) \
7004 inform (DECL_SOURCE_LOCATION (first_arg), \
7005 "first %<sizeof%> operand was declared here"); \
7011 stack[sp - 1].expr \
7012 = convert_lvalue_to_rvalue (stack[sp - 1].loc, \
7013 stack[sp - 1].expr, true, true); \
7015 = convert_lvalue_to_rvalue (stack[sp].loc, \
7016 stack[sp].expr, true, true); \
7017 if (__builtin_expect (omp_atomic_lhs != NULL_TREE, 0) && sp == 1 \
7018 && c_parser_peek_token (parser)->type == CPP_SEMICOLON \
7019 && ((1 << stack[sp].prec) \
7020 & ((1 << PREC_BITOR) | (1 << PREC_BITXOR) | (1 << PREC_BITAND) \
7021 | (1 << PREC_SHIFT) | (1 << PREC_ADD) | (1 << PREC_MULT))) \
7022 && stack[sp].op != TRUNC_MOD_EXPR \
7023 && stack[0].expr.value != error_mark_node \
7024 && stack[1].expr.value != error_mark_node \
7025 && (c_tree_equal (stack[0].expr.value, omp_atomic_lhs) \
7026 || c_tree_equal (stack[1].expr.value, omp_atomic_lhs))) \
7027 stack[0].expr.value \
7028 = build2 (stack[1].op, TREE_TYPE (stack[0].expr.value), \
7029 stack[0].expr.value, stack[1].expr.value); \
7031 stack[sp - 1].expr = parser_build_binary_op (stack[sp].loc, \
7033 stack[sp - 1].expr, \
7037 gcc_assert (!after
|| c_dialect_objc ());
7038 stack
[0].loc
= c_parser_peek_token (parser
)->location
;
7039 stack
[0].expr
= c_parser_cast_expression (parser
, after
);
7040 stack
[0].prec
= PREC_NONE
;
7041 stack
[0].sizeof_arg
= c_last_sizeof_arg
;
7045 enum c_parser_prec oprec
;
7046 enum tree_code ocode
;
7047 source_range src_range
;
7050 switch (c_parser_peek_token (parser
)->type
)
7058 ocode
= TRUNC_DIV_EXPR
;
7062 ocode
= TRUNC_MOD_EXPR
;
7074 ocode
= LSHIFT_EXPR
;
7078 ocode
= RSHIFT_EXPR
;
7092 case CPP_GREATER_EQ
:
7105 oprec
= PREC_BITAND
;
7106 ocode
= BIT_AND_EXPR
;
7109 oprec
= PREC_BITXOR
;
7110 ocode
= BIT_XOR_EXPR
;
7114 ocode
= BIT_IOR_EXPR
;
7117 oprec
= PREC_LOGAND
;
7118 ocode
= TRUTH_ANDIF_EXPR
;
7122 ocode
= TRUTH_ORIF_EXPR
;
7125 /* Not a binary operator, so end of the binary
7129 binary_loc
= c_parser_peek_token (parser
)->location
;
7130 while (oprec
<= stack
[sp
].prec
)
7132 c_parser_consume_token (parser
);
7135 case TRUTH_ANDIF_EXPR
:
7136 src_range
= stack
[sp
].expr
.src_range
;
7138 = convert_lvalue_to_rvalue (stack
[sp
].loc
,
7139 stack
[sp
].expr
, true, true);
7140 stack
[sp
].expr
.value
= c_objc_common_truthvalue_conversion
7141 (stack
[sp
].loc
, default_conversion (stack
[sp
].expr
.value
));
7142 c_inhibit_evaluation_warnings
+= (stack
[sp
].expr
.value
7143 == truthvalue_false_node
);
7144 set_c_expr_source_range (&stack
[sp
].expr
, src_range
);
7146 case TRUTH_ORIF_EXPR
:
7147 src_range
= stack
[sp
].expr
.src_range
;
7149 = convert_lvalue_to_rvalue (stack
[sp
].loc
,
7150 stack
[sp
].expr
, true, true);
7151 stack
[sp
].expr
.value
= c_objc_common_truthvalue_conversion
7152 (stack
[sp
].loc
, default_conversion (stack
[sp
].expr
.value
));
7153 c_inhibit_evaluation_warnings
+= (stack
[sp
].expr
.value
7154 == truthvalue_true_node
);
7155 set_c_expr_source_range (&stack
[sp
].expr
, src_range
);
7161 stack
[sp
].loc
= binary_loc
;
7162 stack
[sp
].expr
= c_parser_cast_expression (parser
, NULL
);
7163 stack
[sp
].prec
= oprec
;
7164 stack
[sp
].op
= ocode
;
7165 stack
[sp
].sizeof_arg
= c_last_sizeof_arg
;
7170 return stack
[0].expr
;
7174 /* Parse a cast expression (C90 6.3.4, C99 6.5.4, C11 6.5.4). If AFTER
7175 is not NULL then it is an Objective-C message expression which is the
7176 primary-expression starting the expression as an initializer.
7180 ( type-name ) unary-expression
7183 static struct c_expr
7184 c_parser_cast_expression (c_parser
*parser
, struct c_expr
*after
)
7186 location_t cast_loc
= c_parser_peek_token (parser
)->location
;
7187 gcc_assert (!after
|| c_dialect_objc ());
7189 return c_parser_postfix_expression_after_primary (parser
,
7191 /* If the expression begins with a parenthesized type name, it may
7192 be either a cast or a compound literal; we need to see whether
7193 the next character is '{' to tell the difference. If not, it is
7194 an unary expression. Full detection of unknown typenames here
7195 would require a 3-token lookahead. */
7196 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
)
7197 && c_token_starts_typename (c_parser_peek_2nd_token (parser
)))
7199 struct c_type_name
*type_name
;
7202 matching_parens parens
;
7203 parens
.consume_open (parser
);
7204 type_name
= c_parser_type_name (parser
);
7205 parens
.skip_until_found_close (parser
);
7206 if (type_name
== NULL
)
7208 ret
.value
= error_mark_node
;
7209 ret
.original_code
= ERROR_MARK
;
7210 ret
.original_type
= NULL
;
7214 /* Save casted types in the function's used types hash table. */
7215 used_types_insert (type_name
->specs
->type
);
7217 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
7218 return c_parser_postfix_expression_after_paren_type (parser
, type_name
,
7221 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
7222 expr
= c_parser_cast_expression (parser
, NULL
);
7223 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, true, true);
7225 ret
.value
= c_cast_expr (cast_loc
, type_name
, expr
.value
);
7226 if (ret
.value
&& expr
.value
)
7227 set_c_expr_source_range (&ret
, cast_loc
, expr
.get_finish ());
7228 ret
.original_code
= ERROR_MARK
;
7229 ret
.original_type
= NULL
;
7233 return c_parser_unary_expression (parser
);
7236 /* Parse an unary expression (C90 6.3.3, C99 6.5.3, C11 6.5.3).
7242 unary-operator cast-expression
7243 sizeof unary-expression
7244 sizeof ( type-name )
7246 unary-operator: one of
7252 __alignof__ unary-expression
7253 __alignof__ ( type-name )
7256 (C11 permits _Alignof with type names only.)
7258 unary-operator: one of
7259 __extension__ __real__ __imag__
7261 Transactional Memory:
7264 transaction-expression
7266 In addition, the GNU syntax treats ++ and -- as unary operators, so
7267 they may be applied to cast expressions with errors for non-lvalues
7270 static struct c_expr
7271 c_parser_unary_expression (c_parser
*parser
)
7274 struct c_expr ret
, op
;
7275 location_t op_loc
= c_parser_peek_token (parser
)->location
;
7278 ret
.original_code
= ERROR_MARK
;
7279 ret
.original_type
= NULL
;
7280 switch (c_parser_peek_token (parser
)->type
)
7283 c_parser_consume_token (parser
);
7284 exp_loc
= c_parser_peek_token (parser
)->location
;
7285 op
= c_parser_cast_expression (parser
, NULL
);
7287 /* If there is array notations in op, we expand them. */
7288 if (flag_cilkplus
&& TREE_CODE (op
.value
) == ARRAY_NOTATION_REF
)
7289 return fix_array_notation_expr (exp_loc
, PREINCREMENT_EXPR
, op
);
7292 op
= default_function_array_read_conversion (exp_loc
, op
);
7293 return parser_build_unary_op (op_loc
, PREINCREMENT_EXPR
, op
);
7295 case CPP_MINUS_MINUS
:
7296 c_parser_consume_token (parser
);
7297 exp_loc
= c_parser_peek_token (parser
)->location
;
7298 op
= c_parser_cast_expression (parser
, NULL
);
7300 /* If there is array notations in op, we expand them. */
7301 if (flag_cilkplus
&& TREE_CODE (op
.value
) == ARRAY_NOTATION_REF
)
7302 return fix_array_notation_expr (exp_loc
, PREDECREMENT_EXPR
, op
);
7305 op
= default_function_array_read_conversion (exp_loc
, op
);
7306 return parser_build_unary_op (op_loc
, PREDECREMENT_EXPR
, op
);
7309 c_parser_consume_token (parser
);
7310 op
= c_parser_cast_expression (parser
, NULL
);
7311 mark_exp_read (op
.value
);
7312 return parser_build_unary_op (op_loc
, ADDR_EXPR
, op
);
7315 c_parser_consume_token (parser
);
7316 exp_loc
= c_parser_peek_token (parser
)->location
;
7317 op
= c_parser_cast_expression (parser
, NULL
);
7318 finish
= op
.get_finish ();
7319 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
7320 location_t combined_loc
= make_location (op_loc
, op_loc
, finish
);
7321 ret
.value
= build_indirect_ref (combined_loc
, op
.value
, RO_UNARY_STAR
);
7322 ret
.src_range
.m_start
= op_loc
;
7323 ret
.src_range
.m_finish
= finish
;
7327 if (!c_dialect_objc () && !in_system_header_at (input_location
))
7330 "traditional C rejects the unary plus operator");
7331 c_parser_consume_token (parser
);
7332 exp_loc
= c_parser_peek_token (parser
)->location
;
7333 op
= c_parser_cast_expression (parser
, NULL
);
7334 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
7335 return parser_build_unary_op (op_loc
, CONVERT_EXPR
, op
);
7337 c_parser_consume_token (parser
);
7338 exp_loc
= c_parser_peek_token (parser
)->location
;
7339 op
= c_parser_cast_expression (parser
, NULL
);
7340 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
7341 return parser_build_unary_op (op_loc
, NEGATE_EXPR
, op
);
7343 c_parser_consume_token (parser
);
7344 exp_loc
= c_parser_peek_token (parser
)->location
;
7345 op
= c_parser_cast_expression (parser
, NULL
);
7346 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
7347 return parser_build_unary_op (op_loc
, BIT_NOT_EXPR
, op
);
7349 c_parser_consume_token (parser
);
7350 exp_loc
= c_parser_peek_token (parser
)->location
;
7351 op
= c_parser_cast_expression (parser
, NULL
);
7352 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
7353 return parser_build_unary_op (op_loc
, TRUTH_NOT_EXPR
, op
);
7355 /* Refer to the address of a label as a pointer. */
7356 c_parser_consume_token (parser
);
7357 if (c_parser_next_token_is (parser
, CPP_NAME
))
7359 ret
.value
= finish_label_address_expr
7360 (c_parser_peek_token (parser
)->value
, op_loc
);
7361 set_c_expr_source_range (&ret
, op_loc
,
7362 c_parser_peek_token (parser
)->get_finish ());
7363 c_parser_consume_token (parser
);
7367 c_parser_error (parser
, "expected identifier");
7372 switch (c_parser_peek_token (parser
)->keyword
)
7375 return c_parser_sizeof_expression (parser
);
7377 return c_parser_alignof_expression (parser
);
7379 c_parser_consume_token (parser
);
7380 ext
= disable_extension_diagnostics ();
7381 ret
= c_parser_cast_expression (parser
, NULL
);
7382 restore_extension_diagnostics (ext
);
7385 c_parser_consume_token (parser
);
7386 exp_loc
= c_parser_peek_token (parser
)->location
;
7387 op
= c_parser_cast_expression (parser
, NULL
);
7388 op
= default_function_array_conversion (exp_loc
, op
);
7389 return parser_build_unary_op (op_loc
, REALPART_EXPR
, op
);
7391 c_parser_consume_token (parser
);
7392 exp_loc
= c_parser_peek_token (parser
)->location
;
7393 op
= c_parser_cast_expression (parser
, NULL
);
7394 op
= default_function_array_conversion (exp_loc
, op
);
7395 return parser_build_unary_op (op_loc
, IMAGPART_EXPR
, op
);
7396 case RID_TRANSACTION_ATOMIC
:
7397 case RID_TRANSACTION_RELAXED
:
7398 return c_parser_transaction_expression (parser
,
7399 c_parser_peek_token (parser
)->keyword
);
7401 return c_parser_postfix_expression (parser
);
7404 return c_parser_postfix_expression (parser
);
7408 /* Parse a sizeof expression. */
7410 static struct c_expr
7411 c_parser_sizeof_expression (c_parser
*parser
)
7414 struct c_expr result
;
7415 location_t expr_loc
;
7416 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_SIZEOF
));
7419 location_t finish
= UNKNOWN_LOCATION
;
7421 start
= c_parser_peek_token (parser
)->location
;
7423 c_parser_consume_token (parser
);
7424 c_inhibit_evaluation_warnings
++;
7426 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
)
7427 && c_token_starts_typename (c_parser_peek_2nd_token (parser
)))
7429 /* Either sizeof ( type-name ) or sizeof unary-expression
7430 starting with a compound literal. */
7431 struct c_type_name
*type_name
;
7432 matching_parens parens
;
7433 parens
.consume_open (parser
);
7434 expr_loc
= c_parser_peek_token (parser
)->location
;
7435 type_name
= c_parser_type_name (parser
);
7436 parens
.skip_until_found_close (parser
);
7437 finish
= parser
->tokens_buf
[0].location
;
7438 if (type_name
== NULL
)
7441 c_inhibit_evaluation_warnings
--;
7443 ret
.value
= error_mark_node
;
7444 ret
.original_code
= ERROR_MARK
;
7445 ret
.original_type
= NULL
;
7448 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
7450 expr
= c_parser_postfix_expression_after_paren_type (parser
,
7453 finish
= expr
.get_finish ();
7456 /* sizeof ( type-name ). */
7457 c_inhibit_evaluation_warnings
--;
7459 result
= c_expr_sizeof_type (expr_loc
, type_name
);
7463 expr_loc
= c_parser_peek_token (parser
)->location
;
7464 expr
= c_parser_unary_expression (parser
);
7465 finish
= expr
.get_finish ();
7467 c_inhibit_evaluation_warnings
--;
7469 mark_exp_read (expr
.value
);
7470 if (TREE_CODE (expr
.value
) == COMPONENT_REF
7471 && DECL_C_BIT_FIELD (TREE_OPERAND (expr
.value
, 1)))
7472 error_at (expr_loc
, "%<sizeof%> applied to a bit-field");
7473 result
= c_expr_sizeof_expr (expr_loc
, expr
);
7475 if (finish
!= UNKNOWN_LOCATION
)
7476 set_c_expr_source_range (&result
, start
, finish
);
7480 /* Parse an alignof expression. */
7482 static struct c_expr
7483 c_parser_alignof_expression (c_parser
*parser
)
7486 location_t start_loc
= c_parser_peek_token (parser
)->location
;
7488 tree alignof_spelling
= c_parser_peek_token (parser
)->value
;
7489 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ALIGNOF
));
7490 bool is_c11_alignof
= strcmp (IDENTIFIER_POINTER (alignof_spelling
),
7492 /* A diagnostic is not required for the use of this identifier in
7493 the implementation namespace; only diagnose it for the C11
7494 spelling because of existing code using the other spellings. */
7498 pedwarn_c99 (start_loc
, OPT_Wpedantic
, "ISO C99 does not support %qE",
7501 pedwarn_c99 (start_loc
, OPT_Wpedantic
, "ISO C90 does not support %qE",
7504 c_parser_consume_token (parser
);
7505 c_inhibit_evaluation_warnings
++;
7507 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
)
7508 && c_token_starts_typename (c_parser_peek_2nd_token (parser
)))
7510 /* Either __alignof__ ( type-name ) or __alignof__
7511 unary-expression starting with a compound literal. */
7513 struct c_type_name
*type_name
;
7515 matching_parens parens
;
7516 parens
.consume_open (parser
);
7517 loc
= c_parser_peek_token (parser
)->location
;
7518 type_name
= c_parser_type_name (parser
);
7519 end_loc
= c_parser_peek_token (parser
)->location
;
7520 parens
.skip_until_found_close (parser
);
7521 if (type_name
== NULL
)
7524 c_inhibit_evaluation_warnings
--;
7526 ret
.value
= error_mark_node
;
7527 ret
.original_code
= ERROR_MARK
;
7528 ret
.original_type
= NULL
;
7531 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
7533 expr
= c_parser_postfix_expression_after_paren_type (parser
,
7538 /* alignof ( type-name ). */
7539 c_inhibit_evaluation_warnings
--;
7541 ret
.value
= c_sizeof_or_alignof_type (loc
, groktypename (type_name
,
7543 false, is_c11_alignof
, 1);
7544 ret
.original_code
= ERROR_MARK
;
7545 ret
.original_type
= NULL
;
7546 set_c_expr_source_range (&ret
, start_loc
, end_loc
);
7552 expr
= c_parser_unary_expression (parser
);
7553 end_loc
= expr
.src_range
.m_finish
;
7555 mark_exp_read (expr
.value
);
7556 c_inhibit_evaluation_warnings
--;
7560 OPT_Wpedantic
, "ISO C does not allow %<%E (expression)%>",
7562 ret
.value
= c_alignof_expr (start_loc
, expr
.value
);
7563 ret
.original_code
= ERROR_MARK
;
7564 ret
.original_type
= NULL
;
7565 set_c_expr_source_range (&ret
, start_loc
, end_loc
);
7570 /* Helper function to read arguments of builtins which are interfaces
7571 for the middle-end nodes like COMPLEX_EXPR, VEC_PERM_EXPR and
7572 others. The name of the builtin is passed using BNAME parameter.
7573 Function returns true if there were no errors while parsing and
7574 stores the arguments in CEXPR_LIST. If it returns true,
7575 *OUT_CLOSE_PAREN_LOC is written to with the location of the closing
7578 c_parser_get_builtin_args (c_parser
*parser
, const char *bname
,
7579 vec
<c_expr_t
, va_gc
> **ret_cexpr_list
,
7581 location_t
*out_close_paren_loc
)
7583 location_t loc
= c_parser_peek_token (parser
)->location
;
7584 vec
<c_expr_t
, va_gc
> *cexpr_list
;
7586 bool saved_force_folding_builtin_constant_p
;
7588 *ret_cexpr_list
= NULL
;
7589 if (c_parser_next_token_is_not (parser
, CPP_OPEN_PAREN
))
7591 error_at (loc
, "cannot take address of %qs", bname
);
7595 c_parser_consume_token (parser
);
7597 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
7599 *out_close_paren_loc
= c_parser_peek_token (parser
)->location
;
7600 c_parser_consume_token (parser
);
7604 saved_force_folding_builtin_constant_p
7605 = force_folding_builtin_constant_p
;
7606 force_folding_builtin_constant_p
|= choose_expr_p
;
7607 expr
= c_parser_expr_no_commas (parser
, NULL
);
7608 force_folding_builtin_constant_p
7609 = saved_force_folding_builtin_constant_p
;
7610 vec_alloc (cexpr_list
, 1);
7611 vec_safe_push (cexpr_list
, expr
);
7612 while (c_parser_next_token_is (parser
, CPP_COMMA
))
7614 c_parser_consume_token (parser
);
7615 expr
= c_parser_expr_no_commas (parser
, NULL
);
7616 vec_safe_push (cexpr_list
, expr
);
7619 *out_close_paren_loc
= c_parser_peek_token (parser
)->location
;
7620 if (!c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
7623 *ret_cexpr_list
= cexpr_list
;
7627 /* This represents a single generic-association. */
7629 struct c_generic_association
7631 /* The location of the starting token of the type. */
7632 location_t type_location
;
7633 /* The association's type, or NULL_TREE for 'default'. */
7635 /* The association's expression. */
7636 struct c_expr expression
;
7639 /* Parse a generic-selection. (C11 6.5.1.1).
7642 _Generic ( assignment-expression , generic-assoc-list )
7646 generic-assoc-list , generic-association
7648 generic-association:
7649 type-name : assignment-expression
7650 default : assignment-expression
7653 static struct c_expr
7654 c_parser_generic_selection (c_parser
*parser
)
7656 struct c_expr selector
, error_expr
;
7658 struct c_generic_association matched_assoc
;
7659 bool match_found
= false;
7660 location_t generic_loc
, selector_loc
;
7662 error_expr
.original_code
= ERROR_MARK
;
7663 error_expr
.original_type
= NULL
;
7664 error_expr
.set_error ();
7665 matched_assoc
.type_location
= UNKNOWN_LOCATION
;
7666 matched_assoc
.type
= NULL_TREE
;
7667 matched_assoc
.expression
= error_expr
;
7669 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_GENERIC
));
7670 generic_loc
= c_parser_peek_token (parser
)->location
;
7671 c_parser_consume_token (parser
);
7673 pedwarn_c99 (generic_loc
, OPT_Wpedantic
,
7674 "ISO C99 does not support %<_Generic%>");
7676 pedwarn_c99 (generic_loc
, OPT_Wpedantic
,
7677 "ISO C90 does not support %<_Generic%>");
7679 matching_parens parens
;
7680 if (!parens
.require_open (parser
))
7683 c_inhibit_evaluation_warnings
++;
7684 selector_loc
= c_parser_peek_token (parser
)->location
;
7685 selector
= c_parser_expr_no_commas (parser
, NULL
);
7686 selector
= default_function_array_conversion (selector_loc
, selector
);
7687 c_inhibit_evaluation_warnings
--;
7689 if (selector
.value
== error_mark_node
)
7691 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
7694 selector_type
= TREE_TYPE (selector
.value
);
7695 /* In ISO C terms, rvalues (including the controlling expression of
7696 _Generic) do not have qualified types. */
7697 if (TREE_CODE (selector_type
) != ARRAY_TYPE
)
7698 selector_type
= TYPE_MAIN_VARIANT (selector_type
);
7699 /* In ISO C terms, _Noreturn is not part of the type of expressions
7700 such as &abort, but in GCC it is represented internally as a type
7702 if (FUNCTION_POINTER_TYPE_P (selector_type
)
7703 && TYPE_QUALS (TREE_TYPE (selector_type
)) != TYPE_UNQUALIFIED
)
7705 = build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (selector_type
)));
7707 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
7709 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
7713 auto_vec
<c_generic_association
> associations
;
7716 struct c_generic_association assoc
, *iter
;
7718 c_token
*token
= c_parser_peek_token (parser
);
7720 assoc
.type_location
= token
->location
;
7721 if (token
->type
== CPP_KEYWORD
&& token
->keyword
== RID_DEFAULT
)
7723 c_parser_consume_token (parser
);
7724 assoc
.type
= NULL_TREE
;
7728 struct c_type_name
*type_name
;
7730 type_name
= c_parser_type_name (parser
);
7731 if (type_name
== NULL
)
7733 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
7736 assoc
.type
= groktypename (type_name
, NULL
, NULL
);
7737 if (assoc
.type
== error_mark_node
)
7739 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
7743 if (TREE_CODE (assoc
.type
) == FUNCTION_TYPE
)
7744 error_at (assoc
.type_location
,
7745 "%<_Generic%> association has function type");
7746 else if (!COMPLETE_TYPE_P (assoc
.type
))
7747 error_at (assoc
.type_location
,
7748 "%<_Generic%> association has incomplete type");
7750 if (variably_modified_type_p (assoc
.type
, NULL_TREE
))
7751 error_at (assoc
.type_location
,
7752 "%<_Generic%> association has "
7753 "variable length type");
7756 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
7758 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
7762 assoc
.expression
= c_parser_expr_no_commas (parser
, NULL
);
7763 if (assoc
.expression
.value
== error_mark_node
)
7765 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
7769 for (ix
= 0; associations
.iterate (ix
, &iter
); ++ix
)
7771 if (assoc
.type
== NULL_TREE
)
7773 if (iter
->type
== NULL_TREE
)
7775 error_at (assoc
.type_location
,
7776 "duplicate %<default%> case in %<_Generic%>");
7777 inform (iter
->type_location
, "original %<default%> is here");
7780 else if (iter
->type
!= NULL_TREE
)
7782 if (comptypes (assoc
.type
, iter
->type
))
7784 error_at (assoc
.type_location
,
7785 "%<_Generic%> specifies two compatible types");
7786 inform (iter
->type_location
, "compatible type is here");
7791 if (assoc
.type
== NULL_TREE
)
7795 matched_assoc
= assoc
;
7799 else if (comptypes (assoc
.type
, selector_type
))
7801 if (!match_found
|| matched_assoc
.type
== NULL_TREE
)
7803 matched_assoc
= assoc
;
7808 error_at (assoc
.type_location
,
7809 "%<_Generic%> selector matches multiple associations");
7810 inform (matched_assoc
.type_location
,
7811 "other match is here");
7815 associations
.safe_push (assoc
);
7817 if (c_parser_peek_token (parser
)->type
!= CPP_COMMA
)
7819 c_parser_consume_token (parser
);
7822 if (!parens
.require_close (parser
))
7824 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
7830 error_at (selector_loc
, "%<_Generic%> selector of type %qT is not "
7831 "compatible with any association",
7836 return matched_assoc
.expression
;
7839 /* Check the validity of a function pointer argument *EXPR (argument
7840 position POS) to __builtin_tgmath. Return the number of function
7841 arguments if possibly valid; return 0 having reported an error if
7845 check_tgmath_function (c_expr
*expr
, unsigned int pos
)
7847 tree type
= TREE_TYPE (expr
->value
);
7848 if (!FUNCTION_POINTER_TYPE_P (type
))
7850 error_at (expr
->get_location (),
7851 "argument %u of %<__builtin_tgmath%> is not a function pointer",
7855 type
= TREE_TYPE (type
);
7856 if (!prototype_p (type
))
7858 error_at (expr
->get_location (),
7859 "argument %u of %<__builtin_tgmath%> is unprototyped", pos
);
7862 if (stdarg_p (type
))
7864 error_at (expr
->get_location (),
7865 "argument %u of %<__builtin_tgmath%> has variable arguments",
7869 unsigned int nargs
= 0;
7870 function_args_iterator iter
;
7872 FOREACH_FUNCTION_ARGS (type
, t
, iter
)
7874 if (t
== void_type_node
)
7880 error_at (expr
->get_location (),
7881 "argument %u of %<__builtin_tgmath%> has no arguments", pos
);
7887 /* Ways in which a parameter or return value of a type-generic macro
7888 may vary between the different functions the macro may call. */
7889 enum tgmath_parm_kind
7891 tgmath_fixed
, tgmath_real
, tgmath_complex
7894 /* Parse a postfix expression (C90 6.3.1-6.3.2, C99 6.5.1-6.5.2,
7895 C11 6.5.1-6.5.2). Compound literals aren't handled here; callers have to
7896 call c_parser_postfix_expression_after_paren_type on encountering them.
7900 postfix-expression [ expression ]
7901 postfix-expression ( argument-expression-list[opt] )
7902 postfix-expression . identifier
7903 postfix-expression -> identifier
7904 postfix-expression ++
7905 postfix-expression --
7906 ( type-name ) { initializer-list }
7907 ( type-name ) { initializer-list , }
7909 argument-expression-list:
7911 argument-expression-list , argument-expression
7924 (treated as a keyword in GNU C)
7927 ( compound-statement )
7928 __builtin_va_arg ( assignment-expression , type-name )
7929 __builtin_offsetof ( type-name , offsetof-member-designator )
7930 __builtin_choose_expr ( assignment-expression ,
7931 assignment-expression ,
7932 assignment-expression )
7933 __builtin_types_compatible_p ( type-name , type-name )
7934 __builtin_tgmath ( expr-list )
7935 __builtin_complex ( assignment-expression , assignment-expression )
7936 __builtin_shuffle ( assignment-expression , assignment-expression )
7937 __builtin_shuffle ( assignment-expression ,
7938 assignment-expression ,
7939 assignment-expression, )
7941 offsetof-member-designator:
7943 offsetof-member-designator . identifier
7944 offsetof-member-designator [ expression ]
7949 [ objc-receiver objc-message-args ]
7950 @selector ( objc-selector-arg )
7951 @protocol ( identifier )
7952 @encode ( type-name )
7954 Classname . identifier
7957 static struct c_expr
7958 c_parser_postfix_expression (c_parser
*parser
)
7960 struct c_expr expr
, e1
;
7961 struct c_type_name
*t1
, *t2
;
7962 location_t loc
= c_parser_peek_token (parser
)->location
;;
7963 source_range tok_range
= c_parser_peek_token (parser
)->get_range ();
7964 expr
.original_code
= ERROR_MARK
;
7965 expr
.original_type
= NULL
;
7966 switch (c_parser_peek_token (parser
)->type
)
7969 expr
.value
= c_parser_peek_token (parser
)->value
;
7970 set_c_expr_source_range (&expr
, tok_range
);
7971 loc
= c_parser_peek_token (parser
)->location
;
7972 c_parser_consume_token (parser
);
7973 if (TREE_CODE (expr
.value
) == FIXED_CST
7974 && !targetm
.fixed_point_supported_p ())
7976 error_at (loc
, "fixed-point types not supported for this target");
7977 expr
.value
= error_mark_node
;
7984 expr
.value
= c_parser_peek_token (parser
)->value
;
7985 /* For the purpose of warning when a pointer is compared with
7986 a zero character constant. */
7987 expr
.original_type
= char_type_node
;
7988 set_c_expr_source_range (&expr
, tok_range
);
7989 c_parser_consume_token (parser
);
7995 case CPP_UTF8STRING
:
7996 expr
.value
= c_parser_peek_token (parser
)->value
;
7997 set_c_expr_source_range (&expr
, tok_range
);
7998 expr
.original_code
= STRING_CST
;
7999 c_parser_consume_token (parser
);
8001 case CPP_OBJC_STRING
:
8002 gcc_assert (c_dialect_objc ());
8004 = objc_build_string_object (c_parser_peek_token (parser
)->value
);
8005 set_c_expr_source_range (&expr
, tok_range
);
8006 c_parser_consume_token (parser
);
8009 switch (c_parser_peek_token (parser
)->id_kind
)
8013 tree id
= c_parser_peek_token (parser
)->value
;
8014 c_parser_consume_token (parser
);
8015 expr
.value
= build_external_ref (loc
, id
,
8016 (c_parser_peek_token (parser
)->type
8018 &expr
.original_type
);
8019 set_c_expr_source_range (&expr
, tok_range
);
8022 case C_ID_CLASSNAME
:
8024 /* Here we parse the Objective-C 2.0 Class.name dot
8026 tree class_name
= c_parser_peek_token (parser
)->value
;
8028 c_parser_consume_token (parser
);
8029 gcc_assert (c_dialect_objc ());
8030 if (!c_parser_require (parser
, CPP_DOT
, "expected %<.%>"))
8035 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
8037 c_parser_error (parser
, "expected identifier");
8041 c_token
*component_tok
= c_parser_peek_token (parser
);
8042 component
= component_tok
->value
;
8043 location_t end_loc
= component_tok
->get_finish ();
8044 c_parser_consume_token (parser
);
8045 expr
.value
= objc_build_class_component_ref (class_name
,
8047 set_c_expr_source_range (&expr
, loc
, end_loc
);
8051 c_parser_error (parser
, "expected expression");
8056 case CPP_OPEN_PAREN
:
8057 /* A parenthesized expression, statement expression or compound
8059 if (c_parser_peek_2nd_token (parser
)->type
== CPP_OPEN_BRACE
)
8061 /* A statement expression. */
8063 location_t brace_loc
;
8064 c_parser_consume_token (parser
);
8065 brace_loc
= c_parser_peek_token (parser
)->location
;
8066 c_parser_consume_token (parser
);
8067 if (!building_stmt_list_p ())
8069 error_at (loc
, "braced-group within expression allowed "
8070 "only inside a function");
8071 parser
->error
= true;
8072 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
, NULL
);
8073 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8077 stmt
= c_begin_stmt_expr ();
8078 c_parser_compound_statement_nostart (parser
);
8079 location_t close_loc
= c_parser_peek_token (parser
)->location
;
8080 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
8082 pedwarn (loc
, OPT_Wpedantic
,
8083 "ISO C forbids braced-groups within expressions");
8084 expr
.value
= c_finish_stmt_expr (brace_loc
, stmt
);
8085 set_c_expr_source_range (&expr
, loc
, close_loc
);
8086 mark_exp_read (expr
.value
);
8090 /* A parenthesized expression. */
8091 location_t loc_open_paren
= c_parser_peek_token (parser
)->location
;
8092 c_parser_consume_token (parser
);
8093 expr
= c_parser_expression (parser
);
8094 if (TREE_CODE (expr
.value
) == MODIFY_EXPR
)
8095 TREE_NO_WARNING (expr
.value
) = 1;
8096 if (expr
.original_code
!= C_MAYBE_CONST_EXPR
8097 && expr
.original_code
!= SIZEOF_EXPR
)
8098 expr
.original_code
= ERROR_MARK
;
8099 /* Don't change EXPR.ORIGINAL_TYPE. */
8100 location_t loc_close_paren
= c_parser_peek_token (parser
)->location
;
8101 set_c_expr_source_range (&expr
, loc_open_paren
, loc_close_paren
);
8102 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
8103 "expected %<)%>", loc_open_paren
);
8107 switch (c_parser_peek_token (parser
)->keyword
)
8109 case RID_FUNCTION_NAME
:
8110 pedwarn (loc
, OPT_Wpedantic
, "ISO C does not support "
8111 "%<__FUNCTION__%> predefined identifier");
8112 expr
.value
= fname_decl (loc
,
8113 c_parser_peek_token (parser
)->keyword
,
8114 c_parser_peek_token (parser
)->value
);
8115 set_c_expr_source_range (&expr
, loc
, loc
);
8116 c_parser_consume_token (parser
);
8118 case RID_PRETTY_FUNCTION_NAME
:
8119 pedwarn (loc
, OPT_Wpedantic
, "ISO C does not support "
8120 "%<__PRETTY_FUNCTION__%> predefined identifier");
8121 expr
.value
= fname_decl (loc
,
8122 c_parser_peek_token (parser
)->keyword
,
8123 c_parser_peek_token (parser
)->value
);
8124 set_c_expr_source_range (&expr
, loc
, loc
);
8125 c_parser_consume_token (parser
);
8127 case RID_C99_FUNCTION_NAME
:
8128 pedwarn_c90 (loc
, OPT_Wpedantic
, "ISO C90 does not support "
8129 "%<__func__%> predefined identifier");
8130 expr
.value
= fname_decl (loc
,
8131 c_parser_peek_token (parser
)->keyword
,
8132 c_parser_peek_token (parser
)->value
);
8133 set_c_expr_source_range (&expr
, loc
, loc
);
8134 c_parser_consume_token (parser
);
8138 location_t start_loc
= loc
;
8139 c_parser_consume_token (parser
);
8140 matching_parens parens
;
8141 if (!parens
.require_open (parser
))
8146 e1
= c_parser_expr_no_commas (parser
, NULL
);
8147 mark_exp_read (e1
.value
);
8148 e1
.value
= c_fully_fold (e1
.value
, false, NULL
);
8149 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
8151 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8155 loc
= c_parser_peek_token (parser
)->location
;
8156 t1
= c_parser_type_name (parser
);
8157 location_t end_loc
= c_parser_peek_token (parser
)->get_finish ();
8158 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
8166 tree type_expr
= NULL_TREE
;
8167 expr
.value
= c_build_va_arg (start_loc
, e1
.value
, loc
,
8168 groktypename (t1
, &type_expr
, NULL
));
8171 expr
.value
= build2 (C_MAYBE_CONST_EXPR
,
8172 TREE_TYPE (expr
.value
), type_expr
,
8174 C_MAYBE_CONST_EXPR_NON_CONST (expr
.value
) = true;
8176 set_c_expr_source_range (&expr
, start_loc
, end_loc
);
8182 c_parser_consume_token (parser
);
8183 matching_parens parens
;
8184 if (!parens
.require_open (parser
))
8189 t1
= c_parser_type_name (parser
);
8191 parser
->error
= true;
8192 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
8193 gcc_assert (parser
->error
);
8196 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8200 tree type
= groktypename (t1
, NULL
, NULL
);
8202 if (type
== error_mark_node
)
8203 offsetof_ref
= error_mark_node
;
8206 offsetof_ref
= build1 (INDIRECT_REF
, type
, null_pointer_node
);
8207 SET_EXPR_LOCATION (offsetof_ref
, loc
);
8209 /* Parse the second argument to __builtin_offsetof. We
8210 must have one identifier, and beyond that we want to
8211 accept sub structure and sub array references. */
8212 if (c_parser_next_token_is (parser
, CPP_NAME
))
8214 c_token
*comp_tok
= c_parser_peek_token (parser
);
8215 offsetof_ref
= build_component_ref
8216 (loc
, offsetof_ref
, comp_tok
->value
, comp_tok
->location
);
8217 c_parser_consume_token (parser
);
8218 while (c_parser_next_token_is (parser
, CPP_DOT
)
8219 || c_parser_next_token_is (parser
,
8221 || c_parser_next_token_is (parser
,
8224 if (c_parser_next_token_is (parser
, CPP_DEREF
))
8226 loc
= c_parser_peek_token (parser
)->location
;
8227 offsetof_ref
= build_array_ref (loc
,
8232 else if (c_parser_next_token_is (parser
, CPP_DOT
))
8235 c_parser_consume_token (parser
);
8236 if (c_parser_next_token_is_not (parser
,
8239 c_parser_error (parser
, "expected identifier");
8242 c_token
*comp_tok
= c_parser_peek_token (parser
);
8243 offsetof_ref
= build_component_ref
8244 (loc
, offsetof_ref
, comp_tok
->value
,
8245 comp_tok
->location
);
8246 c_parser_consume_token (parser
);
8252 loc
= c_parser_peek_token (parser
)->location
;
8253 c_parser_consume_token (parser
);
8254 ce
= c_parser_expression (parser
);
8255 ce
= convert_lvalue_to_rvalue (loc
, ce
, false, false);
8257 idx
= c_fully_fold (idx
, false, NULL
);
8258 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
8260 offsetof_ref
= build_array_ref (loc
, offsetof_ref
, idx
);
8265 c_parser_error (parser
, "expected identifier");
8266 location_t end_loc
= c_parser_peek_token (parser
)->get_finish ();
8267 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
8269 expr
.value
= fold_offsetof (offsetof_ref
);
8270 set_c_expr_source_range (&expr
, loc
, end_loc
);
8273 case RID_CHOOSE_EXPR
:
8275 vec
<c_expr_t
, va_gc
> *cexpr_list
;
8276 c_expr_t
*e1_p
, *e2_p
, *e3_p
;
8278 location_t close_paren_loc
;
8280 c_parser_consume_token (parser
);
8281 if (!c_parser_get_builtin_args (parser
,
8282 "__builtin_choose_expr",
8290 if (vec_safe_length (cexpr_list
) != 3)
8292 error_at (loc
, "wrong number of arguments to "
8293 "%<__builtin_choose_expr%>");
8298 e1_p
= &(*cexpr_list
)[0];
8299 e2_p
= &(*cexpr_list
)[1];
8300 e3_p
= &(*cexpr_list
)[2];
8303 mark_exp_read (e2_p
->value
);
8304 mark_exp_read (e3_p
->value
);
8305 if (TREE_CODE (c
) != INTEGER_CST
8306 || !INTEGRAL_TYPE_P (TREE_TYPE (c
)))
8308 "first argument to %<__builtin_choose_expr%> not"
8310 constant_expression_warning (c
);
8311 expr
= integer_zerop (c
) ? *e3_p
: *e2_p
;
8312 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
8315 case RID_TYPES_COMPATIBLE_P
:
8317 c_parser_consume_token (parser
);
8318 matching_parens parens
;
8319 if (!parens
.require_open (parser
))
8324 t1
= c_parser_type_name (parser
);
8330 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
8332 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8336 t2
= c_parser_type_name (parser
);
8342 location_t close_paren_loc
= c_parser_peek_token (parser
)->location
;
8343 parens
.skip_until_found_close (parser
);
8345 e1
= groktypename (t1
, NULL
, NULL
);
8346 e2
= groktypename (t2
, NULL
, NULL
);
8347 if (e1
== error_mark_node
|| e2
== error_mark_node
)
8353 e1
= TYPE_MAIN_VARIANT (e1
);
8354 e2
= TYPE_MAIN_VARIANT (e2
);
8357 = comptypes (e1
, e2
) ? integer_one_node
: integer_zero_node
;
8358 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
8361 case RID_BUILTIN_TGMATH
:
8363 vec
<c_expr_t
, va_gc
> *cexpr_list
;
8364 location_t close_paren_loc
;
8366 c_parser_consume_token (parser
);
8367 if (!c_parser_get_builtin_args (parser
,
8376 if (vec_safe_length (cexpr_list
) < 3)
8378 error_at (loc
, "too few arguments to %<__builtin_tgmath%>");
8385 FOR_EACH_VEC_ELT (*cexpr_list
, i
, p
)
8386 *p
= convert_lvalue_to_rvalue (loc
, *p
, true, true);
8387 unsigned int nargs
= check_tgmath_function (&(*cexpr_list
)[0], 1);
8393 if (vec_safe_length (cexpr_list
) < nargs
)
8395 error_at (loc
, "too few arguments to %<__builtin_tgmath%>");
8399 unsigned int num_functions
= vec_safe_length (cexpr_list
) - nargs
;
8400 if (num_functions
< 2)
8402 error_at (loc
, "too few arguments to %<__builtin_tgmath%>");
8407 /* The first NUM_FUNCTIONS expressions are the function
8408 pointers. The remaining NARGS expressions are the
8409 arguments that are to be passed to one of those
8410 functions, chosen following <tgmath.h> rules. */
8411 for (unsigned int j
= 1; j
< num_functions
; j
++)
8413 unsigned int this_nargs
8414 = check_tgmath_function (&(*cexpr_list
)[j
], j
+ 1);
8415 if (this_nargs
== 0)
8420 if (this_nargs
!= nargs
)
8422 error_at ((*cexpr_list
)[j
].get_location (),
8423 "argument %u of %<__builtin_tgmath%> has "
8424 "wrong number of arguments", j
+ 1);
8430 /* The functions all have the same number of arguments.
8431 Determine whether arguments and return types vary in
8432 ways permitted for <tgmath.h> functions. */
8433 /* The first entry in each of these vectors is for the
8434 return type, subsequent entries for parameter
8436 auto_vec
<enum tgmath_parm_kind
> parm_kind (nargs
+ 1);
8437 auto_vec
<tree
> parm_first (nargs
+ 1);
8438 auto_vec
<bool> parm_complex (nargs
+ 1);
8439 auto_vec
<bool> parm_varies (nargs
+ 1);
8440 tree first_type
= TREE_TYPE (TREE_TYPE ((*cexpr_list
)[0].value
));
8441 tree first_ret
= TYPE_MAIN_VARIANT (TREE_TYPE (first_type
));
8442 parm_first
.quick_push (first_ret
);
8443 parm_complex
.quick_push (TREE_CODE (first_ret
) == COMPLEX_TYPE
);
8444 parm_varies
.quick_push (false);
8445 function_args_iterator iter
;
8447 unsigned int argpos
;
8448 FOREACH_FUNCTION_ARGS (first_type
, t
, iter
)
8450 if (t
== void_type_node
)
8452 parm_first
.quick_push (TYPE_MAIN_VARIANT (t
));
8453 parm_complex
.quick_push (TREE_CODE (t
) == COMPLEX_TYPE
);
8454 parm_varies
.quick_push (false);
8456 for (unsigned int j
= 1; j
< num_functions
; j
++)
8458 tree type
= TREE_TYPE (TREE_TYPE ((*cexpr_list
)[j
].value
));
8459 tree ret
= TYPE_MAIN_VARIANT (TREE_TYPE (type
));
8460 if (ret
!= parm_first
[0])
8462 parm_varies
[0] = true;
8463 if (!SCALAR_FLOAT_TYPE_P (parm_first
[0])
8464 && !COMPLEX_FLOAT_TYPE_P (parm_first
[0]))
8466 error_at ((*cexpr_list
)[0].get_location (),
8467 "invalid type-generic return type for "
8468 "argument %u of %<__builtin_tgmath%>",
8473 if (!SCALAR_FLOAT_TYPE_P (ret
)
8474 && !COMPLEX_FLOAT_TYPE_P (ret
))
8476 error_at ((*cexpr_list
)[j
].get_location (),
8477 "invalid type-generic return type for "
8478 "argument %u of %<__builtin_tgmath%>",
8484 if (TREE_CODE (ret
) == COMPLEX_TYPE
)
8485 parm_complex
[0] = true;
8487 FOREACH_FUNCTION_ARGS (type
, t
, iter
)
8489 if (t
== void_type_node
)
8491 t
= TYPE_MAIN_VARIANT (t
);
8492 if (t
!= parm_first
[argpos
])
8494 parm_varies
[argpos
] = true;
8495 if (!SCALAR_FLOAT_TYPE_P (parm_first
[argpos
])
8496 && !COMPLEX_FLOAT_TYPE_P (parm_first
[argpos
]))
8498 error_at ((*cexpr_list
)[0].get_location (),
8499 "invalid type-generic type for "
8500 "argument %u of argument %u of "
8501 "%<__builtin_tgmath%>", argpos
, 1);
8505 if (!SCALAR_FLOAT_TYPE_P (t
)
8506 && !COMPLEX_FLOAT_TYPE_P (t
))
8508 error_at ((*cexpr_list
)[j
].get_location (),
8509 "invalid type-generic type for "
8510 "argument %u of argument %u of "
8511 "%<__builtin_tgmath%>", argpos
, j
+ 1);
8516 if (TREE_CODE (t
) == COMPLEX_TYPE
)
8517 parm_complex
[argpos
] = true;
8521 enum tgmath_parm_kind max_variation
= tgmath_fixed
;
8522 for (unsigned int j
= 0; j
<= nargs
; j
++)
8524 enum tgmath_parm_kind this_kind
;
8527 if (parm_complex
[j
])
8528 max_variation
= this_kind
= tgmath_complex
;
8531 this_kind
= tgmath_real
;
8532 if (max_variation
!= tgmath_complex
)
8533 max_variation
= tgmath_real
;
8537 this_kind
= tgmath_fixed
;
8538 parm_kind
.quick_push (this_kind
);
8540 if (max_variation
== tgmath_fixed
)
8542 error_at (loc
, "function arguments of %<__builtin_tgmath%> "
8543 "all have the same type");
8548 /* Identify a parameter (not the return type) that varies,
8549 including with complex types if any variation includes
8550 complex types; there must be at least one such
8552 unsigned int tgarg
= 0;
8553 for (unsigned int j
= 1; j
<= nargs
; j
++)
8554 if (parm_kind
[j
] == max_variation
)
8561 error_at (loc
, "function arguments of %<__builtin_tgmath%> "
8562 "lack type-generic parameter");
8567 /* Determine the type of the relevant parameter for each
8569 auto_vec
<tree
> tg_type (num_functions
);
8570 for (unsigned int j
= 0; j
< num_functions
; j
++)
8572 tree type
= TREE_TYPE (TREE_TYPE ((*cexpr_list
)[j
].value
));
8574 FOREACH_FUNCTION_ARGS (type
, t
, iter
)
8576 if (argpos
== tgarg
)
8578 tg_type
.quick_push (TYPE_MAIN_VARIANT (t
));
8585 /* Verify that the corresponding types are different for
8586 all the listed functions. Also determine whether all
8587 the types are complex, whether all the types are
8588 standard or binary, and whether all the types are
8590 bool all_complex
= true;
8591 bool all_binary
= true;
8592 bool all_decimal
= true;
8593 hash_set
<tree
> tg_types
;
8594 FOR_EACH_VEC_ELT (tg_type
, i
, t
)
8596 if (TREE_CODE (t
) == COMPLEX_TYPE
)
8597 all_decimal
= false;
8600 all_complex
= false;
8601 if (DECIMAL_FLOAT_TYPE_P (t
))
8604 all_decimal
= false;
8606 if (tg_types
.add (t
))
8608 error_at ((*cexpr_list
)[i
].get_location (),
8609 "duplicate type-generic parameter type for "
8610 "function argument %u of %<__builtin_tgmath%>",
8617 /* Verify that other parameters and the return type whose
8618 types vary have their types varying in the correct
8620 for (unsigned int j
= 0; j
< num_functions
; j
++)
8622 tree exp_type
= tg_type
[j
];
8623 tree exp_real_type
= exp_type
;
8624 if (TREE_CODE (exp_type
) == COMPLEX_TYPE
)
8625 exp_real_type
= TREE_TYPE (exp_type
);
8626 tree type
= TREE_TYPE (TREE_TYPE ((*cexpr_list
)[j
].value
));
8627 tree ret
= TYPE_MAIN_VARIANT (TREE_TYPE (type
));
8628 if ((parm_kind
[0] == tgmath_complex
&& ret
!= exp_type
)
8629 || (parm_kind
[0] == tgmath_real
&& ret
!= exp_real_type
))
8631 error_at ((*cexpr_list
)[j
].get_location (),
8632 "bad return type for function argument %u "
8633 "of %<__builtin_tgmath%>", j
+ 1);
8638 FOREACH_FUNCTION_ARGS (type
, t
, iter
)
8640 if (t
== void_type_node
)
8642 t
= TYPE_MAIN_VARIANT (t
);
8643 if ((parm_kind
[argpos
] == tgmath_complex
8645 || (parm_kind
[argpos
] == tgmath_real
8646 && t
!= exp_real_type
))
8648 error_at ((*cexpr_list
)[j
].get_location (),
8649 "bad type for argument %u of "
8650 "function argument %u of "
8651 "%<__builtin_tgmath%>", argpos
, j
+ 1);
8659 /* The functions listed are a valid set of functions for a
8660 <tgmath.h> macro to select between. Identify the
8661 matching function, if any. First, the argument types
8662 must be combined following <tgmath.h> rules. Integer
8663 types are treated as _Decimal64 if any type-generic
8664 argument is decimal, or if the only alternatives for
8665 type-generic arguments are of decimal types, and are
8666 otherwise treated as double (or _Complex double for
8667 complex integer types). After that adjustment, types
8668 are combined following the usual arithmetic
8669 conversions. If the function only accepts complex
8670 arguments, a complex type is produced. */
8671 bool arg_complex
= all_complex
;
8672 bool arg_binary
= all_binary
;
8673 bool arg_int_decimal
= all_decimal
;
8674 for (unsigned int j
= 1; j
<= nargs
; j
++)
8676 if (parm_kind
[j
] == tgmath_fixed
)
8678 c_expr_t
*ce
= &(*cexpr_list
)[num_functions
+ j
- 1];
8679 tree type
= TREE_TYPE (ce
->value
);
8680 if (!INTEGRAL_TYPE_P (type
)
8681 && !SCALAR_FLOAT_TYPE_P (type
)
8682 && TREE_CODE (type
) != COMPLEX_TYPE
)
8684 error_at (ce
->get_location (),
8685 "invalid type of argument %u of type-generic "
8690 if (DECIMAL_FLOAT_TYPE_P (type
))
8692 arg_int_decimal
= true;
8695 error_at (ce
->get_location (),
8696 "decimal floating-point argument %u to "
8697 "complex-only type-generic function", j
);
8701 else if (all_binary
)
8703 error_at (ce
->get_location (),
8704 "decimal floating-point argument %u to "
8705 "binary-only type-generic function", j
);
8709 else if (arg_complex
)
8711 error_at (ce
->get_location (),
8712 "both complex and decimal floating-point "
8713 "arguments to type-generic function");
8717 else if (arg_binary
)
8719 error_at (ce
->get_location (),
8720 "both binary and decimal floating-point "
8721 "arguments to type-generic function");
8726 else if (TREE_CODE (type
) == COMPLEX_TYPE
)
8729 if (COMPLEX_FLOAT_TYPE_P (type
))
8733 error_at (ce
->get_location (),
8734 "complex argument %u to "
8735 "decimal-only type-generic function", j
);
8739 else if (arg_int_decimal
)
8741 error_at (ce
->get_location (),
8742 "both complex and decimal floating-point "
8743 "arguments to type-generic function");
8748 else if (SCALAR_FLOAT_TYPE_P (type
))
8753 error_at (ce
->get_location (),
8754 "binary argument %u to "
8755 "decimal-only type-generic function", j
);
8759 else if (arg_int_decimal
)
8761 error_at (ce
->get_location (),
8762 "both binary and decimal floating-point "
8763 "arguments to type-generic function");
8769 tree arg_real
= NULL_TREE
;
8770 for (unsigned int j
= 1; j
<= nargs
; j
++)
8772 if (parm_kind
[j
] == tgmath_fixed
)
8774 c_expr_t
*ce
= &(*cexpr_list
)[num_functions
+ j
- 1];
8775 tree type
= TYPE_MAIN_VARIANT (TREE_TYPE (ce
->value
));
8776 if (TREE_CODE (type
) == COMPLEX_TYPE
)
8777 type
= TREE_TYPE (type
);
8778 if (INTEGRAL_TYPE_P (type
))
8779 type
= (arg_int_decimal
8780 ? dfloat64_type_node
8781 : double_type_node
);
8782 if (arg_real
== NULL_TREE
)
8785 arg_real
= common_type (arg_real
, type
);
8786 if (arg_real
== error_mark_node
)
8792 tree arg_type
= (arg_complex
8793 ? build_complex_type (arg_real
)
8796 /* Look for a function to call with type-generic parameter
8798 c_expr_t
*fn
= NULL
;
8799 for (unsigned int j
= 0; j
< num_functions
; j
++)
8801 if (tg_type
[j
] == arg_type
)
8803 fn
= &(*cexpr_list
)[j
];
8808 && parm_kind
[0] == tgmath_fixed
8809 && SCALAR_FLOAT_TYPE_P (parm_first
[0]))
8811 /* Presume this is a macro that rounds its result to a
8812 narrower type, and look for the first function with
8813 at least the range and precision of the argument
8815 for (unsigned int j
= 0; j
< num_functions
; j
++)
8818 != (TREE_CODE (tg_type
[j
]) == COMPLEX_TYPE
))
8820 tree real_tg_type
= (arg_complex
8821 ? TREE_TYPE (tg_type
[j
])
8823 if (DECIMAL_FLOAT_TYPE_P (arg_real
)
8824 != DECIMAL_FLOAT_TYPE_P (real_tg_type
))
8826 scalar_float_mode arg_mode
8827 = SCALAR_FLOAT_TYPE_MODE (arg_real
);
8828 scalar_float_mode tg_mode
8829 = SCALAR_FLOAT_TYPE_MODE (real_tg_type
);
8830 const real_format
*arg_fmt
= REAL_MODE_FORMAT (arg_mode
);
8831 const real_format
*tg_fmt
= REAL_MODE_FORMAT (tg_mode
);
8832 if (arg_fmt
->b
== tg_fmt
->b
8833 && arg_fmt
->p
<= tg_fmt
->p
8834 && arg_fmt
->emax
<= tg_fmt
->emax
8835 && (arg_fmt
->emin
- arg_fmt
->p
8836 >= tg_fmt
->emin
- tg_fmt
->p
))
8838 fn
= &(*cexpr_list
)[j
];
8845 error_at (loc
, "no matching function for type-generic call");
8850 /* Construct a call to FN. */
8851 vec
<tree
, va_gc
> *args
;
8852 vec_alloc (args
, nargs
);
8853 vec
<tree
, va_gc
> *origtypes
;
8854 vec_alloc (origtypes
, nargs
);
8855 auto_vec
<location_t
> arg_loc (nargs
);
8856 for (unsigned int j
= 0; j
< nargs
; j
++)
8858 c_expr_t
*ce
= &(*cexpr_list
)[num_functions
+ j
];
8859 args
->quick_push (ce
->value
);
8860 arg_loc
.quick_push (ce
->get_location ());
8861 origtypes
->quick_push (ce
->original_type
);
8863 expr
.value
= c_build_function_call_vec (loc
, arg_loc
, fn
->value
,
8865 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
8868 case RID_BUILTIN_CALL_WITH_STATIC_CHAIN
:
8870 vec
<c_expr_t
, va_gc
> *cexpr_list
;
8873 location_t close_paren_loc
;
8875 c_parser_consume_token (parser
);
8876 if (!c_parser_get_builtin_args (parser
,
8877 "__builtin_call_with_static_chain",
8884 if (vec_safe_length (cexpr_list
) != 2)
8886 error_at (loc
, "wrong number of arguments to "
8887 "%<__builtin_call_with_static_chain%>");
8892 expr
= (*cexpr_list
)[0];
8893 e2_p
= &(*cexpr_list
)[1];
8894 *e2_p
= convert_lvalue_to_rvalue (loc
, *e2_p
, true, true);
8895 chain_value
= e2_p
->value
;
8896 mark_exp_read (chain_value
);
8898 if (TREE_CODE (expr
.value
) != CALL_EXPR
)
8899 error_at (loc
, "first argument to "
8900 "%<__builtin_call_with_static_chain%> "
8901 "must be a call expression");
8902 else if (TREE_CODE (TREE_TYPE (chain_value
)) != POINTER_TYPE
)
8903 error_at (loc
, "second argument to "
8904 "%<__builtin_call_with_static_chain%> "
8905 "must be a pointer type");
8907 CALL_EXPR_STATIC_CHAIN (expr
.value
) = chain_value
;
8908 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
8911 case RID_BUILTIN_COMPLEX
:
8913 vec
<c_expr_t
, va_gc
> *cexpr_list
;
8914 c_expr_t
*e1_p
, *e2_p
;
8915 location_t close_paren_loc
;
8917 c_parser_consume_token (parser
);
8918 if (!c_parser_get_builtin_args (parser
,
8919 "__builtin_complex",
8927 if (vec_safe_length (cexpr_list
) != 2)
8929 error_at (loc
, "wrong number of arguments to "
8930 "%<__builtin_complex%>");
8935 e1_p
= &(*cexpr_list
)[0];
8936 e2_p
= &(*cexpr_list
)[1];
8938 *e1_p
= convert_lvalue_to_rvalue (loc
, *e1_p
, true, true);
8939 if (TREE_CODE (e1_p
->value
) == EXCESS_PRECISION_EXPR
)
8940 e1_p
->value
= convert (TREE_TYPE (e1_p
->value
),
8941 TREE_OPERAND (e1_p
->value
, 0));
8942 *e2_p
= convert_lvalue_to_rvalue (loc
, *e2_p
, true, true);
8943 if (TREE_CODE (e2_p
->value
) == EXCESS_PRECISION_EXPR
)
8944 e2_p
->value
= convert (TREE_TYPE (e2_p
->value
),
8945 TREE_OPERAND (e2_p
->value
, 0));
8946 if (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (e1_p
->value
))
8947 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e1_p
->value
))
8948 || !SCALAR_FLOAT_TYPE_P (TREE_TYPE (e2_p
->value
))
8949 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e2_p
->value
)))
8951 error_at (loc
, "%<__builtin_complex%> operand "
8952 "not of real binary floating-point type");
8956 if (TYPE_MAIN_VARIANT (TREE_TYPE (e1_p
->value
))
8957 != TYPE_MAIN_VARIANT (TREE_TYPE (e2_p
->value
)))
8960 "%<__builtin_complex%> operands of different types");
8964 pedwarn_c90 (loc
, OPT_Wpedantic
,
8965 "ISO C90 does not support complex types");
8966 expr
.value
= build2_loc (loc
, COMPLEX_EXPR
,
8969 (TREE_TYPE (e1_p
->value
))),
8970 e1_p
->value
, e2_p
->value
);
8971 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
8974 case RID_BUILTIN_SHUFFLE
:
8976 vec
<c_expr_t
, va_gc
> *cexpr_list
;
8979 location_t close_paren_loc
;
8981 c_parser_consume_token (parser
);
8982 if (!c_parser_get_builtin_args (parser
,
8983 "__builtin_shuffle",
8991 FOR_EACH_VEC_SAFE_ELT (cexpr_list
, i
, p
)
8992 *p
= convert_lvalue_to_rvalue (loc
, *p
, true, true);
8994 if (vec_safe_length (cexpr_list
) == 2)
8996 c_build_vec_perm_expr
8997 (loc
, (*cexpr_list
)[0].value
,
8998 NULL_TREE
, (*cexpr_list
)[1].value
);
9000 else if (vec_safe_length (cexpr_list
) == 3)
9002 c_build_vec_perm_expr
9003 (loc
, (*cexpr_list
)[0].value
,
9004 (*cexpr_list
)[1].value
,
9005 (*cexpr_list
)[2].value
);
9008 error_at (loc
, "wrong number of arguments to "
9009 "%<__builtin_shuffle%>");
9012 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
9015 case RID_AT_SELECTOR
:
9017 gcc_assert (c_dialect_objc ());
9018 c_parser_consume_token (parser
);
9019 matching_parens parens
;
9020 if (!parens
.require_open (parser
))
9025 tree sel
= c_parser_objc_selector_arg (parser
);
9026 location_t close_loc
= c_parser_peek_token (parser
)->location
;
9027 parens
.skip_until_found_close (parser
);
9028 expr
.value
= objc_build_selector_expr (loc
, sel
);
9029 set_c_expr_source_range (&expr
, loc
, close_loc
);
9032 case RID_AT_PROTOCOL
:
9034 gcc_assert (c_dialect_objc ());
9035 c_parser_consume_token (parser
);
9036 matching_parens parens
;
9037 if (!parens
.require_open (parser
))
9042 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
9044 c_parser_error (parser
, "expected identifier");
9045 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
9049 tree id
= c_parser_peek_token (parser
)->value
;
9050 c_parser_consume_token (parser
);
9051 location_t close_loc
= c_parser_peek_token (parser
)->location
;
9052 parens
.skip_until_found_close (parser
);
9053 expr
.value
= objc_build_protocol_expr (id
);
9054 set_c_expr_source_range (&expr
, loc
, close_loc
);
9059 /* Extension to support C-structures in the archiver. */
9060 gcc_assert (c_dialect_objc ());
9061 c_parser_consume_token (parser
);
9062 matching_parens parens
;
9063 if (!parens
.require_open (parser
))
9068 t1
= c_parser_type_name (parser
);
9072 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
9075 location_t close_loc
= c_parser_peek_token (parser
)->location
;
9076 parens
.skip_until_found_close (parser
);
9077 tree type
= groktypename (t1
, NULL
, NULL
);
9078 expr
.value
= objc_build_encode_expr (type
);
9079 set_c_expr_source_range (&expr
, loc
, close_loc
);
9083 expr
= c_parser_generic_selection (parser
);
9085 case RID_CILK_SPAWN
:
9086 c_parser_consume_token (parser
);
9089 error_at (loc
, "-fcilkplus must be enabled to use "
9091 expr
= c_parser_cast_expression (parser
, NULL
);
9094 else if (c_parser_peek_token (parser
)->keyword
== RID_CILK_SPAWN
)
9096 error_at (loc
, "consecutive %<_Cilk_spawn%> keywords "
9097 "are not permitted");
9098 /* Now flush out all the _Cilk_spawns. */
9099 while (c_parser_peek_token (parser
)->keyword
== RID_CILK_SPAWN
)
9100 c_parser_consume_token (parser
);
9101 expr
= c_parser_cast_expression (parser
, NULL
);
9105 expr
= c_parser_cast_expression (parser
, NULL
);
9106 expr
.value
= build_cilk_spawn (loc
, expr
.value
);
9110 c_parser_error (parser
, "expected expression");
9115 case CPP_OPEN_SQUARE
:
9116 if (c_dialect_objc ())
9118 tree receiver
, args
;
9119 c_parser_consume_token (parser
);
9120 receiver
= c_parser_objc_receiver (parser
);
9121 args
= c_parser_objc_message_args (parser
);
9122 location_t close_loc
= c_parser_peek_token (parser
)->location
;
9123 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
9125 expr
.value
= objc_build_message_expr (receiver
, args
);
9126 set_c_expr_source_range (&expr
, loc
, close_loc
);
9129 /* Else fall through to report error. */
9132 c_parser_error (parser
, "expected expression");
9137 return c_parser_postfix_expression_after_primary
9138 (parser
, EXPR_LOC_OR_LOC (expr
.value
, loc
), expr
);
9141 /* Parse a postfix expression after a parenthesized type name: the
9142 brace-enclosed initializer of a compound literal, possibly followed
9143 by some postfix operators. This is separate because it is not
9144 possible to tell until after the type name whether a cast
9145 expression has a cast or a compound literal, or whether the operand
9146 of sizeof is a parenthesized type name or starts with a compound
9147 literal. TYPE_LOC is the location where TYPE_NAME starts--the
9148 location of the first token after the parentheses around the type
9151 static struct c_expr
9152 c_parser_postfix_expression_after_paren_type (c_parser
*parser
,
9153 struct c_type_name
*type_name
,
9154 location_t type_loc
)
9160 location_t start_loc
;
9161 tree type_expr
= NULL_TREE
;
9162 bool type_expr_const
= true;
9163 check_compound_literal_type (type_loc
, type_name
);
9164 rich_location
richloc (line_table
, type_loc
);
9165 start_init (NULL_TREE
, NULL
, 0, &richloc
);
9166 type
= groktypename (type_name
, &type_expr
, &type_expr_const
);
9167 start_loc
= c_parser_peek_token (parser
)->location
;
9168 if (type
!= error_mark_node
&& C_TYPE_VARIABLE_SIZE (type
))
9170 error_at (type_loc
, "compound literal has variable size");
9171 type
= error_mark_node
;
9173 init
= c_parser_braced_init (parser
, type
, false, NULL
);
9175 maybe_warn_string_init (type_loc
, type
, init
);
9177 if (type
!= error_mark_node
9178 && !ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (type
))
9179 && current_function_decl
)
9181 error ("compound literal qualified by address-space qualifier");
9182 type
= error_mark_node
;
9185 pedwarn_c90 (start_loc
, OPT_Wpedantic
, "ISO C90 forbids compound literals");
9186 non_const
= ((init
.value
&& TREE_CODE (init
.value
) == CONSTRUCTOR
)
9187 ? CONSTRUCTOR_NON_CONST (init
.value
)
9188 : init
.original_code
== C_MAYBE_CONST_EXPR
);
9189 non_const
|= !type_expr_const
;
9190 expr
.value
= build_compound_literal (start_loc
, type
, init
.value
, non_const
);
9191 set_c_expr_source_range (&expr
, init
.src_range
);
9192 expr
.original_code
= ERROR_MARK
;
9193 expr
.original_type
= NULL
;
9194 if (type
!= error_mark_node
9195 && expr
.value
!= error_mark_node
9198 if (TREE_CODE (expr
.value
) == C_MAYBE_CONST_EXPR
)
9200 gcc_assert (C_MAYBE_CONST_EXPR_PRE (expr
.value
) == NULL_TREE
);
9201 C_MAYBE_CONST_EXPR_PRE (expr
.value
) = type_expr
;
9205 gcc_assert (!non_const
);
9206 expr
.value
= build2 (C_MAYBE_CONST_EXPR
, type
,
9207 type_expr
, expr
.value
);
9210 return c_parser_postfix_expression_after_primary (parser
, start_loc
, expr
);
9213 /* Callback function for sizeof_pointer_memaccess_warning to compare
9217 sizeof_ptr_memacc_comptypes (tree type1
, tree type2
)
9219 return comptypes (type1
, type2
) == 1;
9222 /* Parse a postfix expression after the initial primary or compound
9223 literal; that is, parse a series of postfix operators.
9225 EXPR_LOC is the location of the primary expression. */
9227 static struct c_expr
9228 c_parser_postfix_expression_after_primary (c_parser
*parser
,
9229 location_t expr_loc
,
9232 struct c_expr orig_expr
;
9234 location_t sizeof_arg_loc
[3], comp_loc
;
9236 unsigned int literal_zero_mask
;
9238 vec
<tree
, va_gc
> *exprlist
;
9239 vec
<tree
, va_gc
> *origtypes
= NULL
;
9240 vec
<location_t
> arg_loc
= vNULL
;
9246 location_t op_loc
= c_parser_peek_token (parser
)->location
;
9247 switch (c_parser_peek_token (parser
)->type
)
9249 case CPP_OPEN_SQUARE
:
9250 /* Array reference. */
9251 c_parser_consume_token (parser
);
9253 && c_parser_peek_token (parser
)->type
== CPP_COLON
)
9254 /* If we are here, then we have something like this:
9257 expr
.value
= c_parser_array_notation (expr_loc
, parser
, NULL_TREE
,
9261 idx
= c_parser_expression (parser
).value
;
9262 /* Here we have 3 options:
9263 1. Array [EXPR] -- Normal Array call.
9264 2. Array [EXPR : EXPR] -- Array notation without stride.
9265 3. Array [EXPR : EXPR : EXPR] -- Array notation with stride.
9267 For 1, we just handle it just like a normal array expression.
9268 For 2 and 3 we handle it like we handle array notations. The
9269 idx value we have above becomes the initial/start index.
9272 && c_parser_peek_token (parser
)->type
== CPP_COLON
)
9273 expr
.value
= c_parser_array_notation (expr_loc
, parser
, idx
,
9277 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
9279 start
= expr
.get_start ();
9280 finish
= parser
->tokens_buf
[0].location
;
9281 expr
.value
= build_array_ref (op_loc
, expr
.value
, idx
);
9282 set_c_expr_source_range (&expr
, start
, finish
);
9285 expr
.original_code
= ERROR_MARK
;
9286 expr
.original_type
= NULL
;
9288 case CPP_OPEN_PAREN
:
9289 /* Function call. */
9290 c_parser_consume_token (parser
);
9291 for (i
= 0; i
< 3; i
++)
9293 sizeof_arg
[i
] = NULL_TREE
;
9294 sizeof_arg_loc
[i
] = UNKNOWN_LOCATION
;
9296 literal_zero_mask
= 0;
9297 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
9300 exprlist
= c_parser_expr_list (parser
, true, false, &origtypes
,
9301 sizeof_arg_loc
, sizeof_arg
,
9302 &arg_loc
, &literal_zero_mask
);
9303 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
9306 mark_exp_read (expr
.value
);
9307 if (warn_sizeof_pointer_memaccess
)
9308 sizeof_pointer_memaccess_warning (sizeof_arg_loc
,
9309 expr
.value
, exprlist
,
9311 sizeof_ptr_memacc_comptypes
);
9312 if (TREE_CODE (expr
.value
) == FUNCTION_DECL
9313 && DECL_BUILT_IN_CLASS (expr
.value
) == BUILT_IN_NORMAL
9314 && DECL_FUNCTION_CODE (expr
.value
) == BUILT_IN_MEMSET
9315 && vec_safe_length (exprlist
) == 3)
9317 tree arg0
= (*exprlist
)[0];
9318 tree arg2
= (*exprlist
)[2];
9319 warn_for_memset (expr_loc
, arg0
, arg2
, literal_zero_mask
);
9322 start
= expr
.get_start ();
9323 finish
= parser
->tokens_buf
[0].get_finish ();
9325 = c_build_function_call_vec (expr_loc
, arg_loc
, expr
.value
,
9326 exprlist
, origtypes
);
9327 set_c_expr_source_range (&expr
, start
, finish
);
9329 expr
.original_code
= ERROR_MARK
;
9330 if (TREE_CODE (expr
.value
) == INTEGER_CST
9331 && TREE_CODE (orig_expr
.value
) == FUNCTION_DECL
9332 && DECL_BUILT_IN_CLASS (orig_expr
.value
) == BUILT_IN_NORMAL
9333 && DECL_FUNCTION_CODE (orig_expr
.value
) == BUILT_IN_CONSTANT_P
)
9334 expr
.original_code
= C_MAYBE_CONST_EXPR
;
9335 expr
.original_type
= NULL
;
9338 release_tree_vector (exprlist
);
9339 release_tree_vector (origtypes
);
9344 /* Structure element reference. */
9345 c_parser_consume_token (parser
);
9346 expr
= default_function_array_conversion (expr_loc
, expr
);
9347 if (c_parser_next_token_is (parser
, CPP_NAME
))
9349 c_token
*comp_tok
= c_parser_peek_token (parser
);
9350 ident
= comp_tok
->value
;
9351 comp_loc
= comp_tok
->location
;
9355 c_parser_error (parser
, "expected identifier");
9357 expr
.original_code
= ERROR_MARK
;
9358 expr
.original_type
= NULL
;
9361 start
= expr
.get_start ();
9362 finish
= c_parser_peek_token (parser
)->get_finish ();
9363 c_parser_consume_token (parser
);
9364 expr
.value
= build_component_ref (op_loc
, expr
.value
, ident
,
9366 set_c_expr_source_range (&expr
, start
, finish
);
9367 expr
.original_code
= ERROR_MARK
;
9368 if (TREE_CODE (expr
.value
) != COMPONENT_REF
)
9369 expr
.original_type
= NULL
;
9372 /* Remember the original type of a bitfield. */
9373 tree field
= TREE_OPERAND (expr
.value
, 1);
9374 if (TREE_CODE (field
) != FIELD_DECL
)
9375 expr
.original_type
= NULL
;
9377 expr
.original_type
= DECL_BIT_FIELD_TYPE (field
);
9381 /* Structure element reference. */
9382 c_parser_consume_token (parser
);
9383 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, true, false);
9384 if (c_parser_next_token_is (parser
, CPP_NAME
))
9386 c_token
*comp_tok
= c_parser_peek_token (parser
);
9387 ident
= comp_tok
->value
;
9388 comp_loc
= comp_tok
->location
;
9392 c_parser_error (parser
, "expected identifier");
9394 expr
.original_code
= ERROR_MARK
;
9395 expr
.original_type
= NULL
;
9398 start
= expr
.get_start ();
9399 finish
= c_parser_peek_token (parser
)->get_finish ();
9400 c_parser_consume_token (parser
);
9401 expr
.value
= build_component_ref (op_loc
,
9402 build_indirect_ref (op_loc
,
9406 set_c_expr_source_range (&expr
, start
, finish
);
9407 expr
.original_code
= ERROR_MARK
;
9408 if (TREE_CODE (expr
.value
) != COMPONENT_REF
)
9409 expr
.original_type
= NULL
;
9412 /* Remember the original type of a bitfield. */
9413 tree field
= TREE_OPERAND (expr
.value
, 1);
9414 if (TREE_CODE (field
) != FIELD_DECL
)
9415 expr
.original_type
= NULL
;
9417 expr
.original_type
= DECL_BIT_FIELD_TYPE (field
);
9421 /* Postincrement. */
9422 start
= expr
.get_start ();
9423 finish
= c_parser_peek_token (parser
)->get_finish ();
9424 c_parser_consume_token (parser
);
9425 /* If the expressions have array notations, we expand them. */
9427 && TREE_CODE (expr
.value
) == ARRAY_NOTATION_REF
)
9428 expr
= fix_array_notation_expr (expr_loc
, POSTINCREMENT_EXPR
, expr
);
9431 expr
= default_function_array_read_conversion (expr_loc
, expr
);
9432 expr
.value
= build_unary_op (op_loc
, POSTINCREMENT_EXPR
,
9435 set_c_expr_source_range (&expr
, start
, finish
);
9436 expr
.original_code
= ERROR_MARK
;
9437 expr
.original_type
= NULL
;
9439 case CPP_MINUS_MINUS
:
9440 /* Postdecrement. */
9441 start
= expr
.get_start ();
9442 finish
= c_parser_peek_token (parser
)->get_finish ();
9443 c_parser_consume_token (parser
);
9444 /* If the expressions have array notations, we expand them. */
9446 && TREE_CODE (expr
.value
) == ARRAY_NOTATION_REF
)
9447 expr
= fix_array_notation_expr (expr_loc
, POSTDECREMENT_EXPR
, expr
);
9450 expr
= default_function_array_read_conversion (expr_loc
, expr
);
9451 expr
.value
= build_unary_op (op_loc
, POSTDECREMENT_EXPR
,
9454 set_c_expr_source_range (&expr
, start
, finish
);
9455 expr
.original_code
= ERROR_MARK
;
9456 expr
.original_type
= NULL
;
9464 /* Parse an expression (C90 6.3.17, C99 6.5.17, C11 6.5.17).
9467 assignment-expression
9468 expression , assignment-expression
9471 static struct c_expr
9472 c_parser_expression (c_parser
*parser
)
9474 location_t tloc
= c_parser_peek_token (parser
)->location
;
9476 expr
= c_parser_expr_no_commas (parser
, NULL
);
9477 if (c_parser_next_token_is (parser
, CPP_COMMA
))
9478 expr
= convert_lvalue_to_rvalue (tloc
, expr
, true, false);
9479 while (c_parser_next_token_is (parser
, CPP_COMMA
))
9483 location_t loc
= c_parser_peek_token (parser
)->location
;
9484 location_t expr_loc
;
9485 c_parser_consume_token (parser
);
9486 expr_loc
= c_parser_peek_token (parser
)->location
;
9487 lhsval
= expr
.value
;
9488 while (TREE_CODE (lhsval
) == COMPOUND_EXPR
)
9489 lhsval
= TREE_OPERAND (lhsval
, 1);
9490 if (DECL_P (lhsval
) || handled_component_p (lhsval
))
9491 mark_exp_read (lhsval
);
9492 next
= c_parser_expr_no_commas (parser
, NULL
);
9493 next
= convert_lvalue_to_rvalue (expr_loc
, next
, true, false);
9494 expr
.value
= build_compound_expr (loc
, expr
.value
, next
.value
);
9495 expr
.original_code
= COMPOUND_EXPR
;
9496 expr
.original_type
= next
.original_type
;
9501 /* Parse an expression and convert functions or arrays to pointers and
9502 lvalues to rvalues. */
9504 static struct c_expr
9505 c_parser_expression_conv (c_parser
*parser
)
9508 location_t loc
= c_parser_peek_token (parser
)->location
;
9509 expr
= c_parser_expression (parser
);
9510 expr
= convert_lvalue_to_rvalue (loc
, expr
, true, false);
9514 /* Helper function of c_parser_expr_list. Check if IDXth (0 based)
9515 argument is a literal zero alone and if so, set it in literal_zero_mask. */
9518 c_parser_check_literal_zero (c_parser
*parser
, unsigned *literal_zero_mask
,
9521 if (idx
>= HOST_BITS_PER_INT
)
9524 c_token
*tok
= c_parser_peek_token (parser
);
9532 /* If a parameter is literal zero alone, remember it
9533 for -Wmemset-transposed-args warning. */
9534 if (integer_zerop (tok
->value
)
9535 && !TREE_OVERFLOW (tok
->value
)
9536 && (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
9537 || c_parser_peek_2nd_token (parser
)->type
== CPP_CLOSE_PAREN
))
9538 *literal_zero_mask
|= 1U << idx
;
9544 /* Parse a non-empty list of expressions. If CONVERT_P, convert
9545 functions and arrays to pointers and lvalues to rvalues. If
9546 FOLD_P, fold the expressions. If LOCATIONS is non-NULL, save the
9547 locations of function arguments into this vector.
9550 assignment-expression
9551 nonempty-expr-list , assignment-expression
9554 static vec
<tree
, va_gc
> *
9555 c_parser_expr_list (c_parser
*parser
, bool convert_p
, bool fold_p
,
9556 vec
<tree
, va_gc
> **p_orig_types
,
9557 location_t
*sizeof_arg_loc
, tree
*sizeof_arg
,
9558 vec
<location_t
> *locations
,
9559 unsigned int *literal_zero_mask
)
9561 vec
<tree
, va_gc
> *ret
;
9562 vec
<tree
, va_gc
> *orig_types
;
9564 unsigned int idx
= 0;
9566 ret
= make_tree_vector ();
9567 if (p_orig_types
== NULL
)
9570 orig_types
= make_tree_vector ();
9572 if (literal_zero_mask
)
9573 c_parser_check_literal_zero (parser
, literal_zero_mask
, 0);
9574 expr
= c_parser_expr_no_commas (parser
, NULL
);
9576 expr
= convert_lvalue_to_rvalue (expr
.get_location (), expr
, true, true);
9578 expr
.value
= c_fully_fold (expr
.value
, false, NULL
);
9579 ret
->quick_push (expr
.value
);
9581 orig_types
->quick_push (expr
.original_type
);
9583 locations
->safe_push (expr
.get_location ());
9584 if (sizeof_arg
!= NULL
9585 && expr
.original_code
== SIZEOF_EXPR
)
9587 sizeof_arg
[0] = c_last_sizeof_arg
;
9588 sizeof_arg_loc
[0] = c_last_sizeof_loc
;
9590 while (c_parser_next_token_is (parser
, CPP_COMMA
))
9592 c_parser_consume_token (parser
);
9593 if (literal_zero_mask
)
9594 c_parser_check_literal_zero (parser
, literal_zero_mask
, idx
+ 1);
9595 expr
= c_parser_expr_no_commas (parser
, NULL
);
9597 expr
= convert_lvalue_to_rvalue (expr
.get_location (), expr
, true,
9600 expr
.value
= c_fully_fold (expr
.value
, false, NULL
);
9601 vec_safe_push (ret
, expr
.value
);
9603 vec_safe_push (orig_types
, expr
.original_type
);
9605 locations
->safe_push (expr
.get_location ());
9607 && sizeof_arg
!= NULL
9608 && expr
.original_code
== SIZEOF_EXPR
)
9610 sizeof_arg
[idx
] = c_last_sizeof_arg
;
9611 sizeof_arg_loc
[idx
] = c_last_sizeof_loc
;
9615 *p_orig_types
= orig_types
;
9619 /* Parse Objective-C-specific constructs. */
9621 /* Parse an objc-class-definition.
9623 objc-class-definition:
9624 @interface identifier objc-superclass[opt] objc-protocol-refs[opt]
9625 objc-class-instance-variables[opt] objc-methodprotolist @end
9626 @implementation identifier objc-superclass[opt]
9627 objc-class-instance-variables[opt]
9628 @interface identifier ( identifier ) objc-protocol-refs[opt]
9629 objc-methodprotolist @end
9630 @interface identifier ( ) objc-protocol-refs[opt]
9631 objc-methodprotolist @end
9632 @implementation identifier ( identifier )
9637 "@interface identifier (" must start "@interface identifier (
9638 identifier ) ...": objc-methodprotolist in the first production may
9639 not start with a parenthesized identifier as a declarator of a data
9640 definition with no declaration specifiers if the objc-superclass,
9641 objc-protocol-refs and objc-class-instance-variables are omitted. */
9644 c_parser_objc_class_definition (c_parser
*parser
, tree attributes
)
9649 if (c_parser_next_token_is_keyword (parser
, RID_AT_INTERFACE
))
9651 else if (c_parser_next_token_is_keyword (parser
, RID_AT_IMPLEMENTATION
))
9656 c_parser_consume_token (parser
);
9657 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
9659 c_parser_error (parser
, "expected identifier");
9662 id1
= c_parser_peek_token (parser
)->value
;
9663 c_parser_consume_token (parser
);
9664 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
9666 /* We have a category or class extension. */
9668 tree proto
= NULL_TREE
;
9669 matching_parens parens
;
9670 parens
.consume_open (parser
);
9671 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
9673 if (iface_p
&& c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
9675 /* We have a class extension. */
9680 c_parser_error (parser
, "expected identifier or %<)%>");
9681 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
9687 id2
= c_parser_peek_token (parser
)->value
;
9688 c_parser_consume_token (parser
);
9690 parens
.skip_until_found_close (parser
);
9693 objc_start_category_implementation (id1
, id2
);
9696 if (c_parser_next_token_is (parser
, CPP_LESS
))
9697 proto
= c_parser_objc_protocol_refs (parser
);
9698 objc_start_category_interface (id1
, id2
, proto
, attributes
);
9699 c_parser_objc_methodprotolist (parser
);
9700 c_parser_require_keyword (parser
, RID_AT_END
, "expected %<@end%>");
9701 objc_finish_interface ();
9704 if (c_parser_next_token_is (parser
, CPP_COLON
))
9706 c_parser_consume_token (parser
);
9707 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
9709 c_parser_error (parser
, "expected identifier");
9712 superclass
= c_parser_peek_token (parser
)->value
;
9713 c_parser_consume_token (parser
);
9716 superclass
= NULL_TREE
;
9719 tree proto
= NULL_TREE
;
9720 if (c_parser_next_token_is (parser
, CPP_LESS
))
9721 proto
= c_parser_objc_protocol_refs (parser
);
9722 objc_start_class_interface (id1
, superclass
, proto
, attributes
);
9725 objc_start_class_implementation (id1
, superclass
);
9726 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
9727 c_parser_objc_class_instance_variables (parser
);
9730 objc_continue_interface ();
9731 c_parser_objc_methodprotolist (parser
);
9732 c_parser_require_keyword (parser
, RID_AT_END
, "expected %<@end%>");
9733 objc_finish_interface ();
9737 objc_continue_implementation ();
9742 /* Parse objc-class-instance-variables.
9744 objc-class-instance-variables:
9745 { objc-instance-variable-decl-list[opt] }
9747 objc-instance-variable-decl-list:
9748 objc-visibility-spec
9749 objc-instance-variable-decl ;
9751 objc-instance-variable-decl-list objc-visibility-spec
9752 objc-instance-variable-decl-list objc-instance-variable-decl ;
9753 objc-instance-variable-decl-list ;
9755 objc-visibility-spec:
9760 objc-instance-variable-decl:
9765 c_parser_objc_class_instance_variables (c_parser
*parser
)
9767 gcc_assert (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
));
9768 c_parser_consume_token (parser
);
9769 while (c_parser_next_token_is_not (parser
, CPP_EOF
))
9772 /* Parse any stray semicolon. */
9773 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
9775 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
9777 c_parser_consume_token (parser
);
9780 /* Stop if at the end of the instance variables. */
9781 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
9783 c_parser_consume_token (parser
);
9786 /* Parse any objc-visibility-spec. */
9787 if (c_parser_next_token_is_keyword (parser
, RID_AT_PRIVATE
))
9789 c_parser_consume_token (parser
);
9790 objc_set_visibility (OBJC_IVAR_VIS_PRIVATE
);
9793 else if (c_parser_next_token_is_keyword (parser
, RID_AT_PROTECTED
))
9795 c_parser_consume_token (parser
);
9796 objc_set_visibility (OBJC_IVAR_VIS_PROTECTED
);
9799 else if (c_parser_next_token_is_keyword (parser
, RID_AT_PUBLIC
))
9801 c_parser_consume_token (parser
);
9802 objc_set_visibility (OBJC_IVAR_VIS_PUBLIC
);
9805 else if (c_parser_next_token_is_keyword (parser
, RID_AT_PACKAGE
))
9807 c_parser_consume_token (parser
);
9808 objc_set_visibility (OBJC_IVAR_VIS_PACKAGE
);
9811 else if (c_parser_next_token_is (parser
, CPP_PRAGMA
))
9813 c_parser_pragma (parser
, pragma_external
, NULL
);
9817 /* Parse some comma-separated declarations. */
9818 decls
= c_parser_struct_declaration (parser
);
9821 /* There is a syntax error. We want to skip the offending
9822 tokens up to the next ';' (included) or '}'
9825 /* First, skip manually a ')' or ']'. This is because they
9826 reduce the nesting level, so c_parser_skip_until_found()
9827 wouldn't be able to skip past them. */
9828 c_token
*token
= c_parser_peek_token (parser
);
9829 if (token
->type
== CPP_CLOSE_PAREN
|| token
->type
== CPP_CLOSE_SQUARE
)
9830 c_parser_consume_token (parser
);
9832 /* Then, do the standard skipping. */
9833 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
9835 /* We hopefully recovered. Start normal parsing again. */
9836 parser
->error
= false;
9841 /* Comma-separated instance variables are chained together
9842 in reverse order; add them one by one. */
9843 tree ivar
= nreverse (decls
);
9844 for (; ivar
; ivar
= DECL_CHAIN (ivar
))
9845 objc_add_instance_variable (copy_node (ivar
));
9847 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
9851 /* Parse an objc-class-declaration.
9853 objc-class-declaration:
9854 @class identifier-list ;
9858 c_parser_objc_class_declaration (c_parser
*parser
)
9860 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_CLASS
));
9861 c_parser_consume_token (parser
);
9862 /* Any identifiers, including those declared as type names, are OK
9867 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
9869 c_parser_error (parser
, "expected identifier");
9870 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
9871 parser
->error
= false;
9874 id
= c_parser_peek_token (parser
)->value
;
9875 objc_declare_class (id
);
9876 c_parser_consume_token (parser
);
9877 if (c_parser_next_token_is (parser
, CPP_COMMA
))
9878 c_parser_consume_token (parser
);
9882 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
9885 /* Parse an objc-alias-declaration.
9887 objc-alias-declaration:
9888 @compatibility_alias identifier identifier ;
9892 c_parser_objc_alias_declaration (c_parser
*parser
)
9895 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_ALIAS
));
9896 c_parser_consume_token (parser
);
9897 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
9899 c_parser_error (parser
, "expected identifier");
9900 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
9903 id1
= c_parser_peek_token (parser
)->value
;
9904 c_parser_consume_token (parser
);
9905 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
9907 c_parser_error (parser
, "expected identifier");
9908 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
9911 id2
= c_parser_peek_token (parser
)->value
;
9912 c_parser_consume_token (parser
);
9913 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
9914 objc_declare_alias (id1
, id2
);
9917 /* Parse an objc-protocol-definition.
9919 objc-protocol-definition:
9920 @protocol identifier objc-protocol-refs[opt] objc-methodprotolist @end
9921 @protocol identifier-list ;
9923 "@protocol identifier ;" should be resolved as "@protocol
9924 identifier-list ;": objc-methodprotolist may not start with a
9925 semicolon in the first alternative if objc-protocol-refs are
9929 c_parser_objc_protocol_definition (c_parser
*parser
, tree attributes
)
9931 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_PROTOCOL
));
9933 c_parser_consume_token (parser
);
9934 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
9936 c_parser_error (parser
, "expected identifier");
9939 if (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
9940 || c_parser_peek_2nd_token (parser
)->type
== CPP_SEMICOLON
)
9942 /* Any identifiers, including those declared as type names, are
9947 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
9949 c_parser_error (parser
, "expected identifier");
9952 id
= c_parser_peek_token (parser
)->value
;
9953 objc_declare_protocol (id
, attributes
);
9954 c_parser_consume_token (parser
);
9955 if (c_parser_next_token_is (parser
, CPP_COMMA
))
9956 c_parser_consume_token (parser
);
9960 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
9964 tree id
= c_parser_peek_token (parser
)->value
;
9965 tree proto
= NULL_TREE
;
9966 c_parser_consume_token (parser
);
9967 if (c_parser_next_token_is (parser
, CPP_LESS
))
9968 proto
= c_parser_objc_protocol_refs (parser
);
9969 parser
->objc_pq_context
= true;
9970 objc_start_protocol (id
, proto
, attributes
);
9971 c_parser_objc_methodprotolist (parser
);
9972 c_parser_require_keyword (parser
, RID_AT_END
, "expected %<@end%>");
9973 parser
->objc_pq_context
= false;
9974 objc_finish_interface ();
9978 /* Parse an objc-method-type.
9984 Return true if it is a class method (+) and false if it is
9985 an instance method (-).
9988 c_parser_objc_method_type (c_parser
*parser
)
9990 switch (c_parser_peek_token (parser
)->type
)
9993 c_parser_consume_token (parser
);
9996 c_parser_consume_token (parser
);
10003 /* Parse an objc-method-definition.
10005 objc-method-definition:
10006 objc-method-type objc-method-decl ;[opt] compound-statement
10010 c_parser_objc_method_definition (c_parser
*parser
)
10012 bool is_class_method
= c_parser_objc_method_type (parser
);
10013 tree decl
, attributes
= NULL_TREE
, expr
= NULL_TREE
;
10014 parser
->objc_pq_context
= true;
10015 decl
= c_parser_objc_method_decl (parser
, is_class_method
, &attributes
,
10017 if (decl
== error_mark_node
)
10018 return; /* Bail here. */
10020 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
10022 c_parser_consume_token (parser
);
10023 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
10024 "extra semicolon in method definition specified");
10027 if (!c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
10029 c_parser_error (parser
, "expected %<{%>");
10033 parser
->objc_pq_context
= false;
10034 if (objc_start_method_definition (is_class_method
, decl
, attributes
, expr
))
10036 add_stmt (c_parser_compound_statement (parser
));
10037 objc_finish_method_definition (current_function_decl
);
10041 /* This code is executed when we find a method definition
10042 outside of an @implementation context (or invalid for other
10043 reasons). Parse the method (to keep going) but do not emit
10046 c_parser_compound_statement (parser
);
10050 /* Parse an objc-methodprotolist.
10052 objc-methodprotolist:
10054 objc-methodprotolist objc-methodproto
10055 objc-methodprotolist declaration
10056 objc-methodprotolist ;
10060 The declaration is a data definition, which may be missing
10061 declaration specifiers under the same rules and diagnostics as
10062 other data definitions outside functions, and the stray semicolon
10063 is diagnosed the same way as a stray semicolon outside a
10067 c_parser_objc_methodprotolist (c_parser
*parser
)
10071 /* The list is terminated by @end. */
10072 switch (c_parser_peek_token (parser
)->type
)
10074 case CPP_SEMICOLON
:
10075 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
10076 "ISO C does not allow extra %<;%> outside of a function");
10077 c_parser_consume_token (parser
);
10081 c_parser_objc_methodproto (parser
);
10084 c_parser_pragma (parser
, pragma_external
, NULL
);
10089 if (c_parser_next_token_is_keyword (parser
, RID_AT_END
))
10091 else if (c_parser_next_token_is_keyword (parser
, RID_AT_PROPERTY
))
10092 c_parser_objc_at_property_declaration (parser
);
10093 else if (c_parser_next_token_is_keyword (parser
, RID_AT_OPTIONAL
))
10095 objc_set_method_opt (true);
10096 c_parser_consume_token (parser
);
10098 else if (c_parser_next_token_is_keyword (parser
, RID_AT_REQUIRED
))
10100 objc_set_method_opt (false);
10101 c_parser_consume_token (parser
);
10104 c_parser_declaration_or_fndef (parser
, false, false, true,
10105 false, true, NULL
, vNULL
);
10111 /* Parse an objc-methodproto.
10114 objc-method-type objc-method-decl ;
10118 c_parser_objc_methodproto (c_parser
*parser
)
10120 bool is_class_method
= c_parser_objc_method_type (parser
);
10121 tree decl
, attributes
= NULL_TREE
;
10123 /* Remember protocol qualifiers in prototypes. */
10124 parser
->objc_pq_context
= true;
10125 decl
= c_parser_objc_method_decl (parser
, is_class_method
, &attributes
,
10127 /* Forget protocol qualifiers now. */
10128 parser
->objc_pq_context
= false;
10130 /* Do not allow the presence of attributes to hide an erroneous
10131 method implementation in the interface section. */
10132 if (!c_parser_next_token_is (parser
, CPP_SEMICOLON
))
10134 c_parser_error (parser
, "expected %<;%>");
10138 if (decl
!= error_mark_node
)
10139 objc_add_method_declaration (is_class_method
, decl
, attributes
);
10141 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
10144 /* If we are at a position that method attributes may be present, check that
10145 there are not any parsed already (a syntax error) and then collect any
10146 specified at the current location. Finally, if new attributes were present,
10147 check that the next token is legal ( ';' for decls and '{' for defs). */
10150 c_parser_objc_maybe_method_attributes (c_parser
* parser
, tree
* attributes
)
10155 c_parser_error (parser
,
10156 "method attributes must be specified at the end only");
10157 *attributes
= NULL_TREE
;
10161 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
10162 *attributes
= c_parser_attributes (parser
);
10164 /* If there were no attributes here, just report any earlier error. */
10165 if (*attributes
== NULL_TREE
|| bad
)
10168 /* If the attributes are followed by a ; or {, then just report any earlier
10170 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
)
10171 || c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
10174 /* We've got attributes, but not at the end. */
10175 c_parser_error (parser
,
10176 "expected %<;%> or %<{%> after method attribute definition");
10180 /* Parse an objc-method-decl.
10183 ( objc-type-name ) objc-selector
10185 ( objc-type-name ) objc-keyword-selector objc-optparmlist
10186 objc-keyword-selector objc-optparmlist
10189 objc-keyword-selector:
10191 objc-keyword-selector objc-keyword-decl
10194 objc-selector : ( objc-type-name ) identifier
10195 objc-selector : identifier
10196 : ( objc-type-name ) identifier
10200 objc-optparms objc-optellipsis
10204 objc-opt-parms , parameter-declaration
10212 c_parser_objc_method_decl (c_parser
*parser
, bool is_class_method
,
10213 tree
*attributes
, tree
*expr
)
10215 tree type
= NULL_TREE
;
10217 tree parms
= NULL_TREE
;
10218 bool ellipsis
= false;
10219 bool attr_err
= false;
10221 *attributes
= NULL_TREE
;
10222 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
10224 matching_parens parens
;
10225 parens
.consume_open (parser
);
10226 type
= c_parser_objc_type_name (parser
);
10227 parens
.skip_until_found_close (parser
);
10229 sel
= c_parser_objc_selector (parser
);
10230 /* If there is no selector, or a colon follows, we have an
10231 objc-keyword-selector. If there is a selector, and a colon does
10232 not follow, that selector ends the objc-method-decl. */
10233 if (!sel
|| c_parser_next_token_is (parser
, CPP_COLON
))
10236 tree list
= NULL_TREE
;
10239 tree atype
= NULL_TREE
, id
, keyworddecl
;
10240 tree param_attr
= NULL_TREE
;
10241 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
10243 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
10245 c_parser_consume_token (parser
);
10246 atype
= c_parser_objc_type_name (parser
);
10247 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
10250 /* New ObjC allows attributes on method parameters. */
10251 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
10252 param_attr
= c_parser_attributes (parser
);
10253 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
10255 c_parser_error (parser
, "expected identifier");
10256 return error_mark_node
;
10258 id
= c_parser_peek_token (parser
)->value
;
10259 c_parser_consume_token (parser
);
10260 keyworddecl
= objc_build_keyword_decl (tsel
, atype
, id
, param_attr
);
10261 list
= chainon (list
, keyworddecl
);
10262 tsel
= c_parser_objc_selector (parser
);
10263 if (!tsel
&& c_parser_next_token_is_not (parser
, CPP_COLON
))
10267 attr_err
|= c_parser_objc_maybe_method_attributes (parser
, attributes
) ;
10269 /* Parse the optional parameter list. Optional Objective-C
10270 method parameters follow the C syntax, and may include '...'
10271 to denote a variable number of arguments. */
10272 parms
= make_node (TREE_LIST
);
10273 while (c_parser_next_token_is (parser
, CPP_COMMA
))
10275 struct c_parm
*parm
;
10276 c_parser_consume_token (parser
);
10277 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
10280 c_parser_consume_token (parser
);
10281 attr_err
|= c_parser_objc_maybe_method_attributes
10282 (parser
, attributes
) ;
10285 parm
= c_parser_parameter_declaration (parser
, NULL_TREE
);
10288 parms
= chainon (parms
,
10289 build_tree_list (NULL_TREE
, grokparm (parm
, expr
)));
10294 attr_err
|= c_parser_objc_maybe_method_attributes (parser
, attributes
) ;
10298 c_parser_error (parser
, "objective-c method declaration is expected");
10299 return error_mark_node
;
10303 return error_mark_node
;
10305 return objc_build_method_signature (is_class_method
, type
, sel
, parms
, ellipsis
);
10308 /* Parse an objc-type-name.
10311 objc-type-qualifiers[opt] type-name
10312 objc-type-qualifiers[opt]
10314 objc-type-qualifiers:
10315 objc-type-qualifier
10316 objc-type-qualifiers objc-type-qualifier
10318 objc-type-qualifier: one of
10319 in out inout bycopy byref oneway
10323 c_parser_objc_type_name (c_parser
*parser
)
10325 tree quals
= NULL_TREE
;
10326 struct c_type_name
*type_name
= NULL
;
10327 tree type
= NULL_TREE
;
10330 c_token
*token
= c_parser_peek_token (parser
);
10331 if (token
->type
== CPP_KEYWORD
10332 && (token
->keyword
== RID_IN
10333 || token
->keyword
== RID_OUT
10334 || token
->keyword
== RID_INOUT
10335 || token
->keyword
== RID_BYCOPY
10336 || token
->keyword
== RID_BYREF
10337 || token
->keyword
== RID_ONEWAY
))
10339 quals
= chainon (build_tree_list (NULL_TREE
, token
->value
), quals
);
10340 c_parser_consume_token (parser
);
10345 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_type
))
10346 type_name
= c_parser_type_name (parser
);
10348 type
= groktypename (type_name
, NULL
, NULL
);
10350 /* If the type is unknown, and error has already been produced and
10351 we need to recover from the error. In that case, use NULL_TREE
10352 for the type, as if no type had been specified; this will use the
10353 default type ('id') which is good for error recovery. */
10354 if (type
== error_mark_node
)
10357 return build_tree_list (quals
, type
);
10360 /* Parse objc-protocol-refs.
10362 objc-protocol-refs:
10363 < identifier-list >
10367 c_parser_objc_protocol_refs (c_parser
*parser
)
10369 tree list
= NULL_TREE
;
10370 gcc_assert (c_parser_next_token_is (parser
, CPP_LESS
));
10371 c_parser_consume_token (parser
);
10372 /* Any identifiers, including those declared as type names, are OK
10377 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
10379 c_parser_error (parser
, "expected identifier");
10382 id
= c_parser_peek_token (parser
)->value
;
10383 list
= chainon (list
, build_tree_list (NULL_TREE
, id
));
10384 c_parser_consume_token (parser
);
10385 if (c_parser_next_token_is (parser
, CPP_COMMA
))
10386 c_parser_consume_token (parser
);
10390 c_parser_require (parser
, CPP_GREATER
, "expected %<>%>");
10394 /* Parse an objc-try-catch-finally-statement.
10396 objc-try-catch-finally-statement:
10397 @try compound-statement objc-catch-list[opt]
10398 @try compound-statement objc-catch-list[opt] @finally compound-statement
10401 @catch ( objc-catch-parameter-declaration ) compound-statement
10402 objc-catch-list @catch ( objc-catch-parameter-declaration ) compound-statement
10404 objc-catch-parameter-declaration:
10405 parameter-declaration
10408 where '...' is to be interpreted literally, that is, it means CPP_ELLIPSIS.
10410 PS: This function is identical to cp_parser_objc_try_catch_finally_statement
10411 for C++. Keep them in sync. */
10414 c_parser_objc_try_catch_finally_statement (c_parser
*parser
)
10416 location_t location
;
10419 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_TRY
));
10420 c_parser_consume_token (parser
);
10421 location
= c_parser_peek_token (parser
)->location
;
10422 objc_maybe_warn_exceptions (location
);
10423 stmt
= c_parser_compound_statement (parser
);
10424 objc_begin_try_stmt (location
, stmt
);
10426 while (c_parser_next_token_is_keyword (parser
, RID_AT_CATCH
))
10428 struct c_parm
*parm
;
10429 tree parameter_declaration
= error_mark_node
;
10430 bool seen_open_paren
= false;
10432 c_parser_consume_token (parser
);
10433 matching_parens parens
;
10434 if (!parens
.require_open (parser
))
10435 seen_open_paren
= true;
10436 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
10438 /* We have "@catch (...)" (where the '...' are literally
10439 what is in the code). Skip the '...'.
10440 parameter_declaration is set to NULL_TREE, and
10441 objc_being_catch_clauses() knows that that means
10443 c_parser_consume_token (parser
);
10444 parameter_declaration
= NULL_TREE
;
10448 /* We have "@catch (NSException *exception)" or something
10449 like that. Parse the parameter declaration. */
10450 parm
= c_parser_parameter_declaration (parser
, NULL_TREE
);
10452 parameter_declaration
= error_mark_node
;
10454 parameter_declaration
= grokparm (parm
, NULL
);
10456 if (seen_open_paren
)
10457 parens
.require_close (parser
);
10460 /* If there was no open parenthesis, we are recovering from
10461 an error, and we are trying to figure out what mistake
10462 the user has made. */
10464 /* If there is an immediate closing parenthesis, the user
10465 probably forgot the opening one (ie, they typed "@catch
10466 NSException *e)". Parse the closing parenthesis and keep
10468 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
10469 c_parser_consume_token (parser
);
10471 /* If these is no immediate closing parenthesis, the user
10472 probably doesn't know that parenthesis are required at
10473 all (ie, they typed "@catch NSException *e"). So, just
10474 forget about the closing parenthesis and keep going. */
10476 objc_begin_catch_clause (parameter_declaration
);
10477 if (c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
10478 c_parser_compound_statement_nostart (parser
);
10479 objc_finish_catch_clause ();
10481 if (c_parser_next_token_is_keyword (parser
, RID_AT_FINALLY
))
10483 c_parser_consume_token (parser
);
10484 location
= c_parser_peek_token (parser
)->location
;
10485 stmt
= c_parser_compound_statement (parser
);
10486 objc_build_finally_clause (location
, stmt
);
10488 objc_finish_try_stmt ();
10491 /* Parse an objc-synchronized-statement.
10493 objc-synchronized-statement:
10494 @synchronized ( expression ) compound-statement
10498 c_parser_objc_synchronized_statement (c_parser
*parser
)
10502 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_SYNCHRONIZED
));
10503 c_parser_consume_token (parser
);
10504 loc
= c_parser_peek_token (parser
)->location
;
10505 objc_maybe_warn_exceptions (loc
);
10506 matching_parens parens
;
10507 if (parens
.require_open (parser
))
10509 struct c_expr ce
= c_parser_expression (parser
);
10510 ce
= convert_lvalue_to_rvalue (loc
, ce
, false, false);
10512 expr
= c_fully_fold (expr
, false, NULL
);
10513 parens
.skip_until_found_close (parser
);
10516 expr
= error_mark_node
;
10517 stmt
= c_parser_compound_statement (parser
);
10518 objc_build_synchronized (loc
, expr
, stmt
);
10521 /* Parse an objc-selector; return NULL_TREE without an error if the
10522 next token is not an objc-selector.
10527 enum struct union if else while do for switch case default
10528 break continue return goto asm sizeof typeof __alignof
10529 unsigned long const short volatile signed restrict _Complex
10530 in out inout bycopy byref oneway int char float double void _Bool
10533 ??? Why this selection of keywords but not, for example, storage
10534 class specifiers? */
10537 c_parser_objc_selector (c_parser
*parser
)
10539 c_token
*token
= c_parser_peek_token (parser
);
10540 tree value
= token
->value
;
10541 if (token
->type
== CPP_NAME
)
10543 c_parser_consume_token (parser
);
10546 if (token
->type
!= CPP_KEYWORD
)
10548 switch (token
->keyword
)
10587 CASE_RID_FLOATN_NX
:
10591 case RID_AUTO_TYPE
:
10596 c_parser_consume_token (parser
);
10603 /* Parse an objc-selector-arg.
10607 objc-keywordname-list
10609 objc-keywordname-list:
10611 objc-keywordname-list objc-keywordname
10619 c_parser_objc_selector_arg (c_parser
*parser
)
10621 tree sel
= c_parser_objc_selector (parser
);
10622 tree list
= NULL_TREE
;
10623 if (sel
&& c_parser_next_token_is_not (parser
, CPP_COLON
))
10627 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
10629 list
= chainon (list
, build_tree_list (sel
, NULL_TREE
));
10630 sel
= c_parser_objc_selector (parser
);
10631 if (!sel
&& c_parser_next_token_is_not (parser
, CPP_COLON
))
10637 /* Parse an objc-receiver.
10646 c_parser_objc_receiver (c_parser
*parser
)
10648 location_t loc
= c_parser_peek_token (parser
)->location
;
10650 if (c_parser_peek_token (parser
)->type
== CPP_NAME
10651 && (c_parser_peek_token (parser
)->id_kind
== C_ID_TYPENAME
10652 || c_parser_peek_token (parser
)->id_kind
== C_ID_CLASSNAME
))
10654 tree id
= c_parser_peek_token (parser
)->value
;
10655 c_parser_consume_token (parser
);
10656 return objc_get_class_reference (id
);
10658 struct c_expr ce
= c_parser_expression (parser
);
10659 ce
= convert_lvalue_to_rvalue (loc
, ce
, false, false);
10660 return c_fully_fold (ce
.value
, false, NULL
);
10663 /* Parse objc-message-args.
10667 objc-keywordarg-list
10669 objc-keywordarg-list:
10671 objc-keywordarg-list objc-keywordarg
10674 objc-selector : objc-keywordexpr
10679 c_parser_objc_message_args (c_parser
*parser
)
10681 tree sel
= c_parser_objc_selector (parser
);
10682 tree list
= NULL_TREE
;
10683 if (sel
&& c_parser_next_token_is_not (parser
, CPP_COLON
))
10688 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
10689 return error_mark_node
;
10690 keywordexpr
= c_parser_objc_keywordexpr (parser
);
10691 list
= chainon (list
, build_tree_list (sel
, keywordexpr
));
10692 sel
= c_parser_objc_selector (parser
);
10693 if (!sel
&& c_parser_next_token_is_not (parser
, CPP_COLON
))
10699 /* Parse an objc-keywordexpr.
10706 c_parser_objc_keywordexpr (c_parser
*parser
)
10709 vec
<tree
, va_gc
> *expr_list
= c_parser_expr_list (parser
, true, true,
10710 NULL
, NULL
, NULL
, NULL
);
10711 if (vec_safe_length (expr_list
) == 1)
10713 /* Just return the expression, remove a level of
10715 ret
= (*expr_list
)[0];
10719 /* We have a comma expression, we will collapse later. */
10720 ret
= build_tree_list_vec (expr_list
);
10722 release_tree_vector (expr_list
);
10726 /* A check, needed in several places, that ObjC interface, implementation or
10727 method definitions are not prefixed by incorrect items. */
10729 c_parser_objc_diagnose_bad_element_prefix (c_parser
*parser
,
10730 struct c_declspecs
*specs
)
10732 if (!specs
->declspecs_seen_p
|| specs
->non_sc_seen_p
10733 || specs
->typespec_kind
!= ctsk_none
)
10735 c_parser_error (parser
,
10736 "no type or storage class may be specified here,");
10737 c_parser_skip_to_end_of_block_or_statement (parser
);
10743 /* Parse an Objective-C @property declaration. The syntax is:
10745 objc-property-declaration:
10746 '@property' objc-property-attributes[opt] struct-declaration ;
10748 objc-property-attributes:
10749 '(' objc-property-attribute-list ')'
10751 objc-property-attribute-list:
10752 objc-property-attribute
10753 objc-property-attribute-list, objc-property-attribute
10755 objc-property-attribute
10756 'getter' = identifier
10757 'setter' = identifier
10766 @property NSString *name;
10767 @property (readonly) id object;
10768 @property (retain, nonatomic, getter=getTheName) id name;
10769 @property int a, b, c;
10771 PS: This function is identical to cp_parser_objc_at_propery_declaration
10772 for C++. Keep them in sync. */
10774 c_parser_objc_at_property_declaration (c_parser
*parser
)
10776 /* The following variables hold the attributes of the properties as
10777 parsed. They are 'false' or 'NULL_TREE' if the attribute was not
10778 seen. When we see an attribute, we set them to 'true' (if they
10779 are boolean properties) or to the identifier (if they have an
10780 argument, ie, for getter and setter). Note that here we only
10781 parse the list of attributes, check the syntax and accumulate the
10782 attributes that we find. objc_add_property_declaration() will
10783 then process the information. */
10784 bool property_assign
= false;
10785 bool property_copy
= false;
10786 tree property_getter_ident
= NULL_TREE
;
10787 bool property_nonatomic
= false;
10788 bool property_readonly
= false;
10789 bool property_readwrite
= false;
10790 bool property_retain
= false;
10791 tree property_setter_ident
= NULL_TREE
;
10793 /* 'properties' is the list of properties that we read. Usually a
10794 single one, but maybe more (eg, in "@property int a, b, c;" there
10799 loc
= c_parser_peek_token (parser
)->location
;
10800 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_PROPERTY
));
10802 c_parser_consume_token (parser
); /* Eat '@property'. */
10804 /* Parse the optional attribute list... */
10805 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
10807 matching_parens parens
;
10810 parens
.consume_open (parser
);
10812 /* Property attribute keywords are valid now. */
10813 parser
->objc_property_attr_context
= true;
10817 bool syntax_error
= false;
10818 c_token
*token
= c_parser_peek_token (parser
);
10821 if (token
->type
!= CPP_KEYWORD
)
10823 if (token
->type
== CPP_CLOSE_PAREN
)
10824 c_parser_error (parser
, "expected identifier");
10827 c_parser_consume_token (parser
);
10828 c_parser_error (parser
, "unknown property attribute");
10832 keyword
= token
->keyword
;
10833 c_parser_consume_token (parser
);
10836 case RID_ASSIGN
: property_assign
= true; break;
10837 case RID_COPY
: property_copy
= true; break;
10838 case RID_NONATOMIC
: property_nonatomic
= true; break;
10839 case RID_READONLY
: property_readonly
= true; break;
10840 case RID_READWRITE
: property_readwrite
= true; break;
10841 case RID_RETAIN
: property_retain
= true; break;
10845 if (c_parser_next_token_is_not (parser
, CPP_EQ
))
10847 if (keyword
== RID_GETTER
)
10848 c_parser_error (parser
,
10849 "missing %<=%> (after %<getter%> attribute)");
10851 c_parser_error (parser
,
10852 "missing %<=%> (after %<setter%> attribute)");
10853 syntax_error
= true;
10856 c_parser_consume_token (parser
); /* eat the = */
10857 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
10859 c_parser_error (parser
, "expected identifier");
10860 syntax_error
= true;
10863 if (keyword
== RID_SETTER
)
10865 if (property_setter_ident
!= NULL_TREE
)
10866 c_parser_error (parser
, "the %<setter%> attribute may only be specified once");
10868 property_setter_ident
= c_parser_peek_token (parser
)->value
;
10869 c_parser_consume_token (parser
);
10870 if (c_parser_next_token_is_not (parser
, CPP_COLON
))
10871 c_parser_error (parser
, "setter name must terminate with %<:%>");
10873 c_parser_consume_token (parser
);
10877 if (property_getter_ident
!= NULL_TREE
)
10878 c_parser_error (parser
, "the %<getter%> attribute may only be specified once");
10880 property_getter_ident
= c_parser_peek_token (parser
)->value
;
10881 c_parser_consume_token (parser
);
10885 c_parser_error (parser
, "unknown property attribute");
10886 syntax_error
= true;
10893 if (c_parser_next_token_is (parser
, CPP_COMMA
))
10894 c_parser_consume_token (parser
);
10898 parser
->objc_property_attr_context
= false;
10899 parens
.skip_until_found_close (parser
);
10901 /* ... and the property declaration(s). */
10902 properties
= c_parser_struct_declaration (parser
);
10904 if (properties
== error_mark_node
)
10906 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
10907 parser
->error
= false;
10911 if (properties
== NULL_TREE
)
10912 c_parser_error (parser
, "expected identifier");
10915 /* Comma-separated properties are chained together in
10916 reverse order; add them one by one. */
10917 properties
= nreverse (properties
);
10919 for (; properties
; properties
= TREE_CHAIN (properties
))
10920 objc_add_property_declaration (loc
, copy_node (properties
),
10921 property_readonly
, property_readwrite
,
10922 property_assign
, property_retain
,
10923 property_copy
, property_nonatomic
,
10924 property_getter_ident
, property_setter_ident
);
10927 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
10928 parser
->error
= false;
10931 /* Parse an Objective-C @synthesize declaration. The syntax is:
10933 objc-synthesize-declaration:
10934 @synthesize objc-synthesize-identifier-list ;
10936 objc-synthesize-identifier-list:
10937 objc-synthesize-identifier
10938 objc-synthesize-identifier-list, objc-synthesize-identifier
10940 objc-synthesize-identifier
10942 identifier = identifier
10945 @synthesize MyProperty;
10946 @synthesize OneProperty, AnotherProperty=MyIvar, YetAnotherProperty;
10948 PS: This function is identical to cp_parser_objc_at_synthesize_declaration
10949 for C++. Keep them in sync.
10952 c_parser_objc_at_synthesize_declaration (c_parser
*parser
)
10954 tree list
= NULL_TREE
;
10956 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_SYNTHESIZE
));
10957 loc
= c_parser_peek_token (parser
)->location
;
10959 c_parser_consume_token (parser
);
10962 tree property
, ivar
;
10963 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
10965 c_parser_error (parser
, "expected identifier");
10966 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
10967 /* Once we find the semicolon, we can resume normal parsing.
10968 We have to reset parser->error manually because
10969 c_parser_skip_until_found() won't reset it for us if the
10970 next token is precisely a semicolon. */
10971 parser
->error
= false;
10974 property
= c_parser_peek_token (parser
)->value
;
10975 c_parser_consume_token (parser
);
10976 if (c_parser_next_token_is (parser
, CPP_EQ
))
10978 c_parser_consume_token (parser
);
10979 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
10981 c_parser_error (parser
, "expected identifier");
10982 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
10983 parser
->error
= false;
10986 ivar
= c_parser_peek_token (parser
)->value
;
10987 c_parser_consume_token (parser
);
10991 list
= chainon (list
, build_tree_list (ivar
, property
));
10992 if (c_parser_next_token_is (parser
, CPP_COMMA
))
10993 c_parser_consume_token (parser
);
10997 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
10998 objc_add_synthesize_declaration (loc
, list
);
11001 /* Parse an Objective-C @dynamic declaration. The syntax is:
11003 objc-dynamic-declaration:
11004 @dynamic identifier-list ;
11007 @dynamic MyProperty;
11008 @dynamic MyProperty, AnotherProperty;
11010 PS: This function is identical to cp_parser_objc_at_dynamic_declaration
11011 for C++. Keep them in sync.
11014 c_parser_objc_at_dynamic_declaration (c_parser
*parser
)
11016 tree list
= NULL_TREE
;
11018 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_DYNAMIC
));
11019 loc
= c_parser_peek_token (parser
)->location
;
11021 c_parser_consume_token (parser
);
11025 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11027 c_parser_error (parser
, "expected identifier");
11028 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
11029 parser
->error
= false;
11032 property
= c_parser_peek_token (parser
)->value
;
11033 list
= chainon (list
, build_tree_list (NULL_TREE
, property
));
11034 c_parser_consume_token (parser
);
11035 if (c_parser_next_token_is (parser
, CPP_COMMA
))
11036 c_parser_consume_token (parser
);
11040 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
11041 objc_add_dynamic_declaration (loc
, list
);
11045 /* Handle pragmas. Some OpenMP pragmas are associated with, and therefore
11046 should be considered, statements. ALLOW_STMT is true if we're within
11047 the context of a function and such pragmas are to be allowed. Returns
11048 true if we actually parsed such a pragma. */
11051 c_parser_pragma (c_parser
*parser
, enum pragma_context context
, bool *if_p
)
11054 const char *construct
= NULL
;
11056 id
= c_parser_peek_token (parser
)->pragma_kind
;
11057 gcc_assert (id
!= PRAGMA_NONE
);
11061 case PRAGMA_OACC_DECLARE
:
11062 c_parser_oacc_declare (parser
);
11065 case PRAGMA_OACC_ENTER_DATA
:
11066 if (context
!= pragma_compound
)
11068 construct
= "acc enter data";
11070 if (context
== pragma_stmt
)
11072 error_at (c_parser_peek_token (parser
)->location
,
11073 "%<#pragma %s%> may only be used in compound "
11074 "statements", construct
);
11075 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
11080 c_parser_oacc_enter_exit_data (parser
, true);
11083 case PRAGMA_OACC_EXIT_DATA
:
11084 if (context
!= pragma_compound
)
11086 construct
= "acc exit data";
11089 c_parser_oacc_enter_exit_data (parser
, false);
11092 case PRAGMA_OACC_ROUTINE
:
11093 if (context
!= pragma_external
)
11095 error_at (c_parser_peek_token (parser
)->location
,
11096 "%<#pragma acc routine%> must be at file scope");
11097 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
11100 c_parser_oacc_routine (parser
, context
);
11103 case PRAGMA_OACC_UPDATE
:
11104 if (context
!= pragma_compound
)
11106 construct
= "acc update";
11109 c_parser_oacc_update (parser
);
11112 case PRAGMA_OMP_BARRIER
:
11113 if (context
!= pragma_compound
)
11115 construct
= "omp barrier";
11118 c_parser_omp_barrier (parser
);
11121 case PRAGMA_OMP_FLUSH
:
11122 if (context
!= pragma_compound
)
11124 construct
= "omp flush";
11127 c_parser_omp_flush (parser
);
11130 case PRAGMA_OMP_TASKWAIT
:
11131 if (context
!= pragma_compound
)
11133 construct
= "omp taskwait";
11136 c_parser_omp_taskwait (parser
);
11139 case PRAGMA_OMP_TASKYIELD
:
11140 if (context
!= pragma_compound
)
11142 construct
= "omp taskyield";
11145 c_parser_omp_taskyield (parser
);
11148 case PRAGMA_OMP_CANCEL
:
11149 if (context
!= pragma_compound
)
11151 construct
= "omp cancel";
11154 c_parser_omp_cancel (parser
);
11157 case PRAGMA_OMP_CANCELLATION_POINT
:
11158 c_parser_omp_cancellation_point (parser
, context
);
11161 case PRAGMA_OMP_THREADPRIVATE
:
11162 c_parser_omp_threadprivate (parser
);
11165 case PRAGMA_OMP_TARGET
:
11166 return c_parser_omp_target (parser
, context
, if_p
);
11168 case PRAGMA_OMP_END_DECLARE_TARGET
:
11169 c_parser_omp_end_declare_target (parser
);
11172 case PRAGMA_OMP_SECTION
:
11173 error_at (c_parser_peek_token (parser
)->location
,
11174 "%<#pragma omp section%> may only be used in "
11175 "%<#pragma omp sections%> construct");
11176 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
11179 case PRAGMA_OMP_DECLARE
:
11180 c_parser_omp_declare (parser
, context
);
11183 case PRAGMA_OMP_ORDERED
:
11184 return c_parser_omp_ordered (parser
, context
, if_p
);
11187 c_parser_consume_pragma (parser
);
11188 c_parser_skip_to_pragma_eol (parser
);
11189 if (!c_parser_next_token_is_keyword (parser
, RID_FOR
)
11190 && !c_parser_next_token_is_keyword (parser
, RID_WHILE
)
11191 && !c_parser_next_token_is_keyword (parser
, RID_DO
))
11193 c_parser_error (parser
, "for, while or do statement expected");
11196 if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
11197 c_parser_for_statement (parser
, true, if_p
);
11198 else if (c_parser_next_token_is_keyword (parser
, RID_WHILE
))
11199 c_parser_while_statement (parser
, true, if_p
);
11201 c_parser_do_statement (parser
, true);
11204 case PRAGMA_GCC_PCH_PREPROCESS
:
11205 c_parser_error (parser
, "%<#pragma GCC pch_preprocess%> must be first");
11206 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
11209 case PRAGMA_CILK_SIMD
:
11210 if (!c_parser_cilk_verify_simd (parser
, context
))
11212 c_parser_consume_pragma (parser
);
11213 c_parser_cilk_simd (parser
, if_p
);
11215 case PRAGMA_CILK_GRAINSIZE
:
11216 if (!flag_cilkplus
)
11218 warning (0, "%<#pragma grainsize%> ignored because -fcilkplus is not"
11220 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
11223 if (context
== pragma_external
)
11225 error_at (c_parser_peek_token (parser
)->location
,
11226 "%<#pragma grainsize%> must be inside a function");
11227 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
11230 c_parser_cilk_grainsize (parser
, if_p
);
11233 case PRAGMA_OACC_WAIT
:
11234 if (context
!= pragma_compound
)
11236 construct
= "acc wait";
11239 /* FALL THROUGH. */
11242 if (id
< PRAGMA_FIRST_EXTERNAL
)
11244 if (context
!= pragma_stmt
&& context
!= pragma_compound
)
11247 c_parser_error (parser
, "expected declaration specifiers");
11248 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
11251 c_parser_omp_construct (parser
, if_p
);
11257 c_parser_consume_pragma (parser
);
11258 c_invoke_pragma_handler (id
);
11260 /* Skip to EOL, but suppress any error message. Those will have been
11261 generated by the handler routine through calling error, as opposed
11262 to calling c_parser_error. */
11263 parser
->error
= true;
11264 c_parser_skip_to_pragma_eol (parser
);
11269 /* The interface the pragma parsers have to the lexer. */
11272 pragma_lex (tree
*value
, location_t
*loc
)
11274 c_token
*tok
= c_parser_peek_token (the_parser
);
11275 enum cpp_ttype ret
= tok
->type
;
11277 *value
= tok
->value
;
11279 *loc
= tok
->location
;
11281 if (ret
== CPP_PRAGMA_EOL
|| ret
== CPP_EOF
)
11285 if (ret
== CPP_KEYWORD
)
11287 c_parser_consume_token (the_parser
);
11294 c_parser_pragma_pch_preprocess (c_parser
*parser
)
11298 c_parser_consume_pragma (parser
);
11299 if (c_parser_next_token_is (parser
, CPP_STRING
))
11301 name
= c_parser_peek_token (parser
)->value
;
11302 c_parser_consume_token (parser
);
11305 c_parser_error (parser
, "expected string literal");
11306 c_parser_skip_to_pragma_eol (parser
);
11309 c_common_pch_pragma (parse_in
, TREE_STRING_POINTER (name
));
11312 /* OpenACC and OpenMP parsing routines. */
11314 /* Returns name of the next clause.
11315 If the clause is not recognized PRAGMA_OMP_CLAUSE_NONE is returned and
11316 the token is not consumed. Otherwise appropriate pragma_omp_clause is
11317 returned and the token is consumed. */
11319 static pragma_omp_clause
11320 c_parser_omp_clause_name (c_parser
*parser
)
11322 pragma_omp_clause result
= PRAGMA_OMP_CLAUSE_NONE
;
11324 if (c_parser_next_token_is_keyword (parser
, RID_AUTO
))
11325 result
= PRAGMA_OACC_CLAUSE_AUTO
;
11326 else if (c_parser_next_token_is_keyword (parser
, RID_IF
))
11327 result
= PRAGMA_OMP_CLAUSE_IF
;
11328 else if (c_parser_next_token_is_keyword (parser
, RID_DEFAULT
))
11329 result
= PRAGMA_OMP_CLAUSE_DEFAULT
;
11330 else if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
11331 result
= PRAGMA_OMP_CLAUSE_FOR
;
11332 else if (c_parser_next_token_is (parser
, CPP_NAME
))
11334 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
11339 if (!strcmp ("aligned", p
))
11340 result
= PRAGMA_OMP_CLAUSE_ALIGNED
;
11341 else if (!strcmp ("async", p
))
11342 result
= PRAGMA_OACC_CLAUSE_ASYNC
;
11345 if (!strcmp ("collapse", p
))
11346 result
= PRAGMA_OMP_CLAUSE_COLLAPSE
;
11347 else if (!strcmp ("copy", p
))
11348 result
= PRAGMA_OACC_CLAUSE_COPY
;
11349 else if (!strcmp ("copyin", p
))
11350 result
= PRAGMA_OMP_CLAUSE_COPYIN
;
11351 else if (!strcmp ("copyout", p
))
11352 result
= PRAGMA_OACC_CLAUSE_COPYOUT
;
11353 else if (!strcmp ("copyprivate", p
))
11354 result
= PRAGMA_OMP_CLAUSE_COPYPRIVATE
;
11355 else if (!strcmp ("create", p
))
11356 result
= PRAGMA_OACC_CLAUSE_CREATE
;
11359 if (!strcmp ("defaultmap", p
))
11360 result
= PRAGMA_OMP_CLAUSE_DEFAULTMAP
;
11361 else if (!strcmp ("delete", p
))
11362 result
= PRAGMA_OACC_CLAUSE_DELETE
;
11363 else if (!strcmp ("depend", p
))
11364 result
= PRAGMA_OMP_CLAUSE_DEPEND
;
11365 else if (!strcmp ("device", p
))
11366 result
= PRAGMA_OMP_CLAUSE_DEVICE
;
11367 else if (!strcmp ("deviceptr", p
))
11368 result
= PRAGMA_OACC_CLAUSE_DEVICEPTR
;
11369 else if (!strcmp ("device_resident", p
))
11370 result
= PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT
;
11371 else if (!strcmp ("dist_schedule", p
))
11372 result
= PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
;
11375 if (!strcmp ("final", p
))
11376 result
= PRAGMA_OMP_CLAUSE_FINAL
;
11377 else if (!strcmp ("firstprivate", p
))
11378 result
= PRAGMA_OMP_CLAUSE_FIRSTPRIVATE
;
11379 else if (!strcmp ("from", p
))
11380 result
= PRAGMA_OMP_CLAUSE_FROM
;
11383 if (!strcmp ("gang", p
))
11384 result
= PRAGMA_OACC_CLAUSE_GANG
;
11385 else if (!strcmp ("grainsize", p
))
11386 result
= PRAGMA_OMP_CLAUSE_GRAINSIZE
;
11389 if (!strcmp ("hint", p
))
11390 result
= PRAGMA_OMP_CLAUSE_HINT
;
11391 else if (!strcmp ("host", p
))
11392 result
= PRAGMA_OACC_CLAUSE_HOST
;
11395 if (!strcmp ("inbranch", p
))
11396 result
= PRAGMA_OMP_CLAUSE_INBRANCH
;
11397 else if (!strcmp ("independent", p
))
11398 result
= PRAGMA_OACC_CLAUSE_INDEPENDENT
;
11399 else if (!strcmp ("is_device_ptr", p
))
11400 result
= PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR
;
11403 if (!strcmp ("lastprivate", p
))
11404 result
= PRAGMA_OMP_CLAUSE_LASTPRIVATE
;
11405 else if (!strcmp ("linear", p
))
11406 result
= PRAGMA_OMP_CLAUSE_LINEAR
;
11407 else if (!strcmp ("link", p
))
11408 result
= PRAGMA_OMP_CLAUSE_LINK
;
11411 if (!strcmp ("map", p
))
11412 result
= PRAGMA_OMP_CLAUSE_MAP
;
11413 else if (!strcmp ("mergeable", p
))
11414 result
= PRAGMA_OMP_CLAUSE_MERGEABLE
;
11415 else if (flag_cilkplus
&& !strcmp ("mask", p
))
11416 result
= PRAGMA_CILK_CLAUSE_MASK
;
11419 if (!strcmp ("nogroup", p
))
11420 result
= PRAGMA_OMP_CLAUSE_NOGROUP
;
11421 else if (!strcmp ("notinbranch", p
))
11422 result
= PRAGMA_OMP_CLAUSE_NOTINBRANCH
;
11423 else if (!strcmp ("nowait", p
))
11424 result
= PRAGMA_OMP_CLAUSE_NOWAIT
;
11425 else if (!strcmp ("num_gangs", p
))
11426 result
= PRAGMA_OACC_CLAUSE_NUM_GANGS
;
11427 else if (!strcmp ("num_tasks", p
))
11428 result
= PRAGMA_OMP_CLAUSE_NUM_TASKS
;
11429 else if (!strcmp ("num_teams", p
))
11430 result
= PRAGMA_OMP_CLAUSE_NUM_TEAMS
;
11431 else if (!strcmp ("num_threads", p
))
11432 result
= PRAGMA_OMP_CLAUSE_NUM_THREADS
;
11433 else if (!strcmp ("num_workers", p
))
11434 result
= PRAGMA_OACC_CLAUSE_NUM_WORKERS
;
11435 else if (flag_cilkplus
&& !strcmp ("nomask", p
))
11436 result
= PRAGMA_CILK_CLAUSE_NOMASK
;
11439 if (!strcmp ("ordered", p
))
11440 result
= PRAGMA_OMP_CLAUSE_ORDERED
;
11443 if (!strcmp ("parallel", p
))
11444 result
= PRAGMA_OMP_CLAUSE_PARALLEL
;
11445 else if (!strcmp ("present", p
))
11446 result
= PRAGMA_OACC_CLAUSE_PRESENT
;
11447 else if (!strcmp ("present_or_copy", p
)
11448 || !strcmp ("pcopy", p
))
11449 result
= PRAGMA_OACC_CLAUSE_PRESENT_OR_COPY
;
11450 else if (!strcmp ("present_or_copyin", p
)
11451 || !strcmp ("pcopyin", p
))
11452 result
= PRAGMA_OACC_CLAUSE_PRESENT_OR_COPYIN
;
11453 else if (!strcmp ("present_or_copyout", p
)
11454 || !strcmp ("pcopyout", p
))
11455 result
= PRAGMA_OACC_CLAUSE_PRESENT_OR_COPYOUT
;
11456 else if (!strcmp ("present_or_create", p
)
11457 || !strcmp ("pcreate", p
))
11458 result
= PRAGMA_OACC_CLAUSE_PRESENT_OR_CREATE
;
11459 else if (!strcmp ("priority", p
))
11460 result
= PRAGMA_OMP_CLAUSE_PRIORITY
;
11461 else if (!strcmp ("private", p
))
11462 result
= PRAGMA_OMP_CLAUSE_PRIVATE
;
11463 else if (!strcmp ("proc_bind", p
))
11464 result
= PRAGMA_OMP_CLAUSE_PROC_BIND
;
11467 if (!strcmp ("reduction", p
))
11468 result
= PRAGMA_OMP_CLAUSE_REDUCTION
;
11471 if (!strcmp ("safelen", p
))
11472 result
= PRAGMA_OMP_CLAUSE_SAFELEN
;
11473 else if (!strcmp ("schedule", p
))
11474 result
= PRAGMA_OMP_CLAUSE_SCHEDULE
;
11475 else if (!strcmp ("sections", p
))
11476 result
= PRAGMA_OMP_CLAUSE_SECTIONS
;
11477 else if (!strcmp ("seq", p
))
11478 result
= PRAGMA_OACC_CLAUSE_SEQ
;
11479 else if (!strcmp ("shared", p
))
11480 result
= PRAGMA_OMP_CLAUSE_SHARED
;
11481 else if (!strcmp ("simd", p
))
11482 result
= PRAGMA_OMP_CLAUSE_SIMD
;
11483 else if (!strcmp ("simdlen", p
))
11484 result
= PRAGMA_OMP_CLAUSE_SIMDLEN
;
11485 else if (!strcmp ("self", p
))
11486 result
= PRAGMA_OACC_CLAUSE_SELF
;
11489 if (!strcmp ("taskgroup", p
))
11490 result
= PRAGMA_OMP_CLAUSE_TASKGROUP
;
11491 else if (!strcmp ("thread_limit", p
))
11492 result
= PRAGMA_OMP_CLAUSE_THREAD_LIMIT
;
11493 else if (!strcmp ("threads", p
))
11494 result
= PRAGMA_OMP_CLAUSE_THREADS
;
11495 else if (!strcmp ("tile", p
))
11496 result
= PRAGMA_OACC_CLAUSE_TILE
;
11497 else if (!strcmp ("to", p
))
11498 result
= PRAGMA_OMP_CLAUSE_TO
;
11501 if (!strcmp ("uniform", p
))
11502 result
= PRAGMA_OMP_CLAUSE_UNIFORM
;
11503 else if (!strcmp ("untied", p
))
11504 result
= PRAGMA_OMP_CLAUSE_UNTIED
;
11505 else if (!strcmp ("use_device", p
))
11506 result
= PRAGMA_OACC_CLAUSE_USE_DEVICE
;
11507 else if (!strcmp ("use_device_ptr", p
))
11508 result
= PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR
;
11511 if (!strcmp ("vector", p
))
11512 result
= PRAGMA_OACC_CLAUSE_VECTOR
;
11513 else if (!strcmp ("vector_length", p
))
11514 result
= PRAGMA_OACC_CLAUSE_VECTOR_LENGTH
;
11515 else if (flag_cilkplus
&& !strcmp ("vectorlength", p
))
11516 result
= PRAGMA_CILK_CLAUSE_VECTORLENGTH
;
11519 if (!strcmp ("wait", p
))
11520 result
= PRAGMA_OACC_CLAUSE_WAIT
;
11521 else if (!strcmp ("worker", p
))
11522 result
= PRAGMA_OACC_CLAUSE_WORKER
;
11527 if (result
!= PRAGMA_OMP_CLAUSE_NONE
)
11528 c_parser_consume_token (parser
);
11533 /* Validate that a clause of the given type does not already exist. */
11536 check_no_duplicate_clause (tree clauses
, enum omp_clause_code code
,
11541 for (c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
11542 if (OMP_CLAUSE_CODE (c
) == code
)
11544 location_t loc
= OMP_CLAUSE_LOCATION (c
);
11545 error_at (loc
, "too many %qs clauses", name
);
11551 Parse wait clause or wait directive parameters. */
11554 c_parser_oacc_wait_list (c_parser
*parser
, location_t clause_loc
, tree list
)
11556 vec
<tree
, va_gc
> *args
;
11559 matching_parens parens
;
11560 if (!parens
.require_open (parser
))
11563 args
= c_parser_expr_list (parser
, false, true, NULL
, NULL
, NULL
, NULL
);
11565 if (args
->length () == 0)
11567 c_parser_error (parser
, "expected integer expression before ')'");
11568 release_tree_vector (args
);
11572 args_tree
= build_tree_list_vec (args
);
11574 for (t
= args_tree
; t
; t
= TREE_CHAIN (t
))
11576 tree targ
= TREE_VALUE (t
);
11578 if (targ
!= error_mark_node
)
11580 if (!INTEGRAL_TYPE_P (TREE_TYPE (targ
)))
11582 c_parser_error (parser
, "expression must be integral");
11583 targ
= error_mark_node
;
11587 tree c
= build_omp_clause (clause_loc
, OMP_CLAUSE_WAIT
);
11589 OMP_CLAUSE_DECL (c
) = targ
;
11590 OMP_CLAUSE_CHAIN (c
) = list
;
11596 release_tree_vector (args
);
11597 parens
.require_close (parser
);
11601 /* OpenACC 2.0, OpenMP 2.5:
11604 variable-list , identifier
11606 If KIND is nonzero, create the appropriate node and install the
11607 decl in OMP_CLAUSE_DECL and add the node to the head of the list.
11608 If KIND is nonzero, CLAUSE_LOC is the location of the clause.
11610 If KIND is zero, create a TREE_LIST with the decl in TREE_PURPOSE;
11611 return the list created. */
11614 c_parser_omp_variable_list (c_parser
*parser
,
11615 location_t clause_loc
,
11616 enum omp_clause_code kind
, tree list
)
11618 if (c_parser_next_token_is_not (parser
, CPP_NAME
)
11619 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
11620 c_parser_error (parser
, "expected identifier");
11622 while (c_parser_next_token_is (parser
, CPP_NAME
)
11623 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
)
11625 tree t
= lookup_name (c_parser_peek_token (parser
)->value
);
11627 if (t
== NULL_TREE
)
11629 undeclared_variable (c_parser_peek_token (parser
)->location
,
11630 c_parser_peek_token (parser
)->value
);
11631 t
= error_mark_node
;
11634 c_parser_consume_token (parser
);
11636 if (t
== error_mark_node
)
11638 else if (kind
!= 0)
11642 case OMP_CLAUSE__CACHE_
:
11643 /* The OpenACC cache directive explicitly only allows "array
11644 elements or subarrays". */
11645 if (c_parser_peek_token (parser
)->type
!= CPP_OPEN_SQUARE
)
11647 c_parser_error (parser
, "expected %<[%>");
11648 t
= error_mark_node
;
11652 case OMP_CLAUSE_MAP
:
11653 case OMP_CLAUSE_FROM
:
11654 case OMP_CLAUSE_TO
:
11655 while (c_parser_next_token_is (parser
, CPP_DOT
))
11657 location_t op_loc
= c_parser_peek_token (parser
)->location
;
11658 c_parser_consume_token (parser
);
11659 if (!c_parser_next_token_is (parser
, CPP_NAME
))
11661 c_parser_error (parser
, "expected identifier");
11662 t
= error_mark_node
;
11666 c_token
*comp_tok
= c_parser_peek_token (parser
);
11667 tree ident
= comp_tok
->value
;
11668 location_t comp_loc
= comp_tok
->location
;
11669 c_parser_consume_token (parser
);
11670 t
= build_component_ref (op_loc
, t
, ident
, comp_loc
);
11673 case OMP_CLAUSE_DEPEND
:
11674 case OMP_CLAUSE_REDUCTION
:
11675 while (c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
))
11677 tree low_bound
= NULL_TREE
, length
= NULL_TREE
;
11679 c_parser_consume_token (parser
);
11680 if (!c_parser_next_token_is (parser
, CPP_COLON
))
11682 location_t expr_loc
11683 = c_parser_peek_token (parser
)->location
;
11684 c_expr expr
= c_parser_expression (parser
);
11685 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
,
11687 low_bound
= expr
.value
;
11689 if (c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
11690 length
= integer_one_node
;
11693 /* Look for `:'. */
11694 if (!c_parser_require (parser
, CPP_COLON
,
11697 t
= error_mark_node
;
11700 if (!c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
11702 location_t expr_loc
11703 = c_parser_peek_token (parser
)->location
;
11704 c_expr expr
= c_parser_expression (parser
);
11705 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
,
11707 length
= expr
.value
;
11710 /* Look for the closing `]'. */
11711 if (!c_parser_require (parser
, CPP_CLOSE_SQUARE
,
11714 t
= error_mark_node
;
11718 t
= tree_cons (low_bound
, length
, t
);
11725 if (t
!= error_mark_node
)
11727 tree u
= build_omp_clause (clause_loc
, kind
);
11728 OMP_CLAUSE_DECL (u
) = t
;
11729 OMP_CLAUSE_CHAIN (u
) = list
;
11734 list
= tree_cons (t
, NULL_TREE
, list
);
11736 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
11739 c_parser_consume_token (parser
);
11745 /* Similarly, but expect leading and trailing parenthesis. This is a very
11746 common case for OpenACC and OpenMP clauses. */
11749 c_parser_omp_var_list_parens (c_parser
*parser
, enum omp_clause_code kind
,
11752 /* The clauses location. */
11753 location_t loc
= c_parser_peek_token (parser
)->location
;
11755 matching_parens parens
;
11756 if (parens
.require_open (parser
))
11758 list
= c_parser_omp_variable_list (parser
, loc
, kind
, list
);
11759 parens
.skip_until_found_close (parser
);
11765 copy ( variable-list )
11766 copyin ( variable-list )
11767 copyout ( variable-list )
11768 create ( variable-list )
11769 delete ( variable-list )
11770 present ( variable-list )
11771 present_or_copy ( variable-list )
11772 pcopy ( variable-list )
11773 present_or_copyin ( variable-list )
11774 pcopyin ( variable-list )
11775 present_or_copyout ( variable-list )
11776 pcopyout ( variable-list )
11777 present_or_create ( variable-list )
11778 pcreate ( variable-list ) */
11781 c_parser_oacc_data_clause (c_parser
*parser
, pragma_omp_clause c_kind
,
11784 enum gomp_map_kind kind
;
11787 case PRAGMA_OACC_CLAUSE_COPY
:
11788 kind
= GOMP_MAP_FORCE_TOFROM
;
11790 case PRAGMA_OACC_CLAUSE_COPYIN
:
11791 kind
= GOMP_MAP_FORCE_TO
;
11793 case PRAGMA_OACC_CLAUSE_COPYOUT
:
11794 kind
= GOMP_MAP_FORCE_FROM
;
11796 case PRAGMA_OACC_CLAUSE_CREATE
:
11797 kind
= GOMP_MAP_FORCE_ALLOC
;
11799 case PRAGMA_OACC_CLAUSE_DELETE
:
11800 kind
= GOMP_MAP_DELETE
;
11802 case PRAGMA_OACC_CLAUSE_DEVICE
:
11803 kind
= GOMP_MAP_FORCE_TO
;
11805 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT
:
11806 kind
= GOMP_MAP_DEVICE_RESIDENT
;
11808 case PRAGMA_OACC_CLAUSE_HOST
:
11809 case PRAGMA_OACC_CLAUSE_SELF
:
11810 kind
= GOMP_MAP_FORCE_FROM
;
11812 case PRAGMA_OACC_CLAUSE_LINK
:
11813 kind
= GOMP_MAP_LINK
;
11815 case PRAGMA_OACC_CLAUSE_PRESENT
:
11816 kind
= GOMP_MAP_FORCE_PRESENT
;
11818 case PRAGMA_OACC_CLAUSE_PRESENT_OR_COPY
:
11819 kind
= GOMP_MAP_TOFROM
;
11821 case PRAGMA_OACC_CLAUSE_PRESENT_OR_COPYIN
:
11822 kind
= GOMP_MAP_TO
;
11824 case PRAGMA_OACC_CLAUSE_PRESENT_OR_COPYOUT
:
11825 kind
= GOMP_MAP_FROM
;
11827 case PRAGMA_OACC_CLAUSE_PRESENT_OR_CREATE
:
11828 kind
= GOMP_MAP_ALLOC
;
11831 gcc_unreachable ();
11834 nl
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_MAP
, list
);
11836 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
11837 OMP_CLAUSE_SET_MAP_KIND (c
, kind
);
11843 deviceptr ( variable-list ) */
11846 c_parser_oacc_data_clause_deviceptr (c_parser
*parser
, tree list
)
11848 location_t loc
= c_parser_peek_token (parser
)->location
;
11851 /* Can't use OMP_CLAUSE_MAP here (that is, can't use the generic
11852 c_parser_oacc_data_clause), as for PRAGMA_OACC_CLAUSE_DEVICEPTR,
11853 variable-list must only allow for pointer variables. */
11854 vars
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ERROR
, NULL
);
11855 for (t
= vars
; t
&& t
; t
= TREE_CHAIN (t
))
11857 tree v
= TREE_PURPOSE (t
);
11859 /* FIXME diagnostics: Ideally we should keep individual
11860 locations for all the variables in the var list to make the
11861 following errors more precise. Perhaps
11862 c_parser_omp_var_list_parens() should construct a list of
11863 locations to go along with the var list. */
11865 if (!VAR_P (v
) && TREE_CODE (v
) != PARM_DECL
)
11866 error_at (loc
, "%qD is not a variable", v
);
11867 else if (TREE_TYPE (v
) == error_mark_node
)
11869 else if (!POINTER_TYPE_P (TREE_TYPE (v
)))
11870 error_at (loc
, "%qD is not a pointer variable", v
);
11872 tree u
= build_omp_clause (loc
, OMP_CLAUSE_MAP
);
11873 OMP_CLAUSE_SET_MAP_KIND (u
, GOMP_MAP_FORCE_DEVICEPTR
);
11874 OMP_CLAUSE_DECL (u
) = v
;
11875 OMP_CLAUSE_CHAIN (u
) = list
;
11882 /* OpenACC 2.0, OpenMP 3.0:
11883 collapse ( constant-expression ) */
11886 c_parser_omp_clause_collapse (c_parser
*parser
, tree list
)
11888 tree c
, num
= error_mark_node
;
11892 check_no_duplicate_clause (list
, OMP_CLAUSE_COLLAPSE
, "collapse");
11893 check_no_duplicate_clause (list
, OMP_CLAUSE_TILE
, "tile");
11895 loc
= c_parser_peek_token (parser
)->location
;
11896 matching_parens parens
;
11897 if (parens
.require_open (parser
))
11899 num
= c_parser_expr_no_commas (parser
, NULL
).value
;
11900 parens
.skip_until_found_close (parser
);
11902 if (num
== error_mark_node
)
11904 mark_exp_read (num
);
11905 num
= c_fully_fold (num
, false, NULL
);
11906 if (!INTEGRAL_TYPE_P (TREE_TYPE (num
))
11907 || !tree_fits_shwi_p (num
)
11908 || (n
= tree_to_shwi (num
)) <= 0
11912 "collapse argument needs positive constant integer expression");
11915 c
= build_omp_clause (loc
, OMP_CLAUSE_COLLAPSE
);
11916 OMP_CLAUSE_COLLAPSE_EXPR (c
) = num
;
11917 OMP_CLAUSE_CHAIN (c
) = list
;
11922 copyin ( variable-list ) */
11925 c_parser_omp_clause_copyin (c_parser
*parser
, tree list
)
11927 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_COPYIN
, list
);
11931 copyprivate ( variable-list ) */
11934 c_parser_omp_clause_copyprivate (c_parser
*parser
, tree list
)
11936 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_COPYPRIVATE
, list
);
11940 default ( none | shared )
11943 default ( none | present ) */
11946 c_parser_omp_clause_default (c_parser
*parser
, tree list
, bool is_oacc
)
11948 enum omp_clause_default_kind kind
= OMP_CLAUSE_DEFAULT_UNSPECIFIED
;
11949 location_t loc
= c_parser_peek_token (parser
)->location
;
11952 matching_parens parens
;
11953 if (!parens
.require_open (parser
))
11955 if (c_parser_next_token_is (parser
, CPP_NAME
))
11957 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
11962 if (strcmp ("none", p
) != 0)
11964 kind
= OMP_CLAUSE_DEFAULT_NONE
;
11968 if (strcmp ("present", p
) != 0 || !is_oacc
)
11970 kind
= OMP_CLAUSE_DEFAULT_PRESENT
;
11974 if (strcmp ("shared", p
) != 0 || is_oacc
)
11976 kind
= OMP_CLAUSE_DEFAULT_SHARED
;
11983 c_parser_consume_token (parser
);
11989 c_parser_error (parser
, "expected %<none%> or %<present%>");
11991 c_parser_error (parser
, "expected %<none%> or %<shared%>");
11993 parens
.skip_until_found_close (parser
);
11995 if (kind
== OMP_CLAUSE_DEFAULT_UNSPECIFIED
)
11998 check_no_duplicate_clause (list
, OMP_CLAUSE_DEFAULT
, "default");
11999 c
= build_omp_clause (loc
, OMP_CLAUSE_DEFAULT
);
12000 OMP_CLAUSE_CHAIN (c
) = list
;
12001 OMP_CLAUSE_DEFAULT_KIND (c
) = kind
;
12007 firstprivate ( variable-list ) */
12010 c_parser_omp_clause_firstprivate (c_parser
*parser
, tree list
)
12012 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_FIRSTPRIVATE
, list
);
12016 final ( expression ) */
12019 c_parser_omp_clause_final (c_parser
*parser
, tree list
)
12021 location_t loc
= c_parser_peek_token (parser
)->location
;
12022 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
12024 tree t
= c_parser_paren_condition (parser
);
12027 check_no_duplicate_clause (list
, OMP_CLAUSE_FINAL
, "final");
12029 c
= build_omp_clause (loc
, OMP_CLAUSE_FINAL
);
12030 OMP_CLAUSE_FINAL_EXPR (c
) = t
;
12031 OMP_CLAUSE_CHAIN (c
) = list
;
12035 c_parser_error (parser
, "expected %<(%>");
12040 /* OpenACC, OpenMP 2.5:
12044 if ( directive-name-modifier : expression )
12046 directive-name-modifier:
12047 parallel | task | taskloop | target data | target | target update
12048 | target enter data | target exit data */
12051 c_parser_omp_clause_if (c_parser
*parser
, tree list
, bool is_omp
)
12053 location_t location
= c_parser_peek_token (parser
)->location
;
12054 enum tree_code if_modifier
= ERROR_MARK
;
12056 matching_parens parens
;
12057 if (!parens
.require_open (parser
))
12060 if (is_omp
&& c_parser_next_token_is (parser
, CPP_NAME
))
12062 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
12064 if (strcmp (p
, "parallel") == 0)
12065 if_modifier
= OMP_PARALLEL
;
12066 else if (strcmp (p
, "task") == 0)
12067 if_modifier
= OMP_TASK
;
12068 else if (strcmp (p
, "taskloop") == 0)
12069 if_modifier
= OMP_TASKLOOP
;
12070 else if (strcmp (p
, "target") == 0)
12072 if_modifier
= OMP_TARGET
;
12073 if (c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
12075 p
= IDENTIFIER_POINTER (c_parser_peek_2nd_token (parser
)->value
);
12076 if (strcmp ("data", p
) == 0)
12077 if_modifier
= OMP_TARGET_DATA
;
12078 else if (strcmp ("update", p
) == 0)
12079 if_modifier
= OMP_TARGET_UPDATE
;
12080 else if (strcmp ("enter", p
) == 0)
12081 if_modifier
= OMP_TARGET_ENTER_DATA
;
12082 else if (strcmp ("exit", p
) == 0)
12083 if_modifier
= OMP_TARGET_EXIT_DATA
;
12084 if (if_modifier
!= OMP_TARGET
)
12087 c_parser_consume_token (parser
);
12091 location_t loc
= c_parser_peek_2nd_token (parser
)->location
;
12092 error_at (loc
, "expected %<data%>, %<update%>, %<enter%> "
12094 if_modifier
= ERROR_MARK
;
12096 if (if_modifier
== OMP_TARGET_ENTER_DATA
12097 || if_modifier
== OMP_TARGET_EXIT_DATA
)
12099 if (c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
12101 p
= IDENTIFIER_POINTER
12102 (c_parser_peek_2nd_token (parser
)->value
);
12103 if (strcmp ("data", p
) == 0)
12107 c_parser_consume_token (parser
);
12111 = c_parser_peek_2nd_token (parser
)->location
;
12112 error_at (loc
, "expected %<data%>");
12113 if_modifier
= ERROR_MARK
;
12118 if (if_modifier
!= ERROR_MARK
)
12120 if (c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
12122 c_parser_consume_token (parser
);
12123 c_parser_consume_token (parser
);
12129 location_t loc
= c_parser_peek_2nd_token (parser
)->location
;
12130 error_at (loc
, "expected %<:%>");
12132 if_modifier
= ERROR_MARK
;
12137 tree t
= c_parser_condition (parser
), c
;
12138 parens
.skip_until_found_close (parser
);
12140 for (c
= list
; c
; c
= OMP_CLAUSE_CHAIN (c
))
12141 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_IF
)
12143 if (if_modifier
!= ERROR_MARK
12144 && OMP_CLAUSE_IF_MODIFIER (c
) == if_modifier
)
12146 const char *p
= NULL
;
12147 switch (if_modifier
)
12149 case OMP_PARALLEL
: p
= "parallel"; break;
12150 case OMP_TASK
: p
= "task"; break;
12151 case OMP_TASKLOOP
: p
= "taskloop"; break;
12152 case OMP_TARGET_DATA
: p
= "target data"; break;
12153 case OMP_TARGET
: p
= "target"; break;
12154 case OMP_TARGET_UPDATE
: p
= "target update"; break;
12155 case OMP_TARGET_ENTER_DATA
: p
= "enter data"; break;
12156 case OMP_TARGET_EXIT_DATA
: p
= "exit data"; break;
12157 default: gcc_unreachable ();
12159 error_at (location
, "too many %<if%> clauses with %qs modifier",
12163 else if (OMP_CLAUSE_IF_MODIFIER (c
) == if_modifier
)
12166 error_at (location
, "too many %<if%> clauses");
12168 error_at (location
, "too many %<if%> clauses without modifier");
12171 else if (if_modifier
== ERROR_MARK
12172 || OMP_CLAUSE_IF_MODIFIER (c
) == ERROR_MARK
)
12174 error_at (location
, "if any %<if%> clause has modifier, then all "
12175 "%<if%> clauses have to use modifier");
12180 c
= build_omp_clause (location
, OMP_CLAUSE_IF
);
12181 OMP_CLAUSE_IF_MODIFIER (c
) = if_modifier
;
12182 OMP_CLAUSE_IF_EXPR (c
) = t
;
12183 OMP_CLAUSE_CHAIN (c
) = list
;
12188 lastprivate ( variable-list ) */
12191 c_parser_omp_clause_lastprivate (c_parser
*parser
, tree list
)
12193 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_LASTPRIVATE
, list
);
12200 c_parser_omp_clause_mergeable (c_parser
*parser ATTRIBUTE_UNUSED
, tree list
)
12204 /* FIXME: Should we allow duplicates? */
12205 check_no_duplicate_clause (list
, OMP_CLAUSE_MERGEABLE
, "mergeable");
12207 c
= build_omp_clause (c_parser_peek_token (parser
)->location
,
12208 OMP_CLAUSE_MERGEABLE
);
12209 OMP_CLAUSE_CHAIN (c
) = list
;
12218 c_parser_omp_clause_nowait (c_parser
*parser ATTRIBUTE_UNUSED
, tree list
)
12221 location_t loc
= c_parser_peek_token (parser
)->location
;
12223 check_no_duplicate_clause (list
, OMP_CLAUSE_NOWAIT
, "nowait");
12225 c
= build_omp_clause (loc
, OMP_CLAUSE_NOWAIT
);
12226 OMP_CLAUSE_CHAIN (c
) = list
;
12231 num_threads ( expression ) */
12234 c_parser_omp_clause_num_threads (c_parser
*parser
, tree list
)
12236 location_t num_threads_loc
= c_parser_peek_token (parser
)->location
;
12237 matching_parens parens
;
12238 if (parens
.require_open (parser
))
12240 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
12241 c_expr expr
= c_parser_expression (parser
);
12242 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
12243 tree c
, t
= expr
.value
;
12244 t
= c_fully_fold (t
, false, NULL
);
12246 parens
.skip_until_found_close (parser
);
12248 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
12250 c_parser_error (parser
, "expected integer expression");
12254 /* Attempt to statically determine when the number isn't positive. */
12255 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
12256 build_int_cst (TREE_TYPE (t
), 0));
12257 protected_set_expr_location (c
, expr_loc
);
12258 if (c
== boolean_true_node
)
12260 warning_at (expr_loc
, 0,
12261 "%<num_threads%> value must be positive");
12262 t
= integer_one_node
;
12265 check_no_duplicate_clause (list
, OMP_CLAUSE_NUM_THREADS
, "num_threads");
12267 c
= build_omp_clause (num_threads_loc
, OMP_CLAUSE_NUM_THREADS
);
12268 OMP_CLAUSE_NUM_THREADS_EXPR (c
) = t
;
12269 OMP_CLAUSE_CHAIN (c
) = list
;
12277 num_tasks ( expression ) */
12280 c_parser_omp_clause_num_tasks (c_parser
*parser
, tree list
)
12282 location_t num_tasks_loc
= c_parser_peek_token (parser
)->location
;
12283 matching_parens parens
;
12284 if (parens
.require_open (parser
))
12286 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
12287 c_expr expr
= c_parser_expression (parser
);
12288 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
12289 tree c
, t
= expr
.value
;
12290 t
= c_fully_fold (t
, false, NULL
);
12292 parens
.skip_until_found_close (parser
);
12294 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
12296 c_parser_error (parser
, "expected integer expression");
12300 /* Attempt to statically determine when the number isn't positive. */
12301 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
12302 build_int_cst (TREE_TYPE (t
), 0));
12303 if (CAN_HAVE_LOCATION_P (c
))
12304 SET_EXPR_LOCATION (c
, expr_loc
);
12305 if (c
== boolean_true_node
)
12307 warning_at (expr_loc
, 0, "%<num_tasks%> value must be positive");
12308 t
= integer_one_node
;
12311 check_no_duplicate_clause (list
, OMP_CLAUSE_NUM_TASKS
, "num_tasks");
12313 c
= build_omp_clause (num_tasks_loc
, OMP_CLAUSE_NUM_TASKS
);
12314 OMP_CLAUSE_NUM_TASKS_EXPR (c
) = t
;
12315 OMP_CLAUSE_CHAIN (c
) = list
;
12323 grainsize ( expression ) */
12326 c_parser_omp_clause_grainsize (c_parser
*parser
, tree list
)
12328 location_t grainsize_loc
= c_parser_peek_token (parser
)->location
;
12329 matching_parens parens
;
12330 if (parens
.require_open (parser
))
12332 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
12333 c_expr expr
= c_parser_expression (parser
);
12334 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
12335 tree c
, t
= expr
.value
;
12336 t
= c_fully_fold (t
, false, NULL
);
12338 parens
.skip_until_found_close (parser
);
12340 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
12342 c_parser_error (parser
, "expected integer expression");
12346 /* Attempt to statically determine when the number isn't positive. */
12347 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
12348 build_int_cst (TREE_TYPE (t
), 0));
12349 if (CAN_HAVE_LOCATION_P (c
))
12350 SET_EXPR_LOCATION (c
, expr_loc
);
12351 if (c
== boolean_true_node
)
12353 warning_at (expr_loc
, 0, "%<grainsize%> value must be positive");
12354 t
= integer_one_node
;
12357 check_no_duplicate_clause (list
, OMP_CLAUSE_GRAINSIZE
, "grainsize");
12359 c
= build_omp_clause (grainsize_loc
, OMP_CLAUSE_GRAINSIZE
);
12360 OMP_CLAUSE_GRAINSIZE_EXPR (c
) = t
;
12361 OMP_CLAUSE_CHAIN (c
) = list
;
12369 priority ( expression ) */
12372 c_parser_omp_clause_priority (c_parser
*parser
, tree list
)
12374 location_t priority_loc
= c_parser_peek_token (parser
)->location
;
12375 matching_parens parens
;
12376 if (parens
.require_open (parser
))
12378 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
12379 c_expr expr
= c_parser_expression (parser
);
12380 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
12381 tree c
, t
= expr
.value
;
12382 t
= c_fully_fold (t
, false, NULL
);
12384 parens
.skip_until_found_close (parser
);
12386 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
12388 c_parser_error (parser
, "expected integer expression");
12392 /* Attempt to statically determine when the number isn't
12394 c
= fold_build2_loc (expr_loc
, LT_EXPR
, boolean_type_node
, t
,
12395 build_int_cst (TREE_TYPE (t
), 0));
12396 if (CAN_HAVE_LOCATION_P (c
))
12397 SET_EXPR_LOCATION (c
, expr_loc
);
12398 if (c
== boolean_true_node
)
12400 warning_at (expr_loc
, 0, "%<priority%> value must be non-negative");
12401 t
= integer_one_node
;
12404 check_no_duplicate_clause (list
, OMP_CLAUSE_PRIORITY
, "priority");
12406 c
= build_omp_clause (priority_loc
, OMP_CLAUSE_PRIORITY
);
12407 OMP_CLAUSE_PRIORITY_EXPR (c
) = t
;
12408 OMP_CLAUSE_CHAIN (c
) = list
;
12416 hint ( expression ) */
12419 c_parser_omp_clause_hint (c_parser
*parser
, tree list
)
12421 location_t hint_loc
= c_parser_peek_token (parser
)->location
;
12422 matching_parens parens
;
12423 if (parens
.require_open (parser
))
12425 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
12426 c_expr expr
= c_parser_expression (parser
);
12427 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
12428 tree c
, t
= expr
.value
;
12429 t
= c_fully_fold (t
, false, NULL
);
12431 parens
.skip_until_found_close (parser
);
12433 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
12435 c_parser_error (parser
, "expected integer expression");
12439 check_no_duplicate_clause (list
, OMP_CLAUSE_HINT
, "hint");
12441 c
= build_omp_clause (hint_loc
, OMP_CLAUSE_HINT
);
12442 OMP_CLAUSE_HINT_EXPR (c
) = t
;
12443 OMP_CLAUSE_CHAIN (c
) = list
;
12451 defaultmap ( tofrom : scalar ) */
12454 c_parser_omp_clause_defaultmap (c_parser
*parser
, tree list
)
12456 location_t loc
= c_parser_peek_token (parser
)->location
;
12460 matching_parens parens
;
12461 if (!parens
.require_open (parser
))
12463 if (!c_parser_next_token_is (parser
, CPP_NAME
))
12465 c_parser_error (parser
, "expected %<tofrom%>");
12468 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
12469 if (strcmp (p
, "tofrom") != 0)
12471 c_parser_error (parser
, "expected %<tofrom%>");
12474 c_parser_consume_token (parser
);
12475 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
12477 if (!c_parser_next_token_is (parser
, CPP_NAME
))
12479 c_parser_error (parser
, "expected %<scalar%>");
12482 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
12483 if (strcmp (p
, "scalar") != 0)
12485 c_parser_error (parser
, "expected %<scalar%>");
12488 c_parser_consume_token (parser
);
12489 parens
.skip_until_found_close (parser
);
12490 check_no_duplicate_clause (list
, OMP_CLAUSE_DEFAULTMAP
, "defaultmap");
12491 c
= build_omp_clause (loc
, OMP_CLAUSE_DEFAULTMAP
);
12492 OMP_CLAUSE_CHAIN (c
) = list
;
12496 parens
.skip_until_found_close (parser
);
12501 use_device ( variable-list )
12504 use_device_ptr ( variable-list ) */
12507 c_parser_omp_clause_use_device_ptr (c_parser
*parser
, tree list
)
12509 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_USE_DEVICE_PTR
,
12514 is_device_ptr ( variable-list ) */
12517 c_parser_omp_clause_is_device_ptr (c_parser
*parser
, tree list
)
12519 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_IS_DEVICE_PTR
, list
);
12523 num_gangs ( expression )
12524 num_workers ( expression )
12525 vector_length ( expression ) */
12528 c_parser_oacc_single_int_clause (c_parser
*parser
, omp_clause_code code
,
12531 location_t loc
= c_parser_peek_token (parser
)->location
;
12533 matching_parens parens
;
12534 if (!parens
.require_open (parser
))
12537 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
12538 c_expr expr
= c_parser_expression (parser
);
12539 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
12540 tree c
, t
= expr
.value
;
12541 t
= c_fully_fold (t
, false, NULL
);
12543 parens
.skip_until_found_close (parser
);
12545 if (t
== error_mark_node
)
12547 else if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
12549 error_at (expr_loc
, "%qs expression must be integral",
12550 omp_clause_code_name
[code
]);
12554 /* Attempt to statically determine when the number isn't positive. */
12555 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
12556 build_int_cst (TREE_TYPE (t
), 0));
12557 protected_set_expr_location (c
, expr_loc
);
12558 if (c
== boolean_true_node
)
12560 warning_at (expr_loc
, 0,
12561 "%qs value must be positive",
12562 omp_clause_code_name
[code
]);
12563 t
= integer_one_node
;
12566 check_no_duplicate_clause (list
, code
, omp_clause_code_name
[code
]);
12568 c
= build_omp_clause (loc
, code
);
12569 OMP_CLAUSE_OPERAND (c
, 0) = t
;
12570 OMP_CLAUSE_CHAIN (c
) = list
;
12576 gang [( gang-arg-list )]
12577 worker [( [num:] int-expr )]
12578 vector [( [length:] int-expr )]
12580 where gang-arg is one of:
12585 and size-expr may be:
12592 c_parser_oacc_shape_clause (c_parser
*parser
, omp_clause_code kind
,
12593 const char *str
, tree list
)
12595 const char *id
= "num";
12596 tree ops
[2] = { NULL_TREE
, NULL_TREE
}, c
;
12597 location_t loc
= c_parser_peek_token (parser
)->location
;
12599 if (kind
== OMP_CLAUSE_VECTOR
)
12602 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
12604 c_parser_consume_token (parser
);
12608 c_token
*next
= c_parser_peek_token (parser
);
12611 /* Gang static argument. */
12612 if (kind
== OMP_CLAUSE_GANG
12613 && c_parser_next_token_is_keyword (parser
, RID_STATIC
))
12615 c_parser_consume_token (parser
);
12617 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
12618 goto cleanup_error
;
12621 if (ops
[idx
] != NULL_TREE
)
12623 c_parser_error (parser
, "too many %<static%> arguments");
12624 goto cleanup_error
;
12627 /* Check for the '*' argument. */
12628 if (c_parser_next_token_is (parser
, CPP_MULT
)
12629 && (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
12630 || c_parser_peek_2nd_token (parser
)->type
12631 == CPP_CLOSE_PAREN
))
12633 c_parser_consume_token (parser
);
12634 ops
[idx
] = integer_minus_one_node
;
12636 if (c_parser_next_token_is (parser
, CPP_COMMA
))
12638 c_parser_consume_token (parser
);
12645 /* Worker num: argument and vector length: arguments. */
12646 else if (c_parser_next_token_is (parser
, CPP_NAME
)
12647 && strcmp (id
, IDENTIFIER_POINTER (next
->value
)) == 0
12648 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
12650 c_parser_consume_token (parser
); /* id */
12651 c_parser_consume_token (parser
); /* ':' */
12654 /* Now collect the actual argument. */
12655 if (ops
[idx
] != NULL_TREE
)
12657 c_parser_error (parser
, "unexpected argument");
12658 goto cleanup_error
;
12661 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
12662 c_expr cexpr
= c_parser_expr_no_commas (parser
, NULL
);
12663 cexpr
= convert_lvalue_to_rvalue (expr_loc
, cexpr
, false, true);
12664 tree expr
= cexpr
.value
;
12665 if (expr
== error_mark_node
)
12666 goto cleanup_error
;
12668 expr
= c_fully_fold (expr
, false, NULL
);
12670 /* Attempt to statically determine when the number isn't a
12671 positive integer. */
12673 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr
)))
12675 c_parser_error (parser
, "expected integer expression");
12679 tree c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, expr
,
12680 build_int_cst (TREE_TYPE (expr
), 0));
12681 if (c
== boolean_true_node
)
12683 warning_at (loc
, 0,
12684 "%qs value must be positive", str
);
12685 expr
= integer_one_node
;
12690 if (kind
== OMP_CLAUSE_GANG
12691 && c_parser_next_token_is (parser
, CPP_COMMA
))
12693 c_parser_consume_token (parser
);
12700 if (!c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
12701 goto cleanup_error
;
12704 check_no_duplicate_clause (list
, kind
, str
);
12706 c
= build_omp_clause (loc
, kind
);
12709 OMP_CLAUSE_OPERAND (c
, 1) = ops
[1];
12711 OMP_CLAUSE_OPERAND (c
, 0) = ops
[0];
12712 OMP_CLAUSE_CHAIN (c
) = list
;
12717 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, 0);
12728 c_parser_oacc_simple_clause (c_parser
*parser
, enum omp_clause_code code
,
12731 check_no_duplicate_clause (list
, code
, omp_clause_code_name
[code
]);
12733 tree c
= build_omp_clause (c_parser_peek_token (parser
)->location
, code
);
12734 OMP_CLAUSE_CHAIN (c
) = list
;
12740 async [( int-expr )] */
12743 c_parser_oacc_clause_async (c_parser
*parser
, tree list
)
12746 location_t loc
= c_parser_peek_token (parser
)->location
;
12748 t
= build_int_cst (integer_type_node
, GOMP_ASYNC_NOVAL
);
12750 if (c_parser_peek_token (parser
)->type
== CPP_OPEN_PAREN
)
12752 c_parser_consume_token (parser
);
12754 t
= c_parser_expression (parser
).value
;
12755 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
12756 c_parser_error (parser
, "expected integer expression");
12757 else if (t
== error_mark_node
12758 || !c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
12762 t
= c_fully_fold (t
, false, NULL
);
12764 check_no_duplicate_clause (list
, OMP_CLAUSE_ASYNC
, "async");
12766 c
= build_omp_clause (loc
, OMP_CLAUSE_ASYNC
);
12767 OMP_CLAUSE_ASYNC_EXPR (c
) = t
;
12768 OMP_CLAUSE_CHAIN (c
) = list
;
12775 tile ( size-expr-list ) */
12778 c_parser_oacc_clause_tile (c_parser
*parser
, tree list
)
12780 tree c
, expr
= error_mark_node
;
12782 tree tile
= NULL_TREE
;
12784 check_no_duplicate_clause (list
, OMP_CLAUSE_TILE
, "tile");
12785 check_no_duplicate_clause (list
, OMP_CLAUSE_COLLAPSE
, "collapse");
12787 loc
= c_parser_peek_token (parser
)->location
;
12788 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
12793 if (tile
&& !c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
12796 if (c_parser_next_token_is (parser
, CPP_MULT
)
12797 && (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
12798 || c_parser_peek_2nd_token (parser
)->type
== CPP_CLOSE_PAREN
))
12800 c_parser_consume_token (parser
);
12801 expr
= integer_zero_node
;
12805 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
12806 c_expr cexpr
= c_parser_expr_no_commas (parser
, NULL
);
12807 cexpr
= convert_lvalue_to_rvalue (expr_loc
, cexpr
, false, true);
12808 expr
= cexpr
.value
;
12810 if (expr
== error_mark_node
)
12812 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
12817 expr
= c_fully_fold (expr
, false, NULL
);
12819 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr
))
12820 || !tree_fits_shwi_p (expr
)
12821 || tree_to_shwi (expr
) <= 0)
12823 error_at (expr_loc
, "%<tile%> argument needs positive"
12824 " integral constant");
12825 expr
= integer_zero_node
;
12829 tile
= tree_cons (NULL_TREE
, expr
, tile
);
12831 while (c_parser_next_token_is_not (parser
, CPP_CLOSE_PAREN
));
12833 /* Consume the trailing ')'. */
12834 c_parser_consume_token (parser
);
12836 c
= build_omp_clause (loc
, OMP_CLAUSE_TILE
);
12837 tile
= nreverse (tile
);
12838 OMP_CLAUSE_TILE_LIST (c
) = tile
;
12839 OMP_CLAUSE_CHAIN (c
) = list
;
12844 wait ( int-expr-list ) */
12847 c_parser_oacc_clause_wait (c_parser
*parser
, tree list
)
12849 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
12851 if (c_parser_peek_token (parser
)->type
== CPP_OPEN_PAREN
)
12852 list
= c_parser_oacc_wait_list (parser
, clause_loc
, list
);
12861 ordered ( constant-expression ) */
12864 c_parser_omp_clause_ordered (c_parser
*parser
, tree list
)
12866 check_no_duplicate_clause (list
, OMP_CLAUSE_ORDERED
, "ordered");
12868 tree c
, num
= NULL_TREE
;
12870 location_t loc
= c_parser_peek_token (parser
)->location
;
12871 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
12873 matching_parens parens
;
12874 parens
.consume_open (parser
);
12875 num
= c_parser_expr_no_commas (parser
, NULL
).value
;
12876 parens
.skip_until_found_close (parser
);
12878 if (num
== error_mark_node
)
12882 mark_exp_read (num
);
12883 num
= c_fully_fold (num
, false, NULL
);
12884 if (!INTEGRAL_TYPE_P (TREE_TYPE (num
))
12885 || !tree_fits_shwi_p (num
)
12886 || (n
= tree_to_shwi (num
)) <= 0
12889 error_at (loc
, "ordered argument needs positive "
12890 "constant integer expression");
12894 c
= build_omp_clause (loc
, OMP_CLAUSE_ORDERED
);
12895 OMP_CLAUSE_ORDERED_EXPR (c
) = num
;
12896 OMP_CLAUSE_CHAIN (c
) = list
;
12901 private ( variable-list ) */
12904 c_parser_omp_clause_private (c_parser
*parser
, tree list
)
12906 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_PRIVATE
, list
);
12910 reduction ( reduction-operator : variable-list )
12912 reduction-operator:
12913 One of: + * - & ^ | && ||
12917 reduction-operator:
12918 One of: + * - & ^ | && || max min
12922 reduction-operator:
12923 One of: + * - & ^ | && ||
12927 c_parser_omp_clause_reduction (c_parser
*parser
, tree list
)
12929 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
12930 matching_parens parens
;
12931 if (parens
.require_open (parser
))
12933 enum tree_code code
= ERROR_MARK
;
12934 tree reduc_id
= NULL_TREE
;
12936 switch (c_parser_peek_token (parser
)->type
)
12948 code
= BIT_AND_EXPR
;
12951 code
= BIT_XOR_EXPR
;
12954 code
= BIT_IOR_EXPR
;
12957 code
= TRUTH_ANDIF_EXPR
;
12960 code
= TRUTH_ORIF_EXPR
;
12965 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
12966 if (strcmp (p
, "min") == 0)
12971 if (strcmp (p
, "max") == 0)
12976 reduc_id
= c_parser_peek_token (parser
)->value
;
12980 c_parser_error (parser
,
12981 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
12982 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
12983 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, 0);
12986 c_parser_consume_token (parser
);
12987 reduc_id
= c_omp_reduction_id (code
, reduc_id
);
12988 if (c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
12992 nl
= c_parser_omp_variable_list (parser
, clause_loc
,
12993 OMP_CLAUSE_REDUCTION
, list
);
12994 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
12996 tree d
= OMP_CLAUSE_DECL (c
), type
;
12997 if (TREE_CODE (d
) != TREE_LIST
)
12998 type
= TREE_TYPE (d
);
13003 for (t
= d
; TREE_CODE (t
) == TREE_LIST
; t
= TREE_CHAIN (t
))
13005 type
= TREE_TYPE (t
);
13008 if (TREE_CODE (type
) != POINTER_TYPE
13009 && TREE_CODE (type
) != ARRAY_TYPE
)
13011 type
= TREE_TYPE (type
);
13015 while (TREE_CODE (type
) == ARRAY_TYPE
)
13016 type
= TREE_TYPE (type
);
13017 OMP_CLAUSE_REDUCTION_CODE (c
) = code
;
13018 if (code
== ERROR_MARK
13019 || !(INTEGRAL_TYPE_P (type
)
13020 || TREE_CODE (type
) == REAL_TYPE
13021 || TREE_CODE (type
) == COMPLEX_TYPE
))
13022 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
)
13023 = c_omp_reduction_lookup (reduc_id
,
13024 TYPE_MAIN_VARIANT (type
));
13029 parens
.skip_until_found_close (parser
);
13035 schedule ( schedule-kind )
13036 schedule ( schedule-kind , expression )
13039 static | dynamic | guided | runtime | auto
13042 schedule ( schedule-modifier : schedule-kind )
13043 schedule ( schedule-modifier [ , schedule-modifier ] : schedule-kind , expression )
13051 c_parser_omp_clause_schedule (c_parser
*parser
, tree list
)
13054 location_t loc
= c_parser_peek_token (parser
)->location
;
13055 int modifiers
= 0, nmodifiers
= 0;
13057 matching_parens parens
;
13058 if (!parens
.require_open (parser
))
13061 c
= build_omp_clause (loc
, OMP_CLAUSE_SCHEDULE
);
13063 while (c_parser_next_token_is (parser
, CPP_NAME
))
13065 tree kind
= c_parser_peek_token (parser
)->value
;
13066 const char *p
= IDENTIFIER_POINTER (kind
);
13067 if (strcmp ("simd", p
) == 0)
13068 OMP_CLAUSE_SCHEDULE_SIMD (c
) = 1;
13069 else if (strcmp ("monotonic", p
) == 0)
13070 modifiers
|= OMP_CLAUSE_SCHEDULE_MONOTONIC
;
13071 else if (strcmp ("nonmonotonic", p
) == 0)
13072 modifiers
|= OMP_CLAUSE_SCHEDULE_NONMONOTONIC
;
13075 c_parser_consume_token (parser
);
13076 if (nmodifiers
++ == 0
13077 && c_parser_next_token_is (parser
, CPP_COMMA
))
13078 c_parser_consume_token (parser
);
13081 c_parser_require (parser
, CPP_COLON
, "expected %<:%>");
13086 if ((modifiers
& (OMP_CLAUSE_SCHEDULE_MONOTONIC
13087 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC
))
13088 == (OMP_CLAUSE_SCHEDULE_MONOTONIC
13089 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC
))
13091 error_at (loc
, "both %<monotonic%> and %<nonmonotonic%> modifiers "
13096 if (c_parser_next_token_is (parser
, CPP_NAME
))
13098 tree kind
= c_parser_peek_token (parser
)->value
;
13099 const char *p
= IDENTIFIER_POINTER (kind
);
13104 if (strcmp ("dynamic", p
) != 0)
13106 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_DYNAMIC
;
13110 if (strcmp ("guided", p
) != 0)
13112 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_GUIDED
;
13116 if (strcmp ("runtime", p
) != 0)
13118 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_RUNTIME
;
13125 else if (c_parser_next_token_is_keyword (parser
, RID_STATIC
))
13126 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_STATIC
;
13127 else if (c_parser_next_token_is_keyword (parser
, RID_AUTO
))
13128 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_AUTO
;
13132 c_parser_consume_token (parser
);
13133 if (c_parser_next_token_is (parser
, CPP_COMMA
))
13136 c_parser_consume_token (parser
);
13138 here
= c_parser_peek_token (parser
)->location
;
13139 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
13140 expr
= convert_lvalue_to_rvalue (here
, expr
, false, true);
13142 t
= c_fully_fold (t
, false, NULL
);
13144 if (OMP_CLAUSE_SCHEDULE_KIND (c
) == OMP_CLAUSE_SCHEDULE_RUNTIME
)
13145 error_at (here
, "schedule %<runtime%> does not take "
13146 "a %<chunk_size%> parameter");
13147 else if (OMP_CLAUSE_SCHEDULE_KIND (c
) == OMP_CLAUSE_SCHEDULE_AUTO
)
13149 "schedule %<auto%> does not take "
13150 "a %<chunk_size%> parameter");
13151 else if (TREE_CODE (TREE_TYPE (t
)) == INTEGER_TYPE
)
13153 /* Attempt to statically determine when the number isn't
13155 tree s
= fold_build2_loc (loc
, LE_EXPR
, boolean_type_node
, t
,
13156 build_int_cst (TREE_TYPE (t
), 0));
13157 protected_set_expr_location (s
, loc
);
13158 if (s
== boolean_true_node
)
13160 warning_at (loc
, 0,
13161 "chunk size value must be positive");
13162 t
= integer_one_node
;
13164 OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c
) = t
;
13167 c_parser_error (parser
, "expected integer expression");
13169 parens
.skip_until_found_close (parser
);
13172 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
13173 "expected %<,%> or %<)%>");
13175 OMP_CLAUSE_SCHEDULE_KIND (c
)
13176 = (enum omp_clause_schedule_kind
)
13177 (OMP_CLAUSE_SCHEDULE_KIND (c
) | modifiers
);
13179 check_no_duplicate_clause (list
, OMP_CLAUSE_SCHEDULE
, "schedule");
13180 OMP_CLAUSE_CHAIN (c
) = list
;
13184 c_parser_error (parser
, "invalid schedule kind");
13185 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, 0);
13190 shared ( variable-list ) */
13193 c_parser_omp_clause_shared (c_parser
*parser
, tree list
)
13195 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_SHARED
, list
);
13202 c_parser_omp_clause_untied (c_parser
*parser ATTRIBUTE_UNUSED
, tree list
)
13206 /* FIXME: Should we allow duplicates? */
13207 check_no_duplicate_clause (list
, OMP_CLAUSE_UNTIED
, "untied");
13209 c
= build_omp_clause (c_parser_peek_token (parser
)->location
,
13210 OMP_CLAUSE_UNTIED
);
13211 OMP_CLAUSE_CHAIN (c
) = list
;
13221 c_parser_omp_clause_branch (c_parser
*parser ATTRIBUTE_UNUSED
,
13222 enum omp_clause_code code
, tree list
)
13224 check_no_duplicate_clause (list
, code
, omp_clause_code_name
[code
]);
13226 tree c
= build_omp_clause (c_parser_peek_token (parser
)->location
, code
);
13227 OMP_CLAUSE_CHAIN (c
) = list
;
13239 c_parser_omp_clause_cancelkind (c_parser
*parser ATTRIBUTE_UNUSED
,
13240 enum omp_clause_code code
, tree list
)
13242 tree c
= build_omp_clause (c_parser_peek_token (parser
)->location
, code
);
13243 OMP_CLAUSE_CHAIN (c
) = list
;
13252 c_parser_omp_clause_nogroup (c_parser
*parser ATTRIBUTE_UNUSED
, tree list
)
13254 check_no_duplicate_clause (list
, OMP_CLAUSE_NOGROUP
, "nogroup");
13255 tree c
= build_omp_clause (c_parser_peek_token (parser
)->location
,
13256 OMP_CLAUSE_NOGROUP
);
13257 OMP_CLAUSE_CHAIN (c
) = list
;
13266 c_parser_omp_clause_orderedkind (c_parser
*parser ATTRIBUTE_UNUSED
,
13267 enum omp_clause_code code
, tree list
)
13269 check_no_duplicate_clause (list
, code
, omp_clause_code_name
[code
]);
13270 tree c
= build_omp_clause (c_parser_peek_token (parser
)->location
, code
);
13271 OMP_CLAUSE_CHAIN (c
) = list
;
13276 num_teams ( expression ) */
13279 c_parser_omp_clause_num_teams (c_parser
*parser
, tree list
)
13281 location_t num_teams_loc
= c_parser_peek_token (parser
)->location
;
13282 matching_parens parens
;
13283 if (parens
.require_open (parser
))
13285 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
13286 c_expr expr
= c_parser_expression (parser
);
13287 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
13288 tree c
, t
= expr
.value
;
13289 t
= c_fully_fold (t
, false, NULL
);
13291 parens
.skip_until_found_close (parser
);
13293 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
13295 c_parser_error (parser
, "expected integer expression");
13299 /* Attempt to statically determine when the number isn't positive. */
13300 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
13301 build_int_cst (TREE_TYPE (t
), 0));
13302 protected_set_expr_location (c
, expr_loc
);
13303 if (c
== boolean_true_node
)
13305 warning_at (expr_loc
, 0, "%<num_teams%> value must be positive");
13306 t
= integer_one_node
;
13309 check_no_duplicate_clause (list
, OMP_CLAUSE_NUM_TEAMS
, "num_teams");
13311 c
= build_omp_clause (num_teams_loc
, OMP_CLAUSE_NUM_TEAMS
);
13312 OMP_CLAUSE_NUM_TEAMS_EXPR (c
) = t
;
13313 OMP_CLAUSE_CHAIN (c
) = list
;
13321 thread_limit ( expression ) */
13324 c_parser_omp_clause_thread_limit (c_parser
*parser
, tree list
)
13326 location_t num_thread_limit_loc
= c_parser_peek_token (parser
)->location
;
13327 matching_parens parens
;
13328 if (parens
.require_open (parser
))
13330 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
13331 c_expr expr
= c_parser_expression (parser
);
13332 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
13333 tree c
, t
= expr
.value
;
13334 t
= c_fully_fold (t
, false, NULL
);
13336 parens
.skip_until_found_close (parser
);
13338 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
13340 c_parser_error (parser
, "expected integer expression");
13344 /* Attempt to statically determine when the number isn't positive. */
13345 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
13346 build_int_cst (TREE_TYPE (t
), 0));
13347 protected_set_expr_location (c
, expr_loc
);
13348 if (c
== boolean_true_node
)
13350 warning_at (expr_loc
, 0, "%<thread_limit%> value must be positive");
13351 t
= integer_one_node
;
13354 check_no_duplicate_clause (list
, OMP_CLAUSE_THREAD_LIMIT
,
13357 c
= build_omp_clause (num_thread_limit_loc
, OMP_CLAUSE_THREAD_LIMIT
);
13358 OMP_CLAUSE_THREAD_LIMIT_EXPR (c
) = t
;
13359 OMP_CLAUSE_CHAIN (c
) = list
;
13367 aligned ( variable-list )
13368 aligned ( variable-list : constant-expression ) */
13371 c_parser_omp_clause_aligned (c_parser
*parser
, tree list
)
13373 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
13376 matching_parens parens
;
13377 if (!parens
.require_open (parser
))
13380 nl
= c_parser_omp_variable_list (parser
, clause_loc
,
13381 OMP_CLAUSE_ALIGNED
, list
);
13383 if (c_parser_next_token_is (parser
, CPP_COLON
))
13385 c_parser_consume_token (parser
);
13386 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
13387 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
13388 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
13389 tree alignment
= expr
.value
;
13390 alignment
= c_fully_fold (alignment
, false, NULL
);
13391 if (TREE_CODE (alignment
) != INTEGER_CST
13392 || !INTEGRAL_TYPE_P (TREE_TYPE (alignment
))
13393 || tree_int_cst_sgn (alignment
) != 1)
13395 error_at (clause_loc
, "%<aligned%> clause alignment expression must "
13396 "be positive constant integer expression");
13397 alignment
= NULL_TREE
;
13400 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
13401 OMP_CLAUSE_ALIGNED_ALIGNMENT (c
) = alignment
;
13404 parens
.skip_until_found_close (parser
);
13409 linear ( variable-list )
13410 linear ( variable-list : expression )
13413 linear ( modifier ( variable-list ) )
13414 linear ( modifier ( variable-list ) : expression ) */
13417 c_parser_omp_clause_linear (c_parser
*parser
, tree list
, bool is_cilk_simd_fn
)
13419 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
13421 enum omp_clause_linear_kind kind
= OMP_CLAUSE_LINEAR_DEFAULT
;
13423 matching_parens parens
;
13424 if (!parens
.require_open (parser
))
13427 if (!is_cilk_simd_fn
13428 && c_parser_next_token_is (parser
, CPP_NAME
))
13430 c_token
*tok
= c_parser_peek_token (parser
);
13431 const char *p
= IDENTIFIER_POINTER (tok
->value
);
13432 if (strcmp ("val", p
) == 0)
13433 kind
= OMP_CLAUSE_LINEAR_VAL
;
13434 if (c_parser_peek_2nd_token (parser
)->type
!= CPP_OPEN_PAREN
)
13435 kind
= OMP_CLAUSE_LINEAR_DEFAULT
;
13436 if (kind
!= OMP_CLAUSE_LINEAR_DEFAULT
)
13438 c_parser_consume_token (parser
);
13439 c_parser_consume_token (parser
);
13443 nl
= c_parser_omp_variable_list (parser
, clause_loc
,
13444 OMP_CLAUSE_LINEAR
, list
);
13446 if (kind
!= OMP_CLAUSE_LINEAR_DEFAULT
)
13447 parens
.skip_until_found_close (parser
);
13449 if (c_parser_next_token_is (parser
, CPP_COLON
))
13451 c_parser_consume_token (parser
);
13452 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
13453 c_expr expr
= c_parser_expression (parser
);
13454 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
13456 step
= c_fully_fold (step
, false, NULL
);
13457 if (is_cilk_simd_fn
&& TREE_CODE (step
) == PARM_DECL
)
13459 sorry ("using parameters for %<linear%> step is not supported yet");
13460 step
= integer_one_node
;
13462 if (!INTEGRAL_TYPE_P (TREE_TYPE (step
)))
13464 error_at (clause_loc
, "%<linear%> clause step expression must "
13466 step
= integer_one_node
;
13471 step
= integer_one_node
;
13473 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
13475 OMP_CLAUSE_LINEAR_STEP (c
) = step
;
13476 OMP_CLAUSE_LINEAR_KIND (c
) = kind
;
13479 parens
.skip_until_found_close (parser
);
13484 safelen ( constant-expression ) */
13487 c_parser_omp_clause_safelen (c_parser
*parser
, tree list
)
13489 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
13492 matching_parens parens
;
13493 if (!parens
.require_open (parser
))
13496 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
13497 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
13498 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
13500 t
= c_fully_fold (t
, false, NULL
);
13501 if (TREE_CODE (t
) != INTEGER_CST
13502 || !INTEGRAL_TYPE_P (TREE_TYPE (t
))
13503 || tree_int_cst_sgn (t
) != 1)
13505 error_at (clause_loc
, "%<safelen%> clause expression must "
13506 "be positive constant integer expression");
13510 parens
.skip_until_found_close (parser
);
13511 if (t
== NULL_TREE
|| t
== error_mark_node
)
13514 check_no_duplicate_clause (list
, OMP_CLAUSE_SAFELEN
, "safelen");
13516 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_SAFELEN
);
13517 OMP_CLAUSE_SAFELEN_EXPR (c
) = t
;
13518 OMP_CLAUSE_CHAIN (c
) = list
;
13523 simdlen ( constant-expression ) */
13526 c_parser_omp_clause_simdlen (c_parser
*parser
, tree list
)
13528 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
13531 matching_parens parens
;
13532 if (!parens
.require_open (parser
))
13535 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
13536 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
13537 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
13539 t
= c_fully_fold (t
, false, NULL
);
13540 if (TREE_CODE (t
) != INTEGER_CST
13541 || !INTEGRAL_TYPE_P (TREE_TYPE (t
))
13542 || tree_int_cst_sgn (t
) != 1)
13544 error_at (clause_loc
, "%<simdlen%> clause expression must "
13545 "be positive constant integer expression");
13549 parens
.skip_until_found_close (parser
);
13550 if (t
== NULL_TREE
|| t
== error_mark_node
)
13553 check_no_duplicate_clause (list
, OMP_CLAUSE_SIMDLEN
, "simdlen");
13555 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_SIMDLEN
);
13556 OMP_CLAUSE_SIMDLEN_EXPR (c
) = t
;
13557 OMP_CLAUSE_CHAIN (c
) = list
;
13563 identifier [+/- integer]
13564 vec , identifier [+/- integer]
13568 c_parser_omp_clause_depend_sink (c_parser
*parser
, location_t clause_loc
,
13572 if (c_parser_next_token_is_not (parser
, CPP_NAME
)
13573 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
13575 c_parser_error (parser
, "expected identifier");
13579 while (c_parser_next_token_is (parser
, CPP_NAME
)
13580 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
)
13582 tree t
= lookup_name (c_parser_peek_token (parser
)->value
);
13583 tree addend
= NULL
;
13585 if (t
== NULL_TREE
)
13587 undeclared_variable (c_parser_peek_token (parser
)->location
,
13588 c_parser_peek_token (parser
)->value
);
13589 t
= error_mark_node
;
13592 c_parser_consume_token (parser
);
13595 if (c_parser_next_token_is (parser
, CPP_MINUS
))
13597 else if (!c_parser_next_token_is (parser
, CPP_PLUS
))
13599 addend
= integer_zero_node
;
13601 goto add_to_vector
;
13603 c_parser_consume_token (parser
);
13605 if (c_parser_next_token_is_not (parser
, CPP_NUMBER
))
13607 c_parser_error (parser
, "expected integer");
13611 addend
= c_parser_peek_token (parser
)->value
;
13612 if (TREE_CODE (addend
) != INTEGER_CST
)
13614 c_parser_error (parser
, "expected integer");
13617 c_parser_consume_token (parser
);
13620 if (t
!= error_mark_node
)
13622 vec
= tree_cons (addend
, t
, vec
);
13624 OMP_CLAUSE_DEPEND_SINK_NEGATIVE (vec
) = 1;
13627 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
13630 c_parser_consume_token (parser
);
13633 if (vec
== NULL_TREE
)
13636 tree u
= build_omp_clause (clause_loc
, OMP_CLAUSE_DEPEND
);
13637 OMP_CLAUSE_DEPEND_KIND (u
) = OMP_CLAUSE_DEPEND_SINK
;
13638 OMP_CLAUSE_DECL (u
) = nreverse (vec
);
13639 OMP_CLAUSE_CHAIN (u
) = list
;
13644 depend ( depend-kind: variable-list )
13652 depend ( sink : vec ) */
13655 c_parser_omp_clause_depend (c_parser
*parser
, tree list
)
13657 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
13658 enum omp_clause_depend_kind kind
= OMP_CLAUSE_DEPEND_INOUT
;
13661 matching_parens parens
;
13662 if (!parens
.require_open (parser
))
13665 if (c_parser_next_token_is (parser
, CPP_NAME
))
13667 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
13668 if (strcmp ("in", p
) == 0)
13669 kind
= OMP_CLAUSE_DEPEND_IN
;
13670 else if (strcmp ("inout", p
) == 0)
13671 kind
= OMP_CLAUSE_DEPEND_INOUT
;
13672 else if (strcmp ("out", p
) == 0)
13673 kind
= OMP_CLAUSE_DEPEND_OUT
;
13674 else if (strcmp ("source", p
) == 0)
13675 kind
= OMP_CLAUSE_DEPEND_SOURCE
;
13676 else if (strcmp ("sink", p
) == 0)
13677 kind
= OMP_CLAUSE_DEPEND_SINK
;
13684 c_parser_consume_token (parser
);
13686 if (kind
== OMP_CLAUSE_DEPEND_SOURCE
)
13688 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_DEPEND
);
13689 OMP_CLAUSE_DEPEND_KIND (c
) = kind
;
13690 OMP_CLAUSE_DECL (c
) = NULL_TREE
;
13691 OMP_CLAUSE_CHAIN (c
) = list
;
13692 parens
.skip_until_found_close (parser
);
13696 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
13699 if (kind
== OMP_CLAUSE_DEPEND_SINK
)
13700 nl
= c_parser_omp_clause_depend_sink (parser
, clause_loc
, list
);
13703 nl
= c_parser_omp_variable_list (parser
, clause_loc
,
13704 OMP_CLAUSE_DEPEND
, list
);
13706 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
13707 OMP_CLAUSE_DEPEND_KIND (c
) = kind
;
13710 parens
.skip_until_found_close (parser
);
13714 c_parser_error (parser
, "invalid depend kind");
13716 parens
.skip_until_found_close (parser
);
13721 map ( map-kind: variable-list )
13722 map ( variable-list )
13725 alloc | to | from | tofrom
13729 alloc | to | from | tofrom | release | delete
13731 map ( always [,] map-kind: variable-list ) */
13734 c_parser_omp_clause_map (c_parser
*parser
, tree list
)
13736 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
13737 enum gomp_map_kind kind
= GOMP_MAP_TOFROM
;
13739 enum c_id_kind always_id_kind
= C_ID_NONE
;
13740 location_t always_loc
= UNKNOWN_LOCATION
;
13741 tree always_id
= NULL_TREE
;
13744 matching_parens parens
;
13745 if (!parens
.require_open (parser
))
13748 if (c_parser_next_token_is (parser
, CPP_NAME
))
13750 c_token
*tok
= c_parser_peek_token (parser
);
13751 const char *p
= IDENTIFIER_POINTER (tok
->value
);
13752 always_id_kind
= tok
->id_kind
;
13753 always_loc
= tok
->location
;
13754 always_id
= tok
->value
;
13755 if (strcmp ("always", p
) == 0)
13757 c_token
*sectok
= c_parser_peek_2nd_token (parser
);
13758 if (sectok
->type
== CPP_COMMA
)
13760 c_parser_consume_token (parser
);
13761 c_parser_consume_token (parser
);
13764 else if (sectok
->type
== CPP_NAME
)
13766 p
= IDENTIFIER_POINTER (sectok
->value
);
13767 if (strcmp ("alloc", p
) == 0
13768 || strcmp ("to", p
) == 0
13769 || strcmp ("from", p
) == 0
13770 || strcmp ("tofrom", p
) == 0
13771 || strcmp ("release", p
) == 0
13772 || strcmp ("delete", p
) == 0)
13774 c_parser_consume_token (parser
);
13781 if (c_parser_next_token_is (parser
, CPP_NAME
)
13782 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
13784 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
13785 if (strcmp ("alloc", p
) == 0)
13786 kind
= GOMP_MAP_ALLOC
;
13787 else if (strcmp ("to", p
) == 0)
13788 kind
= always
? GOMP_MAP_ALWAYS_TO
: GOMP_MAP_TO
;
13789 else if (strcmp ("from", p
) == 0)
13790 kind
= always
? GOMP_MAP_ALWAYS_FROM
: GOMP_MAP_FROM
;
13791 else if (strcmp ("tofrom", p
) == 0)
13792 kind
= always
? GOMP_MAP_ALWAYS_TOFROM
: GOMP_MAP_TOFROM
;
13793 else if (strcmp ("release", p
) == 0)
13794 kind
= GOMP_MAP_RELEASE
;
13795 else if (strcmp ("delete", p
) == 0)
13796 kind
= GOMP_MAP_DELETE
;
13799 c_parser_error (parser
, "invalid map kind");
13800 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
13804 c_parser_consume_token (parser
);
13805 c_parser_consume_token (parser
);
13809 if (always_id_kind
!= C_ID_ID
)
13811 c_parser_error (parser
, "expected identifier");
13812 parens
.skip_until_found_close (parser
);
13816 tree t
= lookup_name (always_id
);
13817 if (t
== NULL_TREE
)
13819 undeclared_variable (always_loc
, always_id
);
13820 t
= error_mark_node
;
13822 if (t
!= error_mark_node
)
13824 tree u
= build_omp_clause (clause_loc
, OMP_CLAUSE_MAP
);
13825 OMP_CLAUSE_DECL (u
) = t
;
13826 OMP_CLAUSE_CHAIN (u
) = list
;
13827 OMP_CLAUSE_SET_MAP_KIND (u
, kind
);
13832 parens
.skip_until_found_close (parser
);
13837 nl
= c_parser_omp_variable_list (parser
, clause_loc
, OMP_CLAUSE_MAP
, list
);
13839 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
13840 OMP_CLAUSE_SET_MAP_KIND (c
, kind
);
13842 parens
.skip_until_found_close (parser
);
13847 device ( expression ) */
13850 c_parser_omp_clause_device (c_parser
*parser
, tree list
)
13852 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
13853 matching_parens parens
;
13854 if (parens
.require_open (parser
))
13856 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
13857 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
13858 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
13859 tree c
, t
= expr
.value
;
13860 t
= c_fully_fold (t
, false, NULL
);
13862 parens
.skip_until_found_close (parser
);
13864 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
13866 c_parser_error (parser
, "expected integer expression");
13870 check_no_duplicate_clause (list
, OMP_CLAUSE_DEVICE
, "device");
13872 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_DEVICE
);
13873 OMP_CLAUSE_DEVICE_ID (c
) = t
;
13874 OMP_CLAUSE_CHAIN (c
) = list
;
13882 dist_schedule ( static )
13883 dist_schedule ( static , expression ) */
13886 c_parser_omp_clause_dist_schedule (c_parser
*parser
, tree list
)
13888 tree c
, t
= NULL_TREE
;
13889 location_t loc
= c_parser_peek_token (parser
)->location
;
13891 matching_parens parens
;
13892 if (!parens
.require_open (parser
))
13895 if (!c_parser_next_token_is_keyword (parser
, RID_STATIC
))
13897 c_parser_error (parser
, "invalid dist_schedule kind");
13898 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
13903 c_parser_consume_token (parser
);
13904 if (c_parser_next_token_is (parser
, CPP_COMMA
))
13906 c_parser_consume_token (parser
);
13908 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
13909 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
13910 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
13912 t
= c_fully_fold (t
, false, NULL
);
13913 parens
.skip_until_found_close (parser
);
13916 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
13917 "expected %<,%> or %<)%>");
13919 check_no_duplicate_clause (list
, OMP_CLAUSE_SCHEDULE
, "schedule");
13920 if (t
== error_mark_node
)
13923 c
= build_omp_clause (loc
, OMP_CLAUSE_DIST_SCHEDULE
);
13924 OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c
) = t
;
13925 OMP_CLAUSE_CHAIN (c
) = list
;
13930 proc_bind ( proc-bind-kind )
13933 master | close | spread */
13936 c_parser_omp_clause_proc_bind (c_parser
*parser
, tree list
)
13938 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
13939 enum omp_clause_proc_bind_kind kind
;
13942 matching_parens parens
;
13943 if (!parens
.require_open (parser
))
13946 if (c_parser_next_token_is (parser
, CPP_NAME
))
13948 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
13949 if (strcmp ("master", p
) == 0)
13950 kind
= OMP_CLAUSE_PROC_BIND_MASTER
;
13951 else if (strcmp ("close", p
) == 0)
13952 kind
= OMP_CLAUSE_PROC_BIND_CLOSE
;
13953 else if (strcmp ("spread", p
) == 0)
13954 kind
= OMP_CLAUSE_PROC_BIND_SPREAD
;
13961 c_parser_consume_token (parser
);
13962 parens
.skip_until_found_close (parser
);
13963 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_PROC_BIND
);
13964 OMP_CLAUSE_PROC_BIND_KIND (c
) = kind
;
13965 OMP_CLAUSE_CHAIN (c
) = list
;
13969 c_parser_error (parser
, "invalid proc_bind kind");
13970 parens
.skip_until_found_close (parser
);
13975 to ( variable-list ) */
13978 c_parser_omp_clause_to (c_parser
*parser
, tree list
)
13980 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_TO
, list
);
13984 from ( variable-list ) */
13987 c_parser_omp_clause_from (c_parser
*parser
, tree list
)
13989 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_FROM
, list
);
13993 uniform ( variable-list ) */
13996 c_parser_omp_clause_uniform (c_parser
*parser
, tree list
)
13998 /* The clauses location. */
13999 location_t loc
= c_parser_peek_token (parser
)->location
;
14001 matching_parens parens
;
14002 if (parens
.require_open (parser
))
14004 list
= c_parser_omp_variable_list (parser
, loc
, OMP_CLAUSE_UNIFORM
,
14006 parens
.skip_until_found_close (parser
);
14011 /* Parse all OpenACC clauses. The set clauses allowed by the directive
14012 is a bitmask in MASK. Return the list of clauses found. */
14015 c_parser_oacc_all_clauses (c_parser
*parser
, omp_clause_mask mask
,
14016 const char *where
, bool finish_p
= true)
14018 tree clauses
= NULL
;
14021 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
14024 pragma_omp_clause c_kind
;
14025 const char *c_name
;
14026 tree prev
= clauses
;
14028 if (!first
&& c_parser_next_token_is (parser
, CPP_COMMA
))
14029 c_parser_consume_token (parser
);
14031 here
= c_parser_peek_token (parser
)->location
;
14032 c_kind
= c_parser_omp_clause_name (parser
);
14036 case PRAGMA_OACC_CLAUSE_ASYNC
:
14037 clauses
= c_parser_oacc_clause_async (parser
, clauses
);
14040 case PRAGMA_OACC_CLAUSE_AUTO
:
14041 clauses
= c_parser_oacc_simple_clause (parser
, OMP_CLAUSE_AUTO
,
14045 case PRAGMA_OACC_CLAUSE_COLLAPSE
:
14046 clauses
= c_parser_omp_clause_collapse (parser
, clauses
);
14047 c_name
= "collapse";
14049 case PRAGMA_OACC_CLAUSE_COPY
:
14050 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
14053 case PRAGMA_OACC_CLAUSE_COPYIN
:
14054 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
14057 case PRAGMA_OACC_CLAUSE_COPYOUT
:
14058 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
14059 c_name
= "copyout";
14061 case PRAGMA_OACC_CLAUSE_CREATE
:
14062 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
14065 case PRAGMA_OACC_CLAUSE_DELETE
:
14066 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
14069 case PRAGMA_OMP_CLAUSE_DEFAULT
:
14070 clauses
= c_parser_omp_clause_default (parser
, clauses
, true);
14071 c_name
= "default";
14073 case PRAGMA_OACC_CLAUSE_DEVICE
:
14074 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
14077 case PRAGMA_OACC_CLAUSE_DEVICEPTR
:
14078 clauses
= c_parser_oacc_data_clause_deviceptr (parser
, clauses
);
14079 c_name
= "deviceptr";
14081 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT
:
14082 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
14083 c_name
= "device_resident";
14085 case PRAGMA_OACC_CLAUSE_FIRSTPRIVATE
:
14086 clauses
= c_parser_omp_clause_firstprivate (parser
, clauses
);
14087 c_name
= "firstprivate";
14089 case PRAGMA_OACC_CLAUSE_GANG
:
14091 clauses
= c_parser_oacc_shape_clause (parser
, OMP_CLAUSE_GANG
,
14094 case PRAGMA_OACC_CLAUSE_HOST
:
14095 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
14098 case PRAGMA_OACC_CLAUSE_IF
:
14099 clauses
= c_parser_omp_clause_if (parser
, clauses
, false);
14102 case PRAGMA_OACC_CLAUSE_INDEPENDENT
:
14103 clauses
= c_parser_oacc_simple_clause (parser
, OMP_CLAUSE_INDEPENDENT
,
14105 c_name
= "independent";
14107 case PRAGMA_OACC_CLAUSE_LINK
:
14108 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
14111 case PRAGMA_OACC_CLAUSE_NUM_GANGS
:
14112 clauses
= c_parser_oacc_single_int_clause (parser
,
14113 OMP_CLAUSE_NUM_GANGS
,
14115 c_name
= "num_gangs";
14117 case PRAGMA_OACC_CLAUSE_NUM_WORKERS
:
14118 clauses
= c_parser_oacc_single_int_clause (parser
,
14119 OMP_CLAUSE_NUM_WORKERS
,
14121 c_name
= "num_workers";
14123 case PRAGMA_OACC_CLAUSE_PRESENT
:
14124 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
14125 c_name
= "present";
14127 case PRAGMA_OACC_CLAUSE_PRESENT_OR_COPY
:
14128 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
14129 c_name
= "present_or_copy";
14131 case PRAGMA_OACC_CLAUSE_PRESENT_OR_COPYIN
:
14132 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
14133 c_name
= "present_or_copyin";
14135 case PRAGMA_OACC_CLAUSE_PRESENT_OR_COPYOUT
:
14136 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
14137 c_name
= "present_or_copyout";
14139 case PRAGMA_OACC_CLAUSE_PRESENT_OR_CREATE
:
14140 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
14141 c_name
= "present_or_create";
14143 case PRAGMA_OACC_CLAUSE_PRIVATE
:
14144 clauses
= c_parser_omp_clause_private (parser
, clauses
);
14145 c_name
= "private";
14147 case PRAGMA_OACC_CLAUSE_REDUCTION
:
14148 clauses
= c_parser_omp_clause_reduction (parser
, clauses
);
14149 c_name
= "reduction";
14151 case PRAGMA_OACC_CLAUSE_SELF
:
14152 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
14155 case PRAGMA_OACC_CLAUSE_SEQ
:
14156 clauses
= c_parser_oacc_simple_clause (parser
, OMP_CLAUSE_SEQ
,
14160 case PRAGMA_OACC_CLAUSE_TILE
:
14161 clauses
= c_parser_oacc_clause_tile (parser
, clauses
);
14164 case PRAGMA_OACC_CLAUSE_USE_DEVICE
:
14165 clauses
= c_parser_omp_clause_use_device_ptr (parser
, clauses
);
14166 c_name
= "use_device";
14168 case PRAGMA_OACC_CLAUSE_VECTOR
:
14170 clauses
= c_parser_oacc_shape_clause (parser
, OMP_CLAUSE_VECTOR
,
14173 case PRAGMA_OACC_CLAUSE_VECTOR_LENGTH
:
14174 clauses
= c_parser_oacc_single_int_clause (parser
,
14175 OMP_CLAUSE_VECTOR_LENGTH
,
14177 c_name
= "vector_length";
14179 case PRAGMA_OACC_CLAUSE_WAIT
:
14180 clauses
= c_parser_oacc_clause_wait (parser
, clauses
);
14183 case PRAGMA_OACC_CLAUSE_WORKER
:
14185 clauses
= c_parser_oacc_shape_clause (parser
, OMP_CLAUSE_WORKER
,
14189 c_parser_error (parser
, "expected %<#pragma acc%> clause");
14195 if (((mask
>> c_kind
) & 1) == 0)
14197 /* Remove the invalid clause(s) from the list to avoid
14198 confusing the rest of the compiler. */
14200 error_at (here
, "%qs is not valid for %qs", c_name
, where
);
14205 c_parser_skip_to_pragma_eol (parser
);
14208 return c_finish_omp_clauses (clauses
, C_ORT_ACC
);
14213 /* Parse all OpenMP clauses. The set clauses allowed by the directive
14214 is a bitmask in MASK. Return the list of clauses found. */
14217 c_parser_omp_all_clauses (c_parser
*parser
, omp_clause_mask mask
,
14218 const char *where
, bool finish_p
= true)
14220 tree clauses
= NULL
;
14221 bool first
= true, cilk_simd_fn
= false;
14223 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
14226 pragma_omp_clause c_kind
;
14227 const char *c_name
;
14228 tree prev
= clauses
;
14230 if (!first
&& c_parser_next_token_is (parser
, CPP_COMMA
))
14231 c_parser_consume_token (parser
);
14233 here
= c_parser_peek_token (parser
)->location
;
14234 c_kind
= c_parser_omp_clause_name (parser
);
14238 case PRAGMA_OMP_CLAUSE_COLLAPSE
:
14239 clauses
= c_parser_omp_clause_collapse (parser
, clauses
);
14240 c_name
= "collapse";
14242 case PRAGMA_OMP_CLAUSE_COPYIN
:
14243 clauses
= c_parser_omp_clause_copyin (parser
, clauses
);
14246 case PRAGMA_OMP_CLAUSE_COPYPRIVATE
:
14247 clauses
= c_parser_omp_clause_copyprivate (parser
, clauses
);
14248 c_name
= "copyprivate";
14250 case PRAGMA_OMP_CLAUSE_DEFAULT
:
14251 clauses
= c_parser_omp_clause_default (parser
, clauses
, false);
14252 c_name
= "default";
14254 case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE
:
14255 clauses
= c_parser_omp_clause_firstprivate (parser
, clauses
);
14256 c_name
= "firstprivate";
14258 case PRAGMA_OMP_CLAUSE_FINAL
:
14259 clauses
= c_parser_omp_clause_final (parser
, clauses
);
14262 case PRAGMA_OMP_CLAUSE_GRAINSIZE
:
14263 clauses
= c_parser_omp_clause_grainsize (parser
, clauses
);
14264 c_name
= "grainsize";
14266 case PRAGMA_OMP_CLAUSE_HINT
:
14267 clauses
= c_parser_omp_clause_hint (parser
, clauses
);
14270 case PRAGMA_OMP_CLAUSE_DEFAULTMAP
:
14271 clauses
= c_parser_omp_clause_defaultmap (parser
, clauses
);
14272 c_name
= "defaultmap";
14274 case PRAGMA_OMP_CLAUSE_IF
:
14275 clauses
= c_parser_omp_clause_if (parser
, clauses
, true);
14278 case PRAGMA_OMP_CLAUSE_LASTPRIVATE
:
14279 clauses
= c_parser_omp_clause_lastprivate (parser
, clauses
);
14280 c_name
= "lastprivate";
14282 case PRAGMA_OMP_CLAUSE_MERGEABLE
:
14283 clauses
= c_parser_omp_clause_mergeable (parser
, clauses
);
14284 c_name
= "mergeable";
14286 case PRAGMA_OMP_CLAUSE_NOWAIT
:
14287 clauses
= c_parser_omp_clause_nowait (parser
, clauses
);
14290 case PRAGMA_OMP_CLAUSE_NUM_TASKS
:
14291 clauses
= c_parser_omp_clause_num_tasks (parser
, clauses
);
14292 c_name
= "num_tasks";
14294 case PRAGMA_OMP_CLAUSE_NUM_THREADS
:
14295 clauses
= c_parser_omp_clause_num_threads (parser
, clauses
);
14296 c_name
= "num_threads";
14298 case PRAGMA_OMP_CLAUSE_ORDERED
:
14299 clauses
= c_parser_omp_clause_ordered (parser
, clauses
);
14300 c_name
= "ordered";
14302 case PRAGMA_OMP_CLAUSE_PRIORITY
:
14303 clauses
= c_parser_omp_clause_priority (parser
, clauses
);
14304 c_name
= "priority";
14306 case PRAGMA_OMP_CLAUSE_PRIVATE
:
14307 clauses
= c_parser_omp_clause_private (parser
, clauses
);
14308 c_name
= "private";
14310 case PRAGMA_OMP_CLAUSE_REDUCTION
:
14311 clauses
= c_parser_omp_clause_reduction (parser
, clauses
);
14312 c_name
= "reduction";
14314 case PRAGMA_OMP_CLAUSE_SCHEDULE
:
14315 clauses
= c_parser_omp_clause_schedule (parser
, clauses
);
14316 c_name
= "schedule";
14318 case PRAGMA_OMP_CLAUSE_SHARED
:
14319 clauses
= c_parser_omp_clause_shared (parser
, clauses
);
14322 case PRAGMA_OMP_CLAUSE_UNTIED
:
14323 clauses
= c_parser_omp_clause_untied (parser
, clauses
);
14326 case PRAGMA_OMP_CLAUSE_INBRANCH
:
14327 case PRAGMA_CILK_CLAUSE_MASK
:
14328 clauses
= c_parser_omp_clause_branch (parser
, OMP_CLAUSE_INBRANCH
,
14330 c_name
= "inbranch";
14332 case PRAGMA_OMP_CLAUSE_NOTINBRANCH
:
14333 case PRAGMA_CILK_CLAUSE_NOMASK
:
14334 clauses
= c_parser_omp_clause_branch (parser
, OMP_CLAUSE_NOTINBRANCH
,
14336 c_name
= "notinbranch";
14338 case PRAGMA_OMP_CLAUSE_PARALLEL
:
14340 = c_parser_omp_clause_cancelkind (parser
, OMP_CLAUSE_PARALLEL
,
14342 c_name
= "parallel";
14346 error_at (here
, "%qs must be the first clause of %qs",
14351 case PRAGMA_OMP_CLAUSE_FOR
:
14353 = c_parser_omp_clause_cancelkind (parser
, OMP_CLAUSE_FOR
,
14357 goto clause_not_first
;
14359 case PRAGMA_OMP_CLAUSE_SECTIONS
:
14361 = c_parser_omp_clause_cancelkind (parser
, OMP_CLAUSE_SECTIONS
,
14363 c_name
= "sections";
14365 goto clause_not_first
;
14367 case PRAGMA_OMP_CLAUSE_TASKGROUP
:
14369 = c_parser_omp_clause_cancelkind (parser
, OMP_CLAUSE_TASKGROUP
,
14371 c_name
= "taskgroup";
14373 goto clause_not_first
;
14375 case PRAGMA_OMP_CLAUSE_LINK
:
14377 = c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_LINK
, clauses
);
14380 case PRAGMA_OMP_CLAUSE_TO
:
14381 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_LINK
)) != 0)
14383 = c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_TO_DECLARE
,
14386 clauses
= c_parser_omp_clause_to (parser
, clauses
);
14389 case PRAGMA_OMP_CLAUSE_FROM
:
14390 clauses
= c_parser_omp_clause_from (parser
, clauses
);
14393 case PRAGMA_OMP_CLAUSE_UNIFORM
:
14394 clauses
= c_parser_omp_clause_uniform (parser
, clauses
);
14395 c_name
= "uniform";
14397 case PRAGMA_OMP_CLAUSE_NUM_TEAMS
:
14398 clauses
= c_parser_omp_clause_num_teams (parser
, clauses
);
14399 c_name
= "num_teams";
14401 case PRAGMA_OMP_CLAUSE_THREAD_LIMIT
:
14402 clauses
= c_parser_omp_clause_thread_limit (parser
, clauses
);
14403 c_name
= "thread_limit";
14405 case PRAGMA_OMP_CLAUSE_ALIGNED
:
14406 clauses
= c_parser_omp_clause_aligned (parser
, clauses
);
14407 c_name
= "aligned";
14409 case PRAGMA_OMP_CLAUSE_LINEAR
:
14410 if (((mask
>> PRAGMA_CILK_CLAUSE_VECTORLENGTH
) & 1) != 0)
14411 cilk_simd_fn
= true;
14412 clauses
= c_parser_omp_clause_linear (parser
, clauses
, cilk_simd_fn
);
14415 case PRAGMA_OMP_CLAUSE_DEPEND
:
14416 clauses
= c_parser_omp_clause_depend (parser
, clauses
);
14419 case PRAGMA_OMP_CLAUSE_MAP
:
14420 clauses
= c_parser_omp_clause_map (parser
, clauses
);
14423 case PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR
:
14424 clauses
= c_parser_omp_clause_use_device_ptr (parser
, clauses
);
14425 c_name
= "use_device_ptr";
14427 case PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR
:
14428 clauses
= c_parser_omp_clause_is_device_ptr (parser
, clauses
);
14429 c_name
= "is_device_ptr";
14431 case PRAGMA_OMP_CLAUSE_DEVICE
:
14432 clauses
= c_parser_omp_clause_device (parser
, clauses
);
14435 case PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
:
14436 clauses
= c_parser_omp_clause_dist_schedule (parser
, clauses
);
14437 c_name
= "dist_schedule";
14439 case PRAGMA_OMP_CLAUSE_PROC_BIND
:
14440 clauses
= c_parser_omp_clause_proc_bind (parser
, clauses
);
14441 c_name
= "proc_bind";
14443 case PRAGMA_OMP_CLAUSE_SAFELEN
:
14444 clauses
= c_parser_omp_clause_safelen (parser
, clauses
);
14445 c_name
= "safelen";
14447 case PRAGMA_CILK_CLAUSE_VECTORLENGTH
:
14448 clauses
= c_parser_cilk_clause_vectorlength (parser
, clauses
, true);
14449 c_name
= "simdlen";
14451 case PRAGMA_OMP_CLAUSE_SIMDLEN
:
14452 clauses
= c_parser_omp_clause_simdlen (parser
, clauses
);
14453 c_name
= "simdlen";
14455 case PRAGMA_OMP_CLAUSE_NOGROUP
:
14456 clauses
= c_parser_omp_clause_nogroup (parser
, clauses
);
14457 c_name
= "nogroup";
14459 case PRAGMA_OMP_CLAUSE_THREADS
:
14461 = c_parser_omp_clause_orderedkind (parser
, OMP_CLAUSE_THREADS
,
14463 c_name
= "threads";
14465 case PRAGMA_OMP_CLAUSE_SIMD
:
14467 = c_parser_omp_clause_orderedkind (parser
, OMP_CLAUSE_SIMD
,
14472 c_parser_error (parser
, "expected %<#pragma omp%> clause");
14478 if (((mask
>> c_kind
) & 1) == 0)
14480 /* Remove the invalid clause(s) from the list to avoid
14481 confusing the rest of the compiler. */
14483 error_at (here
, "%qs is not valid for %qs", c_name
, where
);
14488 c_parser_skip_to_pragma_eol (parser
);
14492 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_UNIFORM
)) != 0)
14493 return c_finish_omp_clauses (clauses
, C_ORT_OMP_DECLARE_SIMD
);
14494 return c_finish_omp_clauses (clauses
, C_ORT_OMP
);
14500 /* OpenACC 2.0, OpenMP 2.5:
14504 In practice, we're also interested in adding the statement to an
14505 outer node. So it is convenient if we work around the fact that
14506 c_parser_statement calls add_stmt. */
14509 c_parser_omp_structured_block (c_parser
*parser
, bool *if_p
)
14511 tree stmt
= push_stmt_list ();
14512 c_parser_statement (parser
, if_p
);
14513 return pop_stmt_list (stmt
);
14517 # pragma acc cache (variable-list) new-line
14519 LOC is the location of the #pragma token.
14523 c_parser_oacc_cache (location_t loc
, c_parser
*parser
)
14525 tree stmt
, clauses
;
14527 clauses
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE__CACHE_
, NULL
);
14528 clauses
= c_finish_omp_clauses (clauses
, C_ORT_ACC
);
14530 c_parser_skip_to_pragma_eol (parser
);
14532 stmt
= make_node (OACC_CACHE
);
14533 TREE_TYPE (stmt
) = void_type_node
;
14534 OACC_CACHE_CLAUSES (stmt
) = clauses
;
14535 SET_EXPR_LOCATION (stmt
, loc
);
14542 # pragma acc data oacc-data-clause[optseq] new-line
14545 LOC is the location of the #pragma token.
14548 #define OACC_DATA_CLAUSE_MASK \
14549 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
14550 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
14551 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
14552 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
14553 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
14554 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
14555 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
14556 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT_OR_COPY) \
14557 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT_OR_COPYIN) \
14558 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT_OR_COPYOUT) \
14559 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT_OR_CREATE) )
14562 c_parser_oacc_data (location_t loc
, c_parser
*parser
, bool *if_p
)
14564 tree stmt
, clauses
, block
;
14566 clauses
= c_parser_oacc_all_clauses (parser
, OACC_DATA_CLAUSE_MASK
,
14567 "#pragma acc data");
14569 block
= c_begin_omp_parallel ();
14570 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
14572 stmt
= c_finish_oacc_data (loc
, clauses
, block
);
14578 # pragma acc declare oacc-data-clause[optseq] new-line
14581 #define OACC_DECLARE_CLAUSE_MASK \
14582 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
14583 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
14584 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
14585 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
14586 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
14587 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT) \
14588 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_LINK) \
14589 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
14590 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT_OR_COPY) \
14591 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT_OR_COPYIN) \
14592 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT_OR_COPYOUT) \
14593 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT_OR_CREATE) )
14596 c_parser_oacc_declare (c_parser
*parser
)
14598 location_t pragma_loc
= c_parser_peek_token (parser
)->location
;
14599 tree clauses
, stmt
, t
, decl
;
14601 bool error
= false;
14603 c_parser_consume_pragma (parser
);
14605 clauses
= c_parser_oacc_all_clauses (parser
, OACC_DECLARE_CLAUSE_MASK
,
14606 "#pragma acc declare");
14609 error_at (pragma_loc
,
14610 "no valid clauses specified in %<#pragma acc declare%>");
14614 for (t
= clauses
; t
; t
= OMP_CLAUSE_CHAIN (t
))
14616 location_t loc
= OMP_CLAUSE_LOCATION (t
);
14617 decl
= OMP_CLAUSE_DECL (t
);
14618 if (!DECL_P (decl
))
14620 error_at (loc
, "array section in %<#pragma acc declare%>");
14625 switch (OMP_CLAUSE_MAP_KIND (t
))
14627 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
14628 case GOMP_MAP_FORCE_ALLOC
:
14629 case GOMP_MAP_FORCE_TO
:
14630 case GOMP_MAP_FORCE_DEVICEPTR
:
14631 case GOMP_MAP_DEVICE_RESIDENT
:
14634 case GOMP_MAP_LINK
:
14635 if (!global_bindings_p ()
14636 && (TREE_STATIC (decl
)
14637 || !DECL_EXTERNAL (decl
)))
14640 "%qD must be a global variable in "
14641 "%<#pragma acc declare link%>",
14649 if (global_bindings_p ())
14651 error_at (loc
, "invalid OpenACC clause at file scope");
14655 if (DECL_EXTERNAL (decl
))
14658 "invalid use of %<extern%> variable %qD "
14659 "in %<#pragma acc declare%>", decl
);
14663 else if (TREE_PUBLIC (decl
))
14666 "invalid use of %<global%> variable %qD "
14667 "in %<#pragma acc declare%>", decl
);
14674 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl
))
14675 || lookup_attribute ("omp declare target link",
14676 DECL_ATTRIBUTES (decl
)))
14678 error_at (loc
, "variable %qD used more than once with "
14679 "%<#pragma acc declare%>", decl
);
14688 if (OMP_CLAUSE_MAP_KIND (t
) == GOMP_MAP_LINK
)
14689 id
= get_identifier ("omp declare target link");
14691 id
= get_identifier ("omp declare target");
14693 DECL_ATTRIBUTES (decl
)
14694 = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (decl
));
14696 if (global_bindings_p ())
14698 symtab_node
*node
= symtab_node::get (decl
);
14701 node
->offloadable
= 1;
14702 if (ENABLE_OFFLOADING
)
14704 g
->have_offload
= true;
14705 if (is_a
<varpool_node
*> (node
))
14706 vec_safe_push (offload_vars
, decl
);
14713 if (error
|| global_bindings_p ())
14716 stmt
= make_node (OACC_DECLARE
);
14717 TREE_TYPE (stmt
) = void_type_node
;
14718 OACC_DECLARE_CLAUSES (stmt
) = clauses
;
14719 SET_EXPR_LOCATION (stmt
, pragma_loc
);
14727 # pragma acc enter data oacc-enter-data-clause[optseq] new-line
14731 # pragma acc exit data oacc-exit-data-clause[optseq] new-line
14734 LOC is the location of the #pragma token.
14737 #define OACC_ENTER_DATA_CLAUSE_MASK \
14738 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
14739 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
14740 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
14741 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
14742 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT_OR_COPYIN) \
14743 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT_OR_CREATE) \
14744 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
14746 #define OACC_EXIT_DATA_CLAUSE_MASK \
14747 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
14748 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
14749 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
14750 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DELETE) \
14751 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
14754 c_parser_oacc_enter_exit_data (c_parser
*parser
, bool enter
)
14756 location_t loc
= c_parser_peek_token (parser
)->location
;
14757 tree clauses
, stmt
;
14758 const char *p
= "";
14760 c_parser_consume_pragma (parser
);
14762 if (c_parser_next_token_is (parser
, CPP_NAME
))
14764 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
14765 c_parser_consume_token (parser
);
14768 if (strcmp (p
, "data") != 0)
14770 error_at (loc
, "expected %<data%> after %<#pragma acc %s%>",
14771 enter
? "enter" : "exit");
14772 parser
->error
= true;
14773 c_parser_skip_to_pragma_eol (parser
);
14778 clauses
= c_parser_oacc_all_clauses (parser
, OACC_ENTER_DATA_CLAUSE_MASK
,
14779 "#pragma acc enter data");
14781 clauses
= c_parser_oacc_all_clauses (parser
, OACC_EXIT_DATA_CLAUSE_MASK
,
14782 "#pragma acc exit data");
14784 if (omp_find_clause (clauses
, OMP_CLAUSE_MAP
) == NULL_TREE
)
14786 error_at (loc
, "%<#pragma acc %s data%> has no data movement clause",
14787 enter
? "enter" : "exit");
14791 stmt
= enter
? make_node (OACC_ENTER_DATA
) : make_node (OACC_EXIT_DATA
);
14792 TREE_TYPE (stmt
) = void_type_node
;
14793 OMP_STANDALONE_CLAUSES (stmt
) = clauses
;
14794 SET_EXPR_LOCATION (stmt
, loc
);
14800 # pragma acc host_data oacc-data-clause[optseq] new-line
14804 #define OACC_HOST_DATA_CLAUSE_MASK \
14805 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_USE_DEVICE) )
14808 c_parser_oacc_host_data (location_t loc
, c_parser
*parser
, bool *if_p
)
14810 tree stmt
, clauses
, block
;
14812 clauses
= c_parser_oacc_all_clauses (parser
, OACC_HOST_DATA_CLAUSE_MASK
,
14813 "#pragma acc host_data");
14815 block
= c_begin_omp_parallel ();
14816 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
14817 stmt
= c_finish_oacc_host_data (loc
, clauses
, block
);
14824 # pragma acc loop oacc-loop-clause[optseq] new-line
14827 LOC is the location of the #pragma token.
14830 #define OACC_LOOP_CLAUSE_MASK \
14831 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COLLAPSE) \
14832 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
14833 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
14834 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
14835 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
14836 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
14837 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_AUTO) \
14838 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_INDEPENDENT) \
14839 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \
14840 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_TILE) )
14842 c_parser_oacc_loop (location_t loc
, c_parser
*parser
, char *p_name
,
14843 omp_clause_mask mask
, tree
*cclauses
, bool *if_p
)
14845 bool is_parallel
= ((mask
>> PRAGMA_OACC_CLAUSE_REDUCTION
) & 1) == 1;
14847 strcat (p_name
, " loop");
14848 mask
|= OACC_LOOP_CLAUSE_MASK
;
14850 tree clauses
= c_parser_oacc_all_clauses (parser
, mask
, p_name
,
14854 clauses
= c_oacc_split_loop_clauses (clauses
, cclauses
, is_parallel
);
14856 *cclauses
= c_finish_omp_clauses (*cclauses
, C_ORT_ACC
);
14858 clauses
= c_finish_omp_clauses (clauses
, C_ORT_ACC
);
14861 tree block
= c_begin_compound_stmt (true);
14862 tree stmt
= c_parser_omp_for_loop (loc
, parser
, OACC_LOOP
, clauses
, NULL
,
14864 block
= c_end_compound_stmt (loc
, block
, true);
14871 # pragma acc kernels oacc-kernels-clause[optseq] new-line
14876 # pragma acc parallel oacc-parallel-clause[optseq] new-line
14879 LOC is the location of the #pragma token.
14882 #define OACC_KERNELS_CLAUSE_MASK \
14883 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
14884 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
14885 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
14886 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
14887 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
14888 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
14889 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
14890 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
14891 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
14892 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
14893 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
14894 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT_OR_COPY) \
14895 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT_OR_COPYIN) \
14896 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT_OR_COPYOUT) \
14897 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT_OR_CREATE) \
14898 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
14899 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
14901 #define OACC_PARALLEL_CLAUSE_MASK \
14902 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
14903 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
14904 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
14905 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
14906 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
14907 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
14908 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
14909 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
14910 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
14911 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
14912 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
14913 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
14914 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
14915 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT_OR_COPY) \
14916 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT_OR_COPYIN) \
14917 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT_OR_COPYOUT) \
14918 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT_OR_CREATE) \
14919 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
14920 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
14921 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
14924 c_parser_oacc_kernels_parallel (location_t loc
, c_parser
*parser
,
14925 enum pragma_kind p_kind
, char *p_name
,
14928 omp_clause_mask mask
;
14929 enum tree_code code
;
14932 case PRAGMA_OACC_KERNELS
:
14933 strcat (p_name
, " kernels");
14934 mask
= OACC_KERNELS_CLAUSE_MASK
;
14935 code
= OACC_KERNELS
;
14937 case PRAGMA_OACC_PARALLEL
:
14938 strcat (p_name
, " parallel");
14939 mask
= OACC_PARALLEL_CLAUSE_MASK
;
14940 code
= OACC_PARALLEL
;
14943 gcc_unreachable ();
14946 if (c_parser_next_token_is (parser
, CPP_NAME
))
14948 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
14949 if (strcmp (p
, "loop") == 0)
14951 c_parser_consume_token (parser
);
14952 tree block
= c_begin_omp_parallel ();
14954 c_parser_oacc_loop (loc
, parser
, p_name
, mask
, &clauses
, if_p
);
14955 return c_finish_omp_construct (loc
, code
, block
, clauses
);
14959 tree clauses
= c_parser_oacc_all_clauses (parser
, mask
, p_name
);
14961 tree block
= c_begin_omp_parallel ();
14962 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
14964 return c_finish_omp_construct (loc
, code
, block
, clauses
);
14968 # pragma acc routine oacc-routine-clause[optseq] new-line
14969 function-definition
14971 # pragma acc routine ( name ) oacc-routine-clause[optseq] new-line
14974 #define OACC_ROUTINE_CLAUSE_MASK \
14975 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
14976 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
14977 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
14978 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) )
14980 /* Parse an OpenACC routine directive. For named directives, we apply
14981 immediately to the named function. For unnamed ones we then parse
14982 a declaration or definition, which must be for a function. */
14985 c_parser_oacc_routine (c_parser
*parser
, enum pragma_context context
)
14987 gcc_checking_assert (context
== pragma_external
);
14989 oacc_routine_data data
;
14990 data
.error_seen
= false;
14991 data
.fndecl_seen
= false;
14992 data
.clauses
= NULL_TREE
;
14993 data
.loc
= c_parser_peek_token (parser
)->location
;
14995 c_parser_consume_pragma (parser
);
14997 /* Look for optional '( name )'. */
14998 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
15000 c_parser_consume_token (parser
); /* '(' */
15002 tree decl
= NULL_TREE
;
15003 c_token
*name_token
= c_parser_peek_token (parser
);
15004 location_t name_loc
= name_token
->location
;
15005 if (name_token
->type
== CPP_NAME
15006 && (name_token
->id_kind
== C_ID_ID
15007 || name_token
->id_kind
== C_ID_TYPENAME
))
15009 decl
= lookup_name (name_token
->value
);
15011 error_at (name_loc
,
15012 "%qE has not been declared", name_token
->value
);
15013 c_parser_consume_token (parser
);
15016 c_parser_error (parser
, "expected function name");
15019 || !c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
15021 c_parser_skip_to_pragma_eol (parser
, false);
15026 = c_parser_oacc_all_clauses (parser
, OACC_ROUTINE_CLAUSE_MASK
,
15027 "#pragma acc routine");
15029 if (TREE_CODE (decl
) != FUNCTION_DECL
)
15031 error_at (name_loc
, "%qD does not refer to a function", decl
);
15035 c_finish_oacc_routine (&data
, decl
, false);
15037 else /* No optional '( name )'. */
15040 = c_parser_oacc_all_clauses (parser
, OACC_ROUTINE_CLAUSE_MASK
,
15041 "#pragma acc routine");
15043 /* Emit a helpful diagnostic if there's another pragma following this
15044 one. Also don't allow a static assertion declaration, as in the
15045 following we'll just parse a *single* "declaration or function
15046 definition", and the static assertion counts an one. */
15047 if (c_parser_next_token_is (parser
, CPP_PRAGMA
)
15048 || c_parser_next_token_is_keyword (parser
, RID_STATIC_ASSERT
))
15050 error_at (data
.loc
,
15051 "%<#pragma acc routine%> not immediately followed by"
15052 " function declaration or definition");
15053 /* ..., and then just keep going. */
15057 /* We only have to consider the pragma_external case here. */
15058 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
15059 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
)
15061 int ext
= disable_extension_diagnostics ();
15063 c_parser_consume_token (parser
);
15064 while (c_parser_next_token_is (parser
, CPP_KEYWORD
)
15065 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
);
15066 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
15067 NULL
, vNULL
, &data
);
15068 restore_extension_diagnostics (ext
);
15071 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
15072 NULL
, vNULL
, &data
);
15076 /* Finalize an OpenACC routine pragma, applying it to FNDECL.
15077 IS_DEFN is true if we're applying it to the definition. */
15080 c_finish_oacc_routine (struct oacc_routine_data
*data
, tree fndecl
,
15083 /* Keep going if we're in error reporting mode. */
15084 if (data
->error_seen
15085 || fndecl
== error_mark_node
)
15088 if (data
->fndecl_seen
)
15090 error_at (data
->loc
,
15091 "%<#pragma acc routine%> not immediately followed by"
15092 " a single function declaration or definition");
15093 data
->error_seen
= true;
15096 if (fndecl
== NULL_TREE
|| TREE_CODE (fndecl
) != FUNCTION_DECL
)
15098 error_at (data
->loc
,
15099 "%<#pragma acc routine%> not immediately followed by"
15100 " function declaration or definition");
15101 data
->error_seen
= true;
15105 if (oacc_get_fn_attrib (fndecl
))
15107 error_at (data
->loc
,
15108 "%<#pragma acc routine%> already applied to %qD", fndecl
);
15109 data
->error_seen
= true;
15113 if (TREE_USED (fndecl
) || (!is_defn
&& DECL_SAVED_TREE (fndecl
)))
15115 error_at (data
->loc
,
15117 ? G_("%<#pragma acc routine%> must be applied before use")
15118 : G_("%<#pragma acc routine%> must be applied before "
15120 data
->error_seen
= true;
15124 /* Process the routine's dimension clauses. */
15125 tree dims
= oacc_build_routine_dims (data
->clauses
);
15126 oacc_replace_fn_attrib (fndecl
, dims
);
15128 /* Add an "omp declare target" attribute. */
15129 DECL_ATTRIBUTES (fndecl
)
15130 = tree_cons (get_identifier ("omp declare target"),
15131 NULL_TREE
, DECL_ATTRIBUTES (fndecl
));
15133 /* Remember that we've used this "#pragma acc routine". */
15134 data
->fndecl_seen
= true;
15138 # pragma acc update oacc-update-clause[optseq] new-line
15141 #define OACC_UPDATE_CLAUSE_MASK \
15142 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
15143 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE) \
15144 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_HOST) \
15145 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
15146 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SELF) \
15147 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
15150 c_parser_oacc_update (c_parser
*parser
)
15152 location_t loc
= c_parser_peek_token (parser
)->location
;
15154 c_parser_consume_pragma (parser
);
15156 tree clauses
= c_parser_oacc_all_clauses (parser
, OACC_UPDATE_CLAUSE_MASK
,
15157 "#pragma acc update");
15158 if (omp_find_clause (clauses
, OMP_CLAUSE_MAP
) == NULL_TREE
)
15161 "%<#pragma acc update%> must contain at least one "
15162 "%<device%> or %<host%> or %<self%> clause");
15169 tree stmt
= make_node (OACC_UPDATE
);
15170 TREE_TYPE (stmt
) = void_type_node
;
15171 OACC_UPDATE_CLAUSES (stmt
) = clauses
;
15172 SET_EXPR_LOCATION (stmt
, loc
);
15177 # pragma acc wait [(intseq)] oacc-wait-clause[optseq] new-line
15179 LOC is the location of the #pragma token.
15182 #define OACC_WAIT_CLAUSE_MASK \
15183 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) )
15186 c_parser_oacc_wait (location_t loc
, c_parser
*parser
, char *p_name
)
15188 tree clauses
, list
= NULL_TREE
, stmt
= NULL_TREE
;
15190 if (c_parser_peek_token (parser
)->type
== CPP_OPEN_PAREN
)
15191 list
= c_parser_oacc_wait_list (parser
, loc
, list
);
15193 strcpy (p_name
, " wait");
15194 clauses
= c_parser_oacc_all_clauses (parser
, OACC_WAIT_CLAUSE_MASK
, p_name
);
15195 stmt
= c_finish_oacc_wait (loc
, list
, clauses
);
15202 # pragma omp atomic new-line
15206 x binop= expr | x++ | ++x | x-- | --x
15208 +, *, -, /, &, ^, |, <<, >>
15210 where x is an lvalue expression with scalar type.
15213 # pragma omp atomic new-line
15216 # pragma omp atomic read new-line
15219 # pragma omp atomic write new-line
15222 # pragma omp atomic update new-line
15225 # pragma omp atomic capture new-line
15228 # pragma omp atomic capture new-line
15236 expression-stmt | x = x binop expr
15238 v = expression-stmt
15240 { v = x; update-stmt; } | { update-stmt; v = x; }
15244 expression-stmt | x = x binop expr | x = expr binop x
15248 { v = x; update-stmt; } | { update-stmt; v = x; } | { v = x; x = expr; }
15250 where x and v are lvalue expressions with scalar type.
15252 LOC is the location of the #pragma token. */
15255 c_parser_omp_atomic (location_t loc
, c_parser
*parser
)
15257 tree lhs
= NULL_TREE
, rhs
= NULL_TREE
, v
= NULL_TREE
;
15258 tree lhs1
= NULL_TREE
, rhs1
= NULL_TREE
;
15259 tree stmt
, orig_lhs
, unfolded_lhs
= NULL_TREE
, unfolded_lhs1
= NULL_TREE
;
15260 enum tree_code code
= OMP_ATOMIC
, opcode
= NOP_EXPR
;
15261 struct c_expr expr
;
15263 bool structured_block
= false;
15264 bool swapped
= false;
15265 bool seq_cst
= false;
15268 if (c_parser_next_token_is (parser
, CPP_NAME
))
15270 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
15271 if (!strcmp (p
, "seq_cst"))
15274 c_parser_consume_token (parser
);
15275 if (c_parser_next_token_is (parser
, CPP_COMMA
)
15276 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
15277 c_parser_consume_token (parser
);
15280 if (c_parser_next_token_is (parser
, CPP_NAME
))
15282 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
15284 if (!strcmp (p
, "read"))
15285 code
= OMP_ATOMIC_READ
;
15286 else if (!strcmp (p
, "write"))
15288 else if (!strcmp (p
, "update"))
15290 else if (!strcmp (p
, "capture"))
15291 code
= OMP_ATOMIC_CAPTURE_NEW
;
15295 c_parser_consume_token (parser
);
15299 if (c_parser_next_token_is (parser
, CPP_COMMA
)
15300 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
15301 c_parser_consume_token (parser
);
15303 if (c_parser_next_token_is (parser
, CPP_NAME
))
15306 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
15307 if (!strcmp (p
, "seq_cst"))
15310 c_parser_consume_token (parser
);
15314 c_parser_skip_to_pragma_eol (parser
);
15318 case OMP_ATOMIC_READ
:
15319 case NOP_EXPR
: /* atomic write */
15320 v
= c_parser_cast_expression (parser
, NULL
).value
;
15321 non_lvalue_p
= !lvalue_p (v
);
15322 v
= c_fully_fold (v
, false, NULL
, true);
15323 if (v
== error_mark_node
)
15326 v
= non_lvalue (v
);
15327 loc
= c_parser_peek_token (parser
)->location
;
15328 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
15330 if (code
== NOP_EXPR
)
15332 lhs
= c_parser_expression (parser
).value
;
15333 lhs
= c_fully_fold (lhs
, false, NULL
);
15334 if (lhs
== error_mark_node
)
15339 lhs
= c_parser_cast_expression (parser
, NULL
).value
;
15340 non_lvalue_p
= !lvalue_p (lhs
);
15341 lhs
= c_fully_fold (lhs
, false, NULL
, true);
15342 if (lhs
== error_mark_node
)
15345 lhs
= non_lvalue (lhs
);
15347 if (code
== NOP_EXPR
)
15349 /* atomic write is represented by OMP_ATOMIC with NOP_EXPR
15357 case OMP_ATOMIC_CAPTURE_NEW
:
15358 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
15360 c_parser_consume_token (parser
);
15361 structured_block
= true;
15365 v
= c_parser_cast_expression (parser
, NULL
).value
;
15366 non_lvalue_p
= !lvalue_p (v
);
15367 v
= c_fully_fold (v
, false, NULL
, true);
15368 if (v
== error_mark_node
)
15371 v
= non_lvalue (v
);
15372 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
15380 /* For structured_block case we don't know yet whether
15381 old or new x should be captured. */
15383 eloc
= c_parser_peek_token (parser
)->location
;
15384 expr
= c_parser_cast_expression (parser
, NULL
);
15386 expr
= default_function_array_conversion (eloc
, expr
);
15387 unfolded_lhs
= expr
.value
;
15388 lhs
= c_fully_fold (lhs
, false, NULL
, true);
15390 switch (TREE_CODE (lhs
))
15394 c_parser_skip_to_end_of_block_or_statement (parser
);
15395 if (structured_block
)
15397 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
15398 c_parser_consume_token (parser
);
15399 else if (code
== OMP_ATOMIC_CAPTURE_NEW
)
15401 c_parser_skip_to_end_of_block_or_statement (parser
);
15402 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
15403 c_parser_consume_token (parser
);
15408 case POSTINCREMENT_EXPR
:
15409 if (code
== OMP_ATOMIC_CAPTURE_NEW
&& !structured_block
)
15410 code
= OMP_ATOMIC_CAPTURE_OLD
;
15412 case PREINCREMENT_EXPR
:
15413 lhs
= TREE_OPERAND (lhs
, 0);
15414 unfolded_lhs
= NULL_TREE
;
15415 opcode
= PLUS_EXPR
;
15416 rhs
= integer_one_node
;
15419 case POSTDECREMENT_EXPR
:
15420 if (code
== OMP_ATOMIC_CAPTURE_NEW
&& !structured_block
)
15421 code
= OMP_ATOMIC_CAPTURE_OLD
;
15423 case PREDECREMENT_EXPR
:
15424 lhs
= TREE_OPERAND (lhs
, 0);
15425 unfolded_lhs
= NULL_TREE
;
15426 opcode
= MINUS_EXPR
;
15427 rhs
= integer_one_node
;
15430 case COMPOUND_EXPR
:
15431 if (TREE_CODE (TREE_OPERAND (lhs
, 0)) == SAVE_EXPR
15432 && TREE_CODE (TREE_OPERAND (lhs
, 1)) == COMPOUND_EXPR
15433 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (lhs
, 1), 0)) == MODIFY_EXPR
15434 && TREE_OPERAND (TREE_OPERAND (lhs
, 1), 1) == TREE_OPERAND (lhs
, 0)
15435 && TREE_CODE (TREE_TYPE (TREE_OPERAND (TREE_OPERAND
15436 (TREE_OPERAND (lhs
, 1), 0), 0)))
15438 /* Undo effects of boolean_increment for post {in,de}crement. */
15439 lhs
= TREE_OPERAND (TREE_OPERAND (lhs
, 1), 0);
15442 if (TREE_CODE (lhs
) == MODIFY_EXPR
15443 && TREE_CODE (TREE_TYPE (TREE_OPERAND (lhs
, 0))) == BOOLEAN_TYPE
)
15445 /* Undo effects of boolean_increment. */
15446 if (integer_onep (TREE_OPERAND (lhs
, 1)))
15448 /* This is pre or post increment. */
15449 rhs
= TREE_OPERAND (lhs
, 1);
15450 lhs
= TREE_OPERAND (lhs
, 0);
15451 unfolded_lhs
= NULL_TREE
;
15453 if (code
== OMP_ATOMIC_CAPTURE_NEW
15454 && !structured_block
15455 && TREE_CODE (orig_lhs
) == COMPOUND_EXPR
)
15456 code
= OMP_ATOMIC_CAPTURE_OLD
;
15459 if (TREE_CODE (TREE_OPERAND (lhs
, 1)) == TRUTH_NOT_EXPR
15460 && TREE_OPERAND (lhs
, 0)
15461 == TREE_OPERAND (TREE_OPERAND (lhs
, 1), 0))
15463 /* This is pre or post decrement. */
15464 rhs
= TREE_OPERAND (lhs
, 1);
15465 lhs
= TREE_OPERAND (lhs
, 0);
15466 unfolded_lhs
= NULL_TREE
;
15468 if (code
== OMP_ATOMIC_CAPTURE_NEW
15469 && !structured_block
15470 && TREE_CODE (orig_lhs
) == COMPOUND_EXPR
)
15471 code
= OMP_ATOMIC_CAPTURE_OLD
;
15477 if (!lvalue_p (unfolded_lhs
))
15478 lhs
= non_lvalue (lhs
);
15479 switch (c_parser_peek_token (parser
)->type
)
15482 opcode
= MULT_EXPR
;
15485 opcode
= TRUNC_DIV_EXPR
;
15488 opcode
= PLUS_EXPR
;
15491 opcode
= MINUS_EXPR
;
15493 case CPP_LSHIFT_EQ
:
15494 opcode
= LSHIFT_EXPR
;
15496 case CPP_RSHIFT_EQ
:
15497 opcode
= RSHIFT_EXPR
;
15500 opcode
= BIT_AND_EXPR
;
15503 opcode
= BIT_IOR_EXPR
;
15506 opcode
= BIT_XOR_EXPR
;
15509 c_parser_consume_token (parser
);
15510 eloc
= c_parser_peek_token (parser
)->location
;
15511 expr
= c_parser_expr_no_commas (parser
, NULL
, unfolded_lhs
);
15513 switch (TREE_CODE (rhs1
))
15516 case TRUNC_DIV_EXPR
:
15525 if (c_tree_equal (TREE_OPERAND (rhs1
, 0), unfolded_lhs
))
15527 opcode
= TREE_CODE (rhs1
);
15528 rhs
= c_fully_fold (TREE_OPERAND (rhs1
, 1), false, NULL
,
15530 rhs1
= c_fully_fold (TREE_OPERAND (rhs1
, 0), false, NULL
,
15534 if (c_tree_equal (TREE_OPERAND (rhs1
, 1), unfolded_lhs
))
15536 opcode
= TREE_CODE (rhs1
);
15537 rhs
= c_fully_fold (TREE_OPERAND (rhs1
, 0), false, NULL
,
15539 rhs1
= c_fully_fold (TREE_OPERAND (rhs1
, 1), false, NULL
,
15541 swapped
= !commutative_tree_code (opcode
);
15550 if (c_parser_peek_token (parser
)->type
== CPP_SEMICOLON
)
15552 if (structured_block
&& code
== OMP_ATOMIC_CAPTURE_NEW
)
15554 code
= OMP_ATOMIC_CAPTURE_OLD
;
15557 expr
= default_function_array_read_conversion (eloc
, expr
);
15558 unfolded_lhs1
= expr
.value
;
15559 lhs1
= c_fully_fold (unfolded_lhs1
, false, NULL
, true);
15561 c_parser_consume_token (parser
);
15564 if (structured_block
)
15567 expr
= default_function_array_read_conversion (eloc
, expr
);
15568 rhs
= c_fully_fold (expr
.value
, false, NULL
, true);
15573 c_parser_error (parser
, "invalid form of %<#pragma omp atomic%>");
15576 c_parser_error (parser
,
15577 "invalid operator for %<#pragma omp atomic%>");
15581 /* Arrange to pass the location of the assignment operator to
15582 c_finish_omp_atomic. */
15583 loc
= c_parser_peek_token (parser
)->location
;
15584 c_parser_consume_token (parser
);
15585 eloc
= c_parser_peek_token (parser
)->location
;
15586 expr
= c_parser_expression (parser
);
15587 expr
= default_function_array_read_conversion (eloc
, expr
);
15589 rhs
= c_fully_fold (rhs
, false, NULL
, true);
15593 if (structured_block
&& code
== OMP_ATOMIC_CAPTURE_NEW
)
15595 if (!c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
15597 v
= c_parser_cast_expression (parser
, NULL
).value
;
15598 non_lvalue_p
= !lvalue_p (v
);
15599 v
= c_fully_fold (v
, false, NULL
, true);
15600 if (v
== error_mark_node
)
15603 v
= non_lvalue (v
);
15604 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
15606 eloc
= c_parser_peek_token (parser
)->location
;
15607 expr
= c_parser_cast_expression (parser
, NULL
);
15609 expr
= default_function_array_read_conversion (eloc
, expr
);
15610 unfolded_lhs1
= expr
.value
;
15611 lhs1
= c_fully_fold (lhs1
, false, NULL
, true);
15612 if (lhs1
== error_mark_node
)
15614 if (!lvalue_p (unfolded_lhs1
))
15615 lhs1
= non_lvalue (lhs1
);
15617 if (structured_block
)
15619 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
15620 c_parser_require (parser
, CPP_CLOSE_BRACE
, "expected %<}%>");
15623 if (unfolded_lhs
&& unfolded_lhs1
15624 && !c_tree_equal (unfolded_lhs
, unfolded_lhs1
))
15626 error ("%<#pragma omp atomic capture%> uses two different "
15627 "expressions for memory");
15628 stmt
= error_mark_node
;
15631 stmt
= c_finish_omp_atomic (loc
, code
, opcode
, lhs
, rhs
, v
, lhs1
, rhs1
,
15633 if (stmt
!= error_mark_node
)
15636 if (!structured_block
)
15637 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
15642 # pragma omp barrier new-line
15646 c_parser_omp_barrier (c_parser
*parser
)
15648 location_t loc
= c_parser_peek_token (parser
)->location
;
15649 c_parser_consume_pragma (parser
);
15650 c_parser_skip_to_pragma_eol (parser
);
15652 c_finish_omp_barrier (loc
);
15656 # pragma omp critical [(name)] new-line
15660 # pragma omp critical [(name) [hint(expression)]] new-line
15662 LOC is the location of the #pragma itself. */
15664 #define OMP_CRITICAL_CLAUSE_MASK \
15665 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HINT) )
15668 c_parser_omp_critical (location_t loc
, c_parser
*parser
, bool *if_p
)
15670 tree stmt
, name
= NULL_TREE
, clauses
= NULL_TREE
;
15672 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
15674 c_parser_consume_token (parser
);
15675 if (c_parser_next_token_is (parser
, CPP_NAME
))
15677 name
= c_parser_peek_token (parser
)->value
;
15678 c_parser_consume_token (parser
);
15679 c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>");
15682 c_parser_error (parser
, "expected identifier");
15684 clauses
= c_parser_omp_all_clauses (parser
,
15685 OMP_CRITICAL_CLAUSE_MASK
,
15686 "#pragma omp critical");
15690 if (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
15691 c_parser_error (parser
, "expected %<(%> or end of line");
15692 c_parser_skip_to_pragma_eol (parser
);
15695 stmt
= c_parser_omp_structured_block (parser
, if_p
);
15696 return c_finish_omp_critical (loc
, stmt
, name
, clauses
);
15700 # pragma omp flush flush-vars[opt] new-line
15703 ( variable-list ) */
15706 c_parser_omp_flush (c_parser
*parser
)
15708 location_t loc
= c_parser_peek_token (parser
)->location
;
15709 c_parser_consume_pragma (parser
);
15710 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
15711 c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ERROR
, NULL
);
15712 else if (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
15713 c_parser_error (parser
, "expected %<(%> or end of line");
15714 c_parser_skip_to_pragma_eol (parser
);
15716 c_finish_omp_flush (loc
);
15719 /* Parse the restricted form of loop statements allowed by OpenACC and OpenMP.
15720 The real trick here is to determine the loop control variable early
15721 so that we can push a new decl if necessary to make it private.
15722 LOC is the location of the "acc" or "omp" in "#pragma acc" or "#pragma omp",
15726 c_parser_omp_for_loop (location_t loc
, c_parser
*parser
, enum tree_code code
,
15727 tree clauses
, tree
*cclauses
, bool *if_p
)
15729 tree decl
, cond
, incr
, save_break
, save_cont
, body
, init
, stmt
, cl
;
15730 tree declv
, condv
, incrv
, initv
, ret
= NULL_TREE
;
15731 tree pre_body
= NULL_TREE
, this_pre_body
;
15732 tree ordered_cl
= NULL_TREE
;
15733 bool fail
= false, open_brace_parsed
= false;
15734 int i
, collapse
= 1, ordered
= 0, count
, nbraces
= 0;
15735 location_t for_loc
;
15736 bool tiling
= false;
15737 vec
<tree
, va_gc
> *for_block
= make_tree_vector ();
15739 for (cl
= clauses
; cl
; cl
= OMP_CLAUSE_CHAIN (cl
))
15740 if (OMP_CLAUSE_CODE (cl
) == OMP_CLAUSE_COLLAPSE
)
15741 collapse
= tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (cl
));
15742 else if (OMP_CLAUSE_CODE (cl
) == OMP_CLAUSE_TILE
)
15745 collapse
= list_length (OMP_CLAUSE_TILE_LIST (cl
));
15747 else if (OMP_CLAUSE_CODE (cl
) == OMP_CLAUSE_ORDERED
15748 && OMP_CLAUSE_ORDERED_EXPR (cl
))
15751 ordered
= tree_to_shwi (OMP_CLAUSE_ORDERED_EXPR (cl
));
15754 if (ordered
&& ordered
< collapse
)
15756 error_at (OMP_CLAUSE_LOCATION (ordered_cl
),
15757 "%<ordered%> clause parameter is less than %<collapse%>");
15758 OMP_CLAUSE_ORDERED_EXPR (ordered_cl
)
15759 = build_int_cst (NULL_TREE
, collapse
);
15760 ordered
= collapse
;
15764 for (tree
*pc
= &clauses
; *pc
; )
15765 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_LINEAR
)
15767 error_at (OMP_CLAUSE_LOCATION (*pc
),
15768 "%<linear%> clause may not be specified together "
15769 "with %<ordered%> clause with a parameter");
15770 *pc
= OMP_CLAUSE_CHAIN (*pc
);
15773 pc
= &OMP_CLAUSE_CHAIN (*pc
);
15776 gcc_assert (tiling
|| (collapse
>= 1 && ordered
>= 0));
15777 count
= ordered
? ordered
: collapse
;
15779 declv
= make_tree_vec (count
);
15780 initv
= make_tree_vec (count
);
15781 condv
= make_tree_vec (count
);
15782 incrv
= make_tree_vec (count
);
15784 if (code
!= CILK_FOR
15785 && !c_parser_next_token_is_keyword (parser
, RID_FOR
))
15787 c_parser_error (parser
, "for statement expected");
15790 if (code
== CILK_FOR
15791 && !c_parser_next_token_is_keyword (parser
, RID_CILK_FOR
))
15793 c_parser_error (parser
, "_Cilk_for statement expected");
15796 for_loc
= c_parser_peek_token (parser
)->location
;
15797 c_parser_consume_token (parser
);
15799 for (i
= 0; i
< count
; i
++)
15801 int bracecount
= 0;
15803 matching_parens parens
;
15804 if (!parens
.require_open (parser
))
15807 /* Parse the initialization declaration or expression. */
15808 if (c_parser_next_tokens_start_declaration (parser
))
15811 vec_safe_push (for_block
, c_begin_compound_stmt (true));
15812 this_pre_body
= push_stmt_list ();
15813 c_parser_declaration_or_fndef (parser
, true, true, true, true, true,
15817 this_pre_body
= pop_stmt_list (this_pre_body
);
15821 pre_body
= push_stmt_list ();
15823 add_stmt (this_pre_body
);
15824 pre_body
= pop_stmt_list (pre_body
);
15827 pre_body
= this_pre_body
;
15829 decl
= check_for_loop_decls (for_loc
, flag_isoc99
);
15832 if (DECL_INITIAL (decl
) == error_mark_node
)
15833 decl
= error_mark_node
;
15836 else if (c_parser_next_token_is (parser
, CPP_NAME
)
15837 && c_parser_peek_2nd_token (parser
)->type
== CPP_EQ
)
15839 struct c_expr decl_exp
;
15840 struct c_expr init_exp
;
15841 location_t init_loc
;
15843 decl_exp
= c_parser_postfix_expression (parser
);
15844 decl
= decl_exp
.value
;
15846 c_parser_require (parser
, CPP_EQ
, "expected %<=%>");
15848 init_loc
= c_parser_peek_token (parser
)->location
;
15849 init_exp
= c_parser_expr_no_commas (parser
, NULL
);
15850 init_exp
= default_function_array_read_conversion (init_loc
,
15852 init
= build_modify_expr (init_loc
, decl
, decl_exp
.original_type
,
15853 NOP_EXPR
, init_loc
, init_exp
.value
,
15854 init_exp
.original_type
);
15855 init
= c_process_expr_stmt (init_loc
, init
);
15857 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
15862 c_parser_error (parser
,
15863 "expected iteration declaration or initialization");
15864 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
15870 /* Parse the loop condition. */
15872 if (c_parser_next_token_is_not (parser
, CPP_SEMICOLON
))
15874 location_t cond_loc
= c_parser_peek_token (parser
)->location
;
15875 struct c_expr cond_expr
15876 = c_parser_binary_expression (parser
, NULL
, NULL_TREE
);
15878 cond
= cond_expr
.value
;
15879 cond
= c_objc_common_truthvalue_conversion (cond_loc
, cond
);
15880 if (COMPARISON_CLASS_P (cond
))
15882 tree op0
= TREE_OPERAND (cond
, 0), op1
= TREE_OPERAND (cond
, 1);
15883 op0
= c_fully_fold (op0
, false, NULL
);
15884 op1
= c_fully_fold (op1
, false, NULL
);
15885 TREE_OPERAND (cond
, 0) = op0
;
15886 TREE_OPERAND (cond
, 1) = op1
;
15888 switch (cond_expr
.original_code
)
15896 if (code
== CILK_SIMD
|| code
== CILK_FOR
)
15900 /* Can't be cond = error_mark_node, because we want to preserve
15901 the location until c_finish_omp_for. */
15902 cond
= build1 (NOP_EXPR
, boolean_type_node
, error_mark_node
);
15905 protected_set_expr_location (cond
, cond_loc
);
15907 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
15909 /* Parse the increment expression. */
15911 if (c_parser_next_token_is_not (parser
, CPP_CLOSE_PAREN
))
15913 location_t incr_loc
= c_parser_peek_token (parser
)->location
;
15915 incr
= c_process_expr_stmt (incr_loc
,
15916 c_parser_expression (parser
).value
);
15918 parens
.skip_until_found_close (parser
);
15920 if (decl
== NULL
|| decl
== error_mark_node
|| init
== error_mark_node
)
15924 TREE_VEC_ELT (declv
, i
) = decl
;
15925 TREE_VEC_ELT (initv
, i
) = init
;
15926 TREE_VEC_ELT (condv
, i
) = cond
;
15927 TREE_VEC_ELT (incrv
, i
) = incr
;
15931 if (i
== count
- 1)
15934 /* FIXME: OpenMP 3.0 draft isn't very clear on what exactly is allowed
15935 in between the collapsed for loops to be still considered perfectly
15936 nested. Hopefully the final version clarifies this.
15937 For now handle (multiple) {'s and empty statements. */
15940 if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
15942 c_parser_consume_token (parser
);
15945 else if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
15947 c_parser_consume_token (parser
);
15950 else if (bracecount
15951 && c_parser_next_token_is (parser
, CPP_SEMICOLON
))
15952 c_parser_consume_token (parser
);
15955 c_parser_error (parser
, "not enough perfectly nested loops");
15958 open_brace_parsed
= true;
15968 nbraces
+= bracecount
;
15974 save_break
= c_break_label
;
15975 if (code
== CILK_SIMD
)
15976 c_break_label
= build_int_cst (size_type_node
, 2);
15978 c_break_label
= size_one_node
;
15979 save_cont
= c_cont_label
;
15980 c_cont_label
= NULL_TREE
;
15981 body
= push_stmt_list ();
15983 if (open_brace_parsed
)
15985 location_t here
= c_parser_peek_token (parser
)->location
;
15986 stmt
= c_begin_compound_stmt (true);
15987 c_parser_compound_statement_nostart (parser
);
15988 add_stmt (c_end_compound_stmt (here
, stmt
, true));
15991 add_stmt (c_parser_c99_block_statement (parser
, if_p
));
15994 tree t
= build1 (LABEL_EXPR
, void_type_node
, c_cont_label
);
15995 SET_EXPR_LOCATION (t
, loc
);
15999 body
= pop_stmt_list (body
);
16000 c_break_label
= save_break
;
16001 c_cont_label
= save_cont
;
16005 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
16007 c_parser_consume_token (parser
);
16010 else if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
16011 c_parser_consume_token (parser
);
16014 c_parser_error (parser
, "collapsed loops not perfectly nested");
16017 location_t here
= c_parser_peek_token (parser
)->location
;
16018 stmt
= c_begin_compound_stmt (true);
16020 c_parser_compound_statement_nostart (parser
);
16021 body
= c_end_compound_stmt (here
, stmt
, true);
16028 /* Only bother calling c_finish_omp_for if we haven't already generated
16029 an error from the initialization parsing. */
16032 stmt
= c_finish_omp_for (loc
, code
, declv
, NULL
, initv
, condv
,
16033 incrv
, body
, pre_body
);
16035 /* Check for iterators appearing in lb, b or incr expressions. */
16036 if (stmt
&& !c_omp_check_loop_iv (stmt
, declv
, NULL
))
16043 if (cclauses
!= NULL
16044 && cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
] != NULL
)
16047 for (c
= &cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
]; *c
; )
16048 if (OMP_CLAUSE_CODE (*c
) != OMP_CLAUSE_FIRSTPRIVATE
16049 && OMP_CLAUSE_CODE (*c
) != OMP_CLAUSE_LASTPRIVATE
)
16050 c
= &OMP_CLAUSE_CHAIN (*c
);
16053 for (i
= 0; i
< count
; i
++)
16054 if (TREE_VEC_ELT (declv
, i
) == OMP_CLAUSE_DECL (*c
))
16057 c
= &OMP_CLAUSE_CHAIN (*c
);
16058 else if (OMP_CLAUSE_CODE (*c
) == OMP_CLAUSE_FIRSTPRIVATE
)
16061 "iteration variable %qD should not be firstprivate",
16062 OMP_CLAUSE_DECL (*c
));
16063 *c
= OMP_CLAUSE_CHAIN (*c
);
16067 /* Move lastprivate (decl) clause to OMP_FOR_CLAUSES. */
16069 *c
= OMP_CLAUSE_CHAIN (*c
);
16070 if (code
== OMP_SIMD
)
16072 OMP_CLAUSE_CHAIN (l
)
16073 = cclauses
[C_OMP_CLAUSE_SPLIT_FOR
];
16074 cclauses
[C_OMP_CLAUSE_SPLIT_FOR
] = l
;
16078 OMP_CLAUSE_CHAIN (l
) = clauses
;
16084 OMP_FOR_CLAUSES (stmt
) = clauses
;
16089 while (!for_block
->is_empty ())
16091 /* FIXME diagnostics: LOC below should be the actual location of
16092 this particular for block. We need to build a list of
16093 locations to go along with FOR_BLOCK. */
16094 stmt
= c_end_compound_stmt (loc
, for_block
->pop (), true);
16097 release_tree_vector (for_block
);
16101 /* Helper function for OpenMP parsing, split clauses and call
16102 finish_omp_clauses on each of the set of clauses afterwards. */
16105 omp_split_clauses (location_t loc
, enum tree_code code
,
16106 omp_clause_mask mask
, tree clauses
, tree
*cclauses
)
16109 c_omp_split_clauses (loc
, code
, mask
, clauses
, cclauses
);
16110 for (i
= 0; i
< C_OMP_CLAUSE_SPLIT_COUNT
; i
++)
16112 cclauses
[i
] = c_finish_omp_clauses (cclauses
[i
], C_ORT_OMP
);
16116 #pragma omp simd simd-clause[optseq] new-line
16119 LOC is the location of the #pragma token.
16122 #define OMP_SIMD_CLAUSE_MASK \
16123 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SAFELEN) \
16124 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
16125 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
16126 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
16127 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
16128 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
16129 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
16130 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE))
16133 c_parser_omp_simd (location_t loc
, c_parser
*parser
,
16134 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
16137 tree block
, clauses
, ret
;
16139 strcat (p_name
, " simd");
16140 mask
|= OMP_SIMD_CLAUSE_MASK
;
16142 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
16145 omp_split_clauses (loc
, OMP_SIMD
, mask
, clauses
, cclauses
);
16146 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_SIMD
];
16147 tree c
= omp_find_clause (cclauses
[C_OMP_CLAUSE_SPLIT_FOR
],
16148 OMP_CLAUSE_ORDERED
);
16149 if (c
&& OMP_CLAUSE_ORDERED_EXPR (c
))
16151 error_at (OMP_CLAUSE_LOCATION (c
),
16152 "%<ordered%> clause with parameter may not be specified "
16153 "on %qs construct", p_name
);
16154 OMP_CLAUSE_ORDERED_EXPR (c
) = NULL_TREE
;
16158 block
= c_begin_compound_stmt (true);
16159 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_SIMD
, clauses
, cclauses
, if_p
);
16160 block
= c_end_compound_stmt (loc
, block
, true);
16167 #pragma omp for for-clause[optseq] new-line
16171 #pragma omp for simd for-simd-clause[optseq] new-line
16174 LOC is the location of the #pragma token.
16177 #define OMP_FOR_CLAUSE_MASK \
16178 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
16179 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
16180 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
16181 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
16182 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
16183 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED) \
16184 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE) \
16185 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
16186 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
16189 c_parser_omp_for (location_t loc
, c_parser
*parser
,
16190 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
16193 tree block
, clauses
, ret
;
16195 strcat (p_name
, " for");
16196 mask
|= OMP_FOR_CLAUSE_MASK
;
16197 /* parallel for{, simd} disallows nowait clause, but for
16198 target {teams distribute ,}parallel for{, simd} it should be accepted. */
16199 if (cclauses
&& (mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_MAP
)) == 0)
16200 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_NOWAIT
);
16201 /* Composite distribute parallel for{, simd} disallows ordered clause. */
16202 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
)) != 0)
16203 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_ORDERED
);
16205 if (c_parser_next_token_is (parser
, CPP_NAME
))
16207 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
16209 if (strcmp (p
, "simd") == 0)
16211 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
16212 if (cclauses
== NULL
)
16213 cclauses
= cclauses_buf
;
16215 c_parser_consume_token (parser
);
16216 if (!flag_openmp
) /* flag_openmp_simd */
16217 return c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
,
16219 block
= c_begin_compound_stmt (true);
16220 ret
= c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
16221 block
= c_end_compound_stmt (loc
, block
, true);
16222 if (ret
== NULL_TREE
)
16224 ret
= make_node (OMP_FOR
);
16225 TREE_TYPE (ret
) = void_type_node
;
16226 OMP_FOR_BODY (ret
) = block
;
16227 OMP_FOR_CLAUSES (ret
) = cclauses
[C_OMP_CLAUSE_SPLIT_FOR
];
16228 SET_EXPR_LOCATION (ret
, loc
);
16233 if (!flag_openmp
) /* flag_openmp_simd */
16235 c_parser_skip_to_pragma_eol (parser
, false);
16239 /* Composite distribute parallel for disallows linear clause. */
16240 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
)) != 0)
16241 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_LINEAR
);
16243 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
16246 omp_split_clauses (loc
, OMP_FOR
, mask
, clauses
, cclauses
);
16247 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_FOR
];
16250 block
= c_begin_compound_stmt (true);
16251 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_FOR
, clauses
, cclauses
, if_p
);
16252 block
= c_end_compound_stmt (loc
, block
, true);
16259 # pragma omp master new-line
16262 LOC is the location of the #pragma token.
16266 c_parser_omp_master (location_t loc
, c_parser
*parser
, bool *if_p
)
16268 c_parser_skip_to_pragma_eol (parser
);
16269 return c_finish_omp_master (loc
, c_parser_omp_structured_block (parser
,
16274 # pragma omp ordered new-line
16278 # pragma omp ordered ordered-clauses new-line
16281 # pragma omp ordered depend-clauses new-line */
16283 #define OMP_ORDERED_CLAUSE_MASK \
16284 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREADS) \
16285 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMD))
16287 #define OMP_ORDERED_DEPEND_CLAUSE_MASK \
16288 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)
16291 c_parser_omp_ordered (c_parser
*parser
, enum pragma_context context
,
16294 location_t loc
= c_parser_peek_token (parser
)->location
;
16295 c_parser_consume_pragma (parser
);
16297 if (context
!= pragma_stmt
&& context
!= pragma_compound
)
16299 c_parser_error (parser
, "expected declaration specifiers");
16300 c_parser_skip_to_pragma_eol (parser
, false);
16304 if (c_parser_next_token_is (parser
, CPP_NAME
))
16306 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
16308 if (!strcmp ("depend", p
))
16310 if (!flag_openmp
) /* flag_openmp_simd */
16312 c_parser_skip_to_pragma_eol (parser
, false);
16315 if (context
== pragma_stmt
)
16318 "%<#pragma omp ordered%> with %<depend%> clause may "
16319 "only be used in compound statements");
16320 c_parser_skip_to_pragma_eol (parser
, false);
16325 = c_parser_omp_all_clauses (parser
,
16326 OMP_ORDERED_DEPEND_CLAUSE_MASK
,
16327 "#pragma omp ordered");
16328 c_finish_omp_ordered (loc
, clauses
, NULL_TREE
);
16333 tree clauses
= c_parser_omp_all_clauses (parser
, OMP_ORDERED_CLAUSE_MASK
,
16334 "#pragma omp ordered");
16336 if (!flag_openmp
/* flag_openmp_simd */
16337 && omp_find_clause (clauses
, OMP_CLAUSE_SIMD
) == NULL_TREE
)
16340 c_finish_omp_ordered (loc
, clauses
,
16341 c_parser_omp_structured_block (parser
, if_p
));
16348 { section-sequence }
16351 section-directive[opt] structured-block
16352 section-sequence section-directive structured-block
16354 SECTIONS_LOC is the location of the #pragma omp sections. */
16357 c_parser_omp_sections_scope (location_t sections_loc
, c_parser
*parser
)
16359 tree stmt
, substmt
;
16360 bool error_suppress
= false;
16363 loc
= c_parser_peek_token (parser
)->location
;
16364 if (!c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
16366 /* Avoid skipping until the end of the block. */
16367 parser
->error
= false;
16371 stmt
= push_stmt_list ();
16373 if (c_parser_peek_token (parser
)->pragma_kind
!= PRAGMA_OMP_SECTION
)
16375 substmt
= c_parser_omp_structured_block (parser
, NULL
);
16376 substmt
= build1 (OMP_SECTION
, void_type_node
, substmt
);
16377 SET_EXPR_LOCATION (substmt
, loc
);
16378 add_stmt (substmt
);
16383 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
16385 if (c_parser_next_token_is (parser
, CPP_EOF
))
16388 loc
= c_parser_peek_token (parser
)->location
;
16389 if (c_parser_peek_token (parser
)->pragma_kind
== PRAGMA_OMP_SECTION
)
16391 c_parser_consume_pragma (parser
);
16392 c_parser_skip_to_pragma_eol (parser
);
16393 error_suppress
= false;
16395 else if (!error_suppress
)
16397 error_at (loc
, "expected %<#pragma omp section%> or %<}%>");
16398 error_suppress
= true;
16401 substmt
= c_parser_omp_structured_block (parser
, NULL
);
16402 substmt
= build1 (OMP_SECTION
, void_type_node
, substmt
);
16403 SET_EXPR_LOCATION (substmt
, loc
);
16404 add_stmt (substmt
);
16406 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
,
16407 "expected %<#pragma omp section%> or %<}%>");
16409 substmt
= pop_stmt_list (stmt
);
16411 stmt
= make_node (OMP_SECTIONS
);
16412 SET_EXPR_LOCATION (stmt
, sections_loc
);
16413 TREE_TYPE (stmt
) = void_type_node
;
16414 OMP_SECTIONS_BODY (stmt
) = substmt
;
16416 return add_stmt (stmt
);
16420 # pragma omp sections sections-clause[optseq] newline
16423 LOC is the location of the #pragma token.
16426 #define OMP_SECTIONS_CLAUSE_MASK \
16427 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
16428 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
16429 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
16430 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
16431 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
16434 c_parser_omp_sections (location_t loc
, c_parser
*parser
,
16435 char *p_name
, omp_clause_mask mask
, tree
*cclauses
)
16437 tree block
, clauses
, ret
;
16439 strcat (p_name
, " sections");
16440 mask
|= OMP_SECTIONS_CLAUSE_MASK
;
16442 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_NOWAIT
);
16444 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
16447 omp_split_clauses (loc
, OMP_SECTIONS
, mask
, clauses
, cclauses
);
16448 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_SECTIONS
];
16451 block
= c_begin_compound_stmt (true);
16452 ret
= c_parser_omp_sections_scope (loc
, parser
);
16454 OMP_SECTIONS_CLAUSES (ret
) = clauses
;
16455 block
= c_end_compound_stmt (loc
, block
, true);
16462 # pragma omp parallel parallel-clause[optseq] new-line
16464 # pragma omp parallel for parallel-for-clause[optseq] new-line
16466 # pragma omp parallel sections parallel-sections-clause[optseq] new-line
16470 # pragma omp parallel for simd parallel-for-simd-clause[optseq] new-line
16473 LOC is the location of the #pragma token.
16476 #define OMP_PARALLEL_CLAUSE_MASK \
16477 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
16478 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
16479 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
16480 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
16481 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
16482 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN) \
16483 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
16484 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS) \
16485 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PROC_BIND))
16488 c_parser_omp_parallel (location_t loc
, c_parser
*parser
,
16489 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
16492 tree stmt
, clauses
, block
;
16494 strcat (p_name
, " parallel");
16495 mask
|= OMP_PARALLEL_CLAUSE_MASK
;
16496 /* #pragma omp target parallel{, for, for simd} disallow copyin clause. */
16497 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_MAP
)) != 0
16498 && (mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
)) == 0)
16499 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_COPYIN
);
16501 if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
16503 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
16504 if (cclauses
== NULL
)
16505 cclauses
= cclauses_buf
;
16507 c_parser_consume_token (parser
);
16508 if (!flag_openmp
) /* flag_openmp_simd */
16509 return c_parser_omp_for (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
16510 block
= c_begin_omp_parallel ();
16511 tree ret
= c_parser_omp_for (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
16513 = c_finish_omp_parallel (loc
, cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
16515 if (ret
== NULL_TREE
)
16517 OMP_PARALLEL_COMBINED (stmt
) = 1;
16520 /* When combined with distribute, parallel has to be followed by for.
16521 #pragma omp target parallel is allowed though. */
16523 && (mask
& (OMP_CLAUSE_MASK_1
16524 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
)) != 0)
16526 error_at (loc
, "expected %<for%> after %qs", p_name
);
16527 c_parser_skip_to_pragma_eol (parser
);
16530 else if (!flag_openmp
) /* flag_openmp_simd */
16532 c_parser_skip_to_pragma_eol (parser
, false);
16535 else if (cclauses
== NULL
&& c_parser_next_token_is (parser
, CPP_NAME
))
16537 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
16538 if (strcmp (p
, "sections") == 0)
16540 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
16541 if (cclauses
== NULL
)
16542 cclauses
= cclauses_buf
;
16544 c_parser_consume_token (parser
);
16545 block
= c_begin_omp_parallel ();
16546 c_parser_omp_sections (loc
, parser
, p_name
, mask
, cclauses
);
16547 stmt
= c_finish_omp_parallel (loc
,
16548 cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
16550 OMP_PARALLEL_COMBINED (stmt
) = 1;
16555 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
16558 omp_split_clauses (loc
, OMP_PARALLEL
, mask
, clauses
, cclauses
);
16559 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
];
16562 block
= c_begin_omp_parallel ();
16563 c_parser_statement (parser
, if_p
);
16564 stmt
= c_finish_omp_parallel (loc
, clauses
, block
);
16570 # pragma omp single single-clause[optseq] new-line
16573 LOC is the location of the #pragma.
16576 #define OMP_SINGLE_CLAUSE_MASK \
16577 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
16578 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
16579 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYPRIVATE) \
16580 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
16583 c_parser_omp_single (location_t loc
, c_parser
*parser
, bool *if_p
)
16585 tree stmt
= make_node (OMP_SINGLE
);
16586 SET_EXPR_LOCATION (stmt
, loc
);
16587 TREE_TYPE (stmt
) = void_type_node
;
16589 OMP_SINGLE_CLAUSES (stmt
)
16590 = c_parser_omp_all_clauses (parser
, OMP_SINGLE_CLAUSE_MASK
,
16591 "#pragma omp single");
16592 OMP_SINGLE_BODY (stmt
) = c_parser_omp_structured_block (parser
, if_p
);
16594 return add_stmt (stmt
);
16598 # pragma omp task task-clause[optseq] new-line
16600 LOC is the location of the #pragma.
16603 #define OMP_TASK_CLAUSE_MASK \
16604 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
16605 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
16606 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
16607 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
16608 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
16609 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
16610 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
16611 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
16612 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
16613 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY))
16616 c_parser_omp_task (location_t loc
, c_parser
*parser
, bool *if_p
)
16618 tree clauses
, block
;
16620 clauses
= c_parser_omp_all_clauses (parser
, OMP_TASK_CLAUSE_MASK
,
16621 "#pragma omp task");
16623 block
= c_begin_omp_task ();
16624 c_parser_statement (parser
, if_p
);
16625 return c_finish_omp_task (loc
, clauses
, block
);
16629 # pragma omp taskwait new-line
16633 c_parser_omp_taskwait (c_parser
*parser
)
16635 location_t loc
= c_parser_peek_token (parser
)->location
;
16636 c_parser_consume_pragma (parser
);
16637 c_parser_skip_to_pragma_eol (parser
);
16639 c_finish_omp_taskwait (loc
);
16643 # pragma omp taskyield new-line
16647 c_parser_omp_taskyield (c_parser
*parser
)
16649 location_t loc
= c_parser_peek_token (parser
)->location
;
16650 c_parser_consume_pragma (parser
);
16651 c_parser_skip_to_pragma_eol (parser
);
16653 c_finish_omp_taskyield (loc
);
16657 # pragma omp taskgroup new-line
16661 c_parser_omp_taskgroup (c_parser
*parser
, bool *if_p
)
16663 location_t loc
= c_parser_peek_token (parser
)->location
;
16664 c_parser_skip_to_pragma_eol (parser
);
16665 return c_finish_omp_taskgroup (loc
, c_parser_omp_structured_block (parser
,
16670 # pragma omp cancel cancel-clause[optseq] new-line
16672 LOC is the location of the #pragma.
16675 #define OMP_CANCEL_CLAUSE_MASK \
16676 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
16677 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
16678 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
16679 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP) \
16680 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF))
16683 c_parser_omp_cancel (c_parser
*parser
)
16685 location_t loc
= c_parser_peek_token (parser
)->location
;
16687 c_parser_consume_pragma (parser
);
16688 tree clauses
= c_parser_omp_all_clauses (parser
, OMP_CANCEL_CLAUSE_MASK
,
16689 "#pragma omp cancel");
16691 c_finish_omp_cancel (loc
, clauses
);
16695 # pragma omp cancellation point cancelpt-clause[optseq] new-line
16697 LOC is the location of the #pragma.
16700 #define OMP_CANCELLATION_POINT_CLAUSE_MASK \
16701 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
16702 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
16703 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
16704 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP))
16707 c_parser_omp_cancellation_point (c_parser
*parser
, enum pragma_context context
)
16709 location_t loc
= c_parser_peek_token (parser
)->location
;
16711 bool point_seen
= false;
16713 c_parser_consume_pragma (parser
);
16714 if (c_parser_next_token_is (parser
, CPP_NAME
))
16716 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
16717 if (strcmp (p
, "point") == 0)
16719 c_parser_consume_token (parser
);
16725 c_parser_error (parser
, "expected %<point%>");
16726 c_parser_skip_to_pragma_eol (parser
);
16730 if (context
!= pragma_compound
)
16732 if (context
== pragma_stmt
)
16734 "%<#pragma %s%> may only be used in compound statements",
16735 "omp cancellation point");
16737 c_parser_error (parser
, "expected declaration specifiers");
16738 c_parser_skip_to_pragma_eol (parser
, false);
16743 = c_parser_omp_all_clauses (parser
, OMP_CANCELLATION_POINT_CLAUSE_MASK
,
16744 "#pragma omp cancellation point");
16746 c_finish_omp_cancellation_point (loc
, clauses
);
16750 #pragma omp distribute distribute-clause[optseq] new-line
16753 #define OMP_DISTRIBUTE_CLAUSE_MASK \
16754 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
16755 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
16756 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
16757 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)\
16758 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE))
16761 c_parser_omp_distribute (location_t loc
, c_parser
*parser
,
16762 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
16765 tree clauses
, block
, ret
;
16767 strcat (p_name
, " distribute");
16768 mask
|= OMP_DISTRIBUTE_CLAUSE_MASK
;
16770 if (c_parser_next_token_is (parser
, CPP_NAME
))
16772 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
16774 bool parallel
= false;
16776 if (strcmp (p
, "simd") == 0)
16779 parallel
= strcmp (p
, "parallel") == 0;
16780 if (parallel
|| simd
)
16782 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
16783 if (cclauses
== NULL
)
16784 cclauses
= cclauses_buf
;
16785 c_parser_consume_token (parser
);
16786 if (!flag_openmp
) /* flag_openmp_simd */
16789 return c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
,
16792 return c_parser_omp_parallel (loc
, parser
, p_name
, mask
,
16795 block
= c_begin_compound_stmt (true);
16797 ret
= c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
,
16800 ret
= c_parser_omp_parallel (loc
, parser
, p_name
, mask
, cclauses
,
16802 block
= c_end_compound_stmt (loc
, block
, true);
16805 ret
= make_node (OMP_DISTRIBUTE
);
16806 TREE_TYPE (ret
) = void_type_node
;
16807 OMP_FOR_BODY (ret
) = block
;
16808 OMP_FOR_CLAUSES (ret
) = cclauses
[C_OMP_CLAUSE_SPLIT_DISTRIBUTE
];
16809 SET_EXPR_LOCATION (ret
, loc
);
16814 if (!flag_openmp
) /* flag_openmp_simd */
16816 c_parser_skip_to_pragma_eol (parser
, false);
16820 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
16823 omp_split_clauses (loc
, OMP_DISTRIBUTE
, mask
, clauses
, cclauses
);
16824 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_DISTRIBUTE
];
16827 block
= c_begin_compound_stmt (true);
16828 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_DISTRIBUTE
, clauses
, NULL
,
16830 block
= c_end_compound_stmt (loc
, block
, true);
16837 # pragma omp teams teams-clause[optseq] new-line
16838 structured-block */
16840 #define OMP_TEAMS_CLAUSE_MASK \
16841 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
16842 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
16843 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
16844 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
16845 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS) \
16846 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \
16847 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT))
16850 c_parser_omp_teams (location_t loc
, c_parser
*parser
,
16851 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
16854 tree clauses
, block
, ret
;
16856 strcat (p_name
, " teams");
16857 mask
|= OMP_TEAMS_CLAUSE_MASK
;
16859 if (c_parser_next_token_is (parser
, CPP_NAME
))
16861 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
16862 if (strcmp (p
, "distribute") == 0)
16864 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
16865 if (cclauses
== NULL
)
16866 cclauses
= cclauses_buf
;
16868 c_parser_consume_token (parser
);
16869 if (!flag_openmp
) /* flag_openmp_simd */
16870 return c_parser_omp_distribute (loc
, parser
, p_name
, mask
,
16872 block
= c_begin_compound_stmt (true);
16873 ret
= c_parser_omp_distribute (loc
, parser
, p_name
, mask
, cclauses
,
16875 block
= c_end_compound_stmt (loc
, block
, true);
16878 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_TEAMS
];
16879 ret
= make_node (OMP_TEAMS
);
16880 TREE_TYPE (ret
) = void_type_node
;
16881 OMP_TEAMS_CLAUSES (ret
) = clauses
;
16882 OMP_TEAMS_BODY (ret
) = block
;
16883 OMP_TEAMS_COMBINED (ret
) = 1;
16884 return add_stmt (ret
);
16887 if (!flag_openmp
) /* flag_openmp_simd */
16889 c_parser_skip_to_pragma_eol (parser
, false);
16893 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
16896 omp_split_clauses (loc
, OMP_TEAMS
, mask
, clauses
, cclauses
);
16897 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_TEAMS
];
16900 tree stmt
= make_node (OMP_TEAMS
);
16901 TREE_TYPE (stmt
) = void_type_node
;
16902 OMP_TEAMS_CLAUSES (stmt
) = clauses
;
16903 OMP_TEAMS_BODY (stmt
) = c_parser_omp_structured_block (parser
, if_p
);
16905 return add_stmt (stmt
);
16909 # pragma omp target data target-data-clause[optseq] new-line
16910 structured-block */
16912 #define OMP_TARGET_DATA_CLAUSE_MASK \
16913 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
16914 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
16915 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
16916 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR))
16919 c_parser_omp_target_data (location_t loc
, c_parser
*parser
, bool *if_p
)
16922 = c_parser_omp_all_clauses (parser
, OMP_TARGET_DATA_CLAUSE_MASK
,
16923 "#pragma omp target data");
16925 for (tree
*pc
= &clauses
; *pc
;)
16927 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_MAP
)
16928 switch (OMP_CLAUSE_MAP_KIND (*pc
))
16931 case GOMP_MAP_ALWAYS_TO
:
16932 case GOMP_MAP_FROM
:
16933 case GOMP_MAP_ALWAYS_FROM
:
16934 case GOMP_MAP_TOFROM
:
16935 case GOMP_MAP_ALWAYS_TOFROM
:
16936 case GOMP_MAP_ALLOC
:
16939 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
16940 case GOMP_MAP_ALWAYS_POINTER
:
16944 error_at (OMP_CLAUSE_LOCATION (*pc
),
16945 "%<#pragma omp target data%> with map-type other "
16946 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
16947 "on %<map%> clause");
16948 *pc
= OMP_CLAUSE_CHAIN (*pc
);
16951 pc
= &OMP_CLAUSE_CHAIN (*pc
);
16958 "%<#pragma omp target data%> must contain at least "
16959 "one %<map%> clause");
16963 tree stmt
= make_node (OMP_TARGET_DATA
);
16964 TREE_TYPE (stmt
) = void_type_node
;
16965 OMP_TARGET_DATA_CLAUSES (stmt
) = clauses
;
16966 keep_next_level ();
16967 tree block
= c_begin_compound_stmt (true);
16968 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
16969 OMP_TARGET_DATA_BODY (stmt
) = c_end_compound_stmt (loc
, block
, true);
16971 SET_EXPR_LOCATION (stmt
, loc
);
16972 return add_stmt (stmt
);
16976 # pragma omp target update target-update-clause[optseq] new-line */
16978 #define OMP_TARGET_UPDATE_CLAUSE_MASK \
16979 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FROM) \
16980 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
16981 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
16982 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
16983 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
16984 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
16987 c_parser_omp_target_update (location_t loc
, c_parser
*parser
,
16988 enum pragma_context context
)
16990 if (context
== pragma_stmt
)
16992 error_at (loc
, "%<#pragma %s%> may only be used in compound statements",
16993 "omp target update");
16994 c_parser_skip_to_pragma_eol (parser
, false);
16999 = c_parser_omp_all_clauses (parser
, OMP_TARGET_UPDATE_CLAUSE_MASK
,
17000 "#pragma omp target update");
17001 if (omp_find_clause (clauses
, OMP_CLAUSE_TO
) == NULL_TREE
17002 && omp_find_clause (clauses
, OMP_CLAUSE_FROM
) == NULL_TREE
)
17005 "%<#pragma omp target update%> must contain at least one "
17006 "%<from%> or %<to%> clauses");
17010 tree stmt
= make_node (OMP_TARGET_UPDATE
);
17011 TREE_TYPE (stmt
) = void_type_node
;
17012 OMP_TARGET_UPDATE_CLAUSES (stmt
) = clauses
;
17013 SET_EXPR_LOCATION (stmt
, loc
);
17019 # pragma omp target enter data target-data-clause[optseq] new-line */
17021 #define OMP_TARGET_ENTER_DATA_CLAUSE_MASK \
17022 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
17023 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
17024 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
17025 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
17026 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
17029 c_parser_omp_target_enter_data (location_t loc
, c_parser
*parser
,
17030 enum pragma_context context
)
17032 bool data_seen
= false;
17033 if (c_parser_next_token_is (parser
, CPP_NAME
))
17035 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
17036 if (strcmp (p
, "data") == 0)
17038 c_parser_consume_token (parser
);
17044 c_parser_error (parser
, "expected %<data%>");
17045 c_parser_skip_to_pragma_eol (parser
);
17049 if (context
== pragma_stmt
)
17051 error_at (loc
, "%<#pragma %s%> may only be used in compound statements",
17052 "omp target enter data");
17053 c_parser_skip_to_pragma_eol (parser
, false);
17058 = c_parser_omp_all_clauses (parser
, OMP_TARGET_ENTER_DATA_CLAUSE_MASK
,
17059 "#pragma omp target enter data");
17061 for (tree
*pc
= &clauses
; *pc
;)
17063 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_MAP
)
17064 switch (OMP_CLAUSE_MAP_KIND (*pc
))
17067 case GOMP_MAP_ALWAYS_TO
:
17068 case GOMP_MAP_ALLOC
:
17071 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
17072 case GOMP_MAP_ALWAYS_POINTER
:
17076 error_at (OMP_CLAUSE_LOCATION (*pc
),
17077 "%<#pragma omp target enter data%> with map-type other "
17078 "than %<to%> or %<alloc%> on %<map%> clause");
17079 *pc
= OMP_CLAUSE_CHAIN (*pc
);
17082 pc
= &OMP_CLAUSE_CHAIN (*pc
);
17089 "%<#pragma omp target enter data%> must contain at least "
17090 "one %<map%> clause");
17094 tree stmt
= make_node (OMP_TARGET_ENTER_DATA
);
17095 TREE_TYPE (stmt
) = void_type_node
;
17096 OMP_TARGET_ENTER_DATA_CLAUSES (stmt
) = clauses
;
17097 SET_EXPR_LOCATION (stmt
, loc
);
17103 # pragma omp target exit data target-data-clause[optseq] new-line */
17105 #define OMP_TARGET_EXIT_DATA_CLAUSE_MASK \
17106 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
17107 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
17108 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
17109 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
17110 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
17113 c_parser_omp_target_exit_data (location_t loc
, c_parser
*parser
,
17114 enum pragma_context context
)
17116 bool data_seen
= false;
17117 if (c_parser_next_token_is (parser
, CPP_NAME
))
17119 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
17120 if (strcmp (p
, "data") == 0)
17122 c_parser_consume_token (parser
);
17128 c_parser_error (parser
, "expected %<data%>");
17129 c_parser_skip_to_pragma_eol (parser
);
17133 if (context
== pragma_stmt
)
17135 error_at (loc
, "%<#pragma %s%> may only be used in compound statements",
17136 "omp target exit data");
17137 c_parser_skip_to_pragma_eol (parser
, false);
17142 = c_parser_omp_all_clauses (parser
, OMP_TARGET_EXIT_DATA_CLAUSE_MASK
,
17143 "#pragma omp target exit data");
17146 for (tree
*pc
= &clauses
; *pc
;)
17148 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_MAP
)
17149 switch (OMP_CLAUSE_MAP_KIND (*pc
))
17151 case GOMP_MAP_FROM
:
17152 case GOMP_MAP_ALWAYS_FROM
:
17153 case GOMP_MAP_RELEASE
:
17154 case GOMP_MAP_DELETE
:
17157 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
17158 case GOMP_MAP_ALWAYS_POINTER
:
17162 error_at (OMP_CLAUSE_LOCATION (*pc
),
17163 "%<#pragma omp target exit data%> with map-type other "
17164 "than %<from%>, %<release%> or %<delete%> on %<map%>"
17166 *pc
= OMP_CLAUSE_CHAIN (*pc
);
17169 pc
= &OMP_CLAUSE_CHAIN (*pc
);
17176 "%<#pragma omp target exit data%> must contain at least one "
17181 tree stmt
= make_node (OMP_TARGET_EXIT_DATA
);
17182 TREE_TYPE (stmt
) = void_type_node
;
17183 OMP_TARGET_EXIT_DATA_CLAUSES (stmt
) = clauses
;
17184 SET_EXPR_LOCATION (stmt
, loc
);
17190 # pragma omp target target-clause[optseq] new-line
17191 structured-block */
17193 #define OMP_TARGET_CLAUSE_MASK \
17194 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
17195 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
17196 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
17197 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
17198 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
17199 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
17200 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
17201 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULTMAP) \
17202 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR))
17205 c_parser_omp_target (c_parser
*parser
, enum pragma_context context
, bool *if_p
)
17207 location_t loc
= c_parser_peek_token (parser
)->location
;
17208 c_parser_consume_pragma (parser
);
17209 tree
*pc
= NULL
, stmt
, block
;
17211 if (context
!= pragma_stmt
&& context
!= pragma_compound
)
17213 c_parser_error (parser
, "expected declaration specifiers");
17214 c_parser_skip_to_pragma_eol (parser
);
17218 if (c_parser_next_token_is (parser
, CPP_NAME
))
17220 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
17221 enum tree_code ccode
= ERROR_MARK
;
17223 if (strcmp (p
, "teams") == 0)
17225 else if (strcmp (p
, "parallel") == 0)
17226 ccode
= OMP_PARALLEL
;
17227 else if (strcmp (p
, "simd") == 0)
17229 if (ccode
!= ERROR_MARK
)
17231 tree cclauses
[C_OMP_CLAUSE_SPLIT_COUNT
];
17232 char p_name
[sizeof ("#pragma omp target teams distribute "
17233 "parallel for simd")];
17235 c_parser_consume_token (parser
);
17236 strcpy (p_name
, "#pragma omp target");
17237 if (!flag_openmp
) /* flag_openmp_simd */
17243 stmt
= c_parser_omp_teams (loc
, parser
, p_name
,
17244 OMP_TARGET_CLAUSE_MASK
,
17248 stmt
= c_parser_omp_parallel (loc
, parser
, p_name
,
17249 OMP_TARGET_CLAUSE_MASK
,
17253 stmt
= c_parser_omp_simd (loc
, parser
, p_name
,
17254 OMP_TARGET_CLAUSE_MASK
,
17258 gcc_unreachable ();
17260 return stmt
!= NULL_TREE
;
17262 keep_next_level ();
17263 tree block
= c_begin_compound_stmt (true), ret
;
17267 ret
= c_parser_omp_teams (loc
, parser
, p_name
,
17268 OMP_TARGET_CLAUSE_MASK
, cclauses
,
17272 ret
= c_parser_omp_parallel (loc
, parser
, p_name
,
17273 OMP_TARGET_CLAUSE_MASK
, cclauses
,
17277 ret
= c_parser_omp_simd (loc
, parser
, p_name
,
17278 OMP_TARGET_CLAUSE_MASK
, cclauses
,
17282 gcc_unreachable ();
17284 block
= c_end_compound_stmt (loc
, block
, true);
17285 if (ret
== NULL_TREE
)
17287 if (ccode
== OMP_TEAMS
)
17289 /* For combined target teams, ensure the num_teams and
17290 thread_limit clause expressions are evaluated on the host,
17291 before entering the target construct. */
17293 for (c
= cclauses
[C_OMP_CLAUSE_SPLIT_TEAMS
];
17294 c
; c
= OMP_CLAUSE_CHAIN (c
))
17295 if ((OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_NUM_TEAMS
17296 || OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_THREAD_LIMIT
)
17297 && TREE_CODE (OMP_CLAUSE_OPERAND (c
, 0)) != INTEGER_CST
)
17299 tree expr
= OMP_CLAUSE_OPERAND (c
, 0);
17300 tree tmp
= create_tmp_var_raw (TREE_TYPE (expr
));
17301 expr
= build4 (TARGET_EXPR
, TREE_TYPE (expr
), tmp
,
17302 expr
, NULL_TREE
, NULL_TREE
);
17304 OMP_CLAUSE_OPERAND (c
, 0) = expr
;
17305 tree tc
= build_omp_clause (OMP_CLAUSE_LOCATION (c
),
17306 OMP_CLAUSE_FIRSTPRIVATE
);
17307 OMP_CLAUSE_DECL (tc
) = tmp
;
17308 OMP_CLAUSE_CHAIN (tc
)
17309 = cclauses
[C_OMP_CLAUSE_SPLIT_TARGET
];
17310 cclauses
[C_OMP_CLAUSE_SPLIT_TARGET
] = tc
;
17313 tree stmt
= make_node (OMP_TARGET
);
17314 TREE_TYPE (stmt
) = void_type_node
;
17315 OMP_TARGET_CLAUSES (stmt
) = cclauses
[C_OMP_CLAUSE_SPLIT_TARGET
];
17316 OMP_TARGET_BODY (stmt
) = block
;
17317 OMP_TARGET_COMBINED (stmt
) = 1;
17319 pc
= &OMP_TARGET_CLAUSES (stmt
);
17320 goto check_clauses
;
17322 else if (!flag_openmp
) /* flag_openmp_simd */
17324 c_parser_skip_to_pragma_eol (parser
, false);
17327 else if (strcmp (p
, "data") == 0)
17329 c_parser_consume_token (parser
);
17330 c_parser_omp_target_data (loc
, parser
, if_p
);
17333 else if (strcmp (p
, "enter") == 0)
17335 c_parser_consume_token (parser
);
17336 c_parser_omp_target_enter_data (loc
, parser
, context
);
17339 else if (strcmp (p
, "exit") == 0)
17341 c_parser_consume_token (parser
);
17342 c_parser_omp_target_exit_data (loc
, parser
, context
);
17345 else if (strcmp (p
, "update") == 0)
17347 c_parser_consume_token (parser
);
17348 return c_parser_omp_target_update (loc
, parser
, context
);
17351 if (!flag_openmp
) /* flag_openmp_simd */
17353 c_parser_skip_to_pragma_eol (parser
, false);
17357 stmt
= make_node (OMP_TARGET
);
17358 TREE_TYPE (stmt
) = void_type_node
;
17360 OMP_TARGET_CLAUSES (stmt
)
17361 = c_parser_omp_all_clauses (parser
, OMP_TARGET_CLAUSE_MASK
,
17362 "#pragma omp target");
17363 pc
= &OMP_TARGET_CLAUSES (stmt
);
17364 keep_next_level ();
17365 block
= c_begin_compound_stmt (true);
17366 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
17367 OMP_TARGET_BODY (stmt
) = c_end_compound_stmt (loc
, block
, true);
17369 SET_EXPR_LOCATION (stmt
, loc
);
17375 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_MAP
)
17376 switch (OMP_CLAUSE_MAP_KIND (*pc
))
17379 case GOMP_MAP_ALWAYS_TO
:
17380 case GOMP_MAP_FROM
:
17381 case GOMP_MAP_ALWAYS_FROM
:
17382 case GOMP_MAP_TOFROM
:
17383 case GOMP_MAP_ALWAYS_TOFROM
:
17384 case GOMP_MAP_ALLOC
:
17385 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
17386 case GOMP_MAP_ALWAYS_POINTER
:
17389 error_at (OMP_CLAUSE_LOCATION (*pc
),
17390 "%<#pragma omp target%> with map-type other "
17391 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
17392 "on %<map%> clause");
17393 *pc
= OMP_CLAUSE_CHAIN (*pc
);
17396 pc
= &OMP_CLAUSE_CHAIN (*pc
);
17402 # pragma omp declare simd declare-simd-clauses[optseq] new-line */
17404 #define OMP_DECLARE_SIMD_CLAUSE_MASK \
17405 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
17406 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
17407 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
17408 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM) \
17409 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INBRANCH) \
17410 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOTINBRANCH))
17413 c_parser_omp_declare_simd (c_parser
*parser
, enum pragma_context context
)
17415 auto_vec
<c_token
> clauses
;
17416 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
17418 c_token
*token
= c_parser_peek_token (parser
);
17419 if (token
->type
== CPP_EOF
)
17421 c_parser_skip_to_pragma_eol (parser
);
17424 clauses
.safe_push (*token
);
17425 c_parser_consume_token (parser
);
17427 clauses
.safe_push (*c_parser_peek_token (parser
));
17428 c_parser_skip_to_pragma_eol (parser
);
17430 while (c_parser_next_token_is (parser
, CPP_PRAGMA
))
17432 if (c_parser_peek_token (parser
)->pragma_kind
17433 != PRAGMA_OMP_DECLARE
17434 || c_parser_peek_2nd_token (parser
)->type
!= CPP_NAME
17435 || strcmp (IDENTIFIER_POINTER
17436 (c_parser_peek_2nd_token (parser
)->value
),
17439 c_parser_error (parser
,
17440 "%<#pragma omp declare simd%> must be followed by "
17441 "function declaration or definition or another "
17442 "%<#pragma omp declare simd%>");
17445 c_parser_consume_pragma (parser
);
17446 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
17448 c_token
*token
= c_parser_peek_token (parser
);
17449 if (token
->type
== CPP_EOF
)
17451 c_parser_skip_to_pragma_eol (parser
);
17454 clauses
.safe_push (*token
);
17455 c_parser_consume_token (parser
);
17457 clauses
.safe_push (*c_parser_peek_token (parser
));
17458 c_parser_skip_to_pragma_eol (parser
);
17461 /* Make sure nothing tries to read past the end of the tokens. */
17463 memset (&eof_token
, 0, sizeof (eof_token
));
17464 eof_token
.type
= CPP_EOF
;
17465 clauses
.safe_push (eof_token
);
17466 clauses
.safe_push (eof_token
);
17470 case pragma_external
:
17471 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
17472 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
)
17474 int ext
= disable_extension_diagnostics ();
17476 c_parser_consume_token (parser
);
17477 while (c_parser_next_token_is (parser
, CPP_KEYWORD
)
17478 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
);
17479 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
17481 restore_extension_diagnostics (ext
);
17484 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
17487 case pragma_struct
:
17489 c_parser_error (parser
, "%<#pragma omp declare simd%> must be followed by "
17490 "function declaration or definition");
17492 case pragma_compound
:
17494 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
17495 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
)
17497 int ext
= disable_extension_diagnostics ();
17499 c_parser_consume_token (parser
);
17500 while (c_parser_next_token_is (parser
, CPP_KEYWORD
)
17501 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
);
17502 if (c_parser_next_tokens_start_declaration (parser
))
17504 c_parser_declaration_or_fndef (parser
, true, true, true, true,
17505 true, NULL
, clauses
);
17506 restore_extension_diagnostics (ext
);
17509 restore_extension_diagnostics (ext
);
17511 else if (c_parser_next_tokens_start_declaration (parser
))
17513 c_parser_declaration_or_fndef (parser
, true, true, true, true, true,
17517 c_parser_error (parser
, "%<#pragma omp declare simd%> must be followed by "
17518 "function declaration or definition");
17521 gcc_unreachable ();
17525 /* Finalize #pragma omp declare simd clauses after FNDECL has been parsed,
17526 and put that into "omp declare simd" attribute. */
17529 c_finish_omp_declare_simd (c_parser
*parser
, tree fndecl
, tree parms
,
17530 vec
<c_token
> clauses
)
17533 && (clauses
.exists ()
17534 || lookup_attribute ("simd", DECL_ATTRIBUTES (fndecl
)))
17535 && !vec_safe_is_empty (parser
->cilk_simd_fn_tokens
))
17537 error ("%<#pragma omp declare simd%> or %<simd%> attribute cannot be "
17538 "used in the same function marked as a Cilk Plus SIMD-enabled "
17540 vec_free (parser
->cilk_simd_fn_tokens
);
17544 /* Normally first token is CPP_NAME "simd". CPP_EOF there indicates
17545 error has been reported and CPP_PRAGMA that c_finish_omp_declare_simd
17546 has already processed the tokens. */
17547 if (clauses
.exists () && clauses
[0].type
== CPP_EOF
)
17549 if (fndecl
== NULL_TREE
|| TREE_CODE (fndecl
) != FUNCTION_DECL
)
17551 error ("%<#pragma omp declare simd%> not immediately followed by "
17552 "a function declaration or definition");
17553 clauses
[0].type
= CPP_EOF
;
17556 if (clauses
.exists () && clauses
[0].type
!= CPP_NAME
)
17558 error_at (DECL_SOURCE_LOCATION (fndecl
),
17559 "%<#pragma omp declare simd%> not immediately followed by "
17560 "a single function declaration or definition");
17561 clauses
[0].type
= CPP_EOF
;
17565 if (parms
== NULL_TREE
)
17566 parms
= DECL_ARGUMENTS (fndecl
);
17568 unsigned int tokens_avail
= parser
->tokens_avail
;
17569 gcc_assert (parser
->tokens
== &parser
->tokens_buf
[0]);
17570 bool is_cilkplus_cilk_simd_fn
= false;
17572 if (flag_cilkplus
&& !vec_safe_is_empty (parser
->cilk_simd_fn_tokens
))
17574 parser
->tokens
= parser
->cilk_simd_fn_tokens
->address ();
17575 parser
->tokens_avail
= vec_safe_length (parser
->cilk_simd_fn_tokens
);
17576 is_cilkplus_cilk_simd_fn
= true;
17578 if (lookup_attribute ("simd", DECL_ATTRIBUTES (fndecl
)) != NULL
)
17580 error_at (DECL_SOURCE_LOCATION (fndecl
),
17581 "%<__simd__%> attribute cannot be used in the same "
17582 "function marked as a Cilk Plus SIMD-enabled function");
17583 vec_free (parser
->cilk_simd_fn_tokens
);
17590 parser
->tokens
= clauses
.address ();
17591 parser
->tokens_avail
= clauses
.length ();
17594 /* c_parser_omp_declare_simd pushed 2 extra CPP_EOF tokens at the end. */
17595 while (parser
->tokens_avail
> 3)
17597 c_token
*token
= c_parser_peek_token (parser
);
17598 if (!is_cilkplus_cilk_simd_fn
)
17599 gcc_assert (token
->type
== CPP_NAME
17600 && strcmp (IDENTIFIER_POINTER (token
->value
), "simd") == 0);
17602 gcc_assert (token
->type
== CPP_NAME
17603 && is_cilkplus_vector_p (token
->value
));
17604 c_parser_consume_token (parser
);
17605 parser
->in_pragma
= true;
17607 tree c
= NULL_TREE
;
17608 if (is_cilkplus_cilk_simd_fn
)
17609 c
= c_parser_omp_all_clauses (parser
, CILK_SIMD_FN_CLAUSE_MASK
,
17610 "SIMD-enabled functions attribute");
17612 c
= c_parser_omp_all_clauses (parser
, OMP_DECLARE_SIMD_CLAUSE_MASK
,
17613 "#pragma omp declare simd");
17614 c
= c_omp_declare_simd_clauses_to_numbers (parms
, c
);
17615 if (c
!= NULL_TREE
)
17616 c
= tree_cons (NULL_TREE
, c
, NULL_TREE
);
17617 if (is_cilkplus_cilk_simd_fn
)
17619 tree k
= build_tree_list (get_identifier ("cilk simd function"),
17621 TREE_CHAIN (k
) = DECL_ATTRIBUTES (fndecl
);
17622 DECL_ATTRIBUTES (fndecl
) = k
;
17624 c
= build_tree_list (get_identifier ("omp declare simd"), c
);
17625 TREE_CHAIN (c
) = DECL_ATTRIBUTES (fndecl
);
17626 DECL_ATTRIBUTES (fndecl
) = c
;
17629 parser
->tokens
= &parser
->tokens_buf
[0];
17630 parser
->tokens_avail
= tokens_avail
;
17631 if (clauses
.exists ())
17632 clauses
[0].type
= CPP_PRAGMA
;
17634 if (!vec_safe_is_empty (parser
->cilk_simd_fn_tokens
))
17635 vec_free (parser
->cilk_simd_fn_tokens
);
17640 # pragma omp declare target new-line
17641 declarations and definitions
17642 # pragma omp end declare target new-line
17645 # pragma omp declare target ( extended-list ) new-line
17647 # pragma omp declare target declare-target-clauses[seq] new-line */
17649 #define OMP_DECLARE_TARGET_CLAUSE_MASK \
17650 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
17651 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK))
17654 c_parser_omp_declare_target (c_parser
*parser
)
17656 location_t loc
= c_parser_peek_token (parser
)->location
;
17657 tree clauses
= NULL_TREE
;
17658 if (c_parser_next_token_is (parser
, CPP_NAME
))
17659 clauses
= c_parser_omp_all_clauses (parser
, OMP_DECLARE_TARGET_CLAUSE_MASK
,
17660 "#pragma omp declare target");
17661 else if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
17663 clauses
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_TO_DECLARE
,
17665 clauses
= c_finish_omp_clauses (clauses
, C_ORT_OMP
);
17666 c_parser_skip_to_pragma_eol (parser
);
17670 c_parser_skip_to_pragma_eol (parser
);
17671 current_omp_declare_target_attribute
++;
17674 if (current_omp_declare_target_attribute
)
17675 error_at (loc
, "%<#pragma omp declare target%> with clauses in between "
17676 "%<#pragma omp declare target%> without clauses and "
17677 "%<#pragma omp end declare target%>");
17678 for (tree c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
17680 tree t
= OMP_CLAUSE_DECL (c
), id
;
17681 tree at1
= lookup_attribute ("omp declare target", DECL_ATTRIBUTES (t
));
17682 tree at2
= lookup_attribute ("omp declare target link",
17683 DECL_ATTRIBUTES (t
));
17684 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LINK
)
17686 id
= get_identifier ("omp declare target link");
17687 std::swap (at1
, at2
);
17690 id
= get_identifier ("omp declare target");
17693 error_at (OMP_CLAUSE_LOCATION (c
),
17694 "%qD specified both in declare target %<link%> and %<to%>"
17700 DECL_ATTRIBUTES (t
) = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (t
));
17701 if (TREE_CODE (t
) != FUNCTION_DECL
&& !is_global_var (t
))
17704 symtab_node
*node
= symtab_node::get (t
);
17707 node
->offloadable
= 1;
17708 if (ENABLE_OFFLOADING
)
17710 g
->have_offload
= true;
17711 if (is_a
<varpool_node
*> (node
))
17712 vec_safe_push (offload_vars
, t
);
17720 c_parser_omp_end_declare_target (c_parser
*parser
)
17722 location_t loc
= c_parser_peek_token (parser
)->location
;
17723 c_parser_consume_pragma (parser
);
17724 if (c_parser_next_token_is (parser
, CPP_NAME
)
17725 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
),
17728 c_parser_consume_token (parser
);
17729 if (c_parser_next_token_is (parser
, CPP_NAME
)
17730 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
),
17732 c_parser_consume_token (parser
);
17735 c_parser_error (parser
, "expected %<target%>");
17736 c_parser_skip_to_pragma_eol (parser
);
17742 c_parser_error (parser
, "expected %<declare%>");
17743 c_parser_skip_to_pragma_eol (parser
);
17746 c_parser_skip_to_pragma_eol (parser
);
17747 if (!current_omp_declare_target_attribute
)
17748 error_at (loc
, "%<#pragma omp end declare target%> without corresponding "
17749 "%<#pragma omp declare target%>");
17751 current_omp_declare_target_attribute
--;
17756 #pragma omp declare reduction (reduction-id : typename-list : expression) \
17757 initializer-clause[opt] new-line
17759 initializer-clause:
17760 initializer (omp_priv = initializer)
17761 initializer (function-name (argument-list)) */
17764 c_parser_omp_declare_reduction (c_parser
*parser
, enum pragma_context context
)
17766 unsigned int tokens_avail
= 0, i
;
17767 vec
<tree
> types
= vNULL
;
17768 vec
<c_token
> clauses
= vNULL
;
17769 enum tree_code reduc_code
= ERROR_MARK
;
17770 tree reduc_id
= NULL_TREE
;
17772 location_t rloc
= c_parser_peek_token (parser
)->location
;
17774 if (context
== pragma_struct
|| context
== pragma_param
)
17776 error ("%<#pragma omp declare reduction%> not at file or block scope");
17780 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
17783 switch (c_parser_peek_token (parser
)->type
)
17786 reduc_code
= PLUS_EXPR
;
17789 reduc_code
= MULT_EXPR
;
17792 reduc_code
= MINUS_EXPR
;
17795 reduc_code
= BIT_AND_EXPR
;
17798 reduc_code
= BIT_XOR_EXPR
;
17801 reduc_code
= BIT_IOR_EXPR
;
17804 reduc_code
= TRUTH_ANDIF_EXPR
;
17807 reduc_code
= TRUTH_ORIF_EXPR
;
17811 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
17812 if (strcmp (p
, "min") == 0)
17814 reduc_code
= MIN_EXPR
;
17817 if (strcmp (p
, "max") == 0)
17819 reduc_code
= MAX_EXPR
;
17822 reduc_id
= c_parser_peek_token (parser
)->value
;
17825 c_parser_error (parser
,
17826 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
17827 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
17831 tree orig_reduc_id
, reduc_decl
;
17832 orig_reduc_id
= reduc_id
;
17833 reduc_id
= c_omp_reduction_id (reduc_code
, reduc_id
);
17834 reduc_decl
= c_omp_reduction_decl (reduc_id
);
17835 c_parser_consume_token (parser
);
17837 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
17842 location_t loc
= c_parser_peek_token (parser
)->location
;
17843 struct c_type_name
*ctype
= c_parser_type_name (parser
);
17846 type
= groktypename (ctype
, NULL
, NULL
);
17847 if (type
== error_mark_node
)
17849 else if ((INTEGRAL_TYPE_P (type
)
17850 || TREE_CODE (type
) == REAL_TYPE
17851 || TREE_CODE (type
) == COMPLEX_TYPE
)
17852 && orig_reduc_id
== NULL_TREE
)
17853 error_at (loc
, "predeclared arithmetic type in "
17854 "%<#pragma omp declare reduction%>");
17855 else if (TREE_CODE (type
) == FUNCTION_TYPE
17856 || TREE_CODE (type
) == ARRAY_TYPE
)
17857 error_at (loc
, "function or array type in "
17858 "%<#pragma omp declare reduction%>");
17859 else if (TYPE_ATOMIC (type
))
17860 error_at (loc
, "%<_Atomic%> qualified type in "
17861 "%<#pragma omp declare reduction%>");
17862 else if (TYPE_QUALS_NO_ADDR_SPACE (type
))
17863 error_at (loc
, "const, volatile or restrict qualified type in "
17864 "%<#pragma omp declare reduction%>");
17868 for (t
= DECL_INITIAL (reduc_decl
); t
; t
= TREE_CHAIN (t
))
17869 if (comptypes (TREE_PURPOSE (t
), type
))
17871 error_at (loc
, "redeclaration of %qs "
17872 "%<#pragma omp declare reduction%> for "
17874 IDENTIFIER_POINTER (reduc_id
)
17875 + sizeof ("omp declare reduction ") - 1,
17878 = DECL_SOURCE_LOCATION (TREE_VEC_ELT (TREE_VALUE (t
),
17880 error_at (ploc
, "previous %<#pragma omp declare "
17884 if (t
== NULL_TREE
)
17885 types
.safe_push (type
);
17887 if (c_parser_next_token_is (parser
, CPP_COMMA
))
17888 c_parser_consume_token (parser
);
17896 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>")
17897 || types
.is_empty ())
17900 clauses
.release ();
17904 c_token
*token
= c_parser_peek_token (parser
);
17905 if (token
->type
== CPP_EOF
|| token
->type
== CPP_PRAGMA_EOL
)
17907 c_parser_consume_token (parser
);
17909 c_parser_skip_to_pragma_eol (parser
);
17913 if (types
.length () > 1)
17915 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
17917 c_token
*token
= c_parser_peek_token (parser
);
17918 if (token
->type
== CPP_EOF
)
17920 clauses
.safe_push (*token
);
17921 c_parser_consume_token (parser
);
17923 clauses
.safe_push (*c_parser_peek_token (parser
));
17924 c_parser_skip_to_pragma_eol (parser
);
17926 /* Make sure nothing tries to read past the end of the tokens. */
17928 memset (&eof_token
, 0, sizeof (eof_token
));
17929 eof_token
.type
= CPP_EOF
;
17930 clauses
.safe_push (eof_token
);
17931 clauses
.safe_push (eof_token
);
17934 int errs
= errorcount
;
17935 FOR_EACH_VEC_ELT (types
, i
, type
)
17937 tokens_avail
= parser
->tokens_avail
;
17938 gcc_assert (parser
->tokens
== &parser
->tokens_buf
[0]);
17939 if (!clauses
.is_empty ())
17941 parser
->tokens
= clauses
.address ();
17942 parser
->tokens_avail
= clauses
.length ();
17943 parser
->in_pragma
= true;
17946 bool nested
= current_function_decl
!= NULL_TREE
;
17948 c_push_function_context ();
17949 tree fndecl
= build_decl (BUILTINS_LOCATION
, FUNCTION_DECL
,
17950 reduc_id
, default_function_type
);
17951 current_function_decl
= fndecl
;
17952 allocate_struct_function (fndecl
, true);
17954 tree stmt
= push_stmt_list ();
17955 /* Intentionally BUILTINS_LOCATION, so that -Wshadow doesn't
17956 warn about these. */
17957 tree omp_out
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
17958 get_identifier ("omp_out"), type
);
17959 DECL_ARTIFICIAL (omp_out
) = 1;
17960 DECL_CONTEXT (omp_out
) = fndecl
;
17961 pushdecl (omp_out
);
17962 tree omp_in
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
17963 get_identifier ("omp_in"), type
);
17964 DECL_ARTIFICIAL (omp_in
) = 1;
17965 DECL_CONTEXT (omp_in
) = fndecl
;
17967 struct c_expr combiner
= c_parser_expression (parser
);
17968 struct c_expr initializer
;
17969 tree omp_priv
= NULL_TREE
, omp_orig
= NULL_TREE
;
17971 initializer
.value
= error_mark_node
;
17972 if (!c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
17974 else if (c_parser_next_token_is (parser
, CPP_NAME
)
17975 && strcmp (IDENTIFIER_POINTER
17976 (c_parser_peek_token (parser
)->value
),
17977 "initializer") == 0)
17979 c_parser_consume_token (parser
);
17982 omp_priv
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
17983 get_identifier ("omp_priv"), type
);
17984 DECL_ARTIFICIAL (omp_priv
) = 1;
17985 DECL_INITIAL (omp_priv
) = error_mark_node
;
17986 DECL_CONTEXT (omp_priv
) = fndecl
;
17987 pushdecl (omp_priv
);
17988 omp_orig
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
17989 get_identifier ("omp_orig"), type
);
17990 DECL_ARTIFICIAL (omp_orig
) = 1;
17991 DECL_CONTEXT (omp_orig
) = fndecl
;
17992 pushdecl (omp_orig
);
17993 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
17995 else if (!c_parser_next_token_is (parser
, CPP_NAME
))
17997 c_parser_error (parser
, "expected %<omp_priv%> or "
18001 else if (strcmp (IDENTIFIER_POINTER
18002 (c_parser_peek_token (parser
)->value
),
18005 if (c_parser_peek_2nd_token (parser
)->type
!= CPP_OPEN_PAREN
18006 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
18008 c_parser_error (parser
, "expected function-name %<(%>");
18012 initializer
= c_parser_postfix_expression (parser
);
18013 if (initializer
.value
18014 && TREE_CODE (initializer
.value
) == CALL_EXPR
)
18017 tree c
= initializer
.value
;
18018 for (j
= 0; j
< call_expr_nargs (c
); j
++)
18020 tree a
= CALL_EXPR_ARG (c
, j
);
18022 if (TREE_CODE (a
) == ADDR_EXPR
18023 && TREE_OPERAND (a
, 0) == omp_priv
)
18026 if (j
== call_expr_nargs (c
))
18027 error ("one of the initializer call arguments should be "
18033 c_parser_consume_token (parser
);
18034 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
18038 tree st
= push_stmt_list ();
18039 location_t loc
= c_parser_peek_token (parser
)->location
;
18040 rich_location
richloc (line_table
, loc
);
18041 start_init (omp_priv
, NULL_TREE
, 0, &richloc
);
18042 struct c_expr init
= c_parser_initializer (parser
);
18044 finish_decl (omp_priv
, loc
, init
.value
,
18045 init
.original_type
, NULL_TREE
);
18046 pop_stmt_list (st
);
18050 && !c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
18056 c_parser_skip_to_pragma_eol (parser
);
18058 tree t
= tree_cons (type
, make_tree_vec (omp_priv
? 6 : 3),
18059 DECL_INITIAL (reduc_decl
));
18060 DECL_INITIAL (reduc_decl
) = t
;
18061 DECL_SOURCE_LOCATION (omp_out
) = rloc
;
18062 TREE_VEC_ELT (TREE_VALUE (t
), 0) = omp_out
;
18063 TREE_VEC_ELT (TREE_VALUE (t
), 1) = omp_in
;
18064 TREE_VEC_ELT (TREE_VALUE (t
), 2) = combiner
.value
;
18065 walk_tree (&combiner
.value
, c_check_omp_declare_reduction_r
,
18066 &TREE_VEC_ELT (TREE_VALUE (t
), 0), NULL
);
18069 DECL_SOURCE_LOCATION (omp_priv
) = rloc
;
18070 TREE_VEC_ELT (TREE_VALUE (t
), 3) = omp_priv
;
18071 TREE_VEC_ELT (TREE_VALUE (t
), 4) = omp_orig
;
18072 TREE_VEC_ELT (TREE_VALUE (t
), 5) = initializer
.value
;
18073 walk_tree (&initializer
.value
, c_check_omp_declare_reduction_r
,
18074 &TREE_VEC_ELT (TREE_VALUE (t
), 3), NULL
);
18075 walk_tree (&DECL_INITIAL (omp_priv
),
18076 c_check_omp_declare_reduction_r
,
18077 &TREE_VEC_ELT (TREE_VALUE (t
), 3), NULL
);
18081 pop_stmt_list (stmt
);
18083 if (cfun
->language
!= NULL
)
18085 ggc_free (cfun
->language
);
18086 cfun
->language
= NULL
;
18089 current_function_decl
= NULL_TREE
;
18091 c_pop_function_context ();
18093 if (!clauses
.is_empty ())
18095 parser
->tokens
= &parser
->tokens_buf
[0];
18096 parser
->tokens_avail
= tokens_avail
;
18100 if (errs
!= errorcount
)
18104 clauses
.release ();
18110 #pragma omp declare simd declare-simd-clauses[optseq] new-line
18111 #pragma omp declare reduction (reduction-id : typename-list : expression) \
18112 initializer-clause[opt] new-line
18113 #pragma omp declare target new-line */
18116 c_parser_omp_declare (c_parser
*parser
, enum pragma_context context
)
18118 c_parser_consume_pragma (parser
);
18119 if (c_parser_next_token_is (parser
, CPP_NAME
))
18121 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18122 if (strcmp (p
, "simd") == 0)
18124 /* c_parser_consume_token (parser); done in
18125 c_parser_omp_declare_simd. */
18126 c_parser_omp_declare_simd (parser
, context
);
18129 if (strcmp (p
, "reduction") == 0)
18131 c_parser_consume_token (parser
);
18132 c_parser_omp_declare_reduction (parser
, context
);
18135 if (!flag_openmp
) /* flag_openmp_simd */
18137 c_parser_skip_to_pragma_eol (parser
, false);
18140 if (strcmp (p
, "target") == 0)
18142 c_parser_consume_token (parser
);
18143 c_parser_omp_declare_target (parser
);
18148 c_parser_error (parser
, "expected %<simd%> or %<reduction%> "
18150 c_parser_skip_to_pragma_eol (parser
);
18154 #pragma omp taskloop taskloop-clause[optseq] new-line
18157 #pragma omp taskloop simd taskloop-simd-clause[optseq] new-line
18160 #define OMP_TASKLOOP_CLAUSE_MASK \
18161 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
18162 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
18163 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
18164 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
18165 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
18166 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_GRAINSIZE) \
18167 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TASKS) \
18168 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
18169 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
18170 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
18171 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
18172 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
18173 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP) \
18174 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY))
18177 c_parser_omp_taskloop (location_t loc
, c_parser
*parser
,
18178 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
18181 tree clauses
, block
, ret
;
18183 strcat (p_name
, " taskloop");
18184 mask
|= OMP_TASKLOOP_CLAUSE_MASK
;
18186 if (c_parser_next_token_is (parser
, CPP_NAME
))
18188 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18190 if (strcmp (p
, "simd") == 0)
18192 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
18193 if (cclauses
== NULL
)
18194 cclauses
= cclauses_buf
;
18195 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_REDUCTION
);
18196 c_parser_consume_token (parser
);
18197 if (!flag_openmp
) /* flag_openmp_simd */
18198 return c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
,
18200 block
= c_begin_compound_stmt (true);
18201 ret
= c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
18202 block
= c_end_compound_stmt (loc
, block
, true);
18205 ret
= make_node (OMP_TASKLOOP
);
18206 TREE_TYPE (ret
) = void_type_node
;
18207 OMP_FOR_BODY (ret
) = block
;
18208 OMP_FOR_CLAUSES (ret
) = cclauses
[C_OMP_CLAUSE_SPLIT_TASKLOOP
];
18209 SET_EXPR_LOCATION (ret
, loc
);
18214 if (!flag_openmp
) /* flag_openmp_simd */
18216 c_parser_skip_to_pragma_eol (parser
, false);
18220 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
18223 omp_split_clauses (loc
, OMP_TASKLOOP
, mask
, clauses
, cclauses
);
18224 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_TASKLOOP
];
18227 block
= c_begin_compound_stmt (true);
18228 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_TASKLOOP
, clauses
, NULL
, if_p
);
18229 block
= c_end_compound_stmt (loc
, block
, true);
18235 /* Main entry point to parsing most OpenMP pragmas. */
18238 c_parser_omp_construct (c_parser
*parser
, bool *if_p
)
18240 enum pragma_kind p_kind
;
18243 char p_name
[sizeof "#pragma omp teams distribute parallel for simd"];
18244 omp_clause_mask
mask (0);
18246 loc
= c_parser_peek_token (parser
)->location
;
18247 p_kind
= c_parser_peek_token (parser
)->pragma_kind
;
18248 c_parser_consume_pragma (parser
);
18252 case PRAGMA_OACC_ATOMIC
:
18253 c_parser_omp_atomic (loc
, parser
);
18255 case PRAGMA_OACC_CACHE
:
18256 strcpy (p_name
, "#pragma acc");
18257 stmt
= c_parser_oacc_cache (loc
, parser
);
18259 case PRAGMA_OACC_DATA
:
18260 stmt
= c_parser_oacc_data (loc
, parser
, if_p
);
18262 case PRAGMA_OACC_HOST_DATA
:
18263 stmt
= c_parser_oacc_host_data (loc
, parser
, if_p
);
18265 case PRAGMA_OACC_KERNELS
:
18266 case PRAGMA_OACC_PARALLEL
:
18267 strcpy (p_name
, "#pragma acc");
18268 stmt
= c_parser_oacc_kernels_parallel (loc
, parser
, p_kind
, p_name
,
18271 case PRAGMA_OACC_LOOP
:
18272 strcpy (p_name
, "#pragma acc");
18273 stmt
= c_parser_oacc_loop (loc
, parser
, p_name
, mask
, NULL
, if_p
);
18275 case PRAGMA_OACC_WAIT
:
18276 strcpy (p_name
, "#pragma wait");
18277 stmt
= c_parser_oacc_wait (loc
, parser
, p_name
);
18279 case PRAGMA_OMP_ATOMIC
:
18280 c_parser_omp_atomic (loc
, parser
);
18282 case PRAGMA_OMP_CRITICAL
:
18283 stmt
= c_parser_omp_critical (loc
, parser
, if_p
);
18285 case PRAGMA_OMP_DISTRIBUTE
:
18286 strcpy (p_name
, "#pragma omp");
18287 stmt
= c_parser_omp_distribute (loc
, parser
, p_name
, mask
, NULL
, if_p
);
18289 case PRAGMA_OMP_FOR
:
18290 strcpy (p_name
, "#pragma omp");
18291 stmt
= c_parser_omp_for (loc
, parser
, p_name
, mask
, NULL
, if_p
);
18293 case PRAGMA_OMP_MASTER
:
18294 stmt
= c_parser_omp_master (loc
, parser
, if_p
);
18296 case PRAGMA_OMP_PARALLEL
:
18297 strcpy (p_name
, "#pragma omp");
18298 stmt
= c_parser_omp_parallel (loc
, parser
, p_name
, mask
, NULL
, if_p
);
18300 case PRAGMA_OMP_SECTIONS
:
18301 strcpy (p_name
, "#pragma omp");
18302 stmt
= c_parser_omp_sections (loc
, parser
, p_name
, mask
, NULL
);
18304 case PRAGMA_OMP_SIMD
:
18305 strcpy (p_name
, "#pragma omp");
18306 stmt
= c_parser_omp_simd (loc
, parser
, p_name
, mask
, NULL
, if_p
);
18308 case PRAGMA_OMP_SINGLE
:
18309 stmt
= c_parser_omp_single (loc
, parser
, if_p
);
18311 case PRAGMA_OMP_TASK
:
18312 stmt
= c_parser_omp_task (loc
, parser
, if_p
);
18314 case PRAGMA_OMP_TASKGROUP
:
18315 stmt
= c_parser_omp_taskgroup (parser
, if_p
);
18317 case PRAGMA_OMP_TASKLOOP
:
18318 strcpy (p_name
, "#pragma omp");
18319 stmt
= c_parser_omp_taskloop (loc
, parser
, p_name
, mask
, NULL
, if_p
);
18321 case PRAGMA_OMP_TEAMS
:
18322 strcpy (p_name
, "#pragma omp");
18323 stmt
= c_parser_omp_teams (loc
, parser
, p_name
, mask
, NULL
, if_p
);
18326 gcc_unreachable ();
18330 gcc_assert (EXPR_LOCATION (stmt
) != UNKNOWN_LOCATION
);
18335 # pragma omp threadprivate (variable-list) */
18338 c_parser_omp_threadprivate (c_parser
*parser
)
18343 c_parser_consume_pragma (parser
);
18344 loc
= c_parser_peek_token (parser
)->location
;
18345 vars
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ERROR
, NULL
);
18347 /* Mark every variable in VARS to be assigned thread local storage. */
18348 for (t
= vars
; t
; t
= TREE_CHAIN (t
))
18350 tree v
= TREE_PURPOSE (t
);
18352 /* FIXME diagnostics: Ideally we should keep individual
18353 locations for all the variables in the var list to make the
18354 following errors more precise. Perhaps
18355 c_parser_omp_var_list_parens() should construct a list of
18356 locations to go along with the var list. */
18358 /* If V had already been marked threadprivate, it doesn't matter
18359 whether it had been used prior to this point. */
18361 error_at (loc
, "%qD is not a variable", v
);
18362 else if (TREE_USED (v
) && !C_DECL_THREADPRIVATE_P (v
))
18363 error_at (loc
, "%qE declared %<threadprivate%> after first use", v
);
18364 else if (! is_global_var (v
))
18365 error_at (loc
, "automatic variable %qE cannot be %<threadprivate%>", v
);
18366 else if (TREE_TYPE (v
) == error_mark_node
)
18368 else if (! COMPLETE_TYPE_P (TREE_TYPE (v
)))
18369 error_at (loc
, "%<threadprivate%> %qE has incomplete type", v
);
18372 if (! DECL_THREAD_LOCAL_P (v
))
18374 set_decl_tls_model (v
, decl_default_tls_model (v
));
18375 /* If rtl has been already set for this var, call
18376 make_decl_rtl once again, so that encode_section_info
18377 has a chance to look at the new decl flags. */
18378 if (DECL_RTL_SET_P (v
))
18381 C_DECL_THREADPRIVATE_P (v
) = 1;
18385 c_parser_skip_to_pragma_eol (parser
);
18388 /* Cilk Plus <#pragma simd> parsing routines. */
18390 /* Helper function for c_parser_pragma. Perform some sanity checking
18391 for <#pragma simd> constructs. Returns FALSE if there was a
18395 c_parser_cilk_verify_simd (c_parser
*parser
,
18396 enum pragma_context context
)
18398 if (!flag_cilkplus
)
18400 warning (0, "pragma simd ignored because -fcilkplus is not enabled");
18401 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
18404 if (context
== pragma_external
)
18406 c_parser_error (parser
,"pragma simd must be inside a function");
18407 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
18414 This function is shared by SIMD-enabled functions and #pragma simd.
18415 If IS_SIMD_FN is true then it is parsing a SIMD-enabled function and
18416 CLAUSES is unused. The main purpose of this function is to parse a
18417 vectorlength attribute or clause and check for parse errors.
18418 When IS_SIMD_FN is true then the function is merely caching the tokens
18419 in PARSER->CILK_SIMD_FN_TOKENS. If errors are found then the token
18420 cache is cleared since there is no reason to continue.
18422 vectorlength ( constant-expression ) */
18425 c_parser_cilk_clause_vectorlength (c_parser
*parser
, tree clauses
,
18429 check_no_duplicate_clause (clauses
, OMP_CLAUSE_SIMDLEN
, "vectorlength");
18431 /* The vectorlength clause behaves exactly like OpenMP's safelen
18432 clause. Represent it in OpenMP terms. */
18433 check_no_duplicate_clause (clauses
, OMP_CLAUSE_SAFELEN
, "vectorlength");
18435 matching_parens parens
;
18436 if (!parens
.require_open (parser
))
18439 location_t loc
= c_parser_peek_token (parser
)->location
;
18440 tree expr
= c_parser_expr_no_commas (parser
, NULL
).value
;
18441 expr
= c_fully_fold (expr
, false, NULL
);
18443 /* If expr is an error_mark_node then the above function would have
18444 emitted an error. No reason to do it twice. */
18445 if (expr
== error_mark_node
)
18447 else if (!TREE_TYPE (expr
)
18448 || !TREE_CONSTANT (expr
)
18449 || !INTEGRAL_TYPE_P (TREE_TYPE (expr
)))
18451 error_at (loc
, "vectorlength must be an integer constant");
18452 else if (wi::exact_log2 (wi::to_wide (expr
)) == -1)
18453 error_at (loc
, "vectorlength must be a power of 2");
18458 tree u
= build_omp_clause (loc
, OMP_CLAUSE_SIMDLEN
);
18459 OMP_CLAUSE_SIMDLEN_EXPR (u
) = expr
;
18460 OMP_CLAUSE_CHAIN (u
) = clauses
;
18465 tree u
= build_omp_clause (loc
, OMP_CLAUSE_SAFELEN
);
18466 OMP_CLAUSE_SAFELEN_EXPR (u
) = expr
;
18467 OMP_CLAUSE_CHAIN (u
) = clauses
;
18472 parens
.require_close (parser
);
18478 linear ( simd-linear-variable-list )
18480 simd-linear-variable-list:
18481 simd-linear-variable
18482 simd-linear-variable-list , simd-linear-variable
18484 simd-linear-variable:
18486 id-expression : simd-linear-step
18489 conditional-expression */
18492 c_parser_cilk_clause_linear (c_parser
*parser
, tree clauses
)
18494 matching_parens parens
;
18495 if (!parens
.require_open (parser
))
18498 location_t loc
= c_parser_peek_token (parser
)->location
;
18500 if (c_parser_next_token_is_not (parser
, CPP_NAME
)
18501 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
18502 c_parser_error (parser
, "expected identifier");
18504 while (c_parser_next_token_is (parser
, CPP_NAME
)
18505 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
)
18507 tree var
= lookup_name (c_parser_peek_token (parser
)->value
);
18511 undeclared_variable (c_parser_peek_token (parser
)->location
,
18512 c_parser_peek_token (parser
)->value
);
18513 c_parser_consume_token (parser
);
18515 else if (var
== error_mark_node
)
18516 c_parser_consume_token (parser
);
18519 tree step
= integer_one_node
;
18521 /* Parse the linear step if present. */
18522 if (c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
18524 c_parser_consume_token (parser
);
18525 c_parser_consume_token (parser
);
18527 tree expr
= c_parser_expr_no_commas (parser
, NULL
).value
;
18528 expr
= c_fully_fold (expr
, false, NULL
);
18530 if (TREE_TYPE (expr
)
18531 && INTEGRAL_TYPE_P (TREE_TYPE (expr
))
18532 && (TREE_CONSTANT (expr
)
18536 c_parser_error (parser
,
18537 "step size must be an integer constant "
18538 "expression or an integer variable");
18541 c_parser_consume_token (parser
);
18543 /* Use OMP_CLAUSE_LINEAR, which has the same semantics. */
18544 tree u
= build_omp_clause (loc
, OMP_CLAUSE_LINEAR
);
18545 OMP_CLAUSE_DECL (u
) = var
;
18546 OMP_CLAUSE_LINEAR_STEP (u
) = step
;
18547 OMP_CLAUSE_CHAIN (u
) = clauses
;
18551 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
18554 c_parser_consume_token (parser
);
18557 parens
.skip_until_found_close (parser
);
18562 /* Returns the name of the next clause. If the clause is not
18563 recognized SIMD_OMP_CLAUSE_NONE is returned and the next token is
18564 not consumed. Otherwise, the appropriate pragma_simd_clause is
18565 returned and the token is consumed. */
18567 static pragma_omp_clause
18568 c_parser_cilk_clause_name (c_parser
*parser
)
18570 pragma_omp_clause result
;
18571 c_token
*token
= c_parser_peek_token (parser
);
18573 if (!token
->value
|| token
->type
!= CPP_NAME
)
18574 return PRAGMA_CILK_CLAUSE_NONE
;
18576 const char *p
= IDENTIFIER_POINTER (token
->value
);
18578 if (!strcmp (p
, "vectorlength"))
18579 result
= PRAGMA_CILK_CLAUSE_VECTORLENGTH
;
18580 else if (!strcmp (p
, "linear"))
18581 result
= PRAGMA_CILK_CLAUSE_LINEAR
;
18582 else if (!strcmp (p
, "private"))
18583 result
= PRAGMA_CILK_CLAUSE_PRIVATE
;
18584 else if (!strcmp (p
, "firstprivate"))
18585 result
= PRAGMA_CILK_CLAUSE_FIRSTPRIVATE
;
18586 else if (!strcmp (p
, "lastprivate"))
18587 result
= PRAGMA_CILK_CLAUSE_LASTPRIVATE
;
18588 else if (!strcmp (p
, "reduction"))
18589 result
= PRAGMA_CILK_CLAUSE_REDUCTION
;
18591 return PRAGMA_CILK_CLAUSE_NONE
;
18593 c_parser_consume_token (parser
);
18597 /* Parse all #<pragma simd> clauses. Return the list of clauses
18601 c_parser_cilk_all_clauses (c_parser
*parser
)
18603 tree clauses
= NULL
;
18605 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
18607 pragma_omp_clause c_kind
;
18609 c_kind
= c_parser_cilk_clause_name (parser
);
18613 case PRAGMA_CILK_CLAUSE_VECTORLENGTH
:
18614 clauses
= c_parser_cilk_clause_vectorlength (parser
, clauses
, false);
18616 case PRAGMA_CILK_CLAUSE_LINEAR
:
18617 clauses
= c_parser_cilk_clause_linear (parser
, clauses
);
18619 case PRAGMA_CILK_CLAUSE_PRIVATE
:
18620 /* Use the OpenMP counterpart. */
18621 clauses
= c_parser_omp_clause_private (parser
, clauses
);
18623 case PRAGMA_CILK_CLAUSE_FIRSTPRIVATE
:
18624 /* Use the OpenMP counterpart. */
18625 clauses
= c_parser_omp_clause_firstprivate (parser
, clauses
);
18627 case PRAGMA_CILK_CLAUSE_LASTPRIVATE
:
18628 /* Use the OpenMP counterpart. */
18629 clauses
= c_parser_omp_clause_lastprivate (parser
, clauses
);
18631 case PRAGMA_CILK_CLAUSE_REDUCTION
:
18632 /* Use the OpenMP counterpart. */
18633 clauses
= c_parser_omp_clause_reduction (parser
, clauses
);
18636 c_parser_error (parser
, "expected %<#pragma simd%> clause");
18642 c_parser_skip_to_pragma_eol (parser
);
18643 return c_finish_omp_clauses (clauses
, C_ORT_CILK
);
18646 /* This function helps parse the grainsize pragma for a _Cilk_for statement.
18647 Here is the correct syntax of this pragma:
18648 #pragma cilk grainsize = <EXP>
18652 c_parser_cilk_grainsize (c_parser
*parser
, bool *if_p
)
18654 extern tree
convert_to_integer (tree
, tree
);
18656 /* consume the 'grainsize' keyword. */
18657 c_parser_consume_pragma (parser
);
18659 if (c_parser_require (parser
, CPP_EQ
, "expected %<=%>") != 0)
18661 struct c_expr g_expr
= c_parser_binary_expression (parser
, NULL
, NULL
);
18662 if (g_expr
.value
== error_mark_node
)
18664 c_parser_skip_to_pragma_eol (parser
);
18667 tree grain
= convert_to_integer (long_integer_type_node
,
18668 c_fully_fold (g_expr
.value
, false,
18670 c_parser_skip_to_pragma_eol (parser
);
18671 c_token
*token
= c_parser_peek_token (parser
);
18672 if (token
&& token
->type
== CPP_KEYWORD
18673 && token
->keyword
== RID_CILK_FOR
)
18675 if (grain
== NULL_TREE
|| grain
== error_mark_node
)
18676 grain
= integer_zero_node
;
18677 c_parser_cilk_for (parser
, grain
, if_p
);
18680 warning (0, "%<#pragma cilk grainsize%> is not followed by "
18684 c_parser_skip_to_pragma_eol (parser
);
18687 /* Main entry point for parsing Cilk Plus <#pragma simd> for loops. */
18690 c_parser_cilk_simd (c_parser
*parser
, bool *if_p
)
18692 tree clauses
= c_parser_cilk_all_clauses (parser
);
18693 tree block
= c_begin_compound_stmt (true);
18694 location_t loc
= c_parser_peek_token (parser
)->location
;
18695 c_parser_omp_for_loop (loc
, parser
, CILK_SIMD
, clauses
, NULL
, if_p
);
18696 block
= c_end_compound_stmt (loc
, block
, true);
18700 /* Create an artificial decl with TYPE and emit initialization of it with
18704 c_get_temp_regvar (tree type
, tree init
)
18706 location_t loc
= EXPR_LOCATION (init
);
18707 tree decl
= build_decl (loc
, VAR_DECL
, NULL_TREE
, type
);
18708 DECL_ARTIFICIAL (decl
) = 1;
18709 DECL_IGNORED_P (decl
) = 1;
18711 tree t
= build2 (INIT_EXPR
, type
, decl
, init
);
18716 /* Main entry point for parsing Cilk Plus _Cilk_for loops.
18717 GRAIN is the grain value passed in through pragma or 0. */
18720 c_parser_cilk_for (c_parser
*parser
, tree grain
, bool *if_p
)
18722 tree clauses
= build_omp_clause (EXPR_LOCATION (grain
), OMP_CLAUSE_SCHEDULE
);
18723 OMP_CLAUSE_SCHEDULE_KIND (clauses
) = OMP_CLAUSE_SCHEDULE_CILKFOR
;
18724 OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (clauses
) = grain
;
18725 clauses
= c_finish_omp_clauses (clauses
, C_ORT_CILK
);
18727 tree block
= c_begin_compound_stmt (true);
18728 tree sb
= push_stmt_list ();
18729 location_t loc
= c_parser_peek_token (parser
)->location
;
18730 tree omp_for
= c_parser_omp_for_loop (loc
, parser
, CILK_FOR
, clauses
, NULL
,
18732 sb
= pop_stmt_list (sb
);
18736 tree omp_par
= make_node (OMP_PARALLEL
);
18737 TREE_TYPE (omp_par
) = void_type_node
;
18738 OMP_PARALLEL_CLAUSES (omp_par
) = NULL_TREE
;
18739 tree bind
= build3 (BIND_EXPR
, void_type_node
, NULL
, NULL
, NULL
);
18740 TREE_SIDE_EFFECTS (bind
) = 1;
18741 BIND_EXPR_BODY (bind
) = sb
;
18742 OMP_PARALLEL_BODY (omp_par
) = bind
;
18743 if (OMP_FOR_PRE_BODY (omp_for
))
18745 add_stmt (OMP_FOR_PRE_BODY (omp_for
));
18746 OMP_FOR_PRE_BODY (omp_for
) = NULL_TREE
;
18748 tree init
= TREE_VEC_ELT (OMP_FOR_INIT (omp_for
), 0);
18749 tree decl
= TREE_OPERAND (init
, 0);
18750 tree cond
= TREE_VEC_ELT (OMP_FOR_COND (omp_for
), 0);
18751 tree incr
= TREE_VEC_ELT (OMP_FOR_INCR (omp_for
), 0);
18752 tree t
= TREE_OPERAND (cond
, 1), c
, clauses
= NULL_TREE
;
18753 if (TREE_CODE (t
) != INTEGER_CST
)
18755 TREE_OPERAND (cond
, 1) = c_get_temp_regvar (TREE_TYPE (t
), t
);
18756 c
= build_omp_clause (input_location
, OMP_CLAUSE_FIRSTPRIVATE
);
18757 OMP_CLAUSE_DECL (c
) = TREE_OPERAND (cond
, 1);
18758 OMP_CLAUSE_CHAIN (c
) = clauses
;
18761 if (TREE_CODE (incr
) == MODIFY_EXPR
)
18763 t
= TREE_OPERAND (TREE_OPERAND (incr
, 1), 1);
18764 if (TREE_CODE (t
) != INTEGER_CST
)
18766 TREE_OPERAND (TREE_OPERAND (incr
, 1), 1)
18767 = c_get_temp_regvar (TREE_TYPE (t
), t
);
18768 c
= build_omp_clause (input_location
, OMP_CLAUSE_FIRSTPRIVATE
);
18769 OMP_CLAUSE_DECL (c
) = TREE_OPERAND (TREE_OPERAND (incr
, 1), 1);
18770 OMP_CLAUSE_CHAIN (c
) = clauses
;
18774 t
= TREE_OPERAND (init
, 1);
18775 if (TREE_CODE (t
) != INTEGER_CST
)
18777 TREE_OPERAND (init
, 1) = c_get_temp_regvar (TREE_TYPE (t
), t
);
18778 c
= build_omp_clause (input_location
, OMP_CLAUSE_FIRSTPRIVATE
);
18779 OMP_CLAUSE_DECL (c
) = TREE_OPERAND (init
, 1);
18780 OMP_CLAUSE_CHAIN (c
) = clauses
;
18783 c
= build_omp_clause (input_location
, OMP_CLAUSE_PRIVATE
);
18784 OMP_CLAUSE_DECL (c
) = decl
;
18785 OMP_CLAUSE_CHAIN (c
) = clauses
;
18787 c
= build_omp_clause (input_location
, OMP_CLAUSE__CILK_FOR_COUNT_
);
18788 OMP_CLAUSE_OPERAND (c
, 0)
18789 = cilk_for_number_of_iterations (omp_for
);
18790 OMP_CLAUSE_CHAIN (c
) = clauses
;
18791 OMP_PARALLEL_CLAUSES (omp_par
) = c_finish_omp_clauses (c
, C_ORT_CILK
);
18792 add_stmt (omp_par
);
18795 block
= c_end_compound_stmt (loc
, block
, true);
18800 /* Parse a transaction attribute (GCC Extension).
18802 transaction-attribute:
18806 The transactional memory language description is written for C++,
18807 and uses the C++0x attribute syntax. For compatibility, allow the
18808 bracket style for transactions in C as well. */
18811 c_parser_transaction_attributes (c_parser
*parser
)
18813 tree attr_name
, attr
= NULL
;
18815 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
18816 return c_parser_attributes (parser
);
18818 if (!c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
))
18820 c_parser_consume_token (parser
);
18821 if (!c_parser_require (parser
, CPP_OPEN_SQUARE
, "expected %<[%>"))
18824 attr_name
= c_parser_attribute_any_word (parser
);
18827 c_parser_consume_token (parser
);
18828 attr
= build_tree_list (attr_name
, NULL_TREE
);
18831 c_parser_error (parser
, "expected identifier");
18833 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
, "expected %<]%>");
18835 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
, "expected %<]%>");
18839 /* Parse a __transaction_atomic or __transaction_relaxed statement
18842 transaction-statement:
18843 __transaction_atomic transaction-attribute[opt] compound-statement
18844 __transaction_relaxed compound-statement
18846 Note that the only valid attribute is: "outer".
18850 c_parser_transaction (c_parser
*parser
, enum rid keyword
)
18852 unsigned int old_in
= parser
->in_transaction
;
18853 unsigned int this_in
= 1, new_in
;
18854 location_t loc
= c_parser_peek_token (parser
)->location
;
18857 gcc_assert ((keyword
== RID_TRANSACTION_ATOMIC
18858 || keyword
== RID_TRANSACTION_RELAXED
)
18859 && c_parser_next_token_is_keyword (parser
, keyword
));
18860 c_parser_consume_token (parser
);
18862 if (keyword
== RID_TRANSACTION_RELAXED
)
18863 this_in
|= TM_STMT_ATTR_RELAXED
;
18866 attrs
= c_parser_transaction_attributes (parser
);
18868 this_in
|= parse_tm_stmt_attr (attrs
, TM_STMT_ATTR_OUTER
);
18871 /* Keep track if we're in the lexical scope of an outer transaction. */
18872 new_in
= this_in
| (old_in
& TM_STMT_ATTR_OUTER
);
18874 parser
->in_transaction
= new_in
;
18875 stmt
= c_parser_compound_statement (parser
);
18876 parser
->in_transaction
= old_in
;
18879 stmt
= c_finish_transaction (loc
, stmt
, this_in
);
18881 error_at (loc
, (keyword
== RID_TRANSACTION_ATOMIC
?
18882 "%<__transaction_atomic%> without transactional memory support enabled"
18883 : "%<__transaction_relaxed %> "
18884 "without transactional memory support enabled"));
18889 /* Parse a __transaction_atomic or __transaction_relaxed expression
18892 transaction-expression:
18893 __transaction_atomic ( expression )
18894 __transaction_relaxed ( expression )
18897 static struct c_expr
18898 c_parser_transaction_expression (c_parser
*parser
, enum rid keyword
)
18901 unsigned int old_in
= parser
->in_transaction
;
18902 unsigned int this_in
= 1;
18903 location_t loc
= c_parser_peek_token (parser
)->location
;
18906 gcc_assert ((keyword
== RID_TRANSACTION_ATOMIC
18907 || keyword
== RID_TRANSACTION_RELAXED
)
18908 && c_parser_next_token_is_keyword (parser
, keyword
));
18909 c_parser_consume_token (parser
);
18911 if (keyword
== RID_TRANSACTION_RELAXED
)
18912 this_in
|= TM_STMT_ATTR_RELAXED
;
18915 attrs
= c_parser_transaction_attributes (parser
);
18917 this_in
|= parse_tm_stmt_attr (attrs
, 0);
18920 parser
->in_transaction
= this_in
;
18921 matching_parens parens
;
18922 if (parens
.require_open (parser
))
18924 tree expr
= c_parser_expression (parser
).value
;
18925 ret
.original_type
= TREE_TYPE (expr
);
18926 ret
.value
= build1 (TRANSACTION_EXPR
, ret
.original_type
, expr
);
18927 if (this_in
& TM_STMT_ATTR_RELAXED
)
18928 TRANSACTION_EXPR_RELAXED (ret
.value
) = 1;
18929 SET_EXPR_LOCATION (ret
.value
, loc
);
18930 ret
.original_code
= TRANSACTION_EXPR
;
18931 if (!parens
.require_close (parser
))
18933 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
18940 ret
.value
= error_mark_node
;
18941 ret
.original_code
= ERROR_MARK
;
18942 ret
.original_type
= NULL
;
18944 parser
->in_transaction
= old_in
;
18947 error_at (loc
, (keyword
== RID_TRANSACTION_ATOMIC
?
18948 "%<__transaction_atomic%> without transactional memory support enabled"
18949 : "%<__transaction_relaxed %> "
18950 "without transactional memory support enabled"));
18952 set_c_expr_source_range (&ret
, loc
, loc
);
18957 /* Parse a __transaction_cancel statement (GCC Extension).
18959 transaction-cancel-statement:
18960 __transaction_cancel transaction-attribute[opt] ;
18962 Note that the only valid attribute is "outer".
18966 c_parser_transaction_cancel (c_parser
*parser
)
18968 location_t loc
= c_parser_peek_token (parser
)->location
;
18970 bool is_outer
= false;
18972 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_TRANSACTION_CANCEL
));
18973 c_parser_consume_token (parser
);
18975 attrs
= c_parser_transaction_attributes (parser
);
18977 is_outer
= (parse_tm_stmt_attr (attrs
, TM_STMT_ATTR_OUTER
) != 0);
18981 error_at (loc
, "%<__transaction_cancel%> without "
18982 "transactional memory support enabled");
18985 else if (parser
->in_transaction
& TM_STMT_ATTR_RELAXED
)
18987 error_at (loc
, "%<__transaction_cancel%> within a "
18988 "%<__transaction_relaxed%>");
18993 if ((parser
->in_transaction
& TM_STMT_ATTR_OUTER
) == 0
18994 && !is_tm_may_cancel_outer (current_function_decl
))
18996 error_at (loc
, "outer %<__transaction_cancel%> not "
18997 "within outer %<__transaction_atomic%>");
18998 error_at (loc
, " or a %<transaction_may_cancel_outer%> function");
19002 else if (parser
->in_transaction
== 0)
19004 error_at (loc
, "%<__transaction_cancel%> not within "
19005 "%<__transaction_atomic%>");
19009 return add_stmt (build_tm_abort_call (loc
, is_outer
));
19012 return build1 (NOP_EXPR
, void_type_node
, error_mark_node
);
19015 /* Parse a single source file. */
19018 c_parse_file (void)
19020 /* Use local storage to begin. If the first token is a pragma, parse it.
19021 If it is #pragma GCC pch_preprocess, then this will load a PCH file
19022 which will cause garbage collection. */
19025 memset (&tparser
, 0, sizeof tparser
);
19026 tparser
.tokens
= &tparser
.tokens_buf
[0];
19027 the_parser
= &tparser
;
19029 if (c_parser_peek_token (&tparser
)->pragma_kind
== PRAGMA_GCC_PCH_PREPROCESS
)
19030 c_parser_pragma_pch_preprocess (&tparser
);
19032 the_parser
= ggc_alloc
<c_parser
> ();
19033 *the_parser
= tparser
;
19034 if (tparser
.tokens
== &tparser
.tokens_buf
[0])
19035 the_parser
->tokens
= &the_parser
->tokens_buf
[0];
19037 /* Initialize EH, if we've been told to do so. */
19038 if (flag_exceptions
)
19039 using_eh_for_cleanups ();
19041 c_parser_translation_unit (the_parser
);
19045 /* This function parses Cilk Plus array notation. The starting index is
19046 passed in INITIAL_INDEX and the array name is passes in ARRAY_VALUE. The
19047 return value of this function is a tree_node called VALUE_TREE of type
19048 ARRAY_NOTATION_REF. */
19051 c_parser_array_notation (location_t loc
, c_parser
*parser
, tree initial_index
,
19054 c_token
*token
= NULL
;
19055 tree start_index
= NULL_TREE
, end_index
= NULL_TREE
, stride
= NULL_TREE
;
19056 tree value_tree
= NULL_TREE
, type
= NULL_TREE
, array_type
= NULL_TREE
;
19057 tree array_type_domain
= NULL_TREE
;
19059 if (array_value
== error_mark_node
|| initial_index
== error_mark_node
)
19061 /* No need to continue. If either of these 2 were true, then an error
19062 must be emitted already. Thus, no need to emit them twice. */
19063 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
, NULL
);
19064 return error_mark_node
;
19067 array_type
= TREE_TYPE (array_value
);
19068 gcc_assert (array_type
);
19069 if (TREE_CODE (array_type
) != ARRAY_TYPE
19070 && TREE_CODE (array_type
) != POINTER_TYPE
)
19072 error_at (loc
, "base of array section must be pointer or array type");
19073 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
, NULL
);
19074 return error_mark_node
;
19076 type
= TREE_TYPE (array_type
);
19077 token
= c_parser_peek_token (parser
);
19079 if (token
->type
== CPP_EOF
)
19081 c_parser_error (parser
, "expected %<:%> or numeral");
19084 else if (token
->type
== CPP_COLON
)
19086 if (!initial_index
)
19088 /* If we are here, then we have a case like this A[:]. */
19089 c_parser_consume_token (parser
);
19090 if (TREE_CODE (array_type
) == POINTER_TYPE
)
19092 error_at (loc
, "start-index and length fields necessary for "
19093 "using array notations in pointers");
19094 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
, NULL
);
19095 return error_mark_node
;
19097 if (TREE_CODE (array_type
) == FUNCTION_TYPE
)
19099 error_at (loc
, "array notations cannot be used with function "
19101 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
, NULL
);
19102 return error_mark_node
;
19104 array_type_domain
= TYPE_DOMAIN (array_type
);
19106 if (!array_type_domain
)
19108 error_at (loc
, "start-index and length fields necessary for "
19109 "using array notations in dimensionless arrays");
19110 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
, NULL
);
19111 return error_mark_node
;
19114 start_index
= TYPE_MIN_VALUE (array_type_domain
);
19115 start_index
= fold_build1 (CONVERT_EXPR
, ptrdiff_type_node
,
19117 if (!TYPE_MAX_VALUE (array_type_domain
)
19118 || !TREE_CONSTANT (TYPE_MAX_VALUE (array_type_domain
)))
19120 error_at (loc
, "start-index and length fields necessary for "
19121 "using array notations in variable-length arrays");
19122 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
, NULL
);
19123 return error_mark_node
;
19125 end_index
= TYPE_MAX_VALUE (array_type_domain
);
19126 end_index
= fold_build2 (PLUS_EXPR
, TREE_TYPE (end_index
),
19127 end_index
, integer_one_node
);
19128 end_index
= fold_build1 (CONVERT_EXPR
, ptrdiff_type_node
, end_index
);
19129 stride
= build_int_cst (integer_type_node
, 1);
19130 stride
= fold_build1 (CONVERT_EXPR
, ptrdiff_type_node
, stride
);
19132 else if (initial_index
!= error_mark_node
)
19134 /* If we are here, then there should be 2 possibilities:
19135 1. Array [EXPR : EXPR]
19136 2. Array [EXPR : EXPR : EXPR]
19138 start_index
= initial_index
;
19140 if (TREE_CODE (array_type
) == FUNCTION_TYPE
)
19142 error_at (loc
, "array notations cannot be used with function "
19144 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
, NULL
);
19145 return error_mark_node
;
19147 c_parser_consume_token (parser
); /* consume the ':' */
19148 struct c_expr ce
= c_parser_expression (parser
);
19149 ce
= convert_lvalue_to_rvalue (loc
, ce
, false, false);
19150 end_index
= ce
.value
;
19151 if (!end_index
|| end_index
== error_mark_node
)
19153 c_parser_skip_to_end_of_block_or_statement (parser
);
19154 return error_mark_node
;
19156 if (c_parser_peek_token (parser
)->type
== CPP_COLON
)
19158 c_parser_consume_token (parser
);
19159 ce
= c_parser_expression (parser
);
19160 ce
= convert_lvalue_to_rvalue (loc
, ce
, false, false);
19162 if (!stride
|| stride
== error_mark_node
)
19164 c_parser_skip_to_end_of_block_or_statement (parser
);
19165 return error_mark_node
;
19170 c_parser_error (parser
, "expected array notation expression");
19173 c_parser_error (parser
, "expected array notation expression");
19175 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
, "expected %<]%>");
19177 value_tree
= build_array_notation_ref (loc
, array_value
, start_index
,
19178 end_index
, stride
, type
);
19179 if (value_tree
!= error_mark_node
)
19180 SET_EXPR_LOCATION (value_tree
, loc
);
19184 /* Parse the body of a function declaration marked with "__RTL".
19186 The RTL parser works on the level of characters read from a
19187 FILE *, whereas c_parser works at the level of tokens.
19188 Square this circle by consuming all of the tokens up to and
19189 including the closing brace, recording the start/end of the RTL
19190 fragment, and reopening the file and re-reading the relevant
19191 lines within the RTL parser.
19193 This requires the opening and closing braces of the C function
19194 to be on separate lines from the RTL they wrap.
19196 Take ownership of START_WITH_PASS, if non-NULL. */
19199 c_parser_parse_rtl_body (c_parser
*parser
, char *start_with_pass
)
19201 if (!c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
19203 free (start_with_pass
);
19207 location_t start_loc
= c_parser_peek_token (parser
)->location
;
19209 /* Consume all tokens, up to the closing brace, handling
19210 matching pairs of braces in the rtl dump. */
19211 int num_open_braces
= 1;
19214 switch (c_parser_peek_token (parser
)->type
)
19216 case CPP_OPEN_BRACE
:
19219 case CPP_CLOSE_BRACE
:
19220 if (--num_open_braces
== 0)
19221 goto found_closing_brace
;
19224 error_at (start_loc
, "no closing brace");
19225 free (start_with_pass
);
19230 c_parser_consume_token (parser
);
19233 found_closing_brace
:
19234 /* At the closing brace; record its location. */
19235 location_t end_loc
= c_parser_peek_token (parser
)->location
;
19237 /* Consume the closing brace. */
19238 c_parser_consume_token (parser
);
19240 /* Invoke the RTL parser. */
19241 if (!read_rtl_function_body_from_file_range (start_loc
, end_loc
))
19243 free (start_with_pass
);
19247 /* If a pass name was provided for START_WITH_PASS, run the backend
19248 accordingly now, on the cfun created above, transferring
19249 ownership of START_WITH_PASS. */
19250 if (start_with_pass
)
19251 run_rtl_passes (start_with_pass
);
19254 #include "gt-c-c-parser.h"