]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/c/c-parser.c
c: Fix up cfun->function_end_locus on invalid function bodies [PR94239]
[thirdparty/gcc.git] / gcc / c / c-parser.c
CommitLineData
27bf414c 1/* Parser for C and Objective-C.
8d9254fc 2 Copyright (C) 1987-2020 Free Software Foundation, Inc.
27bf414c
JM
3
4 Parser actions based on the old Bison parser; structure somewhat
5 influenced by and fragments based on the C++ parser.
6
7This file is part of GCC.
8
9GCC is free software; you can redistribute it and/or modify it under
10the terms of the GNU General Public License as published by the Free
9dcd6f09 11Software Foundation; either version 3, or (at your option) any later
27bf414c
JM
12version.
13
14GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15WARRANTY; without even the implied warranty of MERCHANTABILITY or
16FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17for more details.
18
19You should have received a copy of the GNU General Public License
9dcd6f09
NC
20along with GCC; see the file COPYING3. If not see
21<http://www.gnu.org/licenses/>. */
27bf414c
JM
22
23/* TODO:
24
25 Make sure all relevant comments, and all relevant code from all
26 actions, brought over from old parser. Verify exact correspondence
27 of syntax accepted.
28
29 Add testcases covering every input symbol in every state in old and
30 new parsers.
31
32 Include full syntax for GNU C, including erroneous cases accepted
33 with error messages, in syntax productions in comments.
34
35 Make more diagnostics in the front end generally take an explicit
36 location rather than implicitly using input_location. */
37
38#include "config.h"
6c7a259b 39#define INCLUDE_UNIQUE_PTR
27bf414c
JM
40#include "system.h"
41#include "coretypes.h"
2adfab87
AM
42#include "target.h"
43#include "function.h"
2adfab87
AM
44#include "c-tree.h"
45#include "timevar.h"
d8a2d370 46#include "stringpool.h"
2adfab87 47#include "cgraph.h"
d8a2d370
DN
48#include "attribs.h"
49#include "stor-layout.h"
50#include "varasm.h"
51#include "trans-mem.h"
39dabefd 52#include "c-family/c-pragma.h"
acf0174b 53#include "c-lang.h"
61d3ce20 54#include "c-family/c-objc.h"
68a607d8 55#include "plugin.h"
629b3d75
MJ
56#include "omp-general.h"
57#include "omp-offload.h"
9b2b7279 58#include "builtins.h"
41dbbb37 59#include "gomp-constants.h"
992118a1 60#include "c-family/c-indentation.h"
e01d41e5
JJ
61#include "gimple-expr.h"
62#include "context.h"
1a4f11c8 63#include "gcc-rich-location.h"
1ee62b92
PG
64#include "c-parser.h"
65#include "gimple-parser.h"
c2e84327
DM
66#include "read-rtl-function.h"
67#include "run-rtl-passes.h"
324ff1a0 68#include "intl.h"
6c7a259b 69#include "c-family/name-hint.h"
65791f42 70#include "tree-iterator.h"
28567c40 71#include "memmodel.h"
27bf414c 72
d25c7690
PK
73/* We need to walk over decls with incomplete struct/union/enum types
74 after parsing the whole translation unit.
75 In finish_decl(), if the decl is static, has incomplete
76 struct/union/enum type, it is appeneded to incomplete_record_decls.
77 In c_parser_translation_unit(), we iterate over incomplete_record_decls
78 and report error if any of the decls are still incomplete. */
79
7de76362 80vec<tree> incomplete_record_decls;
d25c7690 81
ebedc9a3
DM
82void
83set_c_expr_source_range (c_expr *expr,
84 location_t start, location_t finish)
85{
86 expr->src_range.m_start = start;
87 expr->src_range.m_finish = finish;
bef08b71
DM
88 if (expr->value)
89 set_source_range (expr->value, start, finish);
ebedc9a3
DM
90}
91
92void
93set_c_expr_source_range (c_expr *expr,
94 source_range src_range)
95{
96 expr->src_range = src_range;
bef08b71
DM
97 if (expr->value)
98 set_source_range (expr->value, src_range);
ebedc9a3
DM
99}
100
27bf414c 101\f
27bf414c
JM
102/* Initialization routine for this file. */
103
104void
105c_parse_init (void)
106{
107 /* The only initialization required is of the reserved word
108 identifiers. */
109 unsigned int i;
110 tree id;
eea1139b 111 int mask = 0;
27bf414c 112
36c5e70a
BE
113 /* Make sure RID_MAX hasn't grown past the 8 bits used to hold the keyword in
114 the c_token structure. */
115 gcc_assert (RID_MAX <= 255);
116
eea1139b
ILT
117 mask |= D_CXXONLY;
118 if (!flag_isoc99)
119 mask |= D_C99;
120 if (flag_no_asm)
121 {
122 mask |= D_ASM | D_EXT;
123 if (!flag_isoc99)
124 mask |= D_EXT89;
125 }
27bf414c 126 if (!c_dialect_objc ())
eea1139b 127 mask |= D_OBJC | D_CXX_OBJC;
27bf414c 128
766090c2 129 ridpointers = ggc_cleared_vec_alloc<tree> ((int) RID_MAX);
eea1139b 130 for (i = 0; i < num_c_common_reswords; i++)
27bf414c
JM
131 {
132 /* If a keyword is disabled, do not enter it into the table
133 and so create a canonical spelling that isn't a keyword. */
eea1139b
ILT
134 if (c_common_reswords[i].disable & mask)
135 {
136 if (warn_cxx_compat
137 && (c_common_reswords[i].disable & D_CXXWARN))
138 {
139 id = get_identifier (c_common_reswords[i].word);
140 C_SET_RID_CODE (id, RID_CXX_COMPAT_WARN);
141 C_IS_RESERVED_WORD (id) = 1;
142 }
143 continue;
144 }
27bf414c 145
eea1139b
ILT
146 id = get_identifier (c_common_reswords[i].word);
147 C_SET_RID_CODE (id, c_common_reswords[i].rid);
27bf414c 148 C_IS_RESERVED_WORD (id) = 1;
eea1139b 149 ridpointers [(int) c_common_reswords[i].rid] = id;
27bf414c 150 }
78a7c317
DD
151
152 for (i = 0; i < NUM_INT_N_ENTS; i++)
153 {
154 /* We always create the symbols but they aren't always supported. */
155 char name[50];
156 sprintf (name, "__int%d", int_n_data[i].bitsize);
17958621 157 id = get_identifier (name);
78a7c317
DD
158 C_SET_RID_CODE (id, RID_FIRST_INT_N + i);
159 C_IS_RESERVED_WORD (id) = 1;
5e580306
JL
160
161 sprintf (name, "__int%d__", int_n_data[i].bitsize);
162 id = get_identifier (name);
163 C_SET_RID_CODE (id, RID_FIRST_INT_N + i);
164 C_IS_RESERVED_WORD (id) = 1;
78a7c317 165 }
27bf414c
JM
166}
167\f
27bf414c
JM
168/* A parser structure recording information about the state and
169 context of parsing. Includes lexer information with up to two
170 tokens of look-ahead; more are not needed for C. */
a79683d5 171struct GTY(()) c_parser {
27bf414c 172 /* The look-ahead tokens. */
acf0174b
JJ
173 c_token * GTY((skip)) tokens;
174 /* Buffer for look-ahead tokens. */
de67c4c3
DM
175 c_token tokens_buf[4];
176 /* How many look-ahead tokens are available (0 - 4, or
acf0174b
JJ
177 more if parsing from pre-lexed tokens). */
178 unsigned int tokens_avail;
34b43828
JM
179 /* Raw look-ahead tokens, used only for checking in Objective-C
180 whether '[[' starts attributes. */
181 vec<c_token, va_gc> *raw_tokens;
182 /* The number of raw look-ahead tokens that have since been fully
183 lexed. */
184 unsigned int raw_tokens_used;
27bf414c
JM
185 /* True if a syntax error is being recovered from; false otherwise.
186 c_parser_error sets this flag. It should clear this flag when
187 enough tokens have been consumed to recover from the error. */
188 BOOL_BITFIELD error : 1;
bc4071dd
RH
189 /* True if we're processing a pragma, and shouldn't automatically
190 consume CPP_PRAGMA_EOL. */
191 BOOL_BITFIELD in_pragma : 1;
b4b56033
MLI
192 /* True if we're parsing the outermost block of an if statement. */
193 BOOL_BITFIELD in_if_block : 1;
471c5330
JM
194 /* True if we want to lex a translated, joined string (for an
195 initial #pragma pch_preprocess). Otherwise the parser is
196 responsible for concatenating strings and translating to the
197 execution character set as needed. */
198 BOOL_BITFIELD lex_joined_string : 1;
199 /* True if, when the parser is concatenating string literals, it
200 should translate them to the execution character set (false
201 inside attributes). */
202 BOOL_BITFIELD translate_strings_p : 1;
1973201f 203
0bacb8c7 204 /* Objective-C specific parser/lexer information. */
1973201f
NP
205
206 /* True if we are in a context where the Objective-C "PQ" keywords
207 are considered keywords. */
0bacb8c7 208 BOOL_BITFIELD objc_pq_context : 1;
f05b9d93
NP
209 /* True if we are parsing a (potential) Objective-C foreach
210 statement. This is set to true after we parsed 'for (' and while
211 we wait for 'in' or ';' to decide if it's a standard C for loop or an
212 Objective-C foreach loop. */
213 BOOL_BITFIELD objc_could_be_foreach_context : 1;
0bacb8c7
TT
214 /* The following flag is needed to contextualize Objective-C lexical
215 analysis. In some cases (e.g., 'int NSObject;'), it is
216 undesirable to bind an identifier to an Objective-C class, even
217 if a class with that name exists. */
218 BOOL_BITFIELD objc_need_raw_identifier : 1;
0a35513e
AH
219 /* Nonzero if we're processing a __transaction statement. The value
220 is 1 | TM_STMT_ATTR_*. */
221 unsigned int in_transaction : 4;
668ea4b1
IS
222 /* True if we are in a context where the Objective-C "Property attribute"
223 keywords are valid. */
224 BOOL_BITFIELD objc_property_attr_context : 1;
41958c28 225
8139a48e
DM
226 /* Location of the last consumed token. */
227 location_t last_token_location;
a79683d5 228};
27bf414c 229
1ee62b92
PG
230/* Return a pointer to the Nth token in PARSERs tokens_buf. */
231
232c_token *
233c_parser_tokens_buf (c_parser *parser, unsigned n)
234{
235 return &parser->tokens_buf[n];
236}
237
238/* Return the error state of PARSER. */
239
240bool
241c_parser_error (c_parser *parser)
242{
243 return parser->error;
244}
245
246/* Set the error state of PARSER to ERR. */
247
248void
249c_parser_set_error (c_parser *parser, bool err)
250{
251 parser->error = err;
252}
253
bc4071dd
RH
254
255/* The actual parser and external interface. ??? Does this need to be
256 garbage-collected? */
257
258static GTY (()) c_parser *the_parser;
259
34b43828
JM
260/* Read in and lex a single token, storing it in *TOKEN. If RAW,
261 context-sensitive postprocessing of the token is not done. */
27bf414c
JM
262
263static void
34b43828 264c_lex_one_token (c_parser *parser, c_token *token, bool raw = false)
27bf414c
JM
265{
266 timevar_push (TV_LEX);
bc4071dd 267
34b43828
JM
268 if (raw || vec_safe_length (parser->raw_tokens) == 0)
269 {
270 token->type = c_lex_with_flags (&token->value, &token->location,
271 &token->flags,
272 (parser->lex_joined_string
273 ? 0 : C_LEX_STRING_NO_JOIN));
274 token->id_kind = C_ID_NONE;
275 token->keyword = RID_MAX;
276 token->pragma_kind = PRAGMA_NONE;
277 }
278 else
279 {
280 /* Use a token previously lexed as a raw look-ahead token, and
281 complete the processing on it. */
282 *token = (*parser->raw_tokens)[parser->raw_tokens_used];
283 ++parser->raw_tokens_used;
284 if (parser->raw_tokens_used == vec_safe_length (parser->raw_tokens))
285 {
286 vec_free (parser->raw_tokens);
287 parser->raw_tokens_used = 0;
288 }
289 }
290
291 if (raw)
292 goto out;
bc4071dd 293
27bf414c
JM
294 switch (token->type)
295 {
296 case CPP_NAME:
27bf414c
JM
297 {
298 tree decl;
299
0bacb8c7
TT
300 bool objc_force_identifier = parser->objc_need_raw_identifier;
301 if (c_dialect_objc ())
302 parser->objc_need_raw_identifier = false;
27bf414c
JM
303
304 if (C_IS_RESERVED_WORD (token->value))
305 {
306 enum rid rid_code = C_RID_CODE (token->value);
307
eea1139b
ILT
308 if (rid_code == RID_CXX_COMPAT_WARN)
309 {
3ba09659
AH
310 warning_at (token->location,
311 OPT_Wc___compat,
88388a52
JM
312 "identifier %qE conflicts with C++ keyword",
313 token->value);
eea1139b 314 }
36c5e70a
BE
315 else if (rid_code >= RID_FIRST_ADDR_SPACE
316 && rid_code <= RID_LAST_ADDR_SPACE)
317 {
ffc22840
GJL
318 addr_space_t as;
319 as = (addr_space_t) (rid_code - RID_FIRST_ADDR_SPACE);
320 targetm.addr_space.diagnose_usage (as, token->location);
36c5e70a
BE
321 token->id_kind = C_ID_ADDRSPACE;
322 token->keyword = rid_code;
323 break;
324 }
1973201f 325 else if (c_dialect_objc () && OBJC_IS_PQ_KEYWORD (rid_code))
27bf414c 326 {
1973201f
NP
327 /* We found an Objective-C "pq" keyword (in, out,
328 inout, bycopy, byref, oneway). They need special
329 care because the interpretation depends on the
d853ee42 330 context. */
1973201f 331 if (parser->objc_pq_context)
27bf414c 332 {
27bf414c
JM
333 token->type = CPP_KEYWORD;
334 token->keyword = rid_code;
335 break;
336 }
f05b9d93
NP
337 else if (parser->objc_could_be_foreach_context
338 && rid_code == RID_IN)
339 {
340 /* We are in Objective-C, inside a (potential)
341 foreach context (which means after having
342 parsed 'for (', but before having parsed ';'),
343 and we found 'in'. We consider it the keyword
344 which terminates the declaration at the
345 beginning of a foreach-statement. Note that
346 this means you can't use 'in' for anything else
347 in that context; in particular, in Objective-C
348 you can't use 'in' as the name of the running
349 variable in a C for loop. We could potentially
350 try to add code here to disambiguate, but it
d853ee42 351 seems a reasonable limitation. */
f05b9d93
NP
352 token->type = CPP_KEYWORD;
353 token->keyword = rid_code;
354 break;
355 }
1973201f
NP
356 /* Else, "pq" keywords outside of the "pq" context are
357 not keywords, and we fall through to the code for
d853ee42 358 normal tokens. */
1973201f 359 }
668ea4b1
IS
360 else if (c_dialect_objc () && OBJC_IS_PATTR_KEYWORD (rid_code))
361 {
d853ee42
NP
362 /* We found an Objective-C "property attribute"
363 keyword (getter, setter, readonly, etc). These are
668ea4b1
IS
364 only valid in the property context. */
365 if (parser->objc_property_attr_context)
366 {
367 token->type = CPP_KEYWORD;
368 token->keyword = rid_code;
369 break;
370 }
371 /* Else they are not special keywords.
372 */
373 }
1973201f
NP
374 else if (c_dialect_objc ()
375 && (OBJC_IS_AT_KEYWORD (rid_code)
376 || OBJC_IS_CXX_KEYWORD (rid_code)))
377 {
378 /* We found one of the Objective-C "@" keywords (defs,
379 selector, synchronized, etc) or one of the
380 Objective-C "cxx" keywords (class, private,
381 protected, public, try, catch, throw) without a
382 preceding '@' sign. Do nothing and fall through to
383 the code for normal tokens (in C++ we would still
d853ee42 384 consider the CXX ones keywords, but not in C). */
1973201f 385 ;
27bf414c
JM
386 }
387 else
388 {
27bf414c
JM
389 token->type = CPP_KEYWORD;
390 token->keyword = rid_code;
391 break;
392 }
393 }
394
395 decl = lookup_name (token->value);
396 if (decl)
397 {
398 if (TREE_CODE (decl) == TYPE_DECL)
399 {
400 token->id_kind = C_ID_TYPENAME;
401 break;
402 }
403 }
404 else if (c_dialect_objc ())
405 {
406 tree objc_interface_decl = objc_is_class_name (token->value);
407 /* Objective-C class names are in the same namespace as
408 variables and typedefs, and hence are shadowed by local
409 declarations. */
410 if (objc_interface_decl
0d8a2528 411 && (!objc_force_identifier || global_bindings_p ()))
27bf414c
JM
412 {
413 token->value = objc_interface_decl;
414 token->id_kind = C_ID_CLASSNAME;
415 break;
416 }
417 }
bc4071dd 418 token->id_kind = C_ID_ID;
27bf414c 419 }
27bf414c
JM
420 break;
421 case CPP_AT_NAME:
422 /* This only happens in Objective-C; it must be a keyword. */
423 token->type = CPP_KEYWORD;
49b91f05
NP
424 switch (C_RID_CODE (token->value))
425 {
426 /* Replace 'class' with '@class', 'private' with '@private',
427 etc. This prevents confusion with the C++ keyword
428 'class', and makes the tokens consistent with other
429 Objective-C 'AT' keywords. For example '@class' is
430 reported as RID_AT_CLASS which is consistent with
431 '@synchronized', which is reported as
432 RID_AT_SYNCHRONIZED.
433 */
434 case RID_CLASS: token->keyword = RID_AT_CLASS; break;
435 case RID_PRIVATE: token->keyword = RID_AT_PRIVATE; break;
436 case RID_PROTECTED: token->keyword = RID_AT_PROTECTED; break;
437 case RID_PUBLIC: token->keyword = RID_AT_PUBLIC; break;
438 case RID_THROW: token->keyword = RID_AT_THROW; break;
439 case RID_TRY: token->keyword = RID_AT_TRY; break;
440 case RID_CATCH: token->keyword = RID_AT_CATCH; break;
b8fd7909 441 case RID_SYNCHRONIZED: token->keyword = RID_AT_SYNCHRONIZED; break;
49b91f05
NP
442 default: token->keyword = C_RID_CODE (token->value);
443 }
27bf414c
JM
444 break;
445 case CPP_COLON:
446 case CPP_COMMA:
447 case CPP_CLOSE_PAREN:
448 case CPP_SEMICOLON:
449 /* These tokens may affect the interpretation of any identifiers
450 following, if doing Objective-C. */
0bacb8c7
TT
451 if (c_dialect_objc ())
452 parser->objc_need_raw_identifier = false;
bc4071dd
RH
453 break;
454 case CPP_PRAGMA:
455 /* We smuggled the cpp_token->u.pragma value in an INTEGER_CST. */
d75d71e0 456 token->pragma_kind = (enum pragma_kind) TREE_INT_CST_LOW (token->value);
bc4071dd 457 token->value = NULL;
27bf414c
JM
458 break;
459 default:
27bf414c
JM
460 break;
461 }
34b43828 462 out:
27bf414c
JM
463 timevar_pop (TV_LEX);
464}
465
466/* Return a pointer to the next token from PARSER, reading it in if
467 necessary. */
468
1ee62b92 469c_token *
27bf414c
JM
470c_parser_peek_token (c_parser *parser)
471{
472 if (parser->tokens_avail == 0)
473 {
0bacb8c7 474 c_lex_one_token (parser, &parser->tokens[0]);
27bf414c
JM
475 parser->tokens_avail = 1;
476 }
477 return &parser->tokens[0];
478}
479
29ce73cb
PB
480/* Return a pointer to the next-but-one token from PARSER, reading it
481 in if necessary. The next token is already read in. */
482
1ee62b92 483c_token *
29ce73cb
PB
484c_parser_peek_2nd_token (c_parser *parser)
485{
486 if (parser->tokens_avail >= 2)
487 return &parser->tokens[1];
488 gcc_assert (parser->tokens_avail == 1);
489 gcc_assert (parser->tokens[0].type != CPP_EOF);
490 gcc_assert (parser->tokens[0].type != CPP_PRAGMA_EOL);
491 c_lex_one_token (parser, &parser->tokens[1]);
492 parser->tokens_avail = 2;
493 return &parser->tokens[1];
494}
495
de67c4c3
DM
496/* Return a pointer to the Nth token from PARSER, reading it
497 in if necessary. The N-1th token is already read in. */
498
1ee62b92 499c_token *
de67c4c3
DM
500c_parser_peek_nth_token (c_parser *parser, unsigned int n)
501{
502 /* N is 1-based, not zero-based. */
503 gcc_assert (n > 0);
504
505 if (parser->tokens_avail >= n)
506 return &parser->tokens[n - 1];
507 gcc_assert (parser->tokens_avail == n - 1);
508 c_lex_one_token (parser, &parser->tokens[n - 1]);
509 parser->tokens_avail = n;
510 return &parser->tokens[n - 1];
511}
512
34b43828
JM
513/* Return a pointer to the Nth token from PARSER, reading it in as a
514 raw look-ahead token if necessary. The N-1th token is already read
515 in. Raw look-ahead tokens remain available for when the non-raw
516 functions above are called. */
517
518c_token *
519c_parser_peek_nth_token_raw (c_parser *parser, unsigned int n)
520{
521 /* N is 1-based, not zero-based. */
522 gcc_assert (n > 0);
523
524 if (parser->tokens_avail >= n)
525 return &parser->tokens[n - 1];
526 unsigned int raw_len = vec_safe_length (parser->raw_tokens);
527 unsigned int raw_avail
528 = parser->tokens_avail + raw_len - parser->raw_tokens_used;
529 gcc_assert (raw_avail >= n - 1);
530 if (raw_avail >= n)
531 return &(*parser->raw_tokens)[parser->raw_tokens_used
532 + n - 1 - parser->tokens_avail];
533 vec_safe_reserve (parser->raw_tokens, 1);
534 parser->raw_tokens->quick_grow (raw_len + 1);
535 c_lex_one_token (parser, &(*parser->raw_tokens)[raw_len], true);
536 return &(*parser->raw_tokens)[raw_len];
537}
538
1a4f11c8
DM
539bool
540c_keyword_starts_typename (enum rid keyword)
541{
542 switch (keyword)
543 {
544 case RID_UNSIGNED:
545 case RID_LONG:
546 case RID_SHORT:
547 case RID_SIGNED:
548 case RID_COMPLEX:
549 case RID_INT:
550 case RID_CHAR:
551 case RID_FLOAT:
552 case RID_DOUBLE:
553 case RID_VOID:
554 case RID_DFLOAT32:
555 case RID_DFLOAT64:
556 case RID_DFLOAT128:
c65699ef 557 CASE_RID_FLOATN_NX:
1a4f11c8
DM
558 case RID_BOOL:
559 case RID_ENUM:
560 case RID_STRUCT:
561 case RID_UNION:
562 case RID_TYPEOF:
563 case RID_CONST:
564 case RID_ATOMIC:
565 case RID_VOLATILE:
566 case RID_RESTRICT:
567 case RID_ATTRIBUTE:
568 case RID_FRACT:
569 case RID_ACCUM:
570 case RID_SAT:
571 case RID_AUTO_TYPE:
4b2b493f 572 case RID_ALIGNAS:
1a4f11c8
DM
573 return true;
574 default:
575 if (keyword >= RID_FIRST_INT_N
576 && keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS
577 && int_n_enabled_p[keyword - RID_FIRST_INT_N])
578 return true;
579 return false;
580 }
581}
582
27bf414c
JM
583/* Return true if TOKEN can start a type name,
584 false otherwise. */
1ee62b92 585bool
27bf414c
JM
586c_token_starts_typename (c_token *token)
587{
588 switch (token->type)
589 {
590 case CPP_NAME:
591 switch (token->id_kind)
592 {
593 case C_ID_ID:
594 return false;
36c5e70a
BE
595 case C_ID_ADDRSPACE:
596 return true;
27bf414c
JM
597 case C_ID_TYPENAME:
598 return true;
599 case C_ID_CLASSNAME:
600 gcc_assert (c_dialect_objc ());
601 return true;
602 default:
603 gcc_unreachable ();
604 }
605 case CPP_KEYWORD:
1a4f11c8 606 return c_keyword_starts_typename (token->keyword);
27bf414c
JM
607 case CPP_LESS:
608 if (c_dialect_objc ())
609 return true;
610 return false;
611 default:
612 return false;
613 }
614}
615
616/* Return true if the next token from PARSER can start a type name,
29ce73cb
PB
617 false otherwise. LA specifies how to do lookahead in order to
618 detect unknown type names. If unsure, pick CLA_PREFER_ID. */
619
27bf414c 620static inline bool
29ce73cb 621c_parser_next_tokens_start_typename (c_parser *parser, enum c_lookahead_kind la)
27bf414c
JM
622{
623 c_token *token = c_parser_peek_token (parser);
29ce73cb
PB
624 if (c_token_starts_typename (token))
625 return true;
626
627 /* Try a bit harder to detect an unknown typename. */
628 if (la != cla_prefer_id
629 && token->type == CPP_NAME
630 && token->id_kind == C_ID_ID
631
632 /* Do not try too hard when we could have "object in array". */
633 && !parser->objc_could_be_foreach_context
634
635 && (la == cla_prefer_type
636 || c_parser_peek_2nd_token (parser)->type == CPP_NAME
637 || c_parser_peek_2nd_token (parser)->type == CPP_MULT)
638
639 /* Only unknown identifiers. */
640 && !lookup_name (token->value))
641 return true;
642
643 return false;
27bf414c
JM
644}
645
f725e721
PB
646/* Return true if TOKEN is a type qualifier, false otherwise. */
647static bool
648c_token_is_qualifier (c_token *token)
649{
650 switch (token->type)
651 {
652 case CPP_NAME:
653 switch (token->id_kind)
654 {
655 case C_ID_ADDRSPACE:
656 return true;
657 default:
658 return false;
659 }
660 case CPP_KEYWORD:
661 switch (token->keyword)
662 {
663 case RID_CONST:
664 case RID_VOLATILE:
665 case RID_RESTRICT:
666 case RID_ATTRIBUTE:
267bac10 667 case RID_ATOMIC:
f725e721
PB
668 return true;
669 default:
670 return false;
671 }
672 case CPP_LESS:
673 return false;
674 default:
675 gcc_unreachable ();
676 }
677}
678
679/* Return true if the next token from PARSER is a type qualifier,
680 false otherwise. */
681static inline bool
682c_parser_next_token_is_qualifier (c_parser *parser)
683{
684 c_token *token = c_parser_peek_token (parser);
685 return c_token_is_qualifier (token);
686}
687
4e03c3a7
JM
688/* Return true if TOKEN can start declaration specifiers (not
689 including standard attributes), false otherwise. */
27bf414c
JM
690static bool
691c_token_starts_declspecs (c_token *token)
692{
693 switch (token->type)
694 {
695 case CPP_NAME:
696 switch (token->id_kind)
697 {
698 case C_ID_ID:
699 return false;
36c5e70a
BE
700 case C_ID_ADDRSPACE:
701 return true;
27bf414c
JM
702 case C_ID_TYPENAME:
703 return true;
704 case C_ID_CLASSNAME:
705 gcc_assert (c_dialect_objc ());
706 return true;
707 default:
708 gcc_unreachable ();
709 }
710 case CPP_KEYWORD:
711 switch (token->keyword)
712 {
713 case RID_STATIC:
714 case RID_EXTERN:
715 case RID_REGISTER:
716 case RID_TYPEDEF:
717 case RID_INLINE:
bbceee64 718 case RID_NORETURN:
27bf414c
JM
719 case RID_AUTO:
720 case RID_THREAD:
721 case RID_UNSIGNED:
722 case RID_LONG:
723 case RID_SHORT:
724 case RID_SIGNED:
725 case RID_COMPLEX:
726 case RID_INT:
727 case RID_CHAR:
728 case RID_FLOAT:
729 case RID_DOUBLE:
730 case RID_VOID:
9a8ce21f
JG
731 case RID_DFLOAT32:
732 case RID_DFLOAT64:
733 case RID_DFLOAT128:
c65699ef 734 CASE_RID_FLOATN_NX:
27bf414c
JM
735 case RID_BOOL:
736 case RID_ENUM:
737 case RID_STRUCT:
738 case RID_UNION:
739 case RID_TYPEOF:
740 case RID_CONST:
741 case RID_VOLATILE:
742 case RID_RESTRICT:
743 case RID_ATTRIBUTE:
ab22c1fa
CF
744 case RID_FRACT:
745 case RID_ACCUM:
746 case RID_SAT:
d19fa6b5 747 case RID_ALIGNAS:
267bac10 748 case RID_ATOMIC:
38b7bc7f 749 case RID_AUTO_TYPE:
27bf414c
JM
750 return true;
751 default:
78a7c317
DD
752 if (token->keyword >= RID_FIRST_INT_N
753 && token->keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS
754 && int_n_enabled_p[token->keyword - RID_FIRST_INT_N])
755 return true;
27bf414c
JM
756 return false;
757 }
758 case CPP_LESS:
759 if (c_dialect_objc ())
760 return true;
761 return false;
762 default:
763 return false;
764 }
765}
766
32912286 767
4e03c3a7
JM
768/* Return true if TOKEN can start declaration specifiers (not
769 including standard attributes) or a static assertion, false
770 otherwise. */
32912286
JM
771static bool
772c_token_starts_declaration (c_token *token)
773{
774 if (c_token_starts_declspecs (token)
775 || token->keyword == RID_STATIC_ASSERT)
776 return true;
777 else
778 return false;
779}
780
27bf414c 781/* Return true if the next token from PARSER can start declaration
4e03c3a7
JM
782 specifiers (not including standard attributes), false
783 otherwise. */
1ee62b92 784bool
27bf414c
JM
785c_parser_next_token_starts_declspecs (c_parser *parser)
786{
787 c_token *token = c_parser_peek_token (parser);
bede2adc
NP
788
789 /* In Objective-C, a classname normally starts a declspecs unless it
790 is immediately followed by a dot. In that case, it is the
791 Objective-C 2.0 "dot-syntax" for class objects, ie, calls the
792 setter/getter on the class. c_token_starts_declspecs() can't
793 differentiate between the two cases because it only checks the
794 current token, so we have a special check here. */
795 if (c_dialect_objc ()
796 && token->type == CPP_NAME
797 && token->id_kind == C_ID_CLASSNAME
798 && c_parser_peek_2nd_token (parser)->type == CPP_DOT)
799 return false;
800
27bf414c
JM
801 return c_token_starts_declspecs (token);
802}
803
2f413185 804/* Return true if the next tokens from PARSER can start declaration
4e03c3a7
JM
805 specifiers (not including standard attributes) or a static
806 assertion, false otherwise. */
1ee62b92 807bool
2f413185 808c_parser_next_tokens_start_declaration (c_parser *parser)
32912286
JM
809{
810 c_token *token = c_parser_peek_token (parser);
bede2adc
NP
811
812 /* Same as above. */
813 if (c_dialect_objc ()
814 && token->type == CPP_NAME
815 && token->id_kind == C_ID_CLASSNAME
816 && c_parser_peek_2nd_token (parser)->type == CPP_DOT)
817 return false;
818
2f413185
PB
819 /* Labels do not start declarations. */
820 if (token->type == CPP_NAME
821 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
822 return false;
823
824 if (c_token_starts_declaration (token))
825 return true;
826
29ce73cb 827 if (c_parser_next_tokens_start_typename (parser, cla_nonabstract_decl))
2f413185
PB
828 return true;
829
830 return false;
32912286
JM
831}
832
27bf414c
JM
833/* Consume the next token from PARSER. */
834
1ee62b92 835void
27bf414c
JM
836c_parser_consume_token (c_parser *parser)
837{
bc4071dd
RH
838 gcc_assert (parser->tokens_avail >= 1);
839 gcc_assert (parser->tokens[0].type != CPP_EOF);
840 gcc_assert (!parser->in_pragma || parser->tokens[0].type != CPP_PRAGMA_EOL);
841 gcc_assert (parser->error || parser->tokens[0].type != CPP_PRAGMA);
8139a48e 842 parser->last_token_location = parser->tokens[0].location;
acf0174b
JJ
843 if (parser->tokens != &parser->tokens_buf[0])
844 parser->tokens++;
4e03c3a7
JM
845 else if (parser->tokens_avail >= 2)
846 {
847 parser->tokens[0] = parser->tokens[1];
848 if (parser->tokens_avail >= 3)
852f0ae8
KK
849 {
850 parser->tokens[1] = parser->tokens[2];
851 if (parser->tokens_avail >= 4)
852 parser->tokens[2] = parser->tokens[3];
853 }
4e03c3a7 854 }
27bf414c
JM
855 parser->tokens_avail--;
856}
857
bc4071dd
RH
858/* Expect the current token to be a #pragma. Consume it and remember
859 that we've begun parsing a pragma. */
860
861static void
862c_parser_consume_pragma (c_parser *parser)
863{
864 gcc_assert (!parser->in_pragma);
865 gcc_assert (parser->tokens_avail >= 1);
866 gcc_assert (parser->tokens[0].type == CPP_PRAGMA);
acf0174b
JJ
867 if (parser->tokens != &parser->tokens_buf[0])
868 parser->tokens++;
4e03c3a7
JM
869 else if (parser->tokens_avail >= 2)
870 {
871 parser->tokens[0] = parser->tokens[1];
872 if (parser->tokens_avail >= 3)
873 parser->tokens[1] = parser->tokens[2];
874 }
bc4071dd
RH
875 parser->tokens_avail--;
876 parser->in_pragma = true;
877}
878
8400e75e 879/* Update the global input_location from TOKEN. */
27bf414c
JM
880static inline void
881c_parser_set_source_position_from_token (c_token *token)
882{
883 if (token->type != CPP_EOF)
884 {
885 input_location = token->location;
27bf414c
JM
886 }
887}
888
de67c4c3
DM
889/* Helper function for c_parser_error.
890 Having peeked a token of kind TOK1_KIND that might signify
891 a conflict marker, peek successor tokens to determine
892 if we actually do have a conflict marker.
893 Specifically, we consider a run of 7 '<', '=' or '>' characters
894 at the start of a line as a conflict marker.
895 These come through the lexer as three pairs and a single,
896 e.g. three CPP_LSHIFT ("<<") and a CPP_LESS ('<').
897 If it returns true, *OUT_LOC is written to with the location/range
898 of the marker. */
899
900static bool
901c_parser_peek_conflict_marker (c_parser *parser, enum cpp_ttype tok1_kind,
902 location_t *out_loc)
903{
904 c_token *token2 = c_parser_peek_2nd_token (parser);
905 if (token2->type != tok1_kind)
906 return false;
907 c_token *token3 = c_parser_peek_nth_token (parser, 3);
908 if (token3->type != tok1_kind)
909 return false;
910 c_token *token4 = c_parser_peek_nth_token (parser, 4);
911 if (token4->type != conflict_marker_get_final_tok_kind (tok1_kind))
912 return false;
913
914 /* It must be at the start of the line. */
915 location_t start_loc = c_parser_peek_token (parser)->location;
916 if (LOCATION_COLUMN (start_loc) != 1)
917 return false;
918
919 /* We have a conflict marker. Construct a location of the form:
920 <<<<<<<
921 ^~~~~~~
922 with start == caret, finishing at the end of the marker. */
923 location_t finish_loc = get_finish (token4->location);
924 *out_loc = make_location (start_loc, start_loc, finish_loc);
925
926 return true;
927}
928
27bf414c
JM
929/* Issue a diagnostic of the form
930 FILE:LINE: MESSAGE before TOKEN
931 where TOKEN is the next token in the input stream of PARSER.
932 MESSAGE (specified by the caller) is usually of the form "expected
933 OTHER-TOKEN".
934
32129a17
DM
935 Use RICHLOC as the location of the diagnostic.
936
27bf414c
JM
937 Do not issue a diagnostic if still recovering from an error.
938
32129a17
DM
939 Return true iff an error was actually emitted.
940
27bf414c
JM
941 ??? This is taken from the C++ parser, but building up messages in
942 this way is not i18n-friendly and some other approach should be
943 used. */
944
32129a17
DM
945static bool
946c_parser_error_richloc (c_parser *parser, const char *gmsgid,
947 rich_location *richloc)
27bf414c
JM
948{
949 c_token *token = c_parser_peek_token (parser);
950 if (parser->error)
32129a17 951 return false;
27bf414c 952 parser->error = true;
4b794eaf 953 if (!gmsgid)
32129a17 954 return false;
de67c4c3
DM
955
956 /* If this is actually a conflict marker, report it as such. */
957 if (token->type == CPP_LSHIFT
958 || token->type == CPP_RSHIFT
959 || token->type == CPP_EQ_EQ)
960 {
961 location_t loc;
962 if (c_parser_peek_conflict_marker (parser, token->type, &loc))
963 {
964 error_at (loc, "version control conflict marker in file");
32129a17 965 return true;
de67c4c3
DM
966 }
967 }
968
4b794eaf 969 c_parse_error (gmsgid,
27bf414c
JM
970 /* Because c_parse_error does not understand
971 CPP_KEYWORD, keywords are treated like
972 identifiers. */
973 (token->type == CPP_KEYWORD ? CPP_NAME : token->type),
cfc93532
MLI
974 /* ??? The C parser does not save the cpp flags of a
975 token, we need to pass 0 here and we will not get
976 the source spelling of some tokens but rather the
977 canonical spelling. */
32129a17
DM
978 token->value, /*flags=*/0, richloc);
979 return true;
980}
981
982/* As c_parser_error_richloc, but issue the message at the
983 location of PARSER's next token, or at input_location
984 if the next token is EOF. */
985
986bool
987c_parser_error (c_parser *parser, const char *gmsgid)
988{
989 c_token *token = c_parser_peek_token (parser);
990 c_parser_set_source_position_from_token (token);
991 rich_location richloc (line_table, input_location);
992 return c_parser_error_richloc (parser, gmsgid, &richloc);
993}
994
995/* Some tokens naturally come in pairs e.g.'(' and ')'.
996 This class is for tracking such a matching pair of symbols.
997 In particular, it tracks the location of the first token,
998 so that if the second token is missing, we can highlight the
999 location of the first token when notifying the user about the
1000 problem. */
1001
1002template <typename traits_t>
1003class token_pair
1004{
1005 public:
1006 /* token_pair's ctor. */
1007 token_pair () : m_open_loc (UNKNOWN_LOCATION) {}
1008
1009 /* If the next token is the opening symbol for this pair, consume it and
1010 return true.
1011 Otherwise, issue an error and return false.
1012 In either case, record the location of the opening token. */
1013
1014 bool require_open (c_parser *parser)
1015 {
1016 c_token *token = c_parser_peek_token (parser);
1017 if (token)
1018 m_open_loc = token->location;
1019
1020 return c_parser_require (parser, traits_t::open_token_type,
1021 traits_t::open_gmsgid);
1022 }
1023
1024 /* Consume the next token from PARSER, recording its location as
1025 that of the opening token within the pair. */
1026
1027 void consume_open (c_parser *parser)
1028 {
1029 c_token *token = c_parser_peek_token (parser);
1030 gcc_assert (token->type == traits_t::open_token_type);
1031 m_open_loc = token->location;
1032 c_parser_consume_token (parser);
1033 }
1034
1035 /* If the next token is the closing symbol for this pair, consume it
1036 and return true.
1037 Otherwise, issue an error, highlighting the location of the
1038 corresponding opening token, and return false. */
1039
1040 bool require_close (c_parser *parser) const
1041 {
1042 return c_parser_require (parser, traits_t::close_token_type,
1043 traits_t::close_gmsgid, m_open_loc);
1044 }
1045
1046 /* Like token_pair::require_close, except that tokens will be skipped
1047 until the desired token is found. An error message is still produced
1048 if the next token is not as expected. */
1049
1050 void skip_until_found_close (c_parser *parser) const
1051 {
1052 c_parser_skip_until_found (parser, traits_t::close_token_type,
1053 traits_t::close_gmsgid, m_open_loc);
1054 }
1055
1056 private:
1057 location_t m_open_loc;
1058};
1059
1060/* Traits for token_pair<T> for tracking matching pairs of parentheses. */
1061
1062struct matching_paren_traits
1063{
1064 static const enum cpp_ttype open_token_type = CPP_OPEN_PAREN;
1065 static const char * const open_gmsgid;
1066 static const enum cpp_ttype close_token_type = CPP_CLOSE_PAREN;
1067 static const char * const close_gmsgid;
1068};
1069
1070const char * const matching_paren_traits::open_gmsgid = "expected %<(%>";
1071const char * const matching_paren_traits::close_gmsgid = "expected %<)%>";
1072
1073/* "matching_parens" is a token_pair<T> class for tracking matching
1074 pairs of parentheses. */
1075
1076typedef token_pair<matching_paren_traits> matching_parens;
1077
1078/* Traits for token_pair<T> for tracking matching pairs of braces. */
1079
1080struct matching_brace_traits
1081{
1082 static const enum cpp_ttype open_token_type = CPP_OPEN_BRACE;
1083 static const char * const open_gmsgid;
1084 static const enum cpp_ttype close_token_type = CPP_CLOSE_BRACE;
1085 static const char * const close_gmsgid;
1086};
1087
1088const char * const matching_brace_traits::open_gmsgid = "expected %<{%>";
1089const char * const matching_brace_traits::close_gmsgid = "expected %<}%>";
1090
1091/* "matching_braces" is a token_pair<T> class for tracking matching
1092 pairs of braces. */
1093
1094typedef token_pair<matching_brace_traits> matching_braces;
1095
1096/* Get a description of the matching symbol to TYPE e.g. "(" for
1097 CPP_CLOSE_PAREN. */
1098
1099static const char *
1100get_matching_symbol (enum cpp_ttype type)
1101{
1102 switch (type)
1103 {
1104 default:
1105 gcc_unreachable ();
1106 return "";
1107 case CPP_CLOSE_PAREN:
1108 return "(";
1109 case CPP_CLOSE_BRACE:
1110 return "{";
1111 }
27bf414c
JM
1112}
1113
1114/* If the next token is of the indicated TYPE, consume it. Otherwise,
1115 issue the error MSGID. If MSGID is NULL then a message has already
1116 been produced and no message will be produced this time. Returns
32129a17
DM
1117 true if found, false otherwise.
1118
1119 If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1120 within any error as the location of an "opening" token matching
1121 the close token TYPE (e.g. the location of the '(' when TYPE is
62e1c678
DM
1122 CPP_CLOSE_PAREN).
1123
1124 If TYPE_IS_UNIQUE is true (the default) then msgid describes exactly
1125 one type (e.g. "expected %<)%>") and thus it may be reasonable to
1126 attempt to generate a fix-it hint for the problem.
1127 Otherwise msgid describes multiple token types (e.g.
1128 "expected %<;%>, %<,%> or %<)%>"), and thus we shouldn't attempt to
1129 generate a fix-it hint. */
27bf414c 1130
1ee62b92 1131bool
27bf414c
JM
1132c_parser_require (c_parser *parser,
1133 enum cpp_ttype type,
32129a17 1134 const char *msgid,
62e1c678
DM
1135 location_t matching_location,
1136 bool type_is_unique)
27bf414c
JM
1137{
1138 if (c_parser_next_token_is (parser, type))
1139 {
1140 c_parser_consume_token (parser);
1141 return true;
1142 }
1143 else
1144 {
32129a17
DM
1145 location_t next_token_loc = c_parser_peek_token (parser)->location;
1146 gcc_rich_location richloc (next_token_loc);
1147
62e1c678
DM
1148 /* Potentially supply a fix-it hint, suggesting to add the
1149 missing token immediately after the *previous* token.
1150 This may move the primary location within richloc. */
1151 if (!parser->error && type_is_unique)
1152 maybe_suggest_missing_token_insertion (&richloc, type,
1153 parser->last_token_location);
1154
32129a17
DM
1155 /* If matching_location != UNKNOWN_LOCATION, highlight it.
1156 Attempt to consolidate diagnostics by printing it as a
1157 secondary range within the main diagnostic. */
1158 bool added_matching_location = false;
1159 if (matching_location != UNKNOWN_LOCATION)
1160 added_matching_location
1161 = richloc.add_location_if_nearby (matching_location);
1162
1163 if (c_parser_error_richloc (parser, msgid, &richloc))
1164 /* If we weren't able to consolidate matching_location, then
1165 print it as a secondary diagnostic. */
1166 if (matching_location != UNKNOWN_LOCATION && !added_matching_location)
1167 inform (matching_location, "to match this %qs",
1168 get_matching_symbol (type));
1169
27bf414c
JM
1170 return false;
1171 }
1172}
1173
1174/* If the next token is the indicated keyword, consume it. Otherwise,
1175 issue the error MSGID. Returns true if found, false otherwise. */
1176
1177static bool
1178c_parser_require_keyword (c_parser *parser,
1179 enum rid keyword,
1180 const char *msgid)
1181{
1182 if (c_parser_next_token_is_keyword (parser, keyword))
1183 {
1184 c_parser_consume_token (parser);
1185 return true;
1186 }
1187 else
1188 {
1189 c_parser_error (parser, msgid);
1190 return false;
1191 }
1192}
1193
1194/* Like c_parser_require, except that tokens will be skipped until the
1195 desired token is found. An error message is still produced if the
1196 next token is not as expected. If MSGID is NULL then a message has
1197 already been produced and no message will be produced this
32129a17
DM
1198 time.
1199
1200 If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1201 within any error as the location of an "opening" token matching
1202 the close token TYPE (e.g. the location of the '(' when TYPE is
1203 CPP_CLOSE_PAREN). */
27bf414c 1204
1ee62b92 1205void
27bf414c
JM
1206c_parser_skip_until_found (c_parser *parser,
1207 enum cpp_ttype type,
32129a17
DM
1208 const char *msgid,
1209 location_t matching_location)
27bf414c
JM
1210{
1211 unsigned nesting_depth = 0;
1212
32129a17 1213 if (c_parser_require (parser, type, msgid, matching_location))
27bf414c
JM
1214 return;
1215
1216 /* Skip tokens until the desired token is found. */
1217 while (true)
1218 {
1219 /* Peek at the next token. */
1220 c_token *token = c_parser_peek_token (parser);
1221 /* If we've reached the token we want, consume it and stop. */
1222 if (token->type == type && !nesting_depth)
1223 {
1224 c_parser_consume_token (parser);
1225 break;
1226 }
bc4071dd 1227
27bf414c
JM
1228 /* If we've run out of tokens, stop. */
1229 if (token->type == CPP_EOF)
1230 return;
bc4071dd
RH
1231 if (token->type == CPP_PRAGMA_EOL && parser->in_pragma)
1232 return;
27bf414c
JM
1233 if (token->type == CPP_OPEN_BRACE
1234 || token->type == CPP_OPEN_PAREN
1235 || token->type == CPP_OPEN_SQUARE)
1236 ++nesting_depth;
1237 else if (token->type == CPP_CLOSE_BRACE
1238 || token->type == CPP_CLOSE_PAREN
1239 || token->type == CPP_CLOSE_SQUARE)
1240 {
1241 if (nesting_depth-- == 0)
1242 break;
1243 }
1244 /* Consume this token. */
1245 c_parser_consume_token (parser);
1246 }
1247 parser->error = false;
1248}
1249
1250/* Skip tokens until the end of a parameter is found, but do not
1251 consume the comma, semicolon or closing delimiter. */
1252
1253static void
1254c_parser_skip_to_end_of_parameter (c_parser *parser)
1255{
1256 unsigned nesting_depth = 0;
1257
1258 while (true)
1259 {
1260 c_token *token = c_parser_peek_token (parser);
1261 if ((token->type == CPP_COMMA || token->type == CPP_SEMICOLON)
1262 && !nesting_depth)
1263 break;
1264 /* If we've run out of tokens, stop. */
1265 if (token->type == CPP_EOF)
1266 return;
bc4071dd
RH
1267 if (token->type == CPP_PRAGMA_EOL && parser->in_pragma)
1268 return;
27bf414c
JM
1269 if (token->type == CPP_OPEN_BRACE
1270 || token->type == CPP_OPEN_PAREN
1271 || token->type == CPP_OPEN_SQUARE)
1272 ++nesting_depth;
1273 else if (token->type == CPP_CLOSE_BRACE
1274 || token->type == CPP_CLOSE_PAREN
1275 || token->type == CPP_CLOSE_SQUARE)
1276 {
1277 if (nesting_depth-- == 0)
1278 break;
1279 }
1280 /* Consume this token. */
1281 c_parser_consume_token (parser);
1282 }
1283 parser->error = false;
1284}
1285
bc4071dd
RH
1286/* Expect to be at the end of the pragma directive and consume an
1287 end of line marker. */
1288
1289static void
62021f64 1290c_parser_skip_to_pragma_eol (c_parser *parser, bool error_if_not_eol = true)
bc4071dd
RH
1291{
1292 gcc_assert (parser->in_pragma);
1293 parser->in_pragma = false;
1294
62021f64
TB
1295 if (error_if_not_eol && c_parser_peek_token (parser)->type != CPP_PRAGMA_EOL)
1296 c_parser_error (parser, "expected end of line");
1297
1298 cpp_ttype token_type;
1299 do
1300 {
1301 c_token *token = c_parser_peek_token (parser);
1302 token_type = token->type;
1303 if (token_type == CPP_EOF)
1304 break;
1305 c_parser_consume_token (parser);
1306 }
1307 while (token_type != CPP_PRAGMA_EOL);
bc4071dd
RH
1308
1309 parser->error = false;
1310}
27bf414c 1311
2a83cc52
RH
1312/* Skip tokens until we have consumed an entire block, or until we
1313 have consumed a non-nested ';'. */
1314
1315static void
1316c_parser_skip_to_end_of_block_or_statement (c_parser *parser)
1317{
1318 unsigned nesting_depth = 0;
1319 bool save_error = parser->error;
1320
1321 while (true)
1322 {
1323 c_token *token;
1324
1325 /* Peek at the next token. */
1326 token = c_parser_peek_token (parser);
1327
1328 switch (token->type)
1329 {
1330 case CPP_EOF:
1331 return;
1332
1333 case CPP_PRAGMA_EOL:
1334 if (parser->in_pragma)
1335 return;
1336 break;
1337
1338 case CPP_SEMICOLON:
1339 /* If the next token is a ';', we have reached the
1340 end of the statement. */
1341 if (!nesting_depth)
1342 {
1343 /* Consume the ';'. */
1344 c_parser_consume_token (parser);
1345 goto finished;
1346 }
1347 break;
1348
1349 case CPP_CLOSE_BRACE:
1350 /* If the next token is a non-nested '}', then we have
1351 reached the end of the current block. */
1352 if (nesting_depth == 0 || --nesting_depth == 0)
1353 {
1354 c_parser_consume_token (parser);
1355 goto finished;
1356 }
1357 break;
1358
1359 case CPP_OPEN_BRACE:
1360 /* If it the next token is a '{', then we are entering a new
1361 block. Consume the entire block. */
1362 ++nesting_depth;
1363 break;
1364
1365 case CPP_PRAGMA:
1366 /* If we see a pragma, consume the whole thing at once. We
1367 have some safeguards against consuming pragmas willy-nilly.
1368 Normally, we'd expect to be here with parser->error set,
1369 which disables these safeguards. But it's possible to get
1370 here for secondary error recovery, after parser->error has
1371 been cleared. */
1372 c_parser_consume_pragma (parser);
1373 c_parser_skip_to_pragma_eol (parser);
1374 parser->error = save_error;
1375 continue;
9e33de05
RS
1376
1377 default:
1378 break;
2a83cc52
RH
1379 }
1380
1381 c_parser_consume_token (parser);
1382 }
1383
1384 finished:
1385 parser->error = false;
1386}
1387
d2e796ad
MLI
1388/* CPP's options (initialized by c-opts.c). */
1389extern cpp_options *cpp_opts;
1390
27bf414c
JM
1391/* Save the warning flags which are controlled by __extension__. */
1392
1393static inline int
1394disable_extension_diagnostics (void)
1395{
1396 int ret = (pedantic
1397 | (warn_pointer_arith << 1)
1398 | (warn_traditional << 2)
d2e796ad 1399 | (flag_iso << 3)
24b97832 1400 | (warn_long_long << 4)
b3ab9ea2 1401 | (warn_cxx_compat << 5)
f3bede71 1402 | (warn_overlength_strings << 6)
177cce46
MP
1403 /* warn_c90_c99_compat has three states: -1/0/1, so we must
1404 play tricks to properly restore it. */
1405 | ((warn_c90_c99_compat == 1) << 7)
35aff4fb
MP
1406 | ((warn_c90_c99_compat == -1) << 8)
1407 /* Similarly for warn_c99_c11_compat. */
1408 | ((warn_c99_c11_compat == 1) << 9)
1409 | ((warn_c99_c11_compat == -1) << 10)
9f936c86
JM
1410 /* Similarly for warn_c11_c2x_compat. */
1411 | ((warn_c11_c2x_compat == 1) << 11)
1412 | ((warn_c11_c2x_compat == -1) << 12)
35aff4fb 1413 );
e3339d0f 1414 cpp_opts->cpp_pedantic = pedantic = 0;
27bf414c 1415 warn_pointer_arith = 0;
e3339d0f 1416 cpp_opts->cpp_warn_traditional = warn_traditional = 0;
27bf414c 1417 flag_iso = 0;
e3339d0f 1418 cpp_opts->cpp_warn_long_long = warn_long_long = 0;
24b97832 1419 warn_cxx_compat = 0;
b3ab9ea2 1420 warn_overlength_strings = 0;
f3bede71 1421 warn_c90_c99_compat = 0;
35aff4fb 1422 warn_c99_c11_compat = 0;
9f936c86 1423 warn_c11_c2x_compat = 0;
27bf414c
JM
1424 return ret;
1425}
1426
1427/* Restore the warning flags which are controlled by __extension__.
1428 FLAGS is the return value from disable_extension_diagnostics. */
1429
1430static inline void
1431restore_extension_diagnostics (int flags)
1432{
e3339d0f 1433 cpp_opts->cpp_pedantic = pedantic = flags & 1;
27bf414c 1434 warn_pointer_arith = (flags >> 1) & 1;
e3339d0f 1435 cpp_opts->cpp_warn_traditional = warn_traditional = (flags >> 2) & 1;
27bf414c 1436 flag_iso = (flags >> 3) & 1;
e3339d0f 1437 cpp_opts->cpp_warn_long_long = warn_long_long = (flags >> 4) & 1;
24b97832 1438 warn_cxx_compat = (flags >> 5) & 1;
b3ab9ea2 1439 warn_overlength_strings = (flags >> 6) & 1;
177cce46
MP
1440 /* See above for why is this needed. */
1441 warn_c90_c99_compat = (flags >> 7) & 1 ? 1 : ((flags >> 8) & 1 ? -1 : 0);
35aff4fb 1442 warn_c99_c11_compat = (flags >> 9) & 1 ? 1 : ((flags >> 10) & 1 ? -1 : 0);
9f936c86 1443 warn_c11_c2x_compat = (flags >> 11) & 1 ? 1 : ((flags >> 12) & 1 ? -1 : 0);
27bf414c
JM
1444}
1445
0b212d8c
TS
1446/* Helper data structure for parsing #pragma acc routine. */
1447struct oacc_routine_data {
ae9281fc
TS
1448 bool error_seen; /* Set if error has been reported. */
1449 bool fndecl_seen; /* Set if one fn decl/definition has been seen already. */
0b212d8c
TS
1450 tree clauses;
1451 location_t loc;
1452};
1453
4e03c3a7
JM
1454static bool c_parser_nth_token_starts_std_attributes (c_parser *,
1455 unsigned int);
1456static tree c_parser_std_attribute_specifier_sequence (c_parser *);
27bf414c
JM
1457static void c_parser_external_declaration (c_parser *);
1458static void c_parser_asm_definition (c_parser *);
32912286 1459static void c_parser_declaration_or_fndef (c_parser *, bool, bool, bool,
3a40d81d 1460 bool, bool, tree *, vec<c_token>,
4e03c3a7
JM
1461 bool have_attrs = false,
1462 tree attrs = NULL,
81fea426
MP
1463 struct oacc_routine_data * = NULL,
1464 bool * = NULL);
32912286
JM
1465static void c_parser_static_assert_declaration_no_semi (c_parser *);
1466static void c_parser_static_assert_declaration (c_parser *);
27bf414c
JM
1467static struct c_typespec c_parser_enum_specifier (c_parser *);
1468static struct c_typespec c_parser_struct_or_union_specifier (c_parser *);
1469static tree c_parser_struct_declaration (c_parser *);
1470static struct c_typespec c_parser_typeof_specifier (c_parser *);
d19fa6b5 1471static tree c_parser_alignas_specifier (c_parser *);
27bf414c
JM
1472static struct c_declarator *c_parser_direct_declarator (c_parser *, bool,
1473 c_dtr_syn, bool *);
1474static struct c_declarator *c_parser_direct_declarator_inner (c_parser *,
1475 bool,
1476 struct c_declarator *);
4e03c3a7
JM
1477static struct c_arg_info *c_parser_parms_declarator (c_parser *, bool, tree,
1478 bool);
a04a722b 1479static struct c_arg_info *c_parser_parms_list_declarator (c_parser *, tree,
4e03c3a7
JM
1480 tree, bool);
1481static struct c_parm *c_parser_parameter_declaration (c_parser *, tree, bool);
27bf414c 1482static tree c_parser_simple_asm_expr (c_parser *);
783bfe5e 1483static tree c_parser_gnu_attributes (c_parser *);
27bf414c 1484static struct c_expr c_parser_initializer (c_parser *);
16595a1f
BS
1485static struct c_expr c_parser_braced_init (c_parser *, tree, bool,
1486 struct obstack *);
a1e3b3d9
LB
1487static void c_parser_initelt (c_parser *, struct obstack *);
1488static void c_parser_initval (c_parser *, struct c_expr *,
1489 struct obstack *);
9def91e9
JJ
1490static tree c_parser_compound_statement (c_parser *, location_t * = NULL);
1491static location_t c_parser_compound_statement_nostart (c_parser *);
27bf414c 1492static void c_parser_label (c_parser *);
3e2becc4 1493static void c_parser_statement (c_parser *, bool *, location_t * = NULL);
99cd9857
MP
1494static void c_parser_statement_after_labels (c_parser *, bool *,
1495 vec<tree> * = NULL);
3e2becc4
MP
1496static tree c_parser_c99_block_statement (c_parser *, bool *,
1497 location_t * = NULL);
99cd9857 1498static void c_parser_if_statement (c_parser *, bool *, vec<tree> *);
351f85c5 1499static void c_parser_switch_statement (c_parser *, bool *);
170a8bd6
EB
1500static void c_parser_while_statement (c_parser *, bool, unsigned short, bool *);
1501static void c_parser_do_statement (c_parser *, bool, unsigned short);
1502static void c_parser_for_statement (c_parser *, bool, unsigned short, bool *);
27bf414c 1503static tree c_parser_asm_statement (c_parser *);
eadd3d0d 1504static tree c_parser_asm_operands (c_parser *);
1c384bf1 1505static tree c_parser_asm_goto_operands (c_parser *);
27bf414c 1506static tree c_parser_asm_clobbers (c_parser *);
acf0174b
JJ
1507static struct c_expr c_parser_expr_no_commas (c_parser *, struct c_expr *,
1508 tree = NULL_TREE);
27bf414c 1509static struct c_expr c_parser_conditional_expression (c_parser *,
acf0174b 1510 struct c_expr *, tree);
20906c66 1511static struct c_expr c_parser_binary_expression (c_parser *, struct c_expr *,
acf0174b 1512 tree);
27bf414c
JM
1513static struct c_expr c_parser_cast_expression (c_parser *, struct c_expr *);
1514static struct c_expr c_parser_unary_expression (c_parser *);
1515static struct c_expr c_parser_sizeof_expression (c_parser *);
1516static struct c_expr c_parser_alignof_expression (c_parser *);
1517static struct c_expr c_parser_postfix_expression (c_parser *);
1518static struct c_expr c_parser_postfix_expression_after_paren_type (c_parser *,
24b97832
ILT
1519 struct c_type_name *,
1520 location_t);
27bf414c 1521static struct c_expr c_parser_postfix_expression_after_primary (c_parser *,
c2255bc4 1522 location_t loc,
27bf414c 1523 struct c_expr);
0a35513e
AH
1524static tree c_parser_transaction (c_parser *, enum rid);
1525static struct c_expr c_parser_transaction_expression (c_parser *, enum rid);
1526static tree c_parser_transaction_cancel (c_parser *);
27bf414c 1527static struct c_expr c_parser_expression (c_parser *);
46bdb9cf 1528static struct c_expr c_parser_expression_conv (c_parser *);
9771b263
DN
1529static vec<tree, va_gc> *c_parser_expr_list (c_parser *, bool, bool,
1530 vec<tree, va_gc> **, location_t *,
b108f48f
JJ
1531 tree *, vec<location_t> *,
1532 unsigned int * = NULL);
98f08eb8
MS
1533static struct c_expr c_parser_has_attribute_expression (c_parser *);
1534
6e232ba4 1535static void c_parser_oacc_declare (c_parser *);
41dbbb37
TS
1536static void c_parser_oacc_enter_exit_data (c_parser *, bool);
1537static void c_parser_oacc_update (c_parser *);
dda1bf61 1538static void c_parser_omp_construct (c_parser *, bool *);
953ff289
DN
1539static void c_parser_omp_threadprivate (c_parser *);
1540static void c_parser_omp_barrier (c_parser *);
28567c40 1541static void c_parser_omp_depobj (c_parser *);
953ff289 1542static void c_parser_omp_flush (c_parser *);
41dbbb37 1543static tree c_parser_omp_for_loop (location_t, c_parser *, enum tree_code,
dda1bf61 1544 tree, tree *, bool *);
a68ab351 1545static void c_parser_omp_taskwait (c_parser *);
20906c66 1546static void c_parser_omp_taskyield (c_parser *);
acf0174b 1547static void c_parser_omp_cancel (c_parser *);
27bf414c 1548
acf0174b
JJ
1549enum pragma_context { pragma_external, pragma_struct, pragma_param,
1550 pragma_stmt, pragma_compound };
dda1bf61 1551static bool c_parser_pragma (c_parser *, enum pragma_context, bool *);
54d19c3b 1552static void c_parser_omp_cancellation_point (c_parser *, enum pragma_context);
dda1bf61 1553static bool c_parser_omp_target (c_parser *, enum pragma_context, bool *);
acf0174b
JJ
1554static void c_parser_omp_end_declare_target (c_parser *);
1555static void c_parser_omp_declare (c_parser *, enum pragma_context);
28567c40 1556static void c_parser_omp_requires (c_parser *);
dda1bf61 1557static bool c_parser_omp_ordered (c_parser *, enum pragma_context, bool *);
0b212d8c 1558static void c_parser_oacc_routine (c_parser *, enum pragma_context);
bc4071dd 1559
27bf414c
JM
1560/* These Objective-C parser functions are only ever called when
1561 compiling Objective-C. */
c165dca7 1562static void c_parser_objc_class_definition (c_parser *, tree);
27bf414c
JM
1563static void c_parser_objc_class_instance_variables (c_parser *);
1564static void c_parser_objc_class_declaration (c_parser *);
1565static void c_parser_objc_alias_declaration (c_parser *);
c165dca7 1566static void c_parser_objc_protocol_definition (c_parser *, tree);
249a82c4 1567static bool c_parser_objc_method_type (c_parser *);
27bf414c
JM
1568static void c_parser_objc_method_definition (c_parser *);
1569static void c_parser_objc_methodprotolist (c_parser *);
1570static void c_parser_objc_methodproto (c_parser *);
a04a722b 1571static tree c_parser_objc_method_decl (c_parser *, bool, tree *, tree *);
27bf414c
JM
1572static tree c_parser_objc_type_name (c_parser *);
1573static tree c_parser_objc_protocol_refs (c_parser *);
437c2322 1574static void c_parser_objc_try_catch_finally_statement (c_parser *);
27bf414c
JM
1575static void c_parser_objc_synchronized_statement (c_parser *);
1576static tree c_parser_objc_selector (c_parser *);
1577static tree c_parser_objc_selector_arg (c_parser *);
1578static tree c_parser_objc_receiver (c_parser *);
1579static tree c_parser_objc_message_args (c_parser *);
1580static tree c_parser_objc_keywordexpr (c_parser *);
f614132b 1581static void c_parser_objc_at_property_declaration (c_parser *);
da57d1b9
NP
1582static void c_parser_objc_at_synthesize_declaration (c_parser *);
1583static void c_parser_objc_at_dynamic_declaration (c_parser *);
668ea4b1 1584static bool c_parser_objc_diagnose_bad_element_prefix
c165dca7 1585 (c_parser *, struct c_declspecs *);
9def91e9 1586static location_t c_parser_parse_rtl_body (c_parser *, char *);
c2e84327 1587
31dc71a8 1588/* Parse a translation unit (C90 6.7, C99 6.9, C11 6.9).
27bf414c
JM
1589
1590 translation-unit:
1591 external-declarations
1592
1593 external-declarations:
1594 external-declaration
1595 external-declarations external-declaration
1596
1597 GNU extensions:
1598
1599 translation-unit:
1600 empty
1601*/
1602
1603static void
1604c_parser_translation_unit (c_parser *parser)
1605{
1606 if (c_parser_next_token_is (parser, CPP_EOF))
1607 {
c1771a20 1608 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
509c9d60 1609 "ISO C forbids an empty translation unit");
27bf414c
JM
1610 }
1611 else
1612 {
1613 void *obstack_position = obstack_alloc (&parser_obstack, 0);
6ec637a4 1614 mark_valid_location_for_stdc_pragma (false);
27bf414c
JM
1615 do
1616 {
1617 ggc_collect ();
1618 c_parser_external_declaration (parser);
1619 obstack_free (&parser_obstack, obstack_position);
1620 }
1621 while (c_parser_next_token_is_not (parser, CPP_EOF));
1622 }
d25c7690 1623
13f92e8d
JJ
1624 unsigned int i;
1625 tree decl;
1626 FOR_EACH_VEC_ELT (incomplete_record_decls, i, decl)
1627 if (DECL_SIZE (decl) == NULL_TREE && TREE_TYPE (decl) != error_mark_node)
686e2237 1628 error ("storage size of %q+D isn%'t known", decl);
7cec9588
JJ
1629
1630 if (current_omp_declare_target_attribute)
1631 {
1632 if (!errorcount)
1633 error ("%<#pragma omp declare target%> without corresponding "
1634 "%<#pragma omp end declare target%>");
1635 current_omp_declare_target_attribute = 0;
1636 }
27bf414c
JM
1637}
1638
31dc71a8 1639/* Parse an external declaration (C90 6.7, C99 6.9, C11 6.9).
27bf414c
JM
1640
1641 external-declaration:
1642 function-definition
1643 declaration
1644
1645 GNU extensions:
1646
1647 external-declaration:
1648 asm-definition
1649 ;
1650 __extension__ external-declaration
1651
1652 Objective-C:
1653
1654 external-declaration:
1655 objc-class-definition
1656 objc-class-declaration
1657 objc-alias-declaration
1658 objc-protocol-definition
1659 objc-method-definition
1660 @end
1661*/
1662
1663static void
1664c_parser_external_declaration (c_parser *parser)
1665{
1666 int ext;
1667 switch (c_parser_peek_token (parser)->type)
1668 {
1669 case CPP_KEYWORD:
1670 switch (c_parser_peek_token (parser)->keyword)
1671 {
1672 case RID_EXTENSION:
1673 ext = disable_extension_diagnostics ();
1674 c_parser_consume_token (parser);
1675 c_parser_external_declaration (parser);
1676 restore_extension_diagnostics (ext);
1677 break;
1678 case RID_ASM:
1679 c_parser_asm_definition (parser);
1680 break;
1681 case RID_AT_INTERFACE:
1682 case RID_AT_IMPLEMENTATION:
1683 gcc_assert (c_dialect_objc ());
c165dca7 1684 c_parser_objc_class_definition (parser, NULL_TREE);
27bf414c 1685 break;
49b91f05 1686 case RID_AT_CLASS:
27bf414c
JM
1687 gcc_assert (c_dialect_objc ());
1688 c_parser_objc_class_declaration (parser);
1689 break;
1690 case RID_AT_ALIAS:
1691 gcc_assert (c_dialect_objc ());
1692 c_parser_objc_alias_declaration (parser);
1693 break;
1694 case RID_AT_PROTOCOL:
1695 gcc_assert (c_dialect_objc ());
c165dca7 1696 c_parser_objc_protocol_definition (parser, NULL_TREE);
27bf414c 1697 break;
668ea4b1
IS
1698 case RID_AT_PROPERTY:
1699 gcc_assert (c_dialect_objc ());
f614132b 1700 c_parser_objc_at_property_declaration (parser);
668ea4b1 1701 break;
da57d1b9
NP
1702 case RID_AT_SYNTHESIZE:
1703 gcc_assert (c_dialect_objc ());
1704 c_parser_objc_at_synthesize_declaration (parser);
1705 break;
1706 case RID_AT_DYNAMIC:
1707 gcc_assert (c_dialect_objc ());
1708 c_parser_objc_at_dynamic_declaration (parser);
1709 break;
27bf414c
JM
1710 case RID_AT_END:
1711 gcc_assert (c_dialect_objc ());
1712 c_parser_consume_token (parser);
1713 objc_finish_implementation ();
1714 break;
1715 default:
1716 goto decl_or_fndef;
1717 }
1718 break;
1719 case CPP_SEMICOLON:
c1771a20 1720 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
509c9d60 1721 "ISO C does not allow extra %<;%> outside of a function");
27bf414c
JM
1722 c_parser_consume_token (parser);
1723 break;
bc4071dd 1724 case CPP_PRAGMA:
6ec637a4 1725 mark_valid_location_for_stdc_pragma (true);
dda1bf61 1726 c_parser_pragma (parser, pragma_external, NULL);
6ec637a4 1727 mark_valid_location_for_stdc_pragma (false);
bc4071dd 1728 break;
27bf414c
JM
1729 case CPP_PLUS:
1730 case CPP_MINUS:
1731 if (c_dialect_objc ())
1732 {
1733 c_parser_objc_method_definition (parser);
1734 break;
1735 }
1736 /* Else fall through, and yield a syntax error trying to parse
1737 as a declaration or function definition. */
191816a3 1738 /* FALLTHRU */
27bf414c
JM
1739 default:
1740 decl_or_fndef:
c165dca7
IS
1741 /* A declaration or a function definition (or, in Objective-C,
1742 an @interface or @protocol with prefix attributes). We can
1743 only tell which after parsing the declaration specifiers, if
1744 any, and the first declarator. */
acf0174b
JJ
1745 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
1746 NULL, vNULL);
27bf414c
JM
1747 break;
1748 }
1749}
1750
acf0174b 1751static void c_finish_omp_declare_simd (c_parser *, tree, tree, vec<c_token>);
ae9281fc 1752static void c_finish_oacc_routine (struct oacc_routine_data *, tree, bool);
acf0174b 1753
96a95ac1
AO
1754/* Build and add a DEBUG_BEGIN_STMT statement with location LOC. */
1755
1756static void
1757add_debug_begin_stmt (location_t loc)
1758{
849bbdb9
JJ
1759 /* Don't add DEBUG_BEGIN_STMTs outside of functions, see PR84721. */
1760 if (!MAY_HAVE_DEBUG_MARKER_STMTS || !building_stmt_list_p ())
96a95ac1
AO
1761 return;
1762
1763 tree stmt = build0 (DEBUG_BEGIN_STMT, void_type_node);
1764 SET_EXPR_LOCATION (stmt, loc);
1765 add_stmt (stmt);
1766}
1767
27bf414c 1768/* Parse a declaration or function definition (C90 6.5, 6.7.1, C99
31dc71a8
MP
1769 6.7, 6.9.1, C11 6.7, 6.9.1). If FNDEF_OK is true, a function definition
1770 is accepted; otherwise (old-style parameter declarations) only other
32912286
JM
1771 declarations are accepted. If STATIC_ASSERT_OK is true, a static
1772 assertion is accepted; otherwise (old-style parameter declarations)
1773 it is not. If NESTED is true, we are inside a function or parsing
1774 old-style parameter declarations; any functions encountered are
1775 nested functions and declaration specifiers are required; otherwise
1776 we are at top level and functions are normal functions and
1777 declaration specifiers may be optional. If EMPTY_OK is true, empty
1778 declarations are OK (subject to all other constraints); otherwise
1779 (old-style parameter declarations) they are diagnosed. If
1780 START_ATTR_OK is true, the declaration specifiers may start with
4e03c3a7 1781 attributes (GNU or standard); otherwise they may not.
f05b9d93
NP
1782 OBJC_FOREACH_OBJECT_DECLARATION can be used to get back the parsed
1783 declaration when parsing an Objective-C foreach statement.
81fea426 1784 FALLTHRU_ATTR_P is used to signal whether this function parsed
4e03c3a7
JM
1785 "__attribute__((fallthrough));". ATTRS are any standard attributes
1786 parsed in the caller (in contexts where such attributes had to be
1787 parsed to determine whether what follows is a declaration or a
1788 statement); HAVE_ATTRS says whether there were any such attributes
1789 (even empty).
27bf414c
JM
1790
1791 declaration:
1792 declaration-specifiers init-declarator-list[opt] ;
32912286 1793 static_assert-declaration
27bf414c
JM
1794
1795 function-definition:
1796 declaration-specifiers[opt] declarator declaration-list[opt]
1797 compound-statement
1798
1799 declaration-list:
1800 declaration
1801 declaration-list declaration
1802
1803 init-declarator-list:
1804 init-declarator
1805 init-declarator-list , init-declarator
1806
1807 init-declarator:
783bfe5e
JM
1808 declarator simple-asm-expr[opt] gnu-attributes[opt]
1809 declarator simple-asm-expr[opt] gnu-attributes[opt] = initializer
27bf414c
JM
1810
1811 GNU extensions:
1812
1813 nested-function-definition:
1814 declaration-specifiers declarator declaration-list[opt]
1815 compound-statement
1816
81fea426
MP
1817 attribute ;
1818
c165dca7 1819 Objective-C:
783bfe5e
JM
1820 gnu-attributes objc-class-definition
1821 gnu-attributes objc-category-definition
1822 gnu-attributes objc-protocol-definition
c165dca7 1823
783bfe5e 1824 The simple-asm-expr and gnu-attributes are GNU extensions.
27bf414c
JM
1825
1826 This function does not handle __extension__; that is handled in its
1827 callers. ??? Following the old parser, __extension__ may start
1828 external declarations, declarations in functions and declarations
1829 at the start of "for" loops, but not old-style parameter
1830 declarations.
1831
1832 C99 requires declaration specifiers in a function definition; the
1833 absence is diagnosed through the diagnosis of implicit int. In GNU
1834 C we also allow but diagnose declarations without declaration
1835 specifiers, but only at top level (elsewhere they conflict with
953ff289 1836 other syntax).
b8698a0f 1837
f05b9d93
NP
1838 In Objective-C, declarations of the looping variable in a foreach
1839 statement are exceptionally terminated by 'in' (for example, 'for
1840 (NSObject *object in array) { ... }').
1841
953ff289 1842 OpenMP:
b8698a0f 1843
953ff289 1844 declaration:
1ee62b92
PG
1845 threadprivate-directive
1846
1847 GIMPLE:
1848
1849 gimple-function-definition:
c2e84327
DM
1850 declaration-specifiers[opt] __GIMPLE (gimple-or-rtl-pass-list) declarator
1851 declaration-list[opt] compound-statement
1852
1853 rtl-function-definition:
1854 declaration-specifiers[opt] __RTL (gimple-or-rtl-pass-list) declarator
1ee62b92 1855 declaration-list[opt] compound-statement */
27bf414c
JM
1856
1857static void
32912286
JM
1858c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
1859 bool static_assert_ok, bool empty_ok,
f05b9d93 1860 bool nested, bool start_attr_ok,
acf0174b 1861 tree *objc_foreach_object_declaration,
3a40d81d 1862 vec<c_token> omp_declare_simd_clauses,
4e03c3a7 1863 bool have_attrs, tree attrs,
81fea426
MP
1864 struct oacc_routine_data *oacc_routine_data,
1865 bool *fallthru_attr_p)
27bf414c
JM
1866{
1867 struct c_declspecs *specs;
1868 tree prefix_attrs;
1869 tree all_prefix_attrs;
1870 bool diagnosed_no_specs = false;
c7412148 1871 location_t here = c_parser_peek_token (parser)->location;
bc4071dd 1872
96a95ac1
AO
1873 add_debug_begin_stmt (c_parser_peek_token (parser)->location);
1874
32912286
JM
1875 if (static_assert_ok
1876 && c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
1877 {
1878 c_parser_static_assert_declaration (parser);
1879 return;
1880 }
27bf414c 1881 specs = build_null_declspecs ();
2f413185 1882
4e03c3a7
JM
1883 /* Handle any standard attributes parsed in the caller. */
1884 if (have_attrs)
1885 {
1886 declspecs_add_attrs (here, specs, attrs);
1887 specs->non_std_attrs_seen_p = false;
1888 }
1889
2f413185
PB
1890 /* Try to detect an unknown type name when we have "A B" or "A *B". */
1891 if (c_parser_peek_token (parser)->type == CPP_NAME
1892 && c_parser_peek_token (parser)->id_kind == C_ID_ID
1893 && (c_parser_peek_2nd_token (parser)->type == CPP_NAME
1894 || c_parser_peek_2nd_token (parser)->type == CPP_MULT)
1895 && (!nested || !lookup_name (c_parser_peek_token (parser)->value)))
1896 {
0e36f5c7 1897 tree name = c_parser_peek_token (parser)->value;
1a4f11c8
DM
1898
1899 /* Issue a warning about NAME being an unknown type name, perhaps
1900 with some kind of hint.
1901 If the user forgot a "struct" etc, suggest inserting
1902 it. Otherwise, attempt to look for misspellings. */
1903 gcc_rich_location richloc (here);
0e36f5c7 1904 if (tag_exists_p (RECORD_TYPE, name))
1a4f11c8
DM
1905 {
1906 /* This is not C++ with its implicit typedef. */
254830ba 1907 richloc.add_fixit_insert_before ("struct ");
64a5912c
DM
1908 error_at (&richloc,
1909 "unknown type name %qE;"
1910 " use %<struct%> keyword to refer to the type",
1911 name);
1a4f11c8 1912 }
0e36f5c7 1913 else if (tag_exists_p (UNION_TYPE, name))
1a4f11c8 1914 {
254830ba 1915 richloc.add_fixit_insert_before ("union ");
64a5912c
DM
1916 error_at (&richloc,
1917 "unknown type name %qE;"
1918 " use %<union%> keyword to refer to the type",
1919 name);
1a4f11c8 1920 }
0e36f5c7 1921 else if (tag_exists_p (ENUMERAL_TYPE, name))
1a4f11c8 1922 {
254830ba 1923 richloc.add_fixit_insert_before ("enum ");
64a5912c
DM
1924 error_at (&richloc,
1925 "unknown type name %qE;"
1926 " use %<enum%> keyword to refer to the type",
1927 name);
1a4f11c8
DM
1928 }
1929 else
1930 {
097f82ec 1931 auto_diagnostic_group d;
6c7a259b
DM
1932 name_hint hint = lookup_name_fuzzy (name, FUZZY_LOOKUP_TYPENAME,
1933 here);
7e2de6df 1934 if (const char *suggestion = hint.suggestion ())
1a4f11c8 1935 {
7e2de6df 1936 richloc.add_fixit_replace (suggestion);
64a5912c
DM
1937 error_at (&richloc,
1938 "unknown type name %qE; did you mean %qs?",
7e2de6df 1939 name, suggestion);
1a4f11c8
DM
1940 }
1941 else
1942 error_at (here, "unknown type name %qE", name);
1943 }
2f413185
PB
1944
1945 /* Parse declspecs normally to get a correct pointer type, but avoid
a5812bdc
PB
1946 a further "fails to be a type name" error. Refuse nested functions
1947 since it is not how the user likely wants us to recover. */
2f413185
PB
1948 c_parser_peek_token (parser)->type = CPP_KEYWORD;
1949 c_parser_peek_token (parser)->keyword = RID_VOID;
1950 c_parser_peek_token (parser)->value = error_mark_node;
a5812bdc 1951 fndef_ok = !nested;
2f413185
PB
1952 }
1953
4e03c3a7
JM
1954 /* When there are standard attributes at the start of the
1955 declaration (to apply to the entity being declared), an
1956 init-declarator-list or function definition must be present. */
1957 if (c_parser_nth_token_starts_std_attributes (parser, 1))
1958 have_attrs = true;
1959
568a31f2 1960 c_parser_declspecs (parser, specs, true, true, start_attr_ok,
4e03c3a7 1961 true, true, start_attr_ok, true, cla_nonabstract_decl);
27bf414c
JM
1962 if (parser->error)
1963 {
1964 c_parser_skip_to_end_of_block_or_statement (parser);
1965 return;
1966 }
1967 if (nested && !specs->declspecs_seen_p)
1968 {
1969 c_parser_error (parser, "expected declaration specifiers");
1970 c_parser_skip_to_end_of_block_or_statement (parser);
1971 return;
1972 }
1ee62b92 1973
27bf414c 1974 finish_declspecs (specs);
38b7bc7f 1975 bool auto_type_p = specs->typespec_word == cts_auto_type;
27bf414c
JM
1976 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
1977 {
38b7bc7f
JM
1978 if (auto_type_p)
1979 error_at (here, "%<__auto_type%> in empty declaration");
81fea426
MP
1980 else if (specs->typespec_kind == ctsk_none
1981 && attribute_fallthrough_p (specs->attrs))
1982 {
1983 if (fallthru_attr_p != NULL)
1984 *fallthru_attr_p = true;
f8aea5e3
JM
1985 if (nested)
1986 {
1987 tree fn = build_call_expr_internal_loc (here, IFN_FALLTHROUGH,
1988 void_type_node, 0);
1989 add_stmt (fn);
1990 }
1991 else
1992 pedwarn (here, OPT_Wattributes,
1993 "%<fallthrough%> attribute at top level");
81fea426 1994 }
4e03c3a7
JM
1995 else if (empty_ok && !(have_attrs
1996 && specs->non_std_attrs_seen_p))
27bf414c
JM
1997 shadow_tag (specs);
1998 else
1999 {
2000 shadow_tag_warned (specs, 1);
509c9d60 2001 pedwarn (here, 0, "empty declaration");
27bf414c
JM
2002 }
2003 c_parser_consume_token (parser);
0b212d8c 2004 if (oacc_routine_data)
ae9281fc 2005 c_finish_oacc_routine (oacc_routine_data, NULL_TREE, false);
27bf414c
JM
2006 return;
2007 }
f725e721
PB
2008
2009 /* Provide better error recovery. Note that a type name here is usually
2010 better diagnosed as a redeclaration. */
2011 if (empty_ok
2012 && specs->typespec_kind == ctsk_tagdef
2013 && c_parser_next_token_starts_declspecs (parser)
2014 && !c_parser_next_token_is (parser, CPP_NAME))
2015 {
2016 c_parser_error (parser, "expected %<;%>, identifier or %<(%>");
2017 parser->error = false;
2018 shadow_tag_warned (specs, 1);
2019 return;
2020 }
38b7bc7f 2021 else if (c_dialect_objc () && !auto_type_p)
c165dca7 2022 {
f7e71da5
IS
2023 /* Prefix attributes are an error on method decls. */
2024 switch (c_parser_peek_token (parser)->type)
2025 {
2026 case CPP_PLUS:
2027 case CPP_MINUS:
2028 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2029 return;
2030 if (specs->attrs)
2031 {
2032 warning_at (c_parser_peek_token (parser)->location,
2033 OPT_Wattributes,
2034 "prefix attributes are ignored for methods");
2035 specs->attrs = NULL_TREE;
2036 }
2037 if (fndef_ok)
2038 c_parser_objc_method_definition (parser);
2039 else
2040 c_parser_objc_methodproto (parser);
2041 return;
2042 break;
2043 default:
2044 break;
2045 }
c165dca7
IS
2046 /* This is where we parse 'attributes @interface ...',
2047 'attributes @implementation ...', 'attributes @protocol ...'
2048 (where attributes could be, for example, __attribute__
2049 ((deprecated)).
2050 */
2051 switch (c_parser_peek_token (parser)->keyword)
2052 {
2053 case RID_AT_INTERFACE:
2054 {
2055 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2056 return;
2057 c_parser_objc_class_definition (parser, specs->attrs);
2058 return;
2059 }
2060 break;
2061 case RID_AT_IMPLEMENTATION:
2062 {
2063 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2064 return;
2065 if (specs->attrs)
2066 {
2067 warning_at (c_parser_peek_token (parser)->location,
2068 OPT_Wattributes,
2069 "prefix attributes are ignored for implementations");
2070 specs->attrs = NULL_TREE;
2071 }
2072 c_parser_objc_class_definition (parser, NULL_TREE);
2073 return;
2074 }
2075 break;
2076 case RID_AT_PROTOCOL:
2077 {
2078 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2079 return;
2080 c_parser_objc_protocol_definition (parser, specs->attrs);
2081 return;
2082 }
2083 break;
668ea4b1
IS
2084 case RID_AT_ALIAS:
2085 case RID_AT_CLASS:
2086 case RID_AT_END:
2087 case RID_AT_PROPERTY:
2088 if (specs->attrs)
2089 {
96bbfbac 2090 c_parser_error (parser, "unexpected attribute");
668ea4b1
IS
2091 specs->attrs = NULL;
2092 }
2093 break;
c165dca7
IS
2094 default:
2095 break;
2096 }
2097 }
81fea426
MP
2098 else if (attribute_fallthrough_p (specs->attrs))
2099 warning_at (here, OPT_Wattributes,
2100 "%<fallthrough%> attribute not followed by %<;%>");
2101
27bf414c
JM
2102 pending_xref_error ();
2103 prefix_attrs = specs->attrs;
2104 all_prefix_attrs = prefix_attrs;
2105 specs->attrs = NULL_TREE;
ae9281fc 2106 while (true)
27bf414c
JM
2107 {
2108 struct c_declarator *declarator;
2109 bool dummy = false;
575bfb00 2110 timevar_id_t tv;
1ee62b92 2111 tree fnbody = NULL_TREE;
27bf414c
JM
2112 /* Declaring either one or more declarators (in which case we
2113 should diagnose if there were no declaration specifiers) or a
2114 function definition (in which case the diagnostic for
2115 implicit int suffices). */
9e5b2115
PB
2116 declarator = c_parser_declarator (parser,
2117 specs->typespec_kind != ctsk_none,
27bf414c
JM
2118 C_DTR_NORMAL, &dummy);
2119 if (declarator == NULL)
2120 {
5e9d6aa4 2121 if (omp_declare_simd_clauses.exists ())
acf0174b
JJ
2122 c_finish_omp_declare_simd (parser, NULL_TREE, NULL_TREE,
2123 omp_declare_simd_clauses);
0b212d8c 2124 if (oacc_routine_data)
ae9281fc 2125 c_finish_oacc_routine (oacc_routine_data, NULL_TREE, false);
27bf414c
JM
2126 c_parser_skip_to_end_of_block_or_statement (parser);
2127 return;
2128 }
38b7bc7f
JM
2129 if (auto_type_p && declarator->kind != cdk_id)
2130 {
2131 error_at (here,
2132 "%<__auto_type%> requires a plain identifier"
2133 " as declarator");
2134 c_parser_skip_to_end_of_block_or_statement (parser);
2135 return;
2136 }
27bf414c
JM
2137 if (c_parser_next_token_is (parser, CPP_EQ)
2138 || c_parser_next_token_is (parser, CPP_COMMA)
2139 || c_parser_next_token_is (parser, CPP_SEMICOLON)
2140 || c_parser_next_token_is_keyword (parser, RID_ASM)
f05b9d93
NP
2141 || c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)
2142 || c_parser_next_token_is_keyword (parser, RID_IN))
27bf414c
JM
2143 {
2144 tree asm_name = NULL_TREE;
2145 tree postfix_attrs = NULL_TREE;
2146 if (!diagnosed_no_specs && !specs->declspecs_seen_p)
2147 {
2148 diagnosed_no_specs = true;
509c9d60 2149 pedwarn (here, 0, "data definition has no type or storage class");
27bf414c
JM
2150 }
2151 /* Having seen a data definition, there cannot now be a
2152 function definition. */
2153 fndef_ok = false;
2154 if (c_parser_next_token_is_keyword (parser, RID_ASM))
2155 asm_name = c_parser_simple_asm_expr (parser);
2156 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
ae5ebda4 2157 {
783bfe5e 2158 postfix_attrs = c_parser_gnu_attributes (parser);
ae5ebda4
MP
2159 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
2160 {
2161 /* This means there is an attribute specifier after
2162 the declarator in a function definition. Provide
2163 some more information for the user. */
2164 error_at (here, "attributes should be specified before the "
2165 "declarator in a function definition");
2166 c_parser_skip_to_end_of_block_or_statement (parser);
2167 return;
2168 }
2169 }
27bf414c
JM
2170 if (c_parser_next_token_is (parser, CPP_EQ))
2171 {
2172 tree d;
2173 struct c_expr init;
c2255bc4 2174 location_t init_loc;
27bf414c 2175 c_parser_consume_token (parser);
38b7bc7f
JM
2176 if (auto_type_p)
2177 {
38b7bc7f 2178 init_loc = c_parser_peek_token (parser)->location;
5dd9a9d0
DM
2179 rich_location richloc (line_table, init_loc);
2180 start_init (NULL_TREE, asm_name, global_bindings_p (), &richloc);
36618428
MP
2181 /* A parameter is initialized, which is invalid. Don't
2182 attempt to instrument the initializer. */
2183 int flag_sanitize_save = flag_sanitize;
2184 if (nested && !empty_ok)
2185 flag_sanitize = 0;
38b7bc7f 2186 init = c_parser_expr_no_commas (parser, NULL);
36618428 2187 flag_sanitize = flag_sanitize_save;
38b7bc7f
JM
2188 if (TREE_CODE (init.value) == COMPONENT_REF
2189 && DECL_C_BIT_FIELD (TREE_OPERAND (init.value, 1)))
2190 error_at (here,
2191 "%<__auto_type%> used with a bit-field"
2192 " initializer");
2193 init = convert_lvalue_to_rvalue (init_loc, init, true, true);
2194 tree init_type = TREE_TYPE (init.value);
9698b078 2195 /* As with typeof, remove all qualifiers from atomic types. */
38b7bc7f
JM
2196 if (init_type != error_mark_node && TYPE_ATOMIC (init_type))
2197 init_type
9698b078 2198 = c_build_qualified_type (init_type, TYPE_UNQUALIFIED);
38b7bc7f
JM
2199 bool vm_type = variably_modified_type_p (init_type,
2200 NULL_TREE);
2201 if (vm_type)
b2fa0a8b 2202 init.value = save_expr (init.value);
38b7bc7f
JM
2203 finish_init ();
2204 specs->typespec_kind = ctsk_typeof;
2205 specs->locations[cdw_typedef] = init_loc;
2206 specs->typedef_p = true;
2207 specs->type = init_type;
2208 if (vm_type)
2209 {
2210 bool maybe_const = true;
2211 tree type_expr = c_fully_fold (init.value, false,
2212 &maybe_const);
2213 specs->expr_const_operands &= maybe_const;
2214 if (specs->expr)
2215 specs->expr = build2 (COMPOUND_EXPR,
2216 TREE_TYPE (type_expr),
2217 specs->expr, type_expr);
2218 else
2219 specs->expr = type_expr;
2220 }
2221 d = start_decl (declarator, specs, true,
2222 chainon (postfix_attrs, all_prefix_attrs));
2223 if (!d)
2224 d = error_mark_node;
5e9d6aa4 2225 if (omp_declare_simd_clauses.exists ())
38b7bc7f
JM
2226 c_finish_omp_declare_simd (parser, d, NULL_TREE,
2227 omp_declare_simd_clauses);
2228 }
2229 else
2230 {
2231 /* The declaration of the variable is in effect while
2232 its initializer is parsed. */
2233 d = start_decl (declarator, specs, true,
2234 chainon (postfix_attrs, all_prefix_attrs));
2235 if (!d)
2236 d = error_mark_node;
5e9d6aa4 2237 if (omp_declare_simd_clauses.exists ())
38b7bc7f
JM
2238 c_finish_omp_declare_simd (parser, d, NULL_TREE,
2239 omp_declare_simd_clauses);
38b7bc7f 2240 init_loc = c_parser_peek_token (parser)->location;
5dd9a9d0
DM
2241 rich_location richloc (line_table, init_loc);
2242 start_init (d, asm_name, global_bindings_p (), &richloc);
36618428
MP
2243 /* A parameter is initialized, which is invalid. Don't
2244 attempt to instrument the initializer. */
2245 int flag_sanitize_save = flag_sanitize;
2246 if (TREE_CODE (d) == PARM_DECL)
2247 flag_sanitize = 0;
38b7bc7f 2248 init = c_parser_initializer (parser);
36618428 2249 flag_sanitize = flag_sanitize_save;
38b7bc7f
JM
2250 finish_init ();
2251 }
0b212d8c 2252 if (oacc_routine_data)
ae9281fc 2253 c_finish_oacc_routine (oacc_routine_data, d, false);
27bf414c
JM
2254 if (d != error_mark_node)
2255 {
d033409e 2256 maybe_warn_string_init (init_loc, TREE_TYPE (d), init);
c2255bc4 2257 finish_decl (d, init_loc, init.value,
d033409e 2258 init.original_type, asm_name);
27bf414c
JM
2259 }
2260 }
2261 else
2262 {
38b7bc7f
JM
2263 if (auto_type_p)
2264 {
2265 error_at (here,
2266 "%<__auto_type%> requires an initialized "
2267 "data declaration");
2268 c_parser_skip_to_end_of_block_or_statement (parser);
2269 return;
2270 }
27bf414c
JM
2271 tree d = start_decl (declarator, specs, false,
2272 chainon (postfix_attrs,
2273 all_prefix_attrs));
cfc30fd1
JJ
2274 if (d
2275 && TREE_CODE (d) == FUNCTION_DECL
cfc30fd1
JJ
2276 && DECL_ARGUMENTS (d) == NULL_TREE
2277 && DECL_INITIAL (d) == NULL_TREE)
db376f45
EB
2278 {
2279 /* Find the innermost declarator that is neither cdk_id
2280 nor cdk_attrs. */
2281 const struct c_declarator *decl = declarator;
2282 const struct c_declarator *last_non_id_attrs = NULL;
2283
2284 while (decl)
2285 switch (decl->kind)
2286 {
2287 case cdk_array:
2288 case cdk_function:
2289 case cdk_pointer:
2290 last_non_id_attrs = decl;
2291 decl = decl->declarator;
2292 break;
2293
2294 case cdk_attrs:
2295 decl = decl->declarator;
2296 break;
2297
2298 case cdk_id:
2299 decl = 0;
2300 break;
2301
2302 default:
2303 gcc_unreachable ();
2304 }
2305
2306 /* If it exists and is cdk_function, use its parameters. */
2307 if (last_non_id_attrs
2308 && last_non_id_attrs->kind == cdk_function)
2309 DECL_ARGUMENTS (d) = last_non_id_attrs->u.arg_info->parms;
2310 }
5e9d6aa4 2311 if (omp_declare_simd_clauses.exists ())
acf0174b
JJ
2312 {
2313 tree parms = NULL_TREE;
2314 if (d && TREE_CODE (d) == FUNCTION_DECL)
2315 {
2316 struct c_declarator *ce = declarator;
2317 while (ce != NULL)
2318 if (ce->kind == cdk_function)
2319 {
2320 parms = ce->u.arg_info->parms;
2321 break;
2322 }
2323 else
2324 ce = ce->declarator;
2325 }
2326 if (parms)
2327 temp_store_parm_decls (d, parms);
2328 c_finish_omp_declare_simd (parser, d, parms,
2329 omp_declare_simd_clauses);
2330 if (parms)
2331 temp_pop_parm_decls ();
2332 }
0b212d8c 2333 if (oacc_routine_data)
ae9281fc 2334 c_finish_oacc_routine (oacc_routine_data, d, false);
27bf414c 2335 if (d)
c2255bc4 2336 finish_decl (d, UNKNOWN_LOCATION, NULL_TREE,
f05b9d93
NP
2337 NULL_TREE, asm_name);
2338
2339 if (c_parser_next_token_is_keyword (parser, RID_IN))
2340 {
2341 if (d)
2342 *objc_foreach_object_declaration = d;
2343 else
2344 *objc_foreach_object_declaration = error_mark_node;
2345 }
27bf414c
JM
2346 }
2347 if (c_parser_next_token_is (parser, CPP_COMMA))
2348 {
38b7bc7f
JM
2349 if (auto_type_p)
2350 {
2351 error_at (here,
2352 "%<__auto_type%> may only be used with"
2353 " a single declarator");
2354 c_parser_skip_to_end_of_block_or_statement (parser);
2355 return;
2356 }
27bf414c
JM
2357 c_parser_consume_token (parser);
2358 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
783bfe5e 2359 all_prefix_attrs = chainon (c_parser_gnu_attributes (parser),
27bf414c
JM
2360 prefix_attrs);
2361 else
2362 all_prefix_attrs = prefix_attrs;
2363 continue;
2364 }
2365 else if (c_parser_next_token_is (parser, CPP_SEMICOLON))
2366 {
2367 c_parser_consume_token (parser);
2368 return;
2369 }
f05b9d93
NP
2370 else if (c_parser_next_token_is_keyword (parser, RID_IN))
2371 {
2372 /* This can only happen in Objective-C: we found the
2373 'in' that terminates the declaration inside an
2374 Objective-C foreach statement. Do not consume the
2375 token, so that the caller can use it to determine
2376 that this indeed is a foreach context. */
2377 return;
2378 }
27bf414c
JM
2379 else
2380 {
2381 c_parser_error (parser, "expected %<,%> or %<;%>");
2382 c_parser_skip_to_end_of_block_or_statement (parser);
2383 return;
2384 }
2385 }
38b7bc7f
JM
2386 else if (auto_type_p)
2387 {
2388 error_at (here,
2389 "%<__auto_type%> requires an initialized data declaration");
2390 c_parser_skip_to_end_of_block_or_statement (parser);
2391 return;
2392 }
27bf414c
JM
2393 else if (!fndef_ok)
2394 {
2395 c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, "
2396 "%<asm%> or %<__attribute__%>");
2397 c_parser_skip_to_end_of_block_or_statement (parser);
2398 return;
2399 }
2400 /* Function definition (nested or otherwise). */
2401 if (nested)
2402 {
c1771a20 2403 pedwarn (here, OPT_Wpedantic, "ISO C forbids nested functions");
d2784db4 2404 c_push_function_context ();
27bf414c
JM
2405 }
2406 if (!start_function (specs, declarator, all_prefix_attrs))
2407 {
1a59ccf2
DM
2408 /* At this point we've consumed:
2409 declaration-specifiers declarator
2410 and the next token isn't CPP_EQ, CPP_COMMA, CPP_SEMICOLON,
2411 RID_ASM, RID_ATTRIBUTE, or RID_IN,
2412 but the
2413 declaration-specifiers declarator
2414 aren't grokkable as a function definition, so we have
2415 an error. */
2416 gcc_assert (!c_parser_next_token_is (parser, CPP_SEMICOLON));
2417 if (c_parser_next_token_starts_declspecs (parser))
2418 {
2419 /* If we have
2420 declaration-specifiers declarator decl-specs
2421 then assume we have a missing semicolon, which would
2422 give us:
2423 declaration-specifiers declarator decl-specs
2424 ^
2425 ;
2426 <~~~~~~~~~ declaration ~~~~~~~~~~>
2427 Use c_parser_require to get an error with a fix-it hint. */
2428 c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>");
2429 parser->error = false;
2430 }
2431 else
2432 {
2433 /* This can appear in many cases looking nothing like a
2434 function definition, so we don't give a more specific
2435 error suggesting there was one. */
2436 c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, %<asm%> "
2437 "or %<__attribute__%>");
2438 }
27bf414c 2439 if (nested)
d2784db4 2440 c_pop_function_context ();
27bf414c
JM
2441 break;
2442 }
575bfb00
LC
2443
2444 if (DECL_DECLARED_INLINE_P (current_function_decl))
2445 tv = TV_PARSE_INLINE;
2446 else
2447 tv = TV_PARSE_FUNC;
c2e84327 2448 auto_timevar at (g_timer, tv);
575bfb00 2449
27bf414c
JM
2450 /* Parse old-style parameter declarations. ??? Attributes are
2451 not allowed to start declaration specifiers here because of a
2452 syntax conflict between a function declaration with attribute
2453 suffix and a function definition with an attribute prefix on
2454 first old-style parameter declaration. Following the old
2455 parser, they are not accepted on subsequent old-style
2456 parameter declarations either. However, there is no
2457 ambiguity after the first declaration, nor indeed on the
2458 first as long as we don't allow postfix attributes after a
2459 declarator with a nonempty identifier list in a definition;
2460 and postfix attributes have never been accepted here in
2461 function definitions either. */
2462 while (c_parser_next_token_is_not (parser, CPP_EOF)
2463 && c_parser_next_token_is_not (parser, CPP_OPEN_BRACE))
32912286 2464 c_parser_declaration_or_fndef (parser, false, false, false,
acf0174b 2465 true, false, NULL, vNULL);
27bf414c 2466 store_parm_decls ();
5e9d6aa4 2467 if (omp_declare_simd_clauses.exists ())
acf0174b
JJ
2468 c_finish_omp_declare_simd (parser, current_function_decl, NULL_TREE,
2469 omp_declare_simd_clauses);
0b212d8c 2470 if (oacc_routine_data)
ae9281fc 2471 c_finish_oacc_routine (oacc_routine_data, current_function_decl, true);
5db9e893 2472 location_t startloc = c_parser_peek_token (parser)->location;
1751ecd6 2473 DECL_STRUCT_FUNCTION (current_function_decl)->function_start_locus
5db9e893
JJ
2474 = startloc;
2475 location_t endloc = startloc;
1ee62b92 2476
baa09dc5 2477 /* If the definition was marked with __RTL, use the RTL parser now,
c2e84327 2478 consuming the function body. */
baa09dc5 2479 if (specs->declspec_il == cdil_rtl)
c2e84327 2480 {
9def91e9 2481 endloc = c_parser_parse_rtl_body (parser, specs->gimple_or_rtl_pass);
c2e84327
DM
2482
2483 /* Normally, store_parm_decls sets next_is_function_body,
2484 anticipating a function body. We need a push_scope/pop_scope
2485 pair to flush out this state, or subsequent function parsing
2486 will go wrong. */
2487 push_scope ();
2488 pop_scope ();
2489
9def91e9 2490 finish_function (endloc);
c2e84327
DM
2491 return;
2492 }
baa09dc5
RB
2493 /* If the definition was marked with __GIMPLE then parse the
2494 function body as GIMPLE. */
2495 else if (specs->declspec_il != cdil_none)
2496 {
2497 bool saved = in_late_binary_op;
2498 in_late_binary_op = true;
2499 c_parser_parse_gimple_body (parser, specs->gimple_or_rtl_pass,
d276406a
ML
2500 specs->declspec_il,
2501 specs->entry_bb_count);
baa09dc5
RB
2502 in_late_binary_op = saved;
2503 }
1ee62b92 2504 else
9def91e9 2505 fnbody = c_parser_compound_statement (parser, &endloc);
1ee62b92 2506 tree fndecl = current_function_decl;
27bf414c
JM
2507 if (nested)
2508 {
2509 tree decl = current_function_decl;
9f62cb92
JJ
2510 /* Mark nested functions as needing static-chain initially.
2511 lower_nested_functions will recompute it but the
2512 DECL_STATIC_CHAIN flag is also used before that happens,
2513 by initializer_constant_valid_p. See gcc.dg/nested-fn-2.c. */
2514 DECL_STATIC_CHAIN (decl) = 1;
27bf414c 2515 add_stmt (fnbody);
9def91e9 2516 finish_function (endloc);
d2784db4 2517 c_pop_function_context ();
c2255bc4 2518 add_stmt (build_stmt (DECL_SOURCE_LOCATION (decl), DECL_EXPR, decl));
27bf414c
JM
2519 }
2520 else
2521 {
1ee62b92
PG
2522 if (fnbody)
2523 add_stmt (fnbody);
9def91e9 2524 finish_function (endloc);
27bf414c 2525 }
baa09dc5
RB
2526 /* Get rid of the empty stmt list for GIMPLE/RTL. */
2527 if (specs->declspec_il != cdil_none)
1ee62b92 2528 DECL_SAVED_TREE (fndecl) = NULL_TREE;
575bfb00 2529
27bf414c
JM
2530 break;
2531 }
2532}
2533
2534/* Parse an asm-definition (asm() outside a function body). This is a
2535 GNU extension.
2536
2537 asm-definition:
2538 simple-asm-expr ;
2539*/
2540
2541static void
2542c_parser_asm_definition (c_parser *parser)
2543{
2544 tree asm_str = c_parser_simple_asm_expr (parser);
27bf414c 2545 if (asm_str)
3dafb85c 2546 symtab->finalize_toplevel_asm (asm_str);
27bf414c
JM
2547 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
2548}
2549
48b0b196 2550/* Parse a static assertion (C11 6.7.10).
32912286
JM
2551
2552 static_assert-declaration:
2553 static_assert-declaration-no-semi ;
2554*/
2555
2556static void
2557c_parser_static_assert_declaration (c_parser *parser)
2558{
2559 c_parser_static_assert_declaration_no_semi (parser);
2560 if (parser->error
2561 || !c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
2562 c_parser_skip_to_end_of_block_or_statement (parser);
2563}
2564
48b0b196 2565/* Parse a static assertion (C11 6.7.10), without the trailing
32912286
JM
2566 semicolon.
2567
2568 static_assert-declaration-no-semi:
2569 _Static_assert ( constant-expression , string-literal )
9f936c86
JM
2570
2571 C2X:
2572 static_assert-declaration-no-semi:
2573 _Static_assert ( constant-expression )
32912286
JM
2574*/
2575
2576static void
2577c_parser_static_assert_declaration_no_semi (c_parser *parser)
2578{
2579 location_t assert_loc, value_loc;
2580 tree value;
9f936c86 2581 tree string = NULL_TREE;
32912286
JM
2582
2583 gcc_assert (c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT));
2584 assert_loc = c_parser_peek_token (parser)->location;
35aff4fb
MP
2585 if (flag_isoc99)
2586 pedwarn_c99 (assert_loc, OPT_Wpedantic,
32912286 2587 "ISO C99 does not support %<_Static_assert%>");
35aff4fb
MP
2588 else
2589 pedwarn_c99 (assert_loc, OPT_Wpedantic,
32912286 2590 "ISO C90 does not support %<_Static_assert%>");
32912286 2591 c_parser_consume_token (parser);
32129a17
DM
2592 matching_parens parens;
2593 if (!parens.require_open (parser))
32912286 2594 return;
8062bca6 2595 location_t value_tok_loc = c_parser_peek_token (parser)->location;
32912286 2596 value = c_parser_expr_no_commas (parser, NULL).value;
8062bca6 2597 value_loc = EXPR_LOC_OR_LOC (value, value_tok_loc);
9f936c86 2598 if (c_parser_next_token_is (parser, CPP_COMMA))
32912286 2599 {
32912286 2600 c_parser_consume_token (parser);
9f936c86
JM
2601 switch (c_parser_peek_token (parser)->type)
2602 {
2603 case CPP_STRING:
2604 case CPP_STRING16:
2605 case CPP_STRING32:
2606 case CPP_WSTRING:
2607 case CPP_UTF8STRING:
471c5330 2608 string = c_parser_string_literal (parser, false, true).value;
9f936c86
JM
2609 break;
2610 default:
2611 c_parser_error (parser, "expected string literal");
9f936c86
JM
2612 return;
2613 }
32912286 2614 }
9f936c86
JM
2615 else if (flag_isoc11)
2616 /* If pedantic for pre-C11, the use of _Static_assert itself will
2617 have been diagnosed, so do not also diagnose the use of this
2618 new C2X feature of _Static_assert. */
2619 pedwarn_c11 (assert_loc, OPT_Wpedantic,
2620 "ISO C11 does not support omitting the string in "
2621 "%<_Static_assert%>");
32129a17 2622 parens.require_close (parser);
32912286
JM
2623
2624 if (!INTEGRAL_TYPE_P (TREE_TYPE (value)))
2625 {
2626 error_at (value_loc, "expression in static assertion is not an integer");
2627 return;
2628 }
2629 if (TREE_CODE (value) != INTEGER_CST)
2630 {
2631 value = c_fully_fold (value, false, NULL);
8d95fe25
MP
2632 /* Strip no-op conversions. */
2633 STRIP_TYPE_NOPS (value);
32912286 2634 if (TREE_CODE (value) == INTEGER_CST)
c1771a20 2635 pedwarn (value_loc, OPT_Wpedantic, "expression in static assertion "
32912286
JM
2636 "is not an integer constant expression");
2637 }
2638 if (TREE_CODE (value) != INTEGER_CST)
2639 {
2640 error_at (value_loc, "expression in static assertion is not constant");
2641 return;
2642 }
2643 constant_expression_warning (value);
2644 if (integer_zerop (value))
9f936c86
JM
2645 {
2646 if (string)
2647 error_at (assert_loc, "static assertion failed: %E", string);
2648 else
2649 error_at (assert_loc, "static assertion failed");
2650 }
32912286
JM
2651}
2652
27bf414c 2653/* Parse some declaration specifiers (possibly none) (C90 6.5, C99
31dc71a8 2654 6.7, C11 6.7), adding them to SPECS (which may already include some).
27bf414c 2655 Storage class specifiers are accepted iff SCSPEC_OK; type
568a31f2 2656 specifiers are accepted iff TYPESPEC_OK; alignment specifiers are
783bfe5e 2657 accepted iff ALIGNSPEC_OK; gnu-attributes are accepted at the start
4e03c3a7
JM
2658 iff START_ATTR_OK; __auto_type is accepted iff AUTO_TYPE_OK. In
2659 addition to the syntax shown, standard attributes are accepted at
2660 the start iff START_STD_ATTR_OK and at the end iff END_STD_ATTR_OK;
2661 unlike gnu-attributes, they are not accepted in the middle of the
2662 list. (This combines various different syntax productions in the C
2663 standard, and in some cases gnu-attributes and standard attributes
2664 at the start may already have been parsed before this function is
2665 called.)
27bf414c
JM
2666
2667 declaration-specifiers:
2668 storage-class-specifier declaration-specifiers[opt]
2669 type-specifier declaration-specifiers[opt]
2670 type-qualifier declaration-specifiers[opt]
2671 function-specifier declaration-specifiers[opt]
d19fa6b5 2672 alignment-specifier declaration-specifiers[opt]
27bf414c
JM
2673
2674 Function specifiers (inline) are from C99, and are currently
d19fa6b5 2675 handled as storage class specifiers, as is __thread. Alignment
48b0b196 2676 specifiers are from C11.
27bf414c 2677
31dc71a8 2678 C90 6.5.1, C99 6.7.1, C11 6.7.1:
27bf414c
JM
2679 storage-class-specifier:
2680 typedef
2681 extern
2682 static
2683 auto
2684 register
582d9b50
JM
2685 _Thread_local
2686
2687 (_Thread_local is new in C11.)
27bf414c 2688
31dc71a8 2689 C99 6.7.4, C11 6.7.4:
27bf414c
JM
2690 function-specifier:
2691 inline
c4b3a0a0
JM
2692 _Noreturn
2693
48b0b196 2694 (_Noreturn is new in C11.)
27bf414c 2695
31dc71a8 2696 C90 6.5.2, C99 6.7.2, C11 6.7.2:
27bf414c
JM
2697 type-specifier:
2698 void
2699 char
2700 short
2701 int
2702 long
2703 float
2704 double
2705 signed
2706 unsigned
2707 _Bool
2708 _Complex
2709 [_Imaginary removed in C99 TC2]
2710 struct-or-union-specifier
2711 enum-specifier
2712 typedef-name
267bac10 2713 atomic-type-specifier
27bf414c
JM
2714
2715 (_Bool and _Complex are new in C99.)
267bac10 2716 (atomic-type-specifier is new in C11.)
27bf414c 2717
31dc71a8 2718 C90 6.5.3, C99 6.7.3, C11 6.7.3:
27bf414c
JM
2719
2720 type-qualifier:
2721 const
2722 restrict
2723 volatile
36c5e70a 2724 address-space-qualifier
267bac10 2725 _Atomic
27bf414c
JM
2726
2727 (restrict is new in C99.)
267bac10 2728 (_Atomic is new in C11.)
27bf414c
JM
2729
2730 GNU extensions:
2731
2732 declaration-specifiers:
783bfe5e 2733 gnu-attributes declaration-specifiers[opt]
27bf414c 2734
36c5e70a
BE
2735 type-qualifier:
2736 address-space
2737
2738 address-space:
2739 identifier recognized by the target
2740
27bf414c
JM
2741 storage-class-specifier:
2742 __thread
2743
2744 type-specifier:
2745 typeof-specifier
38b7bc7f 2746 __auto_type
78a7c317 2747 __intN
9a8ce21f
JG
2748 _Decimal32
2749 _Decimal64
2750 _Decimal128
ab22c1fa
CF
2751 _Fract
2752 _Accum
2753 _Sat
2754
2755 (_Fract, _Accum, and _Sat are new from ISO/IEC DTR 18037:
2756 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1169.pdf)
27bf414c 2757
267bac10
JM
2758 atomic-type-specifier
2759 _Atomic ( type-name )
2760
27bf414c
JM
2761 Objective-C:
2762
2763 type-specifier:
2764 class-name objc-protocol-refs[opt]
2765 typedef-name objc-protocol-refs
2766 objc-protocol-refs
2767*/
2768
1ee62b92 2769void
27bf414c 2770c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
29ce73cb 2771 bool scspec_ok, bool typespec_ok, bool start_attr_ok,
38b7bc7f 2772 bool alignspec_ok, bool auto_type_ok,
4e03c3a7 2773 bool start_std_attr_ok, bool end_std_attr_ok,
38b7bc7f 2774 enum c_lookahead_kind la)
27bf414c
JM
2775{
2776 bool attrs_ok = start_attr_ok;
9e5b2115 2777 bool seen_type = specs->typespec_kind != ctsk_none;
29ce73cb
PB
2778
2779 if (!typespec_ok)
2780 gcc_assert (la == cla_prefer_id);
2781
4e03c3a7
JM
2782 if (start_std_attr_ok
2783 && c_parser_nth_token_starts_std_attributes (parser, 1))
2784 {
2785 gcc_assert (!specs->non_std_attrs_seen_p);
2786 location_t loc = c_parser_peek_token (parser)->location;
2787 tree attrs = c_parser_std_attribute_specifier_sequence (parser);
2788 declspecs_add_attrs (loc, specs, attrs);
2789 specs->non_std_attrs_seen_p = false;
2790 }
2791
29ce73cb 2792 while (c_parser_next_token_is (parser, CPP_NAME)
27bf414c
JM
2793 || c_parser_next_token_is (parser, CPP_KEYWORD)
2794 || (c_dialect_objc () && c_parser_next_token_is (parser, CPP_LESS)))
2795 {
2796 struct c_typespec t;
2797 tree attrs;
d19fa6b5 2798 tree align;
dc491a25 2799 location_t loc = c_parser_peek_token (parser)->location;
f725e721 2800
29ce73cb
PB
2801 /* If we cannot accept a type, exit if the next token must start
2802 one. Also, if we already have seen a tagged definition,
2803 a typename would be an error anyway and likely the user
2804 has simply forgotten a semicolon, so we exit. */
2805 if ((!typespec_ok || specs->typespec_kind == ctsk_tagdef)
2806 && c_parser_next_tokens_start_typename (parser, la)
4b2b493f
JM
2807 && !c_parser_next_token_is_qualifier (parser)
2808 && !c_parser_next_token_is_keyword (parser, RID_ALIGNAS))
29ce73cb 2809 break;
f725e721 2810
27bf414c
JM
2811 if (c_parser_next_token_is (parser, CPP_NAME))
2812 {
0b2c4be5
DS
2813 c_token *name_token = c_parser_peek_token (parser);
2814 tree value = name_token->value;
2815 c_id_kind kind = name_token->id_kind;
36c5e70a
BE
2816
2817 if (kind == C_ID_ADDRSPACE)
2818 {
2819 addr_space_t as
0b2c4be5
DS
2820 = name_token->keyword - RID_FIRST_ADDR_SPACE;
2821 declspecs_add_addrspace (name_token->location, specs, as);
36c5e70a
BE
2822 c_parser_consume_token (parser);
2823 attrs_ok = true;
2824 continue;
2825 }
2826
29ce73cb
PB
2827 gcc_assert (!c_parser_next_token_is_qualifier (parser));
2828
2829 /* If we cannot accept a type, and the next token must start one,
2830 exit. Do the same if we already have seen a tagged definition,
2831 since it would be an error anyway and likely the user has simply
2832 forgotten a semicolon. */
2833 if (seen_type || !c_parser_next_tokens_start_typename (parser, la))
2834 break;
2835
2836 /* Now at an unknown typename (C_ID_ID), a C_ID_TYPENAME or
2837 a C_ID_CLASSNAME. */
27bf414c
JM
2838 c_parser_consume_token (parser);
2839 seen_type = true;
2840 attrs_ok = true;
29ce73cb
PB
2841 if (kind == C_ID_ID)
2842 {
1c9f5f33 2843 error_at (loc, "unknown type name %qE", value);
29ce73cb
PB
2844 t.kind = ctsk_typedef;
2845 t.spec = error_mark_node;
2846 }
2847 else if (kind == C_ID_TYPENAME
2848 && (!c_dialect_objc ()
2849 || c_parser_next_token_is_not (parser, CPP_LESS)))
27bf414c
JM
2850 {
2851 t.kind = ctsk_typedef;
2852 /* For a typedef name, record the meaning, not the name.
2853 In case of 'foo foo, bar;'. */
2854 t.spec = lookup_name (value);
2855 }
2856 else
2857 {
2858 tree proto = NULL_TREE;
2859 gcc_assert (c_dialect_objc ());
2860 t.kind = ctsk_objc;
2861 if (c_parser_next_token_is (parser, CPP_LESS))
2862 proto = c_parser_objc_protocol_refs (parser);
2863 t.spec = objc_get_protocol_qualified_type (value, proto);
2864 }
29ce73cb
PB
2865 t.expr = NULL_TREE;
2866 t.expr_const_operands = true;
0b2c4be5 2867 declspecs_add_type (name_token->location, specs, t);
27bf414c
JM
2868 continue;
2869 }
2870 if (c_parser_next_token_is (parser, CPP_LESS))
2871 {
2872 /* Make "<SomeProtocol>" equivalent to "id <SomeProtocol>" -
2873 nisse@lysator.liu.se. */
2874 tree proto;
2875 gcc_assert (c_dialect_objc ());
2876 if (!typespec_ok || seen_type)
2877 break;
2878 proto = c_parser_objc_protocol_refs (parser);
2879 t.kind = ctsk_objc;
2880 t.spec = objc_get_protocol_qualified_type (NULL_TREE, proto);
928c19bb
JM
2881 t.expr = NULL_TREE;
2882 t.expr_const_operands = true;
dc491a25 2883 declspecs_add_type (loc, specs, t);
27bf414c
JM
2884 continue;
2885 }
2886 gcc_assert (c_parser_next_token_is (parser, CPP_KEYWORD));
2887 switch (c_parser_peek_token (parser)->keyword)
2888 {
2889 case RID_STATIC:
2890 case RID_EXTERN:
2891 case RID_REGISTER:
2892 case RID_TYPEDEF:
2893 case RID_INLINE:
bbceee64 2894 case RID_NORETURN:
27bf414c
JM
2895 case RID_AUTO:
2896 case RID_THREAD:
2897 if (!scspec_ok)
2898 goto out;
2899 attrs_ok = true;
bbceee64 2900 /* TODO: Distinguish between function specifiers (inline, noreturn)
27bf414c
JM
2901 and storage class specifiers, either here or in
2902 declspecs_add_scspec. */
0b2c4be5
DS
2903 declspecs_add_scspec (loc, specs,
2904 c_parser_peek_token (parser)->value);
27bf414c
JM
2905 c_parser_consume_token (parser);
2906 break;
38b7bc7f
JM
2907 case RID_AUTO_TYPE:
2908 if (!auto_type_ok)
2909 goto out;
2910 /* Fall through. */
27bf414c
JM
2911 case RID_UNSIGNED:
2912 case RID_LONG:
2913 case RID_SHORT:
2914 case RID_SIGNED:
2915 case RID_COMPLEX:
2916 case RID_INT:
2917 case RID_CHAR:
2918 case RID_FLOAT:
2919 case RID_DOUBLE:
2920 case RID_VOID:
9a8ce21f
JG
2921 case RID_DFLOAT32:
2922 case RID_DFLOAT64:
2923 case RID_DFLOAT128:
c65699ef 2924 CASE_RID_FLOATN_NX:
27bf414c 2925 case RID_BOOL:
ab22c1fa
CF
2926 case RID_FRACT:
2927 case RID_ACCUM:
2928 case RID_SAT:
78a7c317
DD
2929 case RID_INT_N_0:
2930 case RID_INT_N_1:
2931 case RID_INT_N_2:
2932 case RID_INT_N_3:
27bf414c
JM
2933 if (!typespec_ok)
2934 goto out;
2935 attrs_ok = true;
2936 seen_type = true;
0bacb8c7
TT
2937 if (c_dialect_objc ())
2938 parser->objc_need_raw_identifier = true;
27bf414c
JM
2939 t.kind = ctsk_resword;
2940 t.spec = c_parser_peek_token (parser)->value;
928c19bb
JM
2941 t.expr = NULL_TREE;
2942 t.expr_const_operands = true;
dc491a25 2943 declspecs_add_type (loc, specs, t);
27bf414c
JM
2944 c_parser_consume_token (parser);
2945 break;
2946 case RID_ENUM:
2947 if (!typespec_ok)
2948 goto out;
2949 attrs_ok = true;
2950 seen_type = true;
2951 t = c_parser_enum_specifier (parser);
a4bb6959 2952 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, t.spec);
dc491a25 2953 declspecs_add_type (loc, specs, t);
27bf414c
JM
2954 break;
2955 case RID_STRUCT:
2956 case RID_UNION:
2957 if (!typespec_ok)
2958 goto out;
2959 attrs_ok = true;
2960 seen_type = true;
2961 t = c_parser_struct_or_union_specifier (parser);
dab71827 2962 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, t.spec);
dc491a25 2963 declspecs_add_type (loc, specs, t);
27bf414c
JM
2964 break;
2965 case RID_TYPEOF:
2966 /* ??? The old parser rejected typeof after other type
2967 specifiers, but is a syntax error the best way of
2968 handling this? */
2969 if (!typespec_ok || seen_type)
2970 goto out;
2971 attrs_ok = true;
2972 seen_type = true;
2973 t = c_parser_typeof_specifier (parser);
dc491a25 2974 declspecs_add_type (loc, specs, t);
27bf414c 2975 break;
267bac10
JM
2976 case RID_ATOMIC:
2977 /* C parser handling of Objective-C constructs needs
2978 checking for correct lvalue-to-rvalue conversions, and
2979 the code in build_modify_expr handling various
2980 Objective-C cases, and that in build_unary_op handling
2981 Objective-C cases for increment / decrement, also needs
2982 updating; uses of TYPE_MAIN_VARIANT in objc_compare_types
2983 and objc_types_are_equivalent may also need updates. */
2984 if (c_dialect_objc ())
2985 sorry ("%<_Atomic%> in Objective-C");
35aff4fb
MP
2986 if (flag_isoc99)
2987 pedwarn_c99 (loc, OPT_Wpedantic,
267bac10 2988 "ISO C99 does not support the %<_Atomic%> qualifier");
35aff4fb
MP
2989 else
2990 pedwarn_c99 (loc, OPT_Wpedantic,
267bac10 2991 "ISO C90 does not support the %<_Atomic%> qualifier");
267bac10
JM
2992 attrs_ok = true;
2993 tree value;
2994 value = c_parser_peek_token (parser)->value;
2995 c_parser_consume_token (parser);
2996 if (typespec_ok && c_parser_next_token_is (parser, CPP_OPEN_PAREN))
2997 {
2998 /* _Atomic ( type-name ). */
2999 seen_type = true;
3000 c_parser_consume_token (parser);
3001 struct c_type_name *type = c_parser_type_name (parser);
3002 t.kind = ctsk_typeof;
3003 t.spec = error_mark_node;
3004 t.expr = NULL_TREE;
3005 t.expr_const_operands = true;
3006 if (type != NULL)
3007 t.spec = groktypename (type, &t.expr,
3008 &t.expr_const_operands);
3009 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
3010 "expected %<)%>");
3011 if (t.spec != error_mark_node)
3012 {
3013 if (TREE_CODE (t.spec) == ARRAY_TYPE)
3014 error_at (loc, "%<_Atomic%>-qualified array type");
3015 else if (TREE_CODE (t.spec) == FUNCTION_TYPE)
3016 error_at (loc, "%<_Atomic%>-qualified function type");
3017 else if (TYPE_QUALS (t.spec) != TYPE_UNQUALIFIED)
3018 error_at (loc, "%<_Atomic%> applied to a qualified type");
3019 else
3020 t.spec = c_build_qualified_type (t.spec, TYPE_QUAL_ATOMIC);
3021 }
3022 declspecs_add_type (loc, specs, t);
3023 }
3024 else
3025 declspecs_add_qual (loc, specs, value);
3026 break;
27bf414c
JM
3027 case RID_CONST:
3028 case RID_VOLATILE:
3029 case RID_RESTRICT:
3030 attrs_ok = true;
0b2c4be5 3031 declspecs_add_qual (loc, specs, c_parser_peek_token (parser)->value);
27bf414c
JM
3032 c_parser_consume_token (parser);
3033 break;
3034 case RID_ATTRIBUTE:
3035 if (!attrs_ok)
3036 goto out;
783bfe5e 3037 attrs = c_parser_gnu_attributes (parser);
0b2c4be5 3038 declspecs_add_attrs (loc, specs, attrs);
27bf414c 3039 break;
d19fa6b5 3040 case RID_ALIGNAS:
568a31f2
MP
3041 if (!alignspec_ok)
3042 goto out;
d19fa6b5 3043 align = c_parser_alignas_specifier (parser);
0b2c4be5 3044 declspecs_add_alignas (loc, specs, align);
d19fa6b5 3045 break;
1ee62b92
PG
3046 case RID_GIMPLE:
3047 if (! flag_gimple)
a3f9f006 3048 error_at (loc, "%<__GIMPLE%> only valid with %<-fgimple%>");
1ee62b92 3049 c_parser_consume_token (parser);
baa09dc5 3050 specs->declspec_il = cdil_gimple;
1ee62b92 3051 specs->locations[cdw_gimple] = loc;
baa09dc5 3052 c_parser_gimple_or_rtl_pass_list (parser, specs);
c2e84327
DM
3053 break;
3054 case RID_RTL:
3055 c_parser_consume_token (parser);
baa09dc5 3056 specs->declspec_il = cdil_rtl;
c2e84327 3057 specs->locations[cdw_rtl] = loc;
baa09dc5 3058 c_parser_gimple_or_rtl_pass_list (parser, specs);
1ee62b92 3059 break;
27bf414c
JM
3060 default:
3061 goto out;
3062 }
3063 }
4e03c3a7
JM
3064 out:
3065 if (end_std_attr_ok
3066 && c_parser_nth_token_starts_std_attributes (parser, 1))
3067 specs->postfix_attrs = c_parser_std_attribute_specifier_sequence (parser);
27bf414c
JM
3068}
3069
31dc71a8 3070/* Parse an enum specifier (C90 6.5.2.2, C99 6.7.2.2, C11 6.7.2.2).
27bf414c
JM
3071
3072 enum-specifier:
783bfe5e
JM
3073 enum gnu-attributes[opt] identifier[opt] { enumerator-list }
3074 gnu-attributes[opt]
3075 enum gnu-attributes[opt] identifier[opt] { enumerator-list , }
3076 gnu-attributes[opt]
3077 enum gnu-attributes[opt] identifier
27bf414c
JM
3078
3079 The form with trailing comma is new in C99. The forms with
783bfe5e 3080 gnu-attributes are GNU extensions. In GNU C, we accept any expression
27bf414c
JM
3081 without commas in the syntax (assignment expressions, not just
3082 conditional expressions); assignment expressions will be diagnosed
3083 as non-constant.
3084
3085 enumerator-list:
3086 enumerator
3087 enumerator-list , enumerator
3088
3089 enumerator:
4e03c3a7
JM
3090 enumeration-constant attribute-specifier-sequence[opt]
3091 enumeration-constant attribute-specifier-sequence[opt]
3092 = constant-expression
fd5c817a
MP
3093
3094 GNU Extensions:
3095
3096 enumerator:
4e03c3a7
JM
3097 enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt]
3098 enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt]
3099 = constant-expression
fd5c817a 3100
27bf414c
JM
3101*/
3102
3103static struct c_typespec
3104c_parser_enum_specifier (c_parser *parser)
3105{
3106 struct c_typespec ret;
4e03c3a7
JM
3107 bool have_std_attrs;
3108 tree std_attrs = NULL_TREE;
27bf414c
JM
3109 tree attrs;
3110 tree ident = NULL_TREE;
24b97832 3111 location_t enum_loc;
922f2908 3112 location_t ident_loc = UNKNOWN_LOCATION; /* Quiet warning. */
27bf414c
JM
3113 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ENUM));
3114 c_parser_consume_token (parser);
4e03c3a7
JM
3115 have_std_attrs = c_parser_nth_token_starts_std_attributes (parser, 1);
3116 if (have_std_attrs)
3117 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
783bfe5e 3118 attrs = c_parser_gnu_attributes (parser);
c2255bc4 3119 enum_loc = c_parser_peek_token (parser)->location;
5af28c74
TT
3120 /* Set the location in case we create a decl now. */
3121 c_parser_set_source_position_from_token (c_parser_peek_token (parser));
27bf414c
JM
3122 if (c_parser_next_token_is (parser, CPP_NAME))
3123 {
3124 ident = c_parser_peek_token (parser)->value;
c7412148 3125 ident_loc = c_parser_peek_token (parser)->location;
24b97832 3126 enum_loc = ident_loc;
27bf414c
JM
3127 c_parser_consume_token (parser);
3128 }
3129 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
3130 {
3131 /* Parse an enum definition. */
7114359f 3132 struct c_enum_contents the_enum;
575bfb00 3133 tree type;
27bf414c
JM
3134 tree postfix_attrs;
3135 /* We chain the enumerators in reverse order, then put them in
3136 forward order at the end. */
575bfb00
LC
3137 tree values;
3138 timevar_push (TV_PARSE_ENUM);
3139 type = start_enum (enum_loc, &the_enum, ident);
3140 values = NULL_TREE;
27bf414c
JM
3141 c_parser_consume_token (parser);
3142 while (true)
3143 {
3144 tree enum_id;
3145 tree enum_value;
3146 tree enum_decl;
3147 bool seen_comma;
5af28c74 3148 c_token *token;
922f2908 3149 location_t comma_loc = UNKNOWN_LOCATION; /* Quiet warning. */
7370e0da 3150 location_t decl_loc, value_loc;
27bf414c
JM
3151 if (c_parser_next_token_is_not (parser, CPP_NAME))
3152 {
d04ff417
MP
3153 /* Give a nicer error for "enum {}". */
3154 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)
3155 && !parser->error)
3156 {
3157 error_at (c_parser_peek_token (parser)->location,
3158 "empty enum is invalid");
3159 parser->error = true;
3160 }
3161 else
3162 c_parser_error (parser, "expected identifier");
27bf414c
JM
3163 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
3164 values = error_mark_node;
3165 break;
3166 }
5af28c74
TT
3167 token = c_parser_peek_token (parser);
3168 enum_id = token->value;
3169 /* Set the location in case we create a decl now. */
3170 c_parser_set_source_position_from_token (token);
7370e0da 3171 decl_loc = value_loc = token->location;
27bf414c 3172 c_parser_consume_token (parser);
fd5c817a 3173 /* Parse any specified attributes. */
4e03c3a7
JM
3174 tree std_attrs = NULL_TREE;
3175 if (c_parser_nth_token_starts_std_attributes (parser, 1))
3176 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
3177 tree enum_attrs = chainon (std_attrs,
3178 c_parser_gnu_attributes (parser));
27bf414c
JM
3179 if (c_parser_next_token_is (parser, CPP_EQ))
3180 {
3181 c_parser_consume_token (parser);
85790e66 3182 value_loc = c_parser_peek_token (parser)->location;
27bf414c
JM
3183 enum_value = c_parser_expr_no_commas (parser, NULL).value;
3184 }
3185 else
3186 enum_value = NULL_TREE;
7370e0da 3187 enum_decl = build_enumerator (decl_loc, value_loc,
fd5c817a
MP
3188 &the_enum, enum_id, enum_value);
3189 if (enum_attrs)
3190 decl_attributes (&TREE_PURPOSE (enum_decl), enum_attrs, 0);
27bf414c
JM
3191 TREE_CHAIN (enum_decl) = values;
3192 values = enum_decl;
3193 seen_comma = false;
3194 if (c_parser_next_token_is (parser, CPP_COMMA))
3195 {
c7412148 3196 comma_loc = c_parser_peek_token (parser)->location;
27bf414c
JM
3197 seen_comma = true;
3198 c_parser_consume_token (parser);
3199 }
3200 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3201 {
f3bede71
MP
3202 if (seen_comma)
3203 pedwarn_c90 (comma_loc, OPT_Wpedantic,
3204 "comma at end of enumerator list");
27bf414c
JM
3205 c_parser_consume_token (parser);
3206 break;
3207 }
3208 if (!seen_comma)
3209 {
3210 c_parser_error (parser, "expected %<,%> or %<}%>");
3211 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
3212 values = error_mark_node;
3213 break;
3214 }
3215 }
783bfe5e 3216 postfix_attrs = c_parser_gnu_attributes (parser);
27bf414c 3217 ret.spec = finish_enum (type, nreverse (values),
4e03c3a7
JM
3218 chainon (std_attrs,
3219 chainon (attrs, postfix_attrs)));
27bf414c 3220 ret.kind = ctsk_tagdef;
928c19bb
JM
3221 ret.expr = NULL_TREE;
3222 ret.expr_const_operands = true;
575bfb00 3223 timevar_pop (TV_PARSE_ENUM);
27bf414c
JM
3224 return ret;
3225 }
3226 else if (!ident)
3227 {
3228 c_parser_error (parser, "expected %<{%>");
3229 ret.spec = error_mark_node;
3230 ret.kind = ctsk_tagref;
928c19bb
JM
3231 ret.expr = NULL_TREE;
3232 ret.expr_const_operands = true;
27bf414c
JM
3233 return ret;
3234 }
4e03c3a7
JM
3235 /* Attributes may only appear when the members are defined or in
3236 certain forward declarations (treat enum forward declarations in
3237 GNU C analogously to struct and union forward declarations in
3238 standard C). */
3239 if (have_std_attrs && c_parser_next_token_is_not (parser, CPP_SEMICOLON))
3240 c_parser_error (parser, "expected %<;%>");
3241 ret = parser_xref_tag (ident_loc, ENUMERAL_TYPE, ident, have_std_attrs,
3242 std_attrs);
27bf414c
JM
3243 /* In ISO C, enumerated types can be referred to only if already
3244 defined. */
3245 if (pedantic && !COMPLETE_TYPE_P (ret.spec))
c7412148
TT
3246 {
3247 gcc_assert (ident);
c1771a20 3248 pedwarn (enum_loc, OPT_Wpedantic,
509c9d60 3249 "ISO C forbids forward references to %<enum%> types");
c7412148 3250 }
27bf414c
JM
3251 return ret;
3252}
3253
31dc71a8 3254/* Parse a struct or union specifier (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1).
27bf414c
JM
3255
3256 struct-or-union-specifier:
4e03c3a7
JM
3257 struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
3258 identifier[opt] { struct-contents } gnu-attributes[opt]
3259 struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
3260 identifier
27bf414c
JM
3261
3262 struct-contents:
3263 struct-declaration-list
3264
3265 struct-declaration-list:
3266 struct-declaration ;
3267 struct-declaration-list struct-declaration ;
3268
3269 GNU extensions:
3270
3271 struct-contents:
3272 empty
3273 struct-declaration
3274 struct-declaration-list struct-declaration
3275
3276 struct-declaration-list:
3277 struct-declaration-list ;
3278 ;
3279
3280 (Note that in the syntax here, unlike that in ISO C, the semicolons
3281 are included here rather than in struct-declaration, in order to
3282 describe the syntax with extra semicolons and missing semicolon at
3283 end.)
3284
3285 Objective-C:
3286
3287 struct-declaration-list:
3288 @defs ( class-name )
3289
3290 (Note this does not include a trailing semicolon, but can be
3291 followed by further declarations, and gets a pedwarn-if-pedantic
3292 when followed by a semicolon.) */
3293
3294static struct c_typespec
3295c_parser_struct_or_union_specifier (c_parser *parser)
3296{
3297 struct c_typespec ret;
4e03c3a7
JM
3298 bool have_std_attrs;
3299 tree std_attrs = NULL_TREE;
27bf414c
JM
3300 tree attrs;
3301 tree ident = NULL_TREE;
24b97832
ILT
3302 location_t struct_loc;
3303 location_t ident_loc = UNKNOWN_LOCATION;
27bf414c
JM
3304 enum tree_code code;
3305 switch (c_parser_peek_token (parser)->keyword)
3306 {
3307 case RID_STRUCT:
3308 code = RECORD_TYPE;
3309 break;
3310 case RID_UNION:
3311 code = UNION_TYPE;
3312 break;
3313 default:
3314 gcc_unreachable ();
3315 }
24b97832 3316 struct_loc = c_parser_peek_token (parser)->location;
27bf414c 3317 c_parser_consume_token (parser);
4e03c3a7
JM
3318 have_std_attrs = c_parser_nth_token_starts_std_attributes (parser, 1);
3319 if (have_std_attrs)
3320 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
783bfe5e 3321 attrs = c_parser_gnu_attributes (parser);
c2255bc4 3322
5af28c74
TT
3323 /* Set the location in case we create a decl now. */
3324 c_parser_set_source_position_from_token (c_parser_peek_token (parser));
c2255bc4 3325
27bf414c
JM
3326 if (c_parser_next_token_is (parser, CPP_NAME))
3327 {
3328 ident = c_parser_peek_token (parser)->value;
24b97832
ILT
3329 ident_loc = c_parser_peek_token (parser)->location;
3330 struct_loc = ident_loc;
27bf414c
JM
3331 c_parser_consume_token (parser);
3332 }
3333 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
3334 {
3335 /* Parse a struct or union definition. Start the scope of the
3336 tag before parsing components. */
99b1c316 3337 class c_struct_parse_info *struct_info;
dc491a25 3338 tree type = start_struct (struct_loc, code, ident, &struct_info);
27bf414c
JM
3339 tree postfix_attrs;
3340 /* We chain the components in reverse order, then put them in
3341 forward order at the end. Each struct-declaration may
3342 declare multiple components (comma-separated), so we must use
3343 chainon to join them, although when parsing each
3344 struct-declaration we can use TREE_CHAIN directly.
3345
3346 The theory behind all this is that there will be more
3347 semicolon separated fields than comma separated fields, and
3348 so we'll be minimizing the number of node traversals required
3349 by chainon. */
575bfb00
LC
3350 tree contents;
3351 timevar_push (TV_PARSE_STRUCT);
3352 contents = NULL_TREE;
27bf414c
JM
3353 c_parser_consume_token (parser);
3354 /* Handle the Objective-C @defs construct,
3355 e.g. foo(sizeof(struct{ @defs(ClassName) }));. */
3356 if (c_parser_next_token_is_keyword (parser, RID_AT_DEFS))
3357 {
3358 tree name;
3359 gcc_assert (c_dialect_objc ());
3360 c_parser_consume_token (parser);
32129a17
DM
3361 matching_parens parens;
3362 if (!parens.require_open (parser))
27bf414c
JM
3363 goto end_at_defs;
3364 if (c_parser_next_token_is (parser, CPP_NAME)
3365 && c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME)
3366 {
3367 name = c_parser_peek_token (parser)->value;
3368 c_parser_consume_token (parser);
3369 }
3370 else
3371 {
3372 c_parser_error (parser, "expected class name");
3373 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
3374 goto end_at_defs;
3375 }
32129a17 3376 parens.skip_until_found_close (parser);
27bf414c
JM
3377 contents = nreverse (objc_get_class_ivars (name));
3378 }
3379 end_at_defs:
3380 /* Parse the struct-declarations and semicolons. Problems with
3381 semicolons are diagnosed here; empty structures are diagnosed
3382 elsewhere. */
3383 while (true)
3384 {
3385 tree decls;
3386 /* Parse any stray semicolon. */
3387 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
3388 {
1c4ea66f
DM
3389 location_t semicolon_loc
3390 = c_parser_peek_token (parser)->location;
3391 gcc_rich_location richloc (semicolon_loc);
3392 richloc.add_fixit_remove ();
64a5912c
DM
3393 pedwarn (&richloc, OPT_Wpedantic,
3394 "extra semicolon in struct or union specified");
27bf414c
JM
3395 c_parser_consume_token (parser);
3396 continue;
3397 }
3398 /* Stop if at the end of the struct or union contents. */
3399 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3400 {
3401 c_parser_consume_token (parser);
3402 break;
3403 }
bc4071dd
RH
3404 /* Accept #pragmas at struct scope. */
3405 if (c_parser_next_token_is (parser, CPP_PRAGMA))
3406 {
dda1bf61 3407 c_parser_pragma (parser, pragma_struct, NULL);
bc4071dd
RH
3408 continue;
3409 }
27bf414c
JM
3410 /* Parse some comma-separated declarations, but not the
3411 trailing semicolon if any. */
3412 decls = c_parser_struct_declaration (parser);
3413 contents = chainon (decls, contents);
3414 /* If no semicolon follows, either we have a parse error or
3415 are at the end of the struct or union and should
3416 pedwarn. */
3417 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
3418 c_parser_consume_token (parser);
3419 else
3420 {
3421 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
b8698a0f 3422 pedwarn (c_parser_peek_token (parser)->location, 0,
509c9d60 3423 "no semicolon at end of struct or union");
f725e721
PB
3424 else if (parser->error
3425 || !c_parser_next_token_starts_declspecs (parser))
27bf414c
JM
3426 {
3427 c_parser_error (parser, "expected %<;%>");
3428 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
3429 break;
3430 }
f725e721
PB
3431
3432 /* If we come here, we have already emitted an error
3433 for an expected `;', identifier or `(', and we also
3434 recovered already. Go on with the next field. */
27bf414c
JM
3435 }
3436 }
783bfe5e 3437 postfix_attrs = c_parser_gnu_attributes (parser);
c2255bc4 3438 ret.spec = finish_struct (struct_loc, type, nreverse (contents),
4e03c3a7
JM
3439 chainon (std_attrs,
3440 chainon (attrs, postfix_attrs)),
3441 struct_info);
27bf414c 3442 ret.kind = ctsk_tagdef;
928c19bb
JM
3443 ret.expr = NULL_TREE;
3444 ret.expr_const_operands = true;
575bfb00 3445 timevar_pop (TV_PARSE_STRUCT);
27bf414c
JM
3446 return ret;
3447 }
3448 else if (!ident)
3449 {
3450 c_parser_error (parser, "expected %<{%>");
3451 ret.spec = error_mark_node;
3452 ret.kind = ctsk_tagref;
928c19bb
JM
3453 ret.expr = NULL_TREE;
3454 ret.expr_const_operands = true;
67c2939d 3455 return ret;
27bf414c 3456 }
4e03c3a7
JM
3457 /* Attributes may only appear when the members are defined or in
3458 certain forward declarations. */
3459 if (have_std_attrs && c_parser_next_token_is_not (parser, CPP_SEMICOLON))
3460 c_parser_error (parser, "expected %<;%>");
3461 /* ??? Existing practice is that GNU attributes are ignored after
3462 the struct or union keyword when not defining the members. */
3463 ret = parser_xref_tag (ident_loc, code, ident, have_std_attrs, std_attrs);
27bf414c
JM
3464 return ret;
3465}
3466
31dc71a8
MP
3467/* Parse a struct-declaration (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1),
3468 *without* the trailing semicolon.
27bf414c
JM
3469
3470 struct-declaration:
4e03c3a7
JM
3471 attribute-specifier-sequence[opt] specifier-qualifier-list
3472 attribute-specifier-sequence[opt] struct-declarator-list
32912286 3473 static_assert-declaration-no-semi
27bf414c
JM
3474
3475 specifier-qualifier-list:
3476 type-specifier specifier-qualifier-list[opt]
3477 type-qualifier specifier-qualifier-list[opt]
4b2b493f 3478 alignment-specifier specifier-qualifier-list[opt]
783bfe5e 3479 gnu-attributes specifier-qualifier-list[opt]
27bf414c
JM
3480
3481 struct-declarator-list:
3482 struct-declarator
783bfe5e 3483 struct-declarator-list , gnu-attributes[opt] struct-declarator
27bf414c
JM
3484
3485 struct-declarator:
783bfe5e
JM
3486 declarator gnu-attributes[opt]
3487 declarator[opt] : constant-expression gnu-attributes[opt]
27bf414c
JM
3488
3489 GNU extensions:
3490
3491 struct-declaration:
3492 __extension__ struct-declaration
3493 specifier-qualifier-list
3494
3495 Unlike the ISO C syntax, semicolons are handled elsewhere. The use
783bfe5e 3496 of gnu-attributes where shown is a GNU extension. In GNU C, we accept
27bf414c
JM
3497 any expression without commas in the syntax (assignment
3498 expressions, not just conditional expressions); assignment
3499 expressions will be diagnosed as non-constant. */
3500
3501static tree
3502c_parser_struct_declaration (c_parser *parser)
3503{
3504 struct c_declspecs *specs;
3505 tree prefix_attrs;
3506 tree all_prefix_attrs;
3507 tree decls;
c7412148 3508 location_t decl_loc;
27bf414c
JM
3509 if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
3510 {
3511 int ext;
3512 tree decl;
3513 ext = disable_extension_diagnostics ();
3514 c_parser_consume_token (parser);
3515 decl = c_parser_struct_declaration (parser);
3516 restore_extension_diagnostics (ext);
3517 return decl;
3518 }
32912286
JM
3519 if (c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
3520 {
3521 c_parser_static_assert_declaration_no_semi (parser);
3522 return NULL_TREE;
3523 }
27bf414c 3524 specs = build_null_declspecs ();
c7412148 3525 decl_loc = c_parser_peek_token (parser)->location;
f28aa681
MP
3526 /* Strictly by the standard, we shouldn't allow _Alignas here,
3527 but it appears to have been intended to allow it there, so
3528 we're keeping it as it is until WG14 reaches a conclusion
3529 of N1731.
3530 <http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1731.pdf> */
568a31f2 3531 c_parser_declspecs (parser, specs, false, true, true,
4e03c3a7 3532 true, false, true, true, cla_nonabstract_decl);
27bf414c 3533 if (parser->error)
67c2939d 3534 return NULL_TREE;
27bf414c
JM
3535 if (!specs->declspecs_seen_p)
3536 {
3537 c_parser_error (parser, "expected specifier-qualifier-list");
3538 return NULL_TREE;
3539 }
3540 finish_declspecs (specs);
b8cbdff5
JM
3541 if (c_parser_next_token_is (parser, CPP_SEMICOLON)
3542 || c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
27bf414c
JM
3543 {
3544 tree ret;
9e5b2115 3545 if (specs->typespec_kind == ctsk_none)
27bf414c 3546 {
c1771a20 3547 pedwarn (decl_loc, OPT_Wpedantic,
509c9d60 3548 "ISO C forbids member declarations with no members");
27bf414c
JM
3549 shadow_tag_warned (specs, pedantic);
3550 ret = NULL_TREE;
3551 }
3552 else
3553 {
3554 /* Support for unnamed structs or unions as members of
3555 structs or unions (which is [a] useful and [b] supports
3556 MS P-SDK). */
b9baeecd 3557 tree attrs = NULL;
3d10ed6c
AH
3558
3559 ret = grokfield (c_parser_peek_token (parser)->location,
3560 build_id_declarator (NULL_TREE), specs,
b9baeecd 3561 NULL_TREE, &attrs);
0ad7e054
RS
3562 if (ret)
3563 decl_attributes (&ret, attrs, 0);
27bf414c
JM
3564 }
3565 return ret;
3566 }
f725e721
PB
3567
3568 /* Provide better error recovery. Note that a type name here is valid,
3569 and will be treated as a field name. */
3570 if (specs->typespec_kind == ctsk_tagdef
3571 && TREE_CODE (specs->type) != ENUMERAL_TYPE
3572 && c_parser_next_token_starts_declspecs (parser)
3573 && !c_parser_next_token_is (parser, CPP_NAME))
3574 {
3575 c_parser_error (parser, "expected %<;%>, identifier or %<(%>");
3576 parser->error = false;
3577 return NULL_TREE;
3578 }
3579
27bf414c
JM
3580 pending_xref_error ();
3581 prefix_attrs = specs->attrs;
3582 all_prefix_attrs = prefix_attrs;
3583 specs->attrs = NULL_TREE;
3584 decls = NULL_TREE;
3585 while (true)
3586 {
3587 /* Declaring one or more declarators or un-named bit-fields. */
3588 struct c_declarator *declarator;
3589 bool dummy = false;
3590 if (c_parser_next_token_is (parser, CPP_COLON))
3591 declarator = build_id_declarator (NULL_TREE);
3592 else
9e5b2115
PB
3593 declarator = c_parser_declarator (parser,
3594 specs->typespec_kind != ctsk_none,
27bf414c
JM
3595 C_DTR_NORMAL, &dummy);
3596 if (declarator == NULL)
3597 {
3598 c_parser_skip_to_end_of_block_or_statement (parser);
3599 break;
3600 }
3601 if (c_parser_next_token_is (parser, CPP_COLON)
3602 || c_parser_next_token_is (parser, CPP_COMMA)
3603 || c_parser_next_token_is (parser, CPP_SEMICOLON)
3604 || c_parser_next_token_is (parser, CPP_CLOSE_BRACE)
3605 || c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
3606 {
3607 tree postfix_attrs = NULL_TREE;
3608 tree width = NULL_TREE;
3609 tree d;
3610 if (c_parser_next_token_is (parser, CPP_COLON))
3611 {
3612 c_parser_consume_token (parser);
3613 width = c_parser_expr_no_commas (parser, NULL).value;
3614 }
3615 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
783bfe5e 3616 postfix_attrs = c_parser_gnu_attributes (parser);
3d10ed6c
AH
3617 d = grokfield (c_parser_peek_token (parser)->location,
3618 declarator, specs, width, &all_prefix_attrs);
27bf414c
JM
3619 decl_attributes (&d, chainon (postfix_attrs,
3620 all_prefix_attrs), 0);
910ad8de 3621 DECL_CHAIN (d) = decls;
27bf414c
JM
3622 decls = d;
3623 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
783bfe5e 3624 all_prefix_attrs = chainon (c_parser_gnu_attributes (parser),
27bf414c
JM
3625 prefix_attrs);
3626 else
3627 all_prefix_attrs = prefix_attrs;
3628 if (c_parser_next_token_is (parser, CPP_COMMA))
3629 c_parser_consume_token (parser);
3630 else if (c_parser_next_token_is (parser, CPP_SEMICOLON)
3631 || c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3632 {
3633 /* Semicolon consumed in caller. */
3634 break;
3635 }
3636 else
3637 {
3638 c_parser_error (parser, "expected %<,%>, %<;%> or %<}%>");
3639 break;
3640 }
3641 }
3642 else
3643 {
3644 c_parser_error (parser,
3645 "expected %<:%>, %<,%>, %<;%>, %<}%> or "
3646 "%<__attribute__%>");
3647 break;
3648 }
3649 }
3650 return decls;
3651}
3652
3653/* Parse a typeof specifier (a GNU extension).
3654
3655 typeof-specifier:
3656 typeof ( expression )
3657 typeof ( type-name )
3658*/
3659
3660static struct c_typespec
3661c_parser_typeof_specifier (c_parser *parser)
3662{
3663 struct c_typespec ret;
3664 ret.kind = ctsk_typeof;
3665 ret.spec = error_mark_node;
928c19bb
JM
3666 ret.expr = NULL_TREE;
3667 ret.expr_const_operands = true;
27bf414c
JM
3668 gcc_assert (c_parser_next_token_is_keyword (parser, RID_TYPEOF));
3669 c_parser_consume_token (parser);
7d882b83 3670 c_inhibit_evaluation_warnings++;
27bf414c 3671 in_typeof++;
32129a17
DM
3672 matching_parens parens;
3673 if (!parens.require_open (parser))
27bf414c 3674 {
7d882b83 3675 c_inhibit_evaluation_warnings--;
27bf414c
JM
3676 in_typeof--;
3677 return ret;
3678 }
29ce73cb 3679 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
27bf414c
JM
3680 {
3681 struct c_type_name *type = c_parser_type_name (parser);
7d882b83 3682 c_inhibit_evaluation_warnings--;
27bf414c
JM
3683 in_typeof--;
3684 if (type != NULL)
3685 {
928c19bb 3686 ret.spec = groktypename (type, &ret.expr, &ret.expr_const_operands);
27bf414c
JM
3687 pop_maybe_used (variably_modified_type_p (ret.spec, NULL_TREE));
3688 }
3689 }
3690 else
3691 {
52ffd86e 3692 bool was_vm;
c7412148 3693 location_t here = c_parser_peek_token (parser)->location;
27bf414c 3694 struct c_expr expr = c_parser_expression (parser);
7d882b83 3695 c_inhibit_evaluation_warnings--;
27bf414c
JM
3696 in_typeof--;
3697 if (TREE_CODE (expr.value) == COMPONENT_REF
3698 && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
3ba09659 3699 error_at (here, "%<typeof%> applied to a bit-field");
ebfbbdc5 3700 mark_exp_read (expr.value);
27bf414c 3701 ret.spec = TREE_TYPE (expr.value);
52ffd86e 3702 was_vm = variably_modified_type_p (ret.spec, NULL_TREE);
928c19bb
JM
3703 /* This is returned with the type so that when the type is
3704 evaluated, this can be evaluated. */
3705 if (was_vm)
3706 ret.expr = c_fully_fold (expr.value, false, &ret.expr_const_operands);
52ffd86e 3707 pop_maybe_used (was_vm);
9698b078
SH
3708 /* For use in macros such as those in <stdatomic.h>, remove all
3709 qualifiers from atomic types. (const can be an issue for more macros
3710 using typeof than just the <stdatomic.h> ones.) */
267bac10 3711 if (ret.spec != error_mark_node && TYPE_ATOMIC (ret.spec))
9698b078 3712 ret.spec = c_build_qualified_type (ret.spec, TYPE_UNQUALIFIED);
27bf414c 3713 }
32129a17 3714 parens.skip_until_found_close (parser);
27bf414c
JM
3715 return ret;
3716}
3717
d19fa6b5
JM
3718/* Parse an alignment-specifier.
3719
48b0b196 3720 C11 6.7.5:
d19fa6b5
JM
3721
3722 alignment-specifier:
3723 _Alignas ( type-name )
3724 _Alignas ( constant-expression )
3725*/
3726
3727static tree
3728c_parser_alignas_specifier (c_parser * parser)
3729{
3730 tree ret = error_mark_node;
3731 location_t loc = c_parser_peek_token (parser)->location;
3732 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ALIGNAS));
3733 c_parser_consume_token (parser);
35aff4fb
MP
3734 if (flag_isoc99)
3735 pedwarn_c99 (loc, OPT_Wpedantic,
d19fa6b5 3736 "ISO C99 does not support %<_Alignas%>");
35aff4fb
MP
3737 else
3738 pedwarn_c99 (loc, OPT_Wpedantic,
d19fa6b5 3739 "ISO C90 does not support %<_Alignas%>");
32129a17
DM
3740 matching_parens parens;
3741 if (!parens.require_open (parser))
d19fa6b5
JM
3742 return ret;
3743 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
3744 {
3745 struct c_type_name *type = c_parser_type_name (parser);
3746 if (type != NULL)
296674db
JM
3747 ret = c_sizeof_or_alignof_type (loc, groktypename (type, NULL, NULL),
3748 false, true, 1);
d19fa6b5
JM
3749 }
3750 else
3751 ret = c_parser_expr_no_commas (parser, NULL).value;
32129a17 3752 parens.skip_until_found_close (parser);
d19fa6b5
JM
3753 return ret;
3754}
3755
27bf414c 3756/* Parse a declarator, possibly an abstract declarator (C90 6.5.4,
31dc71a8
MP
3757 6.5.5, C99 6.7.5, 6.7.6, C11 6.7.6, 6.7.7). If TYPE_SEEN_P then
3758 a typedef name may be redeclared; otherwise it may not. KIND
3759 indicates which kind of declarator is wanted. Returns a valid
3760 declarator except in the case of a syntax error in which case NULL is
3761 returned. *SEEN_ID is set to true if an identifier being declared is
3762 seen; this is used to diagnose bad forms of abstract array declarators
3763 and to determine whether an identifier list is syntactically permitted.
27bf414c
JM
3764
3765 declarator:
3766 pointer[opt] direct-declarator
3767
3768 direct-declarator:
3769 identifier
783bfe5e 3770 ( gnu-attributes[opt] declarator )
27bf414c
JM
3771 direct-declarator array-declarator
3772 direct-declarator ( parameter-type-list )
3773 direct-declarator ( identifier-list[opt] )
3774
3775 pointer:
3776 * type-qualifier-list[opt]
3777 * type-qualifier-list[opt] pointer
3778
3779 type-qualifier-list:
3780 type-qualifier
783bfe5e 3781 gnu-attributes
27bf414c 3782 type-qualifier-list type-qualifier
783bfe5e 3783 type-qualifier-list gnu-attributes
27bf414c 3784
568a31f2
MP
3785 array-declarator:
3786 [ type-qualifier-list[opt] assignment-expression[opt] ]
3787 [ static type-qualifier-list[opt] assignment-expression ]
3788 [ type-qualifier-list static assignment-expression ]
3789 [ type-qualifier-list[opt] * ]
3790
27bf414c
JM
3791 parameter-type-list:
3792 parameter-list
3793 parameter-list , ...
3794
3795 parameter-list:
3796 parameter-declaration
3797 parameter-list , parameter-declaration
3798
3799 parameter-declaration:
783bfe5e
JM
3800 declaration-specifiers declarator gnu-attributes[opt]
3801 declaration-specifiers abstract-declarator[opt] gnu-attributes[opt]
27bf414c
JM
3802
3803 identifier-list:
3804 identifier
3805 identifier-list , identifier
3806
3807 abstract-declarator:
3808 pointer
3809 pointer[opt] direct-abstract-declarator
3810
3811 direct-abstract-declarator:
783bfe5e 3812 ( gnu-attributes[opt] abstract-declarator )
27bf414c
JM
3813 direct-abstract-declarator[opt] array-declarator
3814 direct-abstract-declarator[opt] ( parameter-type-list[opt] )
3815
3816 GNU extensions:
3817
3818 direct-declarator:
3819 direct-declarator ( parameter-forward-declarations
3820 parameter-type-list[opt] )
3821
3822 direct-abstract-declarator:
c22cacf3 3823 direct-abstract-declarator[opt] ( parameter-forward-declarations
27bf414c
JM
3824 parameter-type-list[opt] )
3825
3826 parameter-forward-declarations:
3827 parameter-list ;
3828 parameter-forward-declarations parameter-list ;
3829
783bfe5e 3830 The uses of gnu-attributes shown above are GNU extensions.
27bf414c
JM
3831
3832 Some forms of array declarator are not included in C99 in the
3833 syntax for abstract declarators; these are disallowed elsewhere.
3834 This may be a defect (DR#289).
3835
3836 This function also accepts an omitted abstract declarator as being
3837 an abstract declarator, although not part of the formal syntax. */
3838
1ee62b92 3839struct c_declarator *
27bf414c
JM
3840c_parser_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
3841 bool *seen_id)
3842{
3843 /* Parse any initial pointer part. */
3844 if (c_parser_next_token_is (parser, CPP_MULT))
3845 {
3846 struct c_declspecs *quals_attrs = build_null_declspecs ();
3847 struct c_declarator *inner;
3848 c_parser_consume_token (parser);
568a31f2 3849 c_parser_declspecs (parser, quals_attrs, false, false, true,
4e03c3a7 3850 false, false, true, false, cla_prefer_id);
27bf414c
JM
3851 inner = c_parser_declarator (parser, type_seen_p, kind, seen_id);
3852 if (inner == NULL)
3853 return NULL;
3854 else
3855 return make_pointer_declarator (quals_attrs, inner);
3856 }
3857 /* Now we have a direct declarator, direct abstract declarator or
3858 nothing (which counts as a direct abstract declarator here). */
3859 return c_parser_direct_declarator (parser, type_seen_p, kind, seen_id);
3860}
3861
3862/* Parse a direct declarator or direct abstract declarator; arguments
3863 as c_parser_declarator. */
3864
3865static struct c_declarator *
3866c_parser_direct_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
3867 bool *seen_id)
3868{
3869 /* The direct declarator must start with an identifier (possibly
3870 omitted) or a parenthesized declarator (possibly abstract). In
3871 an ordinary declarator, initial parentheses must start a
3872 parenthesized declarator. In an abstract declarator or parameter
3873 declarator, they could start a parenthesized declarator or a
3874 parameter list. To tell which, the open parenthesis and any
4e03c3a7
JM
3875 following gnu-attributes must be read. If a declaration
3876 specifier or standard attributes follow, then it is a parameter
3877 list; if the specifier is a typedef name, there might be an
3878 ambiguity about redeclaring it, which is resolved in the
3879 direction of treating it as a typedef name. If a close
3880 parenthesis follows, it is also an empty parameter list, as the
3881 syntax does not permit empty abstract declarators. Otherwise, it
3882 is a parenthesized declarator (in which case the analysis may be
3883 repeated inside it, recursively).
27bf414c
JM
3884
3885 ??? There is an ambiguity in a parameter declaration "int
3886 (__attribute__((foo)) x)", where x is not a typedef name: it
3887 could be an abstract declarator for a function, or declare x with
3888 parentheses. The proper resolution of this ambiguity needs
3889 documenting. At present we follow an accident of the old
3890 parser's implementation, whereby the first parameter must have
783bfe5e 3891 some declaration specifiers other than just gnu-attributes. Thus as
0fa2e4df 3892 a parameter declaration it is treated as a parenthesized
27bf414c
JM
3893 parameter named x, and as an abstract declarator it is
3894 rejected.
3895
783bfe5e 3896 ??? Also following the old parser, gnu-attributes inside an empty
27bf414c
JM
3897 parameter list are ignored, making it a list not yielding a
3898 prototype, rather than giving an error or making it have one
3899 parameter with implicit type int.
3900
3901 ??? Also following the old parser, typedef names may be
3902 redeclared in declarators, but not Objective-C class names. */
3903
3904 if (kind != C_DTR_ABSTRACT
3905 && c_parser_next_token_is (parser, CPP_NAME)
3906 && ((type_seen_p
a6341d57
NP
3907 && (c_parser_peek_token (parser)->id_kind == C_ID_TYPENAME
3908 || c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME))
27bf414c
JM
3909 || c_parser_peek_token (parser)->id_kind == C_ID_ID))
3910 {
3911 struct c_declarator *inner
3912 = build_id_declarator (c_parser_peek_token (parser)->value);
3913 *seen_id = true;
6037d88d 3914 inner->id_loc = c_parser_peek_token (parser)->location;
27bf414c 3915 c_parser_consume_token (parser);
4e03c3a7 3916 if (c_parser_nth_token_starts_std_attributes (parser, 1))
1723e1be 3917 inner->u.id.attrs = c_parser_std_attribute_specifier_sequence (parser);
27bf414c
JM
3918 return c_parser_direct_declarator_inner (parser, *seen_id, inner);
3919 }
3920
3921 if (kind != C_DTR_NORMAL
4e03c3a7
JM
3922 && c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
3923 && !c_parser_nth_token_starts_std_attributes (parser, 1))
27bf414c
JM
3924 {
3925 struct c_declarator *inner = build_id_declarator (NULL_TREE);
1f40cff3 3926 inner->id_loc = c_parser_peek_token (parser)->location;
27bf414c
JM
3927 return c_parser_direct_declarator_inner (parser, *seen_id, inner);
3928 }
3929
3930 /* Either we are at the end of an abstract declarator, or we have
3931 parentheses. */
3932
3933 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
3934 {
3935 tree attrs;
3936 struct c_declarator *inner;
3937 c_parser_consume_token (parser);
4e03c3a7
JM
3938 bool have_gnu_attrs = c_parser_next_token_is_keyword (parser,
3939 RID_ATTRIBUTE);
783bfe5e 3940 attrs = c_parser_gnu_attributes (parser);
27bf414c
JM
3941 if (kind != C_DTR_NORMAL
3942 && (c_parser_next_token_starts_declspecs (parser)
4e03c3a7
JM
3943 || (!have_gnu_attrs
3944 && c_parser_nth_token_starts_std_attributes (parser, 1))
27bf414c
JM
3945 || c_parser_next_token_is (parser, CPP_CLOSE_PAREN)))
3946 {
3947 struct c_arg_info *args
3948 = c_parser_parms_declarator (parser, kind == C_DTR_NORMAL,
4e03c3a7 3949 attrs, have_gnu_attrs);
27bf414c
JM
3950 if (args == NULL)
3951 return NULL;
3952 else
3953 {
1723e1be 3954 inner = build_id_declarator (NULL_TREE);
4e03c3a7
JM
3955 if (!(args->types
3956 && args->types != error_mark_node
3957 && TREE_CODE (TREE_VALUE (args->types)) == IDENTIFIER_NODE)
3958 && c_parser_nth_token_starts_std_attributes (parser, 1))
3959 {
3960 tree std_attrs
3961 = c_parser_std_attribute_specifier_sequence (parser);
3962 if (std_attrs)
3963 inner = build_attrs_declarator (std_attrs, inner);
3964 }
1723e1be 3965 inner = build_function_declarator (args, inner);
27bf414c
JM
3966 return c_parser_direct_declarator_inner (parser, *seen_id,
3967 inner);
3968 }
3969 }
3970 /* A parenthesized declarator. */
3971 inner = c_parser_declarator (parser, type_seen_p, kind, seen_id);
3972 if (inner != NULL && attrs != NULL)
3973 inner = build_attrs_declarator (attrs, inner);
3974 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
3975 {
3976 c_parser_consume_token (parser);
3977 if (inner == NULL)
3978 return NULL;
3979 else
3980 return c_parser_direct_declarator_inner (parser, *seen_id, inner);
3981 }
3982 else
3983 {
3984 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
3985 "expected %<)%>");
3986 return NULL;
3987 }
3988 }
3989 else
3990 {
3991 if (kind == C_DTR_NORMAL)
3992 {
3993 c_parser_error (parser, "expected identifier or %<(%>");
3994 return NULL;
3995 }
3996 else
3997 return build_id_declarator (NULL_TREE);
3998 }
3999}
4000
4001/* Parse part of a direct declarator or direct abstract declarator,
4002 given that some (in INNER) has already been parsed; ID_PRESENT is
4003 true if an identifier is present, false for an abstract
4004 declarator. */
4005
4006static struct c_declarator *
4007c_parser_direct_declarator_inner (c_parser *parser, bool id_present,
4008 struct c_declarator *inner)
4009{
4010 /* Parse a sequence of array declarators and parameter lists. */
4e03c3a7
JM
4011 if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
4012 && !c_parser_nth_token_starts_std_attributes (parser, 1))
27bf414c 4013 {
b8698a0f 4014 location_t brace_loc = c_parser_peek_token (parser)->location;
27bf414c
JM
4015 struct c_declarator *declarator;
4016 struct c_declspecs *quals_attrs = build_null_declspecs ();
4017 bool static_seen;
4018 bool star_seen;
267bac10
JM
4019 struct c_expr dimen;
4020 dimen.value = NULL_TREE;
4021 dimen.original_code = ERROR_MARK;
4022 dimen.original_type = NULL_TREE;
27bf414c 4023 c_parser_consume_token (parser);
568a31f2 4024 c_parser_declspecs (parser, quals_attrs, false, false, true,
4e03c3a7 4025 false, false, false, false, cla_prefer_id);
27bf414c
JM
4026 static_seen = c_parser_next_token_is_keyword (parser, RID_STATIC);
4027 if (static_seen)
4028 c_parser_consume_token (parser);
4029 if (static_seen && !quals_attrs->declspecs_seen_p)
568a31f2 4030 c_parser_declspecs (parser, quals_attrs, false, false, true,
4e03c3a7 4031 false, false, false, false, cla_prefer_id);
27bf414c
JM
4032 if (!quals_attrs->declspecs_seen_p)
4033 quals_attrs = NULL;
4034 /* If "static" is present, there must be an array dimension.
4035 Otherwise, there may be a dimension, "*", or no
4036 dimension. */
4037 if (static_seen)
4038 {
4039 star_seen = false;
267bac10 4040 dimen = c_parser_expr_no_commas (parser, NULL);
27bf414c
JM
4041 }
4042 else
4043 {
4044 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
4045 {
267bac10 4046 dimen.value = NULL_TREE;
27bf414c
JM
4047 star_seen = false;
4048 }
4049 else if (c_parser_next_token_is (parser, CPP_MULT))
4050 {
4051 if (c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_SQUARE)
4052 {
267bac10 4053 dimen.value = NULL_TREE;
27bf414c
JM
4054 star_seen = true;
4055 c_parser_consume_token (parser);
4056 }
4057 else
4058 {
4059 star_seen = false;
267bac10 4060 dimen = c_parser_expr_no_commas (parser, NULL);
27bf414c
JM
4061 }
4062 }
4063 else
4064 {
4065 star_seen = false;
267bac10 4066 dimen = c_parser_expr_no_commas (parser, NULL);
27bf414c
JM
4067 }
4068 }
4069 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
4070 c_parser_consume_token (parser);
4071 else
4072 {
4073 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
4074 "expected %<]%>");
4075 return NULL;
4076 }
267bac10
JM
4077 if (dimen.value)
4078 dimen = convert_lvalue_to_rvalue (brace_loc, dimen, true, true);
4079 declarator = build_array_declarator (brace_loc, dimen.value, quals_attrs,
c2255bc4 4080 static_seen, star_seen);
52ffd86e
MS
4081 if (declarator == NULL)
4082 return NULL;
4e03c3a7
JM
4083 if (c_parser_nth_token_starts_std_attributes (parser, 1))
4084 {
4085 tree std_attrs
4086 = c_parser_std_attribute_specifier_sequence (parser);
4087 if (std_attrs)
4088 inner = build_attrs_declarator (std_attrs, inner);
4089 }
1723e1be 4090 inner = set_array_declarator_inner (declarator, inner);
27bf414c
JM
4091 return c_parser_direct_declarator_inner (parser, id_present, inner);
4092 }
4093 else if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
4094 {
4095 tree attrs;
4096 struct c_arg_info *args;
4097 c_parser_consume_token (parser);
4e03c3a7
JM
4098 bool have_gnu_attrs = c_parser_next_token_is_keyword (parser,
4099 RID_ATTRIBUTE);
783bfe5e 4100 attrs = c_parser_gnu_attributes (parser);
4e03c3a7
JM
4101 args = c_parser_parms_declarator (parser, id_present, attrs,
4102 have_gnu_attrs);
27bf414c
JM
4103 if (args == NULL)
4104 return NULL;
4105 else
4106 {
4e03c3a7
JM
4107 if (!(args->types
4108 && args->types != error_mark_node
4109 && TREE_CODE (TREE_VALUE (args->types)) == IDENTIFIER_NODE)
4110 && c_parser_nth_token_starts_std_attributes (parser, 1))
4111 {
4112 tree std_attrs
4113 = c_parser_std_attribute_specifier_sequence (parser);
4114 if (std_attrs)
4115 inner = build_attrs_declarator (std_attrs, inner);
4116 }
1723e1be 4117 inner = build_function_declarator (args, inner);
27bf414c
JM
4118 return c_parser_direct_declarator_inner (parser, id_present, inner);
4119 }
4120 }
4121 return inner;
4122}
4123
4124/* Parse a parameter list or identifier list, including the closing
4e03c3a7
JM
4125 parenthesis but not the opening one. ATTRS are the gnu-attributes
4126 at the start of the list. ID_LIST_OK is true if an identifier list
4127 is acceptable; such a list must not have attributes at the start.
4128 HAVE_GNU_ATTRS says whether any gnu-attributes (including empty
4129 attributes) were present (in which case standard attributes cannot
4130 occur). */
27bf414c
JM
4131
4132static struct c_arg_info *
4e03c3a7
JM
4133c_parser_parms_declarator (c_parser *parser, bool id_list_ok, tree attrs,
4134 bool have_gnu_attrs)
27bf414c
JM
4135{
4136 push_scope ();
4137 declare_parm_level ();
4138 /* If the list starts with an identifier, it is an identifier list.
4139 Otherwise, it is either a prototype list or an empty list. */
4140 if (id_list_ok
4141 && !attrs
4142 && c_parser_next_token_is (parser, CPP_NAME)
29ce73cb
PB
4143 && c_parser_peek_token (parser)->id_kind == C_ID_ID
4144
4145 /* Look ahead to detect typos in type names. */
4146 && c_parser_peek_2nd_token (parser)->type != CPP_NAME
4147 && c_parser_peek_2nd_token (parser)->type != CPP_MULT
4148 && c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN
1a4f11c8
DM
4149 && c_parser_peek_2nd_token (parser)->type != CPP_OPEN_SQUARE
4150 && c_parser_peek_2nd_token (parser)->type != CPP_KEYWORD)
27bf414c 4151 {
7fa3585c 4152 tree list = NULL_TREE, *nextp = &list;
27bf414c
JM
4153 while (c_parser_next_token_is (parser, CPP_NAME)
4154 && c_parser_peek_token (parser)->id_kind == C_ID_ID)
4155 {
7fa3585c
GK
4156 *nextp = build_tree_list (NULL_TREE,
4157 c_parser_peek_token (parser)->value);
4158 nextp = & TREE_CHAIN (*nextp);
27bf414c
JM
4159 c_parser_consume_token (parser);
4160 if (c_parser_next_token_is_not (parser, CPP_COMMA))
4161 break;
4162 c_parser_consume_token (parser);
4163 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4164 {
4165 c_parser_error (parser, "expected identifier");
4166 break;
4167 }
4168 }
4169 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4170 {
b3399d18 4171 struct c_arg_info *ret = build_arg_info ();
27bf414c 4172 ret->types = list;
27bf414c
JM
4173 c_parser_consume_token (parser);
4174 pop_scope ();
4175 return ret;
4176 }
4177 else
4178 {
4179 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4180 "expected %<)%>");
4181 pop_scope ();
4182 return NULL;
4183 }
4184 }
4185 else
4186 {
4e03c3a7
JM
4187 struct c_arg_info *ret
4188 = c_parser_parms_list_declarator (parser, attrs, NULL, have_gnu_attrs);
27bf414c
JM
4189 pop_scope ();
4190 return ret;
4191 }
4192}
4193
4194/* Parse a parameter list (possibly empty), including the closing
4e03c3a7
JM
4195 parenthesis but not the opening one. ATTRS are the gnu-attributes
4196 at the start of the list; if HAVE_GNU_ATTRS, there were some such
4197 attributes (possibly empty, in which case ATTRS is NULL_TREE),
4198 which means standard attributes cannot start the list. EXPR is
4199 NULL or an expression that needs to be evaluated for the side
4200 effects of array size expressions in the parameters. */
27bf414c
JM
4201
4202static struct c_arg_info *
4e03c3a7
JM
4203c_parser_parms_list_declarator (c_parser *parser, tree attrs, tree expr,
4204 bool have_gnu_attrs)
27bf414c 4205{
09a1e889 4206 bool bad_parm = false;
a04a722b 4207
27bf414c
JM
4208 /* ??? Following the old parser, forward parameter declarations may
4209 use abstract declarators, and if no real parameter declarations
4210 follow the forward declarations then this is not diagnosed. Also
4e03c3a7 4211 note as above that gnu-attributes are ignored as the only contents of
27bf414c
JM
4212 the parentheses, or as the only contents after forward
4213 declarations. */
4214 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4215 {
b3399d18 4216 struct c_arg_info *ret = build_arg_info ();
27bf414c
JM
4217 c_parser_consume_token (parser);
4218 return ret;
4219 }
4220 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
4221 {
b3399d18 4222 struct c_arg_info *ret = build_arg_info ();
6637388f
TG
4223
4224 if (flag_allow_parameterless_variadic_functions)
4225 {
4226 /* F (...) is allowed. */
4227 ret->types = NULL_TREE;
4228 }
4229 else
4230 {
4231 /* Suppress -Wold-style-definition for this case. */
4232 ret->types = error_mark_node;
4233 error_at (c_parser_peek_token (parser)->location,
4234 "ISO C requires a named argument before %<...%>");
4235 }
27bf414c
JM
4236 c_parser_consume_token (parser);
4237 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4238 {
4239 c_parser_consume_token (parser);
4240 return ret;
4241 }
4242 else
4243 {
4244 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4245 "expected %<)%>");
4246 return NULL;
4247 }
4248 }
4249 /* Nonempty list of parameters, either terminated with semicolon
4250 (forward declarations; recurse) or with close parenthesis (normal
4251 function) or with ", ... )" (variadic function). */
4252 while (true)
4253 {
4254 /* Parse a parameter. */
4e03c3a7
JM
4255 struct c_parm *parm = c_parser_parameter_declaration (parser, attrs,
4256 have_gnu_attrs);
27bf414c 4257 attrs = NULL_TREE;
4e03c3a7 4258 have_gnu_attrs = false;
09a1e889
SZ
4259 if (parm == NULL)
4260 bad_parm = true;
4261 else
a04a722b 4262 push_parm_decl (parm, &expr);
27bf414c
JM
4263 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
4264 {
4265 tree new_attrs;
4266 c_parser_consume_token (parser);
91d975b8 4267 mark_forward_parm_decls ();
4e03c3a7
JM
4268 bool new_have_gnu_attrs
4269 = c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE);
783bfe5e 4270 new_attrs = c_parser_gnu_attributes (parser);
4e03c3a7
JM
4271 return c_parser_parms_list_declarator (parser, new_attrs, expr,
4272 new_have_gnu_attrs);
27bf414c
JM
4273 }
4274 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4275 {
4276 c_parser_consume_token (parser);
09a1e889 4277 if (bad_parm)
a04a722b 4278 return NULL;
09a1e889 4279 else
a04a722b 4280 return get_parm_info (false, expr);
27bf414c
JM
4281 }
4282 if (!c_parser_require (parser, CPP_COMMA,
62e1c678
DM
4283 "expected %<;%>, %<,%> or %<)%>",
4284 UNKNOWN_LOCATION, false))
27bf414c
JM
4285 {
4286 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4287 return NULL;
4288 }
4289 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
4290 {
4291 c_parser_consume_token (parser);
4292 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4293 {
4294 c_parser_consume_token (parser);
09a1e889 4295 if (bad_parm)
a04a722b 4296 return NULL;
09a1e889 4297 else
a04a722b 4298 return get_parm_info (true, expr);
27bf414c
JM
4299 }
4300 else
4301 {
4302 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4303 "expected %<)%>");
4304 return NULL;
4305 }
4306 }
4307 }
4308}
4309
4e03c3a7
JM
4310/* Parse a parameter declaration. ATTRS are the gnu-attributes at the
4311 start of the declaration if it is the first parameter;
4312 HAVE_GNU_ATTRS is true if there were any gnu-attributes there (even
4313 empty) there. */
27bf414c
JM
4314
4315static struct c_parm *
4e03c3a7
JM
4316c_parser_parameter_declaration (c_parser *parser, tree attrs,
4317 bool have_gnu_attrs)
27bf414c
JM
4318{
4319 struct c_declspecs *specs;
4320 struct c_declarator *declarator;
4321 tree prefix_attrs;
4322 tree postfix_attrs = NULL_TREE;
4323 bool dummy = false;
51a1aacf
TG
4324
4325 /* Accept #pragmas between parameter declarations. */
4326 while (c_parser_next_token_is (parser, CPP_PRAGMA))
dda1bf61 4327 c_parser_pragma (parser, pragma_param, NULL);
51a1aacf 4328
4e03c3a7
JM
4329 if (!c_parser_next_token_starts_declspecs (parser)
4330 && !c_parser_nth_token_starts_std_attributes (parser, 1))
27bf414c 4331 {
09a1e889
SZ
4332 c_token *token = c_parser_peek_token (parser);
4333 if (parser->error)
4334 return NULL;
4335 c_parser_set_source_position_from_token (token);
29ce73cb 4336 if (c_parser_next_tokens_start_typename (parser, cla_prefer_type))
09a1e889 4337 {
097f82ec 4338 auto_diagnostic_group d;
6c7a259b
DM
4339 name_hint hint = lookup_name_fuzzy (token->value,
4340 FUZZY_LOOKUP_TYPENAME,
4341 token->location);
7e2de6df 4342 if (const char *suggestion = hint.suggestion ())
1a4f11c8 4343 {
1a4f11c8 4344 gcc_rich_location richloc (token->location);
7e2de6df 4345 richloc.add_fixit_replace (suggestion);
64a5912c
DM
4346 error_at (&richloc,
4347 "unknown type name %qE; did you mean %qs?",
7e2de6df 4348 token->value, suggestion);
1a4f11c8
DM
4349 }
4350 else
4351 error_at (token->location, "unknown type name %qE", token->value);
09a1e889
SZ
4352 parser->error = true;
4353 }
27bf414c
JM
4354 /* ??? In some Objective-C cases '...' isn't applicable so there
4355 should be a different message. */
09a1e889
SZ
4356 else
4357 c_parser_error (parser,
4358 "expected declaration specifiers or %<...%>");
27bf414c
JM
4359 c_parser_skip_to_end_of_parameter (parser);
4360 return NULL;
4361 }
8139a48e
DM
4362
4363 location_t start_loc = c_parser_peek_token (parser)->location;
4364
27bf414c
JM
4365 specs = build_null_declspecs ();
4366 if (attrs)
4367 {
0b2c4be5 4368 declspecs_add_attrs (input_location, specs, attrs);
27bf414c
JM
4369 attrs = NULL_TREE;
4370 }
38b7bc7f 4371 c_parser_declspecs (parser, specs, true, true, true, true, false,
4e03c3a7 4372 !have_gnu_attrs, true, cla_nonabstract_decl);
27bf414c
JM
4373 finish_declspecs (specs);
4374 pending_xref_error ();
4375 prefix_attrs = specs->attrs;
4376 specs->attrs = NULL_TREE;
9e5b2115
PB
4377 declarator = c_parser_declarator (parser,
4378 specs->typespec_kind != ctsk_none,
27bf414c
JM
4379 C_DTR_PARM, &dummy);
4380 if (declarator == NULL)
4381 {
4382 c_parser_skip_until_found (parser, CPP_COMMA, NULL);
4383 return NULL;
4384 }
4385 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
783bfe5e 4386 postfix_attrs = c_parser_gnu_attributes (parser);
8139a48e
DM
4387
4388 /* Generate a location for the parameter, ranging from the start of the
4389 initial token to the end of the final token.
4390
4391 If we have a identifier, then use it for the caret location, e.g.
4392
4393 extern int callee (int one, int (*two)(int, int), float three);
4394 ~~~~~~^~~~~~~~~~~~~~
4395
4396 otherwise, reuse the start location for the caret location e.g.:
4397
4398 extern int callee (int one, int (*)(int, int), float three);
4399 ^~~~~~~~~~~~~~~~~
4400 */
4401 location_t end_loc = parser->last_token_location;
4402
4403 /* Find any cdk_id declarator; determine if we have an identifier. */
4404 c_declarator *id_declarator = declarator;
4405 while (id_declarator && id_declarator->kind != cdk_id)
4406 id_declarator = id_declarator->declarator;
1723e1be 4407 location_t caret_loc = (id_declarator->u.id.id
8139a48e
DM
4408 ? id_declarator->id_loc
4409 : start_loc);
4410 location_t param_loc = make_location (caret_loc, start_loc, end_loc);
4411
27bf414c 4412 return build_c_parm (specs, chainon (postfix_attrs, prefix_attrs),
8139a48e 4413 declarator, param_loc);
27bf414c
JM
4414}
4415
4416/* Parse a string literal in an asm expression. It should not be
4417 translated, and wide string literals are an error although
4418 permitted by the syntax. This is a GNU extension.
4419
4420 asm-string-literal:
4421 string-literal
471c5330 4422*/
27bf414c
JM
4423
4424static tree
4425c_parser_asm_string_literal (c_parser *parser)
4426{
4427 tree str;
87f9e23d
TT
4428 int save_flag = warn_overlength_strings;
4429 warn_overlength_strings = 0;
471c5330 4430 str = c_parser_string_literal (parser, false, false).value;
87f9e23d 4431 warn_overlength_strings = save_flag;
27bf414c
JM
4432 return str;
4433}
4434
4435/* Parse a simple asm expression. This is used in restricted
4436 contexts, where a full expression with inputs and outputs does not
4437 make sense. This is a GNU extension.
4438
4439 simple-asm-expr:
4440 asm ( asm-string-literal )
4441*/
4442
4443static tree
4444c_parser_simple_asm_expr (c_parser *parser)
4445{
4446 tree str;
4447 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
27bf414c 4448 c_parser_consume_token (parser);
32129a17
DM
4449 matching_parens parens;
4450 if (!parens.require_open (parser))
471c5330 4451 return NULL_TREE;
27bf414c 4452 str = c_parser_asm_string_literal (parser);
32129a17 4453 if (!parens.require_close (parser))
27bf414c
JM
4454 {
4455 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4456 return NULL_TREE;
4457 }
4458 return str;
4459}
4460
0a35513e 4461static tree
783bfe5e 4462c_parser_gnu_attribute_any_word (c_parser *parser)
0a35513e
AH
4463{
4464 tree attr_name = NULL_TREE;
4465
4466 if (c_parser_next_token_is (parser, CPP_KEYWORD))
4467 {
4468 /* ??? See comment above about what keywords are accepted here. */
4469 bool ok;
4470 switch (c_parser_peek_token (parser)->keyword)
4471 {
4472 case RID_STATIC:
4473 case RID_UNSIGNED:
4474 case RID_LONG:
0a35513e
AH
4475 case RID_CONST:
4476 case RID_EXTERN:
4477 case RID_REGISTER:
4478 case RID_TYPEDEF:
4479 case RID_SHORT:
4480 case RID_INLINE:
4481 case RID_NORETURN:
4482 case RID_VOLATILE:
4483 case RID_SIGNED:
4484 case RID_AUTO:
4485 case RID_RESTRICT:
4486 case RID_COMPLEX:
4487 case RID_THREAD:
4488 case RID_INT:
4489 case RID_CHAR:
4490 case RID_FLOAT:
4491 case RID_DOUBLE:
4492 case RID_VOID:
4493 case RID_DFLOAT32:
4494 case RID_DFLOAT64:
4495 case RID_DFLOAT128:
c65699ef 4496 CASE_RID_FLOATN_NX:
0a35513e
AH
4497 case RID_BOOL:
4498 case RID_FRACT:
4499 case RID_ACCUM:
4500 case RID_SAT:
4501 case RID_TRANSACTION_ATOMIC:
4502 case RID_TRANSACTION_CANCEL:
267bac10 4503 case RID_ATOMIC:
38b7bc7f 4504 case RID_AUTO_TYPE:
78a7c317
DD
4505 case RID_INT_N_0:
4506 case RID_INT_N_1:
4507 case RID_INT_N_2:
4508 case RID_INT_N_3:
0a35513e
AH
4509 ok = true;
4510 break;
4511 default:
4512 ok = false;
4513 break;
4514 }
4515 if (!ok)
4516 return NULL_TREE;
4517
4518 /* Accept __attribute__((__const)) as __attribute__((const)) etc. */
4519 attr_name = ridpointers[(int) c_parser_peek_token (parser)->keyword];
4520 }
4521 else if (c_parser_next_token_is (parser, CPP_NAME))
4522 attr_name = c_parser_peek_token (parser)->value;
4523
4524 return attr_name;
4525}
4526
c01bd174
JM
4527/* Parse attribute arguments. This is a common form of syntax
4528 covering all currently valid GNU and standard attributes.
4529
4530 gnu-attribute-arguments:
4531 identifier
4532 identifier , nonempty-expr-list
4533 expr-list
4534
4535 where the "identifier" must not be declared as a type. ??? Why not
4536 allow identifiers declared as types to start the arguments? */
4537
4538static tree
2cc94aa8
JM
4539c_parser_attribute_arguments (c_parser *parser, bool takes_identifier,
4540 bool require_string, bool allow_empty_args)
c01bd174
JM
4541{
4542 vec<tree, va_gc> *expr_list;
4543 tree attr_args;
4544 /* Parse the attribute contents. If they start with an
4545 identifier which is followed by a comma or close
4546 parenthesis, then the arguments start with that
4547 identifier; otherwise they are an expression list.
4548 In objective-c the identifier may be a classname. */
4549 if (c_parser_next_token_is (parser, CPP_NAME)
4550 && (c_parser_peek_token (parser)->id_kind == C_ID_ID
4551 || (c_dialect_objc ()
4552 && c_parser_peek_token (parser)->id_kind
4553 == C_ID_CLASSNAME))
4554 && ((c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
4555 || (c_parser_peek_2nd_token (parser)->type
4556 == CPP_CLOSE_PAREN))
4557 && (takes_identifier
4558 || (c_dialect_objc ()
4559 && c_parser_peek_token (parser)->id_kind
4560 == C_ID_CLASSNAME)))
4561 {
4562 tree arg1 = c_parser_peek_token (parser)->value;
4563 c_parser_consume_token (parser);
4564 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4565 attr_args = build_tree_list (NULL_TREE, arg1);
4566 else
4567 {
4568 tree tree_list;
4569 c_parser_consume_token (parser);
4570 expr_list = c_parser_expr_list (parser, false, true,
4571 NULL, NULL, NULL, NULL);
4572 tree_list = build_tree_list_vec (expr_list);
4573 attr_args = tree_cons (NULL_TREE, arg1, tree_list);
4574 release_tree_vector (expr_list);
4575 }
4576 }
4577 else
4578 {
4579 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
2cc94aa8
JM
4580 {
4581 if (!allow_empty_args)
4582 error_at (c_parser_peek_token (parser)->location,
4583 "parentheses must be omitted if "
4584 "attribute argument list is empty");
4585 attr_args = NULL_TREE;
4586 }
4587 else if (require_string)
4588 {
4589 /* The only valid argument for this attribute is a string
4590 literal. Handle this specially here to avoid accepting
4591 string literals with excess parentheses. */
4592 tree string = c_parser_string_literal (parser, false, true).value;
4593 attr_args = build_tree_list (NULL_TREE, string);
4594 }
c01bd174
JM
4595 else
4596 {
4597 expr_list = c_parser_expr_list (parser, false, true,
4598 NULL, NULL, NULL, NULL);
4599 attr_args = build_tree_list_vec (expr_list);
4600 release_tree_vector (expr_list);
4601 }
4602 }
4603 return attr_args;
4604}
4605
783bfe5e 4606/* Parse (possibly empty) gnu-attributes. This is a GNU extension.
27bf414c 4607
783bfe5e 4608 gnu-attributes:
27bf414c 4609 empty
783bfe5e 4610 gnu-attributes gnu-attribute
27bf414c 4611
783bfe5e
JM
4612 gnu-attribute:
4613 __attribute__ ( ( gnu-attribute-list ) )
27bf414c 4614
783bfe5e
JM
4615 gnu-attribute-list:
4616 gnu-attrib
4617 gnu-attribute_list , gnu-attrib
27bf414c 4618
783bfe5e 4619 gnu-attrib:
27bf414c
JM
4620 empty
4621 any-word
c01bd174 4622 any-word ( gnu-attribute-arguments )
27bf414c 4623
c01bd174 4624 where "any-word" may be any identifier (including one declared as a
27bf414c
JM
4625 type), a reserved word storage class specifier, type specifier or
4626 type qualifier. ??? This still leaves out most reserved keywords
c01bd174 4627 (following the old parser), shouldn't we include them?
98f08eb8
MS
4628 When EXPECT_COMMA is true, expect the attribute to be preceded
4629 by a comma and fail if it isn't.
4630 When EMPTY_OK is true, allow and consume any number of consecutive
4631 commas with no attributes in between. */
4632
4633static tree
783bfe5e
JM
4634c_parser_gnu_attribute (c_parser *parser, tree attrs,
4635 bool expect_comma = false, bool empty_ok = true)
98f08eb8
MS
4636{
4637 bool comma_first = c_parser_next_token_is (parser, CPP_COMMA);
4638 if (!comma_first
4639 && !c_parser_next_token_is (parser, CPP_NAME)
4640 && !c_parser_next_token_is (parser, CPP_KEYWORD))
4641 return NULL_TREE;
4642
4643 while (c_parser_next_token_is (parser, CPP_COMMA))
4644 {
4645 c_parser_consume_token (parser);
4646 if (!empty_ok)
4647 return attrs;
4648 }
4649
783bfe5e 4650 tree attr_name = c_parser_gnu_attribute_any_word (parser);
98f08eb8
MS
4651 if (attr_name == NULL_TREE)
4652 return NULL_TREE;
4653
4654 attr_name = canonicalize_attr_name (attr_name);
4655 c_parser_consume_token (parser);
4656
4657 tree attr;
4658 if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
4659 {
4660 if (expect_comma && !comma_first)
4661 {
4662 /* A comma is missing between the last attribute on the chain
4663 and this one. */
4664 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4665 "expected %<)%>");
4666 return error_mark_node;
4667 }
4668 attr = build_tree_list (attr_name, NULL_TREE);
4669 /* Add this attribute to the list. */
4670 attrs = chainon (attrs, attr);
4671 return attrs;
4672 }
4673 c_parser_consume_token (parser);
4674
c01bd174
JM
4675 tree attr_args
4676 = c_parser_attribute_arguments (parser,
2cc94aa8
JM
4677 attribute_takes_identifier_p (attr_name),
4678 false, true);
98f08eb8
MS
4679
4680 attr = build_tree_list (attr_name, attr_args);
4681 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4682 c_parser_consume_token (parser);
4683 else
4684 {
98f08eb8
MS
4685 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4686 "expected %<)%>");
4687 return error_mark_node;
4688 }
4689
4690 if (expect_comma && !comma_first)
4691 {
4692 /* A comma is missing between the last attribute on the chain
4693 and this one. */
4694 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4695 "expected %<)%>");
4696 return error_mark_node;
4697 }
4698
4699 /* Add this attribute to the list. */
4700 attrs = chainon (attrs, attr);
4701 return attrs;
4702}
27bf414c
JM
4703
4704static tree
783bfe5e 4705c_parser_gnu_attributes (c_parser *parser)
27bf414c
JM
4706{
4707 tree attrs = NULL_TREE;
4708 while (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
4709 {
471c5330
JM
4710 bool save_translate_strings_p = parser->translate_strings_p;
4711 parser->translate_strings_p = false;
2c7020eb 4712 /* Consume the `__attribute__' keyword. */
27bf414c 4713 c_parser_consume_token (parser);
2c7020eb 4714 /* Look for the two `(' tokens. */
27bf414c
JM
4715 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
4716 {
471c5330 4717 parser->translate_strings_p = save_translate_strings_p;
27bf414c
JM
4718 return attrs;
4719 }
4720 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
4721 {
471c5330 4722 parser->translate_strings_p = save_translate_strings_p;
27bf414c
JM
4723 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4724 return attrs;
4725 }
98f08eb8
MS
4726 /* Parse the attribute list. Require a comma between successive
4727 (possibly empty) attributes. */
4728 for (bool expect_comma = false; ; expect_comma = true)
27bf414c 4729 {
98f08eb8 4730 /* Parse a single attribute. */
783bfe5e 4731 tree attr = c_parser_gnu_attribute (parser, attrs, expect_comma);
98f08eb8
MS
4732 if (attr == error_mark_node)
4733 return attrs;
4734 if (!attr)
0a35513e 4735 break;
98f08eb8
MS
4736 attrs = attr;
4737 }
577eec56 4738
2c7020eb 4739 /* Look for the two `)' tokens. */
27bf414c
JM
4740 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4741 c_parser_consume_token (parser);
4742 else
4743 {
471c5330 4744 parser->translate_strings_p = save_translate_strings_p;
27bf414c
JM
4745 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4746 "expected %<)%>");
4747 return attrs;
4748 }
4749 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4750 c_parser_consume_token (parser);
4751 else
4752 {
471c5330 4753 parser->translate_strings_p = save_translate_strings_p;
27bf414c
JM
4754 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4755 "expected %<)%>");
4756 return attrs;
4757 }
471c5330 4758 parser->translate_strings_p = save_translate_strings_p;
27bf414c 4759 }
41958c28 4760
27bf414c
JM
4761 return attrs;
4762}
4763
c01bd174
JM
4764/* Parse an optional balanced token sequence.
4765
4766 balanced-token-sequence:
4767 balanced-token
4768 balanced-token-sequence balanced-token
4769
4770 balanced-token:
4771 ( balanced-token-sequence[opt] )
4772 [ balanced-token-sequence[opt] ]
4773 { balanced-token-sequence[opt] }
4774 any token other than ()[]{}
4775*/
4776
4777static void
4778c_parser_balanced_token_sequence (c_parser *parser)
4779{
4780 while (true)
4781 {
4782 c_token *token = c_parser_peek_token (parser);
4783 switch (token->type)
4784 {
4785 case CPP_OPEN_BRACE:
4786 {
4787 matching_braces braces;
4788 braces.consume_open (parser);
4789 c_parser_balanced_token_sequence (parser);
4790 braces.require_close (parser);
4791 break;
4792 }
4793
4794 case CPP_OPEN_PAREN:
4795 {
4796 matching_parens parens;
4797 parens.consume_open (parser);
4798 c_parser_balanced_token_sequence (parser);
4799 parens.require_close (parser);
4800 break;
4801 }
4802
4803 case CPP_OPEN_SQUARE:
4804 c_parser_consume_token (parser);
4805 c_parser_balanced_token_sequence (parser);
4806 c_parser_require (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
4807 break;
4808
4809 case CPP_CLOSE_BRACE:
4810 case CPP_CLOSE_PAREN:
4811 case CPP_CLOSE_SQUARE:
4812 case CPP_EOF:
4813 return;
4814
4815 default:
4816 c_parser_consume_token (parser);
4817 break;
4818 }
4819 }
4820}
4821
4822/* Parse standard (C2X) attributes (including GNU attributes in the
4823 gnu:: namespace).
4824
4825 attribute-specifier-sequence:
4826 attribute-specifier-sequence[opt] attribute-specifier
4827
4828 attribute-specifier:
4829 [ [ attribute-list ] ]
4830
4831 attribute-list:
4832 attribute[opt]
4833 attribute-list, attribute[opt]
4834
4835 attribute:
4836 attribute-token attribute-argument-clause[opt]
4837
4838 attribute-token:
4839 standard-attribute
4840 attribute-prefixed-token
4841
4842 standard-attribute:
4843 identifier
4844
4845 attribute-prefixed-token:
4846 attribute-prefix :: identifier
4847
4848 attribute-prefix:
4849 identifier
4850
4851 attribute-argument-clause:
4852 ( balanced-token-sequence[opt] )
4853
4854 Keywords are accepted as identifiers for this purpose.
4855*/
4856
4857static tree
192961ff 4858c_parser_std_attribute (c_parser *parser, bool for_tm)
c01bd174
JM
4859{
4860 c_token *token = c_parser_peek_token (parser);
4861 tree ns, name, attribute;
4862
4863 /* Parse the attribute-token. */
4864 if (token->type != CPP_NAME && token->type != CPP_KEYWORD)
4865 {
4866 c_parser_error (parser, "expected identifier");
4867 return error_mark_node;
4868 }
4869 name = canonicalize_attr_name (token->value);
4870 c_parser_consume_token (parser);
4871 if (c_parser_next_token_is (parser, CPP_SCOPE))
4872 {
4873 ns = name;
4874 c_parser_consume_token (parser);
4875 token = c_parser_peek_token (parser);
4876 if (token->type != CPP_NAME && token->type != CPP_KEYWORD)
4877 {
4878 c_parser_error (parser, "expected identifier");
4879 return error_mark_node;
4880 }
4881 name = canonicalize_attr_name (token->value);
4882 c_parser_consume_token (parser);
4883 }
4884 else
4885 ns = NULL_TREE;
4886 attribute = build_tree_list (build_tree_list (ns, name), NULL_TREE);
4887
4888 /* Parse the arguments, if any. */
c01bd174 4889 const attribute_spec *as = lookup_attribute_spec (TREE_PURPOSE (attribute));
192961ff
JM
4890 if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
4891 goto out;
4892 {
4893 location_t open_loc = c_parser_peek_token (parser)->location;
4894 matching_parens parens;
4895 parens.consume_open (parser);
4896 if ((as && as->max_length == 0)
4897 /* Special-case the transactional-memory attribute "outer",
4898 which is specially handled but not registered as an
4899 attribute, to avoid allowing arbitrary balanced token
4900 sequences as arguments. */
4901 || is_attribute_p ("outer", name))
4902 {
4903 error_at (open_loc, "%qE attribute does not take any arguments", name);
4904 parens.skip_until_found_close (parser);
4905 return error_mark_node;
4906 }
4907 if (as)
4908 {
4909 bool takes_identifier
4910 = (ns != NULL_TREE
4911 && strcmp (IDENTIFIER_POINTER (ns), "gnu") == 0
4912 && attribute_takes_identifier_p (name));
4913 bool require_string
4914 = (ns == NULL_TREE
4915 && strcmp (IDENTIFIER_POINTER (name), "deprecated") == 0);
4916 TREE_VALUE (attribute)
4917 = c_parser_attribute_arguments (parser, takes_identifier,
4918 require_string, false);
4919 }
4920 else
4921 c_parser_balanced_token_sequence (parser);
4922 parens.require_close (parser);
4923 }
4924 out:
4925 if (ns == NULL_TREE && !for_tm && !as && !is_attribute_p ("nodiscard", name))
c01bd174 4926 {
192961ff
JM
4927 /* An attribute with standard syntax and no namespace specified
4928 is a constraint violation if it is not one of the known
4929 standard attributes (of which nodiscard is the only one
4930 without a handler in GCC). Diagnose it here with a pedwarn
4931 and then discard it to prevent a duplicate warning later. */
4932 pedwarn (input_location, OPT_Wattributes, "%qE attribute ignored",
4933 name);
c01bd174
JM
4934 return error_mark_node;
4935 }
c01bd174
JM
4936 return attribute;
4937}
4938
4939static tree
4940c_parser_std_attribute_specifier (c_parser *parser, bool for_tm)
4941{
d5fbe5e0
JM
4942 bool seen_deprecated = false;
4943 bool seen_fallthrough = false;
4944 bool seen_maybe_unused = false;
c01bd174
JM
4945 location_t loc = c_parser_peek_token (parser)->location;
4946 if (!c_parser_require (parser, CPP_OPEN_SQUARE, "expected %<[%>"))
4947 return NULL_TREE;
4948 if (!c_parser_require (parser, CPP_OPEN_SQUARE, "expected %<[%>"))
4949 {
4950 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
4951 return NULL_TREE;
4952 }
4953 if (!for_tm)
4954 pedwarn_c11 (loc, OPT_Wpedantic,
4955 "ISO C does not support %<[[]]%> attributes before C2X");
4956 tree attributes = NULL_TREE;
4957 while (true)
4958 {
4959 c_token *token = c_parser_peek_token (parser);
4960 if (token->type == CPP_CLOSE_SQUARE)
4961 break;
4962 if (token->type == CPP_COMMA)
4963 {
4964 c_parser_consume_token (parser);
4965 continue;
4966 }
192961ff 4967 tree attribute = c_parser_std_attribute (parser, for_tm);
c01bd174
JM
4968 if (attribute != error_mark_node)
4969 {
d5fbe5e0
JM
4970 bool duplicate = false;
4971 tree name = get_attribute_name (attribute);
4972 tree ns = get_attribute_namespace (attribute);
4973 if (ns == NULL_TREE)
4974 {
4975 /* Some standard attributes may appear at most once in
4976 each attribute list. Diagnose duplicates and remove
4977 them from the list to avoid subsequent diagnostics
4978 such as the more general one for multiple
4979 "fallthrough" attributes in the same place (including
4980 in separate attribute lists in the same attribute
4981 specifier sequence, which is not a constraint
4982 violation). */
4983 if (is_attribute_p ("deprecated", name))
4984 {
4985 if (seen_deprecated)
4986 {
4987 error ("attribute %<deprecated%> can appear at most "
4988 "once in an attribute-list");
4989 duplicate = true;
4990 }
4991 seen_deprecated = true;
4992 }
4993 else if (is_attribute_p ("fallthrough", name))
4994 {
4995 if (seen_fallthrough)
4996 {
4997 error ("attribute %<fallthrough%> can appear at most "
4998 "once in an attribute-list");
4999 duplicate = true;
5000 }
5001 seen_fallthrough = true;
5002 }
5003 else if (is_attribute_p ("maybe_unused", name))
5004 {
5005 if (seen_maybe_unused)
5006 {
5007 error ("attribute %<maybe_unused%> can appear at most "
5008 "once in an attribute-list");
5009 duplicate = true;
5010 }
5011 seen_maybe_unused = true;
5012 }
5013 }
5014 if (!duplicate)
5015 {
5016 TREE_CHAIN (attribute) = attributes;
5017 attributes = attribute;
5018 }
c01bd174
JM
5019 }
5020 if (c_parser_next_token_is_not (parser, CPP_COMMA))
5021 break;
5022 }
5023 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
5024 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
5025 return nreverse (attributes);
5026}
5027
34b43828
JM
5028/* Look past an optional balanced token sequence of raw look-ahead
5029 tokens starting with the *Nth token. *N is updated to point to the
5030 following token. Return true if such a sequence was found, false
5031 if the tokens parsed were not balanced. */
5032
5033static bool
5034c_parser_check_balanced_raw_token_sequence (c_parser *parser, unsigned int *n)
5035{
5036 while (true)
5037 {
5038 c_token *token = c_parser_peek_nth_token_raw (parser, *n);
5039 switch (token->type)
5040 {
5041 case CPP_OPEN_BRACE:
5042 {
5043 ++*n;
5044 if (c_parser_check_balanced_raw_token_sequence (parser, n))
5045 {
5046 token = c_parser_peek_nth_token_raw (parser, *n);
5047 if (token->type == CPP_CLOSE_BRACE)
5048 ++*n;
5049 else
5050 return false;
5051 }
5052 else
5053 return false;
5054 break;
5055 }
5056
5057 case CPP_OPEN_PAREN:
5058 {
5059 ++*n;
5060 if (c_parser_check_balanced_raw_token_sequence (parser, n))
5061 {
5062 token = c_parser_peek_nth_token_raw (parser, *n);
5063 if (token->type == CPP_CLOSE_PAREN)
5064 ++*n;
5065 else
5066 return false;
5067 }
5068 else
5069 return false;
5070 break;
5071 }
5072
5073 case CPP_OPEN_SQUARE:
5074 {
5075 ++*n;
5076 if (c_parser_check_balanced_raw_token_sequence (parser, n))
5077 {
5078 token = c_parser_peek_nth_token_raw (parser, *n);
5079 if (token->type == CPP_CLOSE_SQUARE)
5080 ++*n;
5081 else
5082 return false;
5083 }
5084 else
5085 return false;
5086 break;
5087 }
5088
5089 case CPP_CLOSE_BRACE:
5090 case CPP_CLOSE_PAREN:
5091 case CPP_CLOSE_SQUARE:
5092 case CPP_EOF:
5093 return true;
5094
5095 default:
5096 ++*n;
5097 break;
5098 }
5099 }
5100}
5101
4e03c3a7
JM
5102/* Return whether standard attributes start with the Nth token. */
5103
5104static bool
5105c_parser_nth_token_starts_std_attributes (c_parser *parser, unsigned int n)
5106{
5107 if (!(c_parser_peek_nth_token (parser, n)->type == CPP_OPEN_SQUARE
5108 && c_parser_peek_nth_token (parser, n + 1)->type == CPP_OPEN_SQUARE))
5109 return false;
34b43828
JM
5110 /* In C, '[[' must start attributes. In Objective-C, we need to
5111 check whether '[[' is matched by ']]'. */
5112 if (!c_dialect_objc ())
5113 return true;
5114 n += 2;
5115 if (!c_parser_check_balanced_raw_token_sequence (parser, &n))
5116 return false;
5117 c_token *token = c_parser_peek_nth_token_raw (parser, n);
5118 if (token->type != CPP_CLOSE_SQUARE)
5119 return false;
5120 token = c_parser_peek_nth_token_raw (parser, n + 1);
5121 return token->type == CPP_CLOSE_SQUARE;
4e03c3a7
JM
5122}
5123
5124static tree
5125c_parser_std_attribute_specifier_sequence (c_parser *parser)
5126{
5127 tree attributes = NULL_TREE;
5128 do
5129 {
5130 tree attrs = c_parser_std_attribute_specifier (parser, false);
5131 attributes = chainon (attributes, attrs);
5132 }
5133 while (c_parser_nth_token_starts_std_attributes (parser, 1));
5134 return attributes;
5135}
5136
4b2b493f
JM
5137/* Parse a type name (C90 6.5.5, C99 6.7.6, C11 6.7.7). ALIGNAS_OK
5138 says whether alignment specifiers are OK (only in cases that might
5139 be the type name of a compound literal).
27bf414c
JM
5140
5141 type-name:
5142 specifier-qualifier-list abstract-declarator[opt]
5143*/
5144
1ee62b92 5145struct c_type_name *
4b2b493f 5146c_parser_type_name (c_parser *parser, bool alignas_ok)
27bf414c
JM
5147{
5148 struct c_declspecs *specs = build_null_declspecs ();
5149 struct c_declarator *declarator;
5150 struct c_type_name *ret;
5151 bool dummy = false;
4b2b493f 5152 c_parser_declspecs (parser, specs, false, true, true, alignas_ok, false,
4e03c3a7 5153 false, true, cla_prefer_type);
27bf414c
JM
5154 if (!specs->declspecs_seen_p)
5155 {
5156 c_parser_error (parser, "expected specifier-qualifier-list");
5157 return NULL;
5158 }
29ce73cb
PB
5159 if (specs->type != error_mark_node)
5160 {
5161 pending_xref_error ();
5162 finish_declspecs (specs);
5163 }
9e5b2115
PB
5164 declarator = c_parser_declarator (parser,
5165 specs->typespec_kind != ctsk_none,
27bf414c
JM
5166 C_DTR_ABSTRACT, &dummy);
5167 if (declarator == NULL)
5168 return NULL;
5169 ret = XOBNEW (&parser_obstack, struct c_type_name);
5170 ret->specs = specs;
5171 ret->declarator = declarator;
5172 return ret;
5173}
5174
31dc71a8 5175/* Parse an initializer (C90 6.5.7, C99 6.7.8, C11 6.7.9).
27bf414c
JM
5176
5177 initializer:
5178 assignment-expression
5179 { initializer-list }
5180 { initializer-list , }
5181
5182 initializer-list:
5183 designation[opt] initializer
5184 initializer-list , designation[opt] initializer
5185
5186 designation:
5187 designator-list =
5188
5189 designator-list:
5190 designator
5191 designator-list designator
5192
5193 designator:
5194 array-designator
5195 . identifier
5196
5197 array-designator:
5198 [ constant-expression ]
5199
5200 GNU extensions:
5201
5202 initializer:
5203 { }
5204
5205 designation:
5206 array-designator
5207 identifier :
5208
5209 array-designator:
5210 [ constant-expression ... constant-expression ]
5211
5212 Any expression without commas is accepted in the syntax for the
5213 constant-expressions, with non-constant expressions rejected later.
5214
5215 This function is only used for top-level initializers; for nested
5216 ones, see c_parser_initval. */
5217
5218static struct c_expr
5219c_parser_initializer (c_parser *parser)
5220{
5221 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
16595a1f 5222 return c_parser_braced_init (parser, NULL_TREE, false, NULL);
27bf414c 5223 else
46bdb9cf
JM
5224 {
5225 struct c_expr ret;
c2255bc4 5226 location_t loc = c_parser_peek_token (parser)->location;
46bdb9cf
JM
5227 ret = c_parser_expr_no_commas (parser, NULL);
5228 if (TREE_CODE (ret.value) != STRING_CST
5229 && TREE_CODE (ret.value) != COMPOUND_LITERAL_EXPR)
267bac10 5230 ret = convert_lvalue_to_rvalue (loc, ret, true, true);
46bdb9cf
JM
5231 return ret;
5232 }
27bf414c
JM
5233}
5234
5dd9a9d0
DM
5235/* The location of the last comma within the current initializer list,
5236 or UNKNOWN_LOCATION if not within one. */
5237
5238location_t last_init_list_comma;
5239
27bf414c
JM
5240/* Parse a braced initializer list. TYPE is the type specified for a
5241 compound literal, and NULL_TREE for other initializers and for
5242 nested braced lists. NESTED_P is true for nested braced lists,
5243 false for the list of a compound literal or the list that is the
5244 top-level initializer in a declaration. */
5245
5246static struct c_expr
16595a1f
BS
5247c_parser_braced_init (c_parser *parser, tree type, bool nested_p,
5248 struct obstack *outer_obstack)
27bf414c 5249{
a1e3b3d9
LB
5250 struct c_expr ret;
5251 struct obstack braced_init_obstack;
c7412148 5252 location_t brace_loc = c_parser_peek_token (parser)->location;
a1e3b3d9 5253 gcc_obstack_init (&braced_init_obstack);
27bf414c 5254 gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE));
32129a17
DM
5255 matching_braces braces;
5256 braces.consume_open (parser);
27bf414c 5257 if (nested_p)
16595a1f
BS
5258 {
5259 finish_implicit_inits (brace_loc, outer_obstack);
5260 push_init_level (brace_loc, 0, &braced_init_obstack);
5261 }
27bf414c
JM
5262 else
5263 really_start_incremental_init (type);
5264 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5265 {
c1771a20 5266 pedwarn (brace_loc, OPT_Wpedantic, "ISO C forbids empty initializer braces");
27bf414c
JM
5267 }
5268 else
5269 {
5270 /* Parse a non-empty initializer list, possibly with a trailing
5271 comma. */
5272 while (true)
5273 {
a1e3b3d9 5274 c_parser_initelt (parser, &braced_init_obstack);
27bf414c
JM
5275 if (parser->error)
5276 break;
5277 if (c_parser_next_token_is (parser, CPP_COMMA))
5dd9a9d0
DM
5278 {
5279 last_init_list_comma = c_parser_peek_token (parser)->location;
5280 c_parser_consume_token (parser);
5281 }
27bf414c
JM
5282 else
5283 break;
5284 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5285 break;
5286 }
5287 }
bef08b71
DM
5288 c_token *next_tok = c_parser_peek_token (parser);
5289 if (next_tok->type != CPP_CLOSE_BRACE)
27bf414c 5290 {
913884f7 5291 ret.set_error ();
27bf414c 5292 ret.original_code = ERROR_MARK;
6866c6e8 5293 ret.original_type = NULL;
32129a17 5294 braces.skip_until_found_close (parser);
5dd9a9d0 5295 pop_init_level (brace_loc, 0, &braced_init_obstack, last_init_list_comma);
a1e3b3d9 5296 obstack_free (&braced_init_obstack, NULL);
27bf414c
JM
5297 return ret;
5298 }
bef08b71 5299 location_t close_loc = next_tok->location;
27bf414c 5300 c_parser_consume_token (parser);
5dd9a9d0 5301 ret = pop_init_level (brace_loc, 0, &braced_init_obstack, close_loc);
a1e3b3d9 5302 obstack_free (&braced_init_obstack, NULL);
bef08b71 5303 set_c_expr_source_range (&ret, brace_loc, close_loc);
a1e3b3d9 5304 return ret;
27bf414c
JM
5305}
5306
5307/* Parse a nested initializer, including designators. */
5308
5309static void
a1e3b3d9 5310c_parser_initelt (c_parser *parser, struct obstack * braced_init_obstack)
27bf414c
JM
5311{
5312 /* Parse any designator or designator list. A single array
5313 designator may have the subsequent "=" omitted in GNU C, but a
5314 longer list or a structure member designator may not. */
5315 if (c_parser_next_token_is (parser, CPP_NAME)
5316 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
5317 {
5318 /* Old-style structure member designator. */
ea58ef42
MP
5319 set_init_label (c_parser_peek_token (parser)->location,
5320 c_parser_peek_token (parser)->value,
f7e4f2e3 5321 c_parser_peek_token (parser)->location,
a1e3b3d9 5322 braced_init_obstack);
fcf73884 5323 /* Use the colon as the error location. */
c1771a20 5324 pedwarn (c_parser_peek_2nd_token (parser)->location, OPT_Wpedantic,
509c9d60 5325 "obsolete use of designated initializer with %<:%>");
27bf414c
JM
5326 c_parser_consume_token (parser);
5327 c_parser_consume_token (parser);
5328 }
5329 else
5330 {
5331 /* des_seen is 0 if there have been no designators, 1 if there
5332 has been a single array designator and 2 otherwise. */
5333 int des_seen = 0;
c7412148 5334 /* Location of a designator. */
922f2908 5335 location_t des_loc = UNKNOWN_LOCATION; /* Quiet warning. */
27bf414c
JM
5336 while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
5337 || c_parser_next_token_is (parser, CPP_DOT))
5338 {
5339 int des_prev = des_seen;
c7412148
TT
5340 if (!des_seen)
5341 des_loc = c_parser_peek_token (parser)->location;
27bf414c
JM
5342 if (des_seen < 2)
5343 des_seen++;
5344 if (c_parser_next_token_is (parser, CPP_DOT))
5345 {
5346 des_seen = 2;
5347 c_parser_consume_token (parser);
5348 if (c_parser_next_token_is (parser, CPP_NAME))
5349 {
ea58ef42 5350 set_init_label (des_loc, c_parser_peek_token (parser)->value,
f7e4f2e3 5351 c_parser_peek_token (parser)->location,
a1e3b3d9 5352 braced_init_obstack);
27bf414c
JM
5353 c_parser_consume_token (parser);
5354 }
5355 else
5356 {
5357 struct c_expr init;
913884f7 5358 init.set_error ();
27bf414c 5359 init.original_code = ERROR_MARK;
6866c6e8 5360 init.original_type = NULL;
27bf414c
JM
5361 c_parser_error (parser, "expected identifier");
5362 c_parser_skip_until_found (parser, CPP_COMMA, NULL);
34cf811f
MP
5363 process_init_element (input_location, init, false,
5364 braced_init_obstack);
27bf414c
JM
5365 return;
5366 }
5367 }
5368 else
5369 {
5370 tree first, second;
922f2908 5371 location_t ellipsis_loc = UNKNOWN_LOCATION; /* Quiet warning. */
ea58ef42 5372 location_t array_index_loc = UNKNOWN_LOCATION;
27bf414c
JM
5373 /* ??? Following the old parser, [ objc-receiver
5374 objc-message-args ] is accepted as an initializer,
5375 being distinguished from a designator by what follows
5376 the first assignment expression inside the square
5377 brackets, but after a first array designator a
5378 subsequent square bracket is for Objective-C taken to
5379 start an expression, using the obsolete form of
5380 designated initializer without '=', rather than
5381 possibly being a second level of designation: in LALR
5382 terms, the '[' is shifted rather than reducing
5383 designator to designator-list. */
5384 if (des_prev == 1 && c_dialect_objc ())
5385 {
5386 des_seen = des_prev;
5387 break;
5388 }
5389 if (des_prev == 0 && c_dialect_objc ())
5390 {
5391 /* This might be an array designator or an
5392 Objective-C message expression. If the former,
5393 continue parsing here; if the latter, parse the
5394 remainder of the initializer given the starting
5395 primary-expression. ??? It might make sense to
5396 distinguish when des_prev == 1 as well; see
5397 previous comment. */
5398 tree rec, args;
5399 struct c_expr mexpr;
5400 c_parser_consume_token (parser);
5401 if (c_parser_peek_token (parser)->type == CPP_NAME
5402 && ((c_parser_peek_token (parser)->id_kind
5403 == C_ID_TYPENAME)
5404 || (c_parser_peek_token (parser)->id_kind
5405 == C_ID_CLASSNAME)))
5406 {
5407 /* Type name receiver. */
5408 tree id = c_parser_peek_token (parser)->value;
5409 c_parser_consume_token (parser);
5410 rec = objc_get_class_reference (id);
5411 goto parse_message_args;
5412 }
5413 first = c_parser_expr_no_commas (parser, NULL).value;
ebfbbdc5 5414 mark_exp_read (first);
27bf414c
JM
5415 if (c_parser_next_token_is (parser, CPP_ELLIPSIS)
5416 || c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
5417 goto array_desig_after_first;
5418 /* Expression receiver. So far only one part
5419 without commas has been parsed; there might be
5420 more of the expression. */
5421 rec = first;
5422 while (c_parser_next_token_is (parser, CPP_COMMA))
5423 {
f2a71bbc 5424 struct c_expr next;
c2255bc4
AH
5425 location_t comma_loc, exp_loc;
5426 comma_loc = c_parser_peek_token (parser)->location;
27bf414c 5427 c_parser_consume_token (parser);
c2255bc4 5428 exp_loc = c_parser_peek_token (parser)->location;
f2a71bbc 5429 next = c_parser_expr_no_commas (parser, NULL);
267bac10
JM
5430 next = convert_lvalue_to_rvalue (exp_loc, next,
5431 true, true);
c2255bc4 5432 rec = build_compound_expr (comma_loc, rec, next.value);
27bf414c
JM
5433 }
5434 parse_message_args:
5435 /* Now parse the objc-message-args. */
5436 args = c_parser_objc_message_args (parser);
5437 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
5438 "expected %<]%>");
5439 mexpr.value
eb345401 5440 = objc_build_message_expr (rec, args);
27bf414c 5441 mexpr.original_code = ERROR_MARK;
6866c6e8 5442 mexpr.original_type = NULL;
27bf414c
JM
5443 /* Now parse and process the remainder of the
5444 initializer, starting with this message
5445 expression as a primary-expression. */
a1e3b3d9 5446 c_parser_initval (parser, &mexpr, braced_init_obstack);
27bf414c
JM
5447 return;
5448 }
5449 c_parser_consume_token (parser);
ea58ef42 5450 array_index_loc = c_parser_peek_token (parser)->location;
27bf414c 5451 first = c_parser_expr_no_commas (parser, NULL).value;
ebfbbdc5 5452 mark_exp_read (first);
27bf414c
JM
5453 array_desig_after_first:
5454 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
5455 {
c7412148 5456 ellipsis_loc = c_parser_peek_token (parser)->location;
27bf414c
JM
5457 c_parser_consume_token (parser);
5458 second = c_parser_expr_no_commas (parser, NULL).value;
ebfbbdc5 5459 mark_exp_read (second);
27bf414c
JM
5460 }
5461 else
5462 second = NULL_TREE;
5463 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
5464 {
5465 c_parser_consume_token (parser);
ea58ef42
MP
5466 set_init_index (array_index_loc, first, second,
5467 braced_init_obstack);
fcf73884 5468 if (second)
c1771a20 5469 pedwarn (ellipsis_loc, OPT_Wpedantic,
509c9d60 5470 "ISO C forbids specifying range of elements to initialize");
27bf414c
JM
5471 }
5472 else
5473 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
5474 "expected %<]%>");
5475 }
5476 }
5477 if (des_seen >= 1)
5478 {
5479 if (c_parser_next_token_is (parser, CPP_EQ))
5480 {
f3bede71
MP
5481 pedwarn_c90 (des_loc, OPT_Wpedantic,
5482 "ISO C90 forbids specifying subobject "
5483 "to initialize");
27bf414c
JM
5484 c_parser_consume_token (parser);
5485 }
5486 else
5487 {
5488 if (des_seen == 1)
c1771a20 5489 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
509c9d60 5490 "obsolete use of designated initializer without %<=%>");
27bf414c
JM
5491 else
5492 {
5493 struct c_expr init;
913884f7 5494 init.set_error ();
27bf414c 5495 init.original_code = ERROR_MARK;
6866c6e8 5496 init.original_type = NULL;
27bf414c
JM
5497 c_parser_error (parser, "expected %<=%>");
5498 c_parser_skip_until_found (parser, CPP_COMMA, NULL);
34cf811f
MP
5499 process_init_element (input_location, init, false,
5500 braced_init_obstack);
27bf414c
JM
5501 return;
5502 }
5503 }
5504 }
5505 }
a1e3b3d9 5506 c_parser_initval (parser, NULL, braced_init_obstack);
27bf414c
JM
5507}
5508
5509/* Parse a nested initializer; as c_parser_initializer but parses
5510 initializers within braced lists, after any designators have been
5511 applied. If AFTER is not NULL then it is an Objective-C message
5512 expression which is the primary-expression starting the
5513 initializer. */
5514
5515static void
a1e3b3d9
LB
5516c_parser_initval (c_parser *parser, struct c_expr *after,
5517 struct obstack * braced_init_obstack)
27bf414c
JM
5518{
5519 struct c_expr init;
5520 gcc_assert (!after || c_dialect_objc ());
34cf811f
MP
5521 location_t loc = c_parser_peek_token (parser)->location;
5522
27bf414c 5523 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE) && !after)
16595a1f
BS
5524 init = c_parser_braced_init (parser, NULL_TREE, true,
5525 braced_init_obstack);
27bf414c 5526 else
46bdb9cf
JM
5527 {
5528 init = c_parser_expr_no_commas (parser, after);
5529 if (init.value != NULL_TREE
5530 && TREE_CODE (init.value) != STRING_CST
5531 && TREE_CODE (init.value) != COMPOUND_LITERAL_EXPR)
267bac10 5532 init = convert_lvalue_to_rvalue (loc, init, true, true);
46bdb9cf 5533 }
34cf811f 5534 process_init_element (loc, init, false, braced_init_obstack);
27bf414c
JM
5535}
5536
5537/* Parse a compound statement (possibly a function body) (C90 6.6.2,
31dc71a8 5538 C99 6.8.2, C11 6.8.2).
27bf414c
JM
5539
5540 compound-statement:
5541 { block-item-list[opt] }
5542 { label-declarations block-item-list }
5543
5544 block-item-list:
5545 block-item
5546 block-item-list block-item
5547
5548 block-item:
5549 nested-declaration
5550 statement
5551
5552 nested-declaration:
5553 declaration
5554
5555 GNU extensions:
5556
5557 compound-statement:
5558 { label-declarations block-item-list }
5559
5560 nested-declaration:
5561 __extension__ nested-declaration
5562 nested-function-definition
5563
5564 label-declarations:
5565 label-declaration
5566 label-declarations label-declaration
5567
5568 label-declaration:
5569 __label__ identifier-list ;
5570
5571 Allowing the mixing of declarations and code is new in C99. The
5572 GNU syntax also permits (not shown above) labels at the end of
5573 compound statements, which yield an error. We don't allow labels
5574 on declarations; this might seem like a natural extension, but
783bfe5e
JM
5575 there would be a conflict between gnu-attributes on the label and
5576 prefix gnu-attributes on the declaration. ??? The syntax follows the
27bf414c
JM
5577 old parser in requiring something after label declarations.
5578 Although they are erroneous if the labels declared aren't defined,
953ff289 5579 is it useful for the syntax to be this way?
b8698a0f 5580
41dbbb37
TS
5581 OpenACC:
5582
5583 block-item:
5584 openacc-directive
5585
5586 openacc-directive:
5587 update-directive
5588
953ff289 5589 OpenMP:
b8698a0f 5590
953ff289
DN
5591 block-item:
5592 openmp-directive
5593
5594 openmp-directive:
5595 barrier-directive
acf0174b
JJ
5596 flush-directive
5597 taskwait-directive
5598 taskyield-directive
5599 cancel-directive
5600 cancellation-point-directive */
27bf414c
JM
5601
5602static tree
9def91e9 5603c_parser_compound_statement (c_parser *parser, location_t *endlocp)
27bf414c
JM
5604{
5605 tree stmt;
c2255bc4
AH
5606 location_t brace_loc;
5607 brace_loc = c_parser_peek_token (parser)->location;
27bf414c 5608 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
5600f233
JM
5609 {
5610 /* Ensure a scope is entered and left anyway to avoid confusion
5611 if we have just prepared to enter a function body. */
5612 stmt = c_begin_compound_stmt (true);
c2255bc4 5613 c_end_compound_stmt (brace_loc, stmt, true);
5600f233
JM
5614 return error_mark_node;
5615 }
27bf414c 5616 stmt = c_begin_compound_stmt (true);
9def91e9
JJ
5617 location_t end_loc = c_parser_compound_statement_nostart (parser);
5618 if (endlocp)
5619 *endlocp = end_loc;
36536d79 5620
c2255bc4 5621 return c_end_compound_stmt (brace_loc, stmt, true);
27bf414c
JM
5622}
5623
5624/* Parse a compound statement except for the opening brace. This is
5625 used for parsing both compound statements and statement expressions
5626 (which follow different paths to handling the opening). */
5627
9def91e9 5628static location_t
27bf414c
JM
5629c_parser_compound_statement_nostart (c_parser *parser)
5630{
5631 bool last_stmt = false;
5632 bool last_label = false;
6ec637a4 5633 bool save_valid_for_pragma = valid_location_for_stdc_pragma_p ();
3ba09659 5634 location_t label_loc = UNKNOWN_LOCATION; /* Quiet warning. */
27bf414c
JM
5635 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5636 {
9def91e9
JJ
5637 location_t endloc = c_parser_peek_token (parser)->location;
5638 add_debug_begin_stmt (endloc);
27bf414c 5639 c_parser_consume_token (parser);
9def91e9 5640 return endloc;
27bf414c 5641 }
6ec637a4 5642 mark_valid_location_for_stdc_pragma (true);
27bf414c
JM
5643 if (c_parser_next_token_is_keyword (parser, RID_LABEL))
5644 {
5645 /* Read zero or more forward-declarations for labels that nested
5646 functions can jump to. */
6ec637a4 5647 mark_valid_location_for_stdc_pragma (false);
27bf414c
JM
5648 while (c_parser_next_token_is_keyword (parser, RID_LABEL))
5649 {
c2255bc4 5650 label_loc = c_parser_peek_token (parser)->location;
27bf414c
JM
5651 c_parser_consume_token (parser);
5652 /* Any identifiers, including those declared as type names,
5653 are OK here. */
5654 while (true)
5655 {
5656 tree label;
5657 if (c_parser_next_token_is_not (parser, CPP_NAME))
5658 {
5659 c_parser_error (parser, "expected identifier");
5660 break;
5661 }
5662 label
5663 = declare_label (c_parser_peek_token (parser)->value);
5664 C_DECLARED_LABEL_FLAG (label) = 1;
c2255bc4 5665 add_stmt (build_stmt (label_loc, DECL_EXPR, label));
27bf414c
JM
5666 c_parser_consume_token (parser);
5667 if (c_parser_next_token_is (parser, CPP_COMMA))
5668 c_parser_consume_token (parser);
5669 else
5670 break;
5671 }
5672 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
5673 }
c1771a20 5674 pedwarn (label_loc, OPT_Wpedantic, "ISO C forbids label declarations");
27bf414c
JM
5675 }
5676 /* We must now have at least one statement, label or declaration. */
5677 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5678 {
6ec637a4 5679 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
27bf414c 5680 c_parser_error (parser, "expected declaration or statement");
9def91e9 5681 location_t endloc = c_parser_peek_token (parser)->location;
27bf414c 5682 c_parser_consume_token (parser);
9def91e9 5683 return endloc;
27bf414c
JM
5684 }
5685 while (c_parser_next_token_is_not (parser, CPP_CLOSE_BRACE))
5686 {
5687 location_t loc = c_parser_peek_token (parser)->location;
2be4dfcb 5688 loc = expansion_point_location_if_in_system_header (loc);
4e03c3a7
JM
5689 /* Standard attributes may start a statement or a declaration. */
5690 bool have_std_attrs
5691 = c_parser_nth_token_starts_std_attributes (parser, 1);
5692 tree std_attrs = NULL_TREE;
5693 if (have_std_attrs)
5694 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
27bf414c
JM
5695 if (c_parser_next_token_is_keyword (parser, RID_CASE)
5696 || c_parser_next_token_is_keyword (parser, RID_DEFAULT)
5697 || (c_parser_next_token_is (parser, CPP_NAME)
5698 && c_parser_peek_2nd_token (parser)->type == CPP_COLON))
5699 {
4e03c3a7 5700 c_warn_unused_attributes (std_attrs);
c7412148
TT
5701 if (c_parser_next_token_is_keyword (parser, RID_CASE))
5702 label_loc = c_parser_peek_2nd_token (parser)->location;
5703 else
5704 label_loc = c_parser_peek_token (parser)->location;
27bf414c
JM
5705 last_label = true;
5706 last_stmt = false;
6ec637a4 5707 mark_valid_location_for_stdc_pragma (false);
27bf414c
JM
5708 c_parser_label (parser);
5709 }
5710 else if (!last_label
4e03c3a7
JM
5711 && (c_parser_next_tokens_start_declaration (parser)
5712 || (have_std_attrs
5713 && c_parser_next_token_is (parser, CPP_SEMICOLON))))
27bf414c
JM
5714 {
5715 last_label = false;
6ec637a4 5716 mark_valid_location_for_stdc_pragma (false);
81fea426 5717 bool fallthru_attr_p = false;
4e03c3a7
JM
5718 c_parser_declaration_or_fndef (parser, true, !have_std_attrs,
5719 true, true, true, NULL,
5720 vNULL, have_std_attrs, std_attrs,
5721 NULL, &fallthru_attr_p);
81fea426 5722 if (last_stmt && !fallthru_attr_p)
177cce46 5723 pedwarn_c90 (loc, OPT_Wdeclaration_after_statement,
509c9d60 5724 "ISO C90 forbids mixed declarations and code");
81fea426 5725 last_stmt = fallthru_attr_p;
27bf414c
JM
5726 }
5727 else if (!last_label
5728 && c_parser_next_token_is_keyword (parser, RID_EXTENSION))
5729 {
5730 /* __extension__ can start a declaration, but is also an
5731 unary operator that can start an expression. Consume all
5732 but the last of a possible series of __extension__ to
4e03c3a7
JM
5733 determine which. If standard attributes have already
5734 been seen, it must start a statement, not a declaration,
5735 but standard attributes starting a declaration may appear
5736 after __extension__. */
27bf414c
JM
5737 while (c_parser_peek_2nd_token (parser)->type == CPP_KEYWORD
5738 && (c_parser_peek_2nd_token (parser)->keyword
5739 == RID_EXTENSION))
5740 c_parser_consume_token (parser);
4e03c3a7
JM
5741 if (!have_std_attrs
5742 && (c_token_starts_declaration (c_parser_peek_2nd_token (parser))
5743 || c_parser_nth_token_starts_std_attributes (parser, 2)))
27bf414c
JM
5744 {
5745 int ext;
5746 ext = disable_extension_diagnostics ();
5747 c_parser_consume_token (parser);
5748 last_label = false;
6ec637a4 5749 mark_valid_location_for_stdc_pragma (false);
32912286 5750 c_parser_declaration_or_fndef (parser, true, true, true, true,
acf0174b 5751 true, NULL, vNULL);
27bf414c
JM
5752 /* Following the old parser, __extension__ does not
5753 disable this diagnostic. */
5754 restore_extension_diagnostics (ext);
fcf73884 5755 if (last_stmt)
177cce46 5756 pedwarn_c90 (loc, OPT_Wdeclaration_after_statement,
509c9d60 5757 "ISO C90 forbids mixed declarations and code");
27bf414c
JM
5758 last_stmt = false;
5759 }
5760 else
5761 goto statement;
5762 }
bc4071dd
RH
5763 else if (c_parser_next_token_is (parser, CPP_PRAGMA))
5764 {
4e03c3a7
JM
5765 if (have_std_attrs)
5766 c_parser_error (parser, "expected declaration or statement");
bc4071dd
RH
5767 /* External pragmas, and some omp pragmas, are not associated
5768 with regular c code, and so are not to be considered statements
5769 syntactically. This ensures that the user doesn't put them
5770 places that would turn into syntax errors if the directive
5771 were ignored. */
aec17bfe 5772 if (c_parser_pragma (parser,
dda1bf61
JJ
5773 last_label ? pragma_stmt : pragma_compound,
5774 NULL))
bc4071dd
RH
5775 last_label = false, last_stmt = true;
5776 }
5777 else if (c_parser_next_token_is (parser, CPP_EOF))
5778 {
6ec637a4 5779 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
bc4071dd 5780 c_parser_error (parser, "expected declaration or statement");
9def91e9 5781 return c_parser_peek_token (parser)->location;
bc4071dd 5782 }
b4b56033
MLI
5783 else if (c_parser_next_token_is_keyword (parser, RID_ELSE))
5784 {
b8698a0f 5785 if (parser->in_if_block)
b4b56033 5786 {
6ec637a4 5787 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
92fa0f9e 5788 error_at (loc, "expected %<}%> before %<else%>");
9def91e9 5789 return c_parser_peek_token (parser)->location;
b4b56033 5790 }
b8698a0f 5791 else
b4b56033 5792 {
3ba09659 5793 error_at (loc, "%<else%> without a previous %<if%>");
b4b56033
MLI
5794 c_parser_consume_token (parser);
5795 continue;
5796 }
5797 }
27bf414c
JM
5798 else
5799 {
5800 statement:
4e03c3a7 5801 c_warn_unused_attributes (std_attrs);
27bf414c
JM
5802 last_label = false;
5803 last_stmt = true;
6ec637a4 5804 mark_valid_location_for_stdc_pragma (false);
99cd9857 5805 c_parser_statement_after_labels (parser, NULL);
27bf414c 5806 }
2c14ae9a
VR
5807
5808 parser->error = false;
27bf414c
JM
5809 }
5810 if (last_label)
3ba09659 5811 error_at (label_loc, "label at end of compound statement");
9def91e9 5812 location_t endloc = c_parser_peek_token (parser)->location;
27bf414c 5813 c_parser_consume_token (parser);
6ec637a4
JJ
5814 /* Restore the value we started with. */
5815 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
9def91e9 5816 return endloc;
27bf414c
JM
5817}
5818
4e03c3a7
JM
5819/* Parse all consecutive labels, possibly preceded by standard
5820 attributes. In this context, a statement is required, not a
5821 declaration, so attributes must be followed by a statement that is
5822 not just a semicolon. */
74d98c1e
AB
5823
5824static void
5825c_parser_all_labels (c_parser *parser)
5826{
4e03c3a7
JM
5827 if (c_parser_nth_token_starts_std_attributes (parser, 1))
5828 {
5829 tree std_attrs = c_parser_std_attribute_specifier_sequence (parser);
5830 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
5831 c_parser_error (parser, "expected statement");
5832 else
5833 c_warn_unused_attributes (std_attrs);
5834 }
74d98c1e
AB
5835 while (c_parser_next_token_is_keyword (parser, RID_CASE)
5836 || c_parser_next_token_is_keyword (parser, RID_DEFAULT)
5837 || (c_parser_next_token_is (parser, CPP_NAME)
5838 && c_parser_peek_2nd_token (parser)->type == CPP_COLON))
5839 c_parser_label (parser);
5840}
5841
31dc71a8 5842/* Parse a label (C90 6.6.1, C99 6.8.1, C11 6.8.1).
27bf414c
JM
5843
5844 label:
783bfe5e 5845 identifier : gnu-attributes[opt]
27bf414c
JM
5846 case constant-expression :
5847 default :
5848
5849 GNU extensions:
5850
5851 label:
5852 case constant-expression ... constant-expression :
5853
783bfe5e 5854 The use of gnu-attributes on labels is a GNU extension. The syntax in
27bf414c 5855 GNU C accepts any expressions without commas, non-constant
4e03c3a7
JM
5856 expressions being rejected later. Any standard
5857 attribute-specifier-sequence before the first label has been parsed
5858 in the caller, to distinguish statements from declarations. Any
5859 attribute-specifier-sequence after the label is parsed in this
5860 function. */
27bf414c
JM
5861
5862static void
5863c_parser_label (c_parser *parser)
5864{
5865 location_t loc1 = c_parser_peek_token (parser)->location;
5866 tree label = NULL_TREE;
81fea426
MP
5867
5868 /* Remember whether this case or a user-defined label is allowed to fall
5869 through to. */
5870 bool fallthrough_p = c_parser_peek_token (parser)->flags & PREV_FALLTHROUGH;
5871
27bf414c
JM
5872 if (c_parser_next_token_is_keyword (parser, RID_CASE))
5873 {
5874 tree exp1, exp2;
5875 c_parser_consume_token (parser);
5876 exp1 = c_parser_expr_no_commas (parser, NULL).value;
5877 if (c_parser_next_token_is (parser, CPP_COLON))
5878 {
5879 c_parser_consume_token (parser);
c2255bc4 5880 label = do_case (loc1, exp1, NULL_TREE);
27bf414c
JM
5881 }
5882 else if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
5883 {
5884 c_parser_consume_token (parser);
5885 exp2 = c_parser_expr_no_commas (parser, NULL).value;
5886 if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
c2255bc4 5887 label = do_case (loc1, exp1, exp2);
27bf414c
JM
5888 }
5889 else
5890 c_parser_error (parser, "expected %<:%> or %<...%>");
5891 }
5892 else if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
5893 {
5894 c_parser_consume_token (parser);
5895 if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
c2255bc4 5896 label = do_case (loc1, NULL_TREE, NULL_TREE);
27bf414c
JM
5897 }
5898 else
5899 {
5900 tree name = c_parser_peek_token (parser)->value;
5901 tree tlab;
27bf414c 5902 tree attrs;
c7412148 5903 location_t loc2 = c_parser_peek_token (parser)->location;
27bf414c
JM
5904 gcc_assert (c_parser_next_token_is (parser, CPP_NAME));
5905 c_parser_consume_token (parser);
5906 gcc_assert (c_parser_next_token_is (parser, CPP_COLON));
27bf414c 5907 c_parser_consume_token (parser);
783bfe5e 5908 attrs = c_parser_gnu_attributes (parser);
27bf414c
JM
5909 tlab = define_label (loc2, name);
5910 if (tlab)
5911 {
5912 decl_attributes (&tlab, attrs, 0);
c2255bc4 5913 label = add_stmt (build_stmt (loc1, LABEL_EXPR, tlab));
27bf414c
JM
5914 }
5915 }
5916 if (label)
3d57f0f0 5917 {
81fea426
MP
5918 if (TREE_CODE (label) == LABEL_EXPR)
5919 FALLTHROUGH_LABEL_P (LABEL_EXPR_LABEL (label)) = fallthrough_p;
5920 else
5921 FALLTHROUGH_LABEL_P (CASE_LABEL (label)) = fallthrough_p;
5922
4e03c3a7
JM
5923 /* Standard attributes are only allowed here if they start a
5924 statement, not a declaration (including the case of an
5925 attribute-declaration with only attributes). */
5926 bool have_std_attrs
5927 = c_parser_nth_token_starts_std_attributes (parser, 1);
5928 tree std_attrs = NULL_TREE;
5929 if (have_std_attrs)
5930 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
5931
81fea426 5932 /* Allow '__attribute__((fallthrough));'. */
4e03c3a7
JM
5933 if (!have_std_attrs
5934 && c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
81fea426
MP
5935 {
5936 location_t loc = c_parser_peek_token (parser)->location;
783bfe5e 5937 tree attrs = c_parser_gnu_attributes (parser);
81fea426
MP
5938 if (attribute_fallthrough_p (attrs))
5939 {
5940 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
5941 {
5942 tree fn = build_call_expr_internal_loc (loc,
5943 IFN_FALLTHROUGH,
5944 void_type_node, 0);
5945 add_stmt (fn);
5946 }
5947 else
5948 warning_at (loc, OPT_Wattributes, "%<fallthrough%> attribute "
5949 "not followed by %<;%>");
5950 }
5951 else if (attrs != NULL_TREE)
5952 warning_at (loc, OPT_Wattributes, "only attribute %<fallthrough%>"
5953 " can be applied to a null statement");
5954 }
4e03c3a7
JM
5955 if (c_parser_next_tokens_start_declaration (parser)
5956 || (have_std_attrs
5957 && c_parser_next_token_is (parser, CPP_SEMICOLON)))
3d57f0f0 5958 {
3ba09659
AH
5959 error_at (c_parser_peek_token (parser)->location,
5960 "a label can only be part of a statement and "
5961 "a declaration is not a statement");
b8698a0f 5962 c_parser_declaration_or_fndef (parser, /*fndef_ok*/ false,
32912286 5963 /*static_assert_ok*/ true,
6265d07c 5964 /*empty_ok*/ true, /*nested*/ true,
acf0174b 5965 /*start_attr_ok*/ true, NULL,
4e03c3a7 5966 vNULL, have_std_attrs, std_attrs);
3d57f0f0 5967 }
4e03c3a7
JM
5968 else if (std_attrs)
5969 /* Nonempty attributes on the following statement are ignored. */
5970 c_warn_unused_attributes (std_attrs);
3d57f0f0 5971 }
27bf414c
JM
5972}
5973
31dc71a8 5974/* Parse a statement (C90 6.6, C99 6.8, C11 6.8).
27bf414c
JM
5975
5976 statement:
5977 labeled-statement
4e03c3a7 5978 attribute-specifier-sequence[opt] compound-statement
27bf414c 5979 expression-statement
4e03c3a7
JM
5980 attribute-specifier-sequence[opt] selection-statement
5981 attribute-specifier-sequence[opt] iteration-statement
5982 attribute-specifier-sequence[opt] jump-statement
27bf414c
JM
5983
5984 labeled-statement:
4e03c3a7 5985 attribute-specifier-sequence[opt] label statement
27bf414c
JM
5986
5987 expression-statement:
5988 expression[opt] ;
4e03c3a7 5989 attribute-specifier-sequence expression ;
27bf414c
JM
5990
5991 selection-statement:
5992 if-statement
5993 switch-statement
5994
5995 iteration-statement:
5996 while-statement
5997 do-statement
5998 for-statement
5999
6000 jump-statement:
6001 goto identifier ;
6002 continue ;
6003 break ;
6004 return expression[opt] ;
6005
6006 GNU extensions:
6007
6008 statement:
4e03c3a7 6009 attribute-specifier-sequence[opt] asm-statement
27bf414c
JM
6010
6011 jump-statement:
6012 goto * expression ;
6013
81fea426 6014 expression-statement:
783bfe5e 6015 gnu-attributes ;
81fea426 6016
27bf414c
JM
6017 Objective-C:
6018
6019 statement:
4e03c3a7
JM
6020 attribute-specifier-sequence[opt] objc-throw-statement
6021 attribute-specifier-sequence[opt] objc-try-catch-statement
6022 attribute-specifier-sequence[opt] objc-synchronized-statement
27bf414c
JM
6023
6024 objc-throw-statement:
6025 @throw expression ;
6026 @throw ;
953ff289 6027
41dbbb37
TS
6028 OpenACC:
6029
6030 statement:
4e03c3a7 6031 attribute-specifier-sequence[opt] openacc-construct
41dbbb37
TS
6032
6033 openacc-construct:
6034 parallel-construct
6035 kernels-construct
6036 data-construct
6037 loop-construct
6038
6039 parallel-construct:
6040 parallel-directive structured-block
6041
6042 kernels-construct:
6043 kernels-directive structured-block
6044
6045 data-construct:
6046 data-directive structured-block
6047
6048 loop-construct:
6049 loop-directive structured-block
6050
953ff289
DN
6051 OpenMP:
6052
6053 statement:
4e03c3a7 6054 attribute-specifier-sequence[opt] openmp-construct
953ff289
DN
6055
6056 openmp-construct:
6057 parallel-construct
6058 for-construct
acf0174b
JJ
6059 simd-construct
6060 for-simd-construct
953ff289
DN
6061 sections-construct
6062 single-construct
6063 parallel-for-construct
acf0174b 6064 parallel-for-simd-construct
953ff289
DN
6065 parallel-sections-construct
6066 master-construct
6067 critical-construct
6068 atomic-construct
6069 ordered-construct
6070
6071 parallel-construct:
6072 parallel-directive structured-block
6073
6074 for-construct:
6075 for-directive iteration-statement
6076
acf0174b
JJ
6077 simd-construct:
6078 simd-directive iteration-statements
6079
6080 for-simd-construct:
6081 for-simd-directive iteration-statements
6082
953ff289
DN
6083 sections-construct:
6084 sections-directive section-scope
6085
6086 single-construct:
6087 single-directive structured-block
6088
6089 parallel-for-construct:
6090 parallel-for-directive iteration-statement
6091
acf0174b
JJ
6092 parallel-for-simd-construct:
6093 parallel-for-simd-directive iteration-statement
6094
953ff289
DN
6095 parallel-sections-construct:
6096 parallel-sections-directive section-scope
6097
6098 master-construct:
6099 master-directive structured-block
6100
6101 critical-construct:
6102 critical-directive structured-block
6103
6104 atomic-construct:
6105 atomic-directive expression-statement
6106
6107 ordered-construct:
0a35513e
AH
6108 ordered-directive structured-block
6109
6110 Transactional Memory:
6111
6112 statement:
4e03c3a7
JM
6113 attribute-specifier-sequence[opt] transaction-statement
6114 attribute-specifier-sequence[opt] transaction-cancel-statement
99cd9857
MP
6115
6116 IF_P is used to track whether there's a (possibly labeled) if statement
6117 which is not enclosed in braces and has an else clause. This is used to
6118 implement -Wparentheses. */
27bf414c
JM
6119
6120static void
3e2becc4 6121c_parser_statement (c_parser *parser, bool *if_p, location_t *loc_after_labels)
27bf414c 6122{
74d98c1e 6123 c_parser_all_labels (parser);
3e2becc4
MP
6124 if (loc_after_labels)
6125 *loc_after_labels = c_parser_peek_token (parser)->location;
99cd9857 6126 c_parser_statement_after_labels (parser, if_p, NULL);
27bf414c
JM
6127}
6128
3e3b8d63 6129/* Parse a statement, other than a labeled statement. CHAIN is a vector
4e03c3a7
JM
6130 of if-else-if conditions. All labels and standard attributes have
6131 been parsed in the caller.
99cd9857
MP
6132
6133 IF_P is used to track whether there's a (possibly labeled) if statement
6134 which is not enclosed in braces and has an else clause. This is used to
6135 implement -Wparentheses. */
27bf414c
JM
6136
6137static void
99cd9857
MP
6138c_parser_statement_after_labels (c_parser *parser, bool *if_p,
6139 vec<tree> *chain)
27bf414c
JM
6140{
6141 location_t loc = c_parser_peek_token (parser)->location;
6142 tree stmt = NULL_TREE;
b4b56033
MLI
6143 bool in_if_block = parser->in_if_block;
6144 parser->in_if_block = false;
99cd9857
MP
6145 if (if_p != NULL)
6146 *if_p = false;
96a95ac1
AO
6147
6148 if (c_parser_peek_token (parser)->type != CPP_OPEN_BRACE)
6149 add_debug_begin_stmt (loc);
6150
27bf414c
JM
6151 switch (c_parser_peek_token (parser)->type)
6152 {
6153 case CPP_OPEN_BRACE:
6154 add_stmt (c_parser_compound_statement (parser));
6155 break;
6156 case CPP_KEYWORD:
6157 switch (c_parser_peek_token (parser)->keyword)
6158 {
6159 case RID_IF:
99cd9857 6160 c_parser_if_statement (parser, if_p, chain);
27bf414c
JM
6161 break;
6162 case RID_SWITCH:
351f85c5 6163 c_parser_switch_statement (parser, if_p);
27bf414c
JM
6164 break;
6165 case RID_WHILE:
170a8bd6 6166 c_parser_while_statement (parser, false, 0, if_p);
27bf414c
JM
6167 break;
6168 case RID_DO:
170a8bd6 6169 c_parser_do_statement (parser, 0, false);
27bf414c
JM
6170 break;
6171 case RID_FOR:
170a8bd6 6172 c_parser_for_statement (parser, false, 0, if_p);
27bf414c
JM
6173 break;
6174 case RID_GOTO:
6175 c_parser_consume_token (parser);
6176 if (c_parser_next_token_is (parser, CPP_NAME))
6177 {
c2255bc4
AH
6178 stmt = c_finish_goto_label (loc,
6179 c_parser_peek_token (parser)->value);
27bf414c
JM
6180 c_parser_consume_token (parser);
6181 }
6182 else if (c_parser_next_token_is (parser, CPP_MULT))
6183 {
267bac10 6184 struct c_expr val;
84628aa8 6185
27bf414c 6186 c_parser_consume_token (parser);
267bac10
JM
6187 val = c_parser_expression (parser);
6188 val = convert_lvalue_to_rvalue (loc, val, false, true);
6189 stmt = c_finish_goto_ptr (loc, val.value);
27bf414c
JM
6190 }
6191 else
6192 c_parser_error (parser, "expected identifier or %<*%>");
6193 goto expect_semicolon;
6194 case RID_CONTINUE:
6195 c_parser_consume_token (parser);
c2255bc4 6196 stmt = c_finish_bc_stmt (loc, &c_cont_label, false);
27bf414c
JM
6197 goto expect_semicolon;
6198 case RID_BREAK:
6199 c_parser_consume_token (parser);
c2255bc4 6200 stmt = c_finish_bc_stmt (loc, &c_break_label, true);
27bf414c
JM
6201 goto expect_semicolon;
6202 case RID_RETURN:
6203 c_parser_consume_token (parser);
6204 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6205 {
c2255bc4 6206 stmt = c_finish_return (loc, NULL_TREE, NULL_TREE);
27bf414c
JM
6207 c_parser_consume_token (parser);
6208 }
6209 else
6210 {
6e07c515 6211 location_t xloc = c_parser_peek_token (parser)->location;
bbbbb16a 6212 struct c_expr expr = c_parser_expression_conv (parser);
ebfbbdc5 6213 mark_exp_read (expr.value);
94c40e19
DM
6214 stmt = c_finish_return (EXPR_LOC_OR_LOC (expr.value, xloc),
6215 expr.value, expr.original_type);
27bf414c
JM
6216 goto expect_semicolon;
6217 }
6218 break;
6219 case RID_ASM:
6220 stmt = c_parser_asm_statement (parser);
6221 break;
0a35513e
AH
6222 case RID_TRANSACTION_ATOMIC:
6223 case RID_TRANSACTION_RELAXED:
6224 stmt = c_parser_transaction (parser,
6225 c_parser_peek_token (parser)->keyword);
6226 break;
6227 case RID_TRANSACTION_CANCEL:
6228 stmt = c_parser_transaction_cancel (parser);
6229 goto expect_semicolon;
49b91f05 6230 case RID_AT_THROW:
27bf414c
JM
6231 gcc_assert (c_dialect_objc ());
6232 c_parser_consume_token (parser);
6233 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6234 {
c2255bc4 6235 stmt = objc_build_throw_stmt (loc, NULL_TREE);
27bf414c
JM
6236 c_parser_consume_token (parser);
6237 }
6238 else
6239 {
267bac10
JM
6240 struct c_expr expr = c_parser_expression (parser);
6241 expr = convert_lvalue_to_rvalue (loc, expr, false, false);
5e9d6aa4
JK
6242 expr.value = c_fully_fold (expr.value, false, NULL);
6243 stmt = objc_build_throw_stmt (loc, expr.value);
27bf414c
JM
6244 goto expect_semicolon;
6245 }
6246 break;
49b91f05 6247 case RID_AT_TRY:
27bf414c 6248 gcc_assert (c_dialect_objc ());
437c2322 6249 c_parser_objc_try_catch_finally_statement (parser);
27bf414c
JM
6250 break;
6251 case RID_AT_SYNCHRONIZED:
6252 gcc_assert (c_dialect_objc ());
6253 c_parser_objc_synchronized_statement (parser);
6254 break;
81fea426
MP
6255 case RID_ATTRIBUTE:
6256 {
6257 /* Allow '__attribute__((fallthrough));'. */
783bfe5e 6258 tree attrs = c_parser_gnu_attributes (parser);
81fea426
MP
6259 if (attribute_fallthrough_p (attrs))
6260 {
6261 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6262 {
6263 tree fn = build_call_expr_internal_loc (loc,
6264 IFN_FALLTHROUGH,
6265 void_type_node, 0);
6266 add_stmt (fn);
6267 /* Eat the ';'. */
6268 c_parser_consume_token (parser);
6269 }
6270 else
6271 warning_at (loc, OPT_Wattributes,
6272 "%<fallthrough%> attribute not followed "
6273 "by %<;%>");
6274 }
6275 else if (attrs != NULL_TREE)
6276 warning_at (loc, OPT_Wattributes, "only attribute %<fallthrough%>"
6277 " can be applied to a null statement");
6278 break;
6279 }
27bf414c
JM
6280 default:
6281 goto expr_stmt;
6282 }
6283 break;
6284 case CPP_SEMICOLON:
6285 c_parser_consume_token (parser);
6286 break;
6287 case CPP_CLOSE_PAREN:
6288 case CPP_CLOSE_SQUARE:
6289 /* Avoid infinite loop in error recovery:
6290 c_parser_skip_until_found stops at a closing nesting
6291 delimiter without consuming it, but here we need to consume
6292 it to proceed further. */
6293 c_parser_error (parser, "expected statement");
6294 c_parser_consume_token (parser);
6295 break;
bc4071dd 6296 case CPP_PRAGMA:
dda1bf61 6297 c_parser_pragma (parser, pragma_stmt, if_p);
bc4071dd 6298 break;
27bf414c
JM
6299 default:
6300 expr_stmt:
c2255bc4 6301 stmt = c_finish_expr_stmt (loc, c_parser_expression_conv (parser).value);
27bf414c
JM
6302 expect_semicolon:
6303 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
6304 break;
6305 }
6306 /* Two cases cannot and do not have line numbers associated: If stmt
6307 is degenerate, such as "2;", then stmt is an INTEGER_CST, which
6308 cannot hold line numbers. But that's OK because the statement
6309 will either be changed to a MODIFY_EXPR during gimplification of
6310 the statement expr, or discarded. If stmt was compound, but
6311 without new variables, we will have skipped the creation of a
6312 BIND and will have a bare STATEMENT_LIST. But that's OK because
6313 (recursively) all of the component statements should already have
6314 line numbers assigned. ??? Can we discard no-op statements
6315 earlier? */
21ba0cea
MP
6316 if (EXPR_LOCATION (stmt) == UNKNOWN_LOCATION)
6317 protected_set_expr_location (stmt, loc);
b4b56033
MLI
6318
6319 parser->in_if_block = in_if_block;
27bf414c
JM
6320}
6321
ca085fd7
MLI
6322/* Parse the condition from an if, do, while or for statements. */
6323
6324static tree
6325c_parser_condition (c_parser *parser)
6326{
c2255bc4 6327 location_t loc = c_parser_peek_token (parser)->location;
ca085fd7 6328 tree cond;
928c19bb
JM
6329 cond = c_parser_expression_conv (parser).value;
6330 cond = c_objc_common_truthvalue_conversion (loc, cond);
6331 cond = c_fully_fold (cond, false, NULL);
ca085fd7
MLI
6332 if (warn_sequence_point)
6333 verify_sequence_points (cond);
6334 return cond;
6335}
6336
27bf414c
JM
6337/* Parse a parenthesized condition from an if, do or while statement.
6338
6339 condition:
6340 ( expression )
6341*/
6342static tree
6343c_parser_paren_condition (c_parser *parser)
6344{
27bf414c 6345 tree cond;
32129a17
DM
6346 matching_parens parens;
6347 if (!parens.require_open (parser))
27bf414c 6348 return error_mark_node;
ca085fd7 6349 cond = c_parser_condition (parser);
32129a17 6350 parens.skip_until_found_close (parser);
27bf414c
JM
6351 return cond;
6352}
6353
99cd9857
MP
6354/* Parse a statement which is a block in C99.
6355
6356 IF_P is used to track whether there's a (possibly labeled) if statement
6357 which is not enclosed in braces and has an else clause. This is used to
6358 implement -Wparentheses. */
27bf414c
JM
6359
6360static tree
3e2becc4
MP
6361c_parser_c99_block_statement (c_parser *parser, bool *if_p,
6362 location_t *loc_after_labels)
27bf414c
JM
6363{
6364 tree block = c_begin_compound_stmt (flag_isoc99);
c2255bc4 6365 location_t loc = c_parser_peek_token (parser)->location;
3e2becc4 6366 c_parser_statement (parser, if_p, loc_after_labels);
c2255bc4 6367 return c_end_compound_stmt (loc, block, flag_isoc99);
27bf414c
JM
6368}
6369
b4b56033
MLI
6370/* Parse the body of an if statement. This is just parsing a
6371 statement but (a) it is a block in C99, (b) we track whether the
6372 body is an if statement for the sake of -Wparentheses warnings, (c)
6373 we handle an empty body specially for the sake of -Wempty-body
6374 warnings, and (d) we call parser_compound_statement directly
6375 because c_parser_statement_after_labels resets
99cd9857
MP
6376 parser->in_if_block.
6377
6378 IF_P is used to track whether there's a (possibly labeled) if statement
6379 which is not enclosed in braces and has an else clause. This is used to
6380 implement -Wparentheses. */
27bf414c
JM
6381
6382static tree
992118a1
PP
6383c_parser_if_body (c_parser *parser, bool *if_p,
6384 const token_indent_info &if_tinfo)
27bf414c
JM
6385{
6386 tree block = c_begin_compound_stmt (flag_isoc99);
c2255bc4 6387 location_t body_loc = c_parser_peek_token (parser)->location;
3e2becc4 6388 location_t body_loc_after_labels = UNKNOWN_LOCATION;
992118a1
PP
6389 token_indent_info body_tinfo
6390 = get_token_indent_info (c_parser_peek_token (parser));
6391
74d98c1e 6392 c_parser_all_labels (parser);
62e00e94 6393 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
b4b56033 6394 {
626c34b5 6395 location_t loc = c_parser_peek_token (parser)->location;
c2255bc4 6396 add_stmt (build_empty_stmt (loc));
b4b56033 6397 c_parser_consume_token (parser);
626c34b5
PB
6398 if (!c_parser_next_token_is_keyword (parser, RID_ELSE))
6399 warning_at (loc, OPT_Wempty_body,
6400 "suggest braces around empty body in an %<if%> statement");
b4b56033
MLI
6401 }
6402 else if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
6403 add_stmt (c_parser_compound_statement (parser));
6404 else
3e2becc4
MP
6405 {
6406 body_loc_after_labels = c_parser_peek_token (parser)->location;
6407 c_parser_statement_after_labels (parser, if_p);
6408 }
992118a1
PP
6409
6410 token_indent_info next_tinfo
6411 = get_token_indent_info (c_parser_peek_token (parser));
6412 warn_for_misleading_indentation (if_tinfo, body_tinfo, next_tinfo);
3e2becc4
MP
6413 if (body_loc_after_labels != UNKNOWN_LOCATION
6414 && next_tinfo.type != CPP_SEMICOLON)
6415 warn_for_multistatement_macros (body_loc_after_labels, next_tinfo.location,
6416 if_tinfo.location, RID_IF);
c3388e62 6417
c2255bc4 6418 return c_end_compound_stmt (body_loc, block, flag_isoc99);
b4b56033
MLI
6419}
6420
6421/* Parse the else body of an if statement. This is just parsing a
6422 statement but (a) it is a block in C99, (b) we handle an empty body
3e3b8d63
MP
6423 specially for the sake of -Wempty-body warnings. CHAIN is a vector
6424 of if-else-if conditions. */
b4b56033
MLI
6425
6426static tree
3e3b8d63
MP
6427c_parser_else_body (c_parser *parser, const token_indent_info &else_tinfo,
6428 vec<tree> *chain)
b4b56033 6429{
c3388e62 6430 location_t body_loc = c_parser_peek_token (parser)->location;
b4b56033 6431 tree block = c_begin_compound_stmt (flag_isoc99);
992118a1
PP
6432 token_indent_info body_tinfo
6433 = get_token_indent_info (c_parser_peek_token (parser));
3e2becc4 6434 location_t body_loc_after_labels = UNKNOWN_LOCATION;
992118a1 6435
74d98c1e 6436 c_parser_all_labels (parser);
b4b56033
MLI
6437 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6438 {
c2255bc4
AH
6439 location_t loc = c_parser_peek_token (parser)->location;
6440 warning_at (loc,
626c34b5
PB
6441 OPT_Wempty_body,
6442 "suggest braces around empty body in an %<else%> statement");
c2255bc4 6443 add_stmt (build_empty_stmt (loc));
b4b56033
MLI
6444 c_parser_consume_token (parser);
6445 }
b8698a0f 6446 else
3e2becc4 6447 {
d49718d6
MP
6448 if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE))
6449 body_loc_after_labels = c_parser_peek_token (parser)->location;
3e2becc4
MP
6450 c_parser_statement_after_labels (parser, NULL, chain);
6451 }
992118a1
PP
6452
6453 token_indent_info next_tinfo
6454 = get_token_indent_info (c_parser_peek_token (parser));
6455 warn_for_misleading_indentation (else_tinfo, body_tinfo, next_tinfo);
3e2becc4
MP
6456 if (body_loc_after_labels != UNKNOWN_LOCATION
6457 && next_tinfo.type != CPP_SEMICOLON)
6458 warn_for_multistatement_macros (body_loc_after_labels, next_tinfo.location,
6459 else_tinfo.location, RID_ELSE);
992118a1 6460
c3388e62 6461 return c_end_compound_stmt (body_loc, block, flag_isoc99);
27bf414c
JM
6462}
6463
2448a956
MP
6464/* We might need to reclassify any previously-lexed identifier, e.g.
6465 when we've left a for loop with an if-statement without else in the
6466 body - we might have used a wrong scope for the token. See PR67784. */
6467
6468static void
6469c_parser_maybe_reclassify_token (c_parser *parser)
6470{
6471 if (c_parser_next_token_is (parser, CPP_NAME))
6472 {
6473 c_token *token = c_parser_peek_token (parser);
6474
6475 if (token->id_kind != C_ID_CLASSNAME)
6476 {
6477 tree decl = lookup_name (token->value);
6478
6479 token->id_kind = C_ID_ID;
6480 if (decl)
6481 {
6482 if (TREE_CODE (decl) == TYPE_DECL)
6483 token->id_kind = C_ID_TYPENAME;
6484 }
6485 else if (c_dialect_objc ())
6486 {
6487 tree objc_interface_decl = objc_is_class_name (token->value);
6488 /* Objective-C class names are in the same namespace as
6489 variables and typedefs, and hence are shadowed by local
6490 declarations. */
6491 if (objc_interface_decl)
6492 {
6493 token->value = objc_interface_decl;
6494 token->id_kind = C_ID_CLASSNAME;
6495 }
6496 }
6497 }
6498 }
6499}
6500
31dc71a8 6501/* Parse an if statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
27bf414c
JM
6502
6503 if-statement:
6504 if ( expression ) statement
6505 if ( expression ) statement else statement
3e3b8d63 6506
99cd9857
MP
6507 CHAIN is a vector of if-else-if conditions.
6508 IF_P is used to track whether there's a (possibly labeled) if statement
6509 which is not enclosed in braces and has an else clause. This is used to
6510 implement -Wparentheses. */
27bf414c
JM
6511
6512static void
99cd9857 6513c_parser_if_statement (c_parser *parser, bool *if_p, vec<tree> *chain)
27bf414c
JM
6514{
6515 tree block;
6516 location_t loc;
6517 tree cond;
99cd9857 6518 bool nested_if = false;
27bf414c 6519 tree first_body, second_body;
b4b56033
MLI
6520 bool in_if_block;
6521
27bf414c 6522 gcc_assert (c_parser_next_token_is_keyword (parser, RID_IF));
992118a1
PP
6523 token_indent_info if_tinfo
6524 = get_token_indent_info (c_parser_peek_token (parser));
27bf414c
JM
6525 c_parser_consume_token (parser);
6526 block = c_begin_compound_stmt (flag_isoc99);
6527 loc = c_parser_peek_token (parser)->location;
6528 cond = c_parser_paren_condition (parser);
b4b56033
MLI
6529 in_if_block = parser->in_if_block;
6530 parser->in_if_block = true;
99cd9857 6531 first_body = c_parser_if_body (parser, &nested_if, if_tinfo);
b4b56033 6532 parser->in_if_block = in_if_block;
3e3b8d63
MP
6533
6534 if (warn_duplicated_cond)
6535 warn_duplicated_cond_add_or_warn (EXPR_LOCATION (cond), cond, &chain);
6536
27bf414c
JM
6537 if (c_parser_next_token_is_keyword (parser, RID_ELSE))
6538 {
992118a1
PP
6539 token_indent_info else_tinfo
6540 = get_token_indent_info (c_parser_peek_token (parser));
27bf414c 6541 c_parser_consume_token (parser);
3e3b8d63
MP
6542 if (warn_duplicated_cond)
6543 {
6544 if (c_parser_next_token_is_keyword (parser, RID_IF)
6545 && chain == NULL)
6546 {
6547 /* We've got "if (COND) else if (COND2)". Start the
6548 condition chain and add COND as the first element. */
6549 chain = new vec<tree> ();
6550 if (!CONSTANT_CLASS_P (cond) && !TREE_SIDE_EFFECTS (cond))
6551 chain->safe_push (cond);
6552 }
6553 else if (!c_parser_next_token_is_keyword (parser, RID_IF))
6554 {
6555 /* This is if-else without subsequent if. Zap the condition
6556 chain; we would have already warned at this point. */
6557 delete chain;
6558 chain = NULL;
6559 }
6560 }
6561 second_body = c_parser_else_body (parser, else_tinfo, chain);
99cd9857
MP
6562 /* Set IF_P to true to indicate that this if statement has an
6563 else clause. This may trigger the Wparentheses warning
6564 below when we get back up to the parent if statement. */
6565 if (if_p != NULL)
6566 *if_p = true;
27bf414c
JM
6567 }
6568 else
3e3b8d63
MP
6569 {
6570 second_body = NULL_TREE;
99cd9857
MP
6571
6572 /* Diagnose an ambiguous else if if-then-else is nested inside
6573 if-then. */
6574 if (nested_if)
deef7113 6575 warning_at (loc, OPT_Wdangling_else,
99cd9857
MP
6576 "suggest explicit braces to avoid ambiguous %<else%>");
6577
3e3b8d63
MP
6578 if (warn_duplicated_cond)
6579 {
6580 /* This if statement does not have an else clause. We don't
6581 need the condition chain anymore. */
6582 delete chain;
6583 chain = NULL;
6584 }
6585 }
99cd9857 6586 c_finish_if_stmt (loc, cond, first_body, second_body);
5e9d6aa4 6587 add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
36536d79 6588
2448a956 6589 c_parser_maybe_reclassify_token (parser);
27bf414c
JM
6590}
6591
31dc71a8 6592/* Parse a switch statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
27bf414c
JM
6593
6594 switch-statement:
6595 switch (expression) statement
6596*/
6597
6598static void
351f85c5 6599c_parser_switch_statement (c_parser *parser, bool *if_p)
27bf414c 6600{
267bac10 6601 struct c_expr ce;
27bf414c 6602 tree block, expr, body, save_break;
c2255bc4
AH
6603 location_t switch_loc = c_parser_peek_token (parser)->location;
6604 location_t switch_cond_loc;
27bf414c
JM
6605 gcc_assert (c_parser_next_token_is_keyword (parser, RID_SWITCH));
6606 c_parser_consume_token (parser);
6607 block = c_begin_compound_stmt (flag_isoc99);
fedfecef 6608 bool explicit_cast_p = false;
32129a17
DM
6609 matching_parens parens;
6610 if (parens.require_open (parser))
27bf414c 6611 {
c2255bc4 6612 switch_cond_loc = c_parser_peek_token (parser)->location;
fedfecef
MP
6613 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
6614 && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
6615 explicit_cast_p = true;
267bac10 6616 ce = c_parser_expression (parser);
f9eb0973 6617 ce = convert_lvalue_to_rvalue (switch_cond_loc, ce, true, true);
267bac10 6618 expr = ce.value;
e5e44252 6619 /* ??? expr has no valid location? */
32129a17 6620 parens.skip_until_found_close (parser);
27bf414c
JM
6621 }
6622 else
c2255bc4
AH
6623 {
6624 switch_cond_loc = UNKNOWN_LOCATION;
6625 expr = error_mark_node;
efd0786f 6626 ce.original_type = error_mark_node;
c2255bc4 6627 }
fedfecef 6628 c_start_case (switch_loc, switch_cond_loc, expr, explicit_cast_p);
27bf414c
JM
6629 save_break = c_break_label;
6630 c_break_label = NULL_TREE;
3e2becc4
MP
6631 location_t loc_after_labels;
6632 bool open_brace_p = c_parser_peek_token (parser)->type == CPP_OPEN_BRACE;
6633 body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
6634 location_t next_loc = c_parser_peek_token (parser)->location;
6635 if (!open_brace_p && c_parser_peek_token (parser)->type != CPP_SEMICOLON)
6636 warn_for_multistatement_macros (loc_after_labels, next_loc, switch_loc,
6637 RID_SWITCH);
27bf414c 6638 if (c_break_label)
c2255bc4
AH
6639 {
6640 location_t here = c_parser_peek_token (parser)->location;
6641 tree t = build1 (LABEL_EXPR, void_type_node, c_break_label);
6642 SET_EXPR_LOCATION (t, here);
65791f42
JJ
6643 SWITCH_BREAK_LABEL_P (c_break_label) = 1;
6644 append_to_statement_list_force (t, &body);
c2255bc4 6645 }
65791f42 6646 c_finish_case (body, ce.original_type);
27bf414c 6647 c_break_label = save_break;
c2255bc4 6648 add_stmt (c_end_compound_stmt (switch_loc, block, flag_isoc99));
2448a956 6649 c_parser_maybe_reclassify_token (parser);
27bf414c
JM
6650}
6651
31dc71a8 6652/* Parse a while statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
27bf414c
JM
6653
6654 while-statement:
6655 while (expression) statement
99cd9857
MP
6656
6657 IF_P is used to track whether there's a (possibly labeled) if statement
6658 which is not enclosed in braces and has an else clause. This is used to
6659 implement -Wparentheses. */
27bf414c
JM
6660
6661static void
170a8bd6
EB
6662c_parser_while_statement (c_parser *parser, bool ivdep, unsigned short unroll,
6663 bool *if_p)
27bf414c
JM
6664{
6665 tree block, cond, body, save_break, save_cont;
6666 location_t loc;
6667 gcc_assert (c_parser_next_token_is_keyword (parser, RID_WHILE));
992118a1
PP
6668 token_indent_info while_tinfo
6669 = get_token_indent_info (c_parser_peek_token (parser));
27bf414c
JM
6670 c_parser_consume_token (parser);
6671 block = c_begin_compound_stmt (flag_isoc99);
6672 loc = c_parser_peek_token (parser)->location;
6673 cond = c_parser_paren_condition (parser);
d4af74d4 6674 if (ivdep && cond != error_mark_node)
ac9effed 6675 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
d4af74d4 6676 build_int_cst (integer_type_node,
ac9effed
EB
6677 annot_expr_ivdep_kind),
6678 integer_zero_node);
170a8bd6
EB
6679 if (unroll && cond != error_mark_node)
6680 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6681 build_int_cst (integer_type_node,
6682 annot_expr_unroll_kind),
6683 build_int_cst (integer_type_node, unroll));
27bf414c
JM
6684 save_break = c_break_label;
6685 c_break_label = NULL_TREE;
6686 save_cont = c_cont_label;
6687 c_cont_label = NULL_TREE;
c3388e62 6688
992118a1
PP
6689 token_indent_info body_tinfo
6690 = get_token_indent_info (c_parser_peek_token (parser));
6691
3e2becc4 6692 location_t loc_after_labels;
d49718d6 6693 bool open_brace = c_parser_next_token_is (parser, CPP_OPEN_BRACE);
3e2becc4 6694 body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
f179b64e
JJ
6695 c_finish_loop (loc, loc, cond, UNKNOWN_LOCATION, NULL, body,
6696 c_break_label, c_cont_label, true);
f6b0b3db 6697 add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
2448a956 6698 c_parser_maybe_reclassify_token (parser);
992118a1
PP
6699
6700 token_indent_info next_tinfo
6701 = get_token_indent_info (c_parser_peek_token (parser));
6702 warn_for_misleading_indentation (while_tinfo, body_tinfo, next_tinfo);
c3388e62 6703
d49718d6 6704 if (next_tinfo.type != CPP_SEMICOLON && !open_brace)
3e2becc4
MP
6705 warn_for_multistatement_macros (loc_after_labels, next_tinfo.location,
6706 while_tinfo.location, RID_WHILE);
6707
27bf414c
JM
6708 c_break_label = save_break;
6709 c_cont_label = save_cont;
6710}
6711
31dc71a8 6712/* Parse a do statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
27bf414c
JM
6713
6714 do-statement:
6715 do statement while ( expression ) ;
6716*/
6717
6718static void
170a8bd6 6719c_parser_do_statement (c_parser *parser, bool ivdep, unsigned short unroll)
27bf414c
JM
6720{
6721 tree block, cond, body, save_break, save_cont, new_break, new_cont;
6722 location_t loc;
6723 gcc_assert (c_parser_next_token_is_keyword (parser, RID_DO));
6724 c_parser_consume_token (parser);
62e00e94 6725 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
3ba09659
AH
6726 warning_at (c_parser_peek_token (parser)->location,
6727 OPT_Wempty_body,
6728 "suggest braces around empty body in %<do%> statement");
27bf414c
JM
6729 block = c_begin_compound_stmt (flag_isoc99);
6730 loc = c_parser_peek_token (parser)->location;
6731 save_break = c_break_label;
6732 c_break_label = NULL_TREE;
6733 save_cont = c_cont_label;
6734 c_cont_label = NULL_TREE;
99cd9857 6735 body = c_parser_c99_block_statement (parser, NULL);
27bf414c
JM
6736 c_parser_require_keyword (parser, RID_WHILE, "expected %<while%>");
6737 new_break = c_break_label;
6738 c_break_label = save_break;
6739 new_cont = c_cont_label;
6740 c_cont_label = save_cont;
f179b64e 6741 location_t cond_loc = c_parser_peek_token (parser)->location;
27bf414c 6742 cond = c_parser_paren_condition (parser);
d4af74d4 6743 if (ivdep && cond != error_mark_node)
ac9effed 6744 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
d4af74d4 6745 build_int_cst (integer_type_node,
ac9effed
EB
6746 annot_expr_ivdep_kind),
6747 integer_zero_node);
170a8bd6
EB
6748 if (unroll && cond != error_mark_node)
6749 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6750 build_int_cst (integer_type_node,
6751 annot_expr_unroll_kind),
6752 build_int_cst (integer_type_node, unroll));
27bf414c
JM
6753 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
6754 c_parser_skip_to_end_of_block_or_statement (parser);
f179b64e
JJ
6755 c_finish_loop (loc, cond_loc, cond, UNKNOWN_LOCATION, NULL, body,
6756 new_break, new_cont, false);
c2255bc4 6757 add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
27bf414c
JM
6758}
6759
31dc71a8 6760/* Parse a for statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
27bf414c
JM
6761
6762 for-statement:
6763 for ( expression[opt] ; expression[opt] ; expression[opt] ) statement
6764 for ( nested-declaration expression[opt] ; expression[opt] ) statement
6765
6766 The form with a declaration is new in C99.
6767
6768 ??? In accordance with the old parser, the declaration may be a
6769 nested function, which is then rejected in check_for_loop_decls,
6770 but does it make any sense for this to be included in the grammar?
6771 Note in particular that the nested function does not include a
6772 trailing ';', whereas the "declaration" production includes one.
6773 Also, can we reject bad declarations earlier and cheaper than
f05b9d93
NP
6774 check_for_loop_decls?
6775
6776 In Objective-C, there are two additional variants:
6777
6778 foreach-statement:
6779 for ( expression in expresssion ) statement
6780 for ( declaration in expression ) statement
6781
6782 This is inconsistent with C, because the second variant is allowed
6783 even if c99 is not enabled.
6784
6785 The rest of the comment documents these Objective-C foreach-statement.
6786
6787 Here is the canonical example of the first variant:
6788 for (object in array) { do something with object }
6789 we call the first expression ("object") the "object_expression" and
6790 the second expression ("array") the "collection_expression".
6791 object_expression must be an lvalue of type "id" (a generic Objective-C
6792 object) because the loop works by assigning to object_expression the
6793 various objects from the collection_expression. collection_expression
6794 must evaluate to something of type "id" which responds to the method
6795 countByEnumeratingWithState:objects:count:.
6796
6797 The canonical example of the second variant is:
6798 for (id object in array) { do something with object }
6799 which is completely equivalent to
6800 {
6801 id object;
6802 for (object in array) { do something with object }
6803 }
6804 Note that initizializing 'object' in some way (eg, "for ((object =
6805 xxx) in array) { do something with object }") is possibly
6806 technically valid, but completely pointless as 'object' will be
6807 assigned to something else as soon as the loop starts. We should
6808 most likely reject it (TODO).
6809
6810 The beginning of the Objective-C foreach-statement looks exactly
6811 like the beginning of the for-statement, and we can tell it is a
6812 foreach-statement only because the initial declaration or
6813 expression is terminated by 'in' instead of ';'.
99cd9857
MP
6814
6815 IF_P is used to track whether there's a (possibly labeled) if statement
6816 which is not enclosed in braces and has an else clause. This is used to
6817 implement -Wparentheses. */
27bf414c
JM
6818
6819static void
170a8bd6
EB
6820c_parser_for_statement (c_parser *parser, bool ivdep, unsigned short unroll,
6821 bool *if_p)
27bf414c
JM
6822{
6823 tree block, cond, incr, save_break, save_cont, body;
f05b9d93 6824 /* The following are only used when parsing an ObjC foreach statement. */
689f2c82
AO
6825 tree object_expression;
6826 /* Silence the bogus uninitialized warning. */
6827 tree collection_expression = NULL;
c2255bc4 6828 location_t loc = c_parser_peek_token (parser)->location;
f179b64e
JJ
6829 location_t for_loc = loc;
6830 location_t cond_loc = UNKNOWN_LOCATION;
6831 location_t incr_loc = UNKNOWN_LOCATION;
f05b9d93 6832 bool is_foreach_statement = false;
27bf414c 6833 gcc_assert (c_parser_next_token_is_keyword (parser, RID_FOR));
992118a1
PP
6834 token_indent_info for_tinfo
6835 = get_token_indent_info (c_parser_peek_token (parser));
27bf414c 6836 c_parser_consume_token (parser);
f05b9d93
NP
6837 /* Open a compound statement in Objective-C as well, just in case this is
6838 as foreach expression. */
6839 block = c_begin_compound_stmt (flag_isoc99 || c_dialect_objc ());
91b90ead
UB
6840 cond = error_mark_node;
6841 incr = error_mark_node;
32129a17
DM
6842 matching_parens parens;
6843 if (parens.require_open (parser))
27bf414c
JM
6844 {
6845 /* Parse the initialization declaration or expression. */
f05b9d93 6846 object_expression = error_mark_node;
a5812bdc 6847 parser->objc_could_be_foreach_context = c_dialect_objc ();
27bf414c
JM
6848 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6849 {
a5812bdc 6850 parser->objc_could_be_foreach_context = false;
27bf414c 6851 c_parser_consume_token (parser);
c2255bc4 6852 c_finish_expr_stmt (loc, NULL_TREE);
27bf414c 6853 }
4e03c3a7
JM
6854 else if (c_parser_next_tokens_start_declaration (parser)
6855 || c_parser_nth_token_starts_std_attributes (parser, 1))
27bf414c 6856 {
f05b9d93 6857 c_parser_declaration_or_fndef (parser, true, true, true, true, true,
acf0174b 6858 &object_expression, vNULL);
f05b9d93
NP
6859 parser->objc_could_be_foreach_context = false;
6860
6861 if (c_parser_next_token_is_keyword (parser, RID_IN))
6862 {
6863 c_parser_consume_token (parser);
6864 is_foreach_statement = true;
6865 if (check_for_loop_decls (for_loc, true) == NULL_TREE)
f179b64e
JJ
6866 c_parser_error (parser, "multiple iterating variables in "
6867 "fast enumeration");
f05b9d93
NP
6868 }
6869 else
6870 check_for_loop_decls (for_loc, flag_isoc99);
27bf414c
JM
6871 }
6872 else if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
6873 {
6874 /* __extension__ can start a declaration, but is also an
6875 unary operator that can start an expression. Consume all
6876 but the last of a possible series of __extension__ to
6877 determine which. */
6878 while (c_parser_peek_2nd_token (parser)->type == CPP_KEYWORD
6879 && (c_parser_peek_2nd_token (parser)->keyword
6880 == RID_EXTENSION))
6881 c_parser_consume_token (parser);
4e03c3a7
JM
6882 if (c_token_starts_declaration (c_parser_peek_2nd_token (parser))
6883 || c_parser_nth_token_starts_std_attributes (parser, 2))
27bf414c
JM
6884 {
6885 int ext;
6886 ext = disable_extension_diagnostics ();
6887 c_parser_consume_token (parser);
32912286 6888 c_parser_declaration_or_fndef (parser, true, true, true, true,
acf0174b 6889 true, &object_expression, vNULL);
f05b9d93
NP
6890 parser->objc_could_be_foreach_context = false;
6891
27bf414c 6892 restore_extension_diagnostics (ext);
f05b9d93
NP
6893 if (c_parser_next_token_is_keyword (parser, RID_IN))
6894 {
6895 c_parser_consume_token (parser);
6896 is_foreach_statement = true;
6897 if (check_for_loop_decls (for_loc, true) == NULL_TREE)
f179b64e
JJ
6898 c_parser_error (parser, "multiple iterating variables in "
6899 "fast enumeration");
f05b9d93
NP
6900 }
6901 else
6902 check_for_loop_decls (for_loc, flag_isoc99);
27bf414c
JM
6903 }
6904 else
6905 goto init_expr;
6906 }
6907 else
6908 {
6909 init_expr:
f05b9d93 6910 {
267bac10 6911 struct c_expr ce;
f05b9d93 6912 tree init_expression;
267bac10
JM
6913 ce = c_parser_expression (parser);
6914 init_expression = ce.value;
f05b9d93
NP
6915 parser->objc_could_be_foreach_context = false;
6916 if (c_parser_next_token_is_keyword (parser, RID_IN))
6917 {
6918 c_parser_consume_token (parser);
6919 is_foreach_statement = true;
6920 if (! lvalue_p (init_expression))
f179b64e
JJ
6921 c_parser_error (parser, "invalid iterating variable in "
6922 "fast enumeration");
6923 object_expression
6924 = c_fully_fold (init_expression, false, NULL);
f05b9d93
NP
6925 }
6926 else
6927 {
267bac10
JM
6928 ce = convert_lvalue_to_rvalue (loc, ce, true, false);
6929 init_expression = ce.value;
f05b9d93 6930 c_finish_expr_stmt (loc, init_expression);
f179b64e
JJ
6931 c_parser_skip_until_found (parser, CPP_SEMICOLON,
6932 "expected %<;%>");
f05b9d93
NP
6933 }
6934 }
27bf414c 6935 }
f05b9d93
NP
6936 /* Parse the loop condition. In the case of a foreach
6937 statement, there is no loop condition. */
a5812bdc 6938 gcc_assert (!parser->objc_could_be_foreach_context);
f05b9d93 6939 if (!is_foreach_statement)
27bf414c 6940 {
f179b64e 6941 cond_loc = c_parser_peek_token (parser)->location;
f05b9d93
NP
6942 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6943 {
8170608b
TB
6944 if (ivdep)
6945 {
f179b64e
JJ
6946 c_parser_error (parser, "missing loop condition in loop "
6947 "with %<GCC ivdep%> pragma");
8170608b
TB
6948 cond = error_mark_node;
6949 }
170a8bd6
EB
6950 else if (unroll)
6951 {
f179b64e
JJ
6952 c_parser_error (parser, "missing loop condition in loop "
6953 "with %<GCC unroll%> pragma");
170a8bd6
EB
6954 cond = error_mark_node;
6955 }
8170608b
TB
6956 else
6957 {
6958 c_parser_consume_token (parser);
6959 cond = NULL_TREE;
6960 }
f05b9d93
NP
6961 }
6962 else
6963 {
6964 cond = c_parser_condition (parser);
36536d79
BI
6965 c_parser_skip_until_found (parser, CPP_SEMICOLON,
6966 "expected %<;%>");
f05b9d93 6967 }
8170608b 6968 if (ivdep && cond != error_mark_node)
ac9effed 6969 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
8170608b 6970 build_int_cst (integer_type_node,
ac9effed
EB
6971 annot_expr_ivdep_kind),
6972 integer_zero_node);
170a8bd6
EB
6973 if (unroll && cond != error_mark_node)
6974 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6975 build_int_cst (integer_type_node,
6976 annot_expr_unroll_kind),
6977 build_int_cst (integer_type_node, unroll));
27bf414c 6978 }
f05b9d93
NP
6979 /* Parse the increment expression (the third expression in a
6980 for-statement). In the case of a foreach-statement, this is
6981 the expression that follows the 'in'. */
f179b64e 6982 loc = incr_loc = c_parser_peek_token (parser)->location;
f05b9d93 6983 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
27bf414c 6984 {
f05b9d93
NP
6985 if (is_foreach_statement)
6986 {
f179b64e
JJ
6987 c_parser_error (parser,
6988 "missing collection in fast enumeration");
f05b9d93
NP
6989 collection_expression = error_mark_node;
6990 }
6991 else
6992 incr = c_process_expr_stmt (loc, NULL_TREE);
27bf414c 6993 }
27bf414c 6994 else
f05b9d93
NP
6995 {
6996 if (is_foreach_statement)
f179b64e
JJ
6997 collection_expression
6998 = c_fully_fold (c_parser_expression (parser).value, false, NULL);
f05b9d93 6999 else
267bac10
JM
7000 {
7001 struct c_expr ce = c_parser_expression (parser);
7002 ce = convert_lvalue_to_rvalue (loc, ce, true, false);
7003 incr = c_process_expr_stmt (loc, ce.value);
7004 }
f05b9d93 7005 }
32129a17 7006 parens.skip_until_found_close (parser);
27bf414c 7007 }
27bf414c
JM
7008 save_break = c_break_label;
7009 c_break_label = NULL_TREE;
7010 save_cont = c_cont_label;
7011 c_cont_label = NULL_TREE;
c3388e62 7012
992118a1
PP
7013 token_indent_info body_tinfo
7014 = get_token_indent_info (c_parser_peek_token (parser));
7015
3e2becc4 7016 location_t loc_after_labels;
d49718d6 7017 bool open_brace = c_parser_next_token_is (parser, CPP_OPEN_BRACE);
3e2becc4 7018 body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
992118a1 7019
f05b9d93 7020 if (is_foreach_statement)
f179b64e
JJ
7021 objc_finish_foreach_loop (for_loc, object_expression,
7022 collection_expression, body, c_break_label,
7023 c_cont_label);
f05b9d93 7024 else
f179b64e
JJ
7025 c_finish_loop (for_loc, cond_loc, cond, incr_loc, incr, body,
7026 c_break_label, c_cont_label, true);
7027 add_stmt (c_end_compound_stmt (for_loc, block,
7028 flag_isoc99 || c_dialect_objc ()));
2448a956 7029 c_parser_maybe_reclassify_token (parser);
9be4f715 7030
f6b0b3db
AA
7031 token_indent_info next_tinfo
7032 = get_token_indent_info (c_parser_peek_token (parser));
7033 warn_for_misleading_indentation (for_tinfo, body_tinfo, next_tinfo);
7034
d49718d6 7035 if (next_tinfo.type != CPP_SEMICOLON && !open_brace)
3e2becc4
MP
7036 warn_for_multistatement_macros (loc_after_labels, next_tinfo.location,
7037 for_tinfo.location, RID_FOR);
7038
27bf414c
JM
7039 c_break_label = save_break;
7040 c_cont_label = save_cont;
7041}
7042
7043/* Parse an asm statement, a GNU extension. This is a full-blown asm
5b76e75f
SB
7044 statement with inputs, outputs, clobbers, and volatile, inline, and goto
7045 tags allowed.
27bf414c 7046
30bd42b9
SB
7047 asm-qualifier:
7048 volatile
5b76e75f 7049 inline
30bd42b9
SB
7050 goto
7051
7052 asm-qualifier-list:
7053 asm-qualifier-list asm-qualifier
7054 asm-qualifier
7055
27bf414c 7056 asm-statement:
30bd42b9 7057 asm asm-qualifier-list[opt] ( asm-argument ) ;
27bf414c
JM
7058
7059 asm-argument:
7060 asm-string-literal
7061 asm-string-literal : asm-operands[opt]
7062 asm-string-literal : asm-operands[opt] : asm-operands[opt]
30bd42b9
SB
7063 asm-string-literal : asm-operands[opt] : asm-operands[opt] \
7064 : asm-clobbers[opt]
1c384bf1
RH
7065 asm-string-literal : : asm-operands[opt] : asm-clobbers[opt] \
7066 : asm-goto-operands
27bf414c 7067
30bd42b9
SB
7068 The form with asm-goto-operands is valid if and only if the
7069 asm-qualifier-list contains goto, and is the only allowed form in that case.
93313b94
JM
7070 Duplicate asm-qualifiers are not allowed.
7071
7072 The :: token is considered equivalent to two consecutive : tokens. */
27bf414c
JM
7073
7074static tree
7075c_parser_asm_statement (c_parser *parser)
7076{
db4fd626
SB
7077 tree str, outputs, inputs, clobbers, labels, ret;
7078 bool simple;
c2255bc4 7079 location_t asm_loc = c_parser_peek_token (parser)->location;
1c384bf1
RH
7080 int section, nsections;
7081
27bf414c
JM
7082 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
7083 c_parser_consume_token (parser);
1c384bf1 7084
db4fd626
SB
7085 /* Handle the asm-qualifier-list. */
7086 location_t volatile_loc = UNKNOWN_LOCATION;
7087 location_t inline_loc = UNKNOWN_LOCATION;
7088 location_t goto_loc = UNKNOWN_LOCATION;
9c9cfcbb
SB
7089 for (;;)
7090 {
db4fd626
SB
7091 c_token *token = c_parser_peek_token (parser);
7092 location_t loc = token->location;
7093 switch (token->keyword)
9c9cfcbb
SB
7094 {
7095 case RID_VOLATILE:
db4fd626
SB
7096 if (volatile_loc)
7097 {
a9c697b8 7098 error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
db4fd626
SB
7099 inform (volatile_loc, "first seen here");
7100 }
7101 else
7102 volatile_loc = loc;
9c9cfcbb
SB
7103 c_parser_consume_token (parser);
7104 continue;
7105
7106 case RID_INLINE:
db4fd626
SB
7107 if (inline_loc)
7108 {
a9c697b8 7109 error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
db4fd626
SB
7110 inform (inline_loc, "first seen here");
7111 }
7112 else
7113 inline_loc = loc;
9c9cfcbb
SB
7114 c_parser_consume_token (parser);
7115 continue;
7116
7117 case RID_GOTO:
db4fd626
SB
7118 if (goto_loc)
7119 {
a9c697b8 7120 error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
db4fd626
SB
7121 inform (goto_loc, "first seen here");
7122 }
7123 else
7124 goto_loc = loc;
9c9cfcbb
SB
7125 c_parser_consume_token (parser);
7126 continue;
7127
1edf8866
SB
7128 case RID_CONST:
7129 case RID_RESTRICT:
a9c697b8 7130 error_at (loc, "%qE is not a valid %<asm%> qualifier", token->value);
1edf8866
SB
7131 c_parser_consume_token (parser);
7132 continue;
7133
9c9cfcbb
SB
7134 default:
7135 break;
7136 }
7137 break;
7138 }
1c384bf1 7139
db4fd626
SB
7140 bool is_volatile = (volatile_loc != UNKNOWN_LOCATION);
7141 bool is_inline = (inline_loc != UNKNOWN_LOCATION);
7142 bool is_goto = (goto_loc != UNKNOWN_LOCATION);
7143
1c384bf1
RH
7144 ret = NULL;
7145
32129a17
DM
7146 matching_parens parens;
7147 if (!parens.require_open (parser))
1c384bf1
RH
7148 goto error;
7149
27bf414c 7150 str = c_parser_asm_string_literal (parser);
b85eb797 7151 if (str == NULL_TREE)
1c384bf1
RH
7152 goto error_close_paren;
7153
7154 simple = true;
7155 outputs = NULL_TREE;
7156 inputs = NULL_TREE;
7157 clobbers = NULL_TREE;
7158 labels = NULL_TREE;
7159
7160 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN) && !is_goto)
7161 goto done_asm;
7162
7163 /* Parse each colon-delimited section of operands. */
7164 nsections = 3 + is_goto;
7165 for (section = 0; section < nsections; ++section)
b85eb797 7166 {
93313b94
JM
7167 if (c_parser_next_token_is (parser, CPP_SCOPE))
7168 {
7169 ++section;
7170 if (section == nsections)
7171 {
7172 c_parser_error (parser, "expected %<)%>");
7173 goto error_close_paren;
7174 }
7175 c_parser_consume_token (parser);
7176 }
7177 else if (!c_parser_require (parser, CPP_COLON,
7178 is_goto
7179 ? G_("expected %<:%>")
7180 : G_("expected %<:%> or %<)%>"),
7181 UNKNOWN_LOCATION, is_goto))
1c384bf1
RH
7182 goto error_close_paren;
7183
7184 /* Once past any colon, we're no longer a simple asm. */
7185 simple = false;
7186
7187 if ((!c_parser_next_token_is (parser, CPP_COLON)
93313b94 7188 && !c_parser_next_token_is (parser, CPP_SCOPE)
1c384bf1
RH
7189 && !c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
7190 || section == 3)
7191 switch (section)
7192 {
7193 case 0:
7194 /* For asm goto, we don't allow output operands, but reserve
7195 the slot for a future extension that does allow them. */
7196 if (!is_goto)
eadd3d0d 7197 outputs = c_parser_asm_operands (parser);
1c384bf1
RH
7198 break;
7199 case 1:
eadd3d0d 7200 inputs = c_parser_asm_operands (parser);
1c384bf1
RH
7201 break;
7202 case 2:
7203 clobbers = c_parser_asm_clobbers (parser);
7204 break;
7205 case 3:
7206 labels = c_parser_asm_goto_operands (parser);
7207 break;
7208 default:
7209 gcc_unreachable ();
7210 }
7211
7212 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN) && !is_goto)
7213 goto done_asm;
27bf414c 7214 }
1c384bf1 7215
27bf414c 7216 done_asm:
32129a17 7217 if (!parens.require_close (parser))
27bf414c
JM
7218 {
7219 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
1c384bf1 7220 goto error;
27bf414c 7221 }
1c384bf1 7222
27bf414c
JM
7223 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
7224 c_parser_skip_to_end_of_block_or_statement (parser);
1c384bf1 7225
db4fd626
SB
7226 ret = build_asm_stmt (is_volatile,
7227 build_asm_expr (asm_loc, str, outputs, inputs,
7228 clobbers, labels, simple, is_inline));
1c384bf1
RH
7229
7230 error:
27bf414c 7231 return ret;
1c384bf1
RH
7232
7233 error_close_paren:
7234 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
7235 goto error;
27bf414c
JM
7236}
7237
eadd3d0d 7238/* Parse asm operands, a GNU extension.
27bf414c
JM
7239
7240 asm-operands:
7241 asm-operand
7242 asm-operands , asm-operand
7243
7244 asm-operand:
7245 asm-string-literal ( expression )
7246 [ identifier ] asm-string-literal ( expression )
7247*/
7248
7249static tree
eadd3d0d 7250c_parser_asm_operands (c_parser *parser)
27bf414c
JM
7251{
7252 tree list = NULL_TREE;
7253 while (true)
7254 {
f2a71bbc
JM
7255 tree name, str;
7256 struct c_expr expr;
27bf414c
JM
7257 if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
7258 {
7259 c_parser_consume_token (parser);
7260 if (c_parser_next_token_is (parser, CPP_NAME))
7261 {
7262 tree id = c_parser_peek_token (parser)->value;
7263 c_parser_consume_token (parser);
7264 name = build_string (IDENTIFIER_LENGTH (id),
7265 IDENTIFIER_POINTER (id));
7266 }
7267 else
7268 {
7269 c_parser_error (parser, "expected identifier");
7270 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL);
7271 return NULL_TREE;
7272 }
7273 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
7274 "expected %<]%>");
7275 }
7276 else
7277 name = NULL_TREE;
7278 str = c_parser_asm_string_literal (parser);
7279 if (str == NULL_TREE)
7280 return NULL_TREE;
32129a17
DM
7281 matching_parens parens;
7282 if (!parens.require_open (parser))
471c5330 7283 return NULL_TREE;
f2a71bbc 7284 expr = c_parser_expression (parser);
ebfbbdc5 7285 mark_exp_read (expr.value);
32129a17 7286 if (!parens.require_close (parser))
27bf414c
JM
7287 {
7288 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
7289 return NULL_TREE;
7290 }
7291 list = chainon (list, build_tree_list (build_tree_list (name, str),
f2a71bbc 7292 expr.value));
27bf414c
JM
7293 if (c_parser_next_token_is (parser, CPP_COMMA))
7294 c_parser_consume_token (parser);
7295 else
7296 break;
7297 }
7298 return list;
7299}
7300
7301/* Parse asm clobbers, a GNU extension.
7302
7303 asm-clobbers:
7304 asm-string-literal
7305 asm-clobbers , asm-string-literal
7306*/
7307
7308static tree
7309c_parser_asm_clobbers (c_parser *parser)
7310{
7311 tree list = NULL_TREE;
7312 while (true)
7313 {
7314 tree str = c_parser_asm_string_literal (parser);
7315 if (str)
7316 list = tree_cons (NULL_TREE, str, list);
7317 else
7318 return NULL_TREE;
7319 if (c_parser_next_token_is (parser, CPP_COMMA))
7320 c_parser_consume_token (parser);
7321 else
7322 break;
7323 }
7324 return list;
7325}
7326
1c384bf1 7327/* Parse asm goto labels, a GNU extension.
b8698a0f 7328
1c384bf1
RH
7329 asm-goto-operands:
7330 identifier
7331 asm-goto-operands , identifier
7332*/
7333
7334static tree
7335c_parser_asm_goto_operands (c_parser *parser)
7336{
7337 tree list = NULL_TREE;
7338 while (true)
7339 {
7340 tree name, label;
7341
7342 if (c_parser_next_token_is (parser, CPP_NAME))
7343 {
7344 c_token *tok = c_parser_peek_token (parser);
7345 name = tok->value;
7346 label = lookup_label_for_goto (tok->location, name);
7347 c_parser_consume_token (parser);
7348 TREE_USED (label) = 1;
7349 }
7350 else
7351 {
7352 c_parser_error (parser, "expected identifier");
7353 return NULL_TREE;
7354 }
7355
7356 name = build_string (IDENTIFIER_LENGTH (name),
7357 IDENTIFIER_POINTER (name));
7358 list = tree_cons (name, label, list);
7359 if (c_parser_next_token_is (parser, CPP_COMMA))
7360 c_parser_consume_token (parser);
7361 else
7362 return nreverse (list);
7363 }
7364}
7365
471c5330
JM
7366/* Parse a possibly concatenated sequence of string literals.
7367 TRANSLATE says whether to translate them to the execution character
7368 set; WIDE_OK says whether any kind of prefixed string literal is
7369 permitted in this context. This code is based on that in
7370 lex_string. */
7371
7372struct c_expr
7373c_parser_string_literal (c_parser *parser, bool translate, bool wide_ok)
7374{
7375 struct c_expr ret;
7376 size_t count;
7377 struct obstack str_ob;
7378 struct obstack loc_ob;
7379 cpp_string str, istr, *strs;
7380 c_token *tok;
7381 location_t loc, last_tok_loc;
7382 enum cpp_ttype type;
7383 tree value, string_tree;
7384
7385 tok = c_parser_peek_token (parser);
7386 loc = tok->location;
7387 last_tok_loc = linemap_resolve_location (line_table, loc,
7388 LRK_MACRO_DEFINITION_LOCATION,
7389 NULL);
7390 type = tok->type;
7391 switch (type)
7392 {
7393 case CPP_STRING:
7394 case CPP_WSTRING:
7395 case CPP_STRING16:
7396 case CPP_STRING32:
7397 case CPP_UTF8STRING:
7398 string_tree = tok->value;
7399 break;
7400
7401 default:
7402 c_parser_error (parser, "expected string literal");
7403 ret.set_error ();
7404 ret.value = NULL_TREE;
7405 ret.original_code = ERROR_MARK;
7406 ret.original_type = NULL_TREE;
7407 return ret;
7408 }
7409
7410 /* Try to avoid the overhead of creating and destroying an obstack
7411 for the common case of just one string. */
7412 switch (c_parser_peek_2nd_token (parser)->type)
7413 {
7414 default:
7415 c_parser_consume_token (parser);
7416 str.text = (const unsigned char *) TREE_STRING_POINTER (string_tree);
7417 str.len = TREE_STRING_LENGTH (string_tree);
7418 count = 1;
7419 strs = &str;
7420 break;
7421
7422 case CPP_STRING:
7423 case CPP_WSTRING:
7424 case CPP_STRING16:
7425 case CPP_STRING32:
7426 case CPP_UTF8STRING:
7427 gcc_obstack_init (&str_ob);
7428 gcc_obstack_init (&loc_ob);
7429 count = 0;
7430 do
7431 {
7432 c_parser_consume_token (parser);
7433 count++;
7434 str.text = (const unsigned char *) TREE_STRING_POINTER (string_tree);
7435 str.len = TREE_STRING_LENGTH (string_tree);
7436 if (type != tok->type)
7437 {
7438 if (type == CPP_STRING)
7439 type = tok->type;
7440 else if (tok->type != CPP_STRING)
7441 error ("unsupported non-standard concatenation "
7442 "of string literals");
7443 }
7444 obstack_grow (&str_ob, &str, sizeof (cpp_string));
7445 obstack_grow (&loc_ob, &last_tok_loc, sizeof (location_t));
7446 tok = c_parser_peek_token (parser);
7447 string_tree = tok->value;
7448 last_tok_loc
7449 = linemap_resolve_location (line_table, tok->location,
7450 LRK_MACRO_DEFINITION_LOCATION, NULL);
7451 }
7452 while (tok->type == CPP_STRING
7453 || tok->type == CPP_WSTRING
7454 || tok->type == CPP_STRING16
7455 || tok->type == CPP_STRING32
7456 || tok->type == CPP_UTF8STRING);
7457 strs = (cpp_string *) obstack_finish (&str_ob);
7458 }
7459
7460 if (count > 1 && !in_system_header_at (input_location))
7461 warning (OPT_Wtraditional,
7462 "traditional C rejects string constant concatenation");
7463
7464 if ((type == CPP_STRING || wide_ok)
7465 && ((translate
7466 ? cpp_interpret_string : cpp_interpret_string_notranslate)
7467 (parse_in, strs, count, &istr, type)))
7468 {
7469 value = build_string (istr.len, (const char *) istr.text);
7470 free (CONST_CAST (unsigned char *, istr.text));
7471 if (count > 1)
7472 {
7473 location_t *locs = (location_t *) obstack_finish (&loc_ob);
7474 gcc_assert (g_string_concat_db);
7475 g_string_concat_db->record_string_concatenation (count, locs);
7476 }
7477 }
7478 else
7479 {
7480 if (type != CPP_STRING && !wide_ok)
7481 {
7482 error_at (loc, "a wide string is invalid in this context");
7483 type = CPP_STRING;
7484 }
7485 /* Callers cannot generally handle error_mark_node in this
7486 context, so return the empty string instead. An error has
7487 been issued, either above or from cpp_interpret_string. */
7488 switch (type)
7489 {
7490 default:
7491 case CPP_STRING:
7492 case CPP_UTF8STRING:
7493 value = build_string (1, "");
7494 break;
7495 case CPP_STRING16:
7496 value = build_string (TYPE_PRECISION (char16_type_node)
7497 / TYPE_PRECISION (char_type_node),
7498 "\0"); /* char16_t is 16 bits */
7499 break;
7500 case CPP_STRING32:
7501 value = build_string (TYPE_PRECISION (char32_type_node)
7502 / TYPE_PRECISION (char_type_node),
7503 "\0\0\0"); /* char32_t is 32 bits */
7504 break;
7505 case CPP_WSTRING:
7506 value = build_string (TYPE_PRECISION (wchar_type_node)
7507 / TYPE_PRECISION (char_type_node),
7508 "\0\0\0"); /* widest supported wchar_t
7509 is 32 bits */
7510 break;
7511 }
7512 }
7513
7514 switch (type)
7515 {
7516 default:
7517 case CPP_STRING:
7518 case CPP_UTF8STRING:
7519 TREE_TYPE (value) = char_array_type_node;
7520 break;
7521 case CPP_STRING16:
7522 TREE_TYPE (value) = char16_array_type_node;
7523 break;
7524 case CPP_STRING32:
7525 TREE_TYPE (value) = char32_array_type_node;
7526 break;
7527 case CPP_WSTRING:
7528 TREE_TYPE (value) = wchar_array_type_node;
7529 }
7530 value = fix_string_type (value);
7531
7532 if (count > 1)
7533 {
7534 obstack_free (&str_ob, 0);
7535 obstack_free (&loc_ob, 0);
7536 }
7537
7538 ret.value = value;
7539 ret.original_code = STRING_CST;
7540 ret.original_type = NULL_TREE;
7541 set_c_expr_source_range (&ret, get_range_from_loc (line_table, loc));
7542 return ret;
7543}
7544
27bf414c 7545/* Parse an expression other than a compound expression; that is, an
31dc71a8
MP
7546 assignment expression (C90 6.3.16, C99 6.5.16, C11 6.5.16). If
7547 AFTER is not NULL then it is an Objective-C message expression which
7548 is the primary-expression starting the expression as an initializer.
27bf414c
JM
7549
7550 assignment-expression:
7551 conditional-expression
7552 unary-expression assignment-operator assignment-expression
7553
7554 assignment-operator: one of
7555 = *= /= %= += -= <<= >>= &= ^= |=
7556
7557 In GNU C we accept any conditional expression on the LHS and
7558 diagnose the invalid lvalue rather than producing a syntax
7559 error. */
7560
7561static struct c_expr
acf0174b
JJ
7562c_parser_expr_no_commas (c_parser *parser, struct c_expr *after,
7563 tree omp_atomic_lhs)
27bf414c
JM
7564{
7565 struct c_expr lhs, rhs, ret;
7566 enum tree_code code;
c2255bc4 7567 location_t op_location, exp_location;
27bf414c 7568 gcc_assert (!after || c_dialect_objc ());
acf0174b 7569 lhs = c_parser_conditional_expression (parser, after, omp_atomic_lhs);
c9f9eb5d 7570 op_location = c_parser_peek_token (parser)->location;
27bf414c
JM
7571 switch (c_parser_peek_token (parser)->type)
7572 {
7573 case CPP_EQ:
7574 code = NOP_EXPR;
7575 break;
7576 case CPP_MULT_EQ:
7577 code = MULT_EXPR;
7578 break;
7579 case CPP_DIV_EQ:
7580 code = TRUNC_DIV_EXPR;
7581 break;
7582 case CPP_MOD_EQ:
7583 code = TRUNC_MOD_EXPR;
7584 break;
7585 case CPP_PLUS_EQ:
7586 code = PLUS_EXPR;
7587 break;
7588 case CPP_MINUS_EQ:
7589 code = MINUS_EXPR;
7590 break;
7591 case CPP_LSHIFT_EQ:
7592 code = LSHIFT_EXPR;
7593 break;
7594 case CPP_RSHIFT_EQ:
7595 code = RSHIFT_EXPR;
7596 break;
7597 case CPP_AND_EQ:
7598 code = BIT_AND_EXPR;
7599 break;
7600 case CPP_XOR_EQ:
7601 code = BIT_XOR_EXPR;
7602 break;
7603 case CPP_OR_EQ:
7604 code = BIT_IOR_EXPR;
7605 break;
7606 default:
7607 return lhs;
7608 }
7609 c_parser_consume_token (parser);
c2255bc4 7610 exp_location = c_parser_peek_token (parser)->location;
27bf414c 7611 rhs = c_parser_expr_no_commas (parser, NULL);
267bac10 7612 rhs = convert_lvalue_to_rvalue (exp_location, rhs, true, true);
36536d79 7613
25c22937
BI
7614 ret.value = build_modify_expr (op_location, lhs.value, lhs.original_type,
7615 code, exp_location, rhs.value,
7616 rhs.original_type);
ebedc9a3 7617 set_c_expr_source_range (&ret, lhs.get_start (), rhs.get_finish ());
27bf414c
JM
7618 if (code == NOP_EXPR)
7619 ret.original_code = MODIFY_EXPR;
7620 else
7621 {
7622 TREE_NO_WARNING (ret.value) = 1;
7623 ret.original_code = ERROR_MARK;
7624 }
6866c6e8 7625 ret.original_type = NULL;
27bf414c
JM
7626 return ret;
7627}
7628
31dc71a8
MP
7629/* Parse a conditional expression (C90 6.3.15, C99 6.5.15, C11 6.5.15). If
7630 AFTER is not NULL then it is an Objective-C message expression which is
27bf414c
JM
7631 the primary-expression starting the expression as an initializer.
7632
7633 conditional-expression:
7634 logical-OR-expression
7635 logical-OR-expression ? expression : conditional-expression
7636
7637 GNU extensions:
7638
7639 conditional-expression:
7640 logical-OR-expression ? : conditional-expression
7641*/
7642
7643static struct c_expr
acf0174b
JJ
7644c_parser_conditional_expression (c_parser *parser, struct c_expr *after,
7645 tree omp_atomic_lhs)
27bf414c
JM
7646{
7647 struct c_expr cond, exp1, exp2, ret;
a32c8316 7648 location_t start, cond_loc, colon_loc;
ba47d38d 7649
27bf414c 7650 gcc_assert (!after || c_dialect_objc ());
ba47d38d 7651
acf0174b 7652 cond = c_parser_binary_expression (parser, after, omp_atomic_lhs);
ba47d38d 7653
27bf414c
JM
7654 if (c_parser_next_token_is_not (parser, CPP_QUERY))
7655 return cond;
ebedc9a3
DM
7656 if (cond.value != error_mark_node)
7657 start = cond.get_start ();
7658 else
7659 start = UNKNOWN_LOCATION;
c2255bc4 7660 cond_loc = c_parser_peek_token (parser)->location;
267bac10 7661 cond = convert_lvalue_to_rvalue (cond_loc, cond, true, true);
27bf414c
JM
7662 c_parser_consume_token (parser);
7663 if (c_parser_next_token_is (parser, CPP_COLON))
7664 {
8ce94e44 7665 tree eptype = NULL_TREE;
d166d4c3 7666
a32c8316 7667 location_t middle_loc = c_parser_peek_token (parser)->location;
54dcdb88 7668 pedwarn (middle_loc, OPT_Wpedantic,
a9c697b8 7669 "ISO C forbids omitting the middle term of a %<?:%> expression");
8ce94e44
JM
7670 if (TREE_CODE (cond.value) == EXCESS_PRECISION_EXPR)
7671 {
7672 eptype = TREE_TYPE (cond.value);
7673 cond.value = TREE_OPERAND (cond.value, 0);
7674 }
54dcdb88
BE
7675 tree e = cond.value;
7676 while (TREE_CODE (e) == COMPOUND_EXPR)
7677 e = TREE_OPERAND (e, 1);
7678 warn_for_omitted_condop (middle_loc, e);
27bf414c 7679 /* Make sure first operand is calculated only once. */
b2fa0a8b 7680 exp1.value = save_expr (default_conversion (cond.value));
8ce94e44
JM
7681 if (eptype)
7682 exp1.value = build1 (EXCESS_PRECISION_EXPR, eptype, exp1.value);
6866c6e8 7683 exp1.original_type = NULL;
a32c8316 7684 exp1.src_range = cond.src_range;
ba47d38d 7685 cond.value = c_objc_common_truthvalue_conversion (cond_loc, exp1.value);
7d882b83 7686 c_inhibit_evaluation_warnings += cond.value == truthvalue_true_node;
27bf414c
JM
7687 }
7688 else
7689 {
7690 cond.value
85498824 7691 = c_objc_common_truthvalue_conversion
ba47d38d 7692 (cond_loc, default_conversion (cond.value));
7d882b83 7693 c_inhibit_evaluation_warnings += cond.value == truthvalue_false_node;
46bdb9cf 7694 exp1 = c_parser_expression_conv (parser);
ebfbbdc5 7695 mark_exp_read (exp1.value);
7d882b83
ILT
7696 c_inhibit_evaluation_warnings +=
7697 ((cond.value == truthvalue_true_node)
7698 - (cond.value == truthvalue_false_node));
27bf414c 7699 }
744aa42f
ILT
7700
7701 colon_loc = c_parser_peek_token (parser)->location;
27bf414c
JM
7702 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
7703 {
7d882b83 7704 c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node;
913884f7 7705 ret.set_error ();
27bf414c 7706 ret.original_code = ERROR_MARK;
6866c6e8 7707 ret.original_type = NULL;
27bf414c
JM
7708 return ret;
7709 }
c2255bc4
AH
7710 {
7711 location_t exp2_loc = c_parser_peek_token (parser)->location;
acf0174b 7712 exp2 = c_parser_conditional_expression (parser, NULL, NULL_TREE);
267bac10 7713 exp2 = convert_lvalue_to_rvalue (exp2_loc, exp2, true, true);
c2255bc4 7714 }
7d882b83 7715 c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node;
a32c8316
MP
7716 location_t loc1 = make_location (exp1.get_start (), exp1.src_range);
7717 location_t loc2 = make_location (exp2.get_start (), exp2.src_range);
744aa42f 7718 ret.value = build_conditional_expr (colon_loc, cond.value,
928c19bb 7719 cond.original_code == C_MAYBE_CONST_EXPR,
a32c8316
MP
7720 exp1.value, exp1.original_type, loc1,
7721 exp2.value, exp2.original_type, loc2);
27bf414c 7722 ret.original_code = ERROR_MARK;
6866c6e8
ILT
7723 if (exp1.value == error_mark_node || exp2.value == error_mark_node)
7724 ret.original_type = NULL;
7725 else
7726 {
7727 tree t1, t2;
7728
7729 /* If both sides are enum type, the default conversion will have
7730 made the type of the result be an integer type. We want to
7731 remember the enum types we started with. */
7732 t1 = exp1.original_type ? exp1.original_type : TREE_TYPE (exp1.value);
7733 t2 = exp2.original_type ? exp2.original_type : TREE_TYPE (exp2.value);
7734 ret.original_type = ((t1 != error_mark_node
7735 && t2 != error_mark_node
7736 && (TYPE_MAIN_VARIANT (t1)
7737 == TYPE_MAIN_VARIANT (t2)))
7738 ? t1
7739 : NULL);
7740 }
ebedc9a3 7741 set_c_expr_source_range (&ret, start, exp2.get_finish ());
27bf414c
JM
7742 return ret;
7743}
7744
7745/* Parse a binary expression; that is, a logical-OR-expression (C90
31dc71a8
MP
7746 6.3.5-6.3.14, C99 6.5.5-6.5.14, C11 6.5.5-6.5.14). If AFTER is not
7747 NULL then it is an Objective-C message expression which is the
7748 primary-expression starting the expression as an initializer.
acf0174b
JJ
7749
7750 OMP_ATOMIC_LHS is NULL, unless parsing OpenMP #pragma omp atomic,
7751 when it should be the unfolded lhs. In a valid OpenMP source,
7752 one of the operands of the toplevel binary expression must be equal
7753 to it. In that case, just return a build2 created binary operation
7754 rather than result of parser_build_binary_op.
27bf414c
JM
7755
7756 multiplicative-expression:
7757 cast-expression
7758 multiplicative-expression * cast-expression
7759 multiplicative-expression / cast-expression
7760 multiplicative-expression % cast-expression
7761
7762 additive-expression:
7763 multiplicative-expression
7764 additive-expression + multiplicative-expression
7765 additive-expression - multiplicative-expression
7766
7767 shift-expression:
7768 additive-expression
7769 shift-expression << additive-expression
7770 shift-expression >> additive-expression
7771
7772 relational-expression:
7773 shift-expression
7774 relational-expression < shift-expression
7775 relational-expression > shift-expression
7776 relational-expression <= shift-expression
7777 relational-expression >= shift-expression
7778
7779 equality-expression:
7780 relational-expression
7781 equality-expression == relational-expression
7782 equality-expression != relational-expression
7783
7784 AND-expression:
7785 equality-expression
7786 AND-expression & equality-expression
7787
7788 exclusive-OR-expression:
7789 AND-expression
7790 exclusive-OR-expression ^ AND-expression
7791
7792 inclusive-OR-expression:
7793 exclusive-OR-expression
7794 inclusive-OR-expression | exclusive-OR-expression
7795
7796 logical-AND-expression:
7797 inclusive-OR-expression
7798 logical-AND-expression && inclusive-OR-expression
7799
7800 logical-OR-expression:
7801 logical-AND-expression
7802 logical-OR-expression || logical-AND-expression
7803*/
7804
7805static struct c_expr
20906c66 7806c_parser_binary_expression (c_parser *parser, struct c_expr *after,
acf0174b 7807 tree omp_atomic_lhs)
27bf414c
JM
7808{
7809 /* A binary expression is parsed using operator-precedence parsing,
7810 with the operands being cast expressions. All the binary
7811 operators are left-associative. Thus a binary expression is of
7812 form:
7813
7814 E0 op1 E1 op2 E2 ...
7815
7816 which we represent on a stack. On the stack, the precedence
7817 levels are strictly increasing. When a new operator is
7818 encountered of higher precedence than that at the top of the
7819 stack, it is pushed; its LHS is the top expression, and its RHS
7820 is everything parsed until it is popped. When a new operator is
7821 encountered with precedence less than or equal to that at the top
7822 of the stack, triples E[i-1] op[i] E[i] are popped and replaced
7823 by the result of the operation until the operator at the top of
7824 the stack has lower precedence than the new operator or there is
7825 only one element on the stack; then the top expression is the LHS
7826 of the new operator. In the case of logical AND and OR
7d882b83
ILT
7827 expressions, we also need to adjust c_inhibit_evaluation_warnings
7828 as appropriate when the operators are pushed and popped. */
27bf414c 7829
27bf414c
JM
7830 struct {
7831 /* The expression at this stack level. */
7832 struct c_expr expr;
7833 /* The precedence of the operator on its left, PREC_NONE at the
7834 bottom of the stack. */
20906c66 7835 enum c_parser_prec prec;
27bf414c
JM
7836 /* The operation on its left. */
7837 enum tree_code op;
ca80e52b
EB
7838 /* The source location of this operation. */
7839 location_t loc;
40ffd95f
BE
7840 /* The sizeof argument if expr.original_code == SIZEOF_EXPR. */
7841 tree sizeof_arg;
27bf414c
JM
7842 } stack[NUM_PRECS];
7843 int sp;
ba47d38d 7844 /* Location of the binary operator. */
1f6d0c60 7845 location_t binary_loc = UNKNOWN_LOCATION; /* Quiet warning. */
27bf414c
JM
7846#define POP \
7847 do { \
7848 switch (stack[sp].op) \
7849 { \
7850 case TRUTH_ANDIF_EXPR: \
7d882b83
ILT
7851 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
7852 == truthvalue_false_node); \
27bf414c
JM
7853 break; \
7854 case TRUTH_ORIF_EXPR: \
7d882b83
ILT
7855 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
7856 == truthvalue_true_node); \
27bf414c 7857 break; \
40ffd95f
BE
7858 case TRUNC_DIV_EXPR: \
7859 if (stack[sp - 1].expr.original_code == SIZEOF_EXPR \
7860 && stack[sp].expr.original_code == SIZEOF_EXPR) \
7861 { \
7862 tree type0 = stack[sp - 1].sizeof_arg; \
7863 tree type1 = stack[sp].sizeof_arg; \
7864 tree first_arg = type0; \
7865 if (!TYPE_P (type0)) \
7866 type0 = TREE_TYPE (type0); \
7867 if (!TYPE_P (type1)) \
7868 type1 = TREE_TYPE (type1); \
7869 if (POINTER_TYPE_P (type0) \
7870 && comptypes (TREE_TYPE (type0), type1) \
7871 && !(TREE_CODE (first_arg) == PARM_DECL \
7872 && C_ARRAY_PARAMETER (first_arg) \
7873 && warn_sizeof_array_argument)) \
097f82ec
DM
7874 { \
7875 auto_diagnostic_group d; \
7876 if (warning_at (stack[sp].loc, OPT_Wsizeof_pointer_div, \
7877 "division %<sizeof (%T) / sizeof (%T)%> " \
7878 "does not compute the number of array " \
7879 "elements", \
7880 type0, type1)) \
7881 if (DECL_P (first_arg)) \
7882 inform (DECL_SOURCE_LOCATION (first_arg), \
7883 "first %<sizeof%> operand was declared here"); \
7884 } \
7885 } \
40ffd95f 7886 break; \
27bf414c
JM
7887 default: \
7888 break; \
7889 } \
f2a71bbc 7890 stack[sp - 1].expr \
267bac10
JM
7891 = convert_lvalue_to_rvalue (stack[sp - 1].loc, \
7892 stack[sp - 1].expr, true, true); \
f2a71bbc 7893 stack[sp].expr \
267bac10
JM
7894 = convert_lvalue_to_rvalue (stack[sp].loc, \
7895 stack[sp].expr, true, true); \
acf0174b
JJ
7896 if (__builtin_expect (omp_atomic_lhs != NULL_TREE, 0) && sp == 1 \
7897 && c_parser_peek_token (parser)->type == CPP_SEMICOLON \
7898 && ((1 << stack[sp].prec) \
fa01ffcc
JJ
7899 & ((1 << PREC_BITOR) | (1 << PREC_BITXOR) | (1 << PREC_BITAND) \
7900 | (1 << PREC_SHIFT) | (1 << PREC_ADD) | (1 << PREC_MULT))) \
acf0174b
JJ
7901 && stack[sp].op != TRUNC_MOD_EXPR \
7902 && stack[0].expr.value != error_mark_node \
7903 && stack[1].expr.value != error_mark_node \
7904 && (c_tree_equal (stack[0].expr.value, omp_atomic_lhs) \
7905 || c_tree_equal (stack[1].expr.value, omp_atomic_lhs))) \
7906 stack[0].expr.value \
7907 = build2 (stack[1].op, TREE_TYPE (stack[0].expr.value), \
7908 stack[0].expr.value, stack[1].expr.value); \
7909 else \
7910 stack[sp - 1].expr = parser_build_binary_op (stack[sp].loc, \
7911 stack[sp].op, \
7912 stack[sp - 1].expr, \
7913 stack[sp].expr); \
27bf414c
JM
7914 sp--; \
7915 } while (0)
7916 gcc_assert (!after || c_dialect_objc ());
ca80e52b 7917 stack[0].loc = c_parser_peek_token (parser)->location;
27bf414c 7918 stack[0].expr = c_parser_cast_expression (parser, after);
acf0174b 7919 stack[0].prec = PREC_NONE;
40ffd95f 7920 stack[0].sizeof_arg = c_last_sizeof_arg;
27bf414c
JM
7921 sp = 0;
7922 while (true)
7923 {
20906c66 7924 enum c_parser_prec oprec;
27bf414c 7925 enum tree_code ocode;
ebedc9a3 7926 source_range src_range;
27bf414c
JM
7927 if (parser->error)
7928 goto out;
7929 switch (c_parser_peek_token (parser)->type)
7930 {
7931 case CPP_MULT:
7932 oprec = PREC_MULT;
7933 ocode = MULT_EXPR;
7934 break;
7935 case CPP_DIV:
7936 oprec = PREC_MULT;
7937 ocode = TRUNC_DIV_EXPR;
7938 break;
7939 case CPP_MOD:
7940 oprec = PREC_MULT;
7941 ocode = TRUNC_MOD_EXPR;
7942 break;
7943 case CPP_PLUS:
7944 oprec = PREC_ADD;
7945 ocode = PLUS_EXPR;
7946 break;
7947 case CPP_MINUS:
7948 oprec = PREC_ADD;
7949 ocode = MINUS_EXPR;
7950 break;
7951 case CPP_LSHIFT:
7952 oprec = PREC_SHIFT;
7953 ocode = LSHIFT_EXPR;
7954 break;
7955 case CPP_RSHIFT:
7956 oprec = PREC_SHIFT;
7957 ocode = RSHIFT_EXPR;
7958 break;
7959 case CPP_LESS:
7960 oprec = PREC_REL;
7961 ocode = LT_EXPR;
7962 break;
7963 case CPP_GREATER:
7964 oprec = PREC_REL;
7965 ocode = GT_EXPR;
7966 break;
7967 case CPP_LESS_EQ:
7968 oprec = PREC_REL;
7969 ocode = LE_EXPR;
7970 break;
7971 case CPP_GREATER_EQ:
7972 oprec = PREC_REL;
7973 ocode = GE_EXPR;
7974 break;
7975 case CPP_EQ_EQ:
7976 oprec = PREC_EQ;
7977 ocode = EQ_EXPR;
7978 break;
7979 case CPP_NOT_EQ:
7980 oprec = PREC_EQ;
7981 ocode = NE_EXPR;
7982 break;
7983 case CPP_AND:
7984 oprec = PREC_BITAND;
7985 ocode = BIT_AND_EXPR;
7986 break;
7987 case CPP_XOR:
7988 oprec = PREC_BITXOR;
7989 ocode = BIT_XOR_EXPR;
7990 break;
7991 case CPP_OR:
7992 oprec = PREC_BITOR;
7993 ocode = BIT_IOR_EXPR;
7994 break;
7995 case CPP_AND_AND:
7996 oprec = PREC_LOGAND;
7997 ocode = TRUTH_ANDIF_EXPR;
7998 break;
7999 case CPP_OR_OR:
8000 oprec = PREC_LOGOR;
8001 ocode = TRUTH_ORIF_EXPR;
8002 break;
8003 default:
8004 /* Not a binary operator, so end of the binary
8005 expression. */
8006 goto out;
8007 }
ba47d38d 8008 binary_loc = c_parser_peek_token (parser)->location;
27bf414c 8009 while (oprec <= stack[sp].prec)
acf0174b 8010 POP;
20906c66 8011 c_parser_consume_token (parser);
27bf414c
JM
8012 switch (ocode)
8013 {
8014 case TRUTH_ANDIF_EXPR:
ebedc9a3 8015 src_range = stack[sp].expr.src_range;
f2a71bbc 8016 stack[sp].expr
267bac10
JM
8017 = convert_lvalue_to_rvalue (stack[sp].loc,
8018 stack[sp].expr, true, true);
85498824 8019 stack[sp].expr.value = c_objc_common_truthvalue_conversion
ca80e52b 8020 (stack[sp].loc, default_conversion (stack[sp].expr.value));
7d882b83
ILT
8021 c_inhibit_evaluation_warnings += (stack[sp].expr.value
8022 == truthvalue_false_node);
ebedc9a3 8023 set_c_expr_source_range (&stack[sp].expr, src_range);
27bf414c
JM
8024 break;
8025 case TRUTH_ORIF_EXPR:
ebedc9a3 8026 src_range = stack[sp].expr.src_range;
f2a71bbc 8027 stack[sp].expr
267bac10
JM
8028 = convert_lvalue_to_rvalue (stack[sp].loc,
8029 stack[sp].expr, true, true);
85498824 8030 stack[sp].expr.value = c_objc_common_truthvalue_conversion
ca80e52b 8031 (stack[sp].loc, default_conversion (stack[sp].expr.value));
7d882b83
ILT
8032 c_inhibit_evaluation_warnings += (stack[sp].expr.value
8033 == truthvalue_true_node);
ebedc9a3 8034 set_c_expr_source_range (&stack[sp].expr, src_range);
27bf414c
JM
8035 break;
8036 default:
8037 break;
8038 }
8039 sp++;
ca80e52b 8040 stack[sp].loc = binary_loc;
27bf414c
JM
8041 stack[sp].expr = c_parser_cast_expression (parser, NULL);
8042 stack[sp].prec = oprec;
8043 stack[sp].op = ocode;
40ffd95f 8044 stack[sp].sizeof_arg = c_last_sizeof_arg;
27bf414c
JM
8045 }
8046 out:
8047 while (sp > 0)
8048 POP;
8049 return stack[0].expr;
8050#undef POP
8051}
8052
31dc71a8
MP
8053/* Parse a cast expression (C90 6.3.4, C99 6.5.4, C11 6.5.4). If AFTER
8054 is not NULL then it is an Objective-C message expression which is the
27bf414c
JM
8055 primary-expression starting the expression as an initializer.
8056
8057 cast-expression:
8058 unary-expression
8059 ( type-name ) unary-expression
8060*/
8061
8062static struct c_expr
8063c_parser_cast_expression (c_parser *parser, struct c_expr *after)
8064{
c2255bc4 8065 location_t cast_loc = c_parser_peek_token (parser)->location;
27bf414c
JM
8066 gcc_assert (!after || c_dialect_objc ());
8067 if (after)
c2255bc4
AH
8068 return c_parser_postfix_expression_after_primary (parser,
8069 cast_loc, *after);
27bf414c
JM
8070 /* If the expression begins with a parenthesized type name, it may
8071 be either a cast or a compound literal; we need to see whether
8072 the next character is '{' to tell the difference. If not, it is
29ce73cb
PB
8073 an unary expression. Full detection of unknown typenames here
8074 would require a 3-token lookahead. */
27bf414c
JM
8075 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
8076 && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
8077 {
8078 struct c_type_name *type_name;
8079 struct c_expr ret;
f2a71bbc 8080 struct c_expr expr;
32129a17
DM
8081 matching_parens parens;
8082 parens.consume_open (parser);
4b2b493f 8083 type_name = c_parser_type_name (parser, true);
32129a17 8084 parens.skip_until_found_close (parser);
27bf414c
JM
8085 if (type_name == NULL)
8086 {
913884f7 8087 ret.set_error ();
27bf414c 8088 ret.original_code = ERROR_MARK;
6866c6e8 8089 ret.original_type = NULL;
27bf414c
JM
8090 return ret;
8091 }
33c9159e
AH
8092
8093 /* Save casted types in the function's used types hash table. */
8d8d1a28 8094 used_types_insert (type_name->specs->type);
33c9159e 8095
27bf414c 8096 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
24b97832 8097 return c_parser_postfix_expression_after_paren_type (parser, type_name,
c2255bc4 8098 cast_loc);
4b2b493f
JM
8099 if (type_name->specs->alignas_p)
8100 error_at (type_name->specs->locations[cdw_alignas],
8101 "alignment specified for type name in cast");
c2255bc4
AH
8102 {
8103 location_t expr_loc = c_parser_peek_token (parser)->location;
8104 expr = c_parser_cast_expression (parser, NULL);
267bac10 8105 expr = convert_lvalue_to_rvalue (expr_loc, expr, true, true);
c2255bc4
AH
8106 }
8107 ret.value = c_cast_expr (cast_loc, type_name, expr.value);
ebedc9a3
DM
8108 if (ret.value && expr.value)
8109 set_c_expr_source_range (&ret, cast_loc, expr.get_finish ());
27bf414c 8110 ret.original_code = ERROR_MARK;
6866c6e8 8111 ret.original_type = NULL;
27bf414c
JM
8112 return ret;
8113 }
8114 else
8115 return c_parser_unary_expression (parser);
8116}
8117
31dc71a8 8118/* Parse an unary expression (C90 6.3.3, C99 6.5.3, C11 6.5.3).
27bf414c
JM
8119
8120 unary-expression:
8121 postfix-expression
8122 ++ unary-expression
8123 -- unary-expression
8124 unary-operator cast-expression
8125 sizeof unary-expression
8126 sizeof ( type-name )
8127
8128 unary-operator: one of
8129 & * + - ~ !
8130
8131 GNU extensions:
8132
8133 unary-expression:
8134 __alignof__ unary-expression
8135 __alignof__ ( type-name )
8136 && identifier
8137
48b0b196 8138 (C11 permits _Alignof with type names only.)
d19fa6b5 8139
27bf414c
JM
8140 unary-operator: one of
8141 __extension__ __real__ __imag__
8142
0a35513e
AH
8143 Transactional Memory:
8144
8145 unary-expression:
8146 transaction-expression
8147
27bf414c
JM
8148 In addition, the GNU syntax treats ++ and -- as unary operators, so
8149 they may be applied to cast expressions with errors for non-lvalues
8150 given later. */
8151
8152static struct c_expr
8153c_parser_unary_expression (c_parser *parser)
8154{
8155 int ext;
46bdb9cf 8156 struct c_expr ret, op;
c2255bc4
AH
8157 location_t op_loc = c_parser_peek_token (parser)->location;
8158 location_t exp_loc;
ebedc9a3 8159 location_t finish;
6866c6e8
ILT
8160 ret.original_code = ERROR_MARK;
8161 ret.original_type = NULL;
27bf414c
JM
8162 switch (c_parser_peek_token (parser)->type)
8163 {
8164 case CPP_PLUS_PLUS:
8165 c_parser_consume_token (parser);
c2255bc4 8166 exp_loc = c_parser_peek_token (parser)->location;
46bdb9cf 8167 op = c_parser_cast_expression (parser, NULL);
36536d79 8168
5e9d6aa4
JK
8169 op = default_function_array_read_conversion (exp_loc, op);
8170 return parser_build_unary_op (op_loc, PREINCREMENT_EXPR, op);
27bf414c
JM
8171 case CPP_MINUS_MINUS:
8172 c_parser_consume_token (parser);
c2255bc4 8173 exp_loc = c_parser_peek_token (parser)->location;
46bdb9cf 8174 op = c_parser_cast_expression (parser, NULL);
36536d79 8175
5e9d6aa4
JK
8176 op = default_function_array_read_conversion (exp_loc, op);
8177 return parser_build_unary_op (op_loc, PREDECREMENT_EXPR, op);
27bf414c
JM
8178 case CPP_AND:
8179 c_parser_consume_token (parser);
ebfbbdc5
JJ
8180 op = c_parser_cast_expression (parser, NULL);
8181 mark_exp_read (op.value);
8182 return parser_build_unary_op (op_loc, ADDR_EXPR, op);
27bf414c 8183 case CPP_MULT:
7443cf13
DM
8184 {
8185 c_parser_consume_token (parser);
8186 exp_loc = c_parser_peek_token (parser)->location;
8187 op = c_parser_cast_expression (parser, NULL);
8188 finish = op.get_finish ();
8189 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8190 location_t combined_loc = make_location (op_loc, op_loc, finish);
8191 ret.value = build_indirect_ref (combined_loc, op.value, RO_UNARY_STAR);
8192 ret.src_range.m_start = op_loc;
8193 ret.src_range.m_finish = finish;
8194 return ret;
8195 }
27bf414c 8196 case CPP_PLUS:
8400e75e 8197 if (!c_dialect_objc () && !in_system_header_at (input_location))
c2255bc4 8198 warning_at (op_loc,
3ba09659
AH
8199 OPT_Wtraditional,
8200 "traditional C rejects the unary plus operator");
c7412148 8201 c_parser_consume_token (parser);
c2255bc4 8202 exp_loc = c_parser_peek_token (parser)->location;
46bdb9cf 8203 op = c_parser_cast_expression (parser, NULL);
267bac10 8204 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
c2255bc4 8205 return parser_build_unary_op (op_loc, CONVERT_EXPR, op);
27bf414c
JM
8206 case CPP_MINUS:
8207 c_parser_consume_token (parser);
c2255bc4 8208 exp_loc = c_parser_peek_token (parser)->location;
46bdb9cf 8209 op = c_parser_cast_expression (parser, NULL);
267bac10 8210 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
c2255bc4 8211 return parser_build_unary_op (op_loc, NEGATE_EXPR, op);
27bf414c
JM
8212 case CPP_COMPL:
8213 c_parser_consume_token (parser);
c2255bc4 8214 exp_loc = c_parser_peek_token (parser)->location;
46bdb9cf 8215 op = c_parser_cast_expression (parser, NULL);
267bac10 8216 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
c2255bc4 8217 return parser_build_unary_op (op_loc, BIT_NOT_EXPR, op);
27bf414c
JM
8218 case CPP_NOT:
8219 c_parser_consume_token (parser);
c2255bc4 8220 exp_loc = c_parser_peek_token (parser)->location;
46bdb9cf 8221 op = c_parser_cast_expression (parser, NULL);
267bac10 8222 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
c2255bc4 8223 return parser_build_unary_op (op_loc, TRUTH_NOT_EXPR, op);
27bf414c
JM
8224 case CPP_AND_AND:
8225 /* Refer to the address of a label as a pointer. */
8226 c_parser_consume_token (parser);
8227 if (c_parser_next_token_is (parser, CPP_NAME))
8228 {
8229 ret.value = finish_label_address_expr
c2255bc4 8230 (c_parser_peek_token (parser)->value, op_loc);
bef08b71
DM
8231 set_c_expr_source_range (&ret, op_loc,
8232 c_parser_peek_token (parser)->get_finish ());
27bf414c 8233 c_parser_consume_token (parser);
27bf414c
JM
8234 }
8235 else
8236 {
8237 c_parser_error (parser, "expected identifier");
f7b6353a 8238 ret.set_error ();
27bf414c 8239 }
f7b6353a 8240 return ret;
27bf414c
JM
8241 case CPP_KEYWORD:
8242 switch (c_parser_peek_token (parser)->keyword)
8243 {
8244 case RID_SIZEOF:
8245 return c_parser_sizeof_expression (parser);
8246 case RID_ALIGNOF:
8247 return c_parser_alignof_expression (parser);
98f08eb8
MS
8248 case RID_BUILTIN_HAS_ATTRIBUTE:
8249 return c_parser_has_attribute_expression (parser);
27bf414c
JM
8250 case RID_EXTENSION:
8251 c_parser_consume_token (parser);
8252 ext = disable_extension_diagnostics ();
8253 ret = c_parser_cast_expression (parser, NULL);
8254 restore_extension_diagnostics (ext);
8255 return ret;
8256 case RID_REALPART:
8257 c_parser_consume_token (parser);
c2255bc4 8258 exp_loc = c_parser_peek_token (parser)->location;
46bdb9cf 8259 op = c_parser_cast_expression (parser, NULL);
c2255bc4
AH
8260 op = default_function_array_conversion (exp_loc, op);
8261 return parser_build_unary_op (op_loc, REALPART_EXPR, op);
27bf414c
JM
8262 case RID_IMAGPART:
8263 c_parser_consume_token (parser);
c2255bc4 8264 exp_loc = c_parser_peek_token (parser)->location;
46bdb9cf 8265 op = c_parser_cast_expression (parser, NULL);
c2255bc4
AH
8266 op = default_function_array_conversion (exp_loc, op);
8267 return parser_build_unary_op (op_loc, IMAGPART_EXPR, op);
0a35513e
AH
8268 case RID_TRANSACTION_ATOMIC:
8269 case RID_TRANSACTION_RELAXED:
8270 return c_parser_transaction_expression (parser,
8271 c_parser_peek_token (parser)->keyword);
27bf414c
JM
8272 default:
8273 return c_parser_postfix_expression (parser);
8274 }
8275 default:
8276 return c_parser_postfix_expression (parser);
8277 }
8278}
8279
8280/* Parse a sizeof expression. */
8281
8282static struct c_expr
8283c_parser_sizeof_expression (c_parser *parser)
8284{
8285 struct c_expr expr;
ebedc9a3 8286 struct c_expr result;
c7412148 8287 location_t expr_loc;
27bf414c 8288 gcc_assert (c_parser_next_token_is_keyword (parser, RID_SIZEOF));
ebedc9a3
DM
8289
8290 location_t start;
8291 location_t finish = UNKNOWN_LOCATION;
8292
8293 start = c_parser_peek_token (parser)->location;
8294
27bf414c 8295 c_parser_consume_token (parser);
7d882b83 8296 c_inhibit_evaluation_warnings++;
27bf414c
JM
8297 in_sizeof++;
8298 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
8299 && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
8300 {
8301 /* Either sizeof ( type-name ) or sizeof unary-expression
8302 starting with a compound literal. */
8303 struct c_type_name *type_name;
32129a17
DM
8304 matching_parens parens;
8305 parens.consume_open (parser);
c7412148 8306 expr_loc = c_parser_peek_token (parser)->location;
4b2b493f 8307 type_name = c_parser_type_name (parser, true);
32129a17 8308 parens.skip_until_found_close (parser);
ebedc9a3 8309 finish = parser->tokens_buf[0].location;
27bf414c
JM
8310 if (type_name == NULL)
8311 {
8312 struct c_expr ret;
7d882b83 8313 c_inhibit_evaluation_warnings--;
27bf414c 8314 in_sizeof--;
913884f7 8315 ret.set_error ();
27bf414c 8316 ret.original_code = ERROR_MARK;
6866c6e8 8317 ret.original_type = NULL;
27bf414c
JM
8318 return ret;
8319 }
8320 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
8321 {
4bd2511b
JL
8322 expr = c_parser_postfix_expression_after_paren_type (parser,
8323 type_name,
8324 expr_loc);
ebedc9a3 8325 finish = expr.get_finish ();
4bd2511b 8326 goto sizeof_expr;
27bf414c 8327 }
4bd2511b 8328 /* sizeof ( type-name ). */
4b2b493f
JM
8329 if (type_name->specs->alignas_p)
8330 error_at (type_name->specs->locations[cdw_alignas],
8331 "alignment specified for type name in %<sizeof%>");
4bd2511b
JL
8332 c_inhibit_evaluation_warnings--;
8333 in_sizeof--;
ebedc9a3 8334 result = c_expr_sizeof_type (expr_loc, type_name);
27bf414c
JM
8335 }
8336 else
8337 {
c7412148 8338 expr_loc = c_parser_peek_token (parser)->location;
27bf414c 8339 expr = c_parser_unary_expression (parser);
ebedc9a3 8340 finish = expr.get_finish ();
4bd2511b
JL
8341 sizeof_expr:
8342 c_inhibit_evaluation_warnings--;
8343 in_sizeof--;
8344 mark_exp_read (expr.value);
8345 if (TREE_CODE (expr.value) == COMPONENT_REF
8346 && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
8347 error_at (expr_loc, "%<sizeof%> applied to a bit-field");
ebedc9a3 8348 result = c_expr_sizeof_expr (expr_loc, expr);
27bf414c 8349 }
a28351e7
JJ
8350 if (finish == UNKNOWN_LOCATION)
8351 finish = start;
8352 set_c_expr_source_range (&result, start, finish);
ebedc9a3 8353 return result;
27bf414c
JM
8354}
8355
8356/* Parse an alignof expression. */
8357
8358static struct c_expr
8359c_parser_alignof_expression (c_parser *parser)
8360{
8361 struct c_expr expr;
a1b93f8d
DM
8362 location_t start_loc = c_parser_peek_token (parser)->location;
8363 location_t end_loc;
d19fa6b5 8364 tree alignof_spelling = c_parser_peek_token (parser)->value;
27bf414c 8365 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ALIGNOF));
296674db
JM
8366 bool is_c11_alignof = strcmp (IDENTIFIER_POINTER (alignof_spelling),
8367 "_Alignof") == 0;
d19fa6b5 8368 /* A diagnostic is not required for the use of this identifier in
48b0b196 8369 the implementation namespace; only diagnose it for the C11
d19fa6b5 8370 spelling because of existing code using the other spellings. */
35aff4fb 8371 if (is_c11_alignof)
d19fa6b5
JM
8372 {
8373 if (flag_isoc99)
a1b93f8d 8374 pedwarn_c99 (start_loc, OPT_Wpedantic, "ISO C99 does not support %qE",
35aff4fb 8375 alignof_spelling);
d19fa6b5 8376 else
a1b93f8d 8377 pedwarn_c99 (start_loc, OPT_Wpedantic, "ISO C90 does not support %qE",
35aff4fb 8378 alignof_spelling);
d19fa6b5 8379 }
27bf414c 8380 c_parser_consume_token (parser);
7d882b83 8381 c_inhibit_evaluation_warnings++;
27bf414c
JM
8382 in_alignof++;
8383 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
8384 && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
8385 {
8386 /* Either __alignof__ ( type-name ) or __alignof__
8387 unary-expression starting with a compound literal. */
24b97832 8388 location_t loc;
27bf414c
JM
8389 struct c_type_name *type_name;
8390 struct c_expr ret;
32129a17
DM
8391 matching_parens parens;
8392 parens.consume_open (parser);
24b97832 8393 loc = c_parser_peek_token (parser)->location;
4b2b493f 8394 type_name = c_parser_type_name (parser, true);
a1b93f8d 8395 end_loc = c_parser_peek_token (parser)->location;
32129a17 8396 parens.skip_until_found_close (parser);
27bf414c
JM
8397 if (type_name == NULL)
8398 {
8399 struct c_expr ret;
7d882b83 8400 c_inhibit_evaluation_warnings--;
27bf414c 8401 in_alignof--;
913884f7 8402 ret.set_error ();
27bf414c 8403 ret.original_code = ERROR_MARK;
6866c6e8 8404 ret.original_type = NULL;
27bf414c
JM
8405 return ret;
8406 }
8407 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
8408 {
8409 expr = c_parser_postfix_expression_after_paren_type (parser,
24b97832
ILT
8410 type_name,
8411 loc);
27bf414c
JM
8412 goto alignof_expr;
8413 }
8414 /* alignof ( type-name ). */
4b2b493f
JM
8415 if (type_name->specs->alignas_p)
8416 error_at (type_name->specs->locations[cdw_alignas],
8417 "alignment specified for type name in %qE",
8418 alignof_spelling);
7d882b83 8419 c_inhibit_evaluation_warnings--;
27bf414c 8420 in_alignof--;
296674db
JM
8421 ret.value = c_sizeof_or_alignof_type (loc, groktypename (type_name,
8422 NULL, NULL),
8423 false, is_c11_alignof, 1);
27bf414c 8424 ret.original_code = ERROR_MARK;
6866c6e8 8425 ret.original_type = NULL;
a1b93f8d 8426 set_c_expr_source_range (&ret, start_loc, end_loc);
27bf414c
JM
8427 return ret;
8428 }
8429 else
8430 {
8431 struct c_expr ret;
8432 expr = c_parser_unary_expression (parser);
a1b93f8d 8433 end_loc = expr.src_range.m_finish;
27bf414c 8434 alignof_expr:
ebfbbdc5 8435 mark_exp_read (expr.value);
7d882b83 8436 c_inhibit_evaluation_warnings--;
27bf414c 8437 in_alignof--;
aa0db437
MS
8438 if (is_c11_alignof)
8439 pedwarn (start_loc,
8440 OPT_Wpedantic, "ISO C does not allow %<%E (expression)%>",
8441 alignof_spelling);
a1b93f8d 8442 ret.value = c_alignof_expr (start_loc, expr.value);
27bf414c 8443 ret.original_code = ERROR_MARK;
6866c6e8 8444 ret.original_type = NULL;
a1b93f8d 8445 set_c_expr_source_range (&ret, start_loc, end_loc);
27bf414c
JM
8446 return ret;
8447 }
8448}
8449
98f08eb8
MS
8450/* Parse the __builtin_has_attribute ([expr|type], attribute-spec)
8451 expression. */
8452
8453static struct c_expr
8454c_parser_has_attribute_expression (c_parser *parser)
8455{
8456 gcc_assert (c_parser_next_token_is_keyword (parser,
8457 RID_BUILTIN_HAS_ATTRIBUTE));
8458 c_parser_consume_token (parser);
8459
8460 c_inhibit_evaluation_warnings++;
8461
8462 matching_parens parens;
8463 if (!parens.require_open (parser))
8464 {
8465 c_inhibit_evaluation_warnings--;
8466 in_typeof--;
8467
8468 struct c_expr result;
8469 result.set_error ();
8470 result.original_code = ERROR_MARK;
8471 result.original_type = NULL;
8472 return result;
8473 }
8474
8475 /* Treat the type argument the same way as in typeof for the purposes
8476 of warnings. FIXME: Generalize this so the warning refers to
8477 __builtin_has_attribute rather than typeof. */
8478 in_typeof++;
8479
8480 /* The first operand: one of DECL, EXPR, or TYPE. */
8481 tree oper = NULL_TREE;
8482 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
8483 {
8484 struct c_type_name *tname = c_parser_type_name (parser);
8485 in_typeof--;
8486 if (tname)
8487 {
8488 oper = groktypename (tname, NULL, NULL);
8489 pop_maybe_used (variably_modified_type_p (oper, NULL_TREE));
8490 }
8491 }
8492 else
8493 {
8494 struct c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
8495 c_inhibit_evaluation_warnings--;
8496 in_typeof--;
8497 if (cexpr.value != error_mark_node)
8498 {
8499 mark_exp_read (cexpr.value);
8500 oper = cexpr.value;
8501 tree etype = TREE_TYPE (oper);
8502 bool was_vm = variably_modified_type_p (etype, NULL_TREE);
8503 /* This is returned with the type so that when the type is
8504 evaluated, this can be evaluated. */
8505 if (was_vm)
8506 oper = c_fully_fold (oper, false, NULL);
8507 pop_maybe_used (was_vm);
8508 }
8509 }
8510
8511 struct c_expr result;
8512 result.original_code = ERROR_MARK;
8513 result.original_type = NULL;
8514
8515 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
8516 {
8517 /* Consume the closing parenthesis if that's the next token
8518 in the likely case the built-in was invoked with fewer
8519 than two arguments. */
8520 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
8521 c_parser_consume_token (parser);
8522 c_inhibit_evaluation_warnings--;
8523 result.set_error ();
8524 return result;
8525 }
8526
471c5330 8527 bool save_translate_strings_p = parser->translate_strings_p;
98f08eb8
MS
8528
8529 location_t atloc = c_parser_peek_token (parser)->location;
8530 /* Parse a single attribute. Require no leading comma and do not
8531 allow empty attributes. */
783bfe5e 8532 tree attr = c_parser_gnu_attribute (parser, NULL_TREE, false, false);
98f08eb8 8533
471c5330 8534 parser->translate_strings_p = save_translate_strings_p;
98f08eb8
MS
8535
8536 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
8537 c_parser_consume_token (parser);
8538 else
8539 {
8540 c_parser_error (parser, "expected identifier");
8541 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8542
8543 result.set_error ();
8544 return result;
8545 }
8546
8547 if (!attr)
8548 {
8549 error_at (atloc, "expected identifier");
8550 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
8551 "expected %<)%>");
8552 result.set_error ();
8553 return result;
8554 }
8555
8556 result.original_code = INTEGER_CST;
8557 result.original_type = boolean_type_node;
8558
8559 if (has_attribute (atloc, oper, attr, default_conversion))
8560 result.value = boolean_true_node;
8561 else
8562 result.value = boolean_false_node;
8563
8564 return result;
8565}
8566
f90e8e2e 8567/* Helper function to read arguments of builtins which are interfaces
2205ed25 8568 for the middle-end nodes like COMPLEX_EXPR, VEC_PERM_EXPR and
f90e8e2e
AS
8569 others. The name of the builtin is passed using BNAME parameter.
8570 Function returns true if there were no errors while parsing and
46c6e1e2
DM
8571 stores the arguments in CEXPR_LIST. If it returns true,
8572 *OUT_CLOSE_PAREN_LOC is written to with the location of the closing
8573 parenthesis. */
f90e8e2e
AS
8574static bool
8575c_parser_get_builtin_args (c_parser *parser, const char *bname,
4e7d7b3d 8576 vec<c_expr_t, va_gc> **ret_cexpr_list,
46c6e1e2
DM
8577 bool choose_expr_p,
8578 location_t *out_close_paren_loc)
f90e8e2e
AS
8579{
8580 location_t loc = c_parser_peek_token (parser)->location;
9771b263 8581 vec<c_expr_t, va_gc> *cexpr_list;
86785830 8582 c_expr_t expr;
4e7d7b3d 8583 bool saved_force_folding_builtin_constant_p;
f90e8e2e 8584
86785830 8585 *ret_cexpr_list = NULL;
f90e8e2e
AS
8586 if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
8587 {
8588 error_at (loc, "cannot take address of %qs", bname);
8589 return false;
8590 }
8591
8592 c_parser_consume_token (parser);
8593
8594 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
8595 {
46c6e1e2 8596 *out_close_paren_loc = c_parser_peek_token (parser)->location;
f90e8e2e
AS
8597 c_parser_consume_token (parser);
8598 return true;
8599 }
86785830 8600
4e7d7b3d
JJ
8601 saved_force_folding_builtin_constant_p
8602 = force_folding_builtin_constant_p;
8603 force_folding_builtin_constant_p |= choose_expr_p;
86785830 8604 expr = c_parser_expr_no_commas (parser, NULL);
4e7d7b3d
JJ
8605 force_folding_builtin_constant_p
8606 = saved_force_folding_builtin_constant_p;
9771b263 8607 vec_alloc (cexpr_list, 1);
b581c05c 8608 vec_safe_push (cexpr_list, expr);
86785830
AS
8609 while (c_parser_next_token_is (parser, CPP_COMMA))
8610 {
8611 c_parser_consume_token (parser);
8612 expr = c_parser_expr_no_commas (parser, NULL);
b581c05c 8613 vec_safe_push (cexpr_list, expr);
86785830 8614 }
f90e8e2e 8615
46c6e1e2 8616 *out_close_paren_loc = c_parser_peek_token (parser)->location;
f90e8e2e
AS
8617 if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
8618 return false;
8619
86785830 8620 *ret_cexpr_list = cexpr_list;
f90e8e2e
AS
8621 return true;
8622}
8623
433cc7b0
TT
8624/* This represents a single generic-association. */
8625
8626struct c_generic_association
8627{
8628 /* The location of the starting token of the type. */
8629 location_t type_location;
fb48aadc 8630 /* The association's type, or NULL_TREE for 'default'. */
433cc7b0
TT
8631 tree type;
8632 /* The association's expression. */
8633 struct c_expr expression;
8634};
8635
8636/* Parse a generic-selection. (C11 6.5.1.1).
8637
8638 generic-selection:
8639 _Generic ( assignment-expression , generic-assoc-list )
8640
8641 generic-assoc-list:
8642 generic-association
8643 generic-assoc-list , generic-association
8644
8645 generic-association:
8646 type-name : assignment-expression
8647 default : assignment-expression
8648*/
8649
8650static struct c_expr
8651c_parser_generic_selection (c_parser *parser)
8652{
433cc7b0
TT
8653 struct c_expr selector, error_expr;
8654 tree selector_type;
8655 struct c_generic_association matched_assoc;
8656 bool match_found = false;
8657 location_t generic_loc, selector_loc;
8658
8659 error_expr.original_code = ERROR_MARK;
8660 error_expr.original_type = NULL;
8a40fef3 8661 error_expr.set_error ();
433cc7b0
TT
8662 matched_assoc.type_location = UNKNOWN_LOCATION;
8663 matched_assoc.type = NULL_TREE;
8664 matched_assoc.expression = error_expr;
8665
8666 gcc_assert (c_parser_next_token_is_keyword (parser, RID_GENERIC));
8667 generic_loc = c_parser_peek_token (parser)->location;
8668 c_parser_consume_token (parser);
35aff4fb
MP
8669 if (flag_isoc99)
8670 pedwarn_c99 (generic_loc, OPT_Wpedantic,
433cc7b0 8671 "ISO C99 does not support %<_Generic%>");
35aff4fb
MP
8672 else
8673 pedwarn_c99 (generic_loc, OPT_Wpedantic,
433cc7b0 8674 "ISO C90 does not support %<_Generic%>");
433cc7b0 8675
32129a17
DM
8676 matching_parens parens;
8677 if (!parens.require_open (parser))
433cc7b0
TT
8678 return error_expr;
8679
8680 c_inhibit_evaluation_warnings++;
8681 selector_loc = c_parser_peek_token (parser)->location;
8682 selector = c_parser_expr_no_commas (parser, NULL);
8683 selector = default_function_array_conversion (selector_loc, selector);
8684 c_inhibit_evaluation_warnings--;
8685
8686 if (selector.value == error_mark_node)
8687 {
8688 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8689 return selector;
8690 }
8691 selector_type = TREE_TYPE (selector.value);
8692 /* In ISO C terms, rvalues (including the controlling expression of
8693 _Generic) do not have qualified types. */
8694 if (TREE_CODE (selector_type) != ARRAY_TYPE)
8695 selector_type = TYPE_MAIN_VARIANT (selector_type);
8696 /* In ISO C terms, _Noreturn is not part of the type of expressions
8697 such as &abort, but in GCC it is represented internally as a type
8698 qualifier. */
8699 if (FUNCTION_POINTER_TYPE_P (selector_type)
8700 && TYPE_QUALS (TREE_TYPE (selector_type)) != TYPE_UNQUALIFIED)
8701 selector_type
8702 = build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (selector_type)));
8703
8704 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
8705 {
8706 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8707 return error_expr;
8708 }
8709
8c681247 8710 auto_vec<c_generic_association> associations;
433cc7b0
TT
8711 while (1)
8712 {
8713 struct c_generic_association assoc, *iter;
8714 unsigned int ix;
8715 c_token *token = c_parser_peek_token (parser);
8716
8717 assoc.type_location = token->location;
8718 if (token->type == CPP_KEYWORD && token->keyword == RID_DEFAULT)
8719 {
8720 c_parser_consume_token (parser);
8721 assoc.type = NULL_TREE;
8722 }
8723 else
8724 {
8725 struct c_type_name *type_name;
8726
8727 type_name = c_parser_type_name (parser);
8728 if (type_name == NULL)
8729 {
8730 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8c681247 8731 return error_expr;
433cc7b0
TT
8732 }
8733 assoc.type = groktypename (type_name, NULL, NULL);
8734 if (assoc.type == error_mark_node)
8735 {
8736 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8c681247 8737 return error_expr;
433cc7b0
TT
8738 }
8739
8740 if (TREE_CODE (assoc.type) == FUNCTION_TYPE)
8741 error_at (assoc.type_location,
8742 "%<_Generic%> association has function type");
8743 else if (!COMPLETE_TYPE_P (assoc.type))
8744 error_at (assoc.type_location,
8745 "%<_Generic%> association has incomplete type");
8746
8747 if (variably_modified_type_p (assoc.type, NULL_TREE))
8748 error_at (assoc.type_location,
8749 "%<_Generic%> association has "
8750 "variable length type");
8751 }
8752
8753 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
8754 {
8755 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8c681247 8756 return error_expr;
433cc7b0
TT
8757 }
8758
8759 assoc.expression = c_parser_expr_no_commas (parser, NULL);
8760 if (assoc.expression.value == error_mark_node)
8761 {
8762 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8c681247 8763 return error_expr;
433cc7b0
TT
8764 }
8765
8766 for (ix = 0; associations.iterate (ix, &iter); ++ix)
8767 {
8768 if (assoc.type == NULL_TREE)
8769 {
8770 if (iter->type == NULL_TREE)
8771 {
8772 error_at (assoc.type_location,
8773 "duplicate %<default%> case in %<_Generic%>");
8774 inform (iter->type_location, "original %<default%> is here");
8775 }
8776 }
8777 else if (iter->type != NULL_TREE)
8778 {
8779 if (comptypes (assoc.type, iter->type))
8780 {
8781 error_at (assoc.type_location,
8782 "%<_Generic%> specifies two compatible types");
8783 inform (iter->type_location, "compatible type is here");
8784 }
8785 }
8786 }
8787
8788 if (assoc.type == NULL_TREE)
8789 {
8790 if (!match_found)
8791 {
8792 matched_assoc = assoc;
8793 match_found = true;
8794 }
8795 }
8796 else if (comptypes (assoc.type, selector_type))
8797 {
8798 if (!match_found || matched_assoc.type == NULL_TREE)
8799 {
8800 matched_assoc = assoc;
8801 match_found = true;
8802 }
8803 else
8804 {
8805 error_at (assoc.type_location,
883c8f06 8806 "%<_Generic%> selector matches multiple associations");
433cc7b0
TT
8807 inform (matched_assoc.type_location,
8808 "other match is here");
8809 }
8810 }
8811
8812 associations.safe_push (assoc);
8813
8814 if (c_parser_peek_token (parser)->type != CPP_COMMA)
8815 break;
8816 c_parser_consume_token (parser);
8817 }
8818
32129a17 8819 if (!parens.require_close (parser))
433cc7b0
TT
8820 {
8821 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8822 return error_expr;
8823 }
8824
8825 if (!match_found)
8826 {
8827 error_at (selector_loc, "%<_Generic%> selector of type %qT is not "
8828 "compatible with any association",
8829 selector_type);
8830 return error_expr;
8831 }
8832
8833 return matched_assoc.expression;
433cc7b0 8834}
f90e8e2e 8835
3ca0dc60
JM
8836/* Check the validity of a function pointer argument *EXPR (argument
8837 position POS) to __builtin_tgmath. Return the number of function
8838 arguments if possibly valid; return 0 having reported an error if
8839 not valid. */
8840
8841static unsigned int
8842check_tgmath_function (c_expr *expr, unsigned int pos)
8843{
8844 tree type = TREE_TYPE (expr->value);
8845 if (!FUNCTION_POINTER_TYPE_P (type))
8846 {
8847 error_at (expr->get_location (),
8848 "argument %u of %<__builtin_tgmath%> is not a function pointer",
8849 pos);
8850 return 0;
8851 }
8852 type = TREE_TYPE (type);
8853 if (!prototype_p (type))
8854 {
8855 error_at (expr->get_location (),
8856 "argument %u of %<__builtin_tgmath%> is unprototyped", pos);
8857 return 0;
8858 }
8859 if (stdarg_p (type))
8860 {
8861 error_at (expr->get_location (),
8862 "argument %u of %<__builtin_tgmath%> has variable arguments",
8863 pos);
8864 return 0;
8865 }
8866 unsigned int nargs = 0;
8867 function_args_iterator iter;
8868 tree t;
8869 FOREACH_FUNCTION_ARGS (type, t, iter)
8870 {
8871 if (t == void_type_node)
8872 break;
8873 nargs++;
8874 }
8875 if (nargs == 0)
8876 {
8877 error_at (expr->get_location (),
8878 "argument %u of %<__builtin_tgmath%> has no arguments", pos);
8879 return 0;
8880 }
8881 return nargs;
8882}
8883
8884/* Ways in which a parameter or return value of a type-generic macro
8885 may vary between the different functions the macro may call. */
8886enum tgmath_parm_kind
8887 {
8888 tgmath_fixed, tgmath_real, tgmath_complex
8889 };
8890
59bc434a
JJ
8891/* Helper function for c_parser_postfix_expression. Parse predefined
8892 identifiers. */
8893
8894static struct c_expr
8895c_parser_predefined_identifier (c_parser *parser)
8896{
8897 location_t loc = c_parser_peek_token (parser)->location;
8898 switch (c_parser_peek_token (parser)->keyword)
8899 {
8900 case RID_FUNCTION_NAME:
8901 pedwarn (loc, OPT_Wpedantic, "ISO C does not support %qs predefined "
8902 "identifier", "__FUNCTION__");
8903 break;
8904 case RID_PRETTY_FUNCTION_NAME:
8905 pedwarn (loc, OPT_Wpedantic, "ISO C does not support %qs predefined "
8906 "identifier", "__PRETTY_FUNCTION__");
8907 break;
8908 case RID_C99_FUNCTION_NAME:
8909 pedwarn_c90 (loc, OPT_Wpedantic, "ISO C90 does not support "
8910 "%<__func__%> predefined identifier");
8911 break;
8912 default:
8913 gcc_unreachable ();
8914 }
8915
8916 struct c_expr expr;
8917 expr.original_code = ERROR_MARK;
8918 expr.original_type = NULL;
8919 expr.value = fname_decl (loc, c_parser_peek_token (parser)->keyword,
8920 c_parser_peek_token (parser)->value);
8921 set_c_expr_source_range (&expr, loc, loc);
8922 c_parser_consume_token (parser);
8923 return expr;
8924}
8925
31dc71a8 8926/* Parse a postfix expression (C90 6.3.1-6.3.2, C99 6.5.1-6.5.2,
3e7b80d7
MP
8927 C11 6.5.1-6.5.2). Compound literals aren't handled here; callers have to
8928 call c_parser_postfix_expression_after_paren_type on encountering them.
27bf414c
JM
8929
8930 postfix-expression:
8931 primary-expression
8932 postfix-expression [ expression ]
8933 postfix-expression ( argument-expression-list[opt] )
8934 postfix-expression . identifier
8935 postfix-expression -> identifier
8936 postfix-expression ++
8937 postfix-expression --
8938 ( type-name ) { initializer-list }
8939 ( type-name ) { initializer-list , }
8940
8941 argument-expression-list:
8942 argument-expression
8943 argument-expression-list , argument-expression
8944
8945 primary-expression:
8946 identifier
8947 constant
8948 string-literal
8949 ( expression )
433cc7b0 8950 generic-selection
27bf414c
JM
8951
8952 GNU extensions:
8953
8954 primary-expression:
8955 __func__
8956 (treated as a keyword in GNU C)
8957 __FUNCTION__
8958 __PRETTY_FUNCTION__
8959 ( compound-statement )
8960 __builtin_va_arg ( assignment-expression , type-name )
8961 __builtin_offsetof ( type-name , offsetof-member-designator )
8962 __builtin_choose_expr ( assignment-expression ,
8963 assignment-expression ,
8964 assignment-expression )
8965 __builtin_types_compatible_p ( type-name , type-name )
3ca0dc60 8966 __builtin_tgmath ( expr-list )
d4a83c10 8967 __builtin_complex ( assignment-expression , assignment-expression )
f90e8e2e 8968 __builtin_shuffle ( assignment-expression , assignment-expression )
3e7b80d7 8969 __builtin_shuffle ( assignment-expression ,
f90e8e2e
AS
8970 assignment-expression ,
8971 assignment-expression, )
d8fcab68 8972 __builtin_convertvector ( assignment-expression , type-name )
27bf414c
JM
8973
8974 offsetof-member-designator:
8975 identifier
8976 offsetof-member-designator . identifier
8977 offsetof-member-designator [ expression ]
8978
8979 Objective-C:
8980
8981 primary-expression:
8982 [ objc-receiver objc-message-args ]
8983 @selector ( objc-selector-arg )
8984 @protocol ( identifier )
8985 @encode ( type-name )
8986 objc-string-literal
bede2adc 8987 Classname . identifier
27bf414c
JM
8988*/
8989
8990static struct c_expr
8991c_parser_postfix_expression (c_parser *parser)
8992{
f90e8e2e 8993 struct c_expr expr, e1;
27bf414c 8994 struct c_type_name *t1, *t2;
5de73c05 8995 location_t loc = c_parser_peek_token (parser)->location;
ebedc9a3 8996 source_range tok_range = c_parser_peek_token (parser)->get_range ();
6866c6e8
ILT
8997 expr.original_code = ERROR_MARK;
8998 expr.original_type = NULL;
27bf414c
JM
8999 switch (c_parser_peek_token (parser)->type)
9000 {
9001 case CPP_NUMBER:
754ccf7c 9002 expr.value = c_parser_peek_token (parser)->value;
ebedc9a3 9003 set_c_expr_source_range (&expr, tok_range);
754ccf7c
JJ
9004 loc = c_parser_peek_token (parser)->location;
9005 c_parser_consume_token (parser);
9006 if (TREE_CODE (expr.value) == FIXED_CST
9007 && !targetm.fixed_point_supported_p ())
9008 {
9009 error_at (loc, "fixed-point types not supported for this target");
913884f7 9010 expr.set_error ();
754ccf7c
JJ
9011 }
9012 break;
27bf414c 9013 case CPP_CHAR:
b6baa67d
KVH
9014 case CPP_CHAR16:
9015 case CPP_CHAR32:
7c5890cc 9016 case CPP_UTF8CHAR:
27bf414c
JM
9017 case CPP_WCHAR:
9018 expr.value = c_parser_peek_token (parser)->value;
a9342885
MP
9019 /* For the purpose of warning when a pointer is compared with
9020 a zero character constant. */
9021 expr.original_type = char_type_node;
ebedc9a3 9022 set_c_expr_source_range (&expr, tok_range);
27bf414c
JM
9023 c_parser_consume_token (parser);
9024 break;
9025 case CPP_STRING:
b6baa67d
KVH
9026 case CPP_STRING16:
9027 case CPP_STRING32:
27bf414c 9028 case CPP_WSTRING:
2c6e3f55 9029 case CPP_UTF8STRING:
471c5330
JM
9030 expr = c_parser_string_literal (parser, parser->translate_strings_p,
9031 true);
27bf414c
JM
9032 break;
9033 case CPP_OBJC_STRING:
9034 gcc_assert (c_dialect_objc ());
9035 expr.value
9036 = objc_build_string_object (c_parser_peek_token (parser)->value);
ebedc9a3 9037 set_c_expr_source_range (&expr, tok_range);
27bf414c
JM
9038 c_parser_consume_token (parser);
9039 break;
9040 case CPP_NAME:
bede2adc 9041 switch (c_parser_peek_token (parser)->id_kind)
27bf414c 9042 {
bede2adc
NP
9043 case C_ID_ID:
9044 {
9045 tree id = c_parser_peek_token (parser)->value;
9046 c_parser_consume_token (parser);
9047 expr.value = build_external_ref (loc, id,
9048 (c_parser_peek_token (parser)->type
9049 == CPP_OPEN_PAREN),
9050 &expr.original_type);
ebedc9a3 9051 set_c_expr_source_range (&expr, tok_range);
bede2adc
NP
9052 break;
9053 }
9054 case C_ID_CLASSNAME:
9055 {
9056 /* Here we parse the Objective-C 2.0 Class.name dot
9057 syntax. */
9058 tree class_name = c_parser_peek_token (parser)->value;
9059 tree component;
9060 c_parser_consume_token (parser);
9061 gcc_assert (c_dialect_objc ());
9062 if (!c_parser_require (parser, CPP_DOT, "expected %<.%>"))
9063 {
8a40fef3 9064 expr.set_error ();
bede2adc
NP
9065 break;
9066 }
9067 if (c_parser_next_token_is_not (parser, CPP_NAME))
9068 {
9069 c_parser_error (parser, "expected identifier");
8a40fef3 9070 expr.set_error ();
bede2adc
NP
9071 break;
9072 }
cbd03aee
DM
9073 c_token *component_tok = c_parser_peek_token (parser);
9074 component = component_tok->value;
9075 location_t end_loc = component_tok->get_finish ();
bede2adc
NP
9076 c_parser_consume_token (parser);
9077 expr.value = objc_build_class_component_ref (class_name,
9078 component);
cbd03aee 9079 set_c_expr_source_range (&expr, loc, end_loc);
bede2adc
NP
9080 break;
9081 }
9082 default:
27bf414c 9083 c_parser_error (parser, "expected expression");
8a40fef3 9084 expr.set_error ();
27bf414c
JM
9085 break;
9086 }
27bf414c
JM
9087 break;
9088 case CPP_OPEN_PAREN:
9089 /* A parenthesized expression, statement expression or compound
9090 literal. */
9091 if (c_parser_peek_2nd_token (parser)->type == CPP_OPEN_BRACE)
9092 {
9093 /* A statement expression. */
9094 tree stmt;
c2255bc4 9095 location_t brace_loc;
27bf414c 9096 c_parser_consume_token (parser);
c2255bc4 9097 brace_loc = c_parser_peek_token (parser)->location;
27bf414c 9098 c_parser_consume_token (parser);
f7584c81
DP
9099 /* If we've not yet started the current function's statement list,
9100 or we're in the parameter scope of an old-style function
9101 declaration, statement expressions are not allowed. */
9102 if (!building_stmt_list_p () || old_style_parameter_scope ())
27bf414c 9103 {
c2255bc4 9104 error_at (loc, "braced-group within expression allowed "
3ba09659 9105 "only inside a function");
27bf414c
JM
9106 parser->error = true;
9107 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
9108 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8a40fef3 9109 expr.set_error ();
27bf414c
JM
9110 break;
9111 }
9112 stmt = c_begin_stmt_expr ();
9113 c_parser_compound_statement_nostart (parser);
bef08b71 9114 location_t close_loc = c_parser_peek_token (parser)->location;
27bf414c
JM
9115 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9116 "expected %<)%>");
c1771a20 9117 pedwarn (loc, OPT_Wpedantic,
509c9d60 9118 "ISO C forbids braced-groups within expressions");
c2255bc4 9119 expr.value = c_finish_stmt_expr (brace_loc, stmt);
bef08b71 9120 set_c_expr_source_range (&expr, loc, close_loc);
82c3c067 9121 mark_exp_read (expr.value);
27bf414c 9122 }
27bf414c
JM
9123 else
9124 {
9125 /* A parenthesized expression. */
ebedc9a3 9126 location_t loc_open_paren = c_parser_peek_token (parser)->location;
27bf414c
JM
9127 c_parser_consume_token (parser);
9128 expr = c_parser_expression (parser);
9129 if (TREE_CODE (expr.value) == MODIFY_EXPR)
9130 TREE_NO_WARNING (expr.value) = 1;
40ffd95f
BE
9131 if (expr.original_code != C_MAYBE_CONST_EXPR
9132 && expr.original_code != SIZEOF_EXPR)
928c19bb 9133 expr.original_code = ERROR_MARK;
6866c6e8 9134 /* Don't change EXPR.ORIGINAL_TYPE. */
ebedc9a3
DM
9135 location_t loc_close_paren = c_parser_peek_token (parser)->location;
9136 set_c_expr_source_range (&expr, loc_open_paren, loc_close_paren);
27bf414c 9137 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
32129a17 9138 "expected %<)%>", loc_open_paren);
27bf414c
JM
9139 }
9140 break;
9141 case CPP_KEYWORD:
9142 switch (c_parser_peek_token (parser)->keyword)
9143 {
9144 case RID_FUNCTION_NAME:
9145 case RID_PRETTY_FUNCTION_NAME:
9146 case RID_C99_FUNCTION_NAME:
59bc434a 9147 expr = c_parser_predefined_identifier (parser);
27bf414c
JM
9148 break;
9149 case RID_VA_ARG:
bef08b71
DM
9150 {
9151 location_t start_loc = loc;
9152 c_parser_consume_token (parser);
32129a17
DM
9153 matching_parens parens;
9154 if (!parens.require_open (parser))
bef08b71 9155 {
8a40fef3 9156 expr.set_error ();
bef08b71
DM
9157 break;
9158 }
9159 e1 = c_parser_expr_no_commas (parser, NULL);
9160 mark_exp_read (e1.value);
9161 e1.value = c_fully_fold (e1.value, false, NULL);
9162 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
9163 {
9164 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8a40fef3 9165 expr.set_error ();
bef08b71
DM
9166 break;
9167 }
9168 loc = c_parser_peek_token (parser)->location;
9169 t1 = c_parser_type_name (parser);
9170 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
9171 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9172 "expected %<)%>");
9173 if (t1 == NULL)
9174 {
8a40fef3 9175 expr.set_error ();
bef08b71
DM
9176 }
9177 else
9178 {
9179 tree type_expr = NULL_TREE;
f187980b 9180 expr.value = c_build_va_arg (start_loc, e1.value, loc,
bef08b71
DM
9181 groktypename (t1, &type_expr, NULL));
9182 if (type_expr)
9183 {
9184 expr.value = build2 (C_MAYBE_CONST_EXPR,
9185 TREE_TYPE (expr.value), type_expr,
9186 expr.value);
9187 C_MAYBE_CONST_EXPR_NON_CONST (expr.value) = true;
9188 }
9189 set_c_expr_source_range (&expr, start_loc, end_loc);
9190 }
9191 }
27bf414c
JM
9192 break;
9193 case RID_OFFSETOF:
27bf414c 9194 {
32129a17
DM
9195 c_parser_consume_token (parser);
9196 matching_parens parens;
9197 if (!parens.require_open (parser))
9198 {
9199 expr.set_error ();
9200 break;
9201 }
9202 t1 = c_parser_type_name (parser);
9203 if (t1 == NULL)
9204 parser->error = true;
9205 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
9206 gcc_assert (parser->error);
9207 if (parser->error)
9208 {
9209 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9210 expr.set_error ();
9211 break;
9212 }
928c19bb 9213 tree type = groktypename (t1, NULL, NULL);
27bf414c
JM
9214 tree offsetof_ref;
9215 if (type == error_mark_node)
9216 offsetof_ref = error_mark_node;
9217 else
c2255bc4
AH
9218 {
9219 offsetof_ref = build1 (INDIRECT_REF, type, null_pointer_node);
9220 SET_EXPR_LOCATION (offsetof_ref, loc);
9221 }
27bf414c
JM
9222 /* Parse the second argument to __builtin_offsetof. We
9223 must have one identifier, and beyond that we want to
9224 accept sub structure and sub array references. */
9225 if (c_parser_next_token_is (parser, CPP_NAME))
9226 {
6ffd47b7 9227 c_token *comp_tok = c_parser_peek_token (parser);
27bf414c 9228 offsetof_ref = build_component_ref
6ffd47b7 9229 (loc, offsetof_ref, comp_tok->value, comp_tok->location);
27bf414c
JM
9230 c_parser_consume_token (parser);
9231 while (c_parser_next_token_is (parser, CPP_DOT)
9232 || c_parser_next_token_is (parser,
634b5df5
JJ
9233 CPP_OPEN_SQUARE)
9234 || c_parser_next_token_is (parser,
9235 CPP_DEREF))
27bf414c 9236 {
634b5df5
JJ
9237 if (c_parser_next_token_is (parser, CPP_DEREF))
9238 {
9239 loc = c_parser_peek_token (parser)->location;
c2255bc4
AH
9240 offsetof_ref = build_array_ref (loc,
9241 offsetof_ref,
9242 integer_zero_node);
634b5df5
JJ
9243 goto do_dot;
9244 }
9245 else if (c_parser_next_token_is (parser, CPP_DOT))
27bf414c 9246 {
634b5df5 9247 do_dot:
27bf414c
JM
9248 c_parser_consume_token (parser);
9249 if (c_parser_next_token_is_not (parser,
9250 CPP_NAME))
9251 {
9252 c_parser_error (parser, "expected identifier");
9253 break;
9254 }
6ffd47b7 9255 c_token *comp_tok = c_parser_peek_token (parser);
27bf414c 9256 offsetof_ref = build_component_ref
6ffd47b7
DM
9257 (loc, offsetof_ref, comp_tok->value,
9258 comp_tok->location);
27bf414c
JM
9259 c_parser_consume_token (parser);
9260 }
9261 else
9262 {
267bac10 9263 struct c_expr ce;
27bf414c 9264 tree idx;
6a3799eb 9265 loc = c_parser_peek_token (parser)->location;
27bf414c 9266 c_parser_consume_token (parser);
267bac10
JM
9267 ce = c_parser_expression (parser);
9268 ce = convert_lvalue_to_rvalue (loc, ce, false, false);
9269 idx = ce.value;
928c19bb 9270 idx = c_fully_fold (idx, false, NULL);
27bf414c
JM
9271 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
9272 "expected %<]%>");
c2255bc4 9273 offsetof_ref = build_array_ref (loc, offsetof_ref, idx);
27bf414c
JM
9274 }
9275 }
9276 }
9277 else
9278 c_parser_error (parser, "expected identifier");
bef08b71 9279 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
27bf414c
JM
9280 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9281 "expected %<)%>");
cf9e9959 9282 expr.value = fold_offsetof (offsetof_ref);
bef08b71 9283 set_c_expr_source_range (&expr, loc, end_loc);
27bf414c
JM
9284 }
9285 break;
9286 case RID_CHOOSE_EXPR:
27bf414c 9287 {
9771b263 9288 vec<c_expr_t, va_gc> *cexpr_list;
86785830
AS
9289 c_expr_t *e1_p, *e2_p, *e3_p;
9290 tree c;
46c6e1e2 9291 location_t close_paren_loc;
27bf414c 9292
f90e8e2e
AS
9293 c_parser_consume_token (parser);
9294 if (!c_parser_get_builtin_args (parser,
9295 "__builtin_choose_expr",
46c6e1e2
DM
9296 &cexpr_list, true,
9297 &close_paren_loc))
f90e8e2e 9298 {
8a40fef3 9299 expr.set_error ();
f90e8e2e
AS
9300 break;
9301 }
9302
9771b263 9303 if (vec_safe_length (cexpr_list) != 3)
f90e8e2e
AS
9304 {
9305 error_at (loc, "wrong number of arguments to "
9306 "%<__builtin_choose_expr%>");
8a40fef3 9307 expr.set_error ();
f90e8e2e
AS
9308 break;
9309 }
86785830 9310
9771b263
DN
9311 e1_p = &(*cexpr_list)[0];
9312 e2_p = &(*cexpr_list)[1];
9313 e3_p = &(*cexpr_list)[2];
86785830
AS
9314
9315 c = e1_p->value;
9316 mark_exp_read (e2_p->value);
9317 mark_exp_read (e3_p->value);
928c19bb
JM
9318 if (TREE_CODE (c) != INTEGER_CST
9319 || !INTEGRAL_TYPE_P (TREE_TYPE (c)))
3ba09659
AH
9320 error_at (loc,
9321 "first argument to %<__builtin_choose_expr%> not"
9322 " a constant");
928c19bb 9323 constant_expression_warning (c);
86785830 9324 expr = integer_zerop (c) ? *e3_p : *e2_p;
46c6e1e2 9325 set_c_expr_source_range (&expr, loc, close_paren_loc);
f90e8e2e 9326 break;
27bf414c 9327 }
27bf414c 9328 case RID_TYPES_COMPATIBLE_P:
27bf414c 9329 {
32129a17
DM
9330 c_parser_consume_token (parser);
9331 matching_parens parens;
9332 if (!parens.require_open (parser))
9333 {
9334 expr.set_error ();
9335 break;
9336 }
9337 t1 = c_parser_type_name (parser);
9338 if (t1 == NULL)
9339 {
9340 expr.set_error ();
9341 break;
9342 }
9343 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
9344 {
9345 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9346 expr.set_error ();
9347 break;
9348 }
9349 t2 = c_parser_type_name (parser);
9350 if (t2 == NULL)
9351 {
9352 expr.set_error ();
9353 break;
9354 }
4bbf545b 9355 location_t close_paren_loc = c_parser_peek_token (parser)->location;
32129a17 9356 parens.skip_until_found_close (parser);
27bf414c 9357 tree e1, e2;
9abfe986
AP
9358 e1 = groktypename (t1, NULL, NULL);
9359 e2 = groktypename (t2, NULL, NULL);
9360 if (e1 == error_mark_node || e2 == error_mark_node)
9361 {
8a40fef3 9362 expr.set_error ();
9abfe986
AP
9363 break;
9364 }
27bf414c 9365
9abfe986
AP
9366 e1 = TYPE_MAIN_VARIANT (e1);
9367 e2 = TYPE_MAIN_VARIANT (e2);
27bf414c 9368
9a9d280e
AS
9369 expr.value
9370 = comptypes (e1, e2) ? integer_one_node : integer_zero_node;
4bbf545b 9371 set_c_expr_source_range (&expr, loc, close_paren_loc);
27bf414c
JM
9372 }
9373 break;
3ca0dc60
JM
9374 case RID_BUILTIN_TGMATH:
9375 {
9376 vec<c_expr_t, va_gc> *cexpr_list;
9377 location_t close_paren_loc;
9378
9379 c_parser_consume_token (parser);
9380 if (!c_parser_get_builtin_args (parser,
9381 "__builtin_tgmath",
9382 &cexpr_list, false,
9383 &close_paren_loc))
9384 {
9385 expr.set_error ();
9386 break;
9387 }
9388
9389 if (vec_safe_length (cexpr_list) < 3)
9390 {
9391 error_at (loc, "too few arguments to %<__builtin_tgmath%>");
9392 expr.set_error ();
9393 break;
9394 }
9395
9396 unsigned int i;
9397 c_expr_t *p;
9398 FOR_EACH_VEC_ELT (*cexpr_list, i, p)
9399 *p = convert_lvalue_to_rvalue (loc, *p, true, true);
9400 unsigned int nargs = check_tgmath_function (&(*cexpr_list)[0], 1);
9401 if (nargs == 0)
9402 {
9403 expr.set_error ();
9404 break;
9405 }
9406 if (vec_safe_length (cexpr_list) < nargs)
9407 {
9408 error_at (loc, "too few arguments to %<__builtin_tgmath%>");
9409 expr.set_error ();
9410 break;
9411 }
9412 unsigned int num_functions = vec_safe_length (cexpr_list) - nargs;
9413 if (num_functions < 2)
9414 {
9415 error_at (loc, "too few arguments to %<__builtin_tgmath%>");
9416 expr.set_error ();
9417 break;
9418 }
9419
9420 /* The first NUM_FUNCTIONS expressions are the function
9421 pointers. The remaining NARGS expressions are the
9422 arguments that are to be passed to one of those
9423 functions, chosen following <tgmath.h> rules. */
9424 for (unsigned int j = 1; j < num_functions; j++)
9425 {
9426 unsigned int this_nargs
9427 = check_tgmath_function (&(*cexpr_list)[j], j + 1);
9428 if (this_nargs == 0)
9429 {
9430 expr.set_error ();
9431 goto out;
9432 }
9433 if (this_nargs != nargs)
9434 {
9435 error_at ((*cexpr_list)[j].get_location (),
9436 "argument %u of %<__builtin_tgmath%> has "
9437 "wrong number of arguments", j + 1);
9438 expr.set_error ();
9439 goto out;
9440 }
9441 }
9442
9443 /* The functions all have the same number of arguments.
9444 Determine whether arguments and return types vary in
9445 ways permitted for <tgmath.h> functions. */
9446 /* The first entry in each of these vectors is for the
9447 return type, subsequent entries for parameter
9448 types. */
9449 auto_vec<enum tgmath_parm_kind> parm_kind (nargs + 1);
9450 auto_vec<tree> parm_first (nargs + 1);
9451 auto_vec<bool> parm_complex (nargs + 1);
9452 auto_vec<bool> parm_varies (nargs + 1);
9453 tree first_type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[0].value));
9454 tree first_ret = TYPE_MAIN_VARIANT (TREE_TYPE (first_type));
9455 parm_first.quick_push (first_ret);
9456 parm_complex.quick_push (TREE_CODE (first_ret) == COMPLEX_TYPE);
9457 parm_varies.quick_push (false);
9458 function_args_iterator iter;
9459 tree t;
9460 unsigned int argpos;
9461 FOREACH_FUNCTION_ARGS (first_type, t, iter)
9462 {
9463 if (t == void_type_node)
9464 break;
9465 parm_first.quick_push (TYPE_MAIN_VARIANT (t));
9466 parm_complex.quick_push (TREE_CODE (t) == COMPLEX_TYPE);
9467 parm_varies.quick_push (false);
9468 }
9469 for (unsigned int j = 1; j < num_functions; j++)
9470 {
9471 tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
9472 tree ret = TYPE_MAIN_VARIANT (TREE_TYPE (type));
9473 if (ret != parm_first[0])
9474 {
9475 parm_varies[0] = true;
9476 if (!SCALAR_FLOAT_TYPE_P (parm_first[0])
9477 && !COMPLEX_FLOAT_TYPE_P (parm_first[0]))
9478 {
9479 error_at ((*cexpr_list)[0].get_location (),
9480 "invalid type-generic return type for "
9481 "argument %u of %<__builtin_tgmath%>",
9482 1);
9483 expr.set_error ();
9484 goto out;
9485 }
9486 if (!SCALAR_FLOAT_TYPE_P (ret)
9487 && !COMPLEX_FLOAT_TYPE_P (ret))
9488 {
9489 error_at ((*cexpr_list)[j].get_location (),
9490 "invalid type-generic return type for "
9491 "argument %u of %<__builtin_tgmath%>",
9492 j + 1);
9493 expr.set_error ();
9494 goto out;
9495 }
9496 }
9497 if (TREE_CODE (ret) == COMPLEX_TYPE)
9498 parm_complex[0] = true;
9499 argpos = 1;
9500 FOREACH_FUNCTION_ARGS (type, t, iter)
9501 {
9502 if (t == void_type_node)
9503 break;
9504 t = TYPE_MAIN_VARIANT (t);
9505 if (t != parm_first[argpos])
9506 {
9507 parm_varies[argpos] = true;
9508 if (!SCALAR_FLOAT_TYPE_P (parm_first[argpos])
9509 && !COMPLEX_FLOAT_TYPE_P (parm_first[argpos]))
9510 {
9511 error_at ((*cexpr_list)[0].get_location (),
9512 "invalid type-generic type for "
9513 "argument %u of argument %u of "
9514 "%<__builtin_tgmath%>", argpos, 1);
9515 expr.set_error ();
9516 goto out;
9517 }
9518 if (!SCALAR_FLOAT_TYPE_P (t)
9519 && !COMPLEX_FLOAT_TYPE_P (t))
9520 {
9521 error_at ((*cexpr_list)[j].get_location (),
9522 "invalid type-generic type for "
9523 "argument %u of argument %u of "
9524 "%<__builtin_tgmath%>", argpos, j + 1);
9525 expr.set_error ();
9526 goto out;
9527 }
9528 }
9529 if (TREE_CODE (t) == COMPLEX_TYPE)
9530 parm_complex[argpos] = true;
9531 argpos++;
9532 }
9533 }
9534 enum tgmath_parm_kind max_variation = tgmath_fixed;
9535 for (unsigned int j = 0; j <= nargs; j++)
9536 {
9537 enum tgmath_parm_kind this_kind;
9538 if (parm_varies[j])
9539 {
9540 if (parm_complex[j])
9541 max_variation = this_kind = tgmath_complex;
9542 else
9543 {
9544 this_kind = tgmath_real;
9545 if (max_variation != tgmath_complex)
9546 max_variation = tgmath_real;
9547 }
9548 }
9549 else
9550 this_kind = tgmath_fixed;
9551 parm_kind.quick_push (this_kind);
9552 }
9553 if (max_variation == tgmath_fixed)
9554 {
9555 error_at (loc, "function arguments of %<__builtin_tgmath%> "
9556 "all have the same type");
9557 expr.set_error ();
9558 break;
9559 }
9560
9561 /* Identify a parameter (not the return type) that varies,
9562 including with complex types if any variation includes
9563 complex types; there must be at least one such
9564 parameter. */
9565 unsigned int tgarg = 0;
9566 for (unsigned int j = 1; j <= nargs; j++)
9567 if (parm_kind[j] == max_variation)
9568 {
9569 tgarg = j;
9570 break;
9571 }
9572 if (tgarg == 0)
9573 {
9574 error_at (loc, "function arguments of %<__builtin_tgmath%> "
9575 "lack type-generic parameter");
9576 expr.set_error ();
9577 break;
9578 }
9579
9580 /* Determine the type of the relevant parameter for each
9581 function. */
9582 auto_vec<tree> tg_type (num_functions);
9583 for (unsigned int j = 0; j < num_functions; j++)
9584 {
9585 tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
9586 argpos = 1;
9587 FOREACH_FUNCTION_ARGS (type, t, iter)
9588 {
9589 if (argpos == tgarg)
9590 {
9591 tg_type.quick_push (TYPE_MAIN_VARIANT (t));
9592 break;
9593 }
9594 argpos++;
9595 }
9596 }
9597
9598 /* Verify that the corresponding types are different for
9599 all the listed functions. Also determine whether all
9600 the types are complex, whether all the types are
9601 standard or binary, and whether all the types are
9602 decimal. */
9603 bool all_complex = true;
9604 bool all_binary = true;
9605 bool all_decimal = true;
9606 hash_set<tree> tg_types;
9607 FOR_EACH_VEC_ELT (tg_type, i, t)
9608 {
9609 if (TREE_CODE (t) == COMPLEX_TYPE)
9610 all_decimal = false;
9611 else
9612 {
9613 all_complex = false;
9614 if (DECIMAL_FLOAT_TYPE_P (t))
9615 all_binary = false;
9616 else
9617 all_decimal = false;
9618 }
9619 if (tg_types.add (t))
9620 {
9621 error_at ((*cexpr_list)[i].get_location (),
9622 "duplicate type-generic parameter type for "
9623 "function argument %u of %<__builtin_tgmath%>",
9624 i + 1);
9625 expr.set_error ();
9626 goto out;
9627 }
9628 }
9629
9630 /* Verify that other parameters and the return type whose
9631 types vary have their types varying in the correct
9632 way. */
9633 for (unsigned int j = 0; j < num_functions; j++)
9634 {
9635 tree exp_type = tg_type[j];
9636 tree exp_real_type = exp_type;
9637 if (TREE_CODE (exp_type) == COMPLEX_TYPE)
9638 exp_real_type = TREE_TYPE (exp_type);
9639 tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
9640 tree ret = TYPE_MAIN_VARIANT (TREE_TYPE (type));
9641 if ((parm_kind[0] == tgmath_complex && ret != exp_type)
9642 || (parm_kind[0] == tgmath_real && ret != exp_real_type))
9643 {
9644 error_at ((*cexpr_list)[j].get_location (),
9645 "bad return type for function argument %u "
9646 "of %<__builtin_tgmath%>", j + 1);
9647 expr.set_error ();
9648 goto out;
9649 }
9650 argpos = 1;
9651 FOREACH_FUNCTION_ARGS (type, t, iter)
9652 {
9653 if (t == void_type_node)
9654 break;
9655 t = TYPE_MAIN_VARIANT (t);
9656 if ((parm_kind[argpos] == tgmath_complex
9657 && t != exp_type)
9658 || (parm_kind[argpos] == tgmath_real
9659 && t != exp_real_type))
9660 {
9661 error_at ((*cexpr_list)[j].get_location (),
9662 "bad type for argument %u of "
9663 "function argument %u of "
9664 "%<__builtin_tgmath%>", argpos, j + 1);
9665 expr.set_error ();
9666 goto out;
9667 }
9668 argpos++;
9669 }
9670 }
9671
9672 /* The functions listed are a valid set of functions for a
9673 <tgmath.h> macro to select between. Identify the
9674 matching function, if any. First, the argument types
9675 must be combined following <tgmath.h> rules. Integer
9676 types are treated as _Decimal64 if any type-generic
9677 argument is decimal, or if the only alternatives for
9678 type-generic arguments are of decimal types, and are
9679 otherwise treated as double (or _Complex double for
c5c5822a
JM
9680 complex integer types, or _Float64 or _Complex _Float64
9681 if all the return types are the same _FloatN or
9682 _FloatNx type). After that adjustment, types are
9683 combined following the usual arithmetic conversions.
9684 If the function only accepts complex arguments, a
9685 complex type is produced. */
3ca0dc60
JM
9686 bool arg_complex = all_complex;
9687 bool arg_binary = all_binary;
9688 bool arg_int_decimal = all_decimal;
9689 for (unsigned int j = 1; j <= nargs; j++)
9690 {
9691 if (parm_kind[j] == tgmath_fixed)
9692 continue;
9693 c_expr_t *ce = &(*cexpr_list)[num_functions + j - 1];
9694 tree type = TREE_TYPE (ce->value);
9695 if (!INTEGRAL_TYPE_P (type)
9696 && !SCALAR_FLOAT_TYPE_P (type)
9697 && TREE_CODE (type) != COMPLEX_TYPE)
9698 {
9699 error_at (ce->get_location (),
9700 "invalid type of argument %u of type-generic "
9701 "function", j);
9702 expr.set_error ();
9703 goto out;
9704 }
9705 if (DECIMAL_FLOAT_TYPE_P (type))
9706 {
9707 arg_int_decimal = true;
9708 if (all_complex)
9709 {
9710 error_at (ce->get_location (),
9711 "decimal floating-point argument %u to "
9712 "complex-only type-generic function", j);
9713 expr.set_error ();
9714 goto out;
9715 }
9716 else if (all_binary)
9717 {
9718 error_at (ce->get_location (),
9719 "decimal floating-point argument %u to "
9720 "binary-only type-generic function", j);
9721 expr.set_error ();
9722 goto out;
9723 }
9724 else if (arg_complex)
9725 {
9726 error_at (ce->get_location (),
9727 "both complex and decimal floating-point "
9728 "arguments to type-generic function");
9729 expr.set_error ();
9730 goto out;
9731 }
9732 else if (arg_binary)
9733 {
9734 error_at (ce->get_location (),
9735 "both binary and decimal floating-point "
9736 "arguments to type-generic function");
9737 expr.set_error ();
9738 goto out;
9739 }
9740 }
9741 else if (TREE_CODE (type) == COMPLEX_TYPE)
9742 {
9743 arg_complex = true;
9744 if (COMPLEX_FLOAT_TYPE_P (type))
9745 arg_binary = true;
9746 if (all_decimal)
9747 {
9748 error_at (ce->get_location (),
9749 "complex argument %u to "
9750 "decimal-only type-generic function", j);
9751 expr.set_error ();
9752 goto out;
9753 }
9754 else if (arg_int_decimal)
9755 {
9756 error_at (ce->get_location (),
9757 "both complex and decimal floating-point "
9758 "arguments to type-generic function");
9759 expr.set_error ();
9760 goto out;
9761 }
9762 }
9763 else if (SCALAR_FLOAT_TYPE_P (type))
9764 {
9765 arg_binary = true;
9766 if (all_decimal)
9767 {
9768 error_at (ce->get_location (),
9769 "binary argument %u to "
9770 "decimal-only type-generic function", j);
9771 expr.set_error ();
9772 goto out;
9773 }
9774 else if (arg_int_decimal)
9775 {
9776 error_at (ce->get_location (),
9777 "both binary and decimal floating-point "
9778 "arguments to type-generic function");
9779 expr.set_error ();
9780 goto out;
9781 }
9782 }
9783 }
c5c5822a
JM
9784 /* For a macro rounding its result to a narrower type, map
9785 integer types to _Float64 not double if the return type
9786 is a _FloatN or _FloatNx type. */
9787 bool arg_int_float64 = false;
9788 if (parm_kind[0] == tgmath_fixed
9789 && SCALAR_FLOAT_TYPE_P (parm_first[0])
9790 && float64_type_node != NULL_TREE)
9791 for (unsigned int j = 0; j < NUM_FLOATN_NX_TYPES; j++)
9792 if (parm_first[0] == FLOATN_TYPE_NODE (j))
9793 {
9794 arg_int_float64 = true;
9795 break;
9796 }
3ca0dc60
JM
9797 tree arg_real = NULL_TREE;
9798 for (unsigned int j = 1; j <= nargs; j++)
9799 {
9800 if (parm_kind[j] == tgmath_fixed)
9801 continue;
9802 c_expr_t *ce = &(*cexpr_list)[num_functions + j - 1];
9803 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (ce->value));
9804 if (TREE_CODE (type) == COMPLEX_TYPE)
9805 type = TREE_TYPE (type);
9806 if (INTEGRAL_TYPE_P (type))
9807 type = (arg_int_decimal
9808 ? dfloat64_type_node
c5c5822a
JM
9809 : arg_int_float64
9810 ? float64_type_node
3ca0dc60
JM
9811 : double_type_node);
9812 if (arg_real == NULL_TREE)
9813 arg_real = type;
9814 else
9815 arg_real = common_type (arg_real, type);
9816 if (arg_real == error_mark_node)
9817 {
9818 expr.set_error ();
9819 goto out;
9820 }
9821 }
9822 tree arg_type = (arg_complex
9823 ? build_complex_type (arg_real)
9824 : arg_real);
9825
9826 /* Look for a function to call with type-generic parameter
9827 type ARG_TYPE. */
9828 c_expr_t *fn = NULL;
9829 for (unsigned int j = 0; j < num_functions; j++)
9830 {
9831 if (tg_type[j] == arg_type)
9832 {
9833 fn = &(*cexpr_list)[j];
9834 break;
9835 }
9836 }
9837 if (fn == NULL
9838 && parm_kind[0] == tgmath_fixed
9839 && SCALAR_FLOAT_TYPE_P (parm_first[0]))
9840 {
9841 /* Presume this is a macro that rounds its result to a
9842 narrower type, and look for the first function with
9843 at least the range and precision of the argument
9844 type. */
9845 for (unsigned int j = 0; j < num_functions; j++)
9846 {
9847 if (arg_complex
9848 != (TREE_CODE (tg_type[j]) == COMPLEX_TYPE))
9849 continue;
9850 tree real_tg_type = (arg_complex
9851 ? TREE_TYPE (tg_type[j])
9852 : tg_type[j]);
9853 if (DECIMAL_FLOAT_TYPE_P (arg_real)
9854 != DECIMAL_FLOAT_TYPE_P (real_tg_type))
9855 continue;
9856 scalar_float_mode arg_mode
9857 = SCALAR_FLOAT_TYPE_MODE (arg_real);
9858 scalar_float_mode tg_mode
9859 = SCALAR_FLOAT_TYPE_MODE (real_tg_type);
9860 const real_format *arg_fmt = REAL_MODE_FORMAT (arg_mode);
9861 const real_format *tg_fmt = REAL_MODE_FORMAT (tg_mode);
9862 if (arg_fmt->b == tg_fmt->b
9863 && arg_fmt->p <= tg_fmt->p
9864 && arg_fmt->emax <= tg_fmt->emax
9865 && (arg_fmt->emin - arg_fmt->p
9866 >= tg_fmt->emin - tg_fmt->p))
9867 {
9868 fn = &(*cexpr_list)[j];
9869 break;
9870 }
9871 }
9872 }
9873 if (fn == NULL)
9874 {
9875 error_at (loc, "no matching function for type-generic call");
9876 expr.set_error ();
9877 break;
9878 }
9879
9880 /* Construct a call to FN. */
9881 vec<tree, va_gc> *args;
9882 vec_alloc (args, nargs);
9883 vec<tree, va_gc> *origtypes;
9884 vec_alloc (origtypes, nargs);
9885 auto_vec<location_t> arg_loc (nargs);
9886 for (unsigned int j = 0; j < nargs; j++)
9887 {
9888 c_expr_t *ce = &(*cexpr_list)[num_functions + j];
9889 args->quick_push (ce->value);
9890 arg_loc.quick_push (ce->get_location ());
9891 origtypes->quick_push (ce->original_type);
9892 }
9893 expr.value = c_build_function_call_vec (loc, arg_loc, fn->value,
9894 args, origtypes);
9895 set_c_expr_source_range (&expr, loc, close_paren_loc);
9896 break;
9897 }
74893f25
RH
9898 case RID_BUILTIN_CALL_WITH_STATIC_CHAIN:
9899 {
9900 vec<c_expr_t, va_gc> *cexpr_list;
9901 c_expr_t *e2_p;
9902 tree chain_value;
46c6e1e2 9903 location_t close_paren_loc;
74893f25
RH
9904
9905 c_parser_consume_token (parser);
9906 if (!c_parser_get_builtin_args (parser,
9907 "__builtin_call_with_static_chain",
46c6e1e2
DM
9908 &cexpr_list, false,
9909 &close_paren_loc))
74893f25 9910 {
8a40fef3 9911 expr.set_error ();
74893f25
RH
9912 break;
9913 }
9914 if (vec_safe_length (cexpr_list) != 2)
9915 {
9916 error_at (loc, "wrong number of arguments to "
9917 "%<__builtin_call_with_static_chain%>");
8a40fef3 9918 expr.set_error ();
74893f25
RH
9919 break;
9920 }
9921
9922 expr = (*cexpr_list)[0];
9923 e2_p = &(*cexpr_list)[1];
9924 *e2_p = convert_lvalue_to_rvalue (loc, *e2_p, true, true);
9925 chain_value = e2_p->value;
9926 mark_exp_read (chain_value);
9927
9928 if (TREE_CODE (expr.value) != CALL_EXPR)
9929 error_at (loc, "first argument to "
9930 "%<__builtin_call_with_static_chain%> "
9931 "must be a call expression");
9932 else if (TREE_CODE (TREE_TYPE (chain_value)) != POINTER_TYPE)
9933 error_at (loc, "second argument to "
9934 "%<__builtin_call_with_static_chain%> "
9935 "must be a pointer type");
9936 else
9937 CALL_EXPR_STATIC_CHAIN (expr.value) = chain_value;
46c6e1e2 9938 set_c_expr_source_range (&expr, loc, close_paren_loc);
74893f25
RH
9939 break;
9940 }
d4a83c10 9941 case RID_BUILTIN_COMPLEX:
86785830 9942 {
9771b263 9943 vec<c_expr_t, va_gc> *cexpr_list;
86785830 9944 c_expr_t *e1_p, *e2_p;
46c6e1e2 9945 location_t close_paren_loc;
86785830 9946
f90e8e2e
AS
9947 c_parser_consume_token (parser);
9948 if (!c_parser_get_builtin_args (parser,
9949 "__builtin_complex",
46c6e1e2
DM
9950 &cexpr_list, false,
9951 &close_paren_loc))
f90e8e2e 9952 {
8a40fef3 9953 expr.set_error ();
f90e8e2e
AS
9954 break;
9955 }
9956
9771b263 9957 if (vec_safe_length (cexpr_list) != 2)
f90e8e2e
AS
9958 {
9959 error_at (loc, "wrong number of arguments to "
9960 "%<__builtin_complex%>");
8a40fef3 9961 expr.set_error ();
f90e8e2e
AS
9962 break;
9963 }
86785830 9964
9771b263
DN
9965 e1_p = &(*cexpr_list)[0];
9966 e2_p = &(*cexpr_list)[1];
86785830 9967
267bac10 9968 *e1_p = convert_lvalue_to_rvalue (loc, *e1_p, true, true);
86785830
AS
9969 if (TREE_CODE (e1_p->value) == EXCESS_PRECISION_EXPR)
9970 e1_p->value = convert (TREE_TYPE (e1_p->value),
9971 TREE_OPERAND (e1_p->value, 0));
267bac10 9972 *e2_p = convert_lvalue_to_rvalue (loc, *e2_p, true, true);
86785830
AS
9973 if (TREE_CODE (e2_p->value) == EXCESS_PRECISION_EXPR)
9974 e2_p->value = convert (TREE_TYPE (e2_p->value),
9975 TREE_OPERAND (e2_p->value, 0));
9976 if (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (e1_p->value))
9977 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e1_p->value))
9978 || !SCALAR_FLOAT_TYPE_P (TREE_TYPE (e2_p->value))
9979 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e2_p->value)))
f90e8e2e
AS
9980 {
9981 error_at (loc, "%<__builtin_complex%> operand "
9982 "not of real binary floating-point type");
8a40fef3 9983 expr.set_error ();
f90e8e2e
AS
9984 break;
9985 }
86785830
AS
9986 if (TYPE_MAIN_VARIANT (TREE_TYPE (e1_p->value))
9987 != TYPE_MAIN_VARIANT (TREE_TYPE (e2_p->value)))
f90e8e2e
AS
9988 {
9989 error_at (loc,
9990 "%<__builtin_complex%> operands of different types");
8a40fef3 9991 expr.set_error ();
f90e8e2e
AS
9992 break;
9993 }
f3bede71
MP
9994 pedwarn_c90 (loc, OPT_Wpedantic,
9995 "ISO C90 does not support complex types");
46c6e1e2
DM
9996 expr.value = build2_loc (loc, COMPLEX_EXPR,
9997 build_complex_type
9998 (TYPE_MAIN_VARIANT
9999 (TREE_TYPE (e1_p->value))),
10000 e1_p->value, e2_p->value);
10001 set_c_expr_source_range (&expr, loc, close_paren_loc);
f90e8e2e
AS
10002 break;
10003 }
10004 case RID_BUILTIN_SHUFFLE:
10005 {
9771b263 10006 vec<c_expr_t, va_gc> *cexpr_list;
9243c51d
JJ
10007 unsigned int i;
10008 c_expr_t *p;
46c6e1e2 10009 location_t close_paren_loc;
86785830 10010
f90e8e2e
AS
10011 c_parser_consume_token (parser);
10012 if (!c_parser_get_builtin_args (parser,
10013 "__builtin_shuffle",
46c6e1e2
DM
10014 &cexpr_list, false,
10015 &close_paren_loc))
f90e8e2e 10016 {
8a40fef3 10017 expr.set_error ();
f90e8e2e
AS
10018 break;
10019 }
10020
9771b263 10021 FOR_EACH_VEC_SAFE_ELT (cexpr_list, i, p)
267bac10 10022 *p = convert_lvalue_to_rvalue (loc, *p, true, true);
9243c51d 10023
9771b263 10024 if (vec_safe_length (cexpr_list) == 2)
d8fcab68
JJ
10025 expr.value = c_build_vec_perm_expr (loc, (*cexpr_list)[0].value,
10026 NULL_TREE,
10027 (*cexpr_list)[1].value);
86785830 10028
9771b263 10029 else if (vec_safe_length (cexpr_list) == 3)
d8fcab68
JJ
10030 expr.value = c_build_vec_perm_expr (loc, (*cexpr_list)[0].value,
10031 (*cexpr_list)[1].value,
10032 (*cexpr_list)[2].value);
f90e8e2e
AS
10033 else
10034 {
10035 error_at (loc, "wrong number of arguments to "
10036 "%<__builtin_shuffle%>");
8a40fef3 10037 expr.set_error ();
f90e8e2e 10038 }
46c6e1e2 10039 set_c_expr_source_range (&expr, loc, close_paren_loc);
f90e8e2e
AS
10040 break;
10041 }
d8fcab68
JJ
10042 case RID_BUILTIN_CONVERTVECTOR:
10043 {
10044 location_t start_loc = loc;
10045 c_parser_consume_token (parser);
10046 matching_parens parens;
10047 if (!parens.require_open (parser))
10048 {
10049 expr.set_error ();
10050 break;
10051 }
10052 e1 = c_parser_expr_no_commas (parser, NULL);
10053 mark_exp_read (e1.value);
10054 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
10055 {
10056 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10057 expr.set_error ();
10058 break;
10059 }
10060 loc = c_parser_peek_token (parser)->location;
10061 t1 = c_parser_type_name (parser);
10062 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
10063 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
10064 "expected %<)%>");
10065 if (t1 == NULL)
10066 expr.set_error ();
10067 else
10068 {
10069 tree type_expr = NULL_TREE;
10070 expr.value = c_build_vec_convert (start_loc, e1.value, loc,
10071 groktypename (t1, &type_expr,
10072 NULL));
10073 set_c_expr_source_range (&expr, start_loc, end_loc);
10074 }
10075 }
10076 break;
27bf414c 10077 case RID_AT_SELECTOR:
27bf414c 10078 {
32129a17
DM
10079 gcc_assert (c_dialect_objc ());
10080 c_parser_consume_token (parser);
10081 matching_parens parens;
10082 if (!parens.require_open (parser))
10083 {
10084 expr.set_error ();
10085 break;
10086 }
27bf414c 10087 tree sel = c_parser_objc_selector_arg (parser);
cbd03aee 10088 location_t close_loc = c_parser_peek_token (parser)->location;
32129a17 10089 parens.skip_until_found_close (parser);
c2255bc4 10090 expr.value = objc_build_selector_expr (loc, sel);
cbd03aee 10091 set_c_expr_source_range (&expr, loc, close_loc);
27bf414c
JM
10092 }
10093 break;
10094 case RID_AT_PROTOCOL:
27bf414c 10095 {
32129a17
DM
10096 gcc_assert (c_dialect_objc ());
10097 c_parser_consume_token (parser);
10098 matching_parens parens;
10099 if (!parens.require_open (parser))
10100 {
10101 expr.set_error ();
10102 break;
10103 }
10104 if (c_parser_next_token_is_not (parser, CPP_NAME))
10105 {
10106 c_parser_error (parser, "expected identifier");
10107 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10108 expr.set_error ();
10109 break;
10110 }
27bf414c
JM
10111 tree id = c_parser_peek_token (parser)->value;
10112 c_parser_consume_token (parser);
cbd03aee 10113 location_t close_loc = c_parser_peek_token (parser)->location;
32129a17 10114 parens.skip_until_found_close (parser);
27bf414c 10115 expr.value = objc_build_protocol_expr (id);
cbd03aee 10116 set_c_expr_source_range (&expr, loc, close_loc);
27bf414c
JM
10117 }
10118 break;
10119 case RID_AT_ENCODE:
27bf414c 10120 {
32129a17
DM
10121 /* Extension to support C-structures in the archiver. */
10122 gcc_assert (c_dialect_objc ());
10123 c_parser_consume_token (parser);
10124 matching_parens parens;
10125 if (!parens.require_open (parser))
10126 {
10127 expr.set_error ();
10128 break;
10129 }
10130 t1 = c_parser_type_name (parser);
10131 if (t1 == NULL)
10132 {
10133 expr.set_error ();
10134 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10135 break;
10136 }
cbd03aee 10137 location_t close_loc = c_parser_peek_token (parser)->location;
32129a17 10138 parens.skip_until_found_close (parser);
928c19bb 10139 tree type = groktypename (t1, NULL, NULL);
27bf414c 10140 expr.value = objc_build_encode_expr (type);
cbd03aee 10141 set_c_expr_source_range (&expr, loc, close_loc);
27bf414c
JM
10142 }
10143 break;
433cc7b0
TT
10144 case RID_GENERIC:
10145 expr = c_parser_generic_selection (parser);
10146 break;
27bf414c
JM
10147 default:
10148 c_parser_error (parser, "expected expression");
8a40fef3 10149 expr.set_error ();
27bf414c
JM
10150 break;
10151 }
10152 break;
10153 case CPP_OPEN_SQUARE:
10154 if (c_dialect_objc ())
10155 {
10156 tree receiver, args;
10157 c_parser_consume_token (parser);
10158 receiver = c_parser_objc_receiver (parser);
10159 args = c_parser_objc_message_args (parser);
cbd03aee 10160 location_t close_loc = c_parser_peek_token (parser)->location;
27bf414c
JM
10161 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
10162 "expected %<]%>");
eb345401 10163 expr.value = objc_build_message_expr (receiver, args);
cbd03aee 10164 set_c_expr_source_range (&expr, loc, close_loc);
27bf414c
JM
10165 break;
10166 }
10167 /* Else fall through to report error. */
191816a3 10168 /* FALLTHRU */
27bf414c
JM
10169 default:
10170 c_parser_error (parser, "expected expression");
8a40fef3 10171 expr.set_error ();
27bf414c
JM
10172 break;
10173 }
3ca0dc60 10174 out:
a10704e1
DM
10175 return c_parser_postfix_expression_after_primary
10176 (parser, EXPR_LOC_OR_LOC (expr.value, loc), expr);
27bf414c
JM
10177}
10178
10179/* Parse a postfix expression after a parenthesized type name: the
10180 brace-enclosed initializer of a compound literal, possibly followed
10181 by some postfix operators. This is separate because it is not
10182 possible to tell until after the type name whether a cast
10183 expression has a cast or a compound literal, or whether the operand
10184 of sizeof is a parenthesized type name or starts with a compound
24b97832
ILT
10185 literal. TYPE_LOC is the location where TYPE_NAME starts--the
10186 location of the first token after the parentheses around the type
10187 name. */
27bf414c
JM
10188
10189static struct c_expr
10190c_parser_postfix_expression_after_paren_type (c_parser *parser,
24b97832
ILT
10191 struct c_type_name *type_name,
10192 location_t type_loc)
27bf414c
JM
10193{
10194 tree type;
10195 struct c_expr init;
928c19bb 10196 bool non_const;
27bf414c 10197 struct c_expr expr;
c7412148 10198 location_t start_loc;
928c19bb
JM
10199 tree type_expr = NULL_TREE;
10200 bool type_expr_const = true;
c2255bc4 10201 check_compound_literal_type (type_loc, type_name);
5dd9a9d0
DM
10202 rich_location richloc (line_table, type_loc);
10203 start_init (NULL_TREE, NULL, 0, &richloc);
928c19bb 10204 type = groktypename (type_name, &type_expr, &type_expr_const);
c7412148 10205 start_loc = c_parser_peek_token (parser)->location;
85cad37c 10206 if (type != error_mark_node && C_TYPE_VARIABLE_SIZE (type))
27bf414c 10207 {
24b97832 10208 error_at (type_loc, "compound literal has variable size");
27bf414c
JM
10209 type = error_mark_node;
10210 }
16595a1f 10211 init = c_parser_braced_init (parser, type, false, NULL);
27bf414c 10212 finish_init ();
d033409e 10213 maybe_warn_string_init (type_loc, type, init);
27bf414c 10214
36c5e70a
BE
10215 if (type != error_mark_node
10216 && !ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (type))
10217 && current_function_decl)
10218 {
10219 error ("compound literal qualified by address-space qualifier");
10220 type = error_mark_node;
10221 }
10222
f3bede71 10223 pedwarn_c90 (start_loc, OPT_Wpedantic, "ISO C90 forbids compound literals");
928c19bb
JM
10224 non_const = ((init.value && TREE_CODE (init.value) == CONSTRUCTOR)
10225 ? CONSTRUCTOR_NON_CONST (init.value)
10226 : init.original_code == C_MAYBE_CONST_EXPR);
10227 non_const |= !type_expr_const;
4b2b493f
JM
10228 unsigned int alignas_align = 0;
10229 if (type != error_mark_node
10230 && type_name->specs->align_log != -1)
10231 {
10232 alignas_align = 1U << type_name->specs->align_log;
10233 if (alignas_align < min_align_of_type (type))
10234 {
10235 error_at (type_name->specs->locations[cdw_alignas],
10236 "%<_Alignas%> specifiers cannot reduce "
10237 "alignment of compound literal");
10238 alignas_align = 0;
10239 }
10240 }
10241 expr.value = build_compound_literal (start_loc, type, init.value, non_const,
10242 alignas_align);
bef08b71 10243 set_c_expr_source_range (&expr, init.src_range);
27bf414c 10244 expr.original_code = ERROR_MARK;
6866c6e8 10245 expr.original_type = NULL;
a5b5c8b6
MP
10246 if (type != error_mark_node
10247 && expr.value != error_mark_node
10248 && type_expr)
928c19bb
JM
10249 {
10250 if (TREE_CODE (expr.value) == C_MAYBE_CONST_EXPR)
10251 {
10252 gcc_assert (C_MAYBE_CONST_EXPR_PRE (expr.value) == NULL_TREE);
10253 C_MAYBE_CONST_EXPR_PRE (expr.value) = type_expr;
10254 }
10255 else
10256 {
10257 gcc_assert (!non_const);
10258 expr.value = build2 (C_MAYBE_CONST_EXPR, type,
10259 type_expr, expr.value);
10260 }
10261 }
c2255bc4 10262 return c_parser_postfix_expression_after_primary (parser, start_loc, expr);
27bf414c
JM
10263}
10264
1a4049e7
JJ
10265/* Callback function for sizeof_pointer_memaccess_warning to compare
10266 types. */
10267
10268static bool
10269sizeof_ptr_memacc_comptypes (tree type1, tree type2)
10270{
10271 return comptypes (type1, type2) == 1;
10272}
10273
80c6d1f4 10274/* Warn for patterns where abs-like function appears to be used incorrectly,
ce6f0888
MJ
10275 gracefully ignore any non-abs-like function. The warning location should
10276 be LOC. FNDECL is the declaration of called function, it must be a
80c6d1f4
MJ
10277 BUILT_IN_NORMAL function. ARG is the first and only argument of the
10278 call. */
10279
10280static void
10281warn_for_abs (location_t loc, tree fndecl, tree arg)
10282{
3c2a70cb
MS
10283 /* Avoid warning in unreachable subexpressions. */
10284 if (c_inhibit_evaluation_warnings)
10285 return;
10286
80c6d1f4
MJ
10287 tree atype = TREE_TYPE (arg);
10288
10289 /* Casts from pointers (and thus arrays and fndecls) will generate
10290 -Wint-conversion warnings. Most other wrong types hopefully lead to type
10291 mismatch errors. TODO: Think about what to do with FIXED_POINT_TYPE_P
10292 types and possibly other exotic types. */
10293 if (!INTEGRAL_TYPE_P (atype)
10294 && !SCALAR_FLOAT_TYPE_P (atype)
10295 && TREE_CODE (atype) != COMPLEX_TYPE)
10296 return;
10297
10298 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10299
10300 switch (fcode)
10301 {
10302 case BUILT_IN_ABS:
10303 case BUILT_IN_LABS:
10304 case BUILT_IN_LLABS:
10305 case BUILT_IN_IMAXABS:
10306 if (!INTEGRAL_TYPE_P (atype))
10307 {
10308 if (SCALAR_FLOAT_TYPE_P (atype))
10309 warning_at (loc, OPT_Wabsolute_value,
10310 "using integer absolute value function %qD when "
0ecf545c 10311 "argument is of floating-point type %qT",
80c6d1f4
MJ
10312 fndecl, atype);
10313 else if (TREE_CODE (atype) == COMPLEX_TYPE)
10314 warning_at (loc, OPT_Wabsolute_value,
10315 "using integer absolute value function %qD when "
10316 "argument is of complex type %qT", fndecl, atype);
10317 else
10318 gcc_unreachable ();
10319 return;
10320 }
10321 if (TYPE_UNSIGNED (atype))
10322 warning_at (loc, OPT_Wabsolute_value,
10323 "taking the absolute value of unsigned type %qT "
10324 "has no effect", atype);
10325 break;
10326
10327 CASE_FLT_FN (BUILT_IN_FABS):
10328 CASE_FLT_FN_FLOATN_NX (BUILT_IN_FABS):
10329 if (!SCALAR_FLOAT_TYPE_P (atype)
10330 || DECIMAL_FLOAT_MODE_P (TYPE_MODE (atype)))
10331 {
10332 if (INTEGRAL_TYPE_P (atype))
10333 warning_at (loc, OPT_Wabsolute_value,
0ecf545c 10334 "using floating-point absolute value function %qD "
80c6d1f4
MJ
10335 "when argument is of integer type %qT", fndecl, atype);
10336 else if (DECIMAL_FLOAT_TYPE_P (atype))
10337 warning_at (loc, OPT_Wabsolute_value,
0ecf545c
MS
10338 "using floating-point absolute value function %qD "
10339 "when argument is of decimal floating-point type %qT",
80c6d1f4
MJ
10340 fndecl, atype);
10341 else if (TREE_CODE (atype) == COMPLEX_TYPE)
10342 warning_at (loc, OPT_Wabsolute_value,
0ecf545c 10343 "using floating-point absolute value function %qD when "
80c6d1f4
MJ
10344 "argument is of complex type %qT", fndecl, atype);
10345 else
10346 gcc_unreachable ();
10347 return;
10348 }
10349 break;
10350
10351 CASE_FLT_FN (BUILT_IN_CABS):
10352 if (TREE_CODE (atype) != COMPLEX_TYPE)
10353 {
10354 if (INTEGRAL_TYPE_P (atype))
10355 warning_at (loc, OPT_Wabsolute_value,
10356 "using complex absolute value function %qD when "
10357 "argument is of integer type %qT", fndecl, atype);
10358 else if (SCALAR_FLOAT_TYPE_P (atype))
10359 warning_at (loc, OPT_Wabsolute_value,
10360 "using complex absolute value function %qD when "
0ecf545c 10361 "argument is of floating-point type %qT",
80c6d1f4
MJ
10362 fndecl, atype);
10363 else
10364 gcc_unreachable ();
10365
10366 return;
10367 }
10368 break;
10369
10370 case BUILT_IN_FABSD32:
10371 case BUILT_IN_FABSD64:
10372 case BUILT_IN_FABSD128:
10373 if (!DECIMAL_FLOAT_TYPE_P (atype))
10374 {
10375 if (INTEGRAL_TYPE_P (atype))
10376 warning_at (loc, OPT_Wabsolute_value,
0ecf545c 10377 "using decimal floating-point absolute value "
80c6d1f4
MJ
10378 "function %qD when argument is of integer type %qT",
10379 fndecl, atype);
10380 else if (SCALAR_FLOAT_TYPE_P (atype))
10381 warning_at (loc, OPT_Wabsolute_value,
0ecf545c
MS
10382 "using decimal floating-point absolute value "
10383 "function %qD when argument is of floating-point "
80c6d1f4
MJ
10384 "type %qT", fndecl, atype);
10385 else if (TREE_CODE (atype) == COMPLEX_TYPE)
10386 warning_at (loc, OPT_Wabsolute_value,
0ecf545c 10387 "using decimal floating-point absolute value "
80c6d1f4
MJ
10388 "function %qD when argument is of complex type %qT",
10389 fndecl, atype);
10390 else
10391 gcc_unreachable ();
10392 return;
10393 }
10394 break;
10395
10396 default:
10397 return;
10398 }
10399
ce6f0888
MJ
10400 if (!TYPE_ARG_TYPES (TREE_TYPE (fndecl)))
10401 return;
10402
80c6d1f4
MJ
10403 tree ftype = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
10404 if (TREE_CODE (atype) == COMPLEX_TYPE)
10405 {
10406 gcc_assert (TREE_CODE (ftype) == COMPLEX_TYPE);
10407 atype = TREE_TYPE (atype);
10408 ftype = TREE_TYPE (ftype);
10409 }
10410
10411 if (TYPE_PRECISION (ftype) < TYPE_PRECISION (atype))
10412 warning_at (loc, OPT_Wabsolute_value,
10413 "absolute value function %qD given an argument of type %qT "
10414 "but has parameter of type %qT which may cause truncation "
10415 "of value", fndecl, atype, ftype);
10416}
10417
10418
27bf414c 10419/* Parse a postfix expression after the initial primary or compound
c2255bc4
AH
10420 literal; that is, parse a series of postfix operators.
10421
10422 EXPR_LOC is the location of the primary expression. */
27bf414c
JM
10423
10424static struct c_expr
10425c_parser_postfix_expression_after_primary (c_parser *parser,
c2255bc4 10426 location_t expr_loc,
27bf414c
JM
10427 struct c_expr expr)
10428{
928c19bb 10429 struct c_expr orig_expr;
bbbbb16a 10430 tree ident, idx;
6ffd47b7 10431 location_t sizeof_arg_loc[3], comp_loc;
3a785c97 10432 tree sizeof_arg[3];
b108f48f 10433 unsigned int literal_zero_mask;
3a785c97 10434 unsigned int i;
9771b263 10435 vec<tree, va_gc> *exprlist;
2ee028f1 10436 vec<tree, va_gc> *origtypes = NULL;
81e5eca8 10437 vec<location_t> arg_loc = vNULL;
ebedc9a3
DM
10438 location_t start;
10439 location_t finish;
81e5eca8 10440
27bf414c
JM
10441 while (true)
10442 {
c2255bc4 10443 location_t op_loc = c_parser_peek_token (parser)->location;
27bf414c
JM
10444 switch (c_parser_peek_token (parser)->type)
10445 {
10446 case CPP_OPEN_SQUARE:
10447 /* Array reference. */
10448 c_parser_consume_token (parser);
5e9d6aa4
JK
10449 idx = c_parser_expression (parser).value;
10450 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
10451 "expected %<]%>");
10452 start = expr.get_start ();
10453 finish = parser->tokens_buf[0].location;
10454 expr.value = build_array_ref (op_loc, expr.value, idx);
10455 set_c_expr_source_range (&expr, start, finish);
27bf414c 10456 expr.original_code = ERROR_MARK;
6866c6e8 10457 expr.original_type = NULL;
27bf414c
JM
10458 break;
10459 case CPP_OPEN_PAREN:
10460 /* Function call. */
10461 c_parser_consume_token (parser);
3a785c97
JJ
10462 for (i = 0; i < 3; i++)
10463 {
10464 sizeof_arg[i] = NULL_TREE;
10465 sizeof_arg_loc[i] = UNKNOWN_LOCATION;
10466 }
b108f48f 10467 literal_zero_mask = 0;
27bf414c 10468 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
bbbbb16a 10469 exprlist = NULL;
27bf414c 10470 else
1a4049e7 10471 exprlist = c_parser_expr_list (parser, true, false, &origtypes,
81e5eca8 10472 sizeof_arg_loc, sizeof_arg,
b108f48f 10473 &arg_loc, &literal_zero_mask);
27bf414c
JM
10474 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
10475 "expected %<)%>");
928c19bb 10476 orig_expr = expr;
ebfbbdc5 10477 mark_exp_read (expr.value);
3a785c97
JJ
10478 if (warn_sizeof_pointer_memaccess)
10479 sizeof_pointer_memaccess_warning (sizeof_arg_loc,
1a4049e7 10480 expr.value, exprlist,
3a785c97 10481 sizeof_arg,
1a4049e7 10482 sizeof_ptr_memacc_comptypes);
80c6d1f4 10483 if (TREE_CODE (expr.value) == FUNCTION_DECL)
c1e1f433 10484 {
80c6d1f4
MJ
10485 if (fndecl_built_in_p (expr.value, BUILT_IN_MEMSET)
10486 && vec_safe_length (exprlist) == 3)
10487 {
10488 tree arg0 = (*exprlist)[0];
10489 tree arg2 = (*exprlist)[2];
10490 warn_for_memset (expr_loc, arg0, arg2, literal_zero_mask);
10491 }
10492 if (warn_absolute_value
10493 && fndecl_built_in_p (expr.value, BUILT_IN_NORMAL)
10494 && vec_safe_length (exprlist) == 1)
10495 warn_for_abs (expr_loc, expr.value, (*exprlist)[0]);
c1e1f433 10496 }
b108f48f 10497
ebedc9a3
DM
10498 start = expr.get_start ();
10499 finish = parser->tokens_buf[0].get_finish ();
8edbfaa6
JJ
10500 expr.value
10501 = c_build_function_call_vec (expr_loc, arg_loc, expr.value,
10502 exprlist, origtypes);
ebedc9a3
DM
10503 set_c_expr_source_range (&expr, start, finish);
10504
27bf414c 10505 expr.original_code = ERROR_MARK;
928c19bb
JM
10506 if (TREE_CODE (expr.value) == INTEGER_CST
10507 && TREE_CODE (orig_expr.value) == FUNCTION_DECL
3d78e008 10508 && fndecl_built_in_p (orig_expr.value, BUILT_IN_CONSTANT_P))
928c19bb 10509 expr.original_code = C_MAYBE_CONST_EXPR;
6866c6e8 10510 expr.original_type = NULL;
9771b263 10511 if (exprlist)
bbbbb16a 10512 {
c166b898
ILT
10513 release_tree_vector (exprlist);
10514 release_tree_vector (origtypes);
bbbbb16a 10515 }
81e5eca8 10516 arg_loc.release ();
27bf414c
JM
10517 break;
10518 case CPP_DOT:
10519 /* Structure element reference. */
10520 c_parser_consume_token (parser);
c2255bc4 10521 expr = default_function_array_conversion (expr_loc, expr);
27bf414c 10522 if (c_parser_next_token_is (parser, CPP_NAME))
6ffd47b7
DM
10523 {
10524 c_token *comp_tok = c_parser_peek_token (parser);
10525 ident = comp_tok->value;
10526 comp_loc = comp_tok->location;
10527 }
27bf414c
JM
10528 else
10529 {
10530 c_parser_error (parser, "expected identifier");
8a40fef3 10531 expr.set_error ();
27bf414c 10532 expr.original_code = ERROR_MARK;
6866c6e8 10533 expr.original_type = NULL;
27bf414c
JM
10534 return expr;
10535 }
ebedc9a3
DM
10536 start = expr.get_start ();
10537 finish = c_parser_peek_token (parser)->get_finish ();
27bf414c 10538 c_parser_consume_token (parser);
6ffd47b7
DM
10539 expr.value = build_component_ref (op_loc, expr.value, ident,
10540 comp_loc);
ebedc9a3 10541 set_c_expr_source_range (&expr, start, finish);
27bf414c 10542 expr.original_code = ERROR_MARK;
6866c6e8
ILT
10543 if (TREE_CODE (expr.value) != COMPONENT_REF)
10544 expr.original_type = NULL;
10545 else
10546 {
10547 /* Remember the original type of a bitfield. */
10548 tree field = TREE_OPERAND (expr.value, 1);
10549 if (TREE_CODE (field) != FIELD_DECL)
10550 expr.original_type = NULL;
10551 else
10552 expr.original_type = DECL_BIT_FIELD_TYPE (field);
10553 }
27bf414c
JM
10554 break;
10555 case CPP_DEREF:
10556 /* Structure element reference. */
10557 c_parser_consume_token (parser);
267bac10 10558 expr = convert_lvalue_to_rvalue (expr_loc, expr, true, false);
27bf414c 10559 if (c_parser_next_token_is (parser, CPP_NAME))
6ffd47b7
DM
10560 {
10561 c_token *comp_tok = c_parser_peek_token (parser);
10562 ident = comp_tok->value;
10563 comp_loc = comp_tok->location;
10564 }
27bf414c
JM
10565 else
10566 {
10567 c_parser_error (parser, "expected identifier");
8a40fef3 10568 expr.set_error ();
27bf414c 10569 expr.original_code = ERROR_MARK;
6866c6e8 10570 expr.original_type = NULL;
27bf414c
JM
10571 return expr;
10572 }
ebedc9a3
DM
10573 start = expr.get_start ();
10574 finish = c_parser_peek_token (parser)->get_finish ();
27bf414c 10575 c_parser_consume_token (parser);
c2255bc4
AH
10576 expr.value = build_component_ref (op_loc,
10577 build_indirect_ref (op_loc,
c9f9eb5d 10578 expr.value,
dd865ef6 10579 RO_ARROW),
6ffd47b7 10580 ident, comp_loc);
ebedc9a3 10581 set_c_expr_source_range (&expr, start, finish);
27bf414c 10582 expr.original_code = ERROR_MARK;
6866c6e8
ILT
10583 if (TREE_CODE (expr.value) != COMPONENT_REF)
10584 expr.original_type = NULL;
10585 else
10586 {
10587 /* Remember the original type of a bitfield. */
10588 tree field = TREE_OPERAND (expr.value, 1);
10589 if (TREE_CODE (field) != FIELD_DECL)
10590 expr.original_type = NULL;
10591 else
10592 expr.original_type = DECL_BIT_FIELD_TYPE (field);
10593 }
27bf414c
JM
10594 break;
10595 case CPP_PLUS_PLUS:
10596 /* Postincrement. */
ebedc9a3
DM
10597 start = expr.get_start ();
10598 finish = c_parser_peek_token (parser)->get_finish ();
27bf414c 10599 c_parser_consume_token (parser);
5e9d6aa4
JK
10600 expr = default_function_array_read_conversion (expr_loc, expr);
10601 expr.value = build_unary_op (op_loc, POSTINCREMENT_EXPR,
10602 expr.value, false);
ebedc9a3 10603 set_c_expr_source_range (&expr, start, finish);
27bf414c 10604 expr.original_code = ERROR_MARK;
6866c6e8 10605 expr.original_type = NULL;
27bf414c
JM
10606 break;
10607 case CPP_MINUS_MINUS:
10608 /* Postdecrement. */
ebedc9a3
DM
10609 start = expr.get_start ();
10610 finish = c_parser_peek_token (parser)->get_finish ();
27bf414c 10611 c_parser_consume_token (parser);
5e9d6aa4
JK
10612 expr = default_function_array_read_conversion (expr_loc, expr);
10613 expr.value = build_unary_op (op_loc, POSTDECREMENT_EXPR,
10614 expr.value, false);
ebedc9a3 10615 set_c_expr_source_range (&expr, start, finish);
27bf414c 10616 expr.original_code = ERROR_MARK;
6866c6e8 10617 expr.original_type = NULL;
27bf414c
JM
10618 break;
10619 default:
10620 return expr;
10621 }
10622 }
10623}
10624
31dc71a8 10625/* Parse an expression (C90 6.3.17, C99 6.5.17, C11 6.5.17).
27bf414c
JM
10626
10627 expression:
10628 assignment-expression
10629 expression , assignment-expression
10630*/
10631
10632static struct c_expr
10633c_parser_expression (c_parser *parser)
10634{
267bac10 10635 location_t tloc = c_parser_peek_token (parser)->location;
27bf414c
JM
10636 struct c_expr expr;
10637 expr = c_parser_expr_no_commas (parser, NULL);
267bac10
JM
10638 if (c_parser_next_token_is (parser, CPP_COMMA))
10639 expr = convert_lvalue_to_rvalue (tloc, expr, true, false);
27bf414c
JM
10640 while (c_parser_next_token_is (parser, CPP_COMMA))
10641 {
10642 struct c_expr next;
056928b2 10643 tree lhsval;
c2255bc4
AH
10644 location_t loc = c_parser_peek_token (parser)->location;
10645 location_t expr_loc;
27bf414c 10646 c_parser_consume_token (parser);
c2255bc4 10647 expr_loc = c_parser_peek_token (parser)->location;
056928b2
JJ
10648 lhsval = expr.value;
10649 while (TREE_CODE (lhsval) == COMPOUND_EXPR)
10650 lhsval = TREE_OPERAND (lhsval, 1);
10651 if (DECL_P (lhsval) || handled_component_p (lhsval))
10652 mark_exp_read (lhsval);
27bf414c 10653 next = c_parser_expr_no_commas (parser, NULL);
267bac10 10654 next = convert_lvalue_to_rvalue (expr_loc, next, true, false);
c2255bc4 10655 expr.value = build_compound_expr (loc, expr.value, next.value);
27bf414c 10656 expr.original_code = COMPOUND_EXPR;
81f40b79 10657 expr.original_type = next.original_type;
27bf414c
JM
10658 }
10659 return expr;
10660}
10661
267bac10
JM
10662/* Parse an expression and convert functions or arrays to pointers and
10663 lvalues to rvalues. */
46bdb9cf
JM
10664
10665static struct c_expr
10666c_parser_expression_conv (c_parser *parser)
10667{
10668 struct c_expr expr;
c2255bc4 10669 location_t loc = c_parser_peek_token (parser)->location;
46bdb9cf 10670 expr = c_parser_expression (parser);
267bac10 10671 expr = convert_lvalue_to_rvalue (loc, expr, true, false);
46bdb9cf
JM
10672 return expr;
10673}
10674
b108f48f
JJ
10675/* Helper function of c_parser_expr_list. Check if IDXth (0 based)
10676 argument is a literal zero alone and if so, set it in literal_zero_mask. */
10677
10678static inline void
10679c_parser_check_literal_zero (c_parser *parser, unsigned *literal_zero_mask,
10680 unsigned int idx)
10681{
10682 if (idx >= HOST_BITS_PER_INT)
10683 return;
10684
10685 c_token *tok = c_parser_peek_token (parser);
10686 switch (tok->type)
10687 {
10688 case CPP_NUMBER:
10689 case CPP_CHAR:
10690 case CPP_WCHAR:
10691 case CPP_CHAR16:
10692 case CPP_CHAR32:
7c5890cc 10693 case CPP_UTF8CHAR:
b108f48f
JJ
10694 /* If a parameter is literal zero alone, remember it
10695 for -Wmemset-transposed-args warning. */
10696 if (integer_zerop (tok->value)
10697 && !TREE_OVERFLOW (tok->value)
10698 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
10699 || c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_PAREN))
10700 *literal_zero_mask |= 1U << idx;
10701 default:
10702 break;
10703 }
10704}
10705
46bdb9cf 10706/* Parse a non-empty list of expressions. If CONVERT_P, convert
267bac10 10707 functions and arrays to pointers and lvalues to rvalues. If
81e5eca8
MP
10708 FOLD_P, fold the expressions. If LOCATIONS is non-NULL, save the
10709 locations of function arguments into this vector.
27bf414c
JM
10710
10711 nonempty-expr-list:
10712 assignment-expression
10713 nonempty-expr-list , assignment-expression
10714*/
10715
9771b263 10716static vec<tree, va_gc> *
bbbbb16a 10717c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p,
9771b263 10718 vec<tree, va_gc> **p_orig_types,
81e5eca8 10719 location_t *sizeof_arg_loc, tree *sizeof_arg,
b108f48f
JJ
10720 vec<location_t> *locations,
10721 unsigned int *literal_zero_mask)
27bf414c 10722{
9771b263
DN
10723 vec<tree, va_gc> *ret;
10724 vec<tree, va_gc> *orig_types;
27bf414c 10725 struct c_expr expr;
3a785c97 10726 unsigned int idx = 0;
bbbbb16a 10727
c166b898 10728 ret = make_tree_vector ();
bbbbb16a
ILT
10729 if (p_orig_types == NULL)
10730 orig_types = NULL;
10731 else
c166b898 10732 orig_types = make_tree_vector ();
bbbbb16a 10733
b108f48f
JJ
10734 if (literal_zero_mask)
10735 c_parser_check_literal_zero (parser, literal_zero_mask, 0);
27bf414c 10736 expr = c_parser_expr_no_commas (parser, NULL);
46bdb9cf 10737 if (convert_p)
7f204c0f 10738 expr = convert_lvalue_to_rvalue (expr.get_location (), expr, true, true);
928c19bb
JM
10739 if (fold_p)
10740 expr.value = c_fully_fold (expr.value, false, NULL);
9771b263
DN
10741 ret->quick_push (expr.value);
10742 if (orig_types)
10743 orig_types->quick_push (expr.original_type);
81e5eca8 10744 if (locations)
7f204c0f 10745 locations->safe_push (expr.get_location ());
3a785c97 10746 if (sizeof_arg != NULL
3a785c97
JJ
10747 && expr.original_code == SIZEOF_EXPR)
10748 {
10749 sizeof_arg[0] = c_last_sizeof_arg;
40ffd95f 10750 sizeof_arg_loc[0] = c_last_sizeof_loc;
3a785c97 10751 }
27bf414c
JM
10752 while (c_parser_next_token_is (parser, CPP_COMMA))
10753 {
10754 c_parser_consume_token (parser);
b108f48f
JJ
10755 if (literal_zero_mask)
10756 c_parser_check_literal_zero (parser, literal_zero_mask, idx + 1);
27bf414c 10757 expr = c_parser_expr_no_commas (parser, NULL);
46bdb9cf 10758 if (convert_p)
7f204c0f
DM
10759 expr = convert_lvalue_to_rvalue (expr.get_location (), expr, true,
10760 true);
928c19bb
JM
10761 if (fold_p)
10762 expr.value = c_fully_fold (expr.value, false, NULL);
9771b263
DN
10763 vec_safe_push (ret, expr.value);
10764 if (orig_types)
10765 vec_safe_push (orig_types, expr.original_type);
81e5eca8 10766 if (locations)
7f204c0f 10767 locations->safe_push (expr.get_location ());
3a785c97
JJ
10768 if (++idx < 3
10769 && sizeof_arg != NULL
1a4049e7
JJ
10770 && expr.original_code == SIZEOF_EXPR)
10771 {
3a785c97 10772 sizeof_arg[idx] = c_last_sizeof_arg;
40ffd95f 10773 sizeof_arg_loc[idx] = c_last_sizeof_loc;
1a4049e7
JJ
10774 }
10775 }
9771b263 10776 if (orig_types)
bbbbb16a 10777 *p_orig_types = orig_types;
27bf414c
JM
10778 return ret;
10779}
27bf414c
JM
10780\f
10781/* Parse Objective-C-specific constructs. */
10782
10783/* Parse an objc-class-definition.
10784
10785 objc-class-definition:
10786 @interface identifier objc-superclass[opt] objc-protocol-refs[opt]
10787 objc-class-instance-variables[opt] objc-methodprotolist @end
10788 @implementation identifier objc-superclass[opt]
10789 objc-class-instance-variables[opt]
10790 @interface identifier ( identifier ) objc-protocol-refs[opt]
10791 objc-methodprotolist @end
ec3e9f82
NP
10792 @interface identifier ( ) objc-protocol-refs[opt]
10793 objc-methodprotolist @end
27bf414c
JM
10794 @implementation identifier ( identifier )
10795
10796 objc-superclass:
10797 : identifier
10798
10799 "@interface identifier (" must start "@interface identifier (
10800 identifier ) ...": objc-methodprotolist in the first production may
0fa2e4df 10801 not start with a parenthesized identifier as a declarator of a data
27bf414c
JM
10802 definition with no declaration specifiers if the objc-superclass,
10803 objc-protocol-refs and objc-class-instance-variables are omitted. */
10804
10805static void
c165dca7 10806c_parser_objc_class_definition (c_parser *parser, tree attributes)
27bf414c
JM
10807{
10808 bool iface_p;
10809 tree id1;
10810 tree superclass;
10811 if (c_parser_next_token_is_keyword (parser, RID_AT_INTERFACE))
10812 iface_p = true;
10813 else if (c_parser_next_token_is_keyword (parser, RID_AT_IMPLEMENTATION))
10814 iface_p = false;
10815 else
10816 gcc_unreachable ();
c165dca7 10817
27bf414c
JM
10818 c_parser_consume_token (parser);
10819 if (c_parser_next_token_is_not (parser, CPP_NAME))
10820 {
10821 c_parser_error (parser, "expected identifier");
10822 return;
10823 }
10824 id1 = c_parser_peek_token (parser)->value;
10825 c_parser_consume_token (parser);
10826 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
10827 {
ec3e9f82 10828 /* We have a category or class extension. */
27bf414c
JM
10829 tree id2;
10830 tree proto = NULL_TREE;
32129a17
DM
10831 matching_parens parens;
10832 parens.consume_open (parser);
27bf414c
JM
10833 if (c_parser_next_token_is_not (parser, CPP_NAME))
10834 {
ec3e9f82
NP
10835 if (iface_p && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
10836 {
10837 /* We have a class extension. */
10838 id2 = NULL_TREE;
10839 }
10840 else
10841 {
10842 c_parser_error (parser, "expected identifier or %<)%>");
10843 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10844 return;
10845 }
10846 }
10847 else
10848 {
10849 id2 = c_parser_peek_token (parser)->value;
10850 c_parser_consume_token (parser);
27bf414c 10851 }
32129a17 10852 parens.skip_until_found_close (parser);
27bf414c
JM
10853 if (!iface_p)
10854 {
10855 objc_start_category_implementation (id1, id2);
10856 return;
10857 }
10858 if (c_parser_next_token_is (parser, CPP_LESS))
10859 proto = c_parser_objc_protocol_refs (parser);
c165dca7 10860 objc_start_category_interface (id1, id2, proto, attributes);
27bf414c
JM
10861 c_parser_objc_methodprotolist (parser);
10862 c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
10863 objc_finish_interface ();
10864 return;
10865 }
10866 if (c_parser_next_token_is (parser, CPP_COLON))
10867 {
10868 c_parser_consume_token (parser);
10869 if (c_parser_next_token_is_not (parser, CPP_NAME))
10870 {
10871 c_parser_error (parser, "expected identifier");
10872 return;
10873 }
10874 superclass = c_parser_peek_token (parser)->value;
10875 c_parser_consume_token (parser);
10876 }
10877 else
10878 superclass = NULL_TREE;
10879 if (iface_p)
10880 {
10881 tree proto = NULL_TREE;
10882 if (c_parser_next_token_is (parser, CPP_LESS))
10883 proto = c_parser_objc_protocol_refs (parser);
c165dca7 10884 objc_start_class_interface (id1, superclass, proto, attributes);
27bf414c
JM
10885 }
10886 else
10887 objc_start_class_implementation (id1, superclass);
10888 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
10889 c_parser_objc_class_instance_variables (parser);
10890 if (iface_p)
10891 {
10892 objc_continue_interface ();
10893 c_parser_objc_methodprotolist (parser);
10894 c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
10895 objc_finish_interface ();
10896 }
10897 else
10898 {
10899 objc_continue_implementation ();
10900 return;
10901 }
10902}
10903
10904/* Parse objc-class-instance-variables.
10905
10906 objc-class-instance-variables:
10907 { objc-instance-variable-decl-list[opt] }
10908
10909 objc-instance-variable-decl-list:
10910 objc-visibility-spec
10911 objc-instance-variable-decl ;
10912 ;
10913 objc-instance-variable-decl-list objc-visibility-spec
10914 objc-instance-variable-decl-list objc-instance-variable-decl ;
10915 objc-instance-variable-decl-list ;
10916
10917 objc-visibility-spec:
10918 @private
10919 @protected
10920 @public
10921
10922 objc-instance-variable-decl:
10923 struct-declaration
10924*/
10925
10926static void
10927c_parser_objc_class_instance_variables (c_parser *parser)
10928{
10929 gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE));
10930 c_parser_consume_token (parser);
10931 while (c_parser_next_token_is_not (parser, CPP_EOF))
10932 {
10933 tree decls;
10934 /* Parse any stray semicolon. */
10935 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
10936 {
c1771a20 10937 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
4e26ba90 10938 "extra semicolon");
27bf414c
JM
10939 c_parser_consume_token (parser);
10940 continue;
10941 }
10942 /* Stop if at the end of the instance variables. */
10943 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
10944 {
10945 c_parser_consume_token (parser);
10946 break;
10947 }
10948 /* Parse any objc-visibility-spec. */
49b91f05 10949 if (c_parser_next_token_is_keyword (parser, RID_AT_PRIVATE))
27bf414c
JM
10950 {
10951 c_parser_consume_token (parser);
c37d8c30 10952 objc_set_visibility (OBJC_IVAR_VIS_PRIVATE);
27bf414c
JM
10953 continue;
10954 }
49b91f05 10955 else if (c_parser_next_token_is_keyword (parser, RID_AT_PROTECTED))
27bf414c
JM
10956 {
10957 c_parser_consume_token (parser);
c37d8c30 10958 objc_set_visibility (OBJC_IVAR_VIS_PROTECTED);
27bf414c
JM
10959 continue;
10960 }
49b91f05 10961 else if (c_parser_next_token_is_keyword (parser, RID_AT_PUBLIC))
27bf414c
JM
10962 {
10963 c_parser_consume_token (parser);
c37d8c30
IS
10964 objc_set_visibility (OBJC_IVAR_VIS_PUBLIC);
10965 continue;
10966 }
10967 else if (c_parser_next_token_is_keyword (parser, RID_AT_PACKAGE))
10968 {
10969 c_parser_consume_token (parser);
10970 objc_set_visibility (OBJC_IVAR_VIS_PACKAGE);
27bf414c
JM
10971 continue;
10972 }
bc4071dd
RH
10973 else if (c_parser_next_token_is (parser, CPP_PRAGMA))
10974 {
dda1bf61 10975 c_parser_pragma (parser, pragma_external, NULL);
bc4071dd
RH
10976 continue;
10977 }
10978
27bf414c
JM
10979 /* Parse some comma-separated declarations. */
10980 decls = c_parser_struct_declaration (parser);
4e26ba90
NP
10981 if (decls == NULL)
10982 {
10983 /* There is a syntax error. We want to skip the offending
10984 tokens up to the next ';' (included) or '}'
10985 (excluded). */
10986
10987 /* First, skip manually a ')' or ']'. This is because they
10988 reduce the nesting level, so c_parser_skip_until_found()
10989 wouldn't be able to skip past them. */
10990 c_token *token = c_parser_peek_token (parser);
10991 if (token->type == CPP_CLOSE_PAREN || token->type == CPP_CLOSE_SQUARE)
10992 c_parser_consume_token (parser);
10993
10994 /* Then, do the standard skipping. */
10995 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
10996
10997 /* We hopefully recovered. Start normal parsing again. */
10998 parser->error = false;
10999 continue;
11000 }
11001 else
11002 {
11003 /* Comma-separated instance variables are chained together
11004 in reverse order; add them one by one. */
11005 tree ivar = nreverse (decls);
11006 for (; ivar; ivar = DECL_CHAIN (ivar))
11007 objc_add_instance_variable (copy_node (ivar));
11008 }
27bf414c
JM
11009 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11010 }
11011}
11012
11013/* Parse an objc-class-declaration.
11014
11015 objc-class-declaration:
11016 @class identifier-list ;
11017*/
11018
11019static void
11020c_parser_objc_class_declaration (c_parser *parser)
11021{
49b91f05 11022 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_CLASS));
27bf414c
JM
11023 c_parser_consume_token (parser);
11024 /* Any identifiers, including those declared as type names, are OK
11025 here. */
11026 while (true)
11027 {
11028 tree id;
11029 if (c_parser_next_token_is_not (parser, CPP_NAME))
11030 {
11031 c_parser_error (parser, "expected identifier");
da57d1b9
NP
11032 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11033 parser->error = false;
11034 return;
27bf414c
JM
11035 }
11036 id = c_parser_peek_token (parser)->value;
32dabdaf 11037 objc_declare_class (id);
27bf414c
JM
11038 c_parser_consume_token (parser);
11039 if (c_parser_next_token_is (parser, CPP_COMMA))
11040 c_parser_consume_token (parser);
11041 else
11042 break;
11043 }
11044 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
27bf414c
JM
11045}
11046
11047/* Parse an objc-alias-declaration.
11048
11049 objc-alias-declaration:
11050 @compatibility_alias identifier identifier ;
11051*/
11052
11053static void
11054c_parser_objc_alias_declaration (c_parser *parser)
11055{
11056 tree id1, id2;
11057 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_ALIAS));
11058 c_parser_consume_token (parser);
11059 if (c_parser_next_token_is_not (parser, CPP_NAME))
11060 {
11061 c_parser_error (parser, "expected identifier");
11062 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11063 return;
11064 }
11065 id1 = c_parser_peek_token (parser)->value;
11066 c_parser_consume_token (parser);
11067 if (c_parser_next_token_is_not (parser, CPP_NAME))
11068 {
11069 c_parser_error (parser, "expected identifier");
11070 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11071 return;
11072 }
11073 id2 = c_parser_peek_token (parser)->value;
11074 c_parser_consume_token (parser);
11075 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11076 objc_declare_alias (id1, id2);
11077}
11078
11079/* Parse an objc-protocol-definition.
11080
11081 objc-protocol-definition:
11082 @protocol identifier objc-protocol-refs[opt] objc-methodprotolist @end
11083 @protocol identifier-list ;
11084
11085 "@protocol identifier ;" should be resolved as "@protocol
11086 identifier-list ;": objc-methodprotolist may not start with a
11087 semicolon in the first alternative if objc-protocol-refs are
11088 omitted. */
11089
11090static void
c165dca7 11091c_parser_objc_protocol_definition (c_parser *parser, tree attributes)
27bf414c
JM
11092{
11093 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_PROTOCOL));
c165dca7 11094
27bf414c
JM
11095 c_parser_consume_token (parser);
11096 if (c_parser_next_token_is_not (parser, CPP_NAME))
11097 {
11098 c_parser_error (parser, "expected identifier");
11099 return;
11100 }
11101 if (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
11102 || c_parser_peek_2nd_token (parser)->type == CPP_SEMICOLON)
11103 {
27bf414c
JM
11104 /* Any identifiers, including those declared as type names, are
11105 OK here. */
11106 while (true)
11107 {
11108 tree id;
11109 if (c_parser_next_token_is_not (parser, CPP_NAME))
11110 {
11111 c_parser_error (parser, "expected identifier");
11112 break;
11113 }
11114 id = c_parser_peek_token (parser)->value;
c59633d9 11115 objc_declare_protocol (id, attributes);
27bf414c
JM
11116 c_parser_consume_token (parser);
11117 if (c_parser_next_token_is (parser, CPP_COMMA))
11118 c_parser_consume_token (parser);
11119 else
11120 break;
11121 }
11122 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
27bf414c
JM
11123 }
11124 else
11125 {
11126 tree id = c_parser_peek_token (parser)->value;
11127 tree proto = NULL_TREE;
11128 c_parser_consume_token (parser);
11129 if (c_parser_next_token_is (parser, CPP_LESS))
11130 proto = c_parser_objc_protocol_refs (parser);
0bacb8c7 11131 parser->objc_pq_context = true;
c165dca7 11132 objc_start_protocol (id, proto, attributes);
27bf414c
JM
11133 c_parser_objc_methodprotolist (parser);
11134 c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
0bacb8c7 11135 parser->objc_pq_context = false;
27bf414c
JM
11136 objc_finish_interface ();
11137 }
11138}
11139
11140/* Parse an objc-method-type.
11141
11142 objc-method-type:
11143 +
11144 -
27bf414c 11145
249a82c4
NP
11146 Return true if it is a class method (+) and false if it is
11147 an instance method (-).
11148*/
11149static inline bool
27bf414c
JM
11150c_parser_objc_method_type (c_parser *parser)
11151{
11152 switch (c_parser_peek_token (parser)->type)
11153 {
11154 case CPP_PLUS:
11155 c_parser_consume_token (parser);
249a82c4 11156 return true;
27bf414c
JM
11157 case CPP_MINUS:
11158 c_parser_consume_token (parser);
249a82c4 11159 return false;
27bf414c
JM
11160 default:
11161 gcc_unreachable ();
11162 }
11163}
11164
11165/* Parse an objc-method-definition.
11166
11167 objc-method-definition:
11168 objc-method-type objc-method-decl ;[opt] compound-statement
11169*/
11170
11171static void
11172c_parser_objc_method_definition (c_parser *parser)
11173{
249a82c4 11174 bool is_class_method = c_parser_objc_method_type (parser);
a04a722b 11175 tree decl, attributes = NULL_TREE, expr = NULL_TREE;
0bacb8c7 11176 parser->objc_pq_context = true;
a04a722b
JM
11177 decl = c_parser_objc_method_decl (parser, is_class_method, &attributes,
11178 &expr);
f7e71da5
IS
11179 if (decl == error_mark_node)
11180 return; /* Bail here. */
11181
27bf414c
JM
11182 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
11183 {
11184 c_parser_consume_token (parser);
c1771a20 11185 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
509c9d60 11186 "extra semicolon in method definition specified");
27bf414c 11187 }
f7e71da5 11188
8f078c08
AP
11189 if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE))
11190 {
11191 c_parser_error (parser, "expected %<{%>");
11192 return;
11193 }
f7e71da5 11194
0bacb8c7 11195 parser->objc_pq_context = false;
a04a722b 11196 if (objc_start_method_definition (is_class_method, decl, attributes, expr))
45547c7f
NP
11197 {
11198 add_stmt (c_parser_compound_statement (parser));
11199 objc_finish_method_definition (current_function_decl);
11200 }
11201 else
11202 {
11203 /* This code is executed when we find a method definition
a26d8862
NP
11204 outside of an @implementation context (or invalid for other
11205 reasons). Parse the method (to keep going) but do not emit
11206 any code.
45547c7f
NP
11207 */
11208 c_parser_compound_statement (parser);
11209 }
27bf414c
JM
11210}
11211
11212/* Parse an objc-methodprotolist.
11213
11214 objc-methodprotolist:
11215 empty
11216 objc-methodprotolist objc-methodproto
11217 objc-methodprotolist declaration
11218 objc-methodprotolist ;
92902b1b
IS
11219 @optional
11220 @required
27bf414c
JM
11221
11222 The declaration is a data definition, which may be missing
11223 declaration specifiers under the same rules and diagnostics as
11224 other data definitions outside functions, and the stray semicolon
11225 is diagnosed the same way as a stray semicolon outside a
11226 function. */
11227
11228static void
11229c_parser_objc_methodprotolist (c_parser *parser)
11230{
11231 while (true)
11232 {
11233 /* The list is terminated by @end. */
11234 switch (c_parser_peek_token (parser)->type)
11235 {
11236 case CPP_SEMICOLON:
c1771a20 11237 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
509c9d60 11238 "ISO C does not allow extra %<;%> outside of a function");
27bf414c
JM
11239 c_parser_consume_token (parser);
11240 break;
11241 case CPP_PLUS:
11242 case CPP_MINUS:
11243 c_parser_objc_methodproto (parser);
11244 break;
b9b58168 11245 case CPP_PRAGMA:
dda1bf61 11246 c_parser_pragma (parser, pragma_external, NULL);
b9b58168 11247 break;
27bf414c
JM
11248 case CPP_EOF:
11249 return;
11250 default:
11251 if (c_parser_next_token_is_keyword (parser, RID_AT_END))
11252 return;
668ea4b1 11253 else if (c_parser_next_token_is_keyword (parser, RID_AT_PROPERTY))
f614132b 11254 c_parser_objc_at_property_declaration (parser);
92902b1b
IS
11255 else if (c_parser_next_token_is_keyword (parser, RID_AT_OPTIONAL))
11256 {
11257 objc_set_method_opt (true);
11258 c_parser_consume_token (parser);
11259 }
11260 else if (c_parser_next_token_is_keyword (parser, RID_AT_REQUIRED))
11261 {
11262 objc_set_method_opt (false);
11263 c_parser_consume_token (parser);
11264 }
11265 else
11266 c_parser_declaration_or_fndef (parser, false, false, true,
acf0174b 11267 false, true, NULL, vNULL);
27bf414c
JM
11268 break;
11269 }
11270 }
11271}
11272
11273/* Parse an objc-methodproto.
11274
11275 objc-methodproto:
11276 objc-method-type objc-method-decl ;
11277*/
11278
11279static void
11280c_parser_objc_methodproto (c_parser *parser)
11281{
249a82c4 11282 bool is_class_method = c_parser_objc_method_type (parser);
f7e71da5 11283 tree decl, attributes = NULL_TREE;
249a82c4 11284
27bf414c 11285 /* Remember protocol qualifiers in prototypes. */
0bacb8c7 11286 parser->objc_pq_context = true;
a04a722b
JM
11287 decl = c_parser_objc_method_decl (parser, is_class_method, &attributes,
11288 NULL);
f7e71da5 11289 /* Forget protocol qualifiers now. */
0bacb8c7 11290 parser->objc_pq_context = false;
f7e71da5
IS
11291
11292 /* Do not allow the presence of attributes to hide an erroneous
11293 method implementation in the interface section. */
11294 if (!c_parser_next_token_is (parser, CPP_SEMICOLON))
11295 {
11296 c_parser_error (parser, "expected %<;%>");
11297 return;
11298 }
11299
11300 if (decl != error_mark_node)
249a82c4 11301 objc_add_method_declaration (is_class_method, decl, attributes);
f7e71da5 11302
27bf414c
JM
11303 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11304}
11305
f7e71da5
IS
11306/* If we are at a position that method attributes may be present, check that
11307 there are not any parsed already (a syntax error) and then collect any
11308 specified at the current location. Finally, if new attributes were present,
11309 check that the next token is legal ( ';' for decls and '{' for defs). */
11310
11311static bool
11312c_parser_objc_maybe_method_attributes (c_parser* parser, tree* attributes)
11313{
11314 bool bad = false;
11315 if (*attributes)
11316 {
11317 c_parser_error (parser,
11318 "method attributes must be specified at the end only");
11319 *attributes = NULL_TREE;
11320 bad = true;
11321 }
11322
11323 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
783bfe5e 11324 *attributes = c_parser_gnu_attributes (parser);
f7e71da5
IS
11325
11326 /* If there were no attributes here, just report any earlier error. */
11327 if (*attributes == NULL_TREE || bad)
11328 return bad;
11329
11330 /* If the attributes are followed by a ; or {, then just report any earlier
11331 error. */
11332 if (c_parser_next_token_is (parser, CPP_SEMICOLON)
11333 || c_parser_next_token_is (parser, CPP_OPEN_BRACE))
11334 return bad;
11335
11336 /* We've got attributes, but not at the end. */
11337 c_parser_error (parser,
11338 "expected %<;%> or %<{%> after method attribute definition");
11339 return true;
11340}
11341
27bf414c
JM
11342/* Parse an objc-method-decl.
11343
11344 objc-method-decl:
11345 ( objc-type-name ) objc-selector
11346 objc-selector
11347 ( objc-type-name ) objc-keyword-selector objc-optparmlist
11348 objc-keyword-selector objc-optparmlist
783bfe5e 11349 gnu-attributes
27bf414c
JM
11350
11351 objc-keyword-selector:
11352 objc-keyword-decl
11353 objc-keyword-selector objc-keyword-decl
11354
11355 objc-keyword-decl:
11356 objc-selector : ( objc-type-name ) identifier
11357 objc-selector : identifier
11358 : ( objc-type-name ) identifier
11359 : identifier
11360
11361 objc-optparmlist:
11362 objc-optparms objc-optellipsis
11363
11364 objc-optparms:
11365 empty
11366 objc-opt-parms , parameter-declaration
11367
11368 objc-optellipsis:
11369 empty
11370 , ...
11371*/
11372
11373static tree
a04a722b
JM
11374c_parser_objc_method_decl (c_parser *parser, bool is_class_method,
11375 tree *attributes, tree *expr)
27bf414c
JM
11376{
11377 tree type = NULL_TREE;
11378 tree sel;
11379 tree parms = NULL_TREE;
dbb74365 11380 bool ellipsis = false;
f7e71da5 11381 bool attr_err = false;
dbb74365 11382
f7e71da5 11383 *attributes = NULL_TREE;
27bf414c
JM
11384 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
11385 {
32129a17
DM
11386 matching_parens parens;
11387 parens.consume_open (parser);
27bf414c 11388 type = c_parser_objc_type_name (parser);
32129a17 11389 parens.skip_until_found_close (parser);
27bf414c
JM
11390 }
11391 sel = c_parser_objc_selector (parser);
11392 /* If there is no selector, or a colon follows, we have an
11393 objc-keyword-selector. If there is a selector, and a colon does
11394 not follow, that selector ends the objc-method-decl. */
11395 if (!sel || c_parser_next_token_is (parser, CPP_COLON))
11396 {
11397 tree tsel = sel;
11398 tree list = NULL_TREE;
27bf414c
JM
11399 while (true)
11400 {
11401 tree atype = NULL_TREE, id, keyworddecl;
f7e71da5 11402 tree param_attr = NULL_TREE;
27bf414c
JM
11403 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
11404 break;
11405 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
11406 {
11407 c_parser_consume_token (parser);
11408 atype = c_parser_objc_type_name (parser);
11409 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
11410 "expected %<)%>");
11411 }
f7e71da5
IS
11412 /* New ObjC allows attributes on method parameters. */
11413 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
783bfe5e 11414 param_attr = c_parser_gnu_attributes (parser);
27bf414c
JM
11415 if (c_parser_next_token_is_not (parser, CPP_NAME))
11416 {
11417 c_parser_error (parser, "expected identifier");
11418 return error_mark_node;
11419 }
11420 id = c_parser_peek_token (parser)->value;
11421 c_parser_consume_token (parser);
f7e71da5 11422 keyworddecl = objc_build_keyword_decl (tsel, atype, id, param_attr);
27bf414c
JM
11423 list = chainon (list, keyworddecl);
11424 tsel = c_parser_objc_selector (parser);
11425 if (!tsel && c_parser_next_token_is_not (parser, CPP_COLON))
11426 break;
11427 }
f7e71da5
IS
11428
11429 attr_err |= c_parser_objc_maybe_method_attributes (parser, attributes) ;
11430
27bf414c
JM
11431 /* Parse the optional parameter list. Optional Objective-C
11432 method parameters follow the C syntax, and may include '...'
11433 to denote a variable number of arguments. */
11434 parms = make_node (TREE_LIST);
27bf414c
JM
11435 while (c_parser_next_token_is (parser, CPP_COMMA))
11436 {
11437 struct c_parm *parm;
11438 c_parser_consume_token (parser);
11439 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
11440 {
11441 ellipsis = true;
11442 c_parser_consume_token (parser);
f7e71da5
IS
11443 attr_err |= c_parser_objc_maybe_method_attributes
11444 (parser, attributes) ;
27bf414c
JM
11445 break;
11446 }
4e03c3a7 11447 parm = c_parser_parameter_declaration (parser, NULL_TREE, false);
27bf414c
JM
11448 if (parm == NULL)
11449 break;
11450 parms = chainon (parms,
a04a722b 11451 build_tree_list (NULL_TREE, grokparm (parm, expr)));
27bf414c 11452 }
27bf414c
JM
11453 sel = list;
11454 }
f7e71da5
IS
11455 else
11456 attr_err |= c_parser_objc_maybe_method_attributes (parser, attributes) ;
11457
11458 if (sel == NULL)
11459 {
11460 c_parser_error (parser, "objective-c method declaration is expected");
11461 return error_mark_node;
11462 }
11463
11464 if (attr_err)
11465 return error_mark_node;
11466
249a82c4 11467 return objc_build_method_signature (is_class_method, type, sel, parms, ellipsis);
27bf414c
JM
11468}
11469
11470/* Parse an objc-type-name.
11471
11472 objc-type-name:
11473 objc-type-qualifiers[opt] type-name
11474 objc-type-qualifiers[opt]
11475
11476 objc-type-qualifiers:
11477 objc-type-qualifier
11478 objc-type-qualifiers objc-type-qualifier
11479
11480 objc-type-qualifier: one of
11481 in out inout bycopy byref oneway
11482*/
11483
11484static tree
11485c_parser_objc_type_name (c_parser *parser)
11486{
11487 tree quals = NULL_TREE;
d75d71e0 11488 struct c_type_name *type_name = NULL;
27bf414c
JM
11489 tree type = NULL_TREE;
11490 while (true)
11491 {
11492 c_token *token = c_parser_peek_token (parser);
11493 if (token->type == CPP_KEYWORD
11494 && (token->keyword == RID_IN
11495 || token->keyword == RID_OUT
11496 || token->keyword == RID_INOUT
11497 || token->keyword == RID_BYCOPY
11498 || token->keyword == RID_BYREF
11499 || token->keyword == RID_ONEWAY))
11500 {
71fc71d8 11501 quals = chainon (build_tree_list (NULL_TREE, token->value), quals);
27bf414c
JM
11502 c_parser_consume_token (parser);
11503 }
11504 else
11505 break;
11506 }
29ce73cb 11507 if (c_parser_next_tokens_start_typename (parser, cla_prefer_type))
d75d71e0
ILT
11508 type_name = c_parser_type_name (parser);
11509 if (type_name)
928c19bb 11510 type = groktypename (type_name, NULL, NULL);
046608a3
NP
11511
11512 /* If the type is unknown, and error has already been produced and
11513 we need to recover from the error. In that case, use NULL_TREE
11514 for the type, as if no type had been specified; this will use the
11515 default type ('id') which is good for error recovery. */
11516 if (type == error_mark_node)
11517 type = NULL_TREE;
11518
27bf414c
JM
11519 return build_tree_list (quals, type);
11520}
11521
11522/* Parse objc-protocol-refs.
11523
11524 objc-protocol-refs:
11525 < identifier-list >
11526*/
11527
11528static tree
11529c_parser_objc_protocol_refs (c_parser *parser)
11530{
11531 tree list = NULL_TREE;
11532 gcc_assert (c_parser_next_token_is (parser, CPP_LESS));
11533 c_parser_consume_token (parser);
11534 /* Any identifiers, including those declared as type names, are OK
11535 here. */
11536 while (true)
11537 {
11538 tree id;
11539 if (c_parser_next_token_is_not (parser, CPP_NAME))
11540 {
11541 c_parser_error (parser, "expected identifier");
11542 break;
11543 }
11544 id = c_parser_peek_token (parser)->value;
11545 list = chainon (list, build_tree_list (NULL_TREE, id));
11546 c_parser_consume_token (parser);
11547 if (c_parser_next_token_is (parser, CPP_COMMA))
11548 c_parser_consume_token (parser);
11549 else
11550 break;
11551 }
11552 c_parser_require (parser, CPP_GREATER, "expected %<>%>");
11553 return list;
11554}
11555
437c2322 11556/* Parse an objc-try-catch-finally-statement.
27bf414c 11557
437c2322 11558 objc-try-catch-finally-statement:
27bf414c
JM
11559 @try compound-statement objc-catch-list[opt]
11560 @try compound-statement objc-catch-list[opt] @finally compound-statement
11561
11562 objc-catch-list:
437c2322
NP
11563 @catch ( objc-catch-parameter-declaration ) compound-statement
11564 objc-catch-list @catch ( objc-catch-parameter-declaration ) compound-statement
11565
11566 objc-catch-parameter-declaration:
11567 parameter-declaration
11568 '...'
11569
11570 where '...' is to be interpreted literally, that is, it means CPP_ELLIPSIS.
11571
11572 PS: This function is identical to cp_parser_objc_try_catch_finally_statement
11573 for C++. Keep them in sync. */
27bf414c
JM
11574
11575static void
437c2322 11576c_parser_objc_try_catch_finally_statement (c_parser *parser)
27bf414c 11577{
437c2322 11578 location_t location;
27bf414c 11579 tree stmt;
437c2322 11580
49b91f05 11581 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_TRY));
27bf414c 11582 c_parser_consume_token (parser);
437c2322 11583 location = c_parser_peek_token (parser)->location;
46270f14 11584 objc_maybe_warn_exceptions (location);
27bf414c 11585 stmt = c_parser_compound_statement (parser);
437c2322
NP
11586 objc_begin_try_stmt (location, stmt);
11587
49b91f05 11588 while (c_parser_next_token_is_keyword (parser, RID_AT_CATCH))
27bf414c
JM
11589 {
11590 struct c_parm *parm;
437c2322
NP
11591 tree parameter_declaration = error_mark_node;
11592 bool seen_open_paren = false;
11593
27bf414c 11594 c_parser_consume_token (parser);
32129a17
DM
11595 matching_parens parens;
11596 if (!parens.require_open (parser))
437c2322
NP
11597 seen_open_paren = true;
11598 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
27bf414c 11599 {
437c2322
NP
11600 /* We have "@catch (...)" (where the '...' are literally
11601 what is in the code). Skip the '...'.
11602 parameter_declaration is set to NULL_TREE, and
11603 objc_being_catch_clauses() knows that that means
11604 '...'. */
11605 c_parser_consume_token (parser);
11606 parameter_declaration = NULL_TREE;
27bf414c 11607 }
437c2322
NP
11608 else
11609 {
11610 /* We have "@catch (NSException *exception)" or something
11611 like that. Parse the parameter declaration. */
4e03c3a7 11612 parm = c_parser_parameter_declaration (parser, NULL_TREE, false);
437c2322
NP
11613 if (parm == NULL)
11614 parameter_declaration = error_mark_node;
11615 else
a04a722b 11616 parameter_declaration = grokparm (parm, NULL);
437c2322
NP
11617 }
11618 if (seen_open_paren)
32129a17 11619 parens.require_close (parser);
437c2322
NP
11620 else
11621 {
11622 /* If there was no open parenthesis, we are recovering from
11623 an error, and we are trying to figure out what mistake
11624 the user has made. */
11625
11626 /* If there is an immediate closing parenthesis, the user
11627 probably forgot the opening one (ie, they typed "@catch
11628 NSException *e)". Parse the closing parenthesis and keep
11629 going. */
11630 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
11631 c_parser_consume_token (parser);
11632
11633 /* If these is no immediate closing parenthesis, the user
11634 probably doesn't know that parenthesis are required at
11635 all (ie, they typed "@catch NSException *e"). So, just
11636 forget about the closing parenthesis and keep going. */
11637 }
11638 objc_begin_catch_clause (parameter_declaration);
27bf414c
JM
11639 if (c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
11640 c_parser_compound_statement_nostart (parser);
11641 objc_finish_catch_clause ();
11642 }
11643 if (c_parser_next_token_is_keyword (parser, RID_AT_FINALLY))
11644 {
27bf414c 11645 c_parser_consume_token (parser);
437c2322
NP
11646 location = c_parser_peek_token (parser)->location;
11647 stmt = c_parser_compound_statement (parser);
11648 objc_build_finally_clause (location, stmt);
27bf414c
JM
11649 }
11650 objc_finish_try_stmt ();
11651}
11652
11653/* Parse an objc-synchronized-statement.
11654
11655 objc-synchronized-statement:
11656 @synchronized ( expression ) compound-statement
11657*/
11658
11659static void
11660c_parser_objc_synchronized_statement (c_parser *parser)
11661{
11662 location_t loc;
11663 tree expr, stmt;
11664 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_SYNCHRONIZED));
11665 c_parser_consume_token (parser);
11666 loc = c_parser_peek_token (parser)->location;
46270f14 11667 objc_maybe_warn_exceptions (loc);
32129a17
DM
11668 matching_parens parens;
11669 if (parens.require_open (parser))
27bf414c 11670 {
267bac10
JM
11671 struct c_expr ce = c_parser_expression (parser);
11672 ce = convert_lvalue_to_rvalue (loc, ce, false, false);
11673 expr = ce.value;
928c19bb 11674 expr = c_fully_fold (expr, false, NULL);
32129a17 11675 parens.skip_until_found_close (parser);
27bf414c
JM
11676 }
11677 else
11678 expr = error_mark_node;
11679 stmt = c_parser_compound_statement (parser);
11680 objc_build_synchronized (loc, expr, stmt);
11681}
11682
11683/* Parse an objc-selector; return NULL_TREE without an error if the
11684 next token is not an objc-selector.
11685
11686 objc-selector:
11687 identifier
11688 one of
11689 enum struct union if else while do for switch case default
11690 break continue return goto asm sizeof typeof __alignof
11691 unsigned long const short volatile signed restrict _Complex
11692 in out inout bycopy byref oneway int char float double void _Bool
267bac10 11693 _Atomic
27bf414c
JM
11694
11695 ??? Why this selection of keywords but not, for example, storage
11696 class specifiers? */
11697
11698static tree
11699c_parser_objc_selector (c_parser *parser)
11700{
11701 c_token *token = c_parser_peek_token (parser);
11702 tree value = token->value;
11703 if (token->type == CPP_NAME)
11704 {
11705 c_parser_consume_token (parser);
11706 return value;
11707 }
11708 if (token->type != CPP_KEYWORD)
11709 return NULL_TREE;
11710 switch (token->keyword)
11711 {
11712 case RID_ENUM:
11713 case RID_STRUCT:
11714 case RID_UNION:
11715 case RID_IF:
11716 case RID_ELSE:
11717 case RID_WHILE:
11718 case RID_DO:
11719 case RID_FOR:
11720 case RID_SWITCH:
11721 case RID_CASE:
11722 case RID_DEFAULT:
11723 case RID_BREAK:
11724 case RID_CONTINUE:
11725 case RID_RETURN:
11726 case RID_GOTO:
11727 case RID_ASM:
11728 case RID_SIZEOF:
11729 case RID_TYPEOF:
11730 case RID_ALIGNOF:
11731 case RID_UNSIGNED:
11732 case RID_LONG:
11733 case RID_CONST:
11734 case RID_SHORT:
11735 case RID_VOLATILE:
11736 case RID_SIGNED:
11737 case RID_RESTRICT:
11738 case RID_COMPLEX:
11739 case RID_IN:
11740 case RID_OUT:
11741 case RID_INOUT:
11742 case RID_BYCOPY:
11743 case RID_BYREF:
11744 case RID_ONEWAY:
11745 case RID_INT:
11746 case RID_CHAR:
11747 case RID_FLOAT:
11748 case RID_DOUBLE:
c65699ef 11749 CASE_RID_FLOATN_NX:
27bf414c
JM
11750 case RID_VOID:
11751 case RID_BOOL:
267bac10 11752 case RID_ATOMIC:
38b7bc7f 11753 case RID_AUTO_TYPE:
78a7c317
DD
11754 case RID_INT_N_0:
11755 case RID_INT_N_1:
11756 case RID_INT_N_2:
11757 case RID_INT_N_3:
27bf414c
JM
11758 c_parser_consume_token (parser);
11759 return value;
11760 default:
11761 return NULL_TREE;
11762 }
11763}
11764
11765/* Parse an objc-selector-arg.
11766
11767 objc-selector-arg:
11768 objc-selector
11769 objc-keywordname-list
11770
11771 objc-keywordname-list:
11772 objc-keywordname
11773 objc-keywordname-list objc-keywordname
11774
11775 objc-keywordname:
11776 objc-selector :
11777 :
11778*/
11779
11780static tree
11781c_parser_objc_selector_arg (c_parser *parser)
11782{
11783 tree sel = c_parser_objc_selector (parser);
11784 tree list = NULL_TREE;
11785 if (sel && c_parser_next_token_is_not (parser, CPP_COLON))
11786 return sel;
11787 while (true)
11788 {
11789 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
11790 return list;
11791 list = chainon (list, build_tree_list (sel, NULL_TREE));
11792 sel = c_parser_objc_selector (parser);
11793 if (!sel && c_parser_next_token_is_not (parser, CPP_COLON))
11794 break;
11795 }
11796 return list;
11797}
11798
11799/* Parse an objc-receiver.
11800
11801 objc-receiver:
11802 expression
11803 class-name
11804 type-name
11805*/
11806
11807static tree
11808c_parser_objc_receiver (c_parser *parser)
11809{
267bac10
JM
11810 location_t loc = c_parser_peek_token (parser)->location;
11811
27bf414c
JM
11812 if (c_parser_peek_token (parser)->type == CPP_NAME
11813 && (c_parser_peek_token (parser)->id_kind == C_ID_TYPENAME
11814 || c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME))
11815 {
11816 tree id = c_parser_peek_token (parser)->value;
11817 c_parser_consume_token (parser);
11818 return objc_get_class_reference (id);
11819 }
267bac10
JM
11820 struct c_expr ce = c_parser_expression (parser);
11821 ce = convert_lvalue_to_rvalue (loc, ce, false, false);
11822 return c_fully_fold (ce.value, false, NULL);
27bf414c
JM
11823}
11824
11825/* Parse objc-message-args.
11826
11827 objc-message-args:
11828 objc-selector
11829 objc-keywordarg-list
11830
11831 objc-keywordarg-list:
11832 objc-keywordarg
11833 objc-keywordarg-list objc-keywordarg
11834
11835 objc-keywordarg:
11836 objc-selector : objc-keywordexpr
11837 : objc-keywordexpr
11838*/
11839
11840static tree
11841c_parser_objc_message_args (c_parser *parser)
11842{
11843 tree sel = c_parser_objc_selector (parser);
11844 tree list = NULL_TREE;
11845 if (sel && c_parser_next_token_is_not (parser, CPP_COLON))
11846 return sel;
11847 while (true)
11848 {
11849 tree keywordexpr;
11850 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
0a7d7dea 11851 return error_mark_node;
27bf414c
JM
11852 keywordexpr = c_parser_objc_keywordexpr (parser);
11853 list = chainon (list, build_tree_list (sel, keywordexpr));
11854 sel = c_parser_objc_selector (parser);
11855 if (!sel && c_parser_next_token_is_not (parser, CPP_COLON))
11856 break;
11857 }
11858 return list;
11859}
11860
11861/* Parse an objc-keywordexpr.
11862
11863 objc-keywordexpr:
11864 nonempty-expr-list
11865*/
11866
11867static tree
11868c_parser_objc_keywordexpr (c_parser *parser)
11869{
bbbbb16a 11870 tree ret;
9771b263 11871 vec<tree, va_gc> *expr_list = c_parser_expr_list (parser, true, true,
81e5eca8 11872 NULL, NULL, NULL, NULL);
9771b263 11873 if (vec_safe_length (expr_list) == 1)
27bf414c
JM
11874 {
11875 /* Just return the expression, remove a level of
11876 indirection. */
9771b263 11877 ret = (*expr_list)[0];
27bf414c
JM
11878 }
11879 else
11880 {
11881 /* We have a comma expression, we will collapse later. */
c166b898 11882 ret = build_tree_list_vec (expr_list);
27bf414c 11883 }
c166b898 11884 release_tree_vector (expr_list);
bbbbb16a 11885 return ret;
27bf414c
JM
11886}
11887
c165dca7
IS
11888/* A check, needed in several places, that ObjC interface, implementation or
11889 method definitions are not prefixed by incorrect items. */
11890static bool
11891c_parser_objc_diagnose_bad_element_prefix (c_parser *parser,
11892 struct c_declspecs *specs)
11893{
9e5b2115
PB
11894 if (!specs->declspecs_seen_p || specs->non_sc_seen_p
11895 || specs->typespec_kind != ctsk_none)
c165dca7
IS
11896 {
11897 c_parser_error (parser,
11898 "no type or storage class may be specified here,");
11899 c_parser_skip_to_end_of_block_or_statement (parser);
11900 return true;
11901 }
11902 return false;
11903}
668ea4b1 11904
f614132b 11905/* Parse an Objective-C @property declaration. The syntax is:
668ea4b1 11906
f614132b
NP
11907 objc-property-declaration:
11908 '@property' objc-property-attributes[opt] struct-declaration ;
668ea4b1 11909
f614132b
NP
11910 objc-property-attributes:
11911 '(' objc-property-attribute-list ')'
11912
11913 objc-property-attribute-list:
11914 objc-property-attribute
11915 objc-property-attribute-list, objc-property-attribute
11916
11917 objc-property-attribute
11918 'getter' = identifier
11919 'setter' = identifier
11920 'readonly'
11921 'readwrite'
11922 'assign'
11923 'retain'
11924 'copy'
11925 'nonatomic'
11926
11927 For example:
11928 @property NSString *name;
11929 @property (readonly) id object;
11930 @property (retain, nonatomic, getter=getTheName) id name;
11931 @property int a, b, c;
11932
11933 PS: This function is identical to cp_parser_objc_at_propery_declaration
200290f2 11934 for C++. Keep them in sync. */
668ea4b1 11935static void
f614132b 11936c_parser_objc_at_property_declaration (c_parser *parser)
668ea4b1 11937{
200290f2
NP
11938 /* The following variables hold the attributes of the properties as
11939 parsed. They are 'false' or 'NULL_TREE' if the attribute was not
11940 seen. When we see an attribute, we set them to 'true' (if they
11941 are boolean properties) or to the identifier (if they have an
11942 argument, ie, for getter and setter). Note that here we only
11943 parse the list of attributes, check the syntax and accumulate the
11944 attributes that we find. objc_add_property_declaration() will
11945 then process the information. */
11946 bool property_assign = false;
11947 bool property_copy = false;
11948 tree property_getter_ident = NULL_TREE;
11949 bool property_nonatomic = false;
11950 bool property_readonly = false;
11951 bool property_readwrite = false;
11952 bool property_retain = false;
11953 tree property_setter_ident = NULL_TREE;
200290f2
NP
11954
11955 /* 'properties' is the list of properties that we read. Usually a
11956 single one, but maybe more (eg, in "@property int a, b, c;" there
11957 are three). */
f614132b
NP
11958 tree properties;
11959 location_t loc;
200290f2 11960
f614132b
NP
11961 loc = c_parser_peek_token (parser)->location;
11962 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_PROPERTY));
668ea4b1 11963
f614132b 11964 c_parser_consume_token (parser); /* Eat '@property'. */
668ea4b1 11965
f614132b
NP
11966 /* Parse the optional attribute list... */
11967 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
668ea4b1 11968 {
32129a17
DM
11969 matching_parens parens;
11970
f614132b 11971 /* Eat the '(' */
32129a17
DM
11972 parens.consume_open (parser);
11973
f614132b
NP
11974 /* Property attribute keywords are valid now. */
11975 parser->objc_property_attr_context = true;
11976
11977 while (true)
668ea4b1 11978 {
f614132b
NP
11979 bool syntax_error = false;
11980 c_token *token = c_parser_peek_token (parser);
11981 enum rid keyword;
11982
11983 if (token->type != CPP_KEYWORD)
11984 {
11985 if (token->type == CPP_CLOSE_PAREN)
11986 c_parser_error (parser, "expected identifier");
11987 else
11988 {
11989 c_parser_consume_token (parser);
11990 c_parser_error (parser, "unknown property attribute");
11991 }
11992 break;
11993 }
11994 keyword = token->keyword;
200290f2 11995 c_parser_consume_token (parser);
f614132b
NP
11996 switch (keyword)
11997 {
200290f2 11998 case RID_ASSIGN: property_assign = true; break;
200290f2
NP
11999 case RID_COPY: property_copy = true; break;
12000 case RID_NONATOMIC: property_nonatomic = true; break;
12001 case RID_READONLY: property_readonly = true; break;
12002 case RID_READWRITE: property_readwrite = true; break;
12003 case RID_RETAIN: property_retain = true; break;
12004
f614132b
NP
12005 case RID_GETTER:
12006 case RID_SETTER:
f614132b
NP
12007 if (c_parser_next_token_is_not (parser, CPP_EQ))
12008 {
d853ee42
NP
12009 if (keyword == RID_GETTER)
12010 c_parser_error (parser,
12011 "missing %<=%> (after %<getter%> attribute)");
12012 else
12013 c_parser_error (parser,
12014 "missing %<=%> (after %<setter%> attribute)");
f614132b
NP
12015 syntax_error = true;
12016 break;
12017 }
12018 c_parser_consume_token (parser); /* eat the = */
12019 if (c_parser_next_token_is_not (parser, CPP_NAME))
12020 {
12021 c_parser_error (parser, "expected identifier");
12022 syntax_error = true;
12023 break;
12024 }
f614132b
NP
12025 if (keyword == RID_SETTER)
12026 {
200290f2
NP
12027 if (property_setter_ident != NULL_TREE)
12028 c_parser_error (parser, "the %<setter%> attribute may only be specified once");
12029 else
12030 property_setter_ident = c_parser_peek_token (parser)->value;
f614132b 12031 c_parser_consume_token (parser);
200290f2
NP
12032 if (c_parser_next_token_is_not (parser, CPP_COLON))
12033 c_parser_error (parser, "setter name must terminate with %<:%>");
12034 else
12035 c_parser_consume_token (parser);
f614132b 12036 }
46a88c12 12037 else
f614132b 12038 {
200290f2
NP
12039 if (property_getter_ident != NULL_TREE)
12040 c_parser_error (parser, "the %<getter%> attribute may only be specified once");
12041 else
12042 property_getter_ident = c_parser_peek_token (parser)->value;
f614132b 12043 c_parser_consume_token (parser);
f614132b 12044 }
200290f2
NP
12045 break;
12046 default:
12047 c_parser_error (parser, "unknown property attribute");
f614132b
NP
12048 syntax_error = true;
12049 break;
12050 }
12051
12052 if (syntax_error)
668ea4b1 12053 break;
f614132b
NP
12054
12055 if (c_parser_next_token_is (parser, CPP_COMMA))
668ea4b1 12056 c_parser_consume_token (parser);
f614132b 12057 else
668ea4b1
IS
12058 break;
12059 }
f614132b 12060 parser->objc_property_attr_context = false;
32129a17 12061 parens.skip_until_found_close (parser);
f614132b
NP
12062 }
12063 /* ... and the property declaration(s). */
12064 properties = c_parser_struct_declaration (parser);
668ea4b1 12065
f614132b
NP
12066 if (properties == error_mark_node)
12067 {
12068 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12069 parser->error = false;
12070 return;
12071 }
668ea4b1 12072
f614132b
NP
12073 if (properties == NULL_TREE)
12074 c_parser_error (parser, "expected identifier");
12075 else
12076 {
12077 /* Comma-separated properties are chained together in
12078 reverse order; add them one by one. */
12079 properties = nreverse (properties);
12080
12081 for (; properties; properties = TREE_CHAIN (properties))
200290f2
NP
12082 objc_add_property_declaration (loc, copy_node (properties),
12083 property_readonly, property_readwrite,
12084 property_assign, property_retain,
12085 property_copy, property_nonatomic,
46a88c12 12086 property_getter_ident, property_setter_ident);
f614132b 12087 }
668ea4b1
IS
12088
12089 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
f614132b 12090 parser->error = false;
668ea4b1
IS
12091}
12092
da57d1b9
NP
12093/* Parse an Objective-C @synthesize declaration. The syntax is:
12094
12095 objc-synthesize-declaration:
12096 @synthesize objc-synthesize-identifier-list ;
12097
12098 objc-synthesize-identifier-list:
12099 objc-synthesize-identifier
12100 objc-synthesize-identifier-list, objc-synthesize-identifier
12101
12102 objc-synthesize-identifier
12103 identifier
12104 identifier = identifier
12105
12106 For example:
12107 @synthesize MyProperty;
12108 @synthesize OneProperty, AnotherProperty=MyIvar, YetAnotherProperty;
12109
12110 PS: This function is identical to cp_parser_objc_at_synthesize_declaration
12111 for C++. Keep them in sync.
12112*/
12113static void
12114c_parser_objc_at_synthesize_declaration (c_parser *parser)
12115{
12116 tree list = NULL_TREE;
12117 location_t loc;
12118 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_SYNTHESIZE));
12119 loc = c_parser_peek_token (parser)->location;
12120
12121 c_parser_consume_token (parser);
12122 while (true)
12123 {
12124 tree property, ivar;
12125 if (c_parser_next_token_is_not (parser, CPP_NAME))
12126 {
12127 c_parser_error (parser, "expected identifier");
12128 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12129 /* Once we find the semicolon, we can resume normal parsing.
12130 We have to reset parser->error manually because
12131 c_parser_skip_until_found() won't reset it for us if the
12132 next token is precisely a semicolon. */
12133 parser->error = false;
12134 return;
12135 }
12136 property = c_parser_peek_token (parser)->value;
12137 c_parser_consume_token (parser);
12138 if (c_parser_next_token_is (parser, CPP_EQ))
12139 {
12140 c_parser_consume_token (parser);
12141 if (c_parser_next_token_is_not (parser, CPP_NAME))
12142 {
12143 c_parser_error (parser, "expected identifier");
12144 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12145 parser->error = false;
12146 return;
12147 }
12148 ivar = c_parser_peek_token (parser)->value;
12149 c_parser_consume_token (parser);
12150 }
12151 else
12152 ivar = NULL_TREE;
12153 list = chainon (list, build_tree_list (ivar, property));
12154 if (c_parser_next_token_is (parser, CPP_COMMA))
12155 c_parser_consume_token (parser);
12156 else
12157 break;
12158 }
12159 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
12160 objc_add_synthesize_declaration (loc, list);
12161}
12162
12163/* Parse an Objective-C @dynamic declaration. The syntax is:
12164
12165 objc-dynamic-declaration:
12166 @dynamic identifier-list ;
12167
12168 For example:
12169 @dynamic MyProperty;
12170 @dynamic MyProperty, AnotherProperty;
12171
12172 PS: This function is identical to cp_parser_objc_at_dynamic_declaration
12173 for C++. Keep them in sync.
12174*/
12175static void
12176c_parser_objc_at_dynamic_declaration (c_parser *parser)
12177{
12178 tree list = NULL_TREE;
12179 location_t loc;
12180 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_DYNAMIC));
12181 loc = c_parser_peek_token (parser)->location;
12182
12183 c_parser_consume_token (parser);
12184 while (true)
12185 {
12186 tree property;
12187 if (c_parser_next_token_is_not (parser, CPP_NAME))
12188 {
12189 c_parser_error (parser, "expected identifier");
12190 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12191 parser->error = false;
12192 return;
12193 }
12194 property = c_parser_peek_token (parser)->value;
12195 list = chainon (list, build_tree_list (NULL_TREE, property));
12196 c_parser_consume_token (parser);
12197 if (c_parser_next_token_is (parser, CPP_COMMA))
12198 c_parser_consume_token (parser);
12199 else
12200 break;
12201 }
12202 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
12203 objc_add_dynamic_declaration (loc, list);
12204}
12205
27bf414c 12206\f
170a8bd6
EB
12207/* Parse a pragma GCC ivdep. */
12208
12209static bool
12210c_parse_pragma_ivdep (c_parser *parser)
12211{
12212 c_parser_consume_pragma (parser);
12213 c_parser_skip_to_pragma_eol (parser);
12214 return true;
12215}
12216
12217/* Parse a pragma GCC unroll. */
12218
12219static unsigned short
12220c_parser_pragma_unroll (c_parser *parser)
12221{
12222 unsigned short unroll;
12223 c_parser_consume_pragma (parser);
12224 location_t location = c_parser_peek_token (parser)->location;
12225 tree expr = c_parser_expr_no_commas (parser, NULL).value;
12226 mark_exp_read (expr);
12227 expr = c_fully_fold (expr, false, NULL);
12228 HOST_WIDE_INT lunroll = 0;
12229 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr))
12230 || TREE_CODE (expr) != INTEGER_CST
12231 || (lunroll = tree_to_shwi (expr)) < 0
12232 || lunroll >= USHRT_MAX)
12233 {
12234 error_at (location, "%<#pragma GCC unroll%> requires an"
12235 " assignment-expression that evaluates to a non-negative"
12236 " integral constant less than %u", USHRT_MAX);
12237 unroll = 0;
12238 }
12239 else
12240 {
12241 unroll = (unsigned short)lunroll;
12242 if (unroll == 0)
12243 unroll = 1;
12244 }
12245
12246 c_parser_skip_to_pragma_eol (parser);
12247 return unroll;
12248}
12249
953ff289
DN
12250/* Handle pragmas. Some OpenMP pragmas are associated with, and therefore
12251 should be considered, statements. ALLOW_STMT is true if we're within
12252 the context of a function and such pragmas are to be allowed. Returns
12253 true if we actually parsed such a pragma. */
27bf414c 12254
bc4071dd 12255static bool
dda1bf61 12256c_parser_pragma (c_parser *parser, enum pragma_context context, bool *if_p)
bc4071dd
RH
12257{
12258 unsigned int id;
a71dbc63 12259 const char *construct = NULL;
bc4071dd
RH
12260
12261 id = c_parser_peek_token (parser)->pragma_kind;
12262 gcc_assert (id != PRAGMA_NONE);
12263
12264 switch (id)
12265 {
6e232ba4
JN
12266 case PRAGMA_OACC_DECLARE:
12267 c_parser_oacc_declare (parser);
12268 return false;
12269
41dbbb37 12270 case PRAGMA_OACC_ENTER_DATA:
c5af52eb
CP
12271 if (context != pragma_compound)
12272 {
a71dbc63
JJ
12273 construct = "acc enter data";
12274 in_compound:
c5af52eb 12275 if (context == pragma_stmt)
a71dbc63
JJ
12276 {
12277 error_at (c_parser_peek_token (parser)->location,
12278 "%<#pragma %s%> may only be used in compound "
12279 "statements", construct);
12280 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12281 return false;
12282 }
c5af52eb
CP
12283 goto bad_stmt;
12284 }
41dbbb37
TS
12285 c_parser_oacc_enter_exit_data (parser, true);
12286 return false;
12287
12288 case PRAGMA_OACC_EXIT_DATA:
c5af52eb
CP
12289 if (context != pragma_compound)
12290 {
a71dbc63
JJ
12291 construct = "acc exit data";
12292 goto in_compound;
c5af52eb 12293 }
41dbbb37
TS
12294 c_parser_oacc_enter_exit_data (parser, false);
12295 return false;
12296
3a40d81d 12297 case PRAGMA_OACC_ROUTINE:
ae9281fc
TS
12298 if (context != pragma_external)
12299 {
12300 error_at (c_parser_peek_token (parser)->location,
12301 "%<#pragma acc routine%> must be at file scope");
12302 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12303 return false;
12304 }
3a40d81d
NS
12305 c_parser_oacc_routine (parser, context);
12306 return false;
12307
41dbbb37
TS
12308 case PRAGMA_OACC_UPDATE:
12309 if (context != pragma_compound)
12310 {
a71dbc63
JJ
12311 construct = "acc update";
12312 goto in_compound;
41dbbb37
TS
12313 }
12314 c_parser_oacc_update (parser);
12315 return false;
12316
953ff289
DN
12317 case PRAGMA_OMP_BARRIER:
12318 if (context != pragma_compound)
12319 {
a71dbc63
JJ
12320 construct = "omp barrier";
12321 goto in_compound;
953ff289
DN
12322 }
12323 c_parser_omp_barrier (parser);
12324 return false;
12325
28567c40
JJ
12326 case PRAGMA_OMP_DEPOBJ:
12327 if (context != pragma_compound)
12328 {
12329 construct = "omp depobj";
12330 goto in_compound;
12331 }
12332 c_parser_omp_depobj (parser);
12333 return false;
12334
953ff289
DN
12335 case PRAGMA_OMP_FLUSH:
12336 if (context != pragma_compound)
12337 {
a71dbc63
JJ
12338 construct = "omp flush";
12339 goto in_compound;
953ff289
DN
12340 }
12341 c_parser_omp_flush (parser);
12342 return false;
12343
a68ab351
JJ
12344 case PRAGMA_OMP_TASKWAIT:
12345 if (context != pragma_compound)
12346 {
a71dbc63
JJ
12347 construct = "omp taskwait";
12348 goto in_compound;
a68ab351
JJ
12349 }
12350 c_parser_omp_taskwait (parser);
12351 return false;
12352
20906c66
JJ
12353 case PRAGMA_OMP_TASKYIELD:
12354 if (context != pragma_compound)
12355 {
a71dbc63
JJ
12356 construct = "omp taskyield";
12357 goto in_compound;
20906c66
JJ
12358 }
12359 c_parser_omp_taskyield (parser);
12360 return false;
12361
acf0174b
JJ
12362 case PRAGMA_OMP_CANCEL:
12363 if (context != pragma_compound)
12364 {
a71dbc63
JJ
12365 construct = "omp cancel";
12366 goto in_compound;
acf0174b
JJ
12367 }
12368 c_parser_omp_cancel (parser);
12369 return false;
12370
12371 case PRAGMA_OMP_CANCELLATION_POINT:
54d19c3b 12372 c_parser_omp_cancellation_point (parser, context);
acf0174b
JJ
12373 return false;
12374
953ff289
DN
12375 case PRAGMA_OMP_THREADPRIVATE:
12376 c_parser_omp_threadprivate (parser);
12377 return false;
12378
acf0174b 12379 case PRAGMA_OMP_TARGET:
dda1bf61 12380 return c_parser_omp_target (parser, context, if_p);
acf0174b
JJ
12381
12382 case PRAGMA_OMP_END_DECLARE_TARGET:
12383 c_parser_omp_end_declare_target (parser);
12384 return false;
12385
bf38f7e9
JJ
12386 case PRAGMA_OMP_SCAN:
12387 error_at (c_parser_peek_token (parser)->location,
12388 "%<#pragma omp scan%> may only be used in "
12389 "a loop construct with %<inscan%> %<reduction%> clause");
12390 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12391 return false;
12392
953ff289 12393 case PRAGMA_OMP_SECTION:
3ba09659
AH
12394 error_at (c_parser_peek_token (parser)->location,
12395 "%<#pragma omp section%> may only be used in "
12396 "%<#pragma omp sections%> construct");
953ff289
DN
12397 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12398 return false;
12399
f9d8d994 12400 case PRAGMA_OMP_DECLARE:
acf0174b
JJ
12401 c_parser_omp_declare (parser, context);
12402 return false;
d9a6bd32 12403
28567c40
JJ
12404 case PRAGMA_OMP_REQUIRES:
12405 c_parser_omp_requires (parser);
12406 return false;
12407
d9a6bd32 12408 case PRAGMA_OMP_ORDERED:
dda1bf61 12409 return c_parser_omp_ordered (parser, context, if_p);
d9a6bd32 12410
8170608b 12411 case PRAGMA_IVDEP:
170a8bd6
EB
12412 {
12413 const bool ivdep = c_parse_pragma_ivdep (parser);
12414 unsigned short unroll;
12415 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_UNROLL)
12416 unroll = c_parser_pragma_unroll (parser);
12417 else
12418 unroll = 0;
12419 if (!c_parser_next_token_is_keyword (parser, RID_FOR)
12420 && !c_parser_next_token_is_keyword (parser, RID_WHILE)
12421 && !c_parser_next_token_is_keyword (parser, RID_DO))
12422 {
12423 c_parser_error (parser, "for, while or do statement expected");
12424 return false;
12425 }
12426 if (c_parser_next_token_is_keyword (parser, RID_FOR))
12427 c_parser_for_statement (parser, ivdep, unroll, if_p);
12428 else if (c_parser_next_token_is_keyword (parser, RID_WHILE))
12429 c_parser_while_statement (parser, ivdep, unroll, if_p);
12430 else
12431 c_parser_do_statement (parser, ivdep, unroll);
12432 }
12433 return false;
12434
12435 case PRAGMA_UNROLL:
12436 {
12437 unsigned short unroll = c_parser_pragma_unroll (parser);
12438 bool ivdep;
12439 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_IVDEP)
12440 ivdep = c_parse_pragma_ivdep (parser);
12441 else
12442 ivdep = false;
12443 if (!c_parser_next_token_is_keyword (parser, RID_FOR)
12444 && !c_parser_next_token_is_keyword (parser, RID_WHILE)
12445 && !c_parser_next_token_is_keyword (parser, RID_DO))
12446 {
12447 c_parser_error (parser, "for, while or do statement expected");
12448 return false;
12449 }
12450 if (c_parser_next_token_is_keyword (parser, RID_FOR))
12451 c_parser_for_statement (parser, ivdep, unroll, if_p);
12452 else if (c_parser_next_token_is_keyword (parser, RID_WHILE))
12453 c_parser_while_statement (parser, ivdep, unroll, if_p);
12454 else
12455 c_parser_do_statement (parser, ivdep, unroll);
12456 }
8170608b 12457 return false;
acf0174b 12458
bc4071dd
RH
12459 case PRAGMA_GCC_PCH_PREPROCESS:
12460 c_parser_error (parser, "%<#pragma GCC pch_preprocess%> must be first");
12461 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12462 return false;
12463
c5af52eb
CP
12464 case PRAGMA_OACC_WAIT:
12465 if (context != pragma_compound)
12466 {
a71dbc63
JJ
12467 construct = "acc wait";
12468 goto in_compound;
c5af52eb
CP
12469 }
12470 /* FALL THROUGH. */
12471
bc4071dd 12472 default:
953ff289
DN
12473 if (id < PRAGMA_FIRST_EXTERNAL)
12474 {
acf0174b 12475 if (context != pragma_stmt && context != pragma_compound)
953ff289
DN
12476 {
12477 bad_stmt:
12478 c_parser_error (parser, "expected declaration specifiers");
12479 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12480 return false;
12481 }
dda1bf61 12482 c_parser_omp_construct (parser, if_p);
953ff289
DN
12483 return true;
12484 }
bc4071dd
RH
12485 break;
12486 }
12487
12488 c_parser_consume_pragma (parser);
12489 c_invoke_pragma_handler (id);
27bf414c 12490
b8698a0f 12491 /* Skip to EOL, but suppress any error message. Those will have been
bc4071dd
RH
12492 generated by the handler routine through calling error, as opposed
12493 to calling c_parser_error. */
12494 parser->error = true;
12495 c_parser_skip_to_pragma_eol (parser);
12496
12497 return false;
12498}
12499
12500/* The interface the pragma parsers have to the lexer. */
12501
12502enum cpp_ttype
c4914de6 12503pragma_lex (tree *value, location_t *loc)
bc4071dd
RH
12504{
12505 c_token *tok = c_parser_peek_token (the_parser);
12506 enum cpp_ttype ret = tok->type;
12507
12508 *value = tok->value;
c4914de6
MLI
12509 if (loc)
12510 *loc = tok->location;
12511
bc4071dd
RH
12512 if (ret == CPP_PRAGMA_EOL || ret == CPP_EOF)
12513 ret = CPP_EOF;
471c5330
JM
12514 else if (ret == CPP_STRING)
12515 *value = c_parser_string_literal (the_parser, false, false).value;
bc4071dd
RH
12516 else
12517 {
12518 if (ret == CPP_KEYWORD)
12519 ret = CPP_NAME;
12520 c_parser_consume_token (the_parser);
12521 }
12522
12523 return ret;
12524}
12525
12526static void
12527c_parser_pragma_pch_preprocess (c_parser *parser)
12528{
12529 tree name = NULL;
12530
471c5330 12531 parser->lex_joined_string = true;
bc4071dd
RH
12532 c_parser_consume_pragma (parser);
12533 if (c_parser_next_token_is (parser, CPP_STRING))
12534 {
12535 name = c_parser_peek_token (parser)->value;
12536 c_parser_consume_token (parser);
12537 }
12538 else
12539 c_parser_error (parser, "expected string literal");
12540 c_parser_skip_to_pragma_eol (parser);
471c5330 12541 parser->lex_joined_string = false;
bc4071dd
RH
12542
12543 if (name)
12544 c_common_pch_pragma (parse_in, TREE_STRING_POINTER (name));
12545}
953ff289 12546\f
41dbbb37 12547/* OpenACC and OpenMP parsing routines. */
953ff289
DN
12548
12549/* Returns name of the next clause.
12550 If the clause is not recognized PRAGMA_OMP_CLAUSE_NONE is returned and
12551 the token is not consumed. Otherwise appropriate pragma_omp_clause is
12552 returned and the token is consumed. */
12553
12554static pragma_omp_clause
12555c_parser_omp_clause_name (c_parser *parser)
12556{
12557 pragma_omp_clause result = PRAGMA_OMP_CLAUSE_NONE;
12558
41dbbb37
TS
12559 if (c_parser_next_token_is_keyword (parser, RID_AUTO))
12560 result = PRAGMA_OACC_CLAUSE_AUTO;
12561 else if (c_parser_next_token_is_keyword (parser, RID_IF))
953ff289
DN
12562 result = PRAGMA_OMP_CLAUSE_IF;
12563 else if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
12564 result = PRAGMA_OMP_CLAUSE_DEFAULT;
acf0174b
JJ
12565 else if (c_parser_next_token_is_keyword (parser, RID_FOR))
12566 result = PRAGMA_OMP_CLAUSE_FOR;
953ff289
DN
12567 else if (c_parser_next_token_is (parser, CPP_NAME))
12568 {
12569 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
12570
12571 switch (p[0])
12572 {
acf0174b
JJ
12573 case 'a':
12574 if (!strcmp ("aligned", p))
12575 result = PRAGMA_OMP_CLAUSE_ALIGNED;
41dbbb37
TS
12576 else if (!strcmp ("async", p))
12577 result = PRAGMA_OACC_CLAUSE_ASYNC;
519d7496
JB
12578 else if (!strcmp ("attach", p))
12579 result = PRAGMA_OACC_CLAUSE_ATTACH;
acf0174b 12580 break;
554a530f
JJ
12581 case 'b':
12582 if (!strcmp ("bind", p))
12583 result = PRAGMA_OMP_CLAUSE_BIND;
12584 break;
953ff289 12585 case 'c':
a68ab351
JJ
12586 if (!strcmp ("collapse", p))
12587 result = PRAGMA_OMP_CLAUSE_COLLAPSE;
41dbbb37
TS
12588 else if (!strcmp ("copy", p))
12589 result = PRAGMA_OACC_CLAUSE_COPY;
a68ab351 12590 else if (!strcmp ("copyin", p))
953ff289 12591 result = PRAGMA_OMP_CLAUSE_COPYIN;
41dbbb37
TS
12592 else if (!strcmp ("copyout", p))
12593 result = PRAGMA_OACC_CLAUSE_COPYOUT;
953ff289
DN
12594 else if (!strcmp ("copyprivate", p))
12595 result = PRAGMA_OMP_CLAUSE_COPYPRIVATE;
41dbbb37
TS
12596 else if (!strcmp ("create", p))
12597 result = PRAGMA_OACC_CLAUSE_CREATE;
953ff289 12598 break;
acf0174b 12599 case 'd':
d9a6bd32
JJ
12600 if (!strcmp ("defaultmap", p))
12601 result = PRAGMA_OMP_CLAUSE_DEFAULTMAP;
12602 else if (!strcmp ("delete", p))
41dbbb37
TS
12603 result = PRAGMA_OACC_CLAUSE_DELETE;
12604 else if (!strcmp ("depend", p))
acf0174b 12605 result = PRAGMA_OMP_CLAUSE_DEPEND;
519d7496
JB
12606 else if (!strcmp ("detach", p))
12607 result = PRAGMA_OACC_CLAUSE_DETACH;
acf0174b
JJ
12608 else if (!strcmp ("device", p))
12609 result = PRAGMA_OMP_CLAUSE_DEVICE;
41dbbb37
TS
12610 else if (!strcmp ("deviceptr", p))
12611 result = PRAGMA_OACC_CLAUSE_DEVICEPTR;
6e232ba4
JN
12612 else if (!strcmp ("device_resident", p))
12613 result = PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT;
77eb117f
JJ
12614 else if (!strcmp ("device_type", p))
12615 result = PRAGMA_OMP_CLAUSE_DEVICE_TYPE;
acf0174b
JJ
12616 else if (!strcmp ("dist_schedule", p))
12617 result = PRAGMA_OMP_CLAUSE_DIST_SCHEDULE;
12618 break;
953ff289 12619 case 'f':
20906c66
JJ
12620 if (!strcmp ("final", p))
12621 result = PRAGMA_OMP_CLAUSE_FINAL;
829c6349
CLT
12622 else if (!strcmp ("finalize", p))
12623 result = PRAGMA_OACC_CLAUSE_FINALIZE;
20906c66 12624 else if (!strcmp ("firstprivate", p))
953ff289 12625 result = PRAGMA_OMP_CLAUSE_FIRSTPRIVATE;
acf0174b
JJ
12626 else if (!strcmp ("from", p))
12627 result = PRAGMA_OMP_CLAUSE_FROM;
12628 break;
41dbbb37
TS
12629 case 'g':
12630 if (!strcmp ("gang", p))
12631 result = PRAGMA_OACC_CLAUSE_GANG;
d9a6bd32
JJ
12632 else if (!strcmp ("grainsize", p))
12633 result = PRAGMA_OMP_CLAUSE_GRAINSIZE;
41dbbb37
TS
12634 break;
12635 case 'h':
d9a6bd32
JJ
12636 if (!strcmp ("hint", p))
12637 result = PRAGMA_OMP_CLAUSE_HINT;
12638 else if (!strcmp ("host", p))
41dbbb37
TS
12639 result = PRAGMA_OACC_CLAUSE_HOST;
12640 break;
acf0174b 12641 case 'i':
829c6349
CLT
12642 if (!strcmp ("if_present", p))
12643 result = PRAGMA_OACC_CLAUSE_IF_PRESENT;
28567c40
JJ
12644 else if (!strcmp ("in_reduction", p))
12645 result = PRAGMA_OMP_CLAUSE_IN_REDUCTION;
829c6349 12646 else if (!strcmp ("inbranch", p))
acf0174b 12647 result = PRAGMA_OMP_CLAUSE_INBRANCH;
7a5e4956
CP
12648 else if (!strcmp ("independent", p))
12649 result = PRAGMA_OACC_CLAUSE_INDEPENDENT;
d9a6bd32
JJ
12650 else if (!strcmp ("is_device_ptr", p))
12651 result = PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR;
953ff289
DN
12652 break;
12653 case 'l':
12654 if (!strcmp ("lastprivate", p))
12655 result = PRAGMA_OMP_CLAUSE_LASTPRIVATE;
acf0174b
JJ
12656 else if (!strcmp ("linear", p))
12657 result = PRAGMA_OMP_CLAUSE_LINEAR;
d9a6bd32
JJ
12658 else if (!strcmp ("link", p))
12659 result = PRAGMA_OMP_CLAUSE_LINK;
953ff289 12660 break;
20906c66 12661 case 'm':
acf0174b
JJ
12662 if (!strcmp ("map", p))
12663 result = PRAGMA_OMP_CLAUSE_MAP;
12664 else if (!strcmp ("mergeable", p))
20906c66
JJ
12665 result = PRAGMA_OMP_CLAUSE_MERGEABLE;
12666 break;
953ff289 12667 case 'n':
a6163563
JB
12668 if (!strcmp ("no_create", p))
12669 result = PRAGMA_OACC_CLAUSE_NO_CREATE;
12670 else if (!strcmp ("nogroup", p))
d9a6bd32 12671 result = PRAGMA_OMP_CLAUSE_NOGROUP;
28567c40
JJ
12672 else if (!strcmp ("nontemporal", p))
12673 result = PRAGMA_OMP_CLAUSE_NONTEMPORAL;
d9a6bd32 12674 else if (!strcmp ("notinbranch", p))
acf0174b
JJ
12675 result = PRAGMA_OMP_CLAUSE_NOTINBRANCH;
12676 else if (!strcmp ("nowait", p))
953ff289 12677 result = PRAGMA_OMP_CLAUSE_NOWAIT;
41dbbb37
TS
12678 else if (!strcmp ("num_gangs", p))
12679 result = PRAGMA_OACC_CLAUSE_NUM_GANGS;
d9a6bd32
JJ
12680 else if (!strcmp ("num_tasks", p))
12681 result = PRAGMA_OMP_CLAUSE_NUM_TASKS;
acf0174b
JJ
12682 else if (!strcmp ("num_teams", p))
12683 result = PRAGMA_OMP_CLAUSE_NUM_TEAMS;
953ff289
DN
12684 else if (!strcmp ("num_threads", p))
12685 result = PRAGMA_OMP_CLAUSE_NUM_THREADS;
41dbbb37
TS
12686 else if (!strcmp ("num_workers", p))
12687 result = PRAGMA_OACC_CLAUSE_NUM_WORKERS;
953ff289
DN
12688 break;
12689 case 'o':
12690 if (!strcmp ("ordered", p))
12691 result = PRAGMA_OMP_CLAUSE_ORDERED;
1fdd6f04
JJ
12692 else if (!strcmp ("order", p))
12693 result = PRAGMA_OMP_CLAUSE_ORDER;
953ff289
DN
12694 break;
12695 case 'p':
acf0174b
JJ
12696 if (!strcmp ("parallel", p))
12697 result = PRAGMA_OMP_CLAUSE_PARALLEL;
41dbbb37
TS
12698 else if (!strcmp ("present", p))
12699 result = PRAGMA_OACC_CLAUSE_PRESENT;
829c6349
CLT
12700 /* As of OpenACC 2.5, these are now aliases of the non-present_or
12701 clauses. */
41dbbb37
TS
12702 else if (!strcmp ("present_or_copy", p)
12703 || !strcmp ("pcopy", p))
829c6349 12704 result = PRAGMA_OACC_CLAUSE_COPY;
41dbbb37
TS
12705 else if (!strcmp ("present_or_copyin", p)
12706 || !strcmp ("pcopyin", p))
829c6349 12707 result = PRAGMA_OACC_CLAUSE_COPYIN;
41dbbb37
TS
12708 else if (!strcmp ("present_or_copyout", p)
12709 || !strcmp ("pcopyout", p))
829c6349 12710 result = PRAGMA_OACC_CLAUSE_COPYOUT;
41dbbb37
TS
12711 else if (!strcmp ("present_or_create", p)
12712 || !strcmp ("pcreate", p))
829c6349 12713 result = PRAGMA_OACC_CLAUSE_CREATE;
d9a6bd32
JJ
12714 else if (!strcmp ("priority", p))
12715 result = PRAGMA_OMP_CLAUSE_PRIORITY;
acf0174b 12716 else if (!strcmp ("private", p))
953ff289 12717 result = PRAGMA_OMP_CLAUSE_PRIVATE;
acf0174b
JJ
12718 else if (!strcmp ("proc_bind", p))
12719 result = PRAGMA_OMP_CLAUSE_PROC_BIND;
953ff289
DN
12720 break;
12721 case 'r':
12722 if (!strcmp ("reduction", p))
12723 result = PRAGMA_OMP_CLAUSE_REDUCTION;
12724 break;
12725 case 's':
acf0174b
JJ
12726 if (!strcmp ("safelen", p))
12727 result = PRAGMA_OMP_CLAUSE_SAFELEN;
12728 else if (!strcmp ("schedule", p))
953ff289 12729 result = PRAGMA_OMP_CLAUSE_SCHEDULE;
acf0174b
JJ
12730 else if (!strcmp ("sections", p))
12731 result = PRAGMA_OMP_CLAUSE_SECTIONS;
829c6349
CLT
12732 else if (!strcmp ("self", p)) /* "self" is a synonym for "host". */
12733 result = PRAGMA_OACC_CLAUSE_HOST;
41dbbb37
TS
12734 else if (!strcmp ("seq", p))
12735 result = PRAGMA_OACC_CLAUSE_SEQ;
953ff289
DN
12736 else if (!strcmp ("shared", p))
12737 result = PRAGMA_OMP_CLAUSE_SHARED;
d9a6bd32
JJ
12738 else if (!strcmp ("simd", p))
12739 result = PRAGMA_OMP_CLAUSE_SIMD;
acf0174b
JJ
12740 else if (!strcmp ("simdlen", p))
12741 result = PRAGMA_OMP_CLAUSE_SIMDLEN;
12742 break;
12743 case 't':
28567c40
JJ
12744 if (!strcmp ("task_reduction", p))
12745 result = PRAGMA_OMP_CLAUSE_TASK_REDUCTION;
12746 else if (!strcmp ("taskgroup", p))
acf0174b
JJ
12747 result = PRAGMA_OMP_CLAUSE_TASKGROUP;
12748 else if (!strcmp ("thread_limit", p))
12749 result = PRAGMA_OMP_CLAUSE_THREAD_LIMIT;
d9a6bd32
JJ
12750 else if (!strcmp ("threads", p))
12751 result = PRAGMA_OMP_CLAUSE_THREADS;
7a5e4956
CP
12752 else if (!strcmp ("tile", p))
12753 result = PRAGMA_OACC_CLAUSE_TILE;
acf0174b
JJ
12754 else if (!strcmp ("to", p))
12755 result = PRAGMA_OMP_CLAUSE_TO;
953ff289 12756 break;
a68ab351 12757 case 'u':
acf0174b
JJ
12758 if (!strcmp ("uniform", p))
12759 result = PRAGMA_OMP_CLAUSE_UNIFORM;
12760 else if (!strcmp ("untied", p))
a68ab351 12761 result = PRAGMA_OMP_CLAUSE_UNTIED;
37d5ad46
JB
12762 else if (!strcmp ("use_device", p))
12763 result = PRAGMA_OACC_CLAUSE_USE_DEVICE;
398e3feb
JJ
12764 else if (!strcmp ("use_device_addr", p))
12765 result = PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR;
ff7a55bf
TS
12766 else if (!strcmp ("use_device_ptr", p))
12767 result = PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR;
a68ab351 12768 break;
41958c28 12769 case 'v':
41dbbb37
TS
12770 if (!strcmp ("vector", p))
12771 result = PRAGMA_OACC_CLAUSE_VECTOR;
12772 else if (!strcmp ("vector_length", p))
12773 result = PRAGMA_OACC_CLAUSE_VECTOR_LENGTH;
41958c28 12774 break;
41dbbb37
TS
12775 case 'w':
12776 if (!strcmp ("wait", p))
12777 result = PRAGMA_OACC_CLAUSE_WAIT;
12778 else if (!strcmp ("worker", p))
12779 result = PRAGMA_OACC_CLAUSE_WORKER;
12780 break;
953ff289
DN
12781 }
12782 }
12783
12784 if (result != PRAGMA_OMP_CLAUSE_NONE)
12785 c_parser_consume_token (parser);
12786
12787 return result;
12788}
12789
12790/* Validate that a clause of the given type does not already exist. */
12791
12792static void
d75d71e0
ILT
12793check_no_duplicate_clause (tree clauses, enum omp_clause_code code,
12794 const char *name)
953ff289 12795{
bb522e2e
JJ
12796 if (tree c = omp_find_clause (clauses, code))
12797 error_at (OMP_CLAUSE_LOCATION (c), "too many %qs clauses", name);
953ff289
DN
12798}
12799
41dbbb37
TS
12800/* OpenACC 2.0
12801 Parse wait clause or wait directive parameters. */
12802
12803static tree
12804c_parser_oacc_wait_list (c_parser *parser, location_t clause_loc, tree list)
12805{
12806 vec<tree, va_gc> *args;
12807 tree t, args_tree;
12808
32129a17
DM
12809 matching_parens parens;
12810 if (!parens.require_open (parser))
41dbbb37
TS
12811 return list;
12812
12813 args = c_parser_expr_list (parser, false, true, NULL, NULL, NULL, NULL);
41dbbb37
TS
12814 args_tree = build_tree_list_vec (args);
12815
12816 for (t = args_tree; t; t = TREE_CHAIN (t))
12817 {
12818 tree targ = TREE_VALUE (t);
12819
12820 if (targ != error_mark_node)
12821 {
12822 if (!INTEGRAL_TYPE_P (TREE_TYPE (targ)))
12823 {
12824 c_parser_error (parser, "expression must be integral");
12825 targ = error_mark_node;
12826 }
12827 else
12828 {
12829 tree c = build_omp_clause (clause_loc, OMP_CLAUSE_WAIT);
12830
12831 OMP_CLAUSE_DECL (c) = targ;
12832 OMP_CLAUSE_CHAIN (c) = list;
12833 list = c;
12834 }
12835 }
12836 }
12837
12838 release_tree_vector (args);
32129a17 12839 parens.require_close (parser);
41dbbb37
TS
12840 return list;
12841}
12842
12843/* OpenACC 2.0, OpenMP 2.5:
953ff289
DN
12844 variable-list:
12845 identifier
12846 variable-list , identifier
12847
c2255bc4
AH
12848 If KIND is nonzero, create the appropriate node and install the
12849 decl in OMP_CLAUSE_DECL and add the node to the head of the list.
12850 If KIND is nonzero, CLAUSE_LOC is the location of the clause.
953ff289
DN
12851
12852 If KIND is zero, create a TREE_LIST with the decl in TREE_PURPOSE;
519d7496
JB
12853 return the list created.
12854
12855 The optional ALLOW_DEREF argument is true if list items can use the deref
12856 (->) operator. */
953ff289
DN
12857
12858static tree
c2255bc4
AH
12859c_parser_omp_variable_list (c_parser *parser,
12860 location_t clause_loc,
519d7496
JB
12861 enum omp_clause_code kind, tree list,
12862 bool allow_deref = false)
953ff289 12863{
28567c40
JJ
12864 auto_vec<c_token> tokens;
12865 unsigned int tokens_avail = 0;
59bc434a 12866 bool first = true;
28567c40 12867
59bc434a 12868 while (1)
953ff289 12869 {
28567c40
JJ
12870 bool array_section_p = false;
12871 if (kind == OMP_CLAUSE_DEPEND)
12872 {
12873 if (c_parser_next_token_is_not (parser, CPP_NAME)
12874 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
12875 {
12876 struct c_expr expr = c_parser_expr_no_commas (parser, NULL);
12877 if (expr.value != error_mark_node)
12878 {
12879 tree u = build_omp_clause (clause_loc, kind);
12880 OMP_CLAUSE_DECL (u) = expr.value;
12881 OMP_CLAUSE_CHAIN (u) = list;
12882 list = u;
12883 }
12884
12885 if (c_parser_next_token_is_not (parser, CPP_COMMA))
12886 break;
12887
12888 c_parser_consume_token (parser);
59bc434a 12889 first = false;
28567c40
JJ
12890 continue;
12891 }
12892
12893 tokens.truncate (0);
12894 unsigned int nesting_depth = 0;
12895 while (1)
12896 {
12897 c_token *token = c_parser_peek_token (parser);
12898 switch (token->type)
12899 {
12900 case CPP_EOF:
12901 case CPP_PRAGMA_EOL:
12902 break;
12903 case CPP_OPEN_BRACE:
12904 case CPP_OPEN_PAREN:
12905 case CPP_OPEN_SQUARE:
12906 ++nesting_depth;
12907 goto add;
12908 case CPP_CLOSE_BRACE:
12909 case CPP_CLOSE_PAREN:
12910 case CPP_CLOSE_SQUARE:
12911 if (nesting_depth-- == 0)
12912 break;
12913 goto add;
12914 case CPP_COMMA:
12915 if (nesting_depth == 0)
12916 break;
12917 goto add;
12918 default:
12919 add:
12920 tokens.safe_push (*token);
12921 c_parser_consume_token (parser);
12922 continue;
12923 }
12924 break;
12925 }
12926
12927 /* Make sure nothing tries to read past the end of the tokens. */
12928 c_token eof_token;
12929 memset (&eof_token, 0, sizeof (eof_token));
12930 eof_token.type = CPP_EOF;
12931 tokens.safe_push (eof_token);
12932 tokens.safe_push (eof_token);
12933
12934 tokens_avail = parser->tokens_avail;
12935 gcc_assert (parser->tokens == &parser->tokens_buf[0]);
12936 parser->tokens = tokens.address ();
12937 parser->tokens_avail = tokens.length ();
12938 }
12939
59bc434a 12940 tree t = NULL_TREE;
953ff289 12941
59bc434a
JJ
12942 if (c_parser_next_token_is (parser, CPP_NAME)
12943 && c_parser_peek_token (parser)->id_kind == C_ID_ID)
acf0174b 12944 {
59bc434a 12945 t = lookup_name (c_parser_peek_token (parser)->value);
acf0174b 12946
59bc434a
JJ
12947 if (t == NULL_TREE)
12948 {
12949 undeclared_variable (c_parser_peek_token (parser)->location,
12950 c_parser_peek_token (parser)->value);
12951 t = error_mark_node;
12952 }
12953
12954 c_parser_consume_token (parser);
12955 }
12956 else if (c_parser_next_token_is (parser, CPP_KEYWORD)
12957 && (c_parser_peek_token (parser)->keyword == RID_FUNCTION_NAME
12958 || (c_parser_peek_token (parser)->keyword
12959 == RID_PRETTY_FUNCTION_NAME)
12960 || (c_parser_peek_token (parser)->keyword
12961 == RID_C99_FUNCTION_NAME)))
12962 t = c_parser_predefined_identifier (parser).value;
12963 else
12964 {
12965 if (first)
12966 c_parser_error (parser, "expected identifier");
12967 break;
12968 }
acf0174b
JJ
12969
12970 if (t == error_mark_node)
953ff289
DN
12971 ;
12972 else if (kind != 0)
12973 {
acf0174b
JJ
12974 switch (kind)
12975 {
41dbbb37 12976 case OMP_CLAUSE__CACHE_:
4b1ffdb1
TS
12977 /* The OpenACC cache directive explicitly only allows "array
12978 elements or subarrays". */
41dbbb37
TS
12979 if (c_parser_peek_token (parser)->type != CPP_OPEN_SQUARE)
12980 {
12981 c_parser_error (parser, "expected %<[%>");
12982 t = error_mark_node;
12983 break;
12984 }
d9a6bd32 12985 /* FALLTHROUGH */
acf0174b
JJ
12986 case OMP_CLAUSE_MAP:
12987 case OMP_CLAUSE_FROM:
12988 case OMP_CLAUSE_TO:
519d7496
JB
12989 while (c_parser_next_token_is (parser, CPP_DOT)
12990 || (allow_deref
12991 && c_parser_next_token_is (parser, CPP_DEREF)))
d9a6bd32
JJ
12992 {
12993 location_t op_loc = c_parser_peek_token (parser)->location;
519d7496
JB
12994 if (c_parser_next_token_is (parser, CPP_DEREF))
12995 t = build_simple_mem_ref (t);
d9a6bd32
JJ
12996 c_parser_consume_token (parser);
12997 if (!c_parser_next_token_is (parser, CPP_NAME))
12998 {
12999 c_parser_error (parser, "expected identifier");
13000 t = error_mark_node;
13001 break;
13002 }
6ffd47b7
DM
13003
13004 c_token *comp_tok = c_parser_peek_token (parser);
13005 tree ident = comp_tok->value;
13006 location_t comp_loc = comp_tok->location;
d9a6bd32 13007 c_parser_consume_token (parser);
6ffd47b7 13008 t = build_component_ref (op_loc, t, ident, comp_loc);
d9a6bd32
JJ
13009 }
13010 /* FALLTHROUGH */
acf0174b 13011 case OMP_CLAUSE_DEPEND:
d9a6bd32 13012 case OMP_CLAUSE_REDUCTION:
28567c40
JJ
13013 case OMP_CLAUSE_IN_REDUCTION:
13014 case OMP_CLAUSE_TASK_REDUCTION:
acf0174b
JJ
13015 while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
13016 {
13017 tree low_bound = NULL_TREE, length = NULL_TREE;
13018
13019 c_parser_consume_token (parser);
13020 if (!c_parser_next_token_is (parser, CPP_COLON))
d90c0a59 13021 {
9dc5773f
JJ
13022 location_t expr_loc
13023 = c_parser_peek_token (parser)->location;
13024 c_expr expr = c_parser_expression (parser);
13025 expr = convert_lvalue_to_rvalue (expr_loc, expr,
13026 false, true);
13027 low_bound = expr.value;
d90c0a59 13028 }
acf0174b
JJ
13029 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
13030 length = integer_one_node;
13031 else
13032 {
13033 /* Look for `:'. */
13034 if (!c_parser_require (parser, CPP_COLON,
13035 "expected %<:%>"))
13036 {
13037 t = error_mark_node;
13038 break;
13039 }
28567c40 13040 array_section_p = true;
acf0174b 13041 if (!c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
d90c0a59 13042 {
9dc5773f
JJ
13043 location_t expr_loc
13044 = c_parser_peek_token (parser)->location;
13045 c_expr expr = c_parser_expression (parser);
13046 expr = convert_lvalue_to_rvalue (expr_loc, expr,
13047 false, true);
13048 length = expr.value;
d90c0a59 13049 }
acf0174b
JJ
13050 }
13051 /* Look for the closing `]'. */
13052 if (!c_parser_require (parser, CPP_CLOSE_SQUARE,
13053 "expected %<]%>"))
13054 {
13055 t = error_mark_node;
13056 break;
13057 }
41dbbb37 13058
acf0174b
JJ
13059 t = tree_cons (low_bound, length, t);
13060 }
28567c40
JJ
13061 if (kind == OMP_CLAUSE_DEPEND
13062 && t != error_mark_node
13063 && parser->tokens_avail != 2)
13064 {
13065 if (array_section_p)
13066 {
13067 error_at (c_parser_peek_token (parser)->location,
13068 "expected %<)%> or %<,%>");
13069 t = error_mark_node;
13070 }
13071 else
13072 {
13073 parser->tokens = tokens.address ();
13074 parser->tokens_avail = tokens.length ();
13075
13076 t = c_parser_expr_no_commas (parser, NULL).value;
13077 if (t != error_mark_node && parser->tokens_avail != 2)
13078 {
13079 error_at (c_parser_peek_token (parser)->location,
13080 "expected %<)%> or %<,%>");
13081 t = error_mark_node;
13082 }
13083 }
13084 }
acf0174b
JJ
13085 break;
13086 default:
13087 break;
13088 }
13089
13090 if (t != error_mark_node)
13091 {
13092 tree u = build_omp_clause (clause_loc, kind);
13093 OMP_CLAUSE_DECL (u) = t;
13094 OMP_CLAUSE_CHAIN (u) = list;
13095 list = u;
13096 }
953ff289
DN
13097 }
13098 else
13099 list = tree_cons (t, NULL_TREE, list);
13100
28567c40
JJ
13101 if (kind == OMP_CLAUSE_DEPEND)
13102 {
13103 parser->tokens = &parser->tokens_buf[0];
13104 parser->tokens_avail = tokens_avail;
13105 }
953ff289
DN
13106 if (c_parser_next_token_is_not (parser, CPP_COMMA))
13107 break;
13108
13109 c_parser_consume_token (parser);
59bc434a 13110 first = false;
953ff289
DN
13111 }
13112
13113 return list;
13114}
13115
13116/* Similarly, but expect leading and trailing parenthesis. This is a very
519d7496
JB
13117 common case for OpenACC and OpenMP clauses. The optional ALLOW_DEREF
13118 argument is true if list items can use the deref (->) operator. */
953ff289
DN
13119
13120static tree
d75d71e0 13121c_parser_omp_var_list_parens (c_parser *parser, enum omp_clause_code kind,
519d7496 13122 tree list, bool allow_deref = false)
953ff289 13123{
c2255bc4
AH
13124 /* The clauses location. */
13125 location_t loc = c_parser_peek_token (parser)->location;
13126
32129a17
DM
13127 matching_parens parens;
13128 if (parens.require_open (parser))
953ff289 13129 {
519d7496 13130 list = c_parser_omp_variable_list (parser, loc, kind, list, allow_deref);
32129a17 13131 parens.skip_until_found_close (parser);
953ff289
DN
13132 }
13133 return list;
13134}
13135
41dbbb37
TS
13136/* OpenACC 2.0:
13137 copy ( variable-list )
13138 copyin ( variable-list )
13139 copyout ( variable-list )
13140 create ( variable-list )
13141 delete ( variable-list )
a6163563
JB
13142 present ( variable-list )
13143
13144 OpenACC 2.6:
519d7496
JB
13145 no_create ( variable-list )
13146 attach ( variable-list )
13147 detach ( variable-list ) */
41dbbb37
TS
13148
13149static tree
13150c_parser_oacc_data_clause (c_parser *parser, pragma_omp_clause c_kind,
13151 tree list)
13152{
13153 enum gomp_map_kind kind;
13154 switch (c_kind)
13155 {
519d7496
JB
13156 case PRAGMA_OACC_CLAUSE_ATTACH:
13157 kind = GOMP_MAP_ATTACH;
13158 break;
41dbbb37 13159 case PRAGMA_OACC_CLAUSE_COPY:
829c6349 13160 kind = GOMP_MAP_TOFROM;
41dbbb37
TS
13161 break;
13162 case PRAGMA_OACC_CLAUSE_COPYIN:
829c6349 13163 kind = GOMP_MAP_TO;
41dbbb37
TS
13164 break;
13165 case PRAGMA_OACC_CLAUSE_COPYOUT:
829c6349 13166 kind = GOMP_MAP_FROM;
41dbbb37
TS
13167 break;
13168 case PRAGMA_OACC_CLAUSE_CREATE:
829c6349 13169 kind = GOMP_MAP_ALLOC;
41dbbb37
TS
13170 break;
13171 case PRAGMA_OACC_CLAUSE_DELETE:
829c6349 13172 kind = GOMP_MAP_RELEASE;
41dbbb37 13173 break;
519d7496
JB
13174 case PRAGMA_OACC_CLAUSE_DETACH:
13175 kind = GOMP_MAP_DETACH;
13176 break;
41dbbb37
TS
13177 case PRAGMA_OACC_CLAUSE_DEVICE:
13178 kind = GOMP_MAP_FORCE_TO;
13179 break;
6e232ba4
JN
13180 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT:
13181 kind = GOMP_MAP_DEVICE_RESIDENT;
13182 break;
41dbbb37 13183 case PRAGMA_OACC_CLAUSE_HOST:
41dbbb37
TS
13184 kind = GOMP_MAP_FORCE_FROM;
13185 break;
6e232ba4
JN
13186 case PRAGMA_OACC_CLAUSE_LINK:
13187 kind = GOMP_MAP_LINK;
13188 break;
a6163563
JB
13189 case PRAGMA_OACC_CLAUSE_NO_CREATE:
13190 kind = GOMP_MAP_IF_PRESENT;
13191 break;
41dbbb37
TS
13192 case PRAGMA_OACC_CLAUSE_PRESENT:
13193 kind = GOMP_MAP_FORCE_PRESENT;
13194 break;
41dbbb37
TS
13195 default:
13196 gcc_unreachable ();
13197 }
13198 tree nl, c;
519d7496 13199 nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_MAP, list, true);
41dbbb37
TS
13200
13201 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
13202 OMP_CLAUSE_SET_MAP_KIND (c, kind);
13203
13204 return nl;
13205}
13206
13207/* OpenACC 2.0:
13208 deviceptr ( variable-list ) */
13209
13210static tree
13211c_parser_oacc_data_clause_deviceptr (c_parser *parser, tree list)
13212{
13213 location_t loc = c_parser_peek_token (parser)->location;
13214 tree vars, t;
13215
13216 /* Can't use OMP_CLAUSE_MAP here (that is, can't use the generic
13217 c_parser_oacc_data_clause), as for PRAGMA_OACC_CLAUSE_DEVICEPTR,
13218 variable-list must only allow for pointer variables. */
13219 vars = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
13220 for (t = vars; t && t; t = TREE_CHAIN (t))
13221 {
13222 tree v = TREE_PURPOSE (t);
13223
13224 /* FIXME diagnostics: Ideally we should keep individual
13225 locations for all the variables in the var list to make the
13226 following errors more precise. Perhaps
13227 c_parser_omp_var_list_parens() should construct a list of
13228 locations to go along with the var list. */
13229
ba539195 13230 if (!VAR_P (v) && TREE_CODE (v) != PARM_DECL)
41dbbb37
TS
13231 error_at (loc, "%qD is not a variable", v);
13232 else if (TREE_TYPE (v) == error_mark_node)
13233 ;
13234 else if (!POINTER_TYPE_P (TREE_TYPE (v)))
13235 error_at (loc, "%qD is not a pointer variable", v);
13236
13237 tree u = build_omp_clause (loc, OMP_CLAUSE_MAP);
13238 OMP_CLAUSE_SET_MAP_KIND (u, GOMP_MAP_FORCE_DEVICEPTR);
13239 OMP_CLAUSE_DECL (u) = v;
13240 OMP_CLAUSE_CHAIN (u) = list;
13241 list = u;
13242 }
13243
13244 return list;
13245}
13246
13247/* OpenACC 2.0, OpenMP 3.0:
a68ab351
JJ
13248 collapse ( constant-expression ) */
13249
13250static tree
13251c_parser_omp_clause_collapse (c_parser *parser, tree list)
13252{
13253 tree c, num = error_mark_node;
13254 HOST_WIDE_INT n;
13255 location_t loc;
13256
13257 check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse");
02889d23 13258 check_no_duplicate_clause (list, OMP_CLAUSE_TILE, "tile");
a68ab351
JJ
13259
13260 loc = c_parser_peek_token (parser)->location;
32129a17
DM
13261 matching_parens parens;
13262 if (parens.require_open (parser))
a68ab351
JJ
13263 {
13264 num = c_parser_expr_no_commas (parser, NULL).value;
32129a17 13265 parens.skip_until_found_close (parser);
a68ab351
JJ
13266 }
13267 if (num == error_mark_node)
13268 return list;
acf0174b
JJ
13269 mark_exp_read (num);
13270 num = c_fully_fold (num, false, NULL);
a68ab351 13271 if (!INTEGRAL_TYPE_P (TREE_TYPE (num))
9541ffee 13272 || !tree_fits_shwi_p (num)
9439e9a1 13273 || (n = tree_to_shwi (num)) <= 0
a68ab351
JJ
13274 || (int) n != n)
13275 {
3ba09659
AH
13276 error_at (loc,
13277 "collapse argument needs positive constant integer expression");
a68ab351
JJ
13278 return list;
13279 }
c2255bc4 13280 c = build_omp_clause (loc, OMP_CLAUSE_COLLAPSE);
a68ab351
JJ
13281 OMP_CLAUSE_COLLAPSE_EXPR (c) = num;
13282 OMP_CLAUSE_CHAIN (c) = list;
13283 return c;
13284}
13285
953ff289
DN
13286/* OpenMP 2.5:
13287 copyin ( variable-list ) */
13288
13289static tree
13290c_parser_omp_clause_copyin (c_parser *parser, tree list)
13291{
13292 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_COPYIN, list);
13293}
13294
13295/* OpenMP 2.5:
13296 copyprivate ( variable-list ) */
13297
13298static tree
13299c_parser_omp_clause_copyprivate (c_parser *parser, tree list)
13300{
13301 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_COPYPRIVATE, list);
13302}
13303
13304/* OpenMP 2.5:
7fd549d2 13305 default ( none | shared )
7a5e4956 13306
7fd549d2
TS
13307 OpenACC:
13308 default ( none | present ) */
953ff289
DN
13309
13310static tree
7a5e4956 13311c_parser_omp_clause_default (c_parser *parser, tree list, bool is_oacc)
953ff289
DN
13312{
13313 enum omp_clause_default_kind kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED;
c2255bc4 13314 location_t loc = c_parser_peek_token (parser)->location;
953ff289
DN
13315 tree c;
13316
32129a17
DM
13317 matching_parens parens;
13318 if (!parens.require_open (parser))
953ff289
DN
13319 return list;
13320 if (c_parser_next_token_is (parser, CPP_NAME))
13321 {
13322 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
13323
13324 switch (p[0])
13325 {
13326 case 'n':
13327 if (strcmp ("none", p) != 0)
13328 goto invalid_kind;
13329 kind = OMP_CLAUSE_DEFAULT_NONE;
13330 break;
13331
7fd549d2
TS
13332 case 'p':
13333 if (strcmp ("present", p) != 0 || !is_oacc)
13334 goto invalid_kind;
13335 kind = OMP_CLAUSE_DEFAULT_PRESENT;
13336 break;
13337
953ff289 13338 case 's':
7a5e4956 13339 if (strcmp ("shared", p) != 0 || is_oacc)
953ff289
DN
13340 goto invalid_kind;
13341 kind = OMP_CLAUSE_DEFAULT_SHARED;
13342 break;
13343
13344 default:
13345 goto invalid_kind;
13346 }
13347
13348 c_parser_consume_token (parser);
13349 }
13350 else
13351 {
13352 invalid_kind:
7a5e4956 13353 if (is_oacc)
7fd549d2 13354 c_parser_error (parser, "expected %<none%> or %<present%>");
7a5e4956
CP
13355 else
13356 c_parser_error (parser, "expected %<none%> or %<shared%>");
953ff289 13357 }
32129a17 13358 parens.skip_until_found_close (parser);
953ff289
DN
13359
13360 if (kind == OMP_CLAUSE_DEFAULT_UNSPECIFIED)
13361 return list;
13362
13363 check_no_duplicate_clause (list, OMP_CLAUSE_DEFAULT, "default");
c2255bc4 13364 c = build_omp_clause (loc, OMP_CLAUSE_DEFAULT);
953ff289
DN
13365 OMP_CLAUSE_CHAIN (c) = list;
13366 OMP_CLAUSE_DEFAULT_KIND (c) = kind;
13367
13368 return c;
13369}
13370
13371/* OpenMP 2.5:
13372 firstprivate ( variable-list ) */
13373
13374static tree
13375c_parser_omp_clause_firstprivate (c_parser *parser, tree list)
13376{
13377 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_FIRSTPRIVATE, list);
13378}
13379
20906c66
JJ
13380/* OpenMP 3.1:
13381 final ( expression ) */
13382
13383static tree
13384c_parser_omp_clause_final (c_parser *parser, tree list)
13385{
13386 location_t loc = c_parser_peek_token (parser)->location;
13387 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
13388 {
81a227c6
JJ
13389 matching_parens parens;
13390 tree t, c;
13391 if (!parens.require_open (parser))
13392 t = error_mark_node;
13393 else
13394 {
13395 location_t eloc = c_parser_peek_token (parser)->location;
13396 c_expr expr = c_parser_expr_no_commas (parser, NULL);
13397 t = convert_lvalue_to_rvalue (eloc, expr, true, true).value;
13398 t = c_objc_common_truthvalue_conversion (eloc, t);
13399 t = c_fully_fold (t, false, NULL);
13400 parens.skip_until_found_close (parser);
13401 }
20906c66
JJ
13402
13403 check_no_duplicate_clause (list, OMP_CLAUSE_FINAL, "final");
13404
13405 c = build_omp_clause (loc, OMP_CLAUSE_FINAL);
13406 OMP_CLAUSE_FINAL_EXPR (c) = t;
13407 OMP_CLAUSE_CHAIN (c) = list;
13408 list = c;
13409 }
13410 else
13411 c_parser_error (parser, "expected %<(%>");
13412
13413 return list;
13414}
13415
41dbbb37 13416/* OpenACC, OpenMP 2.5:
d9a6bd32
JJ
13417 if ( expression )
13418
13419 OpenMP 4.5:
13420 if ( directive-name-modifier : expression )
13421
13422 directive-name-modifier:
13423 parallel | task | taskloop | target data | target | target update
28567c40
JJ
13424 | target enter data | target exit data
13425
13426 OpenMP 5.0:
13427 directive-name-modifier:
13428 ... | simd | cancel */
953ff289
DN
13429
13430static tree
d9a6bd32 13431c_parser_omp_clause_if (c_parser *parser, tree list, bool is_omp)
953ff289 13432{
d9a6bd32
JJ
13433 location_t location = c_parser_peek_token (parser)->location;
13434 enum tree_code if_modifier = ERROR_MARK;
953ff289 13435
32129a17
DM
13436 matching_parens parens;
13437 if (!parens.require_open (parser))
d9a6bd32 13438 return list;
953ff289 13439
d9a6bd32
JJ
13440 if (is_omp && c_parser_next_token_is (parser, CPP_NAME))
13441 {
13442 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
13443 int n = 2;
28567c40
JJ
13444 if (strcmp (p, "cancel") == 0)
13445 if_modifier = VOID_CST;
13446 else if (strcmp (p, "parallel") == 0)
d9a6bd32 13447 if_modifier = OMP_PARALLEL;
28567c40
JJ
13448 else if (strcmp (p, "simd") == 0)
13449 if_modifier = OMP_SIMD;
d9a6bd32
JJ
13450 else if (strcmp (p, "task") == 0)
13451 if_modifier = OMP_TASK;
13452 else if (strcmp (p, "taskloop") == 0)
13453 if_modifier = OMP_TASKLOOP;
13454 else if (strcmp (p, "target") == 0)
13455 {
13456 if_modifier = OMP_TARGET;
13457 if (c_parser_peek_2nd_token (parser)->type == CPP_NAME)
13458 {
13459 p = IDENTIFIER_POINTER (c_parser_peek_2nd_token (parser)->value);
13460 if (strcmp ("data", p) == 0)
13461 if_modifier = OMP_TARGET_DATA;
13462 else if (strcmp ("update", p) == 0)
13463 if_modifier = OMP_TARGET_UPDATE;
13464 else if (strcmp ("enter", p) == 0)
13465 if_modifier = OMP_TARGET_ENTER_DATA;
13466 else if (strcmp ("exit", p) == 0)
13467 if_modifier = OMP_TARGET_EXIT_DATA;
13468 if (if_modifier != OMP_TARGET)
13469 {
13470 n = 3;
13471 c_parser_consume_token (parser);
13472 }
13473 else
13474 {
13475 location_t loc = c_parser_peek_2nd_token (parser)->location;
13476 error_at (loc, "expected %<data%>, %<update%>, %<enter%> "
13477 "or %<exit%>");
13478 if_modifier = ERROR_MARK;
13479 }
13480 if (if_modifier == OMP_TARGET_ENTER_DATA
13481 || if_modifier == OMP_TARGET_EXIT_DATA)
13482 {
13483 if (c_parser_peek_2nd_token (parser)->type == CPP_NAME)
13484 {
13485 p = IDENTIFIER_POINTER
13486 (c_parser_peek_2nd_token (parser)->value);
13487 if (strcmp ("data", p) == 0)
13488 n = 4;
13489 }
13490 if (n == 4)
13491 c_parser_consume_token (parser);
13492 else
13493 {
13494 location_t loc
13495 = c_parser_peek_2nd_token (parser)->location;
13496 error_at (loc, "expected %<data%>");
13497 if_modifier = ERROR_MARK;
13498 }
13499 }
13500 }
13501 }
13502 if (if_modifier != ERROR_MARK)
13503 {
13504 if (c_parser_peek_2nd_token (parser)->type == CPP_COLON)
13505 {
13506 c_parser_consume_token (parser);
13507 c_parser_consume_token (parser);
13508 }
13509 else
13510 {
13511 if (n > 2)
13512 {
13513 location_t loc = c_parser_peek_2nd_token (parser)->location;
13514 error_at (loc, "expected %<:%>");
13515 }
13516 if_modifier = ERROR_MARK;
13517 }
13518 }
953ff289 13519 }
953ff289 13520
81a227c6
JJ
13521 location_t loc = c_parser_peek_token (parser)->location;
13522 c_expr expr = c_parser_expr_no_commas (parser, NULL);
13523 expr = convert_lvalue_to_rvalue (loc, expr, true, true);
13524 tree t = c_objc_common_truthvalue_conversion (loc, expr.value), c;
13525 t = c_fully_fold (t, false, NULL);
32129a17 13526 parens.skip_until_found_close (parser);
d9a6bd32
JJ
13527
13528 for (c = list; c ; c = OMP_CLAUSE_CHAIN (c))
13529 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IF)
13530 {
13531 if (if_modifier != ERROR_MARK
13532 && OMP_CLAUSE_IF_MODIFIER (c) == if_modifier)
13533 {
13534 const char *p = NULL;
13535 switch (if_modifier)
13536 {
28567c40 13537 case VOID_CST: p = "cancel"; break;
d9a6bd32 13538 case OMP_PARALLEL: p = "parallel"; break;
28567c40 13539 case OMP_SIMD: p = "simd"; break;
d9a6bd32
JJ
13540 case OMP_TASK: p = "task"; break;
13541 case OMP_TASKLOOP: p = "taskloop"; break;
13542 case OMP_TARGET_DATA: p = "target data"; break;
13543 case OMP_TARGET: p = "target"; break;
13544 case OMP_TARGET_UPDATE: p = "target update"; break;
bb522e2e
JJ
13545 case OMP_TARGET_ENTER_DATA: p = "target enter data"; break;
13546 case OMP_TARGET_EXIT_DATA: p = "target exit data"; break;
d9a6bd32
JJ
13547 default: gcc_unreachable ();
13548 }
13549 error_at (location, "too many %<if%> clauses with %qs modifier",
13550 p);
13551 return list;
13552 }
13553 else if (OMP_CLAUSE_IF_MODIFIER (c) == if_modifier)
13554 {
13555 if (!is_omp)
13556 error_at (location, "too many %<if%> clauses");
13557 else
13558 error_at (location, "too many %<if%> clauses without modifier");
13559 return list;
13560 }
13561 else if (if_modifier == ERROR_MARK
13562 || OMP_CLAUSE_IF_MODIFIER (c) == ERROR_MARK)
13563 {
13564 error_at (location, "if any %<if%> clause has modifier, then all "
13565 "%<if%> clauses have to use modifier");
13566 return list;
13567 }
13568 }
13569
13570 c = build_omp_clause (location, OMP_CLAUSE_IF);
13571 OMP_CLAUSE_IF_MODIFIER (c) = if_modifier;
13572 OMP_CLAUSE_IF_EXPR (c) = t;
13573 OMP_CLAUSE_CHAIN (c) = list;
13574 return c;
953ff289
DN
13575}
13576
13577/* OpenMP 2.5:
28567c40
JJ
13578 lastprivate ( variable-list )
13579
13580 OpenMP 5.0:
13581 lastprivate ( [ lastprivate-modifier : ] variable-list ) */
953ff289
DN
13582
13583static tree
13584c_parser_omp_clause_lastprivate (c_parser *parser, tree list)
13585{
28567c40
JJ
13586 /* The clauses location. */
13587 location_t loc = c_parser_peek_token (parser)->location;
13588
13589 if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
13590 {
13591 bool conditional = false;
13592 if (c_parser_next_token_is (parser, CPP_NAME)
13593 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
13594 {
13595 const char *p
13596 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
13597 if (strcmp (p, "conditional") == 0)
13598 {
13599 conditional = true;
13600 c_parser_consume_token (parser);
13601 c_parser_consume_token (parser);
13602 }
13603 }
13604 tree nlist = c_parser_omp_variable_list (parser, loc,
13605 OMP_CLAUSE_LASTPRIVATE, list);
13606 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
13607 if (conditional)
13608 for (tree c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
13609 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 1;
13610 return nlist;
13611 }
13612 return list;
953ff289
DN
13613}
13614
20906c66
JJ
13615/* OpenMP 3.1:
13616 mergeable */
13617
13618static tree
13619c_parser_omp_clause_mergeable (c_parser *parser ATTRIBUTE_UNUSED, tree list)
13620{
13621 tree c;
13622
13623 /* FIXME: Should we allow duplicates? */
13624 check_no_duplicate_clause (list, OMP_CLAUSE_MERGEABLE, "mergeable");
13625
13626 c = build_omp_clause (c_parser_peek_token (parser)->location,
13627 OMP_CLAUSE_MERGEABLE);
13628 OMP_CLAUSE_CHAIN (c) = list;
13629
13630 return c;
13631}
13632
953ff289
DN
13633/* OpenMP 2.5:
13634 nowait */
13635
13636static tree
13637c_parser_omp_clause_nowait (c_parser *parser ATTRIBUTE_UNUSED, tree list)
13638{
13639 tree c;
c2255bc4 13640 location_t loc = c_parser_peek_token (parser)->location;
953ff289
DN
13641
13642 check_no_duplicate_clause (list, OMP_CLAUSE_NOWAIT, "nowait");
13643
c2255bc4 13644 c = build_omp_clause (loc, OMP_CLAUSE_NOWAIT);
953ff289
DN
13645 OMP_CLAUSE_CHAIN (c) = list;
13646 return c;
13647}
13648
13649/* OpenMP 2.5:
13650 num_threads ( expression ) */
13651
13652static tree
13653c_parser_omp_clause_num_threads (c_parser *parser, tree list)
13654{
c2255bc4 13655 location_t num_threads_loc = c_parser_peek_token (parser)->location;
32129a17
DM
13656 matching_parens parens;
13657 if (parens.require_open (parser))
953ff289 13658 {
c7412148 13659 location_t expr_loc = c_parser_peek_token (parser)->location;
81a227c6 13660 c_expr expr = c_parser_expr_no_commas (parser, NULL);
9dc5773f
JJ
13661 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
13662 tree c, t = expr.value;
928c19bb 13663 t = c_fully_fold (t, false, NULL);
953ff289 13664
32129a17 13665 parens.skip_until_found_close (parser);
953ff289
DN
13666
13667 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
13668 {
13669 c_parser_error (parser, "expected integer expression");
13670 return list;
13671 }
13672
13673 /* Attempt to statically determine when the number isn't positive. */
db3927fb 13674 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
953ff289 13675 build_int_cst (TREE_TYPE (t), 0));
21ba0cea 13676 protected_set_expr_location (c, expr_loc);
953ff289
DN
13677 if (c == boolean_true_node)
13678 {
3ba09659
AH
13679 warning_at (expr_loc, 0,
13680 "%<num_threads%> value must be positive");
953ff289
DN
13681 t = integer_one_node;
13682 }
13683
13684 check_no_duplicate_clause (list, OMP_CLAUSE_NUM_THREADS, "num_threads");
13685
c2255bc4 13686 c = build_omp_clause (num_threads_loc, OMP_CLAUSE_NUM_THREADS);
953ff289
DN
13687 OMP_CLAUSE_NUM_THREADS_EXPR (c) = t;
13688 OMP_CLAUSE_CHAIN (c) = list;
13689 list = c;
13690 }
13691
13692 return list;
13693}
13694
d9a6bd32
JJ
13695/* OpenMP 4.5:
13696 num_tasks ( expression ) */
13697
13698static tree
13699c_parser_omp_clause_num_tasks (c_parser *parser, tree list)
13700{
13701 location_t num_tasks_loc = c_parser_peek_token (parser)->location;
32129a17
DM
13702 matching_parens parens;
13703 if (parens.require_open (parser))
d9a6bd32
JJ
13704 {
13705 location_t expr_loc = c_parser_peek_token (parser)->location;
81a227c6 13706 c_expr expr = c_parser_expr_no_commas (parser, NULL);
9dc5773f
JJ
13707 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
13708 tree c, t = expr.value;
d9a6bd32
JJ
13709 t = c_fully_fold (t, false, NULL);
13710
32129a17 13711 parens.skip_until_found_close (parser);
d9a6bd32
JJ
13712
13713 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
13714 {
13715 c_parser_error (parser, "expected integer expression");
13716 return list;
13717 }
13718
13719 /* Attempt to statically determine when the number isn't positive. */
13720 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
13721 build_int_cst (TREE_TYPE (t), 0));
13722 if (CAN_HAVE_LOCATION_P (c))
13723 SET_EXPR_LOCATION (c, expr_loc);
13724 if (c == boolean_true_node)
13725 {
13726 warning_at (expr_loc, 0, "%<num_tasks%> value must be positive");
13727 t = integer_one_node;
13728 }
13729
13730 check_no_duplicate_clause (list, OMP_CLAUSE_NUM_TASKS, "num_tasks");
13731
13732 c = build_omp_clause (num_tasks_loc, OMP_CLAUSE_NUM_TASKS);
13733 OMP_CLAUSE_NUM_TASKS_EXPR (c) = t;
13734 OMP_CLAUSE_CHAIN (c) = list;
13735 list = c;
13736 }
13737
13738 return list;
13739}
13740
13741/* OpenMP 4.5:
13742 grainsize ( expression ) */
13743
13744static tree
13745c_parser_omp_clause_grainsize (c_parser *parser, tree list)
13746{
13747 location_t grainsize_loc = c_parser_peek_token (parser)->location;
32129a17
DM
13748 matching_parens parens;
13749 if (parens.require_open (parser))
d9a6bd32
JJ
13750 {
13751 location_t expr_loc = c_parser_peek_token (parser)->location;
81a227c6 13752 c_expr expr = c_parser_expr_no_commas (parser, NULL);
9dc5773f
JJ
13753 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
13754 tree c, t = expr.value;
d9a6bd32
JJ
13755 t = c_fully_fold (t, false, NULL);
13756
32129a17 13757 parens.skip_until_found_close (parser);
d9a6bd32
JJ
13758
13759 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
13760 {
13761 c_parser_error (parser, "expected integer expression");
13762 return list;
13763 }
13764
13765 /* Attempt to statically determine when the number isn't positive. */
13766 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
13767 build_int_cst (TREE_TYPE (t), 0));
13768 if (CAN_HAVE_LOCATION_P (c))
13769 SET_EXPR_LOCATION (c, expr_loc);
13770 if (c == boolean_true_node)
13771 {
13772 warning_at (expr_loc, 0, "%<grainsize%> value must be positive");
13773 t = integer_one_node;
13774 }
13775
13776 check_no_duplicate_clause (list, OMP_CLAUSE_GRAINSIZE, "grainsize");
13777
13778 c = build_omp_clause (grainsize_loc, OMP_CLAUSE_GRAINSIZE);
13779 OMP_CLAUSE_GRAINSIZE_EXPR (c) = t;
13780 OMP_CLAUSE_CHAIN (c) = list;
13781 list = c;
13782 }
13783
13784 return list;
13785}
13786
13787/* OpenMP 4.5:
13788 priority ( expression ) */
13789
13790static tree
13791c_parser_omp_clause_priority (c_parser *parser, tree list)
13792{
13793 location_t priority_loc = c_parser_peek_token (parser)->location;
32129a17
DM
13794 matching_parens parens;
13795 if (parens.require_open (parser))
d9a6bd32
JJ
13796 {
13797 location_t expr_loc = c_parser_peek_token (parser)->location;
81a227c6 13798 c_expr expr = c_parser_expr_no_commas (parser, NULL);
9dc5773f
JJ
13799 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
13800 tree c, t = expr.value;
d9a6bd32
JJ
13801 t = c_fully_fold (t, false, NULL);
13802
32129a17 13803 parens.skip_until_found_close (parser);
d9a6bd32
JJ
13804
13805 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
13806 {
13807 c_parser_error (parser, "expected integer expression");
13808 return list;
13809 }
13810
13811 /* Attempt to statically determine when the number isn't
13812 non-negative. */
13813 c = fold_build2_loc (expr_loc, LT_EXPR, boolean_type_node, t,
13814 build_int_cst (TREE_TYPE (t), 0));
13815 if (CAN_HAVE_LOCATION_P (c))
13816 SET_EXPR_LOCATION (c, expr_loc);
13817 if (c == boolean_true_node)
13818 {
13819 warning_at (expr_loc, 0, "%<priority%> value must be non-negative");
13820 t = integer_one_node;
13821 }
13822
13823 check_no_duplicate_clause (list, OMP_CLAUSE_PRIORITY, "priority");
13824
13825 c = build_omp_clause (priority_loc, OMP_CLAUSE_PRIORITY);
13826 OMP_CLAUSE_PRIORITY_EXPR (c) = t;
13827 OMP_CLAUSE_CHAIN (c) = list;
13828 list = c;
13829 }
13830
13831 return list;
13832}
13833
13834/* OpenMP 4.5:
13835 hint ( expression ) */
13836
13837static tree
13838c_parser_omp_clause_hint (c_parser *parser, tree list)
13839{
13840 location_t hint_loc = c_parser_peek_token (parser)->location;
32129a17
DM
13841 matching_parens parens;
13842 if (parens.require_open (parser))
d9a6bd32 13843 {
9dc5773f 13844 location_t expr_loc = c_parser_peek_token (parser)->location;
81a227c6 13845 c_expr expr = c_parser_expr_no_commas (parser, NULL);
9dc5773f
JJ
13846 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
13847 tree c, t = expr.value;
d9a6bd32
JJ
13848 t = c_fully_fold (t, false, NULL);
13849
32129a17 13850 parens.skip_until_found_close (parser);
d9a6bd32 13851
28567c40
JJ
13852 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
13853 || TREE_CODE (t) != INTEGER_CST)
d9a6bd32 13854 {
28567c40 13855 c_parser_error (parser, "expected constant integer expression");
d9a6bd32
JJ
13856 return list;
13857 }
13858
13859 check_no_duplicate_clause (list, OMP_CLAUSE_HINT, "hint");
13860
13861 c = build_omp_clause (hint_loc, OMP_CLAUSE_HINT);
13862 OMP_CLAUSE_HINT_EXPR (c) = t;
13863 OMP_CLAUSE_CHAIN (c) = list;
13864 list = c;
13865 }
13866
13867 return list;
13868}
13869
13870/* OpenMP 4.5:
28567c40
JJ
13871 defaultmap ( tofrom : scalar )
13872
13873 OpenMP 5.0:
13874 defaultmap ( implicit-behavior [ : variable-category ] ) */
d9a6bd32
JJ
13875
13876static tree
13877c_parser_omp_clause_defaultmap (c_parser *parser, tree list)
13878{
13879 location_t loc = c_parser_peek_token (parser)->location;
13880 tree c;
13881 const char *p;
28567c40
JJ
13882 enum omp_clause_defaultmap_kind behavior = OMP_CLAUSE_DEFAULTMAP_DEFAULT;
13883 enum omp_clause_defaultmap_kind category
13884 = OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED;
d9a6bd32 13885
32129a17
DM
13886 matching_parens parens;
13887 if (!parens.require_open (parser))
d9a6bd32 13888 return list;
28567c40
JJ
13889 if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
13890 p = "default";
13891 else if (!c_parser_next_token_is (parser, CPP_NAME))
13892 {
13893 invalid_behavior:
13894 c_parser_error (parser, "expected %<alloc%>, %<to%>, %<from%>, "
13895 "%<tofrom%>, %<firstprivate%>, %<none%> "
13896 "or %<default%>");
d9a6bd32
JJ
13897 goto out_err;
13898 }
28567c40
JJ
13899 else
13900 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
13901
13902 switch (p[0])
d9a6bd32 13903 {
28567c40
JJ
13904 case 'a':
13905 if (strcmp ("alloc", p) == 0)
13906 behavior = OMP_CLAUSE_DEFAULTMAP_ALLOC;
13907 else
13908 goto invalid_behavior;
13909 break;
13910
13911 case 'd':
13912 if (strcmp ("default", p) == 0)
13913 behavior = OMP_CLAUSE_DEFAULTMAP_DEFAULT;
13914 else
13915 goto invalid_behavior;
13916 break;
13917
13918 case 'f':
13919 if (strcmp ("firstprivate", p) == 0)
13920 behavior = OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE;
13921 else if (strcmp ("from", p) == 0)
13922 behavior = OMP_CLAUSE_DEFAULTMAP_FROM;
13923 else
13924 goto invalid_behavior;
13925 break;
13926
13927 case 'n':
13928 if (strcmp ("none", p) == 0)
13929 behavior = OMP_CLAUSE_DEFAULTMAP_NONE;
13930 else
13931 goto invalid_behavior;
13932 break;
13933
13934 case 't':
13935 if (strcmp ("tofrom", p) == 0)
13936 behavior = OMP_CLAUSE_DEFAULTMAP_TOFROM;
13937 else if (strcmp ("to", p) == 0)
13938 behavior = OMP_CLAUSE_DEFAULTMAP_TO;
13939 else
13940 goto invalid_behavior;
13941 break;
13942
13943 default:
13944 goto invalid_behavior;
d9a6bd32
JJ
13945 }
13946 c_parser_consume_token (parser);
28567c40
JJ
13947
13948 if (!c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
d9a6bd32 13949 {
28567c40
JJ
13950 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
13951 goto out_err;
13952 if (!c_parser_next_token_is (parser, CPP_NAME))
13953 {
13954 invalid_category:
13955 c_parser_error (parser, "expected %<scalar%>, %<aggregate%> or "
13956 "%<pointer%>");
13957 goto out_err;
13958 }
13959 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
13960 switch (p[0])
13961 {
13962 case 'a':
13963 if (strcmp ("aggregate", p) == 0)
13964 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE;
13965 else
13966 goto invalid_category;
13967 break;
13968
13969 case 'p':
13970 if (strcmp ("pointer", p) == 0)
13971 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER;
13972 else
13973 goto invalid_category;
13974 break;
13975
13976 case 's':
13977 if (strcmp ("scalar", p) == 0)
13978 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR;
13979 else
13980 goto invalid_category;
13981 break;
13982
13983 default:
13984 goto invalid_category;
13985 }
13986
13987 c_parser_consume_token (parser);
d9a6bd32 13988 }
32129a17 13989 parens.skip_until_found_close (parser);
28567c40
JJ
13990
13991 for (c = list; c ; c = OMP_CLAUSE_CHAIN (c))
13992 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEFAULTMAP
13993 && (category == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
13994 || OMP_CLAUSE_DEFAULTMAP_CATEGORY (c) == category
13995 || (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c)
13996 == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)))
13997 {
13998 enum omp_clause_defaultmap_kind cat = category;
13999 location_t loc = OMP_CLAUSE_LOCATION (c);
14000 if (cat == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)
14001 cat = OMP_CLAUSE_DEFAULTMAP_CATEGORY (c);
14002 p = NULL;
14003 switch (cat)
14004 {
14005 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED:
14006 p = NULL;
14007 break;
14008 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE:
14009 p = "aggregate";
14010 break;
14011 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER:
14012 p = "pointer";
14013 break;
14014 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR:
14015 p = "scalar";
14016 break;
14017 default:
14018 gcc_unreachable ();
14019 }
14020 if (p)
14021 error_at (loc, "too many %<defaultmap%> clauses with %qs category",
14022 p);
14023 else
14024 error_at (loc, "too many %<defaultmap%> clauses with unspecified "
14025 "category");
14026 break;
14027 }
14028
d9a6bd32 14029 c = build_omp_clause (loc, OMP_CLAUSE_DEFAULTMAP);
28567c40 14030 OMP_CLAUSE_DEFAULTMAP_SET_KIND (c, behavior, category);
d9a6bd32
JJ
14031 OMP_CLAUSE_CHAIN (c) = list;
14032 return c;
14033
14034 out_err:
32129a17 14035 parens.skip_until_found_close (parser);
d9a6bd32
JJ
14036 return list;
14037}
14038
c7b48c8a
TS
14039/* OpenACC 2.0:
14040 use_device ( variable-list )
14041
14042 OpenMP 4.5:
d9a6bd32
JJ
14043 use_device_ptr ( variable-list ) */
14044
14045static tree
14046c_parser_omp_clause_use_device_ptr (c_parser *parser, tree list)
14047{
14048 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_USE_DEVICE_PTR,
14049 list);
14050}
14051
398e3feb
JJ
14052/* OpenMP 5.0:
14053 use_device_addr ( variable-list ) */
14054
14055static tree
14056c_parser_omp_clause_use_device_addr (c_parser *parser, tree list)
14057{
14058 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_USE_DEVICE_ADDR,
14059 list);
14060}
14061
d9a6bd32
JJ
14062/* OpenMP 4.5:
14063 is_device_ptr ( variable-list ) */
14064
14065static tree
14066c_parser_omp_clause_is_device_ptr (c_parser *parser, tree list)
14067{
14068 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_IS_DEVICE_PTR, list);
14069}
14070
41dbbb37 14071/* OpenACC:
1e47f02b
TS
14072 num_gangs ( expression )
14073 num_workers ( expression )
14074 vector_length ( expression ) */
41dbbb37
TS
14075
14076static tree
1e47f02b
TS
14077c_parser_oacc_single_int_clause (c_parser *parser, omp_clause_code code,
14078 tree list)
41dbbb37 14079{
1e47f02b 14080 location_t loc = c_parser_peek_token (parser)->location;
41dbbb37 14081
32129a17
DM
14082 matching_parens parens;
14083 if (!parens.require_open (parser))
1e47f02b 14084 return list;
41dbbb37 14085
1e47f02b
TS
14086 location_t expr_loc = c_parser_peek_token (parser)->location;
14087 c_expr expr = c_parser_expression (parser);
14088 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14089 tree c, t = expr.value;
14090 t = c_fully_fold (t, false, NULL);
41dbbb37 14091
32129a17 14092 parens.skip_until_found_close (parser);
41dbbb37 14093
1e47f02b
TS
14094 if (t == error_mark_node)
14095 return list;
14096 else if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14097 {
14098 error_at (expr_loc, "%qs expression must be integral",
14099 omp_clause_code_name[code]);
14100 return list;
14101 }
41dbbb37 14102
1e47f02b
TS
14103 /* Attempt to statically determine when the number isn't positive. */
14104 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
14105 build_int_cst (TREE_TYPE (t), 0));
14106 protected_set_expr_location (c, expr_loc);
14107 if (c == boolean_true_node)
14108 {
14109 warning_at (expr_loc, 0,
14110 "%qs value must be positive",
14111 omp_clause_code_name[code]);
14112 t = integer_one_node;
41dbbb37
TS
14113 }
14114
1e47f02b
TS
14115 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
14116
14117 c = build_omp_clause (loc, code);
14118 OMP_CLAUSE_OPERAND (c, 0) = t;
14119 OMP_CLAUSE_CHAIN (c) = list;
14120 return c;
41dbbb37
TS
14121}
14122
765dd391
CP
14123/* OpenACC:
14124
14125 gang [( gang-arg-list )]
14126 worker [( [num:] int-expr )]
14127 vector [( [length:] int-expr )]
14128
14129 where gang-arg is one of:
14130
14131 [num:] int-expr
14132 static: size-expr
14133
14134 and size-expr may be:
14135
14136 *
14137 int-expr
14138*/
14139
14140static tree
2263c9f2
TS
14141c_parser_oacc_shape_clause (c_parser *parser, location_t loc,
14142 omp_clause_code kind,
765dd391
CP
14143 const char *str, tree list)
14144{
14145 const char *id = "num";
14146 tree ops[2] = { NULL_TREE, NULL_TREE }, c;
765dd391
CP
14147
14148 if (kind == OMP_CLAUSE_VECTOR)
14149 id = "length";
14150
14151 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
14152 {
14153 c_parser_consume_token (parser);
14154
14155 do
14156 {
14157 c_token *next = c_parser_peek_token (parser);
14158 int idx = 0;
14159
14160 /* Gang static argument. */
14161 if (kind == OMP_CLAUSE_GANG
14162 && c_parser_next_token_is_keyword (parser, RID_STATIC))
14163 {
14164 c_parser_consume_token (parser);
14165
14166 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
14167 goto cleanup_error;
14168
14169 idx = 1;
14170 if (ops[idx] != NULL_TREE)
14171 {
14172 c_parser_error (parser, "too many %<static%> arguments");
14173 goto cleanup_error;
14174 }
14175
14176 /* Check for the '*' argument. */
7a5e4956
CP
14177 if (c_parser_next_token_is (parser, CPP_MULT)
14178 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
14179 || c_parser_peek_2nd_token (parser)->type
14180 == CPP_CLOSE_PAREN))
765dd391
CP
14181 {
14182 c_parser_consume_token (parser);
14183 ops[idx] = integer_minus_one_node;
14184
14185 if (c_parser_next_token_is (parser, CPP_COMMA))
14186 {
14187 c_parser_consume_token (parser);
14188 continue;
14189 }
14190 else
14191 break;
14192 }
14193 }
14194 /* Worker num: argument and vector length: arguments. */
14195 else if (c_parser_next_token_is (parser, CPP_NAME)
14196 && strcmp (id, IDENTIFIER_POINTER (next->value)) == 0
14197 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
14198 {
14199 c_parser_consume_token (parser); /* id */
14200 c_parser_consume_token (parser); /* ':' */
14201 }
14202
14203 /* Now collect the actual argument. */
14204 if (ops[idx] != NULL_TREE)
14205 {
14206 c_parser_error (parser, "unexpected argument");
14207 goto cleanup_error;
14208 }
14209
14210 location_t expr_loc = c_parser_peek_token (parser)->location;
9dc5773f
JJ
14211 c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
14212 cexpr = convert_lvalue_to_rvalue (expr_loc, cexpr, false, true);
14213 tree expr = cexpr.value;
765dd391
CP
14214 if (expr == error_mark_node)
14215 goto cleanup_error;
14216
765dd391
CP
14217 expr = c_fully_fold (expr, false, NULL);
14218
14219 /* Attempt to statically determine when the number isn't a
14220 positive integer. */
14221
14222 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr)))
14223 {
14224 c_parser_error (parser, "expected integer expression");
14225 return list;
14226 }
14227
14228 tree c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, expr,
14229 build_int_cst (TREE_TYPE (expr), 0));
14230 if (c == boolean_true_node)
14231 {
14232 warning_at (loc, 0,
2f6f187a 14233 "%qs value must be positive", str);
765dd391
CP
14234 expr = integer_one_node;
14235 }
14236
14237 ops[idx] = expr;
14238
14239 if (kind == OMP_CLAUSE_GANG
14240 && c_parser_next_token_is (parser, CPP_COMMA))
14241 {
14242 c_parser_consume_token (parser);
14243 continue;
14244 }
14245 break;
14246 }
14247 while (1);
14248
14249 if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
14250 goto cleanup_error;
14251 }
14252
14253 check_no_duplicate_clause (list, kind, str);
14254
14255 c = build_omp_clause (loc, kind);
14256
14257 if (ops[1])
14258 OMP_CLAUSE_OPERAND (c, 1) = ops[1];
14259
14260 OMP_CLAUSE_OPERAND (c, 0) = ops[0];
14261 OMP_CLAUSE_CHAIN (c) = list;
14262
14263 return c;
14264
14265 cleanup_error:
14266 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
14267 return list;
14268}
14269
829c6349 14270/* OpenACC 2.5:
765dd391 14271 auto
829c6349 14272 finalize
765dd391
CP
14273 independent
14274 nohost
14275 seq */
14276
14277static tree
2263c9f2 14278c_parser_oacc_simple_clause (location_t loc, enum omp_clause_code code,
765dd391
CP
14279 tree list)
14280{
14281 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
14282
2263c9f2 14283 tree c = build_omp_clause (loc, code);
765dd391
CP
14284 OMP_CLAUSE_CHAIN (c) = list;
14285
14286 return c;
14287}
14288
41dbbb37
TS
14289/* OpenACC:
14290 async [( int-expr )] */
14291
14292static tree
14293c_parser_oacc_clause_async (c_parser *parser, tree list)
14294{
14295 tree c, t;
14296 location_t loc = c_parser_peek_token (parser)->location;
14297
14298 t = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL);
14299
14300 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
14301 {
14302 c_parser_consume_token (parser);
14303
14304 t = c_parser_expression (parser).value;
14305 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14306 c_parser_error (parser, "expected integer expression");
14307 else if (t == error_mark_node
14308 || !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
14309 return list;
14310 }
14311 else
14312 t = c_fully_fold (t, false, NULL);
14313
14314 check_no_duplicate_clause (list, OMP_CLAUSE_ASYNC, "async");
14315
14316 c = build_omp_clause (loc, OMP_CLAUSE_ASYNC);
14317 OMP_CLAUSE_ASYNC_EXPR (c) = t;
14318 OMP_CLAUSE_CHAIN (c) = list;
14319 list = c;
14320
14321 return list;
14322}
14323
7a5e4956
CP
14324/* OpenACC 2.0:
14325 tile ( size-expr-list ) */
14326
14327static tree
14328c_parser_oacc_clause_tile (c_parser *parser, tree list)
14329{
14330 tree c, expr = error_mark_node;
02889d23 14331 location_t loc;
7a5e4956
CP
14332 tree tile = NULL_TREE;
14333
14334 check_no_duplicate_clause (list, OMP_CLAUSE_TILE, "tile");
02889d23 14335 check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse");
7a5e4956
CP
14336
14337 loc = c_parser_peek_token (parser)->location;
14338 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
14339 return list;
14340
14341 do
14342 {
02889d23
CLT
14343 if (tile && !c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
14344 return list;
14345
7a5e4956
CP
14346 if (c_parser_next_token_is (parser, CPP_MULT)
14347 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
14348 || c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_PAREN))
14349 {
14350 c_parser_consume_token (parser);
02889d23 14351 expr = integer_zero_node;
7a5e4956
CP
14352 }
14353 else
14354 {
02889d23 14355 location_t expr_loc = c_parser_peek_token (parser)->location;
9dc5773f
JJ
14356 c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
14357 cexpr = convert_lvalue_to_rvalue (expr_loc, cexpr, false, true);
14358 expr = cexpr.value;
7a5e4956
CP
14359
14360 if (expr == error_mark_node)
14361 {
14362 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
14363 "expected %<)%>");
14364 return list;
14365 }
14366
7a5e4956
CP
14367 expr = c_fully_fold (expr, false, NULL);
14368
02889d23
CLT
14369 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr))
14370 || !tree_fits_shwi_p (expr)
14371 || tree_to_shwi (expr) <= 0)
7a5e4956 14372 {
02889d23
CLT
14373 error_at (expr_loc, "%<tile%> argument needs positive"
14374 " integral constant");
14375 expr = integer_zero_node;
7a5e4956
CP
14376 }
14377 }
14378
14379 tile = tree_cons (NULL_TREE, expr, tile);
7a5e4956
CP
14380 }
14381 while (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN));
14382
14383 /* Consume the trailing ')'. */
14384 c_parser_consume_token (parser);
14385
14386 c = build_omp_clause (loc, OMP_CLAUSE_TILE);
14387 tile = nreverse (tile);
14388 OMP_CLAUSE_TILE_LIST (c) = tile;
14389 OMP_CLAUSE_CHAIN (c) = list;
14390 return c;
14391}
14392
41dbbb37 14393/* OpenACC:
19695f4d 14394 wait [( int-expr-list )] */
41dbbb37
TS
14395
14396static tree
14397c_parser_oacc_clause_wait (c_parser *parser, tree list)
14398{
14399 location_t clause_loc = c_parser_peek_token (parser)->location;
14400
14401 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
14402 list = c_parser_oacc_wait_list (parser, clause_loc, list);
19695f4d
CLT
14403 else
14404 {
14405 tree c = build_omp_clause (clause_loc, OMP_CLAUSE_WAIT);
14406
14407 OMP_CLAUSE_DECL (c) = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL);
14408 OMP_CLAUSE_CHAIN (c) = list;
14409 list = c;
14410 }
41dbbb37
TS
14411
14412 return list;
14413}
14414
1fdd6f04
JJ
14415
14416/* OpenMP 5.0:
14417 order ( concurrent ) */
14418
14419static tree
14420c_parser_omp_clause_order (c_parser *parser, tree list)
14421{
14422 location_t loc = c_parser_peek_token (parser)->location;
14423 tree c;
14424 const char *p;
14425
14426 matching_parens parens;
14427 if (!parens.require_open (parser))
14428 return list;
14429 if (!c_parser_next_token_is (parser, CPP_NAME))
14430 {
14431 c_parser_error (parser, "expected %<concurrent%>");
14432 goto out_err;
14433 }
14434 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14435 if (strcmp (p, "concurrent") != 0)
14436 {
14437 c_parser_error (parser, "expected %<concurrent%>");
14438 goto out_err;
14439 }
14440 c_parser_consume_token (parser);
14441 parens.skip_until_found_close (parser);
14442 /* check_no_duplicate_clause (list, OMP_CLAUSE_ORDER, "order"); */
14443 c = build_omp_clause (loc, OMP_CLAUSE_ORDER);
14444 OMP_CLAUSE_CHAIN (c) = list;
14445 return c;
14446
14447 out_err:
14448 parens.skip_until_found_close (parser);
14449 return list;
14450}
14451
14452
554a530f
JJ
14453/* OpenMP 5.0:
14454 bind ( teams | parallel | thread ) */
14455
14456static tree
14457c_parser_omp_clause_bind (c_parser *parser, tree list)
14458{
14459 location_t loc = c_parser_peek_token (parser)->location;
14460 tree c;
14461 const char *p;
14462 enum omp_clause_bind_kind kind = OMP_CLAUSE_BIND_THREAD;
14463
14464 matching_parens parens;
14465 if (!parens.require_open (parser))
14466 return list;
14467 if (!c_parser_next_token_is (parser, CPP_NAME))
14468 {
14469 invalid:
14470 c_parser_error (parser,
14471 "expected %<teams%>, %<parallel%> or %<thread%>");
14472 parens.skip_until_found_close (parser);
14473 return list;
14474 }
14475 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14476 if (strcmp (p, "teams") == 0)
14477 kind = OMP_CLAUSE_BIND_TEAMS;
14478 else if (strcmp (p, "parallel") == 0)
14479 kind = OMP_CLAUSE_BIND_PARALLEL;
14480 else if (strcmp (p, "thread") != 0)
14481 goto invalid;
14482 c_parser_consume_token (parser);
14483 parens.skip_until_found_close (parser);
14484 /* check_no_duplicate_clause (list, OMP_CLAUSE_BIND, "bind"); */
14485 c = build_omp_clause (loc, OMP_CLAUSE_BIND);
14486 OMP_CLAUSE_BIND_KIND (c) = kind;
14487 OMP_CLAUSE_CHAIN (c) = list;
14488 return c;
14489}
14490
14491
953ff289 14492/* OpenMP 2.5:
d9a6bd32
JJ
14493 ordered
14494
14495 OpenMP 4.5:
14496 ordered ( constant-expression ) */
953ff289
DN
14497
14498static tree
c2255bc4 14499c_parser_omp_clause_ordered (c_parser *parser, tree list)
953ff289 14500{
953ff289
DN
14501 check_no_duplicate_clause (list, OMP_CLAUSE_ORDERED, "ordered");
14502
d9a6bd32
JJ
14503 tree c, num = NULL_TREE;
14504 HOST_WIDE_INT n;
14505 location_t loc = c_parser_peek_token (parser)->location;
14506 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
14507 {
32129a17
DM
14508 matching_parens parens;
14509 parens.consume_open (parser);
d9a6bd32 14510 num = c_parser_expr_no_commas (parser, NULL).value;
32129a17 14511 parens.skip_until_found_close (parser);
d9a6bd32
JJ
14512 }
14513 if (num == error_mark_node)
14514 return list;
14515 if (num)
14516 {
14517 mark_exp_read (num);
14518 num = c_fully_fold (num, false, NULL);
14519 if (!INTEGRAL_TYPE_P (TREE_TYPE (num))
14520 || !tree_fits_shwi_p (num)
14521 || (n = tree_to_shwi (num)) <= 0
14522 || (int) n != n)
14523 {
14524 error_at (loc, "ordered argument needs positive "
14525 "constant integer expression");
14526 return list;
14527 }
14528 }
14529 c = build_omp_clause (loc, OMP_CLAUSE_ORDERED);
14530 OMP_CLAUSE_ORDERED_EXPR (c) = num;
953ff289
DN
14531 OMP_CLAUSE_CHAIN (c) = list;
14532 return c;
14533}
14534
14535/* OpenMP 2.5:
14536 private ( variable-list ) */
14537
14538static tree
14539c_parser_omp_clause_private (c_parser *parser, tree list)
14540{
14541 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_PRIVATE, list);
14542}
14543
14544/* OpenMP 2.5:
14545 reduction ( reduction-operator : variable-list )
14546
14547 reduction-operator:
20906c66 14548 One of: + * - & ^ | && ||
acf0174b 14549
20906c66
JJ
14550 OpenMP 3.1:
14551
14552 reduction-operator:
acf0174b
JJ
14553 One of: + * - & ^ | && || max min
14554
14555 OpenMP 4.0:
14556
14557 reduction-operator:
14558 One of: + * - & ^ | && ||
28567c40
JJ
14559 identifier
14560
14561 OpenMP 5.0:
14562 reduction ( reduction-modifier, reduction-operator : variable-list )
14563 in_reduction ( reduction-operator : variable-list )
14564 task_reduction ( reduction-operator : variable-list ) */
953ff289
DN
14565
14566static tree
28567c40
JJ
14567c_parser_omp_clause_reduction (c_parser *parser, enum omp_clause_code kind,
14568 bool is_omp, tree list)
953ff289 14569{
c2255bc4 14570 location_t clause_loc = c_parser_peek_token (parser)->location;
32129a17
DM
14571 matching_parens parens;
14572 if (parens.require_open (parser))
953ff289 14573 {
28567c40
JJ
14574 bool task = false;
14575 bool inscan = false;
acf0174b
JJ
14576 enum tree_code code = ERROR_MARK;
14577 tree reduc_id = NULL_TREE;
953ff289 14578
28567c40
JJ
14579 if (kind == OMP_CLAUSE_REDUCTION && is_omp)
14580 {
14581 if (c_parser_next_token_is_keyword (parser, RID_DEFAULT)
14582 && c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
14583 {
14584 c_parser_consume_token (parser);
14585 c_parser_consume_token (parser);
14586 }
14587 else if (c_parser_next_token_is (parser, CPP_NAME)
14588 && c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
14589 {
14590 const char *p
14591 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14592 if (strcmp (p, "task") == 0)
14593 task = true;
14594 else if (strcmp (p, "inscan") == 0)
bf38f7e9 14595 inscan = true;
28567c40
JJ
14596 if (task || inscan)
14597 {
14598 c_parser_consume_token (parser);
14599 c_parser_consume_token (parser);
14600 }
14601 }
14602 }
14603
953ff289
DN
14604 switch (c_parser_peek_token (parser)->type)
14605 {
14606 case CPP_PLUS:
14607 code = PLUS_EXPR;
14608 break;
14609 case CPP_MULT:
14610 code = MULT_EXPR;
14611 break;
14612 case CPP_MINUS:
14613 code = MINUS_EXPR;
14614 break;
14615 case CPP_AND:
14616 code = BIT_AND_EXPR;
14617 break;
14618 case CPP_XOR:
14619 code = BIT_XOR_EXPR;
14620 break;
14621 case CPP_OR:
14622 code = BIT_IOR_EXPR;
14623 break;
14624 case CPP_AND_AND:
14625 code = TRUTH_ANDIF_EXPR;
14626 break;
14627 case CPP_OR_OR:
14628 code = TRUTH_ORIF_EXPR;
14629 break;
20906c66
JJ
14630 case CPP_NAME:
14631 {
14632 const char *p
14633 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14634 if (strcmp (p, "min") == 0)
14635 {
14636 code = MIN_EXPR;
14637 break;
14638 }
14639 if (strcmp (p, "max") == 0)
14640 {
14641 code = MAX_EXPR;
14642 break;
14643 }
acf0174b
JJ
14644 reduc_id = c_parser_peek_token (parser)->value;
14645 break;
20906c66 14646 }
953ff289
DN
14647 default:
14648 c_parser_error (parser,
14649 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
79c9b7a8 14650 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
953ff289
DN
14651 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
14652 return list;
14653 }
14654 c_parser_consume_token (parser);
acf0174b 14655 reduc_id = c_omp_reduction_id (code, reduc_id);
953ff289
DN
14656 if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
14657 {
14658 tree nl, c;
14659
28567c40 14660 nl = c_parser_omp_variable_list (parser, clause_loc, kind, list);
953ff289 14661 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
acf0174b 14662 {
d9a6bd32
JJ
14663 tree d = OMP_CLAUSE_DECL (c), type;
14664 if (TREE_CODE (d) != TREE_LIST)
14665 type = TREE_TYPE (d);
14666 else
14667 {
14668 int cnt = 0;
14669 tree t;
14670 for (t = d; TREE_CODE (t) == TREE_LIST; t = TREE_CHAIN (t))
14671 cnt++;
14672 type = TREE_TYPE (t);
14673 while (cnt > 0)
14674 {
14675 if (TREE_CODE (type) != POINTER_TYPE
14676 && TREE_CODE (type) != ARRAY_TYPE)
14677 break;
14678 type = TREE_TYPE (type);
14679 cnt--;
14680 }
14681 }
14682 while (TREE_CODE (type) == ARRAY_TYPE)
14683 type = TREE_TYPE (type);
acf0174b 14684 OMP_CLAUSE_REDUCTION_CODE (c) = code;
28567c40
JJ
14685 if (task)
14686 OMP_CLAUSE_REDUCTION_TASK (c) = 1;
14687 else if (inscan)
14688 OMP_CLAUSE_REDUCTION_INSCAN (c) = 1;
acf0174b
JJ
14689 if (code == ERROR_MARK
14690 || !(INTEGRAL_TYPE_P (type)
14691 || TREE_CODE (type) == REAL_TYPE
14692 || TREE_CODE (type) == COMPLEX_TYPE))
14693 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)
14694 = c_omp_reduction_lookup (reduc_id,
14695 TYPE_MAIN_VARIANT (type));
14696 }
953ff289
DN
14697
14698 list = nl;
14699 }
32129a17 14700 parens.skip_until_found_close (parser);
953ff289
DN
14701 }
14702 return list;
14703}
14704
14705/* OpenMP 2.5:
14706 schedule ( schedule-kind )
14707 schedule ( schedule-kind , expression )
14708
14709 schedule-kind:
a68ab351 14710 static | dynamic | guided | runtime | auto
d9a6bd32
JJ
14711
14712 OpenMP 4.5:
14713 schedule ( schedule-modifier : schedule-kind )
e01d41e5 14714 schedule ( schedule-modifier [ , schedule-modifier ] : schedule-kind , expression )
d9a6bd32
JJ
14715
14716 schedule-modifier:
e01d41e5
JJ
14717 simd
14718 monotonic
14719 nonmonotonic */
953ff289
DN
14720
14721static tree
14722c_parser_omp_clause_schedule (c_parser *parser, tree list)
14723{
14724 tree c, t;
c2255bc4 14725 location_t loc = c_parser_peek_token (parser)->location;
e01d41e5 14726 int modifiers = 0, nmodifiers = 0;
953ff289 14727
32129a17
DM
14728 matching_parens parens;
14729 if (!parens.require_open (parser))
953ff289
DN
14730 return list;
14731
c2255bc4 14732 c = build_omp_clause (loc, OMP_CLAUSE_SCHEDULE);
953ff289 14733
e01d41e5 14734 while (c_parser_next_token_is (parser, CPP_NAME))
d9a6bd32
JJ
14735 {
14736 tree kind = c_parser_peek_token (parser)->value;
14737 const char *p = IDENTIFIER_POINTER (kind);
e01d41e5
JJ
14738 if (strcmp ("simd", p) == 0)
14739 OMP_CLAUSE_SCHEDULE_SIMD (c) = 1;
14740 else if (strcmp ("monotonic", p) == 0)
14741 modifiers |= OMP_CLAUSE_SCHEDULE_MONOTONIC;
14742 else if (strcmp ("nonmonotonic", p) == 0)
14743 modifiers |= OMP_CLAUSE_SCHEDULE_NONMONOTONIC;
14744 else
14745 break;
14746 c_parser_consume_token (parser);
14747 if (nmodifiers++ == 0
14748 && c_parser_next_token_is (parser, CPP_COMMA))
14749 c_parser_consume_token (parser);
14750 else
d9a6bd32 14751 {
e01d41e5
JJ
14752 c_parser_require (parser, CPP_COLON, "expected %<:%>");
14753 break;
d9a6bd32
JJ
14754 }
14755 }
14756
e01d41e5
JJ
14757 if ((modifiers & (OMP_CLAUSE_SCHEDULE_MONOTONIC
14758 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC))
14759 == (OMP_CLAUSE_SCHEDULE_MONOTONIC
14760 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC))
14761 {
14762 error_at (loc, "both %<monotonic%> and %<nonmonotonic%> modifiers "
14763 "specified");
14764 modifiers = 0;
14765 }
14766
953ff289
DN
14767 if (c_parser_next_token_is (parser, CPP_NAME))
14768 {
14769 tree kind = c_parser_peek_token (parser)->value;
14770 const char *p = IDENTIFIER_POINTER (kind);
14771
14772 switch (p[0])
14773 {
14774 case 'd':
14775 if (strcmp ("dynamic", p) != 0)
14776 goto invalid_kind;
14777 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_DYNAMIC;
14778 break;
14779
14780 case 'g':
14781 if (strcmp ("guided", p) != 0)
14782 goto invalid_kind;
14783 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_GUIDED;
14784 break;
14785
14786 case 'r':
14787 if (strcmp ("runtime", p) != 0)
14788 goto invalid_kind;
14789 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_RUNTIME;
14790 break;
14791
14792 default:
14793 goto invalid_kind;
14794 }
14795 }
14796 else if (c_parser_next_token_is_keyword (parser, RID_STATIC))
14797 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_STATIC;
a68ab351
JJ
14798 else if (c_parser_next_token_is_keyword (parser, RID_AUTO))
14799 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_AUTO;
953ff289
DN
14800 else
14801 goto invalid_kind;
14802
14803 c_parser_consume_token (parser);
14804 if (c_parser_next_token_is (parser, CPP_COMMA))
14805 {
c7412148 14806 location_t here;
953ff289
DN
14807 c_parser_consume_token (parser);
14808
c7412148 14809 here = c_parser_peek_token (parser)->location;
9dc5773f
JJ
14810 c_expr expr = c_parser_expr_no_commas (parser, NULL);
14811 expr = convert_lvalue_to_rvalue (here, expr, false, true);
14812 t = expr.value;
928c19bb 14813 t = c_fully_fold (t, false, NULL);
953ff289
DN
14814
14815 if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_RUNTIME)
3ba09659
AH
14816 error_at (here, "schedule %<runtime%> does not take "
14817 "a %<chunk_size%> parameter");
a68ab351 14818 else if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_AUTO)
3ba09659
AH
14819 error_at (here,
14820 "schedule %<auto%> does not take "
14821 "a %<chunk_size%> parameter");
953ff289 14822 else if (TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE)
7211a097
JJ
14823 {
14824 /* Attempt to statically determine when the number isn't
14825 positive. */
14826 tree s = fold_build2_loc (loc, LE_EXPR, boolean_type_node, t,
14827 build_int_cst (TREE_TYPE (t), 0));
14828 protected_set_expr_location (s, loc);
14829 if (s == boolean_true_node)
14830 {
14831 warning_at (loc, 0,
14832 "chunk size value must be positive");
14833 t = integer_one_node;
14834 }
14835 OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = t;
14836 }
953ff289
DN
14837 else
14838 c_parser_error (parser, "expected integer expression");
14839
32129a17 14840 parens.skip_until_found_close (parser);
953ff289
DN
14841 }
14842 else
14843 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
14844 "expected %<,%> or %<)%>");
14845
e01d41e5
JJ
14846 OMP_CLAUSE_SCHEDULE_KIND (c)
14847 = (enum omp_clause_schedule_kind)
14848 (OMP_CLAUSE_SCHEDULE_KIND (c) | modifiers);
14849
953ff289
DN
14850 check_no_duplicate_clause (list, OMP_CLAUSE_SCHEDULE, "schedule");
14851 OMP_CLAUSE_CHAIN (c) = list;
14852 return c;
14853
14854 invalid_kind:
14855 c_parser_error (parser, "invalid schedule kind");
14856 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
14857 return list;
14858}
14859
14860/* OpenMP 2.5:
14861 shared ( variable-list ) */
14862
14863static tree
14864c_parser_omp_clause_shared (c_parser *parser, tree list)
14865{
14866 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_SHARED, list);
14867}
14868
a68ab351
JJ
14869/* OpenMP 3.0:
14870 untied */
14871
14872static tree
14873c_parser_omp_clause_untied (c_parser *parser ATTRIBUTE_UNUSED, tree list)
14874{
14875 tree c;
14876
14877 /* FIXME: Should we allow duplicates? */
14878 check_no_duplicate_clause (list, OMP_CLAUSE_UNTIED, "untied");
14879
c2255bc4
AH
14880 c = build_omp_clause (c_parser_peek_token (parser)->location,
14881 OMP_CLAUSE_UNTIED);
a68ab351 14882 OMP_CLAUSE_CHAIN (c) = list;
c2255bc4 14883
a68ab351
JJ
14884 return c;
14885}
14886
41dbbb37
TS
14887/* OpenMP 4.0:
14888 inbranch
14889 notinbranch */
14890
14891static tree
14892c_parser_omp_clause_branch (c_parser *parser ATTRIBUTE_UNUSED,
14893 enum omp_clause_code code, tree list)
14894{
14895 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
14896
14897 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
14898 OMP_CLAUSE_CHAIN (c) = list;
14899
14900 return c;
14901}
14902
14903/* OpenMP 4.0:
14904 parallel
14905 for
14906 sections
14907 taskgroup */
14908
14909static tree
14910c_parser_omp_clause_cancelkind (c_parser *parser ATTRIBUTE_UNUSED,
14911 enum omp_clause_code code, tree list)
14912{
14913 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
14914 OMP_CLAUSE_CHAIN (c) = list;
acf0174b
JJ
14915
14916 return c;
14917}
14918
d9a6bd32
JJ
14919/* OpenMP 4.5:
14920 nogroup */
14921
14922static tree
14923c_parser_omp_clause_nogroup (c_parser *parser ATTRIBUTE_UNUSED, tree list)
14924{
14925 check_no_duplicate_clause (list, OMP_CLAUSE_NOGROUP, "nogroup");
14926 tree c = build_omp_clause (c_parser_peek_token (parser)->location,
14927 OMP_CLAUSE_NOGROUP);
14928 OMP_CLAUSE_CHAIN (c) = list;
14929 return c;
14930}
14931
14932/* OpenMP 4.5:
14933 simd
14934 threads */
14935
14936static tree
14937c_parser_omp_clause_orderedkind (c_parser *parser ATTRIBUTE_UNUSED,
14938 enum omp_clause_code code, tree list)
14939{
14940 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
14941 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
14942 OMP_CLAUSE_CHAIN (c) = list;
14943 return c;
14944}
14945
acf0174b
JJ
14946/* OpenMP 4.0:
14947 num_teams ( expression ) */
14948
14949static tree
14950c_parser_omp_clause_num_teams (c_parser *parser, tree list)
14951{
14952 location_t num_teams_loc = c_parser_peek_token (parser)->location;
32129a17
DM
14953 matching_parens parens;
14954 if (parens.require_open (parser))
acf0174b
JJ
14955 {
14956 location_t expr_loc = c_parser_peek_token (parser)->location;
81a227c6 14957 c_expr expr = c_parser_expr_no_commas (parser, NULL);
9dc5773f
JJ
14958 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14959 tree c, t = expr.value;
acf0174b
JJ
14960 t = c_fully_fold (t, false, NULL);
14961
32129a17 14962 parens.skip_until_found_close (parser);
acf0174b
JJ
14963
14964 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
953ff289 14965 {
acf0174b
JJ
14966 c_parser_error (parser, "expected integer expression");
14967 return list;
953ff289
DN
14968 }
14969
acf0174b
JJ
14970 /* Attempt to statically determine when the number isn't positive. */
14971 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
14972 build_int_cst (TREE_TYPE (t), 0));
21ba0cea 14973 protected_set_expr_location (c, expr_loc);
acf0174b 14974 if (c == boolean_true_node)
953ff289 14975 {
acf0174b
JJ
14976 warning_at (expr_loc, 0, "%<num_teams%> value must be positive");
14977 t = integer_one_node;
953ff289 14978 }
953ff289 14979
acf0174b 14980 check_no_duplicate_clause (list, OMP_CLAUSE_NUM_TEAMS, "num_teams");
953ff289 14981
acf0174b
JJ
14982 c = build_omp_clause (num_teams_loc, OMP_CLAUSE_NUM_TEAMS);
14983 OMP_CLAUSE_NUM_TEAMS_EXPR (c) = t;
14984 OMP_CLAUSE_CHAIN (c) = list;
14985 list = c;
14986 }
953ff289 14987
acf0174b
JJ
14988 return list;
14989}
953ff289 14990
acf0174b
JJ
14991/* OpenMP 4.0:
14992 thread_limit ( expression ) */
953ff289
DN
14993
14994static tree
acf0174b 14995c_parser_omp_clause_thread_limit (c_parser *parser, tree list)
953ff289 14996{
68c81f24 14997 location_t num_thread_limit_loc = c_parser_peek_token (parser)->location;
32129a17
DM
14998 matching_parens parens;
14999 if (parens.require_open (parser))
acf0174b
JJ
15000 {
15001 location_t expr_loc = c_parser_peek_token (parser)->location;
81a227c6 15002 c_expr expr = c_parser_expr_no_commas (parser, NULL);
9dc5773f
JJ
15003 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15004 tree c, t = expr.value;
acf0174b 15005 t = c_fully_fold (t, false, NULL);
953ff289 15006
32129a17 15007 parens.skip_until_found_close (parser);
953ff289 15008
acf0174b
JJ
15009 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
15010 {
15011 c_parser_error (parser, "expected integer expression");
15012 return list;
15013 }
c2255bc4 15014
acf0174b
JJ
15015 /* Attempt to statically determine when the number isn't positive. */
15016 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
15017 build_int_cst (TREE_TYPE (t), 0));
21ba0cea 15018 protected_set_expr_location (c, expr_loc);
acf0174b
JJ
15019 if (c == boolean_true_node)
15020 {
15021 warning_at (expr_loc, 0, "%<thread_limit%> value must be positive");
15022 t = integer_one_node;
15023 }
20906c66 15024
acf0174b
JJ
15025 check_no_duplicate_clause (list, OMP_CLAUSE_THREAD_LIMIT,
15026 "thread_limit");
20906c66 15027
68c81f24 15028 c = build_omp_clause (num_thread_limit_loc, OMP_CLAUSE_THREAD_LIMIT);
acf0174b
JJ
15029 OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = t;
15030 OMP_CLAUSE_CHAIN (c) = list;
15031 list = c;
15032 }
20906c66 15033
acf0174b
JJ
15034 return list;
15035}
20906c66 15036
acf0174b
JJ
15037/* OpenMP 4.0:
15038 aligned ( variable-list )
15039 aligned ( variable-list : constant-expression ) */
20906c66 15040
acf0174b
JJ
15041static tree
15042c_parser_omp_clause_aligned (c_parser *parser, tree list)
15043{
15044 location_t clause_loc = c_parser_peek_token (parser)->location;
15045 tree nl, c;
20906c66 15046
32129a17
DM
15047 matching_parens parens;
15048 if (!parens.require_open (parser))
acf0174b 15049 return list;
20906c66 15050
acf0174b
JJ
15051 nl = c_parser_omp_variable_list (parser, clause_loc,
15052 OMP_CLAUSE_ALIGNED, list);
20906c66 15053
acf0174b
JJ
15054 if (c_parser_next_token_is (parser, CPP_COLON))
15055 {
15056 c_parser_consume_token (parser);
9dc5773f
JJ
15057 location_t expr_loc = c_parser_peek_token (parser)->location;
15058 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15059 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15060 tree alignment = expr.value;
acf0174b 15061 alignment = c_fully_fold (alignment, false, NULL);
fce5e5e3
JJ
15062 if (TREE_CODE (alignment) != INTEGER_CST
15063 || !INTEGRAL_TYPE_P (TREE_TYPE (alignment))
15064 || tree_int_cst_sgn (alignment) != 1)
acf0174b
JJ
15065 {
15066 error_at (clause_loc, "%<aligned%> clause alignment expression must "
15067 "be positive constant integer expression");
15068 alignment = NULL_TREE;
15069 }
953ff289 15070
acf0174b
JJ
15071 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
15072 OMP_CLAUSE_ALIGNED_ALIGNMENT (c) = alignment;
15073 }
15074
32129a17 15075 parens.skip_until_found_close (parser);
acf0174b
JJ
15076 return nl;
15077}
15078
15079/* OpenMP 4.0:
15080 linear ( variable-list )
d9a6bd32
JJ
15081 linear ( variable-list : expression )
15082
15083 OpenMP 4.5:
15084 linear ( modifier ( variable-list ) )
15085 linear ( modifier ( variable-list ) : expression ) */
acf0174b
JJ
15086
15087static tree
5e9d6aa4 15088c_parser_omp_clause_linear (c_parser *parser, tree list)
953ff289 15089{
acf0174b
JJ
15090 location_t clause_loc = c_parser_peek_token (parser)->location;
15091 tree nl, c, step;
d9a6bd32 15092 enum omp_clause_linear_kind kind = OMP_CLAUSE_LINEAR_DEFAULT;
acf0174b 15093
32129a17
DM
15094 matching_parens parens;
15095 if (!parens.require_open (parser))
acf0174b
JJ
15096 return list;
15097
5e9d6aa4 15098 if (c_parser_next_token_is (parser, CPP_NAME))
d9a6bd32
JJ
15099 {
15100 c_token *tok = c_parser_peek_token (parser);
15101 const char *p = IDENTIFIER_POINTER (tok->value);
15102 if (strcmp ("val", p) == 0)
15103 kind = OMP_CLAUSE_LINEAR_VAL;
15104 if (c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN)
15105 kind = OMP_CLAUSE_LINEAR_DEFAULT;
15106 if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
15107 {
15108 c_parser_consume_token (parser);
15109 c_parser_consume_token (parser);
15110 }
15111 }
15112
acf0174b
JJ
15113 nl = c_parser_omp_variable_list (parser, clause_loc,
15114 OMP_CLAUSE_LINEAR, list);
15115
d9a6bd32 15116 if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
32129a17 15117 parens.skip_until_found_close (parser);
d9a6bd32 15118
acf0174b
JJ
15119 if (c_parser_next_token_is (parser, CPP_COLON))
15120 {
15121 c_parser_consume_token (parser);
9dc5773f 15122 location_t expr_loc = c_parser_peek_token (parser)->location;
81a227c6 15123 c_expr expr = c_parser_expr_no_commas (parser, NULL);
9dc5773f
JJ
15124 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15125 step = expr.value;
acf0174b
JJ
15126 step = c_fully_fold (step, false, NULL);
15127 if (!INTEGRAL_TYPE_P (TREE_TYPE (step)))
15128 {
15129 error_at (clause_loc, "%<linear%> clause step expression must "
15130 "be integral");
15131 step = integer_one_node;
15132 }
15133
15134 }
15135 else
15136 step = integer_one_node;
15137
15138 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
15139 {
15140 OMP_CLAUSE_LINEAR_STEP (c) = step;
d9a6bd32 15141 OMP_CLAUSE_LINEAR_KIND (c) = kind;
acf0174b
JJ
15142 }
15143
32129a17 15144 parens.skip_until_found_close (parser);
acf0174b
JJ
15145 return nl;
15146}
15147
28567c40
JJ
15148/* OpenMP 5.0:
15149 nontemporal ( variable-list ) */
15150
15151static tree
15152c_parser_omp_clause_nontemporal (c_parser *parser, tree list)
15153{
15154 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_NONTEMPORAL, list);
15155}
15156
acf0174b
JJ
15157/* OpenMP 4.0:
15158 safelen ( constant-expression ) */
15159
15160static tree
15161c_parser_omp_clause_safelen (c_parser *parser, tree list)
15162{
15163 location_t clause_loc = c_parser_peek_token (parser)->location;
15164 tree c, t;
15165
32129a17
DM
15166 matching_parens parens;
15167 if (!parens.require_open (parser))
acf0174b
JJ
15168 return list;
15169
9dc5773f
JJ
15170 location_t expr_loc = c_parser_peek_token (parser)->location;
15171 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15172 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15173 t = expr.value;
acf0174b 15174 t = c_fully_fold (t, false, NULL);
fce5e5e3
JJ
15175 if (TREE_CODE (t) != INTEGER_CST
15176 || !INTEGRAL_TYPE_P (TREE_TYPE (t))
15177 || tree_int_cst_sgn (t) != 1)
acf0174b
JJ
15178 {
15179 error_at (clause_loc, "%<safelen%> clause expression must "
15180 "be positive constant integer expression");
15181 t = NULL_TREE;
15182 }
15183
32129a17 15184 parens.skip_until_found_close (parser);
acf0174b
JJ
15185 if (t == NULL_TREE || t == error_mark_node)
15186 return list;
15187
15188 check_no_duplicate_clause (list, OMP_CLAUSE_SAFELEN, "safelen");
15189
15190 c = build_omp_clause (clause_loc, OMP_CLAUSE_SAFELEN);
15191 OMP_CLAUSE_SAFELEN_EXPR (c) = t;
15192 OMP_CLAUSE_CHAIN (c) = list;
15193 return c;
15194}
15195
15196/* OpenMP 4.0:
15197 simdlen ( constant-expression ) */
15198
15199static tree
15200c_parser_omp_clause_simdlen (c_parser *parser, tree list)
15201{
15202 location_t clause_loc = c_parser_peek_token (parser)->location;
15203 tree c, t;
15204
32129a17
DM
15205 matching_parens parens;
15206 if (!parens.require_open (parser))
acf0174b
JJ
15207 return list;
15208
9dc5773f
JJ
15209 location_t expr_loc = c_parser_peek_token (parser)->location;
15210 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15211 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15212 t = expr.value;
acf0174b 15213 t = c_fully_fold (t, false, NULL);
fce5e5e3
JJ
15214 if (TREE_CODE (t) != INTEGER_CST
15215 || !INTEGRAL_TYPE_P (TREE_TYPE (t))
15216 || tree_int_cst_sgn (t) != 1)
acf0174b
JJ
15217 {
15218 error_at (clause_loc, "%<simdlen%> clause expression must "
15219 "be positive constant integer expression");
15220 t = NULL_TREE;
15221 }
15222
32129a17 15223 parens.skip_until_found_close (parser);
acf0174b
JJ
15224 if (t == NULL_TREE || t == error_mark_node)
15225 return list;
15226
15227 check_no_duplicate_clause (list, OMP_CLAUSE_SIMDLEN, "simdlen");
15228
15229 c = build_omp_clause (clause_loc, OMP_CLAUSE_SIMDLEN);
15230 OMP_CLAUSE_SIMDLEN_EXPR (c) = t;
15231 OMP_CLAUSE_CHAIN (c) = list;
15232 return c;
15233}
15234
d9a6bd32
JJ
15235/* OpenMP 4.5:
15236 vec:
15237 identifier [+/- integer]
15238 vec , identifier [+/- integer]
15239*/
15240
15241static tree
15242c_parser_omp_clause_depend_sink (c_parser *parser, location_t clause_loc,
15243 tree list)
15244{
15245 tree vec = NULL;
15246 if (c_parser_next_token_is_not (parser, CPP_NAME)
15247 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
15248 {
15249 c_parser_error (parser, "expected identifier");
15250 return list;
15251 }
15252
15253 while (c_parser_next_token_is (parser, CPP_NAME)
15254 && c_parser_peek_token (parser)->id_kind == C_ID_ID)
15255 {
15256 tree t = lookup_name (c_parser_peek_token (parser)->value);
15257 tree addend = NULL;
15258
15259 if (t == NULL_TREE)
15260 {
15261 undeclared_variable (c_parser_peek_token (parser)->location,
15262 c_parser_peek_token (parser)->value);
15263 t = error_mark_node;
15264 }
15265
15266 c_parser_consume_token (parser);
15267
15268 bool neg = false;
15269 if (c_parser_next_token_is (parser, CPP_MINUS))
15270 neg = true;
15271 else if (!c_parser_next_token_is (parser, CPP_PLUS))
15272 {
15273 addend = integer_zero_node;
15274 neg = false;
15275 goto add_to_vector;
15276 }
15277 c_parser_consume_token (parser);
15278
15279 if (c_parser_next_token_is_not (parser, CPP_NUMBER))
15280 {
15281 c_parser_error (parser, "expected integer");
15282 return list;
15283 }
15284
15285 addend = c_parser_peek_token (parser)->value;
15286 if (TREE_CODE (addend) != INTEGER_CST)
15287 {
15288 c_parser_error (parser, "expected integer");
15289 return list;
15290 }
15291 c_parser_consume_token (parser);
15292
15293 add_to_vector:
15294 if (t != error_mark_node)
15295 {
15296 vec = tree_cons (addend, t, vec);
15297 if (neg)
15298 OMP_CLAUSE_DEPEND_SINK_NEGATIVE (vec) = 1;
15299 }
15300
15301 if (c_parser_next_token_is_not (parser, CPP_COMMA))
15302 break;
15303
15304 c_parser_consume_token (parser);
15305 }
15306
15307 if (vec == NULL_TREE)
15308 return list;
15309
15310 tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DEPEND);
15311 OMP_CLAUSE_DEPEND_KIND (u) = OMP_CLAUSE_DEPEND_SINK;
15312 OMP_CLAUSE_DECL (u) = nreverse (vec);
15313 OMP_CLAUSE_CHAIN (u) = list;
15314 return u;
15315}
15316
28567c40
JJ
15317/* OpenMP 5.0:
15318 iterators ( iterators-definition )
15319
15320 iterators-definition:
15321 iterator-specifier
15322 iterator-specifier , iterators-definition
15323
15324 iterator-specifier:
15325 identifier = range-specification
15326 iterator-type identifier = range-specification
15327
15328 range-specification:
15329 begin : end
15330 begin : end : step */
15331
15332static tree
15333c_parser_omp_iterators (c_parser *parser)
15334{
15335 tree ret = NULL_TREE, *last = &ret;
15336 c_parser_consume_token (parser);
15337
15338 push_scope ();
15339
15340 matching_parens parens;
15341 if (!parens.require_open (parser))
15342 return error_mark_node;
15343
15344 do
15345 {
15346 tree iter_type = NULL_TREE, type_expr = NULL_TREE;
15347 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
15348 {
15349 struct c_type_name *type = c_parser_type_name (parser);
15350 if (type != NULL)
15351 iter_type = groktypename (type, &type_expr, NULL);
15352 }
15353 if (iter_type == NULL_TREE)
15354 iter_type = integer_type_node;
15355
15356 location_t loc = c_parser_peek_token (parser)->location;
15357 if (!c_parser_next_token_is (parser, CPP_NAME))
15358 {
15359 c_parser_error (parser, "expected identifier");
15360 break;
15361 }
15362
15363 tree id = c_parser_peek_token (parser)->value;
15364 c_parser_consume_token (parser);
15365
15366 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
15367 break;
15368
15369 location_t eloc = c_parser_peek_token (parser)->location;
15370 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15371 expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
15372 tree begin = expr.value;
15373
15374 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
15375 break;
15376
15377 eloc = c_parser_peek_token (parser)->location;
15378 expr = c_parser_expr_no_commas (parser, NULL);
15379 expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
15380 tree end = expr.value;
15381
15382 tree step = integer_one_node;
15383 if (c_parser_next_token_is (parser, CPP_COLON))
15384 {
15385 c_parser_consume_token (parser);
15386 eloc = c_parser_peek_token (parser)->location;
15387 expr = c_parser_expr_no_commas (parser, NULL);
15388 expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
15389 step = expr.value;
15390 }
15391
15392 tree iter_var = build_decl (loc, VAR_DECL, id, iter_type);
15393 DECL_ARTIFICIAL (iter_var) = 1;
15394 DECL_CONTEXT (iter_var) = current_function_decl;
15395 pushdecl (iter_var);
15396
15397 *last = make_tree_vec (6);
15398 TREE_VEC_ELT (*last, 0) = iter_var;
15399 TREE_VEC_ELT (*last, 1) = begin;
15400 TREE_VEC_ELT (*last, 2) = end;
15401 TREE_VEC_ELT (*last, 3) = step;
15402 last = &TREE_CHAIN (*last);
15403
15404 if (c_parser_next_token_is (parser, CPP_COMMA))
15405 {
15406 c_parser_consume_token (parser);
15407 continue;
15408 }
15409 break;
15410 }
15411 while (1);
15412
15413 parens.skip_until_found_close (parser);
15414 return ret ? ret : error_mark_node;
15415}
15416
acf0174b
JJ
15417/* OpenMP 4.0:
15418 depend ( depend-kind: variable-list )
15419
15420 depend-kind:
d9a6bd32
JJ
15421 in | out | inout
15422
15423 OpenMP 4.5:
15424 depend ( source )
15425
28567c40
JJ
15426 depend ( sink : vec )
15427
15428 OpenMP 5.0:
15429 depend ( depend-modifier , depend-kind: variable-list )
15430
15431 depend-kind:
15432 in | out | inout | mutexinoutset | depobj
15433
15434 depend-modifier:
15435 iterator ( iterators-definition ) */
acf0174b
JJ
15436
15437static tree
15438c_parser_omp_clause_depend (c_parser *parser, tree list)
15439{
15440 location_t clause_loc = c_parser_peek_token (parser)->location;
28567c40
JJ
15441 enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_LAST;
15442 tree nl, c, iterators = NULL_TREE;
acf0174b 15443
32129a17
DM
15444 matching_parens parens;
15445 if (!parens.require_open (parser))
acf0174b 15446 return list;
953ff289 15447
28567c40 15448 do
20906c66 15449 {
28567c40
JJ
15450 if (c_parser_next_token_is_not (parser, CPP_NAME))
15451 goto invalid_kind;
15452
20906c66 15453 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
28567c40
JJ
15454 if (strcmp ("iterator", p) == 0 && iterators == NULL_TREE)
15455 {
15456 iterators = c_parser_omp_iterators (parser);
15457 c_parser_require (parser, CPP_COMMA, "expected %<,%>");
15458 continue;
15459 }
acf0174b
JJ
15460 if (strcmp ("in", p) == 0)
15461 kind = OMP_CLAUSE_DEPEND_IN;
15462 else if (strcmp ("inout", p) == 0)
15463 kind = OMP_CLAUSE_DEPEND_INOUT;
28567c40
JJ
15464 else if (strcmp ("mutexinoutset", p) == 0)
15465 kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET;
acf0174b
JJ
15466 else if (strcmp ("out", p) == 0)
15467 kind = OMP_CLAUSE_DEPEND_OUT;
28567c40
JJ
15468 else if (strcmp ("depobj", p) == 0)
15469 kind = OMP_CLAUSE_DEPEND_DEPOBJ;
d9a6bd32
JJ
15470 else if (strcmp ("sink", p) == 0)
15471 kind = OMP_CLAUSE_DEPEND_SINK;
28567c40
JJ
15472 else if (strcmp ("source", p) == 0)
15473 kind = OMP_CLAUSE_DEPEND_SOURCE;
20906c66 15474 else
acf0174b 15475 goto invalid_kind;
28567c40 15476 break;
20906c66 15477 }
28567c40 15478 while (1);
953ff289 15479
acf0174b 15480 c_parser_consume_token (parser);
d9a6bd32 15481
28567c40
JJ
15482 if (iterators
15483 && (kind == OMP_CLAUSE_DEPEND_SOURCE || kind == OMP_CLAUSE_DEPEND_SINK))
15484 {
15485 pop_scope ();
15486 error_at (clause_loc, "%<iterator%> modifier incompatible with %qs",
15487 kind == OMP_CLAUSE_DEPEND_SOURCE ? "source" : "sink");
15488 iterators = NULL_TREE;
15489 }
15490
d9a6bd32
JJ
15491 if (kind == OMP_CLAUSE_DEPEND_SOURCE)
15492 {
15493 c = build_omp_clause (clause_loc, OMP_CLAUSE_DEPEND);
15494 OMP_CLAUSE_DEPEND_KIND (c) = kind;
15495 OMP_CLAUSE_DECL (c) = NULL_TREE;
15496 OMP_CLAUSE_CHAIN (c) = list;
32129a17 15497 parens.skip_until_found_close (parser);
d9a6bd32
JJ
15498 return c;
15499 }
15500
acf0174b
JJ
15501 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
15502 goto resync_fail;
15503
d9a6bd32
JJ
15504 if (kind == OMP_CLAUSE_DEPEND_SINK)
15505 nl = c_parser_omp_clause_depend_sink (parser, clause_loc, list);
15506 else
15507 {
15508 nl = c_parser_omp_variable_list (parser, clause_loc,
15509 OMP_CLAUSE_DEPEND, list);
acf0174b 15510
28567c40
JJ
15511 if (iterators)
15512 {
15513 tree block = pop_scope ();
15514 if (iterators == error_mark_node)
15515 iterators = NULL_TREE;
15516 else
15517 TREE_VEC_ELT (iterators, 5) = block;
15518 }
15519
d9a6bd32 15520 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
28567c40
JJ
15521 {
15522 OMP_CLAUSE_DEPEND_KIND (c) = kind;
15523 if (iterators)
15524 OMP_CLAUSE_DECL (c)
15525 = build_tree_list (iterators, OMP_CLAUSE_DECL (c));
15526 }
d9a6bd32 15527 }
acf0174b 15528
32129a17 15529 parens.skip_until_found_close (parser);
acf0174b
JJ
15530 return nl;
15531
15532 invalid_kind:
15533 c_parser_error (parser, "invalid depend kind");
15534 resync_fail:
32129a17 15535 parens.skip_until_found_close (parser);
28567c40
JJ
15536 if (iterators)
15537 pop_scope ();
acf0174b
JJ
15538 return list;
15539}
15540
15541/* OpenMP 4.0:
15542 map ( map-kind: variable-list )
15543 map ( variable-list )
15544
15545 map-kind:
d9a6bd32
JJ
15546 alloc | to | from | tofrom
15547
15548 OpenMP 4.5:
15549 map-kind:
15550 alloc | to | from | tofrom | release | delete
15551
15552 map ( always [,] map-kind: variable-list ) */
acf0174b
JJ
15553
15554static tree
15555c_parser_omp_clause_map (c_parser *parser, tree list)
15556{
15557 location_t clause_loc = c_parser_peek_token (parser)->location;
41dbbb37 15558 enum gomp_map_kind kind = GOMP_MAP_TOFROM;
d9a6bd32
JJ
15559 int always = 0;
15560 enum c_id_kind always_id_kind = C_ID_NONE;
15561 location_t always_loc = UNKNOWN_LOCATION;
15562 tree always_id = NULL_TREE;
acf0174b
JJ
15563 tree nl, c;
15564
32129a17
DM
15565 matching_parens parens;
15566 if (!parens.require_open (parser))
acf0174b
JJ
15567 return list;
15568
d9a6bd32
JJ
15569 if (c_parser_next_token_is (parser, CPP_NAME))
15570 {
15571 c_token *tok = c_parser_peek_token (parser);
15572 const char *p = IDENTIFIER_POINTER (tok->value);
15573 always_id_kind = tok->id_kind;
15574 always_loc = tok->location;
15575 always_id = tok->value;
15576 if (strcmp ("always", p) == 0)
15577 {
15578 c_token *sectok = c_parser_peek_2nd_token (parser);
15579 if (sectok->type == CPP_COMMA)
15580 {
15581 c_parser_consume_token (parser);
15582 c_parser_consume_token (parser);
15583 always = 2;
15584 }
15585 else if (sectok->type == CPP_NAME)
15586 {
15587 p = IDENTIFIER_POINTER (sectok->value);
15588 if (strcmp ("alloc", p) == 0
15589 || strcmp ("to", p) == 0
15590 || strcmp ("from", p) == 0
15591 || strcmp ("tofrom", p) == 0
15592 || strcmp ("release", p) == 0
15593 || strcmp ("delete", p) == 0)
15594 {
15595 c_parser_consume_token (parser);
15596 always = 1;
15597 }
15598 }
15599 }
15600 }
15601
acf0174b
JJ
15602 if (c_parser_next_token_is (parser, CPP_NAME)
15603 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
20906c66 15604 {
acf0174b
JJ
15605 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
15606 if (strcmp ("alloc", p) == 0)
41dbbb37 15607 kind = GOMP_MAP_ALLOC;
acf0174b 15608 else if (strcmp ("to", p) == 0)
d9a6bd32 15609 kind = always ? GOMP_MAP_ALWAYS_TO : GOMP_MAP_TO;
acf0174b 15610 else if (strcmp ("from", p) == 0)
d9a6bd32 15611 kind = always ? GOMP_MAP_ALWAYS_FROM : GOMP_MAP_FROM;
acf0174b 15612 else if (strcmp ("tofrom", p) == 0)
d9a6bd32
JJ
15613 kind = always ? GOMP_MAP_ALWAYS_TOFROM : GOMP_MAP_TOFROM;
15614 else if (strcmp ("release", p) == 0)
15615 kind = GOMP_MAP_RELEASE;
15616 else if (strcmp ("delete", p) == 0)
15617 kind = GOMP_MAP_DELETE;
20906c66
JJ
15618 else
15619 {
acf0174b
JJ
15620 c_parser_error (parser, "invalid map kind");
15621 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
15622 "expected %<)%>");
15623 return list;
20906c66 15624 }
acf0174b
JJ
15625 c_parser_consume_token (parser);
15626 c_parser_consume_token (parser);
20906c66 15627 }
d9a6bd32
JJ
15628 else if (always)
15629 {
15630 if (always_id_kind != C_ID_ID)
15631 {
15632 c_parser_error (parser, "expected identifier");
32129a17 15633 parens.skip_until_found_close (parser);
d9a6bd32
JJ
15634 return list;
15635 }
15636
15637 tree t = lookup_name (always_id);
15638 if (t == NULL_TREE)
15639 {
15640 undeclared_variable (always_loc, always_id);
15641 t = error_mark_node;
15642 }
15643 if (t != error_mark_node)
15644 {
15645 tree u = build_omp_clause (clause_loc, OMP_CLAUSE_MAP);
15646 OMP_CLAUSE_DECL (u) = t;
15647 OMP_CLAUSE_CHAIN (u) = list;
15648 OMP_CLAUSE_SET_MAP_KIND (u, kind);
15649 list = u;
15650 }
15651 if (always == 1)
15652 {
32129a17 15653 parens.skip_until_found_close (parser);
d9a6bd32
JJ
15654 return list;
15655 }
15656 }
20906c66 15657
acf0174b
JJ
15658 nl = c_parser_omp_variable_list (parser, clause_loc, OMP_CLAUSE_MAP, list);
15659
15660 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
41dbbb37 15661 OMP_CLAUSE_SET_MAP_KIND (c, kind);
acf0174b 15662
32129a17 15663 parens.skip_until_found_close (parser);
acf0174b
JJ
15664 return nl;
15665}
15666
15667/* OpenMP 4.0:
15668 device ( expression ) */
15669
15670static tree
15671c_parser_omp_clause_device (c_parser *parser, tree list)
15672{
15673 location_t clause_loc = c_parser_peek_token (parser)->location;
32129a17
DM
15674 matching_parens parens;
15675 if (parens.require_open (parser))
953ff289 15676 {
9dc5773f
JJ
15677 location_t expr_loc = c_parser_peek_token (parser)->location;
15678 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15679 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15680 tree c, t = expr.value;
acf0174b
JJ
15681 t = c_fully_fold (t, false, NULL);
15682
32129a17 15683 parens.skip_until_found_close (parser);
acf0174b
JJ
15684
15685 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
20906c66 15686 {
acf0174b
JJ
15687 c_parser_error (parser, "expected integer expression");
15688 return list;
20906c66 15689 }
953ff289 15690
acf0174b 15691 check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE, "device");
953ff289 15692
acf0174b
JJ
15693 c = build_omp_clause (clause_loc, OMP_CLAUSE_DEVICE);
15694 OMP_CLAUSE_DEVICE_ID (c) = t;
15695 OMP_CLAUSE_CHAIN (c) = list;
15696 list = c;
15697 }
953ff289 15698
acf0174b
JJ
15699 return list;
15700}
15701
15702/* OpenMP 4.0:
15703 dist_schedule ( static )
15704 dist_schedule ( static , expression ) */
15705
15706static tree
15707c_parser_omp_clause_dist_schedule (c_parser *parser, tree list)
15708{
15709 tree c, t = NULL_TREE;
15710 location_t loc = c_parser_peek_token (parser)->location;
15711
32129a17
DM
15712 matching_parens parens;
15713 if (!parens.require_open (parser))
acf0174b
JJ
15714 return list;
15715
15716 if (!c_parser_next_token_is_keyword (parser, RID_STATIC))
15717 {
15718 c_parser_error (parser, "invalid dist_schedule kind");
15719 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
15720 "expected %<)%>");
15721 return list;
15722 }
15723
15724 c_parser_consume_token (parser);
15725 if (c_parser_next_token_is (parser, CPP_COMMA))
15726 {
15727 c_parser_consume_token (parser);
15728
9dc5773f
JJ
15729 location_t expr_loc = c_parser_peek_token (parser)->location;
15730 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15731 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15732 t = expr.value;
acf0174b 15733 t = c_fully_fold (t, false, NULL);
32129a17 15734 parens.skip_until_found_close (parser);
acf0174b
JJ
15735 }
15736 else
15737 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
15738 "expected %<,%> or %<)%>");
15739
2c3b8bad
JJ
15740 /* check_no_duplicate_clause (list, OMP_CLAUSE_DIST_SCHEDULE,
15741 "dist_schedule"); */
15742 if (omp_find_clause (list, OMP_CLAUSE_DIST_SCHEDULE))
15743 warning_at (loc, 0, "too many %qs clauses", "dist_schedule");
acf0174b
JJ
15744 if (t == error_mark_node)
15745 return list;
15746
15747 c = build_omp_clause (loc, OMP_CLAUSE_DIST_SCHEDULE);
15748 OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c) = t;
15749 OMP_CLAUSE_CHAIN (c) = list;
15750 return c;
15751}
15752
15753/* OpenMP 4.0:
15754 proc_bind ( proc-bind-kind )
15755
15756 proc-bind-kind:
15757 master | close | spread */
15758
15759static tree
15760c_parser_omp_clause_proc_bind (c_parser *parser, tree list)
15761{
15762 location_t clause_loc = c_parser_peek_token (parser)->location;
15763 enum omp_clause_proc_bind_kind kind;
15764 tree c;
15765
32129a17
DM
15766 matching_parens parens;
15767 if (!parens.require_open (parser))
acf0174b
JJ
15768 return list;
15769
15770 if (c_parser_next_token_is (parser, CPP_NAME))
15771 {
15772 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
15773 if (strcmp ("master", p) == 0)
15774 kind = OMP_CLAUSE_PROC_BIND_MASTER;
15775 else if (strcmp ("close", p) == 0)
15776 kind = OMP_CLAUSE_PROC_BIND_CLOSE;
15777 else if (strcmp ("spread", p) == 0)
15778 kind = OMP_CLAUSE_PROC_BIND_SPREAD;
15779 else
15780 goto invalid_kind;
15781 }
15782 else
15783 goto invalid_kind;
15784
bb522e2e 15785 check_no_duplicate_clause (list, OMP_CLAUSE_PROC_BIND, "proc_bind");
acf0174b 15786 c_parser_consume_token (parser);
32129a17 15787 parens.skip_until_found_close (parser);
acf0174b
JJ
15788 c = build_omp_clause (clause_loc, OMP_CLAUSE_PROC_BIND);
15789 OMP_CLAUSE_PROC_BIND_KIND (c) = kind;
15790 OMP_CLAUSE_CHAIN (c) = list;
15791 return c;
15792
15793 invalid_kind:
15794 c_parser_error (parser, "invalid proc_bind kind");
32129a17 15795 parens.skip_until_found_close (parser);
acf0174b
JJ
15796 return list;
15797}
15798
77eb117f
JJ
15799/* OpenMP 5.0:
15800 device_type ( host | nohost | any ) */
15801
15802static tree
15803c_parser_omp_clause_device_type (c_parser *parser, tree list)
15804{
15805 location_t clause_loc = c_parser_peek_token (parser)->location;
15806 enum omp_clause_device_type_kind kind;
15807 tree c;
15808
15809 matching_parens parens;
15810 if (!parens.require_open (parser))
15811 return list;
15812
15813 if (c_parser_next_token_is (parser, CPP_NAME))
15814 {
15815 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
15816 if (strcmp ("host", p) == 0)
15817 kind = OMP_CLAUSE_DEVICE_TYPE_HOST;
15818 else if (strcmp ("nohost", p) == 0)
15819 kind = OMP_CLAUSE_DEVICE_TYPE_NOHOST;
15820 else if (strcmp ("any", p) == 0)
15821 kind = OMP_CLAUSE_DEVICE_TYPE_ANY;
15822 else
15823 goto invalid_kind;
15824 }
15825 else
15826 goto invalid_kind;
15827
15828 /* check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE_TYPE,
15829 "device_type"); */
15830 c_parser_consume_token (parser);
15831 parens.skip_until_found_close (parser);
15832 c = build_omp_clause (clause_loc, OMP_CLAUSE_DEVICE_TYPE);
15833 OMP_CLAUSE_DEVICE_TYPE_KIND (c) = kind;
15834 OMP_CLAUSE_CHAIN (c) = list;
15835 return c;
15836
15837 invalid_kind:
15838 c_parser_error (parser, "expected %<host%>, %<nohost%> or %<any%>");
15839 parens.skip_until_found_close (parser);
15840 return list;
15841}
15842
acf0174b
JJ
15843/* OpenMP 4.0:
15844 to ( variable-list ) */
15845
15846static tree
15847c_parser_omp_clause_to (c_parser *parser, tree list)
15848{
15849 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_TO, list);
15850}
15851
15852/* OpenMP 4.0:
15853 from ( variable-list ) */
15854
15855static tree
15856c_parser_omp_clause_from (c_parser *parser, tree list)
15857{
15858 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_FROM, list);
15859}
15860
15861/* OpenMP 4.0:
15862 uniform ( variable-list ) */
15863
15864static tree
15865c_parser_omp_clause_uniform (c_parser *parser, tree list)
15866{
15867 /* The clauses location. */
15868 location_t loc = c_parser_peek_token (parser)->location;
15869
32129a17
DM
15870 matching_parens parens;
15871 if (parens.require_open (parser))
acf0174b
JJ
15872 {
15873 list = c_parser_omp_variable_list (parser, loc, OMP_CLAUSE_UNIFORM,
15874 list);
32129a17 15875 parens.skip_until_found_close (parser);
acf0174b
JJ
15876 }
15877 return list;
15878}
15879
41dbbb37
TS
15880/* Parse all OpenACC clauses. The set clauses allowed by the directive
15881 is a bitmask in MASK. Return the list of clauses found. */
15882
15883static tree
15884c_parser_oacc_all_clauses (c_parser *parser, omp_clause_mask mask,
15885 const char *where, bool finish_p = true)
15886{
15887 tree clauses = NULL;
15888 bool first = true;
15889
15890 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
15891 {
15892 location_t here;
15893 pragma_omp_clause c_kind;
15894 const char *c_name;
15895 tree prev = clauses;
15896
15897 if (!first && c_parser_next_token_is (parser, CPP_COMMA))
15898 c_parser_consume_token (parser);
15899
15900 here = c_parser_peek_token (parser)->location;
15901 c_kind = c_parser_omp_clause_name (parser);
15902
15903 switch (c_kind)
15904 {
15905 case PRAGMA_OACC_CLAUSE_ASYNC:
15906 clauses = c_parser_oacc_clause_async (parser, clauses);
15907 c_name = "async";
15908 break;
765dd391 15909 case PRAGMA_OACC_CLAUSE_AUTO:
2263c9f2
TS
15910 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_AUTO,
15911 clauses);
765dd391
CP
15912 c_name = "auto";
15913 break;
519d7496
JB
15914 case PRAGMA_OACC_CLAUSE_ATTACH:
15915 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
15916 c_name = "attach";
15917 break;
41dbbb37
TS
15918 case PRAGMA_OACC_CLAUSE_COLLAPSE:
15919 clauses = c_parser_omp_clause_collapse (parser, clauses);
15920 c_name = "collapse";
15921 break;
15922 case PRAGMA_OACC_CLAUSE_COPY:
15923 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
15924 c_name = "copy";
15925 break;
15926 case PRAGMA_OACC_CLAUSE_COPYIN:
15927 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
15928 c_name = "copyin";
15929 break;
15930 case PRAGMA_OACC_CLAUSE_COPYOUT:
15931 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
15932 c_name = "copyout";
15933 break;
15934 case PRAGMA_OACC_CLAUSE_CREATE:
15935 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
15936 c_name = "create";
15937 break;
15938 case PRAGMA_OACC_CLAUSE_DELETE:
15939 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
15940 c_name = "delete";
15941 break;
7a5e4956
CP
15942 case PRAGMA_OMP_CLAUSE_DEFAULT:
15943 clauses = c_parser_omp_clause_default (parser, clauses, true);
15944 c_name = "default";
15945 break;
519d7496
JB
15946 case PRAGMA_OACC_CLAUSE_DETACH:
15947 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
15948 c_name = "detach";
15949 break;
41dbbb37
TS
15950 case PRAGMA_OACC_CLAUSE_DEVICE:
15951 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
15952 c_name = "device";
15953 break;
15954 case PRAGMA_OACC_CLAUSE_DEVICEPTR:
15955 clauses = c_parser_oacc_data_clause_deviceptr (parser, clauses);
15956 c_name = "deviceptr";
15957 break;
6e232ba4
JN
15958 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT:
15959 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
15960 c_name = "device_resident";
15961 break;
829c6349 15962 case PRAGMA_OACC_CLAUSE_FINALIZE:
2263c9f2 15963 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_FINALIZE,
829c6349
CLT
15964 clauses);
15965 c_name = "finalize";
15966 break;
41dbbb37
TS
15967 case PRAGMA_OACC_CLAUSE_FIRSTPRIVATE:
15968 clauses = c_parser_omp_clause_firstprivate (parser, clauses);
15969 c_name = "firstprivate";
15970 break;
765dd391
CP
15971 case PRAGMA_OACC_CLAUSE_GANG:
15972 c_name = "gang";
2263c9f2 15973 clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_GANG,
765dd391
CP
15974 c_name, clauses);
15975 break;
41dbbb37
TS
15976 case PRAGMA_OACC_CLAUSE_HOST:
15977 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
15978 c_name = "host";
15979 break;
15980 case PRAGMA_OACC_CLAUSE_IF:
d9a6bd32 15981 clauses = c_parser_omp_clause_if (parser, clauses, false);
41dbbb37
TS
15982 c_name = "if";
15983 break;
829c6349 15984 case PRAGMA_OACC_CLAUSE_IF_PRESENT:
2263c9f2 15985 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_IF_PRESENT,
829c6349
CLT
15986 clauses);
15987 c_name = "if_present";
15988 break;
7a5e4956 15989 case PRAGMA_OACC_CLAUSE_INDEPENDENT:
2263c9f2
TS
15990 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_INDEPENDENT,
15991 clauses);
7a5e4956
CP
15992 c_name = "independent";
15993 break;
6e232ba4
JN
15994 case PRAGMA_OACC_CLAUSE_LINK:
15995 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
15996 c_name = "link";
15997 break;
a6163563
JB
15998 case PRAGMA_OACC_CLAUSE_NO_CREATE:
15999 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16000 c_name = "no_create";
16001 break;
41dbbb37 16002 case PRAGMA_OACC_CLAUSE_NUM_GANGS:
1e47f02b
TS
16003 clauses = c_parser_oacc_single_int_clause (parser,
16004 OMP_CLAUSE_NUM_GANGS,
16005 clauses);
41dbbb37
TS
16006 c_name = "num_gangs";
16007 break;
16008 case PRAGMA_OACC_CLAUSE_NUM_WORKERS:
1e47f02b
TS
16009 clauses = c_parser_oacc_single_int_clause (parser,
16010 OMP_CLAUSE_NUM_WORKERS,
16011 clauses);
41dbbb37
TS
16012 c_name = "num_workers";
16013 break;
16014 case PRAGMA_OACC_CLAUSE_PRESENT:
16015 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16016 c_name = "present";
16017 break;
41dbbb37
TS
16018 case PRAGMA_OACC_CLAUSE_PRIVATE:
16019 clauses = c_parser_omp_clause_private (parser, clauses);
16020 c_name = "private";
16021 break;
16022 case PRAGMA_OACC_CLAUSE_REDUCTION:
28567c40
JJ
16023 clauses
16024 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
16025 false, clauses);
41dbbb37
TS
16026 c_name = "reduction";
16027 break;
765dd391 16028 case PRAGMA_OACC_CLAUSE_SEQ:
2263c9f2 16029 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_SEQ,
28567c40 16030 clauses);
765dd391
CP
16031 c_name = "seq";
16032 break;
7a5e4956
CP
16033 case PRAGMA_OACC_CLAUSE_TILE:
16034 clauses = c_parser_oacc_clause_tile (parser, clauses);
16035 c_name = "tile";
16036 break;
ff7a55bf 16037 case PRAGMA_OACC_CLAUSE_USE_DEVICE:
c7b48c8a 16038 clauses = c_parser_omp_clause_use_device_ptr (parser, clauses);
ff7a55bf
TS
16039 c_name = "use_device";
16040 break;
765dd391
CP
16041 case PRAGMA_OACC_CLAUSE_VECTOR:
16042 c_name = "vector";
2263c9f2 16043 clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_VECTOR,
765dd391
CP
16044 c_name, clauses);
16045 break;
41dbbb37 16046 case PRAGMA_OACC_CLAUSE_VECTOR_LENGTH:
1e47f02b
TS
16047 clauses = c_parser_oacc_single_int_clause (parser,
16048 OMP_CLAUSE_VECTOR_LENGTH,
16049 clauses);
41dbbb37
TS
16050 c_name = "vector_length";
16051 break;
16052 case PRAGMA_OACC_CLAUSE_WAIT:
16053 clauses = c_parser_oacc_clause_wait (parser, clauses);
16054 c_name = "wait";
16055 break;
765dd391
CP
16056 case PRAGMA_OACC_CLAUSE_WORKER:
16057 c_name = "worker";
2263c9f2 16058 clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_WORKER,
765dd391
CP
16059 c_name, clauses);
16060 break;
41dbbb37
TS
16061 default:
16062 c_parser_error (parser, "expected %<#pragma acc%> clause");
16063 goto saw_error;
16064 }
16065
16066 first = false;
16067
0bb99c11 16068 if (((mask >> c_kind) & 1) == 0)
41dbbb37
TS
16069 {
16070 /* Remove the invalid clause(s) from the list to avoid
16071 confusing the rest of the compiler. */
16072 clauses = prev;
16073 error_at (here, "%qs is not valid for %qs", c_name, where);
16074 }
16075 }
16076
16077 saw_error:
16078 c_parser_skip_to_pragma_eol (parser);
16079
16080 if (finish_p)
77886428 16081 return c_finish_omp_clauses (clauses, C_ORT_ACC);
41dbbb37
TS
16082
16083 return clauses;
16084}
16085
acf0174b 16086/* Parse all OpenMP clauses. The set clauses allowed by the directive
94e7f906
JJ
16087 is a bitmask in MASK. Return the list of clauses found.
16088 FINISH_P set if c_finish_omp_clauses should be called.
b9424661
JJ
16089 NESTED non-zero if clauses should be terminated by closing paren instead
16090 of end of pragma. If it is 2, additionally commas are required in between
16091 the clauses. */
acf0174b
JJ
16092
16093static tree
16094c_parser_omp_all_clauses (c_parser *parser, omp_clause_mask mask,
94e7f906 16095 const char *where, bool finish_p = true,
b9424661 16096 int nested = 0)
acf0174b
JJ
16097{
16098 tree clauses = NULL;
5e9d6aa4 16099 bool first = true;
acf0174b
JJ
16100
16101 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
16102 {
16103 location_t here;
16104 pragma_omp_clause c_kind;
16105 const char *c_name;
16106 tree prev = clauses;
16107
b9424661 16108 if (nested && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
94e7f906
JJ
16109 break;
16110
b9424661
JJ
16111 if (!first)
16112 {
16113 if (c_parser_next_token_is (parser, CPP_COMMA))
16114 c_parser_consume_token (parser);
16115 else if (nested == 2)
16116 error_at (c_parser_peek_token (parser)->location,
16117 "clauses in %<simd%> trait should be separated "
16118 "by %<,%>");
16119 }
acf0174b
JJ
16120
16121 here = c_parser_peek_token (parser)->location;
16122 c_kind = c_parser_omp_clause_name (parser);
16123
16124 switch (c_kind)
953ff289 16125 {
554a530f
JJ
16126 case PRAGMA_OMP_CLAUSE_BIND:
16127 clauses = c_parser_omp_clause_bind (parser, clauses);
16128 c_name = "bind";
16129 break;
acf0174b
JJ
16130 case PRAGMA_OMP_CLAUSE_COLLAPSE:
16131 clauses = c_parser_omp_clause_collapse (parser, clauses);
16132 c_name = "collapse";
953ff289 16133 break;
acf0174b
JJ
16134 case PRAGMA_OMP_CLAUSE_COPYIN:
16135 clauses = c_parser_omp_clause_copyin (parser, clauses);
16136 c_name = "copyin";
953ff289 16137 break;
acf0174b
JJ
16138 case PRAGMA_OMP_CLAUSE_COPYPRIVATE:
16139 clauses = c_parser_omp_clause_copyprivate (parser, clauses);
16140 c_name = "copyprivate";
953ff289 16141 break;
acf0174b 16142 case PRAGMA_OMP_CLAUSE_DEFAULT:
7a5e4956 16143 clauses = c_parser_omp_clause_default (parser, clauses, false);
acf0174b 16144 c_name = "default";
953ff289 16145 break;
acf0174b
JJ
16146 case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE:
16147 clauses = c_parser_omp_clause_firstprivate (parser, clauses);
16148 c_name = "firstprivate";
953ff289 16149 break;
acf0174b
JJ
16150 case PRAGMA_OMP_CLAUSE_FINAL:
16151 clauses = c_parser_omp_clause_final (parser, clauses);
16152 c_name = "final";
953ff289 16153 break;
d9a6bd32
JJ
16154 case PRAGMA_OMP_CLAUSE_GRAINSIZE:
16155 clauses = c_parser_omp_clause_grainsize (parser, clauses);
16156 c_name = "grainsize";
16157 break;
16158 case PRAGMA_OMP_CLAUSE_HINT:
16159 clauses = c_parser_omp_clause_hint (parser, clauses);
16160 c_name = "hint";
16161 break;
16162 case PRAGMA_OMP_CLAUSE_DEFAULTMAP:
16163 clauses = c_parser_omp_clause_defaultmap (parser, clauses);
16164 c_name = "defaultmap";
16165 break;
acf0174b 16166 case PRAGMA_OMP_CLAUSE_IF:
d9a6bd32 16167 clauses = c_parser_omp_clause_if (parser, clauses, true);
acf0174b 16168 c_name = "if";
953ff289 16169 break;
28567c40
JJ
16170 case PRAGMA_OMP_CLAUSE_IN_REDUCTION:
16171 clauses
16172 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_IN_REDUCTION,
16173 true, clauses);
16174 c_name = "in_reduction";
16175 break;
acf0174b
JJ
16176 case PRAGMA_OMP_CLAUSE_LASTPRIVATE:
16177 clauses = c_parser_omp_clause_lastprivate (parser, clauses);
16178 c_name = "lastprivate";
953ff289 16179 break;
acf0174b
JJ
16180 case PRAGMA_OMP_CLAUSE_MERGEABLE:
16181 clauses = c_parser_omp_clause_mergeable (parser, clauses);
16182 c_name = "mergeable";
953ff289 16183 break;
acf0174b
JJ
16184 case PRAGMA_OMP_CLAUSE_NOWAIT:
16185 clauses = c_parser_omp_clause_nowait (parser, clauses);
16186 c_name = "nowait";
16187 break;
d9a6bd32
JJ
16188 case PRAGMA_OMP_CLAUSE_NUM_TASKS:
16189 clauses = c_parser_omp_clause_num_tasks (parser, clauses);
16190 c_name = "num_tasks";
16191 break;
acf0174b
JJ
16192 case PRAGMA_OMP_CLAUSE_NUM_THREADS:
16193 clauses = c_parser_omp_clause_num_threads (parser, clauses);
16194 c_name = "num_threads";
16195 break;
1fdd6f04
JJ
16196 case PRAGMA_OMP_CLAUSE_ORDER:
16197 clauses = c_parser_omp_clause_order (parser, clauses);
16198 c_name = "order";
16199 break;
acf0174b
JJ
16200 case PRAGMA_OMP_CLAUSE_ORDERED:
16201 clauses = c_parser_omp_clause_ordered (parser, clauses);
16202 c_name = "ordered";
16203 break;
d9a6bd32
JJ
16204 case PRAGMA_OMP_CLAUSE_PRIORITY:
16205 clauses = c_parser_omp_clause_priority (parser, clauses);
16206 c_name = "priority";
16207 break;
acf0174b
JJ
16208 case PRAGMA_OMP_CLAUSE_PRIVATE:
16209 clauses = c_parser_omp_clause_private (parser, clauses);
16210 c_name = "private";
16211 break;
16212 case PRAGMA_OMP_CLAUSE_REDUCTION:
28567c40
JJ
16213 clauses
16214 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
16215 true, clauses);
acf0174b
JJ
16216 c_name = "reduction";
16217 break;
16218 case PRAGMA_OMP_CLAUSE_SCHEDULE:
16219 clauses = c_parser_omp_clause_schedule (parser, clauses);
16220 c_name = "schedule";
16221 break;
16222 case PRAGMA_OMP_CLAUSE_SHARED:
16223 clauses = c_parser_omp_clause_shared (parser, clauses);
16224 c_name = "shared";
16225 break;
28567c40
JJ
16226 case PRAGMA_OMP_CLAUSE_TASK_REDUCTION:
16227 clauses
16228 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_TASK_REDUCTION,
16229 true, clauses);
16230 c_name = "task_reduction";
16231 break;
acf0174b
JJ
16232 case PRAGMA_OMP_CLAUSE_UNTIED:
16233 clauses = c_parser_omp_clause_untied (parser, clauses);
16234 c_name = "untied";
16235 break;
16236 case PRAGMA_OMP_CLAUSE_INBRANCH:
16237 clauses = c_parser_omp_clause_branch (parser, OMP_CLAUSE_INBRANCH,
16238 clauses);
16239 c_name = "inbranch";
16240 break;
28567c40
JJ
16241 case PRAGMA_OMP_CLAUSE_NONTEMPORAL:
16242 clauses = c_parser_omp_clause_nontemporal (parser, clauses);
16243 c_name = "nontemporal";
16244 break;
acf0174b
JJ
16245 case PRAGMA_OMP_CLAUSE_NOTINBRANCH:
16246 clauses = c_parser_omp_clause_branch (parser, OMP_CLAUSE_NOTINBRANCH,
16247 clauses);
16248 c_name = "notinbranch";
16249 break;
16250 case PRAGMA_OMP_CLAUSE_PARALLEL:
16251 clauses
16252 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_PARALLEL,
16253 clauses);
16254 c_name = "parallel";
16255 if (!first)
20906c66 16256 {
acf0174b
JJ
16257 clause_not_first:
16258 error_at (here, "%qs must be the first clause of %qs",
16259 c_name, where);
16260 clauses = prev;
16261 }
16262 break;
16263 case PRAGMA_OMP_CLAUSE_FOR:
16264 clauses
16265 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_FOR,
16266 clauses);
16267 c_name = "for";
16268 if (!first)
16269 goto clause_not_first;
16270 break;
16271 case PRAGMA_OMP_CLAUSE_SECTIONS:
16272 clauses
16273 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_SECTIONS,
16274 clauses);
16275 c_name = "sections";
16276 if (!first)
16277 goto clause_not_first;
16278 break;
16279 case PRAGMA_OMP_CLAUSE_TASKGROUP:
16280 clauses
16281 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_TASKGROUP,
16282 clauses);
16283 c_name = "taskgroup";
16284 if (!first)
16285 goto clause_not_first;
16286 break;
d9a6bd32
JJ
16287 case PRAGMA_OMP_CLAUSE_LINK:
16288 clauses
16289 = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_LINK, clauses);
16290 c_name = "link";
16291 break;
acf0174b 16292 case PRAGMA_OMP_CLAUSE_TO:
d9a6bd32
JJ
16293 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK)) != 0)
16294 clauses
16295 = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_TO_DECLARE,
16296 clauses);
16297 else
16298 clauses = c_parser_omp_clause_to (parser, clauses);
acf0174b
JJ
16299 c_name = "to";
16300 break;
16301 case PRAGMA_OMP_CLAUSE_FROM:
16302 clauses = c_parser_omp_clause_from (parser, clauses);
16303 c_name = "from";
16304 break;
16305 case PRAGMA_OMP_CLAUSE_UNIFORM:
16306 clauses = c_parser_omp_clause_uniform (parser, clauses);
16307 c_name = "uniform";
16308 break;
16309 case PRAGMA_OMP_CLAUSE_NUM_TEAMS:
16310 clauses = c_parser_omp_clause_num_teams (parser, clauses);
16311 c_name = "num_teams";
16312 break;
16313 case PRAGMA_OMP_CLAUSE_THREAD_LIMIT:
16314 clauses = c_parser_omp_clause_thread_limit (parser, clauses);
16315 c_name = "thread_limit";
16316 break;
16317 case PRAGMA_OMP_CLAUSE_ALIGNED:
16318 clauses = c_parser_omp_clause_aligned (parser, clauses);
16319 c_name = "aligned";
16320 break;
41958c28 16321 case PRAGMA_OMP_CLAUSE_LINEAR:
5e9d6aa4 16322 clauses = c_parser_omp_clause_linear (parser, clauses);
acf0174b
JJ
16323 c_name = "linear";
16324 break;
16325 case PRAGMA_OMP_CLAUSE_DEPEND:
16326 clauses = c_parser_omp_clause_depend (parser, clauses);
16327 c_name = "depend";
16328 break;
16329 case PRAGMA_OMP_CLAUSE_MAP:
16330 clauses = c_parser_omp_clause_map (parser, clauses);
16331 c_name = "map";
16332 break;
d9a6bd32
JJ
16333 case PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR:
16334 clauses = c_parser_omp_clause_use_device_ptr (parser, clauses);
16335 c_name = "use_device_ptr";
16336 break;
398e3feb
JJ
16337 case PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR:
16338 clauses = c_parser_omp_clause_use_device_addr (parser, clauses);
16339 c_name = "use_device_addr";
16340 break;
d9a6bd32
JJ
16341 case PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR:
16342 clauses = c_parser_omp_clause_is_device_ptr (parser, clauses);
16343 c_name = "is_device_ptr";
16344 break;
acf0174b
JJ
16345 case PRAGMA_OMP_CLAUSE_DEVICE:
16346 clauses = c_parser_omp_clause_device (parser, clauses);
16347 c_name = "device";
16348 break;
16349 case PRAGMA_OMP_CLAUSE_DIST_SCHEDULE:
16350 clauses = c_parser_omp_clause_dist_schedule (parser, clauses);
16351 c_name = "dist_schedule";
16352 break;
16353 case PRAGMA_OMP_CLAUSE_PROC_BIND:
16354 clauses = c_parser_omp_clause_proc_bind (parser, clauses);
16355 c_name = "proc_bind";
16356 break;
77eb117f
JJ
16357 case PRAGMA_OMP_CLAUSE_DEVICE_TYPE:
16358 clauses = c_parser_omp_clause_device_type (parser, clauses);
16359 c_name = "device_type";
16360 break;
acf0174b
JJ
16361 case PRAGMA_OMP_CLAUSE_SAFELEN:
16362 clauses = c_parser_omp_clause_safelen (parser, clauses);
16363 c_name = "safelen";
16364 break;
16365 case PRAGMA_OMP_CLAUSE_SIMDLEN:
16366 clauses = c_parser_omp_clause_simdlen (parser, clauses);
16367 c_name = "simdlen";
16368 break;
d9a6bd32
JJ
16369 case PRAGMA_OMP_CLAUSE_NOGROUP:
16370 clauses = c_parser_omp_clause_nogroup (parser, clauses);
16371 c_name = "nogroup";
16372 break;
16373 case PRAGMA_OMP_CLAUSE_THREADS:
16374 clauses
16375 = c_parser_omp_clause_orderedkind (parser, OMP_CLAUSE_THREADS,
16376 clauses);
16377 c_name = "threads";
16378 break;
16379 case PRAGMA_OMP_CLAUSE_SIMD:
16380 clauses
16381 = c_parser_omp_clause_orderedkind (parser, OMP_CLAUSE_SIMD,
16382 clauses);
16383 c_name = "simd";
16384 break;
953ff289 16385 default:
acf0174b 16386 c_parser_error (parser, "expected %<#pragma omp%> clause");
953ff289
DN
16387 goto saw_error;
16388 }
16389
acf0174b
JJ
16390 first = false;
16391
0bb99c11 16392 if (((mask >> c_kind) & 1) == 0)
acf0174b
JJ
16393 {
16394 /* Remove the invalid clause(s) from the list to avoid
16395 confusing the rest of the compiler. */
16396 clauses = prev;
16397 error_at (here, "%qs is not valid for %qs", c_name, where);
16398 }
16399 }
16400
16401 saw_error:
b9424661 16402 if (!nested)
94e7f906 16403 c_parser_skip_to_pragma_eol (parser);
acf0174b
JJ
16404
16405 if (finish_p)
d9a6bd32
JJ
16406 {
16407 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM)) != 0)
77886428
CP
16408 return c_finish_omp_clauses (clauses, C_ORT_OMP_DECLARE_SIMD);
16409 return c_finish_omp_clauses (clauses, C_ORT_OMP);
d9a6bd32 16410 }
acf0174b
JJ
16411
16412 return clauses;
16413}
16414
41dbbb37 16415/* OpenACC 2.0, OpenMP 2.5:
acf0174b
JJ
16416 structured-block:
16417 statement
16418
16419 In practice, we're also interested in adding the statement to an
16420 outer node. So it is convenient if we work around the fact that
16421 c_parser_statement calls add_stmt. */
16422
16423static tree
dda1bf61 16424c_parser_omp_structured_block (c_parser *parser, bool *if_p)
acf0174b
JJ
16425{
16426 tree stmt = push_stmt_list ();
dda1bf61 16427 c_parser_statement (parser, if_p);
acf0174b
JJ
16428 return pop_stmt_list (stmt);
16429}
16430
41dbbb37
TS
16431/* OpenACC 2.0:
16432 # pragma acc cache (variable-list) new-line
16433
16434 LOC is the location of the #pragma token.
16435*/
16436
16437static tree
16438c_parser_oacc_cache (location_t loc, c_parser *parser)
16439{
16440 tree stmt, clauses;
16441
16442 clauses = c_parser_omp_var_list_parens (parser, OMP_CLAUSE__CACHE_, NULL);
77886428 16443 clauses = c_finish_omp_clauses (clauses, C_ORT_ACC);
41dbbb37
TS
16444
16445 c_parser_skip_to_pragma_eol (parser);
16446
16447 stmt = make_node (OACC_CACHE);
16448 TREE_TYPE (stmt) = void_type_node;
16449 OACC_CACHE_CLAUSES (stmt) = clauses;
16450 SET_EXPR_LOCATION (stmt, loc);
16451 add_stmt (stmt);
16452
16453 return stmt;
16454}
16455
16456/* OpenACC 2.0:
16457 # pragma acc data oacc-data-clause[optseq] new-line
16458 structured-block
16459
16460 LOC is the location of the #pragma token.
16461*/
16462
16463#define OACC_DATA_CLAUSE_MASK \
519d7496
JB
16464 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
16465 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
41dbbb37
TS
16466 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
16467 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
16468 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
16469 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
16470 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
a6163563 16471 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
829c6349 16472 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
41dbbb37
TS
16473
16474static tree
dda1bf61 16475c_parser_oacc_data (location_t loc, c_parser *parser, bool *if_p)
41dbbb37
TS
16476{
16477 tree stmt, clauses, block;
16478
16479 clauses = c_parser_oacc_all_clauses (parser, OACC_DATA_CLAUSE_MASK,
16480 "#pragma acc data");
16481
16482 block = c_begin_omp_parallel ();
dda1bf61 16483 add_stmt (c_parser_omp_structured_block (parser, if_p));
41dbbb37
TS
16484
16485 stmt = c_finish_oacc_data (loc, clauses, block);
16486
16487 return stmt;
16488}
16489
6e232ba4
JN
16490/* OpenACC 2.0:
16491 # pragma acc declare oacc-data-clause[optseq] new-line
16492*/
16493
16494#define OACC_DECLARE_CLAUSE_MASK \
16495 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
16496 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
16497 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
16498 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
16499 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
16500 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT) \
16501 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_LINK) \
829c6349 16502 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
6e232ba4
JN
16503
16504static void
16505c_parser_oacc_declare (c_parser *parser)
16506{
16507 location_t pragma_loc = c_parser_peek_token (parser)->location;
16508 tree clauses, stmt, t, decl;
16509
16510 bool error = false;
16511
16512 c_parser_consume_pragma (parser);
16513
16514 clauses = c_parser_oacc_all_clauses (parser, OACC_DECLARE_CLAUSE_MASK,
16515 "#pragma acc declare");
16516 if (!clauses)
16517 {
16518 error_at (pragma_loc,
16519 "no valid clauses specified in %<#pragma acc declare%>");
16520 return;
16521 }
16522
16523 for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t))
16524 {
16525 location_t loc = OMP_CLAUSE_LOCATION (t);
16526 decl = OMP_CLAUSE_DECL (t);
16527 if (!DECL_P (decl))
16528 {
16529 error_at (loc, "array section in %<#pragma acc declare%>");
16530 error = true;
16531 continue;
16532 }
16533
16534 switch (OMP_CLAUSE_MAP_KIND (t))
16535 {
e46c7770 16536 case GOMP_MAP_FIRSTPRIVATE_POINTER:
829c6349
CLT
16537 case GOMP_MAP_ALLOC:
16538 case GOMP_MAP_TO:
6e232ba4
JN
16539 case GOMP_MAP_FORCE_DEVICEPTR:
16540 case GOMP_MAP_DEVICE_RESIDENT:
16541 break;
16542
6e232ba4
JN
16543 case GOMP_MAP_LINK:
16544 if (!global_bindings_p ()
16545 && (TREE_STATIC (decl)
16546 || !DECL_EXTERNAL (decl)))
16547 {
16548 error_at (loc,
aa326bfb 16549 "%qD must be a global variable in "
6e232ba4
JN
16550 "%<#pragma acc declare link%>",
16551 decl);
16552 error = true;
16553 continue;
16554 }
16555 break;
16556
16557 default:
16558 if (global_bindings_p ())
16559 {
16560 error_at (loc, "invalid OpenACC clause at file scope");
16561 error = true;
16562 continue;
16563 }
16564 if (DECL_EXTERNAL (decl))
16565 {
16566 error_at (loc,
16567 "invalid use of %<extern%> variable %qD "
16568 "in %<#pragma acc declare%>", decl);
16569 error = true;
16570 continue;
16571 }
16572 else if (TREE_PUBLIC (decl))
16573 {
16574 error_at (loc,
16575 "invalid use of %<global%> variable %qD "
16576 "in %<#pragma acc declare%>", decl);
16577 error = true;
16578 continue;
16579 }
16580 break;
16581 }
16582
16583 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl))
16584 || lookup_attribute ("omp declare target link",
16585 DECL_ATTRIBUTES (decl)))
16586 {
16587 error_at (loc, "variable %qD used more than once with "
16588 "%<#pragma acc declare%>", decl);
16589 error = true;
16590 continue;
16591 }
16592
16593 if (!error)
16594 {
16595 tree id;
16596
16597 if (OMP_CLAUSE_MAP_KIND (t) == GOMP_MAP_LINK)
16598 id = get_identifier ("omp declare target link");
16599 else
16600 id = get_identifier ("omp declare target");
16601
16602 DECL_ATTRIBUTES (decl)
16603 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (decl));
16604
16605 if (global_bindings_p ())
16606 {
16607 symtab_node *node = symtab_node::get (decl);
16608 if (node != NULL)
16609 {
16610 node->offloadable = 1;
688c4de0 16611 if (ENABLE_OFFLOADING)
6e232ba4 16612 {
688c4de0
IV
16613 g->have_offload = true;
16614 if (is_a <varpool_node *> (node))
e6d6ec9e 16615 vec_safe_push (offload_vars, decl);
6e232ba4 16616 }
6e232ba4
JN
16617 }
16618 }
16619 }
16620 }
16621
16622 if (error || global_bindings_p ())
16623 return;
16624
16625 stmt = make_node (OACC_DECLARE);
16626 TREE_TYPE (stmt) = void_type_node;
16627 OACC_DECLARE_CLAUSES (stmt) = clauses;
16628 SET_EXPR_LOCATION (stmt, pragma_loc);
16629
16630 add_stmt (stmt);
16631
16632 return;
16633}
16634
41dbbb37
TS
16635/* OpenACC 2.0:
16636 # pragma acc enter data oacc-enter-data-clause[optseq] new-line
16637
16638 or
16639
16640 # pragma acc exit data oacc-exit-data-clause[optseq] new-line
16641
16642
16643 LOC is the location of the #pragma token.
16644*/
16645
16646#define OACC_ENTER_DATA_CLAUSE_MASK \
16647 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
16648 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
519d7496 16649 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
41dbbb37
TS
16650 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
16651 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
41dbbb37
TS
16652 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
16653
16654#define OACC_EXIT_DATA_CLAUSE_MASK \
16655 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
16656 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
16657 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
16658 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DELETE) \
519d7496 16659 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DETACH) \
829c6349 16660 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FINALIZE) \
41dbbb37
TS
16661 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
16662
16663static void
16664c_parser_oacc_enter_exit_data (c_parser *parser, bool enter)
16665{
16666 location_t loc = c_parser_peek_token (parser)->location;
16667 tree clauses, stmt;
c5af52eb 16668 const char *p = "";
41dbbb37
TS
16669
16670 c_parser_consume_pragma (parser);
16671
c5af52eb 16672 if (c_parser_next_token_is (parser, CPP_NAME))
41dbbb37 16673 {
c5af52eb
CP
16674 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16675 c_parser_consume_token (parser);
41dbbb37
TS
16676 }
16677
41dbbb37
TS
16678 if (strcmp (p, "data") != 0)
16679 {
324ff1a0
JJ
16680 error_at (loc, "expected %<data%> after %<#pragma acc %s%>",
16681 enter ? "enter" : "exit");
c5af52eb 16682 parser->error = true;
41dbbb37
TS
16683 c_parser_skip_to_pragma_eol (parser);
16684 return;
16685 }
16686
41dbbb37
TS
16687 if (enter)
16688 clauses = c_parser_oacc_all_clauses (parser, OACC_ENTER_DATA_CLAUSE_MASK,
16689 "#pragma acc enter data");
16690 else
16691 clauses = c_parser_oacc_all_clauses (parser, OACC_EXIT_DATA_CLAUSE_MASK,
16692 "#pragma acc exit data");
16693
629b3d75 16694 if (omp_find_clause (clauses, OMP_CLAUSE_MAP) == NULL_TREE)
41dbbb37 16695 {
324ff1a0
JJ
16696 error_at (loc, "%<#pragma acc %s data%> has no data movement clause",
16697 enter ? "enter" : "exit");
41dbbb37
TS
16698 return;
16699 }
16700
06aca1d5 16701 stmt = enter ? make_node (OACC_ENTER_DATA) : make_node (OACC_EXIT_DATA);
41dbbb37 16702 TREE_TYPE (stmt) = void_type_node;
b811915d 16703 OMP_STANDALONE_CLAUSES (stmt) = clauses;
41dbbb37
TS
16704 SET_EXPR_LOCATION (stmt, loc);
16705 add_stmt (stmt);
16706}
16707
16708
37d5ad46
JB
16709/* OpenACC 2.0:
16710 # pragma acc host_data oacc-data-clause[optseq] new-line
16711 structured-block
16712*/
16713
16714#define OACC_HOST_DATA_CLAUSE_MASK \
d5c23c6c
TB
16715 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_USE_DEVICE) \
16716 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
16717 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) )
37d5ad46
JB
16718
16719static tree
dda1bf61 16720c_parser_oacc_host_data (location_t loc, c_parser *parser, bool *if_p)
37d5ad46
JB
16721{
16722 tree stmt, clauses, block;
16723
16724 clauses = c_parser_oacc_all_clauses (parser, OACC_HOST_DATA_CLAUSE_MASK,
16725 "#pragma acc host_data");
16726
16727 block = c_begin_omp_parallel ();
dda1bf61 16728 add_stmt (c_parser_omp_structured_block (parser, if_p));
37d5ad46
JB
16729 stmt = c_finish_oacc_host_data (loc, clauses, block);
16730 return stmt;
16731}
16732
16733
41dbbb37
TS
16734/* OpenACC 2.0:
16735
16736 # pragma acc loop oacc-loop-clause[optseq] new-line
16737 structured-block
16738
16739 LOC is the location of the #pragma token.
16740*/
16741
16742#define OACC_LOOP_CLAUSE_MASK \
16743 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COLLAPSE) \
7a5e4956
CP
16744 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
16745 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
765dd391
CP
16746 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
16747 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
16748 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
16749 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_AUTO) \
7a5e4956 16750 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_INDEPENDENT) \
765dd391 16751 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \
7a5e4956 16752 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_TILE) )
41dbbb37 16753static tree
88bae6f4 16754c_parser_oacc_loop (location_t loc, c_parser *parser, char *p_name,
dda1bf61 16755 omp_clause_mask mask, tree *cclauses, bool *if_p)
41dbbb37 16756{
e7ff0319
CP
16757 bool is_parallel = ((mask >> PRAGMA_OACC_CLAUSE_REDUCTION) & 1) == 1;
16758
41dbbb37 16759 strcat (p_name, " loop");
88bae6f4 16760 mask |= OACC_LOOP_CLAUSE_MASK;
41dbbb37 16761
88bae6f4
TS
16762 tree clauses = c_parser_oacc_all_clauses (parser, mask, p_name,
16763 cclauses == NULL);
16764 if (cclauses)
16765 {
e7ff0319 16766 clauses = c_oacc_split_loop_clauses (clauses, cclauses, is_parallel);
88bae6f4 16767 if (*cclauses)
77886428 16768 *cclauses = c_finish_omp_clauses (*cclauses, C_ORT_ACC);
88bae6f4 16769 if (clauses)
77886428 16770 clauses = c_finish_omp_clauses (clauses, C_ORT_ACC);
88bae6f4 16771 }
41dbbb37 16772
88bae6f4 16773 tree block = c_begin_compound_stmt (true);
dda1bf61
JJ
16774 tree stmt = c_parser_omp_for_loop (loc, parser, OACC_LOOP, clauses, NULL,
16775 if_p);
41dbbb37
TS
16776 block = c_end_compound_stmt (loc, block, true);
16777 add_stmt (block);
16778
16779 return stmt;
16780}
16781
16782/* OpenACC 2.0:
88bae6f4
TS
16783 # pragma acc kernels oacc-kernels-clause[optseq] new-line
16784 structured-block
16785
16786 or
16787
41dbbb37
TS
16788 # pragma acc parallel oacc-parallel-clause[optseq] new-line
16789 structured-block
16790
62aee289
MR
16791 OpenACC 2.6:
16792
16793 # pragma acc serial oacc-serial-clause[optseq] new-line
16794 structured-block
16795
41dbbb37
TS
16796 LOC is the location of the #pragma token.
16797*/
16798
88bae6f4
TS
16799#define OACC_KERNELS_CLAUSE_MASK \
16800 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
519d7496 16801 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
88bae6f4
TS
16802 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
16803 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
16804 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
16805 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
7a5e4956 16806 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
88bae6f4
TS
16807 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
16808 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
a6163563 16809 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
fd71a9a2
TS
16810 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
16811 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
88bae6f4 16812 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
fd71a9a2 16813 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
88bae6f4
TS
16814 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
16815
41dbbb37
TS
16816#define OACC_PARALLEL_CLAUSE_MASK \
16817 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
519d7496 16818 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
41dbbb37
TS
16819 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
16820 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
16821 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
16822 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
7a5e4956 16823 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
41dbbb37
TS
16824 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
16825 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
a6163563 16826 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
7a5e4956
CP
16827 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
16828 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
41dbbb37
TS
16829 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
16830 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
16831 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
41dbbb37
TS
16832 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
16833 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
16834 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
16835
62aee289
MR
16836#define OACC_SERIAL_CLAUSE_MASK \
16837 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
519d7496 16838 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
62aee289
MR
16839 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
16840 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
16841 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
16842 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
16843 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
16844 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
16845 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
a6163563 16846 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
62aee289
MR
16847 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
16848 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
16849 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
16850 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
16851 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
16852
41dbbb37 16853static tree
62aee289
MR
16854c_parser_oacc_compute (location_t loc, c_parser *parser,
16855 enum pragma_kind p_kind, char *p_name, bool *if_p)
41dbbb37 16856{
88bae6f4
TS
16857 omp_clause_mask mask;
16858 enum tree_code code;
16859 switch (p_kind)
16860 {
16861 case PRAGMA_OACC_KERNELS:
16862 strcat (p_name, " kernels");
16863 mask = OACC_KERNELS_CLAUSE_MASK;
16864 code = OACC_KERNELS;
16865 break;
16866 case PRAGMA_OACC_PARALLEL:
16867 strcat (p_name, " parallel");
16868 mask = OACC_PARALLEL_CLAUSE_MASK;
16869 code = OACC_PARALLEL;
16870 break;
62aee289
MR
16871 case PRAGMA_OACC_SERIAL:
16872 strcat (p_name, " serial");
16873 mask = OACC_SERIAL_CLAUSE_MASK;
16874 code = OACC_SERIAL;
16875 break;
88bae6f4
TS
16876 default:
16877 gcc_unreachable ();
16878 }
41dbbb37
TS
16879
16880 if (c_parser_next_token_is (parser, CPP_NAME))
16881 {
16882 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16883 if (strcmp (p, "loop") == 0)
16884 {
16885 c_parser_consume_token (parser);
88bae6f4
TS
16886 tree block = c_begin_omp_parallel ();
16887 tree clauses;
dda1bf61 16888 c_parser_oacc_loop (loc, parser, p_name, mask, &clauses, if_p);
88bae6f4 16889 return c_finish_omp_construct (loc, code, block, clauses);
41dbbb37
TS
16890 }
16891 }
16892
88bae6f4 16893 tree clauses = c_parser_oacc_all_clauses (parser, mask, p_name);
41dbbb37 16894
88bae6f4 16895 tree block = c_begin_omp_parallel ();
dda1bf61 16896 add_stmt (c_parser_omp_structured_block (parser, if_p));
41dbbb37 16897
88bae6f4 16898 return c_finish_omp_construct (loc, code, block, clauses);
41dbbb37
TS
16899}
16900
3a40d81d
NS
16901/* OpenACC 2.0:
16902 # pragma acc routine oacc-routine-clause[optseq] new-line
16903 function-definition
16904
16905 # pragma acc routine ( name ) oacc-routine-clause[optseq] new-line
16906*/
16907
16908#define OACC_ROUTINE_CLAUSE_MASK \
16909 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
16910 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
16911 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
16912 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) )
16913
16914/* Parse an OpenACC routine directive. For named directives, we apply
16915 immediately to the named function. For unnamed ones we then parse
16916 a declaration or definition, which must be for a function. */
16917
16918static void
16919c_parser_oacc_routine (c_parser *parser, enum pragma_context context)
16920{
ae9281fc
TS
16921 gcc_checking_assert (context == pragma_external);
16922
0b212d8c 16923 oacc_routine_data data;
ae9281fc
TS
16924 data.error_seen = false;
16925 data.fndecl_seen = false;
0b212d8c
TS
16926 data.clauses = NULL_TREE;
16927 data.loc = c_parser_peek_token (parser)->location;
3a40d81d
NS
16928
16929 c_parser_consume_pragma (parser);
16930
ae9281fc
TS
16931 /* Look for optional '( name )'. */
16932 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
3a40d81d 16933 {
ae9281fc 16934 c_parser_consume_token (parser); /* '(' */
3a40d81d 16935
ae9281fc
TS
16936 tree decl = NULL_TREE;
16937 c_token *name_token = c_parser_peek_token (parser);
16938 location_t name_loc = name_token->location;
16939 if (name_token->type == CPP_NAME
16940 && (name_token->id_kind == C_ID_ID
16941 || name_token->id_kind == C_ID_TYPENAME))
3a40d81d 16942 {
ae9281fc 16943 decl = lookup_name (name_token->value);
3a40d81d 16944 if (!decl)
ae9281fc
TS
16945 error_at (name_loc,
16946 "%qE has not been declared", name_token->value);
a04e69c0 16947 c_parser_consume_token (parser);
3a40d81d
NS
16948 }
16949 else
16950 c_parser_error (parser, "expected function name");
16951
a04e69c0
TS
16952 if (!decl
16953 || !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
16954 {
16955 c_parser_skip_to_pragma_eol (parser, false);
16956 return;
16957 }
ae9281fc
TS
16958
16959 data.clauses
16960 = c_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK,
16961 "#pragma acc routine");
5bf04509
TS
16962 /* The clauses are in reverse order; fix that to make later diagnostic
16963 emission easier. */
16964 data.clauses = nreverse (data.clauses);
ae9281fc
TS
16965
16966 if (TREE_CODE (decl) != FUNCTION_DECL)
16967 {
16968 error_at (name_loc, "%qD does not refer to a function", decl);
16969 return;
16970 }
16971
16972 c_finish_oacc_routine (&data, decl, false);
3a40d81d 16973 }
ae9281fc
TS
16974 else /* No optional '( name )'. */
16975 {
16976 data.clauses
16977 = c_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK,
16978 "#pragma acc routine");
5bf04509
TS
16979 /* The clauses are in reverse order; fix that to make later diagnostic
16980 emission easier. */
16981 data.clauses = nreverse (data.clauses);
3a40d81d 16982
ae9281fc
TS
16983 /* Emit a helpful diagnostic if there's another pragma following this
16984 one. Also don't allow a static assertion declaration, as in the
16985 following we'll just parse a *single* "declaration or function
16986 definition", and the static assertion counts an one. */
16987 if (c_parser_next_token_is (parser, CPP_PRAGMA)
16988 || c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
16989 {
16990 error_at (data.loc,
16991 "%<#pragma acc routine%> not immediately followed by"
16992 " function declaration or definition");
16993 /* ..., and then just keep going. */
16994 return;
16995 }
16996
16997 /* We only have to consider the pragma_external case here. */
16998 if (c_parser_next_token_is (parser, CPP_KEYWORD)
16999 && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
17000 {
17001 int ext = disable_extension_diagnostics ();
17002 do
17003 c_parser_consume_token (parser);
17004 while (c_parser_next_token_is (parser, CPP_KEYWORD)
17005 && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
17006 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
4e03c3a7 17007 NULL, vNULL, false, NULL, &data);
ae9281fc
TS
17008 restore_extension_diagnostics (ext);
17009 }
17010 else
17011 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
4e03c3a7 17012 NULL, vNULL, false, NULL, &data);
ae9281fc 17013 }
3a40d81d
NS
17014}
17015
0b212d8c
TS
17016/* Finalize an OpenACC routine pragma, applying it to FNDECL.
17017 IS_DEFN is true if we're applying it to the definition. */
3a40d81d
NS
17018
17019static void
0b212d8c 17020c_finish_oacc_routine (struct oacc_routine_data *data, tree fndecl,
ae9281fc 17021 bool is_defn)
3a40d81d 17022{
ae9281fc
TS
17023 /* Keep going if we're in error reporting mode. */
17024 if (data->error_seen
17025 || fndecl == error_mark_node)
17026 return;
17027
17028 if (data->fndecl_seen)
3a40d81d 17029 {
ae9281fc
TS
17030 error_at (data->loc,
17031 "%<#pragma acc routine%> not immediately followed by"
17032 " a single function declaration or definition");
17033 data->error_seen = true;
17034 return;
17035 }
17036 if (fndecl == NULL_TREE || TREE_CODE (fndecl) != FUNCTION_DECL)
17037 {
17038 error_at (data->loc,
17039 "%<#pragma acc routine%> not immediately followed by"
17040 " function declaration or definition");
17041 data->error_seen = true;
3a40d81d
NS
17042 return;
17043 }
17044
b48f44bf
TS
17045 int compatible
17046 = oacc_verify_routine_clauses (fndecl, &data->clauses, data->loc,
17047 "#pragma acc routine");
17048 if (compatible < 0)
ae9281fc 17049 {
ae9281fc
TS
17050 data->error_seen = true;
17051 return;
17052 }
b48f44bf 17053 if (compatible > 0)
ae9281fc 17054 {
ae9281fc 17055 }
b48f44bf
TS
17056 else
17057 {
17058 if (TREE_USED (fndecl) || (!is_defn && DECL_SAVED_TREE (fndecl)))
17059 {
17060 error_at (data->loc,
17061 TREE_USED (fndecl)
17062 ? G_("%<#pragma acc routine%> must be applied before use")
17063 : G_("%<#pragma acc routine%> must be applied before"
17064 " definition"));
17065 data->error_seen = true;
17066 return;
17067 }
3a40d81d 17068
b48f44bf
TS
17069 /* Set the routine's level of parallelism. */
17070 tree dims = oacc_build_routine_dims (data->clauses);
17071 oacc_replace_fn_attrib (fndecl, dims);
3a40d81d 17072
b48f44bf
TS
17073 /* Add an "omp declare target" attribute. */
17074 DECL_ATTRIBUTES (fndecl)
17075 = tree_cons (get_identifier ("omp declare target"),
17076 data->clauses, DECL_ATTRIBUTES (fndecl));
17077 }
ae9281fc
TS
17078
17079 /* Remember that we've used this "#pragma acc routine". */
17080 data->fndecl_seen = true;
3a40d81d
NS
17081}
17082
41dbbb37
TS
17083/* OpenACC 2.0:
17084 # pragma acc update oacc-update-clause[optseq] new-line
17085*/
17086
17087#define OACC_UPDATE_CLAUSE_MASK \
17088 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17089 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE) \
17090 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_HOST) \
17091 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
829c6349 17092 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) \
41dbbb37
TS
17093 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17094
17095static void
17096c_parser_oacc_update (c_parser *parser)
17097{
17098 location_t loc = c_parser_peek_token (parser)->location;
17099
17100 c_parser_consume_pragma (parser);
17101
17102 tree clauses = c_parser_oacc_all_clauses (parser, OACC_UPDATE_CLAUSE_MASK,
17103 "#pragma acc update");
629b3d75 17104 if (omp_find_clause (clauses, OMP_CLAUSE_MAP) == NULL_TREE)
41dbbb37
TS
17105 {
17106 error_at (loc,
17107 "%<#pragma acc update%> must contain at least one "
7a5e4956 17108 "%<device%> or %<host%> or %<self%> clause");
41dbbb37
TS
17109 return;
17110 }
17111
17112 if (parser->error)
17113 return;
17114
17115 tree stmt = make_node (OACC_UPDATE);
17116 TREE_TYPE (stmt) = void_type_node;
17117 OACC_UPDATE_CLAUSES (stmt) = clauses;
17118 SET_EXPR_LOCATION (stmt, loc);
17119 add_stmt (stmt);
17120}
17121
17122/* OpenACC 2.0:
17123 # pragma acc wait [(intseq)] oacc-wait-clause[optseq] new-line
17124
17125 LOC is the location of the #pragma token.
17126*/
17127
17128#define OACC_WAIT_CLAUSE_MASK \
17129 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) )
17130
17131static tree
17132c_parser_oacc_wait (location_t loc, c_parser *parser, char *p_name)
17133{
17134 tree clauses, list = NULL_TREE, stmt = NULL_TREE;
17135
17136 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
17137 list = c_parser_oacc_wait_list (parser, loc, list);
17138
17139 strcpy (p_name, " wait");
17140 clauses = c_parser_oacc_all_clauses (parser, OACC_WAIT_CLAUSE_MASK, p_name);
17141 stmt = c_finish_oacc_wait (loc, list, clauses);
04d2fbcc 17142 add_stmt (stmt);
41dbbb37
TS
17143
17144 return stmt;
17145}
17146
acf0174b
JJ
17147/* OpenMP 2.5:
17148 # pragma omp atomic new-line
17149 expression-stmt
17150
17151 expression-stmt:
17152 x binop= expr | x++ | ++x | x-- | --x
17153 binop:
17154 +, *, -, /, &, ^, |, <<, >>
17155
17156 where x is an lvalue expression with scalar type.
17157
17158 OpenMP 3.1:
17159 # pragma omp atomic new-line
17160 update-stmt
17161
17162 # pragma omp atomic read new-line
17163 read-stmt
17164
17165 # pragma omp atomic write new-line
17166 write-stmt
17167
17168 # pragma omp atomic update new-line
17169 update-stmt
17170
17171 # pragma omp atomic capture new-line
17172 capture-stmt
17173
17174 # pragma omp atomic capture new-line
17175 capture-block
17176
17177 read-stmt:
17178 v = x
17179 write-stmt:
17180 x = expr
17181 update-stmt:
17182 expression-stmt | x = x binop expr
17183 capture-stmt:
17184 v = expression-stmt
17185 capture-block:
17186 { v = x; update-stmt; } | { update-stmt; v = x; }
17187
17188 OpenMP 4.0:
17189 update-stmt:
17190 expression-stmt | x = x binop expr | x = expr binop x
17191 capture-stmt:
17192 v = update-stmt
17193 capture-block:
17194 { v = x; update-stmt; } | { update-stmt; v = x; } | { v = x; x = expr; }
17195
17196 where x and v are lvalue expressions with scalar type.
17197
17198 LOC is the location of the #pragma token. */
17199
17200static void
17201c_parser_omp_atomic (location_t loc, c_parser *parser)
17202{
17203 tree lhs = NULL_TREE, rhs = NULL_TREE, v = NULL_TREE;
17204 tree lhs1 = NULL_TREE, rhs1 = NULL_TREE;
17205 tree stmt, orig_lhs, unfolded_lhs = NULL_TREE, unfolded_lhs1 = NULL_TREE;
28567c40
JJ
17206 enum tree_code code = ERROR_MARK, opcode = NOP_EXPR;
17207 enum omp_memory_order memory_order = OMP_MEMORY_ORDER_UNSPECIFIED;
acf0174b
JJ
17208 struct c_expr expr;
17209 location_t eloc;
17210 bool structured_block = false;
17211 bool swapped = false;
f4b189d5 17212 bool non_lvalue_p;
28567c40
JJ
17213 bool first = true;
17214 tree clauses = NULL_TREE;
acf0174b 17215
28567c40 17216 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
acf0174b 17217 {
28567c40 17218 if (!first && c_parser_next_token_is (parser, CPP_COMMA))
42056eac
JJ
17219 c_parser_consume_token (parser);
17220
28567c40
JJ
17221 first = false;
17222
42056eac 17223 if (c_parser_next_token_is (parser, CPP_NAME))
acf0174b 17224 {
42056eac
JJ
17225 const char *p
17226 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
28567c40
JJ
17227 location_t cloc = c_parser_peek_token (parser)->location;
17228 enum tree_code new_code = ERROR_MARK;
17229 enum omp_memory_order new_memory_order
17230 = OMP_MEMORY_ORDER_UNSPECIFIED;
17231
17232 if (!strcmp (p, "read"))
17233 new_code = OMP_ATOMIC_READ;
17234 else if (!strcmp (p, "write"))
17235 new_code = NOP_EXPR;
17236 else if (!strcmp (p, "update"))
17237 new_code = OMP_ATOMIC;
17238 else if (!strcmp (p, "capture"))
17239 new_code = OMP_ATOMIC_CAPTURE_NEW;
17240 else if (!strcmp (p, "seq_cst"))
17241 new_memory_order = OMP_MEMORY_ORDER_SEQ_CST;
17242 else if (!strcmp (p, "acq_rel"))
17243 new_memory_order = OMP_MEMORY_ORDER_ACQ_REL;
17244 else if (!strcmp (p, "release"))
17245 new_memory_order = OMP_MEMORY_ORDER_RELEASE;
17246 else if (!strcmp (p, "acquire"))
17247 new_memory_order = OMP_MEMORY_ORDER_ACQUIRE;
17248 else if (!strcmp (p, "relaxed"))
17249 new_memory_order = OMP_MEMORY_ORDER_RELAXED;
17250 else if (!strcmp (p, "hint"))
42056eac 17251 {
42056eac 17252 c_parser_consume_token (parser);
28567c40
JJ
17253 clauses = c_parser_omp_clause_hint (parser, clauses);
17254 continue;
17255 }
17256 else
17257 {
17258 p = NULL;
17259 error_at (cloc, "expected %<read%>, %<write%>, %<update%>, "
17260 "%<capture%>, %<seq_cst%>, %<acq_rel%>, "
17261 "%<release%>, %<relaxed%> or %<hint%> clause");
17262 }
17263 if (p)
17264 {
17265 if (new_code != ERROR_MARK)
17266 {
17267 if (code != ERROR_MARK)
17268 error_at (cloc, "too many atomic clauses");
17269 else
17270 code = new_code;
17271 }
17272 else if (new_memory_order != OMP_MEMORY_ORDER_UNSPECIFIED)
17273 {
17274 if (memory_order != OMP_MEMORY_ORDER_UNSPECIFIED)
17275 error_at (cloc, "too many memory order clauses");
17276 else
17277 memory_order = new_memory_order;
17278 }
17279 c_parser_consume_token (parser);
17280 continue;
17281 }
17282 }
17283 break;
17284 }
17285 c_parser_skip_to_pragma_eol (parser);
17286
17287 if (code == ERROR_MARK)
17288 code = OMP_ATOMIC;
17289 if (memory_order == OMP_MEMORY_ORDER_UNSPECIFIED)
17290 {
17291 omp_requires_mask
17292 = (enum omp_requires) (omp_requires_mask
17293 | OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED);
17294 switch ((enum omp_memory_order)
17295 (omp_requires_mask & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER))
17296 {
17297 case OMP_MEMORY_ORDER_UNSPECIFIED:
17298 case OMP_MEMORY_ORDER_RELAXED:
17299 memory_order = OMP_MEMORY_ORDER_RELAXED;
17300 break;
17301 case OMP_MEMORY_ORDER_SEQ_CST:
17302 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
17303 break;
17304 case OMP_MEMORY_ORDER_ACQ_REL:
17305 switch (code)
17306 {
17307 case OMP_ATOMIC_READ:
17308 memory_order = OMP_MEMORY_ORDER_ACQUIRE;
17309 break;
17310 case NOP_EXPR: /* atomic write */
17311 case OMP_ATOMIC:
17312 memory_order = OMP_MEMORY_ORDER_RELEASE;
17313 break;
17314 default:
17315 memory_order = OMP_MEMORY_ORDER_ACQ_REL;
17316 break;
42056eac 17317 }
28567c40
JJ
17318 break;
17319 default:
17320 gcc_unreachable ();
acf0174b
JJ
17321 }
17322 }
28567c40
JJ
17323 else
17324 switch (code)
17325 {
17326 case OMP_ATOMIC_READ:
17327 if (memory_order == OMP_MEMORY_ORDER_ACQ_REL
17328 || memory_order == OMP_MEMORY_ORDER_RELEASE)
17329 {
17330 error_at (loc, "%<#pragma omp atomic read%> incompatible with "
17331 "%<acq_rel%> or %<release%> clauses");
17332 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
17333 }
17334 break;
17335 case NOP_EXPR: /* atomic write */
17336 if (memory_order == OMP_MEMORY_ORDER_ACQ_REL
17337 || memory_order == OMP_MEMORY_ORDER_ACQUIRE)
17338 {
17339 error_at (loc, "%<#pragma omp atomic write%> incompatible with "
17340 "%<acq_rel%> or %<acquire%> clauses");
17341 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
17342 }
17343 break;
17344 case OMP_ATOMIC:
17345 if (memory_order == OMP_MEMORY_ORDER_ACQ_REL
17346 || memory_order == OMP_MEMORY_ORDER_ACQUIRE)
17347 {
17348 error_at (loc, "%<#pragma omp atomic update%> incompatible with "
17349 "%<acq_rel%> or %<acquire%> clauses");
17350 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
17351 }
17352 break;
17353 default:
17354 break;
17355 }
acf0174b
JJ
17356
17357 switch (code)
17358 {
17359 case OMP_ATOMIC_READ:
17360 case NOP_EXPR: /* atomic write */
f4b189d5
JJ
17361 v = c_parser_cast_expression (parser, NULL).value;
17362 non_lvalue_p = !lvalue_p (v);
f9c59f7e 17363 v = c_fully_fold (v, false, NULL, true);
acf0174b
JJ
17364 if (v == error_mark_node)
17365 goto saw_error;
f4b189d5
JJ
17366 if (non_lvalue_p)
17367 v = non_lvalue (v);
acf0174b
JJ
17368 loc = c_parser_peek_token (parser)->location;
17369 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
17370 goto saw_error;
17371 if (code == NOP_EXPR)
f4b189d5
JJ
17372 {
17373 lhs = c_parser_expression (parser).value;
17374 lhs = c_fully_fold (lhs, false, NULL);
17375 if (lhs == error_mark_node)
17376 goto saw_error;
17377 }
acf0174b 17378 else
f4b189d5
JJ
17379 {
17380 lhs = c_parser_cast_expression (parser, NULL).value;
17381 non_lvalue_p = !lvalue_p (lhs);
f9c59f7e 17382 lhs = c_fully_fold (lhs, false, NULL, true);
f4b189d5
JJ
17383 if (lhs == error_mark_node)
17384 goto saw_error;
17385 if (non_lvalue_p)
17386 lhs = non_lvalue (lhs);
17387 }
acf0174b
JJ
17388 if (code == NOP_EXPR)
17389 {
17390 /* atomic write is represented by OMP_ATOMIC with NOP_EXPR
17391 opcode. */
17392 code = OMP_ATOMIC;
17393 rhs = lhs;
17394 lhs = v;
17395 v = NULL_TREE;
17396 }
17397 goto done;
17398 case OMP_ATOMIC_CAPTURE_NEW:
17399 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
17400 {
17401 c_parser_consume_token (parser);
17402 structured_block = true;
17403 }
17404 else
17405 {
f4b189d5
JJ
17406 v = c_parser_cast_expression (parser, NULL).value;
17407 non_lvalue_p = !lvalue_p (v);
f9c59f7e 17408 v = c_fully_fold (v, false, NULL, true);
acf0174b
JJ
17409 if (v == error_mark_node)
17410 goto saw_error;
f4b189d5
JJ
17411 if (non_lvalue_p)
17412 v = non_lvalue (v);
acf0174b
JJ
17413 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
17414 goto saw_error;
17415 }
17416 break;
17417 default:
17418 break;
17419 }
17420
17421 /* For structured_block case we don't know yet whether
17422 old or new x should be captured. */
17423restart:
17424 eloc = c_parser_peek_token (parser)->location;
f4b189d5 17425 expr = c_parser_cast_expression (parser, NULL);
acf0174b
JJ
17426 lhs = expr.value;
17427 expr = default_function_array_conversion (eloc, expr);
17428 unfolded_lhs = expr.value;
f9c59f7e 17429 lhs = c_fully_fold (lhs, false, NULL, true);
acf0174b
JJ
17430 orig_lhs = lhs;
17431 switch (TREE_CODE (lhs))
17432 {
17433 case ERROR_MARK:
17434 saw_error:
17435 c_parser_skip_to_end_of_block_or_statement (parser);
17436 if (structured_block)
17437 {
17438 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
17439 c_parser_consume_token (parser);
17440 else if (code == OMP_ATOMIC_CAPTURE_NEW)
17441 {
17442 c_parser_skip_to_end_of_block_or_statement (parser);
17443 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
17444 c_parser_consume_token (parser);
17445 }
17446 }
17447 return;
17448
17449 case POSTINCREMENT_EXPR:
17450 if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
17451 code = OMP_ATOMIC_CAPTURE_OLD;
17452 /* FALLTHROUGH */
17453 case PREINCREMENT_EXPR:
17454 lhs = TREE_OPERAND (lhs, 0);
17455 unfolded_lhs = NULL_TREE;
17456 opcode = PLUS_EXPR;
17457 rhs = integer_one_node;
17458 break;
17459
17460 case POSTDECREMENT_EXPR:
17461 if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
17462 code = OMP_ATOMIC_CAPTURE_OLD;
17463 /* FALLTHROUGH */
17464 case PREDECREMENT_EXPR:
17465 lhs = TREE_OPERAND (lhs, 0);
17466 unfolded_lhs = NULL_TREE;
17467 opcode = MINUS_EXPR;
17468 rhs = integer_one_node;
17469 break;
17470
17471 case COMPOUND_EXPR:
17472 if (TREE_CODE (TREE_OPERAND (lhs, 0)) == SAVE_EXPR
17473 && TREE_CODE (TREE_OPERAND (lhs, 1)) == COMPOUND_EXPR
17474 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (lhs, 1), 0)) == MODIFY_EXPR
17475 && TREE_OPERAND (TREE_OPERAND (lhs, 1), 1) == TREE_OPERAND (lhs, 0)
17476 && TREE_CODE (TREE_TYPE (TREE_OPERAND (TREE_OPERAND
17477 (TREE_OPERAND (lhs, 1), 0), 0)))
17478 == BOOLEAN_TYPE)
17479 /* Undo effects of boolean_increment for post {in,de}crement. */
17480 lhs = TREE_OPERAND (TREE_OPERAND (lhs, 1), 0);
17481 /* FALLTHRU */
17482 case MODIFY_EXPR:
17483 if (TREE_CODE (lhs) == MODIFY_EXPR
17484 && TREE_CODE (TREE_TYPE (TREE_OPERAND (lhs, 0))) == BOOLEAN_TYPE)
17485 {
17486 /* Undo effects of boolean_increment. */
17487 if (integer_onep (TREE_OPERAND (lhs, 1)))
17488 {
17489 /* This is pre or post increment. */
17490 rhs = TREE_OPERAND (lhs, 1);
17491 lhs = TREE_OPERAND (lhs, 0);
17492 unfolded_lhs = NULL_TREE;
17493 opcode = NOP_EXPR;
17494 if (code == OMP_ATOMIC_CAPTURE_NEW
17495 && !structured_block
17496 && TREE_CODE (orig_lhs) == COMPOUND_EXPR)
17497 code = OMP_ATOMIC_CAPTURE_OLD;
17498 break;
17499 }
17500 if (TREE_CODE (TREE_OPERAND (lhs, 1)) == TRUTH_NOT_EXPR
17501 && TREE_OPERAND (lhs, 0)
17502 == TREE_OPERAND (TREE_OPERAND (lhs, 1), 0))
17503 {
17504 /* This is pre or post decrement. */
17505 rhs = TREE_OPERAND (lhs, 1);
17506 lhs = TREE_OPERAND (lhs, 0);
17507 unfolded_lhs = NULL_TREE;
17508 opcode = NOP_EXPR;
17509 if (code == OMP_ATOMIC_CAPTURE_NEW
17510 && !structured_block
17511 && TREE_CODE (orig_lhs) == COMPOUND_EXPR)
17512 code = OMP_ATOMIC_CAPTURE_OLD;
17513 break;
17514 }
17515 }
17516 /* FALLTHRU */
17517 default:
f4b189d5
JJ
17518 if (!lvalue_p (unfolded_lhs))
17519 lhs = non_lvalue (lhs);
acf0174b
JJ
17520 switch (c_parser_peek_token (parser)->type)
17521 {
17522 case CPP_MULT_EQ:
17523 opcode = MULT_EXPR;
17524 break;
17525 case CPP_DIV_EQ:
17526 opcode = TRUNC_DIV_EXPR;
17527 break;
17528 case CPP_PLUS_EQ:
17529 opcode = PLUS_EXPR;
17530 break;
17531 case CPP_MINUS_EQ:
17532 opcode = MINUS_EXPR;
17533 break;
17534 case CPP_LSHIFT_EQ:
17535 opcode = LSHIFT_EXPR;
17536 break;
17537 case CPP_RSHIFT_EQ:
17538 opcode = RSHIFT_EXPR;
17539 break;
17540 case CPP_AND_EQ:
17541 opcode = BIT_AND_EXPR;
17542 break;
17543 case CPP_OR_EQ:
17544 opcode = BIT_IOR_EXPR;
17545 break;
17546 case CPP_XOR_EQ:
17547 opcode = BIT_XOR_EXPR;
17548 break;
17549 case CPP_EQ:
17550 c_parser_consume_token (parser);
17551 eloc = c_parser_peek_token (parser)->location;
17552 expr = c_parser_expr_no_commas (parser, NULL, unfolded_lhs);
17553 rhs1 = expr.value;
17554 switch (TREE_CODE (rhs1))
17555 {
17556 case MULT_EXPR:
17557 case TRUNC_DIV_EXPR:
4886ec8e 17558 case RDIV_EXPR:
acf0174b
JJ
17559 case PLUS_EXPR:
17560 case MINUS_EXPR:
17561 case LSHIFT_EXPR:
17562 case RSHIFT_EXPR:
17563 case BIT_AND_EXPR:
17564 case BIT_IOR_EXPR:
17565 case BIT_XOR_EXPR:
17566 if (c_tree_equal (TREE_OPERAND (rhs1, 0), unfolded_lhs))
17567 {
17568 opcode = TREE_CODE (rhs1);
f9c59f7e
JJ
17569 rhs = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
17570 true);
17571 rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 0), false, NULL,
17572 true);
acf0174b
JJ
17573 goto stmt_done;
17574 }
17575 if (c_tree_equal (TREE_OPERAND (rhs1, 1), unfolded_lhs))
17576 {
17577 opcode = TREE_CODE (rhs1);
f9c59f7e
JJ
17578 rhs = c_fully_fold (TREE_OPERAND (rhs1, 0), false, NULL,
17579 true);
17580 rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
17581 true);
acf0174b
JJ
17582 swapped = !commutative_tree_code (opcode);
17583 goto stmt_done;
17584 }
17585 break;
17586 case ERROR_MARK:
17587 goto saw_error;
17588 default:
17589 break;
17590 }
17591 if (c_parser_peek_token (parser)->type == CPP_SEMICOLON)
17592 {
17593 if (structured_block && code == OMP_ATOMIC_CAPTURE_NEW)
17594 {
17595 code = OMP_ATOMIC_CAPTURE_OLD;
17596 v = lhs;
17597 lhs = NULL_TREE;
17598 expr = default_function_array_read_conversion (eloc, expr);
17599 unfolded_lhs1 = expr.value;
f9c59f7e 17600 lhs1 = c_fully_fold (unfolded_lhs1, false, NULL, true);
acf0174b
JJ
17601 rhs1 = NULL_TREE;
17602 c_parser_consume_token (parser);
17603 goto restart;
17604 }
17605 if (structured_block)
17606 {
17607 opcode = NOP_EXPR;
17608 expr = default_function_array_read_conversion (eloc, expr);
f9c59f7e 17609 rhs = c_fully_fold (expr.value, false, NULL, true);
acf0174b
JJ
17610 rhs1 = NULL_TREE;
17611 goto stmt_done;
17612 }
17613 }
17614 c_parser_error (parser, "invalid form of %<#pragma omp atomic%>");
17615 goto saw_error;
17616 default:
17617 c_parser_error (parser,
17618 "invalid operator for %<#pragma omp atomic%>");
17619 goto saw_error;
17620 }
17621
17622 /* Arrange to pass the location of the assignment operator to
17623 c_finish_omp_atomic. */
17624 loc = c_parser_peek_token (parser)->location;
17625 c_parser_consume_token (parser);
17626 eloc = c_parser_peek_token (parser)->location;
17627 expr = c_parser_expression (parser);
17628 expr = default_function_array_read_conversion (eloc, expr);
17629 rhs = expr.value;
f9c59f7e 17630 rhs = c_fully_fold (rhs, false, NULL, true);
acf0174b
JJ
17631 break;
17632 }
17633stmt_done:
17634 if (structured_block && code == OMP_ATOMIC_CAPTURE_NEW)
17635 {
17636 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
17637 goto saw_error;
f4b189d5
JJ
17638 v = c_parser_cast_expression (parser, NULL).value;
17639 non_lvalue_p = !lvalue_p (v);
f9c59f7e 17640 v = c_fully_fold (v, false, NULL, true);
acf0174b
JJ
17641 if (v == error_mark_node)
17642 goto saw_error;
f4b189d5
JJ
17643 if (non_lvalue_p)
17644 v = non_lvalue (v);
acf0174b
JJ
17645 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
17646 goto saw_error;
17647 eloc = c_parser_peek_token (parser)->location;
f4b189d5 17648 expr = c_parser_cast_expression (parser, NULL);
acf0174b
JJ
17649 lhs1 = expr.value;
17650 expr = default_function_array_read_conversion (eloc, expr);
17651 unfolded_lhs1 = expr.value;
f9c59f7e 17652 lhs1 = c_fully_fold (lhs1, false, NULL, true);
acf0174b
JJ
17653 if (lhs1 == error_mark_node)
17654 goto saw_error;
f4b189d5
JJ
17655 if (!lvalue_p (unfolded_lhs1))
17656 lhs1 = non_lvalue (lhs1);
acf0174b
JJ
17657 }
17658 if (structured_block)
17659 {
17660 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
17661 c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>");
17662 }
17663done:
17664 if (unfolded_lhs && unfolded_lhs1
17665 && !c_tree_equal (unfolded_lhs, unfolded_lhs1))
17666 {
17667 error ("%<#pragma omp atomic capture%> uses two different "
17668 "expressions for memory");
17669 stmt = error_mark_node;
17670 }
17671 else
17672 stmt = c_finish_omp_atomic (loc, code, opcode, lhs, rhs, v, lhs1, rhs1,
28567c40 17673 swapped, memory_order);
acf0174b
JJ
17674 if (stmt != error_mark_node)
17675 add_stmt (stmt);
17676
17677 if (!structured_block)
17678 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
17679}
17680
17681
17682/* OpenMP 2.5:
17683 # pragma omp barrier new-line
17684*/
17685
17686static void
17687c_parser_omp_barrier (c_parser *parser)
17688{
17689 location_t loc = c_parser_peek_token (parser)->location;
17690 c_parser_consume_pragma (parser);
17691 c_parser_skip_to_pragma_eol (parser);
17692
17693 c_finish_omp_barrier (loc);
17694}
17695
17696/* OpenMP 2.5:
17697 # pragma omp critical [(name)] new-line
17698 structured-block
17699
d9a6bd32
JJ
17700 OpenMP 4.5:
17701 # pragma omp critical [(name) [hint(expression)]] new-line
17702
acf0174b
JJ
17703 LOC is the location of the #pragma itself. */
17704
d9a6bd32
JJ
17705#define OMP_CRITICAL_CLAUSE_MASK \
17706 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HINT) )
17707
acf0174b 17708static tree
dda1bf61 17709c_parser_omp_critical (location_t loc, c_parser *parser, bool *if_p)
acf0174b 17710{
d9a6bd32 17711 tree stmt, name = NULL_TREE, clauses = NULL_TREE;
acf0174b
JJ
17712
17713 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
17714 {
17715 c_parser_consume_token (parser);
17716 if (c_parser_next_token_is (parser, CPP_NAME))
17717 {
17718 name = c_parser_peek_token (parser)->value;
17719 c_parser_consume_token (parser);
17720 c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>");
17721 }
17722 else
17723 c_parser_error (parser, "expected identifier");
d9a6bd32 17724
28567c40
JJ
17725 if (c_parser_next_token_is (parser, CPP_COMMA)
17726 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
17727 c_parser_consume_token (parser);
17728
d9a6bd32
JJ
17729 clauses = c_parser_omp_all_clauses (parser,
17730 OMP_CRITICAL_CLAUSE_MASK,
17731 "#pragma omp critical");
17732 }
17733 else
17734 {
17735 if (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
17736 c_parser_error (parser, "expected %<(%> or end of line");
17737 c_parser_skip_to_pragma_eol (parser);
acf0174b 17738 }
acf0174b 17739
dda1bf61 17740 stmt = c_parser_omp_structured_block (parser, if_p);
d9a6bd32 17741 return c_finish_omp_critical (loc, stmt, name, clauses);
acf0174b
JJ
17742}
17743
28567c40
JJ
17744/* OpenMP 5.0:
17745 # pragma omp depobj ( depobj ) depobj-clause new-line
17746
17747 depobj-clause:
17748 depend (dependence-type : locator)
17749 destroy
17750 update (dependence-type)
17751
17752 dependence-type:
17753 in
17754 out
17755 inout
17756 mutexinout */
17757
17758static void
17759c_parser_omp_depobj (c_parser *parser)
17760{
17761 location_t loc = c_parser_peek_token (parser)->location;
17762 c_parser_consume_pragma (parser);
17763 matching_parens parens;
17764 if (!parens.require_open (parser))
17765 {
17766 c_parser_skip_to_pragma_eol (parser);
17767 return;
17768 }
17769
17770 tree depobj = c_parser_expr_no_commas (parser, NULL).value;
17771 if (depobj != error_mark_node)
17772 {
17773 if (!lvalue_p (depobj))
17774 {
17775 error_at (EXPR_LOC_OR_LOC (depobj, loc),
17776 "%<depobj%> expression is not lvalue expression");
17777 depobj = error_mark_node;
17778 }
17779 else
17780 {
17781 tree addr = build_unary_op (EXPR_LOC_OR_LOC (depobj, loc), ADDR_EXPR,
17782 depobj, false);
17783 if (addr == error_mark_node)
17784 depobj = error_mark_node;
17785 else
17786 depobj = build_indirect_ref (EXPR_LOC_OR_LOC (depobj, loc),
17787 addr, RO_UNARY_STAR);
17788 }
17789 }
17790
17791 parens.skip_until_found_close (parser);
17792 tree clause = NULL_TREE;
17793 enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_SOURCE;
17794 location_t c_loc = c_parser_peek_token (parser)->location;
17795 if (c_parser_next_token_is (parser, CPP_NAME))
17796 {
17797 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17798
17799 c_parser_consume_token (parser);
17800 if (!strcmp ("depend", p))
17801 {
17802 clause = c_parser_omp_clause_depend (parser, NULL_TREE);
17803 clause = c_finish_omp_clauses (clause, C_ORT_OMP);
17804 if (!clause)
17805 clause = error_mark_node;
17806 }
17807 else if (!strcmp ("destroy", p))
17808 kind = OMP_CLAUSE_DEPEND_LAST;
17809 else if (!strcmp ("update", p))
17810 {
17811 matching_parens c_parens;
17812 if (c_parens.require_open (parser))
17813 {
17814 location_t c2_loc = c_parser_peek_token (parser)->location;
17815 if (c_parser_next_token_is (parser, CPP_NAME))
17816 {
17817 const char *p2
17818 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17819
17820 c_parser_consume_token (parser);
17821 if (!strcmp ("in", p2))
17822 kind = OMP_CLAUSE_DEPEND_IN;
17823 else if (!strcmp ("out", p2))
17824 kind = OMP_CLAUSE_DEPEND_OUT;
17825 else if (!strcmp ("inout", p2))
17826 kind = OMP_CLAUSE_DEPEND_INOUT;
17827 else if (!strcmp ("mutexinoutset", p2))
17828 kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET;
17829 }
17830 if (kind == OMP_CLAUSE_DEPEND_SOURCE)
17831 {
17832 clause = error_mark_node;
17833 error_at (c2_loc, "expected %<in%>, %<out%>, %<inout%> or "
17834 "%<mutexinoutset%>");
17835 }
17836 c_parens.skip_until_found_close (parser);
17837 }
17838 else
17839 clause = error_mark_node;
17840 }
17841 }
17842 if (!clause && kind == OMP_CLAUSE_DEPEND_SOURCE)
17843 {
17844 clause = error_mark_node;
17845 error_at (c_loc, "expected %<depend%>, %<destroy%> or %<update%> clause");
17846 }
17847 c_parser_skip_to_pragma_eol (parser);
17848
17849 c_finish_omp_depobj (loc, depobj, kind, clause);
17850}
17851
17852
acf0174b
JJ
17853/* OpenMP 2.5:
17854 # pragma omp flush flush-vars[opt] new-line
17855
17856 flush-vars:
28567c40
JJ
17857 ( variable-list )
17858
17859 OpenMP 5.0:
17860 # pragma omp flush memory-order-clause new-line */
acf0174b
JJ
17861
17862static void
17863c_parser_omp_flush (c_parser *parser)
17864{
17865 location_t loc = c_parser_peek_token (parser)->location;
17866 c_parser_consume_pragma (parser);
28567c40
JJ
17867 enum memmodel mo = MEMMODEL_LAST;
17868 if (c_parser_next_token_is (parser, CPP_NAME))
17869 {
17870 const char *p
17871 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17872
17873 if (!strcmp (p, "acq_rel"))
17874 mo = MEMMODEL_ACQ_REL;
17875 else if (!strcmp (p, "release"))
17876 mo = MEMMODEL_RELEASE;
17877 else if (!strcmp (p, "acquire"))
17878 mo = MEMMODEL_ACQUIRE;
17879 else
17880 error_at (c_parser_peek_token (parser)->location,
17881 "expected %<acq_rel%>, %<release%> or %<acquire%>");
17882 c_parser_consume_token (parser);
17883 }
acf0174b 17884 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
28567c40
JJ
17885 {
17886 if (mo != MEMMODEL_LAST)
17887 error_at (c_parser_peek_token (parser)->location,
17888 "%<flush%> list specified together with memory order "
17889 "clause");
17890 c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
17891 }
acf0174b
JJ
17892 else if (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
17893 c_parser_error (parser, "expected %<(%> or end of line");
17894 c_parser_skip_to_pragma_eol (parser);
17895
28567c40 17896 c_finish_omp_flush (loc, mo);
acf0174b
JJ
17897}
17898
bf38f7e9
JJ
17899/* OpenMP 5.0:
17900
17901 scan-loop-body:
17902 { structured-block scan-directive structured-block } */
17903
17904static void
17905c_parser_omp_scan_loop_body (c_parser *parser, bool open_brace_parsed)
17906{
17907 tree substmt;
17908 location_t loc;
17909 tree clauses = NULL_TREE;
17910
17911 loc = c_parser_peek_token (parser)->location;
17912 if (!open_brace_parsed
17913 && !c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
17914 {
17915 /* Avoid skipping until the end of the block. */
17916 parser->error = false;
17917 return;
17918 }
17919
17920 substmt = c_parser_omp_structured_block (parser, NULL);
17921 substmt = build2 (OMP_SCAN, void_type_node, substmt, NULL_TREE);
17922 SET_EXPR_LOCATION (substmt, loc);
17923 add_stmt (substmt);
17924
17925 loc = c_parser_peek_token (parser)->location;
17926 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SCAN)
17927 {
17928 enum omp_clause_code clause = OMP_CLAUSE_ERROR;
17929
17930 c_parser_consume_pragma (parser);
17931
17932 if (c_parser_next_token_is (parser, CPP_NAME))
17933 {
17934 const char *p
17935 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17936 if (strcmp (p, "inclusive") == 0)
17937 clause = OMP_CLAUSE_INCLUSIVE;
17938 else if (strcmp (p, "exclusive") == 0)
17939 clause = OMP_CLAUSE_EXCLUSIVE;
17940 }
17941 if (clause != OMP_CLAUSE_ERROR)
17942 {
17943 c_parser_consume_token (parser);
17944 clauses = c_parser_omp_var_list_parens (parser, clause, NULL_TREE);
17945 }
17946 else
17947 c_parser_error (parser, "expected %<inclusive%> or "
17948 "%<exclusive%> clause");
17949 c_parser_skip_to_pragma_eol (parser);
17950 }
17951 else
17952 error ("expected %<#pragma omp scan%>");
17953
17954 clauses = c_finish_omp_clauses (clauses, C_ORT_OMP);
17955 substmt = c_parser_omp_structured_block (parser, NULL);
17956 substmt = build2 (OMP_SCAN, void_type_node, substmt, clauses);
17957 SET_EXPR_LOCATION (substmt, loc);
17958 add_stmt (substmt);
17959
17960 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE,
17961 "expected %<}%>");
17962}
17963
41dbbb37 17964/* Parse the restricted form of loop statements allowed by OpenACC and OpenMP.
acf0174b
JJ
17965 The real trick here is to determine the loop control variable early
17966 so that we can push a new decl if necessary to make it private.
41dbbb37
TS
17967 LOC is the location of the "acc" or "omp" in "#pragma acc" or "#pragma omp",
17968 respectively. */
acf0174b
JJ
17969
17970static tree
17971c_parser_omp_for_loop (location_t loc, c_parser *parser, enum tree_code code,
dda1bf61 17972 tree clauses, tree *cclauses, bool *if_p)
acf0174b
JJ
17973{
17974 tree decl, cond, incr, save_break, save_cont, body, init, stmt, cl;
a8a098ac
JJ
17975 tree declv, condv, incrv, initv, ret = NULL_TREE;
17976 tree pre_body = NULL_TREE, this_pre_body;
d9a6bd32 17977 tree ordered_cl = NULL_TREE;
acf0174b 17978 bool fail = false, open_brace_parsed = false;
d9a6bd32 17979 int i, collapse = 1, ordered = 0, count, nbraces = 0;
acf0174b 17980 location_t for_loc;
02889d23 17981 bool tiling = false;
bf38f7e9 17982 bool inscan = false;
acf0174b
JJ
17983 vec<tree, va_gc> *for_block = make_tree_vector ();
17984
17985 for (cl = clauses; cl; cl = OMP_CLAUSE_CHAIN (cl))
17986 if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_COLLAPSE)
9439e9a1 17987 collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (cl));
02889d23
CLT
17988 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_TILE)
17989 {
17990 tiling = true;
17991 collapse = list_length (OMP_CLAUSE_TILE_LIST (cl));
17992 }
d9a6bd32
JJ
17993 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_ORDERED
17994 && OMP_CLAUSE_ORDERED_EXPR (cl))
17995 {
17996 ordered_cl = cl;
17997 ordered = tree_to_shwi (OMP_CLAUSE_ORDERED_EXPR (cl));
17998 }
bf38f7e9
JJ
17999 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_REDUCTION
18000 && OMP_CLAUSE_REDUCTION_INSCAN (cl)
18001 && (code == OMP_SIMD || code == OMP_FOR))
18002 inscan = true;
d9a6bd32
JJ
18003
18004 if (ordered && ordered < collapse)
18005 {
18006 error_at (OMP_CLAUSE_LOCATION (ordered_cl),
18007 "%<ordered%> clause parameter is less than %<collapse%>");
18008 OMP_CLAUSE_ORDERED_EXPR (ordered_cl)
18009 = build_int_cst (NULL_TREE, collapse);
18010 ordered = collapse;
18011 }
18012 if (ordered)
18013 {
18014 for (tree *pc = &clauses; *pc; )
18015 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_LINEAR)
18016 {
18017 error_at (OMP_CLAUSE_LOCATION (*pc),
18018 "%<linear%> clause may not be specified together "
18019 "with %<ordered%> clause with a parameter");
18020 *pc = OMP_CLAUSE_CHAIN (*pc);
18021 }
18022 else
18023 pc = &OMP_CLAUSE_CHAIN (*pc);
18024 }
acf0174b 18025
02889d23 18026 gcc_assert (tiling || (collapse >= 1 && ordered >= 0));
d9a6bd32 18027 count = ordered ? ordered : collapse;
acf0174b 18028
d9a6bd32
JJ
18029 declv = make_tree_vec (count);
18030 initv = make_tree_vec (count);
18031 condv = make_tree_vec (count);
18032 incrv = make_tree_vec (count);
acf0174b 18033
5e9d6aa4 18034 if (!c_parser_next_token_is_keyword (parser, RID_FOR))
acf0174b
JJ
18035 {
18036 c_parser_error (parser, "for statement expected");
18037 return NULL;
18038 }
18039 for_loc = c_parser_peek_token (parser)->location;
18040 c_parser_consume_token (parser);
18041
d9a6bd32 18042 for (i = 0; i < count; i++)
acf0174b
JJ
18043 {
18044 int bracecount = 0;
18045
32129a17
DM
18046 matching_parens parens;
18047 if (!parens.require_open (parser))
acf0174b
JJ
18048 goto pop_scopes;
18049
18050 /* Parse the initialization declaration or expression. */
18051 if (c_parser_next_tokens_start_declaration (parser))
18052 {
18053 if (i > 0)
18054 vec_safe_push (for_block, c_begin_compound_stmt (true));
a8a098ac 18055 this_pre_body = push_stmt_list ();
acf0174b
JJ
18056 c_parser_declaration_or_fndef (parser, true, true, true, true, true,
18057 NULL, vNULL);
a8a098ac
JJ
18058 if (this_pre_body)
18059 {
18060 this_pre_body = pop_stmt_list (this_pre_body);
18061 if (pre_body)
18062 {
18063 tree t = pre_body;
18064 pre_body = push_stmt_list ();
18065 add_stmt (t);
18066 add_stmt (this_pre_body);
18067 pre_body = pop_stmt_list (pre_body);
18068 }
18069 else
18070 pre_body = this_pre_body;
18071 }
acf0174b
JJ
18072 decl = check_for_loop_decls (for_loc, flag_isoc99);
18073 if (decl == NULL)
18074 goto error_init;
18075 if (DECL_INITIAL (decl) == error_mark_node)
18076 decl = error_mark_node;
18077 init = decl;
18078 }
18079 else if (c_parser_next_token_is (parser, CPP_NAME)
18080 && c_parser_peek_2nd_token (parser)->type == CPP_EQ)
18081 {
18082 struct c_expr decl_exp;
18083 struct c_expr init_exp;
18084 location_t init_loc;
18085
18086 decl_exp = c_parser_postfix_expression (parser);
18087 decl = decl_exp.value;
18088
18089 c_parser_require (parser, CPP_EQ, "expected %<=%>");
18090
18091 init_loc = c_parser_peek_token (parser)->location;
18092 init_exp = c_parser_expr_no_commas (parser, NULL);
18093 init_exp = default_function_array_read_conversion (init_loc,
18094 init_exp);
18095 init = build_modify_expr (init_loc, decl, decl_exp.original_type,
18096 NOP_EXPR, init_loc, init_exp.value,
18097 init_exp.original_type);
18098 init = c_process_expr_stmt (init_loc, init);
18099
18100 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
18101 }
18102 else
18103 {
18104 error_init:
18105 c_parser_error (parser,
18106 "expected iteration declaration or initialization");
18107 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
18108 "expected %<)%>");
18109 fail = true;
18110 goto parse_next;
18111 }
18112
18113 /* Parse the loop condition. */
18114 cond = NULL_TREE;
18115 if (c_parser_next_token_is_not (parser, CPP_SEMICOLON))
18116 {
18117 location_t cond_loc = c_parser_peek_token (parser)->location;
18118 struct c_expr cond_expr
18119 = c_parser_binary_expression (parser, NULL, NULL_TREE);
18120
18121 cond = cond_expr.value;
18122 cond = c_objc_common_truthvalue_conversion (cond_loc, cond);
ebc6a85e
TV
18123 if (COMPARISON_CLASS_P (cond))
18124 {
18125 tree op0 = TREE_OPERAND (cond, 0), op1 = TREE_OPERAND (cond, 1);
18126 op0 = c_fully_fold (op0, false, NULL);
18127 op1 = c_fully_fold (op1, false, NULL);
18128 TREE_OPERAND (cond, 0) = op0;
18129 TREE_OPERAND (cond, 1) = op1;
18130 }
acf0174b
JJ
18131 switch (cond_expr.original_code)
18132 {
18133 case GT_EXPR:
18134 case GE_EXPR:
18135 case LT_EXPR:
18136 case LE_EXPR:
18137 break;
28567c40
JJ
18138 case NE_EXPR:
18139 if (code != OACC_LOOP)
18140 break;
18141 /* FALLTHRU. */
acf0174b
JJ
18142 default:
18143 /* Can't be cond = error_mark_node, because we want to preserve
18144 the location until c_finish_omp_for. */
18145 cond = build1 (NOP_EXPR, boolean_type_node, error_mark_node);
18146 break;
18147 }
18148 protected_set_expr_location (cond, cond_loc);
18149 }
18150 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
18151
18152 /* Parse the increment expression. */
18153 incr = NULL_TREE;
18154 if (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN))
18155 {
18156 location_t incr_loc = c_parser_peek_token (parser)->location;
18157
18158 incr = c_process_expr_stmt (incr_loc,
18159 c_parser_expression (parser).value);
18160 }
32129a17 18161 parens.skip_until_found_close (parser);
acf0174b
JJ
18162
18163 if (decl == NULL || decl == error_mark_node || init == error_mark_node)
18164 fail = true;
18165 else
18166 {
18167 TREE_VEC_ELT (declv, i) = decl;
18168 TREE_VEC_ELT (initv, i) = init;
18169 TREE_VEC_ELT (condv, i) = cond;
18170 TREE_VEC_ELT (incrv, i) = incr;
18171 }
18172
18173 parse_next:
d9a6bd32 18174 if (i == count - 1)
acf0174b
JJ
18175 break;
18176
18177 /* FIXME: OpenMP 3.0 draft isn't very clear on what exactly is allowed
18178 in between the collapsed for loops to be still considered perfectly
18179 nested. Hopefully the final version clarifies this.
18180 For now handle (multiple) {'s and empty statements. */
18181 do
18182 {
18183 if (c_parser_next_token_is_keyword (parser, RID_FOR))
18184 {
18185 c_parser_consume_token (parser);
18186 break;
18187 }
18188 else if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
18189 {
18190 c_parser_consume_token (parser);
18191 bracecount++;
18192 }
18193 else if (bracecount
18194 && c_parser_next_token_is (parser, CPP_SEMICOLON))
18195 c_parser_consume_token (parser);
18196 else
18197 {
18198 c_parser_error (parser, "not enough perfectly nested loops");
18199 if (bracecount)
18200 {
18201 open_brace_parsed = true;
18202 bracecount--;
18203 }
18204 fail = true;
d9a6bd32 18205 count = 0;
acf0174b
JJ
18206 break;
18207 }
18208 }
18209 while (1);
18210
18211 nbraces += bracecount;
18212 }
18213
dda1bf61
JJ
18214 if (nbraces)
18215 if_p = NULL;
18216
acf0174b 18217 save_break = c_break_label;
5e9d6aa4 18218 c_break_label = size_one_node;
acf0174b
JJ
18219 save_cont = c_cont_label;
18220 c_cont_label = NULL_TREE;
18221 body = push_stmt_list ();
18222
bf38f7e9
JJ
18223 if (inscan)
18224 c_parser_omp_scan_loop_body (parser, open_brace_parsed);
18225 else if (open_brace_parsed)
acf0174b
JJ
18226 {
18227 location_t here = c_parser_peek_token (parser)->location;
18228 stmt = c_begin_compound_stmt (true);
18229 c_parser_compound_statement_nostart (parser);
18230 add_stmt (c_end_compound_stmt (here, stmt, true));
18231 }
18232 else
dda1bf61 18233 add_stmt (c_parser_c99_block_statement (parser, if_p));
acf0174b
JJ
18234 if (c_cont_label)
18235 {
18236 tree t = build1 (LABEL_EXPR, void_type_node, c_cont_label);
18237 SET_EXPR_LOCATION (t, loc);
18238 add_stmt (t);
18239 }
18240
18241 body = pop_stmt_list (body);
18242 c_break_label = save_break;
18243 c_cont_label = save_cont;
18244
18245 while (nbraces)
18246 {
18247 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
18248 {
18249 c_parser_consume_token (parser);
18250 nbraces--;
18251 }
18252 else if (c_parser_next_token_is (parser, CPP_SEMICOLON))
18253 c_parser_consume_token (parser);
18254 else
18255 {
18256 c_parser_error (parser, "collapsed loops not perfectly nested");
18257 while (nbraces)
18258 {
18259 location_t here = c_parser_peek_token (parser)->location;
18260 stmt = c_begin_compound_stmt (true);
18261 add_stmt (body);
18262 c_parser_compound_statement_nostart (parser);
18263 body = c_end_compound_stmt (here, stmt, true);
18264 nbraces--;
18265 }
18266 goto pop_scopes;
18267 }
18268 }
18269
18270 /* Only bother calling c_finish_omp_for if we haven't already generated
18271 an error from the initialization parsing. */
18272 if (!fail)
18273 {
d9a6bd32 18274 stmt = c_finish_omp_for (loc, code, declv, NULL, initv, condv,
28567c40 18275 incrv, body, pre_body, true);
e01d41e5
JJ
18276
18277 /* Check for iterators appearing in lb, b or incr expressions. */
18278 if (stmt && !c_omp_check_loop_iv (stmt, declv, NULL))
18279 stmt = NULL_TREE;
18280
acf0174b
JJ
18281 if (stmt)
18282 {
e01d41e5
JJ
18283 add_stmt (stmt);
18284
acf0174b
JJ
18285 if (cclauses != NULL
18286 && cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] != NULL)
18287 {
18288 tree *c;
18289 for (c = &cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL]; *c ; )
18290 if (OMP_CLAUSE_CODE (*c) != OMP_CLAUSE_FIRSTPRIVATE
18291 && OMP_CLAUSE_CODE (*c) != OMP_CLAUSE_LASTPRIVATE)
18292 c = &OMP_CLAUSE_CHAIN (*c);
18293 else
18294 {
d9a6bd32 18295 for (i = 0; i < count; i++)
acf0174b
JJ
18296 if (TREE_VEC_ELT (declv, i) == OMP_CLAUSE_DECL (*c))
18297 break;
d9a6bd32 18298 if (i == count)
acf0174b
JJ
18299 c = &OMP_CLAUSE_CHAIN (*c);
18300 else if (OMP_CLAUSE_CODE (*c) == OMP_CLAUSE_FIRSTPRIVATE)
18301 {
18302 error_at (loc,
18303 "iteration variable %qD should not be firstprivate",
18304 OMP_CLAUSE_DECL (*c));
18305 *c = OMP_CLAUSE_CHAIN (*c);
18306 }
18307 else
18308 {
41b37d5e
JJ
18309 /* Move lastprivate (decl) clause to OMP_FOR_CLAUSES. */
18310 tree l = *c;
18311 *c = OMP_CLAUSE_CHAIN (*c);
56ad0e38
JJ
18312 if (code == OMP_SIMD)
18313 {
18314 OMP_CLAUSE_CHAIN (l)
18315 = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
18316 cclauses[C_OMP_CLAUSE_SPLIT_FOR] = l;
18317 }
18318 else
18319 {
18320 OMP_CLAUSE_CHAIN (l) = clauses;
18321 clauses = l;
18322 }
acf0174b
JJ
18323 }
18324 }
18325 }
18326 OMP_FOR_CLAUSES (stmt) = clauses;
18327 }
18328 ret = stmt;
18329 }
18330pop_scopes:
18331 while (!for_block->is_empty ())
18332 {
18333 /* FIXME diagnostics: LOC below should be the actual location of
18334 this particular for block. We need to build a list of
18335 locations to go along with FOR_BLOCK. */
18336 stmt = c_end_compound_stmt (loc, for_block->pop (), true);
18337 add_stmt (stmt);
18338 }
18339 release_tree_vector (for_block);
18340 return ret;
18341}
18342
18343/* Helper function for OpenMP parsing, split clauses and call
18344 finish_omp_clauses on each of the set of clauses afterwards. */
18345
18346static void
18347omp_split_clauses (location_t loc, enum tree_code code,
18348 omp_clause_mask mask, tree clauses, tree *cclauses)
18349{
18350 int i;
18351 c_omp_split_clauses (loc, code, mask, clauses, cclauses);
18352 for (i = 0; i < C_OMP_CLAUSE_SPLIT_COUNT; i++)
18353 if (cclauses[i])
77886428 18354 cclauses[i] = c_finish_omp_clauses (cclauses[i], C_ORT_OMP);
acf0174b
JJ
18355}
18356
554a530f
JJ
18357/* OpenMP 5.0:
18358 #pragma omp loop loop-clause[optseq] new-line
18359 for-loop
18360
18361 LOC is the location of the #pragma token.
18362*/
18363
18364#define OMP_LOOP_CLAUSE_MASK \
18365 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
18366 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
18367 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
18368 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
18369 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_BIND) \
18370 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
18371
18372static tree
18373c_parser_omp_loop (location_t loc, c_parser *parser,
18374 char *p_name, omp_clause_mask mask, tree *cclauses,
18375 bool *if_p)
18376{
18377 tree block, clauses, ret;
18378
18379 strcat (p_name, " loop");
18380 mask |= OMP_LOOP_CLAUSE_MASK;
18381
18382 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
18383 if (cclauses)
18384 {
18385 omp_split_clauses (loc, OMP_LOOP, mask, clauses, cclauses);
18386 clauses = cclauses[C_OMP_CLAUSE_SPLIT_LOOP];
18387 }
18388
18389 block = c_begin_compound_stmt (true);
18390 ret = c_parser_omp_for_loop (loc, parser, OMP_LOOP, clauses, cclauses, if_p);
18391 block = c_end_compound_stmt (loc, block, true);
18392 add_stmt (block);
18393
18394 return ret;
18395}
18396
acf0174b
JJ
18397/* OpenMP 4.0:
18398 #pragma omp simd simd-clause[optseq] new-line
18399 for-loop
18400
18401 LOC is the location of the #pragma token.
18402*/
18403
18404#define OMP_SIMD_CLAUSE_MASK \
18405 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SAFELEN) \
d9a6bd32 18406 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
acf0174b
JJ
18407 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
18408 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
18409 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
18410 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
18411 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
28567c40
JJ
18412 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
18413 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
1fdd6f04
JJ
18414 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NONTEMPORAL) \
18415 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
acf0174b
JJ
18416
18417static tree
18418c_parser_omp_simd (location_t loc, c_parser *parser,
dda1bf61
JJ
18419 char *p_name, omp_clause_mask mask, tree *cclauses,
18420 bool *if_p)
acf0174b
JJ
18421{
18422 tree block, clauses, ret;
18423
18424 strcat (p_name, " simd");
18425 mask |= OMP_SIMD_CLAUSE_MASK;
acf0174b
JJ
18426
18427 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
18428 if (cclauses)
18429 {
18430 omp_split_clauses (loc, OMP_SIMD, mask, clauses, cclauses);
18431 clauses = cclauses[C_OMP_CLAUSE_SPLIT_SIMD];
629b3d75 18432 tree c = omp_find_clause (cclauses[C_OMP_CLAUSE_SPLIT_FOR],
d9a6bd32
JJ
18433 OMP_CLAUSE_ORDERED);
18434 if (c && OMP_CLAUSE_ORDERED_EXPR (c))
18435 {
18436 error_at (OMP_CLAUSE_LOCATION (c),
18437 "%<ordered%> clause with parameter may not be specified "
18438 "on %qs construct", p_name);
18439 OMP_CLAUSE_ORDERED_EXPR (c) = NULL_TREE;
18440 }
acf0174b
JJ
18441 }
18442
18443 block = c_begin_compound_stmt (true);
dda1bf61 18444 ret = c_parser_omp_for_loop (loc, parser, OMP_SIMD, clauses, cclauses, if_p);
acf0174b
JJ
18445 block = c_end_compound_stmt (loc, block, true);
18446 add_stmt (block);
18447
18448 return ret;
18449}
18450
18451/* OpenMP 2.5:
18452 #pragma omp for for-clause[optseq] new-line
18453 for-loop
18454
18455 OpenMP 4.0:
18456 #pragma omp for simd for-simd-clause[optseq] new-line
18457 for-loop
18458
18459 LOC is the location of the #pragma token.
18460*/
18461
18462#define OMP_FOR_CLAUSE_MASK \
18463 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
18464 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
18465 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
d9a6bd32 18466 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
acf0174b
JJ
18467 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
18468 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED) \
18469 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE) \
18470 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
1fdd6f04
JJ
18471 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
18472 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
acf0174b
JJ
18473
18474static tree
18475c_parser_omp_for (location_t loc, c_parser *parser,
dda1bf61
JJ
18476 char *p_name, omp_clause_mask mask, tree *cclauses,
18477 bool *if_p)
acf0174b
JJ
18478{
18479 tree block, clauses, ret;
18480
18481 strcat (p_name, " for");
18482 mask |= OMP_FOR_CLAUSE_MASK;
00631022
JJ
18483 /* parallel for{, simd} disallows nowait clause, but for
18484 target {teams distribute ,}parallel for{, simd} it should be accepted. */
18485 if (cclauses && (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) == 0)
acf0174b 18486 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT);
d9a6bd32
JJ
18487 /* Composite distribute parallel for{, simd} disallows ordered clause. */
18488 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
18489 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED);
acf0174b
JJ
18490
18491 if (c_parser_next_token_is (parser, CPP_NAME))
20906c66 18492 {
acf0174b
JJ
18493 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18494
18495 if (strcmp (p, "simd") == 0)
18496 {
18497 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
18498 if (cclauses == NULL)
18499 cclauses = cclauses_buf;
18500
18501 c_parser_consume_token (parser);
6d7f7e0a 18502 if (!flag_openmp) /* flag_openmp_simd */
dda1bf61
JJ
18503 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
18504 if_p);
acf0174b 18505 block = c_begin_compound_stmt (true);
dda1bf61 18506 ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses, if_p);
acf0174b
JJ
18507 block = c_end_compound_stmt (loc, block, true);
18508 if (ret == NULL_TREE)
18509 return ret;
18510 ret = make_node (OMP_FOR);
18511 TREE_TYPE (ret) = void_type_node;
18512 OMP_FOR_BODY (ret) = block;
18513 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
18514 SET_EXPR_LOCATION (ret, loc);
18515 add_stmt (ret);
18516 return ret;
18517 }
20906c66 18518 }
6d7f7e0a
TB
18519 if (!flag_openmp) /* flag_openmp_simd */
18520 {
62021f64 18521 c_parser_skip_to_pragma_eol (parser, false);
6d7f7e0a
TB
18522 return NULL_TREE;
18523 }
acf0174b 18524
d9a6bd32
JJ
18525 /* Composite distribute parallel for disallows linear clause. */
18526 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
18527 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR);
18528
acf0174b
JJ
18529 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
18530 if (cclauses)
20906c66 18531 {
acf0174b
JJ
18532 omp_split_clauses (loc, OMP_FOR, mask, clauses, cclauses);
18533 clauses = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
20906c66 18534 }
20906c66 18535
acf0174b 18536 block = c_begin_compound_stmt (true);
dda1bf61 18537 ret = c_parser_omp_for_loop (loc, parser, OMP_FOR, clauses, cclauses, if_p);
acf0174b
JJ
18538 block = c_end_compound_stmt (loc, block, true);
18539 add_stmt (block);
18540
18541 return ret;
953ff289
DN
18542}
18543
28567c40
JJ
18544static tree c_parser_omp_taskloop (location_t, c_parser *, char *,
18545 omp_clause_mask, tree *, bool *);
18546
acf0174b
JJ
18547/* OpenMP 2.5:
18548 # pragma omp master new-line
18549 structured-block
18550
18551 LOC is the location of the #pragma token.
18552*/
18553
18554static tree
28567c40
JJ
18555c_parser_omp_master (location_t loc, c_parser *parser,
18556 char *p_name, omp_clause_mask mask, tree *cclauses,
18557 bool *if_p)
acf0174b 18558{
28567c40
JJ
18559 tree block, clauses, ret;
18560
18561 strcat (p_name, " master");
18562
18563 if (c_parser_next_token_is (parser, CPP_NAME))
18564 {
18565 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18566
18567 if (strcmp (p, "taskloop") == 0)
18568 {
18569 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
18570 if (cclauses == NULL)
18571 cclauses = cclauses_buf;
18572
18573 c_parser_consume_token (parser);
18574 if (!flag_openmp) /* flag_openmp_simd */
18575 return c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
18576 if_p);
18577 block = c_begin_compound_stmt (true);
18578 ret = c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
18579 if_p);
18580 block = c_end_compound_stmt (loc, block, true);
18581 if (ret == NULL_TREE)
18582 return ret;
18583 ret = c_finish_omp_master (loc, block);
18584 return ret;
18585 }
18586 }
18587 if (!flag_openmp) /* flag_openmp_simd */
18588 {
18589 c_parser_skip_to_pragma_eol (parser, false);
18590 return NULL_TREE;
18591 }
18592
18593 if (cclauses)
18594 {
18595 clauses = c_parser_omp_all_clauses (parser, mask, p_name, false);
18596 omp_split_clauses (loc, OMP_MASTER, mask, clauses, cclauses);
18597 }
18598 else
18599 c_parser_skip_to_pragma_eol (parser);
18600
dda1bf61
JJ
18601 return c_finish_omp_master (loc, c_parser_omp_structured_block (parser,
18602 if_p));
acf0174b 18603}
953ff289
DN
18604
18605/* OpenMP 2.5:
acf0174b
JJ
18606 # pragma omp ordered new-line
18607 structured-block
18608
d9a6bd32
JJ
18609 OpenMP 4.5:
18610 # pragma omp ordered ordered-clauses new-line
18611 structured-block
18612
18613 # pragma omp ordered depend-clauses new-line */
18614
18615#define OMP_ORDERED_CLAUSE_MASK \
18616 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREADS) \
18617 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMD))
18618
18619#define OMP_ORDERED_DEPEND_CLAUSE_MASK \
18620 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)
18621
18622static bool
dda1bf61
JJ
18623c_parser_omp_ordered (c_parser *parser, enum pragma_context context,
18624 bool *if_p)
d9a6bd32
JJ
18625{
18626 location_t loc = c_parser_peek_token (parser)->location;
18627 c_parser_consume_pragma (parser);
18628
18629 if (context != pragma_stmt && context != pragma_compound)
18630 {
18631 c_parser_error (parser, "expected declaration specifiers");
192b048b 18632 c_parser_skip_to_pragma_eol (parser, false);
d9a6bd32
JJ
18633 return false;
18634 }
18635
18636 if (c_parser_next_token_is (parser, CPP_NAME))
18637 {
18638 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18639
18640 if (!strcmp ("depend", p))
18641 {
d2e05fcb
JJ
18642 if (!flag_openmp) /* flag_openmp_simd */
18643 {
18644 c_parser_skip_to_pragma_eol (parser, false);
18645 return false;
18646 }
d9a6bd32
JJ
18647 if (context == pragma_stmt)
18648 {
18649 error_at (loc,
883c8f06 18650 "%<#pragma omp ordered%> with %<depend%> clause may "
d9a6bd32 18651 "only be used in compound statements");
aec17bfe 18652 c_parser_skip_to_pragma_eol (parser, false);
d9a6bd32
JJ
18653 return false;
18654 }
18655
18656 tree clauses
18657 = c_parser_omp_all_clauses (parser,
18658 OMP_ORDERED_DEPEND_CLAUSE_MASK,
18659 "#pragma omp ordered");
18660 c_finish_omp_ordered (loc, clauses, NULL_TREE);
18661 return false;
18662 }
18663 }
953ff289 18664
d9a6bd32
JJ
18665 tree clauses = c_parser_omp_all_clauses (parser, OMP_ORDERED_CLAUSE_MASK,
18666 "#pragma omp ordered");
d2e05fcb
JJ
18667
18668 if (!flag_openmp /* flag_openmp_simd */
18669 && omp_find_clause (clauses, OMP_CLAUSE_SIMD) == NULL_TREE)
18670 return false;
18671
d9a6bd32 18672 c_finish_omp_ordered (loc, clauses,
dda1bf61 18673 c_parser_omp_structured_block (parser, if_p));
d9a6bd32 18674 return true;
acf0174b 18675}
953ff289 18676
acf0174b
JJ
18677/* OpenMP 2.5:
18678
18679 section-scope:
18680 { section-sequence }
18681
18682 section-sequence:
18683 section-directive[opt] structured-block
18684 section-sequence section-directive structured-block
18685
18686 SECTIONS_LOC is the location of the #pragma omp sections. */
18687
18688static tree
18689c_parser_omp_sections_scope (location_t sections_loc, c_parser *parser)
18690{
18691 tree stmt, substmt;
18692 bool error_suppress = false;
18693 location_t loc;
18694
18695 loc = c_parser_peek_token (parser)->location;
18696 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
18697 {
18698 /* Avoid skipping until the end of the block. */
18699 parser->error = false;
18700 return NULL_TREE;
18701 }
18702
18703 stmt = push_stmt_list ();
18704
18705 if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_SECTION)
18706 {
dda1bf61 18707 substmt = c_parser_omp_structured_block (parser, NULL);
acf0174b
JJ
18708 substmt = build1 (OMP_SECTION, void_type_node, substmt);
18709 SET_EXPR_LOCATION (substmt, loc);
18710 add_stmt (substmt);
18711 }
18712
18713 while (1)
18714 {
18715 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
18716 break;
18717 if (c_parser_next_token_is (parser, CPP_EOF))
18718 break;
18719
18720 loc = c_parser_peek_token (parser)->location;
18721 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SECTION)
18722 {
18723 c_parser_consume_pragma (parser);
18724 c_parser_skip_to_pragma_eol (parser);
18725 error_suppress = false;
18726 }
18727 else if (!error_suppress)
18728 {
18729 error_at (loc, "expected %<#pragma omp section%> or %<}%>");
18730 error_suppress = true;
18731 }
18732
dda1bf61 18733 substmt = c_parser_omp_structured_block (parser, NULL);
acf0174b
JJ
18734 substmt = build1 (OMP_SECTION, void_type_node, substmt);
18735 SET_EXPR_LOCATION (substmt, loc);
18736 add_stmt (substmt);
18737 }
18738 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE,
18739 "expected %<#pragma omp section%> or %<}%>");
18740
18741 substmt = pop_stmt_list (stmt);
18742
18743 stmt = make_node (OMP_SECTIONS);
18744 SET_EXPR_LOCATION (stmt, sections_loc);
18745 TREE_TYPE (stmt) = void_type_node;
18746 OMP_SECTIONS_BODY (stmt) = substmt;
18747
18748 return add_stmt (stmt);
953ff289
DN
18749}
18750
18751/* OpenMP 2.5:
acf0174b
JJ
18752 # pragma omp sections sections-clause[optseq] newline
18753 sections-scope
c2255bc4 18754
acf0174b
JJ
18755 LOC is the location of the #pragma token.
18756*/
18757
18758#define OMP_SECTIONS_CLAUSE_MASK \
18759 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
18760 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
18761 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
18762 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
18763 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
953ff289
DN
18764
18765static tree
acf0174b
JJ
18766c_parser_omp_sections (location_t loc, c_parser *parser,
18767 char *p_name, omp_clause_mask mask, tree *cclauses)
953ff289 18768{
acf0174b 18769 tree block, clauses, ret;
953ff289 18770
acf0174b
JJ
18771 strcat (p_name, " sections");
18772 mask |= OMP_SECTIONS_CLAUSE_MASK;
18773 if (cclauses)
18774 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT);
18775
18776 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
18777 if (cclauses)
18778 {
18779 omp_split_clauses (loc, OMP_SECTIONS, mask, clauses, cclauses);
18780 clauses = cclauses[C_OMP_CLAUSE_SPLIT_SECTIONS];
18781 }
18782
18783 block = c_begin_compound_stmt (true);
18784 ret = c_parser_omp_sections_scope (loc, parser);
18785 if (ret)
18786 OMP_SECTIONS_CLAUSES (ret) = clauses;
18787 block = c_end_compound_stmt (loc, block, true);
18788 add_stmt (block);
18789
18790 return ret;
18791}
18792
18793/* OpenMP 2.5:
cef0fd0e
TS
18794 # pragma omp parallel parallel-clause[optseq] new-line
18795 structured-block
18796 # pragma omp parallel for parallel-for-clause[optseq] new-line
18797 structured-block
18798 # pragma omp parallel sections parallel-sections-clause[optseq] new-line
18799 structured-block
18800
18801 OpenMP 4.0:
18802 # pragma omp parallel for simd parallel-for-simd-clause[optseq] new-line
18803 structured-block
acf0174b
JJ
18804
18805 LOC is the location of the #pragma token.
18806*/
18807
18808#define OMP_PARALLEL_CLAUSE_MASK \
18809 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
18810 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
18811 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
18812 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
18813 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
18814 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN) \
18815 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
18816 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS) \
18817 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PROC_BIND))
18818
18819static tree
18820c_parser_omp_parallel (location_t loc, c_parser *parser,
dda1bf61
JJ
18821 char *p_name, omp_clause_mask mask, tree *cclauses,
18822 bool *if_p)
acf0174b
JJ
18823{
18824 tree stmt, clauses, block;
18825
18826 strcat (p_name, " parallel");
18827 mask |= OMP_PARALLEL_CLAUSE_MASK;
d9a6bd32
JJ
18828 /* #pragma omp target parallel{, for, for simd} disallow copyin clause. */
18829 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) != 0
18830 && (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) == 0)
18831 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN);
acf0174b
JJ
18832
18833 if (c_parser_next_token_is_keyword (parser, RID_FOR))
953ff289 18834 {
acf0174b
JJ
18835 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
18836 if (cclauses == NULL)
18837 cclauses = cclauses_buf;
18838
953ff289 18839 c_parser_consume_token (parser);
6d7f7e0a 18840 if (!flag_openmp) /* flag_openmp_simd */
dda1bf61 18841 return c_parser_omp_for (loc, parser, p_name, mask, cclauses, if_p);
acf0174b 18842 block = c_begin_omp_parallel ();
dda1bf61 18843 tree ret = c_parser_omp_for (loc, parser, p_name, mask, cclauses, if_p);
acf0174b
JJ
18844 stmt
18845 = c_finish_omp_parallel (loc, cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
18846 block);
e162a134
JJ
18847 if (ret == NULL_TREE)
18848 return ret;
acf0174b
JJ
18849 OMP_PARALLEL_COMBINED (stmt) = 1;
18850 return stmt;
18851 }
d9a6bd32
JJ
18852 /* When combined with distribute, parallel has to be followed by for.
18853 #pragma omp target parallel is allowed though. */
18854 else if (cclauses
18855 && (mask & (OMP_CLAUSE_MASK_1
18856 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
acf0174b
JJ
18857 {
18858 error_at (loc, "expected %<for%> after %qs", p_name);
18859 c_parser_skip_to_pragma_eol (parser);
18860 return NULL_TREE;
18861 }
554a530f 18862 else if (c_parser_next_token_is (parser, CPP_NAME))
acf0174b
JJ
18863 {
18864 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
554a530f 18865 if (cclauses == NULL && strcmp (p, "master") == 0)
953ff289 18866 {
acf0174b 18867 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
28567c40
JJ
18868 cclauses = cclauses_buf;
18869
18870 c_parser_consume_token (parser);
18871 if (!flag_openmp) /* flag_openmp_simd */
18872 return c_parser_omp_master (loc, parser, p_name, mask, cclauses,
18873 if_p);
18874 block = c_begin_omp_parallel ();
18875 tree ret = c_parser_omp_master (loc, parser, p_name, mask, cclauses,
18876 if_p);
18877 stmt = c_finish_omp_parallel (loc,
18878 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
18879 block);
18880 OMP_PARALLEL_COMBINED (stmt) = 1;
18881 if (ret == NULL)
18882 return ret;
18883 return stmt;
18884 }
554a530f
JJ
18885 else if (strcmp (p, "loop") == 0)
18886 {
18887 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
18888 if (cclauses == NULL)
18889 cclauses = cclauses_buf;
18890
18891 c_parser_consume_token (parser);
18892 if (!flag_openmp) /* flag_openmp_simd */
18893 return c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
18894 if_p);
18895 block = c_begin_omp_parallel ();
18896 tree ret = c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
18897 if_p);
18898 stmt
18899 = c_finish_omp_parallel (loc,
18900 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
18901 block);
18902 if (ret == NULL_TREE)
18903 return ret;
18904 OMP_PARALLEL_COMBINED (stmt) = 1;
18905 return stmt;
18906 }
28567c40
JJ
18907 else if (!flag_openmp) /* flag_openmp_simd */
18908 {
18909 c_parser_skip_to_pragma_eol (parser, false);
18910 return NULL_TREE;
18911 }
554a530f 18912 else if (cclauses == NULL && strcmp (p, "sections") == 0)
28567c40
JJ
18913 {
18914 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
18915 cclauses = cclauses_buf;
acf0174b 18916
953ff289 18917 c_parser_consume_token (parser);
acf0174b
JJ
18918 block = c_begin_omp_parallel ();
18919 c_parser_omp_sections (loc, parser, p_name, mask, cclauses);
18920 stmt = c_finish_omp_parallel (loc,
18921 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
18922 block);
18923 OMP_PARALLEL_COMBINED (stmt) = 1;
18924 return stmt;
953ff289 18925 }
953ff289 18926 }
28567c40
JJ
18927 else if (!flag_openmp) /* flag_openmp_simd */
18928 {
18929 c_parser_skip_to_pragma_eol (parser, false);
18930 return NULL_TREE;
18931 }
953ff289 18932
acf0174b 18933 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
d9a6bd32
JJ
18934 if (cclauses)
18935 {
18936 omp_split_clauses (loc, OMP_PARALLEL, mask, clauses, cclauses);
18937 clauses = cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL];
18938 }
acf0174b
JJ
18939
18940 block = c_begin_omp_parallel ();
dda1bf61 18941 c_parser_statement (parser, if_p);
acf0174b
JJ
18942 stmt = c_finish_omp_parallel (loc, clauses, block);
18943
18944 return stmt;
18945}
18946
18947/* OpenMP 2.5:
18948 # pragma omp single single-clause[optseq] new-line
18949 structured-block
18950
18951 LOC is the location of the #pragma.
18952*/
18953
18954#define OMP_SINGLE_CLAUSE_MASK \
18955 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
18956 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
18957 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYPRIVATE) \
18958 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
18959
18960static tree
dda1bf61 18961c_parser_omp_single (location_t loc, c_parser *parser, bool *if_p)
acf0174b
JJ
18962{
18963 tree stmt = make_node (OMP_SINGLE);
18964 SET_EXPR_LOCATION (stmt, loc);
18965 TREE_TYPE (stmt) = void_type_node;
18966
18967 OMP_SINGLE_CLAUSES (stmt)
18968 = c_parser_omp_all_clauses (parser, OMP_SINGLE_CLAUSE_MASK,
18969 "#pragma omp single");
dda1bf61 18970 OMP_SINGLE_BODY (stmt) = c_parser_omp_structured_block (parser, if_p);
acf0174b
JJ
18971
18972 return add_stmt (stmt);
18973}
18974
18975/* OpenMP 3.0:
18976 # pragma omp task task-clause[optseq] new-line
18977
18978 LOC is the location of the #pragma.
18979*/
18980
18981#define OMP_TASK_CLAUSE_MASK \
18982 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
18983 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
18984 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
18985 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
18986 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
18987 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
18988 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
18989 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
d9a6bd32 18990 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
28567c40
JJ
18991 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
18992 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION))
acf0174b
JJ
18993
18994static tree
dda1bf61 18995c_parser_omp_task (location_t loc, c_parser *parser, bool *if_p)
acf0174b
JJ
18996{
18997 tree clauses, block;
18998
18999 clauses = c_parser_omp_all_clauses (parser, OMP_TASK_CLAUSE_MASK,
19000 "#pragma omp task");
19001
19002 block = c_begin_omp_task ();
dda1bf61 19003 c_parser_statement (parser, if_p);
acf0174b 19004 return c_finish_omp_task (loc, clauses, block);
953ff289
DN
19005}
19006
acf0174b
JJ
19007/* OpenMP 3.0:
19008 # pragma omp taskwait new-line
28567c40
JJ
19009
19010 OpenMP 5.0:
19011 # pragma omp taskwait taskwait-clause[optseq] new-line
acf0174b 19012*/
953ff289 19013
28567c40
JJ
19014#define OMP_TASKWAIT_CLAUSE_MASK \
19015 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)
19016
953ff289 19017static void
acf0174b 19018c_parser_omp_taskwait (c_parser *parser)
953ff289 19019{
c2255bc4 19020 location_t loc = c_parser_peek_token (parser)->location;
953ff289 19021 c_parser_consume_pragma (parser);
953ff289 19022
28567c40
JJ
19023 tree clauses
19024 = c_parser_omp_all_clauses (parser, OMP_TASKWAIT_CLAUSE_MASK,
19025 "#pragma omp taskwait");
19026
19027 if (clauses)
19028 {
19029 tree stmt = make_node (OMP_TASK);
19030 TREE_TYPE (stmt) = void_node;
19031 OMP_TASK_CLAUSES (stmt) = clauses;
19032 OMP_TASK_BODY (stmt) = NULL_TREE;
19033 SET_EXPR_LOCATION (stmt, loc);
19034 add_stmt (stmt);
19035 }
19036 else
19037 c_finish_omp_taskwait (loc);
953ff289
DN
19038}
19039
acf0174b
JJ
19040/* OpenMP 3.1:
19041 # pragma omp taskyield new-line
19042*/
953ff289 19043
acf0174b
JJ
19044static void
19045c_parser_omp_taskyield (c_parser *parser)
953ff289 19046{
acf0174b
JJ
19047 location_t loc = c_parser_peek_token (parser)->location;
19048 c_parser_consume_pragma (parser);
19049 c_parser_skip_to_pragma_eol (parser);
a68ab351 19050
acf0174b
JJ
19051 c_finish_omp_taskyield (loc);
19052}
3ba09659 19053
acf0174b
JJ
19054/* OpenMP 4.0:
19055 # pragma omp taskgroup new-line
28567c40
JJ
19056
19057 OpenMP 5.0:
19058 # pragma omp taskgroup taskgroup-clause[optseq] new-line
acf0174b 19059*/
953ff289 19060
28567c40
JJ
19061#define OMP_TASKGROUP_CLAUSE_MASK \
19062 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASK_REDUCTION))
19063
acf0174b 19064static tree
28567c40 19065c_parser_omp_taskgroup (location_t loc, c_parser *parser, bool *if_p)
acf0174b 19066{
28567c40
JJ
19067 tree clauses = c_parser_omp_all_clauses (parser, OMP_TASKGROUP_CLAUSE_MASK,
19068 "#pragma omp taskgroup");
19069
19070 tree body = c_parser_omp_structured_block (parser, if_p);
19071 return c_finish_omp_taskgroup (loc, body, clauses);
acf0174b 19072}
c9f9eb5d 19073
acf0174b
JJ
19074/* OpenMP 4.0:
19075 # pragma omp cancel cancel-clause[optseq] new-line
953ff289 19076
acf0174b
JJ
19077 LOC is the location of the #pragma.
19078*/
a68ab351 19079
acf0174b
JJ
19080#define OMP_CANCEL_CLAUSE_MASK \
19081 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
19082 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
19083 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
19084 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP) \
19085 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF))
a68ab351 19086
acf0174b
JJ
19087static void
19088c_parser_omp_cancel (c_parser *parser)
19089{
19090 location_t loc = c_parser_peek_token (parser)->location;
a68ab351 19091
acf0174b
JJ
19092 c_parser_consume_pragma (parser);
19093 tree clauses = c_parser_omp_all_clauses (parser, OMP_CANCEL_CLAUSE_MASK,
19094 "#pragma omp cancel");
953ff289 19095
acf0174b
JJ
19096 c_finish_omp_cancel (loc, clauses);
19097}
953ff289 19098
acf0174b
JJ
19099/* OpenMP 4.0:
19100 # pragma omp cancellation point cancelpt-clause[optseq] new-line
953ff289 19101
acf0174b
JJ
19102 LOC is the location of the #pragma.
19103*/
953ff289 19104
acf0174b
JJ
19105#define OMP_CANCELLATION_POINT_CLAUSE_MASK \
19106 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
19107 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
19108 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
19109 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP))
a68ab351 19110
acf0174b 19111static void
54d19c3b 19112c_parser_omp_cancellation_point (c_parser *parser, enum pragma_context context)
acf0174b
JJ
19113{
19114 location_t loc = c_parser_peek_token (parser)->location;
19115 tree clauses;
19116 bool point_seen = false;
19117
19118 c_parser_consume_pragma (parser);
19119 if (c_parser_next_token_is (parser, CPP_NAME))
a68ab351 19120 {
acf0174b
JJ
19121 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19122 if (strcmp (p, "point") == 0)
a68ab351 19123 {
acf0174b
JJ
19124 c_parser_consume_token (parser);
19125 point_seen = true;
a68ab351 19126 }
a68ab351 19127 }
acf0174b 19128 if (!point_seen)
a68ab351 19129 {
acf0174b
JJ
19130 c_parser_error (parser, "expected %<point%>");
19131 c_parser_skip_to_pragma_eol (parser);
19132 return;
a68ab351 19133 }
953ff289 19134
54d19c3b
TS
19135 if (context != pragma_compound)
19136 {
19137 if (context == pragma_stmt)
a71dbc63
JJ
19138 error_at (loc,
19139 "%<#pragma %s%> may only be used in compound statements",
19140 "omp cancellation point");
54d19c3b
TS
19141 else
19142 c_parser_error (parser, "expected declaration specifiers");
19143 c_parser_skip_to_pragma_eol (parser, false);
19144 return;
19145 }
19146
acf0174b
JJ
19147 clauses
19148 = c_parser_omp_all_clauses (parser, OMP_CANCELLATION_POINT_CLAUSE_MASK,
19149 "#pragma omp cancellation point");
c2255bc4 19150
acf0174b
JJ
19151 c_finish_omp_cancellation_point (loc, clauses);
19152}
953ff289 19153
acf0174b
JJ
19154/* OpenMP 4.0:
19155 #pragma omp distribute distribute-clause[optseq] new-line
19156 for-loop */
19157
19158#define OMP_DISTRIBUTE_CLAUSE_MASK \
19159 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19160 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
e01d41e5 19161 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
acf0174b
JJ
19162 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)\
19163 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE))
953ff289
DN
19164
19165static tree
acf0174b 19166c_parser_omp_distribute (location_t loc, c_parser *parser,
dda1bf61
JJ
19167 char *p_name, omp_clause_mask mask, tree *cclauses,
19168 bool *if_p)
953ff289 19169{
acf0174b
JJ
19170 tree clauses, block, ret;
19171
19172 strcat (p_name, " distribute");
19173 mask |= OMP_DISTRIBUTE_CLAUSE_MASK;
19174
19175 if (c_parser_next_token_is (parser, CPP_NAME))
19176 {
19177 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19178 bool simd = false;
19179 bool parallel = false;
19180
19181 if (strcmp (p, "simd") == 0)
19182 simd = true;
19183 else
19184 parallel = strcmp (p, "parallel") == 0;
19185 if (parallel || simd)
19186 {
19187 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
19188 if (cclauses == NULL)
19189 cclauses = cclauses_buf;
19190 c_parser_consume_token (parser);
6d7f7e0a
TB
19191 if (!flag_openmp) /* flag_openmp_simd */
19192 {
19193 if (simd)
dda1bf61
JJ
19194 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
19195 if_p);
6d7f7e0a
TB
19196 else
19197 return c_parser_omp_parallel (loc, parser, p_name, mask,
dda1bf61 19198 cclauses, if_p);
6d7f7e0a 19199 }
acf0174b
JJ
19200 block = c_begin_compound_stmt (true);
19201 if (simd)
dda1bf61
JJ
19202 ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
19203 if_p);
acf0174b 19204 else
dda1bf61
JJ
19205 ret = c_parser_omp_parallel (loc, parser, p_name, mask, cclauses,
19206 if_p);
acf0174b
JJ
19207 block = c_end_compound_stmt (loc, block, true);
19208 if (ret == NULL)
19209 return ret;
19210 ret = make_node (OMP_DISTRIBUTE);
19211 TREE_TYPE (ret) = void_type_node;
19212 OMP_FOR_BODY (ret) = block;
19213 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE];
19214 SET_EXPR_LOCATION (ret, loc);
19215 add_stmt (ret);
19216 return ret;
19217 }
19218 }
6d7f7e0a
TB
19219 if (!flag_openmp) /* flag_openmp_simd */
19220 {
62021f64 19221 c_parser_skip_to_pragma_eol (parser, false);
6d7f7e0a
TB
19222 return NULL_TREE;
19223 }
953ff289 19224
acf0174b
JJ
19225 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
19226 if (cclauses)
19227 {
19228 omp_split_clauses (loc, OMP_DISTRIBUTE, mask, clauses, cclauses);
19229 clauses = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE];
19230 }
953ff289
DN
19231
19232 block = c_begin_compound_stmt (true);
dda1bf61
JJ
19233 ret = c_parser_omp_for_loop (loc, parser, OMP_DISTRIBUTE, clauses, NULL,
19234 if_p);
c2255bc4 19235 block = c_end_compound_stmt (loc, block, true);
953ff289
DN
19236 add_stmt (block);
19237
19238 return ret;
19239}
19240
acf0174b
JJ
19241/* OpenMP 4.0:
19242 # pragma omp teams teams-clause[optseq] new-line
19243 structured-block */
c2255bc4 19244
acf0174b
JJ
19245#define OMP_TEAMS_CLAUSE_MASK \
19246 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19247 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
19248 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
19249 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
19250 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS) \
19251 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \
19252 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT))
953ff289
DN
19253
19254static tree
acf0174b 19255c_parser_omp_teams (location_t loc, c_parser *parser,
dda1bf61
JJ
19256 char *p_name, omp_clause_mask mask, tree *cclauses,
19257 bool *if_p)
953ff289 19258{
acf0174b
JJ
19259 tree clauses, block, ret;
19260
19261 strcat (p_name, " teams");
19262 mask |= OMP_TEAMS_CLAUSE_MASK;
19263
19264 if (c_parser_next_token_is (parser, CPP_NAME))
19265 {
19266 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19267 if (strcmp (p, "distribute") == 0)
19268 {
19269 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
19270 if (cclauses == NULL)
19271 cclauses = cclauses_buf;
19272
19273 c_parser_consume_token (parser);
6d7f7e0a 19274 if (!flag_openmp) /* flag_openmp_simd */
dda1bf61
JJ
19275 return c_parser_omp_distribute (loc, parser, p_name, mask,
19276 cclauses, if_p);
28567c40 19277 block = c_begin_omp_parallel ();
dda1bf61
JJ
19278 ret = c_parser_omp_distribute (loc, parser, p_name, mask, cclauses,
19279 if_p);
acf0174b
JJ
19280 block = c_end_compound_stmt (loc, block, true);
19281 if (ret == NULL)
19282 return ret;
19283 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
19284 ret = make_node (OMP_TEAMS);
19285 TREE_TYPE (ret) = void_type_node;
19286 OMP_TEAMS_CLAUSES (ret) = clauses;
19287 OMP_TEAMS_BODY (ret) = block;
41b37d5e 19288 OMP_TEAMS_COMBINED (ret) = 1;
28567c40 19289 SET_EXPR_LOCATION (ret, loc);
acf0174b
JJ
19290 return add_stmt (ret);
19291 }
554a530f
JJ
19292 else if (strcmp (p, "loop") == 0)
19293 {
19294 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
19295 if (cclauses == NULL)
19296 cclauses = cclauses_buf;
19297
19298 c_parser_consume_token (parser);
19299 if (!flag_openmp) /* flag_openmp_simd */
19300 return c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
19301 if_p);
19302 block = c_begin_omp_parallel ();
19303 ret = c_parser_omp_loop (loc, parser, p_name, mask, cclauses, if_p);
19304 block = c_end_compound_stmt (loc, block, true);
19305 if (ret == NULL)
19306 return ret;
19307 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
19308 ret = make_node (OMP_TEAMS);
19309 TREE_TYPE (ret) = void_type_node;
19310 OMP_TEAMS_CLAUSES (ret) = clauses;
19311 OMP_TEAMS_BODY (ret) = block;
19312 OMP_TEAMS_COMBINED (ret) = 1;
19313 SET_EXPR_LOCATION (ret, loc);
19314 return add_stmt (ret);
19315 }
acf0174b 19316 }
6d7f7e0a
TB
19317 if (!flag_openmp) /* flag_openmp_simd */
19318 {
62021f64 19319 c_parser_skip_to_pragma_eol (parser, false);
6d7f7e0a
TB
19320 return NULL_TREE;
19321 }
acf0174b
JJ
19322
19323 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
19324 if (cclauses)
19325 {
19326 omp_split_clauses (loc, OMP_TEAMS, mask, clauses, cclauses);
19327 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
19328 }
19329
19330 tree stmt = make_node (OMP_TEAMS);
19331 TREE_TYPE (stmt) = void_type_node;
19332 OMP_TEAMS_CLAUSES (stmt) = clauses;
28567c40
JJ
19333 block = c_begin_omp_parallel ();
19334 add_stmt (c_parser_omp_structured_block (parser, if_p));
19335 OMP_TEAMS_BODY (stmt) = c_end_compound_stmt (loc, block, true);
19336 SET_EXPR_LOCATION (stmt, loc);
acf0174b
JJ
19337
19338 return add_stmt (stmt);
953ff289
DN
19339}
19340
acf0174b
JJ
19341/* OpenMP 4.0:
19342 # pragma omp target data target-data-clause[optseq] new-line
19343 structured-block */
c2255bc4 19344
acf0174b
JJ
19345#define OMP_TARGET_DATA_CLAUSE_MASK \
19346 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
19347 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
d9a6bd32 19348 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
398e3feb
JJ
19349 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR) \
19350 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR))
953ff289
DN
19351
19352static tree
dda1bf61 19353c_parser_omp_target_data (location_t loc, c_parser *parser, bool *if_p)
953ff289 19354{
d9a6bd32 19355 tree clauses
acf0174b
JJ
19356 = c_parser_omp_all_clauses (parser, OMP_TARGET_DATA_CLAUSE_MASK,
19357 "#pragma omp target data");
d9a6bd32
JJ
19358 int map_seen = 0;
19359 for (tree *pc = &clauses; *pc;)
19360 {
19361 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
19362 switch (OMP_CLAUSE_MAP_KIND (*pc))
19363 {
19364 case GOMP_MAP_TO:
19365 case GOMP_MAP_ALWAYS_TO:
19366 case GOMP_MAP_FROM:
19367 case GOMP_MAP_ALWAYS_FROM:
19368 case GOMP_MAP_TOFROM:
19369 case GOMP_MAP_ALWAYS_TOFROM:
19370 case GOMP_MAP_ALLOC:
19371 map_seen = 3;
19372 break;
19373 case GOMP_MAP_FIRSTPRIVATE_POINTER:
e01d41e5 19374 case GOMP_MAP_ALWAYS_POINTER:
d9a6bd32
JJ
19375 break;
19376 default:
19377 map_seen |= 1;
19378 error_at (OMP_CLAUSE_LOCATION (*pc),
19379 "%<#pragma omp target data%> with map-type other "
19380 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
19381 "on %<map%> clause");
19382 *pc = OMP_CLAUSE_CHAIN (*pc);
19383 continue;
19384 }
398e3feb
JJ
19385 else if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_PTR
19386 || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_ADDR)
28567c40 19387 map_seen = 3;
d9a6bd32
JJ
19388 pc = &OMP_CLAUSE_CHAIN (*pc);
19389 }
19390
19391 if (map_seen != 3)
19392 {
19393 if (map_seen == 0)
19394 error_at (loc,
19395 "%<#pragma omp target data%> must contain at least "
398e3feb
JJ
19396 "one %<map%>, %<use_device_ptr%> or %<use_device_addr%> "
19397 "clause");
d9a6bd32
JJ
19398 return NULL_TREE;
19399 }
19400
19401 tree stmt = make_node (OMP_TARGET_DATA);
19402 TREE_TYPE (stmt) = void_type_node;
19403 OMP_TARGET_DATA_CLAUSES (stmt) = clauses;
acf0174b
JJ
19404 keep_next_level ();
19405 tree block = c_begin_compound_stmt (true);
dda1bf61 19406 add_stmt (c_parser_omp_structured_block (parser, if_p));
acf0174b 19407 OMP_TARGET_DATA_BODY (stmt) = c_end_compound_stmt (loc, block, true);
953ff289 19408
acf0174b
JJ
19409 SET_EXPR_LOCATION (stmt, loc);
19410 return add_stmt (stmt);
19411}
953ff289 19412
acf0174b
JJ
19413/* OpenMP 4.0:
19414 # pragma omp target update target-update-clause[optseq] new-line */
c2255bc4 19415
acf0174b
JJ
19416#define OMP_TARGET_UPDATE_CLAUSE_MASK \
19417 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FROM) \
19418 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
19419 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
d9a6bd32
JJ
19420 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
19421 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
19422 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
953ff289 19423
acf0174b
JJ
19424static bool
19425c_parser_omp_target_update (location_t loc, c_parser *parser,
19426 enum pragma_context context)
953ff289 19427{
acf0174b
JJ
19428 if (context == pragma_stmt)
19429 {
a71dbc63
JJ
19430 error_at (loc, "%<#pragma %s%> may only be used in compound statements",
19431 "omp target update");
aec17bfe 19432 c_parser_skip_to_pragma_eol (parser, false);
acf0174b
JJ
19433 return false;
19434 }
953ff289 19435
acf0174b
JJ
19436 tree clauses
19437 = c_parser_omp_all_clauses (parser, OMP_TARGET_UPDATE_CLAUSE_MASK,
19438 "#pragma omp target update");
629b3d75
MJ
19439 if (omp_find_clause (clauses, OMP_CLAUSE_TO) == NULL_TREE
19440 && omp_find_clause (clauses, OMP_CLAUSE_FROM) == NULL_TREE)
953ff289 19441 {
acf0174b 19442 error_at (loc,
06aca1d5 19443 "%<#pragma omp target update%> must contain at least one "
acf0174b
JJ
19444 "%<from%> or %<to%> clauses");
19445 return false;
953ff289
DN
19446 }
19447
acf0174b
JJ
19448 tree stmt = make_node (OMP_TARGET_UPDATE);
19449 TREE_TYPE (stmt) = void_type_node;
19450 OMP_TARGET_UPDATE_CLAUSES (stmt) = clauses;
19451 SET_EXPR_LOCATION (stmt, loc);
19452 add_stmt (stmt);
19453 return false;
19454}
953ff289 19455
d9a6bd32
JJ
19456/* OpenMP 4.5:
19457 # pragma omp target enter data target-data-clause[optseq] new-line */
19458
19459#define OMP_TARGET_ENTER_DATA_CLAUSE_MASK \
19460 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
19461 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
19462 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
19463 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
19464 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
19465
19466static tree
19467c_parser_omp_target_enter_data (location_t loc, c_parser *parser,
19468 enum pragma_context context)
19469{
19470 bool data_seen = false;
19471 if (c_parser_next_token_is (parser, CPP_NAME))
19472 {
19473 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19474 if (strcmp (p, "data") == 0)
19475 {
19476 c_parser_consume_token (parser);
19477 data_seen = true;
19478 }
19479 }
19480 if (!data_seen)
19481 {
19482 c_parser_error (parser, "expected %<data%>");
19483 c_parser_skip_to_pragma_eol (parser);
19484 return NULL_TREE;
19485 }
19486
19487 if (context == pragma_stmt)
19488 {
a71dbc63
JJ
19489 error_at (loc, "%<#pragma %s%> may only be used in compound statements",
19490 "omp target enter data");
aec17bfe 19491 c_parser_skip_to_pragma_eol (parser, false);
d9a6bd32
JJ
19492 return NULL_TREE;
19493 }
19494
19495 tree clauses
19496 = c_parser_omp_all_clauses (parser, OMP_TARGET_ENTER_DATA_CLAUSE_MASK,
19497 "#pragma omp target enter data");
19498 int map_seen = 0;
19499 for (tree *pc = &clauses; *pc;)
19500 {
19501 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
19502 switch (OMP_CLAUSE_MAP_KIND (*pc))
19503 {
19504 case GOMP_MAP_TO:
19505 case GOMP_MAP_ALWAYS_TO:
19506 case GOMP_MAP_ALLOC:
19507 map_seen = 3;
19508 break;
19509 case GOMP_MAP_FIRSTPRIVATE_POINTER:
e01d41e5 19510 case GOMP_MAP_ALWAYS_POINTER:
d9a6bd32
JJ
19511 break;
19512 default:
19513 map_seen |= 1;
19514 error_at (OMP_CLAUSE_LOCATION (*pc),
19515 "%<#pragma omp target enter data%> with map-type other "
19516 "than %<to%> or %<alloc%> on %<map%> clause");
19517 *pc = OMP_CLAUSE_CHAIN (*pc);
19518 continue;
19519 }
19520 pc = &OMP_CLAUSE_CHAIN (*pc);
19521 }
19522
19523 if (map_seen != 3)
19524 {
19525 if (map_seen == 0)
19526 error_at (loc,
19527 "%<#pragma omp target enter data%> must contain at least "
19528 "one %<map%> clause");
19529 return NULL_TREE;
19530 }
19531
19532 tree stmt = make_node (OMP_TARGET_ENTER_DATA);
19533 TREE_TYPE (stmt) = void_type_node;
19534 OMP_TARGET_ENTER_DATA_CLAUSES (stmt) = clauses;
19535 SET_EXPR_LOCATION (stmt, loc);
19536 add_stmt (stmt);
19537 return stmt;
19538}
19539
19540/* OpenMP 4.5:
19541 # pragma omp target exit data target-data-clause[optseq] new-line */
19542
19543#define OMP_TARGET_EXIT_DATA_CLAUSE_MASK \
19544 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
19545 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
19546 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
19547 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
19548 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
19549
19550static tree
19551c_parser_omp_target_exit_data (location_t loc, c_parser *parser,
19552 enum pragma_context context)
19553{
19554 bool data_seen = false;
19555 if (c_parser_next_token_is (parser, CPP_NAME))
19556 {
19557 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19558 if (strcmp (p, "data") == 0)
19559 {
19560 c_parser_consume_token (parser);
19561 data_seen = true;
19562 }
19563 }
19564 if (!data_seen)
19565 {
19566 c_parser_error (parser, "expected %<data%>");
19567 c_parser_skip_to_pragma_eol (parser);
19568 return NULL_TREE;
19569 }
19570
19571 if (context == pragma_stmt)
19572 {
a71dbc63
JJ
19573 error_at (loc, "%<#pragma %s%> may only be used in compound statements",
19574 "omp target exit data");
aec17bfe 19575 c_parser_skip_to_pragma_eol (parser, false);
d9a6bd32
JJ
19576 return NULL_TREE;
19577 }
19578
19579 tree clauses
19580 = c_parser_omp_all_clauses (parser, OMP_TARGET_EXIT_DATA_CLAUSE_MASK,
19581 "#pragma omp target exit data");
19582
19583 int map_seen = 0;
19584 for (tree *pc = &clauses; *pc;)
19585 {
19586 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
19587 switch (OMP_CLAUSE_MAP_KIND (*pc))
19588 {
19589 case GOMP_MAP_FROM:
19590 case GOMP_MAP_ALWAYS_FROM:
19591 case GOMP_MAP_RELEASE:
19592 case GOMP_MAP_DELETE:
19593 map_seen = 3;
19594 break;
19595 case GOMP_MAP_FIRSTPRIVATE_POINTER:
e01d41e5 19596 case GOMP_MAP_ALWAYS_POINTER:
d9a6bd32
JJ
19597 break;
19598 default:
19599 map_seen |= 1;
19600 error_at (OMP_CLAUSE_LOCATION (*pc),
19601 "%<#pragma omp target exit data%> with map-type other "
883c8f06 19602 "than %<from%>, %<release%> or %<delete%> on %<map%>"
d9a6bd32
JJ
19603 " clause");
19604 *pc = OMP_CLAUSE_CHAIN (*pc);
19605 continue;
19606 }
19607 pc = &OMP_CLAUSE_CHAIN (*pc);
19608 }
19609
19610 if (map_seen != 3)
19611 {
19612 if (map_seen == 0)
19613 error_at (loc,
19614 "%<#pragma omp target exit data%> must contain at least one "
19615 "%<map%> clause");
19616 return NULL_TREE;
19617 }
19618
19619 tree stmt = make_node (OMP_TARGET_EXIT_DATA);
19620 TREE_TYPE (stmt) = void_type_node;
19621 OMP_TARGET_EXIT_DATA_CLAUSES (stmt) = clauses;
19622 SET_EXPR_LOCATION (stmt, loc);
19623 add_stmt (stmt);
19624 return stmt;
19625}
19626
acf0174b
JJ
19627/* OpenMP 4.0:
19628 # pragma omp target target-clause[optseq] new-line
19629 structured-block */
953ff289 19630
acf0174b
JJ
19631#define OMP_TARGET_CLAUSE_MASK \
19632 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
19633 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
d9a6bd32
JJ
19634 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
19635 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
19636 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
19637 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19638 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
19639 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULTMAP) \
19640 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR))
953ff289 19641
acf0174b 19642static bool
dda1bf61 19643c_parser_omp_target (c_parser *parser, enum pragma_context context, bool *if_p)
acf0174b
JJ
19644{
19645 location_t loc = c_parser_peek_token (parser)->location;
19646 c_parser_consume_pragma (parser);
d9a6bd32 19647 tree *pc = NULL, stmt, block;
953ff289 19648
acf0174b
JJ
19649 if (context != pragma_stmt && context != pragma_compound)
19650 {
19651 c_parser_error (parser, "expected declaration specifiers");
19652 c_parser_skip_to_pragma_eol (parser);
19653 return false;
953ff289
DN
19654 }
19655
28567c40
JJ
19656 if (flag_openmp)
19657 omp_requires_mask
19658 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
19659
acf0174b 19660 if (c_parser_next_token_is (parser, CPP_NAME))
953ff289 19661 {
acf0174b 19662 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
d9a6bd32 19663 enum tree_code ccode = ERROR_MARK;
953ff289 19664
6d7f7e0a 19665 if (strcmp (p, "teams") == 0)
d9a6bd32
JJ
19666 ccode = OMP_TEAMS;
19667 else if (strcmp (p, "parallel") == 0)
19668 ccode = OMP_PARALLEL;
19669 else if (strcmp (p, "simd") == 0)
19670 ccode = OMP_SIMD;
19671 if (ccode != ERROR_MARK)
acf0174b
JJ
19672 {
19673 tree cclauses[C_OMP_CLAUSE_SPLIT_COUNT];
19674 char p_name[sizeof ("#pragma omp target teams distribute "
19675 "parallel for simd")];
953ff289 19676
acf0174b 19677 c_parser_consume_token (parser);
e7bd1de1 19678 strcpy (p_name, "#pragma omp target");
6d7f7e0a 19679 if (!flag_openmp) /* flag_openmp_simd */
edbba2ce 19680 {
d9a6bd32
JJ
19681 tree stmt;
19682 switch (ccode)
19683 {
19684 case OMP_TEAMS:
19685 stmt = c_parser_omp_teams (loc, parser, p_name,
19686 OMP_TARGET_CLAUSE_MASK,
dda1bf61 19687 cclauses, if_p);
d9a6bd32
JJ
19688 break;
19689 case OMP_PARALLEL:
19690 stmt = c_parser_omp_parallel (loc, parser, p_name,
19691 OMP_TARGET_CLAUSE_MASK,
dda1bf61 19692 cclauses, if_p);
d9a6bd32
JJ
19693 break;
19694 case OMP_SIMD:
19695 stmt = c_parser_omp_simd (loc, parser, p_name,
19696 OMP_TARGET_CLAUSE_MASK,
dda1bf61 19697 cclauses, if_p);
d9a6bd32
JJ
19698 break;
19699 default:
19700 gcc_unreachable ();
19701 }
edbba2ce
TS
19702 return stmt != NULL_TREE;
19703 }
acf0174b 19704 keep_next_level ();
d9a6bd32
JJ
19705 tree block = c_begin_compound_stmt (true), ret;
19706 switch (ccode)
19707 {
19708 case OMP_TEAMS:
19709 ret = c_parser_omp_teams (loc, parser, p_name,
dda1bf61
JJ
19710 OMP_TARGET_CLAUSE_MASK, cclauses,
19711 if_p);
d9a6bd32
JJ
19712 break;
19713 case OMP_PARALLEL:
19714 ret = c_parser_omp_parallel (loc, parser, p_name,
dda1bf61
JJ
19715 OMP_TARGET_CLAUSE_MASK, cclauses,
19716 if_p);
d9a6bd32
JJ
19717 break;
19718 case OMP_SIMD:
19719 ret = c_parser_omp_simd (loc, parser, p_name,
dda1bf61
JJ
19720 OMP_TARGET_CLAUSE_MASK, cclauses,
19721 if_p);
d9a6bd32
JJ
19722 break;
19723 default:
19724 gcc_unreachable ();
19725 }
acf0174b 19726 block = c_end_compound_stmt (loc, block, true);
edbba2ce
TS
19727 if (ret == NULL_TREE)
19728 return false;
e01d41e5
JJ
19729 if (ccode == OMP_TEAMS)
19730 {
19731 /* For combined target teams, ensure the num_teams and
19732 thread_limit clause expressions are evaluated on the host,
19733 before entering the target construct. */
19734 tree c;
19735 for (c = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
19736 c; c = OMP_CLAUSE_CHAIN (c))
19737 if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS
19738 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
19739 && TREE_CODE (OMP_CLAUSE_OPERAND (c, 0)) != INTEGER_CST)
19740 {
19741 tree expr = OMP_CLAUSE_OPERAND (c, 0);
19742 tree tmp = create_tmp_var_raw (TREE_TYPE (expr));
19743 expr = build4 (TARGET_EXPR, TREE_TYPE (expr), tmp,
19744 expr, NULL_TREE, NULL_TREE);
19745 add_stmt (expr);
19746 OMP_CLAUSE_OPERAND (c, 0) = expr;
19747 tree tc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
19748 OMP_CLAUSE_FIRSTPRIVATE);
19749 OMP_CLAUSE_DECL (tc) = tmp;
19750 OMP_CLAUSE_CHAIN (tc)
19751 = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
19752 cclauses[C_OMP_CLAUSE_SPLIT_TARGET] = tc;
19753 }
19754 }
acf0174b
JJ
19755 tree stmt = make_node (OMP_TARGET);
19756 TREE_TYPE (stmt) = void_type_node;
19757 OMP_TARGET_CLAUSES (stmt) = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
19758 OMP_TARGET_BODY (stmt) = block;
d9a6bd32 19759 OMP_TARGET_COMBINED (stmt) = 1;
28567c40 19760 SET_EXPR_LOCATION (stmt, loc);
acf0174b 19761 add_stmt (stmt);
d9a6bd32
JJ
19762 pc = &OMP_TARGET_CLAUSES (stmt);
19763 goto check_clauses;
acf0174b 19764 }
6d7f7e0a
TB
19765 else if (!flag_openmp) /* flag_openmp_simd */
19766 {
62021f64 19767 c_parser_skip_to_pragma_eol (parser, false);
edbba2ce 19768 return false;
6d7f7e0a
TB
19769 }
19770 else if (strcmp (p, "data") == 0)
19771 {
19772 c_parser_consume_token (parser);
dda1bf61 19773 c_parser_omp_target_data (loc, parser, if_p);
6d7f7e0a
TB
19774 return true;
19775 }
d9a6bd32
JJ
19776 else if (strcmp (p, "enter") == 0)
19777 {
19778 c_parser_consume_token (parser);
19779 c_parser_omp_target_enter_data (loc, parser, context);
19780 return false;
19781 }
19782 else if (strcmp (p, "exit") == 0)
19783 {
19784 c_parser_consume_token (parser);
19785 c_parser_omp_target_exit_data (loc, parser, context);
19786 return false;
19787 }
6d7f7e0a
TB
19788 else if (strcmp (p, "update") == 0)
19789 {
19790 c_parser_consume_token (parser);
19791 return c_parser_omp_target_update (loc, parser, context);
19792 }
953ff289 19793 }
bcac0b4d
JJ
19794 if (!flag_openmp) /* flag_openmp_simd */
19795 {
19796 c_parser_skip_to_pragma_eol (parser, false);
19797 return false;
19798 }
953ff289 19799
d9a6bd32 19800 stmt = make_node (OMP_TARGET);
953ff289 19801 TREE_TYPE (stmt) = void_type_node;
953ff289 19802
acf0174b
JJ
19803 OMP_TARGET_CLAUSES (stmt)
19804 = c_parser_omp_all_clauses (parser, OMP_TARGET_CLAUSE_MASK,
19805 "#pragma omp target");
d9a6bd32 19806 pc = &OMP_TARGET_CLAUSES (stmt);
acf0174b 19807 keep_next_level ();
d9a6bd32 19808 block = c_begin_compound_stmt (true);
dda1bf61 19809 add_stmt (c_parser_omp_structured_block (parser, if_p));
acf0174b
JJ
19810 OMP_TARGET_BODY (stmt) = c_end_compound_stmt (loc, block, true);
19811
19812 SET_EXPR_LOCATION (stmt, loc);
19813 add_stmt (stmt);
d9a6bd32
JJ
19814
19815check_clauses:
19816 while (*pc)
19817 {
19818 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
19819 switch (OMP_CLAUSE_MAP_KIND (*pc))
19820 {
19821 case GOMP_MAP_TO:
19822 case GOMP_MAP_ALWAYS_TO:
19823 case GOMP_MAP_FROM:
19824 case GOMP_MAP_ALWAYS_FROM:
19825 case GOMP_MAP_TOFROM:
19826 case GOMP_MAP_ALWAYS_TOFROM:
19827 case GOMP_MAP_ALLOC:
19828 case GOMP_MAP_FIRSTPRIVATE_POINTER:
e01d41e5 19829 case GOMP_MAP_ALWAYS_POINTER:
d9a6bd32
JJ
19830 break;
19831 default:
19832 error_at (OMP_CLAUSE_LOCATION (*pc),
19833 "%<#pragma omp target%> with map-type other "
19834 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
19835 "on %<map%> clause");
19836 *pc = OMP_CLAUSE_CHAIN (*pc);
19837 continue;
19838 }
19839 pc = &OMP_CLAUSE_CHAIN (*pc);
19840 }
acf0174b
JJ
19841 return true;
19842}
19843
19844/* OpenMP 4.0:
94e7f906
JJ
19845 # pragma omp declare simd declare-simd-clauses[optseq] new-line
19846
19847 OpenMP 5.0:
19848 # pragma omp declare variant (identifier) match(context-selector) new-line
19849 */
acf0174b
JJ
19850
19851#define OMP_DECLARE_SIMD_CLAUSE_MASK \
19852 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
19853 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
19854 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
19855 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM) \
19856 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INBRANCH) \
19857 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOTINBRANCH))
19858
19859static void
19860c_parser_omp_declare_simd (c_parser *parser, enum pragma_context context)
19861{
94e7f906
JJ
19862 c_token *token = c_parser_peek_token (parser);
19863 gcc_assert (token->type == CPP_NAME);
19864 tree kind = token->value;
19865 gcc_assert (strcmp (IDENTIFIER_POINTER (kind), "simd") == 0
19866 || strcmp (IDENTIFIER_POINTER (kind), "variant") == 0);
19867
8c681247 19868 auto_vec<c_token> clauses;
acf0174b
JJ
19869 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
19870 {
19871 c_token *token = c_parser_peek_token (parser);
19872 if (token->type == CPP_EOF)
19873 {
19874 c_parser_skip_to_pragma_eol (parser);
acf0174b
JJ
19875 return;
19876 }
19877 clauses.safe_push (*token);
19878 c_parser_consume_token (parser);
19879 }
19880 clauses.safe_push (*c_parser_peek_token (parser));
19881 c_parser_skip_to_pragma_eol (parser);
19882
19883 while (c_parser_next_token_is (parser, CPP_PRAGMA))
19884 {
94e7f906 19885 if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_DECLARE
acf0174b 19886 || c_parser_peek_2nd_token (parser)->type != CPP_NAME
94e7f906 19887 || c_parser_peek_2nd_token (parser)->value != kind)
acf0174b 19888 {
94e7f906
JJ
19889 error ("%<#pragma omp declare %s%> must be followed by "
19890 "function declaration or definition or another "
19891 "%<#pragma omp declare %s%>",
19892 IDENTIFIER_POINTER (kind), IDENTIFIER_POINTER (kind));
acf0174b
JJ
19893 return;
19894 }
19895 c_parser_consume_pragma (parser);
19896 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
19897 {
19898 c_token *token = c_parser_peek_token (parser);
19899 if (token->type == CPP_EOF)
19900 {
19901 c_parser_skip_to_pragma_eol (parser);
acf0174b
JJ
19902 return;
19903 }
19904 clauses.safe_push (*token);
19905 c_parser_consume_token (parser);
19906 }
19907 clauses.safe_push (*c_parser_peek_token (parser));
19908 c_parser_skip_to_pragma_eol (parser);
19909 }
19910
19911 /* Make sure nothing tries to read past the end of the tokens. */
19912 c_token eof_token;
19913 memset (&eof_token, 0, sizeof (eof_token));
19914 eof_token.type = CPP_EOF;
19915 clauses.safe_push (eof_token);
19916 clauses.safe_push (eof_token);
19917
19918 switch (context)
19919 {
19920 case pragma_external:
19921 if (c_parser_next_token_is (parser, CPP_KEYWORD)
19922 && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
19923 {
19924 int ext = disable_extension_diagnostics ();
19925 do
19926 c_parser_consume_token (parser);
19927 while (c_parser_next_token_is (parser, CPP_KEYWORD)
19928 && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
19929 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
19930 NULL, clauses);
19931 restore_extension_diagnostics (ext);
19932 }
19933 else
19934 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
19935 NULL, clauses);
19936 break;
19937 case pragma_struct:
19938 case pragma_param:
41521dee 19939 case pragma_stmt:
94e7f906
JJ
19940 error ("%<#pragma omp declare %s%> must be followed by "
19941 "function declaration or definition",
19942 IDENTIFIER_POINTER (kind));
acf0174b
JJ
19943 break;
19944 case pragma_compound:
acf0174b
JJ
19945 if (c_parser_next_token_is (parser, CPP_KEYWORD)
19946 && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
19947 {
19948 int ext = disable_extension_diagnostics ();
19949 do
19950 c_parser_consume_token (parser);
19951 while (c_parser_next_token_is (parser, CPP_KEYWORD)
19952 && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
19953 if (c_parser_next_tokens_start_declaration (parser))
19954 {
19955 c_parser_declaration_or_fndef (parser, true, true, true, true,
19956 true, NULL, clauses);
19957 restore_extension_diagnostics (ext);
19958 break;
19959 }
19960 restore_extension_diagnostics (ext);
19961 }
19962 else if (c_parser_next_tokens_start_declaration (parser))
19963 {
19964 c_parser_declaration_or_fndef (parser, true, true, true, true, true,
19965 NULL, clauses);
19966 break;
19967 }
94e7f906
JJ
19968 error ("%<#pragma omp declare %s%> must be followed by "
19969 "function declaration or definition",
19970 IDENTIFIER_POINTER (kind));
acf0174b
JJ
19971 break;
19972 default:
19973 gcc_unreachable ();
19974 }
953ff289
DN
19975}
19976
94e7f906
JJ
19977static const char *const omp_construct_selectors[] = {
19978 "simd", "target", "teams", "parallel", "for", NULL };
19979static const char *const omp_device_selectors[] = {
19980 "kind", "isa", "arch", NULL };
19981static const char *const omp_implementation_selectors[] = {
19982 "vendor", "extension", "atomic_default_mem_order", "unified_address",
19983 "unified_shared_memory", "dynamic_allocators", "reverse_offload", NULL };
19984static const char *const omp_user_selectors[] = {
19985 "condition", NULL };
19986
19987/* OpenMP 5.0:
19988
19989 trait-selector:
19990 trait-selector-name[([trait-score:]trait-property[,trait-property[,...]])]
19991
19992 trait-score:
19993 score(score-expression) */
19994
19995static tree
19996c_parser_omp_context_selector (c_parser *parser, tree set, tree parms)
19997{
19998 tree ret = NULL_TREE;
19999 do
20000 {
20001 tree selector;
20002 if (c_parser_next_token_is (parser, CPP_KEYWORD)
20003 || c_parser_next_token_is (parser, CPP_NAME))
20004 selector = c_parser_peek_token (parser)->value;
20005 else
20006 {
20007 c_parser_error (parser, "expected trait selector name");
20008 return error_mark_node;
20009 }
20010
20011 tree properties = NULL_TREE;
20012 const char *const *selectors = NULL;
20013 bool allow_score = true;
20014 bool allow_user = false;
20015 int property_limit = 0;
b2417b59
JJ
20016 enum { CTX_PROPERTY_NONE, CTX_PROPERTY_USER, CTX_PROPERTY_NAME_LIST,
20017 CTX_PROPERTY_ID, CTX_PROPERTY_EXPR,
20018 CTX_PROPERTY_SIMD } property_kind = CTX_PROPERTY_NONE;
94e7f906
JJ
20019 switch (IDENTIFIER_POINTER (set)[0])
20020 {
20021 case 'c': /* construct */
20022 selectors = omp_construct_selectors;
20023 allow_score = false;
20024 property_limit = 1;
20025 property_kind = CTX_PROPERTY_SIMD;
20026 break;
20027 case 'd': /* device */
20028 selectors = omp_device_selectors;
20029 allow_score = false;
20030 allow_user = true;
20031 property_limit = 3;
b2417b59 20032 property_kind = CTX_PROPERTY_NAME_LIST;
94e7f906
JJ
20033 break;
20034 case 'i': /* implementation */
20035 selectors = omp_implementation_selectors;
20036 allow_user = true;
20037 property_limit = 3;
b2417b59 20038 property_kind = CTX_PROPERTY_NAME_LIST;
94e7f906
JJ
20039 break;
20040 case 'u': /* user */
20041 selectors = omp_user_selectors;
20042 property_limit = 1;
20043 property_kind = CTX_PROPERTY_EXPR;
20044 break;
20045 default:
20046 gcc_unreachable ();
20047 }
20048 for (int i = 0; ; i++)
20049 {
20050 if (selectors[i] == NULL)
20051 {
20052 if (allow_user)
20053 {
20054 property_kind = CTX_PROPERTY_USER;
20055 break;
20056 }
20057 else
20058 {
20059 error_at (c_parser_peek_token (parser)->location,
20060 "selector %qs not allowed for context selector "
20061 "set %qs", IDENTIFIER_POINTER (selector),
20062 IDENTIFIER_POINTER (set));
20063 c_parser_consume_token (parser);
20064 return error_mark_node;
20065 }
20066 }
20067 if (i == property_limit)
20068 property_kind = CTX_PROPERTY_NONE;
20069 if (strcmp (selectors[i], IDENTIFIER_POINTER (selector)) == 0)
20070 break;
20071 }
b2417b59
JJ
20072 if (property_kind == CTX_PROPERTY_NAME_LIST
20073 && IDENTIFIER_POINTER (set)[0] == 'i'
20074 && strcmp (IDENTIFIER_POINTER (selector),
20075 "atomic_default_mem_order") == 0)
20076 property_kind = CTX_PROPERTY_ID;
94e7f906
JJ
20077
20078 c_parser_consume_token (parser);
20079
20080 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
20081 {
20082 if (property_kind == CTX_PROPERTY_NONE)
20083 {
20084 error_at (c_parser_peek_token (parser)->location,
20085 "selector %qs does not accept any properties",
20086 IDENTIFIER_POINTER (selector));
20087 return error_mark_node;
20088 }
20089
20090 matching_parens parens;
20091 parens.require_open (parser);
20092
20093 c_token *token = c_parser_peek_token (parser);
20094 if (allow_score
20095 && c_parser_next_token_is (parser, CPP_NAME)
20096 && strcmp (IDENTIFIER_POINTER (token->value), "score") == 0
20097 && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN)
20098 {
20099 c_parser_consume_token (parser);
20100
20101 matching_parens parens2;
20102 parens2.require_open (parser);
20103 tree score = c_parser_expr_no_commas (parser, NULL).value;
20104 parens2.skip_until_found_close (parser);
20105 c_parser_require (parser, CPP_COLON, "expected %<:%>");
20106 if (score != error_mark_node)
20107 {
20108 mark_exp_read (score);
20109 score = c_fully_fold (score, false, NULL);
20110 if (!INTEGRAL_TYPE_P (TREE_TYPE (score))
bedb7f04 20111 || TREE_CODE (score) != INTEGER_CST)
94e7f906
JJ
20112 error_at (token->location, "score argument must be "
20113 "constant integer expression");
bedb7f04
JJ
20114 else if (tree_int_cst_sgn (score) < 0)
20115 error_at (token->location, "score argument must be "
20116 "non-negative");
94e7f906
JJ
20117 else
20118 properties = tree_cons (get_identifier (" score"),
20119 score, properties);
20120 }
20121 token = c_parser_peek_token (parser);
20122 }
20123
20124 switch (property_kind)
20125 {
20126 tree t;
20127 case CTX_PROPERTY_USER:
20128 do
20129 {
20130 t = c_parser_expr_no_commas (parser, NULL).value;
20131 if (TREE_CODE (t) == STRING_CST)
20132 properties = tree_cons (NULL_TREE, t, properties);
20133 else if (t != error_mark_node)
20134 {
20135 mark_exp_read (t);
20136 t = c_fully_fold (t, false, NULL);
20137 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
20138 || !tree_fits_shwi_p (t))
20139 error_at (token->location, "property must be "
20140 "constant integer expression or string "
20141 "literal");
20142 else
20143 properties = tree_cons (NULL_TREE, t, properties);
20144 }
20de9568
JJ
20145 else
20146 return error_mark_node;
94e7f906
JJ
20147
20148 if (c_parser_next_token_is (parser, CPP_COMMA))
20149 c_parser_consume_token (parser);
20150 else
20151 break;
20152 }
20153 while (1);
20154 break;
b2417b59
JJ
20155 case CTX_PROPERTY_ID:
20156 if (c_parser_next_token_is (parser, CPP_KEYWORD)
20157 || c_parser_next_token_is (parser, CPP_NAME))
20158 {
20159 tree prop = c_parser_peek_token (parser)->value;
20160 c_parser_consume_token (parser);
20161 properties = tree_cons (prop, NULL_TREE, properties);
20162 }
20163 else
20164 {
20165 c_parser_error (parser, "expected identifier");
20166 return error_mark_node;
20167 }
20168 break;
20169 case CTX_PROPERTY_NAME_LIST:
94e7f906
JJ
20170 do
20171 {
b2417b59 20172 tree prop = NULL_TREE, value = NULL_TREE;
94e7f906
JJ
20173 if (c_parser_next_token_is (parser, CPP_KEYWORD)
20174 || c_parser_next_token_is (parser, CPP_NAME))
b2417b59
JJ
20175 {
20176 prop = c_parser_peek_token (parser)->value;
20177 c_parser_consume_token (parser);
20178 }
20179 else if (c_parser_next_token_is (parser, CPP_STRING))
20180 value = c_parser_string_literal (parser, false,
20181 false).value;
94e7f906
JJ
20182 else
20183 {
b2417b59
JJ
20184 c_parser_error (parser, "expected identifier or "
20185 "string literal");
94e7f906
JJ
20186 return error_mark_node;
20187 }
94e7f906 20188
b2417b59 20189 properties = tree_cons (prop, value, properties);
94e7f906
JJ
20190
20191 if (c_parser_next_token_is (parser, CPP_COMMA))
20192 c_parser_consume_token (parser);
20193 else
20194 break;
20195 }
20196 while (1);
20197 break;
20198 case CTX_PROPERTY_EXPR:
20199 t = c_parser_expr_no_commas (parser, NULL).value;
20200 if (t != error_mark_node)
20201 {
20202 mark_exp_read (t);
20203 t = c_fully_fold (t, false, NULL);
20204 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
20205 || !tree_fits_shwi_p (t))
20206 error_at (token->location, "property must be "
20207 "constant integer expression");
20208 else
20209 properties = tree_cons (NULL_TREE, t, properties);
20210 }
20de9568
JJ
20211 else
20212 return error_mark_node;
94e7f906
JJ
20213 break;
20214 case CTX_PROPERTY_SIMD:
20215 if (parms == NULL_TREE)
20216 {
20217 error_at (token->location, "properties for %<simd%> "
20218 "selector may not be specified in "
20219 "%<metadirective%>");
20220 return error_mark_node;
20221 }
20222 tree c;
20223 c = c_parser_omp_all_clauses (parser,
20224 OMP_DECLARE_SIMD_CLAUSE_MASK,
b9424661 20225 "simd", true, 2);
94e7f906
JJ
20226 c = c_omp_declare_simd_clauses_to_numbers (parms
20227 == error_mark_node
20228 ? NULL_TREE : parms,
20229 c);
20de9568 20230 properties = c;
94e7f906
JJ
20231 break;
20232 default:
20233 gcc_unreachable ();
20234 }
20235
20236 parens.skip_until_found_close (parser);
20237 properties = nreverse (properties);
20238 }
b2417b59
JJ
20239 else if (property_kind == CTX_PROPERTY_NAME_LIST
20240 || property_kind == CTX_PROPERTY_ID
94e7f906
JJ
20241 || property_kind == CTX_PROPERTY_EXPR)
20242 {
20243 c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>");
20244 return error_mark_node;
20245 }
20246
20247 ret = tree_cons (selector, properties, ret);
20248
20249 if (c_parser_next_token_is (parser, CPP_COMMA))
20250 c_parser_consume_token (parser);
20251 else
20252 break;
20253 }
20254 while (1);
20255
20256 return nreverse (ret);
20257}
20258
20259/* OpenMP 5.0:
20260
20261 trait-set-selector[,trait-set-selector[,...]]
20262
20263 trait-set-selector:
20264 trait-set-selector-name = { trait-selector[, trait-selector[, ...]] }
20265
20266 trait-set-selector-name:
20267 constructor
20268 device
20269 implementation
20270 user */
20271
20272static tree
20273c_parser_omp_context_selector_specification (c_parser *parser, tree parms)
20274{
20275 tree ret = NULL_TREE;
20276 do
20277 {
20278 const char *setp = "";
20279 if (c_parser_next_token_is (parser, CPP_NAME))
20280 setp = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20281 switch (setp[0])
20282 {
20283 case 'c':
20284 if (strcmp (setp, "construct") == 0)
20285 setp = NULL;
20286 break;
20287 case 'd':
20288 if (strcmp (setp, "device") == 0)
20289 setp = NULL;
20290 break;
20291 case 'i':
20292 if (strcmp (setp, "implementation") == 0)
20293 setp = NULL;
20294 break;
20295 case 'u':
20296 if (strcmp (setp, "user") == 0)
20297 setp = NULL;
20298 break;
20299 default:
20300 break;
20301 }
20302 if (setp)
20303 {
20304 c_parser_error (parser, "expected %<construct%>, %<device%>, "
20305 "%<implementation%> or %<user%>");
20306 return error_mark_node;
20307 }
20308
20309 tree set = c_parser_peek_token (parser)->value;
20310 c_parser_consume_token (parser);
20311
20312 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
20313 return error_mark_node;
20314
20315 matching_braces braces;
20316 if (!braces.require_open (parser))
20317 return error_mark_node;
20318
20319 tree selectors = c_parser_omp_context_selector (parser, set, parms);
20320 if (selectors == error_mark_node)
20321 ret = error_mark_node;
20322 else if (ret != error_mark_node)
20323 ret = tree_cons (set, selectors, ret);
20324
20325 braces.skip_until_found_close (parser);
20326
20327 if (c_parser_next_token_is (parser, CPP_COMMA))
20328 c_parser_consume_token (parser);
20329 else
20330 break;
20331 }
20332 while (1);
20333
20334 if (ret == error_mark_node)
20335 return ret;
20336 return nreverse (ret);
20337}
20338
20339/* Finalize #pragma omp declare variant after FNDECL has been parsed, and put
20de9568 20340 that into "omp declare variant base" attribute. */
94e7f906
JJ
20341
20342static void
20343c_finish_omp_declare_variant (c_parser *parser, tree fndecl, tree parms)
20344{
20345 matching_parens parens;
20346 if (!parens.require_open (parser))
20347 {
20348 fail:
20349 c_parser_skip_to_pragma_eol (parser, false);
20350 return;
20351 }
20352
20353 if (c_parser_next_token_is_not (parser, CPP_NAME)
20354 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
20355 {
20356 c_parser_error (parser, "expected identifier");
20357 goto fail;
20358 }
20359
20360 c_token *token = c_parser_peek_token (parser);
20361 tree variant = lookup_name (token->value);
20362
20363 if (variant == NULL_TREE)
20364 {
20365 undeclared_variable (token->location, token->value);
20366 variant = error_mark_node;
20367 }
20368
20369 c_parser_consume_token (parser);
20370
20371 parens.require_close (parser);
20372
20373 const char *clause = "";
20374 location_t match_loc = c_parser_peek_token (parser)->location;
20375 if (c_parser_next_token_is (parser, CPP_NAME))
20376 clause = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20377 if (strcmp (clause, "match"))
20378 {
20379 c_parser_error (parser, "expected %<match%>");
20380 goto fail;
20381 }
20382
20383 c_parser_consume_token (parser);
20384
20385 if (!parens.require_open (parser))
20386 goto fail;
20387
20388 if (parms == NULL_TREE)
20389 parms = error_mark_node;
20390
20391 tree ctx = c_parser_omp_context_selector_specification (parser, parms);
20392 if (ctx == error_mark_node)
20393 goto fail;
20394 ctx = c_omp_check_context_selector (match_loc, ctx);
20395 if (ctx != error_mark_node && variant != error_mark_node)
20396 {
20397 if (TREE_CODE (variant) != FUNCTION_DECL)
20398 {
20399 error_at (token->location, "variant %qD is not a function", variant);
20400 variant = error_mark_node;
20401 }
d0c464d2 20402 else if (omp_get_context_selector (ctx, "construct", "simd") == NULL_TREE
94e7f906
JJ
20403 && !comptypes (TREE_TYPE (fndecl), TREE_TYPE (variant)))
20404 {
20405 error_at (token->location, "variant %qD and base %qD have "
20406 "incompatible types", variant, fndecl);
20407 variant = error_mark_node;
20408 }
20409 else if (fndecl_built_in_p (variant)
20410 && (strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
20411 "__builtin_", strlen ("__builtin_")) == 0
20412 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
20413 "__sync_", strlen ("__sync_")) == 0
20414 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
20415 "__atomic_", strlen ("__atomic_")) == 0))
20416 {
20417 error_at (token->location, "variant %qD is a built-in", variant);
20418 variant = error_mark_node;
20419 }
20420 if (variant != error_mark_node)
20421 {
20422 C_DECL_USED (variant) = 1;
d0c464d2 20423 tree construct = omp_get_context_selector (ctx, "construct", NULL);
20de9568 20424 c_omp_mark_declare_variant (match_loc, variant, construct);
135df52c 20425 if (omp_context_selector_matches (ctx))
20de9568
JJ
20426 {
20427 tree attr
20428 = tree_cons (get_identifier ("omp declare variant base"),
20429 build_tree_list (variant, ctx),
20430 DECL_ATTRIBUTES (fndecl));
20431 DECL_ATTRIBUTES (fndecl) = attr;
20432 }
94e7f906
JJ
20433 }
20434 }
20435
20436 parens.require_close (parser);
20437 c_parser_skip_to_pragma_eol (parser);
20438}
20439
20440/* Finalize #pragma omp declare simd or #pragma omp declare variant
20441 clauses after FNDECL has been parsed, and put that into "omp declare simd"
20de9568 20442 or "omp declare variant base" attribute. */
c2255bc4 20443
acf0174b
JJ
20444static void
20445c_finish_omp_declare_simd (c_parser *parser, tree fndecl, tree parms,
20446 vec<c_token> clauses)
20447{
94e7f906
JJ
20448 /* Normally first token is CPP_NAME "simd" or "variant". CPP_EOF there
20449 indicates error has been reported and CPP_PRAGMA that
20450 c_finish_omp_declare_simd has already processed the tokens. */
41958c28 20451 if (clauses.exists () && clauses[0].type == CPP_EOF)
acf0174b 20452 return;
94e7f906
JJ
20453 const char *kind = "simd";
20454 if (clauses.exists ()
20455 && (clauses[0].type == CPP_NAME || clauses[0].type == CPP_PRAGMA))
20456 kind = IDENTIFIER_POINTER (clauses[0].value);
20457 gcc_assert (strcmp (kind, "simd") == 0 || strcmp (kind, "variant") == 0);
acf0174b
JJ
20458 if (fndecl == NULL_TREE || TREE_CODE (fndecl) != FUNCTION_DECL)
20459 {
94e7f906
JJ
20460 error ("%<#pragma omp declare %s%> not immediately followed by "
20461 "a function declaration or definition", kind);
acf0174b
JJ
20462 clauses[0].type = CPP_EOF;
20463 return;
20464 }
41958c28 20465 if (clauses.exists () && clauses[0].type != CPP_NAME)
acf0174b
JJ
20466 {
20467 error_at (DECL_SOURCE_LOCATION (fndecl),
94e7f906
JJ
20468 "%<#pragma omp declare %s%> not immediately followed by "
20469 "a single function declaration or definition", kind);
acf0174b
JJ
20470 clauses[0].type = CPP_EOF;
20471 return;
20472 }
953ff289 20473
acf0174b
JJ
20474 if (parms == NULL_TREE)
20475 parms = DECL_ARGUMENTS (fndecl);
953ff289 20476
acf0174b
JJ
20477 unsigned int tokens_avail = parser->tokens_avail;
20478 gcc_assert (parser->tokens == &parser->tokens_buf[0]);
fff77217 20479
5e9d6aa4
JK
20480 parser->tokens = clauses.address ();
20481 parser->tokens_avail = clauses.length ();
41958c28 20482
acf0174b
JJ
20483 /* c_parser_omp_declare_simd pushed 2 extra CPP_EOF tokens at the end. */
20484 while (parser->tokens_avail > 3)
20485 {
20486 c_token *token = c_parser_peek_token (parser);
5e9d6aa4 20487 gcc_assert (token->type == CPP_NAME
94e7f906 20488 && strcmp (IDENTIFIER_POINTER (token->value), kind) == 0);
acf0174b
JJ
20489 c_parser_consume_token (parser);
20490 parser->in_pragma = true;
953ff289 20491
94e7f906
JJ
20492 if (strcmp (kind, "simd") == 0)
20493 {
20494 tree c;
20495 c = c_parser_omp_all_clauses (parser, OMP_DECLARE_SIMD_CLAUSE_MASK,
20496 "#pragma omp declare simd");
20497 c = c_omp_declare_simd_clauses_to_numbers (parms, c);
20498 if (c != NULL_TREE)
20499 c = tree_cons (NULL_TREE, c, NULL_TREE);
20500 c = build_tree_list (get_identifier ("omp declare simd"), c);
20501 TREE_CHAIN (c) = DECL_ATTRIBUTES (fndecl);
20502 DECL_ATTRIBUTES (fndecl) = c;
20503 }
20504 else
20505 {
20506 gcc_assert (strcmp (kind, "variant") == 0);
20507 c_finish_omp_declare_variant (parser, fndecl, parms);
20508 }
acf0174b 20509 }
953ff289 20510
acf0174b
JJ
20511 parser->tokens = &parser->tokens_buf[0];
20512 parser->tokens_avail = tokens_avail;
41958c28
BI
20513 if (clauses.exists ())
20514 clauses[0].type = CPP_PRAGMA;
953ff289
DN
20515}
20516
953ff289 20517
acf0174b
JJ
20518/* OpenMP 4.0:
20519 # pragma omp declare target new-line
20520 declarations and definitions
d9a6bd32
JJ
20521 # pragma omp end declare target new-line
20522
20523 OpenMP 4.5:
20524 # pragma omp declare target ( extended-list ) new-line
20525
20526 # pragma omp declare target declare-target-clauses[seq] new-line */
20527
20528#define OMP_DECLARE_TARGET_CLAUSE_MASK \
20529 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
77eb117f
JJ
20530 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK) \
20531 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE))
953ff289 20532
acf0174b
JJ
20533static void
20534c_parser_omp_declare_target (c_parser *parser)
953ff289 20535{
d9a6bd32 20536 tree clauses = NULL_TREE;
77eb117f
JJ
20537 int device_type = 0;
20538 bool only_device_type = true;
d9a6bd32
JJ
20539 if (c_parser_next_token_is (parser, CPP_NAME))
20540 clauses = c_parser_omp_all_clauses (parser, OMP_DECLARE_TARGET_CLAUSE_MASK,
20541 "#pragma omp declare target");
20542 else if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
20543 {
20544 clauses = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_TO_DECLARE,
20545 clauses);
77886428 20546 clauses = c_finish_omp_clauses (clauses, C_ORT_OMP);
d9a6bd32
JJ
20547 c_parser_skip_to_pragma_eol (parser);
20548 }
20549 else
20550 {
20551 c_parser_skip_to_pragma_eol (parser);
20552 current_omp_declare_target_attribute++;
20553 return;
20554 }
77eb117f
JJ
20555 for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
20556 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
20557 device_type |= OMP_CLAUSE_DEVICE_TYPE_KIND (c);
d9a6bd32
JJ
20558 for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
20559 {
77eb117f
JJ
20560 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
20561 continue;
d9a6bd32
JJ
20562 tree t = OMP_CLAUSE_DECL (c), id;
20563 tree at1 = lookup_attribute ("omp declare target", DECL_ATTRIBUTES (t));
20564 tree at2 = lookup_attribute ("omp declare target link",
20565 DECL_ATTRIBUTES (t));
77eb117f 20566 only_device_type = false;
d9a6bd32
JJ
20567 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINK)
20568 {
20569 id = get_identifier ("omp declare target link");
20570 std::swap (at1, at2);
20571 }
20572 else
20573 id = get_identifier ("omp declare target");
20574 if (at2)
20575 {
20576 error_at (OMP_CLAUSE_LOCATION (c),
20577 "%qD specified both in declare target %<link%> and %<to%>"
20578 " clauses", t);
20579 continue;
20580 }
20581 if (!at1)
e01d41e5 20582 {
e01d41e5 20583 DECL_ATTRIBUTES (t) = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
56f71478
JJ
20584 if (TREE_CODE (t) != FUNCTION_DECL && !is_global_var (t))
20585 continue;
20586
20587 symtab_node *node = symtab_node::get (t);
e01d41e5
JJ
20588 if (node != NULL)
20589 {
20590 node->offloadable = 1;
1d899da2 20591 if (ENABLE_OFFLOADING)
e01d41e5 20592 {
1d899da2
TS
20593 g->have_offload = true;
20594 if (is_a <varpool_node *> (node))
e6d6ec9e 20595 vec_safe_push (offload_vars, t);
e01d41e5 20596 }
e01d41e5
JJ
20597 }
20598 }
77eb117f
JJ
20599 if (TREE_CODE (t) != FUNCTION_DECL)
20600 continue;
20601 if ((device_type & OMP_CLAUSE_DEVICE_TYPE_HOST) != 0)
20602 {
20603 tree at3 = lookup_attribute ("omp declare target host",
20604 DECL_ATTRIBUTES (t));
20605 if (at3 == NULL_TREE)
20606 {
20607 id = get_identifier ("omp declare target host");
20608 DECL_ATTRIBUTES (t)
20609 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
20610 }
20611 }
20612 if ((device_type & OMP_CLAUSE_DEVICE_TYPE_NOHOST) != 0)
20613 {
20614 tree at3 = lookup_attribute ("omp declare target nohost",
20615 DECL_ATTRIBUTES (t));
20616 if (at3 == NULL_TREE)
20617 {
20618 id = get_identifier ("omp declare target nohost");
20619 DECL_ATTRIBUTES (t)
20620 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
20621 }
20622 }
d9a6bd32 20623 }
77eb117f
JJ
20624 if (device_type && only_device_type)
20625 warning_at (OMP_CLAUSE_LOCATION (clauses), 0,
20626 "directive with only %<device_type%> clauses ignored");
acf0174b 20627}
953ff289 20628
acf0174b
JJ
20629static void
20630c_parser_omp_end_declare_target (c_parser *parser)
20631{
20632 location_t loc = c_parser_peek_token (parser)->location;
20633 c_parser_consume_pragma (parser);
20634 if (c_parser_next_token_is (parser, CPP_NAME)
20635 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
20636 "declare") == 0)
953ff289
DN
20637 {
20638 c_parser_consume_token (parser);
acf0174b
JJ
20639 if (c_parser_next_token_is (parser, CPP_NAME)
20640 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
20641 "target") == 0)
20642 c_parser_consume_token (parser);
20643 else
953ff289 20644 {
acf0174b
JJ
20645 c_parser_error (parser, "expected %<target%>");
20646 c_parser_skip_to_pragma_eol (parser);
20647 return;
953ff289
DN
20648 }
20649 }
acf0174b
JJ
20650 else
20651 {
20652 c_parser_error (parser, "expected %<declare%>");
20653 c_parser_skip_to_pragma_eol (parser);
20654 return;
20655 }
20656 c_parser_skip_to_pragma_eol (parser);
20657 if (!current_omp_declare_target_attribute)
20658 error_at (loc, "%<#pragma omp end declare target%> without corresponding "
20659 "%<#pragma omp declare target%>");
20660 else
20661 current_omp_declare_target_attribute--;
20662}
953ff289 20663
953ff289 20664
acf0174b
JJ
20665/* OpenMP 4.0
20666 #pragma omp declare reduction (reduction-id : typename-list : expression) \
20667 initializer-clause[opt] new-line
20668
20669 initializer-clause:
20670 initializer (omp_priv = initializer)
20671 initializer (function-name (argument-list)) */
20672
20673static void
20674c_parser_omp_declare_reduction (c_parser *parser, enum pragma_context context)
20675{
20676 unsigned int tokens_avail = 0, i;
20677 vec<tree> types = vNULL;
20678 vec<c_token> clauses = vNULL;
20679 enum tree_code reduc_code = ERROR_MARK;
20680 tree reduc_id = NULL_TREE;
20681 tree type;
20682 location_t rloc = c_parser_peek_token (parser)->location;
20683
20684 if (context == pragma_struct || context == pragma_param)
953ff289 20685 {
acf0174b
JJ
20686 error ("%<#pragma omp declare reduction%> not at file or block scope");
20687 goto fail;
20688 }
953ff289 20689
acf0174b
JJ
20690 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
20691 goto fail;
953ff289 20692
acf0174b
JJ
20693 switch (c_parser_peek_token (parser)->type)
20694 {
20695 case CPP_PLUS:
20696 reduc_code = PLUS_EXPR;
20697 break;
20698 case CPP_MULT:
20699 reduc_code = MULT_EXPR;
20700 break;
20701 case CPP_MINUS:
20702 reduc_code = MINUS_EXPR;
20703 break;
20704 case CPP_AND:
20705 reduc_code = BIT_AND_EXPR;
20706 break;
20707 case CPP_XOR:
20708 reduc_code = BIT_XOR_EXPR;
20709 break;
20710 case CPP_OR:
20711 reduc_code = BIT_IOR_EXPR;
20712 break;
20713 case CPP_AND_AND:
20714 reduc_code = TRUTH_ANDIF_EXPR;
20715 break;
20716 case CPP_OR_OR:
20717 reduc_code = TRUTH_ORIF_EXPR;
20718 break;
20719 case CPP_NAME:
20720 const char *p;
20721 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20722 if (strcmp (p, "min") == 0)
20723 {
20724 reduc_code = MIN_EXPR;
20725 break;
20726 }
20727 if (strcmp (p, "max") == 0)
20728 {
20729 reduc_code = MAX_EXPR;
20730 break;
20731 }
20732 reduc_id = c_parser_peek_token (parser)->value;
953ff289 20733 break;
953ff289 20734 default:
acf0174b
JJ
20735 c_parser_error (parser,
20736 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
79c9b7a8 20737 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
acf0174b 20738 goto fail;
953ff289
DN
20739 }
20740
acf0174b
JJ
20741 tree orig_reduc_id, reduc_decl;
20742 orig_reduc_id = reduc_id;
20743 reduc_id = c_omp_reduction_id (reduc_code, reduc_id);
20744 reduc_decl = c_omp_reduction_decl (reduc_id);
20745 c_parser_consume_token (parser);
953ff289 20746
acf0174b
JJ
20747 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
20748 goto fail;
c2255bc4 20749
acf0174b
JJ
20750 while (true)
20751 {
20752 location_t loc = c_parser_peek_token (parser)->location;
20753 struct c_type_name *ctype = c_parser_type_name (parser);
20754 if (ctype != NULL)
20755 {
20756 type = groktypename (ctype, NULL, NULL);
20757 if (type == error_mark_node)
20758 ;
20759 else if ((INTEGRAL_TYPE_P (type)
20760 || TREE_CODE (type) == REAL_TYPE
20761 || TREE_CODE (type) == COMPLEX_TYPE)
20762 && orig_reduc_id == NULL_TREE)
20763 error_at (loc, "predeclared arithmetic type in "
20764 "%<#pragma omp declare reduction%>");
20765 else if (TREE_CODE (type) == FUNCTION_TYPE
20766 || TREE_CODE (type) == ARRAY_TYPE)
20767 error_at (loc, "function or array type in "
20768 "%<#pragma omp declare reduction%>");
9dc5773f
JJ
20769 else if (TYPE_ATOMIC (type))
20770 error_at (loc, "%<_Atomic%> qualified type in "
20771 "%<#pragma omp declare reduction%>");
acf0174b
JJ
20772 else if (TYPE_QUALS_NO_ADDR_SPACE (type))
20773 error_at (loc, "const, volatile or restrict qualified type in "
20774 "%<#pragma omp declare reduction%>");
20775 else
20776 {
20777 tree t;
20778 for (t = DECL_INITIAL (reduc_decl); t; t = TREE_CHAIN (t))
20779 if (comptypes (TREE_PURPOSE (t), type))
20780 {
20781 error_at (loc, "redeclaration of %qs "
20782 "%<#pragma omp declare reduction%> for "
20783 "type %qT",
20784 IDENTIFIER_POINTER (reduc_id)
20785 + sizeof ("omp declare reduction ") - 1,
20786 type);
20787 location_t ploc
20788 = DECL_SOURCE_LOCATION (TREE_VEC_ELT (TREE_VALUE (t),
20789 0));
20790 error_at (ploc, "previous %<#pragma omp declare "
20791 "reduction%>");
20792 break;
20793 }
20794 if (t == NULL_TREE)
20795 types.safe_push (type);
20796 }
20797 if (c_parser_next_token_is (parser, CPP_COMMA))
20798 c_parser_consume_token (parser);
20799 else
20800 break;
20801 }
20802 else
20803 break;
20804 }
953ff289 20805
acf0174b
JJ
20806 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>")
20807 || types.is_empty ())
20808 {
20809 fail:
20810 clauses.release ();
20811 types.release ();
20812 while (true)
20813 {
20814 c_token *token = c_parser_peek_token (parser);
20815 if (token->type == CPP_EOF || token->type == CPP_PRAGMA_EOL)
20816 break;
20817 c_parser_consume_token (parser);
20818 }
20819 c_parser_skip_to_pragma_eol (parser);
20820 return;
20821 }
953ff289 20822
acf0174b
JJ
20823 if (types.length () > 1)
20824 {
20825 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
20826 {
20827 c_token *token = c_parser_peek_token (parser);
20828 if (token->type == CPP_EOF)
20829 goto fail;
20830 clauses.safe_push (*token);
20831 c_parser_consume_token (parser);
20832 }
20833 clauses.safe_push (*c_parser_peek_token (parser));
20834 c_parser_skip_to_pragma_eol (parser);
953ff289 20835
acf0174b
JJ
20836 /* Make sure nothing tries to read past the end of the tokens. */
20837 c_token eof_token;
20838 memset (&eof_token, 0, sizeof (eof_token));
20839 eof_token.type = CPP_EOF;
20840 clauses.safe_push (eof_token);
20841 clauses.safe_push (eof_token);
20842 }
953ff289 20843
acf0174b
JJ
20844 int errs = errorcount;
20845 FOR_EACH_VEC_ELT (types, i, type)
20846 {
20847 tokens_avail = parser->tokens_avail;
20848 gcc_assert (parser->tokens == &parser->tokens_buf[0]);
20849 if (!clauses.is_empty ())
20850 {
20851 parser->tokens = clauses.address ();
20852 parser->tokens_avail = clauses.length ();
20853 parser->in_pragma = true;
20854 }
953ff289 20855
acf0174b
JJ
20856 bool nested = current_function_decl != NULL_TREE;
20857 if (nested)
20858 c_push_function_context ();
20859 tree fndecl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
20860 reduc_id, default_function_type);
20861 current_function_decl = fndecl;
20862 allocate_struct_function (fndecl, true);
20863 push_scope ();
20864 tree stmt = push_stmt_list ();
20865 /* Intentionally BUILTINS_LOCATION, so that -Wshadow doesn't
20866 warn about these. */
20867 tree omp_out = build_decl (BUILTINS_LOCATION, VAR_DECL,
20868 get_identifier ("omp_out"), type);
20869 DECL_ARTIFICIAL (omp_out) = 1;
20870 DECL_CONTEXT (omp_out) = fndecl;
20871 pushdecl (omp_out);
20872 tree omp_in = build_decl (BUILTINS_LOCATION, VAR_DECL,
20873 get_identifier ("omp_in"), type);
20874 DECL_ARTIFICIAL (omp_in) = 1;
20875 DECL_CONTEXT (omp_in) = fndecl;
20876 pushdecl (omp_in);
20877 struct c_expr combiner = c_parser_expression (parser);
20878 struct c_expr initializer;
20879 tree omp_priv = NULL_TREE, omp_orig = NULL_TREE;
20880 bool bad = false;
913884f7 20881 initializer.set_error ();
acf0174b
JJ
20882 if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
20883 bad = true;
20884 else if (c_parser_next_token_is (parser, CPP_NAME)
20885 && strcmp (IDENTIFIER_POINTER
20886 (c_parser_peek_token (parser)->value),
20887 "initializer") == 0)
20888 {
20889 c_parser_consume_token (parser);
20890 pop_scope ();
20891 push_scope ();
20892 omp_priv = build_decl (BUILTINS_LOCATION, VAR_DECL,
20893 get_identifier ("omp_priv"), type);
20894 DECL_ARTIFICIAL (omp_priv) = 1;
20895 DECL_INITIAL (omp_priv) = error_mark_node;
20896 DECL_CONTEXT (omp_priv) = fndecl;
20897 pushdecl (omp_priv);
20898 omp_orig = build_decl (BUILTINS_LOCATION, VAR_DECL,
20899 get_identifier ("omp_orig"), type);
20900 DECL_ARTIFICIAL (omp_orig) = 1;
20901 DECL_CONTEXT (omp_orig) = fndecl;
20902 pushdecl (omp_orig);
20903 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
20904 bad = true;
20905 else if (!c_parser_next_token_is (parser, CPP_NAME))
20906 {
20907 c_parser_error (parser, "expected %<omp_priv%> or "
20908 "function-name");
20909 bad = true;
20910 }
20911 else if (strcmp (IDENTIFIER_POINTER
20912 (c_parser_peek_token (parser)->value),
20913 "omp_priv") != 0)
20914 {
20915 if (c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN
20916 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
20917 {
20918 c_parser_error (parser, "expected function-name %<(%>");
20919 bad = true;
20920 }
20921 else
20922 initializer = c_parser_postfix_expression (parser);
20923 if (initializer.value
20924 && TREE_CODE (initializer.value) == CALL_EXPR)
20925 {
20926 int j;
20927 tree c = initializer.value;
20928 for (j = 0; j < call_expr_nargs (c); j++)
d9a6bd32
JJ
20929 {
20930 tree a = CALL_EXPR_ARG (c, j);
20931 STRIP_NOPS (a);
20932 if (TREE_CODE (a) == ADDR_EXPR
20933 && TREE_OPERAND (a, 0) == omp_priv)
20934 break;
20935 }
acf0174b
JJ
20936 if (j == call_expr_nargs (c))
20937 error ("one of the initializer call arguments should be "
20938 "%<&omp_priv%>");
20939 }
20940 }
20941 else
20942 {
20943 c_parser_consume_token (parser);
20944 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
20945 bad = true;
20946 else
20947 {
20948 tree st = push_stmt_list ();
acf0174b 20949 location_t loc = c_parser_peek_token (parser)->location;
5dd9a9d0
DM
20950 rich_location richloc (line_table, loc);
20951 start_init (omp_priv, NULL_TREE, 0, &richloc);
acf0174b
JJ
20952 struct c_expr init = c_parser_initializer (parser);
20953 finish_init ();
20954 finish_decl (omp_priv, loc, init.value,
20955 init.original_type, NULL_TREE);
20956 pop_stmt_list (st);
20957 }
20958 }
20959 if (!bad
20960 && !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
20961 bad = true;
20962 }
c2255bc4 20963
acf0174b
JJ
20964 if (!bad)
20965 {
20966 c_parser_skip_to_pragma_eol (parser);
a68ab351 20967
acf0174b
JJ
20968 tree t = tree_cons (type, make_tree_vec (omp_priv ? 6 : 3),
20969 DECL_INITIAL (reduc_decl));
20970 DECL_INITIAL (reduc_decl) = t;
20971 DECL_SOURCE_LOCATION (omp_out) = rloc;
20972 TREE_VEC_ELT (TREE_VALUE (t), 0) = omp_out;
20973 TREE_VEC_ELT (TREE_VALUE (t), 1) = omp_in;
20974 TREE_VEC_ELT (TREE_VALUE (t), 2) = combiner.value;
20975 walk_tree (&combiner.value, c_check_omp_declare_reduction_r,
20976 &TREE_VEC_ELT (TREE_VALUE (t), 0), NULL);
20977 if (omp_priv)
20978 {
20979 DECL_SOURCE_LOCATION (omp_priv) = rloc;
20980 TREE_VEC_ELT (TREE_VALUE (t), 3) = omp_priv;
20981 TREE_VEC_ELT (TREE_VALUE (t), 4) = omp_orig;
20982 TREE_VEC_ELT (TREE_VALUE (t), 5) = initializer.value;
20983 walk_tree (&initializer.value, c_check_omp_declare_reduction_r,
20984 &TREE_VEC_ELT (TREE_VALUE (t), 3), NULL);
20985 walk_tree (&DECL_INITIAL (omp_priv),
20986 c_check_omp_declare_reduction_r,
20987 &TREE_VEC_ELT (TREE_VALUE (t), 3), NULL);
20988 }
20989 }
a68ab351 20990
acf0174b
JJ
20991 pop_stmt_list (stmt);
20992 pop_scope ();
20993 if (cfun->language != NULL)
20994 {
20995 ggc_free (cfun->language);
20996 cfun->language = NULL;
20997 }
20998 set_cfun (NULL);
20999 current_function_decl = NULL_TREE;
21000 if (nested)
21001 c_pop_function_context ();
a68ab351 21002
acf0174b
JJ
21003 if (!clauses.is_empty ())
21004 {
21005 parser->tokens = &parser->tokens_buf[0];
21006 parser->tokens_avail = tokens_avail;
21007 }
21008 if (bad)
21009 goto fail;
21010 if (errs != errorcount)
21011 break;
21012 }
a68ab351 21013
acf0174b
JJ
21014 clauses.release ();
21015 types.release ();
a68ab351
JJ
21016}
21017
953ff289 21018
acf0174b
JJ
21019/* OpenMP 4.0
21020 #pragma omp declare simd declare-simd-clauses[optseq] new-line
21021 #pragma omp declare reduction (reduction-id : typename-list : expression) \
21022 initializer-clause[opt] new-line
94e7f906
JJ
21023 #pragma omp declare target new-line
21024
21025 OpenMP 5.0
21026 #pragma omp declare variant (identifier) match (context-selector) */
20906c66
JJ
21027
21028static void
acf0174b 21029c_parser_omp_declare (c_parser *parser, enum pragma_context context)
20906c66 21030{
20906c66 21031 c_parser_consume_pragma (parser);
acf0174b
JJ
21032 if (c_parser_next_token_is (parser, CPP_NAME))
21033 {
21034 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21035 if (strcmp (p, "simd") == 0)
21036 {
21037 /* c_parser_consume_token (parser); done in
21038 c_parser_omp_declare_simd. */
21039 c_parser_omp_declare_simd (parser, context);
21040 return;
21041 }
21042 if (strcmp (p, "reduction") == 0)
21043 {
21044 c_parser_consume_token (parser);
21045 c_parser_omp_declare_reduction (parser, context);
21046 return;
21047 }
6d7f7e0a
TB
21048 if (!flag_openmp) /* flag_openmp_simd */
21049 {
62021f64 21050 c_parser_skip_to_pragma_eol (parser, false);
6d7f7e0a
TB
21051 return;
21052 }
acf0174b
JJ
21053 if (strcmp (p, "target") == 0)
21054 {
21055 c_parser_consume_token (parser);
21056 c_parser_omp_declare_target (parser);
21057 return;
21058 }
94e7f906
JJ
21059 if (strcmp (p, "variant") == 0)
21060 {
21061 /* c_parser_consume_token (parser); done in
21062 c_parser_omp_declare_simd. */
21063 c_parser_omp_declare_simd (parser, context);
21064 return;
21065 }
acf0174b 21066 }
20906c66 21067
94e7f906
JJ
21068 c_parser_error (parser, "expected %<simd%>, %<reduction%>, "
21069 "%<target%> or %<variant%>");
acf0174b 21070 c_parser_skip_to_pragma_eol (parser);
20906c66
JJ
21071}
21072
28567c40
JJ
21073/* OpenMP 5.0
21074 #pragma omp requires clauses[optseq] new-line */
21075
21076static void
21077c_parser_omp_requires (c_parser *parser)
21078{
21079 bool first = true;
21080 enum omp_requires new_req = (enum omp_requires) 0;
21081
21082 c_parser_consume_pragma (parser);
21083
21084 location_t loc = c_parser_peek_token (parser)->location;
21085 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
21086 {
21087 if (!first && c_parser_next_token_is (parser, CPP_COMMA))
21088 c_parser_consume_token (parser);
21089
21090 first = false;
21091
21092 if (c_parser_next_token_is (parser, CPP_NAME))
21093 {
21094 const char *p
21095 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21096 location_t cloc = c_parser_peek_token (parser)->location;
21097 enum omp_requires this_req = (enum omp_requires) 0;
21098
21099 if (!strcmp (p, "unified_address"))
21100 this_req = OMP_REQUIRES_UNIFIED_ADDRESS;
21101 else if (!strcmp (p, "unified_shared_memory"))
21102 this_req = OMP_REQUIRES_UNIFIED_SHARED_MEMORY;
21103 else if (!strcmp (p, "dynamic_allocators"))
21104 this_req = OMP_REQUIRES_DYNAMIC_ALLOCATORS;
21105 else if (!strcmp (p, "reverse_offload"))
21106 this_req = OMP_REQUIRES_REVERSE_OFFLOAD;
21107 else if (!strcmp (p, "atomic_default_mem_order"))
21108 {
21109 c_parser_consume_token (parser);
21110
21111 matching_parens parens;
21112 if (parens.require_open (parser))
21113 {
21114 if (c_parser_next_token_is (parser, CPP_NAME))
21115 {
21116 tree v = c_parser_peek_token (parser)->value;
21117 p = IDENTIFIER_POINTER (v);
21118
21119 if (!strcmp (p, "seq_cst"))
21120 this_req
21121 = (enum omp_requires) OMP_MEMORY_ORDER_SEQ_CST;
21122 else if (!strcmp (p, "relaxed"))
21123 this_req
21124 = (enum omp_requires) OMP_MEMORY_ORDER_RELAXED;
21125 else if (!strcmp (p, "acq_rel"))
21126 this_req
21127 = (enum omp_requires) OMP_MEMORY_ORDER_ACQ_REL;
21128 }
21129 if (this_req == 0)
21130 {
21131 error_at (c_parser_peek_token (parser)->location,
21132 "expected %<seq_cst%>, %<relaxed%> or "
21133 "%<acq_rel%>");
21134 if (c_parser_peek_2nd_token (parser)->type
21135 == CPP_CLOSE_PAREN)
21136 c_parser_consume_token (parser);
21137 }
21138 else
21139 c_parser_consume_token (parser);
21140
21141 parens.skip_until_found_close (parser);
21142 if (this_req == 0)
21143 {
21144 c_parser_skip_to_pragma_eol (parser, false);
21145 return;
21146 }
21147 }
21148 p = NULL;
21149 }
21150 else
21151 {
21152 error_at (cloc, "expected %<unified_address%>, "
21153 "%<unified_shared_memory%>, "
21154 "%<dynamic_allocators%>, "
21155 "%<reverse_offload%> "
21156 "or %<atomic_default_mem_order%> clause");
21157 c_parser_skip_to_pragma_eol (parser, false);
21158 return;
21159 }
3179ebae
JJ
21160 if (p)
21161 sorry_at (cloc, "%qs clause on %<requires%> directive not "
21162 "supported yet", p);
28567c40
JJ
21163 if (p)
21164 c_parser_consume_token (parser);
21165 if (this_req)
21166 {
21167 if ((this_req & ~OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
21168 {
21169 if ((this_req & new_req) != 0)
21170 error_at (cloc, "too many %qs clauses", p);
21171 if (this_req != OMP_REQUIRES_DYNAMIC_ALLOCATORS
21172 && (omp_requires_mask & OMP_REQUIRES_TARGET_USED) != 0)
21173 error_at (cloc, "%qs clause used lexically after first "
21174 "target construct or offloading API", p);
21175 }
21176 else if ((new_req & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
21177 {
21178 error_at (cloc, "too many %qs clauses",
21179 "atomic_default_mem_order");
21180 this_req = (enum omp_requires) 0;
21181 }
21182 else if ((omp_requires_mask
21183 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
21184 {
21185 error_at (cloc, "more than one %<atomic_default_mem_order%>"
21186 " clause in a single compilation unit");
21187 this_req
21188 = (enum omp_requires)
21189 (omp_requires_mask
21190 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER);
21191 }
21192 else if ((omp_requires_mask
21193 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED) != 0)
21194 error_at (cloc, "%<atomic_default_mem_order%> clause used "
21195 "lexically after first %<atomic%> construct "
21196 "without memory order clause");
21197 new_req = (enum omp_requires) (new_req | this_req);
21198 omp_requires_mask
21199 = (enum omp_requires) (omp_requires_mask | this_req);
21200 continue;
21201 }
21202 }
21203 break;
21204 }
21205 c_parser_skip_to_pragma_eol (parser);
21206
21207 if (new_req == 0)
21208 error_at (loc, "%<pragma omp requires%> requires at least one clause");
21209}
21210
21211/* Helper function for c_parser_omp_taskloop.
21212 Disallow zero sized or potentially zero sized task reductions. */
21213
21214static tree
21215c_finish_taskloop_clauses (tree clauses)
21216{
21217 tree *pc = &clauses;
21218 for (tree c = clauses; c; c = *pc)
21219 {
21220 bool remove = false;
21221 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
21222 {
21223 tree type = strip_array_types (TREE_TYPE (OMP_CLAUSE_DECL (c)));
21224 if (integer_zerop (TYPE_SIZE_UNIT (type)))
21225 {
21226 error_at (OMP_CLAUSE_LOCATION (c),
21227 "zero sized type %qT in %<reduction%> clause", type);
21228 remove = true;
21229 }
21230 else if (TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST)
21231 {
21232 error_at (OMP_CLAUSE_LOCATION (c),
21233 "variable sized type %qT in %<reduction%> clause",
21234 type);
21235 remove = true;
21236 }
21237 }
21238 if (remove)
21239 *pc = OMP_CLAUSE_CHAIN (c);
21240 else
21241 pc = &OMP_CLAUSE_CHAIN (c);
21242 }
21243 return clauses;
21244}
21245
d9a6bd32
JJ
21246/* OpenMP 4.5:
21247 #pragma omp taskloop taskloop-clause[optseq] new-line
21248 for-loop
21249
21250 #pragma omp taskloop simd taskloop-simd-clause[optseq] new-line
21251 for-loop */
21252
21253#define OMP_TASKLOOP_CLAUSE_MASK \
21254 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
21255 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
21256 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
21257 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
21258 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
21259 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_GRAINSIZE) \
21260 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TASKS) \
21261 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
21262 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
21263 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
21264 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
21265 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
21266 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP) \
28567c40
JJ
21267 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
21268 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
21269 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION))
d9a6bd32
JJ
21270
21271static tree
21272c_parser_omp_taskloop (location_t loc, c_parser *parser,
dda1bf61
JJ
21273 char *p_name, omp_clause_mask mask, tree *cclauses,
21274 bool *if_p)
d9a6bd32
JJ
21275{
21276 tree clauses, block, ret;
21277
21278 strcat (p_name, " taskloop");
21279 mask |= OMP_TASKLOOP_CLAUSE_MASK;
28567c40
JJ
21280 /* #pragma omp parallel master taskloop{, simd} disallow in_reduction
21281 clause. */
21282 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0)
21283 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION);
d9a6bd32
JJ
21284
21285 if (c_parser_next_token_is (parser, CPP_NAME))
21286 {
21287 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21288
21289 if (strcmp (p, "simd") == 0)
21290 {
21291 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
21292 if (cclauses == NULL)
21293 cclauses = cclauses_buf;
d9a6bd32
JJ
21294 c_parser_consume_token (parser);
21295 if (!flag_openmp) /* flag_openmp_simd */
dda1bf61
JJ
21296 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
21297 if_p);
d9a6bd32 21298 block = c_begin_compound_stmt (true);
dda1bf61 21299 ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses, if_p);
d9a6bd32
JJ
21300 block = c_end_compound_stmt (loc, block, true);
21301 if (ret == NULL)
21302 return ret;
21303 ret = make_node (OMP_TASKLOOP);
21304 TREE_TYPE (ret) = void_type_node;
21305 OMP_FOR_BODY (ret) = block;
21306 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
28567c40
JJ
21307 OMP_FOR_CLAUSES (ret)
21308 = c_finish_taskloop_clauses (OMP_FOR_CLAUSES (ret));
d9a6bd32
JJ
21309 SET_EXPR_LOCATION (ret, loc);
21310 add_stmt (ret);
21311 return ret;
21312 }
21313 }
21314 if (!flag_openmp) /* flag_openmp_simd */
21315 {
21316 c_parser_skip_to_pragma_eol (parser, false);
21317 return NULL_TREE;
21318 }
21319
21320 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
21321 if (cclauses)
21322 {
21323 omp_split_clauses (loc, OMP_TASKLOOP, mask, clauses, cclauses);
21324 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
21325 }
21326
28567c40 21327 clauses = c_finish_taskloop_clauses (clauses);
d9a6bd32 21328 block = c_begin_compound_stmt (true);
dda1bf61 21329 ret = c_parser_omp_for_loop (loc, parser, OMP_TASKLOOP, clauses, NULL, if_p);
d9a6bd32
JJ
21330 block = c_end_compound_stmt (loc, block, true);
21331 add_stmt (block);
21332
21333 return ret;
21334}
21335
953ff289
DN
21336/* Main entry point to parsing most OpenMP pragmas. */
21337
21338static void
dda1bf61 21339c_parser_omp_construct (c_parser *parser, bool *if_p)
953ff289
DN
21340{
21341 enum pragma_kind p_kind;
21342 location_t loc;
21343 tree stmt;
acf0174b
JJ
21344 char p_name[sizeof "#pragma omp teams distribute parallel for simd"];
21345 omp_clause_mask mask (0);
953ff289
DN
21346
21347 loc = c_parser_peek_token (parser)->location;
21348 p_kind = c_parser_peek_token (parser)->pragma_kind;
21349 c_parser_consume_pragma (parser);
21350
21351 switch (p_kind)
21352 {
4bf9e5a8
TS
21353 case PRAGMA_OACC_ATOMIC:
21354 c_parser_omp_atomic (loc, parser);
21355 return;
41dbbb37
TS
21356 case PRAGMA_OACC_CACHE:
21357 strcpy (p_name, "#pragma acc");
21358 stmt = c_parser_oacc_cache (loc, parser);
21359 break;
21360 case PRAGMA_OACC_DATA:
dda1bf61 21361 stmt = c_parser_oacc_data (loc, parser, if_p);
41dbbb37 21362 break;
37d5ad46 21363 case PRAGMA_OACC_HOST_DATA:
dda1bf61 21364 stmt = c_parser_oacc_host_data (loc, parser, if_p);
37d5ad46 21365 break;
41dbbb37 21366 case PRAGMA_OACC_KERNELS:
88bae6f4 21367 case PRAGMA_OACC_PARALLEL:
62aee289 21368 case PRAGMA_OACC_SERIAL:
41dbbb37 21369 strcpy (p_name, "#pragma acc");
62aee289 21370 stmt = c_parser_oacc_compute (loc, parser, p_kind, p_name, if_p);
41dbbb37
TS
21371 break;
21372 case PRAGMA_OACC_LOOP:
21373 strcpy (p_name, "#pragma acc");
dda1bf61 21374 stmt = c_parser_oacc_loop (loc, parser, p_name, mask, NULL, if_p);
41dbbb37
TS
21375 break;
21376 case PRAGMA_OACC_WAIT:
21377 strcpy (p_name, "#pragma wait");
21378 stmt = c_parser_oacc_wait (loc, parser, p_name);
21379 break;
953ff289 21380 case PRAGMA_OMP_ATOMIC:
c2255bc4 21381 c_parser_omp_atomic (loc, parser);
953ff289
DN
21382 return;
21383 case PRAGMA_OMP_CRITICAL:
dda1bf61 21384 stmt = c_parser_omp_critical (loc, parser, if_p);
953ff289 21385 break;
acf0174b
JJ
21386 case PRAGMA_OMP_DISTRIBUTE:
21387 strcpy (p_name, "#pragma omp");
dda1bf61 21388 stmt = c_parser_omp_distribute (loc, parser, p_name, mask, NULL, if_p);
acf0174b 21389 break;
953ff289 21390 case PRAGMA_OMP_FOR:
acf0174b 21391 strcpy (p_name, "#pragma omp");
dda1bf61 21392 stmt = c_parser_omp_for (loc, parser, p_name, mask, NULL, if_p);
953ff289 21393 break;
554a530f
JJ
21394 case PRAGMA_OMP_LOOP:
21395 strcpy (p_name, "#pragma omp");
21396 stmt = c_parser_omp_loop (loc, parser, p_name, mask, NULL, if_p);
21397 break;
953ff289 21398 case PRAGMA_OMP_MASTER:
28567c40
JJ
21399 strcpy (p_name, "#pragma omp");
21400 stmt = c_parser_omp_master (loc, parser, p_name, mask, NULL, if_p);
953ff289 21401 break;
953ff289 21402 case PRAGMA_OMP_PARALLEL:
acf0174b 21403 strcpy (p_name, "#pragma omp");
dda1bf61 21404 stmt = c_parser_omp_parallel (loc, parser, p_name, mask, NULL, if_p);
953ff289
DN
21405 break;
21406 case PRAGMA_OMP_SECTIONS:
acf0174b
JJ
21407 strcpy (p_name, "#pragma omp");
21408 stmt = c_parser_omp_sections (loc, parser, p_name, mask, NULL);
21409 break;
21410 case PRAGMA_OMP_SIMD:
21411 strcpy (p_name, "#pragma omp");
dda1bf61 21412 stmt = c_parser_omp_simd (loc, parser, p_name, mask, NULL, if_p);
953ff289
DN
21413 break;
21414 case PRAGMA_OMP_SINGLE:
dda1bf61 21415 stmt = c_parser_omp_single (loc, parser, if_p);
953ff289 21416 break;
a68ab351 21417 case PRAGMA_OMP_TASK:
dda1bf61 21418 stmt = c_parser_omp_task (loc, parser, if_p);
a68ab351 21419 break;
acf0174b 21420 case PRAGMA_OMP_TASKGROUP:
28567c40 21421 stmt = c_parser_omp_taskgroup (loc, parser, if_p);
acf0174b 21422 break;
d9a6bd32
JJ
21423 case PRAGMA_OMP_TASKLOOP:
21424 strcpy (p_name, "#pragma omp");
dda1bf61 21425 stmt = c_parser_omp_taskloop (loc, parser, p_name, mask, NULL, if_p);
d9a6bd32 21426 break;
acf0174b
JJ
21427 case PRAGMA_OMP_TEAMS:
21428 strcpy (p_name, "#pragma omp");
dda1bf61 21429 stmt = c_parser_omp_teams (loc, parser, p_name, mask, NULL, if_p);
acf0174b 21430 break;
953ff289
DN
21431 default:
21432 gcc_unreachable ();
21433 }
21434
21435 if (stmt)
c2255bc4 21436 gcc_assert (EXPR_LOCATION (stmt) != UNKNOWN_LOCATION);
953ff289
DN
21437}
21438
21439
21440/* OpenMP 2.5:
21441 # pragma omp threadprivate (variable-list) */
21442
21443static void
21444c_parser_omp_threadprivate (c_parser *parser)
21445{
21446 tree vars, t;
c2255bc4 21447 location_t loc;
953ff289
DN
21448
21449 c_parser_consume_pragma (parser);
c2255bc4 21450 loc = c_parser_peek_token (parser)->location;
d75d71e0 21451 vars = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
953ff289 21452
953ff289
DN
21453 /* Mark every variable in VARS to be assigned thread local storage. */
21454 for (t = vars; t; t = TREE_CHAIN (t))
21455 {
21456 tree v = TREE_PURPOSE (t);
21457
c2255bc4
AH
21458 /* FIXME diagnostics: Ideally we should keep individual
21459 locations for all the variables in the var list to make the
21460 following errors more precise. Perhaps
21461 c_parser_omp_var_list_parens() should construct a list of
21462 locations to go along with the var list. */
21463
953ff289
DN
21464 /* If V had already been marked threadprivate, it doesn't matter
21465 whether it had been used prior to this point. */
0ae9bd27 21466 if (!VAR_P (v))
c2255bc4 21467 error_at (loc, "%qD is not a variable", v);
5df27e4a 21468 else if (TREE_USED (v) && !C_DECL_THREADPRIVATE_P (v))
c2255bc4 21469 error_at (loc, "%qE declared %<threadprivate%> after first use", v);
62f9079a 21470 else if (! is_global_var (v))
c2255bc4 21471 error_at (loc, "automatic variable %qE cannot be %<threadprivate%>", v);
5df27e4a
JJ
21472 else if (TREE_TYPE (v) == error_mark_node)
21473 ;
953ff289 21474 else if (! COMPLETE_TYPE_P (TREE_TYPE (v)))
c2255bc4 21475 error_at (loc, "%<threadprivate%> %qE has incomplete type", v);
953ff289
DN
21476 else
21477 {
21478 if (! DECL_THREAD_LOCAL_P (v))
21479 {
56363ffd 21480 set_decl_tls_model (v, decl_default_tls_model (v));
953ff289
DN
21481 /* If rtl has been already set for this var, call
21482 make_decl_rtl once again, so that encode_section_info
21483 has a chance to look at the new decl flags. */
21484 if (DECL_RTL_SET_P (v))
21485 make_decl_rtl (v);
21486 }
21487 C_DECL_THREADPRIVATE_P (v) = 1;
21488 }
21489 }
21490
21491 c_parser_skip_to_pragma_eol (parser);
21492}
9a771876 21493
0a35513e
AH
21494/* Parse a transaction attribute (GCC Extension).
21495
21496 transaction-attribute:
783bfe5e 21497 gnu-attributes
c01bd174
JM
21498 attribute-specifier
21499*/
0a35513e
AH
21500
21501static tree
21502c_parser_transaction_attributes (c_parser *parser)
21503{
0a35513e 21504 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
783bfe5e 21505 return c_parser_gnu_attributes (parser);
0a35513e
AH
21506
21507 if (!c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
21508 return NULL_TREE;
c01bd174 21509 return c_parser_std_attribute_specifier (parser, true);
0a35513e
AH
21510}
21511
21512/* Parse a __transaction_atomic or __transaction_relaxed statement
21513 (GCC Extension).
21514
21515 transaction-statement:
21516 __transaction_atomic transaction-attribute[opt] compound-statement
21517 __transaction_relaxed compound-statement
21518
21519 Note that the only valid attribute is: "outer".
21520*/
21521
21522static tree
21523c_parser_transaction (c_parser *parser, enum rid keyword)
21524{
21525 unsigned int old_in = parser->in_transaction;
21526 unsigned int this_in = 1, new_in;
21527 location_t loc = c_parser_peek_token (parser)->location;
21528 tree stmt, attrs;
21529
21530 gcc_assert ((keyword == RID_TRANSACTION_ATOMIC
21531 || keyword == RID_TRANSACTION_RELAXED)
21532 && c_parser_next_token_is_keyword (parser, keyword));
21533 c_parser_consume_token (parser);
21534
21535 if (keyword == RID_TRANSACTION_RELAXED)
21536 this_in |= TM_STMT_ATTR_RELAXED;
21537 else
21538 {
21539 attrs = c_parser_transaction_attributes (parser);
21540 if (attrs)
21541 this_in |= parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER);
21542 }
21543
21544 /* Keep track if we're in the lexical scope of an outer transaction. */
21545 new_in = this_in | (old_in & TM_STMT_ATTR_OUTER);
21546
21547 parser->in_transaction = new_in;
21548 stmt = c_parser_compound_statement (parser);
21549 parser->in_transaction = old_in;
21550
21551 if (flag_tm)
21552 stmt = c_finish_transaction (loc, stmt, this_in);
21553 else
21554 error_at (loc, (keyword == RID_TRANSACTION_ATOMIC ?
21555 "%<__transaction_atomic%> without transactional memory support enabled"
21556 : "%<__transaction_relaxed %> "
21557 "without transactional memory support enabled"));
21558
21559 return stmt;
21560}
21561
21562/* Parse a __transaction_atomic or __transaction_relaxed expression
21563 (GCC Extension).
21564
21565 transaction-expression:
21566 __transaction_atomic ( expression )
21567 __transaction_relaxed ( expression )
21568*/
21569
21570static struct c_expr
21571c_parser_transaction_expression (c_parser *parser, enum rid keyword)
21572{
21573 struct c_expr ret;
21574 unsigned int old_in = parser->in_transaction;
21575 unsigned int this_in = 1;
21576 location_t loc = c_parser_peek_token (parser)->location;
21577 tree attrs;
21578
21579 gcc_assert ((keyword == RID_TRANSACTION_ATOMIC
21580 || keyword == RID_TRANSACTION_RELAXED)
21581 && c_parser_next_token_is_keyword (parser, keyword));
21582 c_parser_consume_token (parser);
21583
21584 if (keyword == RID_TRANSACTION_RELAXED)
21585 this_in |= TM_STMT_ATTR_RELAXED;
21586 else
21587 {
21588 attrs = c_parser_transaction_attributes (parser);
21589 if (attrs)
21590 this_in |= parse_tm_stmt_attr (attrs, 0);
21591 }
21592
21593 parser->in_transaction = this_in;
32129a17
DM
21594 matching_parens parens;
21595 if (parens.require_open (parser))
0a35513e
AH
21596 {
21597 tree expr = c_parser_expression (parser).value;
21598 ret.original_type = TREE_TYPE (expr);
21599 ret.value = build1 (TRANSACTION_EXPR, ret.original_type, expr);
21600 if (this_in & TM_STMT_ATTR_RELAXED)
21601 TRANSACTION_EXPR_RELAXED (ret.value) = 1;
21602 SET_EXPR_LOCATION (ret.value, loc);
21603 ret.original_code = TRANSACTION_EXPR;
32129a17 21604 if (!parens.require_close (parser))
69b76518
TR
21605 {
21606 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
21607 goto error;
21608 }
0a35513e
AH
21609 }
21610 else
21611 {
69b76518 21612 error:
913884f7 21613 ret.set_error ();
0a35513e
AH
21614 ret.original_code = ERROR_MARK;
21615 ret.original_type = NULL;
21616 }
21617 parser->in_transaction = old_in;
21618
21619 if (!flag_tm)
21620 error_at (loc, (keyword == RID_TRANSACTION_ATOMIC ?
21621 "%<__transaction_atomic%> without transactional memory support enabled"
21622 : "%<__transaction_relaxed %> "
21623 "without transactional memory support enabled"));
21624
bef08b71
DM
21625 set_c_expr_source_range (&ret, loc, loc);
21626
0a35513e
AH
21627 return ret;
21628}
21629
21630/* Parse a __transaction_cancel statement (GCC Extension).
21631
21632 transaction-cancel-statement:
21633 __transaction_cancel transaction-attribute[opt] ;
21634
21635 Note that the only valid attribute is "outer".
21636*/
21637
21638static tree
acf0174b 21639c_parser_transaction_cancel (c_parser *parser)
0a35513e
AH
21640{
21641 location_t loc = c_parser_peek_token (parser)->location;
21642 tree attrs;
21643 bool is_outer = false;
21644
21645 gcc_assert (c_parser_next_token_is_keyword (parser, RID_TRANSACTION_CANCEL));
21646 c_parser_consume_token (parser);
21647
21648 attrs = c_parser_transaction_attributes (parser);
21649 if (attrs)
21650 is_outer = (parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER) != 0);
21651
21652 if (!flag_tm)
21653 {
21654 error_at (loc, "%<__transaction_cancel%> without "
21655 "transactional memory support enabled");
21656 goto ret_error;
21657 }
21658 else if (parser->in_transaction & TM_STMT_ATTR_RELAXED)
21659 {
21660 error_at (loc, "%<__transaction_cancel%> within a "
21661 "%<__transaction_relaxed%>");
21662 goto ret_error;
21663 }
21664 else if (is_outer)
21665 {
21666 if ((parser->in_transaction & TM_STMT_ATTR_OUTER) == 0
21667 && !is_tm_may_cancel_outer (current_function_decl))
21668 {
21669 error_at (loc, "outer %<__transaction_cancel%> not "
a9c697b8
MS
21670 "within outer %<__transaction_atomic%> or "
21671 "a %<transaction_may_cancel_outer%> function");
0a35513e
AH
21672 goto ret_error;
21673 }
21674 }
21675 else if (parser->in_transaction == 0)
21676 {
21677 error_at (loc, "%<__transaction_cancel%> not within "
21678 "%<__transaction_atomic%>");
21679 goto ret_error;
21680 }
21681
21682 return add_stmt (build_tm_abort_call (loc, is_outer));
21683
21684 ret_error:
21685 return build1 (NOP_EXPR, void_type_node, error_mark_node);
21686}
bc4071dd 21687\f
27bf414c
JM
21688/* Parse a single source file. */
21689
21690void
21691c_parse_file (void)
21692{
bc4071dd
RH
21693 /* Use local storage to begin. If the first token is a pragma, parse it.
21694 If it is #pragma GCC pch_preprocess, then this will load a PCH file
21695 which will cause garbage collection. */
21696 c_parser tparser;
21697
21698 memset (&tparser, 0, sizeof tparser);
471c5330 21699 tparser.translate_strings_p = true;
acf0174b 21700 tparser.tokens = &tparser.tokens_buf[0];
bc4071dd
RH
21701 the_parser = &tparser;
21702
21703 if (c_parser_peek_token (&tparser)->pragma_kind == PRAGMA_GCC_PCH_PREPROCESS)
21704 c_parser_pragma_pch_preprocess (&tparser);
22f8849d
IS
21705 else
21706 c_common_no_more_pch ();
bc4071dd 21707
766090c2 21708 the_parser = ggc_alloc<c_parser> ();
bc4071dd 21709 *the_parser = tparser;
acf0174b
JJ
21710 if (tparser.tokens == &tparser.tokens_buf[0])
21711 the_parser->tokens = &the_parser->tokens_buf[0];
bc4071dd 21712
f9417da1
RG
21713 /* Initialize EH, if we've been told to do so. */
21714 if (flag_exceptions)
1d65f45c 21715 using_eh_for_cleanups ();
f9417da1 21716
27bf414c
JM
21717 c_parser_translation_unit (the_parser);
21718 the_parser = NULL;
21719}
21720
c2e84327
DM
21721/* Parse the body of a function declaration marked with "__RTL".
21722
21723 The RTL parser works on the level of characters read from a
21724 FILE *, whereas c_parser works at the level of tokens.
21725 Square this circle by consuming all of the tokens up to and
21726 including the closing brace, recording the start/end of the RTL
21727 fragment, and reopening the file and re-reading the relevant
21728 lines within the RTL parser.
21729
21730 This requires the opening and closing braces of the C function
21731 to be on separate lines from the RTL they wrap.
21732
21733 Take ownership of START_WITH_PASS, if non-NULL. */
21734
9def91e9 21735location_t
c2e84327
DM
21736c_parser_parse_rtl_body (c_parser *parser, char *start_with_pass)
21737{
21738 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
21739 {
21740 free (start_with_pass);
9def91e9 21741 return c_parser_peek_token (parser)->location;
c2e84327
DM
21742 }
21743
21744 location_t start_loc = c_parser_peek_token (parser)->location;
21745
21746 /* Consume all tokens, up to the closing brace, handling
21747 matching pairs of braces in the rtl dump. */
21748 int num_open_braces = 1;
21749 while (1)
21750 {
21751 switch (c_parser_peek_token (parser)->type)
21752 {
21753 case CPP_OPEN_BRACE:
21754 num_open_braces++;
21755 break;
21756 case CPP_CLOSE_BRACE:
21757 if (--num_open_braces == 0)
21758 goto found_closing_brace;
21759 break;
21760 case CPP_EOF:
21761 error_at (start_loc, "no closing brace");
21762 free (start_with_pass);
9def91e9 21763 return c_parser_peek_token (parser)->location;
c2e84327
DM
21764 default:
21765 break;
21766 }
21767 c_parser_consume_token (parser);
21768 }
21769
21770 found_closing_brace:
21771 /* At the closing brace; record its location. */
21772 location_t end_loc = c_parser_peek_token (parser)->location;
21773
21774 /* Consume the closing brace. */
21775 c_parser_consume_token (parser);
21776
21777 /* Invoke the RTL parser. */
21778 if (!read_rtl_function_body_from_file_range (start_loc, end_loc))
21779 {
21780 free (start_with_pass);
9def91e9 21781 return end_loc;
c2e84327
DM
21782 }
21783
20a38017
MM
21784 /* Run the backend on the cfun created above, transferring ownership of
21785 START_WITH_PASS. */
21786 run_rtl_passes (start_with_pass);
9def91e9 21787 return end_loc;
c2e84327
DM
21788}
21789
d4a10d0a 21790#include "gt-c-c-parser.h"