1 /* Parser for C and Objective-C.
2 Copyright (C) 1987-2022 Free Software Foundation, Inc.
3
4 Parser actions based on the old Bison parser; structure somewhat
5 influenced by and fragments based on the C++ parser.
6
7 This file is part of GCC.
8
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
12 version.
13
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
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"
39 #define INCLUDE_MEMORY
40 #include "system.h"
41 #include "coretypes.h"
42 #include "target.h"
43 #include "function.h"
44 #include "c-tree.h"
45 #include "timevar.h"
46 #include "stringpool.h"
47 #include "cgraph.h"
48 #include "attribs.h"
49 #include "stor-layout.h"
50 #include "varasm.h"
51 #include "trans-mem.h"
52 #include "c-family/c-pragma.h"
53 #include "c-lang.h"
54 #include "c-family/c-objc.h"
55 #include "plugin.h"
56 #include "omp-general.h"
57 #include "omp-offload.h"
58 #include "builtins.h"
59 #include "gomp-constants.h"
60 #include "c-family/c-indentation.h"
61 #include "gimple-expr.h"
62 #include "context.h"
63 #include "gcc-rich-location.h"
64 #include "c-parser.h"
65 #include "gimple-parser.h"
66 #include "read-rtl-function.h"
67 #include "run-rtl-passes.h"
68 #include "intl.h"
69 #include "c-family/name-hint.h"
70 #include "tree-iterator.h"
71 #include "tree-pretty-print.h"
72 #include "memmodel.h"
73 #include "c-family/known-headers.h"
74
75 /* We need to walk over decls with incomplete struct/union/enum types
76 after parsing the whole translation unit.
77 In finish_decl(), if the decl is static, has incomplete
78 struct/union/enum type, it is appended to incomplete_record_decls.
79 In c_parser_translation_unit(), we iterate over incomplete_record_decls
80 and report error if any of the decls are still incomplete. */
81
82 vec<tree> incomplete_record_decls;
83
84 void
set_c_expr_source_range(c_expr * expr,location_t start,location_t finish)85 set_c_expr_source_range (c_expr *expr,
86 location_t start, location_t finish)
87 {
88 expr->src_range.m_start = start;
89 expr->src_range.m_finish = finish;
90 if (expr->value)
91 set_source_range (expr->value, start, finish);
92 }
93
94 void
set_c_expr_source_range(c_expr * expr,source_range src_range)95 set_c_expr_source_range (c_expr *expr,
96 source_range src_range)
97 {
98 expr->src_range = src_range;
99 if (expr->value)
100 set_source_range (expr->value, src_range);
101 }
102
103
104 /* Initialization routine for this file. */
105
106 void
c_parse_init(void)107 c_parse_init (void)
108 {
109 /* The only initialization required is of the reserved word
110 identifiers. */
111 unsigned int i;
112 tree id;
113 int mask = 0;
114
115 /* Make sure RID_MAX hasn't grown past the 8 bits used to hold the keyword in
116 the c_token structure. */
117 gcc_assert (RID_MAX <= 255);
118
119 mask |= D_CXXONLY;
120 if (!flag_isoc99)
121 mask |= D_C99;
122 if (flag_no_asm)
123 {
124 mask |= D_ASM | D_EXT;
125 if (!flag_isoc99)
126 mask |= D_EXT89;
127 }
128 if (!c_dialect_objc ())
129 mask |= D_OBJC | D_CXX_OBJC;
130
131 ridpointers = ggc_cleared_vec_alloc<tree> ((int) RID_MAX);
132 for (i = 0; i < num_c_common_reswords; i++)
133 {
134 /* If a keyword is disabled, do not enter it into the table
135 and so create a canonical spelling that isn't a keyword. */
136 if (c_common_reswords[i].disable & mask)
137 {
138 if (warn_cxx_compat
139 && (c_common_reswords[i].disable & D_CXXWARN))
140 {
141 id = get_identifier (c_common_reswords[i].word);
142 C_SET_RID_CODE (id, RID_CXX_COMPAT_WARN);
143 C_IS_RESERVED_WORD (id) = 1;
144 }
145 continue;
146 }
147
148 id = get_identifier (c_common_reswords[i].word);
149 C_SET_RID_CODE (id, c_common_reswords[i].rid);
150 C_IS_RESERVED_WORD (id) = 1;
151 ridpointers [(int) c_common_reswords[i].rid] = id;
152 }
153
154 for (i = 0; i < NUM_INT_N_ENTS; i++)
155 {
156 /* We always create the symbols but they aren't always supported. */
157 char name[50];
158 sprintf (name, "__int%d", int_n_data[i].bitsize);
159 id = get_identifier (name);
160 C_SET_RID_CODE (id, RID_FIRST_INT_N + i);
161 C_IS_RESERVED_WORD (id) = 1;
162
163 sprintf (name, "__int%d__", int_n_data[i].bitsize);
164 id = get_identifier (name);
165 C_SET_RID_CODE (id, RID_FIRST_INT_N + i);
166 C_IS_RESERVED_WORD (id) = 1;
167 }
168 }
169
170 /* A parser structure recording information about the state and
171 context of parsing. Includes lexer information with up to two
172 tokens of look-ahead; more are not needed for C. */
173 struct GTY(()) c_parser {
174 /* The look-ahead tokens. */
175 c_token * GTY((skip)) tokens;
176 /* Buffer for look-ahead tokens. */
177 c_token tokens_buf[4];
178 /* How many look-ahead tokens are available (0 - 4, or
179 more if parsing from pre-lexed tokens). */
180 unsigned int tokens_avail;
181 /* Raw look-ahead tokens, used only for checking in Objective-C
182 whether '[[' starts attributes. */
183 vec<c_token, va_gc> *raw_tokens;
184 /* The number of raw look-ahead tokens that have since been fully
185 lexed. */
186 unsigned int raw_tokens_used;
187 /* True if a syntax error is being recovered from; false otherwise.
188 c_parser_error sets this flag. It should clear this flag when
189 enough tokens have been consumed to recover from the error. */
190 BOOL_BITFIELD error : 1;
191 /* True if we're processing a pragma, and shouldn't automatically
192 consume CPP_PRAGMA_EOL. */
193 BOOL_BITFIELD in_pragma : 1;
194 /* True if we're parsing the outermost block of an if statement. */
195 BOOL_BITFIELD in_if_block : 1;
196 /* True if we want to lex a translated, joined string (for an
197 initial #pragma pch_preprocess). Otherwise the parser is
198 responsible for concatenating strings and translating to the
199 execution character set as needed. */
200 BOOL_BITFIELD lex_joined_string : 1;
201 /* True if, when the parser is concatenating string literals, it
202 should translate them to the execution character set (false
203 inside attributes). */
204 BOOL_BITFIELD translate_strings_p : 1;
205
206 /* Objective-C specific parser/lexer information. */
207
208 /* True if we are in a context where the Objective-C "PQ" keywords
209 are considered keywords. */
210 BOOL_BITFIELD objc_pq_context : 1;
211 /* True if we are parsing a (potential) Objective-C foreach
212 statement. This is set to true after we parsed 'for (' and while
213 we wait for 'in' or ';' to decide if it's a standard C for loop or an
214 Objective-C foreach loop. */
215 BOOL_BITFIELD objc_could_be_foreach_context : 1;
216 /* The following flag is needed to contextualize Objective-C lexical
217 analysis. In some cases (e.g., 'int NSObject;'), it is
218 undesirable to bind an identifier to an Objective-C class, even
219 if a class with that name exists. */
220 BOOL_BITFIELD objc_need_raw_identifier : 1;
221 /* Nonzero if we're processing a __transaction statement. The value
222 is 1 | TM_STMT_ATTR_*. */
223 unsigned int in_transaction : 4;
224 /* True if we are in a context where the Objective-C "Property attribute"
225 keywords are valid. */
226 BOOL_BITFIELD objc_property_attr_context : 1;
227
228 /* Whether we have just seen/constructed a string-literal. Set when
229 returning a string-literal from c_parser_string_literal. Reset
230 in consume_token. Useful when we get a parse error and see an
231 unknown token, which could have been a string-literal constant
232 macro. */
233 BOOL_BITFIELD seen_string_literal : 1;
234
235 /* Location of the last consumed token. */
236 location_t last_token_location;
237 };
238
239 /* Return a pointer to the Nth token in PARSERs tokens_buf. */
240
241 c_token *
c_parser_tokens_buf(c_parser * parser,unsigned n)242 c_parser_tokens_buf (c_parser *parser, unsigned n)
243 {
244 return &parser->tokens_buf[n];
245 }
246
247 /* Return the error state of PARSER. */
248
249 bool
c_parser_error(c_parser * parser)250 c_parser_error (c_parser *parser)
251 {
252 return parser->error;
253 }
254
255 /* Set the error state of PARSER to ERR. */
256
257 void
c_parser_set_error(c_parser * parser,bool err)258 c_parser_set_error (c_parser *parser, bool err)
259 {
260 parser->error = err;
261 }
262
263
264 /* The actual parser and external interface. ??? Does this need to be
265 garbage-collected? */
266
267 static GTY (()) c_parser *the_parser;
268
269 /* Read in and lex a single token, storing it in *TOKEN. If RAW,
270 context-sensitive postprocessing of the token is not done. */
271
272 static void
c_lex_one_token(c_parser * parser,c_token * token,bool raw=false)273 c_lex_one_token (c_parser *parser, c_token *token, bool raw = false)
274 {
275 timevar_push (TV_LEX);
276
277 if (raw || vec_safe_length (parser->raw_tokens) == 0)
278 {
279 token->type = c_lex_with_flags (&token->value, &token->location,
280 &token->flags,
281 (parser->lex_joined_string
282 ? 0 : C_LEX_STRING_NO_JOIN));
283 token->id_kind = C_ID_NONE;
284 token->keyword = RID_MAX;
285 token->pragma_kind = PRAGMA_NONE;
286 }
287 else
288 {
289 /* Use a token previously lexed as a raw look-ahead token, and
290 complete the processing on it. */
291 *token = (*parser->raw_tokens)[parser->raw_tokens_used];
292 ++parser->raw_tokens_used;
293 if (parser->raw_tokens_used == vec_safe_length (parser->raw_tokens))
294 {
295 vec_free (parser->raw_tokens);
296 parser->raw_tokens_used = 0;
297 }
298 }
299
300 if (raw)
301 goto out;
302
303 switch (token->type)
304 {
305 case CPP_NAME:
306 {
307 tree decl;
308
309 bool objc_force_identifier = parser->objc_need_raw_identifier;
310 if (c_dialect_objc ())
311 parser->objc_need_raw_identifier = false;
312
313 if (C_IS_RESERVED_WORD (token->value))
314 {
315 enum rid rid_code = C_RID_CODE (token->value);
316
317 if (rid_code == RID_CXX_COMPAT_WARN)
318 {
319 warning_at (token->location,
320 OPT_Wc___compat,
321 "identifier %qE conflicts with C++ keyword",
322 token->value);
323 }
324 else if (rid_code >= RID_FIRST_ADDR_SPACE
325 && rid_code <= RID_LAST_ADDR_SPACE)
326 {
327 addr_space_t as;
328 as = (addr_space_t) (rid_code - RID_FIRST_ADDR_SPACE);
329 targetm.addr_space.diagnose_usage (as, token->location);
330 token->id_kind = C_ID_ADDRSPACE;
331 token->keyword = rid_code;
332 break;
333 }
334 else if (c_dialect_objc () && OBJC_IS_PQ_KEYWORD (rid_code))
335 {
336 /* We found an Objective-C "pq" keyword (in, out,
337 inout, bycopy, byref, oneway). They need special
338 care because the interpretation depends on the
339 context. */
340 if (parser->objc_pq_context)
341 {
342 token->type = CPP_KEYWORD;
343 token->keyword = rid_code;
344 break;
345 }
346 else if (parser->objc_could_be_foreach_context
347 && rid_code == RID_IN)
348 {
349 /* We are in Objective-C, inside a (potential)
350 foreach context (which means after having
351 parsed 'for (', but before having parsed ';'),
352 and we found 'in'. We consider it the keyword
353 which terminates the declaration at the
354 beginning of a foreach-statement. Note that
355 this means you can't use 'in' for anything else
356 in that context; in particular, in Objective-C
357 you can't use 'in' as the name of the running
358 variable in a C for loop. We could potentially
359 try to add code here to disambiguate, but it
360 seems a reasonable limitation. */
361 token->type = CPP_KEYWORD;
362 token->keyword = rid_code;
363 break;
364 }
365 /* Else, "pq" keywords outside of the "pq" context are
366 not keywords, and we fall through to the code for
367 normal tokens. */
368 }
369 else if (c_dialect_objc () && OBJC_IS_PATTR_KEYWORD (rid_code))
370 {
371 /* We found an Objective-C "property attribute"
372 keyword (getter, setter, readonly, etc). These are
373 only valid in the property context. */
374 if (parser->objc_property_attr_context)
375 {
376 token->type = CPP_KEYWORD;
377 token->keyword = rid_code;
378 break;
379 }
380 /* Else they are not special keywords.
381 */
382 }
383 else if (c_dialect_objc ()
384 && (OBJC_IS_AT_KEYWORD (rid_code)
385 || OBJC_IS_CXX_KEYWORD (rid_code)))
386 {
387 /* We found one of the Objective-C "@" keywords (defs,
388 selector, synchronized, etc) or one of the
389 Objective-C "cxx" keywords (class, private,
390 protected, public, try, catch, throw) without a
391 preceding '@' sign. Do nothing and fall through to
392 the code for normal tokens (in C++ we would still
393 consider the CXX ones keywords, but not in C). */
394 ;
395 }
396 else
397 {
398 token->type = CPP_KEYWORD;
399 token->keyword = rid_code;
400 break;
401 }
402 }
403
404 decl = lookup_name (token->value);
405 if (decl)
406 {
407 if (TREE_CODE (decl) == TYPE_DECL)
408 {
409 token->id_kind = C_ID_TYPENAME;
410 break;
411 }
412 }
413 else if (c_dialect_objc ())
414 {
415 tree objc_interface_decl = objc_is_class_name (token->value);
416 /* Objective-C class names are in the same namespace as
417 variables and typedefs, and hence are shadowed by local
418 declarations. */
419 if (objc_interface_decl
420 && (!objc_force_identifier || global_bindings_p ()))
421 {
422 token->value = objc_interface_decl;
423 token->id_kind = C_ID_CLASSNAME;
424 break;
425 }
426 }
427 token->id_kind = C_ID_ID;
428 }
429 break;
430 case CPP_AT_NAME:
431 /* This only happens in Objective-C; it must be a keyword. */
432 token->type = CPP_KEYWORD;
433 switch (C_RID_CODE (token->value))
434 {
435 /* Replace 'class' with '@class', 'private' with '@private',
436 etc. This prevents confusion with the C++ keyword
437 'class', and makes the tokens consistent with other
438 Objective-C 'AT' keywords. For example '@class' is
439 reported as RID_AT_CLASS which is consistent with
440 '@synchronized', which is reported as
441 RID_AT_SYNCHRONIZED.
442 */
443 case RID_CLASS: token->keyword = RID_AT_CLASS; break;
444 case RID_PRIVATE: token->keyword = RID_AT_PRIVATE; break;
445 case RID_PROTECTED: token->keyword = RID_AT_PROTECTED; break;
446 case RID_PUBLIC: token->keyword = RID_AT_PUBLIC; break;
447 case RID_THROW: token->keyword = RID_AT_THROW; break;
448 case RID_TRY: token->keyword = RID_AT_TRY; break;
449 case RID_CATCH: token->keyword = RID_AT_CATCH; break;
450 case RID_SYNCHRONIZED: token->keyword = RID_AT_SYNCHRONIZED; break;
451 default: token->keyword = C_RID_CODE (token->value);
452 }
453 break;
454 case CPP_COLON:
455 case CPP_COMMA:
456 case CPP_CLOSE_PAREN:
457 case CPP_SEMICOLON:
458 /* These tokens may affect the interpretation of any identifiers
459 following, if doing Objective-C. */
460 if (c_dialect_objc ())
461 parser->objc_need_raw_identifier = false;
462 break;
463 case CPP_PRAGMA:
464 /* We smuggled the cpp_token->u.pragma value in an INTEGER_CST. */
465 token->pragma_kind = (enum pragma_kind) TREE_INT_CST_LOW (token->value);
466 token->value = NULL;
467 break;
468 default:
469 break;
470 }
471 out:
472 timevar_pop (TV_LEX);
473 }
474
475 /* Return a pointer to the next token from PARSER, reading it in if
476 necessary. */
477
478 c_token *
c_parser_peek_token(c_parser * parser)479 c_parser_peek_token (c_parser *parser)
480 {
481 if (parser->tokens_avail == 0)
482 {
483 c_lex_one_token (parser, &parser->tokens[0]);
484 parser->tokens_avail = 1;
485 }
486 return &parser->tokens[0];
487 }
488
489 /* Return a pointer to the next-but-one token from PARSER, reading it
490 in if necessary. The next token is already read in. */
491
492 c_token *
c_parser_peek_2nd_token(c_parser * parser)493 c_parser_peek_2nd_token (c_parser *parser)
494 {
495 if (parser->tokens_avail >= 2)
496 return &parser->tokens[1];
497 gcc_assert (parser->tokens_avail == 1);
498 gcc_assert (parser->tokens[0].type != CPP_EOF);
499 gcc_assert (parser->tokens[0].type != CPP_PRAGMA_EOL);
500 c_lex_one_token (parser, &parser->tokens[1]);
501 parser->tokens_avail = 2;
502 return &parser->tokens[1];
503 }
504
505 /* Return a pointer to the Nth token from PARSER, reading it
506 in if necessary. The N-1th token is already read in. */
507
508 c_token *
c_parser_peek_nth_token(c_parser * parser,unsigned int n)509 c_parser_peek_nth_token (c_parser *parser, unsigned int n)
510 {
511 /* N is 1-based, not zero-based. */
512 gcc_assert (n > 0);
513
514 if (parser->tokens_avail >= n)
515 return &parser->tokens[n - 1];
516 gcc_assert (parser->tokens_avail == n - 1);
517 c_lex_one_token (parser, &parser->tokens[n - 1]);
518 parser->tokens_avail = n;
519 return &parser->tokens[n - 1];
520 }
521
522 /* Return a pointer to the Nth token from PARSER, reading it in as a
523 raw look-ahead token if necessary. The N-1th token is already read
524 in. Raw look-ahead tokens remain available for when the non-raw
525 functions above are called. */
526
527 c_token *
c_parser_peek_nth_token_raw(c_parser * parser,unsigned int n)528 c_parser_peek_nth_token_raw (c_parser *parser, unsigned int n)
529 {
530 /* N is 1-based, not zero-based. */
531 gcc_assert (n > 0);
532
533 if (parser->tokens_avail >= n)
534 return &parser->tokens[n - 1];
535 unsigned int raw_len = vec_safe_length (parser->raw_tokens);
536 unsigned int raw_avail
537 = parser->tokens_avail + raw_len - parser->raw_tokens_used;
538 gcc_assert (raw_avail >= n - 1);
539 if (raw_avail >= n)
540 return &(*parser->raw_tokens)[parser->raw_tokens_used
541 + n - 1 - parser->tokens_avail];
542 vec_safe_reserve (parser->raw_tokens, 1);
543 parser->raw_tokens->quick_grow (raw_len + 1);
544 c_lex_one_token (parser, &(*parser->raw_tokens)[raw_len], true);
545 return &(*parser->raw_tokens)[raw_len];
546 }
547
548 bool
c_keyword_starts_typename(enum rid keyword)549 c_keyword_starts_typename (enum rid keyword)
550 {
551 switch (keyword)
552 {
553 case RID_UNSIGNED:
554 case RID_LONG:
555 case RID_SHORT:
556 case RID_SIGNED:
557 case RID_COMPLEX:
558 case RID_INT:
559 case RID_CHAR:
560 case RID_FLOAT:
561 case RID_DOUBLE:
562 case RID_VOID:
563 case RID_DFLOAT32:
564 case RID_DFLOAT64:
565 case RID_DFLOAT128:
566 CASE_RID_FLOATN_NX:
567 case RID_BOOL:
568 case RID_ENUM:
569 case RID_STRUCT:
570 case RID_UNION:
571 case RID_TYPEOF:
572 case RID_CONST:
573 case RID_ATOMIC:
574 case RID_VOLATILE:
575 case RID_RESTRICT:
576 case RID_ATTRIBUTE:
577 case RID_FRACT:
578 case RID_ACCUM:
579 case RID_SAT:
580 case RID_AUTO_TYPE:
581 case RID_ALIGNAS:
582 return true;
583 default:
584 if (keyword >= RID_FIRST_INT_N
585 && keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS
586 && int_n_enabled_p[keyword - RID_FIRST_INT_N])
587 return true;
588 return false;
589 }
590 }
591
592 /* Return true if TOKEN can start a type name,
593 false otherwise. */
594 bool
c_token_starts_typename(c_token * token)595 c_token_starts_typename (c_token *token)
596 {
597 switch (token->type)
598 {
599 case CPP_NAME:
600 switch (token->id_kind)
601 {
602 case C_ID_ID:
603 return false;
604 case C_ID_ADDRSPACE:
605 return true;
606 case C_ID_TYPENAME:
607 return true;
608 case C_ID_CLASSNAME:
609 gcc_assert (c_dialect_objc ());
610 return true;
611 default:
612 gcc_unreachable ();
613 }
614 case CPP_KEYWORD:
615 return c_keyword_starts_typename (token->keyword);
616 case CPP_LESS:
617 if (c_dialect_objc ())
618 return true;
619 return false;
620 default:
621 return false;
622 }
623 }
624
625 /* Return true if the next token from PARSER can start a type name,
626 false otherwise. LA specifies how to do lookahead in order to
627 detect unknown type names. If unsure, pick CLA_PREFER_ID. */
628
629 static inline bool
c_parser_next_tokens_start_typename(c_parser * parser,enum c_lookahead_kind la)630 c_parser_next_tokens_start_typename (c_parser *parser, enum c_lookahead_kind la)
631 {
632 c_token *token = c_parser_peek_token (parser);
633 if (c_token_starts_typename (token))
634 return true;
635
636 /* Try a bit harder to detect an unknown typename. */
637 if (la != cla_prefer_id
638 && token->type == CPP_NAME
639 && token->id_kind == C_ID_ID
640
641 /* Do not try too hard when we could have "object in array". */
642 && !parser->objc_could_be_foreach_context
643
644 && (la == cla_prefer_type
645 || c_parser_peek_2nd_token (parser)->type == CPP_NAME
646 || c_parser_peek_2nd_token (parser)->type == CPP_MULT)
647
648 /* Only unknown identifiers. */
649 && !lookup_name (token->value))
650 return true;
651
652 return false;
653 }
654
655 /* Return true if TOKEN is a type qualifier, false otherwise. */
656 static bool
c_token_is_qualifier(c_token * token)657 c_token_is_qualifier (c_token *token)
658 {
659 switch (token->type)
660 {
661 case CPP_NAME:
662 switch (token->id_kind)
663 {
664 case C_ID_ADDRSPACE:
665 return true;
666 default:
667 return false;
668 }
669 case CPP_KEYWORD:
670 switch (token->keyword)
671 {
672 case RID_CONST:
673 case RID_VOLATILE:
674 case RID_RESTRICT:
675 case RID_ATTRIBUTE:
676 case RID_ATOMIC:
677 return true;
678 default:
679 return false;
680 }
681 case CPP_LESS:
682 return false;
683 default:
684 gcc_unreachable ();
685 }
686 }
687
688 /* Return true if the next token from PARSER is a type qualifier,
689 false otherwise. */
690 static inline bool
c_parser_next_token_is_qualifier(c_parser * parser)691 c_parser_next_token_is_qualifier (c_parser *parser)
692 {
693 c_token *token = c_parser_peek_token (parser);
694 return c_token_is_qualifier (token);
695 }
696
697 /* Return true if TOKEN can start declaration specifiers (not
698 including standard attributes), false otherwise. */
699 static bool
c_token_starts_declspecs(c_token * token)700 c_token_starts_declspecs (c_token *token)
701 {
702 switch (token->type)
703 {
704 case CPP_NAME:
705 switch (token->id_kind)
706 {
707 case C_ID_ID:
708 return false;
709 case C_ID_ADDRSPACE:
710 return true;
711 case C_ID_TYPENAME:
712 return true;
713 case C_ID_CLASSNAME:
714 gcc_assert (c_dialect_objc ());
715 return true;
716 default:
717 gcc_unreachable ();
718 }
719 case CPP_KEYWORD:
720 switch (token->keyword)
721 {
722 case RID_STATIC:
723 case RID_EXTERN:
724 case RID_REGISTER:
725 case RID_TYPEDEF:
726 case RID_INLINE:
727 case RID_NORETURN:
728 case RID_AUTO:
729 case RID_THREAD:
730 case RID_UNSIGNED:
731 case RID_LONG:
732 case RID_SHORT:
733 case RID_SIGNED:
734 case RID_COMPLEX:
735 case RID_INT:
736 case RID_CHAR:
737 case RID_FLOAT:
738 case RID_DOUBLE:
739 case RID_VOID:
740 case RID_DFLOAT32:
741 case RID_DFLOAT64:
742 case RID_DFLOAT128:
743 CASE_RID_FLOATN_NX:
744 case RID_BOOL:
745 case RID_ENUM:
746 case RID_STRUCT:
747 case RID_UNION:
748 case RID_TYPEOF:
749 case RID_CONST:
750 case RID_VOLATILE:
751 case RID_RESTRICT:
752 case RID_ATTRIBUTE:
753 case RID_FRACT:
754 case RID_ACCUM:
755 case RID_SAT:
756 case RID_ALIGNAS:
757 case RID_ATOMIC:
758 case RID_AUTO_TYPE:
759 return true;
760 default:
761 if (token->keyword >= RID_FIRST_INT_N
762 && token->keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS
763 && int_n_enabled_p[token->keyword - RID_FIRST_INT_N])
764 return true;
765 return false;
766 }
767 case CPP_LESS:
768 if (c_dialect_objc ())
769 return true;
770 return false;
771 default:
772 return false;
773 }
774 }
775
776
777 /* Return true if TOKEN can start declaration specifiers (not
778 including standard attributes) or a static assertion, false
779 otherwise. */
780 static bool
c_token_starts_declaration(c_token * token)781 c_token_starts_declaration (c_token *token)
782 {
783 if (c_token_starts_declspecs (token)
784 || token->keyword == RID_STATIC_ASSERT)
785 return true;
786 else
787 return false;
788 }
789
790 /* Return true if the next token from PARSER can start declaration
791 specifiers (not including standard attributes), false
792 otherwise. */
793 bool
c_parser_next_token_starts_declspecs(c_parser * parser)794 c_parser_next_token_starts_declspecs (c_parser *parser)
795 {
796 c_token *token = c_parser_peek_token (parser);
797
798 /* In Objective-C, a classname normally starts a declspecs unless it
799 is immediately followed by a dot. In that case, it is the
800 Objective-C 2.0 "dot-syntax" for class objects, ie, calls the
801 setter/getter on the class. c_token_starts_declspecs() can't
802 differentiate between the two cases because it only checks the
803 current token, so we have a special check here. */
804 if (c_dialect_objc ()
805 && token->type == CPP_NAME
806 && token->id_kind == C_ID_CLASSNAME
807 && c_parser_peek_2nd_token (parser)->type == CPP_DOT)
808 return false;
809
810 return c_token_starts_declspecs (token);
811 }
812
813 /* Return true if the next tokens from PARSER can start declaration
814 specifiers (not including standard attributes) or a static
815 assertion, false otherwise. */
816 bool
c_parser_next_tokens_start_declaration(c_parser * parser)817 c_parser_next_tokens_start_declaration (c_parser *parser)
818 {
819 c_token *token = c_parser_peek_token (parser);
820
821 /* Same as above. */
822 if (c_dialect_objc ()
823 && token->type == CPP_NAME
824 && token->id_kind == C_ID_CLASSNAME
825 && c_parser_peek_2nd_token (parser)->type == CPP_DOT)
826 return false;
827
828 /* Labels do not start declarations. */
829 if (token->type == CPP_NAME
830 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
831 return false;
832
833 if (c_token_starts_declaration (token))
834 return true;
835
836 if (c_parser_next_tokens_start_typename (parser, cla_nonabstract_decl))
837 return true;
838
839 return false;
840 }
841
842 /* Consume the next token from PARSER. */
843
844 void
c_parser_consume_token(c_parser * parser)845 c_parser_consume_token (c_parser *parser)
846 {
847 gcc_assert (parser->tokens_avail >= 1);
848 gcc_assert (parser->tokens[0].type != CPP_EOF);
849 gcc_assert (!parser->in_pragma || parser->tokens[0].type != CPP_PRAGMA_EOL);
850 gcc_assert (parser->error || parser->tokens[0].type != CPP_PRAGMA);
851 parser->last_token_location = parser->tokens[0].location;
852 if (parser->tokens != &parser->tokens_buf[0])
853 parser->tokens++;
854 else if (parser->tokens_avail >= 2)
855 {
856 parser->tokens[0] = parser->tokens[1];
857 if (parser->tokens_avail >= 3)
858 {
859 parser->tokens[1] = parser->tokens[2];
860 if (parser->tokens_avail >= 4)
861 parser->tokens[2] = parser->tokens[3];
862 }
863 }
864 parser->tokens_avail--;
865 parser->seen_string_literal = false;
866 }
867
868 /* Expect the current token to be a #pragma. Consume it and remember
869 that we've begun parsing a pragma. */
870
871 static void
c_parser_consume_pragma(c_parser * parser)872 c_parser_consume_pragma (c_parser *parser)
873 {
874 gcc_assert (!parser->in_pragma);
875 gcc_assert (parser->tokens_avail >= 1);
876 gcc_assert (parser->tokens[0].type == CPP_PRAGMA);
877 if (parser->tokens != &parser->tokens_buf[0])
878 parser->tokens++;
879 else if (parser->tokens_avail >= 2)
880 {
881 parser->tokens[0] = parser->tokens[1];
882 if (parser->tokens_avail >= 3)
883 parser->tokens[1] = parser->tokens[2];
884 }
885 parser->tokens_avail--;
886 parser->in_pragma = true;
887 }
888
889 /* Update the global input_location from TOKEN. */
890 static inline void
c_parser_set_source_position_from_token(c_token * token)891 c_parser_set_source_position_from_token (c_token *token)
892 {
893 if (token->type != CPP_EOF)
894 {
895 input_location = token->location;
896 }
897 }
898
899 /* Helper function for c_parser_error.
900 Having peeked a token of kind TOK1_KIND that might signify
901 a conflict marker, peek successor tokens to determine
902 if we actually do have a conflict marker.
903 Specifically, we consider a run of 7 '<', '=' or '>' characters
904 at the start of a line as a conflict marker.
905 These come through the lexer as three pairs and a single,
906 e.g. three CPP_LSHIFT ("<<") and a CPP_LESS ('<').
907 If it returns true, *OUT_LOC is written to with the location/range
908 of the marker. */
909
910 static bool
c_parser_peek_conflict_marker(c_parser * parser,enum cpp_ttype tok1_kind,location_t * out_loc)911 c_parser_peek_conflict_marker (c_parser *parser, enum cpp_ttype tok1_kind,
912 location_t *out_loc)
913 {
914 c_token *token2 = c_parser_peek_2nd_token (parser);
915 if (token2->type != tok1_kind)
916 return false;
917 c_token *token3 = c_parser_peek_nth_token (parser, 3);
918 if (token3->type != tok1_kind)
919 return false;
920 c_token *token4 = c_parser_peek_nth_token (parser, 4);
921 if (token4->type != conflict_marker_get_final_tok_kind (tok1_kind))
922 return false;
923
924 /* It must be at the start of the line. */
925 location_t start_loc = c_parser_peek_token (parser)->location;
926 if (LOCATION_COLUMN (start_loc) != 1)
927 return false;
928
929 /* We have a conflict marker. Construct a location of the form:
930 <<<<<<<
931 ^~~~~~~
932 with start == caret, finishing at the end of the marker. */
933 location_t finish_loc = get_finish (token4->location);
934 *out_loc = make_location (start_loc, start_loc, finish_loc);
935
936 return true;
937 }
938
939 /* Issue a diagnostic of the form
940 FILE:LINE: MESSAGE before TOKEN
941 where TOKEN is the next token in the input stream of PARSER.
942 MESSAGE (specified by the caller) is usually of the form "expected
943 OTHER-TOKEN".
944
945 Use RICHLOC as the location of the diagnostic.
946
947 Do not issue a diagnostic if still recovering from an error.
948
949 Return true iff an error was actually emitted.
950
951 ??? This is taken from the C++ parser, but building up messages in
952 this way is not i18n-friendly and some other approach should be
953 used. */
954
955 static bool
c_parser_error_richloc(c_parser * parser,const char * gmsgid,rich_location * richloc)956 c_parser_error_richloc (c_parser *parser, const char *gmsgid,
957 rich_location *richloc)
958 {
959 c_token *token = c_parser_peek_token (parser);
960 if (parser->error)
961 return false;
962 parser->error = true;
963 if (!gmsgid)
964 return false;
965
966 /* If this is actually a conflict marker, report it as such. */
967 if (token->type == CPP_LSHIFT
968 || token->type == CPP_RSHIFT
969 || token->type == CPP_EQ_EQ)
970 {
971 location_t loc;
972 if (c_parser_peek_conflict_marker (parser, token->type, &loc))
973 {
974 error_at (loc, "version control conflict marker in file");
975 return true;
976 }
977 }
978
979 /* If we were parsing a string-literal and there is an unknown name
980 token right after, then check to see if that could also have been
981 a literal string by checking the name against a list of known
982 standard string literal constants defined in header files. If
983 there is one, then add that as an hint to the error message. */
984 auto_diagnostic_group d;
985 name_hint h;
986 if (parser->seen_string_literal && token->type == CPP_NAME)
987 {
988 tree name = token->value;
989 const char *token_name = IDENTIFIER_POINTER (name);
990 const char *header_hint
991 = get_c_stdlib_header_for_string_macro_name (token_name);
992 if (header_hint != NULL)
993 h = name_hint (NULL, new suggest_missing_header (token->location,
994 token_name,
995 header_hint));
996 }
997
998 c_parse_error (gmsgid,
999 /* Because c_parse_error does not understand
1000 CPP_KEYWORD, keywords are treated like
1001 identifiers. */
1002 (token->type == CPP_KEYWORD ? CPP_NAME : token->type),
1003 /* ??? The C parser does not save the cpp flags of a
1004 token, we need to pass 0 here and we will not get
1005 the source spelling of some tokens but rather the
1006 canonical spelling. */
1007 token->value, /*flags=*/0, richloc);
1008 return true;
1009 }
1010
1011 /* As c_parser_error_richloc, but issue the message at the
1012 location of PARSER's next token, or at input_location
1013 if the next token is EOF. */
1014
1015 bool
c_parser_error(c_parser * parser,const char * gmsgid)1016 c_parser_error (c_parser *parser, const char *gmsgid)
1017 {
1018 c_token *token = c_parser_peek_token (parser);
1019 c_parser_set_source_position_from_token (token);
1020 rich_location richloc (line_table, input_location);
1021 return c_parser_error_richloc (parser, gmsgid, &richloc);
1022 }
1023
1024 /* Some tokens naturally come in pairs e.g.'(' and ')'.
1025 This class is for tracking such a matching pair of symbols.
1026 In particular, it tracks the location of the first token,
1027 so that if the second token is missing, we can highlight the
1028 location of the first token when notifying the user about the
1029 problem. */
1030
1031 template <typename traits_t>
1032 class token_pair
1033 {
1034 public:
1035 /* token_pair's ctor. */
token_pair()1036 token_pair () : m_open_loc (UNKNOWN_LOCATION) {}
1037
1038 /* If the next token is the opening symbol for this pair, consume it and
1039 return true.
1040 Otherwise, issue an error and return false.
1041 In either case, record the location of the opening token. */
1042
require_open(c_parser * parser)1043 bool require_open (c_parser *parser)
1044 {
1045 c_token *token = c_parser_peek_token (parser);
1046 if (token)
1047 m_open_loc = token->location;
1048
1049 return c_parser_require (parser, traits_t::open_token_type,
1050 traits_t::open_gmsgid);
1051 }
1052
1053 /* Consume the next token from PARSER, recording its location as
1054 that of the opening token within the pair. */
1055
consume_open(c_parser * parser)1056 void consume_open (c_parser *parser)
1057 {
1058 c_token *token = c_parser_peek_token (parser);
1059 gcc_assert (token->type == traits_t::open_token_type);
1060 m_open_loc = token->location;
1061 c_parser_consume_token (parser);
1062 }
1063
1064 /* If the next token is the closing symbol for this pair, consume it
1065 and return true.
1066 Otherwise, issue an error, highlighting the location of the
1067 corresponding opening token, and return false. */
1068
require_close(c_parser * parser) const1069 bool require_close (c_parser *parser) const
1070 {
1071 return c_parser_require (parser, traits_t::close_token_type,
1072 traits_t::close_gmsgid, m_open_loc);
1073 }
1074
1075 /* Like token_pair::require_close, except that tokens will be skipped
1076 until the desired token is found. An error message is still produced
1077 if the next token is not as expected. */
1078
skip_until_found_close(c_parser * parser) const1079 void skip_until_found_close (c_parser *parser) const
1080 {
1081 c_parser_skip_until_found (parser, traits_t::close_token_type,
1082 traits_t::close_gmsgid, m_open_loc);
1083 }
1084
1085 private:
1086 location_t m_open_loc;
1087 };
1088
1089 /* Traits for token_pair<T> for tracking matching pairs of parentheses. */
1090
1091 struct matching_paren_traits
1092 {
1093 static const enum cpp_ttype open_token_type = CPP_OPEN_PAREN;
1094 static const char * const open_gmsgid;
1095 static const enum cpp_ttype close_token_type = CPP_CLOSE_PAREN;
1096 static const char * const close_gmsgid;
1097 };
1098
1099 const char * const matching_paren_traits::open_gmsgid = "expected %<(%>";
1100 const char * const matching_paren_traits::close_gmsgid = "expected %<)%>";
1101
1102 /* "matching_parens" is a token_pair<T> class for tracking matching
1103 pairs of parentheses. */
1104
1105 typedef token_pair<matching_paren_traits> matching_parens;
1106
1107 /* Traits for token_pair<T> for tracking matching pairs of braces. */
1108
1109 struct matching_brace_traits
1110 {
1111 static const enum cpp_ttype open_token_type = CPP_OPEN_BRACE;
1112 static const char * const open_gmsgid;
1113 static const enum cpp_ttype close_token_type = CPP_CLOSE_BRACE;
1114 static const char * const close_gmsgid;
1115 };
1116
1117 const char * const matching_brace_traits::open_gmsgid = "expected %<{%>";
1118 const char * const matching_brace_traits::close_gmsgid = "expected %<}%>";
1119
1120 /* "matching_braces" is a token_pair<T> class for tracking matching
1121 pairs of braces. */
1122
1123 typedef token_pair<matching_brace_traits> matching_braces;
1124
1125 /* Get a description of the matching symbol to TYPE e.g. "(" for
1126 CPP_CLOSE_PAREN. */
1127
1128 static const char *
get_matching_symbol(enum cpp_ttype type)1129 get_matching_symbol (enum cpp_ttype type)
1130 {
1131 switch (type)
1132 {
1133 default:
1134 gcc_unreachable ();
1135 case CPP_CLOSE_PAREN:
1136 return "(";
1137 case CPP_CLOSE_BRACE:
1138 return "{";
1139 }
1140 }
1141
1142 /* If the next token is of the indicated TYPE, consume it. Otherwise,
1143 issue the error MSGID. If MSGID is NULL then a message has already
1144 been produced and no message will be produced this time. Returns
1145 true if found, false otherwise.
1146
1147 If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1148 within any error as the location of an "opening" token matching
1149 the close token TYPE (e.g. the location of the '(' when TYPE is
1150 CPP_CLOSE_PAREN).
1151
1152 If TYPE_IS_UNIQUE is true (the default) then msgid describes exactly
1153 one type (e.g. "expected %<)%>") and thus it may be reasonable to
1154 attempt to generate a fix-it hint for the problem.
1155 Otherwise msgid describes multiple token types (e.g.
1156 "expected %<;%>, %<,%> or %<)%>"), and thus we shouldn't attempt to
1157 generate a fix-it hint. */
1158
1159 bool
c_parser_require(c_parser * parser,enum cpp_ttype type,const char * msgid,location_t matching_location,bool type_is_unique)1160 c_parser_require (c_parser *parser,
1161 enum cpp_ttype type,
1162 const char *msgid,
1163 location_t matching_location,
1164 bool type_is_unique)
1165 {
1166 if (c_parser_next_token_is (parser, type))
1167 {
1168 c_parser_consume_token (parser);
1169 return true;
1170 }
1171 else
1172 {
1173 location_t next_token_loc = c_parser_peek_token (parser)->location;
1174 gcc_rich_location richloc (next_token_loc);
1175
1176 /* Potentially supply a fix-it hint, suggesting to add the
1177 missing token immediately after the *previous* token.
1178 This may move the primary location within richloc. */
1179 if (!parser->error && type_is_unique)
1180 maybe_suggest_missing_token_insertion (&richloc, type,
1181 parser->last_token_location);
1182
1183 /* If matching_location != UNKNOWN_LOCATION, highlight it.
1184 Attempt to consolidate diagnostics by printing it as a
1185 secondary range within the main diagnostic. */
1186 bool added_matching_location = false;
1187 if (matching_location != UNKNOWN_LOCATION)
1188 added_matching_location
1189 = richloc.add_location_if_nearby (matching_location);
1190
1191 if (c_parser_error_richloc (parser, msgid, &richloc))
1192 /* If we weren't able to consolidate matching_location, then
1193 print it as a secondary diagnostic. */
1194 if (matching_location != UNKNOWN_LOCATION && !added_matching_location)
1195 inform (matching_location, "to match this %qs",
1196 get_matching_symbol (type));
1197
1198 return false;
1199 }
1200 }
1201
1202 /* If the next token is the indicated keyword, consume it. Otherwise,
1203 issue the error MSGID. Returns true if found, false otherwise. */
1204
1205 static bool
c_parser_require_keyword(c_parser * parser,enum rid keyword,const char * msgid)1206 c_parser_require_keyword (c_parser *parser,
1207 enum rid keyword,
1208 const char *msgid)
1209 {
1210 if (c_parser_next_token_is_keyword (parser, keyword))
1211 {
1212 c_parser_consume_token (parser);
1213 return true;
1214 }
1215 else
1216 {
1217 c_parser_error (parser, msgid);
1218 return false;
1219 }
1220 }
1221
1222 /* Like c_parser_require, except that tokens will be skipped until the
1223 desired token is found. An error message is still produced if the
1224 next token is not as expected. If MSGID is NULL then a message has
1225 already been produced and no message will be produced this
1226 time.
1227
1228 If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1229 within any error as the location of an "opening" token matching
1230 the close token TYPE (e.g. the location of the '(' when TYPE is
1231 CPP_CLOSE_PAREN). */
1232
1233 void
c_parser_skip_until_found(c_parser * parser,enum cpp_ttype type,const char * msgid,location_t matching_location)1234 c_parser_skip_until_found (c_parser *parser,
1235 enum cpp_ttype type,
1236 const char *msgid,
1237 location_t matching_location)
1238 {
1239 unsigned nesting_depth = 0;
1240
1241 if (c_parser_require (parser, type, msgid, matching_location))
1242 return;
1243
1244 /* Skip tokens until the desired token is found. */
1245 while (true)
1246 {
1247 /* Peek at the next token. */
1248 c_token *token = c_parser_peek_token (parser);
1249 /* If we've reached the token we want, consume it and stop. */
1250 if (token->type == type && !nesting_depth)
1251 {
1252 c_parser_consume_token (parser);
1253 break;
1254 }
1255
1256 /* If we've run out of tokens, stop. */
1257 if (token->type == CPP_EOF)
1258 return;
1259 if (token->type == CPP_PRAGMA_EOL && parser->in_pragma)
1260 return;
1261 if (token->type == CPP_OPEN_BRACE
1262 || token->type == CPP_OPEN_PAREN
1263 || token->type == CPP_OPEN_SQUARE)
1264 ++nesting_depth;
1265 else if (token->type == CPP_CLOSE_BRACE
1266 || token->type == CPP_CLOSE_PAREN
1267 || token->type == CPP_CLOSE_SQUARE)
1268 {
1269 if (nesting_depth-- == 0)
1270 break;
1271 }
1272 /* Consume this token. */
1273 c_parser_consume_token (parser);
1274 }
1275 parser->error = false;
1276 }
1277
1278 /* Skip tokens until the end of a parameter is found, but do not
1279 consume the comma, semicolon or closing delimiter. */
1280
1281 static void
c_parser_skip_to_end_of_parameter(c_parser * parser)1282 c_parser_skip_to_end_of_parameter (c_parser *parser)
1283 {
1284 unsigned nesting_depth = 0;
1285
1286 while (true)
1287 {
1288 c_token *token = c_parser_peek_token (parser);
1289 if ((token->type == CPP_COMMA || token->type == CPP_SEMICOLON)
1290 && !nesting_depth)
1291 break;
1292 /* If we've run out of tokens, stop. */
1293 if (token->type == CPP_EOF)
1294 return;
1295 if (token->type == CPP_PRAGMA_EOL && parser->in_pragma)
1296 return;
1297 if (token->type == CPP_OPEN_BRACE
1298 || token->type == CPP_OPEN_PAREN
1299 || token->type == CPP_OPEN_SQUARE)
1300 ++nesting_depth;
1301 else if (token->type == CPP_CLOSE_BRACE
1302 || token->type == CPP_CLOSE_PAREN
1303 || token->type == CPP_CLOSE_SQUARE)
1304 {
1305 if (nesting_depth-- == 0)
1306 break;
1307 }
1308 /* Consume this token. */
1309 c_parser_consume_token (parser);
1310 }
1311 parser->error = false;
1312 }
1313
1314 /* Expect to be at the end of the pragma directive and consume an
1315 end of line marker. */
1316
1317 static void
c_parser_skip_to_pragma_eol(c_parser * parser,bool error_if_not_eol=true)1318 c_parser_skip_to_pragma_eol (c_parser *parser, bool error_if_not_eol = true)
1319 {
1320 gcc_assert (parser->in_pragma);
1321 parser->in_pragma = false;
1322
1323 if (error_if_not_eol && c_parser_peek_token (parser)->type != CPP_PRAGMA_EOL)
1324 c_parser_error (parser, "expected end of line");
1325
1326 cpp_ttype token_type;
1327 do
1328 {
1329 c_token *token = c_parser_peek_token (parser);
1330 token_type = token->type;
1331 if (token_type == CPP_EOF)
1332 break;
1333 c_parser_consume_token (parser);
1334 }
1335 while (token_type != CPP_PRAGMA_EOL);
1336
1337 parser->error = false;
1338 }
1339
1340 /* Skip tokens until we have consumed an entire block, or until we
1341 have consumed a non-nested ';'. */
1342
1343 static void
c_parser_skip_to_end_of_block_or_statement(c_parser * parser)1344 c_parser_skip_to_end_of_block_or_statement (c_parser *parser)
1345 {
1346 unsigned nesting_depth = 0;
1347 bool save_error = parser->error;
1348
1349 while (true)
1350 {
1351 c_token *token;
1352
1353 /* Peek at the next token. */
1354 token = c_parser_peek_token (parser);
1355
1356 switch (token->type)
1357 {
1358 case CPP_EOF:
1359 return;
1360
1361 case CPP_PRAGMA_EOL:
1362 if (parser->in_pragma)
1363 return;
1364 break;
1365
1366 case CPP_SEMICOLON:
1367 /* If the next token is a ';', we have reached the
1368 end of the statement. */
1369 if (!nesting_depth)
1370 {
1371 /* Consume the ';'. */
1372 c_parser_consume_token (parser);
1373 goto finished;
1374 }
1375 break;
1376
1377 case CPP_CLOSE_BRACE:
1378 /* If the next token is a non-nested '}', then we have
1379 reached the end of the current block. */
1380 if (nesting_depth == 0 || --nesting_depth == 0)
1381 {
1382 c_parser_consume_token (parser);
1383 goto finished;
1384 }
1385 break;
1386
1387 case CPP_OPEN_BRACE:
1388 /* If it the next token is a '{', then we are entering a new
1389 block. Consume the entire block. */
1390 ++nesting_depth;
1391 break;
1392
1393 case CPP_PRAGMA:
1394 /* If we see a pragma, consume the whole thing at once. We
1395 have some safeguards against consuming pragmas willy-nilly.
1396 Normally, we'd expect to be here with parser->error set,
1397 which disables these safeguards. But it's possible to get
1398 here for secondary error recovery, after parser->error has
1399 been cleared. */
1400 c_parser_consume_pragma (parser);
1401 c_parser_skip_to_pragma_eol (parser);
1402 parser->error = save_error;
1403 continue;
1404
1405 default:
1406 break;
1407 }
1408
1409 c_parser_consume_token (parser);
1410 }
1411
1412 finished:
1413 parser->error = false;
1414 }
1415
1416 /* CPP's options (initialized by c-opts.cc). */
1417 extern cpp_options *cpp_opts;
1418
1419 /* Save the warning flags which are controlled by __extension__. */
1420
1421 static inline int
disable_extension_diagnostics(void)1422 disable_extension_diagnostics (void)
1423 {
1424 int ret = (pedantic
1425 | (warn_pointer_arith << 1)
1426 | (warn_traditional << 2)
1427 | (flag_iso << 3)
1428 | (warn_long_long << 4)
1429 | (warn_cxx_compat << 5)
1430 | (warn_overlength_strings << 6)
1431 /* warn_c90_c99_compat has three states: -1/0/1, so we must
1432 play tricks to properly restore it. */
1433 | ((warn_c90_c99_compat == 1) << 7)
1434 | ((warn_c90_c99_compat == -1) << 8)
1435 /* Similarly for warn_c99_c11_compat. */
1436 | ((warn_c99_c11_compat == 1) << 9)
1437 | ((warn_c99_c11_compat == -1) << 10)
1438 /* Similarly for warn_c11_c2x_compat. */
1439 | ((warn_c11_c2x_compat == 1) << 11)
1440 | ((warn_c11_c2x_compat == -1) << 12)
1441 );
1442 cpp_opts->cpp_pedantic = pedantic = 0;
1443 warn_pointer_arith = 0;
1444 cpp_opts->cpp_warn_traditional = warn_traditional = 0;
1445 flag_iso = 0;
1446 cpp_opts->cpp_warn_long_long = warn_long_long = 0;
1447 warn_cxx_compat = 0;
1448 warn_overlength_strings = 0;
1449 warn_c90_c99_compat = 0;
1450 warn_c99_c11_compat = 0;
1451 warn_c11_c2x_compat = 0;
1452 return ret;
1453 }
1454
1455 /* Restore the warning flags which are controlled by __extension__.
1456 FLAGS is the return value from disable_extension_diagnostics. */
1457
1458 static inline void
restore_extension_diagnostics(int flags)1459 restore_extension_diagnostics (int flags)
1460 {
1461 cpp_opts->cpp_pedantic = pedantic = flags & 1;
1462 warn_pointer_arith = (flags >> 1) & 1;
1463 cpp_opts->cpp_warn_traditional = warn_traditional = (flags >> 2) & 1;
1464 flag_iso = (flags >> 3) & 1;
1465 cpp_opts->cpp_warn_long_long = warn_long_long = (flags >> 4) & 1;
1466 warn_cxx_compat = (flags >> 5) & 1;
1467 warn_overlength_strings = (flags >> 6) & 1;
1468 /* See above for why is this needed. */
1469 warn_c90_c99_compat = (flags >> 7) & 1 ? 1 : ((flags >> 8) & 1 ? -1 : 0);
1470 warn_c99_c11_compat = (flags >> 9) & 1 ? 1 : ((flags >> 10) & 1 ? -1 : 0);
1471 warn_c11_c2x_compat = (flags >> 11) & 1 ? 1 : ((flags >> 12) & 1 ? -1 : 0);
1472 }
1473
1474 /* Helper data structure for parsing #pragma acc routine. */
1475 struct oacc_routine_data {
1476 bool error_seen; /* Set if error has been reported. */
1477 bool fndecl_seen; /* Set if one fn decl/definition has been seen already. */
1478 tree clauses;
1479 location_t loc;
1480 };
1481
1482 /* Used for parsing objc foreach statements. */
1483 static tree objc_foreach_break_label, objc_foreach_continue_label;
1484
1485 static bool c_parser_nth_token_starts_std_attributes (c_parser *,
1486 unsigned int);
1487 static tree c_parser_std_attribute_specifier_sequence (c_parser *);
1488 static void c_parser_external_declaration (c_parser *);
1489 static void c_parser_asm_definition (c_parser *);
1490 static void c_parser_declaration_or_fndef (c_parser *, bool, bool, bool,
1491 bool, bool, tree * = NULL,
1492 vec<c_token> * = NULL,
1493 bool have_attrs = false,
1494 tree attrs = NULL,
1495 struct oacc_routine_data * = NULL,
1496 bool * = NULL);
1497 static void c_parser_static_assert_declaration_no_semi (c_parser *);
1498 static void c_parser_static_assert_declaration (c_parser *);
1499 static struct c_typespec c_parser_enum_specifier (c_parser *);
1500 static struct c_typespec c_parser_struct_or_union_specifier (c_parser *);
1501 static tree c_parser_struct_declaration (c_parser *);
1502 static struct c_typespec c_parser_typeof_specifier (c_parser *);
1503 static tree c_parser_alignas_specifier (c_parser *);
1504 static struct c_declarator *c_parser_direct_declarator (c_parser *, bool,
1505 c_dtr_syn, bool *);
1506 static struct c_declarator *c_parser_direct_declarator_inner (c_parser *,
1507 bool,
1508 struct c_declarator *);
1509 static struct c_arg_info *c_parser_parms_declarator (c_parser *, bool, tree,
1510 bool);
1511 static struct c_arg_info *c_parser_parms_list_declarator (c_parser *, tree,
1512 tree, bool);
1513 static struct c_parm *c_parser_parameter_declaration (c_parser *, tree, bool);
1514 static tree c_parser_simple_asm_expr (c_parser *);
1515 static tree c_parser_gnu_attributes (c_parser *);
1516 static struct c_expr c_parser_initializer (c_parser *, tree);
1517 static struct c_expr c_parser_braced_init (c_parser *, tree, bool,
1518 struct obstack *);
1519 static void c_parser_initelt (c_parser *, struct obstack *);
1520 static void c_parser_initval (c_parser *, struct c_expr *,
1521 struct obstack *);
1522 static tree c_parser_compound_statement (c_parser *, location_t * = NULL);
1523 static location_t c_parser_compound_statement_nostart (c_parser *);
1524 static void c_parser_label (c_parser *, tree);
1525 static void c_parser_statement (c_parser *, bool *, location_t * = NULL);
1526 static void c_parser_statement_after_labels (c_parser *, bool *,
1527 vec<tree> * = NULL);
1528 static tree c_parser_c99_block_statement (c_parser *, bool *,
1529 location_t * = NULL);
1530 static void c_parser_if_statement (c_parser *, bool *, vec<tree> *);
1531 static void c_parser_switch_statement (c_parser *, bool *);
1532 static void c_parser_while_statement (c_parser *, bool, unsigned short, bool *);
1533 static void c_parser_do_statement (c_parser *, bool, unsigned short);
1534 static void c_parser_for_statement (c_parser *, bool, unsigned short, bool *);
1535 static tree c_parser_asm_statement (c_parser *);
1536 static tree c_parser_asm_operands (c_parser *);
1537 static tree c_parser_asm_goto_operands (c_parser *);
1538 static tree c_parser_asm_clobbers (c_parser *);
1539 static struct c_expr c_parser_expr_no_commas (c_parser *, struct c_expr *,
1540 tree = NULL_TREE);
1541 static struct c_expr c_parser_conditional_expression (c_parser *,
1542 struct c_expr *, tree);
1543 static struct c_expr c_parser_binary_expression (c_parser *, struct c_expr *,
1544 tree);
1545 static struct c_expr c_parser_cast_expression (c_parser *, struct c_expr *);
1546 static struct c_expr c_parser_unary_expression (c_parser *);
1547 static struct c_expr c_parser_sizeof_expression (c_parser *);
1548 static struct c_expr c_parser_alignof_expression (c_parser *);
1549 static struct c_expr c_parser_postfix_expression (c_parser *);
1550 static struct c_expr c_parser_postfix_expression_after_paren_type (c_parser *,
1551 struct c_type_name *,
1552 location_t);
1553 static struct c_expr c_parser_postfix_expression_after_primary (c_parser *,
1554 location_t loc,
1555 struct c_expr);
1556 static tree c_parser_transaction (c_parser *, enum rid);
1557 static struct c_expr c_parser_transaction_expression (c_parser *, enum rid);
1558 static tree c_parser_transaction_cancel (c_parser *);
1559 static struct c_expr c_parser_expression (c_parser *);
1560 static struct c_expr c_parser_expression_conv (c_parser *);
1561 static vec<tree, va_gc> *c_parser_expr_list (c_parser *, bool, bool,
1562 vec<tree, va_gc> **, location_t *,
1563 tree *, vec<location_t> *,
1564 unsigned int * = NULL);
1565 static struct c_expr c_parser_has_attribute_expression (c_parser *);
1566
1567 static void c_parser_oacc_declare (c_parser *);
1568 static void c_parser_oacc_enter_exit_data (c_parser *, bool);
1569 static void c_parser_oacc_update (c_parser *);
1570 static void c_parser_omp_construct (c_parser *, bool *);
1571 static void c_parser_omp_threadprivate (c_parser *);
1572 static void c_parser_omp_barrier (c_parser *);
1573 static void c_parser_omp_depobj (c_parser *);
1574 static void c_parser_omp_flush (c_parser *);
1575 static tree c_parser_omp_for_loop (location_t, c_parser *, enum tree_code,
1576 tree, tree *, bool *);
1577 static void c_parser_omp_taskwait (c_parser *);
1578 static void c_parser_omp_taskyield (c_parser *);
1579 static void c_parser_omp_cancel (c_parser *);
1580 static void c_parser_omp_nothing (c_parser *);
1581
1582 enum pragma_context { pragma_external, pragma_struct, pragma_param,
1583 pragma_stmt, pragma_compound };
1584 static bool c_parser_pragma (c_parser *, enum pragma_context, bool *);
1585 static bool c_parser_omp_cancellation_point (c_parser *, enum pragma_context);
1586 static bool c_parser_omp_target (c_parser *, enum pragma_context, bool *);
1587 static void c_parser_omp_end_declare_target (c_parser *);
1588 static bool c_parser_omp_declare (c_parser *, enum pragma_context);
1589 static void c_parser_omp_requires (c_parser *);
1590 static bool c_parser_omp_error (c_parser *, enum pragma_context);
1591 static bool c_parser_omp_ordered (c_parser *, enum pragma_context, bool *);
1592 static void c_parser_oacc_routine (c_parser *, enum pragma_context);
1593
1594 /* These Objective-C parser functions are only ever called when
1595 compiling Objective-C. */
1596 static void c_parser_objc_class_definition (c_parser *, tree);
1597 static void c_parser_objc_class_instance_variables (c_parser *);
1598 static void c_parser_objc_class_declaration (c_parser *);
1599 static void c_parser_objc_alias_declaration (c_parser *);
1600 static void c_parser_objc_protocol_definition (c_parser *, tree);
1601 static bool c_parser_objc_method_type (c_parser *);
1602 static void c_parser_objc_method_definition (c_parser *);
1603 static void c_parser_objc_methodprotolist (c_parser *);
1604 static void c_parser_objc_methodproto (c_parser *);
1605 static tree c_parser_objc_method_decl (c_parser *, bool, tree *, tree *);
1606 static tree c_parser_objc_type_name (c_parser *);
1607 static tree c_parser_objc_protocol_refs (c_parser *);
1608 static void c_parser_objc_try_catch_finally_statement (c_parser *);
1609 static void c_parser_objc_synchronized_statement (c_parser *);
1610 static tree c_parser_objc_selector (c_parser *);
1611 static tree c_parser_objc_selector_arg (c_parser *);
1612 static tree c_parser_objc_receiver (c_parser *);
1613 static tree c_parser_objc_message_args (c_parser *);
1614 static tree c_parser_objc_keywordexpr (c_parser *);
1615 static void c_parser_objc_at_property_declaration (c_parser *);
1616 static void c_parser_objc_at_synthesize_declaration (c_parser *);
1617 static void c_parser_objc_at_dynamic_declaration (c_parser *);
1618 static bool c_parser_objc_diagnose_bad_element_prefix
1619 (c_parser *, struct c_declspecs *);
1620 static location_t c_parser_parse_rtl_body (c_parser *, char *);
1621
1622 /* Parse a translation unit (C90 6.7, C99 6.9, C11 6.9).
1623
1624 translation-unit:
1625 external-declarations
1626
1627 external-declarations:
1628 external-declaration
1629 external-declarations external-declaration
1630
1631 GNU extensions:
1632
1633 translation-unit:
1634 empty
1635 */
1636
1637 static void
c_parser_translation_unit(c_parser * parser)1638 c_parser_translation_unit (c_parser *parser)
1639 {
1640 if (c_parser_next_token_is (parser, CPP_EOF))
1641 {
1642 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
1643 "ISO C forbids an empty translation unit");
1644 }
1645 else
1646 {
1647 void *obstack_position = obstack_alloc (&parser_obstack, 0);
1648 mark_valid_location_for_stdc_pragma (false);
1649 do
1650 {
1651 ggc_collect ();
1652 c_parser_external_declaration (parser);
1653 obstack_free (&parser_obstack, obstack_position);
1654 }
1655 while (c_parser_next_token_is_not (parser, CPP_EOF));
1656 }
1657
1658 unsigned int i;
1659 tree decl;
1660 FOR_EACH_VEC_ELT (incomplete_record_decls, i, decl)
1661 if (DECL_SIZE (decl) == NULL_TREE && TREE_TYPE (decl) != error_mark_node)
1662 error ("storage size of %q+D isn%'t known", decl);
1663
1664 if (current_omp_declare_target_attribute)
1665 {
1666 if (!errorcount)
1667 error ("%<#pragma omp declare target%> without corresponding "
1668 "%<#pragma omp end declare target%>");
1669 current_omp_declare_target_attribute = 0;
1670 }
1671 }
1672
1673 /* Parse an external declaration (C90 6.7, C99 6.9, C11 6.9).
1674
1675 external-declaration:
1676 function-definition
1677 declaration
1678
1679 GNU extensions:
1680
1681 external-declaration:
1682 asm-definition
1683 ;
1684 __extension__ external-declaration
1685
1686 Objective-C:
1687
1688 external-declaration:
1689 objc-class-definition
1690 objc-class-declaration
1691 objc-alias-declaration
1692 objc-protocol-definition
1693 objc-method-definition
1694 @end
1695 */
1696
1697 static void
c_parser_external_declaration(c_parser * parser)1698 c_parser_external_declaration (c_parser *parser)
1699 {
1700 int ext;
1701 switch (c_parser_peek_token (parser)->type)
1702 {
1703 case CPP_KEYWORD:
1704 switch (c_parser_peek_token (parser)->keyword)
1705 {
1706 case RID_EXTENSION:
1707 ext = disable_extension_diagnostics ();
1708 c_parser_consume_token (parser);
1709 c_parser_external_declaration (parser);
1710 restore_extension_diagnostics (ext);
1711 break;
1712 case RID_ASM:
1713 c_parser_asm_definition (parser);
1714 break;
1715 case RID_AT_INTERFACE:
1716 case RID_AT_IMPLEMENTATION:
1717 gcc_assert (c_dialect_objc ());
1718 c_parser_objc_class_definition (parser, NULL_TREE);
1719 break;
1720 case RID_AT_CLASS:
1721 gcc_assert (c_dialect_objc ());
1722 c_parser_objc_class_declaration (parser);
1723 break;
1724 case RID_AT_ALIAS:
1725 gcc_assert (c_dialect_objc ());
1726 c_parser_objc_alias_declaration (parser);
1727 break;
1728 case RID_AT_PROTOCOL:
1729 gcc_assert (c_dialect_objc ());
1730 c_parser_objc_protocol_definition (parser, NULL_TREE);
1731 break;
1732 case RID_AT_PROPERTY:
1733 gcc_assert (c_dialect_objc ());
1734 c_parser_objc_at_property_declaration (parser);
1735 break;
1736 case RID_AT_SYNTHESIZE:
1737 gcc_assert (c_dialect_objc ());
1738 c_parser_objc_at_synthesize_declaration (parser);
1739 break;
1740 case RID_AT_DYNAMIC:
1741 gcc_assert (c_dialect_objc ());
1742 c_parser_objc_at_dynamic_declaration (parser);
1743 break;
1744 case RID_AT_END:
1745 gcc_assert (c_dialect_objc ());
1746 c_parser_consume_token (parser);
1747 objc_finish_implementation ();
1748 break;
1749 default:
1750 goto decl_or_fndef;
1751 }
1752 break;
1753 case CPP_SEMICOLON:
1754 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
1755 "ISO C does not allow extra %<;%> outside of a function");
1756 c_parser_consume_token (parser);
1757 break;
1758 case CPP_PRAGMA:
1759 mark_valid_location_for_stdc_pragma (true);
1760 c_parser_pragma (parser, pragma_external, NULL);
1761 mark_valid_location_for_stdc_pragma (false);
1762 break;
1763 case CPP_PLUS:
1764 case CPP_MINUS:
1765 if (c_dialect_objc ())
1766 {
1767 c_parser_objc_method_definition (parser);
1768 break;
1769 }
1770 /* Else fall through, and yield a syntax error trying to parse
1771 as a declaration or function definition. */
1772 /* FALLTHRU */
1773 default:
1774 decl_or_fndef:
1775 /* A declaration or a function definition (or, in Objective-C,
1776 an @interface or @protocol with prefix attributes). We can
1777 only tell which after parsing the declaration specifiers, if
1778 any, and the first declarator. */
1779 c_parser_declaration_or_fndef (parser, true, true, true, false, true);
1780 break;
1781 }
1782 }
1783
1784 static void c_finish_omp_declare_simd (c_parser *, tree, tree, vec<c_token> *);
1785 static void c_finish_oacc_routine (struct oacc_routine_data *, tree, bool);
1786
1787 /* Build and add a DEBUG_BEGIN_STMT statement with location LOC. */
1788
1789 static void
add_debug_begin_stmt(location_t loc)1790 add_debug_begin_stmt (location_t loc)
1791 {
1792 /* Don't add DEBUG_BEGIN_STMTs outside of functions, see PR84721. */
1793 if (!MAY_HAVE_DEBUG_MARKER_STMTS || !building_stmt_list_p ())
1794 return;
1795
1796 tree stmt = build0 (DEBUG_BEGIN_STMT, void_type_node);
1797 SET_EXPR_LOCATION (stmt, loc);
1798 add_stmt (stmt);
1799 }
1800
1801 /* Parse a declaration or function definition (C90 6.5, 6.7.1, C99
1802 6.7, 6.9.1, C11 6.7, 6.9.1). If FNDEF_OK is true, a function definition
1803 is accepted; otherwise (old-style parameter declarations) only other
1804 declarations are accepted. If STATIC_ASSERT_OK is true, a static
1805 assertion is accepted; otherwise (old-style parameter declarations)
1806 it is not. If NESTED is true, we are inside a function or parsing
1807 old-style parameter declarations; any functions encountered are
1808 nested functions and declaration specifiers are required; otherwise
1809 we are at top level and functions are normal functions and
1810 declaration specifiers may be optional. If EMPTY_OK is true, empty
1811 declarations are OK (subject to all other constraints); otherwise
1812 (old-style parameter declarations) they are diagnosed. If
1813 START_ATTR_OK is true, the declaration specifiers may start with
1814 attributes (GNU or standard); otherwise they may not.
1815 OBJC_FOREACH_OBJECT_DECLARATION can be used to get back the parsed
1816 declaration when parsing an Objective-C foreach statement.
1817 FALLTHRU_ATTR_P is used to signal whether this function parsed
1818 "__attribute__((fallthrough));". ATTRS are any standard attributes
1819 parsed in the caller (in contexts where such attributes had to be
1820 parsed to determine whether what follows is a declaration or a
1821 statement); HAVE_ATTRS says whether there were any such attributes
1822 (even empty).
1823
1824 declaration:
1825 declaration-specifiers init-declarator-list[opt] ;
1826 static_assert-declaration
1827
1828 function-definition:
1829 declaration-specifiers[opt] declarator declaration-list[opt]
1830 compound-statement
1831
1832 declaration-list:
1833 declaration
1834 declaration-list declaration
1835
1836 init-declarator-list:
1837 init-declarator
1838 init-declarator-list , init-declarator
1839
1840 init-declarator:
1841 declarator simple-asm-expr[opt] gnu-attributes[opt]
1842 declarator simple-asm-expr[opt] gnu-attributes[opt] = initializer
1843
1844 GNU extensions:
1845
1846 nested-function-definition:
1847 declaration-specifiers declarator declaration-list[opt]
1848 compound-statement
1849
1850 attribute ;
1851
1852 Objective-C:
1853 gnu-attributes objc-class-definition
1854 gnu-attributes objc-category-definition
1855 gnu-attributes objc-protocol-definition
1856
1857 The simple-asm-expr and gnu-attributes are GNU extensions.
1858
1859 This function does not handle __extension__; that is handled in its
1860 callers. ??? Following the old parser, __extension__ may start
1861 external declarations, declarations in functions and declarations
1862 at the start of "for" loops, but not old-style parameter
1863 declarations.
1864
1865 C99 requires declaration specifiers in a function definition; the
1866 absence is diagnosed through the diagnosis of implicit int. In GNU
1867 C we also allow but diagnose declarations without declaration
1868 specifiers, but only at top level (elsewhere they conflict with
1869 other syntax).
1870
1871 In Objective-C, declarations of the looping variable in a foreach
1872 statement are exceptionally terminated by 'in' (for example, 'for
1873 (NSObject *object in array) { ... }').
1874
1875 OpenMP:
1876
1877 declaration:
1878 threadprivate-directive
1879
1880 GIMPLE:
1881
1882 gimple-function-definition:
1883 declaration-specifiers[opt] __GIMPLE (gimple-or-rtl-pass-list) declarator
1884 declaration-list[opt] compound-statement
1885
1886 rtl-function-definition:
1887 declaration-specifiers[opt] __RTL (gimple-or-rtl-pass-list) declarator
1888 declaration-list[opt] compound-statement */
1889
1890 static void
c_parser_declaration_or_fndef(c_parser * parser,bool fndef_ok,bool static_assert_ok,bool empty_ok,bool nested,bool start_attr_ok,tree * objc_foreach_object_declaration,vec<c_token> * omp_declare_simd_clauses,bool have_attrs,tree attrs,struct oacc_routine_data * oacc_routine_data,bool * fallthru_attr_p)1891 c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
1892 bool static_assert_ok, bool empty_ok,
1893 bool nested, bool start_attr_ok,
1894 tree *objc_foreach_object_declaration
1895 /* = NULL */,
1896 vec<c_token> *omp_declare_simd_clauses
1897 /* = NULL */,
1898 bool have_attrs /* = false */,
1899 tree attrs /* = NULL_TREE */,
1900 struct oacc_routine_data *oacc_routine_data
1901 /* = NULL */,
1902 bool *fallthru_attr_p /* = NULL */)
1903 {
1904 struct c_declspecs *specs;
1905 tree prefix_attrs;
1906 tree all_prefix_attrs;
1907 bool diagnosed_no_specs = false;
1908 location_t here = c_parser_peek_token (parser)->location;
1909
1910 add_debug_begin_stmt (c_parser_peek_token (parser)->location);
1911
1912 if (static_assert_ok
1913 && c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
1914 {
1915 c_parser_static_assert_declaration (parser);
1916 return;
1917 }
1918 specs = build_null_declspecs ();
1919
1920 /* Handle any standard attributes parsed in the caller. */
1921 if (have_attrs)
1922 {
1923 declspecs_add_attrs (here, specs, attrs);
1924 specs->non_std_attrs_seen_p = false;
1925 }
1926
1927 /* Try to detect an unknown type name when we have "A B" or "A *B". */
1928 if (c_parser_peek_token (parser)->type == CPP_NAME
1929 && c_parser_peek_token (parser)->id_kind == C_ID_ID
1930 && (c_parser_peek_2nd_token (parser)->type == CPP_NAME
1931 || c_parser_peek_2nd_token (parser)->type == CPP_MULT)
1932 && (!nested || !lookup_name (c_parser_peek_token (parser)->value)))
1933 {
1934 tree name = c_parser_peek_token (parser)->value;
1935
1936 /* Issue a warning about NAME being an unknown type name, perhaps
1937 with some kind of hint.
1938 If the user forgot a "struct" etc, suggest inserting
1939 it. Otherwise, attempt to look for misspellings. */
1940 gcc_rich_location richloc (here);
1941 if (tag_exists_p (RECORD_TYPE, name))
1942 {
1943 /* This is not C++ with its implicit typedef. */
1944 richloc.add_fixit_insert_before ("struct ");
1945 error_at (&richloc,
1946 "unknown type name %qE;"
1947 " use %<struct%> keyword to refer to the type",
1948 name);
1949 }
1950 else if (tag_exists_p (UNION_TYPE, name))
1951 {
1952 richloc.add_fixit_insert_before ("union ");
1953 error_at (&richloc,
1954 "unknown type name %qE;"
1955 " use %<union%> keyword to refer to the type",
1956 name);
1957 }
1958 else if (tag_exists_p (ENUMERAL_TYPE, name))
1959 {
1960 richloc.add_fixit_insert_before ("enum ");
1961 error_at (&richloc,
1962 "unknown type name %qE;"
1963 " use %<enum%> keyword to refer to the type",
1964 name);
1965 }
1966 else
1967 {
1968 auto_diagnostic_group d;
1969 name_hint hint = lookup_name_fuzzy (name, FUZZY_LOOKUP_TYPENAME,
1970 here);
1971 if (const char *suggestion = hint.suggestion ())
1972 {
1973 richloc.add_fixit_replace (suggestion);
1974 error_at (&richloc,
1975 "unknown type name %qE; did you mean %qs?",
1976 name, suggestion);
1977 }
1978 else
1979 error_at (here, "unknown type name %qE", name);
1980 }
1981
1982 /* Parse declspecs normally to get a correct pointer type, but avoid
1983 a further "fails to be a type name" error. Refuse nested functions
1984 since it is not how the user likely wants us to recover. */
1985 c_parser_peek_token (parser)->type = CPP_KEYWORD;
1986 c_parser_peek_token (parser)->keyword = RID_VOID;
1987 c_parser_peek_token (parser)->value = error_mark_node;
1988 fndef_ok = !nested;
1989 }
1990
1991 /* When there are standard attributes at the start of the
1992 declaration (to apply to the entity being declared), an
1993 init-declarator-list or function definition must be present. */
1994 if (c_parser_nth_token_starts_std_attributes (parser, 1))
1995 have_attrs = true;
1996
1997 c_parser_declspecs (parser, specs, true, true, start_attr_ok,
1998 true, true, start_attr_ok, true, cla_nonabstract_decl);
1999 if (parser->error)
2000 {
2001 c_parser_skip_to_end_of_block_or_statement (parser);
2002 return;
2003 }
2004 if (nested && !specs->declspecs_seen_p)
2005 {
2006 c_parser_error (parser, "expected declaration specifiers");
2007 c_parser_skip_to_end_of_block_or_statement (parser);
2008 return;
2009 }
2010
2011 finish_declspecs (specs);
2012 bool auto_type_p = specs->typespec_word == cts_auto_type;
2013 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
2014 {
2015 if (auto_type_p)
2016 error_at (here, "%<__auto_type%> in empty declaration");
2017 else if (specs->typespec_kind == ctsk_none
2018 && attribute_fallthrough_p (specs->attrs))
2019 {
2020 if (fallthru_attr_p != NULL)
2021 *fallthru_attr_p = true;
2022 if (nested)
2023 {
2024 tree fn = build_call_expr_internal_loc (here, IFN_FALLTHROUGH,
2025 void_type_node, 0);
2026 add_stmt (fn);
2027 }
2028 else
2029 pedwarn (here, OPT_Wattributes,
2030 "%<fallthrough%> attribute at top level");
2031 }
2032 else if (empty_ok && !(have_attrs
2033 && specs->non_std_attrs_seen_p))
2034 shadow_tag (specs);
2035 else
2036 {
2037 shadow_tag_warned (specs, 1);
2038 pedwarn (here, 0, "empty declaration");
2039 }
2040 c_parser_consume_token (parser);
2041 if (oacc_routine_data)
2042 c_finish_oacc_routine (oacc_routine_data, NULL_TREE, false);
2043 return;
2044 }
2045
2046 /* Provide better error recovery. Note that a type name here is usually
2047 better diagnosed as a redeclaration. */
2048 if (empty_ok
2049 && specs->typespec_kind == ctsk_tagdef
2050 && c_parser_next_token_starts_declspecs (parser)
2051 && !c_parser_next_token_is (parser, CPP_NAME))
2052 {
2053 c_parser_error (parser, "expected %<;%>, identifier or %<(%>");
2054 parser->error = false;
2055 shadow_tag_warned (specs, 1);
2056 return;
2057 }
2058 else if (c_dialect_objc () && !auto_type_p)
2059 {
2060 /* Prefix attributes are an error on method decls. */
2061 switch (c_parser_peek_token (parser)->type)
2062 {
2063 case CPP_PLUS:
2064 case CPP_MINUS:
2065 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2066 return;
2067 if (specs->attrs)
2068 {
2069 warning_at (c_parser_peek_token (parser)->location,
2070 OPT_Wattributes,
2071 "prefix attributes are ignored for methods");
2072 specs->attrs = NULL_TREE;
2073 }
2074 if (fndef_ok)
2075 c_parser_objc_method_definition (parser);
2076 else
2077 c_parser_objc_methodproto (parser);
2078 return;
2079 break;
2080 default:
2081 break;
2082 }
2083 /* This is where we parse 'attributes @interface ...',
2084 'attributes @implementation ...', 'attributes @protocol ...'
2085 (where attributes could be, for example, __attribute__
2086 ((deprecated)).
2087 */
2088 switch (c_parser_peek_token (parser)->keyword)
2089 {
2090 case RID_AT_INTERFACE:
2091 {
2092 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2093 return;
2094 c_parser_objc_class_definition (parser, specs->attrs);
2095 return;
2096 }
2097 break;
2098 case RID_AT_IMPLEMENTATION:
2099 {
2100 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2101 return;
2102 if (specs->attrs)
2103 {
2104 warning_at (c_parser_peek_token (parser)->location,
2105 OPT_Wattributes,
2106 "prefix attributes are ignored for implementations");
2107 specs->attrs = NULL_TREE;
2108 }
2109 c_parser_objc_class_definition (parser, NULL_TREE);
2110 return;
2111 }
2112 break;
2113 case RID_AT_PROTOCOL:
2114 {
2115 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2116 return;
2117 c_parser_objc_protocol_definition (parser, specs->attrs);
2118 return;
2119 }
2120 break;
2121 case RID_AT_ALIAS:
2122 case RID_AT_CLASS:
2123 case RID_AT_END:
2124 case RID_AT_PROPERTY:
2125 if (specs->attrs)
2126 {
2127 c_parser_error (parser, "unexpected attribute");
2128 specs->attrs = NULL;
2129 }
2130 break;
2131 default:
2132 break;
2133 }
2134 }
2135 else if (attribute_fallthrough_p (specs->attrs))
2136 warning_at (here, OPT_Wattributes,
2137 "%<fallthrough%> attribute not followed by %<;%>");
2138
2139 pending_xref_error ();
2140 prefix_attrs = specs->attrs;
2141 all_prefix_attrs = prefix_attrs;
2142 specs->attrs = NULL_TREE;
2143 while (true)
2144 {
2145 struct c_declarator *declarator;
2146 bool dummy = false;
2147 timevar_id_t tv;
2148 tree fnbody = NULL_TREE;
2149 /* Declaring either one or more declarators (in which case we
2150 should diagnose if there were no declaration specifiers) or a
2151 function definition (in which case the diagnostic for
2152 implicit int suffices). */
2153 declarator = c_parser_declarator (parser,
2154 specs->typespec_kind != ctsk_none,
2155 C_DTR_NORMAL, &dummy);
2156 if (declarator == NULL)
2157 {
2158 if (omp_declare_simd_clauses)
2159 c_finish_omp_declare_simd (parser, NULL_TREE, NULL_TREE,
2160 omp_declare_simd_clauses);
2161 if (oacc_routine_data)
2162 c_finish_oacc_routine (oacc_routine_data, NULL_TREE, false);
2163 c_parser_skip_to_end_of_block_or_statement (parser);
2164 return;
2165 }
2166 if (auto_type_p && declarator->kind != cdk_id)
2167 {
2168 error_at (here,
2169 "%<__auto_type%> requires a plain identifier"
2170 " as declarator");
2171 c_parser_skip_to_end_of_block_or_statement (parser);
2172 return;
2173 }
2174 if (c_parser_next_token_is (parser, CPP_EQ)
2175 || c_parser_next_token_is (parser, CPP_COMMA)
2176 || c_parser_next_token_is (parser, CPP_SEMICOLON)
2177 || c_parser_next_token_is_keyword (parser, RID_ASM)
2178 || c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)
2179 || c_parser_next_token_is_keyword (parser, RID_IN))
2180 {
2181 tree asm_name = NULL_TREE;
2182 tree postfix_attrs = NULL_TREE;
2183 if (!diagnosed_no_specs && !specs->declspecs_seen_p)
2184 {
2185 diagnosed_no_specs = true;
2186 pedwarn (here, 0, "data definition has no type or storage class");
2187 }
2188 /* Having seen a data definition, there cannot now be a
2189 function definition. */
2190 fndef_ok = false;
2191 if (c_parser_next_token_is_keyword (parser, RID_ASM))
2192 asm_name = c_parser_simple_asm_expr (parser);
2193 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
2194 {
2195 postfix_attrs = c_parser_gnu_attributes (parser);
2196 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
2197 {
2198 /* This means there is an attribute specifier after
2199 the declarator in a function definition. Provide
2200 some more information for the user. */
2201 error_at (here, "attributes should be specified before the "
2202 "declarator in a function definition");
2203 c_parser_skip_to_end_of_block_or_statement (parser);
2204 return;
2205 }
2206 }
2207 if (c_parser_next_token_is (parser, CPP_EQ))
2208 {
2209 tree d;
2210 struct c_expr init;
2211 location_t init_loc;
2212 c_parser_consume_token (parser);
2213 if (auto_type_p)
2214 {
2215 init_loc = c_parser_peek_token (parser)->location;
2216 rich_location richloc (line_table, init_loc);
2217 start_init (NULL_TREE, asm_name, global_bindings_p (), &richloc);
2218 /* A parameter is initialized, which is invalid. Don't
2219 attempt to instrument the initializer. */
2220 int flag_sanitize_save = flag_sanitize;
2221 if (nested && !empty_ok)
2222 flag_sanitize = 0;
2223 init = c_parser_expr_no_commas (parser, NULL);
2224 flag_sanitize = flag_sanitize_save;
2225 if (TREE_CODE (init.value) == COMPONENT_REF
2226 && DECL_C_BIT_FIELD (TREE_OPERAND (init.value, 1)))
2227 error_at (here,
2228 "%<__auto_type%> used with a bit-field"
2229 " initializer");
2230 init = convert_lvalue_to_rvalue (init_loc, init, true, true);
2231 tree init_type = TREE_TYPE (init.value);
2232 bool vm_type = variably_modified_type_p (init_type,
2233 NULL_TREE);
2234 if (vm_type)
2235 init.value = save_expr (init.value);
2236 finish_init ();
2237 specs->typespec_kind = ctsk_typeof;
2238 specs->locations[cdw_typedef] = init_loc;
2239 specs->typedef_p = true;
2240 specs->type = init_type;
2241 if (vm_type)
2242 {
2243 bool maybe_const = true;
2244 tree type_expr = c_fully_fold (init.value, false,
2245 &maybe_const);
2246 specs->expr_const_operands &= maybe_const;
2247 if (specs->expr)
2248 specs->expr = build2 (COMPOUND_EXPR,
2249 TREE_TYPE (type_expr),
2250 specs->expr, type_expr);
2251 else
2252 specs->expr = type_expr;
2253 }
2254 d = start_decl (declarator, specs, true,
2255 chainon (postfix_attrs, all_prefix_attrs));
2256 if (!d)
2257 d = error_mark_node;
2258 if (omp_declare_simd_clauses)
2259 c_finish_omp_declare_simd (parser, d, NULL_TREE,
2260 omp_declare_simd_clauses);
2261 }
2262 else
2263 {
2264 /* The declaration of the variable is in effect while
2265 its initializer is parsed. */
2266 d = start_decl (declarator, specs, true,
2267 chainon (postfix_attrs, all_prefix_attrs));
2268 if (!d)
2269 d = error_mark_node;
2270 if (omp_declare_simd_clauses)
2271 c_finish_omp_declare_simd (parser, d, NULL_TREE,
2272 omp_declare_simd_clauses);
2273 init_loc = c_parser_peek_token (parser)->location;
2274 rich_location richloc (line_table, init_loc);
2275 start_init (d, asm_name, global_bindings_p (), &richloc);
2276 /* A parameter is initialized, which is invalid. Don't
2277 attempt to instrument the initializer. */
2278 int flag_sanitize_save = flag_sanitize;
2279 if (TREE_CODE (d) == PARM_DECL)
2280 flag_sanitize = 0;
2281 init = c_parser_initializer (parser, d);
2282 flag_sanitize = flag_sanitize_save;
2283 finish_init ();
2284 }
2285 if (oacc_routine_data)
2286 c_finish_oacc_routine (oacc_routine_data, d, false);
2287 if (d != error_mark_node)
2288 {
2289 maybe_warn_string_init (init_loc, TREE_TYPE (d), init);
2290 finish_decl (d, init_loc, init.value,
2291 init.original_type, asm_name);
2292 }
2293 }
2294 else
2295 {
2296 if (auto_type_p)
2297 {
2298 error_at (here,
2299 "%<__auto_type%> requires an initialized "
2300 "data declaration");
2301 c_parser_skip_to_end_of_block_or_statement (parser);
2302 return;
2303 }
2304
2305 location_t lastloc = UNKNOWN_LOCATION;
2306 tree attrs = chainon (postfix_attrs, all_prefix_attrs);
2307 tree d = start_decl (declarator, specs, false, attrs, &lastloc);
2308 if (d && TREE_CODE (d) == FUNCTION_DECL)
2309 {
2310 /* Find the innermost declarator that is neither cdk_id
2311 nor cdk_attrs. */
2312 const struct c_declarator *decl = declarator;
2313 const struct c_declarator *last_non_id_attrs = NULL;
2314
2315 while (decl)
2316 switch (decl->kind)
2317 {
2318 case cdk_array:
2319 case cdk_function:
2320 case cdk_pointer:
2321 last_non_id_attrs = decl;
2322 decl = decl->declarator;
2323 break;
2324
2325 case cdk_attrs:
2326 decl = decl->declarator;
2327 break;
2328
2329 case cdk_id:
2330 decl = 0;
2331 break;
2332
2333 default:
2334 gcc_unreachable ();
2335 }
2336
2337 /* If it exists and is cdk_function declaration whose
2338 arguments have not been set yet, use its arguments. */
2339 if (last_non_id_attrs
2340 && last_non_id_attrs->kind == cdk_function)
2341 {
2342 tree parms = last_non_id_attrs->u.arg_info->parms;
2343 if (DECL_ARGUMENTS (d) == NULL_TREE
2344 && DECL_INITIAL (d) == NULL_TREE)
2345 DECL_ARGUMENTS (d) = parms;
2346
2347 warn_parm_array_mismatch (lastloc, d, parms);
2348 }
2349 }
2350 if (omp_declare_simd_clauses)
2351 {
2352 tree parms = NULL_TREE;
2353 if (d && TREE_CODE (d) == FUNCTION_DECL)
2354 {
2355 struct c_declarator *ce = declarator;
2356 while (ce != NULL)
2357 if (ce->kind == cdk_function)
2358 {
2359 parms = ce->u.arg_info->parms;
2360 break;
2361 }
2362 else
2363 ce = ce->declarator;
2364 }
2365 if (parms)
2366 temp_store_parm_decls (d, parms);
2367 c_finish_omp_declare_simd (parser, d, parms,
2368 omp_declare_simd_clauses);
2369 if (parms)
2370 temp_pop_parm_decls ();
2371 }
2372 if (oacc_routine_data)
2373 c_finish_oacc_routine (oacc_routine_data, d, false);
2374 if (d)
2375 finish_decl (d, UNKNOWN_LOCATION, NULL_TREE,
2376 NULL_TREE, asm_name);
2377
2378 if (c_parser_next_token_is_keyword (parser, RID_IN))
2379 {
2380 if (d)
2381 *objc_foreach_object_declaration = d;
2382 else
2383 *objc_foreach_object_declaration = error_mark_node;
2384 }
2385 }
2386 if (c_parser_next_token_is (parser, CPP_COMMA))
2387 {
2388 if (auto_type_p)
2389 {
2390 error_at (here,
2391 "%<__auto_type%> may only be used with"
2392 " a single declarator");
2393 c_parser_skip_to_end_of_block_or_statement (parser);
2394 return;
2395 }
2396 c_parser_consume_token (parser);
2397 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
2398 all_prefix_attrs = chainon (c_parser_gnu_attributes (parser),
2399 prefix_attrs);
2400 else
2401 all_prefix_attrs = prefix_attrs;
2402 continue;
2403 }
2404 else if (c_parser_next_token_is (parser, CPP_SEMICOLON))
2405 {
2406 c_parser_consume_token (parser);
2407 return;
2408 }
2409 else if (c_parser_next_token_is_keyword (parser, RID_IN))
2410 {
2411 /* This can only happen in Objective-C: we found the
2412 'in' that terminates the declaration inside an
2413 Objective-C foreach statement. Do not consume the
2414 token, so that the caller can use it to determine
2415 that this indeed is a foreach context. */
2416 return;
2417 }
2418 else
2419 {
2420 c_parser_error (parser, "expected %<,%> or %<;%>");
2421 c_parser_skip_to_end_of_block_or_statement (parser);
2422 return;
2423 }
2424 }
2425 else if (auto_type_p)
2426 {
2427 error_at (here,
2428 "%<__auto_type%> requires an initialized data declaration");
2429 c_parser_skip_to_end_of_block_or_statement (parser);
2430 return;
2431 }
2432 else if (!fndef_ok)
2433 {
2434 c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, "
2435 "%<asm%> or %<__attribute__%>");
2436 c_parser_skip_to_end_of_block_or_statement (parser);
2437 return;
2438 }
2439 /* Function definition (nested or otherwise). */
2440 if (nested)
2441 {
2442 pedwarn (here, OPT_Wpedantic, "ISO C forbids nested functions");
2443 c_push_function_context ();
2444 }
2445 if (!start_function (specs, declarator, all_prefix_attrs))
2446 {
2447 /* At this point we've consumed:
2448 declaration-specifiers declarator
2449 and the next token isn't CPP_EQ, CPP_COMMA, CPP_SEMICOLON,
2450 RID_ASM, RID_ATTRIBUTE, or RID_IN,
2451 but the
2452 declaration-specifiers declarator
2453 aren't grokkable as a function definition, so we have
2454 an error. */
2455 gcc_assert (!c_parser_next_token_is (parser, CPP_SEMICOLON));
2456 if (c_parser_next_token_starts_declspecs (parser))
2457 {
2458 /* If we have
2459 declaration-specifiers declarator decl-specs
2460 then assume we have a missing semicolon, which would
2461 give us:
2462 declaration-specifiers declarator decl-specs
2463 ^
2464 ;
2465 <~~~~~~~~~ declaration ~~~~~~~~~~>
2466 Use c_parser_require to get an error with a fix-it hint. */
2467 c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>");
2468 parser->error = false;
2469 }
2470 else
2471 {
2472 /* This can appear in many cases looking nothing like a
2473 function definition, so we don't give a more specific
2474 error suggesting there was one. */
2475 c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, %<asm%> "
2476 "or %<__attribute__%>");
2477 }
2478 if (nested)
2479 c_pop_function_context ();
2480 break;
2481 }
2482
2483 if (DECL_DECLARED_INLINE_P (current_function_decl))
2484 tv = TV_PARSE_INLINE;
2485 else
2486 tv = TV_PARSE_FUNC;
2487 auto_timevar at (g_timer, tv);
2488
2489 /* Parse old-style parameter declarations. ??? Attributes are
2490 not allowed to start declaration specifiers here because of a
2491 syntax conflict between a function declaration with attribute
2492 suffix and a function definition with an attribute prefix on
2493 first old-style parameter declaration. Following the old
2494 parser, they are not accepted on subsequent old-style
2495 parameter declarations either. However, there is no
2496 ambiguity after the first declaration, nor indeed on the
2497 first as long as we don't allow postfix attributes after a
2498 declarator with a nonempty identifier list in a definition;
2499 and postfix attributes have never been accepted here in
2500 function definitions either. */
2501 int save_debug_nonbind_markers_p = debug_nonbind_markers_p;
2502 debug_nonbind_markers_p = 0;
2503 while (c_parser_next_token_is_not (parser, CPP_EOF)
2504 && c_parser_next_token_is_not (parser, CPP_OPEN_BRACE))
2505 c_parser_declaration_or_fndef (parser, false, false, false,
2506 true, false);
2507 debug_nonbind_markers_p = save_debug_nonbind_markers_p;
2508 store_parm_decls ();
2509 if (omp_declare_simd_clauses)
2510 c_finish_omp_declare_simd (parser, current_function_decl, NULL_TREE,
2511 omp_declare_simd_clauses);
2512 if (oacc_routine_data)
2513 c_finish_oacc_routine (oacc_routine_data, current_function_decl, true);
2514 location_t startloc = c_parser_peek_token (parser)->location;
2515 DECL_STRUCT_FUNCTION (current_function_decl)->function_start_locus
2516 = startloc;
2517 location_t endloc = startloc;
2518
2519 /* If the definition was marked with __RTL, use the RTL parser now,
2520 consuming the function body. */
2521 if (specs->declspec_il == cdil_rtl)
2522 {
2523 endloc = c_parser_parse_rtl_body (parser, specs->gimple_or_rtl_pass);
2524
2525 /* Normally, store_parm_decls sets next_is_function_body,
2526 anticipating a function body. We need a push_scope/pop_scope
2527 pair to flush out this state, or subsequent function parsing
2528 will go wrong. */
2529 push_scope ();
2530 pop_scope ();
2531
2532 finish_function (endloc);
2533 return;
2534 }
2535 /* If the definition was marked with __GIMPLE then parse the
2536 function body as GIMPLE. */
2537 else if (specs->declspec_il != cdil_none)
2538 {
2539 bool saved = in_late_binary_op;
2540 in_late_binary_op = true;
2541 c_parser_parse_gimple_body (parser, specs->gimple_or_rtl_pass,
2542 specs->declspec_il,
2543 specs->entry_bb_count);
2544 in_late_binary_op = saved;
2545 }
2546 else
2547 fnbody = c_parser_compound_statement (parser, &endloc);
2548 tree fndecl = current_function_decl;
2549 if (nested)
2550 {
2551 tree decl = current_function_decl;
2552 /* Mark nested functions as needing static-chain initially.
2553 lower_nested_functions will recompute it but the
2554 DECL_STATIC_CHAIN flag is also used before that happens,
2555 by initializer_constant_valid_p. See gcc.dg/nested-fn-2.c. */
2556 DECL_STATIC_CHAIN (decl) = 1;
2557 add_stmt (fnbody);
2558 finish_function (endloc);
2559 c_pop_function_context ();
2560 add_stmt (build_stmt (DECL_SOURCE_LOCATION (decl), DECL_EXPR, decl));
2561 }
2562 else
2563 {
2564 if (fnbody)
2565 add_stmt (fnbody);
2566 finish_function (endloc);
2567 }
2568 /* Get rid of the empty stmt list for GIMPLE/RTL. */
2569 if (specs->declspec_il != cdil_none)
2570 DECL_SAVED_TREE (fndecl) = NULL_TREE;
2571
2572 break;
2573 }
2574 }
2575
2576 /* Parse an asm-definition (asm() outside a function body). This is a
2577 GNU extension.
2578
2579 asm-definition:
2580 simple-asm-expr ;
2581 */
2582
2583 static void
c_parser_asm_definition(c_parser * parser)2584 c_parser_asm_definition (c_parser *parser)
2585 {
2586 tree asm_str = c_parser_simple_asm_expr (parser);
2587 if (asm_str)
2588 symtab->finalize_toplevel_asm (asm_str);
2589 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
2590 }
2591
2592 /* Parse a static assertion (C11 6.7.10).
2593
2594 static_assert-declaration:
2595 static_assert-declaration-no-semi ;
2596 */
2597
2598 static void
c_parser_static_assert_declaration(c_parser * parser)2599 c_parser_static_assert_declaration (c_parser *parser)
2600 {
2601 c_parser_static_assert_declaration_no_semi (parser);
2602 if (parser->error
2603 || !c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
2604 c_parser_skip_to_end_of_block_or_statement (parser);
2605 }
2606
2607 /* Parse a static assertion (C11 6.7.10), without the trailing
2608 semicolon.
2609
2610 static_assert-declaration-no-semi:
2611 _Static_assert ( constant-expression , string-literal )
2612
2613 C2X:
2614 static_assert-declaration-no-semi:
2615 _Static_assert ( constant-expression )
2616 */
2617
2618 static void
c_parser_static_assert_declaration_no_semi(c_parser * parser)2619 c_parser_static_assert_declaration_no_semi (c_parser *parser)
2620 {
2621 location_t assert_loc, value_loc;
2622 tree value;
2623 tree string = NULL_TREE;
2624
2625 gcc_assert (c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT));
2626 assert_loc = c_parser_peek_token (parser)->location;
2627 if (flag_isoc99)
2628 pedwarn_c99 (assert_loc, OPT_Wpedantic,
2629 "ISO C99 does not support %<_Static_assert%>");
2630 else
2631 pedwarn_c99 (assert_loc, OPT_Wpedantic,
2632 "ISO C90 does not support %<_Static_assert%>");
2633 c_parser_consume_token (parser);
2634 matching_parens parens;
2635 if (!parens.require_open (parser))
2636 return;
2637 location_t value_tok_loc = c_parser_peek_token (parser)->location;
2638 value = c_parser_expr_no_commas (parser, NULL).value;
2639 value_loc = EXPR_LOC_OR_LOC (value, value_tok_loc);
2640 if (c_parser_next_token_is (parser, CPP_COMMA))
2641 {
2642 c_parser_consume_token (parser);
2643 switch (c_parser_peek_token (parser)->type)
2644 {
2645 case CPP_STRING:
2646 case CPP_STRING16:
2647 case CPP_STRING32:
2648 case CPP_WSTRING:
2649 case CPP_UTF8STRING:
2650 string = c_parser_string_literal (parser, false, true).value;
2651 break;
2652 default:
2653 c_parser_error (parser, "expected string literal");
2654 return;
2655 }
2656 }
2657 else if (flag_isoc11)
2658 /* If pedantic for pre-C11, the use of _Static_assert itself will
2659 have been diagnosed, so do not also diagnose the use of this
2660 new C2X feature of _Static_assert. */
2661 pedwarn_c11 (assert_loc, OPT_Wpedantic,
2662 "ISO C11 does not support omitting the string in "
2663 "%<_Static_assert%>");
2664 parens.require_close (parser);
2665
2666 if (!INTEGRAL_TYPE_P (TREE_TYPE (value)))
2667 {
2668 error_at (value_loc, "expression in static assertion is not an integer");
2669 return;
2670 }
2671 if (TREE_CODE (value) != INTEGER_CST)
2672 {
2673 value = c_fully_fold (value, false, NULL);
2674 /* Strip no-op conversions. */
2675 STRIP_TYPE_NOPS (value);
2676 if (TREE_CODE (value) == INTEGER_CST)
2677 pedwarn (value_loc, OPT_Wpedantic, "expression in static assertion "
2678 "is not an integer constant expression");
2679 }
2680 if (TREE_CODE (value) != INTEGER_CST)
2681 {
2682 error_at (value_loc, "expression in static assertion is not constant");
2683 return;
2684 }
2685 constant_expression_warning (value);
2686 if (integer_zerop (value))
2687 {
2688 if (string)
2689 error_at (assert_loc, "static assertion failed: %E", string);
2690 else
2691 error_at (assert_loc, "static assertion failed");
2692 }
2693 }
2694
2695 /* Parse some declaration specifiers (possibly none) (C90 6.5, C99
2696 6.7, C11 6.7), adding them to SPECS (which may already include some).
2697 Storage class specifiers are accepted iff SCSPEC_OK; type
2698 specifiers are accepted iff TYPESPEC_OK; alignment specifiers are
2699 accepted iff ALIGNSPEC_OK; gnu-attributes are accepted at the start
2700 iff START_ATTR_OK; __auto_type is accepted iff AUTO_TYPE_OK. In
2701 addition to the syntax shown, standard attributes are accepted at
2702 the start iff START_STD_ATTR_OK and at the end iff END_STD_ATTR_OK;
2703 unlike gnu-attributes, they are not accepted in the middle of the
2704 list. (This combines various different syntax productions in the C
2705 standard, and in some cases gnu-attributes and standard attributes
2706 at the start may already have been parsed before this function is
2707 called.)
2708
2709 declaration-specifiers:
2710 storage-class-specifier declaration-specifiers[opt]
2711 type-specifier declaration-specifiers[opt]
2712 type-qualifier declaration-specifiers[opt]
2713 function-specifier declaration-specifiers[opt]
2714 alignment-specifier declaration-specifiers[opt]
2715
2716 Function specifiers (inline) are from C99, and are currently
2717 handled as storage class specifiers, as is __thread. Alignment
2718 specifiers are from C11.
2719
2720 C90 6.5.1, C99 6.7.1, C11 6.7.1:
2721 storage-class-specifier:
2722 typedef
2723 extern
2724 static
2725 auto
2726 register
2727 _Thread_local
2728
2729 (_Thread_local is new in C11.)
2730
2731 C99 6.7.4, C11 6.7.4:
2732 function-specifier:
2733 inline
2734 _Noreturn
2735
2736 (_Noreturn is new in C11.)
2737
2738 C90 6.5.2, C99 6.7.2, C11 6.7.2:
2739 type-specifier:
2740 void
2741 char
2742 short
2743 int
2744 long
2745 float
2746 double
2747 signed
2748 unsigned
2749 _Bool
2750 _Complex
2751 [_Imaginary removed in C99 TC2]
2752 struct-or-union-specifier
2753 enum-specifier
2754 typedef-name
2755 atomic-type-specifier
2756
2757 (_Bool and _Complex are new in C99.)
2758 (atomic-type-specifier is new in C11.)
2759
2760 C90 6.5.3, C99 6.7.3, C11 6.7.3:
2761
2762 type-qualifier:
2763 const
2764 restrict
2765 volatile
2766 address-space-qualifier
2767 _Atomic
2768
2769 (restrict is new in C99.)
2770 (_Atomic is new in C11.)
2771
2772 GNU extensions:
2773
2774 declaration-specifiers:
2775 gnu-attributes declaration-specifiers[opt]
2776
2777 type-qualifier:
2778 address-space
2779
2780 address-space:
2781 identifier recognized by the target
2782
2783 storage-class-specifier:
2784 __thread
2785
2786 type-specifier:
2787 typeof-specifier
2788 __auto_type
2789 __intN
2790 _Decimal32
2791 _Decimal64
2792 _Decimal128
2793 _Fract
2794 _Accum
2795 _Sat
2796
2797 (_Fract, _Accum, and _Sat are new from ISO/IEC DTR 18037:
2798 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1169.pdf)
2799
2800 atomic-type-specifier
2801 _Atomic ( type-name )
2802
2803 Objective-C:
2804
2805 type-specifier:
2806 class-name objc-protocol-refs[opt]
2807 typedef-name objc-protocol-refs
2808 objc-protocol-refs
2809 */
2810
2811 void
c_parser_declspecs(c_parser * parser,struct c_declspecs * specs,bool scspec_ok,bool typespec_ok,bool start_attr_ok,bool alignspec_ok,bool auto_type_ok,bool start_std_attr_ok,bool end_std_attr_ok,enum c_lookahead_kind la)2812 c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
2813 bool scspec_ok, bool typespec_ok, bool start_attr_ok,
2814 bool alignspec_ok, bool auto_type_ok,
2815 bool start_std_attr_ok, bool end_std_attr_ok,
2816 enum c_lookahead_kind la)
2817 {
2818 bool attrs_ok = start_attr_ok;
2819 bool seen_type = specs->typespec_kind != ctsk_none;
2820
2821 if (!typespec_ok)
2822 gcc_assert (la == cla_prefer_id);
2823
2824 if (start_std_attr_ok
2825 && c_parser_nth_token_starts_std_attributes (parser, 1))
2826 {
2827 gcc_assert (!specs->non_std_attrs_seen_p);
2828 location_t loc = c_parser_peek_token (parser)->location;
2829 tree attrs = c_parser_std_attribute_specifier_sequence (parser);
2830 declspecs_add_attrs (loc, specs, attrs);
2831 specs->non_std_attrs_seen_p = false;
2832 }
2833
2834 while (c_parser_next_token_is (parser, CPP_NAME)
2835 || c_parser_next_token_is (parser, CPP_KEYWORD)
2836 || (c_dialect_objc () && c_parser_next_token_is (parser, CPP_LESS)))
2837 {
2838 struct c_typespec t;
2839 tree attrs;
2840 tree align;
2841 location_t loc = c_parser_peek_token (parser)->location;
2842
2843 /* If we cannot accept a type, exit if the next token must start
2844 one. Also, if we already have seen a tagged definition,
2845 a typename would be an error anyway and likely the user
2846 has simply forgotten a semicolon, so we exit. */
2847 if ((!typespec_ok || specs->typespec_kind == ctsk_tagdef)
2848 && c_parser_next_tokens_start_typename (parser, la)
2849 && !c_parser_next_token_is_qualifier (parser)
2850 && !c_parser_next_token_is_keyword (parser, RID_ALIGNAS))
2851 break;
2852
2853 if (c_parser_next_token_is (parser, CPP_NAME))
2854 {
2855 c_token *name_token = c_parser_peek_token (parser);
2856 tree value = name_token->value;
2857 c_id_kind kind = name_token->id_kind;
2858
2859 if (kind == C_ID_ADDRSPACE)
2860 {
2861 addr_space_t as
2862 = name_token->keyword - RID_FIRST_ADDR_SPACE;
2863 declspecs_add_addrspace (name_token->location, specs, as);
2864 c_parser_consume_token (parser);
2865 attrs_ok = true;
2866 continue;
2867 }
2868
2869 gcc_assert (!c_parser_next_token_is_qualifier (parser));
2870
2871 /* If we cannot accept a type, and the next token must start one,
2872 exit. Do the same if we already have seen a tagged definition,
2873 since it would be an error anyway and likely the user has simply
2874 forgotten a semicolon. */
2875 if (seen_type || !c_parser_next_tokens_start_typename (parser, la))
2876 break;
2877
2878 /* Now at an unknown typename (C_ID_ID), a C_ID_TYPENAME or
2879 a C_ID_CLASSNAME. */
2880 c_parser_consume_token (parser);
2881 seen_type = true;
2882 attrs_ok = true;
2883 if (kind == C_ID_ID)
2884 {
2885 error_at (loc, "unknown type name %qE", value);
2886 t.kind = ctsk_typedef;
2887 t.spec = error_mark_node;
2888 }
2889 else if (kind == C_ID_TYPENAME
2890 && (!c_dialect_objc ()
2891 || c_parser_next_token_is_not (parser, CPP_LESS)))
2892 {
2893 t.kind = ctsk_typedef;
2894 /* For a typedef name, record the meaning, not the name.
2895 In case of 'foo foo, bar;'. */
2896 t.spec = lookup_name (value);
2897 }
2898 else
2899 {
2900 tree proto = NULL_TREE;
2901 gcc_assert (c_dialect_objc ());
2902 t.kind = ctsk_objc;
2903 if (c_parser_next_token_is (parser, CPP_LESS))
2904 proto = c_parser_objc_protocol_refs (parser);
2905 t.spec = objc_get_protocol_qualified_type (value, proto);
2906 }
2907 t.expr = NULL_TREE;
2908 t.expr_const_operands = true;
2909 declspecs_add_type (name_token->location, specs, t);
2910 continue;
2911 }
2912 if (c_parser_next_token_is (parser, CPP_LESS))
2913 {
2914 /* Make "<SomeProtocol>" equivalent to "id <SomeProtocol>" -
2915 nisse@lysator.liu.se. */
2916 tree proto;
2917 gcc_assert (c_dialect_objc ());
2918 if (!typespec_ok || seen_type)
2919 break;
2920 proto = c_parser_objc_protocol_refs (parser);
2921 t.kind = ctsk_objc;
2922 t.spec = objc_get_protocol_qualified_type (NULL_TREE, proto);
2923 t.expr = NULL_TREE;
2924 t.expr_const_operands = true;
2925 declspecs_add_type (loc, specs, t);
2926 continue;
2927 }
2928 gcc_assert (c_parser_next_token_is (parser, CPP_KEYWORD));
2929 switch (c_parser_peek_token (parser)->keyword)
2930 {
2931 case RID_STATIC:
2932 case RID_EXTERN:
2933 case RID_REGISTER:
2934 case RID_TYPEDEF:
2935 case RID_INLINE:
2936 case RID_NORETURN:
2937 case RID_AUTO:
2938 case RID_THREAD:
2939 if (!scspec_ok)
2940 goto out;
2941 attrs_ok = true;
2942 /* TODO: Distinguish between function specifiers (inline, noreturn)
2943 and storage class specifiers, either here or in
2944 declspecs_add_scspec. */
2945 declspecs_add_scspec (loc, specs,
2946 c_parser_peek_token (parser)->value);
2947 c_parser_consume_token (parser);
2948 break;
2949 case RID_AUTO_TYPE:
2950 if (!auto_type_ok)
2951 goto out;
2952 /* Fall through. */
2953 case RID_UNSIGNED:
2954 case RID_LONG:
2955 case RID_SHORT:
2956 case RID_SIGNED:
2957 case RID_COMPLEX:
2958 case RID_INT:
2959 case RID_CHAR:
2960 case RID_FLOAT:
2961 case RID_DOUBLE:
2962 case RID_VOID:
2963 case RID_DFLOAT32:
2964 case RID_DFLOAT64:
2965 case RID_DFLOAT128:
2966 CASE_RID_FLOATN_NX:
2967 case RID_BOOL:
2968 case RID_FRACT:
2969 case RID_ACCUM:
2970 case RID_SAT:
2971 case RID_INT_N_0:
2972 case RID_INT_N_1:
2973 case RID_INT_N_2:
2974 case RID_INT_N_3:
2975 if (!typespec_ok)
2976 goto out;
2977 attrs_ok = true;
2978 seen_type = true;
2979 if (c_dialect_objc ())
2980 parser->objc_need_raw_identifier = true;
2981 t.kind = ctsk_resword;
2982 t.spec = c_parser_peek_token (parser)->value;
2983 t.expr = NULL_TREE;
2984 t.expr_const_operands = true;
2985 declspecs_add_type (loc, specs, t);
2986 c_parser_consume_token (parser);
2987 break;
2988 case RID_ENUM:
2989 if (!typespec_ok)
2990 goto out;
2991 attrs_ok = true;
2992 seen_type = true;
2993 t = c_parser_enum_specifier (parser);
2994 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, t.spec);
2995 declspecs_add_type (loc, specs, t);
2996 break;
2997 case RID_STRUCT:
2998 case RID_UNION:
2999 if (!typespec_ok)
3000 goto out;
3001 attrs_ok = true;
3002 seen_type = true;
3003 t = c_parser_struct_or_union_specifier (parser);
3004 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, t.spec);
3005 declspecs_add_type (loc, specs, t);
3006 break;
3007 case RID_TYPEOF:
3008 /* ??? The old parser rejected typeof after other type
3009 specifiers, but is a syntax error the best way of
3010 handling this? */
3011 if (!typespec_ok || seen_type)
3012 goto out;
3013 attrs_ok = true;
3014 seen_type = true;
3015 t = c_parser_typeof_specifier (parser);
3016 declspecs_add_type (loc, specs, t);
3017 break;
3018 case RID_ATOMIC:
3019 /* C parser handling of Objective-C constructs needs
3020 checking for correct lvalue-to-rvalue conversions, and
3021 the code in build_modify_expr handling various
3022 Objective-C cases, and that in build_unary_op handling
3023 Objective-C cases for increment / decrement, also needs
3024 updating; uses of TYPE_MAIN_VARIANT in objc_compare_types
3025 and objc_types_are_equivalent may also need updates. */
3026 if (c_dialect_objc ())
3027 sorry ("%<_Atomic%> in Objective-C");
3028 if (flag_isoc99)
3029 pedwarn_c99 (loc, OPT_Wpedantic,
3030 "ISO C99 does not support the %<_Atomic%> qualifier");
3031 else
3032 pedwarn_c99 (loc, OPT_Wpedantic,
3033 "ISO C90 does not support the %<_Atomic%> qualifier");
3034 attrs_ok = true;
3035 tree value;
3036 value = c_parser_peek_token (parser)->value;
3037 c_parser_consume_token (parser);
3038 if (typespec_ok && c_parser_next_token_is (parser, CPP_OPEN_PAREN))
3039 {
3040 /* _Atomic ( type-name ). */
3041 seen_type = true;
3042 c_parser_consume_token (parser);
3043 struct c_type_name *type = c_parser_type_name (parser);
3044 t.kind = ctsk_typeof;
3045 t.spec = error_mark_node;
3046 t.expr = NULL_TREE;
3047 t.expr_const_operands = true;
3048 if (type != NULL)
3049 t.spec = groktypename (type, &t.expr,
3050 &t.expr_const_operands);
3051 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
3052 "expected %<)%>");
3053 if (t.spec != error_mark_node)
3054 {
3055 if (TREE_CODE (t.spec) == ARRAY_TYPE)
3056 error_at (loc, "%<_Atomic%>-qualified array type");
3057 else if (TREE_CODE (t.spec) == FUNCTION_TYPE)
3058 error_at (loc, "%<_Atomic%>-qualified function type");
3059 else if (TYPE_QUALS (t.spec) != TYPE_UNQUALIFIED)
3060 error_at (loc, "%<_Atomic%> applied to a qualified type");
3061 else
3062 t.spec = c_build_qualified_type (t.spec, TYPE_QUAL_ATOMIC);
3063 }
3064 declspecs_add_type (loc, specs, t);
3065 }
3066 else
3067 declspecs_add_qual (loc, specs, value);
3068 break;
3069 case RID_CONST:
3070 case RID_VOLATILE:
3071 case RID_RESTRICT:
3072 attrs_ok = true;
3073 declspecs_add_qual (loc, specs, c_parser_peek_token (parser)->value);
3074 c_parser_consume_token (parser);
3075 break;
3076 case RID_ATTRIBUTE:
3077 if (!attrs_ok)
3078 goto out;
3079 attrs = c_parser_gnu_attributes (parser);
3080 declspecs_add_attrs (loc, specs, attrs);
3081 break;
3082 case RID_ALIGNAS:
3083 if (!alignspec_ok)
3084 goto out;
3085 align = c_parser_alignas_specifier (parser);
3086 declspecs_add_alignas (loc, specs, align);
3087 break;
3088 case RID_GIMPLE:
3089 if (! flag_gimple)
3090 error_at (loc, "%<__GIMPLE%> only valid with %<-fgimple%>");
3091 c_parser_consume_token (parser);
3092 specs->declspec_il = cdil_gimple;
3093 specs->locations[cdw_gimple] = loc;
3094 c_parser_gimple_or_rtl_pass_list (parser, specs);
3095 break;
3096 case RID_RTL:
3097 c_parser_consume_token (parser);
3098 specs->declspec_il = cdil_rtl;
3099 specs->locations[cdw_rtl] = loc;
3100 c_parser_gimple_or_rtl_pass_list (parser, specs);
3101 break;
3102 default:
3103 goto out;
3104 }
3105 }
3106 out:
3107 if (end_std_attr_ok
3108 && c_parser_nth_token_starts_std_attributes (parser, 1))
3109 specs->postfix_attrs = c_parser_std_attribute_specifier_sequence (parser);
3110 }
3111
3112 /* Parse an enum specifier (C90 6.5.2.2, C99 6.7.2.2, C11 6.7.2.2).
3113
3114 enum-specifier:
3115 enum gnu-attributes[opt] identifier[opt] { enumerator-list }
3116 gnu-attributes[opt]
3117 enum gnu-attributes[opt] identifier[opt] { enumerator-list , }
3118 gnu-attributes[opt]
3119 enum gnu-attributes[opt] identifier
3120
3121 The form with trailing comma is new in C99. The forms with
3122 gnu-attributes are GNU extensions. In GNU C, we accept any expression
3123 without commas in the syntax (assignment expressions, not just
3124 conditional expressions); assignment expressions will be diagnosed
3125 as non-constant.
3126
3127 enumerator-list:
3128 enumerator
3129 enumerator-list , enumerator
3130
3131 enumerator:
3132 enumeration-constant attribute-specifier-sequence[opt]
3133 enumeration-constant attribute-specifier-sequence[opt]
3134 = constant-expression
3135
3136 GNU Extensions:
3137
3138 enumerator:
3139 enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt]
3140 enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt]
3141 = constant-expression
3142
3143 */
3144
3145 static struct c_typespec
c_parser_enum_specifier(c_parser * parser)3146 c_parser_enum_specifier (c_parser *parser)
3147 {
3148 struct c_typespec ret;
3149 bool have_std_attrs;
3150 tree std_attrs = NULL_TREE;
3151 tree attrs;
3152 tree ident = NULL_TREE;
3153 location_t enum_loc;
3154 location_t ident_loc = UNKNOWN_LOCATION; /* Quiet warning. */
3155 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ENUM));
3156 c_parser_consume_token (parser);
3157 have_std_attrs = c_parser_nth_token_starts_std_attributes (parser, 1);
3158 if (have_std_attrs)
3159 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
3160 attrs = c_parser_gnu_attributes (parser);
3161 enum_loc = c_parser_peek_token (parser)->location;
3162 /* Set the location in case we create a decl now. */
3163 c_parser_set_source_position_from_token (c_parser_peek_token (parser));
3164 if (c_parser_next_token_is (parser, CPP_NAME))
3165 {
3166 ident = c_parser_peek_token (parser)->value;
3167 ident_loc = c_parser_peek_token (parser)->location;
3168 enum_loc = ident_loc;
3169 c_parser_consume_token (parser);
3170 }
3171 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
3172 {
3173 /* Parse an enum definition. */
3174 struct c_enum_contents the_enum;
3175 tree type;
3176 tree postfix_attrs;
3177 /* We chain the enumerators in reverse order, then put them in
3178 forward order at the end. */
3179 tree values;
3180 timevar_push (TV_PARSE_ENUM);
3181 type = start_enum (enum_loc, &the_enum, ident);
3182 values = NULL_TREE;
3183 c_parser_consume_token (parser);
3184 while (true)
3185 {
3186 tree enum_id;
3187 tree enum_value;
3188 tree enum_decl;
3189 bool seen_comma;
3190 c_token *token;
3191 location_t comma_loc = UNKNOWN_LOCATION; /* Quiet warning. */
3192 location_t decl_loc, value_loc;
3193 if (c_parser_next_token_is_not (parser, CPP_NAME))
3194 {
3195 /* Give a nicer error for "enum {}". */
3196 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)
3197 && !parser->error)
3198 {
3199 error_at (c_parser_peek_token (parser)->location,
3200 "empty enum is invalid");
3201 parser->error = true;
3202 }
3203 else
3204 c_parser_error (parser, "expected identifier");
3205 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
3206 values = error_mark_node;
3207 break;
3208 }
3209 token = c_parser_peek_token (parser);
3210 enum_id = token->value;
3211 /* Set the location in case we create a decl now. */
3212 c_parser_set_source_position_from_token (token);
3213 decl_loc = value_loc = token->location;
3214 c_parser_consume_token (parser);
3215 /* Parse any specified attributes. */
3216 tree std_attrs = NULL_TREE;
3217 if (c_parser_nth_token_starts_std_attributes (parser, 1))
3218 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
3219 tree enum_attrs = chainon (std_attrs,
3220 c_parser_gnu_attributes (parser));
3221 if (c_parser_next_token_is (parser, CPP_EQ))
3222 {
3223 c_parser_consume_token (parser);
3224 value_loc = c_parser_peek_token (parser)->location;
3225 enum_value = c_parser_expr_no_commas (parser, NULL).value;
3226 }
3227 else
3228 enum_value = NULL_TREE;
3229 enum_decl = build_enumerator (decl_loc, value_loc,
3230 &the_enum, enum_id, enum_value);
3231 if (enum_attrs)
3232 decl_attributes (&TREE_PURPOSE (enum_decl), enum_attrs, 0);
3233 TREE_CHAIN (enum_decl) = values;
3234 values = enum_decl;
3235 seen_comma = false;
3236 if (c_parser_next_token_is (parser, CPP_COMMA))
3237 {
3238 comma_loc = c_parser_peek_token (parser)->location;
3239 seen_comma = true;
3240 c_parser_consume_token (parser);
3241 }
3242 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3243 {
3244 if (seen_comma)
3245 pedwarn_c90 (comma_loc, OPT_Wpedantic,
3246 "comma at end of enumerator list");
3247 c_parser_consume_token (parser);
3248 break;
3249 }
3250 if (!seen_comma)
3251 {
3252 c_parser_error (parser, "expected %<,%> or %<}%>");
3253 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
3254 values = error_mark_node;
3255 break;
3256 }
3257 }
3258 postfix_attrs = c_parser_gnu_attributes (parser);
3259 ret.spec = finish_enum (type, nreverse (values),
3260 chainon (std_attrs,
3261 chainon (attrs, postfix_attrs)));
3262 ret.kind = ctsk_tagdef;
3263 ret.expr = NULL_TREE;
3264 ret.expr_const_operands = true;
3265 timevar_pop (TV_PARSE_ENUM);
3266 return ret;
3267 }
3268 else if (!ident)
3269 {
3270 c_parser_error (parser, "expected %<{%>");
3271 ret.spec = error_mark_node;
3272 ret.kind = ctsk_tagref;
3273 ret.expr = NULL_TREE;
3274 ret.expr_const_operands = true;
3275 return ret;
3276 }
3277 /* Attributes may only appear when the members are defined or in
3278 certain forward declarations (treat enum forward declarations in
3279 GNU C analogously to struct and union forward declarations in
3280 standard C). */
3281 if (have_std_attrs && c_parser_next_token_is_not (parser, CPP_SEMICOLON))
3282 c_parser_error (parser, "expected %<;%>");
3283 ret = parser_xref_tag (ident_loc, ENUMERAL_TYPE, ident, have_std_attrs,
3284 std_attrs);
3285 /* In ISO C, enumerated types can be referred to only if already
3286 defined. */
3287 if (pedantic && !COMPLETE_TYPE_P (ret.spec))
3288 {
3289 gcc_assert (ident);
3290 pedwarn (enum_loc, OPT_Wpedantic,
3291 "ISO C forbids forward references to %<enum%> types");
3292 }
3293 return ret;
3294 }
3295
3296 /* Parse a struct or union specifier (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1).
3297
3298 struct-or-union-specifier:
3299 struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
3300 identifier[opt] { struct-contents } gnu-attributes[opt]
3301 struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
3302 identifier
3303
3304 struct-contents:
3305 struct-declaration-list
3306
3307 struct-declaration-list:
3308 struct-declaration ;
3309 struct-declaration-list struct-declaration ;
3310
3311 GNU extensions:
3312
3313 struct-contents:
3314 empty
3315 struct-declaration
3316 struct-declaration-list struct-declaration
3317
3318 struct-declaration-list:
3319 struct-declaration-list ;
3320 ;
3321
3322 (Note that in the syntax here, unlike that in ISO C, the semicolons
3323 are included here rather than in struct-declaration, in order to
3324 describe the syntax with extra semicolons and missing semicolon at
3325 end.)
3326
3327 Objective-C:
3328
3329 struct-declaration-list:
3330 @defs ( class-name )
3331
3332 (Note this does not include a trailing semicolon, but can be
3333 followed by further declarations, and gets a pedwarn-if-pedantic
3334 when followed by a semicolon.) */
3335
3336 static struct c_typespec
c_parser_struct_or_union_specifier(c_parser * parser)3337 c_parser_struct_or_union_specifier (c_parser *parser)
3338 {
3339 struct c_typespec ret;
3340 bool have_std_attrs;
3341 tree std_attrs = NULL_TREE;
3342 tree attrs;
3343 tree ident = NULL_TREE;
3344 location_t struct_loc;
3345 location_t ident_loc = UNKNOWN_LOCATION;
3346 enum tree_code code;
3347 switch (c_parser_peek_token (parser)->keyword)
3348 {
3349 case RID_STRUCT:
3350 code = RECORD_TYPE;
3351 break;
3352 case RID_UNION:
3353 code = UNION_TYPE;
3354 break;
3355 default:
3356 gcc_unreachable ();
3357 }
3358 struct_loc = c_parser_peek_token (parser)->location;
3359 c_parser_consume_token (parser);
3360 have_std_attrs = c_parser_nth_token_starts_std_attributes (parser, 1);
3361 if (have_std_attrs)
3362 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
3363 attrs = c_parser_gnu_attributes (parser);
3364
3365 /* Set the location in case we create a decl now. */
3366 c_parser_set_source_position_from_token (c_parser_peek_token (parser));
3367
3368 if (c_parser_next_token_is (parser, CPP_NAME))
3369 {
3370 ident = c_parser_peek_token (parser)->value;
3371 ident_loc = c_parser_peek_token (parser)->location;
3372 struct_loc = ident_loc;
3373 c_parser_consume_token (parser);
3374 }
3375 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
3376 {
3377 /* Parse a struct or union definition. Start the scope of the
3378 tag before parsing components. */
3379 class c_struct_parse_info *struct_info;
3380 tree type = start_struct (struct_loc, code, ident, &struct_info);
3381 tree postfix_attrs;
3382 /* We chain the components in reverse order, then put them in
3383 forward order at the end. Each struct-declaration may
3384 declare multiple components (comma-separated), so we must use
3385 chainon to join them, although when parsing each
3386 struct-declaration we can use TREE_CHAIN directly.
3387
3388 The theory behind all this is that there will be more
3389 semicolon separated fields than comma separated fields, and
3390 so we'll be minimizing the number of node traversals required
3391 by chainon. */
3392 tree contents;
3393 timevar_push (TV_PARSE_STRUCT);
3394 contents = NULL_TREE;
3395 c_parser_consume_token (parser);
3396 /* Handle the Objective-C @defs construct,
3397 e.g. foo(sizeof(struct{ @defs(ClassName) }));. */
3398 if (c_parser_next_token_is_keyword (parser, RID_AT_DEFS))
3399 {
3400 tree name;
3401 gcc_assert (c_dialect_objc ());
3402 c_parser_consume_token (parser);
3403 matching_parens parens;
3404 if (!parens.require_open (parser))
3405 goto end_at_defs;
3406 if (c_parser_next_token_is (parser, CPP_NAME)
3407 && c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME)
3408 {
3409 name = c_parser_peek_token (parser)->value;
3410 c_parser_consume_token (parser);
3411 }
3412 else
3413 {
3414 c_parser_error (parser, "expected class name");
3415 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
3416 goto end_at_defs;
3417 }
3418 parens.skip_until_found_close (parser);
3419 contents = nreverse (objc_get_class_ivars (name));
3420 }
3421 end_at_defs:
3422 /* Parse the struct-declarations and semicolons. Problems with
3423 semicolons are diagnosed here; empty structures are diagnosed
3424 elsewhere. */
3425 while (true)
3426 {
3427 tree decls;
3428 /* Parse any stray semicolon. */
3429 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
3430 {
3431 location_t semicolon_loc
3432 = c_parser_peek_token (parser)->location;
3433 gcc_rich_location richloc (semicolon_loc);
3434 richloc.add_fixit_remove ();
3435 pedwarn (&richloc, OPT_Wpedantic,
3436 "extra semicolon in struct or union specified");
3437 c_parser_consume_token (parser);
3438 continue;
3439 }
3440 /* Stop if at the end of the struct or union contents. */
3441 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3442 {
3443 c_parser_consume_token (parser);
3444 break;
3445 }
3446 /* Accept #pragmas at struct scope. */
3447 if (c_parser_next_token_is (parser, CPP_PRAGMA))
3448 {
3449 c_parser_pragma (parser, pragma_struct, NULL);
3450 continue;
3451 }
3452 /* Parse some comma-separated declarations, but not the
3453 trailing semicolon if any. */
3454 decls = c_parser_struct_declaration (parser);
3455 contents = chainon (decls, contents);
3456 /* If no semicolon follows, either we have a parse error or
3457 are at the end of the struct or union and should
3458 pedwarn. */
3459 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
3460 c_parser_consume_token (parser);
3461 else
3462 {
3463 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3464 pedwarn (c_parser_peek_token (parser)->location, 0,
3465 "no semicolon at end of struct or union");
3466 else if (parser->error
3467 || !c_parser_next_token_starts_declspecs (parser))
3468 {
3469 c_parser_error (parser, "expected %<;%>");
3470 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
3471 break;
3472 }
3473
3474 /* If we come here, we have already emitted an error
3475 for an expected `;', identifier or `(', and we also
3476 recovered already. Go on with the next field. */
3477 }
3478 }
3479 postfix_attrs = c_parser_gnu_attributes (parser);
3480 ret.spec = finish_struct (struct_loc, type, nreverse (contents),
3481 chainon (std_attrs,
3482 chainon (attrs, postfix_attrs)),
3483 struct_info);
3484 ret.kind = ctsk_tagdef;
3485 ret.expr = NULL_TREE;
3486 ret.expr_const_operands = true;
3487 timevar_pop (TV_PARSE_STRUCT);
3488 return ret;
3489 }
3490 else if (!ident)
3491 {
3492 c_parser_error (parser, "expected %<{%>");
3493 ret.spec = error_mark_node;
3494 ret.kind = ctsk_tagref;
3495 ret.expr = NULL_TREE;
3496 ret.expr_const_operands = true;
3497 return ret;
3498 }
3499 /* Attributes may only appear when the members are defined or in
3500 certain forward declarations. */
3501 if (have_std_attrs && c_parser_next_token_is_not (parser, CPP_SEMICOLON))
3502 c_parser_error (parser, "expected %<;%>");
3503 /* ??? Existing practice is that GNU attributes are ignored after
3504 the struct or union keyword when not defining the members. */
3505 ret = parser_xref_tag (ident_loc, code, ident, have_std_attrs, std_attrs);
3506 return ret;
3507 }
3508
3509 /* Parse a struct-declaration (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1),
3510 *without* the trailing semicolon.
3511
3512 struct-declaration:
3513 attribute-specifier-sequence[opt] specifier-qualifier-list
3514 attribute-specifier-sequence[opt] struct-declarator-list
3515 static_assert-declaration-no-semi
3516
3517 specifier-qualifier-list:
3518 type-specifier specifier-qualifier-list[opt]
3519 type-qualifier specifier-qualifier-list[opt]
3520 alignment-specifier specifier-qualifier-list[opt]
3521 gnu-attributes specifier-qualifier-list[opt]
3522
3523 struct-declarator-list:
3524 struct-declarator
3525 struct-declarator-list , gnu-attributes[opt] struct-declarator
3526
3527 struct-declarator:
3528 declarator gnu-attributes[opt]
3529 declarator[opt] : constant-expression gnu-attributes[opt]
3530
3531 GNU extensions:
3532
3533 struct-declaration:
3534 __extension__ struct-declaration
3535 specifier-qualifier-list
3536
3537 Unlike the ISO C syntax, semicolons are handled elsewhere. The use
3538 of gnu-attributes where shown is a GNU extension. In GNU C, we accept
3539 any expression without commas in the syntax (assignment
3540 expressions, not just conditional expressions); assignment
3541 expressions will be diagnosed as non-constant. */
3542
3543 static tree
c_parser_struct_declaration(c_parser * parser)3544 c_parser_struct_declaration (c_parser *parser)
3545 {
3546 struct c_declspecs *specs;
3547 tree prefix_attrs;
3548 tree all_prefix_attrs;
3549 tree decls;
3550 location_t decl_loc;
3551 if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
3552 {
3553 int ext;
3554 tree decl;
3555 ext = disable_extension_diagnostics ();
3556 c_parser_consume_token (parser);
3557 decl = c_parser_struct_declaration (parser);
3558 restore_extension_diagnostics (ext);
3559 return decl;
3560 }
3561 if (c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
3562 {
3563 c_parser_static_assert_declaration_no_semi (parser);
3564 return NULL_TREE;
3565 }
3566 specs = build_null_declspecs ();
3567 decl_loc = c_parser_peek_token (parser)->location;
3568 /* Strictly by the standard, we shouldn't allow _Alignas here,
3569 but it appears to have been intended to allow it there, so
3570 we're keeping it as it is until WG14 reaches a conclusion
3571 of N1731.
3572 <http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1731.pdf> */
3573 c_parser_declspecs (parser, specs, false, true, true,
3574 true, false, true, true, cla_nonabstract_decl);
3575 if (parser->error)
3576 return NULL_TREE;
3577 if (!specs->declspecs_seen_p)
3578 {
3579 c_parser_error (parser, "expected specifier-qualifier-list");
3580 return NULL_TREE;
3581 }
3582 finish_declspecs (specs);
3583 if (c_parser_next_token_is (parser, CPP_SEMICOLON)
3584 || c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3585 {
3586 tree ret;
3587 if (specs->typespec_kind == ctsk_none)
3588 {
3589 pedwarn (decl_loc, OPT_Wpedantic,
3590 "ISO C forbids member declarations with no members");
3591 shadow_tag_warned (specs, pedantic);
3592 ret = NULL_TREE;
3593 }
3594 else
3595 {
3596 /* Support for unnamed structs or unions as members of
3597 structs or unions (which is [a] useful and [b] supports
3598 MS P-SDK). */
3599 tree attrs = NULL;
3600
3601 ret = grokfield (c_parser_peek_token (parser)->location,
3602 build_id_declarator (NULL_TREE), specs,
3603 NULL_TREE, &attrs);
3604 if (ret)
3605 decl_attributes (&ret, attrs, 0);
3606 }
3607 return ret;
3608 }
3609
3610 /* Provide better error recovery. Note that a type name here is valid,
3611 and will be treated as a field name. */
3612 if (specs->typespec_kind == ctsk_tagdef
3613 && TREE_CODE (specs->type) != ENUMERAL_TYPE
3614 && c_parser_next_token_starts_declspecs (parser)
3615 && !c_parser_next_token_is (parser, CPP_NAME))
3616 {
3617 c_parser_error (parser, "expected %<;%>, identifier or %<(%>");
3618 parser->error = false;
3619 return NULL_TREE;
3620 }
3621
3622 pending_xref_error ();
3623 prefix_attrs = specs->attrs;
3624 all_prefix_attrs = prefix_attrs;
3625 specs->attrs = NULL_TREE;
3626 decls = NULL_TREE;
3627 while (true)
3628 {
3629 /* Declaring one or more declarators or un-named bit-fields. */
3630 struct c_declarator *declarator;
3631 bool dummy = false;
3632 if (c_parser_next_token_is (parser, CPP_COLON))
3633 declarator = build_id_declarator (NULL_TREE);
3634 else
3635 declarator = c_parser_declarator (parser,
3636 specs->typespec_kind != ctsk_none,
3637 C_DTR_NORMAL, &dummy);
3638 if (declarator == NULL)
3639 {
3640 c_parser_skip_to_end_of_block_or_statement (parser);
3641 break;
3642 }
3643 if (c_parser_next_token_is (parser, CPP_COLON)
3644 || c_parser_next_token_is (parser, CPP_COMMA)
3645 || c_parser_next_token_is (parser, CPP_SEMICOLON)
3646 || c_parser_next_token_is (parser, CPP_CLOSE_BRACE)
3647 || c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
3648 {
3649 tree postfix_attrs = NULL_TREE;
3650 tree width = NULL_TREE;
3651 tree d;
3652 if (c_parser_next_token_is (parser, CPP_COLON))
3653 {
3654 c_parser_consume_token (parser);
3655 width = c_parser_expr_no_commas (parser, NULL).value;
3656 }
3657 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
3658 postfix_attrs = c_parser_gnu_attributes (parser);
3659 d = grokfield (c_parser_peek_token (parser)->location,
3660 declarator, specs, width, &all_prefix_attrs);
3661 decl_attributes (&d, chainon (postfix_attrs,
3662 all_prefix_attrs), 0);
3663 DECL_CHAIN (d) = decls;
3664 decls = d;
3665 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
3666 all_prefix_attrs = chainon (c_parser_gnu_attributes (parser),
3667 prefix_attrs);
3668 else
3669 all_prefix_attrs = prefix_attrs;
3670 if (c_parser_next_token_is (parser, CPP_COMMA))
3671 c_parser_consume_token (parser);
3672 else if (c_parser_next_token_is (parser, CPP_SEMICOLON)
3673 || c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3674 {
3675 /* Semicolon consumed in caller. */
3676 break;
3677 }
3678 else
3679 {
3680 c_parser_error (parser, "expected %<,%>, %<;%> or %<}%>");
3681 break;
3682 }
3683 }
3684 else
3685 {
3686 c_parser_error (parser,
3687 "expected %<:%>, %<,%>, %<;%>, %<}%> or "
3688 "%<__attribute__%>");
3689 break;
3690 }
3691 }
3692 return decls;
3693 }
3694
3695 /* Parse a typeof specifier (a GNU extension).
3696
3697 typeof-specifier:
3698 typeof ( expression )
3699 typeof ( type-name )
3700 */
3701
3702 static struct c_typespec
c_parser_typeof_specifier(c_parser * parser)3703 c_parser_typeof_specifier (c_parser *parser)
3704 {
3705 struct c_typespec ret;
3706 ret.kind = ctsk_typeof;
3707 ret.spec = error_mark_node;
3708 ret.expr = NULL_TREE;
3709 ret.expr_const_operands = true;
3710 gcc_assert (c_parser_next_token_is_keyword (parser, RID_TYPEOF));
3711 c_parser_consume_token (parser);
3712 c_inhibit_evaluation_warnings++;
3713 in_typeof++;
3714 matching_parens parens;
3715 if (!parens.require_open (parser))
3716 {
3717 c_inhibit_evaluation_warnings--;
3718 in_typeof--;
3719 return ret;
3720 }
3721 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
3722 {
3723 struct c_type_name *type = c_parser_type_name (parser);
3724 c_inhibit_evaluation_warnings--;
3725 in_typeof--;
3726 if (type != NULL)
3727 {
3728 ret.spec = groktypename (type, &ret.expr, &ret.expr_const_operands);
3729 pop_maybe_used (variably_modified_type_p (ret.spec, NULL_TREE));
3730 }
3731 }
3732 else
3733 {
3734 bool was_vm;
3735 location_t here = c_parser_peek_token (parser)->location;
3736 struct c_expr expr = c_parser_expression (parser);
3737 c_inhibit_evaluation_warnings--;
3738 in_typeof--;
3739 if (TREE_CODE (expr.value) == COMPONENT_REF
3740 && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
3741 error_at (here, "%<typeof%> applied to a bit-field");
3742 mark_exp_read (expr.value);
3743 ret.spec = TREE_TYPE (expr.value);
3744 was_vm = variably_modified_type_p (ret.spec, NULL_TREE);
3745 /* This is returned with the type so that when the type is
3746 evaluated, this can be evaluated. */
3747 if (was_vm)
3748 ret.expr = c_fully_fold (expr.value, false, &ret.expr_const_operands);
3749 pop_maybe_used (was_vm);
3750 }
3751 parens.skip_until_found_close (parser);
3752 return ret;
3753 }
3754
3755 /* Parse an alignment-specifier.
3756
3757 C11 6.7.5:
3758
3759 alignment-specifier:
3760 _Alignas ( type-name )
3761 _Alignas ( constant-expression )
3762 */
3763
3764 static tree
c_parser_alignas_specifier(c_parser * parser)3765 c_parser_alignas_specifier (c_parser * parser)
3766 {
3767 tree ret = error_mark_node;
3768 location_t loc = c_parser_peek_token (parser)->location;
3769 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ALIGNAS));
3770 c_parser_consume_token (parser);
3771 if (flag_isoc99)
3772 pedwarn_c99 (loc, OPT_Wpedantic,
3773 "ISO C99 does not support %<_Alignas%>");
3774 else
3775 pedwarn_c99 (loc, OPT_Wpedantic,
3776 "ISO C90 does not support %<_Alignas%>");
3777 matching_parens parens;
3778 if (!parens.require_open (parser))
3779 return ret;
3780 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
3781 {
3782 struct c_type_name *type = c_parser_type_name (parser);
3783 if (type != NULL)
3784 ret = c_sizeof_or_alignof_type (loc, groktypename (type, NULL, NULL),
3785 false, true, 1);
3786 }
3787 else
3788 ret = c_parser_expr_no_commas (parser, NULL).value;
3789 parens.skip_until_found_close (parser);
3790 return ret;
3791 }
3792
3793 /* Parse a declarator, possibly an abstract declarator (C90 6.5.4,
3794 6.5.5, C99 6.7.5, 6.7.6, C11 6.7.6, 6.7.7). If TYPE_SEEN_P then
3795 a typedef name may be redeclared; otherwise it may not. KIND
3796 indicates which kind of declarator is wanted. Returns a valid
3797 declarator except in the case of a syntax error in which case NULL is
3798 returned. *SEEN_ID is set to true if an identifier being declared is
3799 seen; this is used to diagnose bad forms of abstract array declarators
3800 and to determine whether an identifier list is syntactically permitted.
3801
3802 declarator:
3803 pointer[opt] direct-declarator
3804
3805 direct-declarator:
3806 identifier
3807 ( gnu-attributes[opt] declarator )
3808 direct-declarator array-declarator
3809 direct-declarator ( parameter-type-list )
3810 direct-declarator ( identifier-list[opt] )
3811
3812 pointer:
3813 * type-qualifier-list[opt]
3814 * type-qualifier-list[opt] pointer
3815
3816 type-qualifier-list:
3817 type-qualifier
3818 gnu-attributes
3819 type-qualifier-list type-qualifier
3820 type-qualifier-list gnu-attributes
3821
3822 array-declarator:
3823 [ type-qualifier-list[opt] assignment-expression[opt] ]
3824 [ static type-qualifier-list[opt] assignment-expression ]
3825 [ type-qualifier-list static assignment-expression ]
3826 [ type-qualifier-list[opt] * ]
3827
3828 parameter-type-list:
3829 parameter-list
3830 parameter-list , ...
3831
3832 parameter-list:
3833 parameter-declaration
3834 parameter-list , parameter-declaration
3835
3836 parameter-declaration:
3837 declaration-specifiers declarator gnu-attributes[opt]
3838 declaration-specifiers abstract-declarator[opt] gnu-attributes[opt]
3839
3840 identifier-list:
3841 identifier
3842 identifier-list , identifier
3843
3844 abstract-declarator:
3845 pointer
3846 pointer[opt] direct-abstract-declarator
3847
3848 direct-abstract-declarator:
3849 ( gnu-attributes[opt] abstract-declarator )
3850 direct-abstract-declarator[opt] array-declarator
3851 direct-abstract-declarator[opt] ( parameter-type-list[opt] )
3852
3853 GNU extensions:
3854
3855 direct-declarator:
3856 direct-declarator ( parameter-forward-declarations
3857 parameter-type-list[opt] )
3858
3859 direct-abstract-declarator:
3860 direct-abstract-declarator[opt] ( parameter-forward-declarations
3861 parameter-type-list[opt] )
3862
3863 parameter-forward-declarations:
3864 parameter-list ;
3865 parameter-forward-declarations parameter-list ;
3866
3867 The uses of gnu-attributes shown above are GNU extensions.
3868
3869 Some forms of array declarator are not included in C99 in the
3870 syntax for abstract declarators; these are disallowed elsewhere.
3871 This may be a defect (DR#289).
3872
3873 This function also accepts an omitted abstract declarator as being
3874 an abstract declarator, although not part of the formal syntax. */
3875
3876 struct c_declarator *
c_parser_declarator(c_parser * parser,bool type_seen_p,c_dtr_syn kind,bool * seen_id)3877 c_parser_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
3878 bool *seen_id)
3879 {
3880 /* Parse any initial pointer part. */
3881 if (c_parser_next_token_is (parser, CPP_MULT))
3882 {
3883 struct c_declspecs *quals_attrs = build_null_declspecs ();
3884 struct c_declarator *inner;
3885 c_parser_consume_token (parser);
3886 c_parser_declspecs (parser, quals_attrs, false, false, true,
3887 false, false, true, false, cla_prefer_id);
3888 inner = c_parser_declarator (parser, type_seen_p, kind, seen_id);
3889 if (inner == NULL)
3890 return NULL;
3891 else
3892 return make_pointer_declarator (quals_attrs, inner);
3893 }
3894 /* Now we have a direct declarator, direct abstract declarator or
3895 nothing (which counts as a direct abstract declarator here). */
3896 return c_parser_direct_declarator (parser, type_seen_p, kind, seen_id);
3897 }
3898
3899 /* Parse a direct declarator or direct abstract declarator; arguments
3900 as c_parser_declarator. */
3901
3902 static struct c_declarator *
c_parser_direct_declarator(c_parser * parser,bool type_seen_p,c_dtr_syn kind,bool * seen_id)3903 c_parser_direct_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
3904 bool *seen_id)
3905 {
3906 /* The direct declarator must start with an identifier (possibly
3907 omitted) or a parenthesized declarator (possibly abstract). In
3908 an ordinary declarator, initial parentheses must start a
3909 parenthesized declarator. In an abstract declarator or parameter
3910 declarator, they could start a parenthesized declarator or a
3911 parameter list. To tell which, the open parenthesis and any
3912 following gnu-attributes must be read. If a declaration
3913 specifier or standard attributes follow, then it is a parameter
3914 list; if the specifier is a typedef name, there might be an
3915 ambiguity about redeclaring it, which is resolved in the
3916 direction of treating it as a typedef name. If a close
3917 parenthesis follows, it is also an empty parameter list, as the
3918 syntax does not permit empty abstract declarators. Otherwise, it
3919 is a parenthesized declarator (in which case the analysis may be
3920 repeated inside it, recursively).
3921
3922 ??? There is an ambiguity in a parameter declaration "int
3923 (__attribute__((foo)) x)", where x is not a typedef name: it
3924 could be an abstract declarator for a function, or declare x with
3925 parentheses. The proper resolution of this ambiguity needs
3926 documenting. At present we follow an accident of the old
3927 parser's implementation, whereby the first parameter must have
3928 some declaration specifiers other than just gnu-attributes. Thus as
3929 a parameter declaration it is treated as a parenthesized
3930 parameter named x, and as an abstract declarator it is
3931 rejected.
3932
3933 ??? Also following the old parser, gnu-attributes inside an empty
3934 parameter list are ignored, making it a list not yielding a
3935 prototype, rather than giving an error or making it have one
3936 parameter with implicit type int.
3937
3938 ??? Also following the old parser, typedef names may be
3939 redeclared in declarators, but not Objective-C class names. */
3940
3941 if (kind != C_DTR_ABSTRACT
3942 && c_parser_next_token_is (parser, CPP_NAME)
3943 && ((type_seen_p
3944 && (c_parser_peek_token (parser)->id_kind == C_ID_TYPENAME
3945 || c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME))
3946 || c_parser_peek_token (parser)->id_kind == C_ID_ID))
3947 {
3948 struct c_declarator *inner
3949 = build_id_declarator (c_parser_peek_token (parser)->value);
3950 *seen_id = true;
3951 inner->id_loc = c_parser_peek_token (parser)->location;
3952 c_parser_consume_token (parser);
3953 if (c_parser_nth_token_starts_std_attributes (parser, 1))
3954 inner->u.id.attrs = c_parser_std_attribute_specifier_sequence (parser);
3955 return c_parser_direct_declarator_inner (parser, *seen_id, inner);
3956 }
3957
3958 if (kind != C_DTR_NORMAL
3959 && c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
3960 && !c_parser_nth_token_starts_std_attributes (parser, 1))
3961 {
3962 struct c_declarator *inner = build_id_declarator (NULL_TREE);
3963 inner->id_loc = c_parser_peek_token (parser)->location;
3964 return c_parser_direct_declarator_inner (parser, *seen_id, inner);
3965 }
3966
3967 /* Either we are at the end of an abstract declarator, or we have
3968 parentheses. */
3969
3970 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
3971 {
3972 tree attrs;
3973 struct c_declarator *inner;
3974 c_parser_consume_token (parser);
3975 bool have_gnu_attrs = c_parser_next_token_is_keyword (parser,
3976 RID_ATTRIBUTE);
3977 attrs = c_parser_gnu_attributes (parser);
3978 if (kind != C_DTR_NORMAL
3979 && (c_parser_next_token_starts_declspecs (parser)
3980 || (!have_gnu_attrs
3981 && c_parser_nth_token_starts_std_attributes (parser, 1))
3982 || c_parser_next_token_is (parser, CPP_CLOSE_PAREN)))
3983 {
3984 struct c_arg_info *args
3985 = c_parser_parms_declarator (parser, kind == C_DTR_NORMAL,
3986 attrs, have_gnu_attrs);
3987 if (args == NULL)
3988 return NULL;
3989 else
3990 {
3991 inner = build_id_declarator (NULL_TREE);
3992 if (!(args->types
3993 && args->types != error_mark_node
3994 && TREE_CODE (TREE_VALUE (args->types)) == IDENTIFIER_NODE)
3995 && c_parser_nth_token_starts_std_attributes (parser, 1))
3996 {
3997 tree std_attrs
3998 = c_parser_std_attribute_specifier_sequence (parser);
3999 if (std_attrs)
4000 inner = build_attrs_declarator (std_attrs, inner);
4001 }
4002 inner = build_function_declarator (args, inner);
4003 return c_parser_direct_declarator_inner (parser, *seen_id,
4004 inner);
4005 }
4006 }
4007 /* A parenthesized declarator. */
4008 inner = c_parser_declarator (parser, type_seen_p, kind, seen_id);
4009 if (inner != NULL && attrs != NULL)
4010 inner = build_attrs_declarator (attrs, inner);
4011 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4012 {
4013 c_parser_consume_token (parser);
4014 if (inner == NULL)
4015 return NULL;
4016 else
4017 return c_parser_direct_declarator_inner (parser, *seen_id, inner);
4018 }
4019 else
4020 {
4021 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4022 "expected %<)%>");
4023 return NULL;
4024 }
4025 }
4026 else
4027 {
4028 if (kind == C_DTR_NORMAL)
4029 {
4030 c_parser_error (parser, "expected identifier or %<(%>");
4031 return NULL;
4032 }
4033 else
4034 return build_id_declarator (NULL_TREE);
4035 }
4036 }
4037
4038 /* Parse part of a direct declarator or direct abstract declarator,
4039 given that some (in INNER) has already been parsed; ID_PRESENT is
4040 true if an identifier is present, false for an abstract
4041 declarator. */
4042
4043 static struct c_declarator *
c_parser_direct_declarator_inner(c_parser * parser,bool id_present,struct c_declarator * inner)4044 c_parser_direct_declarator_inner (c_parser *parser, bool id_present,
4045 struct c_declarator *inner)
4046 {
4047 /* Parse a sequence of array declarators and parameter lists. */
4048 if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
4049 && !c_parser_nth_token_starts_std_attributes (parser, 1))
4050 {
4051 location_t brace_loc = c_parser_peek_token (parser)->location;
4052 struct c_declarator *declarator;
4053 struct c_declspecs *quals_attrs = build_null_declspecs ();
4054 bool static_seen;
4055 bool star_seen;
4056 struct c_expr dimen;
4057 dimen.value = NULL_TREE;
4058 dimen.original_code = ERROR_MARK;
4059 dimen.original_type = NULL_TREE;
4060 c_parser_consume_token (parser);
4061 c_parser_declspecs (parser, quals_attrs, false, false, true,
4062 false, false, false, false, cla_prefer_id);
4063 static_seen = c_parser_next_token_is_keyword (parser, RID_STATIC);
4064 if (static_seen)
4065 c_parser_consume_token (parser);
4066 if (static_seen && !quals_attrs->declspecs_seen_p)
4067 c_parser_declspecs (parser, quals_attrs, false, false, true,
4068 false, false, false, false, cla_prefer_id);
4069 if (!quals_attrs->declspecs_seen_p)
4070 quals_attrs = NULL;
4071 /* If "static" is present, there must be an array dimension.
4072 Otherwise, there may be a dimension, "*", or no
4073 dimension. */
4074 if (static_seen)
4075 {
4076 star_seen = false;
4077 dimen = c_parser_expr_no_commas (parser, NULL);
4078 }
4079 else
4080 {
4081 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
4082 {
4083 dimen.value = NULL_TREE;
4084 star_seen = false;
4085 }
4086 else if (c_parser_next_token_is (parser, CPP_MULT))
4087 {
4088 if (c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_SQUARE)
4089 {
4090 dimen.value = NULL_TREE;
4091 star_seen = true;
4092 c_parser_consume_token (parser);
4093 }
4094 else
4095 {
4096 star_seen = false;
4097 dimen = c_parser_expr_no_commas (parser, NULL);
4098 }
4099 }
4100 else
4101 {
4102 star_seen = false;
4103 dimen = c_parser_expr_no_commas (parser, NULL);
4104 }
4105 }
4106 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
4107 c_parser_consume_token (parser);
4108 else
4109 {
4110 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
4111 "expected %<]%>");
4112 return NULL;
4113 }
4114 if (dimen.value)
4115 dimen = convert_lvalue_to_rvalue (brace_loc, dimen, true, true);
4116 declarator = build_array_declarator (brace_loc, dimen.value, quals_attrs,
4117 static_seen, star_seen);
4118 if (declarator == NULL)
4119 return NULL;
4120 if (c_parser_nth_token_starts_std_attributes (parser, 1))
4121 {
4122 tree std_attrs
4123 = c_parser_std_attribute_specifier_sequence (parser);
4124 if (std_attrs)
4125 inner = build_attrs_declarator (std_attrs, inner);
4126 }
4127 inner = set_array_declarator_inner (declarator, inner);
4128 return c_parser_direct_declarator_inner (parser, id_present, inner);
4129 }
4130 else if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
4131 {
4132 tree attrs;
4133 struct c_arg_info *args;
4134 c_parser_consume_token (parser);
4135 bool have_gnu_attrs = c_parser_next_token_is_keyword (parser,
4136 RID_ATTRIBUTE);
4137 attrs = c_parser_gnu_attributes (parser);
4138 args = c_parser_parms_declarator (parser, id_present, attrs,
4139 have_gnu_attrs);
4140 if (args == NULL)
4141 return NULL;
4142 else
4143 {
4144 if (!(args->types
4145 && args->types != error_mark_node
4146 && TREE_CODE (TREE_VALUE (args->types)) == IDENTIFIER_NODE)
4147 && c_parser_nth_token_starts_std_attributes (parser, 1))
4148 {
4149 tree std_attrs
4150 = c_parser_std_attribute_specifier_sequence (parser);
4151 if (std_attrs)
4152 inner = build_attrs_declarator (std_attrs, inner);
4153 }
4154 inner = build_function_declarator (args, inner);
4155 return c_parser_direct_declarator_inner (parser, id_present, inner);
4156 }
4157 }
4158 return inner;
4159 }
4160
4161 /* Parse a parameter list or identifier list, including the closing
4162 parenthesis but not the opening one. ATTRS are the gnu-attributes
4163 at the start of the list. ID_LIST_OK is true if an identifier list
4164 is acceptable; such a list must not have attributes at the start.
4165 HAVE_GNU_ATTRS says whether any gnu-attributes (including empty
4166 attributes) were present (in which case standard attributes cannot
4167 occur). */
4168
4169 static struct c_arg_info *
c_parser_parms_declarator(c_parser * parser,bool id_list_ok,tree attrs,bool have_gnu_attrs)4170 c_parser_parms_declarator (c_parser *parser, bool id_list_ok, tree attrs,
4171 bool have_gnu_attrs)
4172 {
4173 push_scope ();
4174 declare_parm_level ();
4175 /* If the list starts with an identifier, it is an identifier list.
4176 Otherwise, it is either a prototype list or an empty list. */
4177 if (id_list_ok
4178 && !attrs
4179 && c_parser_next_token_is (parser, CPP_NAME)
4180 && c_parser_peek_token (parser)->id_kind == C_ID_ID
4181
4182 /* Look ahead to detect typos in type names. */
4183 && c_parser_peek_2nd_token (parser)->type != CPP_NAME
4184 && c_parser_peek_2nd_token (parser)->type != CPP_MULT
4185 && c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN
4186 && c_parser_peek_2nd_token (parser)->type != CPP_OPEN_SQUARE
4187 && c_parser_peek_2nd_token (parser)->type != CPP_KEYWORD)
4188 {
4189 tree list = NULL_TREE, *nextp = &list;
4190 while (c_parser_next_token_is (parser, CPP_NAME)
4191 && c_parser_peek_token (parser)->id_kind == C_ID_ID)
4192 {
4193 *nextp = build_tree_list (NULL_TREE,
4194 c_parser_peek_token (parser)->value);
4195 nextp = & TREE_CHAIN (*nextp);
4196 c_parser_consume_token (parser);
4197 if (c_parser_next_token_is_not (parser, CPP_COMMA))
4198 break;
4199 c_parser_consume_token (parser);
4200 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4201 {
4202 c_parser_error (parser, "expected identifier");
4203 break;
4204 }
4205 }
4206 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4207 {
4208 struct c_arg_info *ret = build_arg_info ();
4209 ret->types = list;
4210 c_parser_consume_token (parser);
4211 pop_scope ();
4212 return ret;
4213 }
4214 else
4215 {
4216 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4217 "expected %<)%>");
4218 pop_scope ();
4219 return NULL;
4220 }
4221 }
4222 else
4223 {
4224 struct c_arg_info *ret
4225 = c_parser_parms_list_declarator (parser, attrs, NULL, have_gnu_attrs);
4226 pop_scope ();
4227 return ret;
4228 }
4229 }
4230
4231 /* Parse a parameter list (possibly empty), including the closing
4232 parenthesis but not the opening one. ATTRS are the gnu-attributes
4233 at the start of the list; if HAVE_GNU_ATTRS, there were some such
4234 attributes (possibly empty, in which case ATTRS is NULL_TREE),
4235 which means standard attributes cannot start the list. EXPR is
4236 NULL or an expression that needs to be evaluated for the side
4237 effects of array size expressions in the parameters. */
4238
4239 static struct c_arg_info *
c_parser_parms_list_declarator(c_parser * parser,tree attrs,tree expr,bool have_gnu_attrs)4240 c_parser_parms_list_declarator (c_parser *parser, tree attrs, tree expr,
4241 bool have_gnu_attrs)
4242 {
4243 bool bad_parm = false;
4244
4245 /* ??? Following the old parser, forward parameter declarations may
4246 use abstract declarators, and if no real parameter declarations
4247 follow the forward declarations then this is not diagnosed. Also
4248 note as above that gnu-attributes are ignored as the only contents of
4249 the parentheses, or as the only contents after forward
4250 declarations. */
4251 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4252 {
4253 struct c_arg_info *ret = build_arg_info ();
4254 c_parser_consume_token (parser);
4255 return ret;
4256 }
4257 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
4258 {
4259 struct c_arg_info *ret = build_arg_info ();
4260
4261 if (flag_allow_parameterless_variadic_functions)
4262 {
4263 /* F (...) is allowed. */
4264 ret->types = NULL_TREE;
4265 }
4266 else
4267 {
4268 /* Suppress -Wold-style-definition for this case. */
4269 ret->types = error_mark_node;
4270 error_at (c_parser_peek_token (parser)->location,
4271 "ISO C requires a named argument before %<...%>");
4272 }
4273 c_parser_consume_token (parser);
4274 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4275 {
4276 c_parser_consume_token (parser);
4277 return ret;
4278 }
4279 else
4280 {
4281 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4282 "expected %<)%>");
4283 return NULL;
4284 }
4285 }
4286 /* Nonempty list of parameters, either terminated with semicolon
4287 (forward declarations; recurse) or with close parenthesis (normal
4288 function) or with ", ... )" (variadic function). */
4289 while (true)
4290 {
4291 /* Parse a parameter. */
4292 struct c_parm *parm = c_parser_parameter_declaration (parser, attrs,
4293 have_gnu_attrs);
4294 attrs = NULL_TREE;
4295 have_gnu_attrs = false;
4296 if (parm == NULL)
4297 bad_parm = true;
4298 else
4299 push_parm_decl (parm, &expr);
4300 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
4301 {
4302 tree new_attrs;
4303 c_parser_consume_token (parser);
4304 mark_forward_parm_decls ();
4305 bool new_have_gnu_attrs
4306 = c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE);
4307 new_attrs = c_parser_gnu_attributes (parser);
4308 return c_parser_parms_list_declarator (parser, new_attrs, expr,
4309 new_have_gnu_attrs);
4310 }
4311 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4312 {
4313 c_parser_consume_token (parser);
4314 if (bad_parm)
4315 return NULL;
4316 else
4317 return get_parm_info (false, expr);
4318 }
4319 if (!c_parser_require (parser, CPP_COMMA,
4320 "expected %<;%>, %<,%> or %<)%>",
4321 UNKNOWN_LOCATION, false))
4322 {
4323 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4324 return NULL;
4325 }
4326 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
4327 {
4328 c_parser_consume_token (parser);
4329 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4330 {
4331 c_parser_consume_token (parser);
4332 if (bad_parm)
4333 return NULL;
4334 else
4335 return get_parm_info (true, expr);
4336 }
4337 else
4338 {
4339 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4340 "expected %<)%>");
4341 return NULL;
4342 }
4343 }
4344 }
4345 }
4346
4347 /* Parse a parameter declaration. ATTRS are the gnu-attributes at the
4348 start of the declaration if it is the first parameter;
4349 HAVE_GNU_ATTRS is true if there were any gnu-attributes there (even
4350 empty) there. */
4351
4352 static struct c_parm *
c_parser_parameter_declaration(c_parser * parser,tree attrs,bool have_gnu_attrs)4353 c_parser_parameter_declaration (c_parser *parser, tree attrs,
4354 bool have_gnu_attrs)
4355 {
4356 struct c_declspecs *specs;
4357 struct c_declarator *declarator;
4358 tree prefix_attrs;
4359 tree postfix_attrs = NULL_TREE;
4360 bool dummy = false;
4361
4362 /* Accept #pragmas between parameter declarations. */
4363 while (c_parser_next_token_is (parser, CPP_PRAGMA))
4364 c_parser_pragma (parser, pragma_param, NULL);
4365
4366 if (!c_parser_next_token_starts_declspecs (parser)
4367 && !c_parser_nth_token_starts_std_attributes (parser, 1))
4368 {
4369 c_token *token = c_parser_peek_token (parser);
4370 if (parser->error)
4371 return NULL;
4372 c_parser_set_source_position_from_token (token);
4373 if (c_parser_next_tokens_start_typename (parser, cla_prefer_type))
4374 {
4375 auto_diagnostic_group d;
4376 name_hint hint = lookup_name_fuzzy (token->value,
4377 FUZZY_LOOKUP_TYPENAME,
4378 token->location);
4379 if (const char *suggestion = hint.suggestion ())
4380 {
4381 gcc_rich_location richloc (token->location);
4382 richloc.add_fixit_replace (suggestion);
4383 error_at (&richloc,
4384 "unknown type name %qE; did you mean %qs?",
4385 token->value, suggestion);
4386 }
4387 else
4388 error_at (token->location, "unknown type name %qE", token->value);
4389 parser->error = true;
4390 }
4391 /* ??? In some Objective-C cases '...' isn't applicable so there
4392 should be a different message. */
4393 else
4394 c_parser_error (parser,
4395 "expected declaration specifiers or %<...%>");
4396 c_parser_skip_to_end_of_parameter (parser);
4397 return NULL;
4398 }
4399
4400 location_t start_loc = c_parser_peek_token (parser)->location;
4401
4402 specs = build_null_declspecs ();
4403 if (attrs)
4404 {
4405 declspecs_add_attrs (input_location, specs, attrs);
4406 attrs = NULL_TREE;
4407 }
4408 c_parser_declspecs (parser, specs, true, true, true, true, false,
4409 !have_gnu_attrs, true, cla_nonabstract_decl);
4410 finish_declspecs (specs);
4411 pending_xref_error ();
4412 prefix_attrs = specs->attrs;
4413 specs->attrs = NULL_TREE;
4414 declarator = c_parser_declarator (parser,
4415 specs->typespec_kind != ctsk_none,
4416 C_DTR_PARM, &dummy);
4417 if (declarator == NULL)
4418 {
4419 c_parser_skip_until_found (parser, CPP_COMMA, NULL);
4420 return NULL;
4421 }
4422 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
4423 postfix_attrs = c_parser_gnu_attributes (parser);
4424
4425 /* Generate a location for the parameter, ranging from the start of the
4426 initial token to the end of the final token.
4427
4428 If we have a identifier, then use it for the caret location, e.g.
4429
4430 extern int callee (int one, int (*two)(int, int), float three);
4431 ~~~~~~^~~~~~~~~~~~~~
4432
4433 otherwise, reuse the start location for the caret location e.g.:
4434
4435 extern int callee (int one, int (*)(int, int), float three);
4436 ^~~~~~~~~~~~~~~~~
4437 */
4438 location_t end_loc = parser->last_token_location;
4439
4440 /* Find any cdk_id declarator; determine if we have an identifier. */
4441 c_declarator *id_declarator = declarator;
4442 while (id_declarator && id_declarator->kind != cdk_id)
4443 id_declarator = id_declarator->declarator;
4444 location_t caret_loc = (id_declarator->u.id.id
4445 ? id_declarator->id_loc
4446 : start_loc);
4447 location_t param_loc = make_location (caret_loc, start_loc, end_loc);
4448
4449 return build_c_parm (specs, chainon (postfix_attrs, prefix_attrs),
4450 declarator, param_loc);
4451 }
4452
4453 /* Parse a string literal in an asm expression. It should not be
4454 translated, and wide string literals are an error although
4455 permitted by the syntax. This is a GNU extension.
4456
4457 asm-string-literal:
4458 string-literal
4459 */
4460
4461 static tree
c_parser_asm_string_literal(c_parser * parser)4462 c_parser_asm_string_literal (c_parser *parser)
4463 {
4464 tree str;
4465 int save_flag = warn_overlength_strings;
4466 warn_overlength_strings = 0;
4467 str = c_parser_string_literal (parser, false, false).value;
4468 warn_overlength_strings = save_flag;
4469 return str;
4470 }
4471
4472 /* Parse a simple asm expression. This is used in restricted
4473 contexts, where a full expression with inputs and outputs does not
4474 make sense. This is a GNU extension.
4475
4476 simple-asm-expr:
4477 asm ( asm-string-literal )
4478 */
4479
4480 static tree
c_parser_simple_asm_expr(c_parser * parser)4481 c_parser_simple_asm_expr (c_parser *parser)
4482 {
4483 tree str;
4484 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
4485 c_parser_consume_token (parser);
4486 matching_parens parens;
4487 if (!parens.require_open (parser))
4488 return NULL_TREE;
4489 str = c_parser_asm_string_literal (parser);
4490 if (!parens.require_close (parser))
4491 {
4492 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4493 return NULL_TREE;
4494 }
4495 return str;
4496 }
4497
4498 static tree
c_parser_gnu_attribute_any_word(c_parser * parser)4499 c_parser_gnu_attribute_any_word (c_parser *parser)
4500 {
4501 tree attr_name = NULL_TREE;
4502
4503 if (c_parser_next_token_is (parser, CPP_KEYWORD))
4504 {
4505 /* ??? See comment above about what keywords are accepted here. */
4506 bool ok;
4507 switch (c_parser_peek_token (parser)->keyword)
4508 {
4509 case RID_STATIC:
4510 case RID_UNSIGNED:
4511 case RID_LONG:
4512 case RID_CONST:
4513 case RID_EXTERN:
4514 case RID_REGISTER:
4515 case RID_TYPEDEF:
4516 case RID_SHORT:
4517 case RID_INLINE:
4518 case RID_NORETURN:
4519 case RID_VOLATILE:
4520 case RID_SIGNED:
4521 case RID_AUTO:
4522 case RID_RESTRICT:
4523 case RID_COMPLEX:
4524 case RID_THREAD:
4525 case RID_INT:
4526 case RID_CHAR:
4527 case RID_FLOAT:
4528 case RID_DOUBLE:
4529 case RID_VOID:
4530 case RID_DFLOAT32:
4531 case RID_DFLOAT64:
4532 case RID_DFLOAT128:
4533 CASE_RID_FLOATN_NX:
4534 case RID_BOOL:
4535 case RID_FRACT:
4536 case RID_ACCUM:
4537 case RID_SAT:
4538 case RID_TRANSACTION_ATOMIC:
4539 case RID_TRANSACTION_CANCEL:
4540 case RID_ATOMIC:
4541 case RID_AUTO_TYPE:
4542 case RID_INT_N_0:
4543 case RID_INT_N_1:
4544 case RID_INT_N_2:
4545 case RID_INT_N_3:
4546 ok = true;
4547 break;
4548 default:
4549 ok = false;
4550 break;
4551 }
4552 if (!ok)
4553 return NULL_TREE;
4554
4555 /* Accept __attribute__((__const)) as __attribute__((const)) etc. */
4556 attr_name = ridpointers[(int) c_parser_peek_token (parser)->keyword];
4557 }
4558 else if (c_parser_next_token_is (parser, CPP_NAME))
4559 attr_name = c_parser_peek_token (parser)->value;
4560
4561 return attr_name;
4562 }
4563
4564 /* Parse attribute arguments. This is a common form of syntax
4565 covering all currently valid GNU and standard attributes.
4566
4567 gnu-attribute-arguments:
4568 identifier
4569 identifier , nonempty-expr-list
4570 expr-list
4571
4572 where the "identifier" must not be declared as a type. ??? Why not
4573 allow identifiers declared as types to start the arguments? */
4574
4575 static tree
c_parser_attribute_arguments(c_parser * parser,bool takes_identifier,bool require_string,bool allow_empty_args)4576 c_parser_attribute_arguments (c_parser *parser, bool takes_identifier,
4577 bool require_string, bool allow_empty_args)
4578 {
4579 vec<tree, va_gc> *expr_list;
4580 tree attr_args;
4581 /* Parse the attribute contents. If they start with an
4582 identifier which is followed by a comma or close
4583 parenthesis, then the arguments start with that
4584 identifier; otherwise they are an expression list.
4585 In objective-c the identifier may be a classname. */
4586 if (c_parser_next_token_is (parser, CPP_NAME)
4587 && (c_parser_peek_token (parser)->id_kind == C_ID_ID
4588 || (c_dialect_objc ()
4589 && c_parser_peek_token (parser)->id_kind
4590 == C_ID_CLASSNAME))
4591 && ((c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
4592 || (c_parser_peek_2nd_token (parser)->type
4593 == CPP_CLOSE_PAREN))
4594 && (takes_identifier
4595 || (c_dialect_objc ()
4596 && c_parser_peek_token (parser)->id_kind
4597 == C_ID_CLASSNAME)))
4598 {
4599 tree arg1 = c_parser_peek_token (parser)->value;
4600 c_parser_consume_token (parser);
4601 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4602 attr_args = build_tree_list (NULL_TREE, arg1);
4603 else
4604 {
4605 tree tree_list;
4606 c_parser_consume_token (parser);
4607 expr_list = c_parser_expr_list (parser, false, true,
4608 NULL, NULL, NULL, NULL);
4609 tree_list = build_tree_list_vec (expr_list);
4610 attr_args = tree_cons (NULL_TREE, arg1, tree_list);
4611 release_tree_vector (expr_list);
4612 }
4613 }
4614 else
4615 {
4616 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4617 {
4618 if (!allow_empty_args)
4619 error_at (c_parser_peek_token (parser)->location,
4620 "parentheses must be omitted if "
4621 "attribute argument list is empty");
4622 attr_args = NULL_TREE;
4623 }
4624 else if (require_string)
4625 {
4626 /* The only valid argument for this attribute is a string
4627 literal. Handle this specially here to avoid accepting
4628 string literals with excess parentheses. */
4629 tree string = c_parser_string_literal (parser, false, true).value;
4630 attr_args = build_tree_list (NULL_TREE, string);
4631 }
4632 else
4633 {
4634 expr_list = c_parser_expr_list (parser, false, true,
4635 NULL, NULL, NULL, NULL);
4636 attr_args = build_tree_list_vec (expr_list);
4637 release_tree_vector (expr_list);
4638 }
4639 }
4640 return attr_args;
4641 }
4642
4643 /* Parse (possibly empty) gnu-attributes. This is a GNU extension.
4644
4645 gnu-attributes:
4646 empty
4647 gnu-attributes gnu-attribute
4648
4649 gnu-attribute:
4650 __attribute__ ( ( gnu-attribute-list ) )
4651
4652 gnu-attribute-list:
4653 gnu-attrib
4654 gnu-attribute_list , gnu-attrib
4655
4656 gnu-attrib:
4657 empty
4658 any-word
4659 any-word ( gnu-attribute-arguments )
4660
4661 where "any-word" may be any identifier (including one declared as a
4662 type), a reserved word storage class specifier, type specifier or
4663 type qualifier. ??? This still leaves out most reserved keywords
4664 (following the old parser), shouldn't we include them?
4665 When EXPECT_COMMA is true, expect the attribute to be preceded
4666 by a comma and fail if it isn't.
4667 When EMPTY_OK is true, allow and consume any number of consecutive
4668 commas with no attributes in between. */
4669
4670 static tree
c_parser_gnu_attribute(c_parser * parser,tree attrs,bool expect_comma=false,bool empty_ok=true)4671 c_parser_gnu_attribute (c_parser *parser, tree attrs,
4672 bool expect_comma = false, bool empty_ok = true)
4673 {
4674 bool comma_first = c_parser_next_token_is (parser, CPP_COMMA);
4675 if (!comma_first
4676 && !c_parser_next_token_is (parser, CPP_NAME)
4677 && !c_parser_next_token_is (parser, CPP_KEYWORD))
4678 return NULL_TREE;
4679
4680 while (c_parser_next_token_is (parser, CPP_COMMA))
4681 {
4682 c_parser_consume_token (parser);
4683 if (!empty_ok)
4684 return attrs;
4685 }
4686
4687 tree attr_name = c_parser_gnu_attribute_any_word (parser);
4688 if (attr_name == NULL_TREE)
4689 return NULL_TREE;
4690
4691 attr_name = canonicalize_attr_name (attr_name);
4692 c_parser_consume_token (parser);
4693
4694 tree attr;
4695 if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
4696 {
4697 if (expect_comma && !comma_first)
4698 {
4699 /* A comma is missing between the last attribute on the chain
4700 and this one. */
4701 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4702 "expected %<)%>");
4703 return error_mark_node;
4704 }
4705 attr = build_tree_list (attr_name, NULL_TREE);
4706 /* Add this attribute to the list. */
4707 attrs = chainon (attrs, attr);
4708 return attrs;
4709 }
4710 c_parser_consume_token (parser);
4711
4712 tree attr_args
4713 = c_parser_attribute_arguments (parser,
4714 attribute_takes_identifier_p (attr_name),
4715 false, true);
4716
4717 attr = build_tree_list (attr_name, attr_args);
4718 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4719 c_parser_consume_token (parser);
4720 else
4721 {
4722 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4723 "expected %<)%>");
4724 return error_mark_node;
4725 }
4726
4727 if (expect_comma && !comma_first)
4728 {
4729 /* A comma is missing between the last attribute on the chain
4730 and this one. */
4731 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4732 "expected %<)%>");
4733 return error_mark_node;
4734 }
4735
4736 /* Add this attribute to the list. */
4737 attrs = chainon (attrs, attr);
4738 return attrs;
4739 }
4740
4741 static tree
c_parser_gnu_attributes(c_parser * parser)4742 c_parser_gnu_attributes (c_parser *parser)
4743 {
4744 tree attrs = NULL_TREE;
4745 while (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
4746 {
4747 bool save_translate_strings_p = parser->translate_strings_p;
4748 parser->translate_strings_p = false;
4749 /* Consume the `__attribute__' keyword. */
4750 c_parser_consume_token (parser);
4751 /* Look for the two `(' tokens. */
4752 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
4753 {
4754 parser->translate_strings_p = save_translate_strings_p;
4755 return attrs;
4756 }
4757 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
4758 {
4759 parser->translate_strings_p = save_translate_strings_p;
4760 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4761 return attrs;
4762 }
4763 /* Parse the attribute list. Require a comma between successive
4764 (possibly empty) attributes. */
4765 for (bool expect_comma = false; ; expect_comma = true)
4766 {
4767 /* Parse a single attribute. */
4768 tree attr = c_parser_gnu_attribute (parser, attrs, expect_comma);
4769 if (attr == error_mark_node)
4770 return attrs;
4771 if (!attr)
4772 break;
4773 attrs = attr;
4774 }
4775
4776 /* Look for the two `)' tokens. */
4777 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4778 c_parser_consume_token (parser);
4779 else
4780 {
4781 parser->translate_strings_p = save_translate_strings_p;
4782 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4783 "expected %<)%>");
4784 return attrs;
4785 }
4786 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4787 c_parser_consume_token (parser);
4788 else
4789 {
4790 parser->translate_strings_p = save_translate_strings_p;
4791 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4792 "expected %<)%>");
4793 return attrs;
4794 }
4795 parser->translate_strings_p = save_translate_strings_p;
4796 }
4797
4798 return attrs;
4799 }
4800
4801 /* Parse an optional balanced token sequence.
4802
4803 balanced-token-sequence:
4804 balanced-token
4805 balanced-token-sequence balanced-token
4806
4807 balanced-token:
4808 ( balanced-token-sequence[opt] )
4809 [ balanced-token-sequence[opt] ]
4810 { balanced-token-sequence[opt] }
4811 any token other than ()[]{}
4812 */
4813
4814 static void
c_parser_balanced_token_sequence(c_parser * parser)4815 c_parser_balanced_token_sequence (c_parser *parser)
4816 {
4817 while (true)
4818 {
4819 c_token *token = c_parser_peek_token (parser);
4820 switch (token->type)
4821 {
4822 case CPP_OPEN_BRACE:
4823 {
4824 matching_braces braces;
4825 braces.consume_open (parser);
4826 c_parser_balanced_token_sequence (parser);
4827 braces.require_close (parser);
4828 break;
4829 }
4830
4831 case CPP_OPEN_PAREN:
4832 {
4833 matching_parens parens;
4834 parens.consume_open (parser);
4835 c_parser_balanced_token_sequence (parser);
4836 parens.require_close (parser);
4837 break;
4838 }
4839
4840 case CPP_OPEN_SQUARE:
4841 c_parser_consume_token (parser);
4842 c_parser_balanced_token_sequence (parser);
4843 c_parser_require (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
4844 break;
4845
4846 case CPP_CLOSE_BRACE:
4847 case CPP_CLOSE_PAREN:
4848 case CPP_CLOSE_SQUARE:
4849 case CPP_EOF:
4850 return;
4851
4852 case CPP_PRAGMA:
4853 c_parser_consume_pragma (parser);
4854 c_parser_skip_to_pragma_eol (parser, false);
4855 break;
4856
4857 default:
4858 c_parser_consume_token (parser);
4859 break;
4860 }
4861 }
4862 }
4863
4864 /* Parse standard (C2X) attributes (including GNU attributes in the
4865 gnu:: namespace).
4866
4867 attribute-specifier-sequence:
4868 attribute-specifier-sequence[opt] attribute-specifier
4869
4870 attribute-specifier:
4871 [ [ attribute-list ] ]
4872
4873 attribute-list:
4874 attribute[opt]
4875 attribute-list, attribute[opt]
4876
4877 attribute:
4878 attribute-token attribute-argument-clause[opt]
4879
4880 attribute-token:
4881 standard-attribute
4882 attribute-prefixed-token
4883
4884 standard-attribute:
4885 identifier
4886
4887 attribute-prefixed-token:
4888 attribute-prefix :: identifier
4889
4890 attribute-prefix:
4891 identifier
4892
4893 attribute-argument-clause:
4894 ( balanced-token-sequence[opt] )
4895
4896 Keywords are accepted as identifiers for this purpose.
4897 */
4898
4899 static tree
c_parser_std_attribute(c_parser * parser,bool for_tm)4900 c_parser_std_attribute (c_parser *parser, bool for_tm)
4901 {
4902 c_token *token = c_parser_peek_token (parser);
4903 tree ns, name, attribute;
4904
4905 /* Parse the attribute-token. */
4906 if (token->type != CPP_NAME && token->type != CPP_KEYWORD)
4907 {
4908 c_parser_error (parser, "expected identifier");
4909 return error_mark_node;
4910 }
4911 name = canonicalize_attr_name (token->value);
4912 c_parser_consume_token (parser);
4913 if (c_parser_next_token_is (parser, CPP_SCOPE))
4914 {
4915 ns = name;
4916 c_parser_consume_token (parser);
4917 token = c_parser_peek_token (parser);
4918 if (token->type != CPP_NAME && token->type != CPP_KEYWORD)
4919 {
4920 c_parser_error (parser, "expected identifier");
4921 return error_mark_node;
4922 }
4923 name = canonicalize_attr_name (token->value);
4924 c_parser_consume_token (parser);
4925 }
4926 else
4927 ns = NULL_TREE;
4928 attribute = build_tree_list (build_tree_list (ns, name), NULL_TREE);
4929
4930 /* Parse the arguments, if any. */
4931 const attribute_spec *as = lookup_attribute_spec (TREE_PURPOSE (attribute));
4932 if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
4933 goto out;
4934 {
4935 location_t open_loc = c_parser_peek_token (parser)->location;
4936 matching_parens parens;
4937 parens.consume_open (parser);
4938 if ((as && as->max_length == 0)
4939 /* Special-case the transactional-memory attribute "outer",
4940 which is specially handled but not registered as an
4941 attribute, to avoid allowing arbitrary balanced token
4942 sequences as arguments. */
4943 || is_attribute_p ("outer", name))
4944 {
4945 error_at (open_loc, "%qE attribute does not take any arguments", name);
4946 parens.skip_until_found_close (parser);
4947 return error_mark_node;
4948 }
4949 /* If this is a fake attribute created to handle -Wno-attributes,
4950 we must skip parsing the arguments. */
4951 if (as && !attribute_ignored_p (as))
4952 {
4953 bool takes_identifier
4954 = (ns != NULL_TREE
4955 && strcmp (IDENTIFIER_POINTER (ns), "gnu") == 0
4956 && attribute_takes_identifier_p (name));
4957 bool require_string
4958 = (ns == NULL_TREE
4959 && (strcmp (IDENTIFIER_POINTER (name), "deprecated") == 0
4960 || strcmp (IDENTIFIER_POINTER (name), "nodiscard") == 0));
4961 TREE_VALUE (attribute)
4962 = c_parser_attribute_arguments (parser, takes_identifier,
4963 require_string, false);
4964 }
4965 else
4966 c_parser_balanced_token_sequence (parser);
4967 parens.require_close (parser);
4968 }
4969 out:
4970 if (ns == NULL_TREE && !for_tm && !as)
4971 {
4972 /* An attribute with standard syntax and no namespace specified
4973 is a constraint violation if it is not one of the known
4974 standard attributes. Diagnose it here with a pedwarn and
4975 then discard it to prevent a duplicate warning later. */
4976 pedwarn (input_location, OPT_Wattributes, "%qE attribute ignored",
4977 name);
4978 return error_mark_node;
4979 }
4980 return attribute;
4981 }
4982
4983 static tree
c_parser_std_attribute_specifier(c_parser * parser,bool for_tm)4984 c_parser_std_attribute_specifier (c_parser *parser, bool for_tm)
4985 {
4986 location_t loc = c_parser_peek_token (parser)->location;
4987 if (!c_parser_require (parser, CPP_OPEN_SQUARE, "expected %<[%>"))
4988 return NULL_TREE;
4989 if (!c_parser_require (parser, CPP_OPEN_SQUARE, "expected %<[%>"))
4990 {
4991 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
4992 return NULL_TREE;
4993 }
4994 if (!for_tm)
4995 pedwarn_c11 (loc, OPT_Wpedantic,
4996 "ISO C does not support %<[[]]%> attributes before C2X");
4997 tree attributes = NULL_TREE;
4998 while (true)
4999 {
5000 c_token *token = c_parser_peek_token (parser);
5001 if (token->type == CPP_CLOSE_SQUARE)
5002 break;
5003 if (token->type == CPP_COMMA)
5004 {
5005 c_parser_consume_token (parser);
5006 continue;
5007 }
5008 tree attribute = c_parser_std_attribute (parser, for_tm);
5009 if (attribute != error_mark_node)
5010 {
5011 TREE_CHAIN (attribute) = attributes;
5012 attributes = attribute;
5013 }
5014 if (c_parser_next_token_is_not (parser, CPP_COMMA))
5015 break;
5016 }
5017 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
5018 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
5019 return nreverse (attributes);
5020 }
5021
5022 /* Look past an optional balanced token sequence of raw look-ahead
5023 tokens starting with the *Nth token. *N is updated to point to the
5024 following token. Return true if such a sequence was found, false
5025 if the tokens parsed were not balanced. */
5026
5027 static bool
c_parser_check_balanced_raw_token_sequence(c_parser * parser,unsigned int * n)5028 c_parser_check_balanced_raw_token_sequence (c_parser *parser, unsigned int *n)
5029 {
5030 while (true)
5031 {
5032 c_token *token = c_parser_peek_nth_token_raw (parser, *n);
5033 switch (token->type)
5034 {
5035 case CPP_OPEN_BRACE:
5036 {
5037 ++*n;
5038 if (c_parser_check_balanced_raw_token_sequence (parser, n))
5039 {
5040 token = c_parser_peek_nth_token_raw (parser, *n);
5041 if (token->type == CPP_CLOSE_BRACE)
5042 ++*n;
5043 else
5044 return false;
5045 }
5046 else
5047 return false;
5048 break;
5049 }
5050
5051 case CPP_OPEN_PAREN:
5052 {
5053 ++*n;
5054 if (c_parser_check_balanced_raw_token_sequence (parser, n))
5055 {
5056 token = c_parser_peek_nth_token_raw (parser, *n);
5057 if (token->type == CPP_CLOSE_PAREN)
5058 ++*n;
5059 else
5060 return false;
5061 }
5062 else
5063 return false;
5064 break;
5065 }
5066
5067 case CPP_OPEN_SQUARE:
5068 {
5069 ++*n;
5070 if (c_parser_check_balanced_raw_token_sequence (parser, n))
5071 {
5072 token = c_parser_peek_nth_token_raw (parser, *n);
5073 if (token->type == CPP_CLOSE_SQUARE)
5074 ++*n;
5075 else
5076 return false;
5077 }
5078 else
5079 return false;
5080 break;
5081 }
5082
5083 case CPP_CLOSE_BRACE:
5084 case CPP_CLOSE_PAREN:
5085 case CPP_CLOSE_SQUARE:
5086 case CPP_EOF:
5087 return true;
5088
5089 default:
5090 ++*n;
5091 break;
5092 }
5093 }
5094 }
5095
5096 /* Return whether standard attributes start with the Nth token. */
5097
5098 static bool
c_parser_nth_token_starts_std_attributes(c_parser * parser,unsigned int n)5099 c_parser_nth_token_starts_std_attributes (c_parser *parser, unsigned int n)
5100 {
5101 if (!(c_parser_peek_nth_token (parser, n)->type == CPP_OPEN_SQUARE
5102 && c_parser_peek_nth_token (parser, n + 1)->type == CPP_OPEN_SQUARE))
5103 return false;
5104 /* In C, '[[' must start attributes. In Objective-C, we need to
5105 check whether '[[' is matched by ']]'. */
5106 if (!c_dialect_objc ())
5107 return true;
5108 n += 2;
5109 if (!c_parser_check_balanced_raw_token_sequence (parser, &n))
5110 return false;
5111 c_token *token = c_parser_peek_nth_token_raw (parser, n);
5112 if (token->type != CPP_CLOSE_SQUARE)
5113 return false;
5114 token = c_parser_peek_nth_token_raw (parser, n + 1);
5115 return token->type == CPP_CLOSE_SQUARE;
5116 }
5117
5118 static tree
c_parser_std_attribute_specifier_sequence(c_parser * parser)5119 c_parser_std_attribute_specifier_sequence (c_parser *parser)
5120 {
5121 tree attributes = NULL_TREE;
5122 do
5123 {
5124 tree attrs = c_parser_std_attribute_specifier (parser, false);
5125 attributes = chainon (attributes, attrs);
5126 }
5127 while (c_parser_nth_token_starts_std_attributes (parser, 1));
5128 return attributes;
5129 }
5130
5131 /* Parse a type name (C90 6.5.5, C99 6.7.6, C11 6.7.7). ALIGNAS_OK
5132 says whether alignment specifiers are OK (only in cases that might
5133 be the type name of a compound literal).
5134
5135 type-name:
5136 specifier-qualifier-list abstract-declarator[opt]
5137 */
5138
5139 struct c_type_name *
c_parser_type_name(c_parser * parser,bool alignas_ok)5140 c_parser_type_name (c_parser *parser, bool alignas_ok)
5141 {
5142 struct c_declspecs *specs = build_null_declspecs ();
5143 struct c_declarator *declarator;
5144 struct c_type_name *ret;
5145 bool dummy = false;
5146 c_parser_declspecs (parser, specs, false, true, true, alignas_ok, false,
5147 false, true, cla_prefer_type);
5148 if (!specs->declspecs_seen_p)
5149 {
5150 c_parser_error (parser, "expected specifier-qualifier-list");
5151 return NULL;
5152 }
5153 if (specs->type != error_mark_node)
5154 {
5155 pending_xref_error ();
5156 finish_declspecs (specs);
5157 }
5158 declarator = c_parser_declarator (parser,
5159 specs->typespec_kind != ctsk_none,
5160 C_DTR_ABSTRACT, &dummy);
5161 if (declarator == NULL)
5162 return NULL;
5163 ret = XOBNEW (&parser_obstack, struct c_type_name);
5164 ret->specs = specs;
5165 ret->declarator = declarator;
5166 return ret;
5167 }
5168
5169 /* Parse an initializer (C90 6.5.7, C99 6.7.8, C11 6.7.9).
5170
5171 initializer:
5172 assignment-expression
5173 { initializer-list }
5174 { initializer-list , }
5175
5176 initializer-list:
5177 designation[opt] initializer
5178 initializer-list , designation[opt] initializer
5179
5180 designation:
5181 designator-list =
5182
5183 designator-list:
5184 designator
5185 designator-list designator
5186
5187 designator:
5188 array-designator
5189 . identifier
5190
5191 array-designator:
5192 [ constant-expression ]
5193
5194 GNU extensions:
5195
5196 initializer:
5197 { }
5198
5199 designation:
5200 array-designator
5201 identifier :
5202
5203 array-designator:
5204 [ constant-expression ... constant-expression ]
5205
5206 Any expression without commas is accepted in the syntax for the
5207 constant-expressions, with non-constant expressions rejected later.
5208
5209 DECL is the declaration we're parsing this initializer for.
5210
5211 This function is only used for top-level initializers; for nested
5212 ones, see c_parser_initval. */
5213
5214 static struct c_expr
c_parser_initializer(c_parser * parser,tree decl)5215 c_parser_initializer (c_parser *parser, tree decl)
5216 {
5217 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
5218 return c_parser_braced_init (parser, NULL_TREE, false, NULL);
5219 else
5220 {
5221 struct c_expr ret;
5222 location_t loc = c_parser_peek_token (parser)->location;
5223 ret = c_parser_expr_no_commas (parser, NULL);
5224 /* This is handled mostly by gimplify.cc, but we have to deal with
5225 not warning about int x = x; as it is a GCC extension to turn off
5226 this warning but only if warn_init_self is zero. */
5227 if (VAR_P (decl)
5228 && !DECL_EXTERNAL (decl)
5229 && !TREE_STATIC (decl)
5230 && ret.value == decl
5231 && !warning_enabled_at (DECL_SOURCE_LOCATION (decl), OPT_Winit_self))
5232 suppress_warning (decl, OPT_Winit_self);
5233 if (TREE_CODE (ret.value) != STRING_CST
5234 && TREE_CODE (ret.value) != COMPOUND_LITERAL_EXPR)
5235 ret = convert_lvalue_to_rvalue (loc, ret, true, true);
5236 return ret;
5237 }
5238 }
5239
5240 /* The location of the last comma within the current initializer list,
5241 or UNKNOWN_LOCATION if not within one. */
5242
5243 location_t last_init_list_comma;
5244
5245 /* Parse a braced initializer list. TYPE is the type specified for a
5246 compound literal, and NULL_TREE for other initializers and for
5247 nested braced lists. NESTED_P is true for nested braced lists,
5248 false for the list of a compound literal or the list that is the
5249 top-level initializer in a declaration. */
5250
5251 static struct c_expr
c_parser_braced_init(c_parser * parser,tree type,bool nested_p,struct obstack * outer_obstack)5252 c_parser_braced_init (c_parser *parser, tree type, bool nested_p,
5253 struct obstack *outer_obstack)
5254 {
5255 struct c_expr ret;
5256 struct obstack braced_init_obstack;
5257 location_t brace_loc = c_parser_peek_token (parser)->location;
5258 gcc_obstack_init (&braced_init_obstack);
5259 gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE));
5260 matching_braces braces;
5261 braces.consume_open (parser);
5262 if (nested_p)
5263 {
5264 finish_implicit_inits (brace_loc, outer_obstack);
5265 push_init_level (brace_loc, 0, &braced_init_obstack);
5266 }
5267 else
5268 really_start_incremental_init (type);
5269 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5270 {
5271 pedwarn (brace_loc, OPT_Wpedantic, "ISO C forbids empty initializer braces");
5272 }
5273 else
5274 {
5275 /* Parse a non-empty initializer list, possibly with a trailing
5276 comma. */
5277 while (true)
5278 {
5279 c_parser_initelt (parser, &braced_init_obstack);
5280 if (parser->error)
5281 break;
5282 if (c_parser_next_token_is (parser, CPP_COMMA))
5283 {
5284 last_init_list_comma = c_parser_peek_token (parser)->location;
5285 c_parser_consume_token (parser);
5286 }
5287 else
5288 break;
5289 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5290 break;
5291 }
5292 }
5293 c_token *next_tok = c_parser_peek_token (parser);
5294 if (next_tok->type != CPP_CLOSE_BRACE)
5295 {
5296 ret.set_error ();
5297 ret.original_code = ERROR_MARK;
5298 ret.original_type = NULL;
5299 braces.skip_until_found_close (parser);
5300 pop_init_level (brace_loc, 0, &braced_init_obstack, last_init_list_comma);
5301 obstack_free (&braced_init_obstack, NULL);
5302 return ret;
5303 }
5304 location_t close_loc = next_tok->location;
5305 c_parser_consume_token (parser);
5306 ret = pop_init_level (brace_loc, 0, &braced_init_obstack, close_loc);
5307 obstack_free (&braced_init_obstack, NULL);
5308 set_c_expr_source_range (&ret, brace_loc, close_loc);
5309 return ret;
5310 }
5311
5312 /* Parse a nested initializer, including designators. */
5313
5314 static void
c_parser_initelt(c_parser * parser,struct obstack * braced_init_obstack)5315 c_parser_initelt (c_parser *parser, struct obstack * braced_init_obstack)
5316 {
5317 /* Parse any designator or designator list. A single array
5318 designator may have the subsequent "=" omitted in GNU C, but a
5319 longer list or a structure member designator may not. */
5320 if (c_parser_next_token_is (parser, CPP_NAME)
5321 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
5322 {
5323 /* Old-style structure member designator. */
5324 set_init_label (c_parser_peek_token (parser)->location,
5325 c_parser_peek_token (parser)->value,
5326 c_parser_peek_token (parser)->location,
5327 braced_init_obstack);
5328 /* Use the colon as the error location. */
5329 pedwarn (c_parser_peek_2nd_token (parser)->location, OPT_Wpedantic,
5330 "obsolete use of designated initializer with %<:%>");
5331 c_parser_consume_token (parser);
5332 c_parser_consume_token (parser);
5333 }
5334 else
5335 {
5336 /* des_seen is 0 if there have been no designators, 1 if there
5337 has been a single array designator and 2 otherwise. */
5338 int des_seen = 0;
5339 /* Location of a designator. */
5340 location_t des_loc = UNKNOWN_LOCATION; /* Quiet warning. */
5341 while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
5342 || c_parser_next_token_is (parser, CPP_DOT))
5343 {
5344 int des_prev = des_seen;
5345 if (!des_seen)
5346 des_loc = c_parser_peek_token (parser)->location;
5347 if (des_seen < 2)
5348 des_seen++;
5349 if (c_parser_next_token_is (parser, CPP_DOT))
5350 {
5351 des_seen = 2;
5352 c_parser_consume_token (parser);
5353 if (c_parser_next_token_is (parser, CPP_NAME))
5354 {
5355 set_init_label (des_loc, c_parser_peek_token (parser)->value,
5356 c_parser_peek_token (parser)->location,
5357 braced_init_obstack);
5358 c_parser_consume_token (parser);
5359 }
5360 else
5361 {
5362 struct c_expr init;
5363 init.set_error ();
5364 init.original_code = ERROR_MARK;
5365 init.original_type = NULL;
5366 c_parser_error (parser, "expected identifier");
5367 c_parser_skip_until_found (parser, CPP_COMMA, NULL);
5368 process_init_element (input_location, init, false,
5369 braced_init_obstack);
5370 return;
5371 }
5372 }
5373 else
5374 {
5375 tree first, second;
5376 location_t ellipsis_loc = UNKNOWN_LOCATION; /* Quiet warning. */
5377 location_t array_index_loc = UNKNOWN_LOCATION;
5378 /* ??? Following the old parser, [ objc-receiver
5379 objc-message-args ] is accepted as an initializer,
5380 being distinguished from a designator by what follows
5381 the first assignment expression inside the square
5382 brackets, but after a first array designator a
5383 subsequent square bracket is for Objective-C taken to
5384 start an expression, using the obsolete form of
5385 designated initializer without '=', rather than
5386 possibly being a second level of designation: in LALR
5387 terms, the '[' is shifted rather than reducing
5388 designator to designator-list. */
5389 if (des_prev == 1 && c_dialect_objc ())
5390 {
5391 des_seen = des_prev;
5392 break;
5393 }
5394 if (des_prev == 0 && c_dialect_objc ())
5395 {
5396 /* This might be an array designator or an
5397 Objective-C message expression. If the former,
5398 continue parsing here; if the latter, parse the
5399 remainder of the initializer given the starting
5400 primary-expression. ??? It might make sense to
5401 distinguish when des_prev == 1 as well; see
5402 previous comment. */
5403 tree rec, args;
5404 struct c_expr mexpr;
5405 c_parser_consume_token (parser);
5406 if (c_parser_peek_token (parser)->type == CPP_NAME
5407 && ((c_parser_peek_token (parser)->id_kind
5408 == C_ID_TYPENAME)
5409 || (c_parser_peek_token (parser)->id_kind
5410 == C_ID_CLASSNAME)))
5411 {
5412 /* Type name receiver. */
5413 tree id = c_parser_peek_token (parser)->value;
5414 c_parser_consume_token (parser);
5415 rec = objc_get_class_reference (id);
5416 goto parse_message_args;
5417 }
5418 first = c_parser_expr_no_commas (parser, NULL).value;
5419 mark_exp_read (first);
5420 if (c_parser_next_token_is (parser, CPP_ELLIPSIS)
5421 || c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
5422 goto array_desig_after_first;
5423 /* Expression receiver. So far only one part
5424 without commas has been parsed; there might be
5425 more of the expression. */
5426 rec = first;
5427 while (c_parser_next_token_is (parser, CPP_COMMA))
5428 {
5429 struct c_expr next;
5430 location_t comma_loc, exp_loc;
5431 comma_loc = c_parser_peek_token (parser)->location;
5432 c_parser_consume_token (parser);
5433 exp_loc = c_parser_peek_token (parser)->location;
5434 next = c_parser_expr_no_commas (parser, NULL);
5435 next = convert_lvalue_to_rvalue (exp_loc, next,
5436 true, true);
5437 rec = build_compound_expr (comma_loc, rec, next.value);
5438 }
5439 parse_message_args:
5440 /* Now parse the objc-message-args. */
5441 args = c_parser_objc_message_args (parser);
5442 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
5443 "expected %<]%>");
5444 mexpr.value
5445 = objc_build_message_expr (rec, args);
5446 mexpr.original_code = ERROR_MARK;
5447 mexpr.original_type = NULL;
5448 /* Now parse and process the remainder of the
5449 initializer, starting with this message
5450 expression as a primary-expression. */
5451 c_parser_initval (parser, &mexpr, braced_init_obstack);
5452 return;
5453 }
5454 c_parser_consume_token (parser);
5455 array_index_loc = c_parser_peek_token (parser)->location;
5456 first = c_parser_expr_no_commas (parser, NULL).value;
5457 mark_exp_read (first);
5458 array_desig_after_first:
5459 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
5460 {
5461 ellipsis_loc = c_parser_peek_token (parser)->location;
5462 c_parser_consume_token (parser);
5463 second = c_parser_expr_no_commas (parser, NULL).value;
5464 mark_exp_read (second);
5465 }
5466 else
5467 second = NULL_TREE;
5468 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
5469 {
5470 c_parser_consume_token (parser);
5471 set_init_index (array_index_loc, first, second,
5472 braced_init_obstack);
5473 if (second)
5474 pedwarn (ellipsis_loc, OPT_Wpedantic,
5475 "ISO C forbids specifying range of elements to initialize");
5476 }
5477 else
5478 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
5479 "expected %<]%>");
5480 }
5481 }
5482 if (des_seen >= 1)
5483 {
5484 if (c_parser_next_token_is (parser, CPP_EQ))
5485 {
5486 pedwarn_c90 (des_loc, OPT_Wpedantic,
5487 "ISO C90 forbids specifying subobject "
5488 "to initialize");
5489 c_parser_consume_token (parser);
5490 }
5491 else
5492 {
5493 if (des_seen == 1)
5494 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
5495 "obsolete use of designated initializer without %<=%>");
5496 else
5497 {
5498 struct c_expr init;
5499 init.set_error ();
5500 init.original_code = ERROR_MARK;
5501 init.original_type = NULL;
5502 c_parser_error (parser, "expected %<=%>");
5503 c_parser_skip_until_found (parser, CPP_COMMA, NULL);
5504 process_init_element (input_location, init, false,
5505 braced_init_obstack);
5506 return;
5507 }
5508 }
5509 }
5510 }
5511 c_parser_initval (parser, NULL, braced_init_obstack);
5512 }
5513
5514 /* Parse a nested initializer; as c_parser_initializer but parses
5515 initializers within braced lists, after any designators have been
5516 applied. If AFTER is not NULL then it is an Objective-C message
5517 expression which is the primary-expression starting the
5518 initializer. */
5519
5520 static void
c_parser_initval(c_parser * parser,struct c_expr * after,struct obstack * braced_init_obstack)5521 c_parser_initval (c_parser *parser, struct c_expr *after,
5522 struct obstack * braced_init_obstack)
5523 {
5524 struct c_expr init;
5525 gcc_assert (!after || c_dialect_objc ());
5526 location_t loc = c_parser_peek_token (parser)->location;
5527
5528 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE) && !after)
5529 init = c_parser_braced_init (parser, NULL_TREE, true,
5530 braced_init_obstack);
5531 else
5532 {
5533 init = c_parser_expr_no_commas (parser, after);
5534 if (init.value != NULL_TREE
5535 && TREE_CODE (init.value) != STRING_CST
5536 && TREE_CODE (init.value) != COMPOUND_LITERAL_EXPR)
5537 init = convert_lvalue_to_rvalue (loc, init, true, true);
5538 }
5539 process_init_element (loc, init, false, braced_init_obstack);
5540 }
5541
5542 /* Parse a compound statement (possibly a function body) (C90 6.6.2,
5543 C99 6.8.2, C11 6.8.2, C2X 6.8.2).
5544
5545 compound-statement:
5546 { block-item-list[opt] }
5547 { label-declarations block-item-list }
5548
5549 block-item-list:
5550 block-item
5551 block-item-list block-item
5552
5553 block-item:
5554 label
5555 nested-declaration
5556 statement
5557
5558 nested-declaration:
5559 declaration
5560
5561 GNU extensions:
5562
5563 compound-statement:
5564 { label-declarations block-item-list }
5565
5566 nested-declaration:
5567 __extension__ nested-declaration
5568 nested-function-definition
5569
5570 label-declarations:
5571 label-declaration
5572 label-declarations label-declaration
5573
5574 label-declaration:
5575 __label__ identifier-list ;
5576
5577 Allowing the mixing of declarations and code is new in C99. The
5578 GNU syntax also permits (not shown above) labels at the end of
5579 compound statements, which yield an error. We don't allow labels
5580 on declarations; this might seem like a natural extension, but
5581 there would be a conflict between gnu-attributes on the label and
5582 prefix gnu-attributes on the declaration. ??? The syntax follows the
5583 old parser in requiring something after label declarations.
5584 Although they are erroneous if the labels declared aren't defined,
5585 is it useful for the syntax to be this way?
5586
5587 OpenACC:
5588
5589 block-item:
5590 openacc-directive
5591
5592 openacc-directive:
5593 update-directive
5594
5595 OpenMP:
5596
5597 block-item:
5598 openmp-directive
5599
5600 openmp-directive:
5601 barrier-directive
5602 flush-directive
5603 taskwait-directive
5604 taskyield-directive
5605 cancel-directive
5606 cancellation-point-directive */
5607
5608 static tree
c_parser_compound_statement(c_parser * parser,location_t * endlocp)5609 c_parser_compound_statement (c_parser *parser, location_t *endlocp)
5610 {
5611 tree stmt;
5612 location_t brace_loc;
5613 brace_loc = c_parser_peek_token (parser)->location;
5614 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
5615 {
5616 /* Ensure a scope is entered and left anyway to avoid confusion
5617 if we have just prepared to enter a function body. */
5618 stmt = c_begin_compound_stmt (true);
5619 c_end_compound_stmt (brace_loc, stmt, true);
5620 return error_mark_node;
5621 }
5622 stmt = c_begin_compound_stmt (true);
5623 location_t end_loc = c_parser_compound_statement_nostart (parser);
5624 if (endlocp)
5625 *endlocp = end_loc;
5626
5627 return c_end_compound_stmt (brace_loc, stmt, true);
5628 }
5629
5630 /* Parse a compound statement except for the opening brace. This is
5631 used for parsing both compound statements and statement expressions
5632 (which follow different paths to handling the opening). */
5633
5634 static location_t
c_parser_compound_statement_nostart(c_parser * parser)5635 c_parser_compound_statement_nostart (c_parser *parser)
5636 {
5637 bool last_stmt = false;
5638 bool last_label = false;
5639 bool save_valid_for_pragma = valid_location_for_stdc_pragma_p ();
5640 location_t label_loc = UNKNOWN_LOCATION; /* Quiet warning. */
5641 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5642 {
5643 location_t endloc = c_parser_peek_token (parser)->location;
5644 add_debug_begin_stmt (endloc);
5645 c_parser_consume_token (parser);
5646 return endloc;
5647 }
5648 mark_valid_location_for_stdc_pragma (true);
5649 if (c_parser_next_token_is_keyword (parser, RID_LABEL))
5650 {
5651 /* Read zero or more forward-declarations for labels that nested
5652 functions can jump to. */
5653 mark_valid_location_for_stdc_pragma (false);
5654 while (c_parser_next_token_is_keyword (parser, RID_LABEL))
5655 {
5656 label_loc = c_parser_peek_token (parser)->location;
5657 c_parser_consume_token (parser);
5658 /* Any identifiers, including those declared as type names,
5659 are OK here. */
5660 while (true)
5661 {
5662 tree label;
5663 if (c_parser_next_token_is_not (parser, CPP_NAME))
5664 {
5665 c_parser_error (parser, "expected identifier");
5666 break;
5667 }
5668 label
5669 = declare_label (c_parser_peek_token (parser)->value);
5670 C_DECLARED_LABEL_FLAG (label) = 1;
5671 add_stmt (build_stmt (label_loc, DECL_EXPR, label));
5672 c_parser_consume_token (parser);
5673 if (c_parser_next_token_is (parser, CPP_COMMA))
5674 c_parser_consume_token (parser);
5675 else
5676 break;
5677 }
5678 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
5679 }
5680 pedwarn (label_loc, OPT_Wpedantic, "ISO C forbids label declarations");
5681 }
5682 /* We must now have at least one statement, label or declaration. */
5683 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5684 {
5685 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
5686 c_parser_error (parser, "expected declaration or statement");
5687 location_t endloc = c_parser_peek_token (parser)->location;
5688 c_parser_consume_token (parser);
5689 return endloc;
5690 }
5691 while (c_parser_next_token_is_not (parser, CPP_CLOSE_BRACE))
5692 {
5693 location_t loc = c_parser_peek_token (parser)->location;
5694 loc = expansion_point_location_if_in_system_header (loc);
5695 /* Standard attributes may start a label, statement or declaration. */
5696 bool have_std_attrs
5697 = c_parser_nth_token_starts_std_attributes (parser, 1);
5698 tree std_attrs = NULL_TREE;
5699 if (have_std_attrs)
5700 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
5701 if (c_parser_next_token_is_keyword (parser, RID_CASE)
5702 || c_parser_next_token_is_keyword (parser, RID_DEFAULT)
5703 || (c_parser_next_token_is (parser, CPP_NAME)
5704 && c_parser_peek_2nd_token (parser)->type == CPP_COLON))
5705 {
5706 if (c_parser_next_token_is_keyword (parser, RID_CASE))
5707 label_loc = c_parser_peek_2nd_token (parser)->location;
5708 else
5709 label_loc = c_parser_peek_token (parser)->location;
5710 last_label = true;
5711 last_stmt = false;
5712 mark_valid_location_for_stdc_pragma (false);
5713 c_parser_label (parser, std_attrs);
5714 }
5715 else if (c_parser_next_tokens_start_declaration (parser)
5716 || (have_std_attrs
5717 && c_parser_next_token_is (parser, CPP_SEMICOLON)))
5718 {
5719 if (last_label)
5720 pedwarn_c11 (c_parser_peek_token (parser)->location, OPT_Wpedantic,
5721 "a label can only be part of a statement and "
5722 "a declaration is not a statement");
5723
5724 mark_valid_location_for_stdc_pragma (false);
5725 bool fallthru_attr_p = false;
5726 c_parser_declaration_or_fndef (parser, true, !have_std_attrs,
5727 true, true, true, NULL,
5728 NULL, have_std_attrs, std_attrs,
5729 NULL, &fallthru_attr_p);
5730
5731 if (last_stmt && !fallthru_attr_p)
5732 pedwarn_c90 (loc, OPT_Wdeclaration_after_statement,
5733 "ISO C90 forbids mixed declarations and code");
5734 last_stmt = fallthru_attr_p;
5735 last_label = false;
5736 }
5737 else if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
5738 {
5739 /* __extension__ can start a declaration, but is also an
5740 unary operator that can start an expression. Consume all
5741 but the last of a possible series of __extension__ to
5742 determine which. If standard attributes have already
5743 been seen, it must start a statement, not a declaration,
5744 but standard attributes starting a declaration may appear
5745 after __extension__. */
5746 while (c_parser_peek_2nd_token (parser)->type == CPP_KEYWORD
5747 && (c_parser_peek_2nd_token (parser)->keyword
5748 == RID_EXTENSION))
5749 c_parser_consume_token (parser);
5750 if (!have_std_attrs
5751 && (c_token_starts_declaration (c_parser_peek_2nd_token (parser))
5752 || c_parser_nth_token_starts_std_attributes (parser, 2)))
5753 {
5754 int ext;
5755 ext = disable_extension_diagnostics ();
5756 c_parser_consume_token (parser);
5757 last_label = false;
5758 mark_valid_location_for_stdc_pragma (false);
5759 c_parser_declaration_or_fndef (parser, true, true, true, true,
5760 true);
5761 /* Following the old parser, __extension__ does not
5762 disable this diagnostic. */
5763 restore_extension_diagnostics (ext);
5764 if (last_stmt)
5765 pedwarn_c90 (loc, OPT_Wdeclaration_after_statement,
5766 "ISO C90 forbids mixed declarations and code");
5767 last_stmt = false;
5768 }
5769 else
5770 goto statement;
5771 }
5772 else if (c_parser_next_token_is (parser, CPP_PRAGMA))
5773 {
5774 if (have_std_attrs)
5775 c_parser_error (parser, "expected declaration or statement");
5776 /* External pragmas, and some omp pragmas, are not associated
5777 with regular c code, and so are not to be considered statements
5778 syntactically. This ensures that the user doesn't put them
5779 places that would turn into syntax errors if the directive
5780 were ignored. */
5781 if (c_parser_pragma (parser,
5782 last_label ? pragma_stmt : pragma_compound,
5783 NULL))
5784 last_label = false, last_stmt = true;
5785 }
5786 else if (c_parser_next_token_is (parser, CPP_EOF))
5787 {
5788 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
5789 c_parser_error (parser, "expected declaration or statement");
5790 return c_parser_peek_token (parser)->location;
5791 }
5792 else if (c_parser_next_token_is_keyword (parser, RID_ELSE))
5793 {
5794 if (parser->in_if_block)
5795 {
5796 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
5797 error_at (loc, "expected %<}%> before %<else%>");
5798 return c_parser_peek_token (parser)->location;
5799 }
5800 else
5801 {
5802 error_at (loc, "%<else%> without a previous %<if%>");
5803 c_parser_consume_token (parser);
5804 continue;
5805 }
5806 }
5807 else
5808 {
5809 statement:
5810 c_warn_unused_attributes (std_attrs);
5811 last_label = false;
5812 last_stmt = true;
5813 mark_valid_location_for_stdc_pragma (false);
5814 c_parser_statement_after_labels (parser, NULL);
5815 }
5816
5817 parser->error = false;
5818 }
5819 if (last_label)
5820 pedwarn_c11 (label_loc, OPT_Wpedantic, "label at end of compound statement");
5821 location_t endloc = c_parser_peek_token (parser)->location;
5822 c_parser_consume_token (parser);
5823 /* Restore the value we started with. */
5824 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
5825 return endloc;
5826 }
5827
5828 /* Parse all consecutive labels, possibly preceded by standard
5829 attributes. In this context, a statement is required, not a
5830 declaration, so attributes must be followed by a statement that is
5831 not just a semicolon. */
5832
5833 static void
c_parser_all_labels(c_parser * parser)5834 c_parser_all_labels (c_parser *parser)
5835 {
5836 tree std_attrs = NULL;
5837 if (c_parser_nth_token_starts_std_attributes (parser, 1))
5838 {
5839 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
5840 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
5841 c_parser_error (parser, "expected statement");
5842 }
5843 while (c_parser_next_token_is_keyword (parser, RID_CASE)
5844 || c_parser_next_token_is_keyword (parser, RID_DEFAULT)
5845 || (c_parser_next_token_is (parser, CPP_NAME)
5846 && c_parser_peek_2nd_token (parser)->type == CPP_COLON))
5847 {
5848 c_parser_label (parser, std_attrs);
5849 std_attrs = NULL;
5850 if (c_parser_nth_token_starts_std_attributes (parser, 1))
5851 {
5852 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
5853 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
5854 c_parser_error (parser, "expected statement");
5855 }
5856 }
5857 if (std_attrs)
5858 c_warn_unused_attributes (std_attrs);
5859 }
5860
5861 /* Parse a label (C90 6.6.1, C99 6.8.1, C11 6.8.1).
5862
5863 label:
5864 identifier : gnu-attributes[opt]
5865 case constant-expression :
5866 default :
5867
5868 GNU extensions:
5869
5870 label:
5871 case constant-expression ... constant-expression :
5872
5873 The use of gnu-attributes on labels is a GNU extension. The syntax in
5874 GNU C accepts any expressions without commas, non-constant
5875 expressions being rejected later. Any standard
5876 attribute-specifier-sequence before the first label has been parsed
5877 in the caller, to distinguish statements from declarations. Any
5878 attribute-specifier-sequence after the label is parsed in this
5879 function. */
5880 static void
c_parser_label(c_parser * parser,tree std_attrs)5881 c_parser_label (c_parser *parser, tree std_attrs)
5882 {
5883 location_t loc1 = c_parser_peek_token (parser)->location;
5884 tree label = NULL_TREE;
5885
5886 /* Remember whether this case or a user-defined label is allowed to fall
5887 through to. */
5888 bool fallthrough_p = c_parser_peek_token (parser)->flags & PREV_FALLTHROUGH;
5889
5890 if (c_parser_next_token_is_keyword (parser, RID_CASE))
5891 {
5892 tree exp1, exp2;
5893 c_parser_consume_token (parser);
5894 exp1 = c_parser_expr_no_commas (parser, NULL).value;
5895 if (c_parser_next_token_is (parser, CPP_COLON))
5896 {
5897 c_parser_consume_token (parser);
5898 label = do_case (loc1, exp1, NULL_TREE);
5899 }
5900 else if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
5901 {
5902 c_parser_consume_token (parser);
5903 exp2 = c_parser_expr_no_commas (parser, NULL).value;
5904 if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
5905 label = do_case (loc1, exp1, exp2);
5906 }
5907 else
5908 c_parser_error (parser, "expected %<:%> or %<...%>");
5909 }
5910 else if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
5911 {
5912 c_parser_consume_token (parser);
5913 if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
5914 label = do_case (loc1, NULL_TREE, NULL_TREE);
5915 }
5916 else
5917 {
5918 tree name = c_parser_peek_token (parser)->value;
5919 tree tlab;
5920 tree attrs;
5921 location_t loc2 = c_parser_peek_token (parser)->location;
5922 gcc_assert (c_parser_next_token_is (parser, CPP_NAME));
5923 c_parser_consume_token (parser);
5924 gcc_assert (c_parser_next_token_is (parser, CPP_COLON));
5925 c_parser_consume_token (parser);
5926 attrs = c_parser_gnu_attributes (parser);
5927 tlab = define_label (loc2, name);
5928 if (tlab)
5929 {
5930 decl_attributes (&tlab, attrs, 0);
5931 decl_attributes (&tlab, std_attrs, 0);
5932 label = add_stmt (build_stmt (loc1, LABEL_EXPR, tlab));
5933 }
5934 if (attrs
5935 && c_parser_next_tokens_start_declaration (parser))
5936 warning_at (loc2, OPT_Wattributes, "GNU-style attribute between"
5937 " label and declaration appertains to the label");
5938 }
5939 if (label)
5940 {
5941 if (TREE_CODE (label) == LABEL_EXPR)
5942 FALLTHROUGH_LABEL_P (LABEL_EXPR_LABEL (label)) = fallthrough_p;
5943 else
5944 FALLTHROUGH_LABEL_P (CASE_LABEL (label)) = fallthrough_p;
5945 }
5946 }
5947
5948 /* Parse a statement (C90 6.6, C99 6.8, C11 6.8).
5949
5950 statement:
5951 labeled-statement
5952 attribute-specifier-sequence[opt] compound-statement
5953 expression-statement
5954 attribute-specifier-sequence[opt] selection-statement
5955 attribute-specifier-sequence[opt] iteration-statement
5956 attribute-specifier-sequence[opt] jump-statement
5957
5958 labeled-statement:
5959 attribute-specifier-sequence[opt] label statement
5960
5961 expression-statement:
5962 expression[opt] ;
5963 attribute-specifier-sequence expression ;
5964
5965 selection-statement:
5966 if-statement
5967 switch-statement
5968
5969 iteration-statement:
5970 while-statement
5971 do-statement
5972 for-statement
5973
5974 jump-statement:
5975 goto identifier ;
5976 continue ;
5977 break ;
5978 return expression[opt] ;
5979
5980 GNU extensions:
5981
5982 statement:
5983 attribute-specifier-sequence[opt] asm-statement
5984
5985 jump-statement:
5986 goto * expression ;
5987
5988 expression-statement:
5989 gnu-attributes ;
5990
5991 Objective-C:
5992
5993 statement:
5994 attribute-specifier-sequence[opt] objc-throw-statement
5995 attribute-specifier-sequence[opt] objc-try-catch-statement
5996 attribute-specifier-sequence[opt] objc-synchronized-statement
5997
5998 objc-throw-statement:
5999 @throw expression ;
6000 @throw ;
6001
6002 OpenACC:
6003
6004 statement:
6005 attribute-specifier-sequence[opt] openacc-construct
6006
6007 openacc-construct:
6008 parallel-construct
6009 kernels-construct
6010 data-construct
6011 loop-construct
6012
6013 parallel-construct:
6014 parallel-directive structured-block
6015
6016 kernels-construct:
6017 kernels-directive structured-block
6018
6019 data-construct:
6020 data-directive structured-block
6021
6022 loop-construct:
6023 loop-directive structured-block
6024
6025 OpenMP:
6026
6027 statement:
6028 attribute-specifier-sequence[opt] openmp-construct
6029
6030 openmp-construct:
6031 parallel-construct
6032 for-construct
6033 simd-construct
6034 for-simd-construct
6035 sections-construct
6036 single-construct
6037 parallel-for-construct
6038 parallel-for-simd-construct
6039 parallel-sections-construct
6040 master-construct
6041 critical-construct
6042 atomic-construct
6043 ordered-construct
6044
6045 parallel-construct:
6046 parallel-directive structured-block
6047
6048 for-construct:
6049 for-directive iteration-statement
6050
6051 simd-construct:
6052 simd-directive iteration-statements
6053
6054 for-simd-construct:
6055 for-simd-directive iteration-statements
6056
6057 sections-construct:
6058 sections-directive section-scope
6059
6060 single-construct:
6061 single-directive structured-block
6062
6063 parallel-for-construct:
6064 parallel-for-directive iteration-statement
6065
6066 parallel-for-simd-construct:
6067 parallel-for-simd-directive iteration-statement
6068
6069 parallel-sections-construct:
6070 parallel-sections-directive section-scope
6071
6072 master-construct:
6073 master-directive structured-block
6074
6075 critical-construct:
6076 critical-directive structured-block
6077
6078 atomic-construct:
6079 atomic-directive expression-statement
6080
6081 ordered-construct:
6082 ordered-directive structured-block
6083
6084 Transactional Memory:
6085
6086 statement:
6087 attribute-specifier-sequence[opt] transaction-statement
6088 attribute-specifier-sequence[opt] transaction-cancel-statement
6089
6090 IF_P is used to track whether there's a (possibly labeled) if statement
6091 which is not enclosed in braces and has an else clause. This is used to
6092 implement -Wparentheses. */
6093
6094 static void
c_parser_statement(c_parser * parser,bool * if_p,location_t * loc_after_labels)6095 c_parser_statement (c_parser *parser, bool *if_p, location_t *loc_after_labels)
6096 {
6097 c_parser_all_labels (parser);
6098 if (loc_after_labels)
6099 *loc_after_labels = c_parser_peek_token (parser)->location;
6100 c_parser_statement_after_labels (parser, if_p, NULL);
6101 }
6102
6103 /* Parse a statement, other than a labeled statement. CHAIN is a vector
6104 of if-else-if conditions. All labels and standard attributes have
6105 been parsed in the caller.
6106
6107 IF_P is used to track whether there's a (possibly labeled) if statement
6108 which is not enclosed in braces and has an else clause. This is used to
6109 implement -Wparentheses. */
6110
6111 static void
c_parser_statement_after_labels(c_parser * parser,bool * if_p,vec<tree> * chain)6112 c_parser_statement_after_labels (c_parser *parser, bool *if_p,
6113 vec<tree> *chain)
6114 {
6115 location_t loc = c_parser_peek_token (parser)->location;
6116 tree stmt = NULL_TREE;
6117 bool in_if_block = parser->in_if_block;
6118 parser->in_if_block = false;
6119 if (if_p != NULL)
6120 *if_p = false;
6121
6122 if (c_parser_peek_token (parser)->type != CPP_OPEN_BRACE)
6123 add_debug_begin_stmt (loc);
6124
6125 restart:
6126 switch (c_parser_peek_token (parser)->type)
6127 {
6128 case CPP_OPEN_BRACE:
6129 add_stmt (c_parser_compound_statement (parser));
6130 break;
6131 case CPP_KEYWORD:
6132 switch (c_parser_peek_token (parser)->keyword)
6133 {
6134 case RID_IF:
6135 c_parser_if_statement (parser, if_p, chain);
6136 break;
6137 case RID_SWITCH:
6138 c_parser_switch_statement (parser, if_p);
6139 break;
6140 case RID_WHILE:
6141 c_parser_while_statement (parser, false, 0, if_p);
6142 break;
6143 case RID_DO:
6144 c_parser_do_statement (parser, false, 0);
6145 break;
6146 case RID_FOR:
6147 c_parser_for_statement (parser, false, 0, if_p);
6148 break;
6149 case RID_GOTO:
6150 c_parser_consume_token (parser);
6151 if (c_parser_next_token_is (parser, CPP_NAME))
6152 {
6153 stmt = c_finish_goto_label (loc,
6154 c_parser_peek_token (parser)->value);
6155 c_parser_consume_token (parser);
6156 }
6157 else if (c_parser_next_token_is (parser, CPP_MULT))
6158 {
6159 struct c_expr val;
6160
6161 c_parser_consume_token (parser);
6162 val = c_parser_expression (parser);
6163 val = convert_lvalue_to_rvalue (loc, val, false, true);
6164 stmt = c_finish_goto_ptr (loc, val);
6165 }
6166 else
6167 c_parser_error (parser, "expected identifier or %<*%>");
6168 goto expect_semicolon;
6169 case RID_CONTINUE:
6170 c_parser_consume_token (parser);
6171 stmt = c_finish_bc_stmt (loc, objc_foreach_continue_label, false);
6172 goto expect_semicolon;
6173 case RID_BREAK:
6174 c_parser_consume_token (parser);
6175 stmt = c_finish_bc_stmt (loc, objc_foreach_break_label, true);
6176 goto expect_semicolon;
6177 case RID_RETURN:
6178 c_parser_consume_token (parser);
6179 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6180 {
6181 stmt = c_finish_return (loc, NULL_TREE, NULL_TREE);
6182 c_parser_consume_token (parser);
6183 }
6184 else
6185 {
6186 location_t xloc = c_parser_peek_token (parser)->location;
6187 struct c_expr expr = c_parser_expression_conv (parser);
6188 mark_exp_read (expr.value);
6189 stmt = c_finish_return (EXPR_LOC_OR_LOC (expr.value, xloc),
6190 expr.value, expr.original_type);
6191 goto expect_semicolon;
6192 }
6193 break;
6194 case RID_ASM:
6195 stmt = c_parser_asm_statement (parser);
6196 break;
6197 case RID_TRANSACTION_ATOMIC:
6198 case RID_TRANSACTION_RELAXED:
6199 stmt = c_parser_transaction (parser,
6200 c_parser_peek_token (parser)->keyword);
6201 break;
6202 case RID_TRANSACTION_CANCEL:
6203 stmt = c_parser_transaction_cancel (parser);
6204 goto expect_semicolon;
6205 case RID_AT_THROW:
6206 gcc_assert (c_dialect_objc ());
6207 c_parser_consume_token (parser);
6208 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6209 {
6210 stmt = objc_build_throw_stmt (loc, NULL_TREE);
6211 c_parser_consume_token (parser);
6212 }
6213 else
6214 {
6215 struct c_expr expr = c_parser_expression (parser);
6216 expr = convert_lvalue_to_rvalue (loc, expr, false, false);
6217 expr.value = c_fully_fold (expr.value, false, NULL);
6218 stmt = objc_build_throw_stmt (loc, expr.value);
6219 goto expect_semicolon;
6220 }
6221 break;
6222 case RID_AT_TRY:
6223 gcc_assert (c_dialect_objc ());
6224 c_parser_objc_try_catch_finally_statement (parser);
6225 break;
6226 case RID_AT_SYNCHRONIZED:
6227 gcc_assert (c_dialect_objc ());
6228 c_parser_objc_synchronized_statement (parser);
6229 break;
6230 case RID_ATTRIBUTE:
6231 {
6232 /* Allow '__attribute__((fallthrough));'. */
6233 tree attrs = c_parser_gnu_attributes (parser);
6234 if (attribute_fallthrough_p (attrs))
6235 {
6236 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6237 {
6238 tree fn = build_call_expr_internal_loc (loc,
6239 IFN_FALLTHROUGH,
6240 void_type_node, 0);
6241 add_stmt (fn);
6242 /* Eat the ';'. */
6243 c_parser_consume_token (parser);
6244 }
6245 else
6246 warning_at (loc, OPT_Wattributes,
6247 "%<fallthrough%> attribute not followed "
6248 "by %<;%>");
6249 }
6250 else if (attrs != NULL_TREE)
6251 warning_at (loc, OPT_Wattributes, "only attribute %<fallthrough%>"
6252 " can be applied to a null statement");
6253 break;
6254 }
6255 default:
6256 goto expr_stmt;
6257 }
6258 break;
6259 case CPP_SEMICOLON:
6260 c_parser_consume_token (parser);
6261 break;
6262 case CPP_CLOSE_PAREN:
6263 case CPP_CLOSE_SQUARE:
6264 /* Avoid infinite loop in error recovery:
6265 c_parser_skip_until_found stops at a closing nesting
6266 delimiter without consuming it, but here we need to consume
6267 it to proceed further. */
6268 c_parser_error (parser, "expected statement");
6269 c_parser_consume_token (parser);
6270 break;
6271 case CPP_PRAGMA:
6272 if (!c_parser_pragma (parser, pragma_stmt, if_p))
6273 goto restart;
6274 break;
6275 default:
6276 expr_stmt:
6277 stmt = c_finish_expr_stmt (loc, c_parser_expression_conv (parser).value);
6278 expect_semicolon:
6279 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
6280 break;
6281 }
6282 /* Two cases cannot and do not have line numbers associated: If stmt
6283 is degenerate, such as "2;", then stmt is an INTEGER_CST, which
6284 cannot hold line numbers. But that's OK because the statement
6285 will either be changed to a MODIFY_EXPR during gimplification of
6286 the statement expr, or discarded. If stmt was compound, but
6287 without new variables, we will have skipped the creation of a
6288 BIND and will have a bare STATEMENT_LIST. But that's OK because
6289 (recursively) all of the component statements should already have
6290 line numbers assigned. ??? Can we discard no-op statements
6291 earlier? */
6292 if (EXPR_LOCATION (stmt) == UNKNOWN_LOCATION)
6293 protected_set_expr_location (stmt, loc);
6294
6295 parser->in_if_block = in_if_block;
6296 }
6297
6298 /* Parse the condition from an if, do, while or for statements. */
6299
6300 static tree
c_parser_condition(c_parser * parser)6301 c_parser_condition (c_parser *parser)
6302 {
6303 location_t loc = c_parser_peek_token (parser)->location;
6304 tree cond;
6305 cond = c_parser_expression_conv (parser).value;
6306 cond = c_objc_common_truthvalue_conversion (loc, cond);
6307 cond = c_fully_fold (cond, false, NULL);
6308 if (warn_sequence_point)
6309 verify_sequence_points (cond);
6310 return cond;
6311 }
6312
6313 /* Parse a parenthesized condition from an if, do or while statement.
6314
6315 condition:
6316 ( expression )
6317 */
6318 static tree
c_parser_paren_condition(c_parser * parser)6319 c_parser_paren_condition (c_parser *parser)
6320 {
6321 tree cond;
6322 matching_parens parens;
6323 if (!parens.require_open (parser))
6324 return error_mark_node;
6325 cond = c_parser_condition (parser);
6326 parens.skip_until_found_close (parser);
6327 return cond;
6328 }
6329
6330 /* Parse a statement which is a block in C99.
6331
6332 IF_P is used to track whether there's a (possibly labeled) if statement
6333 which is not enclosed in braces and has an else clause. This is used to
6334 implement -Wparentheses. */
6335
6336 static tree
c_parser_c99_block_statement(c_parser * parser,bool * if_p,location_t * loc_after_labels)6337 c_parser_c99_block_statement (c_parser *parser, bool *if_p,
6338 location_t *loc_after_labels)
6339 {
6340 tree block = c_begin_compound_stmt (flag_isoc99);
6341 location_t loc = c_parser_peek_token (parser)->location;
6342 c_parser_statement (parser, if_p, loc_after_labels);
6343 return c_end_compound_stmt (loc, block, flag_isoc99);
6344 }
6345
6346 /* Parse the body of an if statement. This is just parsing a
6347 statement but (a) it is a block in C99, (b) we track whether the
6348 body is an if statement for the sake of -Wparentheses warnings, (c)
6349 we handle an empty body specially for the sake of -Wempty-body
6350 warnings, and (d) we call parser_compound_statement directly
6351 because c_parser_statement_after_labels resets
6352 parser->in_if_block.
6353
6354 IF_P is used to track whether there's a (possibly labeled) if statement
6355 which is not enclosed in braces and has an else clause. This is used to
6356 implement -Wparentheses. */
6357
6358 static tree
c_parser_if_body(c_parser * parser,bool * if_p,const token_indent_info & if_tinfo)6359 c_parser_if_body (c_parser *parser, bool *if_p,
6360 const token_indent_info &if_tinfo)
6361 {
6362 tree block = c_begin_compound_stmt (flag_isoc99);
6363 location_t body_loc = c_parser_peek_token (parser)->location;
6364 location_t body_loc_after_labels = UNKNOWN_LOCATION;
6365 token_indent_info body_tinfo
6366 = get_token_indent_info (c_parser_peek_token (parser));
6367
6368 c_parser_all_labels (parser);
6369 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6370 {
6371 location_t loc = c_parser_peek_token (parser)->location;
6372 add_stmt (build_empty_stmt (loc));
6373 c_parser_consume_token (parser);
6374 if (!c_parser_next_token_is_keyword (parser, RID_ELSE))
6375 warning_at (loc, OPT_Wempty_body,
6376 "suggest braces around empty body in an %<if%> statement");
6377 }
6378 else if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
6379 add_stmt (c_parser_compound_statement (parser));
6380 else
6381 {
6382 body_loc_after_labels = c_parser_peek_token (parser)->location;
6383 c_parser_statement_after_labels (parser, if_p);
6384 }
6385
6386 token_indent_info next_tinfo
6387 = get_token_indent_info (c_parser_peek_token (parser));
6388 warn_for_misleading_indentation (if_tinfo, body_tinfo, next_tinfo);
6389 if (body_loc_after_labels != UNKNOWN_LOCATION
6390 && next_tinfo.type != CPP_SEMICOLON)
6391 warn_for_multistatement_macros (body_loc_after_labels, next_tinfo.location,
6392 if_tinfo.location, RID_IF);
6393
6394 return c_end_compound_stmt (body_loc, block, flag_isoc99);
6395 }
6396
6397 /* Parse the else body of an if statement. This is just parsing a
6398 statement but (a) it is a block in C99, (b) we handle an empty body
6399 specially for the sake of -Wempty-body warnings. CHAIN is a vector
6400 of if-else-if conditions. */
6401
6402 static tree
c_parser_else_body(c_parser * parser,const token_indent_info & else_tinfo,vec<tree> * chain)6403 c_parser_else_body (c_parser *parser, const token_indent_info &else_tinfo,
6404 vec<tree> *chain)
6405 {
6406 location_t body_loc = c_parser_peek_token (parser)->location;
6407 tree block = c_begin_compound_stmt (flag_isoc99);
6408 token_indent_info body_tinfo
6409 = get_token_indent_info (c_parser_peek_token (parser));
6410 location_t body_loc_after_labels = UNKNOWN_LOCATION;
6411
6412 c_parser_all_labels (parser);
6413 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6414 {
6415 location_t loc = c_parser_peek_token (parser)->location;
6416 warning_at (loc,
6417 OPT_Wempty_body,
6418 "suggest braces around empty body in an %<else%> statement");
6419 add_stmt (build_empty_stmt (loc));
6420 c_parser_consume_token (parser);
6421 }
6422 else
6423 {
6424 if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE))
6425 body_loc_after_labels = c_parser_peek_token (parser)->location;
6426 c_parser_statement_after_labels (parser, NULL, chain);
6427 }
6428
6429 token_indent_info next_tinfo
6430 = get_token_indent_info (c_parser_peek_token (parser));
6431 warn_for_misleading_indentation (else_tinfo, body_tinfo, next_tinfo);
6432 if (body_loc_after_labels != UNKNOWN_LOCATION
6433 && next_tinfo.type != CPP_SEMICOLON)
6434 warn_for_multistatement_macros (body_loc_after_labels, next_tinfo.location,
6435 else_tinfo.location, RID_ELSE);
6436
6437 return c_end_compound_stmt (body_loc, block, flag_isoc99);
6438 }
6439
6440 /* We might need to reclassify any previously-lexed identifier, e.g.
6441 when we've left a for loop with an if-statement without else in the
6442 body - we might have used a wrong scope for the token. See PR67784. */
6443
6444 static void
c_parser_maybe_reclassify_token(c_parser * parser)6445 c_parser_maybe_reclassify_token (c_parser *parser)
6446 {
6447 if (c_parser_next_token_is (parser, CPP_NAME))
6448 {
6449 c_token *token = c_parser_peek_token (parser);
6450
6451 if (token->id_kind != C_ID_CLASSNAME)
6452 {
6453 tree decl = lookup_name (token->value);
6454
6455 token->id_kind = C_ID_ID;
6456 if (decl)
6457 {
6458 if (TREE_CODE (decl) == TYPE_DECL)
6459 token->id_kind = C_ID_TYPENAME;
6460 }
6461 else if (c_dialect_objc ())
6462 {
6463 tree objc_interface_decl = objc_is_class_name (token->value);
6464 /* Objective-C class names are in the same namespace as
6465 variables and typedefs, and hence are shadowed by local
6466 declarations. */
6467 if (objc_interface_decl)
6468 {
6469 token->value = objc_interface_decl;
6470 token->id_kind = C_ID_CLASSNAME;
6471 }
6472 }
6473 }
6474 }
6475 }
6476
6477 /* Parse an if statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
6478
6479 if-statement:
6480 if ( expression ) statement
6481 if ( expression ) statement else statement
6482
6483 CHAIN is a vector of if-else-if conditions.
6484 IF_P is used to track whether there's a (possibly labeled) if statement
6485 which is not enclosed in braces and has an else clause. This is used to
6486 implement -Wparentheses. */
6487
6488 static void
c_parser_if_statement(c_parser * parser,bool * if_p,vec<tree> * chain)6489 c_parser_if_statement (c_parser *parser, bool *if_p, vec<tree> *chain)
6490 {
6491 tree block;
6492 location_t loc;
6493 tree cond;
6494 bool nested_if = false;
6495 tree first_body, second_body;
6496 bool in_if_block;
6497
6498 gcc_assert (c_parser_next_token_is_keyword (parser, RID_IF));
6499 token_indent_info if_tinfo
6500 = get_token_indent_info (c_parser_peek_token (parser));
6501 c_parser_consume_token (parser);
6502 block = c_begin_compound_stmt (flag_isoc99);
6503 loc = c_parser_peek_token (parser)->location;
6504 cond = c_parser_paren_condition (parser);
6505 in_if_block = parser->in_if_block;
6506 parser->in_if_block = true;
6507 first_body = c_parser_if_body (parser, &nested_if, if_tinfo);
6508 parser->in_if_block = in_if_block;
6509
6510 if (warn_duplicated_cond)
6511 warn_duplicated_cond_add_or_warn (EXPR_LOCATION (cond), cond, &chain);
6512
6513 if (c_parser_next_token_is_keyword (parser, RID_ELSE))
6514 {
6515 token_indent_info else_tinfo
6516 = get_token_indent_info (c_parser_peek_token (parser));
6517 c_parser_consume_token (parser);
6518 if (warn_duplicated_cond)
6519 {
6520 if (c_parser_next_token_is_keyword (parser, RID_IF)
6521 && chain == NULL)
6522 {
6523 /* We've got "if (COND) else if (COND2)". Start the
6524 condition chain and add COND as the first element. */
6525 chain = new vec<tree> ();
6526 if (!CONSTANT_CLASS_P (cond) && !TREE_SIDE_EFFECTS (cond))
6527 chain->safe_push (cond);
6528 }
6529 else if (!c_parser_next_token_is_keyword (parser, RID_IF))
6530 /* This is if-else without subsequent if. Zap the condition
6531 chain; we would have already warned at this point. */
6532 vec_free (chain);
6533 }
6534 second_body = c_parser_else_body (parser, else_tinfo, chain);
6535 /* Set IF_P to true to indicate that this if statement has an
6536 else clause. This may trigger the Wparentheses warning
6537 below when we get back up to the parent if statement. */
6538 if (if_p != NULL)
6539 *if_p = true;
6540 }
6541 else
6542 {
6543 second_body = NULL_TREE;
6544
6545 /* Diagnose an ambiguous else if if-then-else is nested inside
6546 if-then. */
6547 if (nested_if)
6548 warning_at (loc, OPT_Wdangling_else,
6549 "suggest explicit braces to avoid ambiguous %<else%>");
6550
6551 if (warn_duplicated_cond)
6552 /* This if statement does not have an else clause. We don't
6553 need the condition chain anymore. */
6554 vec_free (chain);
6555 }
6556 c_finish_if_stmt (loc, cond, first_body, second_body);
6557 add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
6558
6559 c_parser_maybe_reclassify_token (parser);
6560 }
6561
6562 /* Parse a switch statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
6563
6564 switch-statement:
6565 switch (expression) statement
6566 */
6567
6568 static void
c_parser_switch_statement(c_parser * parser,bool * if_p)6569 c_parser_switch_statement (c_parser *parser, bool *if_p)
6570 {
6571 struct c_expr ce;
6572 tree block, expr, body;
6573 unsigned char save_in_statement;
6574 location_t switch_loc = c_parser_peek_token (parser)->location;
6575 location_t switch_cond_loc;
6576 gcc_assert (c_parser_next_token_is_keyword (parser, RID_SWITCH));
6577 c_parser_consume_token (parser);
6578 block = c_begin_compound_stmt (flag_isoc99);
6579 bool explicit_cast_p = false;
6580 matching_parens parens;
6581 if (parens.require_open (parser))
6582 {
6583 switch_cond_loc = c_parser_peek_token (parser)->location;
6584 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
6585 && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
6586 explicit_cast_p = true;
6587 ce = c_parser_expression (parser);
6588 ce = convert_lvalue_to_rvalue (switch_cond_loc, ce, true, true);
6589 expr = ce.value;
6590 /* ??? expr has no valid location? */
6591 parens.skip_until_found_close (parser);
6592 }
6593 else
6594 {
6595 switch_cond_loc = UNKNOWN_LOCATION;
6596 expr = error_mark_node;
6597 ce.original_type = error_mark_node;
6598 }
6599 c_start_switch (switch_loc, switch_cond_loc, expr, explicit_cast_p);
6600 save_in_statement = in_statement;
6601 in_statement |= IN_SWITCH_STMT;
6602 location_t loc_after_labels;
6603 bool open_brace_p = c_parser_peek_token (parser)->type == CPP_OPEN_BRACE;
6604 body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
6605 location_t next_loc = c_parser_peek_token (parser)->location;
6606 if (!open_brace_p && c_parser_peek_token (parser)->type != CPP_SEMICOLON)
6607 warn_for_multistatement_macros (loc_after_labels, next_loc, switch_loc,
6608 RID_SWITCH);
6609 c_finish_switch (body, ce.original_type);
6610 in_statement = save_in_statement;
6611 add_stmt (c_end_compound_stmt (switch_loc, block, flag_isoc99));
6612 c_parser_maybe_reclassify_token (parser);
6613 }
6614
6615 /* Parse a while statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6616
6617 while-statement:
6618 while (expression) statement
6619
6620 IF_P is used to track whether there's a (possibly labeled) if statement
6621 which is not enclosed in braces and has an else clause. This is used to
6622 implement -Wparentheses. */
6623
6624 static void
c_parser_while_statement(c_parser * parser,bool ivdep,unsigned short unroll,bool * if_p)6625 c_parser_while_statement (c_parser *parser, bool ivdep, unsigned short unroll,
6626 bool *if_p)
6627 {
6628 tree block, cond, body;
6629 unsigned char save_in_statement;
6630 location_t loc;
6631 gcc_assert (c_parser_next_token_is_keyword (parser, RID_WHILE));
6632 token_indent_info while_tinfo
6633 = get_token_indent_info (c_parser_peek_token (parser));
6634 c_parser_consume_token (parser);
6635 block = c_begin_compound_stmt (flag_isoc99);
6636 loc = c_parser_peek_token (parser)->location;
6637 cond = c_parser_paren_condition (parser);
6638 if (ivdep && cond != error_mark_node)
6639 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6640 build_int_cst (integer_type_node,
6641 annot_expr_ivdep_kind),
6642 integer_zero_node);
6643 if (unroll && cond != error_mark_node)
6644 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6645 build_int_cst (integer_type_node,
6646 annot_expr_unroll_kind),
6647 build_int_cst (integer_type_node, unroll));
6648 save_in_statement = in_statement;
6649 in_statement = IN_ITERATION_STMT;
6650
6651 token_indent_info body_tinfo
6652 = get_token_indent_info (c_parser_peek_token (parser));
6653
6654 location_t loc_after_labels;
6655 bool open_brace = c_parser_next_token_is (parser, CPP_OPEN_BRACE);
6656 body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
6657 add_stmt (build_stmt (loc, WHILE_STMT, cond, body));
6658 add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
6659 c_parser_maybe_reclassify_token (parser);
6660
6661 token_indent_info next_tinfo
6662 = get_token_indent_info (c_parser_peek_token (parser));
6663 warn_for_misleading_indentation (while_tinfo, body_tinfo, next_tinfo);
6664
6665 if (next_tinfo.type != CPP_SEMICOLON && !open_brace)
6666 warn_for_multistatement_macros (loc_after_labels, next_tinfo.location,
6667 while_tinfo.location, RID_WHILE);
6668
6669 in_statement = save_in_statement;
6670 }
6671
6672 /* Parse a do statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6673
6674 do-statement:
6675 do statement while ( expression ) ;
6676 */
6677
6678 static void
c_parser_do_statement(c_parser * parser,bool ivdep,unsigned short unroll)6679 c_parser_do_statement (c_parser *parser, bool ivdep, unsigned short unroll)
6680 {
6681 tree block, cond, body;
6682 unsigned char save_in_statement;
6683 location_t loc;
6684 gcc_assert (c_parser_next_token_is_keyword (parser, RID_DO));
6685 c_parser_consume_token (parser);
6686 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6687 warning_at (c_parser_peek_token (parser)->location,
6688 OPT_Wempty_body,
6689 "suggest braces around empty body in %<do%> statement");
6690 block = c_begin_compound_stmt (flag_isoc99);
6691 loc = c_parser_peek_token (parser)->location;
6692 save_in_statement = in_statement;
6693 in_statement = IN_ITERATION_STMT;
6694 body = c_parser_c99_block_statement (parser, NULL);
6695 c_parser_require_keyword (parser, RID_WHILE, "expected %<while%>");
6696 in_statement = save_in_statement;
6697 cond = c_parser_paren_condition (parser);
6698 if (ivdep && cond != error_mark_node)
6699 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6700 build_int_cst (integer_type_node,
6701 annot_expr_ivdep_kind),
6702 integer_zero_node);
6703 if (unroll && cond != error_mark_node)
6704 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6705 build_int_cst (integer_type_node,
6706 annot_expr_unroll_kind),
6707 build_int_cst (integer_type_node, unroll));
6708 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
6709 c_parser_skip_to_end_of_block_or_statement (parser);
6710
6711 add_stmt (build_stmt (loc, DO_STMT, cond, body));
6712 add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
6713 }
6714
6715 /* Parse a for statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6716
6717 for-statement:
6718 for ( expression[opt] ; expression[opt] ; expression[opt] ) statement
6719 for ( nested-declaration expression[opt] ; expression[opt] ) statement
6720
6721 The form with a declaration is new in C99.
6722
6723 ??? In accordance with the old parser, the declaration may be a
6724 nested function, which is then rejected in check_for_loop_decls,
6725 but does it make any sense for this to be included in the grammar?
6726 Note in particular that the nested function does not include a
6727 trailing ';', whereas the "declaration" production includes one.
6728 Also, can we reject bad declarations earlier and cheaper than
6729 check_for_loop_decls?
6730
6731 In Objective-C, there are two additional variants:
6732
6733 foreach-statement:
6734 for ( expression in expresssion ) statement
6735 for ( declaration in expression ) statement
6736
6737 This is inconsistent with C, because the second variant is allowed
6738 even if c99 is not enabled.
6739
6740 The rest of the comment documents these Objective-C foreach-statement.
6741
6742 Here is the canonical example of the first variant:
6743 for (object in array) { do something with object }
6744 we call the first expression ("object") the "object_expression" and
6745 the second expression ("array") the "collection_expression".
6746 object_expression must be an lvalue of type "id" (a generic Objective-C
6747 object) because the loop works by assigning to object_expression the
6748 various objects from the collection_expression. collection_expression
6749 must evaluate to something of type "id" which responds to the method
6750 countByEnumeratingWithState:objects:count:.
6751
6752 The canonical example of the second variant is:
6753 for (id object in array) { do something with object }
6754 which is completely equivalent to
6755 {
6756 id object;
6757 for (object in array) { do something with object }
6758 }
6759 Note that initizializing 'object' in some way (eg, "for ((object =
6760 xxx) in array) { do something with object }") is possibly
6761 technically valid, but completely pointless as 'object' will be
6762 assigned to something else as soon as the loop starts. We should
6763 most likely reject it (TODO).
6764
6765 The beginning of the Objective-C foreach-statement looks exactly
6766 like the beginning of the for-statement, and we can tell it is a
6767 foreach-statement only because the initial declaration or
6768 expression is terminated by 'in' instead of ';'.
6769
6770 IF_P is used to track whether there's a (possibly labeled) if statement
6771 which is not enclosed in braces and has an else clause. This is used to
6772 implement -Wparentheses. */
6773
6774 static void
c_parser_for_statement(c_parser * parser,bool ivdep,unsigned short unroll,bool * if_p)6775 c_parser_for_statement (c_parser *parser, bool ivdep, unsigned short unroll,
6776 bool *if_p)
6777 {
6778 tree block, cond, incr, body;
6779 unsigned char save_in_statement;
6780 tree save_objc_foreach_break_label, save_objc_foreach_continue_label;
6781 /* The following are only used when parsing an ObjC foreach statement. */
6782 tree object_expression;
6783 /* Silence the bogus uninitialized warning. */
6784 tree collection_expression = NULL;
6785 location_t loc = c_parser_peek_token (parser)->location;
6786 location_t for_loc = loc;
6787 bool is_foreach_statement = false;
6788 gcc_assert (c_parser_next_token_is_keyword (parser, RID_FOR));
6789 token_indent_info for_tinfo
6790 = get_token_indent_info (c_parser_peek_token (parser));
6791 c_parser_consume_token (parser);
6792 /* Open a compound statement in Objective-C as well, just in case this is
6793 as foreach expression. */
6794 block = c_begin_compound_stmt (flag_isoc99 || c_dialect_objc ());
6795 cond = error_mark_node;
6796 incr = error_mark_node;
6797 matching_parens parens;
6798 if (parens.require_open (parser))
6799 {
6800 /* Parse the initialization declaration or expression. */
6801 object_expression = error_mark_node;
6802 parser->objc_could_be_foreach_context = c_dialect_objc ();
6803 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6804 {
6805 parser->objc_could_be_foreach_context = false;
6806 c_parser_consume_token (parser);
6807 c_finish_expr_stmt (loc, NULL_TREE);
6808 }
6809 else if (c_parser_next_tokens_start_declaration (parser)
6810 || c_parser_nth_token_starts_std_attributes (parser, 1))
6811 {
6812 c_parser_declaration_or_fndef (parser, true, true, true, true, true,
6813 &object_expression);
6814 parser->objc_could_be_foreach_context = false;
6815
6816 if (c_parser_next_token_is_keyword (parser, RID_IN))
6817 {
6818 c_parser_consume_token (parser);
6819 is_foreach_statement = true;
6820 if (check_for_loop_decls (for_loc, true) == NULL_TREE)
6821 c_parser_error (parser, "multiple iterating variables in "
6822 "fast enumeration");
6823 }
6824 else
6825 check_for_loop_decls (for_loc, flag_isoc99);
6826 }
6827 else if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
6828 {
6829 /* __extension__ can start a declaration, but is also an
6830 unary operator that can start an expression. Consume all
6831 but the last of a possible series of __extension__ to
6832 determine which. */
6833 while (c_parser_peek_2nd_token (parser)->type == CPP_KEYWORD
6834 && (c_parser_peek_2nd_token (parser)->keyword
6835 == RID_EXTENSION))
6836 c_parser_consume_token (parser);
6837 if (c_token_starts_declaration (c_parser_peek_2nd_token (parser))
6838 || c_parser_nth_token_starts_std_attributes (parser, 2))
6839 {
6840 int ext;
6841 ext = disable_extension_diagnostics ();
6842 c_parser_consume_token (parser);
6843 c_parser_declaration_or_fndef (parser, true, true, true, true,
6844 true, &object_expression);
6845 parser->objc_could_be_foreach_context = false;
6846
6847 restore_extension_diagnostics (ext);
6848 if (c_parser_next_token_is_keyword (parser, RID_IN))
6849 {
6850 c_parser_consume_token (parser);
6851 is_foreach_statement = true;
6852 if (check_for_loop_decls (for_loc, true) == NULL_TREE)
6853 c_parser_error (parser, "multiple iterating variables in "
6854 "fast enumeration");
6855 }
6856 else
6857 check_for_loop_decls (for_loc, flag_isoc99);
6858 }
6859 else
6860 goto init_expr;
6861 }
6862 else
6863 {
6864 init_expr:
6865 {
6866 struct c_expr ce;
6867 tree init_expression;
6868 ce = c_parser_expression (parser);
6869 init_expression = ce.value;
6870 parser->objc_could_be_foreach_context = false;
6871 if (c_parser_next_token_is_keyword (parser, RID_IN))
6872 {
6873 c_parser_consume_token (parser);
6874 is_foreach_statement = true;
6875 if (! lvalue_p (init_expression))
6876 c_parser_error (parser, "invalid iterating variable in "
6877 "fast enumeration");
6878 object_expression
6879 = c_fully_fold (init_expression, false, NULL);
6880 }
6881 else
6882 {
6883 ce = convert_lvalue_to_rvalue (loc, ce, true, false);
6884 init_expression = ce.value;
6885 c_finish_expr_stmt (loc, init_expression);
6886 c_parser_skip_until_found (parser, CPP_SEMICOLON,
6887 "expected %<;%>");
6888 }
6889 }
6890 }
6891 /* Parse the loop condition. In the case of a foreach
6892 statement, there is no loop condition. */
6893 gcc_assert (!parser->objc_could_be_foreach_context);
6894 if (!is_foreach_statement)
6895 {
6896 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6897 {
6898 if (ivdep)
6899 {
6900 c_parser_error (parser, "missing loop condition in loop "
6901 "with %<GCC ivdep%> pragma");
6902 cond = error_mark_node;
6903 }
6904 else if (unroll)
6905 {
6906 c_parser_error (parser, "missing loop condition in loop "
6907 "with %<GCC unroll%> pragma");
6908 cond = error_mark_node;
6909 }
6910 else
6911 {
6912 c_parser_consume_token (parser);
6913 cond = NULL_TREE;
6914 }
6915 }
6916 else
6917 {
6918 cond = c_parser_condition (parser);
6919 c_parser_skip_until_found (parser, CPP_SEMICOLON,
6920 "expected %<;%>");
6921 }
6922 if (ivdep && cond != error_mark_node)
6923 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6924 build_int_cst (integer_type_node,
6925 annot_expr_ivdep_kind),
6926 integer_zero_node);
6927 if (unroll && cond != error_mark_node)
6928 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6929 build_int_cst (integer_type_node,
6930 annot_expr_unroll_kind),
6931 build_int_cst (integer_type_node, unroll));
6932 }
6933 /* Parse the increment expression (the third expression in a
6934 for-statement). In the case of a foreach-statement, this is
6935 the expression that follows the 'in'. */
6936 loc = c_parser_peek_token (parser)->location;
6937 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
6938 {
6939 if (is_foreach_statement)
6940 {
6941 c_parser_error (parser,
6942 "missing collection in fast enumeration");
6943 collection_expression = error_mark_node;
6944 }
6945 else
6946 incr = c_process_expr_stmt (loc, NULL_TREE);
6947 }
6948 else
6949 {
6950 if (is_foreach_statement)
6951 collection_expression
6952 = c_fully_fold (c_parser_expression (parser).value, false, NULL);
6953 else
6954 {
6955 struct c_expr ce = c_parser_expression (parser);
6956 ce = convert_lvalue_to_rvalue (loc, ce, true, false);
6957 incr = c_process_expr_stmt (loc, ce.value);
6958 }
6959 }
6960 parens.skip_until_found_close (parser);
6961 }
6962 save_in_statement = in_statement;
6963 if (is_foreach_statement)
6964 {
6965 in_statement = IN_OBJC_FOREACH;
6966 save_objc_foreach_break_label = objc_foreach_break_label;
6967 save_objc_foreach_continue_label = objc_foreach_continue_label;
6968 objc_foreach_break_label = create_artificial_label (loc);
6969 objc_foreach_continue_label = create_artificial_label (loc);
6970 }
6971 else
6972 in_statement = IN_ITERATION_STMT;
6973
6974 token_indent_info body_tinfo
6975 = get_token_indent_info (c_parser_peek_token (parser));
6976
6977 location_t loc_after_labels;
6978 bool open_brace = c_parser_next_token_is (parser, CPP_OPEN_BRACE);
6979 body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
6980
6981 if (is_foreach_statement)
6982 objc_finish_foreach_loop (for_loc, object_expression,
6983 collection_expression, body,
6984 objc_foreach_break_label,
6985 objc_foreach_continue_label);
6986 else
6987 add_stmt (build_stmt (for_loc, FOR_STMT, NULL_TREE, cond, incr,
6988 body, NULL_TREE));
6989 add_stmt (c_end_compound_stmt (for_loc, block,
6990 flag_isoc99 || c_dialect_objc ()));
6991 c_parser_maybe_reclassify_token (parser);
6992
6993 token_indent_info next_tinfo
6994 = get_token_indent_info (c_parser_peek_token (parser));
6995 warn_for_misleading_indentation (for_tinfo, body_tinfo, next_tinfo);
6996
6997 if (next_tinfo.type != CPP_SEMICOLON && !open_brace)
6998 warn_for_multistatement_macros (loc_after_labels, next_tinfo.location,
6999 for_tinfo.location, RID_FOR);
7000
7001 in_statement = save_in_statement;
7002 if (is_foreach_statement)
7003 {
7004 objc_foreach_break_label = save_objc_foreach_break_label;
7005 objc_foreach_continue_label = save_objc_foreach_continue_label;
7006 }
7007 }
7008
7009 /* Parse an asm statement, a GNU extension. This is a full-blown asm
7010 statement with inputs, outputs, clobbers, and volatile, inline, and goto
7011 tags allowed.
7012
7013 asm-qualifier:
7014 volatile
7015 inline
7016 goto
7017
7018 asm-qualifier-list:
7019 asm-qualifier-list asm-qualifier
7020 asm-qualifier
7021
7022 asm-statement:
7023 asm asm-qualifier-list[opt] ( asm-argument ) ;
7024
7025 asm-argument:
7026 asm-string-literal
7027 asm-string-literal : asm-operands[opt]
7028 asm-string-literal : asm-operands[opt] : asm-operands[opt]
7029 asm-string-literal : asm-operands[opt] : asm-operands[opt] \
7030 : asm-clobbers[opt]
7031 asm-string-literal : : asm-operands[opt] : asm-clobbers[opt] \
7032 : asm-goto-operands
7033
7034 The form with asm-goto-operands is valid if and only if the
7035 asm-qualifier-list contains goto, and is the only allowed form in that case.
7036 Duplicate asm-qualifiers are not allowed.
7037
7038 The :: token is considered equivalent to two consecutive : tokens. */
7039
7040 static tree
c_parser_asm_statement(c_parser * parser)7041 c_parser_asm_statement (c_parser *parser)
7042 {
7043 tree str, outputs, inputs, clobbers, labels, ret;
7044 bool simple;
7045 location_t asm_loc = c_parser_peek_token (parser)->location;
7046 int section, nsections;
7047
7048 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
7049 c_parser_consume_token (parser);
7050
7051 /* Handle the asm-qualifier-list. */
7052 location_t volatile_loc = UNKNOWN_LOCATION;
7053 location_t inline_loc = UNKNOWN_LOCATION;
7054 location_t goto_loc = UNKNOWN_LOCATION;
7055 for (;;)
7056 {
7057 c_token *token = c_parser_peek_token (parser);
7058 location_t loc = token->location;
7059 switch (token->keyword)
7060 {
7061 case RID_VOLATILE:
7062 if (volatile_loc)
7063 {
7064 error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
7065 inform (volatile_loc, "first seen here");
7066 }
7067 else
7068 volatile_loc = loc;
7069 c_parser_consume_token (parser);
7070 continue;
7071
7072 case RID_INLINE:
7073 if (inline_loc)
7074 {
7075 error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
7076 inform (inline_loc, "first seen here");
7077 }
7078 else
7079 inline_loc = loc;
7080 c_parser_consume_token (parser);
7081 continue;
7082
7083 case RID_GOTO:
7084 if (goto_loc)
7085 {
7086 error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
7087 inform (goto_loc, "first seen here");
7088 }
7089 else
7090 goto_loc = loc;
7091 c_parser_consume_token (parser);
7092 continue;
7093
7094 case RID_CONST:
7095 case RID_RESTRICT:
7096 error_at (loc, "%qE is not a valid %<asm%> qualifier", token->value);
7097 c_parser_consume_token (parser);
7098 continue;
7099
7100 default:
7101 break;
7102 }
7103 break;
7104 }
7105
7106 bool is_volatile = (volatile_loc != UNKNOWN_LOCATION);
7107 bool is_inline = (inline_loc != UNKNOWN_LOCATION);
7108 bool is_goto = (goto_loc != UNKNOWN_LOCATION);
7109
7110 ret = NULL;
7111
7112 matching_parens parens;
7113 if (!parens.require_open (parser))
7114 goto error;
7115
7116 str = c_parser_asm_string_literal (parser);
7117 if (str == NULL_TREE)
7118 goto error_close_paren;
7119
7120 simple = true;
7121 outputs = NULL_TREE;
7122 inputs = NULL_TREE;
7123 clobbers = NULL_TREE;
7124 labels = NULL_TREE;
7125
7126 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN) && !is_goto)
7127 goto done_asm;
7128
7129 /* Parse each colon-delimited section of operands. */
7130 nsections = 3 + is_goto;
7131 for (section = 0; section < nsections; ++section)
7132 {
7133 if (c_parser_next_token_is (parser, CPP_SCOPE))
7134 {
7135 ++section;
7136 if (section == nsections)
7137 {
7138 c_parser_error (parser, "expected %<)%>");
7139 goto error_close_paren;
7140 }
7141 c_parser_consume_token (parser);
7142 }
7143 else if (!c_parser_require (parser, CPP_COLON,
7144 is_goto
7145 ? G_("expected %<:%>")
7146 : G_("expected %<:%> or %<)%>"),
7147 UNKNOWN_LOCATION, is_goto))
7148 goto error_close_paren;
7149
7150 /* Once past any colon, we're no longer a simple asm. */
7151 simple = false;
7152
7153 if ((!c_parser_next_token_is (parser, CPP_COLON)
7154 && !c_parser_next_token_is (parser, CPP_SCOPE)
7155 && !c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
7156 || section == 3)
7157 switch (section)
7158 {
7159 case 0:
7160 outputs = c_parser_asm_operands (parser);
7161 break;
7162 case 1:
7163 inputs = c_parser_asm_operands (parser);
7164 break;
7165 case 2:
7166 clobbers = c_parser_asm_clobbers (parser);
7167 break;
7168 case 3:
7169 labels = c_parser_asm_goto_operands (parser);
7170 break;
7171 default:
7172 gcc_unreachable ();
7173 }
7174
7175 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN) && !is_goto)
7176 goto done_asm;
7177 }
7178
7179 done_asm:
7180 if (!parens.require_close (parser))
7181 {
7182 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
7183 goto error;
7184 }
7185
7186 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
7187 c_parser_skip_to_end_of_block_or_statement (parser);
7188
7189 ret = build_asm_stmt (is_volatile,
7190 build_asm_expr (asm_loc, str, outputs, inputs,
7191 clobbers, labels, simple, is_inline));
7192
7193 error:
7194 return ret;
7195
7196 error_close_paren:
7197 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
7198 goto error;
7199 }
7200
7201 /* Parse asm operands, a GNU extension.
7202
7203 asm-operands:
7204 asm-operand
7205 asm-operands , asm-operand
7206
7207 asm-operand:
7208 asm-string-literal ( expression )
7209 [ identifier ] asm-string-literal ( expression )
7210 */
7211
7212 static tree
c_parser_asm_operands(c_parser * parser)7213 c_parser_asm_operands (c_parser *parser)
7214 {
7215 tree list = NULL_TREE;
7216 while (true)
7217 {
7218 tree name, str;
7219 struct c_expr expr;
7220 if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
7221 {
7222 c_parser_consume_token (parser);
7223 if (c_parser_next_token_is (parser, CPP_NAME))
7224 {
7225 tree id = c_parser_peek_token (parser)->value;
7226 c_parser_consume_token (parser);
7227 name = build_string (IDENTIFIER_LENGTH (id),
7228 IDENTIFIER_POINTER (id));
7229 }
7230 else
7231 {
7232 c_parser_error (parser, "expected identifier");
7233 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL);
7234 return NULL_TREE;
7235 }
7236 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
7237 "expected %<]%>");
7238 }
7239 else
7240 name = NULL_TREE;
7241 str = c_parser_asm_string_literal (parser);
7242 if (str == NULL_TREE)
7243 return NULL_TREE;
7244 matching_parens parens;
7245 if (!parens.require_open (parser))
7246 return NULL_TREE;
7247 expr = c_parser_expression (parser);
7248 mark_exp_read (expr.value);
7249 if (!parens.require_close (parser))
7250 {
7251 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
7252 return NULL_TREE;
7253 }
7254 list = chainon (list, build_tree_list (build_tree_list (name, str),
7255 expr.value));
7256 if (c_parser_next_token_is (parser, CPP_COMMA))
7257 c_parser_consume_token (parser);
7258 else
7259 break;
7260 }
7261 return list;
7262 }
7263
7264 /* Parse asm clobbers, a GNU extension.
7265
7266 asm-clobbers:
7267 asm-string-literal
7268 asm-clobbers , asm-string-literal
7269 */
7270
7271 static tree
c_parser_asm_clobbers(c_parser * parser)7272 c_parser_asm_clobbers (c_parser *parser)
7273 {
7274 tree list = NULL_TREE;
7275 while (true)
7276 {
7277 tree str = c_parser_asm_string_literal (parser);
7278 if (str)
7279 list = tree_cons (NULL_TREE, str, list);
7280 else
7281 return NULL_TREE;
7282 if (c_parser_next_token_is (parser, CPP_COMMA))
7283 c_parser_consume_token (parser);
7284 else
7285 break;
7286 }
7287 return list;
7288 }
7289
7290 /* Parse asm goto labels, a GNU extension.
7291
7292 asm-goto-operands:
7293 identifier
7294 asm-goto-operands , identifier
7295 */
7296
7297 static tree
c_parser_asm_goto_operands(c_parser * parser)7298 c_parser_asm_goto_operands (c_parser *parser)
7299 {
7300 tree list = NULL_TREE;
7301 while (true)
7302 {
7303 tree name, label;
7304
7305 if (c_parser_next_token_is (parser, CPP_NAME))
7306 {
7307 c_token *tok = c_parser_peek_token (parser);
7308 name = tok->value;
7309 label = lookup_label_for_goto (tok->location, name);
7310 c_parser_consume_token (parser);
7311 TREE_USED (label) = 1;
7312 }
7313 else
7314 {
7315 c_parser_error (parser, "expected identifier");
7316 return NULL_TREE;
7317 }
7318
7319 name = build_string (IDENTIFIER_LENGTH (name),
7320 IDENTIFIER_POINTER (name));
7321 list = tree_cons (name, label, list);
7322 if (c_parser_next_token_is (parser, CPP_COMMA))
7323 c_parser_consume_token (parser);
7324 else
7325 return nreverse (list);
7326 }
7327 }
7328
7329 /* Parse a possibly concatenated sequence of string literals.
7330 TRANSLATE says whether to translate them to the execution character
7331 set; WIDE_OK says whether any kind of prefixed string literal is
7332 permitted in this context. This code is based on that in
7333 lex_string. */
7334
7335 struct c_expr
c_parser_string_literal(c_parser * parser,bool translate,bool wide_ok)7336 c_parser_string_literal (c_parser *parser, bool translate, bool wide_ok)
7337 {
7338 struct c_expr ret;
7339 size_t count;
7340 struct obstack str_ob;
7341 struct obstack loc_ob;
7342 cpp_string str, istr, *strs;
7343 c_token *tok;
7344 location_t loc, last_tok_loc;
7345 enum cpp_ttype type;
7346 tree value, string_tree;
7347
7348 tok = c_parser_peek_token (parser);
7349 loc = tok->location;
7350 last_tok_loc = linemap_resolve_location (line_table, loc,
7351 LRK_MACRO_DEFINITION_LOCATION,
7352 NULL);
7353 type = tok->type;
7354 switch (type)
7355 {
7356 case CPP_STRING:
7357 case CPP_WSTRING:
7358 case CPP_STRING16:
7359 case CPP_STRING32:
7360 case CPP_UTF8STRING:
7361 string_tree = tok->value;
7362 break;
7363
7364 default:
7365 c_parser_error (parser, "expected string literal");
7366 ret.set_error ();
7367 ret.value = NULL_TREE;
7368 ret.original_code = ERROR_MARK;
7369 ret.original_type = NULL_TREE;
7370 return ret;
7371 }
7372
7373 /* Try to avoid the overhead of creating and destroying an obstack
7374 for the common case of just one string. */
7375 switch (c_parser_peek_2nd_token (parser)->type)
7376 {
7377 default:
7378 c_parser_consume_token (parser);
7379 str.text = (const unsigned char *) TREE_STRING_POINTER (string_tree);
7380 str.len = TREE_STRING_LENGTH (string_tree);
7381 count = 1;
7382 strs = &str;
7383 break;
7384
7385 case CPP_STRING:
7386 case CPP_WSTRING:
7387 case CPP_STRING16:
7388 case CPP_STRING32:
7389 case CPP_UTF8STRING:
7390 gcc_obstack_init (&str_ob);
7391 gcc_obstack_init (&loc_ob);
7392 count = 0;
7393 do
7394 {
7395 c_parser_consume_token (parser);
7396 count++;
7397 str.text = (const unsigned char *) TREE_STRING_POINTER (string_tree);
7398 str.len = TREE_STRING_LENGTH (string_tree);
7399 if (type != tok->type)
7400 {
7401 if (type == CPP_STRING)
7402 type = tok->type;
7403 else if (tok->type != CPP_STRING)
7404 error ("unsupported non-standard concatenation "
7405 "of string literals");
7406 }
7407 obstack_grow (&str_ob, &str, sizeof (cpp_string));
7408 obstack_grow (&loc_ob, &last_tok_loc, sizeof (location_t));
7409 tok = c_parser_peek_token (parser);
7410 string_tree = tok->value;
7411 last_tok_loc
7412 = linemap_resolve_location (line_table, tok->location,
7413 LRK_MACRO_DEFINITION_LOCATION, NULL);
7414 }
7415 while (tok->type == CPP_STRING
7416 || tok->type == CPP_WSTRING
7417 || tok->type == CPP_STRING16
7418 || tok->type == CPP_STRING32
7419 || tok->type == CPP_UTF8STRING);
7420 strs = (cpp_string *) obstack_finish (&str_ob);
7421 }
7422
7423 if (count > 1 && !in_system_header_at (input_location))
7424 warning (OPT_Wtraditional,
7425 "traditional C rejects string constant concatenation");
7426
7427 if ((type == CPP_STRING || wide_ok)
7428 && ((translate
7429 ? cpp_interpret_string : cpp_interpret_string_notranslate)
7430 (parse_in, strs, count, &istr, type)))
7431 {
7432 value = build_string (istr.len, (const char *) istr.text);
7433 free (CONST_CAST (unsigned char *, istr.text));
7434 if (count > 1)
7435 {
7436 location_t *locs = (location_t *) obstack_finish (&loc_ob);
7437 gcc_assert (g_string_concat_db);
7438 g_string_concat_db->record_string_concatenation (count, locs);
7439 }
7440 }
7441 else
7442 {
7443 if (type != CPP_STRING && !wide_ok)
7444 {
7445 error_at (loc, "a wide string is invalid in this context");
7446 type = CPP_STRING;
7447 }
7448 /* Callers cannot generally handle error_mark_node in this
7449 context, so return the empty string instead. An error has
7450 been issued, either above or from cpp_interpret_string. */
7451 switch (type)
7452 {
7453 default:
7454 case CPP_STRING:
7455 case CPP_UTF8STRING:
7456 value = build_string (1, "");
7457 break;
7458 case CPP_STRING16:
7459 value = build_string (TYPE_PRECISION (char16_type_node)
7460 / TYPE_PRECISION (char_type_node),
7461 "\0"); /* char16_t is 16 bits */
7462 break;
7463 case CPP_STRING32:
7464 value = build_string (TYPE_PRECISION (char32_type_node)
7465 / TYPE_PRECISION (char_type_node),
7466 "\0\0\0"); /* char32_t is 32 bits */
7467 break;
7468 case CPP_WSTRING:
7469 value = build_string (TYPE_PRECISION (wchar_type_node)
7470 / TYPE_PRECISION (char_type_node),
7471 "\0\0\0"); /* widest supported wchar_t
7472 is 32 bits */
7473 break;
7474 }
7475 }
7476
7477 switch (type)
7478 {
7479 default:
7480 case CPP_STRING:
7481 case CPP_UTF8STRING:
7482 TREE_TYPE (value) = char_array_type_node;
7483 break;
7484 case CPP_STRING16:
7485 TREE_TYPE (value) = char16_array_type_node;
7486 break;
7487 case CPP_STRING32:
7488 TREE_TYPE (value) = char32_array_type_node;
7489 break;
7490 case CPP_WSTRING:
7491 TREE_TYPE (value) = wchar_array_type_node;
7492 }
7493 value = fix_string_type (value);
7494
7495 if (count > 1)
7496 {
7497 obstack_free (&str_ob, 0);
7498 obstack_free (&loc_ob, 0);
7499 }
7500
7501 ret.value = value;
7502 ret.original_code = STRING_CST;
7503 ret.original_type = NULL_TREE;
7504 set_c_expr_source_range (&ret, get_range_from_loc (line_table, loc));
7505 parser->seen_string_literal = true;
7506 return ret;
7507 }
7508
7509 /* Parse an expression other than a compound expression; that is, an
7510 assignment expression (C90 6.3.16, C99 6.5.16, C11 6.5.16). If
7511 AFTER is not NULL then it is an Objective-C message expression which
7512 is the primary-expression starting the expression as an initializer.
7513
7514 assignment-expression:
7515 conditional-expression
7516 unary-expression assignment-operator assignment-expression
7517
7518 assignment-operator: one of
7519 = *= /= %= += -= <<= >>= &= ^= |=
7520
7521 In GNU C we accept any conditional expression on the LHS and
7522 diagnose the invalid lvalue rather than producing a syntax
7523 error. */
7524
7525 static struct c_expr
c_parser_expr_no_commas(c_parser * parser,struct c_expr * after,tree omp_atomic_lhs)7526 c_parser_expr_no_commas (c_parser *parser, struct c_expr *after,
7527 tree omp_atomic_lhs)
7528 {
7529 struct c_expr lhs, rhs, ret;
7530 enum tree_code code;
7531 location_t op_location, exp_location;
7532 bool save_in_omp_for = c_in_omp_for;
7533 c_in_omp_for = false;
7534 gcc_assert (!after || c_dialect_objc ());
7535 lhs = c_parser_conditional_expression (parser, after, omp_atomic_lhs);
7536 op_location = c_parser_peek_token (parser)->location;
7537 switch (c_parser_peek_token (parser)->type)
7538 {
7539 case CPP_EQ:
7540 code = NOP_EXPR;
7541 break;
7542 case CPP_MULT_EQ:
7543 code = MULT_EXPR;
7544 break;
7545 case CPP_DIV_EQ:
7546 code = TRUNC_DIV_EXPR;
7547 break;
7548 case CPP_MOD_EQ:
7549 code = TRUNC_MOD_EXPR;
7550 break;
7551 case CPP_PLUS_EQ:
7552 code = PLUS_EXPR;
7553 break;
7554 case CPP_MINUS_EQ:
7555 code = MINUS_EXPR;
7556 break;
7557 case CPP_LSHIFT_EQ:
7558 code = LSHIFT_EXPR;
7559 break;
7560 case CPP_RSHIFT_EQ:
7561 code = RSHIFT_EXPR;
7562 break;
7563 case CPP_AND_EQ:
7564 code = BIT_AND_EXPR;
7565 break;
7566 case CPP_XOR_EQ:
7567 code = BIT_XOR_EXPR;
7568 break;
7569 case CPP_OR_EQ:
7570 code = BIT_IOR_EXPR;
7571 break;
7572 default:
7573 c_in_omp_for = save_in_omp_for;
7574 return lhs;
7575 }
7576 c_parser_consume_token (parser);
7577 exp_location = c_parser_peek_token (parser)->location;
7578 rhs = c_parser_expr_no_commas (parser, NULL);
7579 rhs = convert_lvalue_to_rvalue (exp_location, rhs, true, true);
7580
7581 ret.value = build_modify_expr (op_location, lhs.value, lhs.original_type,
7582 code, exp_location, rhs.value,
7583 rhs.original_type);
7584 set_c_expr_source_range (&ret, lhs.get_start (), rhs.get_finish ());
7585 if (code == NOP_EXPR)
7586 ret.original_code = MODIFY_EXPR;
7587 else
7588 {
7589 suppress_warning (ret.value, OPT_Wparentheses);
7590 ret.original_code = ERROR_MARK;
7591 }
7592 ret.original_type = NULL;
7593 c_in_omp_for = save_in_omp_for;
7594 return ret;
7595 }
7596
7597 /* Parse a conditional expression (C90 6.3.15, C99 6.5.15, C11 6.5.15). If
7598 AFTER is not NULL then it is an Objective-C message expression which is
7599 the primary-expression starting the expression as an initializer.
7600
7601 conditional-expression:
7602 logical-OR-expression
7603 logical-OR-expression ? expression : conditional-expression
7604
7605 GNU extensions:
7606
7607 conditional-expression:
7608 logical-OR-expression ? : conditional-expression
7609 */
7610
7611 static struct c_expr
c_parser_conditional_expression(c_parser * parser,struct c_expr * after,tree omp_atomic_lhs)7612 c_parser_conditional_expression (c_parser *parser, struct c_expr *after,
7613 tree omp_atomic_lhs)
7614 {
7615 struct c_expr cond, exp1, exp2, ret;
7616 location_t start, cond_loc, colon_loc;
7617
7618 gcc_assert (!after || c_dialect_objc ());
7619
7620 cond = c_parser_binary_expression (parser, after, omp_atomic_lhs);
7621
7622 if (c_parser_next_token_is_not (parser, CPP_QUERY))
7623 return cond;
7624 if (cond.value != error_mark_node)
7625 start = cond.get_start ();
7626 else
7627 start = UNKNOWN_LOCATION;
7628 cond_loc = c_parser_peek_token (parser)->location;
7629 cond = convert_lvalue_to_rvalue (cond_loc, cond, true, true);
7630 c_parser_consume_token (parser);
7631 if (c_parser_next_token_is (parser, CPP_COLON))
7632 {
7633 tree eptype = NULL_TREE;
7634
7635 location_t middle_loc = c_parser_peek_token (parser)->location;
7636 pedwarn (middle_loc, OPT_Wpedantic,
7637 "ISO C forbids omitting the middle term of a %<?:%> expression");
7638 if (TREE_CODE (cond.value) == EXCESS_PRECISION_EXPR)
7639 {
7640 eptype = TREE_TYPE (cond.value);
7641 cond.value = TREE_OPERAND (cond.value, 0);
7642 }
7643 tree e = cond.value;
7644 while (TREE_CODE (e) == COMPOUND_EXPR)
7645 e = TREE_OPERAND (e, 1);
7646 warn_for_omitted_condop (middle_loc, e);
7647 /* Make sure first operand is calculated only once. */
7648 exp1.value = save_expr (default_conversion (cond.value));
7649 if (eptype)
7650 exp1.value = build1 (EXCESS_PRECISION_EXPR, eptype, exp1.value);
7651 exp1.original_type = NULL;
7652 exp1.src_range = cond.src_range;
7653 cond.value = c_objc_common_truthvalue_conversion (cond_loc, exp1.value);
7654 c_inhibit_evaluation_warnings += cond.value == truthvalue_true_node;
7655 }
7656 else
7657 {
7658 cond.value
7659 = c_objc_common_truthvalue_conversion
7660 (cond_loc, default_conversion (cond.value));
7661 c_inhibit_evaluation_warnings += cond.value == truthvalue_false_node;
7662 exp1 = c_parser_expression_conv (parser);
7663 mark_exp_read (exp1.value);
7664 c_inhibit_evaluation_warnings +=
7665 ((cond.value == truthvalue_true_node)
7666 - (cond.value == truthvalue_false_node));
7667 }
7668
7669 colon_loc = c_parser_peek_token (parser)->location;
7670 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
7671 {
7672 c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node;
7673 ret.set_error ();
7674 ret.original_code = ERROR_MARK;
7675 ret.original_type = NULL;
7676 return ret;
7677 }
7678 {
7679 location_t exp2_loc = c_parser_peek_token (parser)->location;
7680 exp2 = c_parser_conditional_expression (parser, NULL, NULL_TREE);
7681 exp2 = convert_lvalue_to_rvalue (exp2_loc, exp2, true, true);
7682 }
7683 c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node;
7684 location_t loc1 = make_location (exp1.get_start (), exp1.src_range);
7685 location_t loc2 = make_location (exp2.get_start (), exp2.src_range);
7686 if (__builtin_expect (omp_atomic_lhs != NULL, 0)
7687 && (TREE_CODE (cond.value) == GT_EXPR
7688 || TREE_CODE (cond.value) == LT_EXPR
7689 || TREE_CODE (cond.value) == EQ_EXPR)
7690 && c_tree_equal (exp2.value, omp_atomic_lhs)
7691 && (c_tree_equal (TREE_OPERAND (cond.value, 0), omp_atomic_lhs)
7692 || c_tree_equal (TREE_OPERAND (cond.value, 1), omp_atomic_lhs)))
7693 ret.value = build3_loc (colon_loc, COND_EXPR, TREE_TYPE (omp_atomic_lhs),
7694 cond.value, exp1.value, exp2.value);
7695 else
7696 ret.value
7697 = build_conditional_expr (colon_loc, cond.value,
7698 cond.original_code == C_MAYBE_CONST_EXPR,
7699 exp1.value, exp1.original_type, loc1,
7700 exp2.value, exp2.original_type, loc2);
7701 ret.original_code = ERROR_MARK;
7702 if (exp1.value == error_mark_node || exp2.value == error_mark_node)
7703 ret.original_type = NULL;
7704 else
7705 {
7706 tree t1, t2;
7707
7708 /* If both sides are enum type, the default conversion will have
7709 made the type of the result be an integer type. We want to
7710 remember the enum types we started with. */
7711 t1 = exp1.original_type ? exp1.original_type : TREE_TYPE (exp1.value);
7712 t2 = exp2.original_type ? exp2.original_type : TREE_TYPE (exp2.value);
7713 ret.original_type = ((t1 != error_mark_node
7714 && t2 != error_mark_node
7715 && (TYPE_MAIN_VARIANT (t1)
7716 == TYPE_MAIN_VARIANT (t2)))
7717 ? t1
7718 : NULL);
7719 }
7720 set_c_expr_source_range (&ret, start, exp2.get_finish ());
7721 return ret;
7722 }
7723
7724 /* Parse a binary expression; that is, a logical-OR-expression (C90
7725 6.3.5-6.3.14, C99 6.5.5-6.5.14, C11 6.5.5-6.5.14). If AFTER is not
7726 NULL then it is an Objective-C message expression which is the
7727 primary-expression starting the expression as an initializer.
7728
7729 OMP_ATOMIC_LHS is NULL, unless parsing OpenMP #pragma omp atomic,
7730 when it should be the unfolded lhs. In a valid OpenMP source,
7731 one of the operands of the toplevel binary expression must be equal
7732 to it. In that case, just return a build2 created binary operation
7733 rather than result of parser_build_binary_op.
7734
7735 multiplicative-expression:
7736 cast-expression
7737 multiplicative-expression * cast-expression
7738 multiplicative-expression / cast-expression
7739 multiplicative-expression % cast-expression
7740
7741 additive-expression:
7742 multiplicative-expression
7743 additive-expression + multiplicative-expression
7744 additive-expression - multiplicative-expression
7745
7746 shift-expression:
7747 additive-expression
7748 shift-expression << additive-expression
7749 shift-expression >> additive-expression
7750
7751 relational-expression:
7752 shift-expression
7753 relational-expression < shift-expression
7754 relational-expression > shift-expression
7755 relational-expression <= shift-expression
7756 relational-expression >= shift-expression
7757
7758 equality-expression:
7759 relational-expression
7760 equality-expression == relational-expression
7761 equality-expression != relational-expression
7762
7763 AND-expression:
7764 equality-expression
7765 AND-expression & equality-expression
7766
7767 exclusive-OR-expression:
7768 AND-expression
7769 exclusive-OR-expression ^ AND-expression
7770
7771 inclusive-OR-expression:
7772 exclusive-OR-expression
7773 inclusive-OR-expression | exclusive-OR-expression
7774
7775 logical-AND-expression:
7776 inclusive-OR-expression
7777 logical-AND-expression && inclusive-OR-expression
7778
7779 logical-OR-expression:
7780 logical-AND-expression
7781 logical-OR-expression || logical-AND-expression
7782 */
7783
7784 static struct c_expr
c_parser_binary_expression(c_parser * parser,struct c_expr * after,tree omp_atomic_lhs)7785 c_parser_binary_expression (c_parser *parser, struct c_expr *after,
7786 tree omp_atomic_lhs)
7787 {
7788 /* A binary expression is parsed using operator-precedence parsing,
7789 with the operands being cast expressions. All the binary
7790 operators are left-associative. Thus a binary expression is of
7791 form:
7792
7793 E0 op1 E1 op2 E2 ...
7794
7795 which we represent on a stack. On the stack, the precedence
7796 levels are strictly increasing. When a new operator is
7797 encountered of higher precedence than that at the top of the
7798 stack, it is pushed; its LHS is the top expression, and its RHS
7799 is everything parsed until it is popped. When a new operator is
7800 encountered with precedence less than or equal to that at the top
7801 of the stack, triples E[i-1] op[i] E[i] are popped and replaced
7802 by the result of the operation until the operator at the top of
7803 the stack has lower precedence than the new operator or there is
7804 only one element on the stack; then the top expression is the LHS
7805 of the new operator. In the case of logical AND and OR
7806 expressions, we also need to adjust c_inhibit_evaluation_warnings
7807 as appropriate when the operators are pushed and popped. */
7808
7809 struct {
7810 /* The expression at this stack level. */
7811 struct c_expr expr;
7812 /* The precedence of the operator on its left, PREC_NONE at the
7813 bottom of the stack. */
7814 enum c_parser_prec prec;
7815 /* The operation on its left. */
7816 enum tree_code op;
7817 /* The source location of this operation. */
7818 location_t loc;
7819 /* The sizeof argument if expr.original_code == {PAREN_,}SIZEOF_EXPR. */
7820 tree sizeof_arg;
7821 } stack[NUM_PRECS];
7822 int sp;
7823 /* Location of the binary operator. */
7824 location_t binary_loc = UNKNOWN_LOCATION; /* Quiet warning. */
7825 #define POP \
7826 do { \
7827 switch (stack[sp].op) \
7828 { \
7829 case TRUTH_ANDIF_EXPR: \
7830 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
7831 == truthvalue_false_node); \
7832 break; \
7833 case TRUTH_ORIF_EXPR: \
7834 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
7835 == truthvalue_true_node); \
7836 break; \
7837 case TRUNC_DIV_EXPR: \
7838 if ((stack[sp - 1].expr.original_code == SIZEOF_EXPR \
7839 || stack[sp - 1].expr.original_code == PAREN_SIZEOF_EXPR) \
7840 && (stack[sp].expr.original_code == SIZEOF_EXPR \
7841 || stack[sp].expr.original_code == PAREN_SIZEOF_EXPR)) \
7842 { \
7843 tree type0 = stack[sp - 1].sizeof_arg; \
7844 tree type1 = stack[sp].sizeof_arg; \
7845 tree first_arg = type0; \
7846 if (!TYPE_P (type0)) \
7847 type0 = TREE_TYPE (type0); \
7848 if (!TYPE_P (type1)) \
7849 type1 = TREE_TYPE (type1); \
7850 if (POINTER_TYPE_P (type0) \
7851 && comptypes (TREE_TYPE (type0), type1) \
7852 && !(TREE_CODE (first_arg) == PARM_DECL \
7853 && C_ARRAY_PARAMETER (first_arg) \
7854 && warn_sizeof_array_argument)) \
7855 { \
7856 auto_diagnostic_group d; \
7857 if (warning_at (stack[sp].loc, OPT_Wsizeof_pointer_div, \
7858 "division %<sizeof (%T) / sizeof (%T)%> " \
7859 "does not compute the number of array " \
7860 "elements", \
7861 type0, type1)) \
7862 if (DECL_P (first_arg)) \
7863 inform (DECL_SOURCE_LOCATION (first_arg), \
7864 "first %<sizeof%> operand was declared here"); \
7865 } \
7866 else if (TREE_CODE (type0) == ARRAY_TYPE \
7867 && !char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type0))) \
7868 && stack[sp].expr.original_code != PAREN_SIZEOF_EXPR) \
7869 maybe_warn_sizeof_array_div (stack[sp].loc, first_arg, type0, \
7870 stack[sp].sizeof_arg, type1); \
7871 } \
7872 break; \
7873 default: \
7874 break; \
7875 } \
7876 stack[sp - 1].expr \
7877 = convert_lvalue_to_rvalue (stack[sp - 1].loc, \
7878 stack[sp - 1].expr, true, true); \
7879 stack[sp].expr \
7880 = convert_lvalue_to_rvalue (stack[sp].loc, \
7881 stack[sp].expr, true, true); \
7882 if (__builtin_expect (omp_atomic_lhs != NULL_TREE, 0) && sp == 1 \
7883 && ((c_parser_next_token_is (parser, CPP_SEMICOLON) \
7884 && ((1 << stack[sp].prec) \
7885 & ((1 << PREC_BITOR) | (1 << PREC_BITXOR) \
7886 | (1 << PREC_BITAND) | (1 << PREC_SHIFT) \
7887 | (1 << PREC_ADD) | (1 << PREC_MULT) \
7888 | (1 << PREC_EQ)))) \
7889 || ((c_parser_next_token_is (parser, CPP_QUERY) \
7890 || (omp_atomic_lhs == void_list_node \
7891 && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))) \
7892 && (stack[sp].prec == PREC_REL || stack[sp].prec == PREC_EQ)))\
7893 && stack[sp].op != TRUNC_MOD_EXPR \
7894 && stack[sp].op != GE_EXPR \
7895 && stack[sp].op != LE_EXPR \
7896 && stack[sp].op != NE_EXPR \
7897 && stack[0].expr.value != error_mark_node \
7898 && stack[1].expr.value != error_mark_node \
7899 && (omp_atomic_lhs == void_list_node \
7900 || c_tree_equal (stack[0].expr.value, omp_atomic_lhs) \
7901 || c_tree_equal (stack[1].expr.value, omp_atomic_lhs) \
7902 || (stack[sp].op == EQ_EXPR \
7903 && c_parser_peek_2nd_token (parser)->keyword == RID_IF))) \
7904 { \
7905 tree t = make_node (stack[1].op); \
7906 TREE_TYPE (t) = TREE_TYPE (stack[0].expr.value); \
7907 TREE_OPERAND (t, 0) = stack[0].expr.value; \
7908 TREE_OPERAND (t, 1) = stack[1].expr.value; \
7909 stack[0].expr.value = t; \
7910 } \
7911 else \
7912 stack[sp - 1].expr = parser_build_binary_op (stack[sp].loc, \
7913 stack[sp].op, \
7914 stack[sp - 1].expr, \
7915 stack[sp].expr); \
7916 sp--; \
7917 } while (0)
7918 gcc_assert (!after || c_dialect_objc ());
7919 stack[0].loc = c_parser_peek_token (parser)->location;
7920 stack[0].expr = c_parser_cast_expression (parser, after);
7921 stack[0].prec = PREC_NONE;
7922 stack[0].sizeof_arg = c_last_sizeof_arg;
7923 sp = 0;
7924 while (true)
7925 {
7926 enum c_parser_prec oprec;
7927 enum tree_code ocode;
7928 source_range src_range;
7929 if (parser->error)
7930 goto out;
7931 switch (c_parser_peek_token (parser)->type)
7932 {
7933 case CPP_MULT:
7934 oprec = PREC_MULT;
7935 ocode = MULT_EXPR;
7936 break;
7937 case CPP_DIV:
7938 oprec = PREC_MULT;
7939 ocode = TRUNC_DIV_EXPR;
7940 break;
7941 case CPP_MOD:
7942 oprec = PREC_MULT;
7943 ocode = TRUNC_MOD_EXPR;
7944 break;
7945 case CPP_PLUS:
7946 oprec = PREC_ADD;
7947 ocode = PLUS_EXPR;
7948 break;
7949 case CPP_MINUS:
7950 oprec = PREC_ADD;
7951 ocode = MINUS_EXPR;
7952 break;
7953 case CPP_LSHIFT:
7954 oprec = PREC_SHIFT;
7955 ocode = LSHIFT_EXPR;
7956 break;
7957 case CPP_RSHIFT:
7958 oprec = PREC_SHIFT;
7959 ocode = RSHIFT_EXPR;
7960 break;
7961 case CPP_LESS:
7962 oprec = PREC_REL;
7963 ocode = LT_EXPR;
7964 break;
7965 case CPP_GREATER:
7966 oprec = PREC_REL;
7967 ocode = GT_EXPR;
7968 break;
7969 case CPP_LESS_EQ:
7970 oprec = PREC_REL;
7971 ocode = LE_EXPR;
7972 break;
7973 case CPP_GREATER_EQ:
7974 oprec = PREC_REL;
7975 ocode = GE_EXPR;
7976 break;
7977 case CPP_EQ_EQ:
7978 oprec = PREC_EQ;
7979 ocode = EQ_EXPR;
7980 break;
7981 case CPP_NOT_EQ:
7982 oprec = PREC_EQ;
7983 ocode = NE_EXPR;
7984 break;
7985 case CPP_AND:
7986 oprec = PREC_BITAND;
7987 ocode = BIT_AND_EXPR;
7988 break;
7989 case CPP_XOR:
7990 oprec = PREC_BITXOR;
7991 ocode = BIT_XOR_EXPR;
7992 break;
7993 case CPP_OR:
7994 oprec = PREC_BITOR;
7995 ocode = BIT_IOR_EXPR;
7996 break;
7997 case CPP_AND_AND:
7998 oprec = PREC_LOGAND;
7999 ocode = TRUTH_ANDIF_EXPR;
8000 break;
8001 case CPP_OR_OR:
8002 oprec = PREC_LOGOR;
8003 ocode = TRUTH_ORIF_EXPR;
8004 break;
8005 default:
8006 /* Not a binary operator, so end of the binary
8007 expression. */
8008 goto out;
8009 }
8010 binary_loc = c_parser_peek_token (parser)->location;
8011 while (oprec <= stack[sp].prec)
8012 POP;
8013 c_parser_consume_token (parser);
8014 switch (ocode)
8015 {
8016 case TRUTH_ANDIF_EXPR:
8017 src_range = stack[sp].expr.src_range;
8018 stack[sp].expr
8019 = convert_lvalue_to_rvalue (stack[sp].loc,
8020 stack[sp].expr, true, true);
8021 stack[sp].expr.value = c_objc_common_truthvalue_conversion
8022 (stack[sp].loc, default_conversion (stack[sp].expr.value));
8023 c_inhibit_evaluation_warnings += (stack[sp].expr.value
8024 == truthvalue_false_node);
8025 set_c_expr_source_range (&stack[sp].expr, src_range);
8026 break;
8027 case TRUTH_ORIF_EXPR:
8028 src_range = stack[sp].expr.src_range;
8029 stack[sp].expr
8030 = convert_lvalue_to_rvalue (stack[sp].loc,
8031 stack[sp].expr, true, true);
8032 stack[sp].expr.value = c_objc_common_truthvalue_conversion
8033 (stack[sp].loc, default_conversion (stack[sp].expr.value));
8034 c_inhibit_evaluation_warnings += (stack[sp].expr.value
8035 == truthvalue_true_node);
8036 set_c_expr_source_range (&stack[sp].expr, src_range);
8037 break;
8038 default:
8039 break;
8040 }
8041 sp++;
8042 stack[sp].loc = binary_loc;
8043 stack[sp].expr = c_parser_cast_expression (parser, NULL);
8044 stack[sp].prec = oprec;
8045 stack[sp].op = ocode;
8046 stack[sp].sizeof_arg = c_last_sizeof_arg;
8047 }
8048 out:
8049 while (sp > 0)
8050 POP;
8051 return stack[0].expr;
8052 #undef POP
8053 }
8054
8055 /* Parse a cast expression (C90 6.3.4, C99 6.5.4, C11 6.5.4). If AFTER
8056 is not NULL then it is an Objective-C message expression which is the
8057 primary-expression starting the expression as an initializer.
8058
8059 cast-expression:
8060 unary-expression
8061 ( type-name ) unary-expression
8062 */
8063
8064 static struct c_expr
c_parser_cast_expression(c_parser * parser,struct c_expr * after)8065 c_parser_cast_expression (c_parser *parser, struct c_expr *after)
8066 {
8067 location_t cast_loc = c_parser_peek_token (parser)->location;
8068 gcc_assert (!after || c_dialect_objc ());
8069 if (after)
8070 return c_parser_postfix_expression_after_primary (parser,
8071 cast_loc, *after);
8072 /* If the expression begins with a parenthesized type name, it may
8073 be either a cast or a compound literal; we need to see whether
8074 the next character is '{' to tell the difference. If not, it is
8075 an unary expression. Full detection of unknown typenames here
8076 would require a 3-token lookahead. */
8077 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
8078 && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
8079 {
8080 struct c_type_name *type_name;
8081 struct c_expr ret;
8082 struct c_expr expr;
8083 matching_parens parens;
8084 parens.consume_open (parser);
8085 type_name = c_parser_type_name (parser, true);
8086 parens.skip_until_found_close (parser);
8087 if (type_name == NULL)
8088 {
8089 ret.set_error ();
8090 ret.original_code = ERROR_MARK;
8091 ret.original_type = NULL;
8092 return ret;
8093 }
8094
8095 /* Save casted types in the function's used types hash table. */
8096 used_types_insert (type_name->specs->type);
8097
8098 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
8099 return c_parser_postfix_expression_after_paren_type (parser, type_name,
8100 cast_loc);
8101 if (type_name->specs->alignas_p)
8102 error_at (type_name->specs->locations[cdw_alignas],
8103 "alignment specified for type name in cast");
8104 {
8105 location_t expr_loc = c_parser_peek_token (parser)->location;
8106 expr = c_parser_cast_expression (parser, NULL);
8107 expr = convert_lvalue_to_rvalue (expr_loc, expr, true, true);
8108 }
8109 ret.value = c_cast_expr (cast_loc, type_name, expr.value);
8110 if (ret.value && expr.value)
8111 set_c_expr_source_range (&ret, cast_loc, expr.get_finish ());
8112 ret.original_code = ERROR_MARK;
8113 ret.original_type = NULL;
8114 return ret;
8115 }
8116 else
8117 return c_parser_unary_expression (parser);
8118 }
8119
8120 /* Parse an unary expression (C90 6.3.3, C99 6.5.3, C11 6.5.3).
8121
8122 unary-expression:
8123 postfix-expression
8124 ++ unary-expression
8125 -- unary-expression
8126 unary-operator cast-expression
8127 sizeof unary-expression
8128 sizeof ( type-name )
8129
8130 unary-operator: one of
8131 & * + - ~ !
8132
8133 GNU extensions:
8134
8135 unary-expression:
8136 __alignof__ unary-expression
8137 __alignof__ ( type-name )
8138 && identifier
8139
8140 (C11 permits _Alignof with type names only.)
8141
8142 unary-operator: one of
8143 __extension__ __real__ __imag__
8144
8145 Transactional Memory:
8146
8147 unary-expression:
8148 transaction-expression
8149
8150 In addition, the GNU syntax treats ++ and -- as unary operators, so
8151 they may be applied to cast expressions with errors for non-lvalues
8152 given later. */
8153
8154 static struct c_expr
c_parser_unary_expression(c_parser * parser)8155 c_parser_unary_expression (c_parser *parser)
8156 {
8157 int ext;
8158 struct c_expr ret, op;
8159 location_t op_loc = c_parser_peek_token (parser)->location;
8160 location_t exp_loc;
8161 location_t finish;
8162 ret.original_code = ERROR_MARK;
8163 ret.original_type = NULL;
8164 switch (c_parser_peek_token (parser)->type)
8165 {
8166 case CPP_PLUS_PLUS:
8167 c_parser_consume_token (parser);
8168 exp_loc = c_parser_peek_token (parser)->location;
8169 op = c_parser_cast_expression (parser, NULL);
8170
8171 op = default_function_array_read_conversion (exp_loc, op);
8172 return parser_build_unary_op (op_loc, PREINCREMENT_EXPR, op);
8173 case CPP_MINUS_MINUS:
8174 c_parser_consume_token (parser);
8175 exp_loc = c_parser_peek_token (parser)->location;
8176 op = c_parser_cast_expression (parser, NULL);
8177
8178 op = default_function_array_read_conversion (exp_loc, op);
8179 return parser_build_unary_op (op_loc, PREDECREMENT_EXPR, op);
8180 case CPP_AND:
8181 c_parser_consume_token (parser);
8182 op = c_parser_cast_expression (parser, NULL);
8183 mark_exp_read (op.value);
8184 return parser_build_unary_op (op_loc, ADDR_EXPR, op);
8185 case CPP_MULT:
8186 {
8187 c_parser_consume_token (parser);
8188 exp_loc = c_parser_peek_token (parser)->location;
8189 op = c_parser_cast_expression (parser, NULL);
8190 finish = op.get_finish ();
8191 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8192 location_t combined_loc = make_location (op_loc, op_loc, finish);
8193 ret.value = build_indirect_ref (combined_loc, op.value, RO_UNARY_STAR);
8194 ret.src_range.m_start = op_loc;
8195 ret.src_range.m_finish = finish;
8196 return ret;
8197 }
8198 case CPP_PLUS:
8199 if (!c_dialect_objc () && !in_system_header_at (input_location))
8200 warning_at (op_loc,
8201 OPT_Wtraditional,
8202 "traditional C rejects the unary plus operator");
8203 c_parser_consume_token (parser);
8204 exp_loc = c_parser_peek_token (parser)->location;
8205 op = c_parser_cast_expression (parser, NULL);
8206 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8207 return parser_build_unary_op (op_loc, CONVERT_EXPR, op);
8208 case CPP_MINUS:
8209 c_parser_consume_token (parser);
8210 exp_loc = c_parser_peek_token (parser)->location;
8211 op = c_parser_cast_expression (parser, NULL);
8212 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8213 return parser_build_unary_op (op_loc, NEGATE_EXPR, op);
8214 case CPP_COMPL:
8215 c_parser_consume_token (parser);
8216 exp_loc = c_parser_peek_token (parser)->location;
8217 op = c_parser_cast_expression (parser, NULL);
8218 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8219 return parser_build_unary_op (op_loc, BIT_NOT_EXPR, op);
8220 case CPP_NOT:
8221 c_parser_consume_token (parser);
8222 exp_loc = c_parser_peek_token (parser)->location;
8223 op = c_parser_cast_expression (parser, NULL);
8224 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8225 return parser_build_unary_op (op_loc, TRUTH_NOT_EXPR, op);
8226 case CPP_AND_AND:
8227 /* Refer to the address of a label as a pointer. */
8228 c_parser_consume_token (parser);
8229 if (c_parser_next_token_is (parser, CPP_NAME))
8230 {
8231 ret.value = finish_label_address_expr
8232 (c_parser_peek_token (parser)->value, op_loc);
8233 set_c_expr_source_range (&ret, op_loc,
8234 c_parser_peek_token (parser)->get_finish ());
8235 c_parser_consume_token (parser);
8236 }
8237 else
8238 {
8239 c_parser_error (parser, "expected identifier");
8240 ret.set_error ();
8241 }
8242 return ret;
8243 case CPP_KEYWORD:
8244 switch (c_parser_peek_token (parser)->keyword)
8245 {
8246 case RID_SIZEOF:
8247 return c_parser_sizeof_expression (parser);
8248 case RID_ALIGNOF:
8249 return c_parser_alignof_expression (parser);
8250 case RID_BUILTIN_HAS_ATTRIBUTE:
8251 return c_parser_has_attribute_expression (parser);
8252 case RID_EXTENSION:
8253 c_parser_consume_token (parser);
8254 ext = disable_extension_diagnostics ();
8255 ret = c_parser_cast_expression (parser, NULL);
8256 restore_extension_diagnostics (ext);
8257 return ret;
8258 case RID_REALPART:
8259 c_parser_consume_token (parser);
8260 exp_loc = c_parser_peek_token (parser)->location;
8261 op = c_parser_cast_expression (parser, NULL);
8262 op = default_function_array_conversion (exp_loc, op);
8263 return parser_build_unary_op (op_loc, REALPART_EXPR, op);
8264 case RID_IMAGPART:
8265 c_parser_consume_token (parser);
8266 exp_loc = c_parser_peek_token (parser)->location;
8267 op = c_parser_cast_expression (parser, NULL);
8268 op = default_function_array_conversion (exp_loc, op);
8269 return parser_build_unary_op (op_loc, IMAGPART_EXPR, op);
8270 case RID_TRANSACTION_ATOMIC:
8271 case RID_TRANSACTION_RELAXED:
8272 return c_parser_transaction_expression (parser,
8273 c_parser_peek_token (parser)->keyword);
8274 default:
8275 return c_parser_postfix_expression (parser);
8276 }
8277 default:
8278 return c_parser_postfix_expression (parser);
8279 }
8280 }
8281
8282 /* Parse a sizeof expression. */
8283
8284 static struct c_expr
c_parser_sizeof_expression(c_parser * parser)8285 c_parser_sizeof_expression (c_parser *parser)
8286 {
8287 struct c_expr expr;
8288 struct c_expr result;
8289 location_t expr_loc;
8290 gcc_assert (c_parser_next_token_is_keyword (parser, RID_SIZEOF));
8291
8292 location_t start;
8293 location_t finish = UNKNOWN_LOCATION;
8294
8295 start = c_parser_peek_token (parser)->location;
8296
8297 c_parser_consume_token (parser);
8298 c_inhibit_evaluation_warnings++;
8299 in_sizeof++;
8300 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
8301 && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
8302 {
8303 /* Either sizeof ( type-name ) or sizeof unary-expression
8304 starting with a compound literal. */
8305 struct c_type_name *type_name;
8306 matching_parens parens;
8307 parens.consume_open (parser);
8308 expr_loc = c_parser_peek_token (parser)->location;
8309 type_name = c_parser_type_name (parser, true);
8310 parens.skip_until_found_close (parser);
8311 finish = parser->tokens_buf[0].location;
8312 if (type_name == NULL)
8313 {
8314 struct c_expr ret;
8315 c_inhibit_evaluation_warnings--;
8316 in_sizeof--;
8317 ret.set_error ();
8318 ret.original_code = ERROR_MARK;
8319 ret.original_type = NULL;
8320 return ret;
8321 }
8322 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
8323 {
8324 expr = c_parser_postfix_expression_after_paren_type (parser,
8325 type_name,
8326 expr_loc);
8327 finish = expr.get_finish ();
8328 goto sizeof_expr;
8329 }
8330 /* sizeof ( type-name ). */
8331 if (type_name->specs->alignas_p)
8332 error_at (type_name->specs->locations[cdw_alignas],
8333 "alignment specified for type name in %<sizeof%>");
8334 c_inhibit_evaluation_warnings--;
8335 in_sizeof--;
8336 result = c_expr_sizeof_type (expr_loc, type_name);
8337 }
8338 else
8339 {
8340 expr_loc = c_parser_peek_token (parser)->location;
8341 expr = c_parser_unary_expression (parser);
8342 finish = expr.get_finish ();
8343 sizeof_expr:
8344 c_inhibit_evaluation_warnings--;
8345 in_sizeof--;
8346 mark_exp_read (expr.value);
8347 if (TREE_CODE (expr.value) == COMPONENT_REF
8348 && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
8349 error_at (expr_loc, "%<sizeof%> applied to a bit-field");
8350 result = c_expr_sizeof_expr (expr_loc, expr);
8351 }
8352 if (finish == UNKNOWN_LOCATION)
8353 finish = start;
8354 set_c_expr_source_range (&result, start, finish);
8355 return result;
8356 }
8357
8358 /* Parse an alignof expression. */
8359
8360 static struct c_expr
c_parser_alignof_expression(c_parser * parser)8361 c_parser_alignof_expression (c_parser *parser)
8362 {
8363 struct c_expr expr;
8364 location_t start_loc = c_parser_peek_token (parser)->location;
8365 location_t end_loc;
8366 tree alignof_spelling = c_parser_peek_token (parser)->value;
8367 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ALIGNOF));
8368 bool is_c11_alignof = strcmp (IDENTIFIER_POINTER (alignof_spelling),
8369 "_Alignof") == 0;
8370 /* A diagnostic is not required for the use of this identifier in
8371 the implementation namespace; only diagnose it for the C11
8372 spelling because of existing code using the other spellings. */
8373 if (is_c11_alignof)
8374 {
8375 if (flag_isoc99)
8376 pedwarn_c99 (start_loc, OPT_Wpedantic, "ISO C99 does not support %qE",
8377 alignof_spelling);
8378 else
8379 pedwarn_c99 (start_loc, OPT_Wpedantic, "ISO C90 does not support %qE",
8380 alignof_spelling);
8381 }
8382 c_parser_consume_token (parser);
8383 c_inhibit_evaluation_warnings++;
8384 in_alignof++;
8385 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
8386 && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
8387 {
8388 /* Either __alignof__ ( type-name ) or __alignof__
8389 unary-expression starting with a compound literal. */
8390 location_t loc;
8391 struct c_type_name *type_name;
8392 struct c_expr ret;
8393 matching_parens parens;
8394 parens.consume_open (parser);
8395 loc = c_parser_peek_token (parser)->location;
8396 type_name = c_parser_type_name (parser, true);
8397 end_loc = c_parser_peek_token (parser)->location;
8398 parens.skip_until_found_close (parser);
8399 if (type_name == NULL)
8400 {
8401 struct c_expr ret;
8402 c_inhibit_evaluation_warnings--;
8403 in_alignof--;
8404 ret.set_error ();
8405 ret.original_code = ERROR_MARK;
8406 ret.original_type = NULL;
8407 return ret;
8408 }
8409 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
8410 {
8411 expr = c_parser_postfix_expression_after_paren_type (parser,
8412 type_name,
8413 loc);
8414 goto alignof_expr;
8415 }
8416 /* alignof ( type-name ). */
8417 if (type_name->specs->alignas_p)
8418 error_at (type_name->specs->locations[cdw_alignas],
8419 "alignment specified for type name in %qE",
8420 alignof_spelling);
8421 c_inhibit_evaluation_warnings--;
8422 in_alignof--;
8423 ret.value = c_sizeof_or_alignof_type (loc, groktypename (type_name,
8424 NULL, NULL),
8425 false, is_c11_alignof, 1);
8426 ret.original_code = ERROR_MARK;
8427 ret.original_type = NULL;
8428 set_c_expr_source_range (&ret, start_loc, end_loc);
8429 return ret;
8430 }
8431 else
8432 {
8433 struct c_expr ret;
8434 expr = c_parser_unary_expression (parser);
8435 end_loc = expr.src_range.m_finish;
8436 alignof_expr:
8437 mark_exp_read (expr.value);
8438 c_inhibit_evaluation_warnings--;
8439 in_alignof--;
8440 if (is_c11_alignof)
8441 pedwarn (start_loc,
8442 OPT_Wpedantic, "ISO C does not allow %<%E (expression)%>",
8443 alignof_spelling);
8444 ret.value = c_alignof_expr (start_loc, expr.value);
8445 ret.original_code = ERROR_MARK;
8446 ret.original_type = NULL;
8447 set_c_expr_source_range (&ret, start_loc, end_loc);
8448 return ret;
8449 }
8450 }
8451
8452 /* Parse the __builtin_has_attribute ([expr|type], attribute-spec)
8453 expression. */
8454
8455 static struct c_expr
c_parser_has_attribute_expression(c_parser * parser)8456 c_parser_has_attribute_expression (c_parser *parser)
8457 {
8458 gcc_assert (c_parser_next_token_is_keyword (parser,
8459 RID_BUILTIN_HAS_ATTRIBUTE));
8460 location_t start = c_parser_peek_token (parser)->location;
8461 c_parser_consume_token (parser);
8462
8463 c_inhibit_evaluation_warnings++;
8464
8465 matching_parens parens;
8466 if (!parens.require_open (parser))
8467 {
8468 c_inhibit_evaluation_warnings--;
8469 in_typeof--;
8470
8471 struct c_expr result;
8472 result.set_error ();
8473 result.original_code = ERROR_MARK;
8474 result.original_type = NULL;
8475 return result;
8476 }
8477
8478 /* Treat the type argument the same way as in typeof for the purposes
8479 of warnings. FIXME: Generalize this so the warning refers to
8480 __builtin_has_attribute rather than typeof. */
8481 in_typeof++;
8482
8483 /* The first operand: one of DECL, EXPR, or TYPE. */
8484 tree oper = NULL_TREE;
8485 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
8486 {
8487 struct c_type_name *tname = c_parser_type_name (parser);
8488 in_typeof--;
8489 if (tname)
8490 {
8491 oper = groktypename (tname, NULL, NULL);
8492 pop_maybe_used (variably_modified_type_p (oper, NULL_TREE));
8493 }
8494 }
8495 else
8496 {
8497 struct c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
8498 c_inhibit_evaluation_warnings--;
8499 in_typeof--;
8500 if (cexpr.value != error_mark_node)
8501 {
8502 mark_exp_read (cexpr.value);
8503 oper = cexpr.value;
8504 tree etype = TREE_TYPE (oper);
8505 bool was_vm = variably_modified_type_p (etype, NULL_TREE);
8506 /* This is returned with the type so that when the type is
8507 evaluated, this can be evaluated. */
8508 if (was_vm)
8509 oper = c_fully_fold (oper, false, NULL);
8510 pop_maybe_used (was_vm);
8511 }
8512 }
8513
8514 struct c_expr result;
8515 result.original_code = ERROR_MARK;
8516 result.original_type = NULL;
8517
8518 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
8519 {
8520 /* Consume the closing parenthesis if that's the next token
8521 in the likely case the built-in was invoked with fewer
8522 than two arguments. */
8523 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
8524 c_parser_consume_token (parser);
8525 c_inhibit_evaluation_warnings--;
8526 result.set_error ();
8527 return result;
8528 }
8529
8530 bool save_translate_strings_p = parser->translate_strings_p;
8531
8532 location_t atloc = c_parser_peek_token (parser)->location;
8533 /* Parse a single attribute. Require no leading comma and do not
8534 allow empty attributes. */
8535 tree attr = c_parser_gnu_attribute (parser, NULL_TREE, false, false);
8536
8537 parser->translate_strings_p = save_translate_strings_p;
8538
8539 location_t finish = c_parser_peek_token (parser)->location;
8540 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
8541 c_parser_consume_token (parser);
8542 else
8543 {
8544 c_parser_error (parser, "expected identifier");
8545 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8546
8547 result.set_error ();
8548 return result;
8549 }
8550
8551 if (!attr)
8552 {
8553 error_at (atloc, "expected identifier");
8554 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
8555 "expected %<)%>");
8556 result.set_error ();
8557 return result;
8558 }
8559
8560 result.original_code = INTEGER_CST;
8561 result.original_type = boolean_type_node;
8562
8563 if (has_attribute (atloc, oper, attr, default_conversion))
8564 result.value = boolean_true_node;
8565 else
8566 result.value = boolean_false_node;
8567
8568 set_c_expr_source_range (&result, start, finish);
8569 return result;
8570 }
8571
8572 /* Helper function to read arguments of builtins which are interfaces
8573 for the middle-end nodes like COMPLEX_EXPR, VEC_PERM_EXPR and
8574 others. The name of the builtin is passed using BNAME parameter.
8575 Function returns true if there were no errors while parsing and
8576 stores the arguments in CEXPR_LIST. If it returns true,
8577 *OUT_CLOSE_PAREN_LOC is written to with the location of the closing
8578 parenthesis. */
8579 static bool
c_parser_get_builtin_args(c_parser * parser,const char * bname,vec<c_expr_t,va_gc> ** ret_cexpr_list,bool choose_expr_p,location_t * out_close_paren_loc)8580 c_parser_get_builtin_args (c_parser *parser, const char *bname,
8581 vec<c_expr_t, va_gc> **ret_cexpr_list,
8582 bool choose_expr_p,
8583 location_t *out_close_paren_loc)
8584 {
8585 location_t loc = c_parser_peek_token (parser)->location;
8586 vec<c_expr_t, va_gc> *cexpr_list;
8587 c_expr_t expr;
8588 bool saved_force_folding_builtin_constant_p;
8589
8590 *ret_cexpr_list = NULL;
8591 if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
8592 {
8593 error_at (loc, "cannot take address of %qs", bname);
8594 return false;
8595 }
8596
8597 c_parser_consume_token (parser);
8598
8599 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
8600 {
8601 *out_close_paren_loc = c_parser_peek_token (parser)->location;
8602 c_parser_consume_token (parser);
8603 return true;
8604 }
8605
8606 saved_force_folding_builtin_constant_p
8607 = force_folding_builtin_constant_p;
8608 force_folding_builtin_constant_p |= choose_expr_p;
8609 expr = c_parser_expr_no_commas (parser, NULL);
8610 force_folding_builtin_constant_p
8611 = saved_force_folding_builtin_constant_p;
8612 vec_alloc (cexpr_list, 1);
8613 vec_safe_push (cexpr_list, expr);
8614 while (c_parser_next_token_is (parser, CPP_COMMA))
8615 {
8616 c_parser_consume_token (parser);
8617 expr = c_parser_expr_no_commas (parser, NULL);
8618 vec_safe_push (cexpr_list, expr);
8619 }
8620
8621 *out_close_paren_loc = c_parser_peek_token (parser)->location;
8622 if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
8623 return false;
8624
8625 *ret_cexpr_list = cexpr_list;
8626 return true;
8627 }
8628
8629 /* This represents a single generic-association. */
8630
8631 struct c_generic_association
8632 {
8633 /* The location of the starting token of the type. */
8634 location_t type_location;
8635 /* The association's type, or NULL_TREE for 'default'. */
8636 tree type;
8637 /* The association's expression. */
8638 struct c_expr expression;
8639 };
8640
8641 /* Parse a generic-selection. (C11 6.5.1.1).
8642
8643 generic-selection:
8644 _Generic ( assignment-expression , generic-assoc-list )
8645
8646 generic-assoc-list:
8647 generic-association
8648 generic-assoc-list , generic-association
8649
8650 generic-association:
8651 type-name : assignment-expression
8652 default : assignment-expression
8653 */
8654
8655 static struct c_expr
c_parser_generic_selection(c_parser * parser)8656 c_parser_generic_selection (c_parser *parser)
8657 {
8658 struct c_expr selector, error_expr;
8659 tree selector_type;
8660 struct c_generic_association matched_assoc;
8661 int match_found = -1;
8662 location_t generic_loc, selector_loc;
8663
8664 error_expr.original_code = ERROR_MARK;
8665 error_expr.original_type = NULL;
8666 error_expr.set_error ();
8667 matched_assoc.type_location = UNKNOWN_LOCATION;
8668 matched_assoc.type = NULL_TREE;
8669 matched_assoc.expression = error_expr;
8670
8671 gcc_assert (c_parser_next_token_is_keyword (parser, RID_GENERIC));
8672 generic_loc = c_parser_peek_token (parser)->location;
8673 c_parser_consume_token (parser);
8674 if (flag_isoc99)
8675 pedwarn_c99 (generic_loc, OPT_Wpedantic,
8676 "ISO C99 does not support %<_Generic%>");
8677 else
8678 pedwarn_c99 (generic_loc, OPT_Wpedantic,
8679 "ISO C90 does not support %<_Generic%>");
8680
8681 matching_parens parens;
8682 if (!parens.require_open (parser))
8683 return error_expr;
8684
8685 c_inhibit_evaluation_warnings++;
8686 selector_loc = c_parser_peek_token (parser)->location;
8687 selector = c_parser_expr_no_commas (parser, NULL);
8688 selector = default_function_array_conversion (selector_loc, selector);
8689 c_inhibit_evaluation_warnings--;
8690
8691 if (selector.value == error_mark_node)
8692 {
8693 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8694 return selector;
8695 }
8696 mark_exp_read (selector.value);
8697 selector_type = TREE_TYPE (selector.value);
8698 /* In ISO C terms, rvalues (including the controlling expression of
8699 _Generic) do not have qualified types. */
8700 if (TREE_CODE (selector_type) != ARRAY_TYPE)
8701 selector_type = TYPE_MAIN_VARIANT (selector_type);
8702 /* In ISO C terms, _Noreturn is not part of the type of expressions
8703 such as &abort, but in GCC it is represented internally as a type
8704 qualifier. */
8705 if (FUNCTION_POINTER_TYPE_P (selector_type)
8706 && TYPE_QUALS (TREE_TYPE (selector_type)) != TYPE_UNQUALIFIED)
8707 selector_type
8708 = build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (selector_type)));
8709
8710 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
8711 {
8712 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8713 return error_expr;
8714 }
8715
8716 auto_vec<c_generic_association> associations;
8717 while (1)
8718 {
8719 struct c_generic_association assoc, *iter;
8720 unsigned int ix;
8721 c_token *token = c_parser_peek_token (parser);
8722
8723 assoc.type_location = token->location;
8724 if (token->type == CPP_KEYWORD && token->keyword == RID_DEFAULT)
8725 {
8726 c_parser_consume_token (parser);
8727 assoc.type = NULL_TREE;
8728 }
8729 else
8730 {
8731 struct c_type_name *type_name;
8732
8733 type_name = c_parser_type_name (parser);
8734 if (type_name == NULL)
8735 {
8736 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8737 return error_expr;
8738 }
8739 assoc.type = groktypename (type_name, NULL, NULL);
8740 if (assoc.type == error_mark_node)
8741 {
8742 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8743 return error_expr;
8744 }
8745
8746 if (TREE_CODE (assoc.type) == FUNCTION_TYPE)
8747 error_at (assoc.type_location,
8748 "%<_Generic%> association has function type");
8749 else if (!COMPLETE_TYPE_P (assoc.type))
8750 error_at (assoc.type_location,
8751 "%<_Generic%> association has incomplete type");
8752
8753 if (variably_modified_type_p (assoc.type, NULL_TREE))
8754 error_at (assoc.type_location,
8755 "%<_Generic%> association has "
8756 "variable length type");
8757 }
8758
8759 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
8760 {
8761 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8762 return error_expr;
8763 }
8764
8765 assoc.expression = c_parser_expr_no_commas (parser, NULL);
8766 if (assoc.expression.value == error_mark_node)
8767 {
8768 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8769 return error_expr;
8770 }
8771
8772 for (ix = 0; associations.iterate (ix, &iter); ++ix)
8773 {
8774 if (assoc.type == NULL_TREE)
8775 {
8776 if (iter->type == NULL_TREE)
8777 {
8778 error_at (assoc.type_location,
8779 "duplicate %<default%> case in %<_Generic%>");
8780 inform (iter->type_location, "original %<default%> is here");
8781 }
8782 }
8783 else if (iter->type != NULL_TREE)
8784 {
8785 if (comptypes (assoc.type, iter->type))
8786 {
8787 error_at (assoc.type_location,
8788 "%<_Generic%> specifies two compatible types");
8789 inform (iter->type_location, "compatible type is here");
8790 }
8791 }
8792 }
8793
8794 if (assoc.type == NULL_TREE)
8795 {
8796 if (match_found < 0)
8797 {
8798 matched_assoc = assoc;
8799 match_found = associations.length ();
8800 }
8801 }
8802 else if (comptypes (assoc.type, selector_type))
8803 {
8804 if (match_found < 0 || matched_assoc.type == NULL_TREE)
8805 {
8806 matched_assoc = assoc;
8807 match_found = associations.length ();
8808 }
8809 else
8810 {
8811 error_at (assoc.type_location,
8812 "%<_Generic%> selector matches multiple associations");
8813 inform (matched_assoc.type_location,
8814 "other match is here");
8815 }
8816 }
8817
8818 associations.safe_push (assoc);
8819
8820 if (c_parser_peek_token (parser)->type != CPP_COMMA)
8821 break;
8822 c_parser_consume_token (parser);
8823 }
8824
8825 unsigned int ix;
8826 struct c_generic_association *iter;
8827 FOR_EACH_VEC_ELT (associations, ix, iter)
8828 if (ix != (unsigned) match_found)
8829 mark_exp_read (iter->expression.value);
8830
8831 if (!parens.require_close (parser))
8832 {
8833 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8834 return error_expr;
8835 }
8836
8837 if (match_found < 0)
8838 {
8839 error_at (selector_loc, "%<_Generic%> selector of type %qT is not "
8840 "compatible with any association",
8841 selector_type);
8842 return error_expr;
8843 }
8844
8845 return matched_assoc.expression;
8846 }
8847
8848 /* Check the validity of a function pointer argument *EXPR (argument
8849 position POS) to __builtin_tgmath. Return the number of function
8850 arguments if possibly valid; return 0 having reported an error if
8851 not valid. */
8852
8853 static unsigned int
check_tgmath_function(c_expr * expr,unsigned int pos)8854 check_tgmath_function (c_expr *expr, unsigned int pos)
8855 {
8856 tree type = TREE_TYPE (expr->value);
8857 if (!FUNCTION_POINTER_TYPE_P (type))
8858 {
8859 error_at (expr->get_location (),
8860 "argument %u of %<__builtin_tgmath%> is not a function pointer",
8861 pos);
8862 return 0;
8863 }
8864 type = TREE_TYPE (type);
8865 if (!prototype_p (type))
8866 {
8867 error_at (expr->get_location (),
8868 "argument %u of %<__builtin_tgmath%> is unprototyped", pos);
8869 return 0;
8870 }
8871 if (stdarg_p (type))
8872 {
8873 error_at (expr->get_location (),
8874 "argument %u of %<__builtin_tgmath%> has variable arguments",
8875 pos);
8876 return 0;
8877 }
8878 unsigned int nargs = 0;
8879 function_args_iterator iter;
8880 tree t;
8881 FOREACH_FUNCTION_ARGS (type, t, iter)
8882 {
8883 if (t == void_type_node)
8884 break;
8885 nargs++;
8886 }
8887 if (nargs == 0)
8888 {
8889 error_at (expr->get_location (),
8890 "argument %u of %<__builtin_tgmath%> has no arguments", pos);
8891 return 0;
8892 }
8893 return nargs;
8894 }
8895
8896 /* Ways in which a parameter or return value of a type-generic macro
8897 may vary between the different functions the macro may call. */
8898 enum tgmath_parm_kind
8899 {
8900 tgmath_fixed, tgmath_real, tgmath_complex
8901 };
8902
8903 /* Helper function for c_parser_postfix_expression. Parse predefined
8904 identifiers. */
8905
8906 static struct c_expr
c_parser_predefined_identifier(c_parser * parser)8907 c_parser_predefined_identifier (c_parser *parser)
8908 {
8909 location_t loc = c_parser_peek_token (parser)->location;
8910 switch (c_parser_peek_token (parser)->keyword)
8911 {
8912 case RID_FUNCTION_NAME:
8913 pedwarn (loc, OPT_Wpedantic, "ISO C does not support %qs predefined "
8914 "identifier", "__FUNCTION__");
8915 break;
8916 case RID_PRETTY_FUNCTION_NAME:
8917 pedwarn (loc, OPT_Wpedantic, "ISO C does not support %qs predefined "
8918 "identifier", "__PRETTY_FUNCTION__");
8919 break;
8920 case RID_C99_FUNCTION_NAME:
8921 pedwarn_c90 (loc, OPT_Wpedantic, "ISO C90 does not support "
8922 "%<__func__%> predefined identifier");
8923 break;
8924 default:
8925 gcc_unreachable ();
8926 }
8927
8928 struct c_expr expr;
8929 expr.original_code = ERROR_MARK;
8930 expr.original_type = NULL;
8931 expr.value = fname_decl (loc, c_parser_peek_token (parser)->keyword,
8932 c_parser_peek_token (parser)->value);
8933 set_c_expr_source_range (&expr, loc, loc);
8934 c_parser_consume_token (parser);
8935 return expr;
8936 }
8937
8938 /* Parse a postfix expression (C90 6.3.1-6.3.2, C99 6.5.1-6.5.2,
8939 C11 6.5.1-6.5.2). Compound literals aren't handled here; callers have to
8940 call c_parser_postfix_expression_after_paren_type on encountering them.
8941
8942 postfix-expression:
8943 primary-expression
8944 postfix-expression [ expression ]
8945 postfix-expression ( argument-expression-list[opt] )
8946 postfix-expression . identifier
8947 postfix-expression -> identifier
8948 postfix-expression ++
8949 postfix-expression --
8950 ( type-name ) { initializer-list }
8951 ( type-name ) { initializer-list , }
8952
8953 argument-expression-list:
8954 argument-expression
8955 argument-expression-list , argument-expression
8956
8957 primary-expression:
8958 identifier
8959 constant
8960 string-literal
8961 ( expression )
8962 generic-selection
8963
8964 GNU extensions:
8965
8966 primary-expression:
8967 __func__
8968 (treated as a keyword in GNU C)
8969 __FUNCTION__
8970 __PRETTY_FUNCTION__
8971 ( compound-statement )
8972 __builtin_va_arg ( assignment-expression , type-name )
8973 __builtin_offsetof ( type-name , offsetof-member-designator )
8974 __builtin_choose_expr ( assignment-expression ,
8975 assignment-expression ,
8976 assignment-expression )
8977 __builtin_types_compatible_p ( type-name , type-name )
8978 __builtin_tgmath ( expr-list )
8979 __builtin_complex ( assignment-expression , assignment-expression )
8980 __builtin_shuffle ( assignment-expression , assignment-expression )
8981 __builtin_shuffle ( assignment-expression ,
8982 assignment-expression ,
8983 assignment-expression, )
8984 __builtin_convertvector ( assignment-expression , type-name )
8985 __builtin_assoc_barrier ( assignment-expression )
8986
8987 offsetof-member-designator:
8988 identifier
8989 offsetof-member-designator . identifier
8990 offsetof-member-designator [ expression ]
8991
8992 Objective-C:
8993
8994 primary-expression:
8995 [ objc-receiver objc-message-args ]
8996 @selector ( objc-selector-arg )
8997 @protocol ( identifier )
8998 @encode ( type-name )
8999 objc-string-literal
9000 Classname . identifier
9001 */
9002
9003 static struct c_expr
c_parser_postfix_expression(c_parser * parser)9004 c_parser_postfix_expression (c_parser *parser)
9005 {
9006 struct c_expr expr, e1;
9007 struct c_type_name *t1, *t2;
9008 location_t loc = c_parser_peek_token (parser)->location;
9009 source_range tok_range = c_parser_peek_token (parser)->get_range ();
9010 expr.original_code = ERROR_MARK;
9011 expr.original_type = NULL;
9012 switch (c_parser_peek_token (parser)->type)
9013 {
9014 case CPP_NUMBER:
9015 expr.value = c_parser_peek_token (parser)->value;
9016 set_c_expr_source_range (&expr, tok_range);
9017 loc = c_parser_peek_token (parser)->location;
9018 c_parser_consume_token (parser);
9019 if (TREE_CODE (expr.value) == FIXED_CST
9020 && !targetm.fixed_point_supported_p ())
9021 {
9022 error_at (loc, "fixed-point types not supported for this target");
9023 expr.set_error ();
9024 }
9025 break;
9026 case CPP_CHAR:
9027 case CPP_CHAR16:
9028 case CPP_CHAR32:
9029 case CPP_UTF8CHAR:
9030 case CPP_WCHAR:
9031 expr.value = c_parser_peek_token (parser)->value;
9032 /* For the purpose of warning when a pointer is compared with
9033 a zero character constant. */
9034 expr.original_type = char_type_node;
9035 set_c_expr_source_range (&expr, tok_range);
9036 c_parser_consume_token (parser);
9037 break;
9038 case CPP_STRING:
9039 case CPP_STRING16:
9040 case CPP_STRING32:
9041 case CPP_WSTRING:
9042 case CPP_UTF8STRING:
9043 expr = c_parser_string_literal (parser, parser->translate_strings_p,
9044 true);
9045 break;
9046 case CPP_OBJC_STRING:
9047 gcc_assert (c_dialect_objc ());
9048 expr.value
9049 = objc_build_string_object (c_parser_peek_token (parser)->value);
9050 set_c_expr_source_range (&expr, tok_range);
9051 c_parser_consume_token (parser);
9052 break;
9053 case CPP_NAME:
9054 switch (c_parser_peek_token (parser)->id_kind)
9055 {
9056 case C_ID_ID:
9057 {
9058 tree id = c_parser_peek_token (parser)->value;
9059 c_parser_consume_token (parser);
9060 expr.value = build_external_ref (loc, id,
9061 (c_parser_peek_token (parser)->type
9062 == CPP_OPEN_PAREN),
9063 &expr.original_type);
9064 set_c_expr_source_range (&expr, tok_range);
9065 break;
9066 }
9067 case C_ID_CLASSNAME:
9068 {
9069 /* Here we parse the Objective-C 2.0 Class.name dot
9070 syntax. */
9071 tree class_name = c_parser_peek_token (parser)->value;
9072 tree component;
9073 c_parser_consume_token (parser);
9074 gcc_assert (c_dialect_objc ());
9075 if (!c_parser_require (parser, CPP_DOT, "expected %<.%>"))
9076 {
9077 expr.set_error ();
9078 break;
9079 }
9080 if (c_parser_next_token_is_not (parser, CPP_NAME))
9081 {
9082 c_parser_error (parser, "expected identifier");
9083 expr.set_error ();
9084 break;
9085 }
9086 c_token *component_tok = c_parser_peek_token (parser);
9087 component = component_tok->value;
9088 location_t end_loc = component_tok->get_finish ();
9089 c_parser_consume_token (parser);
9090 expr.value = objc_build_class_component_ref (class_name,
9091 component);
9092 set_c_expr_source_range (&expr, loc, end_loc);
9093 break;
9094 }
9095 default:
9096 c_parser_error (parser, "expected expression");
9097 expr.set_error ();
9098 break;
9099 }
9100 break;
9101 case CPP_OPEN_PAREN:
9102 /* A parenthesized expression, statement expression or compound
9103 literal. */
9104 if (c_parser_peek_2nd_token (parser)->type == CPP_OPEN_BRACE)
9105 {
9106 /* A statement expression. */
9107 tree stmt;
9108 location_t brace_loc;
9109 c_parser_consume_token (parser);
9110 brace_loc = c_parser_peek_token (parser)->location;
9111 c_parser_consume_token (parser);
9112 /* If we've not yet started the current function's statement list,
9113 or we're in the parameter scope of an old-style function
9114 declaration, statement expressions are not allowed. */
9115 if (!building_stmt_list_p () || old_style_parameter_scope ())
9116 {
9117 error_at (loc, "braced-group within expression allowed "
9118 "only inside a function");
9119 parser->error = true;
9120 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
9121 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9122 expr.set_error ();
9123 break;
9124 }
9125 stmt = c_begin_stmt_expr ();
9126 c_parser_compound_statement_nostart (parser);
9127 location_t close_loc = c_parser_peek_token (parser)->location;
9128 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9129 "expected %<)%>");
9130 pedwarn (loc, OPT_Wpedantic,
9131 "ISO C forbids braced-groups within expressions");
9132 expr.value = c_finish_stmt_expr (brace_loc, stmt);
9133 set_c_expr_source_range (&expr, loc, close_loc);
9134 mark_exp_read (expr.value);
9135 }
9136 else
9137 {
9138 /* A parenthesized expression. */
9139 location_t loc_open_paren = c_parser_peek_token (parser)->location;
9140 c_parser_consume_token (parser);
9141 expr = c_parser_expression (parser);
9142 if (TREE_CODE (expr.value) == MODIFY_EXPR)
9143 suppress_warning (expr.value, OPT_Wparentheses);
9144 if (expr.original_code != C_MAYBE_CONST_EXPR
9145 && expr.original_code != SIZEOF_EXPR)
9146 expr.original_code = ERROR_MARK;
9147 /* Remember that we saw ( ) around the sizeof. */
9148 if (expr.original_code == SIZEOF_EXPR)
9149 expr.original_code = PAREN_SIZEOF_EXPR;
9150 /* Don't change EXPR.ORIGINAL_TYPE. */
9151 location_t loc_close_paren = c_parser_peek_token (parser)->location;
9152 set_c_expr_source_range (&expr, loc_open_paren, loc_close_paren);
9153 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9154 "expected %<)%>", loc_open_paren);
9155 }
9156 break;
9157 case CPP_KEYWORD:
9158 switch (c_parser_peek_token (parser)->keyword)
9159 {
9160 case RID_FUNCTION_NAME:
9161 case RID_PRETTY_FUNCTION_NAME:
9162 case RID_C99_FUNCTION_NAME:
9163 expr = c_parser_predefined_identifier (parser);
9164 break;
9165 case RID_VA_ARG:
9166 {
9167 location_t start_loc = loc;
9168 c_parser_consume_token (parser);
9169 matching_parens parens;
9170 if (!parens.require_open (parser))
9171 {
9172 expr.set_error ();
9173 break;
9174 }
9175 e1 = c_parser_expr_no_commas (parser, NULL);
9176 mark_exp_read (e1.value);
9177 e1.value = c_fully_fold (e1.value, false, NULL);
9178 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
9179 {
9180 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9181 expr.set_error ();
9182 break;
9183 }
9184 loc = c_parser_peek_token (parser)->location;
9185 t1 = c_parser_type_name (parser);
9186 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
9187 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9188 "expected %<)%>");
9189 if (t1 == NULL)
9190 {
9191 expr.set_error ();
9192 }
9193 else
9194 {
9195 tree type_expr = NULL_TREE;
9196 expr.value = c_build_va_arg (start_loc, e1.value, loc,
9197 groktypename (t1, &type_expr, NULL));
9198 if (type_expr)
9199 {
9200 expr.value = build2 (C_MAYBE_CONST_EXPR,
9201 TREE_TYPE (expr.value), type_expr,
9202 expr.value);
9203 C_MAYBE_CONST_EXPR_NON_CONST (expr.value) = true;
9204 }
9205 set_c_expr_source_range (&expr, start_loc, end_loc);
9206 }
9207 }
9208 break;
9209 case RID_OFFSETOF:
9210 {
9211 c_parser_consume_token (parser);
9212 matching_parens parens;
9213 if (!parens.require_open (parser))
9214 {
9215 expr.set_error ();
9216 break;
9217 }
9218 t1 = c_parser_type_name (parser);
9219 if (t1 == NULL)
9220 parser->error = true;
9221 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
9222 gcc_assert (parser->error);
9223 if (parser->error)
9224 {
9225 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9226 expr.set_error ();
9227 break;
9228 }
9229 tree type = groktypename (t1, NULL, NULL);
9230 tree offsetof_ref;
9231 if (type == error_mark_node)
9232 offsetof_ref = error_mark_node;
9233 else
9234 {
9235 offsetof_ref = build1 (INDIRECT_REF, type, null_pointer_node);
9236 SET_EXPR_LOCATION (offsetof_ref, loc);
9237 }
9238 /* Parse the second argument to __builtin_offsetof. We
9239 must have one identifier, and beyond that we want to
9240 accept sub structure and sub array references. */
9241 if (c_parser_next_token_is (parser, CPP_NAME))
9242 {
9243 c_token *comp_tok = c_parser_peek_token (parser);
9244 offsetof_ref = build_component_ref
9245 (loc, offsetof_ref, comp_tok->value, comp_tok->location);
9246 c_parser_consume_token (parser);
9247 while (c_parser_next_token_is (parser, CPP_DOT)
9248 || c_parser_next_token_is (parser,
9249 CPP_OPEN_SQUARE)
9250 || c_parser_next_token_is (parser,
9251 CPP_DEREF))
9252 {
9253 if (c_parser_next_token_is (parser, CPP_DEREF))
9254 {
9255 loc = c_parser_peek_token (parser)->location;
9256 offsetof_ref = build_array_ref (loc,
9257 offsetof_ref,
9258 integer_zero_node);
9259 goto do_dot;
9260 }
9261 else if (c_parser_next_token_is (parser, CPP_DOT))
9262 {
9263 do_dot:
9264 c_parser_consume_token (parser);
9265 if (c_parser_next_token_is_not (parser,
9266 CPP_NAME))
9267 {
9268 c_parser_error (parser, "expected identifier");
9269 break;
9270 }
9271 c_token *comp_tok = c_parser_peek_token (parser);
9272 offsetof_ref = build_component_ref
9273 (loc, offsetof_ref, comp_tok->value,
9274 comp_tok->location);
9275 c_parser_consume_token (parser);
9276 }
9277 else
9278 {
9279 struct c_expr ce;
9280 tree idx;
9281 loc = c_parser_peek_token (parser)->location;
9282 c_parser_consume_token (parser);
9283 ce = c_parser_expression (parser);
9284 ce = convert_lvalue_to_rvalue (loc, ce, false, false);
9285 idx = ce.value;
9286 idx = c_fully_fold (idx, false, NULL);
9287 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
9288 "expected %<]%>");
9289 offsetof_ref = build_array_ref (loc, offsetof_ref, idx);
9290 }
9291 }
9292 }
9293 else
9294 c_parser_error (parser, "expected identifier");
9295 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
9296 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9297 "expected %<)%>");
9298 expr.value = fold_offsetof (offsetof_ref);
9299 set_c_expr_source_range (&expr, loc, end_loc);
9300 }
9301 break;
9302 case RID_CHOOSE_EXPR:
9303 {
9304 vec<c_expr_t, va_gc> *cexpr_list;
9305 c_expr_t *e1_p, *e2_p, *e3_p;
9306 tree c;
9307 location_t close_paren_loc;
9308
9309 c_parser_consume_token (parser);
9310 if (!c_parser_get_builtin_args (parser,
9311 "__builtin_choose_expr",
9312 &cexpr_list, true,
9313 &close_paren_loc))
9314 {
9315 expr.set_error ();
9316 break;
9317 }
9318
9319 if (vec_safe_length (cexpr_list) != 3)
9320 {
9321 error_at (loc, "wrong number of arguments to "
9322 "%<__builtin_choose_expr%>");
9323 expr.set_error ();
9324 break;
9325 }
9326
9327 e1_p = &(*cexpr_list)[0];
9328 e2_p = &(*cexpr_list)[1];
9329 e3_p = &(*cexpr_list)[2];
9330
9331 c = e1_p->value;
9332 mark_exp_read (e2_p->value);
9333 mark_exp_read (e3_p->value);
9334 if (TREE_CODE (c) != INTEGER_CST
9335 || !INTEGRAL_TYPE_P (TREE_TYPE (c)))
9336 error_at (loc,
9337 "first argument to %<__builtin_choose_expr%> not"
9338 " a constant");
9339 constant_expression_warning (c);
9340 expr = integer_zerop (c) ? *e3_p : *e2_p;
9341 set_c_expr_source_range (&expr, loc, close_paren_loc);
9342 break;
9343 }
9344 case RID_TYPES_COMPATIBLE_P:
9345 {
9346 c_parser_consume_token (parser);
9347 matching_parens parens;
9348 if (!parens.require_open (parser))
9349 {
9350 expr.set_error ();
9351 break;
9352 }
9353 t1 = c_parser_type_name (parser);
9354 if (t1 == NULL)
9355 {
9356 expr.set_error ();
9357 break;
9358 }
9359 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
9360 {
9361 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9362 expr.set_error ();
9363 break;
9364 }
9365 t2 = c_parser_type_name (parser);
9366 if (t2 == NULL)
9367 {
9368 expr.set_error ();
9369 break;
9370 }
9371 location_t close_paren_loc = c_parser_peek_token (parser)->location;
9372 parens.skip_until_found_close (parser);
9373 tree e1, e2;
9374 e1 = groktypename (t1, NULL, NULL);
9375 e2 = groktypename (t2, NULL, NULL);
9376 if (e1 == error_mark_node || e2 == error_mark_node)
9377 {
9378 expr.set_error ();
9379 break;
9380 }
9381
9382 e1 = TYPE_MAIN_VARIANT (e1);
9383 e2 = TYPE_MAIN_VARIANT (e2);
9384
9385 expr.value
9386 = comptypes (e1, e2) ? integer_one_node : integer_zero_node;
9387 set_c_expr_source_range (&expr, loc, close_paren_loc);
9388 }
9389 break;
9390 case RID_BUILTIN_TGMATH:
9391 {
9392 vec<c_expr_t, va_gc> *cexpr_list;
9393 location_t close_paren_loc;
9394
9395 c_parser_consume_token (parser);
9396 if (!c_parser_get_builtin_args (parser,
9397 "__builtin_tgmath",
9398 &cexpr_list, false,
9399 &close_paren_loc))
9400 {
9401 expr.set_error ();
9402 break;
9403 }
9404
9405 if (vec_safe_length (cexpr_list) < 3)
9406 {
9407 error_at (loc, "too few arguments to %<__builtin_tgmath%>");
9408 expr.set_error ();
9409 break;
9410 }
9411
9412 unsigned int i;
9413 c_expr_t *p;
9414 FOR_EACH_VEC_ELT (*cexpr_list, i, p)
9415 *p = convert_lvalue_to_rvalue (loc, *p, true, true);
9416 unsigned int nargs = check_tgmath_function (&(*cexpr_list)[0], 1);
9417 if (nargs == 0)
9418 {
9419 expr.set_error ();
9420 break;
9421 }
9422 if (vec_safe_length (cexpr_list) < nargs)
9423 {
9424 error_at (loc, "too few arguments to %<__builtin_tgmath%>");
9425 expr.set_error ();
9426 break;
9427 }
9428 unsigned int num_functions = vec_safe_length (cexpr_list) - nargs;
9429 if (num_functions < 2)
9430 {
9431 error_at (loc, "too few arguments to %<__builtin_tgmath%>");
9432 expr.set_error ();
9433 break;
9434 }
9435
9436 /* The first NUM_FUNCTIONS expressions are the function
9437 pointers. The remaining NARGS expressions are the
9438 arguments that are to be passed to one of those
9439 functions, chosen following <tgmath.h> rules. */
9440 for (unsigned int j = 1; j < num_functions; j++)
9441 {
9442 unsigned int this_nargs
9443 = check_tgmath_function (&(*cexpr_list)[j], j + 1);
9444 if (this_nargs == 0)
9445 {
9446 expr.set_error ();
9447 goto out;
9448 }
9449 if (this_nargs != nargs)
9450 {
9451 error_at ((*cexpr_list)[j].get_location (),
9452 "argument %u of %<__builtin_tgmath%> has "
9453 "wrong number of arguments", j + 1);
9454 expr.set_error ();
9455 goto out;
9456 }
9457 }
9458
9459 /* The functions all have the same number of arguments.
9460 Determine whether arguments and return types vary in
9461 ways permitted for <tgmath.h> functions. */
9462 /* The first entry in each of these vectors is for the
9463 return type, subsequent entries for parameter
9464 types. */
9465 auto_vec<enum tgmath_parm_kind> parm_kind (nargs + 1);
9466 auto_vec<tree> parm_first (nargs + 1);
9467 auto_vec<bool> parm_complex (nargs + 1);
9468 auto_vec<bool> parm_varies (nargs + 1);
9469 tree first_type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[0].value));
9470 tree first_ret = TYPE_MAIN_VARIANT (TREE_TYPE (first_type));
9471 parm_first.quick_push (first_ret);
9472 parm_complex.quick_push (TREE_CODE (first_ret) == COMPLEX_TYPE);
9473 parm_varies.quick_push (false);
9474 function_args_iterator iter;
9475 tree t;
9476 unsigned int argpos;
9477 FOREACH_FUNCTION_ARGS (first_type, t, iter)
9478 {
9479 if (t == void_type_node)
9480 break;
9481 parm_first.quick_push (TYPE_MAIN_VARIANT (t));
9482 parm_complex.quick_push (TREE_CODE (t) == COMPLEX_TYPE);
9483 parm_varies.quick_push (false);
9484 }
9485 for (unsigned int j = 1; j < num_functions; j++)
9486 {
9487 tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
9488 tree ret = TYPE_MAIN_VARIANT (TREE_TYPE (type));
9489 if (ret != parm_first[0])
9490 {
9491 parm_varies[0] = true;
9492 if (!SCALAR_FLOAT_TYPE_P (parm_first[0])
9493 && !COMPLEX_FLOAT_TYPE_P (parm_first[0]))
9494 {
9495 error_at ((*cexpr_list)[0].get_location (),
9496 "invalid type-generic return type for "
9497 "argument %u of %<__builtin_tgmath%>",
9498 1);
9499 expr.set_error ();
9500 goto out;
9501 }
9502 if (!SCALAR_FLOAT_TYPE_P (ret)
9503 && !COMPLEX_FLOAT_TYPE_P (ret))
9504 {
9505 error_at ((*cexpr_list)[j].get_location (),
9506 "invalid type-generic return type for "
9507 "argument %u of %<__builtin_tgmath%>",
9508 j + 1);
9509 expr.set_error ();
9510 goto out;
9511 }
9512 }
9513 if (TREE_CODE (ret) == COMPLEX_TYPE)
9514 parm_complex[0] = true;
9515 argpos = 1;
9516 FOREACH_FUNCTION_ARGS (type, t, iter)
9517 {
9518 if (t == void_type_node)
9519 break;
9520 t = TYPE_MAIN_VARIANT (t);
9521 if (t != parm_first[argpos])
9522 {
9523 parm_varies[argpos] = true;
9524 if (!SCALAR_FLOAT_TYPE_P (parm_first[argpos])
9525 && !COMPLEX_FLOAT_TYPE_P (parm_first[argpos]))
9526 {
9527 error_at ((*cexpr_list)[0].get_location (),
9528 "invalid type-generic type for "
9529 "argument %u of argument %u of "
9530 "%<__builtin_tgmath%>", argpos, 1);
9531 expr.set_error ();
9532 goto out;
9533 }
9534 if (!SCALAR_FLOAT_TYPE_P (t)
9535 && !COMPLEX_FLOAT_TYPE_P (t))
9536 {
9537 error_at ((*cexpr_list)[j].get_location (),
9538 "invalid type-generic type for "
9539 "argument %u of argument %u of "
9540 "%<__builtin_tgmath%>", argpos, j + 1);
9541 expr.set_error ();
9542 goto out;
9543 }
9544 }
9545 if (TREE_CODE (t) == COMPLEX_TYPE)
9546 parm_complex[argpos] = true;
9547 argpos++;
9548 }
9549 }
9550 enum tgmath_parm_kind max_variation = tgmath_fixed;
9551 for (unsigned int j = 0; j <= nargs; j++)
9552 {
9553 enum tgmath_parm_kind this_kind;
9554 if (parm_varies[j])
9555 {
9556 if (parm_complex[j])
9557 max_variation = this_kind = tgmath_complex;
9558 else
9559 {
9560 this_kind = tgmath_real;
9561 if (max_variation != tgmath_complex)
9562 max_variation = tgmath_real;
9563 }
9564 }
9565 else
9566 this_kind = tgmath_fixed;
9567 parm_kind.quick_push (this_kind);
9568 }
9569 if (max_variation == tgmath_fixed)
9570 {
9571 error_at (loc, "function arguments of %<__builtin_tgmath%> "
9572 "all have the same type");
9573 expr.set_error ();
9574 break;
9575 }
9576
9577 /* Identify a parameter (not the return type) that varies,
9578 including with complex types if any variation includes
9579 complex types; there must be at least one such
9580 parameter. */
9581 unsigned int tgarg = 0;
9582 for (unsigned int j = 1; j <= nargs; j++)
9583 if (parm_kind[j] == max_variation)
9584 {
9585 tgarg = j;
9586 break;
9587 }
9588 if (tgarg == 0)
9589 {
9590 error_at (loc, "function arguments of %<__builtin_tgmath%> "
9591 "lack type-generic parameter");
9592 expr.set_error ();
9593 break;
9594 }
9595
9596 /* Determine the type of the relevant parameter for each
9597 function. */
9598 auto_vec<tree> tg_type (num_functions);
9599 for (unsigned int j = 0; j < num_functions; j++)
9600 {
9601 tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
9602 argpos = 1;
9603 FOREACH_FUNCTION_ARGS (type, t, iter)
9604 {
9605 if (argpos == tgarg)
9606 {
9607 tg_type.quick_push (TYPE_MAIN_VARIANT (t));
9608 break;
9609 }
9610 argpos++;
9611 }
9612 }
9613
9614 /* Verify that the corresponding types are different for
9615 all the listed functions. Also determine whether all
9616 the types are complex, whether all the types are
9617 standard or binary, and whether all the types are
9618 decimal. */
9619 bool all_complex = true;
9620 bool all_binary = true;
9621 bool all_decimal = true;
9622 hash_set<tree> tg_types;
9623 FOR_EACH_VEC_ELT (tg_type, i, t)
9624 {
9625 if (TREE_CODE (t) == COMPLEX_TYPE)
9626 all_decimal = false;
9627 else
9628 {
9629 all_complex = false;
9630 if (DECIMAL_FLOAT_TYPE_P (t))
9631 all_binary = false;
9632 else
9633 all_decimal = false;
9634 }
9635 if (tg_types.add (t))
9636 {
9637 error_at ((*cexpr_list)[i].get_location (),
9638 "duplicate type-generic parameter type for "
9639 "function argument %u of %<__builtin_tgmath%>",
9640 i + 1);
9641 expr.set_error ();
9642 goto out;
9643 }
9644 }
9645
9646 /* Verify that other parameters and the return type whose
9647 types vary have their types varying in the correct
9648 way. */
9649 for (unsigned int j = 0; j < num_functions; j++)
9650 {
9651 tree exp_type = tg_type[j];
9652 tree exp_real_type = exp_type;
9653 if (TREE_CODE (exp_type) == COMPLEX_TYPE)
9654 exp_real_type = TREE_TYPE (exp_type);
9655 tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
9656 tree ret = TYPE_MAIN_VARIANT (TREE_TYPE (type));
9657 if ((parm_kind[0] == tgmath_complex && ret != exp_type)
9658 || (parm_kind[0] == tgmath_real && ret != exp_real_type))
9659 {
9660 error_at ((*cexpr_list)[j].get_location (),
9661 "bad return type for function argument %u "
9662 "of %<__builtin_tgmath%>", j + 1);
9663 expr.set_error ();
9664 goto out;
9665 }
9666 argpos = 1;
9667 FOREACH_FUNCTION_ARGS (type, t, iter)
9668 {
9669 if (t == void_type_node)
9670 break;
9671 t = TYPE_MAIN_VARIANT (t);
9672 if ((parm_kind[argpos] == tgmath_complex
9673 && t != exp_type)
9674 || (parm_kind[argpos] == tgmath_real
9675 && t != exp_real_type))
9676 {
9677 error_at ((*cexpr_list)[j].get_location (),
9678 "bad type for argument %u of "
9679 "function argument %u of "
9680 "%<__builtin_tgmath%>", argpos, j + 1);
9681 expr.set_error ();
9682 goto out;
9683 }
9684 argpos++;
9685 }
9686 }
9687
9688 /* The functions listed are a valid set of functions for a
9689 <tgmath.h> macro to select between. Identify the
9690 matching function, if any. First, the argument types
9691 must be combined following <tgmath.h> rules. Integer
9692 types are treated as _Decimal64 if any type-generic
9693 argument is decimal, or if the only alternatives for
9694 type-generic arguments are of decimal types, and are
9695 otherwise treated as double (or _Complex double for
9696 complex integer types, or _Float64 or _Complex _Float64
9697 if all the return types are the same _FloatN or
9698 _FloatNx type). After that adjustment, types are
9699 combined following the usual arithmetic conversions.
9700 If the function only accepts complex arguments, a
9701 complex type is produced. */
9702 bool arg_complex = all_complex;
9703 bool arg_binary = all_binary;
9704 bool arg_int_decimal = all_decimal;
9705 for (unsigned int j = 1; j <= nargs; j++)
9706 {
9707 if (parm_kind[j] == tgmath_fixed)
9708 continue;
9709 c_expr_t *ce = &(*cexpr_list)[num_functions + j - 1];
9710 tree type = TREE_TYPE (ce->value);
9711 if (!INTEGRAL_TYPE_P (type)
9712 && !SCALAR_FLOAT_TYPE_P (type)
9713 && TREE_CODE (type) != COMPLEX_TYPE)
9714 {
9715 error_at (ce->get_location (),
9716 "invalid type of argument %u of type-generic "
9717 "function", j);
9718 expr.set_error ();
9719 goto out;
9720 }
9721 if (DECIMAL_FLOAT_TYPE_P (type))
9722 {
9723 arg_int_decimal = true;
9724 if (all_complex)
9725 {
9726 error_at (ce->get_location (),
9727 "decimal floating-point argument %u to "
9728 "complex-only type-generic function", j);
9729 expr.set_error ();
9730 goto out;
9731 }
9732 else if (all_binary)
9733 {
9734 error_at (ce->get_location (),
9735 "decimal floating-point argument %u to "
9736 "binary-only type-generic function", j);
9737 expr.set_error ();
9738 goto out;
9739 }
9740 else if (arg_complex)
9741 {
9742 error_at (ce->get_location (),
9743 "both complex and decimal floating-point "
9744 "arguments to type-generic function");
9745 expr.set_error ();
9746 goto out;
9747 }
9748 else if (arg_binary)
9749 {
9750 error_at (ce->get_location (),
9751 "both binary and decimal floating-point "
9752 "arguments to type-generic function");
9753 expr.set_error ();
9754 goto out;
9755 }
9756 }
9757 else if (TREE_CODE (type) == COMPLEX_TYPE)
9758 {
9759 arg_complex = true;
9760 if (COMPLEX_FLOAT_TYPE_P (type))
9761 arg_binary = true;
9762 if (all_decimal)
9763 {
9764 error_at (ce->get_location (),
9765 "complex argument %u to "
9766 "decimal-only type-generic function", j);
9767 expr.set_error ();
9768 goto out;
9769 }
9770 else if (arg_int_decimal)
9771 {
9772 error_at (ce->get_location (),
9773 "both complex and decimal floating-point "
9774 "arguments to type-generic function");
9775 expr.set_error ();
9776 goto out;
9777 }
9778 }
9779 else if (SCALAR_FLOAT_TYPE_P (type))
9780 {
9781 arg_binary = true;
9782 if (all_decimal)
9783 {
9784 error_at (ce->get_location (),
9785 "binary argument %u to "
9786 "decimal-only type-generic function", j);
9787 expr.set_error ();
9788 goto out;
9789 }
9790 else if (arg_int_decimal)
9791 {
9792 error_at (ce->get_location (),
9793 "both binary and decimal floating-point "
9794 "arguments to type-generic function");
9795 expr.set_error ();
9796 goto out;
9797 }
9798 }
9799 }
9800 /* For a macro rounding its result to a narrower type, map
9801 integer types to _Float64 not double if the return type
9802 is a _FloatN or _FloatNx type. */
9803 bool arg_int_float64 = false;
9804 if (parm_kind[0] == tgmath_fixed
9805 && SCALAR_FLOAT_TYPE_P (parm_first[0])
9806 && float64_type_node != NULL_TREE)
9807 for (unsigned int j = 0; j < NUM_FLOATN_NX_TYPES; j++)
9808 if (parm_first[0] == FLOATN_TYPE_NODE (j))
9809 {
9810 arg_int_float64 = true;
9811 break;
9812 }
9813 tree arg_real = NULL_TREE;
9814 for (unsigned int j = 1; j <= nargs; j++)
9815 {
9816 if (parm_kind[j] == tgmath_fixed)
9817 continue;
9818 c_expr_t *ce = &(*cexpr_list)[num_functions + j - 1];
9819 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (ce->value));
9820 if (TREE_CODE (type) == COMPLEX_TYPE)
9821 type = TREE_TYPE (type);
9822 if (INTEGRAL_TYPE_P (type))
9823 type = (arg_int_decimal
9824 ? dfloat64_type_node
9825 : arg_int_float64
9826 ? float64_type_node
9827 : double_type_node);
9828 if (arg_real == NULL_TREE)
9829 arg_real = type;
9830 else
9831 arg_real = common_type (arg_real, type);
9832 if (arg_real == error_mark_node)
9833 {
9834 expr.set_error ();
9835 goto out;
9836 }
9837 }
9838 tree arg_type = (arg_complex
9839 ? build_complex_type (arg_real)
9840 : arg_real);
9841
9842 /* Look for a function to call with type-generic parameter
9843 type ARG_TYPE. */
9844 c_expr_t *fn = NULL;
9845 for (unsigned int j = 0; j < num_functions; j++)
9846 {
9847 if (tg_type[j] == arg_type)
9848 {
9849 fn = &(*cexpr_list)[j];
9850 break;
9851 }
9852 }
9853 if (fn == NULL
9854 && parm_kind[0] == tgmath_fixed
9855 && SCALAR_FLOAT_TYPE_P (parm_first[0]))
9856 {
9857 /* Presume this is a macro that rounds its result to a
9858 narrower type, and look for the first function with
9859 at least the range and precision of the argument
9860 type. */
9861 for (unsigned int j = 0; j < num_functions; j++)
9862 {
9863 if (arg_complex
9864 != (TREE_CODE (tg_type[j]) == COMPLEX_TYPE))
9865 continue;
9866 tree real_tg_type = (arg_complex
9867 ? TREE_TYPE (tg_type[j])
9868 : tg_type[j]);
9869 if (DECIMAL_FLOAT_TYPE_P (arg_real)
9870 != DECIMAL_FLOAT_TYPE_P (real_tg_type))
9871 continue;
9872 scalar_float_mode arg_mode
9873 = SCALAR_FLOAT_TYPE_MODE (arg_real);
9874 scalar_float_mode tg_mode
9875 = SCALAR_FLOAT_TYPE_MODE (real_tg_type);
9876 const real_format *arg_fmt = REAL_MODE_FORMAT (arg_mode);
9877 const real_format *tg_fmt = REAL_MODE_FORMAT (tg_mode);
9878 if (arg_fmt->b == tg_fmt->b
9879 && arg_fmt->p <= tg_fmt->p
9880 && arg_fmt->emax <= tg_fmt->emax
9881 && (arg_fmt->emin - arg_fmt->p
9882 >= tg_fmt->emin - tg_fmt->p))
9883 {
9884 fn = &(*cexpr_list)[j];
9885 break;
9886 }
9887 }
9888 }
9889 if (fn == NULL)
9890 {
9891 error_at (loc, "no matching function for type-generic call");
9892 expr.set_error ();
9893 break;
9894 }
9895
9896 /* Construct a call to FN. */
9897 vec<tree, va_gc> *args;
9898 vec_alloc (args, nargs);
9899 vec<tree, va_gc> *origtypes;
9900 vec_alloc (origtypes, nargs);
9901 auto_vec<location_t> arg_loc (nargs);
9902 for (unsigned int j = 0; j < nargs; j++)
9903 {
9904 c_expr_t *ce = &(*cexpr_list)[num_functions + j];
9905 args->quick_push (ce->value);
9906 arg_loc.quick_push (ce->get_location ());
9907 origtypes->quick_push (ce->original_type);
9908 }
9909 expr.value = c_build_function_call_vec (loc, arg_loc, fn->value,
9910 args, origtypes);
9911 set_c_expr_source_range (&expr, loc, close_paren_loc);
9912 break;
9913 }
9914 case RID_BUILTIN_CALL_WITH_STATIC_CHAIN:
9915 {
9916 vec<c_expr_t, va_gc> *cexpr_list;
9917 c_expr_t *e2_p;
9918 tree chain_value;
9919 location_t close_paren_loc;
9920
9921 c_parser_consume_token (parser);
9922 if (!c_parser_get_builtin_args (parser,
9923 "__builtin_call_with_static_chain",
9924 &cexpr_list, false,
9925 &close_paren_loc))
9926 {
9927 expr.set_error ();
9928 break;
9929 }
9930 if (vec_safe_length (cexpr_list) != 2)
9931 {
9932 error_at (loc, "wrong number of arguments to "
9933 "%<__builtin_call_with_static_chain%>");
9934 expr.set_error ();
9935 break;
9936 }
9937
9938 expr = (*cexpr_list)[0];
9939 e2_p = &(*cexpr_list)[1];
9940 *e2_p = convert_lvalue_to_rvalue (loc, *e2_p, true, true);
9941 chain_value = e2_p->value;
9942 mark_exp_read (chain_value);
9943
9944 if (TREE_CODE (expr.value) != CALL_EXPR)
9945 error_at (loc, "first argument to "
9946 "%<__builtin_call_with_static_chain%> "
9947 "must be a call expression");
9948 else if (TREE_CODE (TREE_TYPE (chain_value)) != POINTER_TYPE)
9949 error_at (loc, "second argument to "
9950 "%<__builtin_call_with_static_chain%> "
9951 "must be a pointer type");
9952 else
9953 CALL_EXPR_STATIC_CHAIN (expr.value) = chain_value;
9954 set_c_expr_source_range (&expr, loc, close_paren_loc);
9955 break;
9956 }
9957 case RID_BUILTIN_COMPLEX:
9958 {
9959 vec<c_expr_t, va_gc> *cexpr_list;
9960 c_expr_t *e1_p, *e2_p;
9961 location_t close_paren_loc;
9962
9963 c_parser_consume_token (parser);
9964 if (!c_parser_get_builtin_args (parser,
9965 "__builtin_complex",
9966 &cexpr_list, false,
9967 &close_paren_loc))
9968 {
9969 expr.set_error ();
9970 break;
9971 }
9972
9973 if (vec_safe_length (cexpr_list) != 2)
9974 {
9975 error_at (loc, "wrong number of arguments to "
9976 "%<__builtin_complex%>");
9977 expr.set_error ();
9978 break;
9979 }
9980
9981 e1_p = &(*cexpr_list)[0];
9982 e2_p = &(*cexpr_list)[1];
9983
9984 *e1_p = convert_lvalue_to_rvalue (loc, *e1_p, true, true);
9985 if (TREE_CODE (e1_p->value) == EXCESS_PRECISION_EXPR)
9986 e1_p->value = convert (TREE_TYPE (e1_p->value),
9987 TREE_OPERAND (e1_p->value, 0));
9988 *e2_p = convert_lvalue_to_rvalue (loc, *e2_p, true, true);
9989 if (TREE_CODE (e2_p->value) == EXCESS_PRECISION_EXPR)
9990 e2_p->value = convert (TREE_TYPE (e2_p->value),
9991 TREE_OPERAND (e2_p->value, 0));
9992 if (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (e1_p->value))
9993 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e1_p->value))
9994 || !SCALAR_FLOAT_TYPE_P (TREE_TYPE (e2_p->value))
9995 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e2_p->value)))
9996 {
9997 error_at (loc, "%<__builtin_complex%> operand "
9998 "not of real binary floating-point type");
9999 expr.set_error ();
10000 break;
10001 }
10002 if (TYPE_MAIN_VARIANT (TREE_TYPE (e1_p->value))
10003 != TYPE_MAIN_VARIANT (TREE_TYPE (e2_p->value)))
10004 {
10005 error_at (loc,
10006 "%<__builtin_complex%> operands of different types");
10007 expr.set_error ();
10008 break;
10009 }
10010 pedwarn_c90 (loc, OPT_Wpedantic,
10011 "ISO C90 does not support complex types");
10012 expr.value = build2_loc (loc, COMPLEX_EXPR,
10013 build_complex_type
10014 (TYPE_MAIN_VARIANT
10015 (TREE_TYPE (e1_p->value))),
10016 e1_p->value, e2_p->value);
10017 set_c_expr_source_range (&expr, loc, close_paren_loc);
10018 break;
10019 }
10020 case RID_BUILTIN_SHUFFLE:
10021 {
10022 vec<c_expr_t, va_gc> *cexpr_list;
10023 unsigned int i;
10024 c_expr_t *p;
10025 location_t close_paren_loc;
10026
10027 c_parser_consume_token (parser);
10028 if (!c_parser_get_builtin_args (parser,
10029 "__builtin_shuffle",
10030 &cexpr_list, false,
10031 &close_paren_loc))
10032 {
10033 expr.set_error ();
10034 break;
10035 }
10036
10037 FOR_EACH_VEC_SAFE_ELT (cexpr_list, i, p)
10038 *p = convert_lvalue_to_rvalue (loc, *p, true, true);
10039
10040 if (vec_safe_length (cexpr_list) == 2)
10041 expr.value = c_build_vec_perm_expr (loc, (*cexpr_list)[0].value,
10042 NULL_TREE,
10043 (*cexpr_list)[1].value);
10044
10045 else if (vec_safe_length (cexpr_list) == 3)
10046 expr.value = c_build_vec_perm_expr (loc, (*cexpr_list)[0].value,
10047 (*cexpr_list)[1].value,
10048 (*cexpr_list)[2].value);
10049 else
10050 {
10051 error_at (loc, "wrong number of arguments to "
10052 "%<__builtin_shuffle%>");
10053 expr.set_error ();
10054 }
10055 set_c_expr_source_range (&expr, loc, close_paren_loc);
10056 break;
10057 }
10058 case RID_BUILTIN_SHUFFLEVECTOR:
10059 {
10060 vec<c_expr_t, va_gc> *cexpr_list;
10061 unsigned int i;
10062 c_expr_t *p;
10063 location_t close_paren_loc;
10064
10065 c_parser_consume_token (parser);
10066 if (!c_parser_get_builtin_args (parser,
10067 "__builtin_shufflevector",
10068 &cexpr_list, false,
10069 &close_paren_loc))
10070 {
10071 expr.set_error ();
10072 break;
10073 }
10074
10075 FOR_EACH_VEC_SAFE_ELT (cexpr_list, i, p)
10076 *p = convert_lvalue_to_rvalue (loc, *p, true, true);
10077
10078 if (vec_safe_length (cexpr_list) < 3)
10079 {
10080 error_at (loc, "wrong number of arguments to "
10081 "%<__builtin_shuffle%>");
10082 expr.set_error ();
10083 }
10084 else
10085 {
10086 auto_vec<tree, 16> mask;
10087 for (i = 2; i < cexpr_list->length (); ++i)
10088 mask.safe_push ((*cexpr_list)[i].value);
10089 expr.value = c_build_shufflevector (loc, (*cexpr_list)[0].value,
10090 (*cexpr_list)[1].value,
10091 mask);
10092 }
10093 set_c_expr_source_range (&expr, loc, close_paren_loc);
10094 break;
10095 }
10096 case RID_BUILTIN_CONVERTVECTOR:
10097 {
10098 location_t start_loc = loc;
10099 c_parser_consume_token (parser);
10100 matching_parens parens;
10101 if (!parens.require_open (parser))
10102 {
10103 expr.set_error ();
10104 break;
10105 }
10106 e1 = c_parser_expr_no_commas (parser, NULL);
10107 mark_exp_read (e1.value);
10108 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
10109 {
10110 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10111 expr.set_error ();
10112 break;
10113 }
10114 loc = c_parser_peek_token (parser)->location;
10115 t1 = c_parser_type_name (parser);
10116 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
10117 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
10118 "expected %<)%>");
10119 if (t1 == NULL)
10120 expr.set_error ();
10121 else
10122 {
10123 tree type_expr = NULL_TREE;
10124 expr.value = c_build_vec_convert (start_loc, e1.value, loc,
10125 groktypename (t1, &type_expr,
10126 NULL));
10127 set_c_expr_source_range (&expr, start_loc, end_loc);
10128 }
10129 }
10130 break;
10131 case RID_BUILTIN_ASSOC_BARRIER:
10132 {
10133 location_t start_loc = loc;
10134 c_parser_consume_token (parser);
10135 matching_parens parens;
10136 if (!parens.require_open (parser))
10137 {
10138 expr.set_error ();
10139 break;
10140 }
10141 e1 = c_parser_expr_no_commas (parser, NULL);
10142 mark_exp_read (e1.value);
10143 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
10144 parens.skip_until_found_close (parser);
10145 expr = parser_build_unary_op (loc, PAREN_EXPR, e1);
10146 set_c_expr_source_range (&expr, start_loc, end_loc);
10147 }
10148 break;
10149 case RID_AT_SELECTOR:
10150 {
10151 gcc_assert (c_dialect_objc ());
10152 c_parser_consume_token (parser);
10153 matching_parens parens;
10154 if (!parens.require_open (parser))
10155 {
10156 expr.set_error ();
10157 break;
10158 }
10159 tree sel = c_parser_objc_selector_arg (parser);
10160 location_t close_loc = c_parser_peek_token (parser)->location;
10161 parens.skip_until_found_close (parser);
10162 expr.value = objc_build_selector_expr (loc, sel);
10163 set_c_expr_source_range (&expr, loc, close_loc);
10164 }
10165 break;
10166 case RID_AT_PROTOCOL:
10167 {
10168 gcc_assert (c_dialect_objc ());
10169 c_parser_consume_token (parser);
10170 matching_parens parens;
10171 if (!parens.require_open (parser))
10172 {
10173 expr.set_error ();
10174 break;
10175 }
10176 if (c_parser_next_token_is_not (parser, CPP_NAME))
10177 {
10178 c_parser_error (parser, "expected identifier");
10179 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10180 expr.set_error ();
10181 break;
10182 }
10183 tree id = c_parser_peek_token (parser)->value;
10184 c_parser_consume_token (parser);
10185 location_t close_loc = c_parser_peek_token (parser)->location;
10186 parens.skip_until_found_close (parser);
10187 expr.value = objc_build_protocol_expr (id);
10188 set_c_expr_source_range (&expr, loc, close_loc);
10189 }
10190 break;
10191 case RID_AT_ENCODE:
10192 {
10193 /* Extension to support C-structures in the archiver. */
10194 gcc_assert (c_dialect_objc ());
10195 c_parser_consume_token (parser);
10196 matching_parens parens;
10197 if (!parens.require_open (parser))
10198 {
10199 expr.set_error ();
10200 break;
10201 }
10202 t1 = c_parser_type_name (parser);
10203 if (t1 == NULL)
10204 {
10205 expr.set_error ();
10206 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10207 break;
10208 }
10209 location_t close_loc = c_parser_peek_token (parser)->location;
10210 parens.skip_until_found_close (parser);
10211 tree type = groktypename (t1, NULL, NULL);
10212 expr.value = objc_build_encode_expr (type);
10213 set_c_expr_source_range (&expr, loc, close_loc);
10214 }
10215 break;
10216 case RID_GENERIC:
10217 expr = c_parser_generic_selection (parser);
10218 break;
10219 default:
10220 c_parser_error (parser, "expected expression");
10221 expr.set_error ();
10222 break;
10223 }
10224 break;
10225 case CPP_OPEN_SQUARE:
10226 if (c_dialect_objc ())
10227 {
10228 tree receiver, args;
10229 c_parser_consume_token (parser);
10230 receiver = c_parser_objc_receiver (parser);
10231 args = c_parser_objc_message_args (parser);
10232 location_t close_loc = c_parser_peek_token (parser)->location;
10233 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
10234 "expected %<]%>");
10235 expr.value = objc_build_message_expr (receiver, args);
10236 set_c_expr_source_range (&expr, loc, close_loc);
10237 break;
10238 }
10239 /* Else fall through to report error. */
10240 /* FALLTHRU */
10241 default:
10242 c_parser_error (parser, "expected expression");
10243 expr.set_error ();
10244 break;
10245 }
10246 out:
10247 return c_parser_postfix_expression_after_primary
10248 (parser, EXPR_LOC_OR_LOC (expr.value, loc), expr);
10249 }
10250
10251 /* Parse a postfix expression after a parenthesized type name: the
10252 brace-enclosed initializer of a compound literal, possibly followed
10253 by some postfix operators. This is separate because it is not
10254 possible to tell until after the type name whether a cast
10255 expression has a cast or a compound literal, or whether the operand
10256 of sizeof is a parenthesized type name or starts with a compound
10257 literal. TYPE_LOC is the location where TYPE_NAME starts--the
10258 location of the first token after the parentheses around the type
10259 name. */
10260
10261 static struct c_expr
c_parser_postfix_expression_after_paren_type(c_parser * parser,struct c_type_name * type_name,location_t type_loc)10262 c_parser_postfix_expression_after_paren_type (c_parser *parser,
10263 struct c_type_name *type_name,
10264 location_t type_loc)
10265 {
10266 tree type;
10267 struct c_expr init;
10268 bool non_const;
10269 struct c_expr expr;
10270 location_t start_loc;
10271 tree type_expr = NULL_TREE;
10272 bool type_expr_const = true;
10273 check_compound_literal_type (type_loc, type_name);
10274 rich_location richloc (line_table, type_loc);
10275 start_init (NULL_TREE, NULL, 0, &richloc);
10276 type = groktypename (type_name, &type_expr, &type_expr_const);
10277 start_loc = c_parser_peek_token (parser)->location;
10278 if (type != error_mark_node && C_TYPE_VARIABLE_SIZE (type))
10279 {
10280 error_at (type_loc, "compound literal has variable size");
10281 type = error_mark_node;
10282 }
10283 init = c_parser_braced_init (parser, type, false, NULL);
10284 finish_init ();
10285 maybe_warn_string_init (type_loc, type, init);
10286
10287 if (type != error_mark_node
10288 && !ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (type))
10289 && current_function_decl)
10290 {
10291 error ("compound literal qualified by address-space qualifier");
10292 type = error_mark_node;
10293 }
10294
10295 pedwarn_c90 (start_loc, OPT_Wpedantic, "ISO C90 forbids compound literals");
10296 non_const = ((init.value && TREE_CODE (init.value) == CONSTRUCTOR)
10297 ? CONSTRUCTOR_NON_CONST (init.value)
10298 : init.original_code == C_MAYBE_CONST_EXPR);
10299 non_const |= !type_expr_const;
10300 unsigned int alignas_align = 0;
10301 if (type != error_mark_node
10302 && type_name->specs->align_log != -1)
10303 {
10304 alignas_align = 1U << type_name->specs->align_log;
10305 if (alignas_align < min_align_of_type (type))
10306 {
10307 error_at (type_name->specs->locations[cdw_alignas],
10308 "%<_Alignas%> specifiers cannot reduce "
10309 "alignment of compound literal");
10310 alignas_align = 0;
10311 }
10312 }
10313 expr.value = build_compound_literal (start_loc, type, init.value, non_const,
10314 alignas_align);
10315 set_c_expr_source_range (&expr, init.src_range);
10316 expr.original_code = ERROR_MARK;
10317 expr.original_type = NULL;
10318 if (type != error_mark_node
10319 && expr.value != error_mark_node
10320 && type_expr)
10321 {
10322 if (TREE_CODE (expr.value) == C_MAYBE_CONST_EXPR)
10323 {
10324 gcc_assert (C_MAYBE_CONST_EXPR_PRE (expr.value) == NULL_TREE);
10325 C_MAYBE_CONST_EXPR_PRE (expr.value) = type_expr;
10326 }
10327 else
10328 {
10329 gcc_assert (!non_const);
10330 expr.value = build2 (C_MAYBE_CONST_EXPR, type,
10331 type_expr, expr.value);
10332 }
10333 }
10334 return c_parser_postfix_expression_after_primary (parser, start_loc, expr);
10335 }
10336
10337 /* Callback function for sizeof_pointer_memaccess_warning to compare
10338 types. */
10339
10340 static bool
sizeof_ptr_memacc_comptypes(tree type1,tree type2)10341 sizeof_ptr_memacc_comptypes (tree type1, tree type2)
10342 {
10343 return comptypes (type1, type2) == 1;
10344 }
10345
10346 /* Warn for patterns where abs-like function appears to be used incorrectly,
10347 gracefully ignore any non-abs-like function. The warning location should
10348 be LOC. FNDECL is the declaration of called function, it must be a
10349 BUILT_IN_NORMAL function. ARG is the first and only argument of the
10350 call. */
10351
10352 static void
warn_for_abs(location_t loc,tree fndecl,tree arg)10353 warn_for_abs (location_t loc, tree fndecl, tree arg)
10354 {
10355 /* Avoid warning in unreachable subexpressions. */
10356 if (c_inhibit_evaluation_warnings)
10357 return;
10358
10359 tree atype = TREE_TYPE (arg);
10360
10361 /* Casts from pointers (and thus arrays and fndecls) will generate
10362 -Wint-conversion warnings. Most other wrong types hopefully lead to type
10363 mismatch errors. TODO: Think about what to do with FIXED_POINT_TYPE_P
10364 types and possibly other exotic types. */
10365 if (!INTEGRAL_TYPE_P (atype)
10366 && !SCALAR_FLOAT_TYPE_P (atype)
10367 && TREE_CODE (atype) != COMPLEX_TYPE)
10368 return;
10369
10370 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10371
10372 switch (fcode)
10373 {
10374 case BUILT_IN_ABS:
10375 case BUILT_IN_LABS:
10376 case BUILT_IN_LLABS:
10377 case BUILT_IN_IMAXABS:
10378 if (!INTEGRAL_TYPE_P (atype))
10379 {
10380 if (SCALAR_FLOAT_TYPE_P (atype))
10381 warning_at (loc, OPT_Wabsolute_value,
10382 "using integer absolute value function %qD when "
10383 "argument is of floating-point type %qT",
10384 fndecl, atype);
10385 else if (TREE_CODE (atype) == COMPLEX_TYPE)
10386 warning_at (loc, OPT_Wabsolute_value,
10387 "using integer absolute value function %qD when "
10388 "argument is of complex type %qT", fndecl, atype);
10389 else
10390 gcc_unreachable ();
10391 return;
10392 }
10393 if (TYPE_UNSIGNED (atype))
10394 warning_at (loc, OPT_Wabsolute_value,
10395 "taking the absolute value of unsigned type %qT "
10396 "has no effect", atype);
10397 break;
10398
10399 CASE_FLT_FN (BUILT_IN_FABS):
10400 CASE_FLT_FN_FLOATN_NX (BUILT_IN_FABS):
10401 if (!SCALAR_FLOAT_TYPE_P (atype)
10402 || DECIMAL_FLOAT_MODE_P (TYPE_MODE (atype)))
10403 {
10404 if (INTEGRAL_TYPE_P (atype))
10405 warning_at (loc, OPT_Wabsolute_value,
10406 "using floating-point absolute value function %qD "
10407 "when argument is of integer type %qT", fndecl, atype);
10408 else if (DECIMAL_FLOAT_TYPE_P (atype))
10409 warning_at (loc, OPT_Wabsolute_value,
10410 "using floating-point absolute value function %qD "
10411 "when argument is of decimal floating-point type %qT",
10412 fndecl, atype);
10413 else if (TREE_CODE (atype) == COMPLEX_TYPE)
10414 warning_at (loc, OPT_Wabsolute_value,
10415 "using floating-point absolute value function %qD when "
10416 "argument is of complex type %qT", fndecl, atype);
10417 else
10418 gcc_unreachable ();
10419 return;
10420 }
10421 break;
10422
10423 CASE_FLT_FN (BUILT_IN_CABS):
10424 if (TREE_CODE (atype) != COMPLEX_TYPE)
10425 {
10426 if (INTEGRAL_TYPE_P (atype))
10427 warning_at (loc, OPT_Wabsolute_value,
10428 "using complex absolute value function %qD when "
10429 "argument is of integer type %qT", fndecl, atype);
10430 else if (SCALAR_FLOAT_TYPE_P (atype))
10431 warning_at (loc, OPT_Wabsolute_value,
10432 "using complex absolute value function %qD when "
10433 "argument is of floating-point type %qT",
10434 fndecl, atype);
10435 else
10436 gcc_unreachable ();
10437
10438 return;
10439 }
10440 break;
10441
10442 case BUILT_IN_FABSD32:
10443 case BUILT_IN_FABSD64:
10444 case BUILT_IN_FABSD128:
10445 if (!DECIMAL_FLOAT_TYPE_P (atype))
10446 {
10447 if (INTEGRAL_TYPE_P (atype))
10448 warning_at (loc, OPT_Wabsolute_value,
10449 "using decimal floating-point absolute value "
10450 "function %qD when argument is of integer type %qT",
10451 fndecl, atype);
10452 else if (SCALAR_FLOAT_TYPE_P (atype))
10453 warning_at (loc, OPT_Wabsolute_value,
10454 "using decimal floating-point absolute value "
10455 "function %qD when argument is of floating-point "
10456 "type %qT", fndecl, atype);
10457 else if (TREE_CODE (atype) == COMPLEX_TYPE)
10458 warning_at (loc, OPT_Wabsolute_value,
10459 "using decimal floating-point absolute value "
10460 "function %qD when argument is of complex type %qT",
10461 fndecl, atype);
10462 else
10463 gcc_unreachable ();
10464 return;
10465 }
10466 break;
10467
10468 default:
10469 return;
10470 }
10471
10472 if (!TYPE_ARG_TYPES (TREE_TYPE (fndecl)))
10473 return;
10474
10475 tree ftype = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
10476 if (TREE_CODE (atype) == COMPLEX_TYPE)
10477 {
10478 gcc_assert (TREE_CODE (ftype) == COMPLEX_TYPE);
10479 atype = TREE_TYPE (atype);
10480 ftype = TREE_TYPE (ftype);
10481 }
10482
10483 if (TYPE_PRECISION (ftype) < TYPE_PRECISION (atype))
10484 warning_at (loc, OPT_Wabsolute_value,
10485 "absolute value function %qD given an argument of type %qT "
10486 "but has parameter of type %qT which may cause truncation "
10487 "of value", fndecl, atype, ftype);
10488 }
10489
10490
10491 /* Parse a postfix expression after the initial primary or compound
10492 literal; that is, parse a series of postfix operators.
10493
10494 EXPR_LOC is the location of the primary expression. */
10495
10496 static struct c_expr
c_parser_postfix_expression_after_primary(c_parser * parser,location_t expr_loc,struct c_expr expr)10497 c_parser_postfix_expression_after_primary (c_parser *parser,
10498 location_t expr_loc,
10499 struct c_expr expr)
10500 {
10501 struct c_expr orig_expr;
10502 tree ident, idx;
10503 location_t sizeof_arg_loc[3], comp_loc;
10504 tree sizeof_arg[3];
10505 unsigned int literal_zero_mask;
10506 unsigned int i;
10507 vec<tree, va_gc> *exprlist;
10508 vec<tree, va_gc> *origtypes = NULL;
10509 vec<location_t> arg_loc = vNULL;
10510 location_t start;
10511 location_t finish;
10512
10513 while (true)
10514 {
10515 location_t op_loc = c_parser_peek_token (parser)->location;
10516 switch (c_parser_peek_token (parser)->type)
10517 {
10518 case CPP_OPEN_SQUARE:
10519 /* Array reference. */
10520 c_parser_consume_token (parser);
10521 idx = c_parser_expression (parser).value;
10522 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
10523 "expected %<]%>");
10524 start = expr.get_start ();
10525 finish = parser->tokens_buf[0].location;
10526 expr.value = build_array_ref (op_loc, expr.value, idx);
10527 set_c_expr_source_range (&expr, start, finish);
10528 expr.original_code = ERROR_MARK;
10529 expr.original_type = NULL;
10530 break;
10531 case CPP_OPEN_PAREN:
10532 /* Function call. */
10533 {
10534 matching_parens parens;
10535 parens.consume_open (parser);
10536 for (i = 0; i < 3; i++)
10537 {
10538 sizeof_arg[i] = NULL_TREE;
10539 sizeof_arg_loc[i] = UNKNOWN_LOCATION;
10540 }
10541 literal_zero_mask = 0;
10542 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
10543 exprlist = NULL;
10544 else
10545 exprlist = c_parser_expr_list (parser, true, false, &origtypes,
10546 sizeof_arg_loc, sizeof_arg,
10547 &arg_loc, &literal_zero_mask);
10548 parens.skip_until_found_close (parser);
10549 }
10550 orig_expr = expr;
10551 mark_exp_read (expr.value);
10552 if (warn_sizeof_pointer_memaccess)
10553 sizeof_pointer_memaccess_warning (sizeof_arg_loc,
10554 expr.value, exprlist,
10555 sizeof_arg,
10556 sizeof_ptr_memacc_comptypes);
10557 if (TREE_CODE (expr.value) == FUNCTION_DECL)
10558 {
10559 if (fndecl_built_in_p (expr.value, BUILT_IN_MEMSET)
10560 && vec_safe_length (exprlist) == 3)
10561 {
10562 tree arg0 = (*exprlist)[0];
10563 tree arg2 = (*exprlist)[2];
10564 warn_for_memset (expr_loc, arg0, arg2, literal_zero_mask);
10565 }
10566 if (warn_absolute_value
10567 && fndecl_built_in_p (expr.value, BUILT_IN_NORMAL)
10568 && vec_safe_length (exprlist) == 1)
10569 warn_for_abs (expr_loc, expr.value, (*exprlist)[0]);
10570 }
10571
10572 start = expr.get_start ();
10573 finish = parser->tokens_buf[0].get_finish ();
10574 expr.value
10575 = c_build_function_call_vec (expr_loc, arg_loc, expr.value,
10576 exprlist, origtypes);
10577 set_c_expr_source_range (&expr, start, finish);
10578
10579 expr.original_code = ERROR_MARK;
10580 if (TREE_CODE (expr.value) == INTEGER_CST
10581 && TREE_CODE (orig_expr.value) == FUNCTION_DECL
10582 && fndecl_built_in_p (orig_expr.value, BUILT_IN_CONSTANT_P))
10583 expr.original_code = C_MAYBE_CONST_EXPR;
10584 expr.original_type = NULL;
10585 if (exprlist)
10586 {
10587 release_tree_vector (exprlist);
10588 release_tree_vector (origtypes);
10589 }
10590 arg_loc.release ();
10591 break;
10592 case CPP_DOT:
10593 /* Structure element reference. */
10594 c_parser_consume_token (parser);
10595 expr = default_function_array_conversion (expr_loc, expr);
10596 if (c_parser_next_token_is (parser, CPP_NAME))
10597 {
10598 c_token *comp_tok = c_parser_peek_token (parser);
10599 ident = comp_tok->value;
10600 comp_loc = comp_tok->location;
10601 }
10602 else
10603 {
10604 c_parser_error (parser, "expected identifier");
10605 expr.set_error ();
10606 expr.original_code = ERROR_MARK;
10607 expr.original_type = NULL;
10608 return expr;
10609 }
10610 start = expr.get_start ();
10611 finish = c_parser_peek_token (parser)->get_finish ();
10612 c_parser_consume_token (parser);
10613 expr.value = build_component_ref (op_loc, expr.value, ident,
10614 comp_loc);
10615 set_c_expr_source_range (&expr, start, finish);
10616 expr.original_code = ERROR_MARK;
10617 if (TREE_CODE (expr.value) != COMPONENT_REF)
10618 expr.original_type = NULL;
10619 else
10620 {
10621 /* Remember the original type of a bitfield. */
10622 tree field = TREE_OPERAND (expr.value, 1);
10623 if (TREE_CODE (field) != FIELD_DECL)
10624 expr.original_type = NULL;
10625 else
10626 expr.original_type = DECL_BIT_FIELD_TYPE (field);
10627 }
10628 break;
10629 case CPP_DEREF:
10630 /* Structure element reference. */
10631 c_parser_consume_token (parser);
10632 expr = convert_lvalue_to_rvalue (expr_loc, expr, true, false);
10633 if (c_parser_next_token_is (parser, CPP_NAME))
10634 {
10635 c_token *comp_tok = c_parser_peek_token (parser);
10636 ident = comp_tok->value;
10637 comp_loc = comp_tok->location;
10638 }
10639 else
10640 {
10641 c_parser_error (parser, "expected identifier");
10642 expr.set_error ();
10643 expr.original_code = ERROR_MARK;
10644 expr.original_type = NULL;
10645 return expr;
10646 }
10647 start = expr.get_start ();
10648 finish = c_parser_peek_token (parser)->get_finish ();
10649 c_parser_consume_token (parser);
10650 expr.value = build_component_ref (op_loc,
10651 build_indirect_ref (op_loc,
10652 expr.value,
10653 RO_ARROW),
10654 ident, comp_loc);
10655 set_c_expr_source_range (&expr, start, finish);
10656 expr.original_code = ERROR_MARK;
10657 if (TREE_CODE (expr.value) != COMPONENT_REF)
10658 expr.original_type = NULL;
10659 else
10660 {
10661 /* Remember the original type of a bitfield. */
10662 tree field = TREE_OPERAND (expr.value, 1);
10663 if (TREE_CODE (field) != FIELD_DECL)
10664 expr.original_type = NULL;
10665 else
10666 expr.original_type = DECL_BIT_FIELD_TYPE (field);
10667 }
10668 break;
10669 case CPP_PLUS_PLUS:
10670 /* Postincrement. */
10671 start = expr.get_start ();
10672 finish = c_parser_peek_token (parser)->get_finish ();
10673 c_parser_consume_token (parser);
10674 expr = default_function_array_read_conversion (expr_loc, expr);
10675 expr.value = build_unary_op (op_loc, POSTINCREMENT_EXPR,
10676 expr.value, false);
10677 set_c_expr_source_range (&expr, start, finish);
10678 expr.original_code = ERROR_MARK;
10679 expr.original_type = NULL;
10680 break;
10681 case CPP_MINUS_MINUS:
10682 /* Postdecrement. */
10683 start = expr.get_start ();
10684 finish = c_parser_peek_token (parser)->get_finish ();
10685 c_parser_consume_token (parser);
10686 expr = default_function_array_read_conversion (expr_loc, expr);
10687 expr.value = build_unary_op (op_loc, POSTDECREMENT_EXPR,
10688 expr.value, false);
10689 set_c_expr_source_range (&expr, start, finish);
10690 expr.original_code = ERROR_MARK;
10691 expr.original_type = NULL;
10692 break;
10693 default:
10694 return expr;
10695 }
10696 }
10697 }
10698
10699 /* Parse an expression (C90 6.3.17, C99 6.5.17, C11 6.5.17).
10700
10701 expression:
10702 assignment-expression
10703 expression , assignment-expression
10704 */
10705
10706 static struct c_expr
c_parser_expression(c_parser * parser)10707 c_parser_expression (c_parser *parser)
10708 {
10709 location_t tloc = c_parser_peek_token (parser)->location;
10710 struct c_expr expr;
10711 expr = c_parser_expr_no_commas (parser, NULL);
10712 if (c_parser_next_token_is (parser, CPP_COMMA))
10713 expr = convert_lvalue_to_rvalue (tloc, expr, true, false);
10714 while (c_parser_next_token_is (parser, CPP_COMMA))
10715 {
10716 struct c_expr next;
10717 tree lhsval;
10718 location_t loc = c_parser_peek_token (parser)->location;
10719 location_t expr_loc;
10720 c_parser_consume_token (parser);
10721 expr_loc = c_parser_peek_token (parser)->location;
10722 lhsval = expr.value;
10723 while (TREE_CODE (lhsval) == COMPOUND_EXPR
10724 || TREE_CODE (lhsval) == NOP_EXPR)
10725 {
10726 if (TREE_CODE (lhsval) == COMPOUND_EXPR)
10727 lhsval = TREE_OPERAND (lhsval, 1);
10728 else
10729 lhsval = TREE_OPERAND (lhsval, 0);
10730 }
10731 if (DECL_P (lhsval) || handled_component_p (lhsval))
10732 mark_exp_read (lhsval);
10733 next = c_parser_expr_no_commas (parser, NULL);
10734 next = convert_lvalue_to_rvalue (expr_loc, next, true, false);
10735 expr.value = build_compound_expr (loc, expr.value, next.value);
10736 expr.original_code = COMPOUND_EXPR;
10737 expr.original_type = next.original_type;
10738 }
10739 return expr;
10740 }
10741
10742 /* Parse an expression and convert functions or arrays to pointers and
10743 lvalues to rvalues. */
10744
10745 static struct c_expr
c_parser_expression_conv(c_parser * parser)10746 c_parser_expression_conv (c_parser *parser)
10747 {
10748 struct c_expr expr;
10749 location_t loc = c_parser_peek_token (parser)->location;
10750 expr = c_parser_expression (parser);
10751 expr = convert_lvalue_to_rvalue (loc, expr, true, false);
10752 return expr;
10753 }
10754
10755 /* Helper function of c_parser_expr_list. Check if IDXth (0 based)
10756 argument is a literal zero alone and if so, set it in literal_zero_mask. */
10757
10758 static inline void
c_parser_check_literal_zero(c_parser * parser,unsigned * literal_zero_mask,unsigned int idx)10759 c_parser_check_literal_zero (c_parser *parser, unsigned *literal_zero_mask,
10760 unsigned int idx)
10761 {
10762 if (idx >= HOST_BITS_PER_INT)
10763 return;
10764
10765 c_token *tok = c_parser_peek_token (parser);
10766 switch (tok->type)
10767 {
10768 case CPP_NUMBER:
10769 case CPP_CHAR:
10770 case CPP_WCHAR:
10771 case CPP_CHAR16:
10772 case CPP_CHAR32:
10773 case CPP_UTF8CHAR:
10774 /* If a parameter is literal zero alone, remember it
10775 for -Wmemset-transposed-args warning. */
10776 if (integer_zerop (tok->value)
10777 && !TREE_OVERFLOW (tok->value)
10778 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
10779 || c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_PAREN))
10780 *literal_zero_mask |= 1U << idx;
10781 default:
10782 break;
10783 }
10784 }
10785
10786 /* Parse a non-empty list of expressions. If CONVERT_P, convert
10787 functions and arrays to pointers and lvalues to rvalues. If
10788 FOLD_P, fold the expressions. If LOCATIONS is non-NULL, save the
10789 locations of function arguments into this vector.
10790
10791 nonempty-expr-list:
10792 assignment-expression
10793 nonempty-expr-list , assignment-expression
10794 */
10795
10796 static vec<tree, va_gc> *
c_parser_expr_list(c_parser * parser,bool convert_p,bool fold_p,vec<tree,va_gc> ** p_orig_types,location_t * sizeof_arg_loc,tree * sizeof_arg,vec<location_t> * locations,unsigned int * literal_zero_mask)10797 c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p,
10798 vec<tree, va_gc> **p_orig_types,
10799 location_t *sizeof_arg_loc, tree *sizeof_arg,
10800 vec<location_t> *locations,
10801 unsigned int *literal_zero_mask)
10802 {
10803 vec<tree, va_gc> *ret;
10804 vec<tree, va_gc> *orig_types;
10805 struct c_expr expr;
10806 unsigned int idx = 0;
10807
10808 ret = make_tree_vector ();
10809 if (p_orig_types == NULL)
10810 orig_types = NULL;
10811 else
10812 orig_types = make_tree_vector ();
10813
10814 if (literal_zero_mask)
10815 c_parser_check_literal_zero (parser, literal_zero_mask, 0);
10816 expr = c_parser_expr_no_commas (parser, NULL);
10817 if (convert_p)
10818 expr = convert_lvalue_to_rvalue (expr.get_location (), expr, true, true);
10819 if (fold_p)
10820 expr.value = c_fully_fold (expr.value, false, NULL);
10821 ret->quick_push (expr.value);
10822 if (orig_types)
10823 orig_types->quick_push (expr.original_type);
10824 if (locations)
10825 locations->safe_push (expr.get_location ());
10826 if (sizeof_arg != NULL
10827 && (expr.original_code == SIZEOF_EXPR
10828 || expr.original_code == PAREN_SIZEOF_EXPR))
10829 {
10830 sizeof_arg[0] = c_last_sizeof_arg;
10831 sizeof_arg_loc[0] = c_last_sizeof_loc;
10832 }
10833 while (c_parser_next_token_is (parser, CPP_COMMA))
10834 {
10835 c_parser_consume_token (parser);
10836 if (literal_zero_mask)
10837 c_parser_check_literal_zero (parser, literal_zero_mask, idx + 1);
10838 expr = c_parser_expr_no_commas (parser, NULL);
10839 if (convert_p)
10840 expr = convert_lvalue_to_rvalue (expr.get_location (), expr, true,
10841 true);
10842 if (fold_p)
10843 expr.value = c_fully_fold (expr.value, false, NULL);
10844 vec_safe_push (ret, expr.value);
10845 if (orig_types)
10846 vec_safe_push (orig_types, expr.original_type);
10847 if (locations)
10848 locations->safe_push (expr.get_location ());
10849 if (++idx < 3
10850 && sizeof_arg != NULL
10851 && (expr.original_code == SIZEOF_EXPR
10852 || expr.original_code == PAREN_SIZEOF_EXPR))
10853 {
10854 sizeof_arg[idx] = c_last_sizeof_arg;
10855 sizeof_arg_loc[idx] = c_last_sizeof_loc;
10856 }
10857 }
10858 if (orig_types)
10859 *p_orig_types = orig_types;
10860 return ret;
10861 }
10862
10863 /* Parse Objective-C-specific constructs. */
10864
10865 /* Parse an objc-class-definition.
10866
10867 objc-class-definition:
10868 @interface identifier objc-superclass[opt] objc-protocol-refs[opt]
10869 objc-class-instance-variables[opt] objc-methodprotolist @end
10870 @implementation identifier objc-superclass[opt]
10871 objc-class-instance-variables[opt]
10872 @interface identifier ( identifier ) objc-protocol-refs[opt]
10873 objc-methodprotolist @end
10874 @interface identifier ( ) objc-protocol-refs[opt]
10875 objc-methodprotolist @end
10876 @implementation identifier ( identifier )
10877
10878 objc-superclass:
10879 : identifier
10880
10881 "@interface identifier (" must start "@interface identifier (
10882 identifier ) ...": objc-methodprotolist in the first production may
10883 not start with a parenthesized identifier as a declarator of a data
10884 definition with no declaration specifiers if the objc-superclass,
10885 objc-protocol-refs and objc-class-instance-variables are omitted. */
10886
10887 static void
c_parser_objc_class_definition(c_parser * parser,tree attributes)10888 c_parser_objc_class_definition (c_parser *parser, tree attributes)
10889 {
10890 bool iface_p;
10891 tree id1;
10892 tree superclass;
10893 if (c_parser_next_token_is_keyword (parser, RID_AT_INTERFACE))
10894 iface_p = true;
10895 else if (c_parser_next_token_is_keyword (parser, RID_AT_IMPLEMENTATION))
10896 iface_p = false;
10897 else
10898 gcc_unreachable ();
10899
10900 c_parser_consume_token (parser);
10901 if (c_parser_next_token_is_not (parser, CPP_NAME))
10902 {
10903 c_parser_error (parser, "expected identifier");
10904 return;
10905 }
10906 id1 = c_parser_peek_token (parser)->value;
10907 location_t loc1 = c_parser_peek_token (parser)->location;
10908 c_parser_consume_token (parser);
10909 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
10910 {
10911 /* We have a category or class extension. */
10912 tree id2;
10913 tree proto = NULL_TREE;
10914 matching_parens parens;
10915 parens.consume_open (parser);
10916 if (c_parser_next_token_is_not (parser, CPP_NAME))
10917 {
10918 if (iface_p && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
10919 {
10920 /* We have a class extension. */
10921 id2 = NULL_TREE;
10922 }
10923 else
10924 {
10925 c_parser_error (parser, "expected identifier or %<)%>");
10926 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10927 return;
10928 }
10929 }
10930 else
10931 {
10932 id2 = c_parser_peek_token (parser)->value;
10933 c_parser_consume_token (parser);
10934 }
10935 parens.skip_until_found_close (parser);
10936 if (!iface_p)
10937 {
10938 objc_start_category_implementation (id1, id2);
10939 return;
10940 }
10941 if (c_parser_next_token_is (parser, CPP_LESS))
10942 proto = c_parser_objc_protocol_refs (parser);
10943 objc_start_category_interface (id1, id2, proto, attributes);
10944 c_parser_objc_methodprotolist (parser);
10945 c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
10946 objc_finish_interface ();
10947 return;
10948 }
10949 if (c_parser_next_token_is (parser, CPP_COLON))
10950 {
10951 c_parser_consume_token (parser);
10952 if (c_parser_next_token_is_not (parser, CPP_NAME))
10953 {
10954 c_parser_error (parser, "expected identifier");
10955 return;
10956 }
10957 superclass = c_parser_peek_token (parser)->value;
10958 c_parser_consume_token (parser);
10959 }
10960 else
10961 superclass = NULL_TREE;
10962 if (iface_p)
10963 {
10964 tree proto = NULL_TREE;
10965 if (c_parser_next_token_is (parser, CPP_LESS))
10966 proto = c_parser_objc_protocol_refs (parser);
10967 objc_start_class_interface (id1, loc1, superclass, proto, attributes);
10968 }
10969 else
10970 objc_start_class_implementation (id1, superclass);
10971 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
10972 c_parser_objc_class_instance_variables (parser);
10973 if (iface_p)
10974 {
10975 objc_continue_interface ();
10976 c_parser_objc_methodprotolist (parser);
10977 c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
10978 objc_finish_interface ();
10979 }
10980 else
10981 {
10982 objc_continue_implementation ();
10983 return;
10984 }
10985 }
10986
10987 /* Parse objc-class-instance-variables.
10988
10989 objc-class-instance-variables:
10990 { objc-instance-variable-decl-list[opt] }
10991
10992 objc-instance-variable-decl-list:
10993 objc-visibility-spec
10994 objc-instance-variable-decl ;
10995 ;
10996 objc-instance-variable-decl-list objc-visibility-spec
10997 objc-instance-variable-decl-list objc-instance-variable-decl ;
10998 objc-instance-variable-decl-list ;
10999
11000 objc-visibility-spec:
11001 @private
11002 @protected
11003 @public
11004
11005 objc-instance-variable-decl:
11006 struct-declaration
11007 */
11008
11009 static void
c_parser_objc_class_instance_variables(c_parser * parser)11010 c_parser_objc_class_instance_variables (c_parser *parser)
11011 {
11012 gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE));
11013 c_parser_consume_token (parser);
11014 while (c_parser_next_token_is_not (parser, CPP_EOF))
11015 {
11016 tree decls;
11017 /* Parse any stray semicolon. */
11018 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
11019 {
11020 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
11021 "extra semicolon");
11022 c_parser_consume_token (parser);
11023 continue;
11024 }
11025 /* Stop if at the end of the instance variables. */
11026 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
11027 {
11028 c_parser_consume_token (parser);
11029 break;
11030 }
11031 /* Parse any objc-visibility-spec. */
11032 if (c_parser_next_token_is_keyword (parser, RID_AT_PRIVATE))
11033 {
11034 c_parser_consume_token (parser);
11035 objc_set_visibility (OBJC_IVAR_VIS_PRIVATE);
11036 continue;
11037 }
11038 else if (c_parser_next_token_is_keyword (parser, RID_AT_PROTECTED))
11039 {
11040 c_parser_consume_token (parser);
11041 objc_set_visibility (OBJC_IVAR_VIS_PROTECTED);
11042 continue;
11043 }
11044 else if (c_parser_next_token_is_keyword (parser, RID_AT_PUBLIC))
11045 {
11046 c_parser_consume_token (parser);
11047 objc_set_visibility (OBJC_IVAR_VIS_PUBLIC);
11048 continue;
11049 }
11050 else if (c_parser_next_token_is_keyword (parser, RID_AT_PACKAGE))
11051 {
11052 c_parser_consume_token (parser);
11053 objc_set_visibility (OBJC_IVAR_VIS_PACKAGE);
11054 continue;
11055 }
11056 else if (c_parser_next_token_is (parser, CPP_PRAGMA))
11057 {
11058 c_parser_pragma (parser, pragma_external, NULL);
11059 continue;
11060 }
11061
11062 /* Parse some comma-separated declarations. */
11063 decls = c_parser_struct_declaration (parser);
11064 if (decls == NULL)
11065 {
11066 /* There is a syntax error. We want to skip the offending
11067 tokens up to the next ';' (included) or '}'
11068 (excluded). */
11069
11070 /* First, skip manually a ')' or ']'. This is because they
11071 reduce the nesting level, so c_parser_skip_until_found()
11072 wouldn't be able to skip past them. */
11073 c_token *token = c_parser_peek_token (parser);
11074 if (token->type == CPP_CLOSE_PAREN || token->type == CPP_CLOSE_SQUARE)
11075 c_parser_consume_token (parser);
11076
11077 /* Then, do the standard skipping. */
11078 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11079
11080 /* We hopefully recovered. Start normal parsing again. */
11081 parser->error = false;
11082 continue;
11083 }
11084 else
11085 {
11086 /* Comma-separated instance variables are chained together
11087 in reverse order; add them one by one. */
11088 tree ivar = nreverse (decls);
11089 for (; ivar; ivar = DECL_CHAIN (ivar))
11090 objc_add_instance_variable (copy_node (ivar));
11091 }
11092 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11093 }
11094 }
11095
11096 /* Parse an objc-class-declaration.
11097
11098 objc-class-declaration:
11099 @class identifier-list ;
11100 */
11101
11102 static void
c_parser_objc_class_declaration(c_parser * parser)11103 c_parser_objc_class_declaration (c_parser *parser)
11104 {
11105 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_CLASS));
11106 c_parser_consume_token (parser);
11107 /* Any identifiers, including those declared as type names, are OK
11108 here. */
11109 while (true)
11110 {
11111 tree id;
11112 if (c_parser_next_token_is_not (parser, CPP_NAME))
11113 {
11114 c_parser_error (parser, "expected identifier");
11115 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11116 parser->error = false;
11117 return;
11118 }
11119 id = c_parser_peek_token (parser)->value;
11120 objc_declare_class (id);
11121 c_parser_consume_token (parser);
11122 if (c_parser_next_token_is (parser, CPP_COMMA))
11123 c_parser_consume_token (parser);
11124 else
11125 break;
11126 }
11127 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11128 }
11129
11130 /* Parse an objc-alias-declaration.
11131
11132 objc-alias-declaration:
11133 @compatibility_alias identifier identifier ;
11134 */
11135
11136 static void
c_parser_objc_alias_declaration(c_parser * parser)11137 c_parser_objc_alias_declaration (c_parser *parser)
11138 {
11139 tree id1, id2;
11140 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_ALIAS));
11141 c_parser_consume_token (parser);
11142 if (c_parser_next_token_is_not (parser, CPP_NAME))
11143 {
11144 c_parser_error (parser, "expected identifier");
11145 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11146 return;
11147 }
11148 id1 = c_parser_peek_token (parser)->value;
11149 c_parser_consume_token (parser);
11150 if (c_parser_next_token_is_not (parser, CPP_NAME))
11151 {
11152 c_parser_error (parser, "expected identifier");
11153 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11154 return;
11155 }
11156 id2 = c_parser_peek_token (parser)->value;
11157 c_parser_consume_token (parser);
11158 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11159 objc_declare_alias (id1, id2);
11160 }
11161
11162 /* Parse an objc-protocol-definition.
11163
11164 objc-protocol-definition:
11165 @protocol identifier objc-protocol-refs[opt] objc-methodprotolist @end
11166 @protocol identifier-list ;
11167
11168 "@protocol identifier ;" should be resolved as "@protocol
11169 identifier-list ;": objc-methodprotolist may not start with a
11170 semicolon in the first alternative if objc-protocol-refs are
11171 omitted. */
11172
11173 static void
c_parser_objc_protocol_definition(c_parser * parser,tree attributes)11174 c_parser_objc_protocol_definition (c_parser *parser, tree attributes)
11175 {
11176 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_PROTOCOL));
11177
11178 c_parser_consume_token (parser);
11179 if (c_parser_next_token_is_not (parser, CPP_NAME))
11180 {
11181 c_parser_error (parser, "expected identifier");
11182 return;
11183 }
11184 if (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
11185 || c_parser_peek_2nd_token (parser)->type == CPP_SEMICOLON)
11186 {
11187 /* Any identifiers, including those declared as type names, are
11188 OK here. */
11189 while (true)
11190 {
11191 tree id;
11192 if (c_parser_next_token_is_not (parser, CPP_NAME))
11193 {
11194 c_parser_error (parser, "expected identifier");
11195 break;
11196 }
11197 id = c_parser_peek_token (parser)->value;
11198 objc_declare_protocol (id, attributes);
11199 c_parser_consume_token (parser);
11200 if (c_parser_next_token_is (parser, CPP_COMMA))
11201 c_parser_consume_token (parser);
11202 else
11203 break;
11204 }
11205 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11206 }
11207 else
11208 {
11209 tree id = c_parser_peek_token (parser)->value;
11210 tree proto = NULL_TREE;
11211 c_parser_consume_token (parser);
11212 if (c_parser_next_token_is (parser, CPP_LESS))
11213 proto = c_parser_objc_protocol_refs (parser);
11214 parser->objc_pq_context = true;
11215 objc_start_protocol (id, proto, attributes);
11216 c_parser_objc_methodprotolist (parser);
11217 c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
11218 parser->objc_pq_context = false;
11219 objc_finish_interface ();
11220 }
11221 }
11222
11223 /* Parse an objc-method-type.
11224
11225 objc-method-type:
11226 +
11227 -
11228
11229 Return true if it is a class method (+) and false if it is
11230 an instance method (-).
11231 */
11232 static inline bool
c_parser_objc_method_type(c_parser * parser)11233 c_parser_objc_method_type (c_parser *parser)
11234 {
11235 switch (c_parser_peek_token (parser)->type)
11236 {
11237 case CPP_PLUS:
11238 c_parser_consume_token (parser);
11239 return true;
11240 case CPP_MINUS:
11241 c_parser_consume_token (parser);
11242 return false;
11243 default:
11244 gcc_unreachable ();
11245 }
11246 }
11247
11248 /* Parse an objc-method-definition.
11249
11250 objc-method-definition:
11251 objc-method-type objc-method-decl ;[opt] compound-statement
11252 */
11253
11254 static void
c_parser_objc_method_definition(c_parser * parser)11255 c_parser_objc_method_definition (c_parser *parser)
11256 {
11257 bool is_class_method = c_parser_objc_method_type (parser);
11258 tree decl, attributes = NULL_TREE, expr = NULL_TREE;
11259 parser->objc_pq_context = true;
11260 decl = c_parser_objc_method_decl (parser, is_class_method, &attributes,
11261 &expr);
11262 if (decl == error_mark_node)
11263 return; /* Bail here. */
11264
11265 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
11266 {
11267 c_parser_consume_token (parser);
11268 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
11269 "extra semicolon in method definition specified");
11270 }
11271
11272 if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE))
11273 {
11274 c_parser_error (parser, "expected %<{%>");
11275 return;
11276 }
11277
11278 parser->objc_pq_context = false;
11279 if (objc_start_method_definition (is_class_method, decl, attributes, expr))
11280 {
11281 add_stmt (c_parser_compound_statement (parser));
11282 objc_finish_method_definition (current_function_decl);
11283 }
11284 else
11285 {
11286 /* This code is executed when we find a method definition
11287 outside of an @implementation context (or invalid for other
11288 reasons). Parse the method (to keep going) but do not emit
11289 any code.
11290 */
11291 c_parser_compound_statement (parser);
11292 }
11293 }
11294
11295 /* Parse an objc-methodprotolist.
11296
11297 objc-methodprotolist:
11298 empty
11299 objc-methodprotolist objc-methodproto
11300 objc-methodprotolist declaration
11301 objc-methodprotolist ;
11302 @optional
11303 @required
11304
11305 The declaration is a data definition, which may be missing
11306 declaration specifiers under the same rules and diagnostics as
11307 other data definitions outside functions, and the stray semicolon
11308 is diagnosed the same way as a stray semicolon outside a
11309 function. */
11310
11311 static void
c_parser_objc_methodprotolist(c_parser * parser)11312 c_parser_objc_methodprotolist (c_parser *parser)
11313 {
11314 while (true)
11315 {
11316 /* The list is terminated by @end. */
11317 switch (c_parser_peek_token (parser)->type)
11318 {
11319 case CPP_SEMICOLON:
11320 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
11321 "ISO C does not allow extra %<;%> outside of a function");
11322 c_parser_consume_token (parser);
11323 break;
11324 case CPP_PLUS:
11325 case CPP_MINUS:
11326 c_parser_objc_methodproto (parser);
11327 break;
11328 case CPP_PRAGMA:
11329 c_parser_pragma (parser, pragma_external, NULL);
11330 break;
11331 case CPP_EOF:
11332 return;
11333 default:
11334 if (c_parser_next_token_is_keyword (parser, RID_AT_END))
11335 return;
11336 else if (c_parser_next_token_is_keyword (parser, RID_AT_PROPERTY))
11337 c_parser_objc_at_property_declaration (parser);
11338 else if (c_parser_next_token_is_keyword (parser, RID_AT_OPTIONAL))
11339 {
11340 objc_set_method_opt (true);
11341 c_parser_consume_token (parser);
11342 }
11343 else if (c_parser_next_token_is_keyword (parser, RID_AT_REQUIRED))
11344 {
11345 objc_set_method_opt (false);
11346 c_parser_consume_token (parser);
11347 }
11348 else
11349 c_parser_declaration_or_fndef (parser, false, false, true,
11350 false, true);
11351 break;
11352 }
11353 }
11354 }
11355
11356 /* Parse an objc-methodproto.
11357
11358 objc-methodproto:
11359 objc-method-type objc-method-decl ;
11360 */
11361
11362 static void
c_parser_objc_methodproto(c_parser * parser)11363 c_parser_objc_methodproto (c_parser *parser)
11364 {
11365 bool is_class_method = c_parser_objc_method_type (parser);
11366 tree decl, attributes = NULL_TREE;
11367
11368 /* Remember protocol qualifiers in prototypes. */
11369 parser->objc_pq_context = true;
11370 decl = c_parser_objc_method_decl (parser, is_class_method, &attributes,
11371 NULL);
11372 /* Forget protocol qualifiers now. */
11373 parser->objc_pq_context = false;
11374
11375 /* Do not allow the presence of attributes to hide an erroneous
11376 method implementation in the interface section. */
11377 if (!c_parser_next_token_is (parser, CPP_SEMICOLON))
11378 {
11379 c_parser_error (parser, "expected %<;%>");
11380 return;
11381 }
11382
11383 if (decl != error_mark_node)
11384 objc_add_method_declaration (is_class_method, decl, attributes);
11385
11386 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11387 }
11388
11389 /* If we are at a position that method attributes may be present, check that
11390 there are not any parsed already (a syntax error) and then collect any
11391 specified at the current location. Finally, if new attributes were present,
11392 check that the next token is legal ( ';' for decls and '{' for defs). */
11393
11394 static bool
c_parser_objc_maybe_method_attributes(c_parser * parser,tree * attributes)11395 c_parser_objc_maybe_method_attributes (c_parser* parser, tree* attributes)
11396 {
11397 bool bad = false;
11398 if (*attributes)
11399 {
11400 c_parser_error (parser,
11401 "method attributes must be specified at the end only");
11402 *attributes = NULL_TREE;
11403 bad = true;
11404 }
11405
11406 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
11407 *attributes = c_parser_gnu_attributes (parser);
11408
11409 /* If there were no attributes here, just report any earlier error. */
11410 if (*attributes == NULL_TREE || bad)
11411 return bad;
11412
11413 /* If the attributes are followed by a ; or {, then just report any earlier
11414 error. */
11415 if (c_parser_next_token_is (parser, CPP_SEMICOLON)
11416 || c_parser_next_token_is (parser, CPP_OPEN_BRACE))
11417 return bad;
11418
11419 /* We've got attributes, but not at the end. */
11420 c_parser_error (parser,
11421 "expected %<;%> or %<{%> after method attribute definition");
11422 return true;
11423 }
11424
11425 /* Parse an objc-method-decl.
11426
11427 objc-method-decl:
11428 ( objc-type-name ) objc-selector
11429 objc-selector
11430 ( objc-type-name ) objc-keyword-selector objc-optparmlist
11431 objc-keyword-selector objc-optparmlist
11432 gnu-attributes
11433
11434 objc-keyword-selector:
11435 objc-keyword-decl
11436 objc-keyword-selector objc-keyword-decl
11437
11438 objc-keyword-decl:
11439 objc-selector : ( objc-type-name ) identifier
11440 objc-selector : identifier
11441 : ( objc-type-name ) identifier
11442 : identifier
11443
11444 objc-optparmlist:
11445 objc-optparms objc-optellipsis
11446
11447 objc-optparms:
11448 empty
11449 objc-opt-parms , parameter-declaration
11450
11451 objc-optellipsis:
11452 empty
11453 , ...
11454 */
11455
11456 static tree
c_parser_objc_method_decl(c_parser * parser,bool is_class_method,tree * attributes,tree * expr)11457 c_parser_objc_method_decl (c_parser *parser, bool is_class_method,
11458 tree *attributes, tree *expr)
11459 {
11460 tree type = NULL_TREE;
11461 tree sel;
11462 tree parms = NULL_TREE;
11463 bool ellipsis = false;
11464 bool attr_err = false;
11465
11466 *attributes = NULL_TREE;
11467 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
11468 {
11469 matching_parens parens;
11470 parens.consume_open (parser);
11471 type = c_parser_objc_type_name (parser);
11472 parens.skip_until_found_close (parser);
11473 }
11474 sel = c_parser_objc_selector (parser);
11475 /* If there is no selector, or a colon follows, we have an
11476 objc-keyword-selector. If there is a selector, and a colon does
11477 not follow, that selector ends the objc-method-decl. */
11478 if (!sel || c_parser_next_token_is (parser, CPP_COLON))
11479 {
11480 tree tsel = sel;
11481 tree list = NULL_TREE;
11482 while (true)
11483 {
11484 tree atype = NULL_TREE, id, keyworddecl;
11485 tree param_attr = NULL_TREE;
11486 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
11487 break;
11488 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
11489 {
11490 c_parser_consume_token (parser);
11491 atype = c_parser_objc_type_name (parser);
11492 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
11493 "expected %<)%>");
11494 }
11495 /* New ObjC allows attributes on method parameters. */
11496 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
11497 param_attr = c_parser_gnu_attributes (parser);
11498 if (c_parser_next_token_is_not (parser, CPP_NAME))
11499 {
11500 c_parser_error (parser, "expected identifier");
11501 return error_mark_node;
11502 }
11503 id = c_parser_peek_token (parser)->value;
11504 c_parser_consume_token (parser);
11505 keyworddecl = objc_build_keyword_decl (tsel, atype, id, param_attr);
11506 list = chainon (list, keyworddecl);
11507 tsel = c_parser_objc_selector (parser);
11508 if (!tsel && c_parser_next_token_is_not (parser, CPP_COLON))
11509 break;
11510 }
11511
11512 attr_err |= c_parser_objc_maybe_method_attributes (parser, attributes) ;
11513
11514 /* Parse the optional parameter list. Optional Objective-C
11515 method parameters follow the C syntax, and may include '...'
11516 to denote a variable number of arguments. */
11517 parms = make_node (TREE_LIST);
11518 while (c_parser_next_token_is (parser, CPP_COMMA))
11519 {
11520 struct c_parm *parm;
11521 c_parser_consume_token (parser);
11522 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
11523 {
11524 ellipsis = true;
11525 c_parser_consume_token (parser);
11526 attr_err |= c_parser_objc_maybe_method_attributes
11527 (parser, attributes) ;
11528 break;
11529 }
11530 parm = c_parser_parameter_declaration (parser, NULL_TREE, false);
11531 if (parm == NULL)
11532 break;
11533 parms = chainon (parms,
11534 build_tree_list (NULL_TREE, grokparm (parm, expr)));
11535 }
11536 sel = list;
11537 }
11538 else
11539 attr_err |= c_parser_objc_maybe_method_attributes (parser, attributes) ;
11540
11541 if (sel == NULL)
11542 {
11543 c_parser_error (parser, "objective-c method declaration is expected");
11544 return error_mark_node;
11545 }
11546
11547 if (attr_err)
11548 return error_mark_node;
11549
11550 return objc_build_method_signature (is_class_method, type, sel, parms, ellipsis);
11551 }
11552
11553 /* Parse an objc-type-name.
11554
11555 objc-type-name:
11556 objc-type-qualifiers[opt] type-name
11557 objc-type-qualifiers[opt]
11558
11559 objc-type-qualifiers:
11560 objc-type-qualifier
11561 objc-type-qualifiers objc-type-qualifier
11562
11563 objc-type-qualifier: one of
11564 in out inout bycopy byref oneway
11565 */
11566
11567 static tree
c_parser_objc_type_name(c_parser * parser)11568 c_parser_objc_type_name (c_parser *parser)
11569 {
11570 tree quals = NULL_TREE;
11571 struct c_type_name *type_name = NULL;
11572 tree type = NULL_TREE;
11573 while (true)
11574 {
11575 c_token *token = c_parser_peek_token (parser);
11576 if (token->type == CPP_KEYWORD
11577 && (token->keyword == RID_IN
11578 || token->keyword == RID_OUT
11579 || token->keyword == RID_INOUT
11580 || token->keyword == RID_BYCOPY
11581 || token->keyword == RID_BYREF
11582 || token->keyword == RID_ONEWAY))
11583 {
11584 quals = chainon (build_tree_list (NULL_TREE, token->value), quals);
11585 c_parser_consume_token (parser);
11586 }
11587 else
11588 break;
11589 }
11590 if (c_parser_next_tokens_start_typename (parser, cla_prefer_type))
11591 type_name = c_parser_type_name (parser);
11592 if (type_name)
11593 type = groktypename (type_name, NULL, NULL);
11594
11595 /* If the type is unknown, and error has already been produced and
11596 we need to recover from the error. In that case, use NULL_TREE
11597 for the type, as if no type had been specified; this will use the
11598 default type ('id') which is good for error recovery. */
11599 if (type == error_mark_node)
11600 type = NULL_TREE;
11601
11602 return build_tree_list (quals, type);
11603 }
11604
11605 /* Parse objc-protocol-refs.
11606
11607 objc-protocol-refs:
11608 < identifier-list >
11609 */
11610
11611 static tree
c_parser_objc_protocol_refs(c_parser * parser)11612 c_parser_objc_protocol_refs (c_parser *parser)
11613 {
11614 tree list = NULL_TREE;
11615 gcc_assert (c_parser_next_token_is (parser, CPP_LESS));
11616 c_parser_consume_token (parser);
11617 /* Any identifiers, including those declared as type names, are OK
11618 here. */
11619 while (true)
11620 {
11621 tree id;
11622 if (c_parser_next_token_is_not (parser, CPP_NAME))
11623 {
11624 c_parser_error (parser, "expected identifier");
11625 break;
11626 }
11627 id = c_parser_peek_token (parser)->value;
11628 list = chainon (list, build_tree_list (NULL_TREE, id));
11629 c_parser_consume_token (parser);
11630 if (c_parser_next_token_is (parser, CPP_COMMA))
11631 c_parser_consume_token (parser);
11632 else
11633 break;
11634 }
11635 c_parser_require (parser, CPP_GREATER, "expected %<>%>");
11636 return list;
11637 }
11638
11639 /* Parse an objc-try-catch-finally-statement.
11640
11641 objc-try-catch-finally-statement:
11642 @try compound-statement objc-catch-list[opt]
11643 @try compound-statement objc-catch-list[opt] @finally compound-statement
11644
11645 objc-catch-list:
11646 @catch ( objc-catch-parameter-declaration ) compound-statement
11647 objc-catch-list @catch ( objc-catch-parameter-declaration ) compound-statement
11648
11649 objc-catch-parameter-declaration:
11650 parameter-declaration
11651 '...'
11652
11653 where '...' is to be interpreted literally, that is, it means CPP_ELLIPSIS.
11654
11655 PS: This function is identical to cp_parser_objc_try_catch_finally_statement
11656 for C++. Keep them in sync. */
11657
11658 static void
c_parser_objc_try_catch_finally_statement(c_parser * parser)11659 c_parser_objc_try_catch_finally_statement (c_parser *parser)
11660 {
11661 location_t location;
11662 tree stmt;
11663
11664 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_TRY));
11665 c_parser_consume_token (parser);
11666 location = c_parser_peek_token (parser)->location;
11667 objc_maybe_warn_exceptions (location);
11668 stmt = c_parser_compound_statement (parser);
11669 objc_begin_try_stmt (location, stmt);
11670
11671 while (c_parser_next_token_is_keyword (parser, RID_AT_CATCH))
11672 {
11673 struct c_parm *parm;
11674 tree parameter_declaration = error_mark_node;
11675 bool seen_open_paren = false;
11676
11677 c_parser_consume_token (parser);
11678 matching_parens parens;
11679 if (!parens.require_open (parser))
11680 seen_open_paren = true;
11681 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
11682 {
11683 /* We have "@catch (...)" (where the '...' are literally
11684 what is in the code). Skip the '...'.
11685 parameter_declaration is set to NULL_TREE, and
11686 objc_being_catch_clauses() knows that that means
11687 '...'. */
11688 c_parser_consume_token (parser);
11689 parameter_declaration = NULL_TREE;
11690 }
11691 else
11692 {
11693 /* We have "@catch (NSException *exception)" or something
11694 like that. Parse the parameter declaration. */
11695 parm = c_parser_parameter_declaration (parser, NULL_TREE, false);
11696 if (parm == NULL)
11697 parameter_declaration = error_mark_node;
11698 else
11699 parameter_declaration = grokparm (parm, NULL);
11700 }
11701 if (seen_open_paren)
11702 parens.require_close (parser);
11703 else
11704 {
11705 /* If there was no open parenthesis, we are recovering from
11706 an error, and we are trying to figure out what mistake
11707 the user has made. */
11708
11709 /* If there is an immediate closing parenthesis, the user
11710 probably forgot the opening one (ie, they typed "@catch
11711 NSException *e)". Parse the closing parenthesis and keep
11712 going. */
11713 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
11714 c_parser_consume_token (parser);
11715
11716 /* If these is no immediate closing parenthesis, the user
11717 probably doesn't know that parenthesis are required at
11718 all (ie, they typed "@catch NSException *e"). So, just
11719 forget about the closing parenthesis and keep going. */
11720 }
11721 objc_begin_catch_clause (parameter_declaration);
11722 if (c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
11723 c_parser_compound_statement_nostart (parser);
11724 objc_finish_catch_clause ();
11725 }
11726 if (c_parser_next_token_is_keyword (parser, RID_AT_FINALLY))
11727 {
11728 c_parser_consume_token (parser);
11729 location = c_parser_peek_token (parser)->location;
11730 stmt = c_parser_compound_statement (parser);
11731 objc_build_finally_clause (location, stmt);
11732 }
11733 objc_finish_try_stmt ();
11734 }
11735
11736 /* Parse an objc-synchronized-statement.
11737
11738 objc-synchronized-statement:
11739 @synchronized ( expression ) compound-statement
11740 */
11741
11742 static void
c_parser_objc_synchronized_statement(c_parser * parser)11743 c_parser_objc_synchronized_statement (c_parser *parser)
11744 {
11745 location_t loc;
11746 tree expr, stmt;
11747 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_SYNCHRONIZED));
11748 c_parser_consume_token (parser);
11749 loc = c_parser_peek_token (parser)->location;
11750 objc_maybe_warn_exceptions (loc);
11751 matching_parens parens;
11752 if (parens.require_open (parser))
11753 {
11754 struct c_expr ce = c_parser_expression (parser);
11755 ce = convert_lvalue_to_rvalue (loc, ce, false, false);
11756 expr = ce.value;
11757 expr = c_fully_fold (expr, false, NULL);
11758 parens.skip_until_found_close (parser);
11759 }
11760 else
11761 expr = error_mark_node;
11762 stmt = c_parser_compound_statement (parser);
11763 objc_build_synchronized (loc, expr, stmt);
11764 }
11765
11766 /* Parse an objc-selector; return NULL_TREE without an error if the
11767 next token is not an objc-selector.
11768
11769 objc-selector:
11770 identifier
11771 one of
11772 enum struct union if else while do for switch case default
11773 break continue return goto asm sizeof typeof __alignof
11774 unsigned long const short volatile signed restrict _Complex
11775 in out inout bycopy byref oneway int char float double void _Bool
11776 _Atomic
11777
11778 ??? Why this selection of keywords but not, for example, storage
11779 class specifiers? */
11780
11781 static tree
c_parser_objc_selector(c_parser * parser)11782 c_parser_objc_selector (c_parser *parser)
11783 {
11784 c_token *token = c_parser_peek_token (parser);
11785 tree value = token->value;
11786 if (token->type == CPP_NAME)
11787 {
11788 c_parser_consume_token (parser);
11789 return value;
11790 }
11791 if (token->type != CPP_KEYWORD)
11792 return NULL_TREE;
11793 switch (token->keyword)
11794 {
11795 case RID_ENUM:
11796 case RID_STRUCT:
11797 case RID_UNION:
11798 case RID_IF:
11799 case RID_ELSE:
11800 case RID_WHILE:
11801 case RID_DO:
11802 case RID_FOR:
11803 case RID_SWITCH:
11804 case RID_CASE:
11805 case RID_DEFAULT:
11806 case RID_BREAK:
11807 case RID_CONTINUE:
11808 case RID_RETURN:
11809 case RID_GOTO:
11810 case RID_ASM:
11811 case RID_SIZEOF:
11812 case RID_TYPEOF:
11813 case RID_ALIGNOF:
11814 case RID_UNSIGNED:
11815 case RID_LONG:
11816 case RID_CONST:
11817 case RID_SHORT:
11818 case RID_VOLATILE:
11819 case RID_SIGNED:
11820 case RID_RESTRICT:
11821 case RID_COMPLEX:
11822 case RID_IN:
11823 case RID_OUT:
11824 case RID_INOUT:
11825 case RID_BYCOPY:
11826 case RID_BYREF:
11827 case RID_ONEWAY:
11828 case RID_INT:
11829 case RID_CHAR:
11830 case RID_FLOAT:
11831 case RID_DOUBLE:
11832 CASE_RID_FLOATN_NX:
11833 case RID_VOID:
11834 case RID_BOOL:
11835 case RID_ATOMIC:
11836 case RID_AUTO_TYPE:
11837 case RID_INT_N_0:
11838 case RID_INT_N_1:
11839 case RID_INT_N_2:
11840 case RID_INT_N_3:
11841 c_parser_consume_token (parser);
11842 return value;
11843 default:
11844 return NULL_TREE;
11845 }
11846 }
11847
11848 /* Parse an objc-selector-arg.
11849
11850 objc-selector-arg:
11851 objc-selector
11852 objc-keywordname-list
11853
11854 objc-keywordname-list:
11855 objc-keywordname
11856 objc-keywordname-list objc-keywordname
11857
11858 objc-keywordname:
11859 objc-selector :
11860 :
11861 */
11862
11863 static tree
c_parser_objc_selector_arg(c_parser * parser)11864 c_parser_objc_selector_arg (c_parser *parser)
11865 {
11866 tree sel = c_parser_objc_selector (parser);
11867 tree list = NULL_TREE;
11868 if (sel
11869 && c_parser_next_token_is_not (parser, CPP_COLON)
11870 && c_parser_next_token_is_not (parser, CPP_SCOPE))
11871 return sel;
11872 while (true)
11873 {
11874 if (c_parser_next_token_is (parser, CPP_SCOPE))
11875 {
11876 c_parser_consume_token (parser);
11877 list = chainon (list, build_tree_list (sel, NULL_TREE));
11878 list = chainon (list, build_tree_list (NULL_TREE, NULL_TREE));
11879 }
11880 else
11881 {
11882 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
11883 return list;
11884 list = chainon (list, build_tree_list (sel, NULL_TREE));
11885 }
11886 sel = c_parser_objc_selector (parser);
11887 if (!sel
11888 && c_parser_next_token_is_not (parser, CPP_COLON)
11889 && c_parser_next_token_is_not (parser, CPP_SCOPE))
11890 break;
11891 }
11892 return list;
11893 }
11894
11895 /* Parse an objc-receiver.
11896
11897 objc-receiver:
11898 expression
11899 class-name
11900 type-name
11901 */
11902
11903 static tree
c_parser_objc_receiver(c_parser * parser)11904 c_parser_objc_receiver (c_parser *parser)
11905 {
11906 location_t loc = c_parser_peek_token (parser)->location;
11907
11908 if (c_parser_peek_token (parser)->type == CPP_NAME
11909 && (c_parser_peek_token (parser)->id_kind == C_ID_TYPENAME
11910 || c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME))
11911 {
11912 tree id = c_parser_peek_token (parser)->value;
11913 c_parser_consume_token (parser);
11914 return objc_get_class_reference (id);
11915 }
11916 struct c_expr ce = c_parser_expression (parser);
11917 ce = convert_lvalue_to_rvalue (loc, ce, false, false);
11918 return c_fully_fold (ce.value, false, NULL);
11919 }
11920
11921 /* Parse objc-message-args.
11922
11923 objc-message-args:
11924 objc-selector
11925 objc-keywordarg-list
11926
11927 objc-keywordarg-list:
11928 objc-keywordarg
11929 objc-keywordarg-list objc-keywordarg
11930
11931 objc-keywordarg:
11932 objc-selector : objc-keywordexpr
11933 : objc-keywordexpr
11934 */
11935
11936 static tree
c_parser_objc_message_args(c_parser * parser)11937 c_parser_objc_message_args (c_parser *parser)
11938 {
11939 tree sel = c_parser_objc_selector (parser);
11940 tree list = NULL_TREE;
11941 if (sel && c_parser_next_token_is_not (parser, CPP_COLON))
11942 return sel;
11943 while (true)
11944 {
11945 tree keywordexpr;
11946 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
11947 return error_mark_node;
11948 keywordexpr = c_parser_objc_keywordexpr (parser);
11949 list = chainon (list, build_tree_list (sel, keywordexpr));
11950 sel = c_parser_objc_selector (parser);
11951 if (!sel && c_parser_next_token_is_not (parser, CPP_COLON))
11952 break;
11953 }
11954 return list;
11955 }
11956
11957 /* Parse an objc-keywordexpr.
11958
11959 objc-keywordexpr:
11960 nonempty-expr-list
11961 */
11962
11963 static tree
c_parser_objc_keywordexpr(c_parser * parser)11964 c_parser_objc_keywordexpr (c_parser *parser)
11965 {
11966 tree ret;
11967 vec<tree, va_gc> *expr_list = c_parser_expr_list (parser, true, true,
11968 NULL, NULL, NULL, NULL);
11969 if (vec_safe_length (expr_list) == 1)
11970 {
11971 /* Just return the expression, remove a level of
11972 indirection. */
11973 ret = (*expr_list)[0];
11974 }
11975 else
11976 {
11977 /* We have a comma expression, we will collapse later. */
11978 ret = build_tree_list_vec (expr_list);
11979 }
11980 release_tree_vector (expr_list);
11981 return ret;
11982 }
11983
11984 /* A check, needed in several places, that ObjC interface, implementation or
11985 method definitions are not prefixed by incorrect items. */
11986 static bool
c_parser_objc_diagnose_bad_element_prefix(c_parser * parser,struct c_declspecs * specs)11987 c_parser_objc_diagnose_bad_element_prefix (c_parser *parser,
11988 struct c_declspecs *specs)
11989 {
11990 if (!specs->declspecs_seen_p || specs->non_sc_seen_p
11991 || specs->typespec_kind != ctsk_none)
11992 {
11993 c_parser_error (parser,
11994 "no type or storage class may be specified here,");
11995 c_parser_skip_to_end_of_block_or_statement (parser);
11996 return true;
11997 }
11998 return false;
11999 }
12000
12001 /* Parse an Objective-C @property declaration. The syntax is:
12002
12003 objc-property-declaration:
12004 '@property' objc-property-attributes[opt] struct-declaration ;
12005
12006 objc-property-attributes:
12007 '(' objc-property-attribute-list ')'
12008
12009 objc-property-attribute-list:
12010 objc-property-attribute
12011 objc-property-attribute-list, objc-property-attribute
12012
12013 objc-property-attribute
12014 'getter' = identifier
12015 'setter' = identifier
12016 'readonly'
12017 'readwrite'
12018 'assign'
12019 'retain'
12020 'copy'
12021 'nonatomic'
12022
12023 For example:
12024 @property NSString *name;
12025 @property (readonly) id object;
12026 @property (retain, nonatomic, getter=getTheName) id name;
12027 @property int a, b, c;
12028
12029 PS: This function is identical to cp_parser_objc_at_propery_declaration
12030 for C++. Keep them in sync. */
12031 static void
c_parser_objc_at_property_declaration(c_parser * parser)12032 c_parser_objc_at_property_declaration (c_parser *parser)
12033 {
12034 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_PROPERTY));
12035 location_t loc = c_parser_peek_token (parser)->location;
12036 c_parser_consume_token (parser); /* Eat '@property'. */
12037
12038 /* Parse the optional attribute list.
12039
12040 A list of parsed, but not verified, attributes. */
12041 vec<property_attribute_info *> prop_attr_list = vNULL;
12042
12043 bool syntax_error = false;
12044 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
12045 {
12046 matching_parens parens;
12047
12048 location_t attr_start = c_parser_peek_token (parser)->location;
12049 /* Eat the '(' */
12050 parens.consume_open (parser);
12051
12052 /* Property attribute keywords are valid now. */
12053 parser->objc_property_attr_context = true;
12054
12055 /* Allow @property (), with a warning. */
12056 location_t attr_end = c_parser_peek_token (parser)->location;
12057
12058 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
12059 {
12060 location_t attr_comb = make_location (attr_end, attr_start, attr_end);
12061 warning_at (attr_comb, OPT_Wattributes,
12062 "empty property attribute list");
12063 }
12064 else
12065 while (true)
12066 {
12067 c_token *token = c_parser_peek_token (parser);
12068 attr_start = token->location;
12069 attr_end = get_finish (token->location);
12070 location_t attr_comb = make_location (attr_start, attr_start,
12071 attr_end);
12072
12073 if (token->type == CPP_CLOSE_PAREN || token->type == CPP_COMMA)
12074 {
12075 warning_at (attr_comb, OPT_Wattributes,
12076 "missing property attribute");
12077 if (token->type == CPP_CLOSE_PAREN)
12078 break;
12079 c_parser_consume_token (parser);
12080 continue;
12081 }
12082
12083 tree attr_name = NULL_TREE;
12084 enum rid keyword = RID_MAX; /* Not a valid property attribute. */
12085 bool add_at = false;
12086 if (token->type == CPP_KEYWORD)
12087 {
12088 keyword = token->keyword;
12089 if (OBJC_IS_AT_KEYWORD (keyword))
12090 {
12091 /* For '@' keywords the token value has the keyword,
12092 prepend the '@' for diagnostics. */
12093 attr_name = token->value;
12094 add_at = true;
12095 }
12096 else
12097 attr_name = ridpointers[(int)keyword];
12098 }
12099 else if (token->type == CPP_NAME)
12100 attr_name = token->value;
12101 c_parser_consume_token (parser);
12102
12103 enum objc_property_attribute_kind prop_kind
12104 = objc_prop_attr_kind_for_rid (keyword);
12105 property_attribute_info *prop
12106 = new property_attribute_info (attr_name, attr_comb, prop_kind);
12107 prop_attr_list.safe_push (prop);
12108
12109 tree meth_name;
12110 switch (prop->prop_kind)
12111 {
12112 default: break;
12113 case OBJC_PROPERTY_ATTR_UNKNOWN:
12114 if (attr_name)
12115 error_at (attr_comb, "unknown property attribute %<%s%s%>",
12116 add_at ? "@" : "", IDENTIFIER_POINTER (attr_name));
12117 else
12118 error_at (attr_comb, "unknown property attribute");
12119 prop->parse_error = syntax_error = true;
12120 break;
12121
12122 case OBJC_PROPERTY_ATTR_GETTER:
12123 case OBJC_PROPERTY_ATTR_SETTER:
12124 if (c_parser_next_token_is_not (parser, CPP_EQ))
12125 {
12126 attr_comb = make_location (attr_end, attr_start, attr_end);
12127 error_at (attr_comb, "expected %<=%> after Objective-C %qE",
12128 attr_name);
12129 prop->parse_error = syntax_error = true;
12130 break;
12131 }
12132 token = c_parser_peek_token (parser);
12133 attr_end = token->location;
12134 c_parser_consume_token (parser); /* eat the = */
12135 if (c_parser_next_token_is_not (parser, CPP_NAME))
12136 {
12137 attr_comb = make_location (attr_end, attr_start, attr_end);
12138 error_at (attr_comb, "expected %qE selector name",
12139 attr_name);
12140 prop->parse_error = syntax_error = true;
12141 break;
12142 }
12143 /* Get the end of the method name, and consume the name. */
12144 token = c_parser_peek_token (parser);
12145 attr_end = get_finish (token->location);
12146 meth_name = token->value;
12147 c_parser_consume_token (parser);
12148 if (prop->prop_kind == OBJC_PROPERTY_ATTR_SETTER)
12149 {
12150 if (c_parser_next_token_is_not (parser, CPP_COLON))
12151 {
12152 attr_comb = make_location (attr_end, attr_start,
12153 attr_end);
12154 error_at (attr_comb, "setter method names must"
12155 " terminate with %<:%>");
12156 prop->parse_error = syntax_error = true;
12157 }
12158 else
12159 {
12160 attr_end = get_finish (c_parser_peek_token
12161 (parser)->location);
12162 c_parser_consume_token (parser);
12163 }
12164 attr_comb = make_location (attr_start, attr_start,
12165 attr_end);
12166 }
12167 else
12168 attr_comb = make_location (attr_start, attr_start,
12169 attr_end);
12170 prop->ident = meth_name;
12171 /* Updated location including all that was successfully
12172 parsed. */
12173 prop->prop_loc = attr_comb;
12174 break;
12175 }
12176
12177 /* If we see a comma here, then keep going - even if we already
12178 saw a syntax error. For simple mistakes e.g. (asign, getter=x)
12179 this makes a more useful output and avoid spurious warnings about
12180 missing attributes that are, in fact, specified after the one with
12181 the syntax error. */
12182 if (c_parser_next_token_is (parser, CPP_COMMA))
12183 c_parser_consume_token (parser);
12184 else
12185 break;
12186 }
12187 parser->objc_property_attr_context = false;
12188
12189 if (syntax_error && c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN))
12190 /* We don't really want to chew the whole of the file looking for a
12191 matching closing parenthesis, so we will try to read the decl and
12192 let the error handling for that close out the statement. */
12193 ;
12194 else
12195 syntax_error = false, parens.skip_until_found_close (parser);
12196 }
12197
12198 /* 'properties' is the list of properties that we read. Usually a
12199 single one, but maybe more (eg, in "@property int a, b, c;" there
12200 are three). */
12201 tree properties = c_parser_struct_declaration (parser);
12202
12203 if (properties == error_mark_node)
12204 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12205 else
12206 {
12207 if (properties == NULL_TREE)
12208 c_parser_error (parser, "expected identifier");
12209 else
12210 {
12211 /* Comma-separated properties are chained together in reverse order;
12212 add them one by one. */
12213 properties = nreverse (properties);
12214 for (; properties; properties = TREE_CHAIN (properties))
12215 objc_add_property_declaration (loc, copy_node (properties),
12216 prop_attr_list);
12217 }
12218 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
12219 }
12220
12221 while (!prop_attr_list.is_empty())
12222 delete prop_attr_list.pop ();
12223 prop_attr_list.release ();
12224 parser->error = false;
12225 }
12226
12227 /* Parse an Objective-C @synthesize declaration. The syntax is:
12228
12229 objc-synthesize-declaration:
12230 @synthesize objc-synthesize-identifier-list ;
12231
12232 objc-synthesize-identifier-list:
12233 objc-synthesize-identifier
12234 objc-synthesize-identifier-list, objc-synthesize-identifier
12235
12236 objc-synthesize-identifier
12237 identifier
12238 identifier = identifier
12239
12240 For example:
12241 @synthesize MyProperty;
12242 @synthesize OneProperty, AnotherProperty=MyIvar, YetAnotherProperty;
12243
12244 PS: This function is identical to cp_parser_objc_at_synthesize_declaration
12245 for C++. Keep them in sync.
12246 */
12247 static void
c_parser_objc_at_synthesize_declaration(c_parser * parser)12248 c_parser_objc_at_synthesize_declaration (c_parser *parser)
12249 {
12250 tree list = NULL_TREE;
12251 location_t loc;
12252 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_SYNTHESIZE));
12253 loc = c_parser_peek_token (parser)->location;
12254
12255 c_parser_consume_token (parser);
12256 while (true)
12257 {
12258 tree property, ivar;
12259 if (c_parser_next_token_is_not (parser, CPP_NAME))
12260 {
12261 c_parser_error (parser, "expected identifier");
12262 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12263 /* Once we find the semicolon, we can resume normal parsing.
12264 We have to reset parser->error manually because
12265 c_parser_skip_until_found() won't reset it for us if the
12266 next token is precisely a semicolon. */
12267 parser->error = false;
12268 return;
12269 }
12270 property = c_parser_peek_token (parser)->value;
12271 c_parser_consume_token (parser);
12272 if (c_parser_next_token_is (parser, CPP_EQ))
12273 {
12274 c_parser_consume_token (parser);
12275 if (c_parser_next_token_is_not (parser, CPP_NAME))
12276 {
12277 c_parser_error (parser, "expected identifier");
12278 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12279 parser->error = false;
12280 return;
12281 }
12282 ivar = c_parser_peek_token (parser)->value;
12283 c_parser_consume_token (parser);
12284 }
12285 else
12286 ivar = NULL_TREE;
12287 list = chainon (list, build_tree_list (ivar, property));
12288 if (c_parser_next_token_is (parser, CPP_COMMA))
12289 c_parser_consume_token (parser);
12290 else
12291 break;
12292 }
12293 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
12294 objc_add_synthesize_declaration (loc, list);
12295 }
12296
12297 /* Parse an Objective-C @dynamic declaration. The syntax is:
12298
12299 objc-dynamic-declaration:
12300 @dynamic identifier-list ;
12301
12302 For example:
12303 @dynamic MyProperty;
12304 @dynamic MyProperty, AnotherProperty;
12305
12306 PS: This function is identical to cp_parser_objc_at_dynamic_declaration
12307 for C++. Keep them in sync.
12308 */
12309 static void
c_parser_objc_at_dynamic_declaration(c_parser * parser)12310 c_parser_objc_at_dynamic_declaration (c_parser *parser)
12311 {
12312 tree list = NULL_TREE;
12313 location_t loc;
12314 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_DYNAMIC));
12315 loc = c_parser_peek_token (parser)->location;
12316
12317 c_parser_consume_token (parser);
12318 while (true)
12319 {
12320 tree property;
12321 if (c_parser_next_token_is_not (parser, CPP_NAME))
12322 {
12323 c_parser_error (parser, "expected identifier");
12324 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12325 parser->error = false;
12326 return;
12327 }
12328 property = c_parser_peek_token (parser)->value;
12329 list = chainon (list, build_tree_list (NULL_TREE, property));
12330 c_parser_consume_token (parser);
12331 if (c_parser_next_token_is (parser, CPP_COMMA))
12332 c_parser_consume_token (parser);
12333 else
12334 break;
12335 }
12336 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
12337 objc_add_dynamic_declaration (loc, list);
12338 }
12339
12340
12341 /* Parse a pragma GCC ivdep. */
12342
12343 static bool
c_parse_pragma_ivdep(c_parser * parser)12344 c_parse_pragma_ivdep (c_parser *parser)
12345 {
12346 c_parser_consume_pragma (parser);
12347 c_parser_skip_to_pragma_eol (parser);
12348 return true;
12349 }
12350
12351 /* Parse a pragma GCC unroll. */
12352
12353 static unsigned short
c_parser_pragma_unroll(c_parser * parser)12354 c_parser_pragma_unroll (c_parser *parser)
12355 {
12356 unsigned short unroll;
12357 c_parser_consume_pragma (parser);
12358 location_t location = c_parser_peek_token (parser)->location;
12359 tree expr = c_parser_expr_no_commas (parser, NULL).value;
12360 mark_exp_read (expr);
12361 expr = c_fully_fold (expr, false, NULL);
12362 HOST_WIDE_INT lunroll = 0;
12363 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr))
12364 || TREE_CODE (expr) != INTEGER_CST
12365 || (lunroll = tree_to_shwi (expr)) < 0
12366 || lunroll >= USHRT_MAX)
12367 {
12368 error_at (location, "%<#pragma GCC unroll%> requires an"
12369 " assignment-expression that evaluates to a non-negative"
12370 " integral constant less than %u", USHRT_MAX);
12371 unroll = 0;
12372 }
12373 else
12374 {
12375 unroll = (unsigned short)lunroll;
12376 if (unroll == 0)
12377 unroll = 1;
12378 }
12379
12380 c_parser_skip_to_pragma_eol (parser);
12381 return unroll;
12382 }
12383
12384 /* Handle pragmas. Some OpenMP pragmas are associated with, and therefore
12385 should be considered, statements. ALLOW_STMT is true if we're within
12386 the context of a function and such pragmas are to be allowed. Returns
12387 true if we actually parsed such a pragma. */
12388
12389 static bool
c_parser_pragma(c_parser * parser,enum pragma_context context,bool * if_p)12390 c_parser_pragma (c_parser *parser, enum pragma_context context, bool *if_p)
12391 {
12392 unsigned int id;
12393 const char *construct = NULL;
12394
12395 input_location = c_parser_peek_token (parser)->location;
12396 id = c_parser_peek_token (parser)->pragma_kind;
12397 gcc_assert (id != PRAGMA_NONE);
12398
12399 switch (id)
12400 {
12401 case PRAGMA_OACC_DECLARE:
12402 c_parser_oacc_declare (parser);
12403 return false;
12404
12405 case PRAGMA_OACC_ENTER_DATA:
12406 if (context != pragma_compound)
12407 {
12408 construct = "acc enter data";
12409 in_compound:
12410 if (context == pragma_stmt)
12411 {
12412 error_at (c_parser_peek_token (parser)->location,
12413 "%<#pragma %s%> may only be used in compound "
12414 "statements", construct);
12415 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12416 return true;
12417 }
12418 goto bad_stmt;
12419 }
12420 c_parser_oacc_enter_exit_data (parser, true);
12421 return false;
12422
12423 case PRAGMA_OACC_EXIT_DATA:
12424 if (context != pragma_compound)
12425 {
12426 construct = "acc exit data";
12427 goto in_compound;
12428 }
12429 c_parser_oacc_enter_exit_data (parser, false);
12430 return false;
12431
12432 case PRAGMA_OACC_ROUTINE:
12433 if (context != pragma_external)
12434 {
12435 error_at (c_parser_peek_token (parser)->location,
12436 "%<#pragma acc routine%> must be at file scope");
12437 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12438 return false;
12439 }
12440 c_parser_oacc_routine (parser, context);
12441 return false;
12442
12443 case PRAGMA_OACC_UPDATE:
12444 if (context != pragma_compound)
12445 {
12446 construct = "acc update";
12447 goto in_compound;
12448 }
12449 c_parser_oacc_update (parser);
12450 return false;
12451
12452 case PRAGMA_OMP_BARRIER:
12453 if (context != pragma_compound)
12454 {
12455 construct = "omp barrier";
12456 goto in_compound;
12457 }
12458 c_parser_omp_barrier (parser);
12459 return false;
12460
12461 case PRAGMA_OMP_DEPOBJ:
12462 if (context != pragma_compound)
12463 {
12464 construct = "omp depobj";
12465 goto in_compound;
12466 }
12467 c_parser_omp_depobj (parser);
12468 return false;
12469
12470 case PRAGMA_OMP_FLUSH:
12471 if (context != pragma_compound)
12472 {
12473 construct = "omp flush";
12474 goto in_compound;
12475 }
12476 c_parser_omp_flush (parser);
12477 return false;
12478
12479 case PRAGMA_OMP_TASKWAIT:
12480 if (context != pragma_compound)
12481 {
12482 construct = "omp taskwait";
12483 goto in_compound;
12484 }
12485 c_parser_omp_taskwait (parser);
12486 return false;
12487
12488 case PRAGMA_OMP_TASKYIELD:
12489 if (context != pragma_compound)
12490 {
12491 construct = "omp taskyield";
12492 goto in_compound;
12493 }
12494 c_parser_omp_taskyield (parser);
12495 return false;
12496
12497 case PRAGMA_OMP_CANCEL:
12498 if (context != pragma_compound)
12499 {
12500 construct = "omp cancel";
12501 goto in_compound;
12502 }
12503 c_parser_omp_cancel (parser);
12504 return false;
12505
12506 case PRAGMA_OMP_CANCELLATION_POINT:
12507 return c_parser_omp_cancellation_point (parser, context);
12508
12509 case PRAGMA_OMP_THREADPRIVATE:
12510 c_parser_omp_threadprivate (parser);
12511 return false;
12512
12513 case PRAGMA_OMP_TARGET:
12514 return c_parser_omp_target (parser, context, if_p);
12515
12516 case PRAGMA_OMP_END_DECLARE_TARGET:
12517 c_parser_omp_end_declare_target (parser);
12518 return false;
12519
12520 case PRAGMA_OMP_SCAN:
12521 error_at (c_parser_peek_token (parser)->location,
12522 "%<#pragma omp scan%> may only be used in "
12523 "a loop construct with %<inscan%> %<reduction%> clause");
12524 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12525 return false;
12526
12527 case PRAGMA_OMP_SECTION:
12528 error_at (c_parser_peek_token (parser)->location,
12529 "%<#pragma omp section%> may only be used in "
12530 "%<#pragma omp sections%> construct");
12531 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12532 return false;
12533
12534 case PRAGMA_OMP_DECLARE:
12535 return c_parser_omp_declare (parser, context);
12536
12537 case PRAGMA_OMP_REQUIRES:
12538 if (context != pragma_external)
12539 {
12540 error_at (c_parser_peek_token (parser)->location,
12541 "%<#pragma omp requires%> may only be used at file scope");
12542 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12543 return false;
12544 }
12545 c_parser_omp_requires (parser);
12546 return false;
12547
12548 case PRAGMA_OMP_NOTHING:
12549 c_parser_omp_nothing (parser);
12550 return false;
12551
12552 case PRAGMA_OMP_ERROR:
12553 return c_parser_omp_error (parser, context);
12554
12555 case PRAGMA_OMP_ORDERED:
12556 return c_parser_omp_ordered (parser, context, if_p);
12557
12558 case PRAGMA_IVDEP:
12559 {
12560 const bool ivdep = c_parse_pragma_ivdep (parser);
12561 unsigned short unroll;
12562 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_UNROLL)
12563 unroll = c_parser_pragma_unroll (parser);
12564 else
12565 unroll = 0;
12566 if (!c_parser_next_token_is_keyword (parser, RID_FOR)
12567 && !c_parser_next_token_is_keyword (parser, RID_WHILE)
12568 && !c_parser_next_token_is_keyword (parser, RID_DO))
12569 {
12570 c_parser_error (parser, "for, while or do statement expected");
12571 return false;
12572 }
12573 if (c_parser_next_token_is_keyword (parser, RID_FOR))
12574 c_parser_for_statement (parser, ivdep, unroll, if_p);
12575 else if (c_parser_next_token_is_keyword (parser, RID_WHILE))
12576 c_parser_while_statement (parser, ivdep, unroll, if_p);
12577 else
12578 c_parser_do_statement (parser, ivdep, unroll);
12579 }
12580 return true;
12581
12582 case PRAGMA_UNROLL:
12583 {
12584 unsigned short unroll = c_parser_pragma_unroll (parser);
12585 bool ivdep;
12586 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_IVDEP)
12587 ivdep = c_parse_pragma_ivdep (parser);
12588 else
12589 ivdep = false;
12590 if (!c_parser_next_token_is_keyword (parser, RID_FOR)
12591 && !c_parser_next_token_is_keyword (parser, RID_WHILE)
12592 && !c_parser_next_token_is_keyword (parser, RID_DO))
12593 {
12594 c_parser_error (parser, "for, while or do statement expected");
12595 return false;
12596 }
12597 if (c_parser_next_token_is_keyword (parser, RID_FOR))
12598 c_parser_for_statement (parser, ivdep, unroll, if_p);
12599 else if (c_parser_next_token_is_keyword (parser, RID_WHILE))
12600 c_parser_while_statement (parser, ivdep, unroll, if_p);
12601 else
12602 c_parser_do_statement (parser, ivdep, unroll);
12603 }
12604 return true;
12605
12606 case PRAGMA_GCC_PCH_PREPROCESS:
12607 c_parser_error (parser, "%<#pragma GCC pch_preprocess%> must be first");
12608 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12609 return false;
12610
12611 case PRAGMA_OACC_WAIT:
12612 if (context != pragma_compound)
12613 {
12614 construct = "acc wait";
12615 goto in_compound;
12616 }
12617 /* FALL THROUGH. */
12618
12619 default:
12620 if (id < PRAGMA_FIRST_EXTERNAL)
12621 {
12622 if (context != pragma_stmt && context != pragma_compound)
12623 {
12624 bad_stmt:
12625 c_parser_error (parser, "expected declaration specifiers");
12626 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12627 return false;
12628 }
12629 c_parser_omp_construct (parser, if_p);
12630 return true;
12631 }
12632 break;
12633 }
12634
12635 c_parser_consume_pragma (parser);
12636 c_invoke_pragma_handler (id);
12637
12638 /* Skip to EOL, but suppress any error message. Those will have been
12639 generated by the handler routine through calling error, as opposed
12640 to calling c_parser_error. */
12641 parser->error = true;
12642 c_parser_skip_to_pragma_eol (parser);
12643
12644 return false;
12645 }
12646
12647 /* The interface the pragma parsers have to the lexer. */
12648
12649 enum cpp_ttype
pragma_lex(tree * value,location_t * loc)12650 pragma_lex (tree *value, location_t *loc)
12651 {
12652 c_token *tok = c_parser_peek_token (the_parser);
12653 enum cpp_ttype ret = tok->type;
12654
12655 *value = tok->value;
12656 if (loc)
12657 *loc = tok->location;
12658
12659 if (ret == CPP_PRAGMA_EOL || ret == CPP_EOF)
12660 ret = CPP_EOF;
12661 else if (ret == CPP_STRING)
12662 *value = c_parser_string_literal (the_parser, false, false).value;
12663 else
12664 {
12665 if (ret == CPP_KEYWORD)
12666 ret = CPP_NAME;
12667 c_parser_consume_token (the_parser);
12668 }
12669
12670 return ret;
12671 }
12672
12673 static void
c_parser_pragma_pch_preprocess(c_parser * parser)12674 c_parser_pragma_pch_preprocess (c_parser *parser)
12675 {
12676 tree name = NULL;
12677
12678 parser->lex_joined_string = true;
12679 c_parser_consume_pragma (parser);
12680 if (c_parser_next_token_is (parser, CPP_STRING))
12681 {
12682 name = c_parser_peek_token (parser)->value;
12683 c_parser_consume_token (parser);
12684 }
12685 else
12686 c_parser_error (parser, "expected string literal");
12687 c_parser_skip_to_pragma_eol (parser);
12688 parser->lex_joined_string = false;
12689
12690 if (name)
12691 c_common_pch_pragma (parse_in, TREE_STRING_POINTER (name));
12692 }
12693
12694 /* OpenACC and OpenMP parsing routines. */
12695
12696 /* Returns name of the next clause.
12697 If the clause is not recognized PRAGMA_OMP_CLAUSE_NONE is returned and
12698 the token is not consumed. Otherwise appropriate pragma_omp_clause is
12699 returned and the token is consumed. */
12700
12701 static pragma_omp_clause
c_parser_omp_clause_name(c_parser * parser)12702 c_parser_omp_clause_name (c_parser *parser)
12703 {
12704 pragma_omp_clause result = PRAGMA_OMP_CLAUSE_NONE;
12705
12706 if (c_parser_next_token_is_keyword (parser, RID_AUTO))
12707 result = PRAGMA_OACC_CLAUSE_AUTO;
12708 else if (c_parser_next_token_is_keyword (parser, RID_IF))
12709 result = PRAGMA_OMP_CLAUSE_IF;
12710 else if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
12711 result = PRAGMA_OMP_CLAUSE_DEFAULT;
12712 else if (c_parser_next_token_is_keyword (parser, RID_FOR))
12713 result = PRAGMA_OMP_CLAUSE_FOR;
12714 else if (c_parser_next_token_is (parser, CPP_NAME))
12715 {
12716 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
12717
12718 switch (p[0])
12719 {
12720 case 'a':
12721 if (!strcmp ("affinity", p))
12722 result = PRAGMA_OMP_CLAUSE_AFFINITY;
12723 else if (!strcmp ("aligned", p))
12724 result = PRAGMA_OMP_CLAUSE_ALIGNED;
12725 else if (!strcmp ("allocate", p))
12726 result = PRAGMA_OMP_CLAUSE_ALLOCATE;
12727 else if (!strcmp ("async", p))
12728 result = PRAGMA_OACC_CLAUSE_ASYNC;
12729 else if (!strcmp ("attach", p))
12730 result = PRAGMA_OACC_CLAUSE_ATTACH;
12731 break;
12732 case 'b':
12733 if (!strcmp ("bind", p))
12734 result = PRAGMA_OMP_CLAUSE_BIND;
12735 break;
12736 case 'c':
12737 if (!strcmp ("collapse", p))
12738 result = PRAGMA_OMP_CLAUSE_COLLAPSE;
12739 else if (!strcmp ("copy", p))
12740 result = PRAGMA_OACC_CLAUSE_COPY;
12741 else if (!strcmp ("copyin", p))
12742 result = PRAGMA_OMP_CLAUSE_COPYIN;
12743 else if (!strcmp ("copyout", p))
12744 result = PRAGMA_OACC_CLAUSE_COPYOUT;
12745 else if (!strcmp ("copyprivate", p))
12746 result = PRAGMA_OMP_CLAUSE_COPYPRIVATE;
12747 else if (!strcmp ("create", p))
12748 result = PRAGMA_OACC_CLAUSE_CREATE;
12749 break;
12750 case 'd':
12751 if (!strcmp ("defaultmap", p))
12752 result = PRAGMA_OMP_CLAUSE_DEFAULTMAP;
12753 else if (!strcmp ("delete", p))
12754 result = PRAGMA_OACC_CLAUSE_DELETE;
12755 else if (!strcmp ("depend", p))
12756 result = PRAGMA_OMP_CLAUSE_DEPEND;
12757 else if (!strcmp ("detach", p))
12758 result = PRAGMA_OACC_CLAUSE_DETACH;
12759 else if (!strcmp ("device", p))
12760 result = PRAGMA_OMP_CLAUSE_DEVICE;
12761 else if (!strcmp ("deviceptr", p))
12762 result = PRAGMA_OACC_CLAUSE_DEVICEPTR;
12763 else if (!strcmp ("device_resident", p))
12764 result = PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT;
12765 else if (!strcmp ("device_type", p))
12766 result = PRAGMA_OMP_CLAUSE_DEVICE_TYPE;
12767 else if (!strcmp ("dist_schedule", p))
12768 result = PRAGMA_OMP_CLAUSE_DIST_SCHEDULE;
12769 break;
12770 case 'f':
12771 if (!strcmp ("filter", p))
12772 result = PRAGMA_OMP_CLAUSE_FILTER;
12773 else if (!strcmp ("final", p))
12774 result = PRAGMA_OMP_CLAUSE_FINAL;
12775 else if (!strcmp ("finalize", p))
12776 result = PRAGMA_OACC_CLAUSE_FINALIZE;
12777 else if (!strcmp ("firstprivate", p))
12778 result = PRAGMA_OMP_CLAUSE_FIRSTPRIVATE;
12779 else if (!strcmp ("from", p))
12780 result = PRAGMA_OMP_CLAUSE_FROM;
12781 break;
12782 case 'g':
12783 if (!strcmp ("gang", p))
12784 result = PRAGMA_OACC_CLAUSE_GANG;
12785 else if (!strcmp ("grainsize", p))
12786 result = PRAGMA_OMP_CLAUSE_GRAINSIZE;
12787 break;
12788 case 'h':
12789 if (!strcmp ("has_device_addr", p))
12790 result = PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR;
12791 else if (!strcmp ("hint", p))
12792 result = PRAGMA_OMP_CLAUSE_HINT;
12793 else if (!strcmp ("host", p))
12794 result = PRAGMA_OACC_CLAUSE_HOST;
12795 break;
12796 case 'i':
12797 if (!strcmp ("if_present", p))
12798 result = PRAGMA_OACC_CLAUSE_IF_PRESENT;
12799 else if (!strcmp ("in_reduction", p))
12800 result = PRAGMA_OMP_CLAUSE_IN_REDUCTION;
12801 else if (!strcmp ("inbranch", p))
12802 result = PRAGMA_OMP_CLAUSE_INBRANCH;
12803 else if (!strcmp ("independent", p))
12804 result = PRAGMA_OACC_CLAUSE_INDEPENDENT;
12805 else if (!strcmp ("is_device_ptr", p))
12806 result = PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR;
12807 break;
12808 case 'l':
12809 if (!strcmp ("lastprivate", p))
12810 result = PRAGMA_OMP_CLAUSE_LASTPRIVATE;
12811 else if (!strcmp ("linear", p))
12812 result = PRAGMA_OMP_CLAUSE_LINEAR;
12813 else if (!strcmp ("link", p))
12814 result = PRAGMA_OMP_CLAUSE_LINK;
12815 break;
12816 case 'm':
12817 if (!strcmp ("map", p))
12818 result = PRAGMA_OMP_CLAUSE_MAP;
12819 else if (!strcmp ("mergeable", p))
12820 result = PRAGMA_OMP_CLAUSE_MERGEABLE;
12821 break;
12822 case 'n':
12823 if (!strcmp ("no_create", p))
12824 result = PRAGMA_OACC_CLAUSE_NO_CREATE;
12825 else if (!strcmp ("nogroup", p))
12826 result = PRAGMA_OMP_CLAUSE_NOGROUP;
12827 else if (!strcmp ("nohost", p))
12828 result = PRAGMA_OACC_CLAUSE_NOHOST;
12829 else if (!strcmp ("nontemporal", p))
12830 result = PRAGMA_OMP_CLAUSE_NONTEMPORAL;
12831 else if (!strcmp ("notinbranch", p))
12832 result = PRAGMA_OMP_CLAUSE_NOTINBRANCH;
12833 else if (!strcmp ("nowait", p))
12834 result = PRAGMA_OMP_CLAUSE_NOWAIT;
12835 else if (!strcmp ("num_gangs", p))
12836 result = PRAGMA_OACC_CLAUSE_NUM_GANGS;
12837 else if (!strcmp ("num_tasks", p))
12838 result = PRAGMA_OMP_CLAUSE_NUM_TASKS;
12839 else if (!strcmp ("num_teams", p))
12840 result = PRAGMA_OMP_CLAUSE_NUM_TEAMS;
12841 else if (!strcmp ("num_threads", p))
12842 result = PRAGMA_OMP_CLAUSE_NUM_THREADS;
12843 else if (!strcmp ("num_workers", p))
12844 result = PRAGMA_OACC_CLAUSE_NUM_WORKERS;
12845 break;
12846 case 'o':
12847 if (!strcmp ("ordered", p))
12848 result = PRAGMA_OMP_CLAUSE_ORDERED;
12849 else if (!strcmp ("order", p))
12850 result = PRAGMA_OMP_CLAUSE_ORDER;
12851 break;
12852 case 'p':
12853 if (!strcmp ("parallel", p))
12854 result = PRAGMA_OMP_CLAUSE_PARALLEL;
12855 else if (!strcmp ("present", p))
12856 result = PRAGMA_OACC_CLAUSE_PRESENT;
12857 /* As of OpenACC 2.5, these are now aliases of the non-present_or
12858 clauses. */
12859 else if (!strcmp ("present_or_copy", p)
12860 || !strcmp ("pcopy", p))
12861 result = PRAGMA_OACC_CLAUSE_COPY;
12862 else if (!strcmp ("present_or_copyin", p)
12863 || !strcmp ("pcopyin", p))
12864 result = PRAGMA_OACC_CLAUSE_COPYIN;
12865 else if (!strcmp ("present_or_copyout", p)
12866 || !strcmp ("pcopyout", p))
12867 result = PRAGMA_OACC_CLAUSE_COPYOUT;
12868 else if (!strcmp ("present_or_create", p)
12869 || !strcmp ("pcreate", p))
12870 result = PRAGMA_OACC_CLAUSE_CREATE;
12871 else if (!strcmp ("priority", p))
12872 result = PRAGMA_OMP_CLAUSE_PRIORITY;
12873 else if (!strcmp ("private", p))
12874 result = PRAGMA_OMP_CLAUSE_PRIVATE;
12875 else if (!strcmp ("proc_bind", p))
12876 result = PRAGMA_OMP_CLAUSE_PROC_BIND;
12877 break;
12878 case 'r':
12879 if (!strcmp ("reduction", p))
12880 result = PRAGMA_OMP_CLAUSE_REDUCTION;
12881 break;
12882 case 's':
12883 if (!strcmp ("safelen", p))
12884 result = PRAGMA_OMP_CLAUSE_SAFELEN;
12885 else if (!strcmp ("schedule", p))
12886 result = PRAGMA_OMP_CLAUSE_SCHEDULE;
12887 else if (!strcmp ("sections", p))
12888 result = PRAGMA_OMP_CLAUSE_SECTIONS;
12889 else if (!strcmp ("self", p)) /* "self" is a synonym for "host". */
12890 result = PRAGMA_OACC_CLAUSE_HOST;
12891 else if (!strcmp ("seq", p))
12892 result = PRAGMA_OACC_CLAUSE_SEQ;
12893 else if (!strcmp ("shared", p))
12894 result = PRAGMA_OMP_CLAUSE_SHARED;
12895 else if (!strcmp ("simd", p))
12896 result = PRAGMA_OMP_CLAUSE_SIMD;
12897 else if (!strcmp ("simdlen", p))
12898 result = PRAGMA_OMP_CLAUSE_SIMDLEN;
12899 break;
12900 case 't':
12901 if (!strcmp ("task_reduction", p))
12902 result = PRAGMA_OMP_CLAUSE_TASK_REDUCTION;
12903 else if (!strcmp ("taskgroup", p))
12904 result = PRAGMA_OMP_CLAUSE_TASKGROUP;
12905 else if (!strcmp ("thread_limit", p))
12906 result = PRAGMA_OMP_CLAUSE_THREAD_LIMIT;
12907 else if (!strcmp ("threads", p))
12908 result = PRAGMA_OMP_CLAUSE_THREADS;
12909 else if (!strcmp ("tile", p))
12910 result = PRAGMA_OACC_CLAUSE_TILE;
12911 else if (!strcmp ("to", p))
12912 result = PRAGMA_OMP_CLAUSE_TO;
12913 break;
12914 case 'u':
12915 if (!strcmp ("uniform", p))
12916 result = PRAGMA_OMP_CLAUSE_UNIFORM;
12917 else if (!strcmp ("untied", p))
12918 result = PRAGMA_OMP_CLAUSE_UNTIED;
12919 else if (!strcmp ("use_device", p))
12920 result = PRAGMA_OACC_CLAUSE_USE_DEVICE;
12921 else if (!strcmp ("use_device_addr", p))
12922 result = PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR;
12923 else if (!strcmp ("use_device_ptr", p))
12924 result = PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR;
12925 break;
12926 case 'v':
12927 if (!strcmp ("vector", p))
12928 result = PRAGMA_OACC_CLAUSE_VECTOR;
12929 else if (!strcmp ("vector_length", p))
12930 result = PRAGMA_OACC_CLAUSE_VECTOR_LENGTH;
12931 break;
12932 case 'w':
12933 if (!strcmp ("wait", p))
12934 result = PRAGMA_OACC_CLAUSE_WAIT;
12935 else if (!strcmp ("worker", p))
12936 result = PRAGMA_OACC_CLAUSE_WORKER;
12937 break;
12938 }
12939 }
12940
12941 if (result != PRAGMA_OMP_CLAUSE_NONE)
12942 c_parser_consume_token (parser);
12943
12944 return result;
12945 }
12946
12947 /* Validate that a clause of the given type does not already exist. */
12948
12949 static void
check_no_duplicate_clause(tree clauses,enum omp_clause_code code,const char * name)12950 check_no_duplicate_clause (tree clauses, enum omp_clause_code code,
12951 const char *name)
12952 {
12953 if (tree c = omp_find_clause (clauses, code))
12954 error_at (OMP_CLAUSE_LOCATION (c), "too many %qs clauses", name);
12955 }
12956
12957 /* OpenACC 2.0
12958 Parse wait clause or wait directive parameters. */
12959
12960 static tree
c_parser_oacc_wait_list(c_parser * parser,location_t clause_loc,tree list)12961 c_parser_oacc_wait_list (c_parser *parser, location_t clause_loc, tree list)
12962 {
12963 vec<tree, va_gc> *args;
12964 tree t, args_tree;
12965
12966 matching_parens parens;
12967 if (!parens.require_open (parser))
12968 return list;
12969
12970 args = c_parser_expr_list (parser, false, true, NULL, NULL, NULL, NULL);
12971 args_tree = build_tree_list_vec (args);
12972
12973 for (t = args_tree; t; t = TREE_CHAIN (t))
12974 {
12975 tree targ = TREE_VALUE (t);
12976
12977 if (targ != error_mark_node)
12978 {
12979 if (!INTEGRAL_TYPE_P (TREE_TYPE (targ)))
12980 {
12981 c_parser_error (parser, "expression must be integral");
12982 targ = error_mark_node;
12983 }
12984 else
12985 {
12986 tree c = build_omp_clause (clause_loc, OMP_CLAUSE_WAIT);
12987
12988 OMP_CLAUSE_DECL (c) = targ;
12989 OMP_CLAUSE_CHAIN (c) = list;
12990 list = c;
12991 }
12992 }
12993 }
12994
12995 release_tree_vector (args);
12996 parens.require_close (parser);
12997 return list;
12998 }
12999
13000 /* OpenACC 2.0, OpenMP 2.5:
13001 variable-list:
13002 identifier
13003 variable-list , identifier
13004
13005 If KIND is nonzero, create the appropriate node and install the
13006 decl in OMP_CLAUSE_DECL and add the node to the head of the list.
13007 If KIND is nonzero, CLAUSE_LOC is the location of the clause.
13008
13009 If KIND is zero, create a TREE_LIST with the decl in TREE_PURPOSE;
13010 return the list created.
13011
13012 The optional ALLOW_DEREF argument is true if list items can use the deref
13013 (->) operator. */
13014
13015 struct omp_dim
13016 {
13017 tree low_bound, length;
13018 location_t loc;
13019 bool no_colon;
omp_dimomp_dim13020 omp_dim (tree lb, tree len, location_t lo, bool nc)
13021 : low_bound (lb), length (len), loc (lo), no_colon (nc) {}
13022 };
13023
13024 static tree
c_parser_omp_variable_list(c_parser * parser,location_t clause_loc,enum omp_clause_code kind,tree list,bool allow_deref=false)13025 c_parser_omp_variable_list (c_parser *parser,
13026 location_t clause_loc,
13027 enum omp_clause_code kind, tree list,
13028 bool allow_deref = false)
13029 {
13030 auto_vec<omp_dim> dims;
13031 bool array_section_p;
13032 auto_vec<c_token> tokens;
13033 unsigned int tokens_avail = 0;
13034 bool first = true;
13035
13036 while (1)
13037 {
13038 if (kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
13039 {
13040 if (c_parser_next_token_is_not (parser, CPP_NAME)
13041 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
13042 {
13043 struct c_expr expr = c_parser_expr_no_commas (parser, NULL);
13044 if (expr.value != error_mark_node)
13045 {
13046 tree u = build_omp_clause (clause_loc, kind);
13047 OMP_CLAUSE_DECL (u) = expr.value;
13048 OMP_CLAUSE_CHAIN (u) = list;
13049 list = u;
13050 }
13051
13052 if (c_parser_next_token_is_not (parser, CPP_COMMA))
13053 break;
13054
13055 c_parser_consume_token (parser);
13056 first = false;
13057 continue;
13058 }
13059
13060 tokens.truncate (0);
13061 unsigned int nesting_depth = 0;
13062 while (1)
13063 {
13064 c_token *token = c_parser_peek_token (parser);
13065 switch (token->type)
13066 {
13067 case CPP_EOF:
13068 case CPP_PRAGMA_EOL:
13069 break;
13070 case CPP_OPEN_BRACE:
13071 case CPP_OPEN_PAREN:
13072 case CPP_OPEN_SQUARE:
13073 ++nesting_depth;
13074 goto add;
13075 case CPP_CLOSE_BRACE:
13076 case CPP_CLOSE_PAREN:
13077 case CPP_CLOSE_SQUARE:
13078 if (nesting_depth-- == 0)
13079 break;
13080 goto add;
13081 case CPP_COMMA:
13082 if (nesting_depth == 0)
13083 break;
13084 goto add;
13085 default:
13086 add:
13087 tokens.safe_push (*token);
13088 c_parser_consume_token (parser);
13089 continue;
13090 }
13091 break;
13092 }
13093
13094 /* Make sure nothing tries to read past the end of the tokens. */
13095 c_token eof_token;
13096 memset (&eof_token, 0, sizeof (eof_token));
13097 eof_token.type = CPP_EOF;
13098 tokens.safe_push (eof_token);
13099 tokens.safe_push (eof_token);
13100
13101 tokens_avail = parser->tokens_avail;
13102 gcc_assert (parser->tokens == &parser->tokens_buf[0]);
13103 parser->tokens = tokens.address ();
13104 parser->tokens_avail = tokens.length ();
13105 }
13106
13107 tree t = NULL_TREE;
13108
13109 if (c_parser_next_token_is (parser, CPP_NAME)
13110 && c_parser_peek_token (parser)->id_kind == C_ID_ID)
13111 {
13112 t = lookup_name (c_parser_peek_token (parser)->value);
13113
13114 if (t == NULL_TREE)
13115 {
13116 undeclared_variable (c_parser_peek_token (parser)->location,
13117 c_parser_peek_token (parser)->value);
13118 t = error_mark_node;
13119 }
13120
13121 c_parser_consume_token (parser);
13122 }
13123 else if (c_parser_next_token_is (parser, CPP_KEYWORD)
13124 && (c_parser_peek_token (parser)->keyword == RID_FUNCTION_NAME
13125 || (c_parser_peek_token (parser)->keyword
13126 == RID_PRETTY_FUNCTION_NAME)
13127 || (c_parser_peek_token (parser)->keyword
13128 == RID_C99_FUNCTION_NAME)))
13129 t = c_parser_predefined_identifier (parser).value;
13130 else
13131 {
13132 if (first)
13133 c_parser_error (parser, "expected identifier");
13134 break;
13135 }
13136
13137 if (t == error_mark_node)
13138 ;
13139 else if (kind != 0)
13140 {
13141 switch (kind)
13142 {
13143 case OMP_CLAUSE__CACHE_:
13144 /* The OpenACC cache directive explicitly only allows "array
13145 elements or subarrays". */
13146 if (c_parser_peek_token (parser)->type != CPP_OPEN_SQUARE)
13147 {
13148 c_parser_error (parser, "expected %<[%>");
13149 t = error_mark_node;
13150 break;
13151 }
13152 /* FALLTHROUGH */
13153 case OMP_CLAUSE_MAP:
13154 case OMP_CLAUSE_FROM:
13155 case OMP_CLAUSE_TO:
13156 start_component_ref:
13157 while (c_parser_next_token_is (parser, CPP_DOT)
13158 || (allow_deref
13159 && c_parser_next_token_is (parser, CPP_DEREF)))
13160 {
13161 location_t op_loc = c_parser_peek_token (parser)->location;
13162 if (c_parser_next_token_is (parser, CPP_DEREF))
13163 {
13164 c_expr t_expr;
13165 t_expr.value = t;
13166 t_expr.original_code = ERROR_MARK;
13167 t_expr.original_type = NULL;
13168 set_c_expr_source_range (&t_expr, op_loc, op_loc);
13169 t_expr = convert_lvalue_to_rvalue (op_loc, t_expr,
13170 true, false);
13171 t = build_indirect_ref (op_loc, t_expr.value, RO_ARROW);
13172 }
13173 c_parser_consume_token (parser);
13174 if (!c_parser_next_token_is (parser, CPP_NAME))
13175 {
13176 c_parser_error (parser, "expected identifier");
13177 t = error_mark_node;
13178 break;
13179 }
13180
13181 c_token *comp_tok = c_parser_peek_token (parser);
13182 tree ident = comp_tok->value;
13183 location_t comp_loc = comp_tok->location;
13184 c_parser_consume_token (parser);
13185 t = build_component_ref (op_loc, t, ident, comp_loc);
13186 }
13187 /* FALLTHROUGH */
13188 case OMP_CLAUSE_AFFINITY:
13189 case OMP_CLAUSE_DEPEND:
13190 case OMP_CLAUSE_REDUCTION:
13191 case OMP_CLAUSE_IN_REDUCTION:
13192 case OMP_CLAUSE_TASK_REDUCTION:
13193 case OMP_CLAUSE_HAS_DEVICE_ADDR:
13194 array_section_p = false;
13195 dims.truncate (0);
13196 while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
13197 {
13198 location_t loc = UNKNOWN_LOCATION;
13199 tree low_bound = NULL_TREE, length = NULL_TREE;
13200 bool no_colon = false;
13201
13202 c_parser_consume_token (parser);
13203 if (!c_parser_next_token_is (parser, CPP_COLON))
13204 {
13205 location_t expr_loc
13206 = c_parser_peek_token (parser)->location;
13207 c_expr expr = c_parser_expression (parser);
13208 expr = convert_lvalue_to_rvalue (expr_loc, expr,
13209 false, true);
13210 low_bound = expr.value;
13211 loc = expr_loc;
13212 }
13213 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
13214 {
13215 length = integer_one_node;
13216 no_colon = true;
13217 }
13218 else
13219 {
13220 /* Look for `:'. */
13221 if (!c_parser_require (parser, CPP_COLON,
13222 "expected %<:%>"))
13223 {
13224 t = error_mark_node;
13225 break;
13226 }
13227 array_section_p = true;
13228 if (!c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
13229 {
13230 location_t expr_loc
13231 = c_parser_peek_token (parser)->location;
13232 c_expr expr = c_parser_expression (parser);
13233 expr = convert_lvalue_to_rvalue (expr_loc, expr,
13234 false, true);
13235 length = expr.value;
13236 }
13237 }
13238 /* Look for the closing `]'. */
13239 if (!c_parser_require (parser, CPP_CLOSE_SQUARE,
13240 "expected %<]%>"))
13241 {
13242 t = error_mark_node;
13243 break;
13244 }
13245
13246 dims.safe_push (omp_dim (low_bound, length, loc, no_colon));
13247 }
13248
13249 if (t != error_mark_node)
13250 {
13251 if ((kind == OMP_CLAUSE_MAP
13252 || kind == OMP_CLAUSE_FROM
13253 || kind == OMP_CLAUSE_TO)
13254 && !array_section_p
13255 && (c_parser_next_token_is (parser, CPP_DOT)
13256 || (allow_deref
13257 && c_parser_next_token_is (parser,
13258 CPP_DEREF))))
13259 {
13260 for (unsigned i = 0; i < dims.length (); i++)
13261 {
13262 gcc_assert (dims[i].length == integer_one_node);
13263 t = build_array_ref (dims[i].loc,
13264 t, dims[i].low_bound);
13265 }
13266 goto start_component_ref;
13267 }
13268 else
13269 for (unsigned i = 0; i < dims.length (); i++)
13270 t = tree_cons (dims[i].low_bound, dims[i].length, t);
13271 }
13272
13273 if ((kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
13274 && t != error_mark_node
13275 && parser->tokens_avail != 2)
13276 {
13277 if (array_section_p)
13278 {
13279 error_at (c_parser_peek_token (parser)->location,
13280 "expected %<)%> or %<,%>");
13281 t = error_mark_node;
13282 }
13283 else
13284 {
13285 parser->tokens = tokens.address ();
13286 parser->tokens_avail = tokens.length ();
13287
13288 t = c_parser_expr_no_commas (parser, NULL).value;
13289 if (t != error_mark_node && parser->tokens_avail != 2)
13290 {
13291 error_at (c_parser_peek_token (parser)->location,
13292 "expected %<)%> or %<,%>");
13293 t = error_mark_node;
13294 }
13295 }
13296 }
13297 break;
13298 default:
13299 break;
13300 }
13301
13302 if (t != error_mark_node)
13303 {
13304 tree u = build_omp_clause (clause_loc, kind);
13305 OMP_CLAUSE_DECL (u) = t;
13306 OMP_CLAUSE_CHAIN (u) = list;
13307 list = u;
13308 }
13309 }
13310 else
13311 list = tree_cons (t, NULL_TREE, list);
13312
13313 if (kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
13314 {
13315 parser->tokens = &parser->tokens_buf[0];
13316 parser->tokens_avail = tokens_avail;
13317 }
13318 if (c_parser_next_token_is_not (parser, CPP_COMMA))
13319 break;
13320
13321 c_parser_consume_token (parser);
13322 first = false;
13323 }
13324
13325 return list;
13326 }
13327
13328 /* Similarly, but expect leading and trailing parenthesis. This is a very
13329 common case for OpenACC and OpenMP clauses. The optional ALLOW_DEREF
13330 argument is true if list items can use the deref (->) operator. */
13331
13332 static tree
c_parser_omp_var_list_parens(c_parser * parser,enum omp_clause_code kind,tree list,bool allow_deref=false)13333 c_parser_omp_var_list_parens (c_parser *parser, enum omp_clause_code kind,
13334 tree list, bool allow_deref = false)
13335 {
13336 /* The clauses location. */
13337 location_t loc = c_parser_peek_token (parser)->location;
13338
13339 matching_parens parens;
13340 if (parens.require_open (parser))
13341 {
13342 list = c_parser_omp_variable_list (parser, loc, kind, list, allow_deref);
13343 parens.skip_until_found_close (parser);
13344 }
13345 return list;
13346 }
13347
13348 /* OpenACC 2.0:
13349 copy ( variable-list )
13350 copyin ( variable-list )
13351 copyout ( variable-list )
13352 create ( variable-list )
13353 delete ( variable-list )
13354 present ( variable-list )
13355
13356 OpenACC 2.6:
13357 no_create ( variable-list )
13358 attach ( variable-list )
13359 detach ( variable-list ) */
13360
13361 static tree
c_parser_oacc_data_clause(c_parser * parser,pragma_omp_clause c_kind,tree list)13362 c_parser_oacc_data_clause (c_parser *parser, pragma_omp_clause c_kind,
13363 tree list)
13364 {
13365 enum gomp_map_kind kind;
13366 switch (c_kind)
13367 {
13368 case PRAGMA_OACC_CLAUSE_ATTACH:
13369 kind = GOMP_MAP_ATTACH;
13370 break;
13371 case PRAGMA_OACC_CLAUSE_COPY:
13372 kind = GOMP_MAP_TOFROM;
13373 break;
13374 case PRAGMA_OACC_CLAUSE_COPYIN:
13375 kind = GOMP_MAP_TO;
13376 break;
13377 case PRAGMA_OACC_CLAUSE_COPYOUT:
13378 kind = GOMP_MAP_FROM;
13379 break;
13380 case PRAGMA_OACC_CLAUSE_CREATE:
13381 kind = GOMP_MAP_ALLOC;
13382 break;
13383 case PRAGMA_OACC_CLAUSE_DELETE:
13384 kind = GOMP_MAP_RELEASE;
13385 break;
13386 case PRAGMA_OACC_CLAUSE_DETACH:
13387 kind = GOMP_MAP_DETACH;
13388 break;
13389 case PRAGMA_OACC_CLAUSE_DEVICE:
13390 kind = GOMP_MAP_FORCE_TO;
13391 break;
13392 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT:
13393 kind = GOMP_MAP_DEVICE_RESIDENT;
13394 break;
13395 case PRAGMA_OACC_CLAUSE_HOST:
13396 kind = GOMP_MAP_FORCE_FROM;
13397 break;
13398 case PRAGMA_OACC_CLAUSE_LINK:
13399 kind = GOMP_MAP_LINK;
13400 break;
13401 case PRAGMA_OACC_CLAUSE_NO_CREATE:
13402 kind = GOMP_MAP_IF_PRESENT;
13403 break;
13404 case PRAGMA_OACC_CLAUSE_PRESENT:
13405 kind = GOMP_MAP_FORCE_PRESENT;
13406 break;
13407 default:
13408 gcc_unreachable ();
13409 }
13410 tree nl, c;
13411 nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_MAP, list, true);
13412
13413 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
13414 OMP_CLAUSE_SET_MAP_KIND (c, kind);
13415
13416 return nl;
13417 }
13418
13419 /* OpenACC 2.0:
13420 deviceptr ( variable-list ) */
13421
13422 static tree
c_parser_oacc_data_clause_deviceptr(c_parser * parser,tree list)13423 c_parser_oacc_data_clause_deviceptr (c_parser *parser, tree list)
13424 {
13425 location_t loc = c_parser_peek_token (parser)->location;
13426 tree vars, t;
13427
13428 /* Can't use OMP_CLAUSE_MAP here (that is, can't use the generic
13429 c_parser_oacc_data_clause), as for PRAGMA_OACC_CLAUSE_DEVICEPTR,
13430 variable-list must only allow for pointer variables. */
13431 vars = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
13432 for (t = vars; t && t; t = TREE_CHAIN (t))
13433 {
13434 tree v = TREE_PURPOSE (t);
13435
13436 /* FIXME diagnostics: Ideally we should keep individual
13437 locations for all the variables in the var list to make the
13438 following errors more precise. Perhaps
13439 c_parser_omp_var_list_parens() should construct a list of
13440 locations to go along with the var list. */
13441
13442 if (!VAR_P (v) && TREE_CODE (v) != PARM_DECL)
13443 error_at (loc, "%qD is not a variable", v);
13444 else if (TREE_TYPE (v) == error_mark_node)
13445 ;
13446 else if (!POINTER_TYPE_P (TREE_TYPE (v)))
13447 error_at (loc, "%qD is not a pointer variable", v);
13448
13449 tree u = build_omp_clause (loc, OMP_CLAUSE_MAP);
13450 OMP_CLAUSE_SET_MAP_KIND (u, GOMP_MAP_FORCE_DEVICEPTR);
13451 OMP_CLAUSE_DECL (u) = v;
13452 OMP_CLAUSE_CHAIN (u) = list;
13453 list = u;
13454 }
13455
13456 return list;
13457 }
13458
13459 /* OpenACC 2.0, OpenMP 3.0:
13460 collapse ( constant-expression ) */
13461
13462 static tree
c_parser_omp_clause_collapse(c_parser * parser,tree list)13463 c_parser_omp_clause_collapse (c_parser *parser, tree list)
13464 {
13465 tree c, num = error_mark_node;
13466 HOST_WIDE_INT n;
13467 location_t loc;
13468
13469 check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse");
13470 check_no_duplicate_clause (list, OMP_CLAUSE_TILE, "tile");
13471
13472 loc = c_parser_peek_token (parser)->location;
13473 matching_parens parens;
13474 if (parens.require_open (parser))
13475 {
13476 num = c_parser_expr_no_commas (parser, NULL).value;
13477 parens.skip_until_found_close (parser);
13478 }
13479 if (num == error_mark_node)
13480 return list;
13481 mark_exp_read (num);
13482 num = c_fully_fold (num, false, NULL);
13483 if (!INTEGRAL_TYPE_P (TREE_TYPE (num))
13484 || !tree_fits_shwi_p (num)
13485 || (n = tree_to_shwi (num)) <= 0
13486 || (int) n != n)
13487 {
13488 error_at (loc,
13489 "collapse argument needs positive constant integer expression");
13490 return list;
13491 }
13492 c = build_omp_clause (loc, OMP_CLAUSE_COLLAPSE);
13493 OMP_CLAUSE_COLLAPSE_EXPR (c) = num;
13494 OMP_CLAUSE_CHAIN (c) = list;
13495 return c;
13496 }
13497
13498 /* OpenMP 2.5:
13499 copyin ( variable-list ) */
13500
13501 static tree
c_parser_omp_clause_copyin(c_parser * parser,tree list)13502 c_parser_omp_clause_copyin (c_parser *parser, tree list)
13503 {
13504 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_COPYIN, list);
13505 }
13506
13507 /* OpenMP 2.5:
13508 copyprivate ( variable-list ) */
13509
13510 static tree
c_parser_omp_clause_copyprivate(c_parser * parser,tree list)13511 c_parser_omp_clause_copyprivate (c_parser *parser, tree list)
13512 {
13513 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_COPYPRIVATE, list);
13514 }
13515
13516 /* OpenMP 2.5:
13517 default ( none | shared )
13518
13519 OpenMP 5.1:
13520 default ( private | firstprivate )
13521
13522 OpenACC:
13523 default ( none | present ) */
13524
13525 static tree
c_parser_omp_clause_default(c_parser * parser,tree list,bool is_oacc)13526 c_parser_omp_clause_default (c_parser *parser, tree list, bool is_oacc)
13527 {
13528 enum omp_clause_default_kind kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED;
13529 location_t loc = c_parser_peek_token (parser)->location;
13530 tree c;
13531
13532 matching_parens parens;
13533 if (!parens.require_open (parser))
13534 return list;
13535 if (c_parser_next_token_is (parser, CPP_NAME))
13536 {
13537 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
13538
13539 switch (p[0])
13540 {
13541 case 'n':
13542 if (strcmp ("none", p) != 0)
13543 goto invalid_kind;
13544 kind = OMP_CLAUSE_DEFAULT_NONE;
13545 break;
13546
13547 case 'p':
13548 if (is_oacc)
13549 {
13550 if (strcmp ("present", p) != 0)
13551 goto invalid_kind;
13552 kind = OMP_CLAUSE_DEFAULT_PRESENT;
13553 }
13554 else
13555 {
13556 if (strcmp ("private", p) != 0)
13557 goto invalid_kind;
13558 kind = OMP_CLAUSE_DEFAULT_PRIVATE;
13559 }
13560 break;
13561
13562 case 'f':
13563 if (strcmp ("firstprivate", p) != 0 || is_oacc)
13564 goto invalid_kind;
13565 kind = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
13566 break;
13567
13568 case 's':
13569 if (strcmp ("shared", p) != 0 || is_oacc)
13570 goto invalid_kind;
13571 kind = OMP_CLAUSE_DEFAULT_SHARED;
13572 break;
13573
13574 default:
13575 goto invalid_kind;
13576 }
13577
13578 c_parser_consume_token (parser);
13579 }
13580 else
13581 {
13582 invalid_kind:
13583 if (is_oacc)
13584 c_parser_error (parser, "expected %<none%> or %<present%>");
13585 else
13586 c_parser_error (parser, "expected %<none%>, %<shared%>, "
13587 "%<private%> or %<firstprivate%>");
13588 }
13589 parens.skip_until_found_close (parser);
13590
13591 if (kind == OMP_CLAUSE_DEFAULT_UNSPECIFIED)
13592 return list;
13593
13594 check_no_duplicate_clause (list, OMP_CLAUSE_DEFAULT, "default");
13595 c = build_omp_clause (loc, OMP_CLAUSE_DEFAULT);
13596 OMP_CLAUSE_CHAIN (c) = list;
13597 OMP_CLAUSE_DEFAULT_KIND (c) = kind;
13598
13599 return c;
13600 }
13601
13602 /* OpenMP 2.5:
13603 firstprivate ( variable-list ) */
13604
13605 static tree
c_parser_omp_clause_firstprivate(c_parser * parser,tree list)13606 c_parser_omp_clause_firstprivate (c_parser *parser, tree list)
13607 {
13608 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_FIRSTPRIVATE, list);
13609 }
13610
13611 /* OpenMP 3.1:
13612 final ( expression ) */
13613
13614 static tree
c_parser_omp_clause_final(c_parser * parser,tree list)13615 c_parser_omp_clause_final (c_parser *parser, tree list)
13616 {
13617 location_t loc = c_parser_peek_token (parser)->location;
13618 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
13619 {
13620 matching_parens parens;
13621 tree t, c;
13622 if (!parens.require_open (parser))
13623 t = error_mark_node;
13624 else
13625 {
13626 location_t eloc = c_parser_peek_token (parser)->location;
13627 c_expr expr = c_parser_expr_no_commas (parser, NULL);
13628 t = convert_lvalue_to_rvalue (eloc, expr, true, true).value;
13629 t = c_objc_common_truthvalue_conversion (eloc, t);
13630 t = c_fully_fold (t, false, NULL);
13631 parens.skip_until_found_close (parser);
13632 }
13633
13634 check_no_duplicate_clause (list, OMP_CLAUSE_FINAL, "final");
13635
13636 c = build_omp_clause (loc, OMP_CLAUSE_FINAL);
13637 OMP_CLAUSE_FINAL_EXPR (c) = t;
13638 OMP_CLAUSE_CHAIN (c) = list;
13639 list = c;
13640 }
13641 else
13642 c_parser_error (parser, "expected %<(%>");
13643
13644 return list;
13645 }
13646
13647 /* OpenACC, OpenMP 2.5:
13648 if ( expression )
13649
13650 OpenMP 4.5:
13651 if ( directive-name-modifier : expression )
13652
13653 directive-name-modifier:
13654 parallel | task | taskloop | target data | target | target update
13655 | target enter data | target exit data
13656
13657 OpenMP 5.0:
13658 directive-name-modifier:
13659 ... | simd | cancel */
13660
13661 static tree
c_parser_omp_clause_if(c_parser * parser,tree list,bool is_omp)13662 c_parser_omp_clause_if (c_parser *parser, tree list, bool is_omp)
13663 {
13664 location_t location = c_parser_peek_token (parser)->location;
13665 enum tree_code if_modifier = ERROR_MARK;
13666
13667 matching_parens parens;
13668 if (!parens.require_open (parser))
13669 return list;
13670
13671 if (is_omp && c_parser_next_token_is (parser, CPP_NAME))
13672 {
13673 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
13674 int n = 2;
13675 if (strcmp (p, "cancel") == 0)
13676 if_modifier = VOID_CST;
13677 else if (strcmp (p, "parallel") == 0)
13678 if_modifier = OMP_PARALLEL;
13679 else if (strcmp (p, "simd") == 0)
13680 if_modifier = OMP_SIMD;
13681 else if (strcmp (p, "task") == 0)
13682 if_modifier = OMP_TASK;
13683 else if (strcmp (p, "taskloop") == 0)
13684 if_modifier = OMP_TASKLOOP;
13685 else if (strcmp (p, "target") == 0)
13686 {
13687 if_modifier = OMP_TARGET;
13688 if (c_parser_peek_2nd_token (parser)->type == CPP_NAME)
13689 {
13690 p = IDENTIFIER_POINTER (c_parser_peek_2nd_token (parser)->value);
13691 if (strcmp ("data", p) == 0)
13692 if_modifier = OMP_TARGET_DATA;
13693 else if (strcmp ("update", p) == 0)
13694 if_modifier = OMP_TARGET_UPDATE;
13695 else if (strcmp ("enter", p) == 0)
13696 if_modifier = OMP_TARGET_ENTER_DATA;
13697 else if (strcmp ("exit", p) == 0)
13698 if_modifier = OMP_TARGET_EXIT_DATA;
13699 if (if_modifier != OMP_TARGET)
13700 {
13701 n = 3;
13702 c_parser_consume_token (parser);
13703 }
13704 else
13705 {
13706 location_t loc = c_parser_peek_2nd_token (parser)->location;
13707 error_at (loc, "expected %<data%>, %<update%>, %<enter%> "
13708 "or %<exit%>");
13709 if_modifier = ERROR_MARK;
13710 }
13711 if (if_modifier == OMP_TARGET_ENTER_DATA
13712 || if_modifier == OMP_TARGET_EXIT_DATA)
13713 {
13714 if (c_parser_peek_2nd_token (parser)->type == CPP_NAME)
13715 {
13716 p = IDENTIFIER_POINTER
13717 (c_parser_peek_2nd_token (parser)->value);
13718 if (strcmp ("data", p) == 0)
13719 n = 4;
13720 }
13721 if (n == 4)
13722 c_parser_consume_token (parser);
13723 else
13724 {
13725 location_t loc
13726 = c_parser_peek_2nd_token (parser)->location;
13727 error_at (loc, "expected %<data%>");
13728 if_modifier = ERROR_MARK;
13729 }
13730 }
13731 }
13732 }
13733 if (if_modifier != ERROR_MARK)
13734 {
13735 if (c_parser_peek_2nd_token (parser)->type == CPP_COLON)
13736 {
13737 c_parser_consume_token (parser);
13738 c_parser_consume_token (parser);
13739 }
13740 else
13741 {
13742 if (n > 2)
13743 {
13744 location_t loc = c_parser_peek_2nd_token (parser)->location;
13745 error_at (loc, "expected %<:%>");
13746 }
13747 if_modifier = ERROR_MARK;
13748 }
13749 }
13750 }
13751
13752 location_t loc = c_parser_peek_token (parser)->location;
13753 c_expr expr = c_parser_expr_no_commas (parser, NULL);
13754 expr = convert_lvalue_to_rvalue (loc, expr, true, true);
13755 tree t = c_objc_common_truthvalue_conversion (loc, expr.value), c;
13756 t = c_fully_fold (t, false, NULL);
13757 parens.skip_until_found_close (parser);
13758
13759 for (c = list; c ; c = OMP_CLAUSE_CHAIN (c))
13760 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IF)
13761 {
13762 if (if_modifier != ERROR_MARK
13763 && OMP_CLAUSE_IF_MODIFIER (c) == if_modifier)
13764 {
13765 const char *p = NULL;
13766 switch (if_modifier)
13767 {
13768 case VOID_CST: p = "cancel"; break;
13769 case OMP_PARALLEL: p = "parallel"; break;
13770 case OMP_SIMD: p = "simd"; break;
13771 case OMP_TASK: p = "task"; break;
13772 case OMP_TASKLOOP: p = "taskloop"; break;
13773 case OMP_TARGET_DATA: p = "target data"; break;
13774 case OMP_TARGET: p = "target"; break;
13775 case OMP_TARGET_UPDATE: p = "target update"; break;
13776 case OMP_TARGET_ENTER_DATA: p = "target enter data"; break;
13777 case OMP_TARGET_EXIT_DATA: p = "target exit data"; break;
13778 default: gcc_unreachable ();
13779 }
13780 error_at (location, "too many %<if%> clauses with %qs modifier",
13781 p);
13782 return list;
13783 }
13784 else if (OMP_CLAUSE_IF_MODIFIER (c) == if_modifier)
13785 {
13786 if (!is_omp)
13787 error_at (location, "too many %<if%> clauses");
13788 else
13789 error_at (location, "too many %<if%> clauses without modifier");
13790 return list;
13791 }
13792 else if (if_modifier == ERROR_MARK
13793 || OMP_CLAUSE_IF_MODIFIER (c) == ERROR_MARK)
13794 {
13795 error_at (location, "if any %<if%> clause has modifier, then all "
13796 "%<if%> clauses have to use modifier");
13797 return list;
13798 }
13799 }
13800
13801 c = build_omp_clause (location, OMP_CLAUSE_IF);
13802 OMP_CLAUSE_IF_MODIFIER (c) = if_modifier;
13803 OMP_CLAUSE_IF_EXPR (c) = t;
13804 OMP_CLAUSE_CHAIN (c) = list;
13805 return c;
13806 }
13807
13808 /* OpenMP 2.5:
13809 lastprivate ( variable-list )
13810
13811 OpenMP 5.0:
13812 lastprivate ( [ lastprivate-modifier : ] variable-list ) */
13813
13814 static tree
c_parser_omp_clause_lastprivate(c_parser * parser,tree list)13815 c_parser_omp_clause_lastprivate (c_parser *parser, tree list)
13816 {
13817 /* The clauses location. */
13818 location_t loc = c_parser_peek_token (parser)->location;
13819
13820 if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
13821 {
13822 bool conditional = false;
13823 if (c_parser_next_token_is (parser, CPP_NAME)
13824 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
13825 {
13826 const char *p
13827 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
13828 if (strcmp (p, "conditional") == 0)
13829 {
13830 conditional = true;
13831 c_parser_consume_token (parser);
13832 c_parser_consume_token (parser);
13833 }
13834 }
13835 tree nlist = c_parser_omp_variable_list (parser, loc,
13836 OMP_CLAUSE_LASTPRIVATE, list);
13837 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
13838 if (conditional)
13839 for (tree c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
13840 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 1;
13841 return nlist;
13842 }
13843 return list;
13844 }
13845
13846 /* OpenMP 3.1:
13847 mergeable */
13848
13849 static tree
c_parser_omp_clause_mergeable(c_parser * parser ATTRIBUTE_UNUSED,tree list)13850 c_parser_omp_clause_mergeable (c_parser *parser ATTRIBUTE_UNUSED, tree list)
13851 {
13852 tree c;
13853
13854 /* FIXME: Should we allow duplicates? */
13855 check_no_duplicate_clause (list, OMP_CLAUSE_MERGEABLE, "mergeable");
13856
13857 c = build_omp_clause (c_parser_peek_token (parser)->location,
13858 OMP_CLAUSE_MERGEABLE);
13859 OMP_CLAUSE_CHAIN (c) = list;
13860
13861 return c;
13862 }
13863
13864 /* OpenMP 2.5:
13865 nowait */
13866
13867 static tree
c_parser_omp_clause_nowait(c_parser * parser ATTRIBUTE_UNUSED,tree list)13868 c_parser_omp_clause_nowait (c_parser *parser ATTRIBUTE_UNUSED, tree list)
13869 {
13870 tree c;
13871 location_t loc = c_parser_peek_token (parser)->location;
13872
13873 check_no_duplicate_clause (list, OMP_CLAUSE_NOWAIT, "nowait");
13874
13875 c = build_omp_clause (loc, OMP_CLAUSE_NOWAIT);
13876 OMP_CLAUSE_CHAIN (c) = list;
13877 return c;
13878 }
13879
13880 /* OpenMP 2.5:
13881 num_threads ( expression ) */
13882
13883 static tree
c_parser_omp_clause_num_threads(c_parser * parser,tree list)13884 c_parser_omp_clause_num_threads (c_parser *parser, tree list)
13885 {
13886 location_t num_threads_loc = c_parser_peek_token (parser)->location;
13887 matching_parens parens;
13888 if (parens.require_open (parser))
13889 {
13890 location_t expr_loc = c_parser_peek_token (parser)->location;
13891 c_expr expr = c_parser_expr_no_commas (parser, NULL);
13892 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
13893 tree c, t = expr.value;
13894 t = c_fully_fold (t, false, NULL);
13895
13896 parens.skip_until_found_close (parser);
13897
13898 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
13899 {
13900 c_parser_error (parser, "expected integer expression");
13901 return list;
13902 }
13903
13904 /* Attempt to statically determine when the number isn't positive. */
13905 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
13906 build_int_cst (TREE_TYPE (t), 0));
13907 protected_set_expr_location (c, expr_loc);
13908 if (c == boolean_true_node)
13909 {
13910 warning_at (expr_loc, 0,
13911 "%<num_threads%> value must be positive");
13912 t = integer_one_node;
13913 }
13914
13915 check_no_duplicate_clause (list, OMP_CLAUSE_NUM_THREADS, "num_threads");
13916
13917 c = build_omp_clause (num_threads_loc, OMP_CLAUSE_NUM_THREADS);
13918 OMP_CLAUSE_NUM_THREADS_EXPR (c) = t;
13919 OMP_CLAUSE_CHAIN (c) = list;
13920 list = c;
13921 }
13922
13923 return list;
13924 }
13925
13926 /* OpenMP 4.5:
13927 num_tasks ( expression )
13928
13929 OpenMP 5.1:
13930 num_tasks ( strict : expression ) */
13931
13932 static tree
c_parser_omp_clause_num_tasks(c_parser * parser,tree list)13933 c_parser_omp_clause_num_tasks (c_parser *parser, tree list)
13934 {
13935 location_t num_tasks_loc = c_parser_peek_token (parser)->location;
13936 matching_parens parens;
13937 if (parens.require_open (parser))
13938 {
13939 bool strict = false;
13940 if (c_parser_next_token_is (parser, CPP_NAME)
13941 && c_parser_peek_2nd_token (parser)->type == CPP_COLON
13942 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
13943 "strict") == 0)
13944 {
13945 strict = true;
13946 c_parser_consume_token (parser);
13947 c_parser_consume_token (parser);
13948 }
13949
13950 location_t expr_loc = c_parser_peek_token (parser)->location;
13951 c_expr expr = c_parser_expr_no_commas (parser, NULL);
13952 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
13953 tree c, t = expr.value;
13954 t = c_fully_fold (t, false, NULL);
13955
13956 parens.skip_until_found_close (parser);
13957
13958 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
13959 {
13960 c_parser_error (parser, "expected integer expression");
13961 return list;
13962 }
13963
13964 /* Attempt to statically determine when the number isn't positive. */
13965 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
13966 build_int_cst (TREE_TYPE (t), 0));
13967 if (CAN_HAVE_LOCATION_P (c))
13968 SET_EXPR_LOCATION (c, expr_loc);
13969 if (c == boolean_true_node)
13970 {
13971 warning_at (expr_loc, 0, "%<num_tasks%> value must be positive");
13972 t = integer_one_node;
13973 }
13974
13975 check_no_duplicate_clause (list, OMP_CLAUSE_NUM_TASKS, "num_tasks");
13976
13977 c = build_omp_clause (num_tasks_loc, OMP_CLAUSE_NUM_TASKS);
13978 OMP_CLAUSE_NUM_TASKS_EXPR (c) = t;
13979 OMP_CLAUSE_NUM_TASKS_STRICT (c) = strict;
13980 OMP_CLAUSE_CHAIN (c) = list;
13981 list = c;
13982 }
13983
13984 return list;
13985 }
13986
13987 /* OpenMP 4.5:
13988 grainsize ( expression )
13989
13990 OpenMP 5.1:
13991 grainsize ( strict : expression ) */
13992
13993 static tree
c_parser_omp_clause_grainsize(c_parser * parser,tree list)13994 c_parser_omp_clause_grainsize (c_parser *parser, tree list)
13995 {
13996 location_t grainsize_loc = c_parser_peek_token (parser)->location;
13997 matching_parens parens;
13998 if (parens.require_open (parser))
13999 {
14000 bool strict = false;
14001 if (c_parser_next_token_is (parser, CPP_NAME)
14002 && c_parser_peek_2nd_token (parser)->type == CPP_COLON
14003 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
14004 "strict") == 0)
14005 {
14006 strict = true;
14007 c_parser_consume_token (parser);
14008 c_parser_consume_token (parser);
14009 }
14010
14011 location_t expr_loc = c_parser_peek_token (parser)->location;
14012 c_expr expr = c_parser_expr_no_commas (parser, NULL);
14013 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14014 tree c, t = expr.value;
14015 t = c_fully_fold (t, false, NULL);
14016
14017 parens.skip_until_found_close (parser);
14018
14019 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14020 {
14021 c_parser_error (parser, "expected integer expression");
14022 return list;
14023 }
14024
14025 /* Attempt to statically determine when the number isn't positive. */
14026 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
14027 build_int_cst (TREE_TYPE (t), 0));
14028 if (CAN_HAVE_LOCATION_P (c))
14029 SET_EXPR_LOCATION (c, expr_loc);
14030 if (c == boolean_true_node)
14031 {
14032 warning_at (expr_loc, 0, "%<grainsize%> value must be positive");
14033 t = integer_one_node;
14034 }
14035
14036 check_no_duplicate_clause (list, OMP_CLAUSE_GRAINSIZE, "grainsize");
14037
14038 c = build_omp_clause (grainsize_loc, OMP_CLAUSE_GRAINSIZE);
14039 OMP_CLAUSE_GRAINSIZE_EXPR (c) = t;
14040 OMP_CLAUSE_GRAINSIZE_STRICT (c) = strict;
14041 OMP_CLAUSE_CHAIN (c) = list;
14042 list = c;
14043 }
14044
14045 return list;
14046 }
14047
14048 /* OpenMP 4.5:
14049 priority ( expression ) */
14050
14051 static tree
c_parser_omp_clause_priority(c_parser * parser,tree list)14052 c_parser_omp_clause_priority (c_parser *parser, tree list)
14053 {
14054 location_t priority_loc = c_parser_peek_token (parser)->location;
14055 matching_parens parens;
14056 if (parens.require_open (parser))
14057 {
14058 location_t expr_loc = c_parser_peek_token (parser)->location;
14059 c_expr expr = c_parser_expr_no_commas (parser, NULL);
14060 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14061 tree c, t = expr.value;
14062 t = c_fully_fold (t, false, NULL);
14063
14064 parens.skip_until_found_close (parser);
14065
14066 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14067 {
14068 c_parser_error (parser, "expected integer expression");
14069 return list;
14070 }
14071
14072 /* Attempt to statically determine when the number isn't
14073 non-negative. */
14074 c = fold_build2_loc (expr_loc, LT_EXPR, boolean_type_node, t,
14075 build_int_cst (TREE_TYPE (t), 0));
14076 if (CAN_HAVE_LOCATION_P (c))
14077 SET_EXPR_LOCATION (c, expr_loc);
14078 if (c == boolean_true_node)
14079 {
14080 warning_at (expr_loc, 0, "%<priority%> value must be non-negative");
14081 t = integer_one_node;
14082 }
14083
14084 check_no_duplicate_clause (list, OMP_CLAUSE_PRIORITY, "priority");
14085
14086 c = build_omp_clause (priority_loc, OMP_CLAUSE_PRIORITY);
14087 OMP_CLAUSE_PRIORITY_EXPR (c) = t;
14088 OMP_CLAUSE_CHAIN (c) = list;
14089 list = c;
14090 }
14091
14092 return list;
14093 }
14094
14095 /* OpenMP 4.5:
14096 hint ( expression ) */
14097
14098 static tree
c_parser_omp_clause_hint(c_parser * parser,tree list)14099 c_parser_omp_clause_hint (c_parser *parser, tree list)
14100 {
14101 location_t hint_loc = c_parser_peek_token (parser)->location;
14102 matching_parens parens;
14103 if (parens.require_open (parser))
14104 {
14105 location_t expr_loc = c_parser_peek_token (parser)->location;
14106 c_expr expr = c_parser_expr_no_commas (parser, NULL);
14107 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14108 tree c, t = expr.value;
14109 t = c_fully_fold (t, false, NULL);
14110 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
14111 || TREE_CODE (t) != INTEGER_CST
14112 || tree_int_cst_sgn (t) == -1)
14113 {
14114 c_parser_error (parser, "expected constant integer expression "
14115 "with valid sync-hint value");
14116 return list;
14117 }
14118 parens.skip_until_found_close (parser);
14119 check_no_duplicate_clause (list, OMP_CLAUSE_HINT, "hint");
14120
14121 c = build_omp_clause (hint_loc, OMP_CLAUSE_HINT);
14122 OMP_CLAUSE_HINT_EXPR (c) = t;
14123 OMP_CLAUSE_CHAIN (c) = list;
14124 list = c;
14125 }
14126
14127 return list;
14128 }
14129
14130 /* OpenMP 5.1:
14131 filter ( integer-expression ) */
14132
14133 static tree
c_parser_omp_clause_filter(c_parser * parser,tree list)14134 c_parser_omp_clause_filter (c_parser *parser, tree list)
14135 {
14136 location_t hint_loc = c_parser_peek_token (parser)->location;
14137 matching_parens parens;
14138 if (parens.require_open (parser))
14139 {
14140 location_t expr_loc = c_parser_peek_token (parser)->location;
14141 c_expr expr = c_parser_expr_no_commas (parser, NULL);
14142 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14143 tree c, t = expr.value;
14144 t = c_fully_fold (t, false, NULL);
14145 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14146 {
14147 c_parser_error (parser, "expected integer expression");
14148 return list;
14149 }
14150 parens.skip_until_found_close (parser);
14151 check_no_duplicate_clause (list, OMP_CLAUSE_FILTER, "filter");
14152
14153 c = build_omp_clause (hint_loc, OMP_CLAUSE_FILTER);
14154 OMP_CLAUSE_FILTER_EXPR (c) = t;
14155 OMP_CLAUSE_CHAIN (c) = list;
14156 list = c;
14157 }
14158
14159 return list;
14160 }
14161
14162 /* OpenMP 4.5:
14163 defaultmap ( tofrom : scalar )
14164
14165 OpenMP 5.0:
14166 defaultmap ( implicit-behavior [ : variable-category ] ) */
14167
14168 static tree
c_parser_omp_clause_defaultmap(c_parser * parser,tree list)14169 c_parser_omp_clause_defaultmap (c_parser *parser, tree list)
14170 {
14171 location_t loc = c_parser_peek_token (parser)->location;
14172 tree c;
14173 const char *p;
14174 enum omp_clause_defaultmap_kind behavior = OMP_CLAUSE_DEFAULTMAP_DEFAULT;
14175 enum omp_clause_defaultmap_kind category
14176 = OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED;
14177
14178 matching_parens parens;
14179 if (!parens.require_open (parser))
14180 return list;
14181 if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
14182 p = "default";
14183 else if (!c_parser_next_token_is (parser, CPP_NAME))
14184 {
14185 invalid_behavior:
14186 c_parser_error (parser, "expected %<alloc%>, %<to%>, %<from%>, "
14187 "%<tofrom%>, %<firstprivate%>, %<none%> "
14188 "or %<default%>");
14189 goto out_err;
14190 }
14191 else
14192 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14193
14194 switch (p[0])
14195 {
14196 case 'a':
14197 if (strcmp ("alloc", p) == 0)
14198 behavior = OMP_CLAUSE_DEFAULTMAP_ALLOC;
14199 else
14200 goto invalid_behavior;
14201 break;
14202
14203 case 'd':
14204 if (strcmp ("default", p) == 0)
14205 behavior = OMP_CLAUSE_DEFAULTMAP_DEFAULT;
14206 else
14207 goto invalid_behavior;
14208 break;
14209
14210 case 'f':
14211 if (strcmp ("firstprivate", p) == 0)
14212 behavior = OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE;
14213 else if (strcmp ("from", p) == 0)
14214 behavior = OMP_CLAUSE_DEFAULTMAP_FROM;
14215 else
14216 goto invalid_behavior;
14217 break;
14218
14219 case 'n':
14220 if (strcmp ("none", p) == 0)
14221 behavior = OMP_CLAUSE_DEFAULTMAP_NONE;
14222 else
14223 goto invalid_behavior;
14224 break;
14225
14226 case 't':
14227 if (strcmp ("tofrom", p) == 0)
14228 behavior = OMP_CLAUSE_DEFAULTMAP_TOFROM;
14229 else if (strcmp ("to", p) == 0)
14230 behavior = OMP_CLAUSE_DEFAULTMAP_TO;
14231 else
14232 goto invalid_behavior;
14233 break;
14234
14235 default:
14236 goto invalid_behavior;
14237 }
14238 c_parser_consume_token (parser);
14239
14240 if (!c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
14241 {
14242 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
14243 goto out_err;
14244 if (!c_parser_next_token_is (parser, CPP_NAME))
14245 {
14246 invalid_category:
14247 c_parser_error (parser, "expected %<scalar%>, %<aggregate%> or "
14248 "%<pointer%>");
14249 goto out_err;
14250 }
14251 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14252 switch (p[0])
14253 {
14254 case 'a':
14255 if (strcmp ("aggregate", p) == 0)
14256 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE;
14257 else
14258 goto invalid_category;
14259 break;
14260
14261 case 'p':
14262 if (strcmp ("pointer", p) == 0)
14263 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER;
14264 else
14265 goto invalid_category;
14266 break;
14267
14268 case 's':
14269 if (strcmp ("scalar", p) == 0)
14270 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR;
14271 else
14272 goto invalid_category;
14273 break;
14274
14275 default:
14276 goto invalid_category;
14277 }
14278
14279 c_parser_consume_token (parser);
14280 }
14281 parens.skip_until_found_close (parser);
14282
14283 for (c = list; c ; c = OMP_CLAUSE_CHAIN (c))
14284 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEFAULTMAP
14285 && (category == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
14286 || OMP_CLAUSE_DEFAULTMAP_CATEGORY (c) == category
14287 || (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c)
14288 == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)))
14289 {
14290 enum omp_clause_defaultmap_kind cat = category;
14291 location_t loc = OMP_CLAUSE_LOCATION (c);
14292 if (cat == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)
14293 cat = OMP_CLAUSE_DEFAULTMAP_CATEGORY (c);
14294 p = NULL;
14295 switch (cat)
14296 {
14297 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED:
14298 p = NULL;
14299 break;
14300 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE:
14301 p = "aggregate";
14302 break;
14303 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER:
14304 p = "pointer";
14305 break;
14306 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR:
14307 p = "scalar";
14308 break;
14309 default:
14310 gcc_unreachable ();
14311 }
14312 if (p)
14313 error_at (loc, "too many %<defaultmap%> clauses with %qs category",
14314 p);
14315 else
14316 error_at (loc, "too many %<defaultmap%> clauses with unspecified "
14317 "category");
14318 break;
14319 }
14320
14321 c = build_omp_clause (loc, OMP_CLAUSE_DEFAULTMAP);
14322 OMP_CLAUSE_DEFAULTMAP_SET_KIND (c, behavior, category);
14323 OMP_CLAUSE_CHAIN (c) = list;
14324 return c;
14325
14326 out_err:
14327 parens.skip_until_found_close (parser);
14328 return list;
14329 }
14330
14331 /* OpenACC 2.0:
14332 use_device ( variable-list )
14333
14334 OpenMP 4.5:
14335 use_device_ptr ( variable-list ) */
14336
14337 static tree
c_parser_omp_clause_use_device_ptr(c_parser * parser,tree list)14338 c_parser_omp_clause_use_device_ptr (c_parser *parser, tree list)
14339 {
14340 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_USE_DEVICE_PTR,
14341 list);
14342 }
14343
14344 /* OpenMP 5.0:
14345 use_device_addr ( variable-list ) */
14346
14347 static tree
c_parser_omp_clause_use_device_addr(c_parser * parser,tree list)14348 c_parser_omp_clause_use_device_addr (c_parser *parser, tree list)
14349 {
14350 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_USE_DEVICE_ADDR,
14351 list);
14352 }
14353
14354 /* OpenMP 5.1:
14355 has_device_addr ( variable-list ) */
14356
14357 static tree
c_parser_omp_clause_has_device_addr(c_parser * parser,tree list)14358 c_parser_omp_clause_has_device_addr (c_parser *parser, tree list)
14359 {
14360 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_HAS_DEVICE_ADDR,
14361 list);
14362 }
14363
14364 /* OpenMP 4.5:
14365 is_device_ptr ( variable-list ) */
14366
14367 static tree
c_parser_omp_clause_is_device_ptr(c_parser * parser,tree list)14368 c_parser_omp_clause_is_device_ptr (c_parser *parser, tree list)
14369 {
14370 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_IS_DEVICE_PTR, list);
14371 }
14372
14373 /* OpenACC:
14374 num_gangs ( expression )
14375 num_workers ( expression )
14376 vector_length ( expression ) */
14377
14378 static tree
c_parser_oacc_single_int_clause(c_parser * parser,omp_clause_code code,tree list)14379 c_parser_oacc_single_int_clause (c_parser *parser, omp_clause_code code,
14380 tree list)
14381 {
14382 location_t loc = c_parser_peek_token (parser)->location;
14383
14384 matching_parens parens;
14385 if (!parens.require_open (parser))
14386 return list;
14387
14388 location_t expr_loc = c_parser_peek_token (parser)->location;
14389 c_expr expr = c_parser_expression (parser);
14390 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14391 tree c, t = expr.value;
14392 t = c_fully_fold (t, false, NULL);
14393
14394 parens.skip_until_found_close (parser);
14395
14396 if (t == error_mark_node)
14397 return list;
14398 else if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14399 {
14400 error_at (expr_loc, "%qs expression must be integral",
14401 omp_clause_code_name[code]);
14402 return list;
14403 }
14404
14405 /* Attempt to statically determine when the number isn't positive. */
14406 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
14407 build_int_cst (TREE_TYPE (t), 0));
14408 protected_set_expr_location (c, expr_loc);
14409 if (c == boolean_true_node)
14410 {
14411 warning_at (expr_loc, 0,
14412 "%qs value must be positive",
14413 omp_clause_code_name[code]);
14414 t = integer_one_node;
14415 }
14416
14417 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
14418
14419 c = build_omp_clause (loc, code);
14420 OMP_CLAUSE_OPERAND (c, 0) = t;
14421 OMP_CLAUSE_CHAIN (c) = list;
14422 return c;
14423 }
14424
14425 /* OpenACC:
14426
14427 gang [( gang-arg-list )]
14428 worker [( [num:] int-expr )]
14429 vector [( [length:] int-expr )]
14430
14431 where gang-arg is one of:
14432
14433 [num:] int-expr
14434 static: size-expr
14435
14436 and size-expr may be:
14437
14438 *
14439 int-expr
14440 */
14441
14442 static tree
c_parser_oacc_shape_clause(c_parser * parser,location_t loc,omp_clause_code kind,const char * str,tree list)14443 c_parser_oacc_shape_clause (c_parser *parser, location_t loc,
14444 omp_clause_code kind,
14445 const char *str, tree list)
14446 {
14447 const char *id = "num";
14448 tree ops[2] = { NULL_TREE, NULL_TREE }, c;
14449
14450 if (kind == OMP_CLAUSE_VECTOR)
14451 id = "length";
14452
14453 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
14454 {
14455 c_parser_consume_token (parser);
14456
14457 do
14458 {
14459 c_token *next = c_parser_peek_token (parser);
14460 int idx = 0;
14461
14462 /* Gang static argument. */
14463 if (kind == OMP_CLAUSE_GANG
14464 && c_parser_next_token_is_keyword (parser, RID_STATIC))
14465 {
14466 c_parser_consume_token (parser);
14467
14468 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
14469 goto cleanup_error;
14470
14471 idx = 1;
14472 if (ops[idx] != NULL_TREE)
14473 {
14474 c_parser_error (parser, "too many %<static%> arguments");
14475 goto cleanup_error;
14476 }
14477
14478 /* Check for the '*' argument. */
14479 if (c_parser_next_token_is (parser, CPP_MULT)
14480 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
14481 || c_parser_peek_2nd_token (parser)->type
14482 == CPP_CLOSE_PAREN))
14483 {
14484 c_parser_consume_token (parser);
14485 ops[idx] = integer_minus_one_node;
14486
14487 if (c_parser_next_token_is (parser, CPP_COMMA))
14488 {
14489 c_parser_consume_token (parser);
14490 continue;
14491 }
14492 else
14493 break;
14494 }
14495 }
14496 /* Worker num: argument and vector length: arguments. */
14497 else if (c_parser_next_token_is (parser, CPP_NAME)
14498 && strcmp (id, IDENTIFIER_POINTER (next->value)) == 0
14499 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
14500 {
14501 c_parser_consume_token (parser); /* id */
14502 c_parser_consume_token (parser); /* ':' */
14503 }
14504
14505 /* Now collect the actual argument. */
14506 if (ops[idx] != NULL_TREE)
14507 {
14508 c_parser_error (parser, "unexpected argument");
14509 goto cleanup_error;
14510 }
14511
14512 location_t expr_loc = c_parser_peek_token (parser)->location;
14513 c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
14514 cexpr = convert_lvalue_to_rvalue (expr_loc, cexpr, false, true);
14515 tree expr = cexpr.value;
14516 if (expr == error_mark_node)
14517 goto cleanup_error;
14518
14519 expr = c_fully_fold (expr, false, NULL);
14520
14521 /* Attempt to statically determine when the number isn't a
14522 positive integer. */
14523
14524 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr)))
14525 {
14526 c_parser_error (parser, "expected integer expression");
14527 return list;
14528 }
14529
14530 tree c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, expr,
14531 build_int_cst (TREE_TYPE (expr), 0));
14532 if (c == boolean_true_node)
14533 {
14534 warning_at (loc, 0,
14535 "%qs value must be positive", str);
14536 expr = integer_one_node;
14537 }
14538
14539 ops[idx] = expr;
14540
14541 if (kind == OMP_CLAUSE_GANG
14542 && c_parser_next_token_is (parser, CPP_COMMA))
14543 {
14544 c_parser_consume_token (parser);
14545 continue;
14546 }
14547 break;
14548 }
14549 while (1);
14550
14551 if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
14552 goto cleanup_error;
14553 }
14554
14555 check_no_duplicate_clause (list, kind, str);
14556
14557 c = build_omp_clause (loc, kind);
14558
14559 if (ops[1])
14560 OMP_CLAUSE_OPERAND (c, 1) = ops[1];
14561
14562 OMP_CLAUSE_OPERAND (c, 0) = ops[0];
14563 OMP_CLAUSE_CHAIN (c) = list;
14564
14565 return c;
14566
14567 cleanup_error:
14568 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
14569 return list;
14570 }
14571
14572 /* OpenACC 2.5:
14573 auto
14574 finalize
14575 independent
14576 nohost
14577 seq */
14578
14579 static tree
c_parser_oacc_simple_clause(location_t loc,enum omp_clause_code code,tree list)14580 c_parser_oacc_simple_clause (location_t loc, enum omp_clause_code code,
14581 tree list)
14582 {
14583 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
14584
14585 tree c = build_omp_clause (loc, code);
14586 OMP_CLAUSE_CHAIN (c) = list;
14587
14588 return c;
14589 }
14590
14591 /* OpenACC:
14592 async [( int-expr )] */
14593
14594 static tree
c_parser_oacc_clause_async(c_parser * parser,tree list)14595 c_parser_oacc_clause_async (c_parser *parser, tree list)
14596 {
14597 tree c, t;
14598 location_t loc = c_parser_peek_token (parser)->location;
14599
14600 t = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL);
14601
14602 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
14603 {
14604 c_parser_consume_token (parser);
14605
14606 t = c_parser_expr_no_commas (parser, NULL).value;
14607 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14608 c_parser_error (parser, "expected integer expression");
14609 else if (t == error_mark_node
14610 || !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
14611 return list;
14612 }
14613 else
14614 t = c_fully_fold (t, false, NULL);
14615
14616 check_no_duplicate_clause (list, OMP_CLAUSE_ASYNC, "async");
14617
14618 c = build_omp_clause (loc, OMP_CLAUSE_ASYNC);
14619 OMP_CLAUSE_ASYNC_EXPR (c) = t;
14620 OMP_CLAUSE_CHAIN (c) = list;
14621 list = c;
14622
14623 return list;
14624 }
14625
14626 /* OpenACC 2.0:
14627 tile ( size-expr-list ) */
14628
14629 static tree
c_parser_oacc_clause_tile(c_parser * parser,tree list)14630 c_parser_oacc_clause_tile (c_parser *parser, tree list)
14631 {
14632 tree c, expr = error_mark_node;
14633 location_t loc;
14634 tree tile = NULL_TREE;
14635
14636 check_no_duplicate_clause (list, OMP_CLAUSE_TILE, "tile");
14637 check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse");
14638
14639 loc = c_parser_peek_token (parser)->location;
14640 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
14641 return list;
14642
14643 do
14644 {
14645 if (tile && !c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
14646 return list;
14647
14648 if (c_parser_next_token_is (parser, CPP_MULT)
14649 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
14650 || c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_PAREN))
14651 {
14652 c_parser_consume_token (parser);
14653 expr = integer_zero_node;
14654 }
14655 else
14656 {
14657 location_t expr_loc = c_parser_peek_token (parser)->location;
14658 c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
14659 cexpr = convert_lvalue_to_rvalue (expr_loc, cexpr, false, true);
14660 expr = cexpr.value;
14661
14662 if (expr == error_mark_node)
14663 {
14664 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
14665 "expected %<)%>");
14666 return list;
14667 }
14668
14669 expr = c_fully_fold (expr, false, NULL);
14670
14671 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr))
14672 || !tree_fits_shwi_p (expr)
14673 || tree_to_shwi (expr) <= 0)
14674 {
14675 error_at (expr_loc, "%<tile%> argument needs positive"
14676 " integral constant");
14677 expr = integer_zero_node;
14678 }
14679 }
14680
14681 tile = tree_cons (NULL_TREE, expr, tile);
14682 }
14683 while (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN));
14684
14685 /* Consume the trailing ')'. */
14686 c_parser_consume_token (parser);
14687
14688 c = build_omp_clause (loc, OMP_CLAUSE_TILE);
14689 tile = nreverse (tile);
14690 OMP_CLAUSE_TILE_LIST (c) = tile;
14691 OMP_CLAUSE_CHAIN (c) = list;
14692 return c;
14693 }
14694
14695 /* OpenACC:
14696 wait [( int-expr-list )] */
14697
14698 static tree
c_parser_oacc_clause_wait(c_parser * parser,tree list)14699 c_parser_oacc_clause_wait (c_parser *parser, tree list)
14700 {
14701 location_t clause_loc = c_parser_peek_token (parser)->location;
14702
14703 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
14704 list = c_parser_oacc_wait_list (parser, clause_loc, list);
14705 else
14706 {
14707 tree c = build_omp_clause (clause_loc, OMP_CLAUSE_WAIT);
14708
14709 OMP_CLAUSE_DECL (c) = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL);
14710 OMP_CLAUSE_CHAIN (c) = list;
14711 list = c;
14712 }
14713
14714 return list;
14715 }
14716
14717
14718 /* OpenMP 5.0:
14719 order ( concurrent )
14720
14721 OpenMP 5.1:
14722 order ( order-modifier : concurrent )
14723
14724 order-modifier:
14725 reproducible
14726 unconstrained */
14727
14728 static tree
c_parser_omp_clause_order(c_parser * parser,tree list)14729 c_parser_omp_clause_order (c_parser *parser, tree list)
14730 {
14731 location_t loc = c_parser_peek_token (parser)->location;
14732 tree c;
14733 const char *p;
14734 bool unconstrained = false;
14735 bool reproducible = false;
14736
14737 matching_parens parens;
14738 if (!parens.require_open (parser))
14739 return list;
14740 if (c_parser_next_token_is (parser, CPP_NAME)
14741 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
14742 {
14743 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14744 if (strcmp (p, "unconstrained") == 0)
14745 unconstrained = true;
14746 else if (strcmp (p, "reproducible") == 0)
14747 reproducible = true;
14748 else
14749 {
14750 c_parser_error (parser, "expected %<reproducible%> or "
14751 "%<unconstrained%>");
14752 goto out_err;
14753 }
14754 c_parser_consume_token (parser);
14755 c_parser_consume_token (parser);
14756 }
14757 if (!c_parser_next_token_is (parser, CPP_NAME))
14758 {
14759 c_parser_error (parser, "expected %<concurrent%>");
14760 goto out_err;
14761 }
14762 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14763 if (strcmp (p, "concurrent") != 0)
14764 {
14765 c_parser_error (parser, "expected %<concurrent%>");
14766 goto out_err;
14767 }
14768 c_parser_consume_token (parser);
14769 parens.skip_until_found_close (parser);
14770 check_no_duplicate_clause (list, OMP_CLAUSE_ORDER, "order");
14771 c = build_omp_clause (loc, OMP_CLAUSE_ORDER);
14772 OMP_CLAUSE_ORDER_UNCONSTRAINED (c) = unconstrained;
14773 OMP_CLAUSE_ORDER_REPRODUCIBLE (c) = reproducible;
14774 OMP_CLAUSE_CHAIN (c) = list;
14775 return c;
14776
14777 out_err:
14778 parens.skip_until_found_close (parser);
14779 return list;
14780 }
14781
14782
14783 /* OpenMP 5.0:
14784 bind ( teams | parallel | thread ) */
14785
14786 static tree
c_parser_omp_clause_bind(c_parser * parser,tree list)14787 c_parser_omp_clause_bind (c_parser *parser, tree list)
14788 {
14789 location_t loc = c_parser_peek_token (parser)->location;
14790 tree c;
14791 const char *p;
14792 enum omp_clause_bind_kind kind = OMP_CLAUSE_BIND_THREAD;
14793
14794 matching_parens parens;
14795 if (!parens.require_open (parser))
14796 return list;
14797 if (!c_parser_next_token_is (parser, CPP_NAME))
14798 {
14799 invalid:
14800 c_parser_error (parser,
14801 "expected %<teams%>, %<parallel%> or %<thread%>");
14802 parens.skip_until_found_close (parser);
14803 return list;
14804 }
14805 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14806 if (strcmp (p, "teams") == 0)
14807 kind = OMP_CLAUSE_BIND_TEAMS;
14808 else if (strcmp (p, "parallel") == 0)
14809 kind = OMP_CLAUSE_BIND_PARALLEL;
14810 else if (strcmp (p, "thread") != 0)
14811 goto invalid;
14812 c_parser_consume_token (parser);
14813 parens.skip_until_found_close (parser);
14814 /* check_no_duplicate_clause (list, OMP_CLAUSE_BIND, "bind"); */
14815 c = build_omp_clause (loc, OMP_CLAUSE_BIND);
14816 OMP_CLAUSE_BIND_KIND (c) = kind;
14817 OMP_CLAUSE_CHAIN (c) = list;
14818 return c;
14819 }
14820
14821
14822 /* OpenMP 2.5:
14823 ordered
14824
14825 OpenMP 4.5:
14826 ordered ( constant-expression ) */
14827
14828 static tree
c_parser_omp_clause_ordered(c_parser * parser,tree list)14829 c_parser_omp_clause_ordered (c_parser *parser, tree list)
14830 {
14831 check_no_duplicate_clause (list, OMP_CLAUSE_ORDERED, "ordered");
14832
14833 tree c, num = NULL_TREE;
14834 HOST_WIDE_INT n;
14835 location_t loc = c_parser_peek_token (parser)->location;
14836 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
14837 {
14838 matching_parens parens;
14839 parens.consume_open (parser);
14840 num = c_parser_expr_no_commas (parser, NULL).value;
14841 parens.skip_until_found_close (parser);
14842 }
14843 if (num == error_mark_node)
14844 return list;
14845 if (num)
14846 {
14847 mark_exp_read (num);
14848 num = c_fully_fold (num, false, NULL);
14849 if (!INTEGRAL_TYPE_P (TREE_TYPE (num))
14850 || !tree_fits_shwi_p (num)
14851 || (n = tree_to_shwi (num)) <= 0
14852 || (int) n != n)
14853 {
14854 error_at (loc, "ordered argument needs positive "
14855 "constant integer expression");
14856 return list;
14857 }
14858 }
14859 c = build_omp_clause (loc, OMP_CLAUSE_ORDERED);
14860 OMP_CLAUSE_ORDERED_EXPR (c) = num;
14861 OMP_CLAUSE_CHAIN (c) = list;
14862 return c;
14863 }
14864
14865 /* OpenMP 2.5:
14866 private ( variable-list ) */
14867
14868 static tree
c_parser_omp_clause_private(c_parser * parser,tree list)14869 c_parser_omp_clause_private (c_parser *parser, tree list)
14870 {
14871 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_PRIVATE, list);
14872 }
14873
14874 /* OpenMP 2.5:
14875 reduction ( reduction-operator : variable-list )
14876
14877 reduction-operator:
14878 One of: + * - & ^ | && ||
14879
14880 OpenMP 3.1:
14881
14882 reduction-operator:
14883 One of: + * - & ^ | && || max min
14884
14885 OpenMP 4.0:
14886
14887 reduction-operator:
14888 One of: + * - & ^ | && ||
14889 identifier
14890
14891 OpenMP 5.0:
14892 reduction ( reduction-modifier, reduction-operator : variable-list )
14893 in_reduction ( reduction-operator : variable-list )
14894 task_reduction ( reduction-operator : variable-list ) */
14895
14896 static tree
c_parser_omp_clause_reduction(c_parser * parser,enum omp_clause_code kind,bool is_omp,tree list)14897 c_parser_omp_clause_reduction (c_parser *parser, enum omp_clause_code kind,
14898 bool is_omp, tree list)
14899 {
14900 location_t clause_loc = c_parser_peek_token (parser)->location;
14901 matching_parens parens;
14902 if (parens.require_open (parser))
14903 {
14904 bool task = false;
14905 bool inscan = false;
14906 enum tree_code code = ERROR_MARK;
14907 tree reduc_id = NULL_TREE;
14908
14909 if (kind == OMP_CLAUSE_REDUCTION && is_omp)
14910 {
14911 if (c_parser_next_token_is_keyword (parser, RID_DEFAULT)
14912 && c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
14913 {
14914 c_parser_consume_token (parser);
14915 c_parser_consume_token (parser);
14916 }
14917 else if (c_parser_next_token_is (parser, CPP_NAME)
14918 && c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
14919 {
14920 const char *p
14921 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14922 if (strcmp (p, "task") == 0)
14923 task = true;
14924 else if (strcmp (p, "inscan") == 0)
14925 inscan = true;
14926 if (task || inscan)
14927 {
14928 c_parser_consume_token (parser);
14929 c_parser_consume_token (parser);
14930 }
14931 }
14932 }
14933
14934 switch (c_parser_peek_token (parser)->type)
14935 {
14936 case CPP_PLUS:
14937 code = PLUS_EXPR;
14938 break;
14939 case CPP_MULT:
14940 code = MULT_EXPR;
14941 break;
14942 case CPP_MINUS:
14943 code = MINUS_EXPR;
14944 break;
14945 case CPP_AND:
14946 code = BIT_AND_EXPR;
14947 break;
14948 case CPP_XOR:
14949 code = BIT_XOR_EXPR;
14950 break;
14951 case CPP_OR:
14952 code = BIT_IOR_EXPR;
14953 break;
14954 case CPP_AND_AND:
14955 code = TRUTH_ANDIF_EXPR;
14956 break;
14957 case CPP_OR_OR:
14958 code = TRUTH_ORIF_EXPR;
14959 break;
14960 case CPP_NAME:
14961 {
14962 const char *p
14963 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14964 if (strcmp (p, "min") == 0)
14965 {
14966 code = MIN_EXPR;
14967 break;
14968 }
14969 if (strcmp (p, "max") == 0)
14970 {
14971 code = MAX_EXPR;
14972 break;
14973 }
14974 reduc_id = c_parser_peek_token (parser)->value;
14975 break;
14976 }
14977 default:
14978 c_parser_error (parser,
14979 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
14980 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
14981 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
14982 return list;
14983 }
14984 c_parser_consume_token (parser);
14985 reduc_id = c_omp_reduction_id (code, reduc_id);
14986 if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
14987 {
14988 tree nl, c;
14989
14990 nl = c_parser_omp_variable_list (parser, clause_loc, kind, list);
14991 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
14992 {
14993 tree d = OMP_CLAUSE_DECL (c), type;
14994 if (TREE_CODE (d) != TREE_LIST)
14995 type = TREE_TYPE (d);
14996 else
14997 {
14998 int cnt = 0;
14999 tree t;
15000 for (t = d; TREE_CODE (t) == TREE_LIST; t = TREE_CHAIN (t))
15001 cnt++;
15002 type = TREE_TYPE (t);
15003 while (cnt > 0)
15004 {
15005 if (TREE_CODE (type) != POINTER_TYPE
15006 && TREE_CODE (type) != ARRAY_TYPE)
15007 break;
15008 type = TREE_TYPE (type);
15009 cnt--;
15010 }
15011 }
15012 while (TREE_CODE (type) == ARRAY_TYPE)
15013 type = TREE_TYPE (type);
15014 OMP_CLAUSE_REDUCTION_CODE (c) = code;
15015 if (task)
15016 OMP_CLAUSE_REDUCTION_TASK (c) = 1;
15017 else if (inscan)
15018 OMP_CLAUSE_REDUCTION_INSCAN (c) = 1;
15019 if (code == ERROR_MARK
15020 || !(INTEGRAL_TYPE_P (type)
15021 || TREE_CODE (type) == REAL_TYPE
15022 || TREE_CODE (type) == COMPLEX_TYPE))
15023 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)
15024 = c_omp_reduction_lookup (reduc_id,
15025 TYPE_MAIN_VARIANT (type));
15026 }
15027
15028 list = nl;
15029 }
15030 parens.skip_until_found_close (parser);
15031 }
15032 return list;
15033 }
15034
15035 /* OpenMP 2.5:
15036 schedule ( schedule-kind )
15037 schedule ( schedule-kind , expression )
15038
15039 schedule-kind:
15040 static | dynamic | guided | runtime | auto
15041
15042 OpenMP 4.5:
15043 schedule ( schedule-modifier : schedule-kind )
15044 schedule ( schedule-modifier [ , schedule-modifier ] : schedule-kind , expression )
15045
15046 schedule-modifier:
15047 simd
15048 monotonic
15049 nonmonotonic */
15050
15051 static tree
c_parser_omp_clause_schedule(c_parser * parser,tree list)15052 c_parser_omp_clause_schedule (c_parser *parser, tree list)
15053 {
15054 tree c, t;
15055 location_t loc = c_parser_peek_token (parser)->location;
15056 int modifiers = 0, nmodifiers = 0;
15057
15058 matching_parens parens;
15059 if (!parens.require_open (parser))
15060 return list;
15061
15062 c = build_omp_clause (loc, OMP_CLAUSE_SCHEDULE);
15063
15064 location_t comma = UNKNOWN_LOCATION;
15065 while (c_parser_next_token_is (parser, CPP_NAME))
15066 {
15067 tree kind = c_parser_peek_token (parser)->value;
15068 const char *p = IDENTIFIER_POINTER (kind);
15069 if (strcmp ("simd", p) == 0)
15070 OMP_CLAUSE_SCHEDULE_SIMD (c) = 1;
15071 else if (strcmp ("monotonic", p) == 0)
15072 modifiers |= OMP_CLAUSE_SCHEDULE_MONOTONIC;
15073 else if (strcmp ("nonmonotonic", p) == 0)
15074 modifiers |= OMP_CLAUSE_SCHEDULE_NONMONOTONIC;
15075 else
15076 break;
15077 comma = UNKNOWN_LOCATION;
15078 c_parser_consume_token (parser);
15079 if (nmodifiers++ == 0
15080 && c_parser_next_token_is (parser, CPP_COMMA))
15081 {
15082 comma = c_parser_peek_token (parser)->location;
15083 c_parser_consume_token (parser);
15084 }
15085 else
15086 {
15087 c_parser_require (parser, CPP_COLON, "expected %<:%>");
15088 break;
15089 }
15090 }
15091 if (comma != UNKNOWN_LOCATION)
15092 error_at (comma, "expected %<:%>");
15093
15094 if ((modifiers & (OMP_CLAUSE_SCHEDULE_MONOTONIC
15095 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC))
15096 == (OMP_CLAUSE_SCHEDULE_MONOTONIC
15097 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC))
15098 {
15099 error_at (loc, "both %<monotonic%> and %<nonmonotonic%> modifiers "
15100 "specified");
15101 modifiers = 0;
15102 }
15103
15104 if (c_parser_next_token_is (parser, CPP_NAME))
15105 {
15106 tree kind = c_parser_peek_token (parser)->value;
15107 const char *p = IDENTIFIER_POINTER (kind);
15108
15109 switch (p[0])
15110 {
15111 case 'd':
15112 if (strcmp ("dynamic", p) != 0)
15113 goto invalid_kind;
15114 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_DYNAMIC;
15115 break;
15116
15117 case 'g':
15118 if (strcmp ("guided", p) != 0)
15119 goto invalid_kind;
15120 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_GUIDED;
15121 break;
15122
15123 case 'r':
15124 if (strcmp ("runtime", p) != 0)
15125 goto invalid_kind;
15126 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_RUNTIME;
15127 break;
15128
15129 default:
15130 goto invalid_kind;
15131 }
15132 }
15133 else if (c_parser_next_token_is_keyword (parser, RID_STATIC))
15134 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_STATIC;
15135 else if (c_parser_next_token_is_keyword (parser, RID_AUTO))
15136 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_AUTO;
15137 else
15138 goto invalid_kind;
15139
15140 c_parser_consume_token (parser);
15141 if (c_parser_next_token_is (parser, CPP_COMMA))
15142 {
15143 location_t here;
15144 c_parser_consume_token (parser);
15145
15146 here = c_parser_peek_token (parser)->location;
15147 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15148 expr = convert_lvalue_to_rvalue (here, expr, false, true);
15149 t = expr.value;
15150 t = c_fully_fold (t, false, NULL);
15151
15152 if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_RUNTIME)
15153 error_at (here, "schedule %<runtime%> does not take "
15154 "a %<chunk_size%> parameter");
15155 else if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_AUTO)
15156 error_at (here,
15157 "schedule %<auto%> does not take "
15158 "a %<chunk_size%> parameter");
15159 else if (TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE)
15160 {
15161 /* Attempt to statically determine when the number isn't
15162 positive. */
15163 tree s = fold_build2_loc (loc, LE_EXPR, boolean_type_node, t,
15164 build_int_cst (TREE_TYPE (t), 0));
15165 protected_set_expr_location (s, loc);
15166 if (s == boolean_true_node)
15167 {
15168 warning_at (loc, 0,
15169 "chunk size value must be positive");
15170 t = integer_one_node;
15171 }
15172 OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = t;
15173 }
15174 else
15175 c_parser_error (parser, "expected integer expression");
15176
15177 parens.skip_until_found_close (parser);
15178 }
15179 else
15180 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
15181 "expected %<,%> or %<)%>");
15182
15183 OMP_CLAUSE_SCHEDULE_KIND (c)
15184 = (enum omp_clause_schedule_kind)
15185 (OMP_CLAUSE_SCHEDULE_KIND (c) | modifiers);
15186
15187 check_no_duplicate_clause (list, OMP_CLAUSE_SCHEDULE, "schedule");
15188 OMP_CLAUSE_CHAIN (c) = list;
15189 return c;
15190
15191 invalid_kind:
15192 c_parser_error (parser, "invalid schedule kind");
15193 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
15194 return list;
15195 }
15196
15197 /* OpenMP 2.5:
15198 shared ( variable-list ) */
15199
15200 static tree
c_parser_omp_clause_shared(c_parser * parser,tree list)15201 c_parser_omp_clause_shared (c_parser *parser, tree list)
15202 {
15203 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_SHARED, list);
15204 }
15205
15206 /* OpenMP 3.0:
15207 untied */
15208
15209 static tree
c_parser_omp_clause_untied(c_parser * parser ATTRIBUTE_UNUSED,tree list)15210 c_parser_omp_clause_untied (c_parser *parser ATTRIBUTE_UNUSED, tree list)
15211 {
15212 tree c;
15213
15214 /* FIXME: Should we allow duplicates? */
15215 check_no_duplicate_clause (list, OMP_CLAUSE_UNTIED, "untied");
15216
15217 c = build_omp_clause (c_parser_peek_token (parser)->location,
15218 OMP_CLAUSE_UNTIED);
15219 OMP_CLAUSE_CHAIN (c) = list;
15220
15221 return c;
15222 }
15223
15224 /* OpenMP 4.0:
15225 inbranch
15226 notinbranch */
15227
15228 static tree
c_parser_omp_clause_branch(c_parser * parser ATTRIBUTE_UNUSED,enum omp_clause_code code,tree list)15229 c_parser_omp_clause_branch (c_parser *parser ATTRIBUTE_UNUSED,
15230 enum omp_clause_code code, tree list)
15231 {
15232 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
15233
15234 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
15235 OMP_CLAUSE_CHAIN (c) = list;
15236
15237 return c;
15238 }
15239
15240 /* OpenMP 4.0:
15241 parallel
15242 for
15243 sections
15244 taskgroup */
15245
15246 static tree
c_parser_omp_clause_cancelkind(c_parser * parser ATTRIBUTE_UNUSED,enum omp_clause_code code,tree list)15247 c_parser_omp_clause_cancelkind (c_parser *parser ATTRIBUTE_UNUSED,
15248 enum omp_clause_code code, tree list)
15249 {
15250 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
15251 OMP_CLAUSE_CHAIN (c) = list;
15252
15253 return c;
15254 }
15255
15256 /* OpenMP 4.5:
15257 nogroup */
15258
15259 static tree
c_parser_omp_clause_nogroup(c_parser * parser ATTRIBUTE_UNUSED,tree list)15260 c_parser_omp_clause_nogroup (c_parser *parser ATTRIBUTE_UNUSED, tree list)
15261 {
15262 check_no_duplicate_clause (list, OMP_CLAUSE_NOGROUP, "nogroup");
15263 tree c = build_omp_clause (c_parser_peek_token (parser)->location,
15264 OMP_CLAUSE_NOGROUP);
15265 OMP_CLAUSE_CHAIN (c) = list;
15266 return c;
15267 }
15268
15269 /* OpenMP 4.5:
15270 simd
15271 threads */
15272
15273 static tree
c_parser_omp_clause_orderedkind(c_parser * parser ATTRIBUTE_UNUSED,enum omp_clause_code code,tree list)15274 c_parser_omp_clause_orderedkind (c_parser *parser ATTRIBUTE_UNUSED,
15275 enum omp_clause_code code, tree list)
15276 {
15277 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
15278 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
15279 OMP_CLAUSE_CHAIN (c) = list;
15280 return c;
15281 }
15282
15283 /* OpenMP 4.0:
15284 num_teams ( expression )
15285
15286 OpenMP 5.1:
15287 num_teams ( expression : expression ) */
15288
15289 static tree
c_parser_omp_clause_num_teams(c_parser * parser,tree list)15290 c_parser_omp_clause_num_teams (c_parser *parser, tree list)
15291 {
15292 location_t num_teams_loc = c_parser_peek_token (parser)->location;
15293 matching_parens parens;
15294 if (parens.require_open (parser))
15295 {
15296 location_t upper_loc = c_parser_peek_token (parser)->location;
15297 location_t lower_loc = UNKNOWN_LOCATION;
15298 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15299 expr = convert_lvalue_to_rvalue (upper_loc, expr, false, true);
15300 tree c, upper = expr.value, lower = NULL_TREE;
15301 upper = c_fully_fold (upper, false, NULL);
15302
15303 if (c_parser_next_token_is (parser, CPP_COLON))
15304 {
15305 c_parser_consume_token (parser);
15306 lower_loc = upper_loc;
15307 lower = upper;
15308 upper_loc = c_parser_peek_token (parser)->location;
15309 expr = c_parser_expr_no_commas (parser, NULL);
15310 expr = convert_lvalue_to_rvalue (upper_loc, expr, false, true);
15311 upper = expr.value;
15312 upper = c_fully_fold (upper, false, NULL);
15313 }
15314
15315 parens.skip_until_found_close (parser);
15316
15317 if (!INTEGRAL_TYPE_P (TREE_TYPE (upper))
15318 || (lower && !INTEGRAL_TYPE_P (TREE_TYPE (lower))))
15319 {
15320 c_parser_error (parser, "expected integer expression");
15321 return list;
15322 }
15323
15324 /* Attempt to statically determine when the number isn't positive. */
15325 c = fold_build2_loc (upper_loc, LE_EXPR, boolean_type_node, upper,
15326 build_int_cst (TREE_TYPE (upper), 0));
15327 protected_set_expr_location (c, upper_loc);
15328 if (c == boolean_true_node)
15329 {
15330 warning_at (upper_loc, 0, "%<num_teams%> value must be positive");
15331 upper = integer_one_node;
15332 }
15333 if (lower)
15334 {
15335 c = fold_build2_loc (lower_loc, LE_EXPR, boolean_type_node, lower,
15336 build_int_cst (TREE_TYPE (lower), 0));
15337 protected_set_expr_location (c, lower_loc);
15338 if (c == boolean_true_node)
15339 {
15340 warning_at (lower_loc, 0, "%<num_teams%> value must be positive");
15341 lower = NULL_TREE;
15342 }
15343 else if (TREE_CODE (lower) == INTEGER_CST
15344 && TREE_CODE (upper) == INTEGER_CST
15345 && tree_int_cst_lt (upper, lower))
15346 {
15347 warning_at (lower_loc, 0, "%<num_teams%> lower bound %qE bigger "
15348 "than upper bound %qE", lower, upper);
15349 lower = NULL_TREE;
15350 }
15351 }
15352
15353 check_no_duplicate_clause (list, OMP_CLAUSE_NUM_TEAMS, "num_teams");
15354
15355 c = build_omp_clause (num_teams_loc, OMP_CLAUSE_NUM_TEAMS);
15356 OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (c) = upper;
15357 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c) = lower;
15358 OMP_CLAUSE_CHAIN (c) = list;
15359 list = c;
15360 }
15361
15362 return list;
15363 }
15364
15365 /* OpenMP 4.0:
15366 thread_limit ( expression ) */
15367
15368 static tree
c_parser_omp_clause_thread_limit(c_parser * parser,tree list)15369 c_parser_omp_clause_thread_limit (c_parser *parser, tree list)
15370 {
15371 location_t num_thread_limit_loc = c_parser_peek_token (parser)->location;
15372 matching_parens parens;
15373 if (parens.require_open (parser))
15374 {
15375 location_t expr_loc = c_parser_peek_token (parser)->location;
15376 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15377 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15378 tree c, t = expr.value;
15379 t = c_fully_fold (t, false, NULL);
15380
15381 parens.skip_until_found_close (parser);
15382
15383 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
15384 {
15385 c_parser_error (parser, "expected integer expression");
15386 return list;
15387 }
15388
15389 /* Attempt to statically determine when the number isn't positive. */
15390 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
15391 build_int_cst (TREE_TYPE (t), 0));
15392 protected_set_expr_location (c, expr_loc);
15393 if (c == boolean_true_node)
15394 {
15395 warning_at (expr_loc, 0, "%<thread_limit%> value must be positive");
15396 t = integer_one_node;
15397 }
15398
15399 check_no_duplicate_clause (list, OMP_CLAUSE_THREAD_LIMIT,
15400 "thread_limit");
15401
15402 c = build_omp_clause (num_thread_limit_loc, OMP_CLAUSE_THREAD_LIMIT);
15403 OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = t;
15404 OMP_CLAUSE_CHAIN (c) = list;
15405 list = c;
15406 }
15407
15408 return list;
15409 }
15410
15411 /* OpenMP 4.0:
15412 aligned ( variable-list )
15413 aligned ( variable-list : constant-expression ) */
15414
15415 static tree
c_parser_omp_clause_aligned(c_parser * parser,tree list)15416 c_parser_omp_clause_aligned (c_parser *parser, tree list)
15417 {
15418 location_t clause_loc = c_parser_peek_token (parser)->location;
15419 tree nl, c;
15420
15421 matching_parens parens;
15422 if (!parens.require_open (parser))
15423 return list;
15424
15425 nl = c_parser_omp_variable_list (parser, clause_loc,
15426 OMP_CLAUSE_ALIGNED, list);
15427
15428 if (c_parser_next_token_is (parser, CPP_COLON))
15429 {
15430 c_parser_consume_token (parser);
15431 location_t expr_loc = c_parser_peek_token (parser)->location;
15432 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15433 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15434 tree alignment = expr.value;
15435 alignment = c_fully_fold (alignment, false, NULL);
15436 if (TREE_CODE (alignment) != INTEGER_CST
15437 || !INTEGRAL_TYPE_P (TREE_TYPE (alignment))
15438 || tree_int_cst_sgn (alignment) != 1)
15439 {
15440 error_at (clause_loc, "%<aligned%> clause alignment expression must "
15441 "be positive constant integer expression");
15442 alignment = NULL_TREE;
15443 }
15444
15445 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
15446 OMP_CLAUSE_ALIGNED_ALIGNMENT (c) = alignment;
15447 }
15448
15449 parens.skip_until_found_close (parser);
15450 return nl;
15451 }
15452
15453 /* OpenMP 5.0:
15454 allocate ( variable-list )
15455 allocate ( expression : variable-list )
15456
15457 OpenMP 5.1:
15458 allocate ( allocator-modifier : variable-list )
15459 allocate ( allocator-modifier , allocator-modifier : variable-list )
15460
15461 allocator-modifier:
15462 allocator ( expression )
15463 align ( expression ) */
15464
15465 static tree
c_parser_omp_clause_allocate(c_parser * parser,tree list)15466 c_parser_omp_clause_allocate (c_parser *parser, tree list)
15467 {
15468 location_t clause_loc = c_parser_peek_token (parser)->location;
15469 tree nl, c;
15470 tree allocator = NULL_TREE;
15471 tree align = NULL_TREE;
15472
15473 matching_parens parens;
15474 if (!parens.require_open (parser))
15475 return list;
15476
15477 if ((c_parser_next_token_is_not (parser, CPP_NAME)
15478 && c_parser_next_token_is_not (parser, CPP_KEYWORD))
15479 || (c_parser_peek_2nd_token (parser)->type != CPP_COMMA
15480 && c_parser_peek_2nd_token (parser)->type != CPP_CLOSE_PAREN))
15481 {
15482 bool has_modifiers = false;
15483 tree orig_type = NULL_TREE;
15484 if (c_parser_next_token_is (parser, CPP_NAME)
15485 && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN)
15486 {
15487 unsigned int n = 3;
15488 const char *p
15489 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
15490 if ((strcmp (p, "allocator") == 0 || strcmp (p, "align") == 0)
15491 && c_parser_check_balanced_raw_token_sequence (parser, &n)
15492 && (c_parser_peek_nth_token_raw (parser, n)->type
15493 == CPP_CLOSE_PAREN))
15494 {
15495 if (c_parser_peek_nth_token_raw (parser, n + 1)->type
15496 == CPP_COLON)
15497 has_modifiers = true;
15498 else if (c_parser_peek_nth_token_raw (parser, n + 1)->type
15499 == CPP_COMMA
15500 && (c_parser_peek_nth_token_raw (parser, n + 2)->type
15501 == CPP_NAME)
15502 && (c_parser_peek_nth_token_raw (parser, n + 3)->type
15503 == CPP_OPEN_PAREN))
15504 {
15505 c_token *tok = c_parser_peek_nth_token_raw (parser, n + 2);
15506 const char *q = IDENTIFIER_POINTER (tok->value);
15507 n += 4;
15508 if ((strcmp (q, "allocator") == 0
15509 || strcmp (q, "align") == 0)
15510 && c_parser_check_balanced_raw_token_sequence (parser,
15511 &n)
15512 && (c_parser_peek_nth_token_raw (parser, n)->type
15513 == CPP_CLOSE_PAREN)
15514 && (c_parser_peek_nth_token_raw (parser, n + 1)->type
15515 == CPP_COLON))
15516 has_modifiers = true;
15517 }
15518 }
15519 if (has_modifiers)
15520 {
15521 c_parser_consume_token (parser);
15522 matching_parens parens2;;
15523 parens2.require_open (parser);
15524 location_t expr_loc = c_parser_peek_token (parser)->location;
15525 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15526 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15527 if (strcmp (p, "allocator") == 0)
15528 {
15529 allocator = expr.value;
15530 allocator = c_fully_fold (allocator, false, NULL);
15531 orig_type = expr.original_type
15532 ? expr.original_type : TREE_TYPE (allocator);
15533 orig_type = TYPE_MAIN_VARIANT (orig_type);
15534 }
15535 else
15536 {
15537 align = expr.value;
15538 align = c_fully_fold (align, false, NULL);
15539 }
15540 parens2.skip_until_found_close (parser);
15541 if (c_parser_next_token_is (parser, CPP_COMMA))
15542 {
15543 c_parser_consume_token (parser);
15544 c_token *tok = c_parser_peek_token (parser);
15545 const char *q = "";
15546 if (c_parser_next_token_is (parser, CPP_NAME))
15547 q = IDENTIFIER_POINTER (tok->value);
15548 if (strcmp (q, "allocator") != 0 && strcmp (q, "align") != 0)
15549 {
15550 c_parser_error (parser, "expected %<allocator%> or "
15551 "%<align%>");
15552 parens.skip_until_found_close (parser);
15553 return list;
15554 }
15555 else if (strcmp (p, q) == 0)
15556 {
15557 error_at (tok->location, "duplicate %qs modifier", p);
15558 parens.skip_until_found_close (parser);
15559 return list;
15560 }
15561 c_parser_consume_token (parser);
15562 if (!parens2.require_open (parser))
15563 {
15564 parens.skip_until_found_close (parser);
15565 return list;
15566 }
15567 expr_loc = c_parser_peek_token (parser)->location;
15568 expr = c_parser_expr_no_commas (parser, NULL);
15569 expr = convert_lvalue_to_rvalue (expr_loc, expr, false,
15570 true);
15571 if (strcmp (q, "allocator") == 0)
15572 {
15573 allocator = expr.value;
15574 allocator = c_fully_fold (allocator, false, NULL);
15575 orig_type = expr.original_type
15576 ? expr.original_type : TREE_TYPE (allocator);
15577 orig_type = TYPE_MAIN_VARIANT (orig_type);
15578 }
15579 else
15580 {
15581 align = expr.value;
15582 align = c_fully_fold (align, false, NULL);
15583 }
15584 parens2.skip_until_found_close (parser);
15585 }
15586 }
15587 }
15588 if (!has_modifiers)
15589 {
15590 location_t expr_loc = c_parser_peek_token (parser)->location;
15591 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15592 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15593 allocator = expr.value;
15594 allocator = c_fully_fold (allocator, false, NULL);
15595 orig_type = expr.original_type
15596 ? expr.original_type : TREE_TYPE (allocator);
15597 orig_type = TYPE_MAIN_VARIANT (orig_type);
15598 }
15599 if (allocator
15600 && (!INTEGRAL_TYPE_P (TREE_TYPE (allocator))
15601 || TREE_CODE (orig_type) != ENUMERAL_TYPE
15602 || (TYPE_NAME (orig_type)
15603 != get_identifier ("omp_allocator_handle_t"))))
15604 {
15605 error_at (clause_loc, "%<allocate%> clause allocator expression "
15606 "has type %qT rather than "
15607 "%<omp_allocator_handle_t%>",
15608 TREE_TYPE (allocator));
15609 allocator = NULL_TREE;
15610 }
15611 if (align
15612 && (!INTEGRAL_TYPE_P (TREE_TYPE (align))
15613 || !tree_fits_uhwi_p (align)
15614 || !integer_pow2p (align)))
15615 {
15616 error_at (clause_loc, "%<allocate%> clause %<align%> modifier "
15617 "argument needs to be positive constant "
15618 "power of two integer expression");
15619 align = NULL_TREE;
15620 }
15621 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
15622 {
15623 parens.skip_until_found_close (parser);
15624 return list;
15625 }
15626 }
15627
15628 nl = c_parser_omp_variable_list (parser, clause_loc,
15629 OMP_CLAUSE_ALLOCATE, list);
15630
15631 if (allocator || align)
15632 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
15633 {
15634 OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) = allocator;
15635 OMP_CLAUSE_ALLOCATE_ALIGN (c) = align;
15636 }
15637
15638 parens.skip_until_found_close (parser);
15639 return nl;
15640 }
15641
15642 /* OpenMP 4.0:
15643 linear ( variable-list )
15644 linear ( variable-list : expression )
15645
15646 OpenMP 4.5:
15647 linear ( modifier ( variable-list ) )
15648 linear ( modifier ( variable-list ) : expression ) */
15649
15650 static tree
c_parser_omp_clause_linear(c_parser * parser,tree list)15651 c_parser_omp_clause_linear (c_parser *parser, tree list)
15652 {
15653 location_t clause_loc = c_parser_peek_token (parser)->location;
15654 tree nl, c, step;
15655 enum omp_clause_linear_kind kind = OMP_CLAUSE_LINEAR_DEFAULT;
15656
15657 matching_parens parens;
15658 if (!parens.require_open (parser))
15659 return list;
15660
15661 if (c_parser_next_token_is (parser, CPP_NAME))
15662 {
15663 c_token *tok = c_parser_peek_token (parser);
15664 const char *p = IDENTIFIER_POINTER (tok->value);
15665 if (strcmp ("val", p) == 0)
15666 kind = OMP_CLAUSE_LINEAR_VAL;
15667 if (c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN)
15668 kind = OMP_CLAUSE_LINEAR_DEFAULT;
15669 if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
15670 {
15671 c_parser_consume_token (parser);
15672 c_parser_consume_token (parser);
15673 }
15674 }
15675
15676 nl = c_parser_omp_variable_list (parser, clause_loc,
15677 OMP_CLAUSE_LINEAR, list);
15678
15679 if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
15680 parens.skip_until_found_close (parser);
15681
15682 if (c_parser_next_token_is (parser, CPP_COLON))
15683 {
15684 c_parser_consume_token (parser);
15685 location_t expr_loc = c_parser_peek_token (parser)->location;
15686 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15687 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15688 step = expr.value;
15689 step = c_fully_fold (step, false, NULL);
15690 if (!INTEGRAL_TYPE_P (TREE_TYPE (step)))
15691 {
15692 error_at (clause_loc, "%<linear%> clause step expression must "
15693 "be integral");
15694 step = integer_one_node;
15695 }
15696
15697 }
15698 else
15699 step = integer_one_node;
15700
15701 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
15702 {
15703 OMP_CLAUSE_LINEAR_STEP (c) = step;
15704 OMP_CLAUSE_LINEAR_KIND (c) = kind;
15705 }
15706
15707 parens.skip_until_found_close (parser);
15708 return nl;
15709 }
15710
15711 /* OpenMP 5.0:
15712 nontemporal ( variable-list ) */
15713
15714 static tree
c_parser_omp_clause_nontemporal(c_parser * parser,tree list)15715 c_parser_omp_clause_nontemporal (c_parser *parser, tree list)
15716 {
15717 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_NONTEMPORAL, list);
15718 }
15719
15720 /* OpenMP 4.0:
15721 safelen ( constant-expression ) */
15722
15723 static tree
c_parser_omp_clause_safelen(c_parser * parser,tree list)15724 c_parser_omp_clause_safelen (c_parser *parser, tree list)
15725 {
15726 location_t clause_loc = c_parser_peek_token (parser)->location;
15727 tree c, t;
15728
15729 matching_parens parens;
15730 if (!parens.require_open (parser))
15731 return list;
15732
15733 location_t expr_loc = c_parser_peek_token (parser)->location;
15734 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15735 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15736 t = expr.value;
15737 t = c_fully_fold (t, false, NULL);
15738 if (TREE_CODE (t) != INTEGER_CST
15739 || !INTEGRAL_TYPE_P (TREE_TYPE (t))
15740 || tree_int_cst_sgn (t) != 1)
15741 {
15742 error_at (clause_loc, "%<safelen%> clause expression must "
15743 "be positive constant integer expression");
15744 t = NULL_TREE;
15745 }
15746
15747 parens.skip_until_found_close (parser);
15748 if (t == NULL_TREE || t == error_mark_node)
15749 return list;
15750
15751 check_no_duplicate_clause (list, OMP_CLAUSE_SAFELEN, "safelen");
15752
15753 c = build_omp_clause (clause_loc, OMP_CLAUSE_SAFELEN);
15754 OMP_CLAUSE_SAFELEN_EXPR (c) = t;
15755 OMP_CLAUSE_CHAIN (c) = list;
15756 return c;
15757 }
15758
15759 /* OpenMP 4.0:
15760 simdlen ( constant-expression ) */
15761
15762 static tree
c_parser_omp_clause_simdlen(c_parser * parser,tree list)15763 c_parser_omp_clause_simdlen (c_parser *parser, tree list)
15764 {
15765 location_t clause_loc = c_parser_peek_token (parser)->location;
15766 tree c, t;
15767
15768 matching_parens parens;
15769 if (!parens.require_open (parser))
15770 return list;
15771
15772 location_t expr_loc = c_parser_peek_token (parser)->location;
15773 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15774 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15775 t = expr.value;
15776 t = c_fully_fold (t, false, NULL);
15777 if (TREE_CODE (t) != INTEGER_CST
15778 || !INTEGRAL_TYPE_P (TREE_TYPE (t))
15779 || tree_int_cst_sgn (t) != 1)
15780 {
15781 error_at (clause_loc, "%<simdlen%> clause expression must "
15782 "be positive constant integer expression");
15783 t = NULL_TREE;
15784 }
15785
15786 parens.skip_until_found_close (parser);
15787 if (t == NULL_TREE || t == error_mark_node)
15788 return list;
15789
15790 check_no_duplicate_clause (list, OMP_CLAUSE_SIMDLEN, "simdlen");
15791
15792 c = build_omp_clause (clause_loc, OMP_CLAUSE_SIMDLEN);
15793 OMP_CLAUSE_SIMDLEN_EXPR (c) = t;
15794 OMP_CLAUSE_CHAIN (c) = list;
15795 return c;
15796 }
15797
15798 /* OpenMP 4.5:
15799 vec:
15800 identifier [+/- integer]
15801 vec , identifier [+/- integer]
15802 */
15803
15804 static tree
c_parser_omp_clause_depend_sink(c_parser * parser,location_t clause_loc,tree list)15805 c_parser_omp_clause_depend_sink (c_parser *parser, location_t clause_loc,
15806 tree list)
15807 {
15808 tree vec = NULL;
15809 if (c_parser_next_token_is_not (parser, CPP_NAME)
15810 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
15811 {
15812 c_parser_error (parser, "expected identifier");
15813 return list;
15814 }
15815
15816 while (c_parser_next_token_is (parser, CPP_NAME)
15817 && c_parser_peek_token (parser)->id_kind == C_ID_ID)
15818 {
15819 tree t = lookup_name (c_parser_peek_token (parser)->value);
15820 tree addend = NULL;
15821
15822 if (t == NULL_TREE)
15823 {
15824 undeclared_variable (c_parser_peek_token (parser)->location,
15825 c_parser_peek_token (parser)->value);
15826 t = error_mark_node;
15827 }
15828
15829 c_parser_consume_token (parser);
15830
15831 bool neg = false;
15832 if (c_parser_next_token_is (parser, CPP_MINUS))
15833 neg = true;
15834 else if (!c_parser_next_token_is (parser, CPP_PLUS))
15835 {
15836 addend = integer_zero_node;
15837 neg = false;
15838 goto add_to_vector;
15839 }
15840 c_parser_consume_token (parser);
15841
15842 if (c_parser_next_token_is_not (parser, CPP_NUMBER))
15843 {
15844 c_parser_error (parser, "expected integer");
15845 return list;
15846 }
15847
15848 addend = c_parser_peek_token (parser)->value;
15849 if (TREE_CODE (addend) != INTEGER_CST)
15850 {
15851 c_parser_error (parser, "expected integer");
15852 return list;
15853 }
15854 c_parser_consume_token (parser);
15855
15856 add_to_vector:
15857 if (t != error_mark_node)
15858 {
15859 vec = tree_cons (addend, t, vec);
15860 if (neg)
15861 OMP_CLAUSE_DEPEND_SINK_NEGATIVE (vec) = 1;
15862 }
15863
15864 if (c_parser_next_token_is_not (parser, CPP_COMMA)
15865 || c_parser_peek_2nd_token (parser)->type != CPP_NAME
15866 || c_parser_peek_2nd_token (parser)->id_kind != C_ID_ID)
15867 break;
15868
15869 c_parser_consume_token (parser);
15870 }
15871
15872 if (vec == NULL_TREE)
15873 return list;
15874
15875 tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DEPEND);
15876 OMP_CLAUSE_DEPEND_KIND (u) = OMP_CLAUSE_DEPEND_SINK;
15877 OMP_CLAUSE_DECL (u) = nreverse (vec);
15878 OMP_CLAUSE_CHAIN (u) = list;
15879 return u;
15880 }
15881
15882 /* OpenMP 5.0:
15883 iterators ( iterators-definition )
15884
15885 iterators-definition:
15886 iterator-specifier
15887 iterator-specifier , iterators-definition
15888
15889 iterator-specifier:
15890 identifier = range-specification
15891 iterator-type identifier = range-specification
15892
15893 range-specification:
15894 begin : end
15895 begin : end : step */
15896
15897 static tree
c_parser_omp_iterators(c_parser * parser)15898 c_parser_omp_iterators (c_parser *parser)
15899 {
15900 tree ret = NULL_TREE, *last = &ret;
15901 c_parser_consume_token (parser);
15902
15903 push_scope ();
15904
15905 matching_parens parens;
15906 if (!parens.require_open (parser))
15907 return error_mark_node;
15908
15909 do
15910 {
15911 tree iter_type = NULL_TREE, type_expr = NULL_TREE;
15912 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
15913 {
15914 struct c_type_name *type = c_parser_type_name (parser);
15915 if (type != NULL)
15916 iter_type = groktypename (type, &type_expr, NULL);
15917 }
15918 if (iter_type == NULL_TREE)
15919 iter_type = integer_type_node;
15920
15921 location_t loc = c_parser_peek_token (parser)->location;
15922 if (!c_parser_next_token_is (parser, CPP_NAME))
15923 {
15924 c_parser_error (parser, "expected identifier");
15925 break;
15926 }
15927
15928 tree id = c_parser_peek_token (parser)->value;
15929 c_parser_consume_token (parser);
15930
15931 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
15932 break;
15933
15934 location_t eloc = c_parser_peek_token (parser)->location;
15935 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15936 expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
15937 tree begin = expr.value;
15938
15939 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
15940 break;
15941
15942 eloc = c_parser_peek_token (parser)->location;
15943 expr = c_parser_expr_no_commas (parser, NULL);
15944 expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
15945 tree end = expr.value;
15946
15947 tree step = integer_one_node;
15948 if (c_parser_next_token_is (parser, CPP_COLON))
15949 {
15950 c_parser_consume_token (parser);
15951 eloc = c_parser_peek_token (parser)->location;
15952 expr = c_parser_expr_no_commas (parser, NULL);
15953 expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
15954 step = expr.value;
15955 }
15956
15957 tree iter_var = build_decl (loc, VAR_DECL, id, iter_type);
15958 DECL_ARTIFICIAL (iter_var) = 1;
15959 DECL_CONTEXT (iter_var) = current_function_decl;
15960 pushdecl (iter_var);
15961
15962 *last = make_tree_vec (6);
15963 TREE_VEC_ELT (*last, 0) = iter_var;
15964 TREE_VEC_ELT (*last, 1) = begin;
15965 TREE_VEC_ELT (*last, 2) = end;
15966 TREE_VEC_ELT (*last, 3) = step;
15967 last = &TREE_CHAIN (*last);
15968
15969 if (c_parser_next_token_is (parser, CPP_COMMA))
15970 {
15971 c_parser_consume_token (parser);
15972 continue;
15973 }
15974 break;
15975 }
15976 while (1);
15977
15978 parens.skip_until_found_close (parser);
15979 return ret ? ret : error_mark_node;
15980 }
15981
15982 /* OpenMP 5.0:
15983 affinity ( [aff-modifier :] variable-list )
15984 aff-modifier:
15985 iterator ( iterators-definition ) */
15986
15987 static tree
c_parser_omp_clause_affinity(c_parser * parser,tree list)15988 c_parser_omp_clause_affinity (c_parser *parser, tree list)
15989 {
15990 location_t clause_loc = c_parser_peek_token (parser)->location;
15991 tree nl, iterators = NULL_TREE;
15992
15993 matching_parens parens;
15994 if (!parens.require_open (parser))
15995 return list;
15996
15997 if (c_parser_next_token_is (parser, CPP_NAME))
15998 {
15999 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16000 bool parse_iter = ((strcmp ("iterator", p) == 0)
16001 && (c_parser_peek_2nd_token (parser)->type
16002 == CPP_OPEN_PAREN));
16003 if (parse_iter)
16004 {
16005 unsigned n = 3;
16006 parse_iter = (c_parser_check_balanced_raw_token_sequence (parser, &n)
16007 && (c_parser_peek_nth_token_raw (parser, n)->type
16008 == CPP_CLOSE_PAREN)
16009 && (c_parser_peek_nth_token_raw (parser, n + 1)->type
16010 == CPP_COLON));
16011 }
16012 if (parse_iter)
16013 {
16014 iterators = c_parser_omp_iterators (parser);
16015 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
16016 {
16017 if (iterators)
16018 pop_scope ();
16019 parens.skip_until_found_close (parser);
16020 return list;
16021 }
16022 }
16023 }
16024 nl = c_parser_omp_variable_list (parser, clause_loc, OMP_CLAUSE_AFFINITY,
16025 list);
16026 if (iterators)
16027 {
16028 tree block = pop_scope ();
16029 if (iterators != error_mark_node)
16030 {
16031 TREE_VEC_ELT (iterators, 5) = block;
16032 for (tree c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
16033 OMP_CLAUSE_DECL (c) = build_tree_list (iterators,
16034 OMP_CLAUSE_DECL (c));
16035 }
16036 }
16037
16038 parens.skip_until_found_close (parser);
16039 return nl;
16040 }
16041
16042
16043 /* OpenMP 4.0:
16044 depend ( depend-kind: variable-list )
16045
16046 depend-kind:
16047 in | out | inout
16048
16049 OpenMP 4.5:
16050 depend ( source )
16051
16052 depend ( sink : vec )
16053
16054 OpenMP 5.0:
16055 depend ( depend-modifier , depend-kind: variable-list )
16056
16057 depend-kind:
16058 in | out | inout | mutexinoutset | depobj
16059
16060 depend-modifier:
16061 iterator ( iterators-definition ) */
16062
16063 static tree
c_parser_omp_clause_depend(c_parser * parser,tree list)16064 c_parser_omp_clause_depend (c_parser *parser, tree list)
16065 {
16066 location_t clause_loc = c_parser_peek_token (parser)->location;
16067 enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_LAST;
16068 tree nl, c, iterators = NULL_TREE;
16069
16070 matching_parens parens;
16071 if (!parens.require_open (parser))
16072 return list;
16073
16074 do
16075 {
16076 if (c_parser_next_token_is_not (parser, CPP_NAME))
16077 goto invalid_kind;
16078
16079 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16080 if (strcmp ("iterator", p) == 0 && iterators == NULL_TREE)
16081 {
16082 iterators = c_parser_omp_iterators (parser);
16083 c_parser_require (parser, CPP_COMMA, "expected %<,%>");
16084 continue;
16085 }
16086 if (strcmp ("in", p) == 0)
16087 kind = OMP_CLAUSE_DEPEND_IN;
16088 else if (strcmp ("inout", p) == 0)
16089 kind = OMP_CLAUSE_DEPEND_INOUT;
16090 else if (strcmp ("mutexinoutset", p) == 0)
16091 kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET;
16092 else if (strcmp ("out", p) == 0)
16093 kind = OMP_CLAUSE_DEPEND_OUT;
16094 else if (strcmp ("depobj", p) == 0)
16095 kind = OMP_CLAUSE_DEPEND_DEPOBJ;
16096 else if (strcmp ("sink", p) == 0)
16097 kind = OMP_CLAUSE_DEPEND_SINK;
16098 else if (strcmp ("source", p) == 0)
16099 kind = OMP_CLAUSE_DEPEND_SOURCE;
16100 else
16101 goto invalid_kind;
16102 break;
16103 }
16104 while (1);
16105
16106 c_parser_consume_token (parser);
16107
16108 if (iterators
16109 && (kind == OMP_CLAUSE_DEPEND_SOURCE || kind == OMP_CLAUSE_DEPEND_SINK))
16110 {
16111 pop_scope ();
16112 error_at (clause_loc, "%<iterator%> modifier incompatible with %qs",
16113 kind == OMP_CLAUSE_DEPEND_SOURCE ? "source" : "sink");
16114 iterators = NULL_TREE;
16115 }
16116
16117 if (kind == OMP_CLAUSE_DEPEND_SOURCE)
16118 {
16119 c = build_omp_clause (clause_loc, OMP_CLAUSE_DEPEND);
16120 OMP_CLAUSE_DEPEND_KIND (c) = kind;
16121 OMP_CLAUSE_DECL (c) = NULL_TREE;
16122 OMP_CLAUSE_CHAIN (c) = list;
16123 parens.skip_until_found_close (parser);
16124 return c;
16125 }
16126
16127 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
16128 goto resync_fail;
16129
16130 if (kind == OMP_CLAUSE_DEPEND_SINK)
16131 nl = c_parser_omp_clause_depend_sink (parser, clause_loc, list);
16132 else
16133 {
16134 nl = c_parser_omp_variable_list (parser, clause_loc,
16135 OMP_CLAUSE_DEPEND, list);
16136
16137 if (iterators)
16138 {
16139 tree block = pop_scope ();
16140 if (iterators == error_mark_node)
16141 iterators = NULL_TREE;
16142 else
16143 TREE_VEC_ELT (iterators, 5) = block;
16144 }
16145
16146 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
16147 {
16148 OMP_CLAUSE_DEPEND_KIND (c) = kind;
16149 if (iterators)
16150 OMP_CLAUSE_DECL (c)
16151 = build_tree_list (iterators, OMP_CLAUSE_DECL (c));
16152 }
16153 }
16154
16155 parens.skip_until_found_close (parser);
16156 return nl;
16157
16158 invalid_kind:
16159 c_parser_error (parser, "invalid depend kind");
16160 resync_fail:
16161 parens.skip_until_found_close (parser);
16162 if (iterators)
16163 pop_scope ();
16164 return list;
16165 }
16166
16167 /* OpenMP 4.0:
16168 map ( map-kind: variable-list )
16169 map ( variable-list )
16170
16171 map-kind:
16172 alloc | to | from | tofrom
16173
16174 OpenMP 4.5:
16175 map-kind:
16176 alloc | to | from | tofrom | release | delete
16177
16178 map ( always [,] map-kind: variable-list )
16179
16180 OpenMP 5.0:
16181 map ( [map-type-modifier[,] ...] map-kind: variable-list )
16182
16183 map-type-modifier:
16184 always | close */
16185
16186 static tree
c_parser_omp_clause_map(c_parser * parser,tree list)16187 c_parser_omp_clause_map (c_parser *parser, tree list)
16188 {
16189 location_t clause_loc = c_parser_peek_token (parser)->location;
16190 enum gomp_map_kind kind = GOMP_MAP_TOFROM;
16191 tree nl, c;
16192
16193 matching_parens parens;
16194 if (!parens.require_open (parser))
16195 return list;
16196
16197 int pos = 1;
16198 int map_kind_pos = 0;
16199 while (c_parser_peek_nth_token_raw (parser, pos)->type == CPP_NAME)
16200 {
16201 if (c_parser_peek_nth_token_raw (parser, pos + 1)->type == CPP_COLON)
16202 {
16203 map_kind_pos = pos;
16204 break;
16205 }
16206
16207 if (c_parser_peek_nth_token_raw (parser, pos + 1)->type == CPP_COMMA)
16208 pos++;
16209 pos++;
16210 }
16211
16212 int always_modifier = 0;
16213 int close_modifier = 0;
16214 for (int pos = 1; pos < map_kind_pos; ++pos)
16215 {
16216 c_token *tok = c_parser_peek_token (parser);
16217
16218 if (tok->type == CPP_COMMA)
16219 {
16220 c_parser_consume_token (parser);
16221 continue;
16222 }
16223
16224 const char *p = IDENTIFIER_POINTER (tok->value);
16225 if (strcmp ("always", p) == 0)
16226 {
16227 if (always_modifier)
16228 {
16229 c_parser_error (parser, "too many %<always%> modifiers");
16230 parens.skip_until_found_close (parser);
16231 return list;
16232 }
16233 always_modifier++;
16234 }
16235 else if (strcmp ("close", p) == 0)
16236 {
16237 if (close_modifier)
16238 {
16239 c_parser_error (parser, "too many %<close%> modifiers");
16240 parens.skip_until_found_close (parser);
16241 return list;
16242 }
16243 close_modifier++;
16244 }
16245 else
16246 {
16247 c_parser_error (parser, "%<#pragma omp target%> with "
16248 "modifier other than %<always%> or "
16249 "%<close%> on %<map%> clause");
16250 parens.skip_until_found_close (parser);
16251 return list;
16252 }
16253
16254 c_parser_consume_token (parser);
16255 }
16256
16257 if (c_parser_next_token_is (parser, CPP_NAME)
16258 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
16259 {
16260 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16261 if (strcmp ("alloc", p) == 0)
16262 kind = GOMP_MAP_ALLOC;
16263 else if (strcmp ("to", p) == 0)
16264 kind = always_modifier ? GOMP_MAP_ALWAYS_TO : GOMP_MAP_TO;
16265 else if (strcmp ("from", p) == 0)
16266 kind = always_modifier ? GOMP_MAP_ALWAYS_FROM : GOMP_MAP_FROM;
16267 else if (strcmp ("tofrom", p) == 0)
16268 kind = always_modifier ? GOMP_MAP_ALWAYS_TOFROM : GOMP_MAP_TOFROM;
16269 else if (strcmp ("release", p) == 0)
16270 kind = GOMP_MAP_RELEASE;
16271 else if (strcmp ("delete", p) == 0)
16272 kind = GOMP_MAP_DELETE;
16273 else
16274 {
16275 c_parser_error (parser, "invalid map kind");
16276 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
16277 "expected %<)%>");
16278 return list;
16279 }
16280 c_parser_consume_token (parser);
16281 c_parser_consume_token (parser);
16282 }
16283
16284 nl = c_parser_omp_variable_list (parser, clause_loc, OMP_CLAUSE_MAP, list,
16285 true);
16286
16287 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
16288 OMP_CLAUSE_SET_MAP_KIND (c, kind);
16289
16290 parens.skip_until_found_close (parser);
16291 return nl;
16292 }
16293
16294 /* OpenMP 4.0:
16295 device ( expression )
16296
16297 OpenMP 5.0:
16298 device ( [device-modifier :] integer-expression )
16299
16300 device-modifier:
16301 ancestor | device_num */
16302
16303 static tree
c_parser_omp_clause_device(c_parser * parser,tree list)16304 c_parser_omp_clause_device (c_parser *parser, tree list)
16305 {
16306 location_t clause_loc = c_parser_peek_token (parser)->location;
16307 location_t expr_loc;
16308 c_expr expr;
16309 tree c, t;
16310 bool ancestor = false;
16311
16312 matching_parens parens;
16313 if (!parens.require_open (parser))
16314 return list;
16315
16316 if (c_parser_next_token_is (parser, CPP_NAME)
16317 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
16318 {
16319 c_token *tok = c_parser_peek_token (parser);
16320 const char *p = IDENTIFIER_POINTER (tok->value);
16321 if (strcmp ("ancestor", p) == 0)
16322 {
16323 /* A requires directive with the reverse_offload clause must be
16324 specified. */
16325 if ((omp_requires_mask & OMP_REQUIRES_REVERSE_OFFLOAD) == 0)
16326 {
16327 error_at (tok->location, "%<ancestor%> device modifier not "
16328 "preceded by %<requires%> directive "
16329 "with %<reverse_offload%> clause");
16330 parens.skip_until_found_close (parser);
16331 return list;
16332 }
16333 ancestor = true;
16334 }
16335 else if (strcmp ("device_num", p) == 0)
16336 ;
16337 else
16338 {
16339 error_at (tok->location, "expected %<ancestor%> or %<device_num%>");
16340 parens.skip_until_found_close (parser);
16341 return list;
16342 }
16343 c_parser_consume_token (parser);
16344 c_parser_consume_token (parser);
16345 }
16346
16347 expr_loc = c_parser_peek_token (parser)->location;
16348 expr = c_parser_expr_no_commas (parser, NULL);
16349 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
16350 t = expr.value;
16351 t = c_fully_fold (t, false, NULL);
16352
16353 parens.skip_until_found_close (parser);
16354
16355 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
16356 {
16357 c_parser_error (parser, "expected integer expression");
16358 return list;
16359 }
16360 if (ancestor && TREE_CODE (t) == INTEGER_CST && !integer_onep (t))
16361 {
16362 error_at (expr_loc, "the %<device%> clause expression must evaluate to "
16363 "%<1%>");
16364 return list;
16365 }
16366
16367 check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE, "device");
16368
16369 c = build_omp_clause (clause_loc, OMP_CLAUSE_DEVICE);
16370
16371 OMP_CLAUSE_DEVICE_ID (c) = t;
16372 OMP_CLAUSE_CHAIN (c) = list;
16373 OMP_CLAUSE_DEVICE_ANCESTOR (c) = ancestor;
16374
16375 list = c;
16376 return list;
16377 }
16378
16379 /* OpenMP 4.0:
16380 dist_schedule ( static )
16381 dist_schedule ( static , expression ) */
16382
16383 static tree
c_parser_omp_clause_dist_schedule(c_parser * parser,tree list)16384 c_parser_omp_clause_dist_schedule (c_parser *parser, tree list)
16385 {
16386 tree c, t = NULL_TREE;
16387 location_t loc = c_parser_peek_token (parser)->location;
16388
16389 matching_parens parens;
16390 if (!parens.require_open (parser))
16391 return list;
16392
16393 if (!c_parser_next_token_is_keyword (parser, RID_STATIC))
16394 {
16395 c_parser_error (parser, "invalid dist_schedule kind");
16396 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
16397 "expected %<)%>");
16398 return list;
16399 }
16400
16401 c_parser_consume_token (parser);
16402 if (c_parser_next_token_is (parser, CPP_COMMA))
16403 {
16404 c_parser_consume_token (parser);
16405
16406 location_t expr_loc = c_parser_peek_token (parser)->location;
16407 c_expr expr = c_parser_expr_no_commas (parser, NULL);
16408 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
16409 t = expr.value;
16410 t = c_fully_fold (t, false, NULL);
16411 parens.skip_until_found_close (parser);
16412 }
16413 else
16414 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
16415 "expected %<,%> or %<)%>");
16416
16417 /* check_no_duplicate_clause (list, OMP_CLAUSE_DIST_SCHEDULE,
16418 "dist_schedule"); */
16419 if (omp_find_clause (list, OMP_CLAUSE_DIST_SCHEDULE))
16420 warning_at (loc, 0, "too many %qs clauses", "dist_schedule");
16421 if (t == error_mark_node)
16422 return list;
16423
16424 c = build_omp_clause (loc, OMP_CLAUSE_DIST_SCHEDULE);
16425 OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c) = t;
16426 OMP_CLAUSE_CHAIN (c) = list;
16427 return c;
16428 }
16429
16430 /* OpenMP 4.0:
16431 proc_bind ( proc-bind-kind )
16432
16433 proc-bind-kind:
16434 primary | master | close | spread
16435 where OpenMP 5.1 added 'primary' and deprecated the alias 'master'. */
16436
16437 static tree
c_parser_omp_clause_proc_bind(c_parser * parser,tree list)16438 c_parser_omp_clause_proc_bind (c_parser *parser, tree list)
16439 {
16440 location_t clause_loc = c_parser_peek_token (parser)->location;
16441 enum omp_clause_proc_bind_kind kind;
16442 tree c;
16443
16444 matching_parens parens;
16445 if (!parens.require_open (parser))
16446 return list;
16447
16448 if (c_parser_next_token_is (parser, CPP_NAME))
16449 {
16450 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16451 if (strcmp ("primary", p) == 0)
16452 kind = OMP_CLAUSE_PROC_BIND_PRIMARY;
16453 else if (strcmp ("master", p) == 0)
16454 kind = OMP_CLAUSE_PROC_BIND_MASTER;
16455 else if (strcmp ("close", p) == 0)
16456 kind = OMP_CLAUSE_PROC_BIND_CLOSE;
16457 else if (strcmp ("spread", p) == 0)
16458 kind = OMP_CLAUSE_PROC_BIND_SPREAD;
16459 else
16460 goto invalid_kind;
16461 }
16462 else
16463 goto invalid_kind;
16464
16465 check_no_duplicate_clause (list, OMP_CLAUSE_PROC_BIND, "proc_bind");
16466 c_parser_consume_token (parser);
16467 parens.skip_until_found_close (parser);
16468 c = build_omp_clause (clause_loc, OMP_CLAUSE_PROC_BIND);
16469 OMP_CLAUSE_PROC_BIND_KIND (c) = kind;
16470 OMP_CLAUSE_CHAIN (c) = list;
16471 return c;
16472
16473 invalid_kind:
16474 c_parser_error (parser, "invalid proc_bind kind");
16475 parens.skip_until_found_close (parser);
16476 return list;
16477 }
16478
16479 /* OpenMP 5.0:
16480 device_type ( host | nohost | any ) */
16481
16482 static tree
c_parser_omp_clause_device_type(c_parser * parser,tree list)16483 c_parser_omp_clause_device_type (c_parser *parser, tree list)
16484 {
16485 location_t clause_loc = c_parser_peek_token (parser)->location;
16486 enum omp_clause_device_type_kind kind;
16487 tree c;
16488
16489 matching_parens parens;
16490 if (!parens.require_open (parser))
16491 return list;
16492
16493 if (c_parser_next_token_is (parser, CPP_NAME))
16494 {
16495 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16496 if (strcmp ("host", p) == 0)
16497 kind = OMP_CLAUSE_DEVICE_TYPE_HOST;
16498 else if (strcmp ("nohost", p) == 0)
16499 kind = OMP_CLAUSE_DEVICE_TYPE_NOHOST;
16500 else if (strcmp ("any", p) == 0)
16501 kind = OMP_CLAUSE_DEVICE_TYPE_ANY;
16502 else
16503 goto invalid_kind;
16504 }
16505 else
16506 goto invalid_kind;
16507
16508 /* check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE_TYPE,
16509 "device_type"); */
16510 c_parser_consume_token (parser);
16511 parens.skip_until_found_close (parser);
16512 c = build_omp_clause (clause_loc, OMP_CLAUSE_DEVICE_TYPE);
16513 OMP_CLAUSE_DEVICE_TYPE_KIND (c) = kind;
16514 OMP_CLAUSE_CHAIN (c) = list;
16515 return c;
16516
16517 invalid_kind:
16518 c_parser_error (parser, "expected %<host%>, %<nohost%> or %<any%>");
16519 parens.skip_until_found_close (parser);
16520 return list;
16521 }
16522
16523 /* OpenMP 4.0:
16524 to ( variable-list ) */
16525
16526 static tree
c_parser_omp_clause_to(c_parser * parser,tree list)16527 c_parser_omp_clause_to (c_parser *parser, tree list)
16528 {
16529 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_TO, list, true);
16530 }
16531
16532 /* OpenMP 4.0:
16533 from ( variable-list ) */
16534
16535 static tree
c_parser_omp_clause_from(c_parser * parser,tree list)16536 c_parser_omp_clause_from (c_parser *parser, tree list)
16537 {
16538 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_FROM, list, true);
16539 }
16540
16541 /* OpenMP 4.0:
16542 uniform ( variable-list ) */
16543
16544 static tree
c_parser_omp_clause_uniform(c_parser * parser,tree list)16545 c_parser_omp_clause_uniform (c_parser *parser, tree list)
16546 {
16547 /* The clauses location. */
16548 location_t loc = c_parser_peek_token (parser)->location;
16549
16550 matching_parens parens;
16551 if (parens.require_open (parser))
16552 {
16553 list = c_parser_omp_variable_list (parser, loc, OMP_CLAUSE_UNIFORM,
16554 list);
16555 parens.skip_until_found_close (parser);
16556 }
16557 return list;
16558 }
16559
16560 /* OpenMP 5.0:
16561 detach ( event-handle ) */
16562
16563 static tree
c_parser_omp_clause_detach(c_parser * parser,tree list)16564 c_parser_omp_clause_detach (c_parser *parser, tree list)
16565 {
16566 matching_parens parens;
16567 location_t clause_loc = c_parser_peek_token (parser)->location;
16568
16569 if (!parens.require_open (parser))
16570 return list;
16571
16572 if (c_parser_next_token_is_not (parser, CPP_NAME)
16573 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
16574 {
16575 c_parser_error (parser, "expected identifier");
16576 parens.skip_until_found_close (parser);
16577 return list;
16578 }
16579
16580 tree t = lookup_name (c_parser_peek_token (parser)->value);
16581 if (t == NULL_TREE)
16582 {
16583 undeclared_variable (c_parser_peek_token (parser)->location,
16584 c_parser_peek_token (parser)->value);
16585 parens.skip_until_found_close (parser);
16586 return list;
16587 }
16588 c_parser_consume_token (parser);
16589
16590 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (t));
16591 if (!INTEGRAL_TYPE_P (type)
16592 || TREE_CODE (type) != ENUMERAL_TYPE
16593 || TYPE_NAME (type) != get_identifier ("omp_event_handle_t"))
16594 {
16595 error_at (clause_loc, "%<detach%> clause event handle "
16596 "has type %qT rather than "
16597 "%<omp_event_handle_t%>",
16598 type);
16599 parens.skip_until_found_close (parser);
16600 return list;
16601 }
16602
16603 tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DETACH);
16604 OMP_CLAUSE_DECL (u) = t;
16605 OMP_CLAUSE_CHAIN (u) = list;
16606 parens.skip_until_found_close (parser);
16607 return u;
16608 }
16609
16610 /* Parse all OpenACC clauses. The set clauses allowed by the directive
16611 is a bitmask in MASK. Return the list of clauses found. */
16612
16613 static tree
c_parser_oacc_all_clauses(c_parser * parser,omp_clause_mask mask,const char * where,bool finish_p=true)16614 c_parser_oacc_all_clauses (c_parser *parser, omp_clause_mask mask,
16615 const char *where, bool finish_p = true)
16616 {
16617 tree clauses = NULL;
16618 bool first = true;
16619
16620 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
16621 {
16622 location_t here;
16623 pragma_omp_clause c_kind;
16624 const char *c_name;
16625 tree prev = clauses;
16626
16627 if (!first && c_parser_next_token_is (parser, CPP_COMMA))
16628 c_parser_consume_token (parser);
16629
16630 here = c_parser_peek_token (parser)->location;
16631 c_kind = c_parser_omp_clause_name (parser);
16632
16633 switch (c_kind)
16634 {
16635 case PRAGMA_OACC_CLAUSE_ASYNC:
16636 clauses = c_parser_oacc_clause_async (parser, clauses);
16637 c_name = "async";
16638 break;
16639 case PRAGMA_OACC_CLAUSE_AUTO:
16640 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_AUTO,
16641 clauses);
16642 c_name = "auto";
16643 break;
16644 case PRAGMA_OACC_CLAUSE_ATTACH:
16645 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16646 c_name = "attach";
16647 break;
16648 case PRAGMA_OACC_CLAUSE_COLLAPSE:
16649 clauses = c_parser_omp_clause_collapse (parser, clauses);
16650 c_name = "collapse";
16651 break;
16652 case PRAGMA_OACC_CLAUSE_COPY:
16653 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16654 c_name = "copy";
16655 break;
16656 case PRAGMA_OACC_CLAUSE_COPYIN:
16657 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16658 c_name = "copyin";
16659 break;
16660 case PRAGMA_OACC_CLAUSE_COPYOUT:
16661 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16662 c_name = "copyout";
16663 break;
16664 case PRAGMA_OACC_CLAUSE_CREATE:
16665 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16666 c_name = "create";
16667 break;
16668 case PRAGMA_OACC_CLAUSE_DELETE:
16669 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16670 c_name = "delete";
16671 break;
16672 case PRAGMA_OMP_CLAUSE_DEFAULT:
16673 clauses = c_parser_omp_clause_default (parser, clauses, true);
16674 c_name = "default";
16675 break;
16676 case PRAGMA_OACC_CLAUSE_DETACH:
16677 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16678 c_name = "detach";
16679 break;
16680 case PRAGMA_OACC_CLAUSE_DEVICE:
16681 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16682 c_name = "device";
16683 break;
16684 case PRAGMA_OACC_CLAUSE_DEVICEPTR:
16685 clauses = c_parser_oacc_data_clause_deviceptr (parser, clauses);
16686 c_name = "deviceptr";
16687 break;
16688 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT:
16689 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16690 c_name = "device_resident";
16691 break;
16692 case PRAGMA_OACC_CLAUSE_FINALIZE:
16693 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_FINALIZE,
16694 clauses);
16695 c_name = "finalize";
16696 break;
16697 case PRAGMA_OACC_CLAUSE_FIRSTPRIVATE:
16698 clauses = c_parser_omp_clause_firstprivate (parser, clauses);
16699 c_name = "firstprivate";
16700 break;
16701 case PRAGMA_OACC_CLAUSE_GANG:
16702 c_name = "gang";
16703 clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_GANG,
16704 c_name, clauses);
16705 break;
16706 case PRAGMA_OACC_CLAUSE_HOST:
16707 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16708 c_name = "host";
16709 break;
16710 case PRAGMA_OACC_CLAUSE_IF:
16711 clauses = c_parser_omp_clause_if (parser, clauses, false);
16712 c_name = "if";
16713 break;
16714 case PRAGMA_OACC_CLAUSE_IF_PRESENT:
16715 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_IF_PRESENT,
16716 clauses);
16717 c_name = "if_present";
16718 break;
16719 case PRAGMA_OACC_CLAUSE_INDEPENDENT:
16720 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_INDEPENDENT,
16721 clauses);
16722 c_name = "independent";
16723 break;
16724 case PRAGMA_OACC_CLAUSE_LINK:
16725 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16726 c_name = "link";
16727 break;
16728 case PRAGMA_OACC_CLAUSE_NO_CREATE:
16729 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16730 c_name = "no_create";
16731 break;
16732 case PRAGMA_OACC_CLAUSE_NOHOST:
16733 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_NOHOST,
16734 clauses);
16735 c_name = "nohost";
16736 break;
16737 case PRAGMA_OACC_CLAUSE_NUM_GANGS:
16738 clauses = c_parser_oacc_single_int_clause (parser,
16739 OMP_CLAUSE_NUM_GANGS,
16740 clauses);
16741 c_name = "num_gangs";
16742 break;
16743 case PRAGMA_OACC_CLAUSE_NUM_WORKERS:
16744 clauses = c_parser_oacc_single_int_clause (parser,
16745 OMP_CLAUSE_NUM_WORKERS,
16746 clauses);
16747 c_name = "num_workers";
16748 break;
16749 case PRAGMA_OACC_CLAUSE_PRESENT:
16750 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16751 c_name = "present";
16752 break;
16753 case PRAGMA_OACC_CLAUSE_PRIVATE:
16754 clauses = c_parser_omp_clause_private (parser, clauses);
16755 c_name = "private";
16756 break;
16757 case PRAGMA_OACC_CLAUSE_REDUCTION:
16758 clauses
16759 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
16760 false, clauses);
16761 c_name = "reduction";
16762 break;
16763 case PRAGMA_OACC_CLAUSE_SEQ:
16764 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_SEQ,
16765 clauses);
16766 c_name = "seq";
16767 break;
16768 case PRAGMA_OACC_CLAUSE_TILE:
16769 clauses = c_parser_oacc_clause_tile (parser, clauses);
16770 c_name = "tile";
16771 break;
16772 case PRAGMA_OACC_CLAUSE_USE_DEVICE:
16773 clauses = c_parser_omp_clause_use_device_ptr (parser, clauses);
16774 c_name = "use_device";
16775 break;
16776 case PRAGMA_OACC_CLAUSE_VECTOR:
16777 c_name = "vector";
16778 clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_VECTOR,
16779 c_name, clauses);
16780 break;
16781 case PRAGMA_OACC_CLAUSE_VECTOR_LENGTH:
16782 clauses = c_parser_oacc_single_int_clause (parser,
16783 OMP_CLAUSE_VECTOR_LENGTH,
16784 clauses);
16785 c_name = "vector_length";
16786 break;
16787 case PRAGMA_OACC_CLAUSE_WAIT:
16788 clauses = c_parser_oacc_clause_wait (parser, clauses);
16789 c_name = "wait";
16790 break;
16791 case PRAGMA_OACC_CLAUSE_WORKER:
16792 c_name = "worker";
16793 clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_WORKER,
16794 c_name, clauses);
16795 break;
16796 default:
16797 c_parser_error (parser, "expected %<#pragma acc%> clause");
16798 goto saw_error;
16799 }
16800
16801 first = false;
16802
16803 if (((mask >> c_kind) & 1) == 0)
16804 {
16805 /* Remove the invalid clause(s) from the list to avoid
16806 confusing the rest of the compiler. */
16807 clauses = prev;
16808 error_at (here, "%qs is not valid for %qs", c_name, where);
16809 }
16810 }
16811
16812 saw_error:
16813 c_parser_skip_to_pragma_eol (parser);
16814
16815 if (finish_p)
16816 return c_finish_omp_clauses (clauses, C_ORT_ACC);
16817
16818 return clauses;
16819 }
16820
16821 /* Parse all OpenMP clauses. The set clauses allowed by the directive
16822 is a bitmask in MASK. Return the list of clauses found.
16823 FINISH_P set if c_finish_omp_clauses should be called.
16824 NESTED non-zero if clauses should be terminated by closing paren instead
16825 of end of pragma. If it is 2, additionally commas are required in between
16826 the clauses. */
16827
16828 static tree
c_parser_omp_all_clauses(c_parser * parser,omp_clause_mask mask,const char * where,bool finish_p=true,int nested=0)16829 c_parser_omp_all_clauses (c_parser *parser, omp_clause_mask mask,
16830 const char *where, bool finish_p = true,
16831 int nested = 0)
16832 {
16833 tree clauses = NULL;
16834 bool first = true;
16835
16836 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
16837 {
16838 location_t here;
16839 pragma_omp_clause c_kind;
16840 const char *c_name;
16841 tree prev = clauses;
16842
16843 if (nested && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
16844 break;
16845
16846 if (!first)
16847 {
16848 if (c_parser_next_token_is (parser, CPP_COMMA))
16849 c_parser_consume_token (parser);
16850 else if (nested == 2)
16851 error_at (c_parser_peek_token (parser)->location,
16852 "clauses in %<simd%> trait should be separated "
16853 "by %<,%>");
16854 }
16855
16856 here = c_parser_peek_token (parser)->location;
16857 c_kind = c_parser_omp_clause_name (parser);
16858
16859 switch (c_kind)
16860 {
16861 case PRAGMA_OMP_CLAUSE_BIND:
16862 clauses = c_parser_omp_clause_bind (parser, clauses);
16863 c_name = "bind";
16864 break;
16865 case PRAGMA_OMP_CLAUSE_COLLAPSE:
16866 clauses = c_parser_omp_clause_collapse (parser, clauses);
16867 c_name = "collapse";
16868 break;
16869 case PRAGMA_OMP_CLAUSE_COPYIN:
16870 clauses = c_parser_omp_clause_copyin (parser, clauses);
16871 c_name = "copyin";
16872 break;
16873 case PRAGMA_OMP_CLAUSE_COPYPRIVATE:
16874 clauses = c_parser_omp_clause_copyprivate (parser, clauses);
16875 c_name = "copyprivate";
16876 break;
16877 case PRAGMA_OMP_CLAUSE_DEFAULT:
16878 clauses = c_parser_omp_clause_default (parser, clauses, false);
16879 c_name = "default";
16880 break;
16881 case PRAGMA_OMP_CLAUSE_DETACH:
16882 clauses = c_parser_omp_clause_detach (parser, clauses);
16883 c_name = "detach";
16884 break;
16885 case PRAGMA_OMP_CLAUSE_FILTER:
16886 clauses = c_parser_omp_clause_filter (parser, clauses);
16887 c_name = "filter";
16888 break;
16889 case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE:
16890 clauses = c_parser_omp_clause_firstprivate (parser, clauses);
16891 c_name = "firstprivate";
16892 break;
16893 case PRAGMA_OMP_CLAUSE_FINAL:
16894 clauses = c_parser_omp_clause_final (parser, clauses);
16895 c_name = "final";
16896 break;
16897 case PRAGMA_OMP_CLAUSE_GRAINSIZE:
16898 clauses = c_parser_omp_clause_grainsize (parser, clauses);
16899 c_name = "grainsize";
16900 break;
16901 case PRAGMA_OMP_CLAUSE_HINT:
16902 clauses = c_parser_omp_clause_hint (parser, clauses);
16903 c_name = "hint";
16904 break;
16905 case PRAGMA_OMP_CLAUSE_DEFAULTMAP:
16906 clauses = c_parser_omp_clause_defaultmap (parser, clauses);
16907 c_name = "defaultmap";
16908 break;
16909 case PRAGMA_OMP_CLAUSE_IF:
16910 clauses = c_parser_omp_clause_if (parser, clauses, true);
16911 c_name = "if";
16912 break;
16913 case PRAGMA_OMP_CLAUSE_IN_REDUCTION:
16914 clauses
16915 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_IN_REDUCTION,
16916 true, clauses);
16917 c_name = "in_reduction";
16918 break;
16919 case PRAGMA_OMP_CLAUSE_LASTPRIVATE:
16920 clauses = c_parser_omp_clause_lastprivate (parser, clauses);
16921 c_name = "lastprivate";
16922 break;
16923 case PRAGMA_OMP_CLAUSE_MERGEABLE:
16924 clauses = c_parser_omp_clause_mergeable (parser, clauses);
16925 c_name = "mergeable";
16926 break;
16927 case PRAGMA_OMP_CLAUSE_NOWAIT:
16928 clauses = c_parser_omp_clause_nowait (parser, clauses);
16929 c_name = "nowait";
16930 break;
16931 case PRAGMA_OMP_CLAUSE_NUM_TASKS:
16932 clauses = c_parser_omp_clause_num_tasks (parser, clauses);
16933 c_name = "num_tasks";
16934 break;
16935 case PRAGMA_OMP_CLAUSE_NUM_THREADS:
16936 clauses = c_parser_omp_clause_num_threads (parser, clauses);
16937 c_name = "num_threads";
16938 break;
16939 case PRAGMA_OMP_CLAUSE_ORDER:
16940 clauses = c_parser_omp_clause_order (parser, clauses);
16941 c_name = "order";
16942 break;
16943 case PRAGMA_OMP_CLAUSE_ORDERED:
16944 clauses = c_parser_omp_clause_ordered (parser, clauses);
16945 c_name = "ordered";
16946 break;
16947 case PRAGMA_OMP_CLAUSE_PRIORITY:
16948 clauses = c_parser_omp_clause_priority (parser, clauses);
16949 c_name = "priority";
16950 break;
16951 case PRAGMA_OMP_CLAUSE_PRIVATE:
16952 clauses = c_parser_omp_clause_private (parser, clauses);
16953 c_name = "private";
16954 break;
16955 case PRAGMA_OMP_CLAUSE_REDUCTION:
16956 clauses
16957 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
16958 true, clauses);
16959 c_name = "reduction";
16960 break;
16961 case PRAGMA_OMP_CLAUSE_SCHEDULE:
16962 clauses = c_parser_omp_clause_schedule (parser, clauses);
16963 c_name = "schedule";
16964 break;
16965 case PRAGMA_OMP_CLAUSE_SHARED:
16966 clauses = c_parser_omp_clause_shared (parser, clauses);
16967 c_name = "shared";
16968 break;
16969 case PRAGMA_OMP_CLAUSE_TASK_REDUCTION:
16970 clauses
16971 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_TASK_REDUCTION,
16972 true, clauses);
16973 c_name = "task_reduction";
16974 break;
16975 case PRAGMA_OMP_CLAUSE_UNTIED:
16976 clauses = c_parser_omp_clause_untied (parser, clauses);
16977 c_name = "untied";
16978 break;
16979 case PRAGMA_OMP_CLAUSE_INBRANCH:
16980 clauses = c_parser_omp_clause_branch (parser, OMP_CLAUSE_INBRANCH,
16981 clauses);
16982 c_name = "inbranch";
16983 break;
16984 case PRAGMA_OMP_CLAUSE_NONTEMPORAL:
16985 clauses = c_parser_omp_clause_nontemporal (parser, clauses);
16986 c_name = "nontemporal";
16987 break;
16988 case PRAGMA_OMP_CLAUSE_NOTINBRANCH:
16989 clauses = c_parser_omp_clause_branch (parser, OMP_CLAUSE_NOTINBRANCH,
16990 clauses);
16991 c_name = "notinbranch";
16992 break;
16993 case PRAGMA_OMP_CLAUSE_PARALLEL:
16994 clauses
16995 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_PARALLEL,
16996 clauses);
16997 c_name = "parallel";
16998 if (!first)
16999 {
17000 clause_not_first:
17001 error_at (here, "%qs must be the first clause of %qs",
17002 c_name, where);
17003 clauses = prev;
17004 }
17005 break;
17006 case PRAGMA_OMP_CLAUSE_FOR:
17007 clauses
17008 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_FOR,
17009 clauses);
17010 c_name = "for";
17011 if (!first)
17012 goto clause_not_first;
17013 break;
17014 case PRAGMA_OMP_CLAUSE_SECTIONS:
17015 clauses
17016 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_SECTIONS,
17017 clauses);
17018 c_name = "sections";
17019 if (!first)
17020 goto clause_not_first;
17021 break;
17022 case PRAGMA_OMP_CLAUSE_TASKGROUP:
17023 clauses
17024 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_TASKGROUP,
17025 clauses);
17026 c_name = "taskgroup";
17027 if (!first)
17028 goto clause_not_first;
17029 break;
17030 case PRAGMA_OMP_CLAUSE_LINK:
17031 clauses
17032 = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_LINK, clauses);
17033 c_name = "link";
17034 break;
17035 case PRAGMA_OMP_CLAUSE_TO:
17036 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK)) != 0)
17037 clauses
17038 = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_TO_DECLARE,
17039 clauses);
17040 else
17041 clauses = c_parser_omp_clause_to (parser, clauses);
17042 c_name = "to";
17043 break;
17044 case PRAGMA_OMP_CLAUSE_FROM:
17045 clauses = c_parser_omp_clause_from (parser, clauses);
17046 c_name = "from";
17047 break;
17048 case PRAGMA_OMP_CLAUSE_UNIFORM:
17049 clauses = c_parser_omp_clause_uniform (parser, clauses);
17050 c_name = "uniform";
17051 break;
17052 case PRAGMA_OMP_CLAUSE_NUM_TEAMS:
17053 clauses = c_parser_omp_clause_num_teams (parser, clauses);
17054 c_name = "num_teams";
17055 break;
17056 case PRAGMA_OMP_CLAUSE_THREAD_LIMIT:
17057 clauses = c_parser_omp_clause_thread_limit (parser, clauses);
17058 c_name = "thread_limit";
17059 break;
17060 case PRAGMA_OMP_CLAUSE_ALIGNED:
17061 clauses = c_parser_omp_clause_aligned (parser, clauses);
17062 c_name = "aligned";
17063 break;
17064 case PRAGMA_OMP_CLAUSE_ALLOCATE:
17065 clauses = c_parser_omp_clause_allocate (parser, clauses);
17066 c_name = "allocate";
17067 break;
17068 case PRAGMA_OMP_CLAUSE_LINEAR:
17069 clauses = c_parser_omp_clause_linear (parser, clauses);
17070 c_name = "linear";
17071 break;
17072 case PRAGMA_OMP_CLAUSE_AFFINITY:
17073 clauses = c_parser_omp_clause_affinity (parser, clauses);
17074 c_name = "affinity";
17075 break;
17076 case PRAGMA_OMP_CLAUSE_DEPEND:
17077 clauses = c_parser_omp_clause_depend (parser, clauses);
17078 c_name = "depend";
17079 break;
17080 case PRAGMA_OMP_CLAUSE_MAP:
17081 clauses = c_parser_omp_clause_map (parser, clauses);
17082 c_name = "map";
17083 break;
17084 case PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR:
17085 clauses = c_parser_omp_clause_use_device_ptr (parser, clauses);
17086 c_name = "use_device_ptr";
17087 break;
17088 case PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR:
17089 clauses = c_parser_omp_clause_use_device_addr (parser, clauses);
17090 c_name = "use_device_addr";
17091 break;
17092 case PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR:
17093 clauses = c_parser_omp_clause_has_device_addr (parser, clauses);
17094 c_name = "has_device_addr";
17095 break;
17096 case PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR:
17097 clauses = c_parser_omp_clause_is_device_ptr (parser, clauses);
17098 c_name = "is_device_ptr";
17099 break;
17100 case PRAGMA_OMP_CLAUSE_DEVICE:
17101 clauses = c_parser_omp_clause_device (parser, clauses);
17102 c_name = "device";
17103 break;
17104 case PRAGMA_OMP_CLAUSE_DIST_SCHEDULE:
17105 clauses = c_parser_omp_clause_dist_schedule (parser, clauses);
17106 c_name = "dist_schedule";
17107 break;
17108 case PRAGMA_OMP_CLAUSE_PROC_BIND:
17109 clauses = c_parser_omp_clause_proc_bind (parser, clauses);
17110 c_name = "proc_bind";
17111 break;
17112 case PRAGMA_OMP_CLAUSE_DEVICE_TYPE:
17113 clauses = c_parser_omp_clause_device_type (parser, clauses);
17114 c_name = "device_type";
17115 break;
17116 case PRAGMA_OMP_CLAUSE_SAFELEN:
17117 clauses = c_parser_omp_clause_safelen (parser, clauses);
17118 c_name = "safelen";
17119 break;
17120 case PRAGMA_OMP_CLAUSE_SIMDLEN:
17121 clauses = c_parser_omp_clause_simdlen (parser, clauses);
17122 c_name = "simdlen";
17123 break;
17124 case PRAGMA_OMP_CLAUSE_NOGROUP:
17125 clauses = c_parser_omp_clause_nogroup (parser, clauses);
17126 c_name = "nogroup";
17127 break;
17128 case PRAGMA_OMP_CLAUSE_THREADS:
17129 clauses
17130 = c_parser_omp_clause_orderedkind (parser, OMP_CLAUSE_THREADS,
17131 clauses);
17132 c_name = "threads";
17133 break;
17134 case PRAGMA_OMP_CLAUSE_SIMD:
17135 clauses
17136 = c_parser_omp_clause_orderedkind (parser, OMP_CLAUSE_SIMD,
17137 clauses);
17138 c_name = "simd";
17139 break;
17140 default:
17141 c_parser_error (parser, "expected %<#pragma omp%> clause");
17142 goto saw_error;
17143 }
17144
17145 first = false;
17146
17147 if (((mask >> c_kind) & 1) == 0)
17148 {
17149 /* Remove the invalid clause(s) from the list to avoid
17150 confusing the rest of the compiler. */
17151 clauses = prev;
17152 error_at (here, "%qs is not valid for %qs", c_name, where);
17153 }
17154 }
17155
17156 saw_error:
17157 if (!nested)
17158 c_parser_skip_to_pragma_eol (parser);
17159
17160 if (finish_p)
17161 {
17162 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM)) != 0)
17163 return c_finish_omp_clauses (clauses, C_ORT_OMP_DECLARE_SIMD);
17164 return c_finish_omp_clauses (clauses, C_ORT_OMP);
17165 }
17166
17167 return clauses;
17168 }
17169
17170 /* OpenACC 2.0, OpenMP 2.5:
17171 structured-block:
17172 statement
17173
17174 In practice, we're also interested in adding the statement to an
17175 outer node. So it is convenient if we work around the fact that
17176 c_parser_statement calls add_stmt. */
17177
17178 static tree
c_parser_omp_structured_block(c_parser * parser,bool * if_p)17179 c_parser_omp_structured_block (c_parser *parser, bool *if_p)
17180 {
17181 tree stmt = push_stmt_list ();
17182 c_parser_statement (parser, if_p);
17183 return pop_stmt_list (stmt);
17184 }
17185
17186 /* OpenACC 2.0:
17187 # pragma acc cache (variable-list) new-line
17188
17189 LOC is the location of the #pragma token.
17190 */
17191
17192 static tree
c_parser_oacc_cache(location_t loc,c_parser * parser)17193 c_parser_oacc_cache (location_t loc, c_parser *parser)
17194 {
17195 tree stmt, clauses;
17196
17197 clauses = c_parser_omp_var_list_parens (parser, OMP_CLAUSE__CACHE_, NULL);
17198 clauses = c_finish_omp_clauses (clauses, C_ORT_ACC);
17199
17200 c_parser_skip_to_pragma_eol (parser);
17201
17202 stmt = make_node (OACC_CACHE);
17203 TREE_TYPE (stmt) = void_type_node;
17204 OACC_CACHE_CLAUSES (stmt) = clauses;
17205 SET_EXPR_LOCATION (stmt, loc);
17206 add_stmt (stmt);
17207
17208 return stmt;
17209 }
17210
17211 /* OpenACC 2.0:
17212 # pragma acc data oacc-data-clause[optseq] new-line
17213 structured-block
17214
17215 LOC is the location of the #pragma token.
17216 */
17217
17218 #define OACC_DATA_CLAUSE_MASK \
17219 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
17220 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
17221 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17222 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17223 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17224 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
17225 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17226 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
17227 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
17228
17229 static tree
c_parser_oacc_data(location_t loc,c_parser * parser,bool * if_p)17230 c_parser_oacc_data (location_t loc, c_parser *parser, bool *if_p)
17231 {
17232 tree stmt, clauses, block;
17233
17234 clauses = c_parser_oacc_all_clauses (parser, OACC_DATA_CLAUSE_MASK,
17235 "#pragma acc data");
17236
17237 block = c_begin_omp_parallel ();
17238 add_stmt (c_parser_omp_structured_block (parser, if_p));
17239
17240 stmt = c_finish_oacc_data (loc, clauses, block);
17241
17242 return stmt;
17243 }
17244
17245 /* OpenACC 2.0:
17246 # pragma acc declare oacc-data-clause[optseq] new-line
17247 */
17248
17249 #define OACC_DECLARE_CLAUSE_MASK \
17250 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
17251 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17252 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17253 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17254 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
17255 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT) \
17256 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_LINK) \
17257 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
17258
17259 static void
c_parser_oacc_declare(c_parser * parser)17260 c_parser_oacc_declare (c_parser *parser)
17261 {
17262 location_t pragma_loc = c_parser_peek_token (parser)->location;
17263 tree clauses, stmt, t, decl;
17264
17265 bool error = false;
17266
17267 c_parser_consume_pragma (parser);
17268
17269 clauses = c_parser_oacc_all_clauses (parser, OACC_DECLARE_CLAUSE_MASK,
17270 "#pragma acc declare");
17271 if (!clauses)
17272 {
17273 error_at (pragma_loc,
17274 "no valid clauses specified in %<#pragma acc declare%>");
17275 return;
17276 }
17277
17278 for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t))
17279 {
17280 location_t loc = OMP_CLAUSE_LOCATION (t);
17281 decl = OMP_CLAUSE_DECL (t);
17282 if (!DECL_P (decl))
17283 {
17284 error_at (loc, "array section in %<#pragma acc declare%>");
17285 error = true;
17286 continue;
17287 }
17288
17289 switch (OMP_CLAUSE_MAP_KIND (t))
17290 {
17291 case GOMP_MAP_FIRSTPRIVATE_POINTER:
17292 case GOMP_MAP_ALLOC:
17293 case GOMP_MAP_TO:
17294 case GOMP_MAP_FORCE_DEVICEPTR:
17295 case GOMP_MAP_DEVICE_RESIDENT:
17296 break;
17297
17298 case GOMP_MAP_LINK:
17299 if (!global_bindings_p ()
17300 && (TREE_STATIC (decl)
17301 || !DECL_EXTERNAL (decl)))
17302 {
17303 error_at (loc,
17304 "%qD must be a global variable in "
17305 "%<#pragma acc declare link%>",
17306 decl);
17307 error = true;
17308 continue;
17309 }
17310 break;
17311
17312 default:
17313 if (global_bindings_p ())
17314 {
17315 error_at (loc, "invalid OpenACC clause at file scope");
17316 error = true;
17317 continue;
17318 }
17319 if (DECL_EXTERNAL (decl))
17320 {
17321 error_at (loc,
17322 "invalid use of %<extern%> variable %qD "
17323 "in %<#pragma acc declare%>", decl);
17324 error = true;
17325 continue;
17326 }
17327 else if (TREE_PUBLIC (decl))
17328 {
17329 error_at (loc,
17330 "invalid use of %<global%> variable %qD "
17331 "in %<#pragma acc declare%>", decl);
17332 error = true;
17333 continue;
17334 }
17335 break;
17336 }
17337
17338 if (!c_check_in_current_scope (decl))
17339 {
17340 error_at (loc,
17341 "%qD must be a variable declared in the same scope as "
17342 "%<#pragma acc declare%>", decl);
17343 error = true;
17344 continue;
17345 }
17346
17347 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl))
17348 || lookup_attribute ("omp declare target link",
17349 DECL_ATTRIBUTES (decl)))
17350 {
17351 error_at (loc, "variable %qD used more than once with "
17352 "%<#pragma acc declare%>", decl);
17353 error = true;
17354 continue;
17355 }
17356
17357 if (!error)
17358 {
17359 tree id;
17360
17361 if (OMP_CLAUSE_MAP_KIND (t) == GOMP_MAP_LINK)
17362 id = get_identifier ("omp declare target link");
17363 else
17364 id = get_identifier ("omp declare target");
17365
17366 DECL_ATTRIBUTES (decl)
17367 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (decl));
17368
17369 if (global_bindings_p ())
17370 {
17371 symtab_node *node = symtab_node::get (decl);
17372 if (node != NULL)
17373 {
17374 node->offloadable = 1;
17375 if (ENABLE_OFFLOADING)
17376 {
17377 g->have_offload = true;
17378 if (is_a <varpool_node *> (node))
17379 vec_safe_push (offload_vars, decl);
17380 }
17381 }
17382 }
17383 }
17384 }
17385
17386 if (error || global_bindings_p ())
17387 return;
17388
17389 stmt = make_node (OACC_DECLARE);
17390 TREE_TYPE (stmt) = void_type_node;
17391 OACC_DECLARE_CLAUSES (stmt) = clauses;
17392 SET_EXPR_LOCATION (stmt, pragma_loc);
17393
17394 add_stmt (stmt);
17395
17396 return;
17397 }
17398
17399 /* OpenACC 2.0:
17400 # pragma acc enter data oacc-enter-data-clause[optseq] new-line
17401
17402 or
17403
17404 # pragma acc exit data oacc-exit-data-clause[optseq] new-line
17405
17406
17407 LOC is the location of the #pragma token.
17408 */
17409
17410 #define OACC_ENTER_DATA_CLAUSE_MASK \
17411 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17412 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17413 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
17414 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17415 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17416 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17417
17418 #define OACC_EXIT_DATA_CLAUSE_MASK \
17419 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17420 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17421 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17422 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DELETE) \
17423 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DETACH) \
17424 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FINALIZE) \
17425 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17426
17427 static void
c_parser_oacc_enter_exit_data(c_parser * parser,bool enter)17428 c_parser_oacc_enter_exit_data (c_parser *parser, bool enter)
17429 {
17430 location_t loc = c_parser_peek_token (parser)->location;
17431 tree clauses, stmt;
17432 const char *p = "";
17433
17434 c_parser_consume_pragma (parser);
17435
17436 if (c_parser_next_token_is (parser, CPP_NAME))
17437 {
17438 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17439 c_parser_consume_token (parser);
17440 }
17441
17442 if (strcmp (p, "data") != 0)
17443 {
17444 error_at (loc, "expected %<data%> after %<#pragma acc %s%>",
17445 enter ? "enter" : "exit");
17446 parser->error = true;
17447 c_parser_skip_to_pragma_eol (parser);
17448 return;
17449 }
17450
17451 if (enter)
17452 clauses = c_parser_oacc_all_clauses (parser, OACC_ENTER_DATA_CLAUSE_MASK,
17453 "#pragma acc enter data");
17454 else
17455 clauses = c_parser_oacc_all_clauses (parser, OACC_EXIT_DATA_CLAUSE_MASK,
17456 "#pragma acc exit data");
17457
17458 if (omp_find_clause (clauses, OMP_CLAUSE_MAP) == NULL_TREE)
17459 {
17460 error_at (loc, "%<#pragma acc %s data%> has no data movement clause",
17461 enter ? "enter" : "exit");
17462 return;
17463 }
17464
17465 stmt = enter ? make_node (OACC_ENTER_DATA) : make_node (OACC_EXIT_DATA);
17466 TREE_TYPE (stmt) = void_type_node;
17467 OMP_STANDALONE_CLAUSES (stmt) = clauses;
17468 SET_EXPR_LOCATION (stmt, loc);
17469 add_stmt (stmt);
17470 }
17471
17472
17473 /* OpenACC 2.0:
17474 # pragma acc host_data oacc-data-clause[optseq] new-line
17475 structured-block
17476 */
17477
17478 #define OACC_HOST_DATA_CLAUSE_MASK \
17479 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_USE_DEVICE) \
17480 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17481 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) )
17482
17483 static tree
c_parser_oacc_host_data(location_t loc,c_parser * parser,bool * if_p)17484 c_parser_oacc_host_data (location_t loc, c_parser *parser, bool *if_p)
17485 {
17486 tree stmt, clauses, block;
17487
17488 clauses = c_parser_oacc_all_clauses (parser, OACC_HOST_DATA_CLAUSE_MASK,
17489 "#pragma acc host_data");
17490
17491 block = c_begin_omp_parallel ();
17492 add_stmt (c_parser_omp_structured_block (parser, if_p));
17493 stmt = c_finish_oacc_host_data (loc, clauses, block);
17494 return stmt;
17495 }
17496
17497
17498 /* OpenACC 2.0:
17499
17500 # pragma acc loop oacc-loop-clause[optseq] new-line
17501 structured-block
17502
17503 LOC is the location of the #pragma token.
17504 */
17505
17506 #define OACC_LOOP_CLAUSE_MASK \
17507 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COLLAPSE) \
17508 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
17509 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
17510 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
17511 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
17512 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
17513 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_AUTO) \
17514 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_INDEPENDENT) \
17515 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \
17516 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_TILE) )
17517 static tree
c_parser_oacc_loop(location_t loc,c_parser * parser,char * p_name,omp_clause_mask mask,tree * cclauses,bool * if_p)17518 c_parser_oacc_loop (location_t loc, c_parser *parser, char *p_name,
17519 omp_clause_mask mask, tree *cclauses, bool *if_p)
17520 {
17521 bool is_parallel = ((mask >> PRAGMA_OACC_CLAUSE_REDUCTION) & 1) == 1;
17522
17523 strcat (p_name, " loop");
17524 mask |= OACC_LOOP_CLAUSE_MASK;
17525
17526 tree clauses = c_parser_oacc_all_clauses (parser, mask, p_name,
17527 cclauses == NULL);
17528 if (cclauses)
17529 {
17530 clauses = c_oacc_split_loop_clauses (clauses, cclauses, is_parallel);
17531 if (*cclauses)
17532 *cclauses = c_finish_omp_clauses (*cclauses, C_ORT_ACC);
17533 if (clauses)
17534 clauses = c_finish_omp_clauses (clauses, C_ORT_ACC);
17535 }
17536
17537 tree block = c_begin_compound_stmt (true);
17538 tree stmt = c_parser_omp_for_loop (loc, parser, OACC_LOOP, clauses, NULL,
17539 if_p);
17540 block = c_end_compound_stmt (loc, block, true);
17541 add_stmt (block);
17542
17543 return stmt;
17544 }
17545
17546 /* OpenACC 2.0:
17547 # pragma acc kernels oacc-kernels-clause[optseq] new-line
17548 structured-block
17549
17550 or
17551
17552 # pragma acc parallel oacc-parallel-clause[optseq] new-line
17553 structured-block
17554
17555 OpenACC 2.6:
17556
17557 # pragma acc serial oacc-serial-clause[optseq] new-line
17558 structured-block
17559
17560 LOC is the location of the #pragma token.
17561 */
17562
17563 #define OACC_KERNELS_CLAUSE_MASK \
17564 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17565 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
17566 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
17567 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17568 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17569 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17570 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
17571 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
17572 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17573 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
17574 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
17575 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
17576 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
17577 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
17578 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17579
17580 #define OACC_PARALLEL_CLAUSE_MASK \
17581 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17582 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
17583 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
17584 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17585 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17586 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17587 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
17588 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
17589 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17590 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
17591 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
17592 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
17593 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
17594 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
17595 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
17596 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
17597 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
17598 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17599
17600 #define OACC_SERIAL_CLAUSE_MASK \
17601 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17602 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
17603 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
17604 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17605 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17606 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17607 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
17608 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
17609 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17610 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
17611 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
17612 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
17613 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
17614 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
17615 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17616
17617 static tree
c_parser_oacc_compute(location_t loc,c_parser * parser,enum pragma_kind p_kind,char * p_name,bool * if_p)17618 c_parser_oacc_compute (location_t loc, c_parser *parser,
17619 enum pragma_kind p_kind, char *p_name, bool *if_p)
17620 {
17621 omp_clause_mask mask;
17622 enum tree_code code;
17623 switch (p_kind)
17624 {
17625 case PRAGMA_OACC_KERNELS:
17626 strcat (p_name, " kernels");
17627 mask = OACC_KERNELS_CLAUSE_MASK;
17628 code = OACC_KERNELS;
17629 break;
17630 case PRAGMA_OACC_PARALLEL:
17631 strcat (p_name, " parallel");
17632 mask = OACC_PARALLEL_CLAUSE_MASK;
17633 code = OACC_PARALLEL;
17634 break;
17635 case PRAGMA_OACC_SERIAL:
17636 strcat (p_name, " serial");
17637 mask = OACC_SERIAL_CLAUSE_MASK;
17638 code = OACC_SERIAL;
17639 break;
17640 default:
17641 gcc_unreachable ();
17642 }
17643
17644 if (c_parser_next_token_is (parser, CPP_NAME))
17645 {
17646 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17647 if (strcmp (p, "loop") == 0)
17648 {
17649 c_parser_consume_token (parser);
17650 tree block = c_begin_omp_parallel ();
17651 tree clauses;
17652 c_parser_oacc_loop (loc, parser, p_name, mask, &clauses, if_p);
17653 return c_finish_omp_construct (loc, code, block, clauses);
17654 }
17655 }
17656
17657 tree clauses = c_parser_oacc_all_clauses (parser, mask, p_name);
17658
17659 tree block = c_begin_omp_parallel ();
17660 add_stmt (c_parser_omp_structured_block (parser, if_p));
17661
17662 return c_finish_omp_construct (loc, code, block, clauses);
17663 }
17664
17665 /* OpenACC 2.0:
17666 # pragma acc routine oacc-routine-clause[optseq] new-line
17667 function-definition
17668
17669 # pragma acc routine ( name ) oacc-routine-clause[optseq] new-line
17670 */
17671
17672 #define OACC_ROUTINE_CLAUSE_MASK \
17673 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
17674 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
17675 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
17676 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \
17677 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NOHOST) )
17678
17679 /* Parse an OpenACC routine directive. For named directives, we apply
17680 immediately to the named function. For unnamed ones we then parse
17681 a declaration or definition, which must be for a function. */
17682
17683 static void
c_parser_oacc_routine(c_parser * parser,enum pragma_context context)17684 c_parser_oacc_routine (c_parser *parser, enum pragma_context context)
17685 {
17686 gcc_checking_assert (context == pragma_external);
17687
17688 oacc_routine_data data;
17689 data.error_seen = false;
17690 data.fndecl_seen = false;
17691 data.loc = c_parser_peek_token (parser)->location;
17692
17693 c_parser_consume_pragma (parser);
17694
17695 /* Look for optional '( name )'. */
17696 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
17697 {
17698 c_parser_consume_token (parser); /* '(' */
17699
17700 tree decl = NULL_TREE;
17701 c_token *name_token = c_parser_peek_token (parser);
17702 location_t name_loc = name_token->location;
17703 if (name_token->type == CPP_NAME
17704 && (name_token->id_kind == C_ID_ID
17705 || name_token->id_kind == C_ID_TYPENAME))
17706 {
17707 decl = lookup_name (name_token->value);
17708 if (!decl)
17709 error_at (name_loc,
17710 "%qE has not been declared", name_token->value);
17711 c_parser_consume_token (parser);
17712 }
17713 else
17714 c_parser_error (parser, "expected function name");
17715
17716 if (!decl
17717 || !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
17718 {
17719 c_parser_skip_to_pragma_eol (parser, false);
17720 return;
17721 }
17722
17723 data.clauses
17724 = c_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK,
17725 "#pragma acc routine");
17726 /* The clauses are in reverse order; fix that to make later diagnostic
17727 emission easier. */
17728 data.clauses = nreverse (data.clauses);
17729
17730 if (TREE_CODE (decl) != FUNCTION_DECL)
17731 {
17732 error_at (name_loc, "%qD does not refer to a function", decl);
17733 return;
17734 }
17735
17736 c_finish_oacc_routine (&data, decl, false);
17737 }
17738 else /* No optional '( name )'. */
17739 {
17740 data.clauses
17741 = c_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK,
17742 "#pragma acc routine");
17743 /* The clauses are in reverse order; fix that to make later diagnostic
17744 emission easier. */
17745 data.clauses = nreverse (data.clauses);
17746
17747 /* Emit a helpful diagnostic if there's another pragma following this
17748 one. Also don't allow a static assertion declaration, as in the
17749 following we'll just parse a *single* "declaration or function
17750 definition", and the static assertion counts an one. */
17751 if (c_parser_next_token_is (parser, CPP_PRAGMA)
17752 || c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
17753 {
17754 error_at (data.loc,
17755 "%<#pragma acc routine%> not immediately followed by"
17756 " function declaration or definition");
17757 /* ..., and then just keep going. */
17758 return;
17759 }
17760
17761 /* We only have to consider the pragma_external case here. */
17762 if (c_parser_next_token_is (parser, CPP_KEYWORD)
17763 && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
17764 {
17765 int ext = disable_extension_diagnostics ();
17766 do
17767 c_parser_consume_token (parser);
17768 while (c_parser_next_token_is (parser, CPP_KEYWORD)
17769 && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
17770 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
17771 NULL, NULL, false, NULL, &data);
17772 restore_extension_diagnostics (ext);
17773 }
17774 else
17775 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
17776 NULL, NULL, false, NULL, &data);
17777 }
17778 }
17779
17780 /* Finalize an OpenACC routine pragma, applying it to FNDECL.
17781 IS_DEFN is true if we're applying it to the definition. */
17782
17783 static void
c_finish_oacc_routine(struct oacc_routine_data * data,tree fndecl,bool is_defn)17784 c_finish_oacc_routine (struct oacc_routine_data *data, tree fndecl,
17785 bool is_defn)
17786 {
17787 /* Keep going if we're in error reporting mode. */
17788 if (data->error_seen
17789 || fndecl == error_mark_node)
17790 return;
17791
17792 if (data->fndecl_seen)
17793 {
17794 error_at (data->loc,
17795 "%<#pragma acc routine%> not immediately followed by"
17796 " a single function declaration or definition");
17797 data->error_seen = true;
17798 return;
17799 }
17800 if (fndecl == NULL_TREE || TREE_CODE (fndecl) != FUNCTION_DECL)
17801 {
17802 error_at (data->loc,
17803 "%<#pragma acc routine%> not immediately followed by"
17804 " function declaration or definition");
17805 data->error_seen = true;
17806 return;
17807 }
17808
17809 int compatible
17810 = oacc_verify_routine_clauses (fndecl, &data->clauses, data->loc,
17811 "#pragma acc routine");
17812 if (compatible < 0)
17813 {
17814 data->error_seen = true;
17815 return;
17816 }
17817 if (compatible > 0)
17818 {
17819 }
17820 else
17821 {
17822 if (TREE_USED (fndecl) || (!is_defn && DECL_SAVED_TREE (fndecl)))
17823 {
17824 error_at (data->loc,
17825 TREE_USED (fndecl)
17826 ? G_("%<#pragma acc routine%> must be applied before use")
17827 : G_("%<#pragma acc routine%> must be applied before"
17828 " definition"));
17829 data->error_seen = true;
17830 return;
17831 }
17832
17833 /* Set the routine's level of parallelism. */
17834 tree dims = oacc_build_routine_dims (data->clauses);
17835 oacc_replace_fn_attrib (fndecl, dims);
17836
17837 /* Add an "omp declare target" attribute. */
17838 DECL_ATTRIBUTES (fndecl)
17839 = tree_cons (get_identifier ("omp declare target"),
17840 data->clauses, DECL_ATTRIBUTES (fndecl));
17841 }
17842
17843 /* Remember that we've used this "#pragma acc routine". */
17844 data->fndecl_seen = true;
17845 }
17846
17847 /* OpenACC 2.0:
17848 # pragma acc update oacc-update-clause[optseq] new-line
17849 */
17850
17851 #define OACC_UPDATE_CLAUSE_MASK \
17852 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17853 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE) \
17854 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_HOST) \
17855 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17856 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) \
17857 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17858
17859 static void
c_parser_oacc_update(c_parser * parser)17860 c_parser_oacc_update (c_parser *parser)
17861 {
17862 location_t loc = c_parser_peek_token (parser)->location;
17863
17864 c_parser_consume_pragma (parser);
17865
17866 tree clauses = c_parser_oacc_all_clauses (parser, OACC_UPDATE_CLAUSE_MASK,
17867 "#pragma acc update");
17868 if (omp_find_clause (clauses, OMP_CLAUSE_MAP) == NULL_TREE)
17869 {
17870 error_at (loc,
17871 "%<#pragma acc update%> must contain at least one "
17872 "%<device%> or %<host%> or %<self%> clause");
17873 return;
17874 }
17875
17876 if (parser->error)
17877 return;
17878
17879 tree stmt = make_node (OACC_UPDATE);
17880 TREE_TYPE (stmt) = void_type_node;
17881 OACC_UPDATE_CLAUSES (stmt) = clauses;
17882 SET_EXPR_LOCATION (stmt, loc);
17883 add_stmt (stmt);
17884 }
17885
17886 /* OpenACC 2.0:
17887 # pragma acc wait [(intseq)] oacc-wait-clause[optseq] new-line
17888
17889 LOC is the location of the #pragma token.
17890 */
17891
17892 #define OACC_WAIT_CLAUSE_MASK \
17893 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) )
17894
17895 static tree
c_parser_oacc_wait(location_t loc,c_parser * parser,char * p_name)17896 c_parser_oacc_wait (location_t loc, c_parser *parser, char *p_name)
17897 {
17898 tree clauses, list = NULL_TREE, stmt = NULL_TREE;
17899
17900 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
17901 list = c_parser_oacc_wait_list (parser, loc, list);
17902
17903 strcpy (p_name, " wait");
17904 clauses = c_parser_oacc_all_clauses (parser, OACC_WAIT_CLAUSE_MASK, p_name);
17905 stmt = c_finish_oacc_wait (loc, list, clauses);
17906 add_stmt (stmt);
17907
17908 return stmt;
17909 }
17910
17911 /* OpenMP 5.0:
17912 # pragma omp allocate (list) [allocator(allocator)] */
17913
17914 static void
c_parser_omp_allocate(location_t loc,c_parser * parser)17915 c_parser_omp_allocate (location_t loc, c_parser *parser)
17916 {
17917 tree allocator = NULL_TREE;
17918 tree nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ALLOCATE, NULL_TREE);
17919 if (c_parser_next_token_is (parser, CPP_NAME))
17920 {
17921 matching_parens parens;
17922 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17923 c_parser_consume_token (parser);
17924 if (strcmp ("allocator", p) != 0)
17925 error_at (c_parser_peek_token (parser)->location,
17926 "expected %<allocator%>");
17927 else if (parens.require_open (parser))
17928 {
17929 location_t expr_loc = c_parser_peek_token (parser)->location;
17930 c_expr expr = c_parser_expr_no_commas (parser, NULL);
17931 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
17932 allocator = expr.value;
17933 allocator = c_fully_fold (allocator, false, NULL);
17934 tree orig_type
17935 = expr.original_type ? expr.original_type : TREE_TYPE (allocator);
17936 orig_type = TYPE_MAIN_VARIANT (orig_type);
17937 if (!INTEGRAL_TYPE_P (TREE_TYPE (allocator))
17938 || TREE_CODE (orig_type) != ENUMERAL_TYPE
17939 || TYPE_NAME (orig_type)
17940 != get_identifier ("omp_allocator_handle_t"))
17941 {
17942 error_at (expr_loc, "%<allocator%> clause allocator expression "
17943 "has type %qT rather than "
17944 "%<omp_allocator_handle_t%>",
17945 TREE_TYPE (allocator));
17946 allocator = NULL_TREE;
17947 }
17948 parens.skip_until_found_close (parser);
17949 }
17950 }
17951 c_parser_skip_to_pragma_eol (parser);
17952
17953 if (allocator)
17954 for (tree c = nl; c != NULL_TREE; c = OMP_CLAUSE_CHAIN (c))
17955 OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) = allocator;
17956
17957 sorry_at (loc, "%<#pragma omp allocate%> not yet supported");
17958 }
17959
17960 /* OpenMP 2.5:
17961 # pragma omp atomic new-line
17962 expression-stmt
17963
17964 expression-stmt:
17965 x binop= expr | x++ | ++x | x-- | --x
17966 binop:
17967 +, *, -, /, &, ^, |, <<, >>
17968
17969 where x is an lvalue expression with scalar type.
17970
17971 OpenMP 3.1:
17972 # pragma omp atomic new-line
17973 update-stmt
17974
17975 # pragma omp atomic read new-line
17976 read-stmt
17977
17978 # pragma omp atomic write new-line
17979 write-stmt
17980
17981 # pragma omp atomic update new-line
17982 update-stmt
17983
17984 # pragma omp atomic capture new-line
17985 capture-stmt
17986
17987 # pragma omp atomic capture new-line
17988 capture-block
17989
17990 read-stmt:
17991 v = x
17992 write-stmt:
17993 x = expr
17994 update-stmt:
17995 expression-stmt | x = x binop expr
17996 capture-stmt:
17997 v = expression-stmt
17998 capture-block:
17999 { v = x; update-stmt; } | { update-stmt; v = x; }
18000
18001 OpenMP 4.0:
18002 update-stmt:
18003 expression-stmt | x = x binop expr | x = expr binop x
18004 capture-stmt:
18005 v = update-stmt
18006 capture-block:
18007 { v = x; update-stmt; } | { update-stmt; v = x; } | { v = x; x = expr; }
18008
18009 OpenMP 5.1:
18010 # pragma omp atomic compare new-line
18011 conditional-update-atomic
18012
18013 # pragma omp atomic compare capture new-line
18014 conditional-update-capture-atomic
18015
18016 conditional-update-atomic:
18017 cond-expr-stmt | cond-update-stmt
18018 cond-expr-stmt:
18019 x = expr ordop x ? expr : x;
18020 x = x ordop expr ? expr : x;
18021 x = x == e ? d : x;
18022 cond-update-stmt:
18023 if (expr ordop x) { x = expr; }
18024 if (x ordop expr) { x = expr; }
18025 if (x == e) { x = d; }
18026 ordop:
18027 <, >
18028 conditional-update-capture-atomic:
18029 v = cond-expr-stmt
18030 { v = x; cond-expr-stmt }
18031 { cond-expr-stmt v = x; }
18032 { v = x; cond-update-stmt }
18033 { cond-update-stmt v = x; }
18034 if (x == e) { x = d; } else { v = x; }
18035 { r = x == e; if (r) { x = d; } }
18036 { r = x == e; if (r) { x = d; } else { v = x; } }
18037
18038 where x, r and v are lvalue expressions with scalar type,
18039 expr, e and d are expressions with scalar type and e might be
18040 the same as v.
18041
18042 LOC is the location of the #pragma token. */
18043
18044 static void
c_parser_omp_atomic(location_t loc,c_parser * parser,bool openacc)18045 c_parser_omp_atomic (location_t loc, c_parser *parser, bool openacc)
18046 {
18047 tree lhs = NULL_TREE, rhs = NULL_TREE, v = NULL_TREE, r = NULL_TREE;
18048 tree lhs1 = NULL_TREE, rhs1 = NULL_TREE;
18049 tree stmt, orig_lhs, unfolded_lhs = NULL_TREE, unfolded_lhs1 = NULL_TREE;
18050 enum tree_code code = ERROR_MARK, opcode = NOP_EXPR;
18051 enum omp_memory_order memory_order = OMP_MEMORY_ORDER_UNSPECIFIED;
18052 struct c_expr expr;
18053 location_t eloc;
18054 bool structured_block = false;
18055 bool swapped = false;
18056 bool non_lvalue_p;
18057 bool first = true;
18058 tree clauses = NULL_TREE;
18059 bool capture = false;
18060 bool compare = false;
18061 bool weak = false;
18062 enum omp_memory_order fail = OMP_MEMORY_ORDER_UNSPECIFIED;
18063 bool no_semicolon = false;
18064 bool extra_scope = false;
18065
18066 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
18067 {
18068 if (!first
18069 && c_parser_next_token_is (parser, CPP_COMMA)
18070 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
18071 c_parser_consume_token (parser);
18072
18073 first = false;
18074
18075 if (c_parser_next_token_is (parser, CPP_NAME))
18076 {
18077 const char *p
18078 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18079 location_t cloc = c_parser_peek_token (parser)->location;
18080 enum tree_code new_code = ERROR_MARK;
18081 enum omp_memory_order new_memory_order
18082 = OMP_MEMORY_ORDER_UNSPECIFIED;
18083 bool new_capture = false;
18084 bool new_compare = false;
18085 bool new_weak = false;
18086 enum omp_memory_order new_fail = OMP_MEMORY_ORDER_UNSPECIFIED;
18087
18088 if (!strcmp (p, "read"))
18089 new_code = OMP_ATOMIC_READ;
18090 else if (!strcmp (p, "write"))
18091 new_code = NOP_EXPR;
18092 else if (!strcmp (p, "update"))
18093 new_code = OMP_ATOMIC;
18094 else if (openacc && !strcmp (p, "capture"))
18095 new_code = OMP_ATOMIC_CAPTURE_NEW;
18096 else if (openacc)
18097 {
18098 p = NULL;
18099 error_at (cloc, "expected %<read%>, %<write%>, %<update%>, "
18100 "or %<capture%> clause");
18101 }
18102 else if (!strcmp (p, "capture"))
18103 new_capture = true;
18104 else if (!strcmp (p, "compare"))
18105 new_compare = true;
18106 else if (!strcmp (p, "weak"))
18107 new_weak = true;
18108 else if (!strcmp (p, "fail"))
18109 {
18110 matching_parens parens;
18111
18112 c_parser_consume_token (parser);
18113 if (!parens.require_open (parser))
18114 continue;
18115
18116 if (c_parser_next_token_is (parser, CPP_NAME))
18117 {
18118 const char *q
18119 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18120
18121 if (!strcmp (q, "seq_cst"))
18122 new_fail = OMP_MEMORY_ORDER_SEQ_CST;
18123 else if (!strcmp (q, "acquire"))
18124 new_fail = OMP_MEMORY_ORDER_ACQUIRE;
18125 else if (!strcmp (q, "relaxed"))
18126 new_fail = OMP_MEMORY_ORDER_RELAXED;
18127 }
18128
18129 if (new_fail != OMP_MEMORY_ORDER_UNSPECIFIED)
18130 {
18131 c_parser_consume_token (parser);
18132 if (fail != OMP_MEMORY_ORDER_UNSPECIFIED)
18133 error_at (cloc, "too many %qs clauses", "fail");
18134 else
18135 fail = new_fail;
18136 }
18137 else
18138 c_parser_error (parser, "expected %<seq_cst%>, %<acquire%> "
18139 "or %<relaxed%>");
18140 parens.skip_until_found_close (parser);
18141 continue;
18142 }
18143 else if (!strcmp (p, "seq_cst"))
18144 new_memory_order = OMP_MEMORY_ORDER_SEQ_CST;
18145 else if (!strcmp (p, "acq_rel"))
18146 new_memory_order = OMP_MEMORY_ORDER_ACQ_REL;
18147 else if (!strcmp (p, "release"))
18148 new_memory_order = OMP_MEMORY_ORDER_RELEASE;
18149 else if (!strcmp (p, "acquire"))
18150 new_memory_order = OMP_MEMORY_ORDER_ACQUIRE;
18151 else if (!strcmp (p, "relaxed"))
18152 new_memory_order = OMP_MEMORY_ORDER_RELAXED;
18153 else if (!strcmp (p, "hint"))
18154 {
18155 c_parser_consume_token (parser);
18156 clauses = c_parser_omp_clause_hint (parser, clauses);
18157 continue;
18158 }
18159 else
18160 {
18161 p = NULL;
18162 error_at (cloc, "expected %<read%>, %<write%>, %<update%>, "
18163 "%<capture%>, %<compare%>, %<weak%>, %<fail%>, "
18164 "%<seq_cst%>, %<acq_rel%>, %<release%>, "
18165 "%<relaxed%> or %<hint%> clause");
18166 }
18167 if (p)
18168 {
18169 if (new_code != ERROR_MARK)
18170 {
18171 /* OpenACC permits 'update capture'. */
18172 if (openacc
18173 && code == OMP_ATOMIC
18174 && new_code == OMP_ATOMIC_CAPTURE_NEW)
18175 code = new_code;
18176 else if (code != ERROR_MARK)
18177 error_at (cloc, "too many atomic clauses");
18178 else
18179 code = new_code;
18180 }
18181 else if (new_memory_order != OMP_MEMORY_ORDER_UNSPECIFIED)
18182 {
18183 if (memory_order != OMP_MEMORY_ORDER_UNSPECIFIED)
18184 error_at (cloc, "too many memory order clauses");
18185 else
18186 memory_order = new_memory_order;
18187 }
18188 else if (new_capture)
18189 {
18190 if (capture)
18191 error_at (cloc, "too many %qs clauses", "capture");
18192 else
18193 capture = true;
18194 }
18195 else if (new_compare)
18196 {
18197 if (compare)
18198 error_at (cloc, "too many %qs clauses", "compare");
18199 else
18200 compare = true;
18201 }
18202 else if (new_weak)
18203 {
18204 if (weak)
18205 error_at (cloc, "too many %qs clauses", "weak");
18206 else
18207 weak = true;
18208 }
18209 c_parser_consume_token (parser);
18210 continue;
18211 }
18212 }
18213 break;
18214 }
18215 c_parser_skip_to_pragma_eol (parser);
18216
18217 if (code == ERROR_MARK)
18218 code = OMP_ATOMIC;
18219 if (capture)
18220 {
18221 if (code != OMP_ATOMIC)
18222 error_at (loc, "%qs clause is incompatible with %<read%> or %<write%> "
18223 "clauses", "capture");
18224 else
18225 code = OMP_ATOMIC_CAPTURE_NEW;
18226 }
18227 if (compare && code != OMP_ATOMIC && code != OMP_ATOMIC_CAPTURE_NEW)
18228 {
18229 error_at (loc, "%qs clause is incompatible with %<read%> or %<write%> "
18230 "clauses", "compare");
18231 compare = false;
18232 }
18233 if (fail != OMP_MEMORY_ORDER_UNSPECIFIED && !compare)
18234 {
18235 error_at (loc, "%qs clause requires %qs clause", "fail", "compare");
18236 fail = OMP_MEMORY_ORDER_UNSPECIFIED;
18237 }
18238 if (weak && !compare)
18239 {
18240 error_at (loc, "%qs clause requires %qs clause", "weak", "compare");
18241 weak = false;
18242 }
18243 if (openacc)
18244 memory_order = OMP_MEMORY_ORDER_RELAXED;
18245 else if (memory_order == OMP_MEMORY_ORDER_UNSPECIFIED)
18246 {
18247 omp_requires_mask
18248 = (enum omp_requires) (omp_requires_mask
18249 | OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED);
18250 switch ((enum omp_memory_order)
18251 (omp_requires_mask & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER))
18252 {
18253 case OMP_MEMORY_ORDER_UNSPECIFIED:
18254 case OMP_MEMORY_ORDER_RELAXED:
18255 memory_order = OMP_MEMORY_ORDER_RELAXED;
18256 break;
18257 case OMP_MEMORY_ORDER_SEQ_CST:
18258 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
18259 break;
18260 case OMP_MEMORY_ORDER_ACQ_REL:
18261 switch (code)
18262 {
18263 case OMP_ATOMIC_READ:
18264 memory_order = OMP_MEMORY_ORDER_ACQUIRE;
18265 break;
18266 case NOP_EXPR: /* atomic write */
18267 memory_order = OMP_MEMORY_ORDER_RELEASE;
18268 break;
18269 default:
18270 memory_order = OMP_MEMORY_ORDER_ACQ_REL;
18271 break;
18272 }
18273 break;
18274 default:
18275 gcc_unreachable ();
18276 }
18277 }
18278 else
18279 switch (code)
18280 {
18281 case OMP_ATOMIC_READ:
18282 if (memory_order == OMP_MEMORY_ORDER_RELEASE)
18283 {
18284 error_at (loc, "%<#pragma omp atomic read%> incompatible with "
18285 "%<release%> clause");
18286 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
18287 }
18288 else if (memory_order == OMP_MEMORY_ORDER_ACQ_REL)
18289 memory_order = OMP_MEMORY_ORDER_ACQUIRE;
18290 break;
18291 case NOP_EXPR: /* atomic write */
18292 if (memory_order == OMP_MEMORY_ORDER_ACQUIRE)
18293 {
18294 error_at (loc, "%<#pragma omp atomic write%> incompatible with "
18295 "%<acquire%> clause");
18296 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
18297 }
18298 else if (memory_order == OMP_MEMORY_ORDER_ACQ_REL)
18299 memory_order = OMP_MEMORY_ORDER_RELEASE;
18300 break;
18301 default:
18302 break;
18303 }
18304 if (fail != OMP_MEMORY_ORDER_UNSPECIFIED)
18305 memory_order
18306 = (enum omp_memory_order) (memory_order
18307 | (fail << OMP_FAIL_MEMORY_ORDER_SHIFT));
18308
18309 switch (code)
18310 {
18311 case OMP_ATOMIC_READ:
18312 case NOP_EXPR: /* atomic write */
18313 v = c_parser_cast_expression (parser, NULL).value;
18314 non_lvalue_p = !lvalue_p (v);
18315 v = c_fully_fold (v, false, NULL, true);
18316 if (v == error_mark_node)
18317 goto saw_error;
18318 if (non_lvalue_p)
18319 v = non_lvalue (v);
18320 loc = c_parser_peek_token (parser)->location;
18321 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
18322 goto saw_error;
18323 if (code == NOP_EXPR)
18324 {
18325 lhs = c_parser_expression (parser).value;
18326 lhs = c_fully_fold (lhs, false, NULL);
18327 if (lhs == error_mark_node)
18328 goto saw_error;
18329 }
18330 else
18331 {
18332 lhs = c_parser_cast_expression (parser, NULL).value;
18333 non_lvalue_p = !lvalue_p (lhs);
18334 lhs = c_fully_fold (lhs, false, NULL, true);
18335 if (lhs == error_mark_node)
18336 goto saw_error;
18337 if (non_lvalue_p)
18338 lhs = non_lvalue (lhs);
18339 }
18340 if (code == NOP_EXPR)
18341 {
18342 /* atomic write is represented by OMP_ATOMIC with NOP_EXPR
18343 opcode. */
18344 code = OMP_ATOMIC;
18345 rhs = lhs;
18346 lhs = v;
18347 v = NULL_TREE;
18348 }
18349 goto done;
18350 case OMP_ATOMIC_CAPTURE_NEW:
18351 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
18352 {
18353 c_parser_consume_token (parser);
18354 structured_block = true;
18355 }
18356 else if (compare
18357 && c_parser_next_token_is_keyword (parser, RID_IF))
18358 break;
18359 else
18360 {
18361 v = c_parser_cast_expression (parser, NULL).value;
18362 non_lvalue_p = !lvalue_p (v);
18363 v = c_fully_fold (v, false, NULL, true);
18364 if (v == error_mark_node)
18365 goto saw_error;
18366 if (non_lvalue_p)
18367 v = non_lvalue (v);
18368 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
18369 goto saw_error;
18370 if (compare && c_parser_next_token_is_keyword (parser, RID_IF))
18371 {
18372 eloc = c_parser_peek_token (parser)->location;
18373 error_at (eloc, "expected expression");
18374 goto saw_error;
18375 }
18376 }
18377 break;
18378 default:
18379 break;
18380 }
18381
18382 /* For structured_block case we don't know yet whether
18383 old or new x should be captured. */
18384 restart:
18385 if (compare && c_parser_next_token_is_keyword (parser, RID_IF))
18386 {
18387 c_parser_consume_token (parser);
18388
18389 matching_parens parens;
18390 if (!parens.require_open (parser))
18391 goto saw_error;
18392 eloc = c_parser_peek_token (parser)->location;
18393 c_expr cmp_expr;
18394 if (r)
18395 {
18396 cmp_expr = c_parser_cast_expression (parser, NULL);
18397 cmp_expr = default_function_array_conversion (eloc, cmp_expr);
18398 }
18399 else
18400 cmp_expr = c_parser_binary_expression (parser, NULL, void_list_node);
18401 parens.skip_until_found_close (parser);
18402 if (cmp_expr.value == error_mark_node)
18403 goto saw_error;
18404 if (r)
18405 {
18406 if (!c_tree_equal (cmp_expr.value, unfolded_lhs))
18407 goto bad_if;
18408 cmp_expr.value = rhs1;
18409 rhs1 = NULL_TREE;
18410 gcc_assert (TREE_CODE (cmp_expr.value) == EQ_EXPR);
18411 }
18412 if (TREE_CODE (cmp_expr.value) == EQ_EXPR)
18413 ;
18414 else if (!structured_block && code == OMP_ATOMIC_CAPTURE_NEW)
18415 {
18416 error_at (EXPR_LOC_OR_LOC (cmp_expr.value, eloc),
18417 "expected %<==%> comparison in %<if%> condition");
18418 goto saw_error;
18419 }
18420 else if (TREE_CODE (cmp_expr.value) != GT_EXPR
18421 && TREE_CODE (cmp_expr.value) != LT_EXPR)
18422 {
18423 error_at (EXPR_LOC_OR_LOC (cmp_expr.value, eloc),
18424 "expected %<==%>, %<<%> or %<>%> comparison in %<if%> "
18425 "condition");
18426 goto saw_error;
18427 }
18428 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
18429 goto saw_error;
18430
18431 extra_scope = true;
18432 eloc = c_parser_peek_token (parser)->location;
18433 expr = c_parser_cast_expression (parser, NULL);
18434 lhs = expr.value;
18435 expr = default_function_array_conversion (eloc, expr);
18436 unfolded_lhs = expr.value;
18437 lhs = c_fully_fold (lhs, false, NULL, true);
18438 orig_lhs = lhs;
18439 if (lhs == error_mark_node)
18440 goto saw_error;
18441 if (!lvalue_p (unfolded_lhs))
18442 lhs = non_lvalue (lhs);
18443 if (!c_parser_next_token_is (parser, CPP_EQ))
18444 {
18445 c_parser_error (parser, "expected %<=%>");
18446 goto saw_error;
18447 }
18448 c_parser_consume_token (parser);
18449 eloc = c_parser_peek_token (parser)->location;
18450 expr = c_parser_expr_no_commas (parser, NULL);
18451 rhs1 = expr.value;
18452
18453 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
18454 goto saw_error;
18455
18456 if (!c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>"))
18457 goto saw_error;
18458
18459 extra_scope = false;
18460 no_semicolon = true;
18461
18462 if (c_tree_equal (TREE_OPERAND (cmp_expr.value, 0), unfolded_lhs))
18463 {
18464 if (TREE_CODE (cmp_expr.value) == EQ_EXPR)
18465 {
18466 opcode = COND_EXPR;
18467 rhs = c_fully_fold (TREE_OPERAND (cmp_expr.value, 1),
18468 false, NULL, true);
18469 rhs1 = c_fully_fold (rhs1, false, NULL, true);
18470 }
18471 else if (c_tree_equal (TREE_OPERAND (cmp_expr.value, 1), rhs1))
18472 {
18473 opcode = (TREE_CODE (cmp_expr.value) == GT_EXPR
18474 ? MIN_EXPR : MAX_EXPR);
18475 rhs = c_fully_fold (rhs1, false, NULL, true);
18476 rhs1 = c_fully_fold (TREE_OPERAND (cmp_expr.value, 0),
18477 false, NULL, true);
18478 }
18479 else
18480 goto bad_if;
18481 }
18482 else if (TREE_CODE (cmp_expr.value) == EQ_EXPR)
18483 goto bad_if;
18484 else if (c_tree_equal (TREE_OPERAND (cmp_expr.value, 1), unfolded_lhs)
18485 && c_tree_equal (TREE_OPERAND (cmp_expr.value, 0), rhs1))
18486 {
18487 opcode = (TREE_CODE (cmp_expr.value) == GT_EXPR
18488 ? MAX_EXPR : MIN_EXPR);
18489 rhs = c_fully_fold (rhs1, false, NULL, true);
18490 rhs1 = c_fully_fold (TREE_OPERAND (cmp_expr.value, 1),
18491 false, NULL, true);
18492 }
18493 else
18494 {
18495 bad_if:
18496 c_parser_error (parser,
18497 "invalid form of %<#pragma omp atomic compare%>");
18498 goto saw_error;
18499 }
18500
18501 if (c_parser_next_token_is_keyword (parser, RID_ELSE))
18502 {
18503 if (code != OMP_ATOMIC_CAPTURE_NEW
18504 || (structured_block && r == NULL_TREE)
18505 || TREE_CODE (cmp_expr.value) != EQ_EXPR)
18506 {
18507 eloc = c_parser_peek_token (parser)->location;
18508 error_at (eloc, "unexpected %<else%>");
18509 goto saw_error;
18510 }
18511
18512 c_parser_consume_token (parser);
18513
18514 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
18515 goto saw_error;
18516
18517 extra_scope = true;
18518 v = c_parser_cast_expression (parser, NULL).value;
18519 non_lvalue_p = !lvalue_p (v);
18520 v = c_fully_fold (v, false, NULL, true);
18521 if (v == error_mark_node)
18522 goto saw_error;
18523 if (non_lvalue_p)
18524 v = non_lvalue (v);
18525 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
18526 goto saw_error;
18527
18528 expr = c_parser_expr_no_commas (parser, NULL);
18529
18530 if (!c_tree_equal (expr.value, unfolded_lhs))
18531 goto bad_if;
18532
18533 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
18534 goto saw_error;
18535
18536 if (!c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>"))
18537 goto saw_error;
18538
18539 extra_scope = false;
18540 code = OMP_ATOMIC_CAPTURE_OLD;
18541 if (r == NULL_TREE)
18542 /* Signal to c_finish_omp_atomic that in
18543 if (x == e) { x = d; } else { v = x; }
18544 case the store to v should be conditional. */
18545 r = void_list_node;
18546 }
18547 else if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
18548 {
18549 c_parser_require_keyword (parser, RID_ELSE, "expected %<else%>");
18550 goto saw_error;
18551 }
18552 else if (code == OMP_ATOMIC_CAPTURE_NEW
18553 && r != NULL_TREE
18554 && v == NULL_TREE)
18555 code = OMP_ATOMIC;
18556 goto stmt_done;
18557 }
18558 eloc = c_parser_peek_token (parser)->location;
18559 expr = c_parser_cast_expression (parser, NULL);
18560 lhs = expr.value;
18561 expr = default_function_array_conversion (eloc, expr);
18562 unfolded_lhs = expr.value;
18563 lhs = c_fully_fold (lhs, false, NULL, true);
18564 orig_lhs = lhs;
18565 switch (TREE_CODE (lhs))
18566 {
18567 invalid_compare:
18568 error_at (eloc, "invalid form of %<pragma omp atomic compare%>");
18569 /* FALLTHRU */
18570 case ERROR_MARK:
18571 saw_error:
18572 c_parser_skip_to_end_of_block_or_statement (parser);
18573 if (extra_scope && c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
18574 c_parser_consume_token (parser);
18575 if (structured_block)
18576 {
18577 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
18578 c_parser_consume_token (parser);
18579 else if (code == OMP_ATOMIC_CAPTURE_NEW)
18580 {
18581 c_parser_skip_to_end_of_block_or_statement (parser);
18582 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
18583 c_parser_consume_token (parser);
18584 }
18585 }
18586 return;
18587
18588 case POSTINCREMENT_EXPR:
18589 if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
18590 code = OMP_ATOMIC_CAPTURE_OLD;
18591 /* FALLTHROUGH */
18592 case PREINCREMENT_EXPR:
18593 lhs = TREE_OPERAND (lhs, 0);
18594 unfolded_lhs = NULL_TREE;
18595 opcode = PLUS_EXPR;
18596 rhs = integer_one_node;
18597 if (compare)
18598 goto invalid_compare;
18599 break;
18600
18601 case POSTDECREMENT_EXPR:
18602 if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
18603 code = OMP_ATOMIC_CAPTURE_OLD;
18604 /* FALLTHROUGH */
18605 case PREDECREMENT_EXPR:
18606 lhs = TREE_OPERAND (lhs, 0);
18607 unfolded_lhs = NULL_TREE;
18608 opcode = MINUS_EXPR;
18609 rhs = integer_one_node;
18610 if (compare)
18611 goto invalid_compare;
18612 break;
18613
18614 case COMPOUND_EXPR:
18615 if (TREE_CODE (TREE_OPERAND (lhs, 0)) == SAVE_EXPR
18616 && TREE_CODE (TREE_OPERAND (lhs, 1)) == COMPOUND_EXPR
18617 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (lhs, 1), 0)) == MODIFY_EXPR
18618 && TREE_OPERAND (TREE_OPERAND (lhs, 1), 1) == TREE_OPERAND (lhs, 0)
18619 && TREE_CODE (TREE_TYPE (TREE_OPERAND (TREE_OPERAND
18620 (TREE_OPERAND (lhs, 1), 0), 0)))
18621 == BOOLEAN_TYPE)
18622 /* Undo effects of boolean_increment for post {in,de}crement. */
18623 lhs = TREE_OPERAND (TREE_OPERAND (lhs, 1), 0);
18624 /* FALLTHRU */
18625 case MODIFY_EXPR:
18626 if (TREE_CODE (lhs) == MODIFY_EXPR
18627 && TREE_CODE (TREE_TYPE (TREE_OPERAND (lhs, 0))) == BOOLEAN_TYPE)
18628 {
18629 /* Undo effects of boolean_increment. */
18630 if (integer_onep (TREE_OPERAND (lhs, 1)))
18631 {
18632 /* This is pre or post increment. */
18633 rhs = TREE_OPERAND (lhs, 1);
18634 lhs = TREE_OPERAND (lhs, 0);
18635 unfolded_lhs = NULL_TREE;
18636 opcode = NOP_EXPR;
18637 if (code == OMP_ATOMIC_CAPTURE_NEW
18638 && !structured_block
18639 && TREE_CODE (orig_lhs) == COMPOUND_EXPR)
18640 code = OMP_ATOMIC_CAPTURE_OLD;
18641 if (compare)
18642 goto invalid_compare;
18643 break;
18644 }
18645 if (TREE_CODE (TREE_OPERAND (lhs, 1)) == TRUTH_NOT_EXPR
18646 && TREE_OPERAND (lhs, 0)
18647 == TREE_OPERAND (TREE_OPERAND (lhs, 1), 0))
18648 {
18649 /* This is pre or post decrement. */
18650 rhs = TREE_OPERAND (lhs, 1);
18651 lhs = TREE_OPERAND (lhs, 0);
18652 unfolded_lhs = NULL_TREE;
18653 opcode = NOP_EXPR;
18654 if (code == OMP_ATOMIC_CAPTURE_NEW
18655 && !structured_block
18656 && TREE_CODE (orig_lhs) == COMPOUND_EXPR)
18657 code = OMP_ATOMIC_CAPTURE_OLD;
18658 if (compare)
18659 goto invalid_compare;
18660 break;
18661 }
18662 }
18663 /* FALLTHRU */
18664 default:
18665 if (!lvalue_p (unfolded_lhs))
18666 lhs = non_lvalue (lhs);
18667 if (compare && !c_parser_next_token_is (parser, CPP_EQ))
18668 {
18669 c_parser_error (parser, "expected %<=%>");
18670 goto saw_error;
18671 }
18672 switch (c_parser_peek_token (parser)->type)
18673 {
18674 case CPP_MULT_EQ:
18675 opcode = MULT_EXPR;
18676 break;
18677 case CPP_DIV_EQ:
18678 opcode = TRUNC_DIV_EXPR;
18679 break;
18680 case CPP_PLUS_EQ:
18681 opcode = PLUS_EXPR;
18682 break;
18683 case CPP_MINUS_EQ:
18684 opcode = MINUS_EXPR;
18685 break;
18686 case CPP_LSHIFT_EQ:
18687 opcode = LSHIFT_EXPR;
18688 break;
18689 case CPP_RSHIFT_EQ:
18690 opcode = RSHIFT_EXPR;
18691 break;
18692 case CPP_AND_EQ:
18693 opcode = BIT_AND_EXPR;
18694 break;
18695 case CPP_OR_EQ:
18696 opcode = BIT_IOR_EXPR;
18697 break;
18698 case CPP_XOR_EQ:
18699 opcode = BIT_XOR_EXPR;
18700 break;
18701 case CPP_EQ:
18702 c_parser_consume_token (parser);
18703 eloc = c_parser_peek_token (parser)->location;
18704 expr = c_parser_expr_no_commas (parser, NULL, unfolded_lhs);
18705 rhs1 = expr.value;
18706 switch (TREE_CODE (rhs1))
18707 {
18708 case MULT_EXPR:
18709 case TRUNC_DIV_EXPR:
18710 case RDIV_EXPR:
18711 case PLUS_EXPR:
18712 case MINUS_EXPR:
18713 case LSHIFT_EXPR:
18714 case RSHIFT_EXPR:
18715 case BIT_AND_EXPR:
18716 case BIT_IOR_EXPR:
18717 case BIT_XOR_EXPR:
18718 if (compare)
18719 break;
18720 if (c_tree_equal (TREE_OPERAND (rhs1, 0), unfolded_lhs))
18721 {
18722 opcode = TREE_CODE (rhs1);
18723 rhs = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
18724 true);
18725 rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 0), false, NULL,
18726 true);
18727 goto stmt_done;
18728 }
18729 if (c_tree_equal (TREE_OPERAND (rhs1, 1), unfolded_lhs))
18730 {
18731 opcode = TREE_CODE (rhs1);
18732 rhs = c_fully_fold (TREE_OPERAND (rhs1, 0), false, NULL,
18733 true);
18734 rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
18735 true);
18736 swapped = !commutative_tree_code (opcode);
18737 goto stmt_done;
18738 }
18739 break;
18740 case COND_EXPR:
18741 if (!compare)
18742 break;
18743 if (TREE_CODE (TREE_OPERAND (rhs1, 0)) != GT_EXPR
18744 && TREE_CODE (TREE_OPERAND (rhs1, 0)) != LT_EXPR
18745 && TREE_CODE (TREE_OPERAND (rhs1, 0)) != EQ_EXPR)
18746 break;
18747 if (!TREE_OPERAND (rhs1, 1))
18748 break;
18749 if (!c_tree_equal (TREE_OPERAND (rhs1, 2), unfolded_lhs))
18750 break;
18751 if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 0),
18752 unfolded_lhs))
18753 {
18754 if (TREE_CODE (TREE_OPERAND (rhs1, 0)) == EQ_EXPR)
18755 {
18756 opcode = COND_EXPR;
18757 rhs = c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1,
18758 0), 1),
18759 false, NULL, true);
18760 rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 1), false,
18761 NULL, true);
18762 goto stmt_done;
18763 }
18764 if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 1),
18765 TREE_OPERAND (rhs1, 1)))
18766 {
18767 opcode = (TREE_CODE (TREE_OPERAND (rhs1, 0)) == GT_EXPR
18768 ? MIN_EXPR : MAX_EXPR);
18769 rhs = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
18770 true);
18771 rhs1 = c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1,
18772 0), 0),
18773 false, NULL, true);
18774 goto stmt_done;
18775 }
18776 }
18777 else if (TREE_CODE (TREE_OPERAND (rhs1, 0)) == EQ_EXPR)
18778 break;
18779 else if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 1),
18780 unfolded_lhs))
18781 {
18782 if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 0),
18783 TREE_OPERAND (rhs1, 1)))
18784 {
18785 opcode = (TREE_CODE (TREE_OPERAND (rhs1, 0)) == GT_EXPR
18786 ? MAX_EXPR : MIN_EXPR);
18787 rhs = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
18788 true);
18789 rhs1 = c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1,
18790 0), 1),
18791 false, NULL, true);
18792 goto stmt_done;
18793 }
18794 }
18795 break;
18796 case EQ_EXPR:
18797 if (!compare
18798 || code != OMP_ATOMIC_CAPTURE_NEW
18799 || !structured_block
18800 || v
18801 || r)
18802 break;
18803 if (c_parser_next_token_is (parser, CPP_SEMICOLON)
18804 && c_parser_peek_2nd_token (parser)->keyword == RID_IF)
18805 {
18806 r = lhs;
18807 lhs = NULL_TREE;
18808 c_parser_consume_token (parser);
18809 goto restart;
18810 }
18811 break;
18812 case ERROR_MARK:
18813 goto saw_error;
18814 default:
18815 break;
18816 }
18817 if (c_parser_peek_token (parser)->type == CPP_SEMICOLON)
18818 {
18819 if (structured_block && code == OMP_ATOMIC_CAPTURE_NEW)
18820 {
18821 code = OMP_ATOMIC_CAPTURE_OLD;
18822 v = lhs;
18823 lhs = NULL_TREE;
18824 expr = default_function_array_read_conversion (eloc, expr);
18825 unfolded_lhs1 = expr.value;
18826 lhs1 = c_fully_fold (unfolded_lhs1, false, NULL, true);
18827 rhs1 = NULL_TREE;
18828 c_parser_consume_token (parser);
18829 goto restart;
18830 }
18831 if (structured_block && !compare)
18832 {
18833 opcode = NOP_EXPR;
18834 expr = default_function_array_read_conversion (eloc, expr);
18835 rhs = c_fully_fold (expr.value, false, NULL, true);
18836 rhs1 = NULL_TREE;
18837 goto stmt_done;
18838 }
18839 }
18840 c_parser_error (parser, "invalid form of %<#pragma omp atomic%>");
18841 goto saw_error;
18842 default:
18843 c_parser_error (parser,
18844 "invalid operator for %<#pragma omp atomic%>");
18845 goto saw_error;
18846 }
18847
18848 /* Arrange to pass the location of the assignment operator to
18849 c_finish_omp_atomic. */
18850 loc = c_parser_peek_token (parser)->location;
18851 c_parser_consume_token (parser);
18852 eloc = c_parser_peek_token (parser)->location;
18853 expr = c_parser_expression (parser);
18854 expr = default_function_array_read_conversion (eloc, expr);
18855 rhs = expr.value;
18856 rhs = c_fully_fold (rhs, false, NULL, true);
18857 break;
18858 }
18859 stmt_done:
18860 if (structured_block && code == OMP_ATOMIC_CAPTURE_NEW && r == NULL_TREE)
18861 {
18862 if (!no_semicolon
18863 && !c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
18864 goto saw_error;
18865 no_semicolon = false;
18866 v = c_parser_cast_expression (parser, NULL).value;
18867 non_lvalue_p = !lvalue_p (v);
18868 v = c_fully_fold (v, false, NULL, true);
18869 if (v == error_mark_node)
18870 goto saw_error;
18871 if (non_lvalue_p)
18872 v = non_lvalue (v);
18873 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
18874 goto saw_error;
18875 eloc = c_parser_peek_token (parser)->location;
18876 expr = c_parser_cast_expression (parser, NULL);
18877 lhs1 = expr.value;
18878 expr = default_function_array_read_conversion (eloc, expr);
18879 unfolded_lhs1 = expr.value;
18880 lhs1 = c_fully_fold (lhs1, false, NULL, true);
18881 if (lhs1 == error_mark_node)
18882 goto saw_error;
18883 if (!lvalue_p (unfolded_lhs1))
18884 lhs1 = non_lvalue (lhs1);
18885 }
18886 if (structured_block)
18887 {
18888 if (!no_semicolon)
18889 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
18890 c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>");
18891 }
18892 done:
18893 if (weak && opcode != COND_EXPR)
18894 {
18895 error_at (loc, "%<weak%> clause requires atomic equality comparison");
18896 weak = false;
18897 }
18898 if (unfolded_lhs && unfolded_lhs1
18899 && !c_tree_equal (unfolded_lhs, unfolded_lhs1))
18900 {
18901 error ("%<#pragma omp atomic capture%> uses two different "
18902 "expressions for memory");
18903 stmt = error_mark_node;
18904 }
18905 else
18906 stmt = c_finish_omp_atomic (loc, code, opcode, lhs, rhs, v, lhs1, rhs1, r,
18907 swapped, memory_order, weak);
18908 if (stmt != error_mark_node)
18909 add_stmt (stmt);
18910
18911 if (!structured_block && !no_semicolon)
18912 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
18913 }
18914
18915
18916 /* OpenMP 2.5:
18917 # pragma omp barrier new-line
18918 */
18919
18920 static void
c_parser_omp_barrier(c_parser * parser)18921 c_parser_omp_barrier (c_parser *parser)
18922 {
18923 location_t loc = c_parser_peek_token (parser)->location;
18924 c_parser_consume_pragma (parser);
18925 c_parser_skip_to_pragma_eol (parser);
18926
18927 c_finish_omp_barrier (loc);
18928 }
18929
18930 /* OpenMP 2.5:
18931 # pragma omp critical [(name)] new-line
18932 structured-block
18933
18934 OpenMP 4.5:
18935 # pragma omp critical [(name) [hint(expression)]] new-line
18936
18937 LOC is the location of the #pragma itself. */
18938
18939 #define OMP_CRITICAL_CLAUSE_MASK \
18940 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HINT) )
18941
18942 static tree
c_parser_omp_critical(location_t loc,c_parser * parser,bool * if_p)18943 c_parser_omp_critical (location_t loc, c_parser *parser, bool *if_p)
18944 {
18945 tree stmt, name = NULL_TREE, clauses = NULL_TREE;
18946
18947 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
18948 {
18949 c_parser_consume_token (parser);
18950 if (c_parser_next_token_is (parser, CPP_NAME))
18951 {
18952 name = c_parser_peek_token (parser)->value;
18953 c_parser_consume_token (parser);
18954 c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>");
18955 }
18956 else
18957 c_parser_error (parser, "expected identifier");
18958
18959 if (c_parser_next_token_is (parser, CPP_COMMA)
18960 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
18961 c_parser_consume_token (parser);
18962 }
18963 clauses = c_parser_omp_all_clauses (parser, OMP_CRITICAL_CLAUSE_MASK,
18964 "#pragma omp critical");
18965 stmt = c_parser_omp_structured_block (parser, if_p);
18966 return c_finish_omp_critical (loc, stmt, name, clauses);
18967 }
18968
18969 /* OpenMP 5.0:
18970 # pragma omp depobj ( depobj ) depobj-clause new-line
18971
18972 depobj-clause:
18973 depend (dependence-type : locator)
18974 destroy
18975 update (dependence-type)
18976
18977 dependence-type:
18978 in
18979 out
18980 inout
18981 mutexinout */
18982
18983 static void
c_parser_omp_depobj(c_parser * parser)18984 c_parser_omp_depobj (c_parser *parser)
18985 {
18986 location_t loc = c_parser_peek_token (parser)->location;
18987 c_parser_consume_pragma (parser);
18988 matching_parens parens;
18989 if (!parens.require_open (parser))
18990 {
18991 c_parser_skip_to_pragma_eol (parser);
18992 return;
18993 }
18994
18995 tree depobj = c_parser_expr_no_commas (parser, NULL).value;
18996 if (depobj != error_mark_node)
18997 {
18998 if (!lvalue_p (depobj))
18999 {
19000 error_at (EXPR_LOC_OR_LOC (depobj, loc),
19001 "%<depobj%> expression is not lvalue expression");
19002 depobj = error_mark_node;
19003 }
19004 else
19005 {
19006 tree addr = build_unary_op (EXPR_LOC_OR_LOC (depobj, loc), ADDR_EXPR,
19007 depobj, false);
19008 if (addr == error_mark_node)
19009 depobj = error_mark_node;
19010 else
19011 depobj = build_indirect_ref (EXPR_LOC_OR_LOC (depobj, loc),
19012 addr, RO_UNARY_STAR);
19013 }
19014 }
19015
19016 parens.skip_until_found_close (parser);
19017 tree clause = NULL_TREE;
19018 enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_SOURCE;
19019 location_t c_loc = c_parser_peek_token (parser)->location;
19020 if (c_parser_next_token_is (parser, CPP_NAME))
19021 {
19022 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19023
19024 c_parser_consume_token (parser);
19025 if (!strcmp ("depend", p))
19026 {
19027 clause = c_parser_omp_clause_depend (parser, NULL_TREE);
19028 clause = c_finish_omp_clauses (clause, C_ORT_OMP);
19029 if (!clause)
19030 clause = error_mark_node;
19031 }
19032 else if (!strcmp ("destroy", p))
19033 kind = OMP_CLAUSE_DEPEND_LAST;
19034 else if (!strcmp ("update", p))
19035 {
19036 matching_parens c_parens;
19037 if (c_parens.require_open (parser))
19038 {
19039 location_t c2_loc = c_parser_peek_token (parser)->location;
19040 if (c_parser_next_token_is (parser, CPP_NAME))
19041 {
19042 const char *p2
19043 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19044
19045 c_parser_consume_token (parser);
19046 if (!strcmp ("in", p2))
19047 kind = OMP_CLAUSE_DEPEND_IN;
19048 else if (!strcmp ("out", p2))
19049 kind = OMP_CLAUSE_DEPEND_OUT;
19050 else if (!strcmp ("inout", p2))
19051 kind = OMP_CLAUSE_DEPEND_INOUT;
19052 else if (!strcmp ("mutexinoutset", p2))
19053 kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET;
19054 }
19055 if (kind == OMP_CLAUSE_DEPEND_SOURCE)
19056 {
19057 clause = error_mark_node;
19058 error_at (c2_loc, "expected %<in%>, %<out%>, %<inout%> or "
19059 "%<mutexinoutset%>");
19060 }
19061 c_parens.skip_until_found_close (parser);
19062 }
19063 else
19064 clause = error_mark_node;
19065 }
19066 }
19067 if (!clause && kind == OMP_CLAUSE_DEPEND_SOURCE)
19068 {
19069 clause = error_mark_node;
19070 error_at (c_loc, "expected %<depend%>, %<destroy%> or %<update%> clause");
19071 }
19072 c_parser_skip_to_pragma_eol (parser);
19073
19074 c_finish_omp_depobj (loc, depobj, kind, clause);
19075 }
19076
19077
19078 /* OpenMP 2.5:
19079 # pragma omp flush flush-vars[opt] new-line
19080
19081 flush-vars:
19082 ( variable-list )
19083
19084 OpenMP 5.0:
19085 # pragma omp flush memory-order-clause new-line */
19086
19087 static void
c_parser_omp_flush(c_parser * parser)19088 c_parser_omp_flush (c_parser *parser)
19089 {
19090 location_t loc = c_parser_peek_token (parser)->location;
19091 c_parser_consume_pragma (parser);
19092 enum memmodel mo = MEMMODEL_LAST;
19093 if (c_parser_next_token_is (parser, CPP_NAME))
19094 {
19095 const char *p
19096 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19097
19098 if (!strcmp (p, "seq_cst"))
19099 mo = MEMMODEL_SEQ_CST;
19100 else if (!strcmp (p, "acq_rel"))
19101 mo = MEMMODEL_ACQ_REL;
19102 else if (!strcmp (p, "release"))
19103 mo = MEMMODEL_RELEASE;
19104 else if (!strcmp (p, "acquire"))
19105 mo = MEMMODEL_ACQUIRE;
19106 else
19107 error_at (c_parser_peek_token (parser)->location,
19108 "expected %<seq_cst%>, %<acq_rel%>, %<release%> or "
19109 "%<acquire%>");
19110 c_parser_consume_token (parser);
19111 }
19112 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
19113 {
19114 if (mo != MEMMODEL_LAST)
19115 error_at (c_parser_peek_token (parser)->location,
19116 "%<flush%> list specified together with memory order "
19117 "clause");
19118 c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
19119 }
19120 else if (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
19121 c_parser_error (parser, "expected %<(%> or end of line");
19122 c_parser_skip_to_pragma_eol (parser);
19123
19124 c_finish_omp_flush (loc, mo);
19125 }
19126
19127 /* Parse an OpenMP structured block sequence. KIND is the corresponding
19128 separating directive. */
19129
19130 static tree
c_parser_omp_structured_block_sequence(c_parser * parser,enum pragma_kind kind)19131 c_parser_omp_structured_block_sequence (c_parser *parser,
19132 enum pragma_kind kind)
19133 {
19134 tree stmt = push_stmt_list ();
19135 c_parser_statement (parser, NULL);
19136 do
19137 {
19138 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
19139 break;
19140 if (c_parser_next_token_is (parser, CPP_EOF))
19141 break;
19142
19143 if (kind != PRAGMA_NONE
19144 && c_parser_peek_token (parser)->pragma_kind == kind)
19145 break;
19146 c_parser_statement (parser, NULL);
19147 }
19148 while (1);
19149 return pop_stmt_list (stmt);
19150 }
19151
19152 /* OpenMP 5.0:
19153
19154 scan-loop-body:
19155 { structured-block scan-directive structured-block } */
19156
19157 static void
c_parser_omp_scan_loop_body(c_parser * parser,bool open_brace_parsed)19158 c_parser_omp_scan_loop_body (c_parser *parser, bool open_brace_parsed)
19159 {
19160 tree substmt;
19161 location_t loc;
19162 tree clauses = NULL_TREE;
19163
19164 loc = c_parser_peek_token (parser)->location;
19165 if (!open_brace_parsed
19166 && !c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
19167 {
19168 /* Avoid skipping until the end of the block. */
19169 parser->error = false;
19170 return;
19171 }
19172
19173 substmt = c_parser_omp_structured_block_sequence (parser, PRAGMA_OMP_SCAN);
19174 substmt = build2 (OMP_SCAN, void_type_node, substmt, NULL_TREE);
19175 SET_EXPR_LOCATION (substmt, loc);
19176 add_stmt (substmt);
19177
19178 loc = c_parser_peek_token (parser)->location;
19179 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SCAN)
19180 {
19181 enum omp_clause_code clause = OMP_CLAUSE_ERROR;
19182
19183 c_parser_consume_pragma (parser);
19184
19185 if (c_parser_next_token_is (parser, CPP_NAME))
19186 {
19187 const char *p
19188 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19189 if (strcmp (p, "inclusive") == 0)
19190 clause = OMP_CLAUSE_INCLUSIVE;
19191 else if (strcmp (p, "exclusive") == 0)
19192 clause = OMP_CLAUSE_EXCLUSIVE;
19193 }
19194 if (clause != OMP_CLAUSE_ERROR)
19195 {
19196 c_parser_consume_token (parser);
19197 clauses = c_parser_omp_var_list_parens (parser, clause, NULL_TREE);
19198 }
19199 else
19200 c_parser_error (parser, "expected %<inclusive%> or "
19201 "%<exclusive%> clause");
19202 c_parser_skip_to_pragma_eol (parser);
19203 }
19204 else
19205 error ("expected %<#pragma omp scan%>");
19206
19207 clauses = c_finish_omp_clauses (clauses, C_ORT_OMP);
19208 substmt = c_parser_omp_structured_block_sequence (parser, PRAGMA_NONE);
19209 substmt = build2 (OMP_SCAN, void_type_node, substmt, clauses);
19210 SET_EXPR_LOCATION (substmt, loc);
19211 add_stmt (substmt);
19212
19213 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE,
19214 "expected %<}%>");
19215 }
19216
19217 /* Parse the restricted form of loop statements allowed by OpenACC and OpenMP.
19218 The real trick here is to determine the loop control variable early
19219 so that we can push a new decl if necessary to make it private.
19220 LOC is the location of the "acc" or "omp" in "#pragma acc" or "#pragma omp",
19221 respectively. */
19222
19223 static tree
c_parser_omp_for_loop(location_t loc,c_parser * parser,enum tree_code code,tree clauses,tree * cclauses,bool * if_p)19224 c_parser_omp_for_loop (location_t loc, c_parser *parser, enum tree_code code,
19225 tree clauses, tree *cclauses, bool *if_p)
19226 {
19227 tree decl, cond, incr, body, init, stmt, cl;
19228 unsigned char save_in_statement;
19229 tree declv, condv, incrv, initv, ret = NULL_TREE;
19230 tree pre_body = NULL_TREE, this_pre_body;
19231 tree ordered_cl = NULL_TREE;
19232 bool fail = false, open_brace_parsed = false;
19233 int i, collapse = 1, ordered = 0, count, nbraces = 0;
19234 location_t for_loc;
19235 bool tiling = false;
19236 bool inscan = false;
19237 vec<tree, va_gc> *for_block = make_tree_vector ();
19238
19239 for (cl = clauses; cl; cl = OMP_CLAUSE_CHAIN (cl))
19240 if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_COLLAPSE)
19241 collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (cl));
19242 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_TILE)
19243 {
19244 tiling = true;
19245 collapse = list_length (OMP_CLAUSE_TILE_LIST (cl));
19246 }
19247 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_ORDERED
19248 && OMP_CLAUSE_ORDERED_EXPR (cl))
19249 {
19250 ordered_cl = cl;
19251 ordered = tree_to_shwi (OMP_CLAUSE_ORDERED_EXPR (cl));
19252 }
19253 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_REDUCTION
19254 && OMP_CLAUSE_REDUCTION_INSCAN (cl)
19255 && (code == OMP_SIMD || code == OMP_FOR))
19256 inscan = true;
19257
19258 if (ordered && ordered < collapse)
19259 {
19260 error_at (OMP_CLAUSE_LOCATION (ordered_cl),
19261 "%<ordered%> clause parameter is less than %<collapse%>");
19262 OMP_CLAUSE_ORDERED_EXPR (ordered_cl)
19263 = build_int_cst (NULL_TREE, collapse);
19264 ordered = collapse;
19265 }
19266 if (ordered)
19267 {
19268 for (tree *pc = &clauses; *pc; )
19269 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_LINEAR)
19270 {
19271 error_at (OMP_CLAUSE_LOCATION (*pc),
19272 "%<linear%> clause may not be specified together "
19273 "with %<ordered%> clause with a parameter");
19274 *pc = OMP_CLAUSE_CHAIN (*pc);
19275 }
19276 else
19277 pc = &OMP_CLAUSE_CHAIN (*pc);
19278 }
19279
19280 gcc_assert (tiling || (collapse >= 1 && ordered >= 0));
19281 count = ordered ? ordered : collapse;
19282
19283 declv = make_tree_vec (count);
19284 initv = make_tree_vec (count);
19285 condv = make_tree_vec (count);
19286 incrv = make_tree_vec (count);
19287
19288 if (!c_parser_next_token_is_keyword (parser, RID_FOR))
19289 {
19290 c_parser_error (parser, "for statement expected");
19291 return NULL;
19292 }
19293 for_loc = c_parser_peek_token (parser)->location;
19294 c_parser_consume_token (parser);
19295
19296 /* Forbid break/continue in the loop initializer, condition, and
19297 increment expressions. */
19298 save_in_statement = in_statement;
19299 in_statement = IN_OMP_BLOCK;
19300
19301 for (i = 0; i < count; i++)
19302 {
19303 int bracecount = 0;
19304
19305 matching_parens parens;
19306 if (!parens.require_open (parser))
19307 goto pop_scopes;
19308
19309 /* Parse the initialization declaration or expression. */
19310 if (c_parser_next_tokens_start_declaration (parser))
19311 {
19312 if (i > 0)
19313 vec_safe_push (for_block, c_begin_compound_stmt (true));
19314 this_pre_body = push_stmt_list ();
19315 c_in_omp_for = true;
19316 c_parser_declaration_or_fndef (parser, true, true, true, true, true);
19317 c_in_omp_for = false;
19318 if (this_pre_body)
19319 {
19320 this_pre_body = pop_stmt_list (this_pre_body);
19321 if (pre_body)
19322 {
19323 tree t = pre_body;
19324 pre_body = push_stmt_list ();
19325 add_stmt (t);
19326 add_stmt (this_pre_body);
19327 pre_body = pop_stmt_list (pre_body);
19328 }
19329 else
19330 pre_body = this_pre_body;
19331 }
19332 decl = check_for_loop_decls (for_loc, flag_isoc99);
19333 if (decl == NULL)
19334 goto error_init;
19335 if (DECL_INITIAL (decl) == error_mark_node)
19336 decl = error_mark_node;
19337 init = decl;
19338 }
19339 else if (c_parser_next_token_is (parser, CPP_NAME)
19340 && c_parser_peek_2nd_token (parser)->type == CPP_EQ)
19341 {
19342 struct c_expr decl_exp;
19343 struct c_expr init_exp;
19344 location_t init_loc;
19345
19346 decl_exp = c_parser_postfix_expression (parser);
19347 decl = decl_exp.value;
19348
19349 c_parser_require (parser, CPP_EQ, "expected %<=%>");
19350
19351 init_loc = c_parser_peek_token (parser)->location;
19352 init_exp = c_parser_expr_no_commas (parser, NULL);
19353 init_exp = default_function_array_read_conversion (init_loc,
19354 init_exp);
19355 c_in_omp_for = true;
19356 init = build_modify_expr (init_loc, decl, decl_exp.original_type,
19357 NOP_EXPR, init_loc, init_exp.value,
19358 init_exp.original_type);
19359 c_in_omp_for = false;
19360 init = c_process_expr_stmt (init_loc, init);
19361
19362 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
19363 }
19364 else
19365 {
19366 error_init:
19367 c_parser_error (parser,
19368 "expected iteration declaration or initialization");
19369 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
19370 "expected %<)%>");
19371 fail = true;
19372 goto parse_next;
19373 }
19374
19375 /* Parse the loop condition. */
19376 cond = NULL_TREE;
19377 if (c_parser_next_token_is_not (parser, CPP_SEMICOLON))
19378 {
19379 location_t cond_loc = c_parser_peek_token (parser)->location;
19380 c_in_omp_for = true;
19381 struct c_expr cond_expr
19382 = c_parser_binary_expression (parser, NULL, NULL_TREE);
19383 c_in_omp_for = false;
19384
19385 cond = cond_expr.value;
19386 cond = c_objc_common_truthvalue_conversion (cond_loc, cond);
19387 switch (cond_expr.original_code)
19388 {
19389 case GT_EXPR:
19390 case GE_EXPR:
19391 case LT_EXPR:
19392 case LE_EXPR:
19393 break;
19394 case NE_EXPR:
19395 if (code != OACC_LOOP)
19396 break;
19397 /* FALLTHRU. */
19398 default:
19399 /* Can't be cond = error_mark_node, because we want to preserve
19400 the location until c_finish_omp_for. */
19401 cond = build1 (NOP_EXPR, boolean_type_node, error_mark_node);
19402 break;
19403 }
19404 protected_set_expr_location (cond, cond_loc);
19405 }
19406 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
19407
19408 /* Parse the increment expression. */
19409 incr = NULL_TREE;
19410 if (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN))
19411 {
19412 location_t incr_loc = c_parser_peek_token (parser)->location;
19413
19414 incr = c_process_expr_stmt (incr_loc,
19415 c_parser_expression (parser).value);
19416 }
19417 parens.skip_until_found_close (parser);
19418
19419 if (decl == NULL || decl == error_mark_node || init == error_mark_node)
19420 fail = true;
19421 else
19422 {
19423 TREE_VEC_ELT (declv, i) = decl;
19424 TREE_VEC_ELT (initv, i) = init;
19425 TREE_VEC_ELT (condv, i) = cond;
19426 TREE_VEC_ELT (incrv, i) = incr;
19427 }
19428
19429 parse_next:
19430 if (i == count - 1)
19431 break;
19432
19433 /* FIXME: OpenMP 3.0 draft isn't very clear on what exactly is allowed
19434 in between the collapsed for loops to be still considered perfectly
19435 nested. Hopefully the final version clarifies this.
19436 For now handle (multiple) {'s and empty statements. */
19437 do
19438 {
19439 if (c_parser_next_token_is_keyword (parser, RID_FOR))
19440 {
19441 c_parser_consume_token (parser);
19442 break;
19443 }
19444 else if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
19445 {
19446 c_parser_consume_token (parser);
19447 bracecount++;
19448 }
19449 else if (bracecount
19450 && c_parser_next_token_is (parser, CPP_SEMICOLON))
19451 c_parser_consume_token (parser);
19452 else
19453 {
19454 c_parser_error (parser, "not enough perfectly nested loops");
19455 if (bracecount)
19456 {
19457 open_brace_parsed = true;
19458 bracecount--;
19459 }
19460 fail = true;
19461 count = 0;
19462 break;
19463 }
19464 }
19465 while (1);
19466
19467 nbraces += bracecount;
19468 }
19469
19470 if (nbraces)
19471 if_p = NULL;
19472
19473 in_statement = IN_OMP_FOR;
19474 body = push_stmt_list ();
19475
19476 if (inscan)
19477 c_parser_omp_scan_loop_body (parser, open_brace_parsed);
19478 else if (open_brace_parsed)
19479 {
19480 location_t here = c_parser_peek_token (parser)->location;
19481 stmt = c_begin_compound_stmt (true);
19482 c_parser_compound_statement_nostart (parser);
19483 add_stmt (c_end_compound_stmt (here, stmt, true));
19484 }
19485 else
19486 add_stmt (c_parser_c99_block_statement (parser, if_p));
19487
19488 body = pop_stmt_list (body);
19489 in_statement = save_in_statement;
19490
19491 while (nbraces)
19492 {
19493 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
19494 {
19495 c_parser_consume_token (parser);
19496 nbraces--;
19497 }
19498 else if (c_parser_next_token_is (parser, CPP_SEMICOLON))
19499 c_parser_consume_token (parser);
19500 else
19501 {
19502 c_parser_error (parser, "collapsed loops not perfectly nested");
19503 while (nbraces)
19504 {
19505 location_t here = c_parser_peek_token (parser)->location;
19506 stmt = c_begin_compound_stmt (true);
19507 add_stmt (body);
19508 c_parser_compound_statement_nostart (parser);
19509 body = c_end_compound_stmt (here, stmt, true);
19510 nbraces--;
19511 }
19512 goto pop_scopes;
19513 }
19514 }
19515
19516 /* Only bother calling c_finish_omp_for if we haven't already generated
19517 an error from the initialization parsing. */
19518 if (!fail)
19519 {
19520 c_in_omp_for = true;
19521 stmt = c_finish_omp_for (loc, code, declv, NULL, initv, condv,
19522 incrv, body, pre_body, true);
19523 c_in_omp_for = false;
19524
19525 /* Check for iterators appearing in lb, b or incr expressions. */
19526 if (stmt && !c_omp_check_loop_iv (stmt, declv, NULL))
19527 stmt = NULL_TREE;
19528
19529 if (stmt)
19530 {
19531 add_stmt (stmt);
19532
19533 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (stmt)); i++)
19534 {
19535 tree init = TREE_VEC_ELT (OMP_FOR_INIT (stmt), i);
19536 gcc_assert (TREE_CODE (init) == MODIFY_EXPR);
19537 tree decl = TREE_OPERAND (init, 0);
19538 tree cond = TREE_VEC_ELT (OMP_FOR_COND (stmt), i);
19539 gcc_assert (COMPARISON_CLASS_P (cond));
19540 gcc_assert (TREE_OPERAND (cond, 0) == decl);
19541
19542 tree op0 = TREE_OPERAND (init, 1);
19543 if (!OMP_FOR_NON_RECTANGULAR (stmt)
19544 || TREE_CODE (op0) != TREE_VEC)
19545 TREE_OPERAND (init, 1) = c_fully_fold (op0, false, NULL);
19546 else
19547 {
19548 TREE_VEC_ELT (op0, 1)
19549 = c_fully_fold (TREE_VEC_ELT (op0, 1), false, NULL);
19550 TREE_VEC_ELT (op0, 2)
19551 = c_fully_fold (TREE_VEC_ELT (op0, 2), false, NULL);
19552 }
19553
19554 tree op1 = TREE_OPERAND (cond, 1);
19555 if (!OMP_FOR_NON_RECTANGULAR (stmt)
19556 || TREE_CODE (op1) != TREE_VEC)
19557 TREE_OPERAND (cond, 1) = c_fully_fold (op1, false, NULL);
19558 else
19559 {
19560 TREE_VEC_ELT (op1, 1)
19561 = c_fully_fold (TREE_VEC_ELT (op1, 1), false, NULL);
19562 TREE_VEC_ELT (op1, 2)
19563 = c_fully_fold (TREE_VEC_ELT (op1, 2), false, NULL);
19564 }
19565 }
19566
19567 if (cclauses != NULL
19568 && cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] != NULL)
19569 {
19570 tree *c;
19571 for (c = &cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL]; *c ; )
19572 if (OMP_CLAUSE_CODE (*c) != OMP_CLAUSE_FIRSTPRIVATE
19573 && OMP_CLAUSE_CODE (*c) != OMP_CLAUSE_LASTPRIVATE)
19574 c = &OMP_CLAUSE_CHAIN (*c);
19575 else
19576 {
19577 for (i = 0; i < count; i++)
19578 if (TREE_VEC_ELT (declv, i) == OMP_CLAUSE_DECL (*c))
19579 break;
19580 if (i == count)
19581 c = &OMP_CLAUSE_CHAIN (*c);
19582 else if (OMP_CLAUSE_CODE (*c) == OMP_CLAUSE_FIRSTPRIVATE)
19583 {
19584 error_at (loc,
19585 "iteration variable %qD should not be firstprivate",
19586 OMP_CLAUSE_DECL (*c));
19587 *c = OMP_CLAUSE_CHAIN (*c);
19588 }
19589 else
19590 {
19591 /* Move lastprivate (decl) clause to OMP_FOR_CLAUSES. */
19592 tree l = *c;
19593 *c = OMP_CLAUSE_CHAIN (*c);
19594 if (code == OMP_SIMD)
19595 {
19596 OMP_CLAUSE_CHAIN (l)
19597 = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
19598 cclauses[C_OMP_CLAUSE_SPLIT_FOR] = l;
19599 }
19600 else
19601 {
19602 OMP_CLAUSE_CHAIN (l) = clauses;
19603 clauses = l;
19604 }
19605 }
19606 }
19607 }
19608 OMP_FOR_CLAUSES (stmt) = clauses;
19609 }
19610 ret = stmt;
19611 }
19612 pop_scopes:
19613 while (!for_block->is_empty ())
19614 {
19615 /* FIXME diagnostics: LOC below should be the actual location of
19616 this particular for block. We need to build a list of
19617 locations to go along with FOR_BLOCK. */
19618 stmt = c_end_compound_stmt (loc, for_block->pop (), true);
19619 add_stmt (stmt);
19620 }
19621 release_tree_vector (for_block);
19622 return ret;
19623 }
19624
19625 /* Helper function for OpenMP parsing, split clauses and call
19626 finish_omp_clauses on each of the set of clauses afterwards. */
19627
19628 static void
omp_split_clauses(location_t loc,enum tree_code code,omp_clause_mask mask,tree clauses,tree * cclauses)19629 omp_split_clauses (location_t loc, enum tree_code code,
19630 omp_clause_mask mask, tree clauses, tree *cclauses)
19631 {
19632 int i;
19633 c_omp_split_clauses (loc, code, mask, clauses, cclauses);
19634 for (i = 0; i < C_OMP_CLAUSE_SPLIT_COUNT; i++)
19635 if (cclauses[i])
19636 cclauses[i] = c_finish_omp_clauses (cclauses[i],
19637 i == C_OMP_CLAUSE_SPLIT_TARGET
19638 ? C_ORT_OMP_TARGET : C_ORT_OMP);
19639 }
19640
19641 /* OpenMP 5.0:
19642 #pragma omp loop loop-clause[optseq] new-line
19643 for-loop
19644
19645 LOC is the location of the #pragma token.
19646 */
19647
19648 #define OMP_LOOP_CLAUSE_MASK \
19649 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19650 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
19651 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
19652 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
19653 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_BIND) \
19654 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
19655
19656 static tree
c_parser_omp_loop(location_t loc,c_parser * parser,char * p_name,omp_clause_mask mask,tree * cclauses,bool * if_p)19657 c_parser_omp_loop (location_t loc, c_parser *parser,
19658 char *p_name, omp_clause_mask mask, tree *cclauses,
19659 bool *if_p)
19660 {
19661 tree block, clauses, ret;
19662
19663 strcat (p_name, " loop");
19664 mask |= OMP_LOOP_CLAUSE_MASK;
19665
19666 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
19667 if (cclauses)
19668 {
19669 omp_split_clauses (loc, OMP_LOOP, mask, clauses, cclauses);
19670 clauses = cclauses[C_OMP_CLAUSE_SPLIT_LOOP];
19671 }
19672
19673 block = c_begin_compound_stmt (true);
19674 ret = c_parser_omp_for_loop (loc, parser, OMP_LOOP, clauses, cclauses, if_p);
19675 block = c_end_compound_stmt (loc, block, true);
19676 add_stmt (block);
19677
19678 return ret;
19679 }
19680
19681 /* OpenMP 4.0:
19682 #pragma omp simd simd-clause[optseq] new-line
19683 for-loop
19684
19685 LOC is the location of the #pragma token.
19686 */
19687
19688 #define OMP_SIMD_CLAUSE_MASK \
19689 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SAFELEN) \
19690 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
19691 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
19692 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
19693 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19694 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
19695 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
19696 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
19697 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
19698 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NONTEMPORAL) \
19699 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
19700
19701 static tree
c_parser_omp_simd(location_t loc,c_parser * parser,char * p_name,omp_clause_mask mask,tree * cclauses,bool * if_p)19702 c_parser_omp_simd (location_t loc, c_parser *parser,
19703 char *p_name, omp_clause_mask mask, tree *cclauses,
19704 bool *if_p)
19705 {
19706 tree block, clauses, ret;
19707
19708 strcat (p_name, " simd");
19709 mask |= OMP_SIMD_CLAUSE_MASK;
19710
19711 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
19712 if (cclauses)
19713 {
19714 omp_split_clauses (loc, OMP_SIMD, mask, clauses, cclauses);
19715 clauses = cclauses[C_OMP_CLAUSE_SPLIT_SIMD];
19716 tree c = omp_find_clause (cclauses[C_OMP_CLAUSE_SPLIT_FOR],
19717 OMP_CLAUSE_ORDERED);
19718 if (c && OMP_CLAUSE_ORDERED_EXPR (c))
19719 {
19720 error_at (OMP_CLAUSE_LOCATION (c),
19721 "%<ordered%> clause with parameter may not be specified "
19722 "on %qs construct", p_name);
19723 OMP_CLAUSE_ORDERED_EXPR (c) = NULL_TREE;
19724 }
19725 }
19726
19727 block = c_begin_compound_stmt (true);
19728 ret = c_parser_omp_for_loop (loc, parser, OMP_SIMD, clauses, cclauses, if_p);
19729 block = c_end_compound_stmt (loc, block, true);
19730 add_stmt (block);
19731
19732 return ret;
19733 }
19734
19735 /* OpenMP 2.5:
19736 #pragma omp for for-clause[optseq] new-line
19737 for-loop
19738
19739 OpenMP 4.0:
19740 #pragma omp for simd for-simd-clause[optseq] new-line
19741 for-loop
19742
19743 LOC is the location of the #pragma token.
19744 */
19745
19746 #define OMP_FOR_CLAUSE_MASK \
19747 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19748 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
19749 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
19750 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
19751 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
19752 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED) \
19753 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE) \
19754 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
19755 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
19756 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
19757 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
19758
19759 static tree
c_parser_omp_for(location_t loc,c_parser * parser,char * p_name,omp_clause_mask mask,tree * cclauses,bool * if_p)19760 c_parser_omp_for (location_t loc, c_parser *parser,
19761 char *p_name, omp_clause_mask mask, tree *cclauses,
19762 bool *if_p)
19763 {
19764 tree block, clauses, ret;
19765
19766 strcat (p_name, " for");
19767 mask |= OMP_FOR_CLAUSE_MASK;
19768 /* parallel for{, simd} disallows nowait clause, but for
19769 target {teams distribute ,}parallel for{, simd} it should be accepted. */
19770 if (cclauses && (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) == 0)
19771 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT);
19772 /* Composite distribute parallel for{, simd} disallows ordered clause. */
19773 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
19774 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED);
19775
19776 if (c_parser_next_token_is (parser, CPP_NAME))
19777 {
19778 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19779
19780 if (strcmp (p, "simd") == 0)
19781 {
19782 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
19783 if (cclauses == NULL)
19784 cclauses = cclauses_buf;
19785
19786 c_parser_consume_token (parser);
19787 if (!flag_openmp) /* flag_openmp_simd */
19788 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
19789 if_p);
19790 block = c_begin_compound_stmt (true);
19791 ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses, if_p);
19792 block = c_end_compound_stmt (loc, block, true);
19793 if (ret == NULL_TREE)
19794 return ret;
19795 ret = make_node (OMP_FOR);
19796 TREE_TYPE (ret) = void_type_node;
19797 OMP_FOR_BODY (ret) = block;
19798 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
19799 SET_EXPR_LOCATION (ret, loc);
19800 add_stmt (ret);
19801 return ret;
19802 }
19803 }
19804 if (!flag_openmp) /* flag_openmp_simd */
19805 {
19806 c_parser_skip_to_pragma_eol (parser, false);
19807 return NULL_TREE;
19808 }
19809
19810 /* Composite distribute parallel for disallows linear clause. */
19811 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
19812 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR);
19813
19814 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
19815 if (cclauses)
19816 {
19817 omp_split_clauses (loc, OMP_FOR, mask, clauses, cclauses);
19818 clauses = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
19819 }
19820
19821 block = c_begin_compound_stmt (true);
19822 ret = c_parser_omp_for_loop (loc, parser, OMP_FOR, clauses, cclauses, if_p);
19823 block = c_end_compound_stmt (loc, block, true);
19824 add_stmt (block);
19825
19826 return ret;
19827 }
19828
19829 static tree c_parser_omp_taskloop (location_t, c_parser *, char *,
19830 omp_clause_mask, tree *, bool *);
19831
19832 /* OpenMP 2.5:
19833 # pragma omp master new-line
19834 structured-block
19835
19836 LOC is the location of the #pragma token.
19837 */
19838
19839 static tree
c_parser_omp_master(location_t loc,c_parser * parser,char * p_name,omp_clause_mask mask,tree * cclauses,bool * if_p)19840 c_parser_omp_master (location_t loc, c_parser *parser,
19841 char *p_name, omp_clause_mask mask, tree *cclauses,
19842 bool *if_p)
19843 {
19844 tree block, clauses, ret;
19845
19846 strcat (p_name, " master");
19847
19848 if (c_parser_next_token_is (parser, CPP_NAME))
19849 {
19850 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19851
19852 if (strcmp (p, "taskloop") == 0)
19853 {
19854 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
19855 if (cclauses == NULL)
19856 cclauses = cclauses_buf;
19857
19858 c_parser_consume_token (parser);
19859 if (!flag_openmp) /* flag_openmp_simd */
19860 return c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
19861 if_p);
19862 block = c_begin_compound_stmt (true);
19863 ret = c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
19864 if_p);
19865 block = c_end_compound_stmt (loc, block, true);
19866 if (ret == NULL_TREE)
19867 return ret;
19868 ret = c_finish_omp_master (loc, block);
19869 OMP_MASTER_COMBINED (ret) = 1;
19870 return ret;
19871 }
19872 }
19873 if (!flag_openmp) /* flag_openmp_simd */
19874 {
19875 c_parser_skip_to_pragma_eol (parser, false);
19876 return NULL_TREE;
19877 }
19878
19879 if (cclauses)
19880 {
19881 clauses = c_parser_omp_all_clauses (parser, mask, p_name, false);
19882 omp_split_clauses (loc, OMP_MASTER, mask, clauses, cclauses);
19883 }
19884 else
19885 c_parser_skip_to_pragma_eol (parser);
19886
19887 return c_finish_omp_master (loc, c_parser_omp_structured_block (parser,
19888 if_p));
19889 }
19890
19891 /* OpenMP 5.1:
19892 # pragma omp masked masked-clauses new-line
19893 structured-block
19894
19895 LOC is the location of the #pragma token.
19896 */
19897
19898 #define OMP_MASKED_CLAUSE_MASK \
19899 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FILTER)
19900
19901 static tree
c_parser_omp_masked(location_t loc,c_parser * parser,char * p_name,omp_clause_mask mask,tree * cclauses,bool * if_p)19902 c_parser_omp_masked (location_t loc, c_parser *parser,
19903 char *p_name, omp_clause_mask mask, tree *cclauses,
19904 bool *if_p)
19905 {
19906 tree block, clauses, ret;
19907
19908 strcat (p_name, " masked");
19909 mask |= OMP_MASKED_CLAUSE_MASK;
19910
19911 if (c_parser_next_token_is (parser, CPP_NAME))
19912 {
19913 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19914
19915 if (strcmp (p, "taskloop") == 0)
19916 {
19917 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
19918 if (cclauses == NULL)
19919 cclauses = cclauses_buf;
19920
19921 c_parser_consume_token (parser);
19922 if (!flag_openmp) /* flag_openmp_simd */
19923 return c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
19924 if_p);
19925 block = c_begin_compound_stmt (true);
19926 ret = c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
19927 if_p);
19928 block = c_end_compound_stmt (loc, block, true);
19929 if (ret == NULL_TREE)
19930 return ret;
19931 ret = c_finish_omp_masked (loc, block,
19932 cclauses[C_OMP_CLAUSE_SPLIT_MASKED]);
19933 OMP_MASKED_COMBINED (ret) = 1;
19934 return ret;
19935 }
19936 }
19937 if (!flag_openmp) /* flag_openmp_simd */
19938 {
19939 c_parser_skip_to_pragma_eol (parser, false);
19940 return NULL_TREE;
19941 }
19942
19943 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
19944 if (cclauses)
19945 {
19946 omp_split_clauses (loc, OMP_MASKED, mask, clauses, cclauses);
19947 clauses = cclauses[C_OMP_CLAUSE_SPLIT_MASKED];
19948 }
19949
19950 return c_finish_omp_masked (loc, c_parser_omp_structured_block (parser,
19951 if_p),
19952 clauses);
19953 }
19954
19955 /* OpenMP 2.5:
19956 # pragma omp ordered new-line
19957 structured-block
19958
19959 OpenMP 4.5:
19960 # pragma omp ordered ordered-clauses new-line
19961 structured-block
19962
19963 # pragma omp ordered depend-clauses new-line */
19964
19965 #define OMP_ORDERED_CLAUSE_MASK \
19966 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREADS) \
19967 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMD))
19968
19969 #define OMP_ORDERED_DEPEND_CLAUSE_MASK \
19970 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)
19971
19972 static bool
c_parser_omp_ordered(c_parser * parser,enum pragma_context context,bool * if_p)19973 c_parser_omp_ordered (c_parser *parser, enum pragma_context context,
19974 bool *if_p)
19975 {
19976 location_t loc = c_parser_peek_token (parser)->location;
19977 c_parser_consume_pragma (parser);
19978
19979 if (context != pragma_stmt && context != pragma_compound)
19980 {
19981 c_parser_error (parser, "expected declaration specifiers");
19982 c_parser_skip_to_pragma_eol (parser, false);
19983 return false;
19984 }
19985
19986 if (c_parser_next_token_is (parser, CPP_NAME))
19987 {
19988 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19989
19990 if (!strcmp ("depend", p))
19991 {
19992 if (!flag_openmp) /* flag_openmp_simd */
19993 {
19994 c_parser_skip_to_pragma_eol (parser, false);
19995 return false;
19996 }
19997 if (context == pragma_stmt)
19998 {
19999 error_at (loc,
20000 "%<#pragma omp ordered%> with %<depend%> clause may "
20001 "only be used in compound statements");
20002 c_parser_skip_to_pragma_eol (parser, false);
20003 return true;
20004 }
20005
20006 tree clauses
20007 = c_parser_omp_all_clauses (parser,
20008 OMP_ORDERED_DEPEND_CLAUSE_MASK,
20009 "#pragma omp ordered");
20010 c_finish_omp_ordered (loc, clauses, NULL_TREE);
20011 return false;
20012 }
20013 }
20014
20015 tree clauses = c_parser_omp_all_clauses (parser, OMP_ORDERED_CLAUSE_MASK,
20016 "#pragma omp ordered");
20017
20018 if (!flag_openmp /* flag_openmp_simd */
20019 && omp_find_clause (clauses, OMP_CLAUSE_SIMD) == NULL_TREE)
20020 return false;
20021
20022 c_finish_omp_ordered (loc, clauses,
20023 c_parser_omp_structured_block (parser, if_p));
20024 return true;
20025 }
20026
20027 /* OpenMP 2.5:
20028
20029 section-scope:
20030 { section-sequence }
20031
20032 section-sequence:
20033 section-directive[opt] structured-block
20034 section-sequence section-directive structured-block
20035
20036 OpenMP 5.1 allows structured-block-sequence instead of structured-block.
20037
20038 SECTIONS_LOC is the location of the #pragma omp sections. */
20039
20040 static tree
c_parser_omp_sections_scope(location_t sections_loc,c_parser * parser)20041 c_parser_omp_sections_scope (location_t sections_loc, c_parser *parser)
20042 {
20043 tree stmt, substmt;
20044 bool error_suppress = false;
20045 location_t loc;
20046
20047 loc = c_parser_peek_token (parser)->location;
20048 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
20049 {
20050 /* Avoid skipping until the end of the block. */
20051 parser->error = false;
20052 return NULL_TREE;
20053 }
20054
20055 stmt = push_stmt_list ();
20056
20057 if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_SECTION)
20058 {
20059 substmt = c_parser_omp_structured_block_sequence (parser,
20060 PRAGMA_OMP_SECTION);
20061 substmt = build1 (OMP_SECTION, void_type_node, substmt);
20062 SET_EXPR_LOCATION (substmt, loc);
20063 add_stmt (substmt);
20064 }
20065
20066 while (1)
20067 {
20068 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
20069 break;
20070 if (c_parser_next_token_is (parser, CPP_EOF))
20071 break;
20072
20073 loc = c_parser_peek_token (parser)->location;
20074 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SECTION)
20075 {
20076 c_parser_consume_pragma (parser);
20077 c_parser_skip_to_pragma_eol (parser);
20078 error_suppress = false;
20079 }
20080 else if (!error_suppress)
20081 {
20082 error_at (loc, "expected %<#pragma omp section%> or %<}%>");
20083 error_suppress = true;
20084 }
20085
20086 substmt = c_parser_omp_structured_block_sequence (parser,
20087 PRAGMA_OMP_SECTION);
20088 substmt = build1 (OMP_SECTION, void_type_node, substmt);
20089 SET_EXPR_LOCATION (substmt, loc);
20090 add_stmt (substmt);
20091 }
20092 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE,
20093 "expected %<#pragma omp section%> or %<}%>");
20094
20095 substmt = pop_stmt_list (stmt);
20096
20097 stmt = make_node (OMP_SECTIONS);
20098 SET_EXPR_LOCATION (stmt, sections_loc);
20099 TREE_TYPE (stmt) = void_type_node;
20100 OMP_SECTIONS_BODY (stmt) = substmt;
20101
20102 return add_stmt (stmt);
20103 }
20104
20105 /* OpenMP 2.5:
20106 # pragma omp sections sections-clause[optseq] newline
20107 sections-scope
20108
20109 LOC is the location of the #pragma token.
20110 */
20111
20112 #define OMP_SECTIONS_CLAUSE_MASK \
20113 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20114 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20115 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
20116 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
20117 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20118 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20119
20120 static tree
c_parser_omp_sections(location_t loc,c_parser * parser,char * p_name,omp_clause_mask mask,tree * cclauses)20121 c_parser_omp_sections (location_t loc, c_parser *parser,
20122 char *p_name, omp_clause_mask mask, tree *cclauses)
20123 {
20124 tree block, clauses, ret;
20125
20126 strcat (p_name, " sections");
20127 mask |= OMP_SECTIONS_CLAUSE_MASK;
20128 if (cclauses)
20129 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT);
20130
20131 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
20132 if (cclauses)
20133 {
20134 omp_split_clauses (loc, OMP_SECTIONS, mask, clauses, cclauses);
20135 clauses = cclauses[C_OMP_CLAUSE_SPLIT_SECTIONS];
20136 }
20137
20138 block = c_begin_compound_stmt (true);
20139 ret = c_parser_omp_sections_scope (loc, parser);
20140 if (ret)
20141 OMP_SECTIONS_CLAUSES (ret) = clauses;
20142 block = c_end_compound_stmt (loc, block, true);
20143 add_stmt (block);
20144
20145 return ret;
20146 }
20147
20148 /* OpenMP 2.5:
20149 # pragma omp parallel parallel-clause[optseq] new-line
20150 structured-block
20151 # pragma omp parallel for parallel-for-clause[optseq] new-line
20152 structured-block
20153 # pragma omp parallel sections parallel-sections-clause[optseq] new-line
20154 structured-block
20155
20156 OpenMP 4.0:
20157 # pragma omp parallel for simd parallel-for-simd-clause[optseq] new-line
20158 structured-block
20159
20160 LOC is the location of the #pragma token.
20161 */
20162
20163 #define OMP_PARALLEL_CLAUSE_MASK \
20164 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
20165 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20166 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20167 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
20168 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
20169 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN) \
20170 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
20171 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS) \
20172 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20173 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PROC_BIND))
20174
20175 static tree
c_parser_omp_parallel(location_t loc,c_parser * parser,char * p_name,omp_clause_mask mask,tree * cclauses,bool * if_p)20176 c_parser_omp_parallel (location_t loc, c_parser *parser,
20177 char *p_name, omp_clause_mask mask, tree *cclauses,
20178 bool *if_p)
20179 {
20180 tree stmt, clauses, block;
20181
20182 strcat (p_name, " parallel");
20183 mask |= OMP_PARALLEL_CLAUSE_MASK;
20184 /* #pragma omp target parallel{, for, for simd} disallow copyin clause. */
20185 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) != 0
20186 && (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) == 0)
20187 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN);
20188
20189 if (c_parser_next_token_is_keyword (parser, RID_FOR))
20190 {
20191 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20192 if (cclauses == NULL)
20193 cclauses = cclauses_buf;
20194
20195 c_parser_consume_token (parser);
20196 if (!flag_openmp) /* flag_openmp_simd */
20197 return c_parser_omp_for (loc, parser, p_name, mask, cclauses, if_p);
20198 block = c_begin_omp_parallel ();
20199 tree ret = c_parser_omp_for (loc, parser, p_name, mask, cclauses, if_p);
20200 stmt
20201 = c_finish_omp_parallel (loc, cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
20202 block);
20203 if (ret == NULL_TREE)
20204 return ret;
20205 OMP_PARALLEL_COMBINED (stmt) = 1;
20206 return stmt;
20207 }
20208 /* When combined with distribute, parallel has to be followed by for.
20209 #pragma omp target parallel is allowed though. */
20210 else if (cclauses
20211 && (mask & (OMP_CLAUSE_MASK_1
20212 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
20213 {
20214 error_at (loc, "expected %<for%> after %qs", p_name);
20215 c_parser_skip_to_pragma_eol (parser);
20216 return NULL_TREE;
20217 }
20218 else if (c_parser_next_token_is (parser, CPP_NAME))
20219 {
20220 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20221 if (cclauses == NULL && strcmp (p, "masked") == 0)
20222 {
20223 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20224 cclauses = cclauses_buf;
20225
20226 c_parser_consume_token (parser);
20227 if (!flag_openmp) /* flag_openmp_simd */
20228 return c_parser_omp_masked (loc, parser, p_name, mask, cclauses,
20229 if_p);
20230 block = c_begin_omp_parallel ();
20231 tree ret = c_parser_omp_masked (loc, parser, p_name, mask, cclauses,
20232 if_p);
20233 stmt = c_finish_omp_parallel (loc,
20234 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
20235 block);
20236 if (ret == NULL)
20237 return ret;
20238 /* masked does have just filter clause, but during gimplification
20239 isn't represented by a gimplification omp context, so for
20240 #pragma omp parallel masked don't set OMP_PARALLEL_COMBINED,
20241 so that
20242 #pragma omp parallel masked
20243 #pragma omp taskloop simd lastprivate (x)
20244 isn't confused with
20245 #pragma omp parallel masked taskloop simd lastprivate (x) */
20246 if (OMP_MASKED_COMBINED (ret))
20247 OMP_PARALLEL_COMBINED (stmt) = 1;
20248 return stmt;
20249 }
20250 else if (cclauses == NULL && strcmp (p, "master") == 0)
20251 {
20252 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20253 cclauses = cclauses_buf;
20254
20255 c_parser_consume_token (parser);
20256 if (!flag_openmp) /* flag_openmp_simd */
20257 return c_parser_omp_master (loc, parser, p_name, mask, cclauses,
20258 if_p);
20259 block = c_begin_omp_parallel ();
20260 tree ret = c_parser_omp_master (loc, parser, p_name, mask, cclauses,
20261 if_p);
20262 stmt = c_finish_omp_parallel (loc,
20263 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
20264 block);
20265 if (ret == NULL)
20266 return ret;
20267 /* master doesn't have any clauses and during gimplification
20268 isn't represented by a gimplification omp context, so for
20269 #pragma omp parallel master don't set OMP_PARALLEL_COMBINED,
20270 so that
20271 #pragma omp parallel master
20272 #pragma omp taskloop simd lastprivate (x)
20273 isn't confused with
20274 #pragma omp parallel master taskloop simd lastprivate (x) */
20275 if (OMP_MASTER_COMBINED (ret))
20276 OMP_PARALLEL_COMBINED (stmt) = 1;
20277 return stmt;
20278 }
20279 else if (strcmp (p, "loop") == 0)
20280 {
20281 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20282 if (cclauses == NULL)
20283 cclauses = cclauses_buf;
20284
20285 c_parser_consume_token (parser);
20286 if (!flag_openmp) /* flag_openmp_simd */
20287 return c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
20288 if_p);
20289 block = c_begin_omp_parallel ();
20290 tree ret = c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
20291 if_p);
20292 stmt
20293 = c_finish_omp_parallel (loc,
20294 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
20295 block);
20296 if (ret == NULL_TREE)
20297 return ret;
20298 OMP_PARALLEL_COMBINED (stmt) = 1;
20299 return stmt;
20300 }
20301 else if (!flag_openmp) /* flag_openmp_simd */
20302 {
20303 c_parser_skip_to_pragma_eol (parser, false);
20304 return NULL_TREE;
20305 }
20306 else if (cclauses == NULL && strcmp (p, "sections") == 0)
20307 {
20308 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20309 cclauses = cclauses_buf;
20310
20311 c_parser_consume_token (parser);
20312 block = c_begin_omp_parallel ();
20313 c_parser_omp_sections (loc, parser, p_name, mask, cclauses);
20314 stmt = c_finish_omp_parallel (loc,
20315 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
20316 block);
20317 OMP_PARALLEL_COMBINED (stmt) = 1;
20318 return stmt;
20319 }
20320 }
20321 else if (!flag_openmp) /* flag_openmp_simd */
20322 {
20323 c_parser_skip_to_pragma_eol (parser, false);
20324 return NULL_TREE;
20325 }
20326
20327 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
20328 if (cclauses)
20329 {
20330 omp_split_clauses (loc, OMP_PARALLEL, mask, clauses, cclauses);
20331 clauses = cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL];
20332 }
20333
20334 block = c_begin_omp_parallel ();
20335 c_parser_statement (parser, if_p);
20336 stmt = c_finish_omp_parallel (loc, clauses, block);
20337
20338 return stmt;
20339 }
20340
20341 /* OpenMP 2.5:
20342 # pragma omp single single-clause[optseq] new-line
20343 structured-block
20344
20345 LOC is the location of the #pragma.
20346 */
20347
20348 #define OMP_SINGLE_CLAUSE_MASK \
20349 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20350 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20351 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYPRIVATE) \
20352 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20353 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20354
20355 static tree
c_parser_omp_single(location_t loc,c_parser * parser,bool * if_p)20356 c_parser_omp_single (location_t loc, c_parser *parser, bool *if_p)
20357 {
20358 tree stmt = make_node (OMP_SINGLE);
20359 SET_EXPR_LOCATION (stmt, loc);
20360 TREE_TYPE (stmt) = void_type_node;
20361
20362 OMP_SINGLE_CLAUSES (stmt)
20363 = c_parser_omp_all_clauses (parser, OMP_SINGLE_CLAUSE_MASK,
20364 "#pragma omp single");
20365 OMP_SINGLE_BODY (stmt) = c_parser_omp_structured_block (parser, if_p);
20366
20367 return add_stmt (stmt);
20368 }
20369
20370 /* OpenMP 5.1:
20371 # pragma omp scope scope-clause[optseq] new-line
20372 structured-block
20373
20374 LOC is the location of the #pragma.
20375 */
20376
20377 #define OMP_SCOPE_CLAUSE_MASK \
20378 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20379 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
20380 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20381
20382 static tree
c_parser_omp_scope(location_t loc,c_parser * parser,bool * if_p)20383 c_parser_omp_scope (location_t loc, c_parser *parser, bool *if_p)
20384 {
20385 tree stmt = make_node (OMP_SCOPE);
20386 SET_EXPR_LOCATION (stmt, loc);
20387 TREE_TYPE (stmt) = void_type_node;
20388
20389 OMP_SCOPE_CLAUSES (stmt)
20390 = c_parser_omp_all_clauses (parser, OMP_SCOPE_CLAUSE_MASK,
20391 "#pragma omp scope");
20392 OMP_SCOPE_BODY (stmt) = c_parser_omp_structured_block (parser, if_p);
20393
20394 return add_stmt (stmt);
20395 }
20396
20397 /* OpenMP 3.0:
20398 # pragma omp task task-clause[optseq] new-line
20399
20400 LOC is the location of the #pragma.
20401 */
20402
20403 #define OMP_TASK_CLAUSE_MASK \
20404 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
20405 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
20406 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
20407 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20408 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20409 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
20410 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
20411 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
20412 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
20413 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
20414 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20415 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION) \
20416 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DETACH) \
20417 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_AFFINITY))
20418
20419 static tree
c_parser_omp_task(location_t loc,c_parser * parser,bool * if_p)20420 c_parser_omp_task (location_t loc, c_parser *parser, bool *if_p)
20421 {
20422 tree clauses, block;
20423
20424 clauses = c_parser_omp_all_clauses (parser, OMP_TASK_CLAUSE_MASK,
20425 "#pragma omp task");
20426
20427 block = c_begin_omp_task ();
20428 c_parser_statement (parser, if_p);
20429 return c_finish_omp_task (loc, clauses, block);
20430 }
20431
20432 /* OpenMP 3.0:
20433 # pragma omp taskwait new-line
20434
20435 OpenMP 5.0:
20436 # pragma omp taskwait taskwait-clause[optseq] new-line
20437 */
20438
20439 #define OMP_TASKWAIT_CLAUSE_MASK \
20440 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)
20441
20442 static void
c_parser_omp_taskwait(c_parser * parser)20443 c_parser_omp_taskwait (c_parser *parser)
20444 {
20445 location_t loc = c_parser_peek_token (parser)->location;
20446 c_parser_consume_pragma (parser);
20447
20448 tree clauses
20449 = c_parser_omp_all_clauses (parser, OMP_TASKWAIT_CLAUSE_MASK,
20450 "#pragma omp taskwait");
20451
20452 if (clauses)
20453 {
20454 tree stmt = make_node (OMP_TASK);
20455 TREE_TYPE (stmt) = void_node;
20456 OMP_TASK_CLAUSES (stmt) = clauses;
20457 OMP_TASK_BODY (stmt) = NULL_TREE;
20458 SET_EXPR_LOCATION (stmt, loc);
20459 add_stmt (stmt);
20460 }
20461 else
20462 c_finish_omp_taskwait (loc);
20463 }
20464
20465 /* OpenMP 3.1:
20466 # pragma omp taskyield new-line
20467 */
20468
20469 static void
c_parser_omp_taskyield(c_parser * parser)20470 c_parser_omp_taskyield (c_parser *parser)
20471 {
20472 location_t loc = c_parser_peek_token (parser)->location;
20473 c_parser_consume_pragma (parser);
20474 c_parser_skip_to_pragma_eol (parser);
20475
20476 c_finish_omp_taskyield (loc);
20477 }
20478
20479 /* OpenMP 4.0:
20480 # pragma omp taskgroup new-line
20481
20482 OpenMP 5.0:
20483 # pragma omp taskgroup taskgroup-clause[optseq] new-line
20484 */
20485
20486 #define OMP_TASKGROUP_CLAUSE_MASK \
20487 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20488 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASK_REDUCTION))
20489
20490 static tree
c_parser_omp_taskgroup(location_t loc,c_parser * parser,bool * if_p)20491 c_parser_omp_taskgroup (location_t loc, c_parser *parser, bool *if_p)
20492 {
20493 tree clauses = c_parser_omp_all_clauses (parser, OMP_TASKGROUP_CLAUSE_MASK,
20494 "#pragma omp taskgroup");
20495
20496 tree body = c_parser_omp_structured_block (parser, if_p);
20497 return c_finish_omp_taskgroup (loc, body, clauses);
20498 }
20499
20500 /* OpenMP 4.0:
20501 # pragma omp cancel cancel-clause[optseq] new-line
20502
20503 LOC is the location of the #pragma.
20504 */
20505
20506 #define OMP_CANCEL_CLAUSE_MASK \
20507 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
20508 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
20509 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
20510 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP) \
20511 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF))
20512
20513 static void
c_parser_omp_cancel(c_parser * parser)20514 c_parser_omp_cancel (c_parser *parser)
20515 {
20516 location_t loc = c_parser_peek_token (parser)->location;
20517
20518 c_parser_consume_pragma (parser);
20519 tree clauses = c_parser_omp_all_clauses (parser, OMP_CANCEL_CLAUSE_MASK,
20520 "#pragma omp cancel");
20521
20522 c_finish_omp_cancel (loc, clauses);
20523 }
20524
20525 /* OpenMP 4.0:
20526 # pragma omp cancellation point cancelpt-clause[optseq] new-line
20527
20528 LOC is the location of the #pragma.
20529 */
20530
20531 #define OMP_CANCELLATION_POINT_CLAUSE_MASK \
20532 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
20533 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
20534 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
20535 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP))
20536
20537 static bool
c_parser_omp_cancellation_point(c_parser * parser,enum pragma_context context)20538 c_parser_omp_cancellation_point (c_parser *parser, enum pragma_context context)
20539 {
20540 location_t loc = c_parser_peek_token (parser)->location;
20541 tree clauses;
20542 bool point_seen = false;
20543
20544 c_parser_consume_pragma (parser);
20545 if (c_parser_next_token_is (parser, CPP_NAME))
20546 {
20547 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20548 if (strcmp (p, "point") == 0)
20549 {
20550 c_parser_consume_token (parser);
20551 point_seen = true;
20552 }
20553 }
20554 if (!point_seen)
20555 {
20556 c_parser_error (parser, "expected %<point%>");
20557 c_parser_skip_to_pragma_eol (parser);
20558 return false;
20559 }
20560
20561 if (context != pragma_compound)
20562 {
20563 if (context == pragma_stmt)
20564 error_at (loc,
20565 "%<#pragma %s%> may only be used in compound statements",
20566 "omp cancellation point");
20567 else
20568 c_parser_error (parser, "expected declaration specifiers");
20569 c_parser_skip_to_pragma_eol (parser, false);
20570 return true;
20571 }
20572
20573 clauses
20574 = c_parser_omp_all_clauses (parser, OMP_CANCELLATION_POINT_CLAUSE_MASK,
20575 "#pragma omp cancellation point");
20576
20577 c_finish_omp_cancellation_point (loc, clauses);
20578 return true;
20579 }
20580
20581 /* OpenMP 4.0:
20582 #pragma omp distribute distribute-clause[optseq] new-line
20583 for-loop */
20584
20585 #define OMP_DISTRIBUTE_CLAUSE_MASK \
20586 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20587 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20588 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
20589 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)\
20590 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20591 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
20592 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
20593
20594 static tree
c_parser_omp_distribute(location_t loc,c_parser * parser,char * p_name,omp_clause_mask mask,tree * cclauses,bool * if_p)20595 c_parser_omp_distribute (location_t loc, c_parser *parser,
20596 char *p_name, omp_clause_mask mask, tree *cclauses,
20597 bool *if_p)
20598 {
20599 tree clauses, block, ret;
20600
20601 strcat (p_name, " distribute");
20602 mask |= OMP_DISTRIBUTE_CLAUSE_MASK;
20603
20604 if (c_parser_next_token_is (parser, CPP_NAME))
20605 {
20606 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20607 bool simd = false;
20608 bool parallel = false;
20609
20610 if (strcmp (p, "simd") == 0)
20611 simd = true;
20612 else
20613 parallel = strcmp (p, "parallel") == 0;
20614 if (parallel || simd)
20615 {
20616 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20617 if (cclauses == NULL)
20618 cclauses = cclauses_buf;
20619 c_parser_consume_token (parser);
20620 if (!flag_openmp) /* flag_openmp_simd */
20621 {
20622 if (simd)
20623 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
20624 if_p);
20625 else
20626 return c_parser_omp_parallel (loc, parser, p_name, mask,
20627 cclauses, if_p);
20628 }
20629 block = c_begin_compound_stmt (true);
20630 if (simd)
20631 ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
20632 if_p);
20633 else
20634 ret = c_parser_omp_parallel (loc, parser, p_name, mask, cclauses,
20635 if_p);
20636 block = c_end_compound_stmt (loc, block, true);
20637 if (ret == NULL)
20638 return ret;
20639 ret = make_node (OMP_DISTRIBUTE);
20640 TREE_TYPE (ret) = void_type_node;
20641 OMP_FOR_BODY (ret) = block;
20642 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE];
20643 SET_EXPR_LOCATION (ret, loc);
20644 add_stmt (ret);
20645 return ret;
20646 }
20647 }
20648 if (!flag_openmp) /* flag_openmp_simd */
20649 {
20650 c_parser_skip_to_pragma_eol (parser, false);
20651 return NULL_TREE;
20652 }
20653
20654 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
20655 if (cclauses)
20656 {
20657 omp_split_clauses (loc, OMP_DISTRIBUTE, mask, clauses, cclauses);
20658 clauses = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE];
20659 }
20660
20661 block = c_begin_compound_stmt (true);
20662 ret = c_parser_omp_for_loop (loc, parser, OMP_DISTRIBUTE, clauses, NULL,
20663 if_p);
20664 block = c_end_compound_stmt (loc, block, true);
20665 add_stmt (block);
20666
20667 return ret;
20668 }
20669
20670 /* OpenMP 4.0:
20671 # pragma omp teams teams-clause[optseq] new-line
20672 structured-block */
20673
20674 #define OMP_TEAMS_CLAUSE_MASK \
20675 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20676 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20677 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
20678 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
20679 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS) \
20680 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \
20681 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20682 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT))
20683
20684 static tree
c_parser_omp_teams(location_t loc,c_parser * parser,char * p_name,omp_clause_mask mask,tree * cclauses,bool * if_p)20685 c_parser_omp_teams (location_t loc, c_parser *parser,
20686 char *p_name, omp_clause_mask mask, tree *cclauses,
20687 bool *if_p)
20688 {
20689 tree clauses, block, ret;
20690
20691 strcat (p_name, " teams");
20692 mask |= OMP_TEAMS_CLAUSE_MASK;
20693
20694 if (c_parser_next_token_is (parser, CPP_NAME))
20695 {
20696 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20697 if (strcmp (p, "distribute") == 0)
20698 {
20699 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20700 if (cclauses == NULL)
20701 cclauses = cclauses_buf;
20702
20703 c_parser_consume_token (parser);
20704 if (!flag_openmp) /* flag_openmp_simd */
20705 return c_parser_omp_distribute (loc, parser, p_name, mask,
20706 cclauses, if_p);
20707 block = c_begin_omp_parallel ();
20708 ret = c_parser_omp_distribute (loc, parser, p_name, mask, cclauses,
20709 if_p);
20710 block = c_end_compound_stmt (loc, block, true);
20711 if (ret == NULL)
20712 return ret;
20713 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
20714 ret = make_node (OMP_TEAMS);
20715 TREE_TYPE (ret) = void_type_node;
20716 OMP_TEAMS_CLAUSES (ret) = clauses;
20717 OMP_TEAMS_BODY (ret) = block;
20718 OMP_TEAMS_COMBINED (ret) = 1;
20719 SET_EXPR_LOCATION (ret, loc);
20720 return add_stmt (ret);
20721 }
20722 else if (strcmp (p, "loop") == 0)
20723 {
20724 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20725 if (cclauses == NULL)
20726 cclauses = cclauses_buf;
20727
20728 c_parser_consume_token (parser);
20729 if (!flag_openmp) /* flag_openmp_simd */
20730 return c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
20731 if_p);
20732 block = c_begin_omp_parallel ();
20733 ret = c_parser_omp_loop (loc, parser, p_name, mask, cclauses, if_p);
20734 block = c_end_compound_stmt (loc, block, true);
20735 if (ret == NULL)
20736 return ret;
20737 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
20738 ret = make_node (OMP_TEAMS);
20739 TREE_TYPE (ret) = void_type_node;
20740 OMP_TEAMS_CLAUSES (ret) = clauses;
20741 OMP_TEAMS_BODY (ret) = block;
20742 OMP_TEAMS_COMBINED (ret) = 1;
20743 SET_EXPR_LOCATION (ret, loc);
20744 return add_stmt (ret);
20745 }
20746 }
20747 if (!flag_openmp) /* flag_openmp_simd */
20748 {
20749 c_parser_skip_to_pragma_eol (parser, false);
20750 return NULL_TREE;
20751 }
20752
20753 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
20754 if (cclauses)
20755 {
20756 omp_split_clauses (loc, OMP_TEAMS, mask, clauses, cclauses);
20757 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
20758 }
20759
20760 tree stmt = make_node (OMP_TEAMS);
20761 TREE_TYPE (stmt) = void_type_node;
20762 OMP_TEAMS_CLAUSES (stmt) = clauses;
20763 block = c_begin_omp_parallel ();
20764 add_stmt (c_parser_omp_structured_block (parser, if_p));
20765 OMP_TEAMS_BODY (stmt) = c_end_compound_stmt (loc, block, true);
20766 SET_EXPR_LOCATION (stmt, loc);
20767
20768 return add_stmt (stmt);
20769 }
20770
20771 /* OpenMP 4.0:
20772 # pragma omp target data target-data-clause[optseq] new-line
20773 structured-block */
20774
20775 #define OMP_TARGET_DATA_CLAUSE_MASK \
20776 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
20777 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
20778 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
20779 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR) \
20780 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR))
20781
20782 static tree
c_parser_omp_target_data(location_t loc,c_parser * parser,bool * if_p)20783 c_parser_omp_target_data (location_t loc, c_parser *parser, bool *if_p)
20784 {
20785 tree clauses
20786 = c_parser_omp_all_clauses (parser, OMP_TARGET_DATA_CLAUSE_MASK,
20787 "#pragma omp target data");
20788 c_omp_adjust_map_clauses (clauses, false);
20789 int map_seen = 0;
20790 for (tree *pc = &clauses; *pc;)
20791 {
20792 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
20793 switch (OMP_CLAUSE_MAP_KIND (*pc))
20794 {
20795 case GOMP_MAP_TO:
20796 case GOMP_MAP_ALWAYS_TO:
20797 case GOMP_MAP_FROM:
20798 case GOMP_MAP_ALWAYS_FROM:
20799 case GOMP_MAP_TOFROM:
20800 case GOMP_MAP_ALWAYS_TOFROM:
20801 case GOMP_MAP_ALLOC:
20802 map_seen = 3;
20803 break;
20804 case GOMP_MAP_FIRSTPRIVATE_POINTER:
20805 case GOMP_MAP_ALWAYS_POINTER:
20806 case GOMP_MAP_ATTACH_DETACH:
20807 break;
20808 default:
20809 map_seen |= 1;
20810 error_at (OMP_CLAUSE_LOCATION (*pc),
20811 "%<#pragma omp target data%> with map-type other "
20812 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
20813 "on %<map%> clause");
20814 *pc = OMP_CLAUSE_CHAIN (*pc);
20815 continue;
20816 }
20817 else if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_PTR
20818 || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_ADDR)
20819 map_seen = 3;
20820 pc = &OMP_CLAUSE_CHAIN (*pc);
20821 }
20822
20823 if (map_seen != 3)
20824 {
20825 if (map_seen == 0)
20826 error_at (loc,
20827 "%<#pragma omp target data%> must contain at least "
20828 "one %<map%>, %<use_device_ptr%> or %<use_device_addr%> "
20829 "clause");
20830 return NULL_TREE;
20831 }
20832
20833 tree stmt = make_node (OMP_TARGET_DATA);
20834 TREE_TYPE (stmt) = void_type_node;
20835 OMP_TARGET_DATA_CLAUSES (stmt) = clauses;
20836 keep_next_level ();
20837 tree block = c_begin_compound_stmt (true);
20838 add_stmt (c_parser_omp_structured_block (parser, if_p));
20839 OMP_TARGET_DATA_BODY (stmt) = c_end_compound_stmt (loc, block, true);
20840
20841 SET_EXPR_LOCATION (stmt, loc);
20842 return add_stmt (stmt);
20843 }
20844
20845 /* OpenMP 4.0:
20846 # pragma omp target update target-update-clause[optseq] new-line */
20847
20848 #define OMP_TARGET_UPDATE_CLAUSE_MASK \
20849 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FROM) \
20850 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
20851 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
20852 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
20853 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
20854 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20855
20856 static bool
c_parser_omp_target_update(location_t loc,c_parser * parser,enum pragma_context context)20857 c_parser_omp_target_update (location_t loc, c_parser *parser,
20858 enum pragma_context context)
20859 {
20860 if (context == pragma_stmt)
20861 {
20862 error_at (loc, "%<#pragma %s%> may only be used in compound statements",
20863 "omp target update");
20864 c_parser_skip_to_pragma_eol (parser, false);
20865 return true;
20866 }
20867
20868 tree clauses
20869 = c_parser_omp_all_clauses (parser, OMP_TARGET_UPDATE_CLAUSE_MASK,
20870 "#pragma omp target update");
20871 if (omp_find_clause (clauses, OMP_CLAUSE_TO) == NULL_TREE
20872 && omp_find_clause (clauses, OMP_CLAUSE_FROM) == NULL_TREE)
20873 {
20874 error_at (loc,
20875 "%<#pragma omp target update%> must contain at least one "
20876 "%<from%> or %<to%> clauses");
20877 return false;
20878 }
20879
20880 tree stmt = make_node (OMP_TARGET_UPDATE);
20881 TREE_TYPE (stmt) = void_type_node;
20882 OMP_TARGET_UPDATE_CLAUSES (stmt) = clauses;
20883 SET_EXPR_LOCATION (stmt, loc);
20884 add_stmt (stmt);
20885 return false;
20886 }
20887
20888 /* OpenMP 4.5:
20889 # pragma omp target enter data target-data-clause[optseq] new-line */
20890
20891 #define OMP_TARGET_ENTER_DATA_CLAUSE_MASK \
20892 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
20893 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
20894 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
20895 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
20896 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20897
20898 static bool
c_parser_omp_target_enter_data(location_t loc,c_parser * parser,enum pragma_context context)20899 c_parser_omp_target_enter_data (location_t loc, c_parser *parser,
20900 enum pragma_context context)
20901 {
20902 bool data_seen = false;
20903 if (c_parser_next_token_is (parser, CPP_NAME))
20904 {
20905 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20906 if (strcmp (p, "data") == 0)
20907 {
20908 c_parser_consume_token (parser);
20909 data_seen = true;
20910 }
20911 }
20912 if (!data_seen)
20913 {
20914 c_parser_error (parser, "expected %<data%>");
20915 c_parser_skip_to_pragma_eol (parser);
20916 return false;
20917 }
20918
20919 if (context == pragma_stmt)
20920 {
20921 error_at (loc, "%<#pragma %s%> may only be used in compound statements",
20922 "omp target enter data");
20923 c_parser_skip_to_pragma_eol (parser, false);
20924 return true;
20925 }
20926
20927 tree clauses
20928 = c_parser_omp_all_clauses (parser, OMP_TARGET_ENTER_DATA_CLAUSE_MASK,
20929 "#pragma omp target enter data");
20930 c_omp_adjust_map_clauses (clauses, false);
20931 int map_seen = 0;
20932 for (tree *pc = &clauses; *pc;)
20933 {
20934 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
20935 switch (OMP_CLAUSE_MAP_KIND (*pc))
20936 {
20937 case GOMP_MAP_TO:
20938 case GOMP_MAP_ALWAYS_TO:
20939 case GOMP_MAP_ALLOC:
20940 map_seen = 3;
20941 break;
20942 case GOMP_MAP_FIRSTPRIVATE_POINTER:
20943 case GOMP_MAP_ALWAYS_POINTER:
20944 case GOMP_MAP_ATTACH_DETACH:
20945 break;
20946 default:
20947 map_seen |= 1;
20948 error_at (OMP_CLAUSE_LOCATION (*pc),
20949 "%<#pragma omp target enter data%> with map-type other "
20950 "than %<to%> or %<alloc%> on %<map%> clause");
20951 *pc = OMP_CLAUSE_CHAIN (*pc);
20952 continue;
20953 }
20954 pc = &OMP_CLAUSE_CHAIN (*pc);
20955 }
20956
20957 if (map_seen != 3)
20958 {
20959 if (map_seen == 0)
20960 error_at (loc,
20961 "%<#pragma omp target enter data%> must contain at least "
20962 "one %<map%> clause");
20963 return true;
20964 }
20965
20966 tree stmt = make_node (OMP_TARGET_ENTER_DATA);
20967 TREE_TYPE (stmt) = void_type_node;
20968 OMP_TARGET_ENTER_DATA_CLAUSES (stmt) = clauses;
20969 SET_EXPR_LOCATION (stmt, loc);
20970 add_stmt (stmt);
20971 return true;
20972 }
20973
20974 /* OpenMP 4.5:
20975 # pragma omp target exit data target-data-clause[optseq] new-line */
20976
20977 #define OMP_TARGET_EXIT_DATA_CLAUSE_MASK \
20978 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
20979 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
20980 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
20981 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
20982 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20983
20984 static bool
c_parser_omp_target_exit_data(location_t loc,c_parser * parser,enum pragma_context context)20985 c_parser_omp_target_exit_data (location_t loc, c_parser *parser,
20986 enum pragma_context context)
20987 {
20988 bool data_seen = false;
20989 if (c_parser_next_token_is (parser, CPP_NAME))
20990 {
20991 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20992 if (strcmp (p, "data") == 0)
20993 {
20994 c_parser_consume_token (parser);
20995 data_seen = true;
20996 }
20997 }
20998 if (!data_seen)
20999 {
21000 c_parser_error (parser, "expected %<data%>");
21001 c_parser_skip_to_pragma_eol (parser);
21002 return false;
21003 }
21004
21005 if (context == pragma_stmt)
21006 {
21007 error_at (loc, "%<#pragma %s%> may only be used in compound statements",
21008 "omp target exit data");
21009 c_parser_skip_to_pragma_eol (parser, false);
21010 return true;
21011 }
21012
21013 tree clauses
21014 = c_parser_omp_all_clauses (parser, OMP_TARGET_EXIT_DATA_CLAUSE_MASK,
21015 "#pragma omp target exit data");
21016 c_omp_adjust_map_clauses (clauses, false);
21017 int map_seen = 0;
21018 for (tree *pc = &clauses; *pc;)
21019 {
21020 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
21021 switch (OMP_CLAUSE_MAP_KIND (*pc))
21022 {
21023 case GOMP_MAP_FROM:
21024 case GOMP_MAP_ALWAYS_FROM:
21025 case GOMP_MAP_RELEASE:
21026 case GOMP_MAP_DELETE:
21027 map_seen = 3;
21028 break;
21029 case GOMP_MAP_FIRSTPRIVATE_POINTER:
21030 case GOMP_MAP_ALWAYS_POINTER:
21031 case GOMP_MAP_ATTACH_DETACH:
21032 break;
21033 default:
21034 map_seen |= 1;
21035 error_at (OMP_CLAUSE_LOCATION (*pc),
21036 "%<#pragma omp target exit data%> with map-type other "
21037 "than %<from%>, %<release%> or %<delete%> on %<map%>"
21038 " clause");
21039 *pc = OMP_CLAUSE_CHAIN (*pc);
21040 continue;
21041 }
21042 pc = &OMP_CLAUSE_CHAIN (*pc);
21043 }
21044
21045 if (map_seen != 3)
21046 {
21047 if (map_seen == 0)
21048 error_at (loc,
21049 "%<#pragma omp target exit data%> must contain at least one "
21050 "%<map%> clause");
21051 return true;
21052 }
21053
21054 tree stmt = make_node (OMP_TARGET_EXIT_DATA);
21055 TREE_TYPE (stmt) = void_type_node;
21056 OMP_TARGET_EXIT_DATA_CLAUSES (stmt) = clauses;
21057 SET_EXPR_LOCATION (stmt, loc);
21058 add_stmt (stmt);
21059 return true;
21060 }
21061
21062 /* OpenMP 4.0:
21063 # pragma omp target target-clause[optseq] new-line
21064 structured-block */
21065
21066 #define OMP_TARGET_CLAUSE_MASK \
21067 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
21068 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
21069 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
21070 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
21071 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
21072 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
21073 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
21074 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
21075 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULTMAP) \
21076 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION) \
21077 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \
21078 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR)\
21079 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR))
21080
21081 static bool
c_parser_omp_target(c_parser * parser,enum pragma_context context,bool * if_p)21082 c_parser_omp_target (c_parser *parser, enum pragma_context context, bool *if_p)
21083 {
21084 location_t loc = c_parser_peek_token (parser)->location;
21085 c_parser_consume_pragma (parser);
21086 tree *pc = NULL, stmt, block;
21087
21088 if (context != pragma_stmt && context != pragma_compound)
21089 {
21090 c_parser_error (parser, "expected declaration specifiers");
21091 c_parser_skip_to_pragma_eol (parser);
21092 return false;
21093 }
21094
21095 if (flag_openmp)
21096 omp_requires_mask
21097 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
21098
21099 if (c_parser_next_token_is (parser, CPP_NAME))
21100 {
21101 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21102 enum tree_code ccode = ERROR_MARK;
21103
21104 if (strcmp (p, "teams") == 0)
21105 ccode = OMP_TEAMS;
21106 else if (strcmp (p, "parallel") == 0)
21107 ccode = OMP_PARALLEL;
21108 else if (strcmp (p, "simd") == 0)
21109 ccode = OMP_SIMD;
21110 if (ccode != ERROR_MARK)
21111 {
21112 tree cclauses[C_OMP_CLAUSE_SPLIT_COUNT];
21113 char p_name[sizeof ("#pragma omp target teams distribute "
21114 "parallel for simd")];
21115
21116 c_parser_consume_token (parser);
21117 strcpy (p_name, "#pragma omp target");
21118 if (!flag_openmp) /* flag_openmp_simd */
21119 {
21120 tree stmt;
21121 switch (ccode)
21122 {
21123 case OMP_TEAMS:
21124 stmt = c_parser_omp_teams (loc, parser, p_name,
21125 OMP_TARGET_CLAUSE_MASK,
21126 cclauses, if_p);
21127 break;
21128 case OMP_PARALLEL:
21129 stmt = c_parser_omp_parallel (loc, parser, p_name,
21130 OMP_TARGET_CLAUSE_MASK,
21131 cclauses, if_p);
21132 break;
21133 case OMP_SIMD:
21134 stmt = c_parser_omp_simd (loc, parser, p_name,
21135 OMP_TARGET_CLAUSE_MASK,
21136 cclauses, if_p);
21137 break;
21138 default:
21139 gcc_unreachable ();
21140 }
21141 return stmt != NULL_TREE;
21142 }
21143 keep_next_level ();
21144 tree block = c_begin_compound_stmt (true), ret;
21145 switch (ccode)
21146 {
21147 case OMP_TEAMS:
21148 ret = c_parser_omp_teams (loc, parser, p_name,
21149 OMP_TARGET_CLAUSE_MASK, cclauses,
21150 if_p);
21151 break;
21152 case OMP_PARALLEL:
21153 ret = c_parser_omp_parallel (loc, parser, p_name,
21154 OMP_TARGET_CLAUSE_MASK, cclauses,
21155 if_p);
21156 break;
21157 case OMP_SIMD:
21158 ret = c_parser_omp_simd (loc, parser, p_name,
21159 OMP_TARGET_CLAUSE_MASK, cclauses,
21160 if_p);
21161 break;
21162 default:
21163 gcc_unreachable ();
21164 }
21165 block = c_end_compound_stmt (loc, block, true);
21166 if (ret == NULL_TREE)
21167 return false;
21168 if (ccode == OMP_TEAMS)
21169 /* For combined target teams, ensure the num_teams and
21170 thread_limit clause expressions are evaluated on the host,
21171 before entering the target construct. */
21172 for (tree c = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
21173 c; c = OMP_CLAUSE_CHAIN (c))
21174 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS
21175 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
21176 for (int i = 0;
21177 i <= (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS); ++i)
21178 if (OMP_CLAUSE_OPERAND (c, i)
21179 && TREE_CODE (OMP_CLAUSE_OPERAND (c, i)) != INTEGER_CST)
21180 {
21181 tree expr = OMP_CLAUSE_OPERAND (c, i);
21182 tree tmp = create_tmp_var_raw (TREE_TYPE (expr));
21183 expr = build4 (TARGET_EXPR, TREE_TYPE (expr), tmp,
21184 expr, NULL_TREE, NULL_TREE);
21185 add_stmt (expr);
21186 OMP_CLAUSE_OPERAND (c, i) = expr;
21187 tree tc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
21188 OMP_CLAUSE_FIRSTPRIVATE);
21189 OMP_CLAUSE_DECL (tc) = tmp;
21190 OMP_CLAUSE_CHAIN (tc)
21191 = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
21192 cclauses[C_OMP_CLAUSE_SPLIT_TARGET] = tc;
21193 }
21194 tree stmt = make_node (OMP_TARGET);
21195 TREE_TYPE (stmt) = void_type_node;
21196 OMP_TARGET_CLAUSES (stmt) = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
21197 c_omp_adjust_map_clauses (OMP_TARGET_CLAUSES (stmt), true);
21198 OMP_TARGET_BODY (stmt) = block;
21199 OMP_TARGET_COMBINED (stmt) = 1;
21200 SET_EXPR_LOCATION (stmt, loc);
21201 add_stmt (stmt);
21202 pc = &OMP_TARGET_CLAUSES (stmt);
21203 goto check_clauses;
21204 }
21205 else if (!flag_openmp) /* flag_openmp_simd */
21206 {
21207 c_parser_skip_to_pragma_eol (parser, false);
21208 return false;
21209 }
21210 else if (strcmp (p, "data") == 0)
21211 {
21212 c_parser_consume_token (parser);
21213 c_parser_omp_target_data (loc, parser, if_p);
21214 return true;
21215 }
21216 else if (strcmp (p, "enter") == 0)
21217 {
21218 c_parser_consume_token (parser);
21219 return c_parser_omp_target_enter_data (loc, parser, context);
21220 }
21221 else if (strcmp (p, "exit") == 0)
21222 {
21223 c_parser_consume_token (parser);
21224 return c_parser_omp_target_exit_data (loc, parser, context);
21225 }
21226 else if (strcmp (p, "update") == 0)
21227 {
21228 c_parser_consume_token (parser);
21229 return c_parser_omp_target_update (loc, parser, context);
21230 }
21231 }
21232 if (!flag_openmp) /* flag_openmp_simd */
21233 {
21234 c_parser_skip_to_pragma_eol (parser, false);
21235 return false;
21236 }
21237
21238 stmt = make_node (OMP_TARGET);
21239 TREE_TYPE (stmt) = void_type_node;
21240
21241 OMP_TARGET_CLAUSES (stmt)
21242 = c_parser_omp_all_clauses (parser, OMP_TARGET_CLAUSE_MASK,
21243 "#pragma omp target", false);
21244 for (tree c = OMP_TARGET_CLAUSES (stmt); c; c = OMP_CLAUSE_CHAIN (c))
21245 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION)
21246 {
21247 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
21248 OMP_CLAUSE_DECL (nc) = OMP_CLAUSE_DECL (c);
21249 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_ALWAYS_TOFROM);
21250 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (c);
21251 OMP_CLAUSE_CHAIN (c) = nc;
21252 }
21253 OMP_TARGET_CLAUSES (stmt)
21254 = c_finish_omp_clauses (OMP_TARGET_CLAUSES (stmt), C_ORT_OMP_TARGET);
21255 c_omp_adjust_map_clauses (OMP_TARGET_CLAUSES (stmt), true);
21256
21257 pc = &OMP_TARGET_CLAUSES (stmt);
21258 keep_next_level ();
21259 block = c_begin_compound_stmt (true);
21260 add_stmt (c_parser_omp_structured_block (parser, if_p));
21261 OMP_TARGET_BODY (stmt) = c_end_compound_stmt (loc, block, true);
21262
21263 SET_EXPR_LOCATION (stmt, loc);
21264 add_stmt (stmt);
21265
21266 check_clauses:
21267 while (*pc)
21268 {
21269 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
21270 switch (OMP_CLAUSE_MAP_KIND (*pc))
21271 {
21272 case GOMP_MAP_TO:
21273 case GOMP_MAP_ALWAYS_TO:
21274 case GOMP_MAP_FROM:
21275 case GOMP_MAP_ALWAYS_FROM:
21276 case GOMP_MAP_TOFROM:
21277 case GOMP_MAP_ALWAYS_TOFROM:
21278 case GOMP_MAP_ALLOC:
21279 case GOMP_MAP_FIRSTPRIVATE_POINTER:
21280 case GOMP_MAP_ALWAYS_POINTER:
21281 case GOMP_MAP_ATTACH_DETACH:
21282 break;
21283 default:
21284 error_at (OMP_CLAUSE_LOCATION (*pc),
21285 "%<#pragma omp target%> with map-type other "
21286 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
21287 "on %<map%> clause");
21288 *pc = OMP_CLAUSE_CHAIN (*pc);
21289 continue;
21290 }
21291 pc = &OMP_CLAUSE_CHAIN (*pc);
21292 }
21293 cfun->has_omp_target = true;
21294 return true;
21295 }
21296
21297 /* OpenMP 4.0:
21298 # pragma omp declare simd declare-simd-clauses[optseq] new-line
21299
21300 OpenMP 5.0:
21301 # pragma omp declare variant (identifier) match(context-selector) new-line
21302 */
21303
21304 #define OMP_DECLARE_SIMD_CLAUSE_MASK \
21305 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
21306 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
21307 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
21308 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM) \
21309 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INBRANCH) \
21310 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOTINBRANCH))
21311
21312 static void
c_parser_omp_declare_simd(c_parser * parser,enum pragma_context context)21313 c_parser_omp_declare_simd (c_parser *parser, enum pragma_context context)
21314 {
21315 c_token *token = c_parser_peek_token (parser);
21316 gcc_assert (token->type == CPP_NAME);
21317 tree kind = token->value;
21318 gcc_assert (strcmp (IDENTIFIER_POINTER (kind), "simd") == 0
21319 || strcmp (IDENTIFIER_POINTER (kind), "variant") == 0);
21320
21321 auto_vec<c_token> clauses;
21322 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
21323 {
21324 c_token *token = c_parser_peek_token (parser);
21325 if (token->type == CPP_EOF)
21326 {
21327 c_parser_skip_to_pragma_eol (parser);
21328 return;
21329 }
21330 clauses.safe_push (*token);
21331 c_parser_consume_token (parser);
21332 }
21333 clauses.safe_push (*c_parser_peek_token (parser));
21334 c_parser_skip_to_pragma_eol (parser);
21335
21336 while (c_parser_next_token_is (parser, CPP_PRAGMA))
21337 {
21338 if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_DECLARE
21339 || c_parser_peek_2nd_token (parser)->type != CPP_NAME
21340 || c_parser_peek_2nd_token (parser)->value != kind)
21341 {
21342 error ("%<#pragma omp declare %s%> must be followed by "
21343 "function declaration or definition or another "
21344 "%<#pragma omp declare %s%>",
21345 IDENTIFIER_POINTER (kind), IDENTIFIER_POINTER (kind));
21346 return;
21347 }
21348 c_parser_consume_pragma (parser);
21349 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
21350 {
21351 c_token *token = c_parser_peek_token (parser);
21352 if (token->type == CPP_EOF)
21353 {
21354 c_parser_skip_to_pragma_eol (parser);
21355 return;
21356 }
21357 clauses.safe_push (*token);
21358 c_parser_consume_token (parser);
21359 }
21360 clauses.safe_push (*c_parser_peek_token (parser));
21361 c_parser_skip_to_pragma_eol (parser);
21362 }
21363
21364 /* Make sure nothing tries to read past the end of the tokens. */
21365 c_token eof_token;
21366 memset (&eof_token, 0, sizeof (eof_token));
21367 eof_token.type = CPP_EOF;
21368 clauses.safe_push (eof_token);
21369 clauses.safe_push (eof_token);
21370
21371 switch (context)
21372 {
21373 case pragma_external:
21374 if (c_parser_next_token_is (parser, CPP_KEYWORD)
21375 && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
21376 {
21377 int ext = disable_extension_diagnostics ();
21378 do
21379 c_parser_consume_token (parser);
21380 while (c_parser_next_token_is (parser, CPP_KEYWORD)
21381 && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
21382 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
21383 NULL, &clauses);
21384 restore_extension_diagnostics (ext);
21385 }
21386 else
21387 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
21388 NULL, &clauses);
21389 break;
21390 case pragma_struct:
21391 case pragma_param:
21392 case pragma_stmt:
21393 error ("%<#pragma omp declare %s%> must be followed by "
21394 "function declaration or definition",
21395 IDENTIFIER_POINTER (kind));
21396 break;
21397 case pragma_compound:
21398 if (c_parser_next_token_is (parser, CPP_KEYWORD)
21399 && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
21400 {
21401 int ext = disable_extension_diagnostics ();
21402 do
21403 c_parser_consume_token (parser);
21404 while (c_parser_next_token_is (parser, CPP_KEYWORD)
21405 && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
21406 if (c_parser_next_tokens_start_declaration (parser))
21407 {
21408 c_parser_declaration_or_fndef (parser, true, true, true, true,
21409 true, NULL, &clauses);
21410 restore_extension_diagnostics (ext);
21411 break;
21412 }
21413 restore_extension_diagnostics (ext);
21414 }
21415 else if (c_parser_next_tokens_start_declaration (parser))
21416 {
21417 c_parser_declaration_or_fndef (parser, true, true, true, true, true,
21418 NULL, &clauses);
21419 break;
21420 }
21421 error ("%<#pragma omp declare %s%> must be followed by "
21422 "function declaration or definition",
21423 IDENTIFIER_POINTER (kind));
21424 break;
21425 default:
21426 gcc_unreachable ();
21427 }
21428 }
21429
21430 static const char *const omp_construct_selectors[] = {
21431 "simd", "target", "teams", "parallel", "for", NULL };
21432 static const char *const omp_device_selectors[] = {
21433 "kind", "isa", "arch", NULL };
21434 static const char *const omp_implementation_selectors[] = {
21435 "vendor", "extension", "atomic_default_mem_order", "unified_address",
21436 "unified_shared_memory", "dynamic_allocators", "reverse_offload", NULL };
21437 static const char *const omp_user_selectors[] = {
21438 "condition", NULL };
21439
21440 /* OpenMP 5.0:
21441
21442 trait-selector:
21443 trait-selector-name[([trait-score:]trait-property[,trait-property[,...]])]
21444
21445 trait-score:
21446 score(score-expression) */
21447
21448 static tree
c_parser_omp_context_selector(c_parser * parser,tree set,tree parms)21449 c_parser_omp_context_selector (c_parser *parser, tree set, tree parms)
21450 {
21451 tree ret = NULL_TREE;
21452 do
21453 {
21454 tree selector;
21455 if (c_parser_next_token_is (parser, CPP_KEYWORD)
21456 || c_parser_next_token_is (parser, CPP_NAME))
21457 selector = c_parser_peek_token (parser)->value;
21458 else
21459 {
21460 c_parser_error (parser, "expected trait selector name");
21461 return error_mark_node;
21462 }
21463
21464 tree properties = NULL_TREE;
21465 const char *const *selectors = NULL;
21466 bool allow_score = true;
21467 bool allow_user = false;
21468 int property_limit = 0;
21469 enum { CTX_PROPERTY_NONE, CTX_PROPERTY_USER, CTX_PROPERTY_NAME_LIST,
21470 CTX_PROPERTY_ID, CTX_PROPERTY_EXPR,
21471 CTX_PROPERTY_SIMD } property_kind = CTX_PROPERTY_NONE;
21472 switch (IDENTIFIER_POINTER (set)[0])
21473 {
21474 case 'c': /* construct */
21475 selectors = omp_construct_selectors;
21476 allow_score = false;
21477 property_limit = 1;
21478 property_kind = CTX_PROPERTY_SIMD;
21479 break;
21480 case 'd': /* device */
21481 selectors = omp_device_selectors;
21482 allow_score = false;
21483 allow_user = true;
21484 property_limit = 3;
21485 property_kind = CTX_PROPERTY_NAME_LIST;
21486 break;
21487 case 'i': /* implementation */
21488 selectors = omp_implementation_selectors;
21489 allow_user = true;
21490 property_limit = 3;
21491 property_kind = CTX_PROPERTY_NAME_LIST;
21492 break;
21493 case 'u': /* user */
21494 selectors = omp_user_selectors;
21495 property_limit = 1;
21496 property_kind = CTX_PROPERTY_EXPR;
21497 break;
21498 default:
21499 gcc_unreachable ();
21500 }
21501 for (int i = 0; ; i++)
21502 {
21503 if (selectors[i] == NULL)
21504 {
21505 if (allow_user)
21506 {
21507 property_kind = CTX_PROPERTY_USER;
21508 break;
21509 }
21510 else
21511 {
21512 error_at (c_parser_peek_token (parser)->location,
21513 "selector %qs not allowed for context selector "
21514 "set %qs", IDENTIFIER_POINTER (selector),
21515 IDENTIFIER_POINTER (set));
21516 c_parser_consume_token (parser);
21517 return error_mark_node;
21518 }
21519 }
21520 if (i == property_limit)
21521 property_kind = CTX_PROPERTY_NONE;
21522 if (strcmp (selectors[i], IDENTIFIER_POINTER (selector)) == 0)
21523 break;
21524 }
21525 if (property_kind == CTX_PROPERTY_NAME_LIST
21526 && IDENTIFIER_POINTER (set)[0] == 'i'
21527 && strcmp (IDENTIFIER_POINTER (selector),
21528 "atomic_default_mem_order") == 0)
21529 property_kind = CTX_PROPERTY_ID;
21530
21531 c_parser_consume_token (parser);
21532
21533 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
21534 {
21535 if (property_kind == CTX_PROPERTY_NONE)
21536 {
21537 error_at (c_parser_peek_token (parser)->location,
21538 "selector %qs does not accept any properties",
21539 IDENTIFIER_POINTER (selector));
21540 return error_mark_node;
21541 }
21542
21543 matching_parens parens;
21544 parens.require_open (parser);
21545
21546 c_token *token = c_parser_peek_token (parser);
21547 if (allow_score
21548 && c_parser_next_token_is (parser, CPP_NAME)
21549 && strcmp (IDENTIFIER_POINTER (token->value), "score") == 0
21550 && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN)
21551 {
21552 c_parser_consume_token (parser);
21553
21554 matching_parens parens2;
21555 parens2.require_open (parser);
21556 tree score = c_parser_expr_no_commas (parser, NULL).value;
21557 parens2.skip_until_found_close (parser);
21558 c_parser_require (parser, CPP_COLON, "expected %<:%>");
21559 if (score != error_mark_node)
21560 {
21561 mark_exp_read (score);
21562 score = c_fully_fold (score, false, NULL);
21563 if (!INTEGRAL_TYPE_P (TREE_TYPE (score))
21564 || TREE_CODE (score) != INTEGER_CST)
21565 error_at (token->location, "score argument must be "
21566 "constant integer expression");
21567 else if (tree_int_cst_sgn (score) < 0)
21568 error_at (token->location, "score argument must be "
21569 "non-negative");
21570 else
21571 properties = tree_cons (get_identifier (" score"),
21572 score, properties);
21573 }
21574 token = c_parser_peek_token (parser);
21575 }
21576
21577 switch (property_kind)
21578 {
21579 tree t;
21580 case CTX_PROPERTY_USER:
21581 do
21582 {
21583 t = c_parser_expr_no_commas (parser, NULL).value;
21584 if (TREE_CODE (t) == STRING_CST)
21585 properties = tree_cons (NULL_TREE, t, properties);
21586 else if (t != error_mark_node)
21587 {
21588 mark_exp_read (t);
21589 t = c_fully_fold (t, false, NULL);
21590 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
21591 || !tree_fits_shwi_p (t))
21592 error_at (token->location, "property must be "
21593 "constant integer expression or string "
21594 "literal");
21595 else
21596 properties = tree_cons (NULL_TREE, t, properties);
21597 }
21598 else
21599 return error_mark_node;
21600
21601 if (c_parser_next_token_is (parser, CPP_COMMA))
21602 c_parser_consume_token (parser);
21603 else
21604 break;
21605 }
21606 while (1);
21607 break;
21608 case CTX_PROPERTY_ID:
21609 if (c_parser_next_token_is (parser, CPP_KEYWORD)
21610 || c_parser_next_token_is (parser, CPP_NAME))
21611 {
21612 tree prop = c_parser_peek_token (parser)->value;
21613 c_parser_consume_token (parser);
21614 properties = tree_cons (prop, NULL_TREE, properties);
21615 }
21616 else
21617 {
21618 c_parser_error (parser, "expected identifier");
21619 return error_mark_node;
21620 }
21621 break;
21622 case CTX_PROPERTY_NAME_LIST:
21623 do
21624 {
21625 tree prop = NULL_TREE, value = NULL_TREE;
21626 if (c_parser_next_token_is (parser, CPP_KEYWORD)
21627 || c_parser_next_token_is (parser, CPP_NAME))
21628 {
21629 prop = c_parser_peek_token (parser)->value;
21630 c_parser_consume_token (parser);
21631 }
21632 else if (c_parser_next_token_is (parser, CPP_STRING))
21633 value = c_parser_string_literal (parser, false,
21634 false).value;
21635 else
21636 {
21637 c_parser_error (parser, "expected identifier or "
21638 "string literal");
21639 return error_mark_node;
21640 }
21641
21642 properties = tree_cons (prop, value, properties);
21643
21644 if (c_parser_next_token_is (parser, CPP_COMMA))
21645 c_parser_consume_token (parser);
21646 else
21647 break;
21648 }
21649 while (1);
21650 break;
21651 case CTX_PROPERTY_EXPR:
21652 t = c_parser_expr_no_commas (parser, NULL).value;
21653 if (t != error_mark_node)
21654 {
21655 mark_exp_read (t);
21656 t = c_fully_fold (t, false, NULL);
21657 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
21658 || !tree_fits_shwi_p (t))
21659 error_at (token->location, "property must be "
21660 "constant integer expression");
21661 else
21662 properties = tree_cons (NULL_TREE, t, properties);
21663 }
21664 else
21665 return error_mark_node;
21666 break;
21667 case CTX_PROPERTY_SIMD:
21668 if (parms == NULL_TREE)
21669 {
21670 error_at (token->location, "properties for %<simd%> "
21671 "selector may not be specified in "
21672 "%<metadirective%>");
21673 return error_mark_node;
21674 }
21675 tree c;
21676 c = c_parser_omp_all_clauses (parser,
21677 OMP_DECLARE_SIMD_CLAUSE_MASK,
21678 "simd", true, 2);
21679 c = c_omp_declare_simd_clauses_to_numbers (parms
21680 == error_mark_node
21681 ? NULL_TREE : parms,
21682 c);
21683 properties = c;
21684 break;
21685 default:
21686 gcc_unreachable ();
21687 }
21688
21689 parens.skip_until_found_close (parser);
21690 properties = nreverse (properties);
21691 }
21692 else if (property_kind == CTX_PROPERTY_NAME_LIST
21693 || property_kind == CTX_PROPERTY_ID
21694 || property_kind == CTX_PROPERTY_EXPR)
21695 {
21696 c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>");
21697 return error_mark_node;
21698 }
21699
21700 ret = tree_cons (selector, properties, ret);
21701
21702 if (c_parser_next_token_is (parser, CPP_COMMA))
21703 c_parser_consume_token (parser);
21704 else
21705 break;
21706 }
21707 while (1);
21708
21709 return nreverse (ret);
21710 }
21711
21712 /* OpenMP 5.0:
21713
21714 trait-set-selector[,trait-set-selector[,...]]
21715
21716 trait-set-selector:
21717 trait-set-selector-name = { trait-selector[, trait-selector[, ...]] }
21718
21719 trait-set-selector-name:
21720 constructor
21721 device
21722 implementation
21723 user */
21724
21725 static tree
c_parser_omp_context_selector_specification(c_parser * parser,tree parms)21726 c_parser_omp_context_selector_specification (c_parser *parser, tree parms)
21727 {
21728 tree ret = NULL_TREE;
21729 do
21730 {
21731 const char *setp = "";
21732 if (c_parser_next_token_is (parser, CPP_NAME))
21733 setp = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21734 switch (setp[0])
21735 {
21736 case 'c':
21737 if (strcmp (setp, "construct") == 0)
21738 setp = NULL;
21739 break;
21740 case 'd':
21741 if (strcmp (setp, "device") == 0)
21742 setp = NULL;
21743 break;
21744 case 'i':
21745 if (strcmp (setp, "implementation") == 0)
21746 setp = NULL;
21747 break;
21748 case 'u':
21749 if (strcmp (setp, "user") == 0)
21750 setp = NULL;
21751 break;
21752 default:
21753 break;
21754 }
21755 if (setp)
21756 {
21757 c_parser_error (parser, "expected %<construct%>, %<device%>, "
21758 "%<implementation%> or %<user%>");
21759 return error_mark_node;
21760 }
21761
21762 tree set = c_parser_peek_token (parser)->value;
21763 c_parser_consume_token (parser);
21764
21765 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
21766 return error_mark_node;
21767
21768 matching_braces braces;
21769 if (!braces.require_open (parser))
21770 return error_mark_node;
21771
21772 tree selectors = c_parser_omp_context_selector (parser, set, parms);
21773 if (selectors == error_mark_node)
21774 ret = error_mark_node;
21775 else if (ret != error_mark_node)
21776 ret = tree_cons (set, selectors, ret);
21777
21778 braces.skip_until_found_close (parser);
21779
21780 if (c_parser_next_token_is (parser, CPP_COMMA))
21781 c_parser_consume_token (parser);
21782 else
21783 break;
21784 }
21785 while (1);
21786
21787 if (ret == error_mark_node)
21788 return ret;
21789 return nreverse (ret);
21790 }
21791
21792 /* Finalize #pragma omp declare variant after FNDECL has been parsed, and put
21793 that into "omp declare variant base" attribute. */
21794
21795 static void
c_finish_omp_declare_variant(c_parser * parser,tree fndecl,tree parms)21796 c_finish_omp_declare_variant (c_parser *parser, tree fndecl, tree parms)
21797 {
21798 matching_parens parens;
21799 if (!parens.require_open (parser))
21800 {
21801 fail:
21802 c_parser_skip_to_pragma_eol (parser, false);
21803 return;
21804 }
21805
21806 if (c_parser_next_token_is_not (parser, CPP_NAME)
21807 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
21808 {
21809 c_parser_error (parser, "expected identifier");
21810 goto fail;
21811 }
21812
21813 c_token *token = c_parser_peek_token (parser);
21814 tree variant = lookup_name (token->value);
21815
21816 if (variant == NULL_TREE)
21817 {
21818 undeclared_variable (token->location, token->value);
21819 variant = error_mark_node;
21820 }
21821
21822 c_parser_consume_token (parser);
21823
21824 parens.require_close (parser);
21825
21826 const char *clause = "";
21827 location_t match_loc = c_parser_peek_token (parser)->location;
21828 if (c_parser_next_token_is (parser, CPP_NAME))
21829 clause = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21830 if (strcmp (clause, "match"))
21831 {
21832 c_parser_error (parser, "expected %<match%>");
21833 goto fail;
21834 }
21835
21836 c_parser_consume_token (parser);
21837
21838 if (!parens.require_open (parser))
21839 goto fail;
21840
21841 if (parms == NULL_TREE)
21842 parms = error_mark_node;
21843
21844 tree ctx = c_parser_omp_context_selector_specification (parser, parms);
21845 if (ctx == error_mark_node)
21846 goto fail;
21847 ctx = omp_check_context_selector (match_loc, ctx);
21848 if (ctx != error_mark_node && variant != error_mark_node)
21849 {
21850 if (TREE_CODE (variant) != FUNCTION_DECL)
21851 {
21852 error_at (token->location, "variant %qD is not a function", variant);
21853 variant = error_mark_node;
21854 }
21855 else if (omp_get_context_selector (ctx, "construct", "simd") == NULL_TREE
21856 && !comptypes (TREE_TYPE (fndecl), TREE_TYPE (variant)))
21857 {
21858 error_at (token->location, "variant %qD and base %qD have "
21859 "incompatible types", variant, fndecl);
21860 variant = error_mark_node;
21861 }
21862 else if (fndecl_built_in_p (variant)
21863 && (strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
21864 "__builtin_", strlen ("__builtin_")) == 0
21865 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
21866 "__sync_", strlen ("__sync_")) == 0
21867 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
21868 "__atomic_", strlen ("__atomic_")) == 0))
21869 {
21870 error_at (token->location, "variant %qD is a built-in", variant);
21871 variant = error_mark_node;
21872 }
21873 if (variant != error_mark_node)
21874 {
21875 C_DECL_USED (variant) = 1;
21876 tree construct = omp_get_context_selector (ctx, "construct", NULL);
21877 omp_mark_declare_variant (match_loc, variant, construct);
21878 if (omp_context_selector_matches (ctx))
21879 {
21880 tree attr
21881 = tree_cons (get_identifier ("omp declare variant base"),
21882 build_tree_list (variant, ctx),
21883 DECL_ATTRIBUTES (fndecl));
21884 DECL_ATTRIBUTES (fndecl) = attr;
21885 }
21886 }
21887 }
21888
21889 parens.require_close (parser);
21890 c_parser_skip_to_pragma_eol (parser);
21891 }
21892
21893 /* Finalize #pragma omp declare simd or #pragma omp declare variant
21894 clauses after FNDECL has been parsed, and put that into "omp declare simd"
21895 or "omp declare variant base" attribute. */
21896
21897 static void
c_finish_omp_declare_simd(c_parser * parser,tree fndecl,tree parms,vec<c_token> * pclauses)21898 c_finish_omp_declare_simd (c_parser *parser, tree fndecl, tree parms,
21899 vec<c_token> *pclauses)
21900 {
21901 vec<c_token> &clauses = *pclauses;
21902
21903 /* Normally first token is CPP_NAME "simd" or "variant". CPP_EOF there
21904 indicates error has been reported and CPP_PRAGMA that
21905 c_finish_omp_declare_simd has already processed the tokens. */
21906 if (clauses.exists () && clauses[0].type == CPP_EOF)
21907 return;
21908 const char *kind = "simd";
21909 if (clauses.exists ()
21910 && (clauses[0].type == CPP_NAME || clauses[0].type == CPP_PRAGMA))
21911 kind = IDENTIFIER_POINTER (clauses[0].value);
21912 gcc_assert (strcmp (kind, "simd") == 0 || strcmp (kind, "variant") == 0);
21913 if (fndecl == NULL_TREE || TREE_CODE (fndecl) != FUNCTION_DECL)
21914 {
21915 error ("%<#pragma omp declare %s%> not immediately followed by "
21916 "a function declaration or definition", kind);
21917 clauses[0].type = CPP_EOF;
21918 return;
21919 }
21920 if (clauses.exists () && clauses[0].type != CPP_NAME)
21921 {
21922 error_at (DECL_SOURCE_LOCATION (fndecl),
21923 "%<#pragma omp declare %s%> not immediately followed by "
21924 "a single function declaration or definition", kind);
21925 clauses[0].type = CPP_EOF;
21926 return;
21927 }
21928
21929 if (parms == NULL_TREE)
21930 parms = DECL_ARGUMENTS (fndecl);
21931
21932 unsigned int tokens_avail = parser->tokens_avail;
21933 gcc_assert (parser->tokens == &parser->tokens_buf[0]);
21934
21935 parser->tokens = clauses.address ();
21936 parser->tokens_avail = clauses.length ();
21937
21938 /* c_parser_omp_declare_simd pushed 2 extra CPP_EOF tokens at the end. */
21939 while (parser->tokens_avail > 3)
21940 {
21941 c_token *token = c_parser_peek_token (parser);
21942 gcc_assert (token->type == CPP_NAME
21943 && strcmp (IDENTIFIER_POINTER (token->value), kind) == 0);
21944 c_parser_consume_token (parser);
21945 parser->in_pragma = true;
21946
21947 if (strcmp (kind, "simd") == 0)
21948 {
21949 tree c;
21950 c = c_parser_omp_all_clauses (parser, OMP_DECLARE_SIMD_CLAUSE_MASK,
21951 "#pragma omp declare simd");
21952 c = c_omp_declare_simd_clauses_to_numbers (parms, c);
21953 if (c != NULL_TREE)
21954 c = tree_cons (NULL_TREE, c, NULL_TREE);
21955 c = build_tree_list (get_identifier ("omp declare simd"), c);
21956 TREE_CHAIN (c) = DECL_ATTRIBUTES (fndecl);
21957 DECL_ATTRIBUTES (fndecl) = c;
21958 }
21959 else
21960 {
21961 gcc_assert (strcmp (kind, "variant") == 0);
21962 c_finish_omp_declare_variant (parser, fndecl, parms);
21963 }
21964 }
21965
21966 parser->tokens = &parser->tokens_buf[0];
21967 parser->tokens_avail = tokens_avail;
21968 if (clauses.exists ())
21969 clauses[0].type = CPP_PRAGMA;
21970 }
21971
21972
21973 /* OpenMP 4.0:
21974 # pragma omp declare target new-line
21975 declarations and definitions
21976 # pragma omp end declare target new-line
21977
21978 OpenMP 4.5:
21979 # pragma omp declare target ( extended-list ) new-line
21980
21981 # pragma omp declare target declare-target-clauses[seq] new-line */
21982
21983 #define OMP_DECLARE_TARGET_CLAUSE_MASK \
21984 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
21985 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK) \
21986 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE))
21987
21988 static void
c_parser_omp_declare_target(c_parser * parser)21989 c_parser_omp_declare_target (c_parser *parser)
21990 {
21991 tree clauses = NULL_TREE;
21992 int device_type = 0;
21993 bool only_device_type = true;
21994 if (c_parser_next_token_is (parser, CPP_NAME))
21995 clauses = c_parser_omp_all_clauses (parser, OMP_DECLARE_TARGET_CLAUSE_MASK,
21996 "#pragma omp declare target");
21997 else if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
21998 {
21999 clauses = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_TO_DECLARE,
22000 clauses);
22001 clauses = c_finish_omp_clauses (clauses, C_ORT_OMP);
22002 c_parser_skip_to_pragma_eol (parser);
22003 }
22004 else
22005 {
22006 c_parser_skip_to_pragma_eol (parser);
22007 current_omp_declare_target_attribute++;
22008 return;
22009 }
22010 for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
22011 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
22012 device_type |= OMP_CLAUSE_DEVICE_TYPE_KIND (c);
22013 for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
22014 {
22015 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
22016 continue;
22017 tree t = OMP_CLAUSE_DECL (c), id;
22018 tree at1 = lookup_attribute ("omp declare target", DECL_ATTRIBUTES (t));
22019 tree at2 = lookup_attribute ("omp declare target link",
22020 DECL_ATTRIBUTES (t));
22021 only_device_type = false;
22022 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINK)
22023 {
22024 id = get_identifier ("omp declare target link");
22025 std::swap (at1, at2);
22026 }
22027 else
22028 id = get_identifier ("omp declare target");
22029 if (at2)
22030 {
22031 error_at (OMP_CLAUSE_LOCATION (c),
22032 "%qD specified both in declare target %<link%> and %<to%>"
22033 " clauses", t);
22034 continue;
22035 }
22036 if (!at1)
22037 {
22038 DECL_ATTRIBUTES (t) = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
22039 if (TREE_CODE (t) != FUNCTION_DECL && !is_global_var (t))
22040 continue;
22041
22042 symtab_node *node = symtab_node::get (t);
22043 if (node != NULL)
22044 {
22045 node->offloadable = 1;
22046 if (ENABLE_OFFLOADING)
22047 {
22048 g->have_offload = true;
22049 if (is_a <varpool_node *> (node))
22050 vec_safe_push (offload_vars, t);
22051 }
22052 }
22053 }
22054 if (TREE_CODE (t) != FUNCTION_DECL)
22055 continue;
22056 if ((device_type & OMP_CLAUSE_DEVICE_TYPE_HOST) != 0)
22057 {
22058 tree at3 = lookup_attribute ("omp declare target host",
22059 DECL_ATTRIBUTES (t));
22060 if (at3 == NULL_TREE)
22061 {
22062 id = get_identifier ("omp declare target host");
22063 DECL_ATTRIBUTES (t)
22064 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
22065 }
22066 }
22067 if ((device_type & OMP_CLAUSE_DEVICE_TYPE_NOHOST) != 0)
22068 {
22069 tree at3 = lookup_attribute ("omp declare target nohost",
22070 DECL_ATTRIBUTES (t));
22071 if (at3 == NULL_TREE)
22072 {
22073 id = get_identifier ("omp declare target nohost");
22074 DECL_ATTRIBUTES (t)
22075 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
22076 }
22077 }
22078 }
22079 if (device_type && only_device_type)
22080 warning_at (OMP_CLAUSE_LOCATION (clauses), 0,
22081 "directive with only %<device_type%> clauses ignored");
22082 }
22083
22084 static void
c_parser_omp_end_declare_target(c_parser * parser)22085 c_parser_omp_end_declare_target (c_parser *parser)
22086 {
22087 location_t loc = c_parser_peek_token (parser)->location;
22088 c_parser_consume_pragma (parser);
22089 if (c_parser_next_token_is (parser, CPP_NAME)
22090 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
22091 "declare") == 0)
22092 {
22093 c_parser_consume_token (parser);
22094 if (c_parser_next_token_is (parser, CPP_NAME)
22095 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
22096 "target") == 0)
22097 c_parser_consume_token (parser);
22098 else
22099 {
22100 c_parser_error (parser, "expected %<target%>");
22101 c_parser_skip_to_pragma_eol (parser);
22102 return;
22103 }
22104 }
22105 else
22106 {
22107 c_parser_error (parser, "expected %<declare%>");
22108 c_parser_skip_to_pragma_eol (parser);
22109 return;
22110 }
22111 c_parser_skip_to_pragma_eol (parser);
22112 if (!current_omp_declare_target_attribute)
22113 error_at (loc, "%<#pragma omp end declare target%> without corresponding "
22114 "%<#pragma omp declare target%>");
22115 else
22116 current_omp_declare_target_attribute--;
22117 }
22118
22119
22120 /* OpenMP 4.0
22121 #pragma omp declare reduction (reduction-id : typename-list : expression) \
22122 initializer-clause[opt] new-line
22123
22124 initializer-clause:
22125 initializer (omp_priv = initializer)
22126 initializer (function-name (argument-list)) */
22127
22128 static void
c_parser_omp_declare_reduction(c_parser * parser,enum pragma_context context)22129 c_parser_omp_declare_reduction (c_parser *parser, enum pragma_context context)
22130 {
22131 unsigned int tokens_avail = 0, i;
22132 vec<tree> types = vNULL;
22133 vec<c_token> clauses = vNULL;
22134 enum tree_code reduc_code = ERROR_MARK;
22135 tree reduc_id = NULL_TREE;
22136 tree type;
22137 location_t rloc = c_parser_peek_token (parser)->location;
22138
22139 if (context == pragma_struct || context == pragma_param)
22140 {
22141 error ("%<#pragma omp declare reduction%> not at file or block scope");
22142 goto fail;
22143 }
22144
22145 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
22146 goto fail;
22147
22148 switch (c_parser_peek_token (parser)->type)
22149 {
22150 case CPP_PLUS:
22151 reduc_code = PLUS_EXPR;
22152 break;
22153 case CPP_MULT:
22154 reduc_code = MULT_EXPR;
22155 break;
22156 case CPP_MINUS:
22157 reduc_code = MINUS_EXPR;
22158 break;
22159 case CPP_AND:
22160 reduc_code = BIT_AND_EXPR;
22161 break;
22162 case CPP_XOR:
22163 reduc_code = BIT_XOR_EXPR;
22164 break;
22165 case CPP_OR:
22166 reduc_code = BIT_IOR_EXPR;
22167 break;
22168 case CPP_AND_AND:
22169 reduc_code = TRUTH_ANDIF_EXPR;
22170 break;
22171 case CPP_OR_OR:
22172 reduc_code = TRUTH_ORIF_EXPR;
22173 break;
22174 case CPP_NAME:
22175 const char *p;
22176 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
22177 if (strcmp (p, "min") == 0)
22178 {
22179 reduc_code = MIN_EXPR;
22180 break;
22181 }
22182 if (strcmp (p, "max") == 0)
22183 {
22184 reduc_code = MAX_EXPR;
22185 break;
22186 }
22187 reduc_id = c_parser_peek_token (parser)->value;
22188 break;
22189 default:
22190 c_parser_error (parser,
22191 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
22192 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
22193 goto fail;
22194 }
22195
22196 tree orig_reduc_id, reduc_decl;
22197 orig_reduc_id = reduc_id;
22198 reduc_id = c_omp_reduction_id (reduc_code, reduc_id);
22199 reduc_decl = c_omp_reduction_decl (reduc_id);
22200 c_parser_consume_token (parser);
22201
22202 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
22203 goto fail;
22204
22205 while (true)
22206 {
22207 location_t loc = c_parser_peek_token (parser)->location;
22208 struct c_type_name *ctype = c_parser_type_name (parser);
22209 if (ctype != NULL)
22210 {
22211 type = groktypename (ctype, NULL, NULL);
22212 if (type == error_mark_node)
22213 ;
22214 else if ((INTEGRAL_TYPE_P (type)
22215 || TREE_CODE (type) == REAL_TYPE
22216 || TREE_CODE (type) == COMPLEX_TYPE)
22217 && orig_reduc_id == NULL_TREE)
22218 error_at (loc, "predeclared arithmetic type in "
22219 "%<#pragma omp declare reduction%>");
22220 else if (TREE_CODE (type) == FUNCTION_TYPE
22221 || TREE_CODE (type) == ARRAY_TYPE)
22222 error_at (loc, "function or array type in "
22223 "%<#pragma omp declare reduction%>");
22224 else if (TYPE_ATOMIC (type))
22225 error_at (loc, "%<_Atomic%> qualified type in "
22226 "%<#pragma omp declare reduction%>");
22227 else if (TYPE_QUALS_NO_ADDR_SPACE (type))
22228 error_at (loc, "const, volatile or restrict qualified type in "
22229 "%<#pragma omp declare reduction%>");
22230 else
22231 {
22232 tree t;
22233 for (t = DECL_INITIAL (reduc_decl); t; t = TREE_CHAIN (t))
22234 if (comptypes (TREE_PURPOSE (t), type))
22235 {
22236 error_at (loc, "redeclaration of %qs "
22237 "%<#pragma omp declare reduction%> for "
22238 "type %qT",
22239 IDENTIFIER_POINTER (reduc_id)
22240 + sizeof ("omp declare reduction ") - 1,
22241 type);
22242 location_t ploc
22243 = DECL_SOURCE_LOCATION (TREE_VEC_ELT (TREE_VALUE (t),
22244 0));
22245 error_at (ploc, "previous %<#pragma omp declare "
22246 "reduction%>");
22247 break;
22248 }
22249 if (t == NULL_TREE)
22250 types.safe_push (type);
22251 }
22252 if (c_parser_next_token_is (parser, CPP_COMMA))
22253 c_parser_consume_token (parser);
22254 else
22255 break;
22256 }
22257 else
22258 break;
22259 }
22260
22261 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>")
22262 || types.is_empty ())
22263 {
22264 fail:
22265 clauses.release ();
22266 types.release ();
22267 while (true)
22268 {
22269 c_token *token = c_parser_peek_token (parser);
22270 if (token->type == CPP_EOF || token->type == CPP_PRAGMA_EOL)
22271 break;
22272 c_parser_consume_token (parser);
22273 }
22274 c_parser_skip_to_pragma_eol (parser);
22275 return;
22276 }
22277
22278 if (types.length () > 1)
22279 {
22280 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
22281 {
22282 c_token *token = c_parser_peek_token (parser);
22283 if (token->type == CPP_EOF)
22284 goto fail;
22285 clauses.safe_push (*token);
22286 c_parser_consume_token (parser);
22287 }
22288 clauses.safe_push (*c_parser_peek_token (parser));
22289 c_parser_skip_to_pragma_eol (parser);
22290
22291 /* Make sure nothing tries to read past the end of the tokens. */
22292 c_token eof_token;
22293 memset (&eof_token, 0, sizeof (eof_token));
22294 eof_token.type = CPP_EOF;
22295 clauses.safe_push (eof_token);
22296 clauses.safe_push (eof_token);
22297 }
22298
22299 int errs = errorcount;
22300 FOR_EACH_VEC_ELT (types, i, type)
22301 {
22302 tokens_avail = parser->tokens_avail;
22303 gcc_assert (parser->tokens == &parser->tokens_buf[0]);
22304 if (!clauses.is_empty ())
22305 {
22306 parser->tokens = clauses.address ();
22307 parser->tokens_avail = clauses.length ();
22308 parser->in_pragma = true;
22309 }
22310
22311 bool nested = current_function_decl != NULL_TREE;
22312 if (nested)
22313 c_push_function_context ();
22314 tree fndecl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
22315 reduc_id, default_function_type);
22316 current_function_decl = fndecl;
22317 allocate_struct_function (fndecl, true);
22318 push_scope ();
22319 tree stmt = push_stmt_list ();
22320 /* Intentionally BUILTINS_LOCATION, so that -Wshadow doesn't
22321 warn about these. */
22322 tree omp_out = build_decl (BUILTINS_LOCATION, VAR_DECL,
22323 get_identifier ("omp_out"), type);
22324 DECL_ARTIFICIAL (omp_out) = 1;
22325 DECL_CONTEXT (omp_out) = fndecl;
22326 pushdecl (omp_out);
22327 tree omp_in = build_decl (BUILTINS_LOCATION, VAR_DECL,
22328 get_identifier ("omp_in"), type);
22329 DECL_ARTIFICIAL (omp_in) = 1;
22330 DECL_CONTEXT (omp_in) = fndecl;
22331 pushdecl (omp_in);
22332 struct c_expr combiner = c_parser_expression (parser);
22333 struct c_expr initializer;
22334 tree omp_priv = NULL_TREE, omp_orig = NULL_TREE;
22335 bool bad = false;
22336 initializer.set_error ();
22337 if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
22338 bad = true;
22339 else if (c_parser_next_token_is (parser, CPP_NAME)
22340 && strcmp (IDENTIFIER_POINTER
22341 (c_parser_peek_token (parser)->value),
22342 "initializer") == 0)
22343 {
22344 c_parser_consume_token (parser);
22345 pop_scope ();
22346 push_scope ();
22347 omp_priv = build_decl (BUILTINS_LOCATION, VAR_DECL,
22348 get_identifier ("omp_priv"), type);
22349 DECL_ARTIFICIAL (omp_priv) = 1;
22350 DECL_INITIAL (omp_priv) = error_mark_node;
22351 DECL_CONTEXT (omp_priv) = fndecl;
22352 pushdecl (omp_priv);
22353 omp_orig = build_decl (BUILTINS_LOCATION, VAR_DECL,
22354 get_identifier ("omp_orig"), type);
22355 DECL_ARTIFICIAL (omp_orig) = 1;
22356 DECL_CONTEXT (omp_orig) = fndecl;
22357 pushdecl (omp_orig);
22358 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
22359 bad = true;
22360 else if (!c_parser_next_token_is (parser, CPP_NAME))
22361 {
22362 c_parser_error (parser, "expected %<omp_priv%> or "
22363 "function-name");
22364 bad = true;
22365 }
22366 else if (strcmp (IDENTIFIER_POINTER
22367 (c_parser_peek_token (parser)->value),
22368 "omp_priv") != 0)
22369 {
22370 if (c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN
22371 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
22372 {
22373 c_parser_error (parser, "expected function-name %<(%>");
22374 bad = true;
22375 }
22376 else
22377 initializer = c_parser_postfix_expression (parser);
22378 if (initializer.value
22379 && TREE_CODE (initializer.value) == CALL_EXPR)
22380 {
22381 int j;
22382 tree c = initializer.value;
22383 for (j = 0; j < call_expr_nargs (c); j++)
22384 {
22385 tree a = CALL_EXPR_ARG (c, j);
22386 STRIP_NOPS (a);
22387 if (TREE_CODE (a) == ADDR_EXPR
22388 && TREE_OPERAND (a, 0) == omp_priv)
22389 break;
22390 }
22391 if (j == call_expr_nargs (c))
22392 error ("one of the initializer call arguments should be "
22393 "%<&omp_priv%>");
22394 }
22395 }
22396 else
22397 {
22398 c_parser_consume_token (parser);
22399 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
22400 bad = true;
22401 else
22402 {
22403 tree st = push_stmt_list ();
22404 location_t loc = c_parser_peek_token (parser)->location;
22405 rich_location richloc (line_table, loc);
22406 start_init (omp_priv, NULL_TREE, 0, &richloc);
22407 struct c_expr init = c_parser_initializer (parser, omp_priv);
22408 finish_init ();
22409 finish_decl (omp_priv, loc, init.value,
22410 init.original_type, NULL_TREE);
22411 pop_stmt_list (st);
22412 }
22413 }
22414 if (!bad
22415 && !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
22416 bad = true;
22417 }
22418
22419 if (!bad)
22420 {
22421 c_parser_skip_to_pragma_eol (parser);
22422
22423 tree t = tree_cons (type, make_tree_vec (omp_priv ? 6 : 3),
22424 DECL_INITIAL (reduc_decl));
22425 DECL_INITIAL (reduc_decl) = t;
22426 DECL_SOURCE_LOCATION (omp_out) = rloc;
22427 TREE_VEC_ELT (TREE_VALUE (t), 0) = omp_out;
22428 TREE_VEC_ELT (TREE_VALUE (t), 1) = omp_in;
22429 TREE_VEC_ELT (TREE_VALUE (t), 2) = combiner.value;
22430 walk_tree (&combiner.value, c_check_omp_declare_reduction_r,
22431 &TREE_VEC_ELT (TREE_VALUE (t), 0), NULL);
22432 if (omp_priv)
22433 {
22434 DECL_SOURCE_LOCATION (omp_priv) = rloc;
22435 TREE_VEC_ELT (TREE_VALUE (t), 3) = omp_priv;
22436 TREE_VEC_ELT (TREE_VALUE (t), 4) = omp_orig;
22437 TREE_VEC_ELT (TREE_VALUE (t), 5) = initializer.value;
22438 walk_tree (&initializer.value, c_check_omp_declare_reduction_r,
22439 &TREE_VEC_ELT (TREE_VALUE (t), 3), NULL);
22440 walk_tree (&DECL_INITIAL (omp_priv),
22441 c_check_omp_declare_reduction_r,
22442 &TREE_VEC_ELT (TREE_VALUE (t), 3), NULL);
22443 }
22444 }
22445
22446 pop_stmt_list (stmt);
22447 pop_scope ();
22448 if (cfun->language != NULL)
22449 {
22450 ggc_free (cfun->language);
22451 cfun->language = NULL;
22452 }
22453 set_cfun (NULL);
22454 current_function_decl = NULL_TREE;
22455 if (nested)
22456 c_pop_function_context ();
22457
22458 if (!clauses.is_empty ())
22459 {
22460 parser->tokens = &parser->tokens_buf[0];
22461 parser->tokens_avail = tokens_avail;
22462 }
22463 if (bad)
22464 goto fail;
22465 if (errs != errorcount)
22466 break;
22467 }
22468
22469 clauses.release ();
22470 types.release ();
22471 }
22472
22473
22474 /* OpenMP 4.0
22475 #pragma omp declare simd declare-simd-clauses[optseq] new-line
22476 #pragma omp declare reduction (reduction-id : typename-list : expression) \
22477 initializer-clause[opt] new-line
22478 #pragma omp declare target new-line
22479
22480 OpenMP 5.0
22481 #pragma omp declare variant (identifier) match (context-selector) */
22482
22483 static bool
c_parser_omp_declare(c_parser * parser,enum pragma_context context)22484 c_parser_omp_declare (c_parser *parser, enum pragma_context context)
22485 {
22486 c_parser_consume_pragma (parser);
22487 if (c_parser_next_token_is (parser, CPP_NAME))
22488 {
22489 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
22490 if (strcmp (p, "simd") == 0)
22491 {
22492 /* c_parser_consume_token (parser); done in
22493 c_parser_omp_declare_simd. */
22494 c_parser_omp_declare_simd (parser, context);
22495 return true;
22496 }
22497 if (strcmp (p, "reduction") == 0)
22498 {
22499 c_parser_consume_token (parser);
22500 c_parser_omp_declare_reduction (parser, context);
22501 return false;
22502 }
22503 if (!flag_openmp) /* flag_openmp_simd */
22504 {
22505 c_parser_skip_to_pragma_eol (parser, false);
22506 return false;
22507 }
22508 if (strcmp (p, "target") == 0)
22509 {
22510 c_parser_consume_token (parser);
22511 c_parser_omp_declare_target (parser);
22512 return false;
22513 }
22514 if (strcmp (p, "variant") == 0)
22515 {
22516 /* c_parser_consume_token (parser); done in
22517 c_parser_omp_declare_simd. */
22518 c_parser_omp_declare_simd (parser, context);
22519 return true;
22520 }
22521 }
22522
22523 c_parser_error (parser, "expected %<simd%>, %<reduction%>, "
22524 "%<target%> or %<variant%>");
22525 c_parser_skip_to_pragma_eol (parser);
22526 return false;
22527 }
22528
22529 /* OpenMP 5.0
22530 #pragma omp requires clauses[optseq] new-line */
22531
22532 static void
c_parser_omp_requires(c_parser * parser)22533 c_parser_omp_requires (c_parser *parser)
22534 {
22535 bool first = true;
22536 enum omp_requires new_req = (enum omp_requires) 0;
22537
22538 c_parser_consume_pragma (parser);
22539
22540 location_t loc = c_parser_peek_token (parser)->location;
22541 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
22542 {
22543 if (!first
22544 && c_parser_next_token_is (parser, CPP_COMMA)
22545 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
22546 c_parser_consume_token (parser);
22547
22548 first = false;
22549
22550 if (c_parser_next_token_is (parser, CPP_NAME))
22551 {
22552 const char *p
22553 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
22554 location_t cloc = c_parser_peek_token (parser)->location;
22555 enum omp_requires this_req = (enum omp_requires) 0;
22556
22557 if (!strcmp (p, "unified_address"))
22558 this_req = OMP_REQUIRES_UNIFIED_ADDRESS;
22559 else if (!strcmp (p, "unified_shared_memory"))
22560 this_req = OMP_REQUIRES_UNIFIED_SHARED_MEMORY;
22561 else if (!strcmp (p, "dynamic_allocators"))
22562 this_req = OMP_REQUIRES_DYNAMIC_ALLOCATORS;
22563 else if (!strcmp (p, "reverse_offload"))
22564 this_req = OMP_REQUIRES_REVERSE_OFFLOAD;
22565 else if (!strcmp (p, "atomic_default_mem_order"))
22566 {
22567 c_parser_consume_token (parser);
22568
22569 matching_parens parens;
22570 if (parens.require_open (parser))
22571 {
22572 if (c_parser_next_token_is (parser, CPP_NAME))
22573 {
22574 tree v = c_parser_peek_token (parser)->value;
22575 p = IDENTIFIER_POINTER (v);
22576
22577 if (!strcmp (p, "seq_cst"))
22578 this_req
22579 = (enum omp_requires) OMP_MEMORY_ORDER_SEQ_CST;
22580 else if (!strcmp (p, "relaxed"))
22581 this_req
22582 = (enum omp_requires) OMP_MEMORY_ORDER_RELAXED;
22583 else if (!strcmp (p, "acq_rel"))
22584 this_req
22585 = (enum omp_requires) OMP_MEMORY_ORDER_ACQ_REL;
22586 }
22587 if (this_req == 0)
22588 {
22589 error_at (c_parser_peek_token (parser)->location,
22590 "expected %<seq_cst%>, %<relaxed%> or "
22591 "%<acq_rel%>");
22592 switch (c_parser_peek_token (parser)->type)
22593 {
22594 case CPP_EOF:
22595 case CPP_PRAGMA_EOL:
22596 case CPP_CLOSE_PAREN:
22597 break;
22598 default:
22599 if (c_parser_peek_2nd_token (parser)->type
22600 == CPP_CLOSE_PAREN)
22601 c_parser_consume_token (parser);
22602 break;
22603 }
22604 }
22605 else
22606 c_parser_consume_token (parser);
22607
22608 parens.skip_until_found_close (parser);
22609 if (this_req == 0)
22610 {
22611 c_parser_skip_to_pragma_eol (parser, false);
22612 return;
22613 }
22614 }
22615 p = NULL;
22616 }
22617 else
22618 {
22619 error_at (cloc, "expected %<unified_address%>, "
22620 "%<unified_shared_memory%>, "
22621 "%<dynamic_allocators%>, "
22622 "%<reverse_offload%> "
22623 "or %<atomic_default_mem_order%> clause");
22624 c_parser_skip_to_pragma_eol (parser, false);
22625 return;
22626 }
22627 if (p && this_req != OMP_REQUIRES_DYNAMIC_ALLOCATORS)
22628 sorry_at (cloc, "%qs clause on %<requires%> directive not "
22629 "supported yet", p);
22630 if (p)
22631 c_parser_consume_token (parser);
22632 if (this_req)
22633 {
22634 if ((this_req & ~OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
22635 {
22636 if ((this_req & new_req) != 0)
22637 error_at (cloc, "too many %qs clauses", p);
22638 if (this_req != OMP_REQUIRES_DYNAMIC_ALLOCATORS
22639 && (omp_requires_mask & OMP_REQUIRES_TARGET_USED) != 0)
22640 error_at (cloc, "%qs clause used lexically after first "
22641 "target construct or offloading API", p);
22642 }
22643 else if ((new_req & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
22644 {
22645 error_at (cloc, "too many %qs clauses",
22646 "atomic_default_mem_order");
22647 this_req = (enum omp_requires) 0;
22648 }
22649 else if ((omp_requires_mask
22650 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
22651 {
22652 error_at (cloc, "more than one %<atomic_default_mem_order%>"
22653 " clause in a single compilation unit");
22654 this_req
22655 = (enum omp_requires)
22656 (omp_requires_mask
22657 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER);
22658 }
22659 else if ((omp_requires_mask
22660 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED) != 0)
22661 error_at (cloc, "%<atomic_default_mem_order%> clause used "
22662 "lexically after first %<atomic%> construct "
22663 "without memory order clause");
22664 new_req = (enum omp_requires) (new_req | this_req);
22665 omp_requires_mask
22666 = (enum omp_requires) (omp_requires_mask | this_req);
22667 continue;
22668 }
22669 }
22670 break;
22671 }
22672 c_parser_skip_to_pragma_eol (parser);
22673
22674 if (new_req == 0)
22675 error_at (loc, "%<pragma omp requires%> requires at least one clause");
22676 }
22677
22678 /* Helper function for c_parser_omp_taskloop.
22679 Disallow zero sized or potentially zero sized task reductions. */
22680
22681 static tree
c_finish_taskloop_clauses(tree clauses)22682 c_finish_taskloop_clauses (tree clauses)
22683 {
22684 tree *pc = &clauses;
22685 for (tree c = clauses; c; c = *pc)
22686 {
22687 bool remove = false;
22688 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
22689 {
22690 tree type = strip_array_types (TREE_TYPE (OMP_CLAUSE_DECL (c)));
22691 if (integer_zerop (TYPE_SIZE_UNIT (type)))
22692 {
22693 error_at (OMP_CLAUSE_LOCATION (c),
22694 "zero sized type %qT in %<reduction%> clause", type);
22695 remove = true;
22696 }
22697 else if (TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST)
22698 {
22699 error_at (OMP_CLAUSE_LOCATION (c),
22700 "variable sized type %qT in %<reduction%> clause",
22701 type);
22702 remove = true;
22703 }
22704 }
22705 if (remove)
22706 *pc = OMP_CLAUSE_CHAIN (c);
22707 else
22708 pc = &OMP_CLAUSE_CHAIN (c);
22709 }
22710 return clauses;
22711 }
22712
22713 /* OpenMP 4.5:
22714 #pragma omp taskloop taskloop-clause[optseq] new-line
22715 for-loop
22716
22717 #pragma omp taskloop simd taskloop-simd-clause[optseq] new-line
22718 for-loop */
22719
22720 #define OMP_TASKLOOP_CLAUSE_MASK \
22721 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
22722 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
22723 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
22724 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
22725 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
22726 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_GRAINSIZE) \
22727 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TASKS) \
22728 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
22729 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
22730 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
22731 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
22732 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
22733 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP) \
22734 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
22735 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
22736 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
22737 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION))
22738
22739 static tree
c_parser_omp_taskloop(location_t loc,c_parser * parser,char * p_name,omp_clause_mask mask,tree * cclauses,bool * if_p)22740 c_parser_omp_taskloop (location_t loc, c_parser *parser,
22741 char *p_name, omp_clause_mask mask, tree *cclauses,
22742 bool *if_p)
22743 {
22744 tree clauses, block, ret;
22745
22746 strcat (p_name, " taskloop");
22747 mask |= OMP_TASKLOOP_CLAUSE_MASK;
22748 /* #pragma omp parallel master taskloop{, simd} disallow in_reduction
22749 clause. */
22750 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0)
22751 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION);
22752
22753 if (c_parser_next_token_is (parser, CPP_NAME))
22754 {
22755 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
22756
22757 if (strcmp (p, "simd") == 0)
22758 {
22759 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
22760 if (cclauses == NULL)
22761 cclauses = cclauses_buf;
22762 c_parser_consume_token (parser);
22763 if (!flag_openmp) /* flag_openmp_simd */
22764 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
22765 if_p);
22766 block = c_begin_compound_stmt (true);
22767 ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses, if_p);
22768 block = c_end_compound_stmt (loc, block, true);
22769 if (ret == NULL)
22770 return ret;
22771 ret = make_node (OMP_TASKLOOP);
22772 TREE_TYPE (ret) = void_type_node;
22773 OMP_FOR_BODY (ret) = block;
22774 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
22775 OMP_FOR_CLAUSES (ret)
22776 = c_finish_taskloop_clauses (OMP_FOR_CLAUSES (ret));
22777 SET_EXPR_LOCATION (ret, loc);
22778 add_stmt (ret);
22779 return ret;
22780 }
22781 }
22782 if (!flag_openmp) /* flag_openmp_simd */
22783 {
22784 c_parser_skip_to_pragma_eol (parser, false);
22785 return NULL_TREE;
22786 }
22787
22788 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
22789 if (cclauses)
22790 {
22791 omp_split_clauses (loc, OMP_TASKLOOP, mask, clauses, cclauses);
22792 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
22793 }
22794
22795 clauses = c_finish_taskloop_clauses (clauses);
22796 block = c_begin_compound_stmt (true);
22797 ret = c_parser_omp_for_loop (loc, parser, OMP_TASKLOOP, clauses, NULL, if_p);
22798 block = c_end_compound_stmt (loc, block, true);
22799 add_stmt (block);
22800
22801 return ret;
22802 }
22803
22804 /* OpenMP 5.1
22805 #pragma omp nothing new-line */
22806
22807 static void
c_parser_omp_nothing(c_parser * parser)22808 c_parser_omp_nothing (c_parser *parser)
22809 {
22810 c_parser_consume_pragma (parser);
22811 c_parser_skip_to_pragma_eol (parser);
22812 }
22813
22814 /* OpenMP 5.1
22815 #pragma omp error clauses[optseq] new-line */
22816
22817 static bool
c_parser_omp_error(c_parser * parser,enum pragma_context context)22818 c_parser_omp_error (c_parser *parser, enum pragma_context context)
22819 {
22820 int at_compilation = -1;
22821 int severity_fatal = -1;
22822 tree message = NULL_TREE;
22823 bool first = true;
22824 bool bad = false;
22825 location_t loc = c_parser_peek_token (parser)->location;
22826
22827 c_parser_consume_pragma (parser);
22828
22829 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
22830 {
22831 if (!first
22832 && c_parser_next_token_is (parser, CPP_COMMA)
22833 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
22834 c_parser_consume_token (parser);
22835
22836 first = false;
22837
22838 if (!c_parser_next_token_is (parser, CPP_NAME))
22839 break;
22840
22841 const char *p
22842 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
22843 location_t cloc = c_parser_peek_token (parser)->location;
22844 static const char *args[] = {
22845 "execution", "compilation", "warning", "fatal"
22846 };
22847 int *v = NULL;
22848 int idx = 0, n = -1;
22849 tree m = NULL_TREE;
22850
22851 if (!strcmp (p, "at"))
22852 v = &at_compilation;
22853 else if (!strcmp (p, "severity"))
22854 {
22855 v = &severity_fatal;
22856 idx += 2;
22857 }
22858 else if (strcmp (p, "message"))
22859 {
22860 error_at (cloc,
22861 "expected %<at%>, %<severity%> or %<message%> clause");
22862 c_parser_skip_to_pragma_eol (parser, false);
22863 return false;
22864 }
22865
22866 c_parser_consume_token (parser);
22867
22868 matching_parens parens;
22869 if (parens.require_open (parser))
22870 {
22871 if (v == NULL)
22872 {
22873 location_t expr_loc = c_parser_peek_token (parser)->location;
22874 c_expr expr = c_parser_expr_no_commas (parser, NULL);
22875 expr = convert_lvalue_to_rvalue (expr_loc, expr, true, true);
22876 m = convert (const_string_type_node, expr.value);
22877 m = c_fully_fold (m, false, NULL);
22878 }
22879 else
22880 {
22881 if (c_parser_next_token_is (parser, CPP_NAME))
22882 {
22883 tree val = c_parser_peek_token (parser)->value;
22884 const char *q = IDENTIFIER_POINTER (val);
22885
22886 if (!strcmp (q, args[idx]))
22887 n = 0;
22888 else if (!strcmp (q, args[idx + 1]))
22889 n = 1;
22890 }
22891 if (n == -1)
22892 {
22893 error_at (c_parser_peek_token (parser)->location,
22894 "expected %qs or %qs", args[idx], args[idx + 1]);
22895 bad = true;
22896 switch (c_parser_peek_token (parser)->type)
22897 {
22898 case CPP_EOF:
22899 case CPP_PRAGMA_EOL:
22900 case CPP_CLOSE_PAREN:
22901 break;
22902 default:
22903 if (c_parser_peek_2nd_token (parser)->type
22904 == CPP_CLOSE_PAREN)
22905 c_parser_consume_token (parser);
22906 break;
22907 }
22908 }
22909 else
22910 c_parser_consume_token (parser);
22911 }
22912
22913 parens.skip_until_found_close (parser);
22914
22915 if (v == NULL)
22916 {
22917 if (message)
22918 {
22919 error_at (cloc, "too many %qs clauses", p);
22920 bad = true;
22921 }
22922 else
22923 message = m;
22924 }
22925 else if (n != -1)
22926 {
22927 if (*v != -1)
22928 {
22929 error_at (cloc, "too many %qs clauses", p);
22930 bad = true;
22931 }
22932 else
22933 *v = n;
22934 }
22935 }
22936 else
22937 bad = true;
22938 }
22939 c_parser_skip_to_pragma_eol (parser);
22940 if (bad)
22941 return true;
22942
22943 if (at_compilation == -1)
22944 at_compilation = 1;
22945 if (severity_fatal == -1)
22946 severity_fatal = 1;
22947 if (!at_compilation)
22948 {
22949 if (context != pragma_compound)
22950 {
22951 error_at (loc, "%<#pragma omp error%> with %<at(execution)%> clause "
22952 "may only be used in compound statements");
22953 return true;
22954 }
22955 tree fndecl
22956 = builtin_decl_explicit (severity_fatal ? BUILT_IN_GOMP_ERROR
22957 : BUILT_IN_GOMP_WARNING);
22958 if (!message)
22959 message = build_zero_cst (const_string_type_node);
22960 tree stmt = build_call_expr_loc (loc, fndecl, 2, message,
22961 build_all_ones_cst (size_type_node));
22962 add_stmt (stmt);
22963 return true;
22964 }
22965 const char *msg = NULL;
22966 if (message)
22967 {
22968 msg = c_getstr (message);
22969 if (msg == NULL)
22970 msg = _("<message unknown at compile time>");
22971 }
22972 if (msg)
22973 emit_diagnostic (severity_fatal ? DK_ERROR : DK_WARNING, loc, 0,
22974 "%<pragma omp error%> encountered: %s", msg);
22975 else
22976 emit_diagnostic (severity_fatal ? DK_ERROR : DK_WARNING, loc, 0,
22977 "%<pragma omp error%> encountered");
22978 return false;
22979 }
22980
22981 /* Main entry point to parsing most OpenMP pragmas. */
22982
22983 static void
c_parser_omp_construct(c_parser * parser,bool * if_p)22984 c_parser_omp_construct (c_parser *parser, bool *if_p)
22985 {
22986 enum pragma_kind p_kind;
22987 location_t loc;
22988 tree stmt;
22989 char p_name[sizeof "#pragma omp teams distribute parallel for simd"];
22990 omp_clause_mask mask (0);
22991
22992 loc = c_parser_peek_token (parser)->location;
22993 p_kind = c_parser_peek_token (parser)->pragma_kind;
22994 c_parser_consume_pragma (parser);
22995
22996 switch (p_kind)
22997 {
22998 case PRAGMA_OACC_ATOMIC:
22999 c_parser_omp_atomic (loc, parser, true);
23000 return;
23001 case PRAGMA_OACC_CACHE:
23002 strcpy (p_name, "#pragma acc");
23003 stmt = c_parser_oacc_cache (loc, parser);
23004 break;
23005 case PRAGMA_OACC_DATA:
23006 stmt = c_parser_oacc_data (loc, parser, if_p);
23007 break;
23008 case PRAGMA_OACC_HOST_DATA:
23009 stmt = c_parser_oacc_host_data (loc, parser, if_p);
23010 break;
23011 case PRAGMA_OACC_KERNELS:
23012 case PRAGMA_OACC_PARALLEL:
23013 case PRAGMA_OACC_SERIAL:
23014 strcpy (p_name, "#pragma acc");
23015 stmt = c_parser_oacc_compute (loc, parser, p_kind, p_name, if_p);
23016 break;
23017 case PRAGMA_OACC_LOOP:
23018 strcpy (p_name, "#pragma acc");
23019 stmt = c_parser_oacc_loop (loc, parser, p_name, mask, NULL, if_p);
23020 break;
23021 case PRAGMA_OACC_WAIT:
23022 strcpy (p_name, "#pragma wait");
23023 stmt = c_parser_oacc_wait (loc, parser, p_name);
23024 break;
23025 case PRAGMA_OMP_ALLOCATE:
23026 c_parser_omp_allocate (loc, parser);
23027 return;
23028 case PRAGMA_OMP_ATOMIC:
23029 c_parser_omp_atomic (loc, parser, false);
23030 return;
23031 case PRAGMA_OMP_CRITICAL:
23032 stmt = c_parser_omp_critical (loc, parser, if_p);
23033 break;
23034 case PRAGMA_OMP_DISTRIBUTE:
23035 strcpy (p_name, "#pragma omp");
23036 stmt = c_parser_omp_distribute (loc, parser, p_name, mask, NULL, if_p);
23037 break;
23038 case PRAGMA_OMP_FOR:
23039 strcpy (p_name, "#pragma omp");
23040 stmt = c_parser_omp_for (loc, parser, p_name, mask, NULL, if_p);
23041 break;
23042 case PRAGMA_OMP_LOOP:
23043 strcpy (p_name, "#pragma omp");
23044 stmt = c_parser_omp_loop (loc, parser, p_name, mask, NULL, if_p);
23045 break;
23046 case PRAGMA_OMP_MASKED:
23047 strcpy (p_name, "#pragma omp");
23048 stmt = c_parser_omp_masked (loc, parser, p_name, mask, NULL, if_p);
23049 break;
23050 case PRAGMA_OMP_MASTER:
23051 strcpy (p_name, "#pragma omp");
23052 stmt = c_parser_omp_master (loc, parser, p_name, mask, NULL, if_p);
23053 break;
23054 case PRAGMA_OMP_PARALLEL:
23055 strcpy (p_name, "#pragma omp");
23056 stmt = c_parser_omp_parallel (loc, parser, p_name, mask, NULL, if_p);
23057 break;
23058 case PRAGMA_OMP_SCOPE:
23059 stmt = c_parser_omp_scope (loc, parser, if_p);
23060 break;
23061 case PRAGMA_OMP_SECTIONS:
23062 strcpy (p_name, "#pragma omp");
23063 stmt = c_parser_omp_sections (loc, parser, p_name, mask, NULL);
23064 break;
23065 case PRAGMA_OMP_SIMD:
23066 strcpy (p_name, "#pragma omp");
23067 stmt = c_parser_omp_simd (loc, parser, p_name, mask, NULL, if_p);
23068 break;
23069 case PRAGMA_OMP_SINGLE:
23070 stmt = c_parser_omp_single (loc, parser, if_p);
23071 break;
23072 case PRAGMA_OMP_TASK:
23073 stmt = c_parser_omp_task (loc, parser, if_p);
23074 break;
23075 case PRAGMA_OMP_TASKGROUP:
23076 stmt = c_parser_omp_taskgroup (loc, parser, if_p);
23077 break;
23078 case PRAGMA_OMP_TASKLOOP:
23079 strcpy (p_name, "#pragma omp");
23080 stmt = c_parser_omp_taskloop (loc, parser, p_name, mask, NULL, if_p);
23081 break;
23082 case PRAGMA_OMP_TEAMS:
23083 strcpy (p_name, "#pragma omp");
23084 stmt = c_parser_omp_teams (loc, parser, p_name, mask, NULL, if_p);
23085 break;
23086 default:
23087 gcc_unreachable ();
23088 }
23089
23090 if (stmt && stmt != error_mark_node)
23091 gcc_assert (EXPR_LOCATION (stmt) != UNKNOWN_LOCATION);
23092 }
23093
23094
23095 /* OpenMP 2.5:
23096 # pragma omp threadprivate (variable-list) */
23097
23098 static void
c_parser_omp_threadprivate(c_parser * parser)23099 c_parser_omp_threadprivate (c_parser *parser)
23100 {
23101 tree vars, t;
23102 location_t loc;
23103
23104 c_parser_consume_pragma (parser);
23105 loc = c_parser_peek_token (parser)->location;
23106 vars = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
23107
23108 /* Mark every variable in VARS to be assigned thread local storage. */
23109 for (t = vars; t; t = TREE_CHAIN (t))
23110 {
23111 tree v = TREE_PURPOSE (t);
23112
23113 /* FIXME diagnostics: Ideally we should keep individual
23114 locations for all the variables in the var list to make the
23115 following errors more precise. Perhaps
23116 c_parser_omp_var_list_parens() should construct a list of
23117 locations to go along with the var list. */
23118
23119 /* If V had already been marked threadprivate, it doesn't matter
23120 whether it had been used prior to this point. */
23121 if (!VAR_P (v))
23122 error_at (loc, "%qD is not a variable", v);
23123 else if (TREE_USED (v) && !C_DECL_THREADPRIVATE_P (v))
23124 error_at (loc, "%qE declared %<threadprivate%> after first use", v);
23125 else if (! is_global_var (v))
23126 error_at (loc, "automatic variable %qE cannot be %<threadprivate%>", v);
23127 else if (TREE_TYPE (v) == error_mark_node)
23128 ;
23129 else if (! COMPLETE_TYPE_P (TREE_TYPE (v)))
23130 error_at (loc, "%<threadprivate%> %qE has incomplete type", v);
23131 else
23132 {
23133 if (! DECL_THREAD_LOCAL_P (v))
23134 {
23135 set_decl_tls_model (v, decl_default_tls_model (v));
23136 /* If rtl has been already set for this var, call
23137 make_decl_rtl once again, so that encode_section_info
23138 has a chance to look at the new decl flags. */
23139 if (DECL_RTL_SET_P (v))
23140 make_decl_rtl (v);
23141 }
23142 C_DECL_THREADPRIVATE_P (v) = 1;
23143 }
23144 }
23145
23146 c_parser_skip_to_pragma_eol (parser);
23147 }
23148
23149 /* Parse a transaction attribute (GCC Extension).
23150
23151 transaction-attribute:
23152 gnu-attributes
23153 attribute-specifier
23154 */
23155
23156 static tree
c_parser_transaction_attributes(c_parser * parser)23157 c_parser_transaction_attributes (c_parser *parser)
23158 {
23159 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
23160 return c_parser_gnu_attributes (parser);
23161
23162 if (!c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
23163 return NULL_TREE;
23164 return c_parser_std_attribute_specifier (parser, true);
23165 }
23166
23167 /* Parse a __transaction_atomic or __transaction_relaxed statement
23168 (GCC Extension).
23169
23170 transaction-statement:
23171 __transaction_atomic transaction-attribute[opt] compound-statement
23172 __transaction_relaxed compound-statement
23173
23174 Note that the only valid attribute is: "outer".
23175 */
23176
23177 static tree
c_parser_transaction(c_parser * parser,enum rid keyword)23178 c_parser_transaction (c_parser *parser, enum rid keyword)
23179 {
23180 unsigned int old_in = parser->in_transaction;
23181 unsigned int this_in = 1, new_in;
23182 location_t loc = c_parser_peek_token (parser)->location;
23183 tree stmt, attrs;
23184
23185 gcc_assert ((keyword == RID_TRANSACTION_ATOMIC
23186 || keyword == RID_TRANSACTION_RELAXED)
23187 && c_parser_next_token_is_keyword (parser, keyword));
23188 c_parser_consume_token (parser);
23189
23190 if (keyword == RID_TRANSACTION_RELAXED)
23191 this_in |= TM_STMT_ATTR_RELAXED;
23192 else
23193 {
23194 attrs = c_parser_transaction_attributes (parser);
23195 if (attrs)
23196 this_in |= parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER);
23197 }
23198
23199 /* Keep track if we're in the lexical scope of an outer transaction. */
23200 new_in = this_in | (old_in & TM_STMT_ATTR_OUTER);
23201
23202 parser->in_transaction = new_in;
23203 stmt = c_parser_compound_statement (parser);
23204 parser->in_transaction = old_in;
23205
23206 if (flag_tm)
23207 stmt = c_finish_transaction (loc, stmt, this_in);
23208 else
23209 error_at (loc, (keyword == RID_TRANSACTION_ATOMIC ?
23210 "%<__transaction_atomic%> without transactional memory support enabled"
23211 : "%<__transaction_relaxed %> "
23212 "without transactional memory support enabled"));
23213
23214 return stmt;
23215 }
23216
23217 /* Parse a __transaction_atomic or __transaction_relaxed expression
23218 (GCC Extension).
23219
23220 transaction-expression:
23221 __transaction_atomic ( expression )
23222 __transaction_relaxed ( expression )
23223 */
23224
23225 static struct c_expr
c_parser_transaction_expression(c_parser * parser,enum rid keyword)23226 c_parser_transaction_expression (c_parser *parser, enum rid keyword)
23227 {
23228 struct c_expr ret;
23229 unsigned int old_in = parser->in_transaction;
23230 unsigned int this_in = 1;
23231 location_t loc = c_parser_peek_token (parser)->location;
23232 tree attrs;
23233
23234 gcc_assert ((keyword == RID_TRANSACTION_ATOMIC
23235 || keyword == RID_TRANSACTION_RELAXED)
23236 && c_parser_next_token_is_keyword (parser, keyword));
23237 c_parser_consume_token (parser);
23238
23239 if (keyword == RID_TRANSACTION_RELAXED)
23240 this_in |= TM_STMT_ATTR_RELAXED;
23241 else
23242 {
23243 attrs = c_parser_transaction_attributes (parser);
23244 if (attrs)
23245 this_in |= parse_tm_stmt_attr (attrs, 0);
23246 }
23247
23248 parser->in_transaction = this_in;
23249 matching_parens parens;
23250 if (parens.require_open (parser))
23251 {
23252 tree expr = c_parser_expression (parser).value;
23253 ret.original_type = TREE_TYPE (expr);
23254 ret.value = build1 (TRANSACTION_EXPR, ret.original_type, expr);
23255 if (this_in & TM_STMT_ATTR_RELAXED)
23256 TRANSACTION_EXPR_RELAXED (ret.value) = 1;
23257 SET_EXPR_LOCATION (ret.value, loc);
23258 ret.original_code = TRANSACTION_EXPR;
23259 if (!parens.require_close (parser))
23260 {
23261 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
23262 goto error;
23263 }
23264 }
23265 else
23266 {
23267 error:
23268 ret.set_error ();
23269 ret.original_code = ERROR_MARK;
23270 ret.original_type = NULL;
23271 }
23272 parser->in_transaction = old_in;
23273
23274 if (!flag_tm)
23275 error_at (loc, (keyword == RID_TRANSACTION_ATOMIC ?
23276 "%<__transaction_atomic%> without transactional memory support enabled"
23277 : "%<__transaction_relaxed %> "
23278 "without transactional memory support enabled"));
23279
23280 set_c_expr_source_range (&ret, loc, loc);
23281
23282 return ret;
23283 }
23284
23285 /* Parse a __transaction_cancel statement (GCC Extension).
23286
23287 transaction-cancel-statement:
23288 __transaction_cancel transaction-attribute[opt] ;
23289
23290 Note that the only valid attribute is "outer".
23291 */
23292
23293 static tree
c_parser_transaction_cancel(c_parser * parser)23294 c_parser_transaction_cancel (c_parser *parser)
23295 {
23296 location_t loc = c_parser_peek_token (parser)->location;
23297 tree attrs;
23298 bool is_outer = false;
23299
23300 gcc_assert (c_parser_next_token_is_keyword (parser, RID_TRANSACTION_CANCEL));
23301 c_parser_consume_token (parser);
23302
23303 attrs = c_parser_transaction_attributes (parser);
23304 if (attrs)
23305 is_outer = (parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER) != 0);
23306
23307 if (!flag_tm)
23308 {
23309 error_at (loc, "%<__transaction_cancel%> without "
23310 "transactional memory support enabled");
23311 goto ret_error;
23312 }
23313 else if (parser->in_transaction & TM_STMT_ATTR_RELAXED)
23314 {
23315 error_at (loc, "%<__transaction_cancel%> within a "
23316 "%<__transaction_relaxed%>");
23317 goto ret_error;
23318 }
23319 else if (is_outer)
23320 {
23321 if ((parser->in_transaction & TM_STMT_ATTR_OUTER) == 0
23322 && !is_tm_may_cancel_outer (current_function_decl))
23323 {
23324 error_at (loc, "outer %<__transaction_cancel%> not "
23325 "within outer %<__transaction_atomic%> or "
23326 "a %<transaction_may_cancel_outer%> function");
23327 goto ret_error;
23328 }
23329 }
23330 else if (parser->in_transaction == 0)
23331 {
23332 error_at (loc, "%<__transaction_cancel%> not within "
23333 "%<__transaction_atomic%>");
23334 goto ret_error;
23335 }
23336
23337 return add_stmt (build_tm_abort_call (loc, is_outer));
23338
23339 ret_error:
23340 return build1 (NOP_EXPR, void_type_node, error_mark_node);
23341 }
23342
23343 /* Parse a single source file. */
23344
23345 void
c_parse_file(void)23346 c_parse_file (void)
23347 {
23348 /* Use local storage to begin. If the first token is a pragma, parse it.
23349 If it is #pragma GCC pch_preprocess, then this will load a PCH file
23350 which will cause garbage collection. */
23351 c_parser tparser;
23352
23353 memset (&tparser, 0, sizeof tparser);
23354 tparser.translate_strings_p = true;
23355 tparser.tokens = &tparser.tokens_buf[0];
23356 the_parser = &tparser;
23357
23358 if (c_parser_peek_token (&tparser)->pragma_kind == PRAGMA_GCC_PCH_PREPROCESS)
23359 c_parser_pragma_pch_preprocess (&tparser);
23360 else
23361 c_common_no_more_pch ();
23362
23363 the_parser = ggc_alloc<c_parser> ();
23364 *the_parser = tparser;
23365 if (tparser.tokens == &tparser.tokens_buf[0])
23366 the_parser->tokens = &the_parser->tokens_buf[0];
23367
23368 /* Initialize EH, if we've been told to do so. */
23369 if (flag_exceptions)
23370 using_eh_for_cleanups ();
23371
23372 c_parser_translation_unit (the_parser);
23373 the_parser = NULL;
23374 }
23375
23376 /* Parse the body of a function declaration marked with "__RTL".
23377
23378 The RTL parser works on the level of characters read from a
23379 FILE *, whereas c_parser works at the level of tokens.
23380 Square this circle by consuming all of the tokens up to and
23381 including the closing brace, recording the start/end of the RTL
23382 fragment, and reopening the file and re-reading the relevant
23383 lines within the RTL parser.
23384
23385 This requires the opening and closing braces of the C function
23386 to be on separate lines from the RTL they wrap.
23387
23388 Take ownership of START_WITH_PASS, if non-NULL. */
23389
23390 location_t
c_parser_parse_rtl_body(c_parser * parser,char * start_with_pass)23391 c_parser_parse_rtl_body (c_parser *parser, char *start_with_pass)
23392 {
23393 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
23394 {
23395 free (start_with_pass);
23396 return c_parser_peek_token (parser)->location;
23397 }
23398
23399 location_t start_loc = c_parser_peek_token (parser)->location;
23400
23401 /* Consume all tokens, up to the closing brace, handling
23402 matching pairs of braces in the rtl dump. */
23403 int num_open_braces = 1;
23404 while (1)
23405 {
23406 switch (c_parser_peek_token (parser)->type)
23407 {
23408 case CPP_OPEN_BRACE:
23409 num_open_braces++;
23410 break;
23411 case CPP_CLOSE_BRACE:
23412 if (--num_open_braces == 0)
23413 goto found_closing_brace;
23414 break;
23415 case CPP_EOF:
23416 error_at (start_loc, "no closing brace");
23417 free (start_with_pass);
23418 return c_parser_peek_token (parser)->location;
23419 default:
23420 break;
23421 }
23422 c_parser_consume_token (parser);
23423 }
23424
23425 found_closing_brace:
23426 /* At the closing brace; record its location. */
23427 location_t end_loc = c_parser_peek_token (parser)->location;
23428
23429 /* Consume the closing brace. */
23430 c_parser_consume_token (parser);
23431
23432 /* Invoke the RTL parser. */
23433 if (!read_rtl_function_body_from_file_range (start_loc, end_loc))
23434 {
23435 free (start_with_pass);
23436 return end_loc;
23437 }
23438
23439 /* Run the backend on the cfun created above, transferring ownership of
23440 START_WITH_PASS. */
23441 run_rtl_passes (start_with_pass);
23442 return end_loc;
23443 }
23444
23445 #include "gt-c-c-parser.h"
23446