1 /* Parser for C and Objective-C.
2 Copyright (C) 1987-2018 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_UNIQUE_PTR
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
72 /* We need to walk over decls with incomplete struct/union/enum types
73 after parsing the whole translation unit.
74 In finish_decl(), if the decl is static, has incomplete
75 struct/union/enum type, it is appeneded to incomplete_record_decls.
76 In c_parser_translation_unit(), we iterate over incomplete_record_decls
77 and report error if any of the decls are still incomplete. */
78
79 vec<tree> incomplete_record_decls;
80
81 void
set_c_expr_source_range(c_expr * expr,location_t start,location_t finish)82 set_c_expr_source_range (c_expr *expr,
83 location_t start, location_t finish)
84 {
85 expr->src_range.m_start = start;
86 expr->src_range.m_finish = finish;
87 if (expr->value)
88 set_source_range (expr->value, start, finish);
89 }
90
91 void
set_c_expr_source_range(c_expr * expr,source_range src_range)92 set_c_expr_source_range (c_expr *expr,
93 source_range src_range)
94 {
95 expr->src_range = src_range;
96 if (expr->value)
97 set_source_range (expr->value, src_range);
98 }
99
100
101 /* Initialization routine for this file. */
102
103 void
c_parse_init(void)104 c_parse_init (void)
105 {
106 /* The only initialization required is of the reserved word
107 identifiers. */
108 unsigned int i;
109 tree id;
110 int mask = 0;
111
112 /* Make sure RID_MAX hasn't grown past the 8 bits used to hold the keyword in
113 the c_token structure. */
114 gcc_assert (RID_MAX <= 255);
115
116 mask |= D_CXXONLY;
117 if (!flag_isoc99)
118 mask |= D_C99;
119 if (flag_no_asm)
120 {
121 mask |= D_ASM | D_EXT;
122 if (!flag_isoc99)
123 mask |= D_EXT89;
124 }
125 if (!c_dialect_objc ())
126 mask |= D_OBJC | D_CXX_OBJC;
127
128 ridpointers = ggc_cleared_vec_alloc<tree> ((int) RID_MAX);
129 for (i = 0; i < num_c_common_reswords; i++)
130 {
131 /* If a keyword is disabled, do not enter it into the table
132 and so create a canonical spelling that isn't a keyword. */
133 if (c_common_reswords[i].disable & mask)
134 {
135 if (warn_cxx_compat
136 && (c_common_reswords[i].disable & D_CXXWARN))
137 {
138 id = get_identifier (c_common_reswords[i].word);
139 C_SET_RID_CODE (id, RID_CXX_COMPAT_WARN);
140 C_IS_RESERVED_WORD (id) = 1;
141 }
142 continue;
143 }
144
145 id = get_identifier (c_common_reswords[i].word);
146 C_SET_RID_CODE (id, c_common_reswords[i].rid);
147 C_IS_RESERVED_WORD (id) = 1;
148 ridpointers [(int) c_common_reswords[i].rid] = id;
149 }
150
151 for (i = 0; i < NUM_INT_N_ENTS; i++)
152 {
153 /* We always create the symbols but they aren't always supported. */
154 char name[50];
155 sprintf (name, "__int%d", int_n_data[i].bitsize);
156 id = get_identifier (name);
157 C_SET_RID_CODE (id, RID_FIRST_INT_N + i);
158 C_IS_RESERVED_WORD (id) = 1;
159 }
160 }
161
162 /* A parser structure recording information about the state and
163 context of parsing. Includes lexer information with up to two
164 tokens of look-ahead; more are not needed for C. */
165 struct GTY(()) c_parser {
166 /* The look-ahead tokens. */
167 c_token * GTY((skip)) tokens;
168 /* Buffer for look-ahead tokens. */
169 c_token tokens_buf[4];
170 /* How many look-ahead tokens are available (0 - 4, or
171 more if parsing from pre-lexed tokens). */
172 unsigned int tokens_avail;
173 /* True if a syntax error is being recovered from; false otherwise.
174 c_parser_error sets this flag. It should clear this flag when
175 enough tokens have been consumed to recover from the error. */
176 BOOL_BITFIELD error : 1;
177 /* True if we're processing a pragma, and shouldn't automatically
178 consume CPP_PRAGMA_EOL. */
179 BOOL_BITFIELD in_pragma : 1;
180 /* True if we're parsing the outermost block of an if statement. */
181 BOOL_BITFIELD in_if_block : 1;
182 /* True if we want to lex an untranslated string. */
183 BOOL_BITFIELD lex_untranslated_string : 1;
184
185 /* Objective-C specific parser/lexer information. */
186
187 /* True if we are in a context where the Objective-C "PQ" keywords
188 are considered keywords. */
189 BOOL_BITFIELD objc_pq_context : 1;
190 /* True if we are parsing a (potential) Objective-C foreach
191 statement. This is set to true after we parsed 'for (' and while
192 we wait for 'in' or ';' to decide if it's a standard C for loop or an
193 Objective-C foreach loop. */
194 BOOL_BITFIELD objc_could_be_foreach_context : 1;
195 /* The following flag is needed to contextualize Objective-C lexical
196 analysis. In some cases (e.g., 'int NSObject;'), it is
197 undesirable to bind an identifier to an Objective-C class, even
198 if a class with that name exists. */
199 BOOL_BITFIELD objc_need_raw_identifier : 1;
200 /* Nonzero if we're processing a __transaction statement. The value
201 is 1 | TM_STMT_ATTR_*. */
202 unsigned int in_transaction : 4;
203 /* True if we are in a context where the Objective-C "Property attribute"
204 keywords are valid. */
205 BOOL_BITFIELD objc_property_attr_context : 1;
206
207 /* Location of the last consumed token. */
208 location_t last_token_location;
209 };
210
211 /* Return a pointer to the Nth token in PARSERs tokens_buf. */
212
213 c_token *
c_parser_tokens_buf(c_parser * parser,unsigned n)214 c_parser_tokens_buf (c_parser *parser, unsigned n)
215 {
216 return &parser->tokens_buf[n];
217 }
218
219 /* Return the error state of PARSER. */
220
221 bool
c_parser_error(c_parser * parser)222 c_parser_error (c_parser *parser)
223 {
224 return parser->error;
225 }
226
227 /* Set the error state of PARSER to ERR. */
228
229 void
c_parser_set_error(c_parser * parser,bool err)230 c_parser_set_error (c_parser *parser, bool err)
231 {
232 parser->error = err;
233 }
234
235
236 /* The actual parser and external interface. ??? Does this need to be
237 garbage-collected? */
238
239 static GTY (()) c_parser *the_parser;
240
241 /* Read in and lex a single token, storing it in *TOKEN. */
242
243 static void
c_lex_one_token(c_parser * parser,c_token * token)244 c_lex_one_token (c_parser *parser, c_token *token)
245 {
246 timevar_push (TV_LEX);
247
248 token->type = c_lex_with_flags (&token->value, &token->location,
249 &token->flags,
250 (parser->lex_untranslated_string
251 ? C_LEX_STRING_NO_TRANSLATE : 0));
252 token->id_kind = C_ID_NONE;
253 token->keyword = RID_MAX;
254 token->pragma_kind = PRAGMA_NONE;
255
256 switch (token->type)
257 {
258 case CPP_NAME:
259 {
260 tree decl;
261
262 bool objc_force_identifier = parser->objc_need_raw_identifier;
263 if (c_dialect_objc ())
264 parser->objc_need_raw_identifier = false;
265
266 if (C_IS_RESERVED_WORD (token->value))
267 {
268 enum rid rid_code = C_RID_CODE (token->value);
269
270 if (rid_code == RID_CXX_COMPAT_WARN)
271 {
272 warning_at (token->location,
273 OPT_Wc___compat,
274 "identifier %qE conflicts with C++ keyword",
275 token->value);
276 }
277 else if (rid_code >= RID_FIRST_ADDR_SPACE
278 && rid_code <= RID_LAST_ADDR_SPACE)
279 {
280 addr_space_t as;
281 as = (addr_space_t) (rid_code - RID_FIRST_ADDR_SPACE);
282 targetm.addr_space.diagnose_usage (as, token->location);
283 token->id_kind = C_ID_ADDRSPACE;
284 token->keyword = rid_code;
285 break;
286 }
287 else if (c_dialect_objc () && OBJC_IS_PQ_KEYWORD (rid_code))
288 {
289 /* We found an Objective-C "pq" keyword (in, out,
290 inout, bycopy, byref, oneway). They need special
291 care because the interpretation depends on the
292 context. */
293 if (parser->objc_pq_context)
294 {
295 token->type = CPP_KEYWORD;
296 token->keyword = rid_code;
297 break;
298 }
299 else if (parser->objc_could_be_foreach_context
300 && rid_code == RID_IN)
301 {
302 /* We are in Objective-C, inside a (potential)
303 foreach context (which means after having
304 parsed 'for (', but before having parsed ';'),
305 and we found 'in'. We consider it the keyword
306 which terminates the declaration at the
307 beginning of a foreach-statement. Note that
308 this means you can't use 'in' for anything else
309 in that context; in particular, in Objective-C
310 you can't use 'in' as the name of the running
311 variable in a C for loop. We could potentially
312 try to add code here to disambiguate, but it
313 seems a reasonable limitation. */
314 token->type = CPP_KEYWORD;
315 token->keyword = rid_code;
316 break;
317 }
318 /* Else, "pq" keywords outside of the "pq" context are
319 not keywords, and we fall through to the code for
320 normal tokens. */
321 }
322 else if (c_dialect_objc () && OBJC_IS_PATTR_KEYWORD (rid_code))
323 {
324 /* We found an Objective-C "property attribute"
325 keyword (getter, setter, readonly, etc). These are
326 only valid in the property context. */
327 if (parser->objc_property_attr_context)
328 {
329 token->type = CPP_KEYWORD;
330 token->keyword = rid_code;
331 break;
332 }
333 /* Else they are not special keywords.
334 */
335 }
336 else if (c_dialect_objc ()
337 && (OBJC_IS_AT_KEYWORD (rid_code)
338 || OBJC_IS_CXX_KEYWORD (rid_code)))
339 {
340 /* We found one of the Objective-C "@" keywords (defs,
341 selector, synchronized, etc) or one of the
342 Objective-C "cxx" keywords (class, private,
343 protected, public, try, catch, throw) without a
344 preceding '@' sign. Do nothing and fall through to
345 the code for normal tokens (in C++ we would still
346 consider the CXX ones keywords, but not in C). */
347 ;
348 }
349 else
350 {
351 token->type = CPP_KEYWORD;
352 token->keyword = rid_code;
353 break;
354 }
355 }
356
357 decl = lookup_name (token->value);
358 if (decl)
359 {
360 if (TREE_CODE (decl) == TYPE_DECL)
361 {
362 token->id_kind = C_ID_TYPENAME;
363 break;
364 }
365 }
366 else if (c_dialect_objc ())
367 {
368 tree objc_interface_decl = objc_is_class_name (token->value);
369 /* Objective-C class names are in the same namespace as
370 variables and typedefs, and hence are shadowed by local
371 declarations. */
372 if (objc_interface_decl
373 && (!objc_force_identifier || global_bindings_p ()))
374 {
375 token->value = objc_interface_decl;
376 token->id_kind = C_ID_CLASSNAME;
377 break;
378 }
379 }
380 token->id_kind = C_ID_ID;
381 }
382 break;
383 case CPP_AT_NAME:
384 /* This only happens in Objective-C; it must be a keyword. */
385 token->type = CPP_KEYWORD;
386 switch (C_RID_CODE (token->value))
387 {
388 /* Replace 'class' with '@class', 'private' with '@private',
389 etc. This prevents confusion with the C++ keyword
390 'class', and makes the tokens consistent with other
391 Objective-C 'AT' keywords. For example '@class' is
392 reported as RID_AT_CLASS which is consistent with
393 '@synchronized', which is reported as
394 RID_AT_SYNCHRONIZED.
395 */
396 case RID_CLASS: token->keyword = RID_AT_CLASS; break;
397 case RID_PRIVATE: token->keyword = RID_AT_PRIVATE; break;
398 case RID_PROTECTED: token->keyword = RID_AT_PROTECTED; break;
399 case RID_PUBLIC: token->keyword = RID_AT_PUBLIC; break;
400 case RID_THROW: token->keyword = RID_AT_THROW; break;
401 case RID_TRY: token->keyword = RID_AT_TRY; break;
402 case RID_CATCH: token->keyword = RID_AT_CATCH; break;
403 case RID_SYNCHRONIZED: token->keyword = RID_AT_SYNCHRONIZED; break;
404 default: token->keyword = C_RID_CODE (token->value);
405 }
406 break;
407 case CPP_COLON:
408 case CPP_COMMA:
409 case CPP_CLOSE_PAREN:
410 case CPP_SEMICOLON:
411 /* These tokens may affect the interpretation of any identifiers
412 following, if doing Objective-C. */
413 if (c_dialect_objc ())
414 parser->objc_need_raw_identifier = false;
415 break;
416 case CPP_PRAGMA:
417 /* We smuggled the cpp_token->u.pragma value in an INTEGER_CST. */
418 token->pragma_kind = (enum pragma_kind) TREE_INT_CST_LOW (token->value);
419 token->value = NULL;
420 break;
421 default:
422 break;
423 }
424 timevar_pop (TV_LEX);
425 }
426
427 /* Return a pointer to the next token from PARSER, reading it in if
428 necessary. */
429
430 c_token *
c_parser_peek_token(c_parser * parser)431 c_parser_peek_token (c_parser *parser)
432 {
433 if (parser->tokens_avail == 0)
434 {
435 c_lex_one_token (parser, &parser->tokens[0]);
436 parser->tokens_avail = 1;
437 }
438 return &parser->tokens[0];
439 }
440
441 /* Return a pointer to the next-but-one token from PARSER, reading it
442 in if necessary. The next token is already read in. */
443
444 c_token *
c_parser_peek_2nd_token(c_parser * parser)445 c_parser_peek_2nd_token (c_parser *parser)
446 {
447 if (parser->tokens_avail >= 2)
448 return &parser->tokens[1];
449 gcc_assert (parser->tokens_avail == 1);
450 gcc_assert (parser->tokens[0].type != CPP_EOF);
451 gcc_assert (parser->tokens[0].type != CPP_PRAGMA_EOL);
452 c_lex_one_token (parser, &parser->tokens[1]);
453 parser->tokens_avail = 2;
454 return &parser->tokens[1];
455 }
456
457 /* Return a pointer to the Nth token from PARSER, reading it
458 in if necessary. The N-1th token is already read in. */
459
460 c_token *
c_parser_peek_nth_token(c_parser * parser,unsigned int n)461 c_parser_peek_nth_token (c_parser *parser, unsigned int n)
462 {
463 /* N is 1-based, not zero-based. */
464 gcc_assert (n > 0);
465
466 if (parser->tokens_avail >= n)
467 return &parser->tokens[n - 1];
468 gcc_assert (parser->tokens_avail == n - 1);
469 c_lex_one_token (parser, &parser->tokens[n - 1]);
470 parser->tokens_avail = n;
471 return &parser->tokens[n - 1];
472 }
473
474 bool
c_keyword_starts_typename(enum rid keyword)475 c_keyword_starts_typename (enum rid keyword)
476 {
477 switch (keyword)
478 {
479 case RID_UNSIGNED:
480 case RID_LONG:
481 case RID_SHORT:
482 case RID_SIGNED:
483 case RID_COMPLEX:
484 case RID_INT:
485 case RID_CHAR:
486 case RID_FLOAT:
487 case RID_DOUBLE:
488 case RID_VOID:
489 case RID_DFLOAT32:
490 case RID_DFLOAT64:
491 case RID_DFLOAT128:
492 CASE_RID_FLOATN_NX:
493 case RID_BOOL:
494 case RID_ENUM:
495 case RID_STRUCT:
496 case RID_UNION:
497 case RID_TYPEOF:
498 case RID_CONST:
499 case RID_ATOMIC:
500 case RID_VOLATILE:
501 case RID_RESTRICT:
502 case RID_ATTRIBUTE:
503 case RID_FRACT:
504 case RID_ACCUM:
505 case RID_SAT:
506 case RID_AUTO_TYPE:
507 case RID_ALIGNAS:
508 return true;
509 default:
510 if (keyword >= RID_FIRST_INT_N
511 && keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS
512 && int_n_enabled_p[keyword - RID_FIRST_INT_N])
513 return true;
514 return false;
515 }
516 }
517
518 /* Return true if TOKEN can start a type name,
519 false otherwise. */
520 bool
c_token_starts_typename(c_token * token)521 c_token_starts_typename (c_token *token)
522 {
523 switch (token->type)
524 {
525 case CPP_NAME:
526 switch (token->id_kind)
527 {
528 case C_ID_ID:
529 return false;
530 case C_ID_ADDRSPACE:
531 return true;
532 case C_ID_TYPENAME:
533 return true;
534 case C_ID_CLASSNAME:
535 gcc_assert (c_dialect_objc ());
536 return true;
537 default:
538 gcc_unreachable ();
539 }
540 case CPP_KEYWORD:
541 return c_keyword_starts_typename (token->keyword);
542 case CPP_LESS:
543 if (c_dialect_objc ())
544 return true;
545 return false;
546 default:
547 return false;
548 }
549 }
550
551 /* Return true if the next token from PARSER can start a type name,
552 false otherwise. LA specifies how to do lookahead in order to
553 detect unknown type names. If unsure, pick CLA_PREFER_ID. */
554
555 static inline bool
c_parser_next_tokens_start_typename(c_parser * parser,enum c_lookahead_kind la)556 c_parser_next_tokens_start_typename (c_parser *parser, enum c_lookahead_kind la)
557 {
558 c_token *token = c_parser_peek_token (parser);
559 if (c_token_starts_typename (token))
560 return true;
561
562 /* Try a bit harder to detect an unknown typename. */
563 if (la != cla_prefer_id
564 && token->type == CPP_NAME
565 && token->id_kind == C_ID_ID
566
567 /* Do not try too hard when we could have "object in array". */
568 && !parser->objc_could_be_foreach_context
569
570 && (la == cla_prefer_type
571 || c_parser_peek_2nd_token (parser)->type == CPP_NAME
572 || c_parser_peek_2nd_token (parser)->type == CPP_MULT)
573
574 /* Only unknown identifiers. */
575 && !lookup_name (token->value))
576 return true;
577
578 return false;
579 }
580
581 /* Return true if TOKEN is a type qualifier, false otherwise. */
582 static bool
c_token_is_qualifier(c_token * token)583 c_token_is_qualifier (c_token *token)
584 {
585 switch (token->type)
586 {
587 case CPP_NAME:
588 switch (token->id_kind)
589 {
590 case C_ID_ADDRSPACE:
591 return true;
592 default:
593 return false;
594 }
595 case CPP_KEYWORD:
596 switch (token->keyword)
597 {
598 case RID_CONST:
599 case RID_VOLATILE:
600 case RID_RESTRICT:
601 case RID_ATTRIBUTE:
602 case RID_ATOMIC:
603 return true;
604 default:
605 return false;
606 }
607 case CPP_LESS:
608 return false;
609 default:
610 gcc_unreachable ();
611 }
612 }
613
614 /* Return true if the next token from PARSER is a type qualifier,
615 false otherwise. */
616 static inline bool
c_parser_next_token_is_qualifier(c_parser * parser)617 c_parser_next_token_is_qualifier (c_parser *parser)
618 {
619 c_token *token = c_parser_peek_token (parser);
620 return c_token_is_qualifier (token);
621 }
622
623 /* Return true if TOKEN can start declaration specifiers, false
624 otherwise. */
625 static bool
c_token_starts_declspecs(c_token * token)626 c_token_starts_declspecs (c_token *token)
627 {
628 switch (token->type)
629 {
630 case CPP_NAME:
631 switch (token->id_kind)
632 {
633 case C_ID_ID:
634 return false;
635 case C_ID_ADDRSPACE:
636 return true;
637 case C_ID_TYPENAME:
638 return true;
639 case C_ID_CLASSNAME:
640 gcc_assert (c_dialect_objc ());
641 return true;
642 default:
643 gcc_unreachable ();
644 }
645 case CPP_KEYWORD:
646 switch (token->keyword)
647 {
648 case RID_STATIC:
649 case RID_EXTERN:
650 case RID_REGISTER:
651 case RID_TYPEDEF:
652 case RID_INLINE:
653 case RID_NORETURN:
654 case RID_AUTO:
655 case RID_THREAD:
656 case RID_UNSIGNED:
657 case RID_LONG:
658 case RID_SHORT:
659 case RID_SIGNED:
660 case RID_COMPLEX:
661 case RID_INT:
662 case RID_CHAR:
663 case RID_FLOAT:
664 case RID_DOUBLE:
665 case RID_VOID:
666 case RID_DFLOAT32:
667 case RID_DFLOAT64:
668 case RID_DFLOAT128:
669 CASE_RID_FLOATN_NX:
670 case RID_BOOL:
671 case RID_ENUM:
672 case RID_STRUCT:
673 case RID_UNION:
674 case RID_TYPEOF:
675 case RID_CONST:
676 case RID_VOLATILE:
677 case RID_RESTRICT:
678 case RID_ATTRIBUTE:
679 case RID_FRACT:
680 case RID_ACCUM:
681 case RID_SAT:
682 case RID_ALIGNAS:
683 case RID_ATOMIC:
684 case RID_AUTO_TYPE:
685 return true;
686 default:
687 if (token->keyword >= RID_FIRST_INT_N
688 && token->keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS
689 && int_n_enabled_p[token->keyword - RID_FIRST_INT_N])
690 return true;
691 return false;
692 }
693 case CPP_LESS:
694 if (c_dialect_objc ())
695 return true;
696 return false;
697 default:
698 return false;
699 }
700 }
701
702
703 /* Return true if TOKEN can start declaration specifiers or a static
704 assertion, false otherwise. */
705 static bool
c_token_starts_declaration(c_token * token)706 c_token_starts_declaration (c_token *token)
707 {
708 if (c_token_starts_declspecs (token)
709 || token->keyword == RID_STATIC_ASSERT)
710 return true;
711 else
712 return false;
713 }
714
715 /* Return true if the next token from PARSER can start declaration
716 specifiers, false otherwise. */
717 bool
c_parser_next_token_starts_declspecs(c_parser * parser)718 c_parser_next_token_starts_declspecs (c_parser *parser)
719 {
720 c_token *token = c_parser_peek_token (parser);
721
722 /* In Objective-C, a classname normally starts a declspecs unless it
723 is immediately followed by a dot. In that case, it is the
724 Objective-C 2.0 "dot-syntax" for class objects, ie, calls the
725 setter/getter on the class. c_token_starts_declspecs() can't
726 differentiate between the two cases because it only checks the
727 current token, so we have a special check here. */
728 if (c_dialect_objc ()
729 && token->type == CPP_NAME
730 && token->id_kind == C_ID_CLASSNAME
731 && c_parser_peek_2nd_token (parser)->type == CPP_DOT)
732 return false;
733
734 return c_token_starts_declspecs (token);
735 }
736
737 /* Return true if the next tokens from PARSER can start declaration
738 specifiers or a static assertion, false otherwise. */
739 bool
c_parser_next_tokens_start_declaration(c_parser * parser)740 c_parser_next_tokens_start_declaration (c_parser *parser)
741 {
742 c_token *token = c_parser_peek_token (parser);
743
744 /* Same as above. */
745 if (c_dialect_objc ()
746 && token->type == CPP_NAME
747 && token->id_kind == C_ID_CLASSNAME
748 && c_parser_peek_2nd_token (parser)->type == CPP_DOT)
749 return false;
750
751 /* Labels do not start declarations. */
752 if (token->type == CPP_NAME
753 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
754 return false;
755
756 if (c_token_starts_declaration (token))
757 return true;
758
759 if (c_parser_next_tokens_start_typename (parser, cla_nonabstract_decl))
760 return true;
761
762 return false;
763 }
764
765 /* Consume the next token from PARSER. */
766
767 void
c_parser_consume_token(c_parser * parser)768 c_parser_consume_token (c_parser *parser)
769 {
770 gcc_assert (parser->tokens_avail >= 1);
771 gcc_assert (parser->tokens[0].type != CPP_EOF);
772 gcc_assert (!parser->in_pragma || parser->tokens[0].type != CPP_PRAGMA_EOL);
773 gcc_assert (parser->error || parser->tokens[0].type != CPP_PRAGMA);
774 parser->last_token_location = parser->tokens[0].location;
775 if (parser->tokens != &parser->tokens_buf[0])
776 parser->tokens++;
777 else if (parser->tokens_avail == 2)
778 parser->tokens[0] = parser->tokens[1];
779 parser->tokens_avail--;
780 }
781
782 /* Expect the current token to be a #pragma. Consume it and remember
783 that we've begun parsing a pragma. */
784
785 static void
c_parser_consume_pragma(c_parser * parser)786 c_parser_consume_pragma (c_parser *parser)
787 {
788 gcc_assert (!parser->in_pragma);
789 gcc_assert (parser->tokens_avail >= 1);
790 gcc_assert (parser->tokens[0].type == CPP_PRAGMA);
791 if (parser->tokens != &parser->tokens_buf[0])
792 parser->tokens++;
793 else if (parser->tokens_avail == 2)
794 parser->tokens[0] = parser->tokens[1];
795 parser->tokens_avail--;
796 parser->in_pragma = true;
797 }
798
799 /* Update the global input_location from TOKEN. */
800 static inline void
c_parser_set_source_position_from_token(c_token * token)801 c_parser_set_source_position_from_token (c_token *token)
802 {
803 if (token->type != CPP_EOF)
804 {
805 input_location = token->location;
806 }
807 }
808
809 /* Helper function for c_parser_error.
810 Having peeked a token of kind TOK1_KIND that might signify
811 a conflict marker, peek successor tokens to determine
812 if we actually do have a conflict marker.
813 Specifically, we consider a run of 7 '<', '=' or '>' characters
814 at the start of a line as a conflict marker.
815 These come through the lexer as three pairs and a single,
816 e.g. three CPP_LSHIFT ("<<") and a CPP_LESS ('<').
817 If it returns true, *OUT_LOC is written to with the location/range
818 of the marker. */
819
820 static bool
c_parser_peek_conflict_marker(c_parser * parser,enum cpp_ttype tok1_kind,location_t * out_loc)821 c_parser_peek_conflict_marker (c_parser *parser, enum cpp_ttype tok1_kind,
822 location_t *out_loc)
823 {
824 c_token *token2 = c_parser_peek_2nd_token (parser);
825 if (token2->type != tok1_kind)
826 return false;
827 c_token *token3 = c_parser_peek_nth_token (parser, 3);
828 if (token3->type != tok1_kind)
829 return false;
830 c_token *token4 = c_parser_peek_nth_token (parser, 4);
831 if (token4->type != conflict_marker_get_final_tok_kind (tok1_kind))
832 return false;
833
834 /* It must be at the start of the line. */
835 location_t start_loc = c_parser_peek_token (parser)->location;
836 if (LOCATION_COLUMN (start_loc) != 1)
837 return false;
838
839 /* We have a conflict marker. Construct a location of the form:
840 <<<<<<<
841 ^~~~~~~
842 with start == caret, finishing at the end of the marker. */
843 location_t finish_loc = get_finish (token4->location);
844 *out_loc = make_location (start_loc, start_loc, finish_loc);
845
846 return true;
847 }
848
849 /* Issue a diagnostic of the form
850 FILE:LINE: MESSAGE before TOKEN
851 where TOKEN is the next token in the input stream of PARSER.
852 MESSAGE (specified by the caller) is usually of the form "expected
853 OTHER-TOKEN".
854
855 Use RICHLOC as the location of the diagnostic.
856
857 Do not issue a diagnostic if still recovering from an error.
858
859 Return true iff an error was actually emitted.
860
861 ??? This is taken from the C++ parser, but building up messages in
862 this way is not i18n-friendly and some other approach should be
863 used. */
864
865 static bool
c_parser_error_richloc(c_parser * parser,const char * gmsgid,rich_location * richloc)866 c_parser_error_richloc (c_parser *parser, const char *gmsgid,
867 rich_location *richloc)
868 {
869 c_token *token = c_parser_peek_token (parser);
870 if (parser->error)
871 return false;
872 parser->error = true;
873 if (!gmsgid)
874 return false;
875
876 /* If this is actually a conflict marker, report it as such. */
877 if (token->type == CPP_LSHIFT
878 || token->type == CPP_RSHIFT
879 || token->type == CPP_EQ_EQ)
880 {
881 location_t loc;
882 if (c_parser_peek_conflict_marker (parser, token->type, &loc))
883 {
884 error_at (loc, "version control conflict marker in file");
885 return true;
886 }
887 }
888
889 c_parse_error (gmsgid,
890 /* Because c_parse_error does not understand
891 CPP_KEYWORD, keywords are treated like
892 identifiers. */
893 (token->type == CPP_KEYWORD ? CPP_NAME : token->type),
894 /* ??? The C parser does not save the cpp flags of a
895 token, we need to pass 0 here and we will not get
896 the source spelling of some tokens but rather the
897 canonical spelling. */
898 token->value, /*flags=*/0, richloc);
899 return true;
900 }
901
902 /* As c_parser_error_richloc, but issue the message at the
903 location of PARSER's next token, or at input_location
904 if the next token is EOF. */
905
906 bool
c_parser_error(c_parser * parser,const char * gmsgid)907 c_parser_error (c_parser *parser, const char *gmsgid)
908 {
909 c_token *token = c_parser_peek_token (parser);
910 c_parser_set_source_position_from_token (token);
911 rich_location richloc (line_table, input_location);
912 return c_parser_error_richloc (parser, gmsgid, &richloc);
913 }
914
915 /* Some tokens naturally come in pairs e.g.'(' and ')'.
916 This class is for tracking such a matching pair of symbols.
917 In particular, it tracks the location of the first token,
918 so that if the second token is missing, we can highlight the
919 location of the first token when notifying the user about the
920 problem. */
921
922 template <typename traits_t>
923 class token_pair
924 {
925 public:
926 /* token_pair's ctor. */
token_pair()927 token_pair () : m_open_loc (UNKNOWN_LOCATION) {}
928
929 /* If the next token is the opening symbol for this pair, consume it and
930 return true.
931 Otherwise, issue an error and return false.
932 In either case, record the location of the opening token. */
933
require_open(c_parser * parser)934 bool require_open (c_parser *parser)
935 {
936 c_token *token = c_parser_peek_token (parser);
937 if (token)
938 m_open_loc = token->location;
939
940 return c_parser_require (parser, traits_t::open_token_type,
941 traits_t::open_gmsgid);
942 }
943
944 /* Consume the next token from PARSER, recording its location as
945 that of the opening token within the pair. */
946
consume_open(c_parser * parser)947 void consume_open (c_parser *parser)
948 {
949 c_token *token = c_parser_peek_token (parser);
950 gcc_assert (token->type == traits_t::open_token_type);
951 m_open_loc = token->location;
952 c_parser_consume_token (parser);
953 }
954
955 /* If the next token is the closing symbol for this pair, consume it
956 and return true.
957 Otherwise, issue an error, highlighting the location of the
958 corresponding opening token, and return false. */
959
require_close(c_parser * parser)960 bool require_close (c_parser *parser) const
961 {
962 return c_parser_require (parser, traits_t::close_token_type,
963 traits_t::close_gmsgid, m_open_loc);
964 }
965
966 /* Like token_pair::require_close, except that tokens will be skipped
967 until the desired token is found. An error message is still produced
968 if the next token is not as expected. */
969
skip_until_found_close(c_parser * parser)970 void skip_until_found_close (c_parser *parser) const
971 {
972 c_parser_skip_until_found (parser, traits_t::close_token_type,
973 traits_t::close_gmsgid, m_open_loc);
974 }
975
976 private:
977 location_t m_open_loc;
978 };
979
980 /* Traits for token_pair<T> for tracking matching pairs of parentheses. */
981
982 struct matching_paren_traits
983 {
984 static const enum cpp_ttype open_token_type = CPP_OPEN_PAREN;
985 static const char * const open_gmsgid;
986 static const enum cpp_ttype close_token_type = CPP_CLOSE_PAREN;
987 static const char * const close_gmsgid;
988 };
989
990 const char * const matching_paren_traits::open_gmsgid = "expected %<(%>";
991 const char * const matching_paren_traits::close_gmsgid = "expected %<)%>";
992
993 /* "matching_parens" is a token_pair<T> class for tracking matching
994 pairs of parentheses. */
995
996 typedef token_pair<matching_paren_traits> matching_parens;
997
998 /* Traits for token_pair<T> for tracking matching pairs of braces. */
999
1000 struct matching_brace_traits
1001 {
1002 static const enum cpp_ttype open_token_type = CPP_OPEN_BRACE;
1003 static const char * const open_gmsgid;
1004 static const enum cpp_ttype close_token_type = CPP_CLOSE_BRACE;
1005 static const char * const close_gmsgid;
1006 };
1007
1008 const char * const matching_brace_traits::open_gmsgid = "expected %<{%>";
1009 const char * const matching_brace_traits::close_gmsgid = "expected %<}%>";
1010
1011 /* "matching_braces" is a token_pair<T> class for tracking matching
1012 pairs of braces. */
1013
1014 typedef token_pair<matching_brace_traits> matching_braces;
1015
1016 /* Get a description of the matching symbol to TYPE e.g. "(" for
1017 CPP_CLOSE_PAREN. */
1018
1019 static const char *
get_matching_symbol(enum cpp_ttype type)1020 get_matching_symbol (enum cpp_ttype type)
1021 {
1022 switch (type)
1023 {
1024 default:
1025 gcc_unreachable ();
1026 return "";
1027 case CPP_CLOSE_PAREN:
1028 return "(";
1029 case CPP_CLOSE_BRACE:
1030 return "{";
1031 }
1032 }
1033
1034 /* If the next token is of the indicated TYPE, consume it. Otherwise,
1035 issue the error MSGID. If MSGID is NULL then a message has already
1036 been produced and no message will be produced this time. Returns
1037 true if found, false otherwise.
1038
1039 If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1040 within any error as the location of an "opening" token matching
1041 the close token TYPE (e.g. the location of the '(' when TYPE is
1042 CPP_CLOSE_PAREN).
1043
1044 If TYPE_IS_UNIQUE is true (the default) then msgid describes exactly
1045 one type (e.g. "expected %<)%>") and thus it may be reasonable to
1046 attempt to generate a fix-it hint for the problem.
1047 Otherwise msgid describes multiple token types (e.g.
1048 "expected %<;%>, %<,%> or %<)%>"), and thus we shouldn't attempt to
1049 generate a fix-it hint. */
1050
1051 bool
c_parser_require(c_parser * parser,enum cpp_ttype type,const char * msgid,location_t matching_location,bool type_is_unique)1052 c_parser_require (c_parser *parser,
1053 enum cpp_ttype type,
1054 const char *msgid,
1055 location_t matching_location,
1056 bool type_is_unique)
1057 {
1058 if (c_parser_next_token_is (parser, type))
1059 {
1060 c_parser_consume_token (parser);
1061 return true;
1062 }
1063 else
1064 {
1065 location_t next_token_loc = c_parser_peek_token (parser)->location;
1066 gcc_rich_location richloc (next_token_loc);
1067
1068 /* Potentially supply a fix-it hint, suggesting to add the
1069 missing token immediately after the *previous* token.
1070 This may move the primary location within richloc. */
1071 if (!parser->error && type_is_unique)
1072 maybe_suggest_missing_token_insertion (&richloc, type,
1073 parser->last_token_location);
1074
1075 /* If matching_location != UNKNOWN_LOCATION, highlight it.
1076 Attempt to consolidate diagnostics by printing it as a
1077 secondary range within the main diagnostic. */
1078 bool added_matching_location = false;
1079 if (matching_location != UNKNOWN_LOCATION)
1080 added_matching_location
1081 = richloc.add_location_if_nearby (matching_location);
1082
1083 if (c_parser_error_richloc (parser, msgid, &richloc))
1084 /* If we weren't able to consolidate matching_location, then
1085 print it as a secondary diagnostic. */
1086 if (matching_location != UNKNOWN_LOCATION && !added_matching_location)
1087 inform (matching_location, "to match this %qs",
1088 get_matching_symbol (type));
1089
1090 return false;
1091 }
1092 }
1093
1094 /* If the next token is the indicated keyword, consume it. Otherwise,
1095 issue the error MSGID. Returns true if found, false otherwise. */
1096
1097 static bool
c_parser_require_keyword(c_parser * parser,enum rid keyword,const char * msgid)1098 c_parser_require_keyword (c_parser *parser,
1099 enum rid keyword,
1100 const char *msgid)
1101 {
1102 if (c_parser_next_token_is_keyword (parser, keyword))
1103 {
1104 c_parser_consume_token (parser);
1105 return true;
1106 }
1107 else
1108 {
1109 c_parser_error (parser, msgid);
1110 return false;
1111 }
1112 }
1113
1114 /* Like c_parser_require, except that tokens will be skipped until the
1115 desired token is found. An error message is still produced if the
1116 next token is not as expected. If MSGID is NULL then a message has
1117 already been produced and no message will be produced this
1118 time.
1119
1120 If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1121 within any error as the location of an "opening" token matching
1122 the close token TYPE (e.g. the location of the '(' when TYPE is
1123 CPP_CLOSE_PAREN). */
1124
1125 void
c_parser_skip_until_found(c_parser * parser,enum cpp_ttype type,const char * msgid,location_t matching_location)1126 c_parser_skip_until_found (c_parser *parser,
1127 enum cpp_ttype type,
1128 const char *msgid,
1129 location_t matching_location)
1130 {
1131 unsigned nesting_depth = 0;
1132
1133 if (c_parser_require (parser, type, msgid, matching_location))
1134 return;
1135
1136 /* Skip tokens until the desired token is found. */
1137 while (true)
1138 {
1139 /* Peek at the next token. */
1140 c_token *token = c_parser_peek_token (parser);
1141 /* If we've reached the token we want, consume it and stop. */
1142 if (token->type == type && !nesting_depth)
1143 {
1144 c_parser_consume_token (parser);
1145 break;
1146 }
1147
1148 /* If we've run out of tokens, stop. */
1149 if (token->type == CPP_EOF)
1150 return;
1151 if (token->type == CPP_PRAGMA_EOL && parser->in_pragma)
1152 return;
1153 if (token->type == CPP_OPEN_BRACE
1154 || token->type == CPP_OPEN_PAREN
1155 || token->type == CPP_OPEN_SQUARE)
1156 ++nesting_depth;
1157 else if (token->type == CPP_CLOSE_BRACE
1158 || token->type == CPP_CLOSE_PAREN
1159 || token->type == CPP_CLOSE_SQUARE)
1160 {
1161 if (nesting_depth-- == 0)
1162 break;
1163 }
1164 /* Consume this token. */
1165 c_parser_consume_token (parser);
1166 }
1167 parser->error = false;
1168 }
1169
1170 /* Skip tokens until the end of a parameter is found, but do not
1171 consume the comma, semicolon or closing delimiter. */
1172
1173 static void
c_parser_skip_to_end_of_parameter(c_parser * parser)1174 c_parser_skip_to_end_of_parameter (c_parser *parser)
1175 {
1176 unsigned nesting_depth = 0;
1177
1178 while (true)
1179 {
1180 c_token *token = c_parser_peek_token (parser);
1181 if ((token->type == CPP_COMMA || token->type == CPP_SEMICOLON)
1182 && !nesting_depth)
1183 break;
1184 /* If we've run out of tokens, stop. */
1185 if (token->type == CPP_EOF)
1186 return;
1187 if (token->type == CPP_PRAGMA_EOL && parser->in_pragma)
1188 return;
1189 if (token->type == CPP_OPEN_BRACE
1190 || token->type == CPP_OPEN_PAREN
1191 || token->type == CPP_OPEN_SQUARE)
1192 ++nesting_depth;
1193 else if (token->type == CPP_CLOSE_BRACE
1194 || token->type == CPP_CLOSE_PAREN
1195 || token->type == CPP_CLOSE_SQUARE)
1196 {
1197 if (nesting_depth-- == 0)
1198 break;
1199 }
1200 /* Consume this token. */
1201 c_parser_consume_token (parser);
1202 }
1203 parser->error = false;
1204 }
1205
1206 /* Expect to be at the end of the pragma directive and consume an
1207 end of line marker. */
1208
1209 static void
1210 c_parser_skip_to_pragma_eol (c_parser *parser, bool error_if_not_eol = true)
1211 {
1212 gcc_assert (parser->in_pragma);
1213 parser->in_pragma = false;
1214
1215 if (error_if_not_eol && c_parser_peek_token (parser)->type != CPP_PRAGMA_EOL)
1216 c_parser_error (parser, "expected end of line");
1217
1218 cpp_ttype token_type;
1219 do
1220 {
1221 c_token *token = c_parser_peek_token (parser);
1222 token_type = token->type;
1223 if (token_type == CPP_EOF)
1224 break;
1225 c_parser_consume_token (parser);
1226 }
1227 while (token_type != CPP_PRAGMA_EOL);
1228
1229 parser->error = false;
1230 }
1231
1232 /* Skip tokens until we have consumed an entire block, or until we
1233 have consumed a non-nested ';'. */
1234
1235 static void
c_parser_skip_to_end_of_block_or_statement(c_parser * parser)1236 c_parser_skip_to_end_of_block_or_statement (c_parser *parser)
1237 {
1238 unsigned nesting_depth = 0;
1239 bool save_error = parser->error;
1240
1241 while (true)
1242 {
1243 c_token *token;
1244
1245 /* Peek at the next token. */
1246 token = c_parser_peek_token (parser);
1247
1248 switch (token->type)
1249 {
1250 case CPP_EOF:
1251 return;
1252
1253 case CPP_PRAGMA_EOL:
1254 if (parser->in_pragma)
1255 return;
1256 break;
1257
1258 case CPP_SEMICOLON:
1259 /* If the next token is a ';', we have reached the
1260 end of the statement. */
1261 if (!nesting_depth)
1262 {
1263 /* Consume the ';'. */
1264 c_parser_consume_token (parser);
1265 goto finished;
1266 }
1267 break;
1268
1269 case CPP_CLOSE_BRACE:
1270 /* If the next token is a non-nested '}', then we have
1271 reached the end of the current block. */
1272 if (nesting_depth == 0 || --nesting_depth == 0)
1273 {
1274 c_parser_consume_token (parser);
1275 goto finished;
1276 }
1277 break;
1278
1279 case CPP_OPEN_BRACE:
1280 /* If it the next token is a '{', then we are entering a new
1281 block. Consume the entire block. */
1282 ++nesting_depth;
1283 break;
1284
1285 case CPP_PRAGMA:
1286 /* If we see a pragma, consume the whole thing at once. We
1287 have some safeguards against consuming pragmas willy-nilly.
1288 Normally, we'd expect to be here with parser->error set,
1289 which disables these safeguards. But it's possible to get
1290 here for secondary error recovery, after parser->error has
1291 been cleared. */
1292 c_parser_consume_pragma (parser);
1293 c_parser_skip_to_pragma_eol (parser);
1294 parser->error = save_error;
1295 continue;
1296
1297 default:
1298 break;
1299 }
1300
1301 c_parser_consume_token (parser);
1302 }
1303
1304 finished:
1305 parser->error = false;
1306 }
1307
1308 /* CPP's options (initialized by c-opts.c). */
1309 extern cpp_options *cpp_opts;
1310
1311 /* Save the warning flags which are controlled by __extension__. */
1312
1313 static inline int
disable_extension_diagnostics(void)1314 disable_extension_diagnostics (void)
1315 {
1316 int ret = (pedantic
1317 | (warn_pointer_arith << 1)
1318 | (warn_traditional << 2)
1319 | (flag_iso << 3)
1320 | (warn_long_long << 4)
1321 | (warn_cxx_compat << 5)
1322 | (warn_overlength_strings << 6)
1323 /* warn_c90_c99_compat has three states: -1/0/1, so we must
1324 play tricks to properly restore it. */
1325 | ((warn_c90_c99_compat == 1) << 7)
1326 | ((warn_c90_c99_compat == -1) << 8)
1327 /* Similarly for warn_c99_c11_compat. */
1328 | ((warn_c99_c11_compat == 1) << 9)
1329 | ((warn_c99_c11_compat == -1) << 10)
1330 );
1331 cpp_opts->cpp_pedantic = pedantic = 0;
1332 warn_pointer_arith = 0;
1333 cpp_opts->cpp_warn_traditional = warn_traditional = 0;
1334 flag_iso = 0;
1335 cpp_opts->cpp_warn_long_long = warn_long_long = 0;
1336 warn_cxx_compat = 0;
1337 warn_overlength_strings = 0;
1338 warn_c90_c99_compat = 0;
1339 warn_c99_c11_compat = 0;
1340 return ret;
1341 }
1342
1343 /* Restore the warning flags which are controlled by __extension__.
1344 FLAGS is the return value from disable_extension_diagnostics. */
1345
1346 static inline void
restore_extension_diagnostics(int flags)1347 restore_extension_diagnostics (int flags)
1348 {
1349 cpp_opts->cpp_pedantic = pedantic = flags & 1;
1350 warn_pointer_arith = (flags >> 1) & 1;
1351 cpp_opts->cpp_warn_traditional = warn_traditional = (flags >> 2) & 1;
1352 flag_iso = (flags >> 3) & 1;
1353 cpp_opts->cpp_warn_long_long = warn_long_long = (flags >> 4) & 1;
1354 warn_cxx_compat = (flags >> 5) & 1;
1355 warn_overlength_strings = (flags >> 6) & 1;
1356 /* See above for why is this needed. */
1357 warn_c90_c99_compat = (flags >> 7) & 1 ? 1 : ((flags >> 8) & 1 ? -1 : 0);
1358 warn_c99_c11_compat = (flags >> 9) & 1 ? 1 : ((flags >> 10) & 1 ? -1 : 0);
1359 }
1360
1361 /* Helper data structure for parsing #pragma acc routine. */
1362 struct oacc_routine_data {
1363 bool error_seen; /* Set if error has been reported. */
1364 bool fndecl_seen; /* Set if one fn decl/definition has been seen already. */
1365 tree clauses;
1366 location_t loc;
1367 };
1368
1369 static void c_parser_external_declaration (c_parser *);
1370 static void c_parser_asm_definition (c_parser *);
1371 static void c_parser_declaration_or_fndef (c_parser *, bool, bool, bool,
1372 bool, bool, tree *, vec<c_token>,
1373 struct oacc_routine_data * = NULL,
1374 bool * = NULL);
1375 static void c_parser_static_assert_declaration_no_semi (c_parser *);
1376 static void c_parser_static_assert_declaration (c_parser *);
1377 static struct c_typespec c_parser_enum_specifier (c_parser *);
1378 static struct c_typespec c_parser_struct_or_union_specifier (c_parser *);
1379 static tree c_parser_struct_declaration (c_parser *);
1380 static struct c_typespec c_parser_typeof_specifier (c_parser *);
1381 static tree c_parser_alignas_specifier (c_parser *);
1382 static struct c_declarator *c_parser_direct_declarator (c_parser *, bool,
1383 c_dtr_syn, bool *);
1384 static struct c_declarator *c_parser_direct_declarator_inner (c_parser *,
1385 bool,
1386 struct c_declarator *);
1387 static struct c_arg_info *c_parser_parms_declarator (c_parser *, bool, tree);
1388 static struct c_arg_info *c_parser_parms_list_declarator (c_parser *, tree,
1389 tree);
1390 static struct c_parm *c_parser_parameter_declaration (c_parser *, tree);
1391 static tree c_parser_simple_asm_expr (c_parser *);
1392 static tree c_parser_attributes (c_parser *);
1393 static struct c_expr c_parser_initializer (c_parser *);
1394 static struct c_expr c_parser_braced_init (c_parser *, tree, bool,
1395 struct obstack *);
1396 static void c_parser_initelt (c_parser *, struct obstack *);
1397 static void c_parser_initval (c_parser *, struct c_expr *,
1398 struct obstack *);
1399 static tree c_parser_compound_statement (c_parser *);
1400 static void c_parser_compound_statement_nostart (c_parser *);
1401 static void c_parser_label (c_parser *);
1402 static void c_parser_statement (c_parser *, bool *, location_t * = NULL);
1403 static void c_parser_statement_after_labels (c_parser *, bool *,
1404 vec<tree> * = NULL);
1405 static tree c_parser_c99_block_statement (c_parser *, bool *,
1406 location_t * = NULL);
1407 static void c_parser_if_statement (c_parser *, bool *, vec<tree> *);
1408 static void c_parser_switch_statement (c_parser *, bool *);
1409 static void c_parser_while_statement (c_parser *, bool, unsigned short, bool *);
1410 static void c_parser_do_statement (c_parser *, bool, unsigned short);
1411 static void c_parser_for_statement (c_parser *, bool, unsigned short, bool *);
1412 static tree c_parser_asm_statement (c_parser *);
1413 static tree c_parser_asm_operands (c_parser *);
1414 static tree c_parser_asm_goto_operands (c_parser *);
1415 static tree c_parser_asm_clobbers (c_parser *);
1416 static struct c_expr c_parser_expr_no_commas (c_parser *, struct c_expr *,
1417 tree = NULL_TREE);
1418 static struct c_expr c_parser_conditional_expression (c_parser *,
1419 struct c_expr *, tree);
1420 static struct c_expr c_parser_binary_expression (c_parser *, struct c_expr *,
1421 tree);
1422 static struct c_expr c_parser_cast_expression (c_parser *, struct c_expr *);
1423 static struct c_expr c_parser_unary_expression (c_parser *);
1424 static struct c_expr c_parser_sizeof_expression (c_parser *);
1425 static struct c_expr c_parser_alignof_expression (c_parser *);
1426 static struct c_expr c_parser_postfix_expression (c_parser *);
1427 static struct c_expr c_parser_postfix_expression_after_paren_type (c_parser *,
1428 struct c_type_name *,
1429 location_t);
1430 static struct c_expr c_parser_postfix_expression_after_primary (c_parser *,
1431 location_t loc,
1432 struct c_expr);
1433 static tree c_parser_transaction (c_parser *, enum rid);
1434 static struct c_expr c_parser_transaction_expression (c_parser *, enum rid);
1435 static tree c_parser_transaction_cancel (c_parser *);
1436 static struct c_expr c_parser_expression (c_parser *);
1437 static struct c_expr c_parser_expression_conv (c_parser *);
1438 static vec<tree, va_gc> *c_parser_expr_list (c_parser *, bool, bool,
1439 vec<tree, va_gc> **, location_t *,
1440 tree *, vec<location_t> *,
1441 unsigned int * = NULL);
1442 static void c_parser_oacc_declare (c_parser *);
1443 static void c_parser_oacc_enter_exit_data (c_parser *, bool);
1444 static void c_parser_oacc_update (c_parser *);
1445 static void c_parser_omp_construct (c_parser *, bool *);
1446 static void c_parser_omp_threadprivate (c_parser *);
1447 static void c_parser_omp_barrier (c_parser *);
1448 static void c_parser_omp_flush (c_parser *);
1449 static tree c_parser_omp_for_loop (location_t, c_parser *, enum tree_code,
1450 tree, tree *, bool *);
1451 static void c_parser_omp_taskwait (c_parser *);
1452 static void c_parser_omp_taskyield (c_parser *);
1453 static void c_parser_omp_cancel (c_parser *);
1454
1455 enum pragma_context { pragma_external, pragma_struct, pragma_param,
1456 pragma_stmt, pragma_compound };
1457 static bool c_parser_pragma (c_parser *, enum pragma_context, bool *);
1458 static void c_parser_omp_cancellation_point (c_parser *, enum pragma_context);
1459 static bool c_parser_omp_target (c_parser *, enum pragma_context, bool *);
1460 static void c_parser_omp_end_declare_target (c_parser *);
1461 static void c_parser_omp_declare (c_parser *, enum pragma_context);
1462 static bool c_parser_omp_ordered (c_parser *, enum pragma_context, bool *);
1463 static void c_parser_oacc_routine (c_parser *, enum pragma_context);
1464
1465 /* These Objective-C parser functions are only ever called when
1466 compiling Objective-C. */
1467 static void c_parser_objc_class_definition (c_parser *, tree);
1468 static void c_parser_objc_class_instance_variables (c_parser *);
1469 static void c_parser_objc_class_declaration (c_parser *);
1470 static void c_parser_objc_alias_declaration (c_parser *);
1471 static void c_parser_objc_protocol_definition (c_parser *, tree);
1472 static bool c_parser_objc_method_type (c_parser *);
1473 static void c_parser_objc_method_definition (c_parser *);
1474 static void c_parser_objc_methodprotolist (c_parser *);
1475 static void c_parser_objc_methodproto (c_parser *);
1476 static tree c_parser_objc_method_decl (c_parser *, bool, tree *, tree *);
1477 static tree c_parser_objc_type_name (c_parser *);
1478 static tree c_parser_objc_protocol_refs (c_parser *);
1479 static void c_parser_objc_try_catch_finally_statement (c_parser *);
1480 static void c_parser_objc_synchronized_statement (c_parser *);
1481 static tree c_parser_objc_selector (c_parser *);
1482 static tree c_parser_objc_selector_arg (c_parser *);
1483 static tree c_parser_objc_receiver (c_parser *);
1484 static tree c_parser_objc_message_args (c_parser *);
1485 static tree c_parser_objc_keywordexpr (c_parser *);
1486 static void c_parser_objc_at_property_declaration (c_parser *);
1487 static void c_parser_objc_at_synthesize_declaration (c_parser *);
1488 static void c_parser_objc_at_dynamic_declaration (c_parser *);
1489 static bool c_parser_objc_diagnose_bad_element_prefix
1490 (c_parser *, struct c_declspecs *);
1491
1492 static void c_parser_parse_rtl_body (c_parser *parser, char *start_with_pass);
1493
1494 /* Parse a translation unit (C90 6.7, C99 6.9, C11 6.9).
1495
1496 translation-unit:
1497 external-declarations
1498
1499 external-declarations:
1500 external-declaration
1501 external-declarations external-declaration
1502
1503 GNU extensions:
1504
1505 translation-unit:
1506 empty
1507 */
1508
1509 static void
c_parser_translation_unit(c_parser * parser)1510 c_parser_translation_unit (c_parser *parser)
1511 {
1512 if (c_parser_next_token_is (parser, CPP_EOF))
1513 {
1514 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
1515 "ISO C forbids an empty translation unit");
1516 }
1517 else
1518 {
1519 void *obstack_position = obstack_alloc (&parser_obstack, 0);
1520 mark_valid_location_for_stdc_pragma (false);
1521 do
1522 {
1523 ggc_collect ();
1524 c_parser_external_declaration (parser);
1525 obstack_free (&parser_obstack, obstack_position);
1526 }
1527 while (c_parser_next_token_is_not (parser, CPP_EOF));
1528 }
1529
1530 unsigned int i;
1531 tree decl;
1532 FOR_EACH_VEC_ELT (incomplete_record_decls, i, decl)
1533 if (DECL_SIZE (decl) == NULL_TREE && TREE_TYPE (decl) != error_mark_node)
1534 error ("storage size of %q+D isn%'t known", decl);
1535 }
1536
1537 /* Parse an external declaration (C90 6.7, C99 6.9, C11 6.9).
1538
1539 external-declaration:
1540 function-definition
1541 declaration
1542
1543 GNU extensions:
1544
1545 external-declaration:
1546 asm-definition
1547 ;
1548 __extension__ external-declaration
1549
1550 Objective-C:
1551
1552 external-declaration:
1553 objc-class-definition
1554 objc-class-declaration
1555 objc-alias-declaration
1556 objc-protocol-definition
1557 objc-method-definition
1558 @end
1559 */
1560
1561 static void
c_parser_external_declaration(c_parser * parser)1562 c_parser_external_declaration (c_parser *parser)
1563 {
1564 int ext;
1565 switch (c_parser_peek_token (parser)->type)
1566 {
1567 case CPP_KEYWORD:
1568 switch (c_parser_peek_token (parser)->keyword)
1569 {
1570 case RID_EXTENSION:
1571 ext = disable_extension_diagnostics ();
1572 c_parser_consume_token (parser);
1573 c_parser_external_declaration (parser);
1574 restore_extension_diagnostics (ext);
1575 break;
1576 case RID_ASM:
1577 c_parser_asm_definition (parser);
1578 break;
1579 case RID_AT_INTERFACE:
1580 case RID_AT_IMPLEMENTATION:
1581 gcc_assert (c_dialect_objc ());
1582 c_parser_objc_class_definition (parser, NULL_TREE);
1583 break;
1584 case RID_AT_CLASS:
1585 gcc_assert (c_dialect_objc ());
1586 c_parser_objc_class_declaration (parser);
1587 break;
1588 case RID_AT_ALIAS:
1589 gcc_assert (c_dialect_objc ());
1590 c_parser_objc_alias_declaration (parser);
1591 break;
1592 case RID_AT_PROTOCOL:
1593 gcc_assert (c_dialect_objc ());
1594 c_parser_objc_protocol_definition (parser, NULL_TREE);
1595 break;
1596 case RID_AT_PROPERTY:
1597 gcc_assert (c_dialect_objc ());
1598 c_parser_objc_at_property_declaration (parser);
1599 break;
1600 case RID_AT_SYNTHESIZE:
1601 gcc_assert (c_dialect_objc ());
1602 c_parser_objc_at_synthesize_declaration (parser);
1603 break;
1604 case RID_AT_DYNAMIC:
1605 gcc_assert (c_dialect_objc ());
1606 c_parser_objc_at_dynamic_declaration (parser);
1607 break;
1608 case RID_AT_END:
1609 gcc_assert (c_dialect_objc ());
1610 c_parser_consume_token (parser);
1611 objc_finish_implementation ();
1612 break;
1613 default:
1614 goto decl_or_fndef;
1615 }
1616 break;
1617 case CPP_SEMICOLON:
1618 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
1619 "ISO C does not allow extra %<;%> outside of a function");
1620 c_parser_consume_token (parser);
1621 break;
1622 case CPP_PRAGMA:
1623 mark_valid_location_for_stdc_pragma (true);
1624 c_parser_pragma (parser, pragma_external, NULL);
1625 mark_valid_location_for_stdc_pragma (false);
1626 break;
1627 case CPP_PLUS:
1628 case CPP_MINUS:
1629 if (c_dialect_objc ())
1630 {
1631 c_parser_objc_method_definition (parser);
1632 break;
1633 }
1634 /* Else fall through, and yield a syntax error trying to parse
1635 as a declaration or function definition. */
1636 /* FALLTHRU */
1637 default:
1638 decl_or_fndef:
1639 /* A declaration or a function definition (or, in Objective-C,
1640 an @interface or @protocol with prefix attributes). We can
1641 only tell which after parsing the declaration specifiers, if
1642 any, and the first declarator. */
1643 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
1644 NULL, vNULL);
1645 break;
1646 }
1647 }
1648
1649 static void c_finish_omp_declare_simd (c_parser *, tree, tree, vec<c_token>);
1650 static void c_finish_oacc_routine (struct oacc_routine_data *, tree, bool);
1651
1652 /* Build and add a DEBUG_BEGIN_STMT statement with location LOC. */
1653
1654 static void
add_debug_begin_stmt(location_t loc)1655 add_debug_begin_stmt (location_t loc)
1656 {
1657 /* Don't add DEBUG_BEGIN_STMTs outside of functions, see PR84721. */
1658 if (!MAY_HAVE_DEBUG_MARKER_STMTS || !building_stmt_list_p ())
1659 return;
1660
1661 tree stmt = build0 (DEBUG_BEGIN_STMT, void_type_node);
1662 SET_EXPR_LOCATION (stmt, loc);
1663 add_stmt (stmt);
1664 }
1665
1666 /* Parse a declaration or function definition (C90 6.5, 6.7.1, C99
1667 6.7, 6.9.1, C11 6.7, 6.9.1). If FNDEF_OK is true, a function definition
1668 is accepted; otherwise (old-style parameter declarations) only other
1669 declarations are accepted. If STATIC_ASSERT_OK is true, a static
1670 assertion is accepted; otherwise (old-style parameter declarations)
1671 it is not. If NESTED is true, we are inside a function or parsing
1672 old-style parameter declarations; any functions encountered are
1673 nested functions and declaration specifiers are required; otherwise
1674 we are at top level and functions are normal functions and
1675 declaration specifiers may be optional. If EMPTY_OK is true, empty
1676 declarations are OK (subject to all other constraints); otherwise
1677 (old-style parameter declarations) they are diagnosed. If
1678 START_ATTR_OK is true, the declaration specifiers may start with
1679 attributes; otherwise they may not.
1680 OBJC_FOREACH_OBJECT_DECLARATION can be used to get back the parsed
1681 declaration when parsing an Objective-C foreach statement.
1682 FALLTHRU_ATTR_P is used to signal whether this function parsed
1683 "__attribute__((fallthrough));".
1684
1685 declaration:
1686 declaration-specifiers init-declarator-list[opt] ;
1687 static_assert-declaration
1688
1689 function-definition:
1690 declaration-specifiers[opt] declarator declaration-list[opt]
1691 compound-statement
1692
1693 declaration-list:
1694 declaration
1695 declaration-list declaration
1696
1697 init-declarator-list:
1698 init-declarator
1699 init-declarator-list , init-declarator
1700
1701 init-declarator:
1702 declarator simple-asm-expr[opt] attributes[opt]
1703 declarator simple-asm-expr[opt] attributes[opt] = initializer
1704
1705 GNU extensions:
1706
1707 nested-function-definition:
1708 declaration-specifiers declarator declaration-list[opt]
1709 compound-statement
1710
1711 attribute ;
1712
1713 Objective-C:
1714 attributes objc-class-definition
1715 attributes objc-category-definition
1716 attributes objc-protocol-definition
1717
1718 The simple-asm-expr and attributes are GNU extensions.
1719
1720 This function does not handle __extension__; that is handled in its
1721 callers. ??? Following the old parser, __extension__ may start
1722 external declarations, declarations in functions and declarations
1723 at the start of "for" loops, but not old-style parameter
1724 declarations.
1725
1726 C99 requires declaration specifiers in a function definition; the
1727 absence is diagnosed through the diagnosis of implicit int. In GNU
1728 C we also allow but diagnose declarations without declaration
1729 specifiers, but only at top level (elsewhere they conflict with
1730 other syntax).
1731
1732 In Objective-C, declarations of the looping variable in a foreach
1733 statement are exceptionally terminated by 'in' (for example, 'for
1734 (NSObject *object in array) { ... }').
1735
1736 OpenMP:
1737
1738 declaration:
1739 threadprivate-directive
1740
1741 GIMPLE:
1742
1743 gimple-function-definition:
1744 declaration-specifiers[opt] __GIMPLE (gimple-or-rtl-pass-list) declarator
1745 declaration-list[opt] compound-statement
1746
1747 rtl-function-definition:
1748 declaration-specifiers[opt] __RTL (gimple-or-rtl-pass-list) declarator
1749 declaration-list[opt] compound-statement */
1750
1751 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,struct oacc_routine_data * oacc_routine_data,bool * fallthru_attr_p)1752 c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
1753 bool static_assert_ok, bool empty_ok,
1754 bool nested, bool start_attr_ok,
1755 tree *objc_foreach_object_declaration,
1756 vec<c_token> omp_declare_simd_clauses,
1757 struct oacc_routine_data *oacc_routine_data,
1758 bool *fallthru_attr_p)
1759 {
1760 struct c_declspecs *specs;
1761 tree prefix_attrs;
1762 tree all_prefix_attrs;
1763 bool diagnosed_no_specs = false;
1764 location_t here = c_parser_peek_token (parser)->location;
1765
1766 add_debug_begin_stmt (c_parser_peek_token (parser)->location);
1767
1768 if (static_assert_ok
1769 && c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
1770 {
1771 c_parser_static_assert_declaration (parser);
1772 return;
1773 }
1774 specs = build_null_declspecs ();
1775
1776 /* Try to detect an unknown type name when we have "A B" or "A *B". */
1777 if (c_parser_peek_token (parser)->type == CPP_NAME
1778 && c_parser_peek_token (parser)->id_kind == C_ID_ID
1779 && (c_parser_peek_2nd_token (parser)->type == CPP_NAME
1780 || c_parser_peek_2nd_token (parser)->type == CPP_MULT)
1781 && (!nested || !lookup_name (c_parser_peek_token (parser)->value)))
1782 {
1783 tree name = c_parser_peek_token (parser)->value;
1784
1785 /* Issue a warning about NAME being an unknown type name, perhaps
1786 with some kind of hint.
1787 If the user forgot a "struct" etc, suggest inserting
1788 it. Otherwise, attempt to look for misspellings. */
1789 gcc_rich_location richloc (here);
1790 if (tag_exists_p (RECORD_TYPE, name))
1791 {
1792 /* This is not C++ with its implicit typedef. */
1793 richloc.add_fixit_insert_before ("struct ");
1794 error_at (&richloc,
1795 "unknown type name %qE;"
1796 " use %<struct%> keyword to refer to the type",
1797 name);
1798 }
1799 else if (tag_exists_p (UNION_TYPE, name))
1800 {
1801 richloc.add_fixit_insert_before ("union ");
1802 error_at (&richloc,
1803 "unknown type name %qE;"
1804 " use %<union%> keyword to refer to the type",
1805 name);
1806 }
1807 else if (tag_exists_p (ENUMERAL_TYPE, name))
1808 {
1809 richloc.add_fixit_insert_before ("enum ");
1810 error_at (&richloc,
1811 "unknown type name %qE;"
1812 " use %<enum%> keyword to refer to the type",
1813 name);
1814 }
1815 else
1816 {
1817 name_hint hint = lookup_name_fuzzy (name, FUZZY_LOOKUP_TYPENAME,
1818 here);
1819 if (hint)
1820 {
1821 richloc.add_fixit_replace (hint.suggestion ());
1822 error_at (&richloc,
1823 "unknown type name %qE; did you mean %qs?",
1824 name, hint.suggestion ());
1825 }
1826 else
1827 error_at (here, "unknown type name %qE", name);
1828 }
1829
1830 /* Parse declspecs normally to get a correct pointer type, but avoid
1831 a further "fails to be a type name" error. Refuse nested functions
1832 since it is not how the user likely wants us to recover. */
1833 c_parser_peek_token (parser)->type = CPP_KEYWORD;
1834 c_parser_peek_token (parser)->keyword = RID_VOID;
1835 c_parser_peek_token (parser)->value = error_mark_node;
1836 fndef_ok = !nested;
1837 }
1838
1839 c_parser_declspecs (parser, specs, true, true, start_attr_ok,
1840 true, true, cla_nonabstract_decl);
1841 if (parser->error)
1842 {
1843 c_parser_skip_to_end_of_block_or_statement (parser);
1844 return;
1845 }
1846 if (nested && !specs->declspecs_seen_p)
1847 {
1848 c_parser_error (parser, "expected declaration specifiers");
1849 c_parser_skip_to_end_of_block_or_statement (parser);
1850 return;
1851 }
1852
1853 finish_declspecs (specs);
1854 bool auto_type_p = specs->typespec_word == cts_auto_type;
1855 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
1856 {
1857 if (auto_type_p)
1858 error_at (here, "%<__auto_type%> in empty declaration");
1859 else if (specs->typespec_kind == ctsk_none
1860 && attribute_fallthrough_p (specs->attrs))
1861 {
1862 if (fallthru_attr_p != NULL)
1863 *fallthru_attr_p = true;
1864 tree fn = build_call_expr_internal_loc (here, IFN_FALLTHROUGH,
1865 void_type_node, 0);
1866 add_stmt (fn);
1867 }
1868 else if (empty_ok)
1869 shadow_tag (specs);
1870 else
1871 {
1872 shadow_tag_warned (specs, 1);
1873 pedwarn (here, 0, "empty declaration");
1874 }
1875 c_parser_consume_token (parser);
1876 if (oacc_routine_data)
1877 c_finish_oacc_routine (oacc_routine_data, NULL_TREE, false);
1878 return;
1879 }
1880
1881 /* Provide better error recovery. Note that a type name here is usually
1882 better diagnosed as a redeclaration. */
1883 if (empty_ok
1884 && specs->typespec_kind == ctsk_tagdef
1885 && c_parser_next_token_starts_declspecs (parser)
1886 && !c_parser_next_token_is (parser, CPP_NAME))
1887 {
1888 c_parser_error (parser, "expected %<;%>, identifier or %<(%>");
1889 parser->error = false;
1890 shadow_tag_warned (specs, 1);
1891 return;
1892 }
1893 else if (c_dialect_objc () && !auto_type_p)
1894 {
1895 /* Prefix attributes are an error on method decls. */
1896 switch (c_parser_peek_token (parser)->type)
1897 {
1898 case CPP_PLUS:
1899 case CPP_MINUS:
1900 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
1901 return;
1902 if (specs->attrs)
1903 {
1904 warning_at (c_parser_peek_token (parser)->location,
1905 OPT_Wattributes,
1906 "prefix attributes are ignored for methods");
1907 specs->attrs = NULL_TREE;
1908 }
1909 if (fndef_ok)
1910 c_parser_objc_method_definition (parser);
1911 else
1912 c_parser_objc_methodproto (parser);
1913 return;
1914 break;
1915 default:
1916 break;
1917 }
1918 /* This is where we parse 'attributes @interface ...',
1919 'attributes @implementation ...', 'attributes @protocol ...'
1920 (where attributes could be, for example, __attribute__
1921 ((deprecated)).
1922 */
1923 switch (c_parser_peek_token (parser)->keyword)
1924 {
1925 case RID_AT_INTERFACE:
1926 {
1927 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
1928 return;
1929 c_parser_objc_class_definition (parser, specs->attrs);
1930 return;
1931 }
1932 break;
1933 case RID_AT_IMPLEMENTATION:
1934 {
1935 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
1936 return;
1937 if (specs->attrs)
1938 {
1939 warning_at (c_parser_peek_token (parser)->location,
1940 OPT_Wattributes,
1941 "prefix attributes are ignored for implementations");
1942 specs->attrs = NULL_TREE;
1943 }
1944 c_parser_objc_class_definition (parser, NULL_TREE);
1945 return;
1946 }
1947 break;
1948 case RID_AT_PROTOCOL:
1949 {
1950 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
1951 return;
1952 c_parser_objc_protocol_definition (parser, specs->attrs);
1953 return;
1954 }
1955 break;
1956 case RID_AT_ALIAS:
1957 case RID_AT_CLASS:
1958 case RID_AT_END:
1959 case RID_AT_PROPERTY:
1960 if (specs->attrs)
1961 {
1962 c_parser_error (parser, "unexpected attribute");
1963 specs->attrs = NULL;
1964 }
1965 break;
1966 default:
1967 break;
1968 }
1969 }
1970 else if (attribute_fallthrough_p (specs->attrs))
1971 warning_at (here, OPT_Wattributes,
1972 "%<fallthrough%> attribute not followed by %<;%>");
1973
1974 pending_xref_error ();
1975 prefix_attrs = specs->attrs;
1976 all_prefix_attrs = prefix_attrs;
1977 specs->attrs = NULL_TREE;
1978 while (true)
1979 {
1980 struct c_declarator *declarator;
1981 bool dummy = false;
1982 timevar_id_t tv;
1983 tree fnbody = NULL_TREE;
1984 /* Declaring either one or more declarators (in which case we
1985 should diagnose if there were no declaration specifiers) or a
1986 function definition (in which case the diagnostic for
1987 implicit int suffices). */
1988 declarator = c_parser_declarator (parser,
1989 specs->typespec_kind != ctsk_none,
1990 C_DTR_NORMAL, &dummy);
1991 if (declarator == NULL)
1992 {
1993 if (omp_declare_simd_clauses.exists ())
1994 c_finish_omp_declare_simd (parser, NULL_TREE, NULL_TREE,
1995 omp_declare_simd_clauses);
1996 if (oacc_routine_data)
1997 c_finish_oacc_routine (oacc_routine_data, NULL_TREE, false);
1998 c_parser_skip_to_end_of_block_or_statement (parser);
1999 return;
2000 }
2001 if (auto_type_p && declarator->kind != cdk_id)
2002 {
2003 error_at (here,
2004 "%<__auto_type%> requires a plain identifier"
2005 " as declarator");
2006 c_parser_skip_to_end_of_block_or_statement (parser);
2007 return;
2008 }
2009 if (c_parser_next_token_is (parser, CPP_EQ)
2010 || c_parser_next_token_is (parser, CPP_COMMA)
2011 || c_parser_next_token_is (parser, CPP_SEMICOLON)
2012 || c_parser_next_token_is_keyword (parser, RID_ASM)
2013 || c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)
2014 || c_parser_next_token_is_keyword (parser, RID_IN))
2015 {
2016 tree asm_name = NULL_TREE;
2017 tree postfix_attrs = NULL_TREE;
2018 if (!diagnosed_no_specs && !specs->declspecs_seen_p)
2019 {
2020 diagnosed_no_specs = true;
2021 pedwarn (here, 0, "data definition has no type or storage class");
2022 }
2023 /* Having seen a data definition, there cannot now be a
2024 function definition. */
2025 fndef_ok = false;
2026 if (c_parser_next_token_is_keyword (parser, RID_ASM))
2027 asm_name = c_parser_simple_asm_expr (parser);
2028 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
2029 {
2030 postfix_attrs = c_parser_attributes (parser);
2031 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
2032 {
2033 /* This means there is an attribute specifier after
2034 the declarator in a function definition. Provide
2035 some more information for the user. */
2036 error_at (here, "attributes should be specified before the "
2037 "declarator in a function definition");
2038 c_parser_skip_to_end_of_block_or_statement (parser);
2039 return;
2040 }
2041 }
2042 if (c_parser_next_token_is (parser, CPP_EQ))
2043 {
2044 tree d;
2045 struct c_expr init;
2046 location_t init_loc;
2047 c_parser_consume_token (parser);
2048 if (auto_type_p)
2049 {
2050 init_loc = c_parser_peek_token (parser)->location;
2051 rich_location richloc (line_table, init_loc);
2052 start_init (NULL_TREE, asm_name, global_bindings_p (), &richloc);
2053 /* A parameter is initialized, which is invalid. Don't
2054 attempt to instrument the initializer. */
2055 int flag_sanitize_save = flag_sanitize;
2056 if (nested && !empty_ok)
2057 flag_sanitize = 0;
2058 init = c_parser_expr_no_commas (parser, NULL);
2059 flag_sanitize = flag_sanitize_save;
2060 if (TREE_CODE (init.value) == COMPONENT_REF
2061 && DECL_C_BIT_FIELD (TREE_OPERAND (init.value, 1)))
2062 error_at (here,
2063 "%<__auto_type%> used with a bit-field"
2064 " initializer");
2065 init = convert_lvalue_to_rvalue (init_loc, init, true, true);
2066 tree init_type = TREE_TYPE (init.value);
2067 /* As with typeof, remove all qualifiers from atomic types. */
2068 if (init_type != error_mark_node && TYPE_ATOMIC (init_type))
2069 init_type
2070 = c_build_qualified_type (init_type, TYPE_UNQUALIFIED);
2071 bool vm_type = variably_modified_type_p (init_type,
2072 NULL_TREE);
2073 if (vm_type)
2074 init.value = save_expr (init.value);
2075 finish_init ();
2076 specs->typespec_kind = ctsk_typeof;
2077 specs->locations[cdw_typedef] = init_loc;
2078 specs->typedef_p = true;
2079 specs->type = init_type;
2080 if (vm_type)
2081 {
2082 bool maybe_const = true;
2083 tree type_expr = c_fully_fold (init.value, false,
2084 &maybe_const);
2085 specs->expr_const_operands &= maybe_const;
2086 if (specs->expr)
2087 specs->expr = build2 (COMPOUND_EXPR,
2088 TREE_TYPE (type_expr),
2089 specs->expr, type_expr);
2090 else
2091 specs->expr = type_expr;
2092 }
2093 d = start_decl (declarator, specs, true,
2094 chainon (postfix_attrs, all_prefix_attrs));
2095 if (!d)
2096 d = error_mark_node;
2097 if (omp_declare_simd_clauses.exists ())
2098 c_finish_omp_declare_simd (parser, d, NULL_TREE,
2099 omp_declare_simd_clauses);
2100 }
2101 else
2102 {
2103 /* The declaration of the variable is in effect while
2104 its initializer is parsed. */
2105 d = start_decl (declarator, specs, true,
2106 chainon (postfix_attrs, all_prefix_attrs));
2107 if (!d)
2108 d = error_mark_node;
2109 if (omp_declare_simd_clauses.exists ())
2110 c_finish_omp_declare_simd (parser, d, NULL_TREE,
2111 omp_declare_simd_clauses);
2112 init_loc = c_parser_peek_token (parser)->location;
2113 rich_location richloc (line_table, init_loc);
2114 start_init (d, asm_name, global_bindings_p (), &richloc);
2115 /* A parameter is initialized, which is invalid. Don't
2116 attempt to instrument the initializer. */
2117 int flag_sanitize_save = flag_sanitize;
2118 if (TREE_CODE (d) == PARM_DECL)
2119 flag_sanitize = 0;
2120 init = c_parser_initializer (parser);
2121 flag_sanitize = flag_sanitize_save;
2122 finish_init ();
2123 }
2124 if (oacc_routine_data)
2125 c_finish_oacc_routine (oacc_routine_data, d, false);
2126 if (d != error_mark_node)
2127 {
2128 maybe_warn_string_init (init_loc, TREE_TYPE (d), init);
2129 finish_decl (d, init_loc, init.value,
2130 init.original_type, asm_name);
2131 }
2132 }
2133 else
2134 {
2135 if (auto_type_p)
2136 {
2137 error_at (here,
2138 "%<__auto_type%> requires an initialized "
2139 "data declaration");
2140 c_parser_skip_to_end_of_block_or_statement (parser);
2141 return;
2142 }
2143 tree d = start_decl (declarator, specs, false,
2144 chainon (postfix_attrs,
2145 all_prefix_attrs));
2146 if (d
2147 && TREE_CODE (d) == FUNCTION_DECL
2148 && declarator->kind == cdk_function
2149 && DECL_ARGUMENTS (d) == NULL_TREE
2150 && DECL_INITIAL (d) == NULL_TREE)
2151 DECL_ARGUMENTS (d) = declarator->u.arg_info->parms;
2152 if (omp_declare_simd_clauses.exists ())
2153 {
2154 tree parms = NULL_TREE;
2155 if (d && TREE_CODE (d) == FUNCTION_DECL)
2156 {
2157 struct c_declarator *ce = declarator;
2158 while (ce != NULL)
2159 if (ce->kind == cdk_function)
2160 {
2161 parms = ce->u.arg_info->parms;
2162 break;
2163 }
2164 else
2165 ce = ce->declarator;
2166 }
2167 if (parms)
2168 temp_store_parm_decls (d, parms);
2169 c_finish_omp_declare_simd (parser, d, parms,
2170 omp_declare_simd_clauses);
2171 if (parms)
2172 temp_pop_parm_decls ();
2173 }
2174 if (oacc_routine_data)
2175 c_finish_oacc_routine (oacc_routine_data, d, false);
2176 if (d)
2177 finish_decl (d, UNKNOWN_LOCATION, NULL_TREE,
2178 NULL_TREE, asm_name);
2179
2180 if (c_parser_next_token_is_keyword (parser, RID_IN))
2181 {
2182 if (d)
2183 *objc_foreach_object_declaration = d;
2184 else
2185 *objc_foreach_object_declaration = error_mark_node;
2186 }
2187 }
2188 if (c_parser_next_token_is (parser, CPP_COMMA))
2189 {
2190 if (auto_type_p)
2191 {
2192 error_at (here,
2193 "%<__auto_type%> may only be used with"
2194 " a single declarator");
2195 c_parser_skip_to_end_of_block_or_statement (parser);
2196 return;
2197 }
2198 c_parser_consume_token (parser);
2199 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
2200 all_prefix_attrs = chainon (c_parser_attributes (parser),
2201 prefix_attrs);
2202 else
2203 all_prefix_attrs = prefix_attrs;
2204 continue;
2205 }
2206 else if (c_parser_next_token_is (parser, CPP_SEMICOLON))
2207 {
2208 c_parser_consume_token (parser);
2209 return;
2210 }
2211 else if (c_parser_next_token_is_keyword (parser, RID_IN))
2212 {
2213 /* This can only happen in Objective-C: we found the
2214 'in' that terminates the declaration inside an
2215 Objective-C foreach statement. Do not consume the
2216 token, so that the caller can use it to determine
2217 that this indeed is a foreach context. */
2218 return;
2219 }
2220 else
2221 {
2222 c_parser_error (parser, "expected %<,%> or %<;%>");
2223 c_parser_skip_to_end_of_block_or_statement (parser);
2224 return;
2225 }
2226 }
2227 else if (auto_type_p)
2228 {
2229 error_at (here,
2230 "%<__auto_type%> requires an initialized data declaration");
2231 c_parser_skip_to_end_of_block_or_statement (parser);
2232 return;
2233 }
2234 else if (!fndef_ok)
2235 {
2236 c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, "
2237 "%<asm%> or %<__attribute__%>");
2238 c_parser_skip_to_end_of_block_or_statement (parser);
2239 return;
2240 }
2241 /* Function definition (nested or otherwise). */
2242 if (nested)
2243 {
2244 pedwarn (here, OPT_Wpedantic, "ISO C forbids nested functions");
2245 c_push_function_context ();
2246 }
2247 if (!start_function (specs, declarator, all_prefix_attrs))
2248 {
2249 /* At this point we've consumed:
2250 declaration-specifiers declarator
2251 and the next token isn't CPP_EQ, CPP_COMMA, CPP_SEMICOLON,
2252 RID_ASM, RID_ATTRIBUTE, or RID_IN,
2253 but the
2254 declaration-specifiers declarator
2255 aren't grokkable as a function definition, so we have
2256 an error. */
2257 gcc_assert (!c_parser_next_token_is (parser, CPP_SEMICOLON));
2258 if (c_parser_next_token_starts_declspecs (parser))
2259 {
2260 /* If we have
2261 declaration-specifiers declarator decl-specs
2262 then assume we have a missing semicolon, which would
2263 give us:
2264 declaration-specifiers declarator decl-specs
2265 ^
2266 ;
2267 <~~~~~~~~~ declaration ~~~~~~~~~~>
2268 Use c_parser_require to get an error with a fix-it hint. */
2269 c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>");
2270 parser->error = false;
2271 }
2272 else
2273 {
2274 /* This can appear in many cases looking nothing like a
2275 function definition, so we don't give a more specific
2276 error suggesting there was one. */
2277 c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, %<asm%> "
2278 "or %<__attribute__%>");
2279 }
2280 if (nested)
2281 c_pop_function_context ();
2282 break;
2283 }
2284
2285 if (DECL_DECLARED_INLINE_P (current_function_decl))
2286 tv = TV_PARSE_INLINE;
2287 else
2288 tv = TV_PARSE_FUNC;
2289 auto_timevar at (g_timer, tv);
2290
2291 /* Parse old-style parameter declarations. ??? Attributes are
2292 not allowed to start declaration specifiers here because of a
2293 syntax conflict between a function declaration with attribute
2294 suffix and a function definition with an attribute prefix on
2295 first old-style parameter declaration. Following the old
2296 parser, they are not accepted on subsequent old-style
2297 parameter declarations either. However, there is no
2298 ambiguity after the first declaration, nor indeed on the
2299 first as long as we don't allow postfix attributes after a
2300 declarator with a nonempty identifier list in a definition;
2301 and postfix attributes have never been accepted here in
2302 function definitions either. */
2303 while (c_parser_next_token_is_not (parser, CPP_EOF)
2304 && c_parser_next_token_is_not (parser, CPP_OPEN_BRACE))
2305 c_parser_declaration_or_fndef (parser, false, false, false,
2306 true, false, NULL, vNULL);
2307 store_parm_decls ();
2308 if (omp_declare_simd_clauses.exists ())
2309 c_finish_omp_declare_simd (parser, current_function_decl, NULL_TREE,
2310 omp_declare_simd_clauses);
2311 if (oacc_routine_data)
2312 c_finish_oacc_routine (oacc_routine_data, current_function_decl, true);
2313 DECL_STRUCT_FUNCTION (current_function_decl)->function_start_locus
2314 = c_parser_peek_token (parser)->location;
2315
2316 /* If the definition was marked with __GIMPLE then parse the
2317 function body as GIMPLE. */
2318 if (specs->gimple_p)
2319 {
2320 cfun->pass_startwith = specs->gimple_or_rtl_pass;
2321 bool saved = in_late_binary_op;
2322 in_late_binary_op = true;
2323 c_parser_parse_gimple_body (parser);
2324 in_late_binary_op = saved;
2325 }
2326 /* Similarly, if it was marked with __RTL, use the RTL parser now,
2327 consuming the function body. */
2328 else if (specs->rtl_p)
2329 {
2330 c_parser_parse_rtl_body (parser, specs->gimple_or_rtl_pass);
2331
2332 /* Normally, store_parm_decls sets next_is_function_body,
2333 anticipating a function body. We need a push_scope/pop_scope
2334 pair to flush out this state, or subsequent function parsing
2335 will go wrong. */
2336 push_scope ();
2337 pop_scope ();
2338
2339 finish_function ();
2340 return;
2341 }
2342 else
2343 fnbody = c_parser_compound_statement (parser);
2344 tree fndecl = current_function_decl;
2345 if (nested)
2346 {
2347 tree decl = current_function_decl;
2348 /* Mark nested functions as needing static-chain initially.
2349 lower_nested_functions will recompute it but the
2350 DECL_STATIC_CHAIN flag is also used before that happens,
2351 by initializer_constant_valid_p. See gcc.dg/nested-fn-2.c. */
2352 DECL_STATIC_CHAIN (decl) = 1;
2353 add_stmt (fnbody);
2354 finish_function ();
2355 c_pop_function_context ();
2356 add_stmt (build_stmt (DECL_SOURCE_LOCATION (decl), DECL_EXPR, decl));
2357 }
2358 else
2359 {
2360 if (fnbody)
2361 add_stmt (fnbody);
2362 finish_function ();
2363 }
2364 /* Get rid of the empty stmt list for GIMPLE. */
2365 if (specs->gimple_p)
2366 DECL_SAVED_TREE (fndecl) = NULL_TREE;
2367
2368 break;
2369 }
2370 }
2371
2372 /* Parse an asm-definition (asm() outside a function body). This is a
2373 GNU extension.
2374
2375 asm-definition:
2376 simple-asm-expr ;
2377 */
2378
2379 static void
c_parser_asm_definition(c_parser * parser)2380 c_parser_asm_definition (c_parser *parser)
2381 {
2382 tree asm_str = c_parser_simple_asm_expr (parser);
2383 if (asm_str)
2384 symtab->finalize_toplevel_asm (asm_str);
2385 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
2386 }
2387
2388 /* Parse a static assertion (C11 6.7.10).
2389
2390 static_assert-declaration:
2391 static_assert-declaration-no-semi ;
2392 */
2393
2394 static void
c_parser_static_assert_declaration(c_parser * parser)2395 c_parser_static_assert_declaration (c_parser *parser)
2396 {
2397 c_parser_static_assert_declaration_no_semi (parser);
2398 if (parser->error
2399 || !c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
2400 c_parser_skip_to_end_of_block_or_statement (parser);
2401 }
2402
2403 /* Parse a static assertion (C11 6.7.10), without the trailing
2404 semicolon.
2405
2406 static_assert-declaration-no-semi:
2407 _Static_assert ( constant-expression , string-literal )
2408 */
2409
2410 static void
c_parser_static_assert_declaration_no_semi(c_parser * parser)2411 c_parser_static_assert_declaration_no_semi (c_parser *parser)
2412 {
2413 location_t assert_loc, value_loc;
2414 tree value;
2415 tree string;
2416
2417 gcc_assert (c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT));
2418 assert_loc = c_parser_peek_token (parser)->location;
2419 if (flag_isoc99)
2420 pedwarn_c99 (assert_loc, OPT_Wpedantic,
2421 "ISO C99 does not support %<_Static_assert%>");
2422 else
2423 pedwarn_c99 (assert_loc, OPT_Wpedantic,
2424 "ISO C90 does not support %<_Static_assert%>");
2425 c_parser_consume_token (parser);
2426 matching_parens parens;
2427 if (!parens.require_open (parser))
2428 return;
2429 location_t value_tok_loc = c_parser_peek_token (parser)->location;
2430 value = c_parser_expr_no_commas (parser, NULL).value;
2431 value_loc = EXPR_LOC_OR_LOC (value, value_tok_loc);
2432 parser->lex_untranslated_string = true;
2433 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
2434 {
2435 parser->lex_untranslated_string = false;
2436 return;
2437 }
2438 switch (c_parser_peek_token (parser)->type)
2439 {
2440 case CPP_STRING:
2441 case CPP_STRING16:
2442 case CPP_STRING32:
2443 case CPP_WSTRING:
2444 case CPP_UTF8STRING:
2445 string = c_parser_peek_token (parser)->value;
2446 c_parser_consume_token (parser);
2447 parser->lex_untranslated_string = false;
2448 break;
2449 default:
2450 c_parser_error (parser, "expected string literal");
2451 parser->lex_untranslated_string = false;
2452 return;
2453 }
2454 parens.require_close (parser);
2455
2456 if (!INTEGRAL_TYPE_P (TREE_TYPE (value)))
2457 {
2458 error_at (value_loc, "expression in static assertion is not an integer");
2459 return;
2460 }
2461 if (TREE_CODE (value) != INTEGER_CST)
2462 {
2463 value = c_fully_fold (value, false, NULL);
2464 /* Strip no-op conversions. */
2465 STRIP_TYPE_NOPS (value);
2466 if (TREE_CODE (value) == INTEGER_CST)
2467 pedwarn (value_loc, OPT_Wpedantic, "expression in static assertion "
2468 "is not an integer constant expression");
2469 }
2470 if (TREE_CODE (value) != INTEGER_CST)
2471 {
2472 error_at (value_loc, "expression in static assertion is not constant");
2473 return;
2474 }
2475 constant_expression_warning (value);
2476 if (integer_zerop (value))
2477 error_at (assert_loc, "static assertion failed: %E", string);
2478 }
2479
2480 /* Parse some declaration specifiers (possibly none) (C90 6.5, C99
2481 6.7, C11 6.7), adding them to SPECS (which may already include some).
2482 Storage class specifiers are accepted iff SCSPEC_OK; type
2483 specifiers are accepted iff TYPESPEC_OK; alignment specifiers are
2484 accepted iff ALIGNSPEC_OK; attributes are accepted at the start
2485 iff START_ATTR_OK; __auto_type is accepted iff AUTO_TYPE_OK.
2486
2487 declaration-specifiers:
2488 storage-class-specifier declaration-specifiers[opt]
2489 type-specifier declaration-specifiers[opt]
2490 type-qualifier declaration-specifiers[opt]
2491 function-specifier declaration-specifiers[opt]
2492 alignment-specifier declaration-specifiers[opt]
2493
2494 Function specifiers (inline) are from C99, and are currently
2495 handled as storage class specifiers, as is __thread. Alignment
2496 specifiers are from C11.
2497
2498 C90 6.5.1, C99 6.7.1, C11 6.7.1:
2499 storage-class-specifier:
2500 typedef
2501 extern
2502 static
2503 auto
2504 register
2505 _Thread_local
2506
2507 (_Thread_local is new in C11.)
2508
2509 C99 6.7.4, C11 6.7.4:
2510 function-specifier:
2511 inline
2512 _Noreturn
2513
2514 (_Noreturn is new in C11.)
2515
2516 C90 6.5.2, C99 6.7.2, C11 6.7.2:
2517 type-specifier:
2518 void
2519 char
2520 short
2521 int
2522 long
2523 float
2524 double
2525 signed
2526 unsigned
2527 _Bool
2528 _Complex
2529 [_Imaginary removed in C99 TC2]
2530 struct-or-union-specifier
2531 enum-specifier
2532 typedef-name
2533 atomic-type-specifier
2534
2535 (_Bool and _Complex are new in C99.)
2536 (atomic-type-specifier is new in C11.)
2537
2538 C90 6.5.3, C99 6.7.3, C11 6.7.3:
2539
2540 type-qualifier:
2541 const
2542 restrict
2543 volatile
2544 address-space-qualifier
2545 _Atomic
2546
2547 (restrict is new in C99.)
2548 (_Atomic is new in C11.)
2549
2550 GNU extensions:
2551
2552 declaration-specifiers:
2553 attributes declaration-specifiers[opt]
2554
2555 type-qualifier:
2556 address-space
2557
2558 address-space:
2559 identifier recognized by the target
2560
2561 storage-class-specifier:
2562 __thread
2563
2564 type-specifier:
2565 typeof-specifier
2566 __auto_type
2567 __intN
2568 _Decimal32
2569 _Decimal64
2570 _Decimal128
2571 _Fract
2572 _Accum
2573 _Sat
2574
2575 (_Fract, _Accum, and _Sat are new from ISO/IEC DTR 18037:
2576 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1169.pdf)
2577
2578 atomic-type-specifier
2579 _Atomic ( type-name )
2580
2581 Objective-C:
2582
2583 type-specifier:
2584 class-name objc-protocol-refs[opt]
2585 typedef-name objc-protocol-refs
2586 objc-protocol-refs
2587 */
2588
2589 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,enum c_lookahead_kind la)2590 c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
2591 bool scspec_ok, bool typespec_ok, bool start_attr_ok,
2592 bool alignspec_ok, bool auto_type_ok,
2593 enum c_lookahead_kind la)
2594 {
2595 bool attrs_ok = start_attr_ok;
2596 bool seen_type = specs->typespec_kind != ctsk_none;
2597
2598 if (!typespec_ok)
2599 gcc_assert (la == cla_prefer_id);
2600
2601 while (c_parser_next_token_is (parser, CPP_NAME)
2602 || c_parser_next_token_is (parser, CPP_KEYWORD)
2603 || (c_dialect_objc () && c_parser_next_token_is (parser, CPP_LESS)))
2604 {
2605 struct c_typespec t;
2606 tree attrs;
2607 tree align;
2608 location_t loc = c_parser_peek_token (parser)->location;
2609
2610 /* If we cannot accept a type, exit if the next token must start
2611 one. Also, if we already have seen a tagged definition,
2612 a typename would be an error anyway and likely the user
2613 has simply forgotten a semicolon, so we exit. */
2614 if ((!typespec_ok || specs->typespec_kind == ctsk_tagdef)
2615 && c_parser_next_tokens_start_typename (parser, la)
2616 && !c_parser_next_token_is_qualifier (parser)
2617 && !c_parser_next_token_is_keyword (parser, RID_ALIGNAS))
2618 break;
2619
2620 if (c_parser_next_token_is (parser, CPP_NAME))
2621 {
2622 c_token *name_token = c_parser_peek_token (parser);
2623 tree value = name_token->value;
2624 c_id_kind kind = name_token->id_kind;
2625
2626 if (kind == C_ID_ADDRSPACE)
2627 {
2628 addr_space_t as
2629 = name_token->keyword - RID_FIRST_ADDR_SPACE;
2630 declspecs_add_addrspace (name_token->location, specs, as);
2631 c_parser_consume_token (parser);
2632 attrs_ok = true;
2633 continue;
2634 }
2635
2636 gcc_assert (!c_parser_next_token_is_qualifier (parser));
2637
2638 /* If we cannot accept a type, and the next token must start one,
2639 exit. Do the same if we already have seen a tagged definition,
2640 since it would be an error anyway and likely the user has simply
2641 forgotten a semicolon. */
2642 if (seen_type || !c_parser_next_tokens_start_typename (parser, la))
2643 break;
2644
2645 /* Now at an unknown typename (C_ID_ID), a C_ID_TYPENAME or
2646 a C_ID_CLASSNAME. */
2647 c_parser_consume_token (parser);
2648 seen_type = true;
2649 attrs_ok = true;
2650 if (kind == C_ID_ID)
2651 {
2652 error_at (loc, "unknown type name %qE", value);
2653 t.kind = ctsk_typedef;
2654 t.spec = error_mark_node;
2655 }
2656 else if (kind == C_ID_TYPENAME
2657 && (!c_dialect_objc ()
2658 || c_parser_next_token_is_not (parser, CPP_LESS)))
2659 {
2660 t.kind = ctsk_typedef;
2661 /* For a typedef name, record the meaning, not the name.
2662 In case of 'foo foo, bar;'. */
2663 t.spec = lookup_name (value);
2664 }
2665 else
2666 {
2667 tree proto = NULL_TREE;
2668 gcc_assert (c_dialect_objc ());
2669 t.kind = ctsk_objc;
2670 if (c_parser_next_token_is (parser, CPP_LESS))
2671 proto = c_parser_objc_protocol_refs (parser);
2672 t.spec = objc_get_protocol_qualified_type (value, proto);
2673 }
2674 t.expr = NULL_TREE;
2675 t.expr_const_operands = true;
2676 declspecs_add_type (name_token->location, specs, t);
2677 continue;
2678 }
2679 if (c_parser_next_token_is (parser, CPP_LESS))
2680 {
2681 /* Make "<SomeProtocol>" equivalent to "id <SomeProtocol>" -
2682 nisse@lysator.liu.se. */
2683 tree proto;
2684 gcc_assert (c_dialect_objc ());
2685 if (!typespec_ok || seen_type)
2686 break;
2687 proto = c_parser_objc_protocol_refs (parser);
2688 t.kind = ctsk_objc;
2689 t.spec = objc_get_protocol_qualified_type (NULL_TREE, proto);
2690 t.expr = NULL_TREE;
2691 t.expr_const_operands = true;
2692 declspecs_add_type (loc, specs, t);
2693 continue;
2694 }
2695 gcc_assert (c_parser_next_token_is (parser, CPP_KEYWORD));
2696 switch (c_parser_peek_token (parser)->keyword)
2697 {
2698 case RID_STATIC:
2699 case RID_EXTERN:
2700 case RID_REGISTER:
2701 case RID_TYPEDEF:
2702 case RID_INLINE:
2703 case RID_NORETURN:
2704 case RID_AUTO:
2705 case RID_THREAD:
2706 if (!scspec_ok)
2707 goto out;
2708 attrs_ok = true;
2709 /* TODO: Distinguish between function specifiers (inline, noreturn)
2710 and storage class specifiers, either here or in
2711 declspecs_add_scspec. */
2712 declspecs_add_scspec (loc, specs,
2713 c_parser_peek_token (parser)->value);
2714 c_parser_consume_token (parser);
2715 break;
2716 case RID_AUTO_TYPE:
2717 if (!auto_type_ok)
2718 goto out;
2719 /* Fall through. */
2720 case RID_UNSIGNED:
2721 case RID_LONG:
2722 case RID_SHORT:
2723 case RID_SIGNED:
2724 case RID_COMPLEX:
2725 case RID_INT:
2726 case RID_CHAR:
2727 case RID_FLOAT:
2728 case RID_DOUBLE:
2729 case RID_VOID:
2730 case RID_DFLOAT32:
2731 case RID_DFLOAT64:
2732 case RID_DFLOAT128:
2733 CASE_RID_FLOATN_NX:
2734 case RID_BOOL:
2735 case RID_FRACT:
2736 case RID_ACCUM:
2737 case RID_SAT:
2738 case RID_INT_N_0:
2739 case RID_INT_N_1:
2740 case RID_INT_N_2:
2741 case RID_INT_N_3:
2742 if (!typespec_ok)
2743 goto out;
2744 attrs_ok = true;
2745 seen_type = true;
2746 if (c_dialect_objc ())
2747 parser->objc_need_raw_identifier = true;
2748 t.kind = ctsk_resword;
2749 t.spec = c_parser_peek_token (parser)->value;
2750 t.expr = NULL_TREE;
2751 t.expr_const_operands = true;
2752 declspecs_add_type (loc, specs, t);
2753 c_parser_consume_token (parser);
2754 break;
2755 case RID_ENUM:
2756 if (!typespec_ok)
2757 goto out;
2758 attrs_ok = true;
2759 seen_type = true;
2760 t = c_parser_enum_specifier (parser);
2761 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, t.spec);
2762 declspecs_add_type (loc, specs, t);
2763 break;
2764 case RID_STRUCT:
2765 case RID_UNION:
2766 if (!typespec_ok)
2767 goto out;
2768 attrs_ok = true;
2769 seen_type = true;
2770 t = c_parser_struct_or_union_specifier (parser);
2771 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, t.spec);
2772 declspecs_add_type (loc, specs, t);
2773 break;
2774 case RID_TYPEOF:
2775 /* ??? The old parser rejected typeof after other type
2776 specifiers, but is a syntax error the best way of
2777 handling this? */
2778 if (!typespec_ok || seen_type)
2779 goto out;
2780 attrs_ok = true;
2781 seen_type = true;
2782 t = c_parser_typeof_specifier (parser);
2783 declspecs_add_type (loc, specs, t);
2784 break;
2785 case RID_ATOMIC:
2786 /* C parser handling of Objective-C constructs needs
2787 checking for correct lvalue-to-rvalue conversions, and
2788 the code in build_modify_expr handling various
2789 Objective-C cases, and that in build_unary_op handling
2790 Objective-C cases for increment / decrement, also needs
2791 updating; uses of TYPE_MAIN_VARIANT in objc_compare_types
2792 and objc_types_are_equivalent may also need updates. */
2793 if (c_dialect_objc ())
2794 sorry ("%<_Atomic%> in Objective-C");
2795 if (flag_isoc99)
2796 pedwarn_c99 (loc, OPT_Wpedantic,
2797 "ISO C99 does not support the %<_Atomic%> qualifier");
2798 else
2799 pedwarn_c99 (loc, OPT_Wpedantic,
2800 "ISO C90 does not support the %<_Atomic%> qualifier");
2801 attrs_ok = true;
2802 tree value;
2803 value = c_parser_peek_token (parser)->value;
2804 c_parser_consume_token (parser);
2805 if (typespec_ok && c_parser_next_token_is (parser, CPP_OPEN_PAREN))
2806 {
2807 /* _Atomic ( type-name ). */
2808 seen_type = true;
2809 c_parser_consume_token (parser);
2810 struct c_type_name *type = c_parser_type_name (parser);
2811 t.kind = ctsk_typeof;
2812 t.spec = error_mark_node;
2813 t.expr = NULL_TREE;
2814 t.expr_const_operands = true;
2815 if (type != NULL)
2816 t.spec = groktypename (type, &t.expr,
2817 &t.expr_const_operands);
2818 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
2819 "expected %<)%>");
2820 if (t.spec != error_mark_node)
2821 {
2822 if (TREE_CODE (t.spec) == ARRAY_TYPE)
2823 error_at (loc, "%<_Atomic%>-qualified array type");
2824 else if (TREE_CODE (t.spec) == FUNCTION_TYPE)
2825 error_at (loc, "%<_Atomic%>-qualified function type");
2826 else if (TYPE_QUALS (t.spec) != TYPE_UNQUALIFIED)
2827 error_at (loc, "%<_Atomic%> applied to a qualified type");
2828 else
2829 t.spec = c_build_qualified_type (t.spec, TYPE_QUAL_ATOMIC);
2830 }
2831 declspecs_add_type (loc, specs, t);
2832 }
2833 else
2834 declspecs_add_qual (loc, specs, value);
2835 break;
2836 case RID_CONST:
2837 case RID_VOLATILE:
2838 case RID_RESTRICT:
2839 attrs_ok = true;
2840 declspecs_add_qual (loc, specs, c_parser_peek_token (parser)->value);
2841 c_parser_consume_token (parser);
2842 break;
2843 case RID_ATTRIBUTE:
2844 if (!attrs_ok)
2845 goto out;
2846 attrs = c_parser_attributes (parser);
2847 declspecs_add_attrs (loc, specs, attrs);
2848 break;
2849 case RID_ALIGNAS:
2850 if (!alignspec_ok)
2851 goto out;
2852 align = c_parser_alignas_specifier (parser);
2853 declspecs_add_alignas (loc, specs, align);
2854 break;
2855 case RID_GIMPLE:
2856 if (! flag_gimple)
2857 error_at (loc, "%<__GIMPLE%> only valid with -fgimple");
2858 c_parser_consume_token (parser);
2859 specs->gimple_p = true;
2860 specs->locations[cdw_gimple] = loc;
2861 specs->gimple_or_rtl_pass = c_parser_gimple_or_rtl_pass_list (parser);
2862 break;
2863 case RID_RTL:
2864 c_parser_consume_token (parser);
2865 specs->rtl_p = true;
2866 specs->locations[cdw_rtl] = loc;
2867 specs->gimple_or_rtl_pass = c_parser_gimple_or_rtl_pass_list (parser);
2868 break;
2869 default:
2870 goto out;
2871 }
2872 }
2873 out: ;
2874 }
2875
2876 /* Parse an enum specifier (C90 6.5.2.2, C99 6.7.2.2, C11 6.7.2.2).
2877
2878 enum-specifier:
2879 enum attributes[opt] identifier[opt] { enumerator-list } attributes[opt]
2880 enum attributes[opt] identifier[opt] { enumerator-list , } attributes[opt]
2881 enum attributes[opt] identifier
2882
2883 The form with trailing comma is new in C99. The forms with
2884 attributes are GNU extensions. In GNU C, we accept any expression
2885 without commas in the syntax (assignment expressions, not just
2886 conditional expressions); assignment expressions will be diagnosed
2887 as non-constant.
2888
2889 enumerator-list:
2890 enumerator
2891 enumerator-list , enumerator
2892
2893 enumerator:
2894 enumeration-constant
2895 enumeration-constant = constant-expression
2896
2897 GNU Extensions:
2898
2899 enumerator:
2900 enumeration-constant attributes[opt]
2901 enumeration-constant attributes[opt] = constant-expression
2902
2903 */
2904
2905 static struct c_typespec
c_parser_enum_specifier(c_parser * parser)2906 c_parser_enum_specifier (c_parser *parser)
2907 {
2908 struct c_typespec ret;
2909 tree attrs;
2910 tree ident = NULL_TREE;
2911 location_t enum_loc;
2912 location_t ident_loc = UNKNOWN_LOCATION; /* Quiet warning. */
2913 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ENUM));
2914 c_parser_consume_token (parser);
2915 attrs = c_parser_attributes (parser);
2916 enum_loc = c_parser_peek_token (parser)->location;
2917 /* Set the location in case we create a decl now. */
2918 c_parser_set_source_position_from_token (c_parser_peek_token (parser));
2919 if (c_parser_next_token_is (parser, CPP_NAME))
2920 {
2921 ident = c_parser_peek_token (parser)->value;
2922 ident_loc = c_parser_peek_token (parser)->location;
2923 enum_loc = ident_loc;
2924 c_parser_consume_token (parser);
2925 }
2926 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
2927 {
2928 /* Parse an enum definition. */
2929 struct c_enum_contents the_enum;
2930 tree type;
2931 tree postfix_attrs;
2932 /* We chain the enumerators in reverse order, then put them in
2933 forward order at the end. */
2934 tree values;
2935 timevar_push (TV_PARSE_ENUM);
2936 type = start_enum (enum_loc, &the_enum, ident);
2937 values = NULL_TREE;
2938 c_parser_consume_token (parser);
2939 while (true)
2940 {
2941 tree enum_id;
2942 tree enum_value;
2943 tree enum_decl;
2944 bool seen_comma;
2945 c_token *token;
2946 location_t comma_loc = UNKNOWN_LOCATION; /* Quiet warning. */
2947 location_t decl_loc, value_loc;
2948 if (c_parser_next_token_is_not (parser, CPP_NAME))
2949 {
2950 /* Give a nicer error for "enum {}". */
2951 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)
2952 && !parser->error)
2953 {
2954 error_at (c_parser_peek_token (parser)->location,
2955 "empty enum is invalid");
2956 parser->error = true;
2957 }
2958 else
2959 c_parser_error (parser, "expected identifier");
2960 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
2961 values = error_mark_node;
2962 break;
2963 }
2964 token = c_parser_peek_token (parser);
2965 enum_id = token->value;
2966 /* Set the location in case we create a decl now. */
2967 c_parser_set_source_position_from_token (token);
2968 decl_loc = value_loc = token->location;
2969 c_parser_consume_token (parser);
2970 /* Parse any specified attributes. */
2971 tree enum_attrs = c_parser_attributes (parser);
2972 if (c_parser_next_token_is (parser, CPP_EQ))
2973 {
2974 c_parser_consume_token (parser);
2975 value_loc = c_parser_peek_token (parser)->location;
2976 enum_value = c_parser_expr_no_commas (parser, NULL).value;
2977 }
2978 else
2979 enum_value = NULL_TREE;
2980 enum_decl = build_enumerator (decl_loc, value_loc,
2981 &the_enum, enum_id, enum_value);
2982 if (enum_attrs)
2983 decl_attributes (&TREE_PURPOSE (enum_decl), enum_attrs, 0);
2984 TREE_CHAIN (enum_decl) = values;
2985 values = enum_decl;
2986 seen_comma = false;
2987 if (c_parser_next_token_is (parser, CPP_COMMA))
2988 {
2989 comma_loc = c_parser_peek_token (parser)->location;
2990 seen_comma = true;
2991 c_parser_consume_token (parser);
2992 }
2993 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
2994 {
2995 if (seen_comma)
2996 pedwarn_c90 (comma_loc, OPT_Wpedantic,
2997 "comma at end of enumerator list");
2998 c_parser_consume_token (parser);
2999 break;
3000 }
3001 if (!seen_comma)
3002 {
3003 c_parser_error (parser, "expected %<,%> or %<}%>");
3004 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
3005 values = error_mark_node;
3006 break;
3007 }
3008 }
3009 postfix_attrs = c_parser_attributes (parser);
3010 ret.spec = finish_enum (type, nreverse (values),
3011 chainon (attrs, postfix_attrs));
3012 ret.kind = ctsk_tagdef;
3013 ret.expr = NULL_TREE;
3014 ret.expr_const_operands = true;
3015 timevar_pop (TV_PARSE_ENUM);
3016 return ret;
3017 }
3018 else if (!ident)
3019 {
3020 c_parser_error (parser, "expected %<{%>");
3021 ret.spec = error_mark_node;
3022 ret.kind = ctsk_tagref;
3023 ret.expr = NULL_TREE;
3024 ret.expr_const_operands = true;
3025 return ret;
3026 }
3027 ret = parser_xref_tag (ident_loc, ENUMERAL_TYPE, ident);
3028 /* In ISO C, enumerated types can be referred to only if already
3029 defined. */
3030 if (pedantic && !COMPLETE_TYPE_P (ret.spec))
3031 {
3032 gcc_assert (ident);
3033 pedwarn (enum_loc, OPT_Wpedantic,
3034 "ISO C forbids forward references to %<enum%> types");
3035 }
3036 return ret;
3037 }
3038
3039 /* Parse a struct or union specifier (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1).
3040
3041 struct-or-union-specifier:
3042 struct-or-union attributes[opt] identifier[opt]
3043 { struct-contents } attributes[opt]
3044 struct-or-union attributes[opt] identifier
3045
3046 struct-contents:
3047 struct-declaration-list
3048
3049 struct-declaration-list:
3050 struct-declaration ;
3051 struct-declaration-list struct-declaration ;
3052
3053 GNU extensions:
3054
3055 struct-contents:
3056 empty
3057 struct-declaration
3058 struct-declaration-list struct-declaration
3059
3060 struct-declaration-list:
3061 struct-declaration-list ;
3062 ;
3063
3064 (Note that in the syntax here, unlike that in ISO C, the semicolons
3065 are included here rather than in struct-declaration, in order to
3066 describe the syntax with extra semicolons and missing semicolon at
3067 end.)
3068
3069 Objective-C:
3070
3071 struct-declaration-list:
3072 @defs ( class-name )
3073
3074 (Note this does not include a trailing semicolon, but can be
3075 followed by further declarations, and gets a pedwarn-if-pedantic
3076 when followed by a semicolon.) */
3077
3078 static struct c_typespec
c_parser_struct_or_union_specifier(c_parser * parser)3079 c_parser_struct_or_union_specifier (c_parser *parser)
3080 {
3081 struct c_typespec ret;
3082 tree attrs;
3083 tree ident = NULL_TREE;
3084 location_t struct_loc;
3085 location_t ident_loc = UNKNOWN_LOCATION;
3086 enum tree_code code;
3087 switch (c_parser_peek_token (parser)->keyword)
3088 {
3089 case RID_STRUCT:
3090 code = RECORD_TYPE;
3091 break;
3092 case RID_UNION:
3093 code = UNION_TYPE;
3094 break;
3095 default:
3096 gcc_unreachable ();
3097 }
3098 struct_loc = c_parser_peek_token (parser)->location;
3099 c_parser_consume_token (parser);
3100 attrs = c_parser_attributes (parser);
3101
3102 /* Set the location in case we create a decl now. */
3103 c_parser_set_source_position_from_token (c_parser_peek_token (parser));
3104
3105 if (c_parser_next_token_is (parser, CPP_NAME))
3106 {
3107 ident = c_parser_peek_token (parser)->value;
3108 ident_loc = c_parser_peek_token (parser)->location;
3109 struct_loc = ident_loc;
3110 c_parser_consume_token (parser);
3111 }
3112 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
3113 {
3114 /* Parse a struct or union definition. Start the scope of the
3115 tag before parsing components. */
3116 struct c_struct_parse_info *struct_info;
3117 tree type = start_struct (struct_loc, code, ident, &struct_info);
3118 tree postfix_attrs;
3119 /* We chain the components in reverse order, then put them in
3120 forward order at the end. Each struct-declaration may
3121 declare multiple components (comma-separated), so we must use
3122 chainon to join them, although when parsing each
3123 struct-declaration we can use TREE_CHAIN directly.
3124
3125 The theory behind all this is that there will be more
3126 semicolon separated fields than comma separated fields, and
3127 so we'll be minimizing the number of node traversals required
3128 by chainon. */
3129 tree contents;
3130 timevar_push (TV_PARSE_STRUCT);
3131 contents = NULL_TREE;
3132 c_parser_consume_token (parser);
3133 /* Handle the Objective-C @defs construct,
3134 e.g. foo(sizeof(struct{ @defs(ClassName) }));. */
3135 if (c_parser_next_token_is_keyword (parser, RID_AT_DEFS))
3136 {
3137 tree name;
3138 gcc_assert (c_dialect_objc ());
3139 c_parser_consume_token (parser);
3140 matching_parens parens;
3141 if (!parens.require_open (parser))
3142 goto end_at_defs;
3143 if (c_parser_next_token_is (parser, CPP_NAME)
3144 && c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME)
3145 {
3146 name = c_parser_peek_token (parser)->value;
3147 c_parser_consume_token (parser);
3148 }
3149 else
3150 {
3151 c_parser_error (parser, "expected class name");
3152 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
3153 goto end_at_defs;
3154 }
3155 parens.skip_until_found_close (parser);
3156 contents = nreverse (objc_get_class_ivars (name));
3157 }
3158 end_at_defs:
3159 /* Parse the struct-declarations and semicolons. Problems with
3160 semicolons are diagnosed here; empty structures are diagnosed
3161 elsewhere. */
3162 while (true)
3163 {
3164 tree decls;
3165 /* Parse any stray semicolon. */
3166 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
3167 {
3168 location_t semicolon_loc
3169 = c_parser_peek_token (parser)->location;
3170 gcc_rich_location richloc (semicolon_loc);
3171 richloc.add_fixit_remove ();
3172 pedwarn (&richloc, OPT_Wpedantic,
3173 "extra semicolon in struct or union specified");
3174 c_parser_consume_token (parser);
3175 continue;
3176 }
3177 /* Stop if at the end of the struct or union contents. */
3178 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3179 {
3180 c_parser_consume_token (parser);
3181 break;
3182 }
3183 /* Accept #pragmas at struct scope. */
3184 if (c_parser_next_token_is (parser, CPP_PRAGMA))
3185 {
3186 c_parser_pragma (parser, pragma_struct, NULL);
3187 continue;
3188 }
3189 /* Parse some comma-separated declarations, but not the
3190 trailing semicolon if any. */
3191 decls = c_parser_struct_declaration (parser);
3192 contents = chainon (decls, contents);
3193 /* If no semicolon follows, either we have a parse error or
3194 are at the end of the struct or union and should
3195 pedwarn. */
3196 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
3197 c_parser_consume_token (parser);
3198 else
3199 {
3200 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3201 pedwarn (c_parser_peek_token (parser)->location, 0,
3202 "no semicolon at end of struct or union");
3203 else if (parser->error
3204 || !c_parser_next_token_starts_declspecs (parser))
3205 {
3206 c_parser_error (parser, "expected %<;%>");
3207 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
3208 break;
3209 }
3210
3211 /* If we come here, we have already emitted an error
3212 for an expected `;', identifier or `(', and we also
3213 recovered already. Go on with the next field. */
3214 }
3215 }
3216 postfix_attrs = c_parser_attributes (parser);
3217 ret.spec = finish_struct (struct_loc, type, nreverse (contents),
3218 chainon (attrs, postfix_attrs), struct_info);
3219 ret.kind = ctsk_tagdef;
3220 ret.expr = NULL_TREE;
3221 ret.expr_const_operands = true;
3222 timevar_pop (TV_PARSE_STRUCT);
3223 return ret;
3224 }
3225 else if (!ident)
3226 {
3227 c_parser_error (parser, "expected %<{%>");
3228 ret.spec = error_mark_node;
3229 ret.kind = ctsk_tagref;
3230 ret.expr = NULL_TREE;
3231 ret.expr_const_operands = true;
3232 return ret;
3233 }
3234 ret = parser_xref_tag (ident_loc, code, ident);
3235 return ret;
3236 }
3237
3238 /* Parse a struct-declaration (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1),
3239 *without* the trailing semicolon.
3240
3241 struct-declaration:
3242 specifier-qualifier-list struct-declarator-list
3243 static_assert-declaration-no-semi
3244
3245 specifier-qualifier-list:
3246 type-specifier specifier-qualifier-list[opt]
3247 type-qualifier specifier-qualifier-list[opt]
3248 alignment-specifier specifier-qualifier-list[opt]
3249 attributes specifier-qualifier-list[opt]
3250
3251 struct-declarator-list:
3252 struct-declarator
3253 struct-declarator-list , attributes[opt] struct-declarator
3254
3255 struct-declarator:
3256 declarator attributes[opt]
3257 declarator[opt] : constant-expression attributes[opt]
3258
3259 GNU extensions:
3260
3261 struct-declaration:
3262 __extension__ struct-declaration
3263 specifier-qualifier-list
3264
3265 Unlike the ISO C syntax, semicolons are handled elsewhere. The use
3266 of attributes where shown is a GNU extension. In GNU C, we accept
3267 any expression without commas in the syntax (assignment
3268 expressions, not just conditional expressions); assignment
3269 expressions will be diagnosed as non-constant. */
3270
3271 static tree
c_parser_struct_declaration(c_parser * parser)3272 c_parser_struct_declaration (c_parser *parser)
3273 {
3274 struct c_declspecs *specs;
3275 tree prefix_attrs;
3276 tree all_prefix_attrs;
3277 tree decls;
3278 location_t decl_loc;
3279 if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
3280 {
3281 int ext;
3282 tree decl;
3283 ext = disable_extension_diagnostics ();
3284 c_parser_consume_token (parser);
3285 decl = c_parser_struct_declaration (parser);
3286 restore_extension_diagnostics (ext);
3287 return decl;
3288 }
3289 if (c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
3290 {
3291 c_parser_static_assert_declaration_no_semi (parser);
3292 return NULL_TREE;
3293 }
3294 specs = build_null_declspecs ();
3295 decl_loc = c_parser_peek_token (parser)->location;
3296 /* Strictly by the standard, we shouldn't allow _Alignas here,
3297 but it appears to have been intended to allow it there, so
3298 we're keeping it as it is until WG14 reaches a conclusion
3299 of N1731.
3300 <http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1731.pdf> */
3301 c_parser_declspecs (parser, specs, false, true, true,
3302 true, false, cla_nonabstract_decl);
3303 if (parser->error)
3304 return NULL_TREE;
3305 if (!specs->declspecs_seen_p)
3306 {
3307 c_parser_error (parser, "expected specifier-qualifier-list");
3308 return NULL_TREE;
3309 }
3310 finish_declspecs (specs);
3311 if (c_parser_next_token_is (parser, CPP_SEMICOLON)
3312 || c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3313 {
3314 tree ret;
3315 if (specs->typespec_kind == ctsk_none)
3316 {
3317 pedwarn (decl_loc, OPT_Wpedantic,
3318 "ISO C forbids member declarations with no members");
3319 shadow_tag_warned (specs, pedantic);
3320 ret = NULL_TREE;
3321 }
3322 else
3323 {
3324 /* Support for unnamed structs or unions as members of
3325 structs or unions (which is [a] useful and [b] supports
3326 MS P-SDK). */
3327 tree attrs = NULL;
3328
3329 ret = grokfield (c_parser_peek_token (parser)->location,
3330 build_id_declarator (NULL_TREE), specs,
3331 NULL_TREE, &attrs);
3332 if (ret)
3333 decl_attributes (&ret, attrs, 0);
3334 }
3335 return ret;
3336 }
3337
3338 /* Provide better error recovery. Note that a type name here is valid,
3339 and will be treated as a field name. */
3340 if (specs->typespec_kind == ctsk_tagdef
3341 && TREE_CODE (specs->type) != ENUMERAL_TYPE
3342 && c_parser_next_token_starts_declspecs (parser)
3343 && !c_parser_next_token_is (parser, CPP_NAME))
3344 {
3345 c_parser_error (parser, "expected %<;%>, identifier or %<(%>");
3346 parser->error = false;
3347 return NULL_TREE;
3348 }
3349
3350 pending_xref_error ();
3351 prefix_attrs = specs->attrs;
3352 all_prefix_attrs = prefix_attrs;
3353 specs->attrs = NULL_TREE;
3354 decls = NULL_TREE;
3355 while (true)
3356 {
3357 /* Declaring one or more declarators or un-named bit-fields. */
3358 struct c_declarator *declarator;
3359 bool dummy = false;
3360 if (c_parser_next_token_is (parser, CPP_COLON))
3361 declarator = build_id_declarator (NULL_TREE);
3362 else
3363 declarator = c_parser_declarator (parser,
3364 specs->typespec_kind != ctsk_none,
3365 C_DTR_NORMAL, &dummy);
3366 if (declarator == NULL)
3367 {
3368 c_parser_skip_to_end_of_block_or_statement (parser);
3369 break;
3370 }
3371 if (c_parser_next_token_is (parser, CPP_COLON)
3372 || c_parser_next_token_is (parser, CPP_COMMA)
3373 || c_parser_next_token_is (parser, CPP_SEMICOLON)
3374 || c_parser_next_token_is (parser, CPP_CLOSE_BRACE)
3375 || c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
3376 {
3377 tree postfix_attrs = NULL_TREE;
3378 tree width = NULL_TREE;
3379 tree d;
3380 if (c_parser_next_token_is (parser, CPP_COLON))
3381 {
3382 c_parser_consume_token (parser);
3383 width = c_parser_expr_no_commas (parser, NULL).value;
3384 }
3385 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
3386 postfix_attrs = c_parser_attributes (parser);
3387 d = grokfield (c_parser_peek_token (parser)->location,
3388 declarator, specs, width, &all_prefix_attrs);
3389 decl_attributes (&d, chainon (postfix_attrs,
3390 all_prefix_attrs), 0);
3391 DECL_CHAIN (d) = decls;
3392 decls = d;
3393 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
3394 all_prefix_attrs = chainon (c_parser_attributes (parser),
3395 prefix_attrs);
3396 else
3397 all_prefix_attrs = prefix_attrs;
3398 if (c_parser_next_token_is (parser, CPP_COMMA))
3399 c_parser_consume_token (parser);
3400 else if (c_parser_next_token_is (parser, CPP_SEMICOLON)
3401 || c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3402 {
3403 /* Semicolon consumed in caller. */
3404 break;
3405 }
3406 else
3407 {
3408 c_parser_error (parser, "expected %<,%>, %<;%> or %<}%>");
3409 break;
3410 }
3411 }
3412 else
3413 {
3414 c_parser_error (parser,
3415 "expected %<:%>, %<,%>, %<;%>, %<}%> or "
3416 "%<__attribute__%>");
3417 break;
3418 }
3419 }
3420 return decls;
3421 }
3422
3423 /* Parse a typeof specifier (a GNU extension).
3424
3425 typeof-specifier:
3426 typeof ( expression )
3427 typeof ( type-name )
3428 */
3429
3430 static struct c_typespec
c_parser_typeof_specifier(c_parser * parser)3431 c_parser_typeof_specifier (c_parser *parser)
3432 {
3433 struct c_typespec ret;
3434 ret.kind = ctsk_typeof;
3435 ret.spec = error_mark_node;
3436 ret.expr = NULL_TREE;
3437 ret.expr_const_operands = true;
3438 gcc_assert (c_parser_next_token_is_keyword (parser, RID_TYPEOF));
3439 c_parser_consume_token (parser);
3440 c_inhibit_evaluation_warnings++;
3441 in_typeof++;
3442 matching_parens parens;
3443 if (!parens.require_open (parser))
3444 {
3445 c_inhibit_evaluation_warnings--;
3446 in_typeof--;
3447 return ret;
3448 }
3449 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
3450 {
3451 struct c_type_name *type = c_parser_type_name (parser);
3452 c_inhibit_evaluation_warnings--;
3453 in_typeof--;
3454 if (type != NULL)
3455 {
3456 ret.spec = groktypename (type, &ret.expr, &ret.expr_const_operands);
3457 pop_maybe_used (variably_modified_type_p (ret.spec, NULL_TREE));
3458 }
3459 }
3460 else
3461 {
3462 bool was_vm;
3463 location_t here = c_parser_peek_token (parser)->location;
3464 struct c_expr expr = c_parser_expression (parser);
3465 c_inhibit_evaluation_warnings--;
3466 in_typeof--;
3467 if (TREE_CODE (expr.value) == COMPONENT_REF
3468 && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
3469 error_at (here, "%<typeof%> applied to a bit-field");
3470 mark_exp_read (expr.value);
3471 ret.spec = TREE_TYPE (expr.value);
3472 was_vm = variably_modified_type_p (ret.spec, NULL_TREE);
3473 /* This is returned with the type so that when the type is
3474 evaluated, this can be evaluated. */
3475 if (was_vm)
3476 ret.expr = c_fully_fold (expr.value, false, &ret.expr_const_operands);
3477 pop_maybe_used (was_vm);
3478 /* For use in macros such as those in <stdatomic.h>, remove all
3479 qualifiers from atomic types. (const can be an issue for more macros
3480 using typeof than just the <stdatomic.h> ones.) */
3481 if (ret.spec != error_mark_node && TYPE_ATOMIC (ret.spec))
3482 ret.spec = c_build_qualified_type (ret.spec, TYPE_UNQUALIFIED);
3483 }
3484 parens.skip_until_found_close (parser);
3485 return ret;
3486 }
3487
3488 /* Parse an alignment-specifier.
3489
3490 C11 6.7.5:
3491
3492 alignment-specifier:
3493 _Alignas ( type-name )
3494 _Alignas ( constant-expression )
3495 */
3496
3497 static tree
c_parser_alignas_specifier(c_parser * parser)3498 c_parser_alignas_specifier (c_parser * parser)
3499 {
3500 tree ret = error_mark_node;
3501 location_t loc = c_parser_peek_token (parser)->location;
3502 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ALIGNAS));
3503 c_parser_consume_token (parser);
3504 if (flag_isoc99)
3505 pedwarn_c99 (loc, OPT_Wpedantic,
3506 "ISO C99 does not support %<_Alignas%>");
3507 else
3508 pedwarn_c99 (loc, OPT_Wpedantic,
3509 "ISO C90 does not support %<_Alignas%>");
3510 matching_parens parens;
3511 if (!parens.require_open (parser))
3512 return ret;
3513 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
3514 {
3515 struct c_type_name *type = c_parser_type_name (parser);
3516 if (type != NULL)
3517 ret = c_sizeof_or_alignof_type (loc, groktypename (type, NULL, NULL),
3518 false, true, 1);
3519 }
3520 else
3521 ret = c_parser_expr_no_commas (parser, NULL).value;
3522 parens.skip_until_found_close (parser);
3523 return ret;
3524 }
3525
3526 /* Parse a declarator, possibly an abstract declarator (C90 6.5.4,
3527 6.5.5, C99 6.7.5, 6.7.6, C11 6.7.6, 6.7.7). If TYPE_SEEN_P then
3528 a typedef name may be redeclared; otherwise it may not. KIND
3529 indicates which kind of declarator is wanted. Returns a valid
3530 declarator except in the case of a syntax error in which case NULL is
3531 returned. *SEEN_ID is set to true if an identifier being declared is
3532 seen; this is used to diagnose bad forms of abstract array declarators
3533 and to determine whether an identifier list is syntactically permitted.
3534
3535 declarator:
3536 pointer[opt] direct-declarator
3537
3538 direct-declarator:
3539 identifier
3540 ( attributes[opt] declarator )
3541 direct-declarator array-declarator
3542 direct-declarator ( parameter-type-list )
3543 direct-declarator ( identifier-list[opt] )
3544
3545 pointer:
3546 * type-qualifier-list[opt]
3547 * type-qualifier-list[opt] pointer
3548
3549 type-qualifier-list:
3550 type-qualifier
3551 attributes
3552 type-qualifier-list type-qualifier
3553 type-qualifier-list attributes
3554
3555 array-declarator:
3556 [ type-qualifier-list[opt] assignment-expression[opt] ]
3557 [ static type-qualifier-list[opt] assignment-expression ]
3558 [ type-qualifier-list static assignment-expression ]
3559 [ type-qualifier-list[opt] * ]
3560
3561 parameter-type-list:
3562 parameter-list
3563 parameter-list , ...
3564
3565 parameter-list:
3566 parameter-declaration
3567 parameter-list , parameter-declaration
3568
3569 parameter-declaration:
3570 declaration-specifiers declarator attributes[opt]
3571 declaration-specifiers abstract-declarator[opt] attributes[opt]
3572
3573 identifier-list:
3574 identifier
3575 identifier-list , identifier
3576
3577 abstract-declarator:
3578 pointer
3579 pointer[opt] direct-abstract-declarator
3580
3581 direct-abstract-declarator:
3582 ( attributes[opt] abstract-declarator )
3583 direct-abstract-declarator[opt] array-declarator
3584 direct-abstract-declarator[opt] ( parameter-type-list[opt] )
3585
3586 GNU extensions:
3587
3588 direct-declarator:
3589 direct-declarator ( parameter-forward-declarations
3590 parameter-type-list[opt] )
3591
3592 direct-abstract-declarator:
3593 direct-abstract-declarator[opt] ( parameter-forward-declarations
3594 parameter-type-list[opt] )
3595
3596 parameter-forward-declarations:
3597 parameter-list ;
3598 parameter-forward-declarations parameter-list ;
3599
3600 The uses of attributes shown above are GNU extensions.
3601
3602 Some forms of array declarator are not included in C99 in the
3603 syntax for abstract declarators; these are disallowed elsewhere.
3604 This may be a defect (DR#289).
3605
3606 This function also accepts an omitted abstract declarator as being
3607 an abstract declarator, although not part of the formal syntax. */
3608
3609 struct c_declarator *
c_parser_declarator(c_parser * parser,bool type_seen_p,c_dtr_syn kind,bool * seen_id)3610 c_parser_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
3611 bool *seen_id)
3612 {
3613 /* Parse any initial pointer part. */
3614 if (c_parser_next_token_is (parser, CPP_MULT))
3615 {
3616 struct c_declspecs *quals_attrs = build_null_declspecs ();
3617 struct c_declarator *inner;
3618 c_parser_consume_token (parser);
3619 c_parser_declspecs (parser, quals_attrs, false, false, true,
3620 false, false, cla_prefer_id);
3621 inner = c_parser_declarator (parser, type_seen_p, kind, seen_id);
3622 if (inner == NULL)
3623 return NULL;
3624 else
3625 return make_pointer_declarator (quals_attrs, inner);
3626 }
3627 /* Now we have a direct declarator, direct abstract declarator or
3628 nothing (which counts as a direct abstract declarator here). */
3629 return c_parser_direct_declarator (parser, type_seen_p, kind, seen_id);
3630 }
3631
3632 /* Parse a direct declarator or direct abstract declarator; arguments
3633 as c_parser_declarator. */
3634
3635 static struct c_declarator *
c_parser_direct_declarator(c_parser * parser,bool type_seen_p,c_dtr_syn kind,bool * seen_id)3636 c_parser_direct_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
3637 bool *seen_id)
3638 {
3639 /* The direct declarator must start with an identifier (possibly
3640 omitted) or a parenthesized declarator (possibly abstract). In
3641 an ordinary declarator, initial parentheses must start a
3642 parenthesized declarator. In an abstract declarator or parameter
3643 declarator, they could start a parenthesized declarator or a
3644 parameter list. To tell which, the open parenthesis and any
3645 following attributes must be read. If a declaration specifier
3646 follows, then it is a parameter list; if the specifier is a
3647 typedef name, there might be an ambiguity about redeclaring it,
3648 which is resolved in the direction of treating it as a typedef
3649 name. If a close parenthesis follows, it is also an empty
3650 parameter list, as the syntax does not permit empty abstract
3651 declarators. Otherwise, it is a parenthesized declarator (in
3652 which case the analysis may be repeated inside it, recursively).
3653
3654 ??? There is an ambiguity in a parameter declaration "int
3655 (__attribute__((foo)) x)", where x is not a typedef name: it
3656 could be an abstract declarator for a function, or declare x with
3657 parentheses. The proper resolution of this ambiguity needs
3658 documenting. At present we follow an accident of the old
3659 parser's implementation, whereby the first parameter must have
3660 some declaration specifiers other than just attributes. Thus as
3661 a parameter declaration it is treated as a parenthesized
3662 parameter named x, and as an abstract declarator it is
3663 rejected.
3664
3665 ??? Also following the old parser, attributes inside an empty
3666 parameter list are ignored, making it a list not yielding a
3667 prototype, rather than giving an error or making it have one
3668 parameter with implicit type int.
3669
3670 ??? Also following the old parser, typedef names may be
3671 redeclared in declarators, but not Objective-C class names. */
3672
3673 if (kind != C_DTR_ABSTRACT
3674 && c_parser_next_token_is (parser, CPP_NAME)
3675 && ((type_seen_p
3676 && (c_parser_peek_token (parser)->id_kind == C_ID_TYPENAME
3677 || c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME))
3678 || c_parser_peek_token (parser)->id_kind == C_ID_ID))
3679 {
3680 struct c_declarator *inner
3681 = build_id_declarator (c_parser_peek_token (parser)->value);
3682 *seen_id = true;
3683 inner->id_loc = c_parser_peek_token (parser)->location;
3684 c_parser_consume_token (parser);
3685 return c_parser_direct_declarator_inner (parser, *seen_id, inner);
3686 }
3687
3688 if (kind != C_DTR_NORMAL
3689 && c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
3690 {
3691 struct c_declarator *inner = build_id_declarator (NULL_TREE);
3692 inner->id_loc = c_parser_peek_token (parser)->location;
3693 return c_parser_direct_declarator_inner (parser, *seen_id, inner);
3694 }
3695
3696 /* Either we are at the end of an abstract declarator, or we have
3697 parentheses. */
3698
3699 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
3700 {
3701 tree attrs;
3702 struct c_declarator *inner;
3703 c_parser_consume_token (parser);
3704 attrs = c_parser_attributes (parser);
3705 if (kind != C_DTR_NORMAL
3706 && (c_parser_next_token_starts_declspecs (parser)
3707 || c_parser_next_token_is (parser, CPP_CLOSE_PAREN)))
3708 {
3709 struct c_arg_info *args
3710 = c_parser_parms_declarator (parser, kind == C_DTR_NORMAL,
3711 attrs);
3712 if (args == NULL)
3713 return NULL;
3714 else
3715 {
3716 inner
3717 = build_function_declarator (args,
3718 build_id_declarator (NULL_TREE));
3719 return c_parser_direct_declarator_inner (parser, *seen_id,
3720 inner);
3721 }
3722 }
3723 /* A parenthesized declarator. */
3724 inner = c_parser_declarator (parser, type_seen_p, kind, seen_id);
3725 if (inner != NULL && attrs != NULL)
3726 inner = build_attrs_declarator (attrs, inner);
3727 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
3728 {
3729 c_parser_consume_token (parser);
3730 if (inner == NULL)
3731 return NULL;
3732 else
3733 return c_parser_direct_declarator_inner (parser, *seen_id, inner);
3734 }
3735 else
3736 {
3737 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
3738 "expected %<)%>");
3739 return NULL;
3740 }
3741 }
3742 else
3743 {
3744 if (kind == C_DTR_NORMAL)
3745 {
3746 c_parser_error (parser, "expected identifier or %<(%>");
3747 return NULL;
3748 }
3749 else
3750 return build_id_declarator (NULL_TREE);
3751 }
3752 }
3753
3754 /* Parse part of a direct declarator or direct abstract declarator,
3755 given that some (in INNER) has already been parsed; ID_PRESENT is
3756 true if an identifier is present, false for an abstract
3757 declarator. */
3758
3759 static struct c_declarator *
c_parser_direct_declarator_inner(c_parser * parser,bool id_present,struct c_declarator * inner)3760 c_parser_direct_declarator_inner (c_parser *parser, bool id_present,
3761 struct c_declarator *inner)
3762 {
3763 /* Parse a sequence of array declarators and parameter lists. */
3764 if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
3765 {
3766 location_t brace_loc = c_parser_peek_token (parser)->location;
3767 struct c_declarator *declarator;
3768 struct c_declspecs *quals_attrs = build_null_declspecs ();
3769 bool static_seen;
3770 bool star_seen;
3771 struct c_expr dimen;
3772 dimen.value = NULL_TREE;
3773 dimen.original_code = ERROR_MARK;
3774 dimen.original_type = NULL_TREE;
3775 c_parser_consume_token (parser);
3776 c_parser_declspecs (parser, quals_attrs, false, false, true,
3777 false, false, cla_prefer_id);
3778 static_seen = c_parser_next_token_is_keyword (parser, RID_STATIC);
3779 if (static_seen)
3780 c_parser_consume_token (parser);
3781 if (static_seen && !quals_attrs->declspecs_seen_p)
3782 c_parser_declspecs (parser, quals_attrs, false, false, true,
3783 false, false, cla_prefer_id);
3784 if (!quals_attrs->declspecs_seen_p)
3785 quals_attrs = NULL;
3786 /* If "static" is present, there must be an array dimension.
3787 Otherwise, there may be a dimension, "*", or no
3788 dimension. */
3789 if (static_seen)
3790 {
3791 star_seen = false;
3792 dimen = c_parser_expr_no_commas (parser, NULL);
3793 }
3794 else
3795 {
3796 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
3797 {
3798 dimen.value = NULL_TREE;
3799 star_seen = false;
3800 }
3801 else if (c_parser_next_token_is (parser, CPP_MULT))
3802 {
3803 if (c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_SQUARE)
3804 {
3805 dimen.value = NULL_TREE;
3806 star_seen = true;
3807 c_parser_consume_token (parser);
3808 }
3809 else
3810 {
3811 star_seen = false;
3812 dimen = c_parser_expr_no_commas (parser, NULL);
3813 }
3814 }
3815 else
3816 {
3817 star_seen = false;
3818 dimen = c_parser_expr_no_commas (parser, NULL);
3819 }
3820 }
3821 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
3822 c_parser_consume_token (parser);
3823 else
3824 {
3825 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
3826 "expected %<]%>");
3827 return NULL;
3828 }
3829 if (dimen.value)
3830 dimen = convert_lvalue_to_rvalue (brace_loc, dimen, true, true);
3831 declarator = build_array_declarator (brace_loc, dimen.value, quals_attrs,
3832 static_seen, star_seen);
3833 if (declarator == NULL)
3834 return NULL;
3835 inner = set_array_declarator_inner (declarator, inner);
3836 return c_parser_direct_declarator_inner (parser, id_present, inner);
3837 }
3838 else if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
3839 {
3840 tree attrs;
3841 struct c_arg_info *args;
3842 c_parser_consume_token (parser);
3843 attrs = c_parser_attributes (parser);
3844 args = c_parser_parms_declarator (parser, id_present, attrs);
3845 if (args == NULL)
3846 return NULL;
3847 else
3848 {
3849 inner = build_function_declarator (args, inner);
3850 return c_parser_direct_declarator_inner (parser, id_present, inner);
3851 }
3852 }
3853 return inner;
3854 }
3855
3856 /* Parse a parameter list or identifier list, including the closing
3857 parenthesis but not the opening one. ATTRS are the attributes at
3858 the start of the list. ID_LIST_OK is true if an identifier list is
3859 acceptable; such a list must not have attributes at the start. */
3860
3861 static struct c_arg_info *
c_parser_parms_declarator(c_parser * parser,bool id_list_ok,tree attrs)3862 c_parser_parms_declarator (c_parser *parser, bool id_list_ok, tree attrs)
3863 {
3864 push_scope ();
3865 declare_parm_level ();
3866 /* If the list starts with an identifier, it is an identifier list.
3867 Otherwise, it is either a prototype list or an empty list. */
3868 if (id_list_ok
3869 && !attrs
3870 && c_parser_next_token_is (parser, CPP_NAME)
3871 && c_parser_peek_token (parser)->id_kind == C_ID_ID
3872
3873 /* Look ahead to detect typos in type names. */
3874 && c_parser_peek_2nd_token (parser)->type != CPP_NAME
3875 && c_parser_peek_2nd_token (parser)->type != CPP_MULT
3876 && c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN
3877 && c_parser_peek_2nd_token (parser)->type != CPP_OPEN_SQUARE
3878 && c_parser_peek_2nd_token (parser)->type != CPP_KEYWORD)
3879 {
3880 tree list = NULL_TREE, *nextp = &list;
3881 while (c_parser_next_token_is (parser, CPP_NAME)
3882 && c_parser_peek_token (parser)->id_kind == C_ID_ID)
3883 {
3884 *nextp = build_tree_list (NULL_TREE,
3885 c_parser_peek_token (parser)->value);
3886 nextp = & TREE_CHAIN (*nextp);
3887 c_parser_consume_token (parser);
3888 if (c_parser_next_token_is_not (parser, CPP_COMMA))
3889 break;
3890 c_parser_consume_token (parser);
3891 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
3892 {
3893 c_parser_error (parser, "expected identifier");
3894 break;
3895 }
3896 }
3897 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
3898 {
3899 struct c_arg_info *ret = build_arg_info ();
3900 ret->types = list;
3901 c_parser_consume_token (parser);
3902 pop_scope ();
3903 return ret;
3904 }
3905 else
3906 {
3907 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
3908 "expected %<)%>");
3909 pop_scope ();
3910 return NULL;
3911 }
3912 }
3913 else
3914 {
3915 struct c_arg_info *ret = c_parser_parms_list_declarator (parser, attrs,
3916 NULL);
3917 pop_scope ();
3918 return ret;
3919 }
3920 }
3921
3922 /* Parse a parameter list (possibly empty), including the closing
3923 parenthesis but not the opening one. ATTRS are the attributes at
3924 the start of the list. EXPR is NULL or an expression that needs to
3925 be evaluated for the side effects of array size expressions in the
3926 parameters. */
3927
3928 static struct c_arg_info *
c_parser_parms_list_declarator(c_parser * parser,tree attrs,tree expr)3929 c_parser_parms_list_declarator (c_parser *parser, tree attrs, tree expr)
3930 {
3931 bool bad_parm = false;
3932
3933 /* ??? Following the old parser, forward parameter declarations may
3934 use abstract declarators, and if no real parameter declarations
3935 follow the forward declarations then this is not diagnosed. Also
3936 note as above that attributes are ignored as the only contents of
3937 the parentheses, or as the only contents after forward
3938 declarations. */
3939 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
3940 {
3941 struct c_arg_info *ret = build_arg_info ();
3942 c_parser_consume_token (parser);
3943 return ret;
3944 }
3945 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
3946 {
3947 struct c_arg_info *ret = build_arg_info ();
3948
3949 if (flag_allow_parameterless_variadic_functions)
3950 {
3951 /* F (...) is allowed. */
3952 ret->types = NULL_TREE;
3953 }
3954 else
3955 {
3956 /* Suppress -Wold-style-definition for this case. */
3957 ret->types = error_mark_node;
3958 error_at (c_parser_peek_token (parser)->location,
3959 "ISO C requires a named argument before %<...%>");
3960 }
3961 c_parser_consume_token (parser);
3962 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
3963 {
3964 c_parser_consume_token (parser);
3965 return ret;
3966 }
3967 else
3968 {
3969 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
3970 "expected %<)%>");
3971 return NULL;
3972 }
3973 }
3974 /* Nonempty list of parameters, either terminated with semicolon
3975 (forward declarations; recurse) or with close parenthesis (normal
3976 function) or with ", ... )" (variadic function). */
3977 while (true)
3978 {
3979 /* Parse a parameter. */
3980 struct c_parm *parm = c_parser_parameter_declaration (parser, attrs);
3981 attrs = NULL_TREE;
3982 if (parm == NULL)
3983 bad_parm = true;
3984 else
3985 push_parm_decl (parm, &expr);
3986 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
3987 {
3988 tree new_attrs;
3989 c_parser_consume_token (parser);
3990 mark_forward_parm_decls ();
3991 new_attrs = c_parser_attributes (parser);
3992 return c_parser_parms_list_declarator (parser, new_attrs, expr);
3993 }
3994 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
3995 {
3996 c_parser_consume_token (parser);
3997 if (bad_parm)
3998 return NULL;
3999 else
4000 return get_parm_info (false, expr);
4001 }
4002 if (!c_parser_require (parser, CPP_COMMA,
4003 "expected %<;%>, %<,%> or %<)%>",
4004 UNKNOWN_LOCATION, false))
4005 {
4006 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4007 return NULL;
4008 }
4009 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
4010 {
4011 c_parser_consume_token (parser);
4012 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4013 {
4014 c_parser_consume_token (parser);
4015 if (bad_parm)
4016 return NULL;
4017 else
4018 return get_parm_info (true, expr);
4019 }
4020 else
4021 {
4022 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4023 "expected %<)%>");
4024 return NULL;
4025 }
4026 }
4027 }
4028 }
4029
4030 /* Parse a parameter declaration. ATTRS are the attributes at the
4031 start of the declaration if it is the first parameter. */
4032
4033 static struct c_parm *
c_parser_parameter_declaration(c_parser * parser,tree attrs)4034 c_parser_parameter_declaration (c_parser *parser, tree attrs)
4035 {
4036 struct c_declspecs *specs;
4037 struct c_declarator *declarator;
4038 tree prefix_attrs;
4039 tree postfix_attrs = NULL_TREE;
4040 bool dummy = false;
4041
4042 /* Accept #pragmas between parameter declarations. */
4043 while (c_parser_next_token_is (parser, CPP_PRAGMA))
4044 c_parser_pragma (parser, pragma_param, NULL);
4045
4046 if (!c_parser_next_token_starts_declspecs (parser))
4047 {
4048 c_token *token = c_parser_peek_token (parser);
4049 if (parser->error)
4050 return NULL;
4051 c_parser_set_source_position_from_token (token);
4052 if (c_parser_next_tokens_start_typename (parser, cla_prefer_type))
4053 {
4054 name_hint hint = lookup_name_fuzzy (token->value,
4055 FUZZY_LOOKUP_TYPENAME,
4056 token->location);
4057 if (hint)
4058 {
4059 gcc_rich_location richloc (token->location);
4060 richloc.add_fixit_replace (hint.suggestion ());
4061 error_at (&richloc,
4062 "unknown type name %qE; did you mean %qs?",
4063 token->value, hint.suggestion ());
4064 }
4065 else
4066 error_at (token->location, "unknown type name %qE", token->value);
4067 parser->error = true;
4068 }
4069 /* ??? In some Objective-C cases '...' isn't applicable so there
4070 should be a different message. */
4071 else
4072 c_parser_error (parser,
4073 "expected declaration specifiers or %<...%>");
4074 c_parser_skip_to_end_of_parameter (parser);
4075 return NULL;
4076 }
4077
4078 location_t start_loc = c_parser_peek_token (parser)->location;
4079
4080 specs = build_null_declspecs ();
4081 if (attrs)
4082 {
4083 declspecs_add_attrs (input_location, specs, attrs);
4084 attrs = NULL_TREE;
4085 }
4086 c_parser_declspecs (parser, specs, true, true, true, true, false,
4087 cla_nonabstract_decl);
4088 finish_declspecs (specs);
4089 pending_xref_error ();
4090 prefix_attrs = specs->attrs;
4091 specs->attrs = NULL_TREE;
4092 declarator = c_parser_declarator (parser,
4093 specs->typespec_kind != ctsk_none,
4094 C_DTR_PARM, &dummy);
4095 if (declarator == NULL)
4096 {
4097 c_parser_skip_until_found (parser, CPP_COMMA, NULL);
4098 return NULL;
4099 }
4100 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
4101 postfix_attrs = c_parser_attributes (parser);
4102
4103 /* Generate a location for the parameter, ranging from the start of the
4104 initial token to the end of the final token.
4105
4106 If we have a identifier, then use it for the caret location, e.g.
4107
4108 extern int callee (int one, int (*two)(int, int), float three);
4109 ~~~~~~^~~~~~~~~~~~~~
4110
4111 otherwise, reuse the start location for the caret location e.g.:
4112
4113 extern int callee (int one, int (*)(int, int), float three);
4114 ^~~~~~~~~~~~~~~~~
4115 */
4116 location_t end_loc = parser->last_token_location;
4117
4118 /* Find any cdk_id declarator; determine if we have an identifier. */
4119 c_declarator *id_declarator = declarator;
4120 while (id_declarator && id_declarator->kind != cdk_id)
4121 id_declarator = id_declarator->declarator;
4122 location_t caret_loc = (id_declarator->u.id
4123 ? id_declarator->id_loc
4124 : start_loc);
4125 location_t param_loc = make_location (caret_loc, start_loc, end_loc);
4126
4127 return build_c_parm (specs, chainon (postfix_attrs, prefix_attrs),
4128 declarator, param_loc);
4129 }
4130
4131 /* Parse a string literal in an asm expression. It should not be
4132 translated, and wide string literals are an error although
4133 permitted by the syntax. This is a GNU extension.
4134
4135 asm-string-literal:
4136 string-literal
4137
4138 ??? At present, following the old parser, the caller needs to have
4139 set lex_untranslated_string to 1. It would be better to follow the
4140 C++ parser rather than using this kludge. */
4141
4142 static tree
c_parser_asm_string_literal(c_parser * parser)4143 c_parser_asm_string_literal (c_parser *parser)
4144 {
4145 tree str;
4146 int save_flag = warn_overlength_strings;
4147 warn_overlength_strings = 0;
4148 if (c_parser_next_token_is (parser, CPP_STRING))
4149 {
4150 str = c_parser_peek_token (parser)->value;
4151 c_parser_consume_token (parser);
4152 }
4153 else if (c_parser_next_token_is (parser, CPP_WSTRING))
4154 {
4155 error_at (c_parser_peek_token (parser)->location,
4156 "wide string literal in %<asm%>");
4157 str = build_string (1, "");
4158 c_parser_consume_token (parser);
4159 }
4160 else
4161 {
4162 c_parser_error (parser, "expected string literal");
4163 str = NULL_TREE;
4164 }
4165 warn_overlength_strings = save_flag;
4166 return str;
4167 }
4168
4169 /* Parse a simple asm expression. This is used in restricted
4170 contexts, where a full expression with inputs and outputs does not
4171 make sense. This is a GNU extension.
4172
4173 simple-asm-expr:
4174 asm ( asm-string-literal )
4175 */
4176
4177 static tree
c_parser_simple_asm_expr(c_parser * parser)4178 c_parser_simple_asm_expr (c_parser *parser)
4179 {
4180 tree str;
4181 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
4182 /* ??? Follow the C++ parser rather than using the
4183 lex_untranslated_string kludge. */
4184 parser->lex_untranslated_string = true;
4185 c_parser_consume_token (parser);
4186 matching_parens parens;
4187 if (!parens.require_open (parser))
4188 {
4189 parser->lex_untranslated_string = false;
4190 return NULL_TREE;
4191 }
4192 str = c_parser_asm_string_literal (parser);
4193 parser->lex_untranslated_string = false;
4194 if (!parens.require_close (parser))
4195 {
4196 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4197 return NULL_TREE;
4198 }
4199 return str;
4200 }
4201
4202 static tree
c_parser_attribute_any_word(c_parser * parser)4203 c_parser_attribute_any_word (c_parser *parser)
4204 {
4205 tree attr_name = NULL_TREE;
4206
4207 if (c_parser_next_token_is (parser, CPP_KEYWORD))
4208 {
4209 /* ??? See comment above about what keywords are accepted here. */
4210 bool ok;
4211 switch (c_parser_peek_token (parser)->keyword)
4212 {
4213 case RID_STATIC:
4214 case RID_UNSIGNED:
4215 case RID_LONG:
4216 case RID_CONST:
4217 case RID_EXTERN:
4218 case RID_REGISTER:
4219 case RID_TYPEDEF:
4220 case RID_SHORT:
4221 case RID_INLINE:
4222 case RID_NORETURN:
4223 case RID_VOLATILE:
4224 case RID_SIGNED:
4225 case RID_AUTO:
4226 case RID_RESTRICT:
4227 case RID_COMPLEX:
4228 case RID_THREAD:
4229 case RID_INT:
4230 case RID_CHAR:
4231 case RID_FLOAT:
4232 case RID_DOUBLE:
4233 case RID_VOID:
4234 case RID_DFLOAT32:
4235 case RID_DFLOAT64:
4236 case RID_DFLOAT128:
4237 CASE_RID_FLOATN_NX:
4238 case RID_BOOL:
4239 case RID_FRACT:
4240 case RID_ACCUM:
4241 case RID_SAT:
4242 case RID_TRANSACTION_ATOMIC:
4243 case RID_TRANSACTION_CANCEL:
4244 case RID_ATOMIC:
4245 case RID_AUTO_TYPE:
4246 case RID_INT_N_0:
4247 case RID_INT_N_1:
4248 case RID_INT_N_2:
4249 case RID_INT_N_3:
4250 ok = true;
4251 break;
4252 default:
4253 ok = false;
4254 break;
4255 }
4256 if (!ok)
4257 return NULL_TREE;
4258
4259 /* Accept __attribute__((__const)) as __attribute__((const)) etc. */
4260 attr_name = ridpointers[(int) c_parser_peek_token (parser)->keyword];
4261 }
4262 else if (c_parser_next_token_is (parser, CPP_NAME))
4263 attr_name = c_parser_peek_token (parser)->value;
4264
4265 return attr_name;
4266 }
4267
4268 /* Parse (possibly empty) attributes. This is a GNU extension.
4269
4270 attributes:
4271 empty
4272 attributes attribute
4273
4274 attribute:
4275 __attribute__ ( ( attribute-list ) )
4276
4277 attribute-list:
4278 attrib
4279 attribute_list , attrib
4280
4281 attrib:
4282 empty
4283 any-word
4284 any-word ( identifier )
4285 any-word ( identifier , nonempty-expr-list )
4286 any-word ( expr-list )
4287
4288 where the "identifier" must not be declared as a type, and
4289 "any-word" may be any identifier (including one declared as a
4290 type), a reserved word storage class specifier, type specifier or
4291 type qualifier. ??? This still leaves out most reserved keywords
4292 (following the old parser), shouldn't we include them, and why not
4293 allow identifiers declared as types to start the arguments? */
4294
4295 static tree
c_parser_attributes(c_parser * parser)4296 c_parser_attributes (c_parser *parser)
4297 {
4298 tree attrs = NULL_TREE;
4299 while (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
4300 {
4301 /* ??? Follow the C++ parser rather than using the
4302 lex_untranslated_string kludge. */
4303 parser->lex_untranslated_string = true;
4304 /* Consume the `__attribute__' keyword. */
4305 c_parser_consume_token (parser);
4306 /* Look for the two `(' tokens. */
4307 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
4308 {
4309 parser->lex_untranslated_string = false;
4310 return attrs;
4311 }
4312 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
4313 {
4314 parser->lex_untranslated_string = false;
4315 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4316 return attrs;
4317 }
4318 /* Parse the attribute list. */
4319 while (c_parser_next_token_is (parser, CPP_COMMA)
4320 || c_parser_next_token_is (parser, CPP_NAME)
4321 || c_parser_next_token_is (parser, CPP_KEYWORD))
4322 {
4323 tree attr, attr_name, attr_args;
4324 vec<tree, va_gc> *expr_list;
4325 if (c_parser_next_token_is (parser, CPP_COMMA))
4326 {
4327 c_parser_consume_token (parser);
4328 continue;
4329 }
4330
4331 attr_name = c_parser_attribute_any_word (parser);
4332 if (attr_name == NULL)
4333 break;
4334 attr_name = canonicalize_attr_name (attr_name);
4335 c_parser_consume_token (parser);
4336 if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
4337 {
4338 attr = build_tree_list (attr_name, NULL_TREE);
4339 /* Add this attribute to the list. */
4340 attrs = chainon (attrs, attr);
4341 /* If the next token isn't a comma, we're done. */
4342 if (!c_parser_next_token_is (parser, CPP_COMMA))
4343 break;
4344 continue;
4345 }
4346 c_parser_consume_token (parser);
4347 /* Parse the attribute contents. If they start with an
4348 identifier which is followed by a comma or close
4349 parenthesis, then the arguments start with that
4350 identifier; otherwise they are an expression list.
4351 In objective-c the identifier may be a classname. */
4352 if (c_parser_next_token_is (parser, CPP_NAME)
4353 && (c_parser_peek_token (parser)->id_kind == C_ID_ID
4354 || (c_dialect_objc ()
4355 && c_parser_peek_token (parser)->id_kind
4356 == C_ID_CLASSNAME))
4357 && ((c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
4358 || (c_parser_peek_2nd_token (parser)->type
4359 == CPP_CLOSE_PAREN))
4360 && (attribute_takes_identifier_p (attr_name)
4361 || (c_dialect_objc ()
4362 && c_parser_peek_token (parser)->id_kind
4363 == C_ID_CLASSNAME)))
4364 {
4365 tree arg1 = c_parser_peek_token (parser)->value;
4366 c_parser_consume_token (parser);
4367 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4368 attr_args = build_tree_list (NULL_TREE, arg1);
4369 else
4370 {
4371 tree tree_list;
4372 c_parser_consume_token (parser);
4373 expr_list = c_parser_expr_list (parser, false, true,
4374 NULL, NULL, NULL, NULL);
4375 tree_list = build_tree_list_vec (expr_list);
4376 attr_args = tree_cons (NULL_TREE, arg1, tree_list);
4377 release_tree_vector (expr_list);
4378 }
4379 }
4380 else
4381 {
4382 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4383 attr_args = NULL_TREE;
4384 else
4385 {
4386 expr_list = c_parser_expr_list (parser, false, true,
4387 NULL, NULL, NULL, NULL);
4388 attr_args = build_tree_list_vec (expr_list);
4389 release_tree_vector (expr_list);
4390 }
4391 }
4392
4393 attr = build_tree_list (attr_name, attr_args);
4394 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4395 c_parser_consume_token (parser);
4396 else
4397 {
4398 parser->lex_untranslated_string = false;
4399 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4400 "expected %<)%>");
4401 return attrs;
4402 }
4403 /* Add this attribute to the list. */
4404 attrs = chainon (attrs, attr);
4405 /* If the next token isn't a comma, we're done. */
4406 if (!c_parser_next_token_is (parser, CPP_COMMA))
4407 break;
4408 }
4409 /* Look for the two `)' tokens. */
4410 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4411 c_parser_consume_token (parser);
4412 else
4413 {
4414 parser->lex_untranslated_string = false;
4415 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4416 "expected %<)%>");
4417 return attrs;
4418 }
4419 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4420 c_parser_consume_token (parser);
4421 else
4422 {
4423 parser->lex_untranslated_string = false;
4424 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4425 "expected %<)%>");
4426 return attrs;
4427 }
4428 parser->lex_untranslated_string = false;
4429 }
4430
4431 return attrs;
4432 }
4433
4434 /* Parse a type name (C90 6.5.5, C99 6.7.6, C11 6.7.7). ALIGNAS_OK
4435 says whether alignment specifiers are OK (only in cases that might
4436 be the type name of a compound literal).
4437
4438 type-name:
4439 specifier-qualifier-list abstract-declarator[opt]
4440 */
4441
4442 struct c_type_name *
c_parser_type_name(c_parser * parser,bool alignas_ok)4443 c_parser_type_name (c_parser *parser, bool alignas_ok)
4444 {
4445 struct c_declspecs *specs = build_null_declspecs ();
4446 struct c_declarator *declarator;
4447 struct c_type_name *ret;
4448 bool dummy = false;
4449 c_parser_declspecs (parser, specs, false, true, true, alignas_ok, false,
4450 cla_prefer_type);
4451 if (!specs->declspecs_seen_p)
4452 {
4453 c_parser_error (parser, "expected specifier-qualifier-list");
4454 return NULL;
4455 }
4456 if (specs->type != error_mark_node)
4457 {
4458 pending_xref_error ();
4459 finish_declspecs (specs);
4460 }
4461 declarator = c_parser_declarator (parser,
4462 specs->typespec_kind != ctsk_none,
4463 C_DTR_ABSTRACT, &dummy);
4464 if (declarator == NULL)
4465 return NULL;
4466 ret = XOBNEW (&parser_obstack, struct c_type_name);
4467 ret->specs = specs;
4468 ret->declarator = declarator;
4469 return ret;
4470 }
4471
4472 /* Parse an initializer (C90 6.5.7, C99 6.7.8, C11 6.7.9).
4473
4474 initializer:
4475 assignment-expression
4476 { initializer-list }
4477 { initializer-list , }
4478
4479 initializer-list:
4480 designation[opt] initializer
4481 initializer-list , designation[opt] initializer
4482
4483 designation:
4484 designator-list =
4485
4486 designator-list:
4487 designator
4488 designator-list designator
4489
4490 designator:
4491 array-designator
4492 . identifier
4493
4494 array-designator:
4495 [ constant-expression ]
4496
4497 GNU extensions:
4498
4499 initializer:
4500 { }
4501
4502 designation:
4503 array-designator
4504 identifier :
4505
4506 array-designator:
4507 [ constant-expression ... constant-expression ]
4508
4509 Any expression without commas is accepted in the syntax for the
4510 constant-expressions, with non-constant expressions rejected later.
4511
4512 This function is only used for top-level initializers; for nested
4513 ones, see c_parser_initval. */
4514
4515 static struct c_expr
c_parser_initializer(c_parser * parser)4516 c_parser_initializer (c_parser *parser)
4517 {
4518 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
4519 return c_parser_braced_init (parser, NULL_TREE, false, NULL);
4520 else
4521 {
4522 struct c_expr ret;
4523 location_t loc = c_parser_peek_token (parser)->location;
4524 ret = c_parser_expr_no_commas (parser, NULL);
4525 if (TREE_CODE (ret.value) != STRING_CST
4526 && TREE_CODE (ret.value) != COMPOUND_LITERAL_EXPR)
4527 ret = convert_lvalue_to_rvalue (loc, ret, true, true);
4528 return ret;
4529 }
4530 }
4531
4532 /* The location of the last comma within the current initializer list,
4533 or UNKNOWN_LOCATION if not within one. */
4534
4535 location_t last_init_list_comma;
4536
4537 /* Parse a braced initializer list. TYPE is the type specified for a
4538 compound literal, and NULL_TREE for other initializers and for
4539 nested braced lists. NESTED_P is true for nested braced lists,
4540 false for the list of a compound literal or the list that is the
4541 top-level initializer in a declaration. */
4542
4543 static struct c_expr
c_parser_braced_init(c_parser * parser,tree type,bool nested_p,struct obstack * outer_obstack)4544 c_parser_braced_init (c_parser *parser, tree type, bool nested_p,
4545 struct obstack *outer_obstack)
4546 {
4547 struct c_expr ret;
4548 struct obstack braced_init_obstack;
4549 location_t brace_loc = c_parser_peek_token (parser)->location;
4550 gcc_obstack_init (&braced_init_obstack);
4551 gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE));
4552 matching_braces braces;
4553 braces.consume_open (parser);
4554 if (nested_p)
4555 {
4556 finish_implicit_inits (brace_loc, outer_obstack);
4557 push_init_level (brace_loc, 0, &braced_init_obstack);
4558 }
4559 else
4560 really_start_incremental_init (type);
4561 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
4562 {
4563 pedwarn (brace_loc, OPT_Wpedantic, "ISO C forbids empty initializer braces");
4564 }
4565 else
4566 {
4567 /* Parse a non-empty initializer list, possibly with a trailing
4568 comma. */
4569 while (true)
4570 {
4571 c_parser_initelt (parser, &braced_init_obstack);
4572 if (parser->error)
4573 break;
4574 if (c_parser_next_token_is (parser, CPP_COMMA))
4575 {
4576 last_init_list_comma = c_parser_peek_token (parser)->location;
4577 c_parser_consume_token (parser);
4578 }
4579 else
4580 break;
4581 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
4582 break;
4583 }
4584 }
4585 c_token *next_tok = c_parser_peek_token (parser);
4586 if (next_tok->type != CPP_CLOSE_BRACE)
4587 {
4588 ret.set_error ();
4589 ret.original_code = ERROR_MARK;
4590 ret.original_type = NULL;
4591 braces.skip_until_found_close (parser);
4592 pop_init_level (brace_loc, 0, &braced_init_obstack, last_init_list_comma);
4593 obstack_free (&braced_init_obstack, NULL);
4594 return ret;
4595 }
4596 location_t close_loc = next_tok->location;
4597 c_parser_consume_token (parser);
4598 ret = pop_init_level (brace_loc, 0, &braced_init_obstack, close_loc);
4599 obstack_free (&braced_init_obstack, NULL);
4600 set_c_expr_source_range (&ret, brace_loc, close_loc);
4601 return ret;
4602 }
4603
4604 /* Parse a nested initializer, including designators. */
4605
4606 static void
c_parser_initelt(c_parser * parser,struct obstack * braced_init_obstack)4607 c_parser_initelt (c_parser *parser, struct obstack * braced_init_obstack)
4608 {
4609 /* Parse any designator or designator list. A single array
4610 designator may have the subsequent "=" omitted in GNU C, but a
4611 longer list or a structure member designator may not. */
4612 if (c_parser_next_token_is (parser, CPP_NAME)
4613 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
4614 {
4615 /* Old-style structure member designator. */
4616 set_init_label (c_parser_peek_token (parser)->location,
4617 c_parser_peek_token (parser)->value,
4618 c_parser_peek_token (parser)->location,
4619 braced_init_obstack);
4620 /* Use the colon as the error location. */
4621 pedwarn (c_parser_peek_2nd_token (parser)->location, OPT_Wpedantic,
4622 "obsolete use of designated initializer with %<:%>");
4623 c_parser_consume_token (parser);
4624 c_parser_consume_token (parser);
4625 }
4626 else
4627 {
4628 /* des_seen is 0 if there have been no designators, 1 if there
4629 has been a single array designator and 2 otherwise. */
4630 int des_seen = 0;
4631 /* Location of a designator. */
4632 location_t des_loc = UNKNOWN_LOCATION; /* Quiet warning. */
4633 while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
4634 || c_parser_next_token_is (parser, CPP_DOT))
4635 {
4636 int des_prev = des_seen;
4637 if (!des_seen)
4638 des_loc = c_parser_peek_token (parser)->location;
4639 if (des_seen < 2)
4640 des_seen++;
4641 if (c_parser_next_token_is (parser, CPP_DOT))
4642 {
4643 des_seen = 2;
4644 c_parser_consume_token (parser);
4645 if (c_parser_next_token_is (parser, CPP_NAME))
4646 {
4647 set_init_label (des_loc, c_parser_peek_token (parser)->value,
4648 c_parser_peek_token (parser)->location,
4649 braced_init_obstack);
4650 c_parser_consume_token (parser);
4651 }
4652 else
4653 {
4654 struct c_expr init;
4655 init.set_error ();
4656 init.original_code = ERROR_MARK;
4657 init.original_type = NULL;
4658 c_parser_error (parser, "expected identifier");
4659 c_parser_skip_until_found (parser, CPP_COMMA, NULL);
4660 process_init_element (input_location, init, false,
4661 braced_init_obstack);
4662 return;
4663 }
4664 }
4665 else
4666 {
4667 tree first, second;
4668 location_t ellipsis_loc = UNKNOWN_LOCATION; /* Quiet warning. */
4669 location_t array_index_loc = UNKNOWN_LOCATION;
4670 /* ??? Following the old parser, [ objc-receiver
4671 objc-message-args ] is accepted as an initializer,
4672 being distinguished from a designator by what follows
4673 the first assignment expression inside the square
4674 brackets, but after a first array designator a
4675 subsequent square bracket is for Objective-C taken to
4676 start an expression, using the obsolete form of
4677 designated initializer without '=', rather than
4678 possibly being a second level of designation: in LALR
4679 terms, the '[' is shifted rather than reducing
4680 designator to designator-list. */
4681 if (des_prev == 1 && c_dialect_objc ())
4682 {
4683 des_seen = des_prev;
4684 break;
4685 }
4686 if (des_prev == 0 && c_dialect_objc ())
4687 {
4688 /* This might be an array designator or an
4689 Objective-C message expression. If the former,
4690 continue parsing here; if the latter, parse the
4691 remainder of the initializer given the starting
4692 primary-expression. ??? It might make sense to
4693 distinguish when des_prev == 1 as well; see
4694 previous comment. */
4695 tree rec, args;
4696 struct c_expr mexpr;
4697 c_parser_consume_token (parser);
4698 if (c_parser_peek_token (parser)->type == CPP_NAME
4699 && ((c_parser_peek_token (parser)->id_kind
4700 == C_ID_TYPENAME)
4701 || (c_parser_peek_token (parser)->id_kind
4702 == C_ID_CLASSNAME)))
4703 {
4704 /* Type name receiver. */
4705 tree id = c_parser_peek_token (parser)->value;
4706 c_parser_consume_token (parser);
4707 rec = objc_get_class_reference (id);
4708 goto parse_message_args;
4709 }
4710 first = c_parser_expr_no_commas (parser, NULL).value;
4711 mark_exp_read (first);
4712 if (c_parser_next_token_is (parser, CPP_ELLIPSIS)
4713 || c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
4714 goto array_desig_after_first;
4715 /* Expression receiver. So far only one part
4716 without commas has been parsed; there might be
4717 more of the expression. */
4718 rec = first;
4719 while (c_parser_next_token_is (parser, CPP_COMMA))
4720 {
4721 struct c_expr next;
4722 location_t comma_loc, exp_loc;
4723 comma_loc = c_parser_peek_token (parser)->location;
4724 c_parser_consume_token (parser);
4725 exp_loc = c_parser_peek_token (parser)->location;
4726 next = c_parser_expr_no_commas (parser, NULL);
4727 next = convert_lvalue_to_rvalue (exp_loc, next,
4728 true, true);
4729 rec = build_compound_expr (comma_loc, rec, next.value);
4730 }
4731 parse_message_args:
4732 /* Now parse the objc-message-args. */
4733 args = c_parser_objc_message_args (parser);
4734 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
4735 "expected %<]%>");
4736 mexpr.value
4737 = objc_build_message_expr (rec, args);
4738 mexpr.original_code = ERROR_MARK;
4739 mexpr.original_type = NULL;
4740 /* Now parse and process the remainder of the
4741 initializer, starting with this message
4742 expression as a primary-expression. */
4743 c_parser_initval (parser, &mexpr, braced_init_obstack);
4744 return;
4745 }
4746 c_parser_consume_token (parser);
4747 array_index_loc = c_parser_peek_token (parser)->location;
4748 first = c_parser_expr_no_commas (parser, NULL).value;
4749 mark_exp_read (first);
4750 array_desig_after_first:
4751 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
4752 {
4753 ellipsis_loc = c_parser_peek_token (parser)->location;
4754 c_parser_consume_token (parser);
4755 second = c_parser_expr_no_commas (parser, NULL).value;
4756 mark_exp_read (second);
4757 }
4758 else
4759 second = NULL_TREE;
4760 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
4761 {
4762 c_parser_consume_token (parser);
4763 set_init_index (array_index_loc, first, second,
4764 braced_init_obstack);
4765 if (second)
4766 pedwarn (ellipsis_loc, OPT_Wpedantic,
4767 "ISO C forbids specifying range of elements to initialize");
4768 }
4769 else
4770 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
4771 "expected %<]%>");
4772 }
4773 }
4774 if (des_seen >= 1)
4775 {
4776 if (c_parser_next_token_is (parser, CPP_EQ))
4777 {
4778 pedwarn_c90 (des_loc, OPT_Wpedantic,
4779 "ISO C90 forbids specifying subobject "
4780 "to initialize");
4781 c_parser_consume_token (parser);
4782 }
4783 else
4784 {
4785 if (des_seen == 1)
4786 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
4787 "obsolete use of designated initializer without %<=%>");
4788 else
4789 {
4790 struct c_expr init;
4791 init.set_error ();
4792 init.original_code = ERROR_MARK;
4793 init.original_type = NULL;
4794 c_parser_error (parser, "expected %<=%>");
4795 c_parser_skip_until_found (parser, CPP_COMMA, NULL);
4796 process_init_element (input_location, init, false,
4797 braced_init_obstack);
4798 return;
4799 }
4800 }
4801 }
4802 }
4803 c_parser_initval (parser, NULL, braced_init_obstack);
4804 }
4805
4806 /* Parse a nested initializer; as c_parser_initializer but parses
4807 initializers within braced lists, after any designators have been
4808 applied. If AFTER is not NULL then it is an Objective-C message
4809 expression which is the primary-expression starting the
4810 initializer. */
4811
4812 static void
c_parser_initval(c_parser * parser,struct c_expr * after,struct obstack * braced_init_obstack)4813 c_parser_initval (c_parser *parser, struct c_expr *after,
4814 struct obstack * braced_init_obstack)
4815 {
4816 struct c_expr init;
4817 gcc_assert (!after || c_dialect_objc ());
4818 location_t loc = c_parser_peek_token (parser)->location;
4819
4820 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE) && !after)
4821 init = c_parser_braced_init (parser, NULL_TREE, true,
4822 braced_init_obstack);
4823 else
4824 {
4825 init = c_parser_expr_no_commas (parser, after);
4826 if (init.value != NULL_TREE
4827 && TREE_CODE (init.value) != STRING_CST
4828 && TREE_CODE (init.value) != COMPOUND_LITERAL_EXPR)
4829 init = convert_lvalue_to_rvalue (loc, init, true, true);
4830 }
4831 process_init_element (loc, init, false, braced_init_obstack);
4832 }
4833
4834 /* Parse a compound statement (possibly a function body) (C90 6.6.2,
4835 C99 6.8.2, C11 6.8.2).
4836
4837 compound-statement:
4838 { block-item-list[opt] }
4839 { label-declarations block-item-list }
4840
4841 block-item-list:
4842 block-item
4843 block-item-list block-item
4844
4845 block-item:
4846 nested-declaration
4847 statement
4848
4849 nested-declaration:
4850 declaration
4851
4852 GNU extensions:
4853
4854 compound-statement:
4855 { label-declarations block-item-list }
4856
4857 nested-declaration:
4858 __extension__ nested-declaration
4859 nested-function-definition
4860
4861 label-declarations:
4862 label-declaration
4863 label-declarations label-declaration
4864
4865 label-declaration:
4866 __label__ identifier-list ;
4867
4868 Allowing the mixing of declarations and code is new in C99. The
4869 GNU syntax also permits (not shown above) labels at the end of
4870 compound statements, which yield an error. We don't allow labels
4871 on declarations; this might seem like a natural extension, but
4872 there would be a conflict between attributes on the label and
4873 prefix attributes on the declaration. ??? The syntax follows the
4874 old parser in requiring something after label declarations.
4875 Although they are erroneous if the labels declared aren't defined,
4876 is it useful for the syntax to be this way?
4877
4878 OpenACC:
4879
4880 block-item:
4881 openacc-directive
4882
4883 openacc-directive:
4884 update-directive
4885
4886 OpenMP:
4887
4888 block-item:
4889 openmp-directive
4890
4891 openmp-directive:
4892 barrier-directive
4893 flush-directive
4894 taskwait-directive
4895 taskyield-directive
4896 cancel-directive
4897 cancellation-point-directive */
4898
4899 static tree
c_parser_compound_statement(c_parser * parser)4900 c_parser_compound_statement (c_parser *parser)
4901 {
4902 tree stmt;
4903 location_t brace_loc;
4904 brace_loc = c_parser_peek_token (parser)->location;
4905 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
4906 {
4907 /* Ensure a scope is entered and left anyway to avoid confusion
4908 if we have just prepared to enter a function body. */
4909 stmt = c_begin_compound_stmt (true);
4910 c_end_compound_stmt (brace_loc, stmt, true);
4911 return error_mark_node;
4912 }
4913 stmt = c_begin_compound_stmt (true);
4914 c_parser_compound_statement_nostart (parser);
4915
4916 return c_end_compound_stmt (brace_loc, stmt, true);
4917 }
4918
4919 /* Parse a compound statement except for the opening brace. This is
4920 used for parsing both compound statements and statement expressions
4921 (which follow different paths to handling the opening). */
4922
4923 static void
c_parser_compound_statement_nostart(c_parser * parser)4924 c_parser_compound_statement_nostart (c_parser *parser)
4925 {
4926 bool last_stmt = false;
4927 bool last_label = false;
4928 bool save_valid_for_pragma = valid_location_for_stdc_pragma_p ();
4929 location_t label_loc = UNKNOWN_LOCATION; /* Quiet warning. */
4930 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
4931 {
4932 add_debug_begin_stmt (c_parser_peek_token (parser)->location);
4933 c_parser_consume_token (parser);
4934 return;
4935 }
4936 mark_valid_location_for_stdc_pragma (true);
4937 if (c_parser_next_token_is_keyword (parser, RID_LABEL))
4938 {
4939 /* Read zero or more forward-declarations for labels that nested
4940 functions can jump to. */
4941 mark_valid_location_for_stdc_pragma (false);
4942 while (c_parser_next_token_is_keyword (parser, RID_LABEL))
4943 {
4944 label_loc = c_parser_peek_token (parser)->location;
4945 c_parser_consume_token (parser);
4946 /* Any identifiers, including those declared as type names,
4947 are OK here. */
4948 while (true)
4949 {
4950 tree label;
4951 if (c_parser_next_token_is_not (parser, CPP_NAME))
4952 {
4953 c_parser_error (parser, "expected identifier");
4954 break;
4955 }
4956 label
4957 = declare_label (c_parser_peek_token (parser)->value);
4958 C_DECLARED_LABEL_FLAG (label) = 1;
4959 add_stmt (build_stmt (label_loc, DECL_EXPR, label));
4960 c_parser_consume_token (parser);
4961 if (c_parser_next_token_is (parser, CPP_COMMA))
4962 c_parser_consume_token (parser);
4963 else
4964 break;
4965 }
4966 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
4967 }
4968 pedwarn (label_loc, OPT_Wpedantic, "ISO C forbids label declarations");
4969 }
4970 /* We must now have at least one statement, label or declaration. */
4971 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
4972 {
4973 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
4974 c_parser_error (parser, "expected declaration or statement");
4975 c_parser_consume_token (parser);
4976 return;
4977 }
4978 while (c_parser_next_token_is_not (parser, CPP_CLOSE_BRACE))
4979 {
4980 location_t loc = c_parser_peek_token (parser)->location;
4981 loc = expansion_point_location_if_in_system_header (loc);
4982 if (c_parser_next_token_is_keyword (parser, RID_CASE)
4983 || c_parser_next_token_is_keyword (parser, RID_DEFAULT)
4984 || (c_parser_next_token_is (parser, CPP_NAME)
4985 && c_parser_peek_2nd_token (parser)->type == CPP_COLON))
4986 {
4987 if (c_parser_next_token_is_keyword (parser, RID_CASE))
4988 label_loc = c_parser_peek_2nd_token (parser)->location;
4989 else
4990 label_loc = c_parser_peek_token (parser)->location;
4991 last_label = true;
4992 last_stmt = false;
4993 mark_valid_location_for_stdc_pragma (false);
4994 c_parser_label (parser);
4995 }
4996 else if (!last_label
4997 && c_parser_next_tokens_start_declaration (parser))
4998 {
4999 last_label = false;
5000 mark_valid_location_for_stdc_pragma (false);
5001 bool fallthru_attr_p = false;
5002 c_parser_declaration_or_fndef (parser, true, true, true, true,
5003 true, NULL, vNULL, NULL,
5004 &fallthru_attr_p);
5005 if (last_stmt && !fallthru_attr_p)
5006 pedwarn_c90 (loc, OPT_Wdeclaration_after_statement,
5007 "ISO C90 forbids mixed declarations and code");
5008 last_stmt = fallthru_attr_p;
5009 }
5010 else if (!last_label
5011 && c_parser_next_token_is_keyword (parser, RID_EXTENSION))
5012 {
5013 /* __extension__ can start a declaration, but is also an
5014 unary operator that can start an expression. Consume all
5015 but the last of a possible series of __extension__ to
5016 determine which. */
5017 while (c_parser_peek_2nd_token (parser)->type == CPP_KEYWORD
5018 && (c_parser_peek_2nd_token (parser)->keyword
5019 == RID_EXTENSION))
5020 c_parser_consume_token (parser);
5021 if (c_token_starts_declaration (c_parser_peek_2nd_token (parser)))
5022 {
5023 int ext;
5024 ext = disable_extension_diagnostics ();
5025 c_parser_consume_token (parser);
5026 last_label = false;
5027 mark_valid_location_for_stdc_pragma (false);
5028 c_parser_declaration_or_fndef (parser, true, true, true, true,
5029 true, NULL, vNULL);
5030 /* Following the old parser, __extension__ does not
5031 disable this diagnostic. */
5032 restore_extension_diagnostics (ext);
5033 if (last_stmt)
5034 pedwarn_c90 (loc, OPT_Wdeclaration_after_statement,
5035 "ISO C90 forbids mixed declarations and code");
5036 last_stmt = false;
5037 }
5038 else
5039 goto statement;
5040 }
5041 else if (c_parser_next_token_is (parser, CPP_PRAGMA))
5042 {
5043 /* External pragmas, and some omp pragmas, are not associated
5044 with regular c code, and so are not to be considered statements
5045 syntactically. This ensures that the user doesn't put them
5046 places that would turn into syntax errors if the directive
5047 were ignored. */
5048 if (c_parser_pragma (parser,
5049 last_label ? pragma_stmt : pragma_compound,
5050 NULL))
5051 last_label = false, last_stmt = true;
5052 }
5053 else if (c_parser_next_token_is (parser, CPP_EOF))
5054 {
5055 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
5056 c_parser_error (parser, "expected declaration or statement");
5057 return;
5058 }
5059 else if (c_parser_next_token_is_keyword (parser, RID_ELSE))
5060 {
5061 if (parser->in_if_block)
5062 {
5063 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
5064 error_at (loc, "expected %<}%> before %<else%>");
5065 return;
5066 }
5067 else
5068 {
5069 error_at (loc, "%<else%> without a previous %<if%>");
5070 c_parser_consume_token (parser);
5071 continue;
5072 }
5073 }
5074 else
5075 {
5076 statement:
5077 last_label = false;
5078 last_stmt = true;
5079 mark_valid_location_for_stdc_pragma (false);
5080 c_parser_statement_after_labels (parser, NULL);
5081 }
5082
5083 parser->error = false;
5084 }
5085 if (last_label)
5086 error_at (label_loc, "label at end of compound statement");
5087 c_parser_consume_token (parser);
5088 /* Restore the value we started with. */
5089 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
5090 }
5091
5092 /* Parse all consecutive labels. */
5093
5094 static void
c_parser_all_labels(c_parser * parser)5095 c_parser_all_labels (c_parser *parser)
5096 {
5097 while (c_parser_next_token_is_keyword (parser, RID_CASE)
5098 || c_parser_next_token_is_keyword (parser, RID_DEFAULT)
5099 || (c_parser_next_token_is (parser, CPP_NAME)
5100 && c_parser_peek_2nd_token (parser)->type == CPP_COLON))
5101 c_parser_label (parser);
5102 }
5103
5104 /* Parse a label (C90 6.6.1, C99 6.8.1, C11 6.8.1).
5105
5106 label:
5107 identifier : attributes[opt]
5108 case constant-expression :
5109 default :
5110
5111 GNU extensions:
5112
5113 label:
5114 case constant-expression ... constant-expression :
5115
5116 The use of attributes on labels is a GNU extension. The syntax in
5117 GNU C accepts any expressions without commas, non-constant
5118 expressions being rejected later. */
5119
5120 static void
c_parser_label(c_parser * parser)5121 c_parser_label (c_parser *parser)
5122 {
5123 location_t loc1 = c_parser_peek_token (parser)->location;
5124 tree label = NULL_TREE;
5125
5126 /* Remember whether this case or a user-defined label is allowed to fall
5127 through to. */
5128 bool fallthrough_p = c_parser_peek_token (parser)->flags & PREV_FALLTHROUGH;
5129
5130 if (c_parser_next_token_is_keyword (parser, RID_CASE))
5131 {
5132 tree exp1, exp2;
5133 c_parser_consume_token (parser);
5134 exp1 = c_parser_expr_no_commas (parser, NULL).value;
5135 if (c_parser_next_token_is (parser, CPP_COLON))
5136 {
5137 c_parser_consume_token (parser);
5138 label = do_case (loc1, exp1, NULL_TREE);
5139 }
5140 else if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
5141 {
5142 c_parser_consume_token (parser);
5143 exp2 = c_parser_expr_no_commas (parser, NULL).value;
5144 if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
5145 label = do_case (loc1, exp1, exp2);
5146 }
5147 else
5148 c_parser_error (parser, "expected %<:%> or %<...%>");
5149 }
5150 else if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
5151 {
5152 c_parser_consume_token (parser);
5153 if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
5154 label = do_case (loc1, NULL_TREE, NULL_TREE);
5155 }
5156 else
5157 {
5158 tree name = c_parser_peek_token (parser)->value;
5159 tree tlab;
5160 tree attrs;
5161 location_t loc2 = c_parser_peek_token (parser)->location;
5162 gcc_assert (c_parser_next_token_is (parser, CPP_NAME));
5163 c_parser_consume_token (parser);
5164 gcc_assert (c_parser_next_token_is (parser, CPP_COLON));
5165 c_parser_consume_token (parser);
5166 attrs = c_parser_attributes (parser);
5167 tlab = define_label (loc2, name);
5168 if (tlab)
5169 {
5170 decl_attributes (&tlab, attrs, 0);
5171 label = add_stmt (build_stmt (loc1, LABEL_EXPR, tlab));
5172 }
5173 }
5174 if (label)
5175 {
5176 if (TREE_CODE (label) == LABEL_EXPR)
5177 FALLTHROUGH_LABEL_P (LABEL_EXPR_LABEL (label)) = fallthrough_p;
5178 else
5179 FALLTHROUGH_LABEL_P (CASE_LABEL (label)) = fallthrough_p;
5180
5181 /* Allow '__attribute__((fallthrough));'. */
5182 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
5183 {
5184 location_t loc = c_parser_peek_token (parser)->location;
5185 tree attrs = c_parser_attributes (parser);
5186 if (attribute_fallthrough_p (attrs))
5187 {
5188 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
5189 {
5190 tree fn = build_call_expr_internal_loc (loc,
5191 IFN_FALLTHROUGH,
5192 void_type_node, 0);
5193 add_stmt (fn);
5194 }
5195 else
5196 warning_at (loc, OPT_Wattributes, "%<fallthrough%> attribute "
5197 "not followed by %<;%>");
5198 }
5199 else if (attrs != NULL_TREE)
5200 warning_at (loc, OPT_Wattributes, "only attribute %<fallthrough%>"
5201 " can be applied to a null statement");
5202 }
5203 if (c_parser_next_tokens_start_declaration (parser))
5204 {
5205 error_at (c_parser_peek_token (parser)->location,
5206 "a label can only be part of a statement and "
5207 "a declaration is not a statement");
5208 c_parser_declaration_or_fndef (parser, /*fndef_ok*/ false,
5209 /*static_assert_ok*/ true,
5210 /*empty_ok*/ true, /*nested*/ true,
5211 /*start_attr_ok*/ true, NULL,
5212 vNULL);
5213 }
5214 }
5215 }
5216
5217 /* Parse a statement (C90 6.6, C99 6.8, C11 6.8).
5218
5219 statement:
5220 labeled-statement
5221 compound-statement
5222 expression-statement
5223 selection-statement
5224 iteration-statement
5225 jump-statement
5226
5227 labeled-statement:
5228 label statement
5229
5230 expression-statement:
5231 expression[opt] ;
5232
5233 selection-statement:
5234 if-statement
5235 switch-statement
5236
5237 iteration-statement:
5238 while-statement
5239 do-statement
5240 for-statement
5241
5242 jump-statement:
5243 goto identifier ;
5244 continue ;
5245 break ;
5246 return expression[opt] ;
5247
5248 GNU extensions:
5249
5250 statement:
5251 asm-statement
5252
5253 jump-statement:
5254 goto * expression ;
5255
5256 expression-statement:
5257 attributes ;
5258
5259 Objective-C:
5260
5261 statement:
5262 objc-throw-statement
5263 objc-try-catch-statement
5264 objc-synchronized-statement
5265
5266 objc-throw-statement:
5267 @throw expression ;
5268 @throw ;
5269
5270 OpenACC:
5271
5272 statement:
5273 openacc-construct
5274
5275 openacc-construct:
5276 parallel-construct
5277 kernels-construct
5278 data-construct
5279 loop-construct
5280
5281 parallel-construct:
5282 parallel-directive structured-block
5283
5284 kernels-construct:
5285 kernels-directive structured-block
5286
5287 data-construct:
5288 data-directive structured-block
5289
5290 loop-construct:
5291 loop-directive structured-block
5292
5293 OpenMP:
5294
5295 statement:
5296 openmp-construct
5297
5298 openmp-construct:
5299 parallel-construct
5300 for-construct
5301 simd-construct
5302 for-simd-construct
5303 sections-construct
5304 single-construct
5305 parallel-for-construct
5306 parallel-for-simd-construct
5307 parallel-sections-construct
5308 master-construct
5309 critical-construct
5310 atomic-construct
5311 ordered-construct
5312
5313 parallel-construct:
5314 parallel-directive structured-block
5315
5316 for-construct:
5317 for-directive iteration-statement
5318
5319 simd-construct:
5320 simd-directive iteration-statements
5321
5322 for-simd-construct:
5323 for-simd-directive iteration-statements
5324
5325 sections-construct:
5326 sections-directive section-scope
5327
5328 single-construct:
5329 single-directive structured-block
5330
5331 parallel-for-construct:
5332 parallel-for-directive iteration-statement
5333
5334 parallel-for-simd-construct:
5335 parallel-for-simd-directive iteration-statement
5336
5337 parallel-sections-construct:
5338 parallel-sections-directive section-scope
5339
5340 master-construct:
5341 master-directive structured-block
5342
5343 critical-construct:
5344 critical-directive structured-block
5345
5346 atomic-construct:
5347 atomic-directive expression-statement
5348
5349 ordered-construct:
5350 ordered-directive structured-block
5351
5352 Transactional Memory:
5353
5354 statement:
5355 transaction-statement
5356 transaction-cancel-statement
5357
5358 IF_P is used to track whether there's a (possibly labeled) if statement
5359 which is not enclosed in braces and has an else clause. This is used to
5360 implement -Wparentheses. */
5361
5362 static void
c_parser_statement(c_parser * parser,bool * if_p,location_t * loc_after_labels)5363 c_parser_statement (c_parser *parser, bool *if_p, location_t *loc_after_labels)
5364 {
5365 c_parser_all_labels (parser);
5366 if (loc_after_labels)
5367 *loc_after_labels = c_parser_peek_token (parser)->location;
5368 c_parser_statement_after_labels (parser, if_p, NULL);
5369 }
5370
5371 /* Parse a statement, other than a labeled statement. CHAIN is a vector
5372 of if-else-if conditions.
5373
5374 IF_P is used to track whether there's a (possibly labeled) if statement
5375 which is not enclosed in braces and has an else clause. This is used to
5376 implement -Wparentheses. */
5377
5378 static void
c_parser_statement_after_labels(c_parser * parser,bool * if_p,vec<tree> * chain)5379 c_parser_statement_after_labels (c_parser *parser, bool *if_p,
5380 vec<tree> *chain)
5381 {
5382 location_t loc = c_parser_peek_token (parser)->location;
5383 tree stmt = NULL_TREE;
5384 bool in_if_block = parser->in_if_block;
5385 parser->in_if_block = false;
5386 if (if_p != NULL)
5387 *if_p = false;
5388
5389 if (c_parser_peek_token (parser)->type != CPP_OPEN_BRACE)
5390 add_debug_begin_stmt (loc);
5391
5392 switch (c_parser_peek_token (parser)->type)
5393 {
5394 case CPP_OPEN_BRACE:
5395 add_stmt (c_parser_compound_statement (parser));
5396 break;
5397 case CPP_KEYWORD:
5398 switch (c_parser_peek_token (parser)->keyword)
5399 {
5400 case RID_IF:
5401 c_parser_if_statement (parser, if_p, chain);
5402 break;
5403 case RID_SWITCH:
5404 c_parser_switch_statement (parser, if_p);
5405 break;
5406 case RID_WHILE:
5407 c_parser_while_statement (parser, false, 0, if_p);
5408 break;
5409 case RID_DO:
5410 c_parser_do_statement (parser, 0, false);
5411 break;
5412 case RID_FOR:
5413 c_parser_for_statement (parser, false, 0, if_p);
5414 break;
5415 case RID_GOTO:
5416 c_parser_consume_token (parser);
5417 if (c_parser_next_token_is (parser, CPP_NAME))
5418 {
5419 stmt = c_finish_goto_label (loc,
5420 c_parser_peek_token (parser)->value);
5421 c_parser_consume_token (parser);
5422 }
5423 else if (c_parser_next_token_is (parser, CPP_MULT))
5424 {
5425 struct c_expr val;
5426
5427 c_parser_consume_token (parser);
5428 val = c_parser_expression (parser);
5429 val = convert_lvalue_to_rvalue (loc, val, false, true);
5430 stmt = c_finish_goto_ptr (loc, val.value);
5431 }
5432 else
5433 c_parser_error (parser, "expected identifier or %<*%>");
5434 goto expect_semicolon;
5435 case RID_CONTINUE:
5436 c_parser_consume_token (parser);
5437 stmt = c_finish_bc_stmt (loc, &c_cont_label, false);
5438 goto expect_semicolon;
5439 case RID_BREAK:
5440 c_parser_consume_token (parser);
5441 stmt = c_finish_bc_stmt (loc, &c_break_label, true);
5442 goto expect_semicolon;
5443 case RID_RETURN:
5444 c_parser_consume_token (parser);
5445 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
5446 {
5447 stmt = c_finish_return (loc, NULL_TREE, NULL_TREE);
5448 c_parser_consume_token (parser);
5449 }
5450 else
5451 {
5452 location_t xloc = c_parser_peek_token (parser)->location;
5453 struct c_expr expr = c_parser_expression_conv (parser);
5454 mark_exp_read (expr.value);
5455 stmt = c_finish_return (EXPR_LOC_OR_LOC (expr.value, xloc),
5456 expr.value, expr.original_type);
5457 goto expect_semicolon;
5458 }
5459 break;
5460 case RID_ASM:
5461 stmt = c_parser_asm_statement (parser);
5462 break;
5463 case RID_TRANSACTION_ATOMIC:
5464 case RID_TRANSACTION_RELAXED:
5465 stmt = c_parser_transaction (parser,
5466 c_parser_peek_token (parser)->keyword);
5467 break;
5468 case RID_TRANSACTION_CANCEL:
5469 stmt = c_parser_transaction_cancel (parser);
5470 goto expect_semicolon;
5471 case RID_AT_THROW:
5472 gcc_assert (c_dialect_objc ());
5473 c_parser_consume_token (parser);
5474 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
5475 {
5476 stmt = objc_build_throw_stmt (loc, NULL_TREE);
5477 c_parser_consume_token (parser);
5478 }
5479 else
5480 {
5481 struct c_expr expr = c_parser_expression (parser);
5482 expr = convert_lvalue_to_rvalue (loc, expr, false, false);
5483 expr.value = c_fully_fold (expr.value, false, NULL);
5484 stmt = objc_build_throw_stmt (loc, expr.value);
5485 goto expect_semicolon;
5486 }
5487 break;
5488 case RID_AT_TRY:
5489 gcc_assert (c_dialect_objc ());
5490 c_parser_objc_try_catch_finally_statement (parser);
5491 break;
5492 case RID_AT_SYNCHRONIZED:
5493 gcc_assert (c_dialect_objc ());
5494 c_parser_objc_synchronized_statement (parser);
5495 break;
5496 case RID_ATTRIBUTE:
5497 {
5498 /* Allow '__attribute__((fallthrough));'. */
5499 tree attrs = c_parser_attributes (parser);
5500 if (attribute_fallthrough_p (attrs))
5501 {
5502 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
5503 {
5504 tree fn = build_call_expr_internal_loc (loc,
5505 IFN_FALLTHROUGH,
5506 void_type_node, 0);
5507 add_stmt (fn);
5508 /* Eat the ';'. */
5509 c_parser_consume_token (parser);
5510 }
5511 else
5512 warning_at (loc, OPT_Wattributes,
5513 "%<fallthrough%> attribute not followed "
5514 "by %<;%>");
5515 }
5516 else if (attrs != NULL_TREE)
5517 warning_at (loc, OPT_Wattributes, "only attribute %<fallthrough%>"
5518 " can be applied to a null statement");
5519 break;
5520 }
5521 default:
5522 goto expr_stmt;
5523 }
5524 break;
5525 case CPP_SEMICOLON:
5526 c_parser_consume_token (parser);
5527 break;
5528 case CPP_CLOSE_PAREN:
5529 case CPP_CLOSE_SQUARE:
5530 /* Avoid infinite loop in error recovery:
5531 c_parser_skip_until_found stops at a closing nesting
5532 delimiter without consuming it, but here we need to consume
5533 it to proceed further. */
5534 c_parser_error (parser, "expected statement");
5535 c_parser_consume_token (parser);
5536 break;
5537 case CPP_PRAGMA:
5538 c_parser_pragma (parser, pragma_stmt, if_p);
5539 break;
5540 default:
5541 expr_stmt:
5542 stmt = c_finish_expr_stmt (loc, c_parser_expression_conv (parser).value);
5543 expect_semicolon:
5544 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
5545 break;
5546 }
5547 /* Two cases cannot and do not have line numbers associated: If stmt
5548 is degenerate, such as "2;", then stmt is an INTEGER_CST, which
5549 cannot hold line numbers. But that's OK because the statement
5550 will either be changed to a MODIFY_EXPR during gimplification of
5551 the statement expr, or discarded. If stmt was compound, but
5552 without new variables, we will have skipped the creation of a
5553 BIND and will have a bare STATEMENT_LIST. But that's OK because
5554 (recursively) all of the component statements should already have
5555 line numbers assigned. ??? Can we discard no-op statements
5556 earlier? */
5557 if (EXPR_LOCATION (stmt) == UNKNOWN_LOCATION)
5558 protected_set_expr_location (stmt, loc);
5559
5560 parser->in_if_block = in_if_block;
5561 }
5562
5563 /* Parse the condition from an if, do, while or for statements. */
5564
5565 static tree
c_parser_condition(c_parser * parser)5566 c_parser_condition (c_parser *parser)
5567 {
5568 location_t loc = c_parser_peek_token (parser)->location;
5569 tree cond;
5570 cond = c_parser_expression_conv (parser).value;
5571 cond = c_objc_common_truthvalue_conversion (loc, cond);
5572 cond = c_fully_fold (cond, false, NULL);
5573 if (warn_sequence_point)
5574 verify_sequence_points (cond);
5575 return cond;
5576 }
5577
5578 /* Parse a parenthesized condition from an if, do or while statement.
5579
5580 condition:
5581 ( expression )
5582 */
5583 static tree
c_parser_paren_condition(c_parser * parser)5584 c_parser_paren_condition (c_parser *parser)
5585 {
5586 tree cond;
5587 matching_parens parens;
5588 if (!parens.require_open (parser))
5589 return error_mark_node;
5590 cond = c_parser_condition (parser);
5591 parens.skip_until_found_close (parser);
5592 return cond;
5593 }
5594
5595 /* Parse a statement which is a block in C99.
5596
5597 IF_P is used to track whether there's a (possibly labeled) if statement
5598 which is not enclosed in braces and has an else clause. This is used to
5599 implement -Wparentheses. */
5600
5601 static tree
c_parser_c99_block_statement(c_parser * parser,bool * if_p,location_t * loc_after_labels)5602 c_parser_c99_block_statement (c_parser *parser, bool *if_p,
5603 location_t *loc_after_labels)
5604 {
5605 tree block = c_begin_compound_stmt (flag_isoc99);
5606 location_t loc = c_parser_peek_token (parser)->location;
5607 c_parser_statement (parser, if_p, loc_after_labels);
5608 return c_end_compound_stmt (loc, block, flag_isoc99);
5609 }
5610
5611 /* Parse the body of an if statement. This is just parsing a
5612 statement but (a) it is a block in C99, (b) we track whether the
5613 body is an if statement for the sake of -Wparentheses warnings, (c)
5614 we handle an empty body specially for the sake of -Wempty-body
5615 warnings, and (d) we call parser_compound_statement directly
5616 because c_parser_statement_after_labels resets
5617 parser->in_if_block.
5618
5619 IF_P is used to track whether there's a (possibly labeled) if statement
5620 which is not enclosed in braces and has an else clause. This is used to
5621 implement -Wparentheses. */
5622
5623 static tree
c_parser_if_body(c_parser * parser,bool * if_p,const token_indent_info & if_tinfo)5624 c_parser_if_body (c_parser *parser, bool *if_p,
5625 const token_indent_info &if_tinfo)
5626 {
5627 tree block = c_begin_compound_stmt (flag_isoc99);
5628 location_t body_loc = c_parser_peek_token (parser)->location;
5629 location_t body_loc_after_labels = UNKNOWN_LOCATION;
5630 token_indent_info body_tinfo
5631 = get_token_indent_info (c_parser_peek_token (parser));
5632
5633 c_parser_all_labels (parser);
5634 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
5635 {
5636 location_t loc = c_parser_peek_token (parser)->location;
5637 add_stmt (build_empty_stmt (loc));
5638 c_parser_consume_token (parser);
5639 if (!c_parser_next_token_is_keyword (parser, RID_ELSE))
5640 warning_at (loc, OPT_Wempty_body,
5641 "suggest braces around empty body in an %<if%> statement");
5642 }
5643 else if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
5644 add_stmt (c_parser_compound_statement (parser));
5645 else
5646 {
5647 body_loc_after_labels = c_parser_peek_token (parser)->location;
5648 c_parser_statement_after_labels (parser, if_p);
5649 }
5650
5651 token_indent_info next_tinfo
5652 = get_token_indent_info (c_parser_peek_token (parser));
5653 warn_for_misleading_indentation (if_tinfo, body_tinfo, next_tinfo);
5654 if (body_loc_after_labels != UNKNOWN_LOCATION
5655 && next_tinfo.type != CPP_SEMICOLON)
5656 warn_for_multistatement_macros (body_loc_after_labels, next_tinfo.location,
5657 if_tinfo.location, RID_IF);
5658
5659 return c_end_compound_stmt (body_loc, block, flag_isoc99);
5660 }
5661
5662 /* Parse the else body of an if statement. This is just parsing a
5663 statement but (a) it is a block in C99, (b) we handle an empty body
5664 specially for the sake of -Wempty-body warnings. CHAIN is a vector
5665 of if-else-if conditions. */
5666
5667 static tree
c_parser_else_body(c_parser * parser,const token_indent_info & else_tinfo,vec<tree> * chain)5668 c_parser_else_body (c_parser *parser, const token_indent_info &else_tinfo,
5669 vec<tree> *chain)
5670 {
5671 location_t body_loc = c_parser_peek_token (parser)->location;
5672 tree block = c_begin_compound_stmt (flag_isoc99);
5673 token_indent_info body_tinfo
5674 = get_token_indent_info (c_parser_peek_token (parser));
5675 location_t body_loc_after_labels = UNKNOWN_LOCATION;
5676
5677 c_parser_all_labels (parser);
5678 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
5679 {
5680 location_t loc = c_parser_peek_token (parser)->location;
5681 warning_at (loc,
5682 OPT_Wempty_body,
5683 "suggest braces around empty body in an %<else%> statement");
5684 add_stmt (build_empty_stmt (loc));
5685 c_parser_consume_token (parser);
5686 }
5687 else
5688 {
5689 if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE))
5690 body_loc_after_labels = c_parser_peek_token (parser)->location;
5691 c_parser_statement_after_labels (parser, NULL, chain);
5692 }
5693
5694 token_indent_info next_tinfo
5695 = get_token_indent_info (c_parser_peek_token (parser));
5696 warn_for_misleading_indentation (else_tinfo, body_tinfo, next_tinfo);
5697 if (body_loc_after_labels != UNKNOWN_LOCATION
5698 && next_tinfo.type != CPP_SEMICOLON)
5699 warn_for_multistatement_macros (body_loc_after_labels, next_tinfo.location,
5700 else_tinfo.location, RID_ELSE);
5701
5702 return c_end_compound_stmt (body_loc, block, flag_isoc99);
5703 }
5704
5705 /* We might need to reclassify any previously-lexed identifier, e.g.
5706 when we've left a for loop with an if-statement without else in the
5707 body - we might have used a wrong scope for the token. See PR67784. */
5708
5709 static void
c_parser_maybe_reclassify_token(c_parser * parser)5710 c_parser_maybe_reclassify_token (c_parser *parser)
5711 {
5712 if (c_parser_next_token_is (parser, CPP_NAME))
5713 {
5714 c_token *token = c_parser_peek_token (parser);
5715
5716 if (token->id_kind != C_ID_CLASSNAME)
5717 {
5718 tree decl = lookup_name (token->value);
5719
5720 token->id_kind = C_ID_ID;
5721 if (decl)
5722 {
5723 if (TREE_CODE (decl) == TYPE_DECL)
5724 token->id_kind = C_ID_TYPENAME;
5725 }
5726 else if (c_dialect_objc ())
5727 {
5728 tree objc_interface_decl = objc_is_class_name (token->value);
5729 /* Objective-C class names are in the same namespace as
5730 variables and typedefs, and hence are shadowed by local
5731 declarations. */
5732 if (objc_interface_decl)
5733 {
5734 token->value = objc_interface_decl;
5735 token->id_kind = C_ID_CLASSNAME;
5736 }
5737 }
5738 }
5739 }
5740 }
5741
5742 /* Parse an if statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
5743
5744 if-statement:
5745 if ( expression ) statement
5746 if ( expression ) statement else statement
5747
5748 CHAIN is a vector of if-else-if conditions.
5749 IF_P is used to track whether there's a (possibly labeled) if statement
5750 which is not enclosed in braces and has an else clause. This is used to
5751 implement -Wparentheses. */
5752
5753 static void
c_parser_if_statement(c_parser * parser,bool * if_p,vec<tree> * chain)5754 c_parser_if_statement (c_parser *parser, bool *if_p, vec<tree> *chain)
5755 {
5756 tree block;
5757 location_t loc;
5758 tree cond;
5759 bool nested_if = false;
5760 tree first_body, second_body;
5761 bool in_if_block;
5762
5763 gcc_assert (c_parser_next_token_is_keyword (parser, RID_IF));
5764 token_indent_info if_tinfo
5765 = get_token_indent_info (c_parser_peek_token (parser));
5766 c_parser_consume_token (parser);
5767 block = c_begin_compound_stmt (flag_isoc99);
5768 loc = c_parser_peek_token (parser)->location;
5769 cond = c_parser_paren_condition (parser);
5770 in_if_block = parser->in_if_block;
5771 parser->in_if_block = true;
5772 first_body = c_parser_if_body (parser, &nested_if, if_tinfo);
5773 parser->in_if_block = in_if_block;
5774
5775 if (warn_duplicated_cond)
5776 warn_duplicated_cond_add_or_warn (EXPR_LOCATION (cond), cond, &chain);
5777
5778 if (c_parser_next_token_is_keyword (parser, RID_ELSE))
5779 {
5780 token_indent_info else_tinfo
5781 = get_token_indent_info (c_parser_peek_token (parser));
5782 c_parser_consume_token (parser);
5783 if (warn_duplicated_cond)
5784 {
5785 if (c_parser_next_token_is_keyword (parser, RID_IF)
5786 && chain == NULL)
5787 {
5788 /* We've got "if (COND) else if (COND2)". Start the
5789 condition chain and add COND as the first element. */
5790 chain = new vec<tree> ();
5791 if (!CONSTANT_CLASS_P (cond) && !TREE_SIDE_EFFECTS (cond))
5792 chain->safe_push (cond);
5793 }
5794 else if (!c_parser_next_token_is_keyword (parser, RID_IF))
5795 {
5796 /* This is if-else without subsequent if. Zap the condition
5797 chain; we would have already warned at this point. */
5798 delete chain;
5799 chain = NULL;
5800 }
5801 }
5802 second_body = c_parser_else_body (parser, else_tinfo, chain);
5803 /* Set IF_P to true to indicate that this if statement has an
5804 else clause. This may trigger the Wparentheses warning
5805 below when we get back up to the parent if statement. */
5806 if (if_p != NULL)
5807 *if_p = true;
5808 }
5809 else
5810 {
5811 second_body = NULL_TREE;
5812
5813 /* Diagnose an ambiguous else if if-then-else is nested inside
5814 if-then. */
5815 if (nested_if)
5816 warning_at (loc, OPT_Wdangling_else,
5817 "suggest explicit braces to avoid ambiguous %<else%>");
5818
5819 if (warn_duplicated_cond)
5820 {
5821 /* This if statement does not have an else clause. We don't
5822 need the condition chain anymore. */
5823 delete chain;
5824 chain = NULL;
5825 }
5826 }
5827 c_finish_if_stmt (loc, cond, first_body, second_body);
5828 add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
5829
5830 c_parser_maybe_reclassify_token (parser);
5831 }
5832
5833 /* Parse a switch statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
5834
5835 switch-statement:
5836 switch (expression) statement
5837 */
5838
5839 static void
c_parser_switch_statement(c_parser * parser,bool * if_p)5840 c_parser_switch_statement (c_parser *parser, bool *if_p)
5841 {
5842 struct c_expr ce;
5843 tree block, expr, body, save_break;
5844 location_t switch_loc = c_parser_peek_token (parser)->location;
5845 location_t switch_cond_loc;
5846 gcc_assert (c_parser_next_token_is_keyword (parser, RID_SWITCH));
5847 c_parser_consume_token (parser);
5848 block = c_begin_compound_stmt (flag_isoc99);
5849 bool explicit_cast_p = false;
5850 matching_parens parens;
5851 if (parens.require_open (parser))
5852 {
5853 switch_cond_loc = c_parser_peek_token (parser)->location;
5854 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
5855 && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
5856 explicit_cast_p = true;
5857 ce = c_parser_expression (parser);
5858 ce = convert_lvalue_to_rvalue (switch_cond_loc, ce, true, false);
5859 expr = ce.value;
5860 /* ??? expr has no valid location? */
5861 parens.skip_until_found_close (parser);
5862 }
5863 else
5864 {
5865 switch_cond_loc = UNKNOWN_LOCATION;
5866 expr = error_mark_node;
5867 ce.original_type = error_mark_node;
5868 }
5869 c_start_case (switch_loc, switch_cond_loc, expr, explicit_cast_p);
5870 save_break = c_break_label;
5871 c_break_label = NULL_TREE;
5872 location_t loc_after_labels;
5873 bool open_brace_p = c_parser_peek_token (parser)->type == CPP_OPEN_BRACE;
5874 body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
5875 location_t next_loc = c_parser_peek_token (parser)->location;
5876 if (!open_brace_p && c_parser_peek_token (parser)->type != CPP_SEMICOLON)
5877 warn_for_multistatement_macros (loc_after_labels, next_loc, switch_loc,
5878 RID_SWITCH);
5879 if (c_break_label)
5880 {
5881 location_t here = c_parser_peek_token (parser)->location;
5882 tree t = build1 (LABEL_EXPR, void_type_node, c_break_label);
5883 SET_EXPR_LOCATION (t, here);
5884 SWITCH_BREAK_LABEL_P (c_break_label) = 1;
5885 append_to_statement_list_force (t, &body);
5886 }
5887 c_finish_case (body, ce.original_type);
5888 c_break_label = save_break;
5889 add_stmt (c_end_compound_stmt (switch_loc, block, flag_isoc99));
5890 c_parser_maybe_reclassify_token (parser);
5891 }
5892
5893 /* Parse a while statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
5894
5895 while-statement:
5896 while (expression) statement
5897
5898 IF_P is used to track whether there's a (possibly labeled) if statement
5899 which is not enclosed in braces and has an else clause. This is used to
5900 implement -Wparentheses. */
5901
5902 static void
c_parser_while_statement(c_parser * parser,bool ivdep,unsigned short unroll,bool * if_p)5903 c_parser_while_statement (c_parser *parser, bool ivdep, unsigned short unroll,
5904 bool *if_p)
5905 {
5906 tree block, cond, body, save_break, save_cont;
5907 location_t loc;
5908 gcc_assert (c_parser_next_token_is_keyword (parser, RID_WHILE));
5909 token_indent_info while_tinfo
5910 = get_token_indent_info (c_parser_peek_token (parser));
5911 c_parser_consume_token (parser);
5912 block = c_begin_compound_stmt (flag_isoc99);
5913 loc = c_parser_peek_token (parser)->location;
5914 cond = c_parser_paren_condition (parser);
5915 if (ivdep && cond != error_mark_node)
5916 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
5917 build_int_cst (integer_type_node,
5918 annot_expr_ivdep_kind),
5919 integer_zero_node);
5920 if (unroll && cond != error_mark_node)
5921 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
5922 build_int_cst (integer_type_node,
5923 annot_expr_unroll_kind),
5924 build_int_cst (integer_type_node, unroll));
5925 save_break = c_break_label;
5926 c_break_label = NULL_TREE;
5927 save_cont = c_cont_label;
5928 c_cont_label = NULL_TREE;
5929
5930 token_indent_info body_tinfo
5931 = get_token_indent_info (c_parser_peek_token (parser));
5932
5933 location_t loc_after_labels;
5934 bool open_brace = c_parser_next_token_is (parser, CPP_OPEN_BRACE);
5935 body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
5936 c_finish_loop (loc, cond, NULL, body, c_break_label, c_cont_label, true);
5937 add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
5938 c_parser_maybe_reclassify_token (parser);
5939
5940 token_indent_info next_tinfo
5941 = get_token_indent_info (c_parser_peek_token (parser));
5942 warn_for_misleading_indentation (while_tinfo, body_tinfo, next_tinfo);
5943
5944 if (next_tinfo.type != CPP_SEMICOLON && !open_brace)
5945 warn_for_multistatement_macros (loc_after_labels, next_tinfo.location,
5946 while_tinfo.location, RID_WHILE);
5947
5948 c_break_label = save_break;
5949 c_cont_label = save_cont;
5950 }
5951
5952 /* Parse a do statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
5953
5954 do-statement:
5955 do statement while ( expression ) ;
5956 */
5957
5958 static void
c_parser_do_statement(c_parser * parser,bool ivdep,unsigned short unroll)5959 c_parser_do_statement (c_parser *parser, bool ivdep, unsigned short unroll)
5960 {
5961 tree block, cond, body, save_break, save_cont, new_break, new_cont;
5962 location_t loc;
5963 gcc_assert (c_parser_next_token_is_keyword (parser, RID_DO));
5964 c_parser_consume_token (parser);
5965 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
5966 warning_at (c_parser_peek_token (parser)->location,
5967 OPT_Wempty_body,
5968 "suggest braces around empty body in %<do%> statement");
5969 block = c_begin_compound_stmt (flag_isoc99);
5970 loc = c_parser_peek_token (parser)->location;
5971 save_break = c_break_label;
5972 c_break_label = NULL_TREE;
5973 save_cont = c_cont_label;
5974 c_cont_label = NULL_TREE;
5975 body = c_parser_c99_block_statement (parser, NULL);
5976 c_parser_require_keyword (parser, RID_WHILE, "expected %<while%>");
5977 new_break = c_break_label;
5978 c_break_label = save_break;
5979 new_cont = c_cont_label;
5980 c_cont_label = save_cont;
5981 cond = c_parser_paren_condition (parser);
5982 if (ivdep && cond != error_mark_node)
5983 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
5984 build_int_cst (integer_type_node,
5985 annot_expr_ivdep_kind),
5986 integer_zero_node);
5987 if (unroll && cond != error_mark_node)
5988 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
5989 build_int_cst (integer_type_node,
5990 annot_expr_unroll_kind),
5991 build_int_cst (integer_type_node, unroll));
5992 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
5993 c_parser_skip_to_end_of_block_or_statement (parser);
5994 c_finish_loop (loc, cond, NULL, body, new_break, new_cont, false);
5995 add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
5996 }
5997
5998 /* Parse a for statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
5999
6000 for-statement:
6001 for ( expression[opt] ; expression[opt] ; expression[opt] ) statement
6002 for ( nested-declaration expression[opt] ; expression[opt] ) statement
6003
6004 The form with a declaration is new in C99.
6005
6006 ??? In accordance with the old parser, the declaration may be a
6007 nested function, which is then rejected in check_for_loop_decls,
6008 but does it make any sense for this to be included in the grammar?
6009 Note in particular that the nested function does not include a
6010 trailing ';', whereas the "declaration" production includes one.
6011 Also, can we reject bad declarations earlier and cheaper than
6012 check_for_loop_decls?
6013
6014 In Objective-C, there are two additional variants:
6015
6016 foreach-statement:
6017 for ( expression in expresssion ) statement
6018 for ( declaration in expression ) statement
6019
6020 This is inconsistent with C, because the second variant is allowed
6021 even if c99 is not enabled.
6022
6023 The rest of the comment documents these Objective-C foreach-statement.
6024
6025 Here is the canonical example of the first variant:
6026 for (object in array) { do something with object }
6027 we call the first expression ("object") the "object_expression" and
6028 the second expression ("array") the "collection_expression".
6029 object_expression must be an lvalue of type "id" (a generic Objective-C
6030 object) because the loop works by assigning to object_expression the
6031 various objects from the collection_expression. collection_expression
6032 must evaluate to something of type "id" which responds to the method
6033 countByEnumeratingWithState:objects:count:.
6034
6035 The canonical example of the second variant is:
6036 for (id object in array) { do something with object }
6037 which is completely equivalent to
6038 {
6039 id object;
6040 for (object in array) { do something with object }
6041 }
6042 Note that initizializing 'object' in some way (eg, "for ((object =
6043 xxx) in array) { do something with object }") is possibly
6044 technically valid, but completely pointless as 'object' will be
6045 assigned to something else as soon as the loop starts. We should
6046 most likely reject it (TODO).
6047
6048 The beginning of the Objective-C foreach-statement looks exactly
6049 like the beginning of the for-statement, and we can tell it is a
6050 foreach-statement only because the initial declaration or
6051 expression is terminated by 'in' instead of ';'.
6052
6053 IF_P is used to track whether there's a (possibly labeled) if statement
6054 which is not enclosed in braces and has an else clause. This is used to
6055 implement -Wparentheses. */
6056
6057 static void
c_parser_for_statement(c_parser * parser,bool ivdep,unsigned short unroll,bool * if_p)6058 c_parser_for_statement (c_parser *parser, bool ivdep, unsigned short unroll,
6059 bool *if_p)
6060 {
6061 tree block, cond, incr, save_break, save_cont, body;
6062 /* The following are only used when parsing an ObjC foreach statement. */
6063 tree object_expression;
6064 /* Silence the bogus uninitialized warning. */
6065 tree collection_expression = NULL;
6066 location_t loc = c_parser_peek_token (parser)->location;
6067 location_t for_loc = c_parser_peek_token (parser)->location;
6068 bool is_foreach_statement = false;
6069 gcc_assert (c_parser_next_token_is_keyword (parser, RID_FOR));
6070 token_indent_info for_tinfo
6071 = get_token_indent_info (c_parser_peek_token (parser));
6072 c_parser_consume_token (parser);
6073 /* Open a compound statement in Objective-C as well, just in case this is
6074 as foreach expression. */
6075 block = c_begin_compound_stmt (flag_isoc99 || c_dialect_objc ());
6076 cond = error_mark_node;
6077 incr = error_mark_node;
6078 matching_parens parens;
6079 if (parens.require_open (parser))
6080 {
6081 /* Parse the initialization declaration or expression. */
6082 object_expression = error_mark_node;
6083 parser->objc_could_be_foreach_context = c_dialect_objc ();
6084 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6085 {
6086 parser->objc_could_be_foreach_context = false;
6087 c_parser_consume_token (parser);
6088 c_finish_expr_stmt (loc, NULL_TREE);
6089 }
6090 else if (c_parser_next_tokens_start_declaration (parser))
6091 {
6092 c_parser_declaration_or_fndef (parser, true, true, true, true, true,
6093 &object_expression, vNULL);
6094 parser->objc_could_be_foreach_context = false;
6095
6096 if (c_parser_next_token_is_keyword (parser, RID_IN))
6097 {
6098 c_parser_consume_token (parser);
6099 is_foreach_statement = true;
6100 if (check_for_loop_decls (for_loc, true) == NULL_TREE)
6101 c_parser_error (parser, "multiple iterating variables in fast enumeration");
6102 }
6103 else
6104 check_for_loop_decls (for_loc, flag_isoc99);
6105 }
6106 else if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
6107 {
6108 /* __extension__ can start a declaration, but is also an
6109 unary operator that can start an expression. Consume all
6110 but the last of a possible series of __extension__ to
6111 determine which. */
6112 while (c_parser_peek_2nd_token (parser)->type == CPP_KEYWORD
6113 && (c_parser_peek_2nd_token (parser)->keyword
6114 == RID_EXTENSION))
6115 c_parser_consume_token (parser);
6116 if (c_token_starts_declaration (c_parser_peek_2nd_token (parser)))
6117 {
6118 int ext;
6119 ext = disable_extension_diagnostics ();
6120 c_parser_consume_token (parser);
6121 c_parser_declaration_or_fndef (parser, true, true, true, true,
6122 true, &object_expression, vNULL);
6123 parser->objc_could_be_foreach_context = false;
6124
6125 restore_extension_diagnostics (ext);
6126 if (c_parser_next_token_is_keyword (parser, RID_IN))
6127 {
6128 c_parser_consume_token (parser);
6129 is_foreach_statement = true;
6130 if (check_for_loop_decls (for_loc, true) == NULL_TREE)
6131 c_parser_error (parser, "multiple iterating variables in fast enumeration");
6132 }
6133 else
6134 check_for_loop_decls (for_loc, flag_isoc99);
6135 }
6136 else
6137 goto init_expr;
6138 }
6139 else
6140 {
6141 init_expr:
6142 {
6143 struct c_expr ce;
6144 tree init_expression;
6145 ce = c_parser_expression (parser);
6146 init_expression = ce.value;
6147 parser->objc_could_be_foreach_context = false;
6148 if (c_parser_next_token_is_keyword (parser, RID_IN))
6149 {
6150 c_parser_consume_token (parser);
6151 is_foreach_statement = true;
6152 if (! lvalue_p (init_expression))
6153 c_parser_error (parser, "invalid iterating variable in fast enumeration");
6154 object_expression = c_fully_fold (init_expression, false, NULL);
6155 }
6156 else
6157 {
6158 ce = convert_lvalue_to_rvalue (loc, ce, true, false);
6159 init_expression = ce.value;
6160 c_finish_expr_stmt (loc, init_expression);
6161 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
6162 }
6163 }
6164 }
6165 /* Parse the loop condition. In the case of a foreach
6166 statement, there is no loop condition. */
6167 gcc_assert (!parser->objc_could_be_foreach_context);
6168 if (!is_foreach_statement)
6169 {
6170 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6171 {
6172 if (ivdep)
6173 {
6174 c_parser_error (parser, "missing loop condition in loop with "
6175 "%<GCC ivdep%> pragma");
6176 cond = error_mark_node;
6177 }
6178 else if (unroll)
6179 {
6180 c_parser_error (parser, "missing loop condition in loop with "
6181 "%<GCC unroll%> pragma");
6182 cond = error_mark_node;
6183 }
6184 else
6185 {
6186 c_parser_consume_token (parser);
6187 cond = NULL_TREE;
6188 }
6189 }
6190 else
6191 {
6192 cond = c_parser_condition (parser);
6193 c_parser_skip_until_found (parser, CPP_SEMICOLON,
6194 "expected %<;%>");
6195 }
6196 if (ivdep && cond != error_mark_node)
6197 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6198 build_int_cst (integer_type_node,
6199 annot_expr_ivdep_kind),
6200 integer_zero_node);
6201 if (unroll && cond != error_mark_node)
6202 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6203 build_int_cst (integer_type_node,
6204 annot_expr_unroll_kind),
6205 build_int_cst (integer_type_node, unroll));
6206 }
6207 /* Parse the increment expression (the third expression in a
6208 for-statement). In the case of a foreach-statement, this is
6209 the expression that follows the 'in'. */
6210 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
6211 {
6212 if (is_foreach_statement)
6213 {
6214 c_parser_error (parser, "missing collection in fast enumeration");
6215 collection_expression = error_mark_node;
6216 }
6217 else
6218 incr = c_process_expr_stmt (loc, NULL_TREE);
6219 }
6220 else
6221 {
6222 if (is_foreach_statement)
6223 collection_expression = c_fully_fold (c_parser_expression (parser).value,
6224 false, NULL);
6225 else
6226 {
6227 struct c_expr ce = c_parser_expression (parser);
6228 ce = convert_lvalue_to_rvalue (loc, ce, true, false);
6229 incr = c_process_expr_stmt (loc, ce.value);
6230 }
6231 }
6232 parens.skip_until_found_close (parser);
6233 }
6234 save_break = c_break_label;
6235 c_break_label = NULL_TREE;
6236 save_cont = c_cont_label;
6237 c_cont_label = NULL_TREE;
6238
6239 token_indent_info body_tinfo
6240 = get_token_indent_info (c_parser_peek_token (parser));
6241
6242 location_t loc_after_labels;
6243 bool open_brace = c_parser_next_token_is (parser, CPP_OPEN_BRACE);
6244 body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
6245
6246 if (is_foreach_statement)
6247 objc_finish_foreach_loop (loc, object_expression, collection_expression, body, c_break_label, c_cont_label);
6248 else
6249 c_finish_loop (loc, cond, incr, body, c_break_label, c_cont_label, true);
6250 add_stmt (c_end_compound_stmt (loc, block, flag_isoc99 || c_dialect_objc ()));
6251 c_parser_maybe_reclassify_token (parser);
6252
6253 token_indent_info next_tinfo
6254 = get_token_indent_info (c_parser_peek_token (parser));
6255 warn_for_misleading_indentation (for_tinfo, body_tinfo, next_tinfo);
6256
6257 if (next_tinfo.type != CPP_SEMICOLON && !open_brace)
6258 warn_for_multistatement_macros (loc_after_labels, next_tinfo.location,
6259 for_tinfo.location, RID_FOR);
6260
6261 c_break_label = save_break;
6262 c_cont_label = save_cont;
6263 }
6264
6265 /* Parse an asm statement, a GNU extension. This is a full-blown asm
6266 statement with inputs, outputs, clobbers, and volatile, inline, and goto
6267 tags allowed.
6268
6269 asm-qualifier:
6270 volatile
6271 inline
6272 goto
6273
6274 asm-qualifier-list:
6275 asm-qualifier-list asm-qualifier
6276 asm-qualifier
6277
6278 asm-statement:
6279 asm asm-qualifier-list[opt] ( asm-argument ) ;
6280
6281 asm-argument:
6282 asm-string-literal
6283 asm-string-literal : asm-operands[opt]
6284 asm-string-literal : asm-operands[opt] : asm-operands[opt]
6285 asm-string-literal : asm-operands[opt] : asm-operands[opt] \
6286 : asm-clobbers[opt]
6287 asm-string-literal : : asm-operands[opt] : asm-clobbers[opt] \
6288 : asm-goto-operands
6289
6290 The form with asm-goto-operands is valid if and only if the
6291 asm-qualifier-list contains goto, and is the only allowed form in that case.
6292 Duplicate asm-qualifiers are not allowed. */
6293
6294 static tree
c_parser_asm_statement(c_parser * parser)6295 c_parser_asm_statement (c_parser *parser)
6296 {
6297 tree str, outputs, inputs, clobbers, labels, ret;
6298 bool simple;
6299 location_t asm_loc = c_parser_peek_token (parser)->location;
6300 int section, nsections;
6301
6302 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
6303 c_parser_consume_token (parser);
6304
6305 /* Handle the asm-qualifier-list. */
6306 location_t volatile_loc = UNKNOWN_LOCATION;
6307 location_t inline_loc = UNKNOWN_LOCATION;
6308 location_t goto_loc = UNKNOWN_LOCATION;
6309 for (;;)
6310 {
6311 c_token *token = c_parser_peek_token (parser);
6312 location_t loc = token->location;
6313 switch (token->keyword)
6314 {
6315 case RID_VOLATILE:
6316 if (volatile_loc)
6317 {
6318 error_at (loc, "duplicate asm qualifier %qE", token->value);
6319 inform (volatile_loc, "first seen here");
6320 }
6321 else
6322 volatile_loc = loc;
6323 c_parser_consume_token (parser);
6324 continue;
6325
6326 case RID_INLINE:
6327 if (inline_loc)
6328 {
6329 error_at (loc, "duplicate asm qualifier %qE", token->value);
6330 inform (inline_loc, "first seen here");
6331 }
6332 else
6333 inline_loc = loc;
6334 c_parser_consume_token (parser);
6335 continue;
6336
6337 case RID_GOTO:
6338 if (goto_loc)
6339 {
6340 error_at (loc, "duplicate asm qualifier %qE", token->value);
6341 inform (goto_loc, "first seen here");
6342 }
6343 else
6344 goto_loc = loc;
6345 c_parser_consume_token (parser);
6346 continue;
6347
6348 case RID_CONST:
6349 case RID_RESTRICT:
6350 warning_at (loc, 0, "%qE is not an asm qualifier", token->value);
6351 c_parser_consume_token (parser);
6352 continue;
6353
6354 default:
6355 break;
6356 }
6357 break;
6358 }
6359
6360 bool is_volatile = (volatile_loc != UNKNOWN_LOCATION);
6361 bool is_inline = (inline_loc != UNKNOWN_LOCATION);
6362 bool is_goto = (goto_loc != UNKNOWN_LOCATION);
6363
6364 /* ??? Follow the C++ parser rather than using the
6365 lex_untranslated_string kludge. */
6366 parser->lex_untranslated_string = true;
6367 ret = NULL;
6368
6369 matching_parens parens;
6370 if (!parens.require_open (parser))
6371 goto error;
6372
6373 str = c_parser_asm_string_literal (parser);
6374 if (str == NULL_TREE)
6375 goto error_close_paren;
6376
6377 simple = true;
6378 outputs = NULL_TREE;
6379 inputs = NULL_TREE;
6380 clobbers = NULL_TREE;
6381 labels = NULL_TREE;
6382
6383 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN) && !is_goto)
6384 goto done_asm;
6385
6386 /* Parse each colon-delimited section of operands. */
6387 nsections = 3 + is_goto;
6388 for (section = 0; section < nsections; ++section)
6389 {
6390 if (!c_parser_require (parser, CPP_COLON,
6391 is_goto
6392 ? G_("expected %<:%>")
6393 : G_("expected %<:%> or %<)%>"),
6394 UNKNOWN_LOCATION, is_goto))
6395 goto error_close_paren;
6396
6397 /* Once past any colon, we're no longer a simple asm. */
6398 simple = false;
6399
6400 if ((!c_parser_next_token_is (parser, CPP_COLON)
6401 && !c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
6402 || section == 3)
6403 switch (section)
6404 {
6405 case 0:
6406 /* For asm goto, we don't allow output operands, but reserve
6407 the slot for a future extension that does allow them. */
6408 if (!is_goto)
6409 outputs = c_parser_asm_operands (parser);
6410 break;
6411 case 1:
6412 inputs = c_parser_asm_operands (parser);
6413 break;
6414 case 2:
6415 clobbers = c_parser_asm_clobbers (parser);
6416 break;
6417 case 3:
6418 labels = c_parser_asm_goto_operands (parser);
6419 break;
6420 default:
6421 gcc_unreachable ();
6422 }
6423
6424 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN) && !is_goto)
6425 goto done_asm;
6426 }
6427
6428 done_asm:
6429 if (!parens.require_close (parser))
6430 {
6431 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
6432 goto error;
6433 }
6434
6435 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
6436 c_parser_skip_to_end_of_block_or_statement (parser);
6437
6438 ret = build_asm_stmt (is_volatile,
6439 build_asm_expr (asm_loc, str, outputs, inputs,
6440 clobbers, labels, simple, is_inline));
6441
6442 error:
6443 parser->lex_untranslated_string = false;
6444 return ret;
6445
6446 error_close_paren:
6447 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
6448 goto error;
6449 }
6450
6451 /* Parse asm operands, a GNU extension.
6452
6453 asm-operands:
6454 asm-operand
6455 asm-operands , asm-operand
6456
6457 asm-operand:
6458 asm-string-literal ( expression )
6459 [ identifier ] asm-string-literal ( expression )
6460 */
6461
6462 static tree
c_parser_asm_operands(c_parser * parser)6463 c_parser_asm_operands (c_parser *parser)
6464 {
6465 tree list = NULL_TREE;
6466 while (true)
6467 {
6468 tree name, str;
6469 struct c_expr expr;
6470 if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
6471 {
6472 c_parser_consume_token (parser);
6473 if (c_parser_next_token_is (parser, CPP_NAME))
6474 {
6475 tree id = c_parser_peek_token (parser)->value;
6476 c_parser_consume_token (parser);
6477 name = build_string (IDENTIFIER_LENGTH (id),
6478 IDENTIFIER_POINTER (id));
6479 }
6480 else
6481 {
6482 c_parser_error (parser, "expected identifier");
6483 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL);
6484 return NULL_TREE;
6485 }
6486 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
6487 "expected %<]%>");
6488 }
6489 else
6490 name = NULL_TREE;
6491 str = c_parser_asm_string_literal (parser);
6492 if (str == NULL_TREE)
6493 return NULL_TREE;
6494 parser->lex_untranslated_string = false;
6495 matching_parens parens;
6496 if (!parens.require_open (parser))
6497 {
6498 parser->lex_untranslated_string = true;
6499 return NULL_TREE;
6500 }
6501 expr = c_parser_expression (parser);
6502 mark_exp_read (expr.value);
6503 parser->lex_untranslated_string = true;
6504 if (!parens.require_close (parser))
6505 {
6506 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
6507 return NULL_TREE;
6508 }
6509 list = chainon (list, build_tree_list (build_tree_list (name, str),
6510 expr.value));
6511 if (c_parser_next_token_is (parser, CPP_COMMA))
6512 c_parser_consume_token (parser);
6513 else
6514 break;
6515 }
6516 return list;
6517 }
6518
6519 /* Parse asm clobbers, a GNU extension.
6520
6521 asm-clobbers:
6522 asm-string-literal
6523 asm-clobbers , asm-string-literal
6524 */
6525
6526 static tree
c_parser_asm_clobbers(c_parser * parser)6527 c_parser_asm_clobbers (c_parser *parser)
6528 {
6529 tree list = NULL_TREE;
6530 while (true)
6531 {
6532 tree str = c_parser_asm_string_literal (parser);
6533 if (str)
6534 list = tree_cons (NULL_TREE, str, list);
6535 else
6536 return NULL_TREE;
6537 if (c_parser_next_token_is (parser, CPP_COMMA))
6538 c_parser_consume_token (parser);
6539 else
6540 break;
6541 }
6542 return list;
6543 }
6544
6545 /* Parse asm goto labels, a GNU extension.
6546
6547 asm-goto-operands:
6548 identifier
6549 asm-goto-operands , identifier
6550 */
6551
6552 static tree
c_parser_asm_goto_operands(c_parser * parser)6553 c_parser_asm_goto_operands (c_parser *parser)
6554 {
6555 tree list = NULL_TREE;
6556 while (true)
6557 {
6558 tree name, label;
6559
6560 if (c_parser_next_token_is (parser, CPP_NAME))
6561 {
6562 c_token *tok = c_parser_peek_token (parser);
6563 name = tok->value;
6564 label = lookup_label_for_goto (tok->location, name);
6565 c_parser_consume_token (parser);
6566 TREE_USED (label) = 1;
6567 }
6568 else
6569 {
6570 c_parser_error (parser, "expected identifier");
6571 return NULL_TREE;
6572 }
6573
6574 name = build_string (IDENTIFIER_LENGTH (name),
6575 IDENTIFIER_POINTER (name));
6576 list = tree_cons (name, label, list);
6577 if (c_parser_next_token_is (parser, CPP_COMMA))
6578 c_parser_consume_token (parser);
6579 else
6580 return nreverse (list);
6581 }
6582 }
6583
6584 /* Parse an expression other than a compound expression; that is, an
6585 assignment expression (C90 6.3.16, C99 6.5.16, C11 6.5.16). If
6586 AFTER is not NULL then it is an Objective-C message expression which
6587 is the primary-expression starting the expression as an initializer.
6588
6589 assignment-expression:
6590 conditional-expression
6591 unary-expression assignment-operator assignment-expression
6592
6593 assignment-operator: one of
6594 = *= /= %= += -= <<= >>= &= ^= |=
6595
6596 In GNU C we accept any conditional expression on the LHS and
6597 diagnose the invalid lvalue rather than producing a syntax
6598 error. */
6599
6600 static struct c_expr
c_parser_expr_no_commas(c_parser * parser,struct c_expr * after,tree omp_atomic_lhs)6601 c_parser_expr_no_commas (c_parser *parser, struct c_expr *after,
6602 tree omp_atomic_lhs)
6603 {
6604 struct c_expr lhs, rhs, ret;
6605 enum tree_code code;
6606 location_t op_location, exp_location;
6607 gcc_assert (!after || c_dialect_objc ());
6608 lhs = c_parser_conditional_expression (parser, after, omp_atomic_lhs);
6609 op_location = c_parser_peek_token (parser)->location;
6610 switch (c_parser_peek_token (parser)->type)
6611 {
6612 case CPP_EQ:
6613 code = NOP_EXPR;
6614 break;
6615 case CPP_MULT_EQ:
6616 code = MULT_EXPR;
6617 break;
6618 case CPP_DIV_EQ:
6619 code = TRUNC_DIV_EXPR;
6620 break;
6621 case CPP_MOD_EQ:
6622 code = TRUNC_MOD_EXPR;
6623 break;
6624 case CPP_PLUS_EQ:
6625 code = PLUS_EXPR;
6626 break;
6627 case CPP_MINUS_EQ:
6628 code = MINUS_EXPR;
6629 break;
6630 case CPP_LSHIFT_EQ:
6631 code = LSHIFT_EXPR;
6632 break;
6633 case CPP_RSHIFT_EQ:
6634 code = RSHIFT_EXPR;
6635 break;
6636 case CPP_AND_EQ:
6637 code = BIT_AND_EXPR;
6638 break;
6639 case CPP_XOR_EQ:
6640 code = BIT_XOR_EXPR;
6641 break;
6642 case CPP_OR_EQ:
6643 code = BIT_IOR_EXPR;
6644 break;
6645 default:
6646 return lhs;
6647 }
6648 c_parser_consume_token (parser);
6649 exp_location = c_parser_peek_token (parser)->location;
6650 rhs = c_parser_expr_no_commas (parser, NULL);
6651 rhs = convert_lvalue_to_rvalue (exp_location, rhs, true, true);
6652
6653 ret.value = build_modify_expr (op_location, lhs.value, lhs.original_type,
6654 code, exp_location, rhs.value,
6655 rhs.original_type);
6656 set_c_expr_source_range (&ret, lhs.get_start (), rhs.get_finish ());
6657 if (code == NOP_EXPR)
6658 ret.original_code = MODIFY_EXPR;
6659 else
6660 {
6661 TREE_NO_WARNING (ret.value) = 1;
6662 ret.original_code = ERROR_MARK;
6663 }
6664 ret.original_type = NULL;
6665 return ret;
6666 }
6667
6668 /* Parse a conditional expression (C90 6.3.15, C99 6.5.15, C11 6.5.15). If
6669 AFTER is not NULL then it is an Objective-C message expression which is
6670 the primary-expression starting the expression as an initializer.
6671
6672 conditional-expression:
6673 logical-OR-expression
6674 logical-OR-expression ? expression : conditional-expression
6675
6676 GNU extensions:
6677
6678 conditional-expression:
6679 logical-OR-expression ? : conditional-expression
6680 */
6681
6682 static struct c_expr
c_parser_conditional_expression(c_parser * parser,struct c_expr * after,tree omp_atomic_lhs)6683 c_parser_conditional_expression (c_parser *parser, struct c_expr *after,
6684 tree omp_atomic_lhs)
6685 {
6686 struct c_expr cond, exp1, exp2, ret;
6687 location_t start, cond_loc, colon_loc;
6688
6689 gcc_assert (!after || c_dialect_objc ());
6690
6691 cond = c_parser_binary_expression (parser, after, omp_atomic_lhs);
6692
6693 if (c_parser_next_token_is_not (parser, CPP_QUERY))
6694 return cond;
6695 if (cond.value != error_mark_node)
6696 start = cond.get_start ();
6697 else
6698 start = UNKNOWN_LOCATION;
6699 cond_loc = c_parser_peek_token (parser)->location;
6700 cond = convert_lvalue_to_rvalue (cond_loc, cond, true, true);
6701 c_parser_consume_token (parser);
6702 if (c_parser_next_token_is (parser, CPP_COLON))
6703 {
6704 tree eptype = NULL_TREE;
6705
6706 location_t middle_loc = c_parser_peek_token (parser)->location;
6707 pedwarn (middle_loc, OPT_Wpedantic,
6708 "ISO C forbids omitting the middle term of a ?: expression");
6709 if (TREE_CODE (cond.value) == EXCESS_PRECISION_EXPR)
6710 {
6711 eptype = TREE_TYPE (cond.value);
6712 cond.value = TREE_OPERAND (cond.value, 0);
6713 }
6714 tree e = cond.value;
6715 while (TREE_CODE (e) == COMPOUND_EXPR)
6716 e = TREE_OPERAND (e, 1);
6717 warn_for_omitted_condop (middle_loc, e);
6718 /* Make sure first operand is calculated only once. */
6719 exp1.value = save_expr (default_conversion (cond.value));
6720 if (eptype)
6721 exp1.value = build1 (EXCESS_PRECISION_EXPR, eptype, exp1.value);
6722 exp1.original_type = NULL;
6723 exp1.src_range = cond.src_range;
6724 cond.value = c_objc_common_truthvalue_conversion (cond_loc, exp1.value);
6725 c_inhibit_evaluation_warnings += cond.value == truthvalue_true_node;
6726 }
6727 else
6728 {
6729 cond.value
6730 = c_objc_common_truthvalue_conversion
6731 (cond_loc, default_conversion (cond.value));
6732 c_inhibit_evaluation_warnings += cond.value == truthvalue_false_node;
6733 exp1 = c_parser_expression_conv (parser);
6734 mark_exp_read (exp1.value);
6735 c_inhibit_evaluation_warnings +=
6736 ((cond.value == truthvalue_true_node)
6737 - (cond.value == truthvalue_false_node));
6738 }
6739
6740 colon_loc = c_parser_peek_token (parser)->location;
6741 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
6742 {
6743 c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node;
6744 ret.set_error ();
6745 ret.original_code = ERROR_MARK;
6746 ret.original_type = NULL;
6747 return ret;
6748 }
6749 {
6750 location_t exp2_loc = c_parser_peek_token (parser)->location;
6751 exp2 = c_parser_conditional_expression (parser, NULL, NULL_TREE);
6752 exp2 = convert_lvalue_to_rvalue (exp2_loc, exp2, true, true);
6753 }
6754 c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node;
6755 location_t loc1 = make_location (exp1.get_start (), exp1.src_range);
6756 location_t loc2 = make_location (exp2.get_start (), exp2.src_range);
6757 ret.value = build_conditional_expr (colon_loc, cond.value,
6758 cond.original_code == C_MAYBE_CONST_EXPR,
6759 exp1.value, exp1.original_type, loc1,
6760 exp2.value, exp2.original_type, loc2);
6761 ret.original_code = ERROR_MARK;
6762 if (exp1.value == error_mark_node || exp2.value == error_mark_node)
6763 ret.original_type = NULL;
6764 else
6765 {
6766 tree t1, t2;
6767
6768 /* If both sides are enum type, the default conversion will have
6769 made the type of the result be an integer type. We want to
6770 remember the enum types we started with. */
6771 t1 = exp1.original_type ? exp1.original_type : TREE_TYPE (exp1.value);
6772 t2 = exp2.original_type ? exp2.original_type : TREE_TYPE (exp2.value);
6773 ret.original_type = ((t1 != error_mark_node
6774 && t2 != error_mark_node
6775 && (TYPE_MAIN_VARIANT (t1)
6776 == TYPE_MAIN_VARIANT (t2)))
6777 ? t1
6778 : NULL);
6779 }
6780 set_c_expr_source_range (&ret, start, exp2.get_finish ());
6781 return ret;
6782 }
6783
6784 /* Parse a binary expression; that is, a logical-OR-expression (C90
6785 6.3.5-6.3.14, C99 6.5.5-6.5.14, C11 6.5.5-6.5.14). If AFTER is not
6786 NULL then it is an Objective-C message expression which is the
6787 primary-expression starting the expression as an initializer.
6788
6789 OMP_ATOMIC_LHS is NULL, unless parsing OpenMP #pragma omp atomic,
6790 when it should be the unfolded lhs. In a valid OpenMP source,
6791 one of the operands of the toplevel binary expression must be equal
6792 to it. In that case, just return a build2 created binary operation
6793 rather than result of parser_build_binary_op.
6794
6795 multiplicative-expression:
6796 cast-expression
6797 multiplicative-expression * cast-expression
6798 multiplicative-expression / cast-expression
6799 multiplicative-expression % cast-expression
6800
6801 additive-expression:
6802 multiplicative-expression
6803 additive-expression + multiplicative-expression
6804 additive-expression - multiplicative-expression
6805
6806 shift-expression:
6807 additive-expression
6808 shift-expression << additive-expression
6809 shift-expression >> additive-expression
6810
6811 relational-expression:
6812 shift-expression
6813 relational-expression < shift-expression
6814 relational-expression > shift-expression
6815 relational-expression <= shift-expression
6816 relational-expression >= shift-expression
6817
6818 equality-expression:
6819 relational-expression
6820 equality-expression == relational-expression
6821 equality-expression != relational-expression
6822
6823 AND-expression:
6824 equality-expression
6825 AND-expression & equality-expression
6826
6827 exclusive-OR-expression:
6828 AND-expression
6829 exclusive-OR-expression ^ AND-expression
6830
6831 inclusive-OR-expression:
6832 exclusive-OR-expression
6833 inclusive-OR-expression | exclusive-OR-expression
6834
6835 logical-AND-expression:
6836 inclusive-OR-expression
6837 logical-AND-expression && inclusive-OR-expression
6838
6839 logical-OR-expression:
6840 logical-AND-expression
6841 logical-OR-expression || logical-AND-expression
6842 */
6843
6844 static struct c_expr
c_parser_binary_expression(c_parser * parser,struct c_expr * after,tree omp_atomic_lhs)6845 c_parser_binary_expression (c_parser *parser, struct c_expr *after,
6846 tree omp_atomic_lhs)
6847 {
6848 /* A binary expression is parsed using operator-precedence parsing,
6849 with the operands being cast expressions. All the binary
6850 operators are left-associative. Thus a binary expression is of
6851 form:
6852
6853 E0 op1 E1 op2 E2 ...
6854
6855 which we represent on a stack. On the stack, the precedence
6856 levels are strictly increasing. When a new operator is
6857 encountered of higher precedence than that at the top of the
6858 stack, it is pushed; its LHS is the top expression, and its RHS
6859 is everything parsed until it is popped. When a new operator is
6860 encountered with precedence less than or equal to that at the top
6861 of the stack, triples E[i-1] op[i] E[i] are popped and replaced
6862 by the result of the operation until the operator at the top of
6863 the stack has lower precedence than the new operator or there is
6864 only one element on the stack; then the top expression is the LHS
6865 of the new operator. In the case of logical AND and OR
6866 expressions, we also need to adjust c_inhibit_evaluation_warnings
6867 as appropriate when the operators are pushed and popped. */
6868
6869 struct {
6870 /* The expression at this stack level. */
6871 struct c_expr expr;
6872 /* The precedence of the operator on its left, PREC_NONE at the
6873 bottom of the stack. */
6874 enum c_parser_prec prec;
6875 /* The operation on its left. */
6876 enum tree_code op;
6877 /* The source location of this operation. */
6878 location_t loc;
6879 /* The sizeof argument if expr.original_code == SIZEOF_EXPR. */
6880 tree sizeof_arg;
6881 } stack[NUM_PRECS];
6882 int sp;
6883 /* Location of the binary operator. */
6884 location_t binary_loc = UNKNOWN_LOCATION; /* Quiet warning. */
6885 #define POP \
6886 do { \
6887 switch (stack[sp].op) \
6888 { \
6889 case TRUTH_ANDIF_EXPR: \
6890 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
6891 == truthvalue_false_node); \
6892 break; \
6893 case TRUTH_ORIF_EXPR: \
6894 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
6895 == truthvalue_true_node); \
6896 break; \
6897 case TRUNC_DIV_EXPR: \
6898 if (stack[sp - 1].expr.original_code == SIZEOF_EXPR \
6899 && stack[sp].expr.original_code == SIZEOF_EXPR) \
6900 { \
6901 tree type0 = stack[sp - 1].sizeof_arg; \
6902 tree type1 = stack[sp].sizeof_arg; \
6903 tree first_arg = type0; \
6904 if (!TYPE_P (type0)) \
6905 type0 = TREE_TYPE (type0); \
6906 if (!TYPE_P (type1)) \
6907 type1 = TREE_TYPE (type1); \
6908 if (POINTER_TYPE_P (type0) \
6909 && comptypes (TREE_TYPE (type0), type1) \
6910 && !(TREE_CODE (first_arg) == PARM_DECL \
6911 && C_ARRAY_PARAMETER (first_arg) \
6912 && warn_sizeof_array_argument)) \
6913 if (warning_at (stack[sp].loc, OPT_Wsizeof_pointer_div, \
6914 "division %<sizeof (%T) / sizeof (%T)%> does " \
6915 "not compute the number of array elements", \
6916 type0, type1)) \
6917 if (DECL_P (first_arg)) \
6918 inform (DECL_SOURCE_LOCATION (first_arg), \
6919 "first %<sizeof%> operand was declared here"); \
6920 } \
6921 break; \
6922 default: \
6923 break; \
6924 } \
6925 stack[sp - 1].expr \
6926 = convert_lvalue_to_rvalue (stack[sp - 1].loc, \
6927 stack[sp - 1].expr, true, true); \
6928 stack[sp].expr \
6929 = convert_lvalue_to_rvalue (stack[sp].loc, \
6930 stack[sp].expr, true, true); \
6931 if (__builtin_expect (omp_atomic_lhs != NULL_TREE, 0) && sp == 1 \
6932 && c_parser_peek_token (parser)->type == CPP_SEMICOLON \
6933 && ((1 << stack[sp].prec) \
6934 & ((1 << PREC_BITOR) | (1 << PREC_BITXOR) | (1 << PREC_BITAND) \
6935 | (1 << PREC_SHIFT) | (1 << PREC_ADD) | (1 << PREC_MULT))) \
6936 && stack[sp].op != TRUNC_MOD_EXPR \
6937 && stack[0].expr.value != error_mark_node \
6938 && stack[1].expr.value != error_mark_node \
6939 && (c_tree_equal (stack[0].expr.value, omp_atomic_lhs) \
6940 || c_tree_equal (stack[1].expr.value, omp_atomic_lhs))) \
6941 stack[0].expr.value \
6942 = build2 (stack[1].op, TREE_TYPE (stack[0].expr.value), \
6943 stack[0].expr.value, stack[1].expr.value); \
6944 else \
6945 stack[sp - 1].expr = parser_build_binary_op (stack[sp].loc, \
6946 stack[sp].op, \
6947 stack[sp - 1].expr, \
6948 stack[sp].expr); \
6949 sp--; \
6950 } while (0)
6951 gcc_assert (!after || c_dialect_objc ());
6952 stack[0].loc = c_parser_peek_token (parser)->location;
6953 stack[0].expr = c_parser_cast_expression (parser, after);
6954 stack[0].prec = PREC_NONE;
6955 stack[0].sizeof_arg = c_last_sizeof_arg;
6956 sp = 0;
6957 while (true)
6958 {
6959 enum c_parser_prec oprec;
6960 enum tree_code ocode;
6961 source_range src_range;
6962 if (parser->error)
6963 goto out;
6964 switch (c_parser_peek_token (parser)->type)
6965 {
6966 case CPP_MULT:
6967 oprec = PREC_MULT;
6968 ocode = MULT_EXPR;
6969 break;
6970 case CPP_DIV:
6971 oprec = PREC_MULT;
6972 ocode = TRUNC_DIV_EXPR;
6973 break;
6974 case CPP_MOD:
6975 oprec = PREC_MULT;
6976 ocode = TRUNC_MOD_EXPR;
6977 break;
6978 case CPP_PLUS:
6979 oprec = PREC_ADD;
6980 ocode = PLUS_EXPR;
6981 break;
6982 case CPP_MINUS:
6983 oprec = PREC_ADD;
6984 ocode = MINUS_EXPR;
6985 break;
6986 case CPP_LSHIFT:
6987 oprec = PREC_SHIFT;
6988 ocode = LSHIFT_EXPR;
6989 break;
6990 case CPP_RSHIFT:
6991 oprec = PREC_SHIFT;
6992 ocode = RSHIFT_EXPR;
6993 break;
6994 case CPP_LESS:
6995 oprec = PREC_REL;
6996 ocode = LT_EXPR;
6997 break;
6998 case CPP_GREATER:
6999 oprec = PREC_REL;
7000 ocode = GT_EXPR;
7001 break;
7002 case CPP_LESS_EQ:
7003 oprec = PREC_REL;
7004 ocode = LE_EXPR;
7005 break;
7006 case CPP_GREATER_EQ:
7007 oprec = PREC_REL;
7008 ocode = GE_EXPR;
7009 break;
7010 case CPP_EQ_EQ:
7011 oprec = PREC_EQ;
7012 ocode = EQ_EXPR;
7013 break;
7014 case CPP_NOT_EQ:
7015 oprec = PREC_EQ;
7016 ocode = NE_EXPR;
7017 break;
7018 case CPP_AND:
7019 oprec = PREC_BITAND;
7020 ocode = BIT_AND_EXPR;
7021 break;
7022 case CPP_XOR:
7023 oprec = PREC_BITXOR;
7024 ocode = BIT_XOR_EXPR;
7025 break;
7026 case CPP_OR:
7027 oprec = PREC_BITOR;
7028 ocode = BIT_IOR_EXPR;
7029 break;
7030 case CPP_AND_AND:
7031 oprec = PREC_LOGAND;
7032 ocode = TRUTH_ANDIF_EXPR;
7033 break;
7034 case CPP_OR_OR:
7035 oprec = PREC_LOGOR;
7036 ocode = TRUTH_ORIF_EXPR;
7037 break;
7038 default:
7039 /* Not a binary operator, so end of the binary
7040 expression. */
7041 goto out;
7042 }
7043 binary_loc = c_parser_peek_token (parser)->location;
7044 while (oprec <= stack[sp].prec)
7045 POP;
7046 c_parser_consume_token (parser);
7047 switch (ocode)
7048 {
7049 case TRUTH_ANDIF_EXPR:
7050 src_range = stack[sp].expr.src_range;
7051 stack[sp].expr
7052 = convert_lvalue_to_rvalue (stack[sp].loc,
7053 stack[sp].expr, true, true);
7054 stack[sp].expr.value = c_objc_common_truthvalue_conversion
7055 (stack[sp].loc, default_conversion (stack[sp].expr.value));
7056 c_inhibit_evaluation_warnings += (stack[sp].expr.value
7057 == truthvalue_false_node);
7058 set_c_expr_source_range (&stack[sp].expr, src_range);
7059 break;
7060 case TRUTH_ORIF_EXPR:
7061 src_range = stack[sp].expr.src_range;
7062 stack[sp].expr
7063 = convert_lvalue_to_rvalue (stack[sp].loc,
7064 stack[sp].expr, true, true);
7065 stack[sp].expr.value = c_objc_common_truthvalue_conversion
7066 (stack[sp].loc, default_conversion (stack[sp].expr.value));
7067 c_inhibit_evaluation_warnings += (stack[sp].expr.value
7068 == truthvalue_true_node);
7069 set_c_expr_source_range (&stack[sp].expr, src_range);
7070 break;
7071 default:
7072 break;
7073 }
7074 sp++;
7075 stack[sp].loc = binary_loc;
7076 stack[sp].expr = c_parser_cast_expression (parser, NULL);
7077 stack[sp].prec = oprec;
7078 stack[sp].op = ocode;
7079 stack[sp].sizeof_arg = c_last_sizeof_arg;
7080 }
7081 out:
7082 while (sp > 0)
7083 POP;
7084 return stack[0].expr;
7085 #undef POP
7086 }
7087
7088 /* Parse a cast expression (C90 6.3.4, C99 6.5.4, C11 6.5.4). If AFTER
7089 is not NULL then it is an Objective-C message expression which is the
7090 primary-expression starting the expression as an initializer.
7091
7092 cast-expression:
7093 unary-expression
7094 ( type-name ) unary-expression
7095 */
7096
7097 static struct c_expr
c_parser_cast_expression(c_parser * parser,struct c_expr * after)7098 c_parser_cast_expression (c_parser *parser, struct c_expr *after)
7099 {
7100 location_t cast_loc = c_parser_peek_token (parser)->location;
7101 gcc_assert (!after || c_dialect_objc ());
7102 if (after)
7103 return c_parser_postfix_expression_after_primary (parser,
7104 cast_loc, *after);
7105 /* If the expression begins with a parenthesized type name, it may
7106 be either a cast or a compound literal; we need to see whether
7107 the next character is '{' to tell the difference. If not, it is
7108 an unary expression. Full detection of unknown typenames here
7109 would require a 3-token lookahead. */
7110 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
7111 && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
7112 {
7113 struct c_type_name *type_name;
7114 struct c_expr ret;
7115 struct c_expr expr;
7116 matching_parens parens;
7117 parens.consume_open (parser);
7118 type_name = c_parser_type_name (parser, true);
7119 parens.skip_until_found_close (parser);
7120 if (type_name == NULL)
7121 {
7122 ret.set_error ();
7123 ret.original_code = ERROR_MARK;
7124 ret.original_type = NULL;
7125 return ret;
7126 }
7127
7128 /* Save casted types in the function's used types hash table. */
7129 used_types_insert (type_name->specs->type);
7130
7131 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
7132 return c_parser_postfix_expression_after_paren_type (parser, type_name,
7133 cast_loc);
7134 if (type_name->specs->alignas_p)
7135 error_at (type_name->specs->locations[cdw_alignas],
7136 "alignment specified for type name in cast");
7137 {
7138 location_t expr_loc = c_parser_peek_token (parser)->location;
7139 expr = c_parser_cast_expression (parser, NULL);
7140 expr = convert_lvalue_to_rvalue (expr_loc, expr, true, true);
7141 }
7142 ret.value = c_cast_expr (cast_loc, type_name, expr.value);
7143 if (ret.value && expr.value)
7144 set_c_expr_source_range (&ret, cast_loc, expr.get_finish ());
7145 ret.original_code = ERROR_MARK;
7146 ret.original_type = NULL;
7147 return ret;
7148 }
7149 else
7150 return c_parser_unary_expression (parser);
7151 }
7152
7153 /* Parse an unary expression (C90 6.3.3, C99 6.5.3, C11 6.5.3).
7154
7155 unary-expression:
7156 postfix-expression
7157 ++ unary-expression
7158 -- unary-expression
7159 unary-operator cast-expression
7160 sizeof unary-expression
7161 sizeof ( type-name )
7162
7163 unary-operator: one of
7164 & * + - ~ !
7165
7166 GNU extensions:
7167
7168 unary-expression:
7169 __alignof__ unary-expression
7170 __alignof__ ( type-name )
7171 && identifier
7172
7173 (C11 permits _Alignof with type names only.)
7174
7175 unary-operator: one of
7176 __extension__ __real__ __imag__
7177
7178 Transactional Memory:
7179
7180 unary-expression:
7181 transaction-expression
7182
7183 In addition, the GNU syntax treats ++ and -- as unary operators, so
7184 they may be applied to cast expressions with errors for non-lvalues
7185 given later. */
7186
7187 static struct c_expr
c_parser_unary_expression(c_parser * parser)7188 c_parser_unary_expression (c_parser *parser)
7189 {
7190 int ext;
7191 struct c_expr ret, op;
7192 location_t op_loc = c_parser_peek_token (parser)->location;
7193 location_t exp_loc;
7194 location_t finish;
7195 ret.original_code = ERROR_MARK;
7196 ret.original_type = NULL;
7197 switch (c_parser_peek_token (parser)->type)
7198 {
7199 case CPP_PLUS_PLUS:
7200 c_parser_consume_token (parser);
7201 exp_loc = c_parser_peek_token (parser)->location;
7202 op = c_parser_cast_expression (parser, NULL);
7203
7204 op = default_function_array_read_conversion (exp_loc, op);
7205 return parser_build_unary_op (op_loc, PREINCREMENT_EXPR, op);
7206 case CPP_MINUS_MINUS:
7207 c_parser_consume_token (parser);
7208 exp_loc = c_parser_peek_token (parser)->location;
7209 op = c_parser_cast_expression (parser, NULL);
7210
7211 op = default_function_array_read_conversion (exp_loc, op);
7212 return parser_build_unary_op (op_loc, PREDECREMENT_EXPR, op);
7213 case CPP_AND:
7214 c_parser_consume_token (parser);
7215 op = c_parser_cast_expression (parser, NULL);
7216 mark_exp_read (op.value);
7217 return parser_build_unary_op (op_loc, ADDR_EXPR, op);
7218 case CPP_MULT:
7219 {
7220 c_parser_consume_token (parser);
7221 exp_loc = c_parser_peek_token (parser)->location;
7222 op = c_parser_cast_expression (parser, NULL);
7223 finish = op.get_finish ();
7224 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
7225 location_t combined_loc = make_location (op_loc, op_loc, finish);
7226 ret.value = build_indirect_ref (combined_loc, op.value, RO_UNARY_STAR);
7227 ret.src_range.m_start = op_loc;
7228 ret.src_range.m_finish = finish;
7229 return ret;
7230 }
7231 case CPP_PLUS:
7232 if (!c_dialect_objc () && !in_system_header_at (input_location))
7233 warning_at (op_loc,
7234 OPT_Wtraditional,
7235 "traditional C rejects the unary plus operator");
7236 c_parser_consume_token (parser);
7237 exp_loc = c_parser_peek_token (parser)->location;
7238 op = c_parser_cast_expression (parser, NULL);
7239 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
7240 return parser_build_unary_op (op_loc, CONVERT_EXPR, op);
7241 case CPP_MINUS:
7242 c_parser_consume_token (parser);
7243 exp_loc = c_parser_peek_token (parser)->location;
7244 op = c_parser_cast_expression (parser, NULL);
7245 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
7246 return parser_build_unary_op (op_loc, NEGATE_EXPR, op);
7247 case CPP_COMPL:
7248 c_parser_consume_token (parser);
7249 exp_loc = c_parser_peek_token (parser)->location;
7250 op = c_parser_cast_expression (parser, NULL);
7251 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
7252 return parser_build_unary_op (op_loc, BIT_NOT_EXPR, op);
7253 case CPP_NOT:
7254 c_parser_consume_token (parser);
7255 exp_loc = c_parser_peek_token (parser)->location;
7256 op = c_parser_cast_expression (parser, NULL);
7257 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
7258 return parser_build_unary_op (op_loc, TRUTH_NOT_EXPR, op);
7259 case CPP_AND_AND:
7260 /* Refer to the address of a label as a pointer. */
7261 c_parser_consume_token (parser);
7262 if (c_parser_next_token_is (parser, CPP_NAME))
7263 {
7264 ret.value = finish_label_address_expr
7265 (c_parser_peek_token (parser)->value, op_loc);
7266 set_c_expr_source_range (&ret, op_loc,
7267 c_parser_peek_token (parser)->get_finish ());
7268 c_parser_consume_token (parser);
7269 }
7270 else
7271 {
7272 c_parser_error (parser, "expected identifier");
7273 ret.set_error ();
7274 }
7275 return ret;
7276 case CPP_KEYWORD:
7277 switch (c_parser_peek_token (parser)->keyword)
7278 {
7279 case RID_SIZEOF:
7280 return c_parser_sizeof_expression (parser);
7281 case RID_ALIGNOF:
7282 return c_parser_alignof_expression (parser);
7283 case RID_EXTENSION:
7284 c_parser_consume_token (parser);
7285 ext = disable_extension_diagnostics ();
7286 ret = c_parser_cast_expression (parser, NULL);
7287 restore_extension_diagnostics (ext);
7288 return ret;
7289 case RID_REALPART:
7290 c_parser_consume_token (parser);
7291 exp_loc = c_parser_peek_token (parser)->location;
7292 op = c_parser_cast_expression (parser, NULL);
7293 op = default_function_array_conversion (exp_loc, op);
7294 return parser_build_unary_op (op_loc, REALPART_EXPR, op);
7295 case RID_IMAGPART:
7296 c_parser_consume_token (parser);
7297 exp_loc = c_parser_peek_token (parser)->location;
7298 op = c_parser_cast_expression (parser, NULL);
7299 op = default_function_array_conversion (exp_loc, op);
7300 return parser_build_unary_op (op_loc, IMAGPART_EXPR, op);
7301 case RID_TRANSACTION_ATOMIC:
7302 case RID_TRANSACTION_RELAXED:
7303 return c_parser_transaction_expression (parser,
7304 c_parser_peek_token (parser)->keyword);
7305 default:
7306 return c_parser_postfix_expression (parser);
7307 }
7308 default:
7309 return c_parser_postfix_expression (parser);
7310 }
7311 }
7312
7313 /* Parse a sizeof expression. */
7314
7315 static struct c_expr
c_parser_sizeof_expression(c_parser * parser)7316 c_parser_sizeof_expression (c_parser *parser)
7317 {
7318 struct c_expr expr;
7319 struct c_expr result;
7320 location_t expr_loc;
7321 gcc_assert (c_parser_next_token_is_keyword (parser, RID_SIZEOF));
7322
7323 location_t start;
7324 location_t finish = UNKNOWN_LOCATION;
7325
7326 start = c_parser_peek_token (parser)->location;
7327
7328 c_parser_consume_token (parser);
7329 c_inhibit_evaluation_warnings++;
7330 in_sizeof++;
7331 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
7332 && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
7333 {
7334 /* Either sizeof ( type-name ) or sizeof unary-expression
7335 starting with a compound literal. */
7336 struct c_type_name *type_name;
7337 matching_parens parens;
7338 parens.consume_open (parser);
7339 expr_loc = c_parser_peek_token (parser)->location;
7340 type_name = c_parser_type_name (parser, true);
7341 parens.skip_until_found_close (parser);
7342 finish = parser->tokens_buf[0].location;
7343 if (type_name == NULL)
7344 {
7345 struct c_expr ret;
7346 c_inhibit_evaluation_warnings--;
7347 in_sizeof--;
7348 ret.set_error ();
7349 ret.original_code = ERROR_MARK;
7350 ret.original_type = NULL;
7351 return ret;
7352 }
7353 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
7354 {
7355 expr = c_parser_postfix_expression_after_paren_type (parser,
7356 type_name,
7357 expr_loc);
7358 finish = expr.get_finish ();
7359 goto sizeof_expr;
7360 }
7361 /* sizeof ( type-name ). */
7362 if (type_name->specs->alignas_p)
7363 error_at (type_name->specs->locations[cdw_alignas],
7364 "alignment specified for type name in %<sizeof%>");
7365 c_inhibit_evaluation_warnings--;
7366 in_sizeof--;
7367 result = c_expr_sizeof_type (expr_loc, type_name);
7368 }
7369 else
7370 {
7371 expr_loc = c_parser_peek_token (parser)->location;
7372 expr = c_parser_unary_expression (parser);
7373 finish = expr.get_finish ();
7374 sizeof_expr:
7375 c_inhibit_evaluation_warnings--;
7376 in_sizeof--;
7377 mark_exp_read (expr.value);
7378 if (TREE_CODE (expr.value) == COMPONENT_REF
7379 && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
7380 error_at (expr_loc, "%<sizeof%> applied to a bit-field");
7381 result = c_expr_sizeof_expr (expr_loc, expr);
7382 }
7383 if (finish != UNKNOWN_LOCATION)
7384 set_c_expr_source_range (&result, start, finish);
7385 return result;
7386 }
7387
7388 /* Parse an alignof expression. */
7389
7390 static struct c_expr
c_parser_alignof_expression(c_parser * parser)7391 c_parser_alignof_expression (c_parser *parser)
7392 {
7393 struct c_expr expr;
7394 location_t start_loc = c_parser_peek_token (parser)->location;
7395 location_t end_loc;
7396 tree alignof_spelling = c_parser_peek_token (parser)->value;
7397 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ALIGNOF));
7398 bool is_c11_alignof = strcmp (IDENTIFIER_POINTER (alignof_spelling),
7399 "_Alignof") == 0;
7400 /* A diagnostic is not required for the use of this identifier in
7401 the implementation namespace; only diagnose it for the C11
7402 spelling because of existing code using the other spellings. */
7403 if (is_c11_alignof)
7404 {
7405 if (flag_isoc99)
7406 pedwarn_c99 (start_loc, OPT_Wpedantic, "ISO C99 does not support %qE",
7407 alignof_spelling);
7408 else
7409 pedwarn_c99 (start_loc, OPT_Wpedantic, "ISO C90 does not support %qE",
7410 alignof_spelling);
7411 }
7412 c_parser_consume_token (parser);
7413 c_inhibit_evaluation_warnings++;
7414 in_alignof++;
7415 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
7416 && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
7417 {
7418 /* Either __alignof__ ( type-name ) or __alignof__
7419 unary-expression starting with a compound literal. */
7420 location_t loc;
7421 struct c_type_name *type_name;
7422 struct c_expr ret;
7423 matching_parens parens;
7424 parens.consume_open (parser);
7425 loc = c_parser_peek_token (parser)->location;
7426 type_name = c_parser_type_name (parser, true);
7427 end_loc = c_parser_peek_token (parser)->location;
7428 parens.skip_until_found_close (parser);
7429 if (type_name == NULL)
7430 {
7431 struct c_expr ret;
7432 c_inhibit_evaluation_warnings--;
7433 in_alignof--;
7434 ret.set_error ();
7435 ret.original_code = ERROR_MARK;
7436 ret.original_type = NULL;
7437 return ret;
7438 }
7439 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
7440 {
7441 expr = c_parser_postfix_expression_after_paren_type (parser,
7442 type_name,
7443 loc);
7444 goto alignof_expr;
7445 }
7446 /* alignof ( type-name ). */
7447 if (type_name->specs->alignas_p)
7448 error_at (type_name->specs->locations[cdw_alignas],
7449 "alignment specified for type name in %qE",
7450 alignof_spelling);
7451 c_inhibit_evaluation_warnings--;
7452 in_alignof--;
7453 ret.value = c_sizeof_or_alignof_type (loc, groktypename (type_name,
7454 NULL, NULL),
7455 false, is_c11_alignof, 1);
7456 ret.original_code = ERROR_MARK;
7457 ret.original_type = NULL;
7458 set_c_expr_source_range (&ret, start_loc, end_loc);
7459 return ret;
7460 }
7461 else
7462 {
7463 struct c_expr ret;
7464 expr = c_parser_unary_expression (parser);
7465 end_loc = expr.src_range.m_finish;
7466 alignof_expr:
7467 mark_exp_read (expr.value);
7468 c_inhibit_evaluation_warnings--;
7469 in_alignof--;
7470 if (is_c11_alignof)
7471 pedwarn (start_loc,
7472 OPT_Wpedantic, "ISO C does not allow %<%E (expression)%>",
7473 alignof_spelling);
7474 ret.value = c_alignof_expr (start_loc, expr.value);
7475 ret.original_code = ERROR_MARK;
7476 ret.original_type = NULL;
7477 set_c_expr_source_range (&ret, start_loc, end_loc);
7478 return ret;
7479 }
7480 }
7481
7482 /* Helper function to read arguments of builtins which are interfaces
7483 for the middle-end nodes like COMPLEX_EXPR, VEC_PERM_EXPR and
7484 others. The name of the builtin is passed using BNAME parameter.
7485 Function returns true if there were no errors while parsing and
7486 stores the arguments in CEXPR_LIST. If it returns true,
7487 *OUT_CLOSE_PAREN_LOC is written to with the location of the closing
7488 parenthesis. */
7489 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)7490 c_parser_get_builtin_args (c_parser *parser, const char *bname,
7491 vec<c_expr_t, va_gc> **ret_cexpr_list,
7492 bool choose_expr_p,
7493 location_t *out_close_paren_loc)
7494 {
7495 location_t loc = c_parser_peek_token (parser)->location;
7496 vec<c_expr_t, va_gc> *cexpr_list;
7497 c_expr_t expr;
7498 bool saved_force_folding_builtin_constant_p;
7499
7500 *ret_cexpr_list = NULL;
7501 if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
7502 {
7503 error_at (loc, "cannot take address of %qs", bname);
7504 return false;
7505 }
7506
7507 c_parser_consume_token (parser);
7508
7509 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
7510 {
7511 *out_close_paren_loc = c_parser_peek_token (parser)->location;
7512 c_parser_consume_token (parser);
7513 return true;
7514 }
7515
7516 saved_force_folding_builtin_constant_p
7517 = force_folding_builtin_constant_p;
7518 force_folding_builtin_constant_p |= choose_expr_p;
7519 expr = c_parser_expr_no_commas (parser, NULL);
7520 force_folding_builtin_constant_p
7521 = saved_force_folding_builtin_constant_p;
7522 vec_alloc (cexpr_list, 1);
7523 vec_safe_push (cexpr_list, expr);
7524 while (c_parser_next_token_is (parser, CPP_COMMA))
7525 {
7526 c_parser_consume_token (parser);
7527 expr = c_parser_expr_no_commas (parser, NULL);
7528 vec_safe_push (cexpr_list, expr);
7529 }
7530
7531 *out_close_paren_loc = c_parser_peek_token (parser)->location;
7532 if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
7533 return false;
7534
7535 *ret_cexpr_list = cexpr_list;
7536 return true;
7537 }
7538
7539 /* This represents a single generic-association. */
7540
7541 struct c_generic_association
7542 {
7543 /* The location of the starting token of the type. */
7544 location_t type_location;
7545 /* The association's type, or NULL_TREE for 'default'. */
7546 tree type;
7547 /* The association's expression. */
7548 struct c_expr expression;
7549 };
7550
7551 /* Parse a generic-selection. (C11 6.5.1.1).
7552
7553 generic-selection:
7554 _Generic ( assignment-expression , generic-assoc-list )
7555
7556 generic-assoc-list:
7557 generic-association
7558 generic-assoc-list , generic-association
7559
7560 generic-association:
7561 type-name : assignment-expression
7562 default : assignment-expression
7563 */
7564
7565 static struct c_expr
c_parser_generic_selection(c_parser * parser)7566 c_parser_generic_selection (c_parser *parser)
7567 {
7568 struct c_expr selector, error_expr;
7569 tree selector_type;
7570 struct c_generic_association matched_assoc;
7571 bool match_found = false;
7572 location_t generic_loc, selector_loc;
7573
7574 error_expr.original_code = ERROR_MARK;
7575 error_expr.original_type = NULL;
7576 error_expr.set_error ();
7577 matched_assoc.type_location = UNKNOWN_LOCATION;
7578 matched_assoc.type = NULL_TREE;
7579 matched_assoc.expression = error_expr;
7580
7581 gcc_assert (c_parser_next_token_is_keyword (parser, RID_GENERIC));
7582 generic_loc = c_parser_peek_token (parser)->location;
7583 c_parser_consume_token (parser);
7584 if (flag_isoc99)
7585 pedwarn_c99 (generic_loc, OPT_Wpedantic,
7586 "ISO C99 does not support %<_Generic%>");
7587 else
7588 pedwarn_c99 (generic_loc, OPT_Wpedantic,
7589 "ISO C90 does not support %<_Generic%>");
7590
7591 matching_parens parens;
7592 if (!parens.require_open (parser))
7593 return error_expr;
7594
7595 c_inhibit_evaluation_warnings++;
7596 selector_loc = c_parser_peek_token (parser)->location;
7597 selector = c_parser_expr_no_commas (parser, NULL);
7598 selector = default_function_array_conversion (selector_loc, selector);
7599 c_inhibit_evaluation_warnings--;
7600
7601 if (selector.value == error_mark_node)
7602 {
7603 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
7604 return selector;
7605 }
7606 selector_type = TREE_TYPE (selector.value);
7607 /* In ISO C terms, rvalues (including the controlling expression of
7608 _Generic) do not have qualified types. */
7609 if (TREE_CODE (selector_type) != ARRAY_TYPE)
7610 selector_type = TYPE_MAIN_VARIANT (selector_type);
7611 /* In ISO C terms, _Noreturn is not part of the type of expressions
7612 such as &abort, but in GCC it is represented internally as a type
7613 qualifier. */
7614 if (FUNCTION_POINTER_TYPE_P (selector_type)
7615 && TYPE_QUALS (TREE_TYPE (selector_type)) != TYPE_UNQUALIFIED)
7616 selector_type
7617 = build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (selector_type)));
7618
7619 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
7620 {
7621 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
7622 return error_expr;
7623 }
7624
7625 auto_vec<c_generic_association> associations;
7626 while (1)
7627 {
7628 struct c_generic_association assoc, *iter;
7629 unsigned int ix;
7630 c_token *token = c_parser_peek_token (parser);
7631
7632 assoc.type_location = token->location;
7633 if (token->type == CPP_KEYWORD && token->keyword == RID_DEFAULT)
7634 {
7635 c_parser_consume_token (parser);
7636 assoc.type = NULL_TREE;
7637 }
7638 else
7639 {
7640 struct c_type_name *type_name;
7641
7642 type_name = c_parser_type_name (parser);
7643 if (type_name == NULL)
7644 {
7645 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
7646 return error_expr;
7647 }
7648 assoc.type = groktypename (type_name, NULL, NULL);
7649 if (assoc.type == error_mark_node)
7650 {
7651 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
7652 return error_expr;
7653 }
7654
7655 if (TREE_CODE (assoc.type) == FUNCTION_TYPE)
7656 error_at (assoc.type_location,
7657 "%<_Generic%> association has function type");
7658 else if (!COMPLETE_TYPE_P (assoc.type))
7659 error_at (assoc.type_location,
7660 "%<_Generic%> association has incomplete type");
7661
7662 if (variably_modified_type_p (assoc.type, NULL_TREE))
7663 error_at (assoc.type_location,
7664 "%<_Generic%> association has "
7665 "variable length type");
7666 }
7667
7668 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
7669 {
7670 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
7671 return error_expr;
7672 }
7673
7674 assoc.expression = c_parser_expr_no_commas (parser, NULL);
7675 if (assoc.expression.value == error_mark_node)
7676 {
7677 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
7678 return error_expr;
7679 }
7680
7681 for (ix = 0; associations.iterate (ix, &iter); ++ix)
7682 {
7683 if (assoc.type == NULL_TREE)
7684 {
7685 if (iter->type == NULL_TREE)
7686 {
7687 error_at (assoc.type_location,
7688 "duplicate %<default%> case in %<_Generic%>");
7689 inform (iter->type_location, "original %<default%> is here");
7690 }
7691 }
7692 else if (iter->type != NULL_TREE)
7693 {
7694 if (comptypes (assoc.type, iter->type))
7695 {
7696 error_at (assoc.type_location,
7697 "%<_Generic%> specifies two compatible types");
7698 inform (iter->type_location, "compatible type is here");
7699 }
7700 }
7701 }
7702
7703 if (assoc.type == NULL_TREE)
7704 {
7705 if (!match_found)
7706 {
7707 matched_assoc = assoc;
7708 match_found = true;
7709 }
7710 }
7711 else if (comptypes (assoc.type, selector_type))
7712 {
7713 if (!match_found || matched_assoc.type == NULL_TREE)
7714 {
7715 matched_assoc = assoc;
7716 match_found = true;
7717 }
7718 else
7719 {
7720 error_at (assoc.type_location,
7721 "%<_Generic%> selector matches multiple associations");
7722 inform (matched_assoc.type_location,
7723 "other match is here");
7724 }
7725 }
7726
7727 associations.safe_push (assoc);
7728
7729 if (c_parser_peek_token (parser)->type != CPP_COMMA)
7730 break;
7731 c_parser_consume_token (parser);
7732 }
7733
7734 if (!parens.require_close (parser))
7735 {
7736 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
7737 return error_expr;
7738 }
7739
7740 if (!match_found)
7741 {
7742 error_at (selector_loc, "%<_Generic%> selector of type %qT is not "
7743 "compatible with any association",
7744 selector_type);
7745 return error_expr;
7746 }
7747
7748 return matched_assoc.expression;
7749 }
7750
7751 /* Check the validity of a function pointer argument *EXPR (argument
7752 position POS) to __builtin_tgmath. Return the number of function
7753 arguments if possibly valid; return 0 having reported an error if
7754 not valid. */
7755
7756 static unsigned int
check_tgmath_function(c_expr * expr,unsigned int pos)7757 check_tgmath_function (c_expr *expr, unsigned int pos)
7758 {
7759 tree type = TREE_TYPE (expr->value);
7760 if (!FUNCTION_POINTER_TYPE_P (type))
7761 {
7762 error_at (expr->get_location (),
7763 "argument %u of %<__builtin_tgmath%> is not a function pointer",
7764 pos);
7765 return 0;
7766 }
7767 type = TREE_TYPE (type);
7768 if (!prototype_p (type))
7769 {
7770 error_at (expr->get_location (),
7771 "argument %u of %<__builtin_tgmath%> is unprototyped", pos);
7772 return 0;
7773 }
7774 if (stdarg_p (type))
7775 {
7776 error_at (expr->get_location (),
7777 "argument %u of %<__builtin_tgmath%> has variable arguments",
7778 pos);
7779 return 0;
7780 }
7781 unsigned int nargs = 0;
7782 function_args_iterator iter;
7783 tree t;
7784 FOREACH_FUNCTION_ARGS (type, t, iter)
7785 {
7786 if (t == void_type_node)
7787 break;
7788 nargs++;
7789 }
7790 if (nargs == 0)
7791 {
7792 error_at (expr->get_location (),
7793 "argument %u of %<__builtin_tgmath%> has no arguments", pos);
7794 return 0;
7795 }
7796 return nargs;
7797 }
7798
7799 /* Ways in which a parameter or return value of a type-generic macro
7800 may vary between the different functions the macro may call. */
7801 enum tgmath_parm_kind
7802 {
7803 tgmath_fixed, tgmath_real, tgmath_complex
7804 };
7805
7806 /* Parse a postfix expression (C90 6.3.1-6.3.2, C99 6.5.1-6.5.2,
7807 C11 6.5.1-6.5.2). Compound literals aren't handled here; callers have to
7808 call c_parser_postfix_expression_after_paren_type on encountering them.
7809
7810 postfix-expression:
7811 primary-expression
7812 postfix-expression [ expression ]
7813 postfix-expression ( argument-expression-list[opt] )
7814 postfix-expression . identifier
7815 postfix-expression -> identifier
7816 postfix-expression ++
7817 postfix-expression --
7818 ( type-name ) { initializer-list }
7819 ( type-name ) { initializer-list , }
7820
7821 argument-expression-list:
7822 argument-expression
7823 argument-expression-list , argument-expression
7824
7825 primary-expression:
7826 identifier
7827 constant
7828 string-literal
7829 ( expression )
7830 generic-selection
7831
7832 GNU extensions:
7833
7834 primary-expression:
7835 __func__
7836 (treated as a keyword in GNU C)
7837 __FUNCTION__
7838 __PRETTY_FUNCTION__
7839 ( compound-statement )
7840 __builtin_va_arg ( assignment-expression , type-name )
7841 __builtin_offsetof ( type-name , offsetof-member-designator )
7842 __builtin_choose_expr ( assignment-expression ,
7843 assignment-expression ,
7844 assignment-expression )
7845 __builtin_types_compatible_p ( type-name , type-name )
7846 __builtin_tgmath ( expr-list )
7847 __builtin_complex ( assignment-expression , assignment-expression )
7848 __builtin_shuffle ( assignment-expression , assignment-expression )
7849 __builtin_shuffle ( assignment-expression ,
7850 assignment-expression ,
7851 assignment-expression, )
7852
7853 offsetof-member-designator:
7854 identifier
7855 offsetof-member-designator . identifier
7856 offsetof-member-designator [ expression ]
7857
7858 Objective-C:
7859
7860 primary-expression:
7861 [ objc-receiver objc-message-args ]
7862 @selector ( objc-selector-arg )
7863 @protocol ( identifier )
7864 @encode ( type-name )
7865 objc-string-literal
7866 Classname . identifier
7867 */
7868
7869 static struct c_expr
c_parser_postfix_expression(c_parser * parser)7870 c_parser_postfix_expression (c_parser *parser)
7871 {
7872 struct c_expr expr, e1;
7873 struct c_type_name *t1, *t2;
7874 location_t loc = c_parser_peek_token (parser)->location;
7875 source_range tok_range = c_parser_peek_token (parser)->get_range ();
7876 expr.original_code = ERROR_MARK;
7877 expr.original_type = NULL;
7878 switch (c_parser_peek_token (parser)->type)
7879 {
7880 case CPP_NUMBER:
7881 expr.value = c_parser_peek_token (parser)->value;
7882 set_c_expr_source_range (&expr, tok_range);
7883 loc = c_parser_peek_token (parser)->location;
7884 c_parser_consume_token (parser);
7885 if (TREE_CODE (expr.value) == FIXED_CST
7886 && !targetm.fixed_point_supported_p ())
7887 {
7888 error_at (loc, "fixed-point types not supported for this target");
7889 expr.set_error ();
7890 }
7891 break;
7892 case CPP_CHAR:
7893 case CPP_CHAR16:
7894 case CPP_CHAR32:
7895 case CPP_WCHAR:
7896 expr.value = c_parser_peek_token (parser)->value;
7897 /* For the purpose of warning when a pointer is compared with
7898 a zero character constant. */
7899 expr.original_type = char_type_node;
7900 set_c_expr_source_range (&expr, tok_range);
7901 c_parser_consume_token (parser);
7902 break;
7903 case CPP_STRING:
7904 case CPP_STRING16:
7905 case CPP_STRING32:
7906 case CPP_WSTRING:
7907 case CPP_UTF8STRING:
7908 expr.value = c_parser_peek_token (parser)->value;
7909 set_c_expr_source_range (&expr, tok_range);
7910 expr.original_code = STRING_CST;
7911 c_parser_consume_token (parser);
7912 break;
7913 case CPP_OBJC_STRING:
7914 gcc_assert (c_dialect_objc ());
7915 expr.value
7916 = objc_build_string_object (c_parser_peek_token (parser)->value);
7917 set_c_expr_source_range (&expr, tok_range);
7918 c_parser_consume_token (parser);
7919 break;
7920 case CPP_NAME:
7921 switch (c_parser_peek_token (parser)->id_kind)
7922 {
7923 case C_ID_ID:
7924 {
7925 tree id = c_parser_peek_token (parser)->value;
7926 c_parser_consume_token (parser);
7927 expr.value = build_external_ref (loc, id,
7928 (c_parser_peek_token (parser)->type
7929 == CPP_OPEN_PAREN),
7930 &expr.original_type);
7931 set_c_expr_source_range (&expr, tok_range);
7932 break;
7933 }
7934 case C_ID_CLASSNAME:
7935 {
7936 /* Here we parse the Objective-C 2.0 Class.name dot
7937 syntax. */
7938 tree class_name = c_parser_peek_token (parser)->value;
7939 tree component;
7940 c_parser_consume_token (parser);
7941 gcc_assert (c_dialect_objc ());
7942 if (!c_parser_require (parser, CPP_DOT, "expected %<.%>"))
7943 {
7944 expr.set_error ();
7945 break;
7946 }
7947 if (c_parser_next_token_is_not (parser, CPP_NAME))
7948 {
7949 c_parser_error (parser, "expected identifier");
7950 expr.set_error ();
7951 break;
7952 }
7953 c_token *component_tok = c_parser_peek_token (parser);
7954 component = component_tok->value;
7955 location_t end_loc = component_tok->get_finish ();
7956 c_parser_consume_token (parser);
7957 expr.value = objc_build_class_component_ref (class_name,
7958 component);
7959 set_c_expr_source_range (&expr, loc, end_loc);
7960 break;
7961 }
7962 default:
7963 c_parser_error (parser, "expected expression");
7964 expr.set_error ();
7965 break;
7966 }
7967 break;
7968 case CPP_OPEN_PAREN:
7969 /* A parenthesized expression, statement expression or compound
7970 literal. */
7971 if (c_parser_peek_2nd_token (parser)->type == CPP_OPEN_BRACE)
7972 {
7973 /* A statement expression. */
7974 tree stmt;
7975 location_t brace_loc;
7976 c_parser_consume_token (parser);
7977 brace_loc = c_parser_peek_token (parser)->location;
7978 c_parser_consume_token (parser);
7979 if (!building_stmt_list_p ())
7980 {
7981 error_at (loc, "braced-group within expression allowed "
7982 "only inside a function");
7983 parser->error = true;
7984 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
7985 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
7986 expr.set_error ();
7987 break;
7988 }
7989 stmt = c_begin_stmt_expr ();
7990 c_parser_compound_statement_nostart (parser);
7991 location_t close_loc = c_parser_peek_token (parser)->location;
7992 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
7993 "expected %<)%>");
7994 pedwarn (loc, OPT_Wpedantic,
7995 "ISO C forbids braced-groups within expressions");
7996 expr.value = c_finish_stmt_expr (brace_loc, stmt);
7997 set_c_expr_source_range (&expr, loc, close_loc);
7998 mark_exp_read (expr.value);
7999 }
8000 else
8001 {
8002 /* A parenthesized expression. */
8003 location_t loc_open_paren = c_parser_peek_token (parser)->location;
8004 c_parser_consume_token (parser);
8005 expr = c_parser_expression (parser);
8006 if (TREE_CODE (expr.value) == MODIFY_EXPR)
8007 TREE_NO_WARNING (expr.value) = 1;
8008 if (expr.original_code != C_MAYBE_CONST_EXPR
8009 && expr.original_code != SIZEOF_EXPR)
8010 expr.original_code = ERROR_MARK;
8011 /* Don't change EXPR.ORIGINAL_TYPE. */
8012 location_t loc_close_paren = c_parser_peek_token (parser)->location;
8013 set_c_expr_source_range (&expr, loc_open_paren, loc_close_paren);
8014 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
8015 "expected %<)%>", loc_open_paren);
8016 }
8017 break;
8018 case CPP_KEYWORD:
8019 switch (c_parser_peek_token (parser)->keyword)
8020 {
8021 case RID_FUNCTION_NAME:
8022 pedwarn (loc, OPT_Wpedantic, "ISO C does not support "
8023 "%<__FUNCTION__%> predefined identifier");
8024 expr.value = fname_decl (loc,
8025 c_parser_peek_token (parser)->keyword,
8026 c_parser_peek_token (parser)->value);
8027 set_c_expr_source_range (&expr, loc, loc);
8028 c_parser_consume_token (parser);
8029 break;
8030 case RID_PRETTY_FUNCTION_NAME:
8031 pedwarn (loc, OPT_Wpedantic, "ISO C does not support "
8032 "%<__PRETTY_FUNCTION__%> predefined identifier");
8033 expr.value = fname_decl (loc,
8034 c_parser_peek_token (parser)->keyword,
8035 c_parser_peek_token (parser)->value);
8036 set_c_expr_source_range (&expr, loc, loc);
8037 c_parser_consume_token (parser);
8038 break;
8039 case RID_C99_FUNCTION_NAME:
8040 pedwarn_c90 (loc, OPT_Wpedantic, "ISO C90 does not support "
8041 "%<__func__%> predefined identifier");
8042 expr.value = fname_decl (loc,
8043 c_parser_peek_token (parser)->keyword,
8044 c_parser_peek_token (parser)->value);
8045 set_c_expr_source_range (&expr, loc, loc);
8046 c_parser_consume_token (parser);
8047 break;
8048 case RID_VA_ARG:
8049 {
8050 location_t start_loc = loc;
8051 c_parser_consume_token (parser);
8052 matching_parens parens;
8053 if (!parens.require_open (parser))
8054 {
8055 expr.set_error ();
8056 break;
8057 }
8058 e1 = c_parser_expr_no_commas (parser, NULL);
8059 mark_exp_read (e1.value);
8060 e1.value = c_fully_fold (e1.value, false, NULL);
8061 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
8062 {
8063 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8064 expr.set_error ();
8065 break;
8066 }
8067 loc = c_parser_peek_token (parser)->location;
8068 t1 = c_parser_type_name (parser);
8069 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
8070 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
8071 "expected %<)%>");
8072 if (t1 == NULL)
8073 {
8074 expr.set_error ();
8075 }
8076 else
8077 {
8078 tree type_expr = NULL_TREE;
8079 expr.value = c_build_va_arg (start_loc, e1.value, loc,
8080 groktypename (t1, &type_expr, NULL));
8081 if (type_expr)
8082 {
8083 expr.value = build2 (C_MAYBE_CONST_EXPR,
8084 TREE_TYPE (expr.value), type_expr,
8085 expr.value);
8086 C_MAYBE_CONST_EXPR_NON_CONST (expr.value) = true;
8087 }
8088 set_c_expr_source_range (&expr, start_loc, end_loc);
8089 }
8090 }
8091 break;
8092 case RID_OFFSETOF:
8093 {
8094 c_parser_consume_token (parser);
8095 matching_parens parens;
8096 if (!parens.require_open (parser))
8097 {
8098 expr.set_error ();
8099 break;
8100 }
8101 t1 = c_parser_type_name (parser);
8102 if (t1 == NULL)
8103 parser->error = true;
8104 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
8105 gcc_assert (parser->error);
8106 if (parser->error)
8107 {
8108 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8109 expr.set_error ();
8110 break;
8111 }
8112 tree type = groktypename (t1, NULL, NULL);
8113 tree offsetof_ref;
8114 if (type == error_mark_node)
8115 offsetof_ref = error_mark_node;
8116 else
8117 {
8118 offsetof_ref = build1 (INDIRECT_REF, type, null_pointer_node);
8119 SET_EXPR_LOCATION (offsetof_ref, loc);
8120 }
8121 /* Parse the second argument to __builtin_offsetof. We
8122 must have one identifier, and beyond that we want to
8123 accept sub structure and sub array references. */
8124 if (c_parser_next_token_is (parser, CPP_NAME))
8125 {
8126 c_token *comp_tok = c_parser_peek_token (parser);
8127 offsetof_ref = build_component_ref
8128 (loc, offsetof_ref, comp_tok->value, comp_tok->location);
8129 c_parser_consume_token (parser);
8130 while (c_parser_next_token_is (parser, CPP_DOT)
8131 || c_parser_next_token_is (parser,
8132 CPP_OPEN_SQUARE)
8133 || c_parser_next_token_is (parser,
8134 CPP_DEREF))
8135 {
8136 if (c_parser_next_token_is (parser, CPP_DEREF))
8137 {
8138 loc = c_parser_peek_token (parser)->location;
8139 offsetof_ref = build_array_ref (loc,
8140 offsetof_ref,
8141 integer_zero_node);
8142 goto do_dot;
8143 }
8144 else if (c_parser_next_token_is (parser, CPP_DOT))
8145 {
8146 do_dot:
8147 c_parser_consume_token (parser);
8148 if (c_parser_next_token_is_not (parser,
8149 CPP_NAME))
8150 {
8151 c_parser_error (parser, "expected identifier");
8152 break;
8153 }
8154 c_token *comp_tok = c_parser_peek_token (parser);
8155 offsetof_ref = build_component_ref
8156 (loc, offsetof_ref, comp_tok->value,
8157 comp_tok->location);
8158 c_parser_consume_token (parser);
8159 }
8160 else
8161 {
8162 struct c_expr ce;
8163 tree idx;
8164 loc = c_parser_peek_token (parser)->location;
8165 c_parser_consume_token (parser);
8166 ce = c_parser_expression (parser);
8167 ce = convert_lvalue_to_rvalue (loc, ce, false, false);
8168 idx = ce.value;
8169 idx = c_fully_fold (idx, false, NULL);
8170 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
8171 "expected %<]%>");
8172 offsetof_ref = build_array_ref (loc, offsetof_ref, idx);
8173 }
8174 }
8175 }
8176 else
8177 c_parser_error (parser, "expected identifier");
8178 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
8179 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
8180 "expected %<)%>");
8181 expr.value = fold_offsetof (offsetof_ref);
8182 set_c_expr_source_range (&expr, loc, end_loc);
8183 }
8184 break;
8185 case RID_CHOOSE_EXPR:
8186 {
8187 vec<c_expr_t, va_gc> *cexpr_list;
8188 c_expr_t *e1_p, *e2_p, *e3_p;
8189 tree c;
8190 location_t close_paren_loc;
8191
8192 c_parser_consume_token (parser);
8193 if (!c_parser_get_builtin_args (parser,
8194 "__builtin_choose_expr",
8195 &cexpr_list, true,
8196 &close_paren_loc))
8197 {
8198 expr.set_error ();
8199 break;
8200 }
8201
8202 if (vec_safe_length (cexpr_list) != 3)
8203 {
8204 error_at (loc, "wrong number of arguments to "
8205 "%<__builtin_choose_expr%>");
8206 expr.set_error ();
8207 break;
8208 }
8209
8210 e1_p = &(*cexpr_list)[0];
8211 e2_p = &(*cexpr_list)[1];
8212 e3_p = &(*cexpr_list)[2];
8213
8214 c = e1_p->value;
8215 mark_exp_read (e2_p->value);
8216 mark_exp_read (e3_p->value);
8217 if (TREE_CODE (c) != INTEGER_CST
8218 || !INTEGRAL_TYPE_P (TREE_TYPE (c)))
8219 error_at (loc,
8220 "first argument to %<__builtin_choose_expr%> not"
8221 " a constant");
8222 constant_expression_warning (c);
8223 expr = integer_zerop (c) ? *e3_p : *e2_p;
8224 set_c_expr_source_range (&expr, loc, close_paren_loc);
8225 break;
8226 }
8227 case RID_TYPES_COMPATIBLE_P:
8228 {
8229 c_parser_consume_token (parser);
8230 matching_parens parens;
8231 if (!parens.require_open (parser))
8232 {
8233 expr.set_error ();
8234 break;
8235 }
8236 t1 = c_parser_type_name (parser);
8237 if (t1 == NULL)
8238 {
8239 expr.set_error ();
8240 break;
8241 }
8242 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
8243 {
8244 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8245 expr.set_error ();
8246 break;
8247 }
8248 t2 = c_parser_type_name (parser);
8249 if (t2 == NULL)
8250 {
8251 expr.set_error ();
8252 break;
8253 }
8254 location_t close_paren_loc = c_parser_peek_token (parser)->location;
8255 parens.skip_until_found_close (parser);
8256 tree e1, e2;
8257 e1 = groktypename (t1, NULL, NULL);
8258 e2 = groktypename (t2, NULL, NULL);
8259 if (e1 == error_mark_node || e2 == error_mark_node)
8260 {
8261 expr.set_error ();
8262 break;
8263 }
8264
8265 e1 = TYPE_MAIN_VARIANT (e1);
8266 e2 = TYPE_MAIN_VARIANT (e2);
8267
8268 expr.value
8269 = comptypes (e1, e2) ? integer_one_node : integer_zero_node;
8270 set_c_expr_source_range (&expr, loc, close_paren_loc);
8271 }
8272 break;
8273 case RID_BUILTIN_TGMATH:
8274 {
8275 vec<c_expr_t, va_gc> *cexpr_list;
8276 location_t close_paren_loc;
8277
8278 c_parser_consume_token (parser);
8279 if (!c_parser_get_builtin_args (parser,
8280 "__builtin_tgmath",
8281 &cexpr_list, false,
8282 &close_paren_loc))
8283 {
8284 expr.set_error ();
8285 break;
8286 }
8287
8288 if (vec_safe_length (cexpr_list) < 3)
8289 {
8290 error_at (loc, "too few arguments to %<__builtin_tgmath%>");
8291 expr.set_error ();
8292 break;
8293 }
8294
8295 unsigned int i;
8296 c_expr_t *p;
8297 FOR_EACH_VEC_ELT (*cexpr_list, i, p)
8298 *p = convert_lvalue_to_rvalue (loc, *p, true, true);
8299 unsigned int nargs = check_tgmath_function (&(*cexpr_list)[0], 1);
8300 if (nargs == 0)
8301 {
8302 expr.set_error ();
8303 break;
8304 }
8305 if (vec_safe_length (cexpr_list) < nargs)
8306 {
8307 error_at (loc, "too few arguments to %<__builtin_tgmath%>");
8308 expr.set_error ();
8309 break;
8310 }
8311 unsigned int num_functions = vec_safe_length (cexpr_list) - nargs;
8312 if (num_functions < 2)
8313 {
8314 error_at (loc, "too few arguments to %<__builtin_tgmath%>");
8315 expr.set_error ();
8316 break;
8317 }
8318
8319 /* The first NUM_FUNCTIONS expressions are the function
8320 pointers. The remaining NARGS expressions are the
8321 arguments that are to be passed to one of those
8322 functions, chosen following <tgmath.h> rules. */
8323 for (unsigned int j = 1; j < num_functions; j++)
8324 {
8325 unsigned int this_nargs
8326 = check_tgmath_function (&(*cexpr_list)[j], j + 1);
8327 if (this_nargs == 0)
8328 {
8329 expr.set_error ();
8330 goto out;
8331 }
8332 if (this_nargs != nargs)
8333 {
8334 error_at ((*cexpr_list)[j].get_location (),
8335 "argument %u of %<__builtin_tgmath%> has "
8336 "wrong number of arguments", j + 1);
8337 expr.set_error ();
8338 goto out;
8339 }
8340 }
8341
8342 /* The functions all have the same number of arguments.
8343 Determine whether arguments and return types vary in
8344 ways permitted for <tgmath.h> functions. */
8345 /* The first entry in each of these vectors is for the
8346 return type, subsequent entries for parameter
8347 types. */
8348 auto_vec<enum tgmath_parm_kind> parm_kind (nargs + 1);
8349 auto_vec<tree> parm_first (nargs + 1);
8350 auto_vec<bool> parm_complex (nargs + 1);
8351 auto_vec<bool> parm_varies (nargs + 1);
8352 tree first_type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[0].value));
8353 tree first_ret = TYPE_MAIN_VARIANT (TREE_TYPE (first_type));
8354 parm_first.quick_push (first_ret);
8355 parm_complex.quick_push (TREE_CODE (first_ret) == COMPLEX_TYPE);
8356 parm_varies.quick_push (false);
8357 function_args_iterator iter;
8358 tree t;
8359 unsigned int argpos;
8360 FOREACH_FUNCTION_ARGS (first_type, t, iter)
8361 {
8362 if (t == void_type_node)
8363 break;
8364 parm_first.quick_push (TYPE_MAIN_VARIANT (t));
8365 parm_complex.quick_push (TREE_CODE (t) == COMPLEX_TYPE);
8366 parm_varies.quick_push (false);
8367 }
8368 for (unsigned int j = 1; j < num_functions; j++)
8369 {
8370 tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
8371 tree ret = TYPE_MAIN_VARIANT (TREE_TYPE (type));
8372 if (ret != parm_first[0])
8373 {
8374 parm_varies[0] = true;
8375 if (!SCALAR_FLOAT_TYPE_P (parm_first[0])
8376 && !COMPLEX_FLOAT_TYPE_P (parm_first[0]))
8377 {
8378 error_at ((*cexpr_list)[0].get_location (),
8379 "invalid type-generic return type for "
8380 "argument %u of %<__builtin_tgmath%>",
8381 1);
8382 expr.set_error ();
8383 goto out;
8384 }
8385 if (!SCALAR_FLOAT_TYPE_P (ret)
8386 && !COMPLEX_FLOAT_TYPE_P (ret))
8387 {
8388 error_at ((*cexpr_list)[j].get_location (),
8389 "invalid type-generic return type for "
8390 "argument %u of %<__builtin_tgmath%>",
8391 j + 1);
8392 expr.set_error ();
8393 goto out;
8394 }
8395 }
8396 if (TREE_CODE (ret) == COMPLEX_TYPE)
8397 parm_complex[0] = true;
8398 argpos = 1;
8399 FOREACH_FUNCTION_ARGS (type, t, iter)
8400 {
8401 if (t == void_type_node)
8402 break;
8403 t = TYPE_MAIN_VARIANT (t);
8404 if (t != parm_first[argpos])
8405 {
8406 parm_varies[argpos] = true;
8407 if (!SCALAR_FLOAT_TYPE_P (parm_first[argpos])
8408 && !COMPLEX_FLOAT_TYPE_P (parm_first[argpos]))
8409 {
8410 error_at ((*cexpr_list)[0].get_location (),
8411 "invalid type-generic type for "
8412 "argument %u of argument %u of "
8413 "%<__builtin_tgmath%>", argpos, 1);
8414 expr.set_error ();
8415 goto out;
8416 }
8417 if (!SCALAR_FLOAT_TYPE_P (t)
8418 && !COMPLEX_FLOAT_TYPE_P (t))
8419 {
8420 error_at ((*cexpr_list)[j].get_location (),
8421 "invalid type-generic type for "
8422 "argument %u of argument %u of "
8423 "%<__builtin_tgmath%>", argpos, j + 1);
8424 expr.set_error ();
8425 goto out;
8426 }
8427 }
8428 if (TREE_CODE (t) == COMPLEX_TYPE)
8429 parm_complex[argpos] = true;
8430 argpos++;
8431 }
8432 }
8433 enum tgmath_parm_kind max_variation = tgmath_fixed;
8434 for (unsigned int j = 0; j <= nargs; j++)
8435 {
8436 enum tgmath_parm_kind this_kind;
8437 if (parm_varies[j])
8438 {
8439 if (parm_complex[j])
8440 max_variation = this_kind = tgmath_complex;
8441 else
8442 {
8443 this_kind = tgmath_real;
8444 if (max_variation != tgmath_complex)
8445 max_variation = tgmath_real;
8446 }
8447 }
8448 else
8449 this_kind = tgmath_fixed;
8450 parm_kind.quick_push (this_kind);
8451 }
8452 if (max_variation == tgmath_fixed)
8453 {
8454 error_at (loc, "function arguments of %<__builtin_tgmath%> "
8455 "all have the same type");
8456 expr.set_error ();
8457 break;
8458 }
8459
8460 /* Identify a parameter (not the return type) that varies,
8461 including with complex types if any variation includes
8462 complex types; there must be at least one such
8463 parameter. */
8464 unsigned int tgarg = 0;
8465 for (unsigned int j = 1; j <= nargs; j++)
8466 if (parm_kind[j] == max_variation)
8467 {
8468 tgarg = j;
8469 break;
8470 }
8471 if (tgarg == 0)
8472 {
8473 error_at (loc, "function arguments of %<__builtin_tgmath%> "
8474 "lack type-generic parameter");
8475 expr.set_error ();
8476 break;
8477 }
8478
8479 /* Determine the type of the relevant parameter for each
8480 function. */
8481 auto_vec<tree> tg_type (num_functions);
8482 for (unsigned int j = 0; j < num_functions; j++)
8483 {
8484 tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
8485 argpos = 1;
8486 FOREACH_FUNCTION_ARGS (type, t, iter)
8487 {
8488 if (argpos == tgarg)
8489 {
8490 tg_type.quick_push (TYPE_MAIN_VARIANT (t));
8491 break;
8492 }
8493 argpos++;
8494 }
8495 }
8496
8497 /* Verify that the corresponding types are different for
8498 all the listed functions. Also determine whether all
8499 the types are complex, whether all the types are
8500 standard or binary, and whether all the types are
8501 decimal. */
8502 bool all_complex = true;
8503 bool all_binary = true;
8504 bool all_decimal = true;
8505 hash_set<tree> tg_types;
8506 FOR_EACH_VEC_ELT (tg_type, i, t)
8507 {
8508 if (TREE_CODE (t) == COMPLEX_TYPE)
8509 all_decimal = false;
8510 else
8511 {
8512 all_complex = false;
8513 if (DECIMAL_FLOAT_TYPE_P (t))
8514 all_binary = false;
8515 else
8516 all_decimal = false;
8517 }
8518 if (tg_types.add (t))
8519 {
8520 error_at ((*cexpr_list)[i].get_location (),
8521 "duplicate type-generic parameter type for "
8522 "function argument %u of %<__builtin_tgmath%>",
8523 i + 1);
8524 expr.set_error ();
8525 goto out;
8526 }
8527 }
8528
8529 /* Verify that other parameters and the return type whose
8530 types vary have their types varying in the correct
8531 way. */
8532 for (unsigned int j = 0; j < num_functions; j++)
8533 {
8534 tree exp_type = tg_type[j];
8535 tree exp_real_type = exp_type;
8536 if (TREE_CODE (exp_type) == COMPLEX_TYPE)
8537 exp_real_type = TREE_TYPE (exp_type);
8538 tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
8539 tree ret = TYPE_MAIN_VARIANT (TREE_TYPE (type));
8540 if ((parm_kind[0] == tgmath_complex && ret != exp_type)
8541 || (parm_kind[0] == tgmath_real && ret != exp_real_type))
8542 {
8543 error_at ((*cexpr_list)[j].get_location (),
8544 "bad return type for function argument %u "
8545 "of %<__builtin_tgmath%>", j + 1);
8546 expr.set_error ();
8547 goto out;
8548 }
8549 argpos = 1;
8550 FOREACH_FUNCTION_ARGS (type, t, iter)
8551 {
8552 if (t == void_type_node)
8553 break;
8554 t = TYPE_MAIN_VARIANT (t);
8555 if ((parm_kind[argpos] == tgmath_complex
8556 && t != exp_type)
8557 || (parm_kind[argpos] == tgmath_real
8558 && t != exp_real_type))
8559 {
8560 error_at ((*cexpr_list)[j].get_location (),
8561 "bad type for argument %u of "
8562 "function argument %u of "
8563 "%<__builtin_tgmath%>", argpos, j + 1);
8564 expr.set_error ();
8565 goto out;
8566 }
8567 argpos++;
8568 }
8569 }
8570
8571 /* The functions listed are a valid set of functions for a
8572 <tgmath.h> macro to select between. Identify the
8573 matching function, if any. First, the argument types
8574 must be combined following <tgmath.h> rules. Integer
8575 types are treated as _Decimal64 if any type-generic
8576 argument is decimal, or if the only alternatives for
8577 type-generic arguments are of decimal types, and are
8578 otherwise treated as double (or _Complex double for
8579 complex integer types, or _Float64 or _Complex _Float64
8580 if all the return types are the same _FloatN or
8581 _FloatNx type). After that adjustment, types are
8582 combined following the usual arithmetic conversions.
8583 If the function only accepts complex arguments, a
8584 complex type is produced. */
8585 bool arg_complex = all_complex;
8586 bool arg_binary = all_binary;
8587 bool arg_int_decimal = all_decimal;
8588 for (unsigned int j = 1; j <= nargs; j++)
8589 {
8590 if (parm_kind[j] == tgmath_fixed)
8591 continue;
8592 c_expr_t *ce = &(*cexpr_list)[num_functions + j - 1];
8593 tree type = TREE_TYPE (ce->value);
8594 if (!INTEGRAL_TYPE_P (type)
8595 && !SCALAR_FLOAT_TYPE_P (type)
8596 && TREE_CODE (type) != COMPLEX_TYPE)
8597 {
8598 error_at (ce->get_location (),
8599 "invalid type of argument %u of type-generic "
8600 "function", j);
8601 expr.set_error ();
8602 goto out;
8603 }
8604 if (DECIMAL_FLOAT_TYPE_P (type))
8605 {
8606 arg_int_decimal = true;
8607 if (all_complex)
8608 {
8609 error_at (ce->get_location (),
8610 "decimal floating-point argument %u to "
8611 "complex-only type-generic function", j);
8612 expr.set_error ();
8613 goto out;
8614 }
8615 else if (all_binary)
8616 {
8617 error_at (ce->get_location (),
8618 "decimal floating-point argument %u to "
8619 "binary-only type-generic function", j);
8620 expr.set_error ();
8621 goto out;
8622 }
8623 else if (arg_complex)
8624 {
8625 error_at (ce->get_location (),
8626 "both complex and decimal floating-point "
8627 "arguments to type-generic function");
8628 expr.set_error ();
8629 goto out;
8630 }
8631 else if (arg_binary)
8632 {
8633 error_at (ce->get_location (),
8634 "both binary and decimal floating-point "
8635 "arguments to type-generic function");
8636 expr.set_error ();
8637 goto out;
8638 }
8639 }
8640 else if (TREE_CODE (type) == COMPLEX_TYPE)
8641 {
8642 arg_complex = true;
8643 if (COMPLEX_FLOAT_TYPE_P (type))
8644 arg_binary = true;
8645 if (all_decimal)
8646 {
8647 error_at (ce->get_location (),
8648 "complex argument %u to "
8649 "decimal-only type-generic function", j);
8650 expr.set_error ();
8651 goto out;
8652 }
8653 else if (arg_int_decimal)
8654 {
8655 error_at (ce->get_location (),
8656 "both complex and decimal floating-point "
8657 "arguments to type-generic function");
8658 expr.set_error ();
8659 goto out;
8660 }
8661 }
8662 else if (SCALAR_FLOAT_TYPE_P (type))
8663 {
8664 arg_binary = true;
8665 if (all_decimal)
8666 {
8667 error_at (ce->get_location (),
8668 "binary argument %u to "
8669 "decimal-only type-generic function", j);
8670 expr.set_error ();
8671 goto out;
8672 }
8673 else if (arg_int_decimal)
8674 {
8675 error_at (ce->get_location (),
8676 "both binary and decimal floating-point "
8677 "arguments to type-generic function");
8678 expr.set_error ();
8679 goto out;
8680 }
8681 }
8682 }
8683 /* For a macro rounding its result to a narrower type, map
8684 integer types to _Float64 not double if the return type
8685 is a _FloatN or _FloatNx type. */
8686 bool arg_int_float64 = false;
8687 if (parm_kind[0] == tgmath_fixed
8688 && SCALAR_FLOAT_TYPE_P (parm_first[0])
8689 && float64_type_node != NULL_TREE)
8690 for (unsigned int j = 0; j < NUM_FLOATN_NX_TYPES; j++)
8691 if (parm_first[0] == FLOATN_TYPE_NODE (j))
8692 {
8693 arg_int_float64 = true;
8694 break;
8695 }
8696 tree arg_real = NULL_TREE;
8697 for (unsigned int j = 1; j <= nargs; j++)
8698 {
8699 if (parm_kind[j] == tgmath_fixed)
8700 continue;
8701 c_expr_t *ce = &(*cexpr_list)[num_functions + j - 1];
8702 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (ce->value));
8703 if (TREE_CODE (type) == COMPLEX_TYPE)
8704 type = TREE_TYPE (type);
8705 if (INTEGRAL_TYPE_P (type))
8706 type = (arg_int_decimal
8707 ? dfloat64_type_node
8708 : arg_int_float64
8709 ? float64_type_node
8710 : double_type_node);
8711 if (arg_real == NULL_TREE)
8712 arg_real = type;
8713 else
8714 arg_real = common_type (arg_real, type);
8715 if (arg_real == error_mark_node)
8716 {
8717 expr.set_error ();
8718 goto out;
8719 }
8720 }
8721 tree arg_type = (arg_complex
8722 ? build_complex_type (arg_real)
8723 : arg_real);
8724
8725 /* Look for a function to call with type-generic parameter
8726 type ARG_TYPE. */
8727 c_expr_t *fn = NULL;
8728 for (unsigned int j = 0; j < num_functions; j++)
8729 {
8730 if (tg_type[j] == arg_type)
8731 {
8732 fn = &(*cexpr_list)[j];
8733 break;
8734 }
8735 }
8736 if (fn == NULL
8737 && parm_kind[0] == tgmath_fixed
8738 && SCALAR_FLOAT_TYPE_P (parm_first[0]))
8739 {
8740 /* Presume this is a macro that rounds its result to a
8741 narrower type, and look for the first function with
8742 at least the range and precision of the argument
8743 type. */
8744 for (unsigned int j = 0; j < num_functions; j++)
8745 {
8746 if (arg_complex
8747 != (TREE_CODE (tg_type[j]) == COMPLEX_TYPE))
8748 continue;
8749 tree real_tg_type = (arg_complex
8750 ? TREE_TYPE (tg_type[j])
8751 : tg_type[j]);
8752 if (DECIMAL_FLOAT_TYPE_P (arg_real)
8753 != DECIMAL_FLOAT_TYPE_P (real_tg_type))
8754 continue;
8755 scalar_float_mode arg_mode
8756 = SCALAR_FLOAT_TYPE_MODE (arg_real);
8757 scalar_float_mode tg_mode
8758 = SCALAR_FLOAT_TYPE_MODE (real_tg_type);
8759 const real_format *arg_fmt = REAL_MODE_FORMAT (arg_mode);
8760 const real_format *tg_fmt = REAL_MODE_FORMAT (tg_mode);
8761 if (arg_fmt->b == tg_fmt->b
8762 && arg_fmt->p <= tg_fmt->p
8763 && arg_fmt->emax <= tg_fmt->emax
8764 && (arg_fmt->emin - arg_fmt->p
8765 >= tg_fmt->emin - tg_fmt->p))
8766 {
8767 fn = &(*cexpr_list)[j];
8768 break;
8769 }
8770 }
8771 }
8772 if (fn == NULL)
8773 {
8774 error_at (loc, "no matching function for type-generic call");
8775 expr.set_error ();
8776 break;
8777 }
8778
8779 /* Construct a call to FN. */
8780 vec<tree, va_gc> *args;
8781 vec_alloc (args, nargs);
8782 vec<tree, va_gc> *origtypes;
8783 vec_alloc (origtypes, nargs);
8784 auto_vec<location_t> arg_loc (nargs);
8785 for (unsigned int j = 0; j < nargs; j++)
8786 {
8787 c_expr_t *ce = &(*cexpr_list)[num_functions + j];
8788 args->quick_push (ce->value);
8789 arg_loc.quick_push (ce->get_location ());
8790 origtypes->quick_push (ce->original_type);
8791 }
8792 expr.value = c_build_function_call_vec (loc, arg_loc, fn->value,
8793 args, origtypes);
8794 set_c_expr_source_range (&expr, loc, close_paren_loc);
8795 break;
8796 }
8797 case RID_BUILTIN_CALL_WITH_STATIC_CHAIN:
8798 {
8799 vec<c_expr_t, va_gc> *cexpr_list;
8800 c_expr_t *e2_p;
8801 tree chain_value;
8802 location_t close_paren_loc;
8803
8804 c_parser_consume_token (parser);
8805 if (!c_parser_get_builtin_args (parser,
8806 "__builtin_call_with_static_chain",
8807 &cexpr_list, false,
8808 &close_paren_loc))
8809 {
8810 expr.set_error ();
8811 break;
8812 }
8813 if (vec_safe_length (cexpr_list) != 2)
8814 {
8815 error_at (loc, "wrong number of arguments to "
8816 "%<__builtin_call_with_static_chain%>");
8817 expr.set_error ();
8818 break;
8819 }
8820
8821 expr = (*cexpr_list)[0];
8822 e2_p = &(*cexpr_list)[1];
8823 *e2_p = convert_lvalue_to_rvalue (loc, *e2_p, true, true);
8824 chain_value = e2_p->value;
8825 mark_exp_read (chain_value);
8826
8827 if (TREE_CODE (expr.value) != CALL_EXPR)
8828 error_at (loc, "first argument to "
8829 "%<__builtin_call_with_static_chain%> "
8830 "must be a call expression");
8831 else if (TREE_CODE (TREE_TYPE (chain_value)) != POINTER_TYPE)
8832 error_at (loc, "second argument to "
8833 "%<__builtin_call_with_static_chain%> "
8834 "must be a pointer type");
8835 else
8836 CALL_EXPR_STATIC_CHAIN (expr.value) = chain_value;
8837 set_c_expr_source_range (&expr, loc, close_paren_loc);
8838 break;
8839 }
8840 case RID_BUILTIN_COMPLEX:
8841 {
8842 vec<c_expr_t, va_gc> *cexpr_list;
8843 c_expr_t *e1_p, *e2_p;
8844 location_t close_paren_loc;
8845
8846 c_parser_consume_token (parser);
8847 if (!c_parser_get_builtin_args (parser,
8848 "__builtin_complex",
8849 &cexpr_list, false,
8850 &close_paren_loc))
8851 {
8852 expr.set_error ();
8853 break;
8854 }
8855
8856 if (vec_safe_length (cexpr_list) != 2)
8857 {
8858 error_at (loc, "wrong number of arguments to "
8859 "%<__builtin_complex%>");
8860 expr.set_error ();
8861 break;
8862 }
8863
8864 e1_p = &(*cexpr_list)[0];
8865 e2_p = &(*cexpr_list)[1];
8866
8867 *e1_p = convert_lvalue_to_rvalue (loc, *e1_p, true, true);
8868 if (TREE_CODE (e1_p->value) == EXCESS_PRECISION_EXPR)
8869 e1_p->value = convert (TREE_TYPE (e1_p->value),
8870 TREE_OPERAND (e1_p->value, 0));
8871 *e2_p = convert_lvalue_to_rvalue (loc, *e2_p, true, true);
8872 if (TREE_CODE (e2_p->value) == EXCESS_PRECISION_EXPR)
8873 e2_p->value = convert (TREE_TYPE (e2_p->value),
8874 TREE_OPERAND (e2_p->value, 0));
8875 if (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (e1_p->value))
8876 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e1_p->value))
8877 || !SCALAR_FLOAT_TYPE_P (TREE_TYPE (e2_p->value))
8878 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e2_p->value)))
8879 {
8880 error_at (loc, "%<__builtin_complex%> operand "
8881 "not of real binary floating-point type");
8882 expr.set_error ();
8883 break;
8884 }
8885 if (TYPE_MAIN_VARIANT (TREE_TYPE (e1_p->value))
8886 != TYPE_MAIN_VARIANT (TREE_TYPE (e2_p->value)))
8887 {
8888 error_at (loc,
8889 "%<__builtin_complex%> operands of different types");
8890 expr.set_error ();
8891 break;
8892 }
8893 pedwarn_c90 (loc, OPT_Wpedantic,
8894 "ISO C90 does not support complex types");
8895 expr.value = build2_loc (loc, COMPLEX_EXPR,
8896 build_complex_type
8897 (TYPE_MAIN_VARIANT
8898 (TREE_TYPE (e1_p->value))),
8899 e1_p->value, e2_p->value);
8900 set_c_expr_source_range (&expr, loc, close_paren_loc);
8901 break;
8902 }
8903 case RID_BUILTIN_SHUFFLE:
8904 {
8905 vec<c_expr_t, va_gc> *cexpr_list;
8906 unsigned int i;
8907 c_expr_t *p;
8908 location_t close_paren_loc;
8909
8910 c_parser_consume_token (parser);
8911 if (!c_parser_get_builtin_args (parser,
8912 "__builtin_shuffle",
8913 &cexpr_list, false,
8914 &close_paren_loc))
8915 {
8916 expr.set_error ();
8917 break;
8918 }
8919
8920 FOR_EACH_VEC_SAFE_ELT (cexpr_list, i, p)
8921 *p = convert_lvalue_to_rvalue (loc, *p, true, true);
8922
8923 if (vec_safe_length (cexpr_list) == 2)
8924 expr.value =
8925 c_build_vec_perm_expr
8926 (loc, (*cexpr_list)[0].value,
8927 NULL_TREE, (*cexpr_list)[1].value);
8928
8929 else if (vec_safe_length (cexpr_list) == 3)
8930 expr.value =
8931 c_build_vec_perm_expr
8932 (loc, (*cexpr_list)[0].value,
8933 (*cexpr_list)[1].value,
8934 (*cexpr_list)[2].value);
8935 else
8936 {
8937 error_at (loc, "wrong number of arguments to "
8938 "%<__builtin_shuffle%>");
8939 expr.set_error ();
8940 }
8941 set_c_expr_source_range (&expr, loc, close_paren_loc);
8942 break;
8943 }
8944 case RID_AT_SELECTOR:
8945 {
8946 gcc_assert (c_dialect_objc ());
8947 c_parser_consume_token (parser);
8948 matching_parens parens;
8949 if (!parens.require_open (parser))
8950 {
8951 expr.set_error ();
8952 break;
8953 }
8954 tree sel = c_parser_objc_selector_arg (parser);
8955 location_t close_loc = c_parser_peek_token (parser)->location;
8956 parens.skip_until_found_close (parser);
8957 expr.value = objc_build_selector_expr (loc, sel);
8958 set_c_expr_source_range (&expr, loc, close_loc);
8959 }
8960 break;
8961 case RID_AT_PROTOCOL:
8962 {
8963 gcc_assert (c_dialect_objc ());
8964 c_parser_consume_token (parser);
8965 matching_parens parens;
8966 if (!parens.require_open (parser))
8967 {
8968 expr.set_error ();
8969 break;
8970 }
8971 if (c_parser_next_token_is_not (parser, CPP_NAME))
8972 {
8973 c_parser_error (parser, "expected identifier");
8974 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8975 expr.set_error ();
8976 break;
8977 }
8978 tree id = c_parser_peek_token (parser)->value;
8979 c_parser_consume_token (parser);
8980 location_t close_loc = c_parser_peek_token (parser)->location;
8981 parens.skip_until_found_close (parser);
8982 expr.value = objc_build_protocol_expr (id);
8983 set_c_expr_source_range (&expr, loc, close_loc);
8984 }
8985 break;
8986 case RID_AT_ENCODE:
8987 {
8988 /* Extension to support C-structures in the archiver. */
8989 gcc_assert (c_dialect_objc ());
8990 c_parser_consume_token (parser);
8991 matching_parens parens;
8992 if (!parens.require_open (parser))
8993 {
8994 expr.set_error ();
8995 break;
8996 }
8997 t1 = c_parser_type_name (parser);
8998 if (t1 == NULL)
8999 {
9000 expr.set_error ();
9001 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9002 break;
9003 }
9004 location_t close_loc = c_parser_peek_token (parser)->location;
9005 parens.skip_until_found_close (parser);
9006 tree type = groktypename (t1, NULL, NULL);
9007 expr.value = objc_build_encode_expr (type);
9008 set_c_expr_source_range (&expr, loc, close_loc);
9009 }
9010 break;
9011 case RID_GENERIC:
9012 expr = c_parser_generic_selection (parser);
9013 break;
9014 default:
9015 c_parser_error (parser, "expected expression");
9016 expr.set_error ();
9017 break;
9018 }
9019 break;
9020 case CPP_OPEN_SQUARE:
9021 if (c_dialect_objc ())
9022 {
9023 tree receiver, args;
9024 c_parser_consume_token (parser);
9025 receiver = c_parser_objc_receiver (parser);
9026 args = c_parser_objc_message_args (parser);
9027 location_t close_loc = c_parser_peek_token (parser)->location;
9028 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
9029 "expected %<]%>");
9030 expr.value = objc_build_message_expr (receiver, args);
9031 set_c_expr_source_range (&expr, loc, close_loc);
9032 break;
9033 }
9034 /* Else fall through to report error. */
9035 /* FALLTHRU */
9036 default:
9037 c_parser_error (parser, "expected expression");
9038 expr.set_error ();
9039 break;
9040 }
9041 out:
9042 return c_parser_postfix_expression_after_primary
9043 (parser, EXPR_LOC_OR_LOC (expr.value, loc), expr);
9044 }
9045
9046 /* Parse a postfix expression after a parenthesized type name: the
9047 brace-enclosed initializer of a compound literal, possibly followed
9048 by some postfix operators. This is separate because it is not
9049 possible to tell until after the type name whether a cast
9050 expression has a cast or a compound literal, or whether the operand
9051 of sizeof is a parenthesized type name or starts with a compound
9052 literal. TYPE_LOC is the location where TYPE_NAME starts--the
9053 location of the first token after the parentheses around the type
9054 name. */
9055
9056 static struct c_expr
c_parser_postfix_expression_after_paren_type(c_parser * parser,struct c_type_name * type_name,location_t type_loc)9057 c_parser_postfix_expression_after_paren_type (c_parser *parser,
9058 struct c_type_name *type_name,
9059 location_t type_loc)
9060 {
9061 tree type;
9062 struct c_expr init;
9063 bool non_const;
9064 struct c_expr expr;
9065 location_t start_loc;
9066 tree type_expr = NULL_TREE;
9067 bool type_expr_const = true;
9068 check_compound_literal_type (type_loc, type_name);
9069 rich_location richloc (line_table, type_loc);
9070 start_init (NULL_TREE, NULL, 0, &richloc);
9071 type = groktypename (type_name, &type_expr, &type_expr_const);
9072 start_loc = c_parser_peek_token (parser)->location;
9073 if (type != error_mark_node && C_TYPE_VARIABLE_SIZE (type))
9074 {
9075 error_at (type_loc, "compound literal has variable size");
9076 type = error_mark_node;
9077 }
9078 init = c_parser_braced_init (parser, type, false, NULL);
9079 finish_init ();
9080 maybe_warn_string_init (type_loc, type, init);
9081
9082 if (type != error_mark_node
9083 && !ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (type))
9084 && current_function_decl)
9085 {
9086 error ("compound literal qualified by address-space qualifier");
9087 type = error_mark_node;
9088 }
9089
9090 pedwarn_c90 (start_loc, OPT_Wpedantic, "ISO C90 forbids compound literals");
9091 non_const = ((init.value && TREE_CODE (init.value) == CONSTRUCTOR)
9092 ? CONSTRUCTOR_NON_CONST (init.value)
9093 : init.original_code == C_MAYBE_CONST_EXPR);
9094 non_const |= !type_expr_const;
9095 unsigned int alignas_align = 0;
9096 if (type != error_mark_node
9097 && type_name->specs->align_log != -1)
9098 {
9099 alignas_align = 1U << type_name->specs->align_log;
9100 if (alignas_align < min_align_of_type (type))
9101 {
9102 error_at (type_name->specs->locations[cdw_alignas],
9103 "%<_Alignas%> specifiers cannot reduce "
9104 "alignment of compound literal");
9105 alignas_align = 0;
9106 }
9107 }
9108 expr.value = build_compound_literal (start_loc, type, init.value, non_const,
9109 alignas_align);
9110 set_c_expr_source_range (&expr, init.src_range);
9111 expr.original_code = ERROR_MARK;
9112 expr.original_type = NULL;
9113 if (type != error_mark_node
9114 && expr.value != error_mark_node
9115 && type_expr)
9116 {
9117 if (TREE_CODE (expr.value) == C_MAYBE_CONST_EXPR)
9118 {
9119 gcc_assert (C_MAYBE_CONST_EXPR_PRE (expr.value) == NULL_TREE);
9120 C_MAYBE_CONST_EXPR_PRE (expr.value) = type_expr;
9121 }
9122 else
9123 {
9124 gcc_assert (!non_const);
9125 expr.value = build2 (C_MAYBE_CONST_EXPR, type,
9126 type_expr, expr.value);
9127 }
9128 }
9129 return c_parser_postfix_expression_after_primary (parser, start_loc, expr);
9130 }
9131
9132 /* Callback function for sizeof_pointer_memaccess_warning to compare
9133 types. */
9134
9135 static bool
sizeof_ptr_memacc_comptypes(tree type1,tree type2)9136 sizeof_ptr_memacc_comptypes (tree type1, tree type2)
9137 {
9138 return comptypes (type1, type2) == 1;
9139 }
9140
9141 /* Parse a postfix expression after the initial primary or compound
9142 literal; that is, parse a series of postfix operators.
9143
9144 EXPR_LOC is the location of the primary expression. */
9145
9146 static struct c_expr
c_parser_postfix_expression_after_primary(c_parser * parser,location_t expr_loc,struct c_expr expr)9147 c_parser_postfix_expression_after_primary (c_parser *parser,
9148 location_t expr_loc,
9149 struct c_expr expr)
9150 {
9151 struct c_expr orig_expr;
9152 tree ident, idx;
9153 location_t sizeof_arg_loc[3], comp_loc;
9154 tree sizeof_arg[3];
9155 unsigned int literal_zero_mask;
9156 unsigned int i;
9157 vec<tree, va_gc> *exprlist;
9158 vec<tree, va_gc> *origtypes = NULL;
9159 vec<location_t> arg_loc = vNULL;
9160 location_t start;
9161 location_t finish;
9162
9163 while (true)
9164 {
9165 location_t op_loc = c_parser_peek_token (parser)->location;
9166 switch (c_parser_peek_token (parser)->type)
9167 {
9168 case CPP_OPEN_SQUARE:
9169 /* Array reference. */
9170 c_parser_consume_token (parser);
9171 idx = c_parser_expression (parser).value;
9172 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
9173 "expected %<]%>");
9174 start = expr.get_start ();
9175 finish = parser->tokens_buf[0].location;
9176 expr.value = build_array_ref (op_loc, expr.value, idx);
9177 set_c_expr_source_range (&expr, start, finish);
9178 expr.original_code = ERROR_MARK;
9179 expr.original_type = NULL;
9180 break;
9181 case CPP_OPEN_PAREN:
9182 /* Function call. */
9183 c_parser_consume_token (parser);
9184 for (i = 0; i < 3; i++)
9185 {
9186 sizeof_arg[i] = NULL_TREE;
9187 sizeof_arg_loc[i] = UNKNOWN_LOCATION;
9188 }
9189 literal_zero_mask = 0;
9190 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
9191 exprlist = NULL;
9192 else
9193 exprlist = c_parser_expr_list (parser, true, false, &origtypes,
9194 sizeof_arg_loc, sizeof_arg,
9195 &arg_loc, &literal_zero_mask);
9196 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9197 "expected %<)%>");
9198 orig_expr = expr;
9199 mark_exp_read (expr.value);
9200 if (warn_sizeof_pointer_memaccess)
9201 sizeof_pointer_memaccess_warning (sizeof_arg_loc,
9202 expr.value, exprlist,
9203 sizeof_arg,
9204 sizeof_ptr_memacc_comptypes);
9205 if (TREE_CODE (expr.value) == FUNCTION_DECL
9206 && DECL_BUILT_IN_CLASS (expr.value) == BUILT_IN_NORMAL
9207 && DECL_FUNCTION_CODE (expr.value) == BUILT_IN_MEMSET
9208 && vec_safe_length (exprlist) == 3)
9209 {
9210 tree arg0 = (*exprlist)[0];
9211 tree arg2 = (*exprlist)[2];
9212 warn_for_memset (expr_loc, arg0, arg2, literal_zero_mask);
9213 }
9214
9215 start = expr.get_start ();
9216 finish = parser->tokens_buf[0].get_finish ();
9217 expr.value
9218 = c_build_function_call_vec (expr_loc, arg_loc, expr.value,
9219 exprlist, origtypes);
9220 set_c_expr_source_range (&expr, start, finish);
9221
9222 expr.original_code = ERROR_MARK;
9223 if (TREE_CODE (expr.value) == INTEGER_CST
9224 && TREE_CODE (orig_expr.value) == FUNCTION_DECL
9225 && DECL_BUILT_IN_CLASS (orig_expr.value) == BUILT_IN_NORMAL
9226 && DECL_FUNCTION_CODE (orig_expr.value) == BUILT_IN_CONSTANT_P)
9227 expr.original_code = C_MAYBE_CONST_EXPR;
9228 expr.original_type = NULL;
9229 if (exprlist)
9230 {
9231 release_tree_vector (exprlist);
9232 release_tree_vector (origtypes);
9233 }
9234 arg_loc.release ();
9235 break;
9236 case CPP_DOT:
9237 /* Structure element reference. */
9238 c_parser_consume_token (parser);
9239 expr = default_function_array_conversion (expr_loc, expr);
9240 if (c_parser_next_token_is (parser, CPP_NAME))
9241 {
9242 c_token *comp_tok = c_parser_peek_token (parser);
9243 ident = comp_tok->value;
9244 comp_loc = comp_tok->location;
9245 }
9246 else
9247 {
9248 c_parser_error (parser, "expected identifier");
9249 expr.set_error ();
9250 expr.original_code = ERROR_MARK;
9251 expr.original_type = NULL;
9252 return expr;
9253 }
9254 start = expr.get_start ();
9255 finish = c_parser_peek_token (parser)->get_finish ();
9256 c_parser_consume_token (parser);
9257 expr.value = build_component_ref (op_loc, expr.value, ident,
9258 comp_loc);
9259 set_c_expr_source_range (&expr, start, finish);
9260 expr.original_code = ERROR_MARK;
9261 if (TREE_CODE (expr.value) != COMPONENT_REF)
9262 expr.original_type = NULL;
9263 else
9264 {
9265 /* Remember the original type of a bitfield. */
9266 tree field = TREE_OPERAND (expr.value, 1);
9267 if (TREE_CODE (field) != FIELD_DECL)
9268 expr.original_type = NULL;
9269 else
9270 expr.original_type = DECL_BIT_FIELD_TYPE (field);
9271 }
9272 break;
9273 case CPP_DEREF:
9274 /* Structure element reference. */
9275 c_parser_consume_token (parser);
9276 expr = convert_lvalue_to_rvalue (expr_loc, expr, true, false);
9277 if (c_parser_next_token_is (parser, CPP_NAME))
9278 {
9279 c_token *comp_tok = c_parser_peek_token (parser);
9280 ident = comp_tok->value;
9281 comp_loc = comp_tok->location;
9282 }
9283 else
9284 {
9285 c_parser_error (parser, "expected identifier");
9286 expr.set_error ();
9287 expr.original_code = ERROR_MARK;
9288 expr.original_type = NULL;
9289 return expr;
9290 }
9291 start = expr.get_start ();
9292 finish = c_parser_peek_token (parser)->get_finish ();
9293 c_parser_consume_token (parser);
9294 expr.value = build_component_ref (op_loc,
9295 build_indirect_ref (op_loc,
9296 expr.value,
9297 RO_ARROW),
9298 ident, comp_loc);
9299 set_c_expr_source_range (&expr, start, finish);
9300 expr.original_code = ERROR_MARK;
9301 if (TREE_CODE (expr.value) != COMPONENT_REF)
9302 expr.original_type = NULL;
9303 else
9304 {
9305 /* Remember the original type of a bitfield. */
9306 tree field = TREE_OPERAND (expr.value, 1);
9307 if (TREE_CODE (field) != FIELD_DECL)
9308 expr.original_type = NULL;
9309 else
9310 expr.original_type = DECL_BIT_FIELD_TYPE (field);
9311 }
9312 break;
9313 case CPP_PLUS_PLUS:
9314 /* Postincrement. */
9315 start = expr.get_start ();
9316 finish = c_parser_peek_token (parser)->get_finish ();
9317 c_parser_consume_token (parser);
9318 expr = default_function_array_read_conversion (expr_loc, expr);
9319 expr.value = build_unary_op (op_loc, POSTINCREMENT_EXPR,
9320 expr.value, false);
9321 set_c_expr_source_range (&expr, start, finish);
9322 expr.original_code = ERROR_MARK;
9323 expr.original_type = NULL;
9324 break;
9325 case CPP_MINUS_MINUS:
9326 /* Postdecrement. */
9327 start = expr.get_start ();
9328 finish = c_parser_peek_token (parser)->get_finish ();
9329 c_parser_consume_token (parser);
9330 expr = default_function_array_read_conversion (expr_loc, expr);
9331 expr.value = build_unary_op (op_loc, POSTDECREMENT_EXPR,
9332 expr.value, false);
9333 set_c_expr_source_range (&expr, start, finish);
9334 expr.original_code = ERROR_MARK;
9335 expr.original_type = NULL;
9336 break;
9337 default:
9338 return expr;
9339 }
9340 }
9341 }
9342
9343 /* Parse an expression (C90 6.3.17, C99 6.5.17, C11 6.5.17).
9344
9345 expression:
9346 assignment-expression
9347 expression , assignment-expression
9348 */
9349
9350 static struct c_expr
c_parser_expression(c_parser * parser)9351 c_parser_expression (c_parser *parser)
9352 {
9353 location_t tloc = c_parser_peek_token (parser)->location;
9354 struct c_expr expr;
9355 expr = c_parser_expr_no_commas (parser, NULL);
9356 if (c_parser_next_token_is (parser, CPP_COMMA))
9357 expr = convert_lvalue_to_rvalue (tloc, expr, true, false);
9358 while (c_parser_next_token_is (parser, CPP_COMMA))
9359 {
9360 struct c_expr next;
9361 tree lhsval;
9362 location_t loc = c_parser_peek_token (parser)->location;
9363 location_t expr_loc;
9364 c_parser_consume_token (parser);
9365 expr_loc = c_parser_peek_token (parser)->location;
9366 lhsval = expr.value;
9367 while (TREE_CODE (lhsval) == COMPOUND_EXPR)
9368 lhsval = TREE_OPERAND (lhsval, 1);
9369 if (DECL_P (lhsval) || handled_component_p (lhsval))
9370 mark_exp_read (lhsval);
9371 next = c_parser_expr_no_commas (parser, NULL);
9372 next = convert_lvalue_to_rvalue (expr_loc, next, true, false);
9373 expr.value = build_compound_expr (loc, expr.value, next.value);
9374 expr.original_code = COMPOUND_EXPR;
9375 expr.original_type = next.original_type;
9376 }
9377 return expr;
9378 }
9379
9380 /* Parse an expression and convert functions or arrays to pointers and
9381 lvalues to rvalues. */
9382
9383 static struct c_expr
c_parser_expression_conv(c_parser * parser)9384 c_parser_expression_conv (c_parser *parser)
9385 {
9386 struct c_expr expr;
9387 location_t loc = c_parser_peek_token (parser)->location;
9388 expr = c_parser_expression (parser);
9389 expr = convert_lvalue_to_rvalue (loc, expr, true, false);
9390 return expr;
9391 }
9392
9393 /* Helper function of c_parser_expr_list. Check if IDXth (0 based)
9394 argument is a literal zero alone and if so, set it in literal_zero_mask. */
9395
9396 static inline void
c_parser_check_literal_zero(c_parser * parser,unsigned * literal_zero_mask,unsigned int idx)9397 c_parser_check_literal_zero (c_parser *parser, unsigned *literal_zero_mask,
9398 unsigned int idx)
9399 {
9400 if (idx >= HOST_BITS_PER_INT)
9401 return;
9402
9403 c_token *tok = c_parser_peek_token (parser);
9404 switch (tok->type)
9405 {
9406 case CPP_NUMBER:
9407 case CPP_CHAR:
9408 case CPP_WCHAR:
9409 case CPP_CHAR16:
9410 case CPP_CHAR32:
9411 /* If a parameter is literal zero alone, remember it
9412 for -Wmemset-transposed-args warning. */
9413 if (integer_zerop (tok->value)
9414 && !TREE_OVERFLOW (tok->value)
9415 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
9416 || c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_PAREN))
9417 *literal_zero_mask |= 1U << idx;
9418 default:
9419 break;
9420 }
9421 }
9422
9423 /* Parse a non-empty list of expressions. If CONVERT_P, convert
9424 functions and arrays to pointers and lvalues to rvalues. If
9425 FOLD_P, fold the expressions. If LOCATIONS is non-NULL, save the
9426 locations of function arguments into this vector.
9427
9428 nonempty-expr-list:
9429 assignment-expression
9430 nonempty-expr-list , assignment-expression
9431 */
9432
9433 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)9434 c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p,
9435 vec<tree, va_gc> **p_orig_types,
9436 location_t *sizeof_arg_loc, tree *sizeof_arg,
9437 vec<location_t> *locations,
9438 unsigned int *literal_zero_mask)
9439 {
9440 vec<tree, va_gc> *ret;
9441 vec<tree, va_gc> *orig_types;
9442 struct c_expr expr;
9443 unsigned int idx = 0;
9444
9445 ret = make_tree_vector ();
9446 if (p_orig_types == NULL)
9447 orig_types = NULL;
9448 else
9449 orig_types = make_tree_vector ();
9450
9451 if (literal_zero_mask)
9452 c_parser_check_literal_zero (parser, literal_zero_mask, 0);
9453 expr = c_parser_expr_no_commas (parser, NULL);
9454 if (convert_p)
9455 expr = convert_lvalue_to_rvalue (expr.get_location (), expr, true, true);
9456 if (fold_p)
9457 expr.value = c_fully_fold (expr.value, false, NULL);
9458 ret->quick_push (expr.value);
9459 if (orig_types)
9460 orig_types->quick_push (expr.original_type);
9461 if (locations)
9462 locations->safe_push (expr.get_location ());
9463 if (sizeof_arg != NULL
9464 && expr.original_code == SIZEOF_EXPR)
9465 {
9466 sizeof_arg[0] = c_last_sizeof_arg;
9467 sizeof_arg_loc[0] = c_last_sizeof_loc;
9468 }
9469 while (c_parser_next_token_is (parser, CPP_COMMA))
9470 {
9471 c_parser_consume_token (parser);
9472 if (literal_zero_mask)
9473 c_parser_check_literal_zero (parser, literal_zero_mask, idx + 1);
9474 expr = c_parser_expr_no_commas (parser, NULL);
9475 if (convert_p)
9476 expr = convert_lvalue_to_rvalue (expr.get_location (), expr, true,
9477 true);
9478 if (fold_p)
9479 expr.value = c_fully_fold (expr.value, false, NULL);
9480 vec_safe_push (ret, expr.value);
9481 if (orig_types)
9482 vec_safe_push (orig_types, expr.original_type);
9483 if (locations)
9484 locations->safe_push (expr.get_location ());
9485 if (++idx < 3
9486 && sizeof_arg != NULL
9487 && expr.original_code == SIZEOF_EXPR)
9488 {
9489 sizeof_arg[idx] = c_last_sizeof_arg;
9490 sizeof_arg_loc[idx] = c_last_sizeof_loc;
9491 }
9492 }
9493 if (orig_types)
9494 *p_orig_types = orig_types;
9495 return ret;
9496 }
9497
9498 /* Parse Objective-C-specific constructs. */
9499
9500 /* Parse an objc-class-definition.
9501
9502 objc-class-definition:
9503 @interface identifier objc-superclass[opt] objc-protocol-refs[opt]
9504 objc-class-instance-variables[opt] objc-methodprotolist @end
9505 @implementation identifier objc-superclass[opt]
9506 objc-class-instance-variables[opt]
9507 @interface identifier ( identifier ) objc-protocol-refs[opt]
9508 objc-methodprotolist @end
9509 @interface identifier ( ) objc-protocol-refs[opt]
9510 objc-methodprotolist @end
9511 @implementation identifier ( identifier )
9512
9513 objc-superclass:
9514 : identifier
9515
9516 "@interface identifier (" must start "@interface identifier (
9517 identifier ) ...": objc-methodprotolist in the first production may
9518 not start with a parenthesized identifier as a declarator of a data
9519 definition with no declaration specifiers if the objc-superclass,
9520 objc-protocol-refs and objc-class-instance-variables are omitted. */
9521
9522 static void
c_parser_objc_class_definition(c_parser * parser,tree attributes)9523 c_parser_objc_class_definition (c_parser *parser, tree attributes)
9524 {
9525 bool iface_p;
9526 tree id1;
9527 tree superclass;
9528 if (c_parser_next_token_is_keyword (parser, RID_AT_INTERFACE))
9529 iface_p = true;
9530 else if (c_parser_next_token_is_keyword (parser, RID_AT_IMPLEMENTATION))
9531 iface_p = false;
9532 else
9533 gcc_unreachable ();
9534
9535 c_parser_consume_token (parser);
9536 if (c_parser_next_token_is_not (parser, CPP_NAME))
9537 {
9538 c_parser_error (parser, "expected identifier");
9539 return;
9540 }
9541 id1 = c_parser_peek_token (parser)->value;
9542 c_parser_consume_token (parser);
9543 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
9544 {
9545 /* We have a category or class extension. */
9546 tree id2;
9547 tree proto = NULL_TREE;
9548 matching_parens parens;
9549 parens.consume_open (parser);
9550 if (c_parser_next_token_is_not (parser, CPP_NAME))
9551 {
9552 if (iface_p && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
9553 {
9554 /* We have a class extension. */
9555 id2 = NULL_TREE;
9556 }
9557 else
9558 {
9559 c_parser_error (parser, "expected identifier or %<)%>");
9560 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9561 return;
9562 }
9563 }
9564 else
9565 {
9566 id2 = c_parser_peek_token (parser)->value;
9567 c_parser_consume_token (parser);
9568 }
9569 parens.skip_until_found_close (parser);
9570 if (!iface_p)
9571 {
9572 objc_start_category_implementation (id1, id2);
9573 return;
9574 }
9575 if (c_parser_next_token_is (parser, CPP_LESS))
9576 proto = c_parser_objc_protocol_refs (parser);
9577 objc_start_category_interface (id1, id2, proto, attributes);
9578 c_parser_objc_methodprotolist (parser);
9579 c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
9580 objc_finish_interface ();
9581 return;
9582 }
9583 if (c_parser_next_token_is (parser, CPP_COLON))
9584 {
9585 c_parser_consume_token (parser);
9586 if (c_parser_next_token_is_not (parser, CPP_NAME))
9587 {
9588 c_parser_error (parser, "expected identifier");
9589 return;
9590 }
9591 superclass = c_parser_peek_token (parser)->value;
9592 c_parser_consume_token (parser);
9593 }
9594 else
9595 superclass = NULL_TREE;
9596 if (iface_p)
9597 {
9598 tree proto = NULL_TREE;
9599 if (c_parser_next_token_is (parser, CPP_LESS))
9600 proto = c_parser_objc_protocol_refs (parser);
9601 objc_start_class_interface (id1, superclass, proto, attributes);
9602 }
9603 else
9604 objc_start_class_implementation (id1, superclass);
9605 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
9606 c_parser_objc_class_instance_variables (parser);
9607 if (iface_p)
9608 {
9609 objc_continue_interface ();
9610 c_parser_objc_methodprotolist (parser);
9611 c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
9612 objc_finish_interface ();
9613 }
9614 else
9615 {
9616 objc_continue_implementation ();
9617 return;
9618 }
9619 }
9620
9621 /* Parse objc-class-instance-variables.
9622
9623 objc-class-instance-variables:
9624 { objc-instance-variable-decl-list[opt] }
9625
9626 objc-instance-variable-decl-list:
9627 objc-visibility-spec
9628 objc-instance-variable-decl ;
9629 ;
9630 objc-instance-variable-decl-list objc-visibility-spec
9631 objc-instance-variable-decl-list objc-instance-variable-decl ;
9632 objc-instance-variable-decl-list ;
9633
9634 objc-visibility-spec:
9635 @private
9636 @protected
9637 @public
9638
9639 objc-instance-variable-decl:
9640 struct-declaration
9641 */
9642
9643 static void
c_parser_objc_class_instance_variables(c_parser * parser)9644 c_parser_objc_class_instance_variables (c_parser *parser)
9645 {
9646 gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE));
9647 c_parser_consume_token (parser);
9648 while (c_parser_next_token_is_not (parser, CPP_EOF))
9649 {
9650 tree decls;
9651 /* Parse any stray semicolon. */
9652 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
9653 {
9654 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
9655 "extra semicolon");
9656 c_parser_consume_token (parser);
9657 continue;
9658 }
9659 /* Stop if at the end of the instance variables. */
9660 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
9661 {
9662 c_parser_consume_token (parser);
9663 break;
9664 }
9665 /* Parse any objc-visibility-spec. */
9666 if (c_parser_next_token_is_keyword (parser, RID_AT_PRIVATE))
9667 {
9668 c_parser_consume_token (parser);
9669 objc_set_visibility (OBJC_IVAR_VIS_PRIVATE);
9670 continue;
9671 }
9672 else if (c_parser_next_token_is_keyword (parser, RID_AT_PROTECTED))
9673 {
9674 c_parser_consume_token (parser);
9675 objc_set_visibility (OBJC_IVAR_VIS_PROTECTED);
9676 continue;
9677 }
9678 else if (c_parser_next_token_is_keyword (parser, RID_AT_PUBLIC))
9679 {
9680 c_parser_consume_token (parser);
9681 objc_set_visibility (OBJC_IVAR_VIS_PUBLIC);
9682 continue;
9683 }
9684 else if (c_parser_next_token_is_keyword (parser, RID_AT_PACKAGE))
9685 {
9686 c_parser_consume_token (parser);
9687 objc_set_visibility (OBJC_IVAR_VIS_PACKAGE);
9688 continue;
9689 }
9690 else if (c_parser_next_token_is (parser, CPP_PRAGMA))
9691 {
9692 c_parser_pragma (parser, pragma_external, NULL);
9693 continue;
9694 }
9695
9696 /* Parse some comma-separated declarations. */
9697 decls = c_parser_struct_declaration (parser);
9698 if (decls == NULL)
9699 {
9700 /* There is a syntax error. We want to skip the offending
9701 tokens up to the next ';' (included) or '}'
9702 (excluded). */
9703
9704 /* First, skip manually a ')' or ']'. This is because they
9705 reduce the nesting level, so c_parser_skip_until_found()
9706 wouldn't be able to skip past them. */
9707 c_token *token = c_parser_peek_token (parser);
9708 if (token->type == CPP_CLOSE_PAREN || token->type == CPP_CLOSE_SQUARE)
9709 c_parser_consume_token (parser);
9710
9711 /* Then, do the standard skipping. */
9712 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
9713
9714 /* We hopefully recovered. Start normal parsing again. */
9715 parser->error = false;
9716 continue;
9717 }
9718 else
9719 {
9720 /* Comma-separated instance variables are chained together
9721 in reverse order; add them one by one. */
9722 tree ivar = nreverse (decls);
9723 for (; ivar; ivar = DECL_CHAIN (ivar))
9724 objc_add_instance_variable (copy_node (ivar));
9725 }
9726 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
9727 }
9728 }
9729
9730 /* Parse an objc-class-declaration.
9731
9732 objc-class-declaration:
9733 @class identifier-list ;
9734 */
9735
9736 static void
c_parser_objc_class_declaration(c_parser * parser)9737 c_parser_objc_class_declaration (c_parser *parser)
9738 {
9739 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_CLASS));
9740 c_parser_consume_token (parser);
9741 /* Any identifiers, including those declared as type names, are OK
9742 here. */
9743 while (true)
9744 {
9745 tree id;
9746 if (c_parser_next_token_is_not (parser, CPP_NAME))
9747 {
9748 c_parser_error (parser, "expected identifier");
9749 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
9750 parser->error = false;
9751 return;
9752 }
9753 id = c_parser_peek_token (parser)->value;
9754 objc_declare_class (id);
9755 c_parser_consume_token (parser);
9756 if (c_parser_next_token_is (parser, CPP_COMMA))
9757 c_parser_consume_token (parser);
9758 else
9759 break;
9760 }
9761 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
9762 }
9763
9764 /* Parse an objc-alias-declaration.
9765
9766 objc-alias-declaration:
9767 @compatibility_alias identifier identifier ;
9768 */
9769
9770 static void
c_parser_objc_alias_declaration(c_parser * parser)9771 c_parser_objc_alias_declaration (c_parser *parser)
9772 {
9773 tree id1, id2;
9774 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_ALIAS));
9775 c_parser_consume_token (parser);
9776 if (c_parser_next_token_is_not (parser, CPP_NAME))
9777 {
9778 c_parser_error (parser, "expected identifier");
9779 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
9780 return;
9781 }
9782 id1 = c_parser_peek_token (parser)->value;
9783 c_parser_consume_token (parser);
9784 if (c_parser_next_token_is_not (parser, CPP_NAME))
9785 {
9786 c_parser_error (parser, "expected identifier");
9787 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
9788 return;
9789 }
9790 id2 = c_parser_peek_token (parser)->value;
9791 c_parser_consume_token (parser);
9792 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
9793 objc_declare_alias (id1, id2);
9794 }
9795
9796 /* Parse an objc-protocol-definition.
9797
9798 objc-protocol-definition:
9799 @protocol identifier objc-protocol-refs[opt] objc-methodprotolist @end
9800 @protocol identifier-list ;
9801
9802 "@protocol identifier ;" should be resolved as "@protocol
9803 identifier-list ;": objc-methodprotolist may not start with a
9804 semicolon in the first alternative if objc-protocol-refs are
9805 omitted. */
9806
9807 static void
c_parser_objc_protocol_definition(c_parser * parser,tree attributes)9808 c_parser_objc_protocol_definition (c_parser *parser, tree attributes)
9809 {
9810 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_PROTOCOL));
9811
9812 c_parser_consume_token (parser);
9813 if (c_parser_next_token_is_not (parser, CPP_NAME))
9814 {
9815 c_parser_error (parser, "expected identifier");
9816 return;
9817 }
9818 if (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
9819 || c_parser_peek_2nd_token (parser)->type == CPP_SEMICOLON)
9820 {
9821 /* Any identifiers, including those declared as type names, are
9822 OK here. */
9823 while (true)
9824 {
9825 tree id;
9826 if (c_parser_next_token_is_not (parser, CPP_NAME))
9827 {
9828 c_parser_error (parser, "expected identifier");
9829 break;
9830 }
9831 id = c_parser_peek_token (parser)->value;
9832 objc_declare_protocol (id, attributes);
9833 c_parser_consume_token (parser);
9834 if (c_parser_next_token_is (parser, CPP_COMMA))
9835 c_parser_consume_token (parser);
9836 else
9837 break;
9838 }
9839 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
9840 }
9841 else
9842 {
9843 tree id = c_parser_peek_token (parser)->value;
9844 tree proto = NULL_TREE;
9845 c_parser_consume_token (parser);
9846 if (c_parser_next_token_is (parser, CPP_LESS))
9847 proto = c_parser_objc_protocol_refs (parser);
9848 parser->objc_pq_context = true;
9849 objc_start_protocol (id, proto, attributes);
9850 c_parser_objc_methodprotolist (parser);
9851 c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
9852 parser->objc_pq_context = false;
9853 objc_finish_interface ();
9854 }
9855 }
9856
9857 /* Parse an objc-method-type.
9858
9859 objc-method-type:
9860 +
9861 -
9862
9863 Return true if it is a class method (+) and false if it is
9864 an instance method (-).
9865 */
9866 static inline bool
c_parser_objc_method_type(c_parser * parser)9867 c_parser_objc_method_type (c_parser *parser)
9868 {
9869 switch (c_parser_peek_token (parser)->type)
9870 {
9871 case CPP_PLUS:
9872 c_parser_consume_token (parser);
9873 return true;
9874 case CPP_MINUS:
9875 c_parser_consume_token (parser);
9876 return false;
9877 default:
9878 gcc_unreachable ();
9879 }
9880 }
9881
9882 /* Parse an objc-method-definition.
9883
9884 objc-method-definition:
9885 objc-method-type objc-method-decl ;[opt] compound-statement
9886 */
9887
9888 static void
c_parser_objc_method_definition(c_parser * parser)9889 c_parser_objc_method_definition (c_parser *parser)
9890 {
9891 bool is_class_method = c_parser_objc_method_type (parser);
9892 tree decl, attributes = NULL_TREE, expr = NULL_TREE;
9893 parser->objc_pq_context = true;
9894 decl = c_parser_objc_method_decl (parser, is_class_method, &attributes,
9895 &expr);
9896 if (decl == error_mark_node)
9897 return; /* Bail here. */
9898
9899 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
9900 {
9901 c_parser_consume_token (parser);
9902 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
9903 "extra semicolon in method definition specified");
9904 }
9905
9906 if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE))
9907 {
9908 c_parser_error (parser, "expected %<{%>");
9909 return;
9910 }
9911
9912 parser->objc_pq_context = false;
9913 if (objc_start_method_definition (is_class_method, decl, attributes, expr))
9914 {
9915 add_stmt (c_parser_compound_statement (parser));
9916 objc_finish_method_definition (current_function_decl);
9917 }
9918 else
9919 {
9920 /* This code is executed when we find a method definition
9921 outside of an @implementation context (or invalid for other
9922 reasons). Parse the method (to keep going) but do not emit
9923 any code.
9924 */
9925 c_parser_compound_statement (parser);
9926 }
9927 }
9928
9929 /* Parse an objc-methodprotolist.
9930
9931 objc-methodprotolist:
9932 empty
9933 objc-methodprotolist objc-methodproto
9934 objc-methodprotolist declaration
9935 objc-methodprotolist ;
9936 @optional
9937 @required
9938
9939 The declaration is a data definition, which may be missing
9940 declaration specifiers under the same rules and diagnostics as
9941 other data definitions outside functions, and the stray semicolon
9942 is diagnosed the same way as a stray semicolon outside a
9943 function. */
9944
9945 static void
c_parser_objc_methodprotolist(c_parser * parser)9946 c_parser_objc_methodprotolist (c_parser *parser)
9947 {
9948 while (true)
9949 {
9950 /* The list is terminated by @end. */
9951 switch (c_parser_peek_token (parser)->type)
9952 {
9953 case CPP_SEMICOLON:
9954 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
9955 "ISO C does not allow extra %<;%> outside of a function");
9956 c_parser_consume_token (parser);
9957 break;
9958 case CPP_PLUS:
9959 case CPP_MINUS:
9960 c_parser_objc_methodproto (parser);
9961 break;
9962 case CPP_PRAGMA:
9963 c_parser_pragma (parser, pragma_external, NULL);
9964 break;
9965 case CPP_EOF:
9966 return;
9967 default:
9968 if (c_parser_next_token_is_keyword (parser, RID_AT_END))
9969 return;
9970 else if (c_parser_next_token_is_keyword (parser, RID_AT_PROPERTY))
9971 c_parser_objc_at_property_declaration (parser);
9972 else if (c_parser_next_token_is_keyword (parser, RID_AT_OPTIONAL))
9973 {
9974 objc_set_method_opt (true);
9975 c_parser_consume_token (parser);
9976 }
9977 else if (c_parser_next_token_is_keyword (parser, RID_AT_REQUIRED))
9978 {
9979 objc_set_method_opt (false);
9980 c_parser_consume_token (parser);
9981 }
9982 else
9983 c_parser_declaration_or_fndef (parser, false, false, true,
9984 false, true, NULL, vNULL);
9985 break;
9986 }
9987 }
9988 }
9989
9990 /* Parse an objc-methodproto.
9991
9992 objc-methodproto:
9993 objc-method-type objc-method-decl ;
9994 */
9995
9996 static void
c_parser_objc_methodproto(c_parser * parser)9997 c_parser_objc_methodproto (c_parser *parser)
9998 {
9999 bool is_class_method = c_parser_objc_method_type (parser);
10000 tree decl, attributes = NULL_TREE;
10001
10002 /* Remember protocol qualifiers in prototypes. */
10003 parser->objc_pq_context = true;
10004 decl = c_parser_objc_method_decl (parser, is_class_method, &attributes,
10005 NULL);
10006 /* Forget protocol qualifiers now. */
10007 parser->objc_pq_context = false;
10008
10009 /* Do not allow the presence of attributes to hide an erroneous
10010 method implementation in the interface section. */
10011 if (!c_parser_next_token_is (parser, CPP_SEMICOLON))
10012 {
10013 c_parser_error (parser, "expected %<;%>");
10014 return;
10015 }
10016
10017 if (decl != error_mark_node)
10018 objc_add_method_declaration (is_class_method, decl, attributes);
10019
10020 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
10021 }
10022
10023 /* If we are at a position that method attributes may be present, check that
10024 there are not any parsed already (a syntax error) and then collect any
10025 specified at the current location. Finally, if new attributes were present,
10026 check that the next token is legal ( ';' for decls and '{' for defs). */
10027
10028 static bool
c_parser_objc_maybe_method_attributes(c_parser * parser,tree * attributes)10029 c_parser_objc_maybe_method_attributes (c_parser* parser, tree* attributes)
10030 {
10031 bool bad = false;
10032 if (*attributes)
10033 {
10034 c_parser_error (parser,
10035 "method attributes must be specified at the end only");
10036 *attributes = NULL_TREE;
10037 bad = true;
10038 }
10039
10040 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
10041 *attributes = c_parser_attributes (parser);
10042
10043 /* If there were no attributes here, just report any earlier error. */
10044 if (*attributes == NULL_TREE || bad)
10045 return bad;
10046
10047 /* If the attributes are followed by a ; or {, then just report any earlier
10048 error. */
10049 if (c_parser_next_token_is (parser, CPP_SEMICOLON)
10050 || c_parser_next_token_is (parser, CPP_OPEN_BRACE))
10051 return bad;
10052
10053 /* We've got attributes, but not at the end. */
10054 c_parser_error (parser,
10055 "expected %<;%> or %<{%> after method attribute definition");
10056 return true;
10057 }
10058
10059 /* Parse an objc-method-decl.
10060
10061 objc-method-decl:
10062 ( objc-type-name ) objc-selector
10063 objc-selector
10064 ( objc-type-name ) objc-keyword-selector objc-optparmlist
10065 objc-keyword-selector objc-optparmlist
10066 attributes
10067
10068 objc-keyword-selector:
10069 objc-keyword-decl
10070 objc-keyword-selector objc-keyword-decl
10071
10072 objc-keyword-decl:
10073 objc-selector : ( objc-type-name ) identifier
10074 objc-selector : identifier
10075 : ( objc-type-name ) identifier
10076 : identifier
10077
10078 objc-optparmlist:
10079 objc-optparms objc-optellipsis
10080
10081 objc-optparms:
10082 empty
10083 objc-opt-parms , parameter-declaration
10084
10085 objc-optellipsis:
10086 empty
10087 , ...
10088 */
10089
10090 static tree
c_parser_objc_method_decl(c_parser * parser,bool is_class_method,tree * attributes,tree * expr)10091 c_parser_objc_method_decl (c_parser *parser, bool is_class_method,
10092 tree *attributes, tree *expr)
10093 {
10094 tree type = NULL_TREE;
10095 tree sel;
10096 tree parms = NULL_TREE;
10097 bool ellipsis = false;
10098 bool attr_err = false;
10099
10100 *attributes = NULL_TREE;
10101 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
10102 {
10103 matching_parens parens;
10104 parens.consume_open (parser);
10105 type = c_parser_objc_type_name (parser);
10106 parens.skip_until_found_close (parser);
10107 }
10108 sel = c_parser_objc_selector (parser);
10109 /* If there is no selector, or a colon follows, we have an
10110 objc-keyword-selector. If there is a selector, and a colon does
10111 not follow, that selector ends the objc-method-decl. */
10112 if (!sel || c_parser_next_token_is (parser, CPP_COLON))
10113 {
10114 tree tsel = sel;
10115 tree list = NULL_TREE;
10116 while (true)
10117 {
10118 tree atype = NULL_TREE, id, keyworddecl;
10119 tree param_attr = NULL_TREE;
10120 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
10121 break;
10122 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
10123 {
10124 c_parser_consume_token (parser);
10125 atype = c_parser_objc_type_name (parser);
10126 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
10127 "expected %<)%>");
10128 }
10129 /* New ObjC allows attributes on method parameters. */
10130 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
10131 param_attr = c_parser_attributes (parser);
10132 if (c_parser_next_token_is_not (parser, CPP_NAME))
10133 {
10134 c_parser_error (parser, "expected identifier");
10135 return error_mark_node;
10136 }
10137 id = c_parser_peek_token (parser)->value;
10138 c_parser_consume_token (parser);
10139 keyworddecl = objc_build_keyword_decl (tsel, atype, id, param_attr);
10140 list = chainon (list, keyworddecl);
10141 tsel = c_parser_objc_selector (parser);
10142 if (!tsel && c_parser_next_token_is_not (parser, CPP_COLON))
10143 break;
10144 }
10145
10146 attr_err |= c_parser_objc_maybe_method_attributes (parser, attributes) ;
10147
10148 /* Parse the optional parameter list. Optional Objective-C
10149 method parameters follow the C syntax, and may include '...'
10150 to denote a variable number of arguments. */
10151 parms = make_node (TREE_LIST);
10152 while (c_parser_next_token_is (parser, CPP_COMMA))
10153 {
10154 struct c_parm *parm;
10155 c_parser_consume_token (parser);
10156 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
10157 {
10158 ellipsis = true;
10159 c_parser_consume_token (parser);
10160 attr_err |= c_parser_objc_maybe_method_attributes
10161 (parser, attributes) ;
10162 break;
10163 }
10164 parm = c_parser_parameter_declaration (parser, NULL_TREE);
10165 if (parm == NULL)
10166 break;
10167 parms = chainon (parms,
10168 build_tree_list (NULL_TREE, grokparm (parm, expr)));
10169 }
10170 sel = list;
10171 }
10172 else
10173 attr_err |= c_parser_objc_maybe_method_attributes (parser, attributes) ;
10174
10175 if (sel == NULL)
10176 {
10177 c_parser_error (parser, "objective-c method declaration is expected");
10178 return error_mark_node;
10179 }
10180
10181 if (attr_err)
10182 return error_mark_node;
10183
10184 return objc_build_method_signature (is_class_method, type, sel, parms, ellipsis);
10185 }
10186
10187 /* Parse an objc-type-name.
10188
10189 objc-type-name:
10190 objc-type-qualifiers[opt] type-name
10191 objc-type-qualifiers[opt]
10192
10193 objc-type-qualifiers:
10194 objc-type-qualifier
10195 objc-type-qualifiers objc-type-qualifier
10196
10197 objc-type-qualifier: one of
10198 in out inout bycopy byref oneway
10199 */
10200
10201 static tree
c_parser_objc_type_name(c_parser * parser)10202 c_parser_objc_type_name (c_parser *parser)
10203 {
10204 tree quals = NULL_TREE;
10205 struct c_type_name *type_name = NULL;
10206 tree type = NULL_TREE;
10207 while (true)
10208 {
10209 c_token *token = c_parser_peek_token (parser);
10210 if (token->type == CPP_KEYWORD
10211 && (token->keyword == RID_IN
10212 || token->keyword == RID_OUT
10213 || token->keyword == RID_INOUT
10214 || token->keyword == RID_BYCOPY
10215 || token->keyword == RID_BYREF
10216 || token->keyword == RID_ONEWAY))
10217 {
10218 quals = chainon (build_tree_list (NULL_TREE, token->value), quals);
10219 c_parser_consume_token (parser);
10220 }
10221 else
10222 break;
10223 }
10224 if (c_parser_next_tokens_start_typename (parser, cla_prefer_type))
10225 type_name = c_parser_type_name (parser);
10226 if (type_name)
10227 type = groktypename (type_name, NULL, NULL);
10228
10229 /* If the type is unknown, and error has already been produced and
10230 we need to recover from the error. In that case, use NULL_TREE
10231 for the type, as if no type had been specified; this will use the
10232 default type ('id') which is good for error recovery. */
10233 if (type == error_mark_node)
10234 type = NULL_TREE;
10235
10236 return build_tree_list (quals, type);
10237 }
10238
10239 /* Parse objc-protocol-refs.
10240
10241 objc-protocol-refs:
10242 < identifier-list >
10243 */
10244
10245 static tree
c_parser_objc_protocol_refs(c_parser * parser)10246 c_parser_objc_protocol_refs (c_parser *parser)
10247 {
10248 tree list = NULL_TREE;
10249 gcc_assert (c_parser_next_token_is (parser, CPP_LESS));
10250 c_parser_consume_token (parser);
10251 /* Any identifiers, including those declared as type names, are OK
10252 here. */
10253 while (true)
10254 {
10255 tree id;
10256 if (c_parser_next_token_is_not (parser, CPP_NAME))
10257 {
10258 c_parser_error (parser, "expected identifier");
10259 break;
10260 }
10261 id = c_parser_peek_token (parser)->value;
10262 list = chainon (list, build_tree_list (NULL_TREE, id));
10263 c_parser_consume_token (parser);
10264 if (c_parser_next_token_is (parser, CPP_COMMA))
10265 c_parser_consume_token (parser);
10266 else
10267 break;
10268 }
10269 c_parser_require (parser, CPP_GREATER, "expected %<>%>");
10270 return list;
10271 }
10272
10273 /* Parse an objc-try-catch-finally-statement.
10274
10275 objc-try-catch-finally-statement:
10276 @try compound-statement objc-catch-list[opt]
10277 @try compound-statement objc-catch-list[opt] @finally compound-statement
10278
10279 objc-catch-list:
10280 @catch ( objc-catch-parameter-declaration ) compound-statement
10281 objc-catch-list @catch ( objc-catch-parameter-declaration ) compound-statement
10282
10283 objc-catch-parameter-declaration:
10284 parameter-declaration
10285 '...'
10286
10287 where '...' is to be interpreted literally, that is, it means CPP_ELLIPSIS.
10288
10289 PS: This function is identical to cp_parser_objc_try_catch_finally_statement
10290 for C++. Keep them in sync. */
10291
10292 static void
c_parser_objc_try_catch_finally_statement(c_parser * parser)10293 c_parser_objc_try_catch_finally_statement (c_parser *parser)
10294 {
10295 location_t location;
10296 tree stmt;
10297
10298 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_TRY));
10299 c_parser_consume_token (parser);
10300 location = c_parser_peek_token (parser)->location;
10301 objc_maybe_warn_exceptions (location);
10302 stmt = c_parser_compound_statement (parser);
10303 objc_begin_try_stmt (location, stmt);
10304
10305 while (c_parser_next_token_is_keyword (parser, RID_AT_CATCH))
10306 {
10307 struct c_parm *parm;
10308 tree parameter_declaration = error_mark_node;
10309 bool seen_open_paren = false;
10310
10311 c_parser_consume_token (parser);
10312 matching_parens parens;
10313 if (!parens.require_open (parser))
10314 seen_open_paren = true;
10315 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
10316 {
10317 /* We have "@catch (...)" (where the '...' are literally
10318 what is in the code). Skip the '...'.
10319 parameter_declaration is set to NULL_TREE, and
10320 objc_being_catch_clauses() knows that that means
10321 '...'. */
10322 c_parser_consume_token (parser);
10323 parameter_declaration = NULL_TREE;
10324 }
10325 else
10326 {
10327 /* We have "@catch (NSException *exception)" or something
10328 like that. Parse the parameter declaration. */
10329 parm = c_parser_parameter_declaration (parser, NULL_TREE);
10330 if (parm == NULL)
10331 parameter_declaration = error_mark_node;
10332 else
10333 parameter_declaration = grokparm (parm, NULL);
10334 }
10335 if (seen_open_paren)
10336 parens.require_close (parser);
10337 else
10338 {
10339 /* If there was no open parenthesis, we are recovering from
10340 an error, and we are trying to figure out what mistake
10341 the user has made. */
10342
10343 /* If there is an immediate closing parenthesis, the user
10344 probably forgot the opening one (ie, they typed "@catch
10345 NSException *e)". Parse the closing parenthesis and keep
10346 going. */
10347 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
10348 c_parser_consume_token (parser);
10349
10350 /* If these is no immediate closing parenthesis, the user
10351 probably doesn't know that parenthesis are required at
10352 all (ie, they typed "@catch NSException *e"). So, just
10353 forget about the closing parenthesis and keep going. */
10354 }
10355 objc_begin_catch_clause (parameter_declaration);
10356 if (c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
10357 c_parser_compound_statement_nostart (parser);
10358 objc_finish_catch_clause ();
10359 }
10360 if (c_parser_next_token_is_keyword (parser, RID_AT_FINALLY))
10361 {
10362 c_parser_consume_token (parser);
10363 location = c_parser_peek_token (parser)->location;
10364 stmt = c_parser_compound_statement (parser);
10365 objc_build_finally_clause (location, stmt);
10366 }
10367 objc_finish_try_stmt ();
10368 }
10369
10370 /* Parse an objc-synchronized-statement.
10371
10372 objc-synchronized-statement:
10373 @synchronized ( expression ) compound-statement
10374 */
10375
10376 static void
c_parser_objc_synchronized_statement(c_parser * parser)10377 c_parser_objc_synchronized_statement (c_parser *parser)
10378 {
10379 location_t loc;
10380 tree expr, stmt;
10381 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_SYNCHRONIZED));
10382 c_parser_consume_token (parser);
10383 loc = c_parser_peek_token (parser)->location;
10384 objc_maybe_warn_exceptions (loc);
10385 matching_parens parens;
10386 if (parens.require_open (parser))
10387 {
10388 struct c_expr ce = c_parser_expression (parser);
10389 ce = convert_lvalue_to_rvalue (loc, ce, false, false);
10390 expr = ce.value;
10391 expr = c_fully_fold (expr, false, NULL);
10392 parens.skip_until_found_close (parser);
10393 }
10394 else
10395 expr = error_mark_node;
10396 stmt = c_parser_compound_statement (parser);
10397 objc_build_synchronized (loc, expr, stmt);
10398 }
10399
10400 /* Parse an objc-selector; return NULL_TREE without an error if the
10401 next token is not an objc-selector.
10402
10403 objc-selector:
10404 identifier
10405 one of
10406 enum struct union if else while do for switch case default
10407 break continue return goto asm sizeof typeof __alignof
10408 unsigned long const short volatile signed restrict _Complex
10409 in out inout bycopy byref oneway int char float double void _Bool
10410 _Atomic
10411
10412 ??? Why this selection of keywords but not, for example, storage
10413 class specifiers? */
10414
10415 static tree
c_parser_objc_selector(c_parser * parser)10416 c_parser_objc_selector (c_parser *parser)
10417 {
10418 c_token *token = c_parser_peek_token (parser);
10419 tree value = token->value;
10420 if (token->type == CPP_NAME)
10421 {
10422 c_parser_consume_token (parser);
10423 return value;
10424 }
10425 if (token->type != CPP_KEYWORD)
10426 return NULL_TREE;
10427 switch (token->keyword)
10428 {
10429 case RID_ENUM:
10430 case RID_STRUCT:
10431 case RID_UNION:
10432 case RID_IF:
10433 case RID_ELSE:
10434 case RID_WHILE:
10435 case RID_DO:
10436 case RID_FOR:
10437 case RID_SWITCH:
10438 case RID_CASE:
10439 case RID_DEFAULT:
10440 case RID_BREAK:
10441 case RID_CONTINUE:
10442 case RID_RETURN:
10443 case RID_GOTO:
10444 case RID_ASM:
10445 case RID_SIZEOF:
10446 case RID_TYPEOF:
10447 case RID_ALIGNOF:
10448 case RID_UNSIGNED:
10449 case RID_LONG:
10450 case RID_CONST:
10451 case RID_SHORT:
10452 case RID_VOLATILE:
10453 case RID_SIGNED:
10454 case RID_RESTRICT:
10455 case RID_COMPLEX:
10456 case RID_IN:
10457 case RID_OUT:
10458 case RID_INOUT:
10459 case RID_BYCOPY:
10460 case RID_BYREF:
10461 case RID_ONEWAY:
10462 case RID_INT:
10463 case RID_CHAR:
10464 case RID_FLOAT:
10465 case RID_DOUBLE:
10466 CASE_RID_FLOATN_NX:
10467 case RID_VOID:
10468 case RID_BOOL:
10469 case RID_ATOMIC:
10470 case RID_AUTO_TYPE:
10471 case RID_INT_N_0:
10472 case RID_INT_N_1:
10473 case RID_INT_N_2:
10474 case RID_INT_N_3:
10475 c_parser_consume_token (parser);
10476 return value;
10477 default:
10478 return NULL_TREE;
10479 }
10480 }
10481
10482 /* Parse an objc-selector-arg.
10483
10484 objc-selector-arg:
10485 objc-selector
10486 objc-keywordname-list
10487
10488 objc-keywordname-list:
10489 objc-keywordname
10490 objc-keywordname-list objc-keywordname
10491
10492 objc-keywordname:
10493 objc-selector :
10494 :
10495 */
10496
10497 static tree
c_parser_objc_selector_arg(c_parser * parser)10498 c_parser_objc_selector_arg (c_parser *parser)
10499 {
10500 tree sel = c_parser_objc_selector (parser);
10501 tree list = NULL_TREE;
10502 if (sel && c_parser_next_token_is_not (parser, CPP_COLON))
10503 return sel;
10504 while (true)
10505 {
10506 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
10507 return list;
10508 list = chainon (list, build_tree_list (sel, NULL_TREE));
10509 sel = c_parser_objc_selector (parser);
10510 if (!sel && c_parser_next_token_is_not (parser, CPP_COLON))
10511 break;
10512 }
10513 return list;
10514 }
10515
10516 /* Parse an objc-receiver.
10517
10518 objc-receiver:
10519 expression
10520 class-name
10521 type-name
10522 */
10523
10524 static tree
c_parser_objc_receiver(c_parser * parser)10525 c_parser_objc_receiver (c_parser *parser)
10526 {
10527 location_t loc = c_parser_peek_token (parser)->location;
10528
10529 if (c_parser_peek_token (parser)->type == CPP_NAME
10530 && (c_parser_peek_token (parser)->id_kind == C_ID_TYPENAME
10531 || c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME))
10532 {
10533 tree id = c_parser_peek_token (parser)->value;
10534 c_parser_consume_token (parser);
10535 return objc_get_class_reference (id);
10536 }
10537 struct c_expr ce = c_parser_expression (parser);
10538 ce = convert_lvalue_to_rvalue (loc, ce, false, false);
10539 return c_fully_fold (ce.value, false, NULL);
10540 }
10541
10542 /* Parse objc-message-args.
10543
10544 objc-message-args:
10545 objc-selector
10546 objc-keywordarg-list
10547
10548 objc-keywordarg-list:
10549 objc-keywordarg
10550 objc-keywordarg-list objc-keywordarg
10551
10552 objc-keywordarg:
10553 objc-selector : objc-keywordexpr
10554 : objc-keywordexpr
10555 */
10556
10557 static tree
c_parser_objc_message_args(c_parser * parser)10558 c_parser_objc_message_args (c_parser *parser)
10559 {
10560 tree sel = c_parser_objc_selector (parser);
10561 tree list = NULL_TREE;
10562 if (sel && c_parser_next_token_is_not (parser, CPP_COLON))
10563 return sel;
10564 while (true)
10565 {
10566 tree keywordexpr;
10567 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
10568 return error_mark_node;
10569 keywordexpr = c_parser_objc_keywordexpr (parser);
10570 list = chainon (list, build_tree_list (sel, keywordexpr));
10571 sel = c_parser_objc_selector (parser);
10572 if (!sel && c_parser_next_token_is_not (parser, CPP_COLON))
10573 break;
10574 }
10575 return list;
10576 }
10577
10578 /* Parse an objc-keywordexpr.
10579
10580 objc-keywordexpr:
10581 nonempty-expr-list
10582 */
10583
10584 static tree
c_parser_objc_keywordexpr(c_parser * parser)10585 c_parser_objc_keywordexpr (c_parser *parser)
10586 {
10587 tree ret;
10588 vec<tree, va_gc> *expr_list = c_parser_expr_list (parser, true, true,
10589 NULL, NULL, NULL, NULL);
10590 if (vec_safe_length (expr_list) == 1)
10591 {
10592 /* Just return the expression, remove a level of
10593 indirection. */
10594 ret = (*expr_list)[0];
10595 }
10596 else
10597 {
10598 /* We have a comma expression, we will collapse later. */
10599 ret = build_tree_list_vec (expr_list);
10600 }
10601 release_tree_vector (expr_list);
10602 return ret;
10603 }
10604
10605 /* A check, needed in several places, that ObjC interface, implementation or
10606 method definitions are not prefixed by incorrect items. */
10607 static bool
c_parser_objc_diagnose_bad_element_prefix(c_parser * parser,struct c_declspecs * specs)10608 c_parser_objc_diagnose_bad_element_prefix (c_parser *parser,
10609 struct c_declspecs *specs)
10610 {
10611 if (!specs->declspecs_seen_p || specs->non_sc_seen_p
10612 || specs->typespec_kind != ctsk_none)
10613 {
10614 c_parser_error (parser,
10615 "no type or storage class may be specified here,");
10616 c_parser_skip_to_end_of_block_or_statement (parser);
10617 return true;
10618 }
10619 return false;
10620 }
10621
10622 /* Parse an Objective-C @property declaration. The syntax is:
10623
10624 objc-property-declaration:
10625 '@property' objc-property-attributes[opt] struct-declaration ;
10626
10627 objc-property-attributes:
10628 '(' objc-property-attribute-list ')'
10629
10630 objc-property-attribute-list:
10631 objc-property-attribute
10632 objc-property-attribute-list, objc-property-attribute
10633
10634 objc-property-attribute
10635 'getter' = identifier
10636 'setter' = identifier
10637 'readonly'
10638 'readwrite'
10639 'assign'
10640 'retain'
10641 'copy'
10642 'nonatomic'
10643
10644 For example:
10645 @property NSString *name;
10646 @property (readonly) id object;
10647 @property (retain, nonatomic, getter=getTheName) id name;
10648 @property int a, b, c;
10649
10650 PS: This function is identical to cp_parser_objc_at_propery_declaration
10651 for C++. Keep them in sync. */
10652 static void
c_parser_objc_at_property_declaration(c_parser * parser)10653 c_parser_objc_at_property_declaration (c_parser *parser)
10654 {
10655 /* The following variables hold the attributes of the properties as
10656 parsed. They are 'false' or 'NULL_TREE' if the attribute was not
10657 seen. When we see an attribute, we set them to 'true' (if they
10658 are boolean properties) or to the identifier (if they have an
10659 argument, ie, for getter and setter). Note that here we only
10660 parse the list of attributes, check the syntax and accumulate the
10661 attributes that we find. objc_add_property_declaration() will
10662 then process the information. */
10663 bool property_assign = false;
10664 bool property_copy = false;
10665 tree property_getter_ident = NULL_TREE;
10666 bool property_nonatomic = false;
10667 bool property_readonly = false;
10668 bool property_readwrite = false;
10669 bool property_retain = false;
10670 tree property_setter_ident = NULL_TREE;
10671
10672 /* 'properties' is the list of properties that we read. Usually a
10673 single one, but maybe more (eg, in "@property int a, b, c;" there
10674 are three). */
10675 tree properties;
10676 location_t loc;
10677
10678 loc = c_parser_peek_token (parser)->location;
10679 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_PROPERTY));
10680
10681 c_parser_consume_token (parser); /* Eat '@property'. */
10682
10683 /* Parse the optional attribute list... */
10684 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
10685 {
10686 matching_parens parens;
10687
10688 /* Eat the '(' */
10689 parens.consume_open (parser);
10690
10691 /* Property attribute keywords are valid now. */
10692 parser->objc_property_attr_context = true;
10693
10694 while (true)
10695 {
10696 bool syntax_error = false;
10697 c_token *token = c_parser_peek_token (parser);
10698 enum rid keyword;
10699
10700 if (token->type != CPP_KEYWORD)
10701 {
10702 if (token->type == CPP_CLOSE_PAREN)
10703 c_parser_error (parser, "expected identifier");
10704 else
10705 {
10706 c_parser_consume_token (parser);
10707 c_parser_error (parser, "unknown property attribute");
10708 }
10709 break;
10710 }
10711 keyword = token->keyword;
10712 c_parser_consume_token (parser);
10713 switch (keyword)
10714 {
10715 case RID_ASSIGN: property_assign = true; break;
10716 case RID_COPY: property_copy = true; break;
10717 case RID_NONATOMIC: property_nonatomic = true; break;
10718 case RID_READONLY: property_readonly = true; break;
10719 case RID_READWRITE: property_readwrite = true; break;
10720 case RID_RETAIN: property_retain = true; break;
10721
10722 case RID_GETTER:
10723 case RID_SETTER:
10724 if (c_parser_next_token_is_not (parser, CPP_EQ))
10725 {
10726 if (keyword == RID_GETTER)
10727 c_parser_error (parser,
10728 "missing %<=%> (after %<getter%> attribute)");
10729 else
10730 c_parser_error (parser,
10731 "missing %<=%> (after %<setter%> attribute)");
10732 syntax_error = true;
10733 break;
10734 }
10735 c_parser_consume_token (parser); /* eat the = */
10736 if (c_parser_next_token_is_not (parser, CPP_NAME))
10737 {
10738 c_parser_error (parser, "expected identifier");
10739 syntax_error = true;
10740 break;
10741 }
10742 if (keyword == RID_SETTER)
10743 {
10744 if (property_setter_ident != NULL_TREE)
10745 c_parser_error (parser, "the %<setter%> attribute may only be specified once");
10746 else
10747 property_setter_ident = c_parser_peek_token (parser)->value;
10748 c_parser_consume_token (parser);
10749 if (c_parser_next_token_is_not (parser, CPP_COLON))
10750 c_parser_error (parser, "setter name must terminate with %<:%>");
10751 else
10752 c_parser_consume_token (parser);
10753 }
10754 else
10755 {
10756 if (property_getter_ident != NULL_TREE)
10757 c_parser_error (parser, "the %<getter%> attribute may only be specified once");
10758 else
10759 property_getter_ident = c_parser_peek_token (parser)->value;
10760 c_parser_consume_token (parser);
10761 }
10762 break;
10763 default:
10764 c_parser_error (parser, "unknown property attribute");
10765 syntax_error = true;
10766 break;
10767 }
10768
10769 if (syntax_error)
10770 break;
10771
10772 if (c_parser_next_token_is (parser, CPP_COMMA))
10773 c_parser_consume_token (parser);
10774 else
10775 break;
10776 }
10777 parser->objc_property_attr_context = false;
10778 parens.skip_until_found_close (parser);
10779 }
10780 /* ... and the property declaration(s). */
10781 properties = c_parser_struct_declaration (parser);
10782
10783 if (properties == error_mark_node)
10784 {
10785 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
10786 parser->error = false;
10787 return;
10788 }
10789
10790 if (properties == NULL_TREE)
10791 c_parser_error (parser, "expected identifier");
10792 else
10793 {
10794 /* Comma-separated properties are chained together in
10795 reverse order; add them one by one. */
10796 properties = nreverse (properties);
10797
10798 for (; properties; properties = TREE_CHAIN (properties))
10799 objc_add_property_declaration (loc, copy_node (properties),
10800 property_readonly, property_readwrite,
10801 property_assign, property_retain,
10802 property_copy, property_nonatomic,
10803 property_getter_ident, property_setter_ident);
10804 }
10805
10806 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
10807 parser->error = false;
10808 }
10809
10810 /* Parse an Objective-C @synthesize declaration. The syntax is:
10811
10812 objc-synthesize-declaration:
10813 @synthesize objc-synthesize-identifier-list ;
10814
10815 objc-synthesize-identifier-list:
10816 objc-synthesize-identifier
10817 objc-synthesize-identifier-list, objc-synthesize-identifier
10818
10819 objc-synthesize-identifier
10820 identifier
10821 identifier = identifier
10822
10823 For example:
10824 @synthesize MyProperty;
10825 @synthesize OneProperty, AnotherProperty=MyIvar, YetAnotherProperty;
10826
10827 PS: This function is identical to cp_parser_objc_at_synthesize_declaration
10828 for C++. Keep them in sync.
10829 */
10830 static void
c_parser_objc_at_synthesize_declaration(c_parser * parser)10831 c_parser_objc_at_synthesize_declaration (c_parser *parser)
10832 {
10833 tree list = NULL_TREE;
10834 location_t loc;
10835 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_SYNTHESIZE));
10836 loc = c_parser_peek_token (parser)->location;
10837
10838 c_parser_consume_token (parser);
10839 while (true)
10840 {
10841 tree property, ivar;
10842 if (c_parser_next_token_is_not (parser, CPP_NAME))
10843 {
10844 c_parser_error (parser, "expected identifier");
10845 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
10846 /* Once we find the semicolon, we can resume normal parsing.
10847 We have to reset parser->error manually because
10848 c_parser_skip_until_found() won't reset it for us if the
10849 next token is precisely a semicolon. */
10850 parser->error = false;
10851 return;
10852 }
10853 property = c_parser_peek_token (parser)->value;
10854 c_parser_consume_token (parser);
10855 if (c_parser_next_token_is (parser, CPP_EQ))
10856 {
10857 c_parser_consume_token (parser);
10858 if (c_parser_next_token_is_not (parser, CPP_NAME))
10859 {
10860 c_parser_error (parser, "expected identifier");
10861 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
10862 parser->error = false;
10863 return;
10864 }
10865 ivar = c_parser_peek_token (parser)->value;
10866 c_parser_consume_token (parser);
10867 }
10868 else
10869 ivar = NULL_TREE;
10870 list = chainon (list, build_tree_list (ivar, property));
10871 if (c_parser_next_token_is (parser, CPP_COMMA))
10872 c_parser_consume_token (parser);
10873 else
10874 break;
10875 }
10876 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
10877 objc_add_synthesize_declaration (loc, list);
10878 }
10879
10880 /* Parse an Objective-C @dynamic declaration. The syntax is:
10881
10882 objc-dynamic-declaration:
10883 @dynamic identifier-list ;
10884
10885 For example:
10886 @dynamic MyProperty;
10887 @dynamic MyProperty, AnotherProperty;
10888
10889 PS: This function is identical to cp_parser_objc_at_dynamic_declaration
10890 for C++. Keep them in sync.
10891 */
10892 static void
c_parser_objc_at_dynamic_declaration(c_parser * parser)10893 c_parser_objc_at_dynamic_declaration (c_parser *parser)
10894 {
10895 tree list = NULL_TREE;
10896 location_t loc;
10897 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_DYNAMIC));
10898 loc = c_parser_peek_token (parser)->location;
10899
10900 c_parser_consume_token (parser);
10901 while (true)
10902 {
10903 tree property;
10904 if (c_parser_next_token_is_not (parser, CPP_NAME))
10905 {
10906 c_parser_error (parser, "expected identifier");
10907 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
10908 parser->error = false;
10909 return;
10910 }
10911 property = c_parser_peek_token (parser)->value;
10912 list = chainon (list, build_tree_list (NULL_TREE, property));
10913 c_parser_consume_token (parser);
10914 if (c_parser_next_token_is (parser, CPP_COMMA))
10915 c_parser_consume_token (parser);
10916 else
10917 break;
10918 }
10919 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
10920 objc_add_dynamic_declaration (loc, list);
10921 }
10922
10923
10924 /* Parse a pragma GCC ivdep. */
10925
10926 static bool
c_parse_pragma_ivdep(c_parser * parser)10927 c_parse_pragma_ivdep (c_parser *parser)
10928 {
10929 c_parser_consume_pragma (parser);
10930 c_parser_skip_to_pragma_eol (parser);
10931 return true;
10932 }
10933
10934 /* Parse a pragma GCC unroll. */
10935
10936 static unsigned short
c_parser_pragma_unroll(c_parser * parser)10937 c_parser_pragma_unroll (c_parser *parser)
10938 {
10939 unsigned short unroll;
10940 c_parser_consume_pragma (parser);
10941 location_t location = c_parser_peek_token (parser)->location;
10942 tree expr = c_parser_expr_no_commas (parser, NULL).value;
10943 mark_exp_read (expr);
10944 expr = c_fully_fold (expr, false, NULL);
10945 HOST_WIDE_INT lunroll = 0;
10946 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr))
10947 || TREE_CODE (expr) != INTEGER_CST
10948 || (lunroll = tree_to_shwi (expr)) < 0
10949 || lunroll >= USHRT_MAX)
10950 {
10951 error_at (location, "%<#pragma GCC unroll%> requires an"
10952 " assignment-expression that evaluates to a non-negative"
10953 " integral constant less than %u", USHRT_MAX);
10954 unroll = 0;
10955 }
10956 else
10957 {
10958 unroll = (unsigned short)lunroll;
10959 if (unroll == 0)
10960 unroll = 1;
10961 }
10962
10963 c_parser_skip_to_pragma_eol (parser);
10964 return unroll;
10965 }
10966
10967 /* Handle pragmas. Some OpenMP pragmas are associated with, and therefore
10968 should be considered, statements. ALLOW_STMT is true if we're within
10969 the context of a function and such pragmas are to be allowed. Returns
10970 true if we actually parsed such a pragma. */
10971
10972 static bool
c_parser_pragma(c_parser * parser,enum pragma_context context,bool * if_p)10973 c_parser_pragma (c_parser *parser, enum pragma_context context, bool *if_p)
10974 {
10975 unsigned int id;
10976 const char *construct = NULL;
10977
10978 id = c_parser_peek_token (parser)->pragma_kind;
10979 gcc_assert (id != PRAGMA_NONE);
10980
10981 switch (id)
10982 {
10983 case PRAGMA_OACC_DECLARE:
10984 c_parser_oacc_declare (parser);
10985 return false;
10986
10987 case PRAGMA_OACC_ENTER_DATA:
10988 if (context != pragma_compound)
10989 {
10990 construct = "acc enter data";
10991 in_compound:
10992 if (context == pragma_stmt)
10993 {
10994 error_at (c_parser_peek_token (parser)->location,
10995 "%<#pragma %s%> may only be used in compound "
10996 "statements", construct);
10997 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
10998 return false;
10999 }
11000 goto bad_stmt;
11001 }
11002 c_parser_oacc_enter_exit_data (parser, true);
11003 return false;
11004
11005 case PRAGMA_OACC_EXIT_DATA:
11006 if (context != pragma_compound)
11007 {
11008 construct = "acc exit data";
11009 goto in_compound;
11010 }
11011 c_parser_oacc_enter_exit_data (parser, false);
11012 return false;
11013
11014 case PRAGMA_OACC_ROUTINE:
11015 if (context != pragma_external)
11016 {
11017 error_at (c_parser_peek_token (parser)->location,
11018 "%<#pragma acc routine%> must be at file scope");
11019 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
11020 return false;
11021 }
11022 c_parser_oacc_routine (parser, context);
11023 return false;
11024
11025 case PRAGMA_OACC_UPDATE:
11026 if (context != pragma_compound)
11027 {
11028 construct = "acc update";
11029 goto in_compound;
11030 }
11031 c_parser_oacc_update (parser);
11032 return false;
11033
11034 case PRAGMA_OMP_BARRIER:
11035 if (context != pragma_compound)
11036 {
11037 construct = "omp barrier";
11038 goto in_compound;
11039 }
11040 c_parser_omp_barrier (parser);
11041 return false;
11042
11043 case PRAGMA_OMP_FLUSH:
11044 if (context != pragma_compound)
11045 {
11046 construct = "omp flush";
11047 goto in_compound;
11048 }
11049 c_parser_omp_flush (parser);
11050 return false;
11051
11052 case PRAGMA_OMP_TASKWAIT:
11053 if (context != pragma_compound)
11054 {
11055 construct = "omp taskwait";
11056 goto in_compound;
11057 }
11058 c_parser_omp_taskwait (parser);
11059 return false;
11060
11061 case PRAGMA_OMP_TASKYIELD:
11062 if (context != pragma_compound)
11063 {
11064 construct = "omp taskyield";
11065 goto in_compound;
11066 }
11067 c_parser_omp_taskyield (parser);
11068 return false;
11069
11070 case PRAGMA_OMP_CANCEL:
11071 if (context != pragma_compound)
11072 {
11073 construct = "omp cancel";
11074 goto in_compound;
11075 }
11076 c_parser_omp_cancel (parser);
11077 return false;
11078
11079 case PRAGMA_OMP_CANCELLATION_POINT:
11080 c_parser_omp_cancellation_point (parser, context);
11081 return false;
11082
11083 case PRAGMA_OMP_THREADPRIVATE:
11084 c_parser_omp_threadprivate (parser);
11085 return false;
11086
11087 case PRAGMA_OMP_TARGET:
11088 return c_parser_omp_target (parser, context, if_p);
11089
11090 case PRAGMA_OMP_END_DECLARE_TARGET:
11091 c_parser_omp_end_declare_target (parser);
11092 return false;
11093
11094 case PRAGMA_OMP_SECTION:
11095 error_at (c_parser_peek_token (parser)->location,
11096 "%<#pragma omp section%> may only be used in "
11097 "%<#pragma omp sections%> construct");
11098 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
11099 return false;
11100
11101 case PRAGMA_OMP_DECLARE:
11102 c_parser_omp_declare (parser, context);
11103 return false;
11104
11105 case PRAGMA_OMP_ORDERED:
11106 return c_parser_omp_ordered (parser, context, if_p);
11107
11108 case PRAGMA_IVDEP:
11109 {
11110 const bool ivdep = c_parse_pragma_ivdep (parser);
11111 unsigned short unroll;
11112 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_UNROLL)
11113 unroll = c_parser_pragma_unroll (parser);
11114 else
11115 unroll = 0;
11116 if (!c_parser_next_token_is_keyword (parser, RID_FOR)
11117 && !c_parser_next_token_is_keyword (parser, RID_WHILE)
11118 && !c_parser_next_token_is_keyword (parser, RID_DO))
11119 {
11120 c_parser_error (parser, "for, while or do statement expected");
11121 return false;
11122 }
11123 if (c_parser_next_token_is_keyword (parser, RID_FOR))
11124 c_parser_for_statement (parser, ivdep, unroll, if_p);
11125 else if (c_parser_next_token_is_keyword (parser, RID_WHILE))
11126 c_parser_while_statement (parser, ivdep, unroll, if_p);
11127 else
11128 c_parser_do_statement (parser, ivdep, unroll);
11129 }
11130 return false;
11131
11132 case PRAGMA_UNROLL:
11133 {
11134 unsigned short unroll = c_parser_pragma_unroll (parser);
11135 bool ivdep;
11136 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_IVDEP)
11137 ivdep = c_parse_pragma_ivdep (parser);
11138 else
11139 ivdep = false;
11140 if (!c_parser_next_token_is_keyword (parser, RID_FOR)
11141 && !c_parser_next_token_is_keyword (parser, RID_WHILE)
11142 && !c_parser_next_token_is_keyword (parser, RID_DO))
11143 {
11144 c_parser_error (parser, "for, while or do statement expected");
11145 return false;
11146 }
11147 if (c_parser_next_token_is_keyword (parser, RID_FOR))
11148 c_parser_for_statement (parser, ivdep, unroll, if_p);
11149 else if (c_parser_next_token_is_keyword (parser, RID_WHILE))
11150 c_parser_while_statement (parser, ivdep, unroll, if_p);
11151 else
11152 c_parser_do_statement (parser, ivdep, unroll);
11153 }
11154 return false;
11155
11156 case PRAGMA_GCC_PCH_PREPROCESS:
11157 c_parser_error (parser, "%<#pragma GCC pch_preprocess%> must be first");
11158 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
11159 return false;
11160
11161 case PRAGMA_OACC_WAIT:
11162 if (context != pragma_compound)
11163 {
11164 construct = "acc wait";
11165 goto in_compound;
11166 }
11167 /* FALL THROUGH. */
11168
11169 default:
11170 if (id < PRAGMA_FIRST_EXTERNAL)
11171 {
11172 if (context != pragma_stmt && context != pragma_compound)
11173 {
11174 bad_stmt:
11175 c_parser_error (parser, "expected declaration specifiers");
11176 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
11177 return false;
11178 }
11179 c_parser_omp_construct (parser, if_p);
11180 return true;
11181 }
11182 break;
11183 }
11184
11185 c_parser_consume_pragma (parser);
11186 c_invoke_pragma_handler (id);
11187
11188 /* Skip to EOL, but suppress any error message. Those will have been
11189 generated by the handler routine through calling error, as opposed
11190 to calling c_parser_error. */
11191 parser->error = true;
11192 c_parser_skip_to_pragma_eol (parser);
11193
11194 return false;
11195 }
11196
11197 /* The interface the pragma parsers have to the lexer. */
11198
11199 enum cpp_ttype
pragma_lex(tree * value,location_t * loc)11200 pragma_lex (tree *value, location_t *loc)
11201 {
11202 c_token *tok = c_parser_peek_token (the_parser);
11203 enum cpp_ttype ret = tok->type;
11204
11205 *value = tok->value;
11206 if (loc)
11207 *loc = tok->location;
11208
11209 if (ret == CPP_PRAGMA_EOL || ret == CPP_EOF)
11210 ret = CPP_EOF;
11211 else
11212 {
11213 if (ret == CPP_KEYWORD)
11214 ret = CPP_NAME;
11215 c_parser_consume_token (the_parser);
11216 }
11217
11218 return ret;
11219 }
11220
11221 static void
c_parser_pragma_pch_preprocess(c_parser * parser)11222 c_parser_pragma_pch_preprocess (c_parser *parser)
11223 {
11224 tree name = NULL;
11225
11226 c_parser_consume_pragma (parser);
11227 if (c_parser_next_token_is (parser, CPP_STRING))
11228 {
11229 name = c_parser_peek_token (parser)->value;
11230 c_parser_consume_token (parser);
11231 }
11232 else
11233 c_parser_error (parser, "expected string literal");
11234 c_parser_skip_to_pragma_eol (parser);
11235
11236 if (name)
11237 c_common_pch_pragma (parse_in, TREE_STRING_POINTER (name));
11238 }
11239
11240 /* OpenACC and OpenMP parsing routines. */
11241
11242 /* Returns name of the next clause.
11243 If the clause is not recognized PRAGMA_OMP_CLAUSE_NONE is returned and
11244 the token is not consumed. Otherwise appropriate pragma_omp_clause is
11245 returned and the token is consumed. */
11246
11247 static pragma_omp_clause
c_parser_omp_clause_name(c_parser * parser)11248 c_parser_omp_clause_name (c_parser *parser)
11249 {
11250 pragma_omp_clause result = PRAGMA_OMP_CLAUSE_NONE;
11251
11252 if (c_parser_next_token_is_keyword (parser, RID_AUTO))
11253 result = PRAGMA_OACC_CLAUSE_AUTO;
11254 else if (c_parser_next_token_is_keyword (parser, RID_IF))
11255 result = PRAGMA_OMP_CLAUSE_IF;
11256 else if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
11257 result = PRAGMA_OMP_CLAUSE_DEFAULT;
11258 else if (c_parser_next_token_is_keyword (parser, RID_FOR))
11259 result = PRAGMA_OMP_CLAUSE_FOR;
11260 else if (c_parser_next_token_is (parser, CPP_NAME))
11261 {
11262 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
11263
11264 switch (p[0])
11265 {
11266 case 'a':
11267 if (!strcmp ("aligned", p))
11268 result = PRAGMA_OMP_CLAUSE_ALIGNED;
11269 else if (!strcmp ("async", p))
11270 result = PRAGMA_OACC_CLAUSE_ASYNC;
11271 break;
11272 case 'c':
11273 if (!strcmp ("collapse", p))
11274 result = PRAGMA_OMP_CLAUSE_COLLAPSE;
11275 else if (!strcmp ("copy", p))
11276 result = PRAGMA_OACC_CLAUSE_COPY;
11277 else if (!strcmp ("copyin", p))
11278 result = PRAGMA_OMP_CLAUSE_COPYIN;
11279 else if (!strcmp ("copyout", p))
11280 result = PRAGMA_OACC_CLAUSE_COPYOUT;
11281 else if (!strcmp ("copyprivate", p))
11282 result = PRAGMA_OMP_CLAUSE_COPYPRIVATE;
11283 else if (!strcmp ("create", p))
11284 result = PRAGMA_OACC_CLAUSE_CREATE;
11285 break;
11286 case 'd':
11287 if (!strcmp ("defaultmap", p))
11288 result = PRAGMA_OMP_CLAUSE_DEFAULTMAP;
11289 else if (!strcmp ("delete", p))
11290 result = PRAGMA_OACC_CLAUSE_DELETE;
11291 else if (!strcmp ("depend", p))
11292 result = PRAGMA_OMP_CLAUSE_DEPEND;
11293 else if (!strcmp ("device", p))
11294 result = PRAGMA_OMP_CLAUSE_DEVICE;
11295 else if (!strcmp ("deviceptr", p))
11296 result = PRAGMA_OACC_CLAUSE_DEVICEPTR;
11297 else if (!strcmp ("device_resident", p))
11298 result = PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT;
11299 else if (!strcmp ("dist_schedule", p))
11300 result = PRAGMA_OMP_CLAUSE_DIST_SCHEDULE;
11301 break;
11302 case 'f':
11303 if (!strcmp ("final", p))
11304 result = PRAGMA_OMP_CLAUSE_FINAL;
11305 else if (!strcmp ("firstprivate", p))
11306 result = PRAGMA_OMP_CLAUSE_FIRSTPRIVATE;
11307 else if (!strcmp ("from", p))
11308 result = PRAGMA_OMP_CLAUSE_FROM;
11309 break;
11310 case 'g':
11311 if (!strcmp ("gang", p))
11312 result = PRAGMA_OACC_CLAUSE_GANG;
11313 else if (!strcmp ("grainsize", p))
11314 result = PRAGMA_OMP_CLAUSE_GRAINSIZE;
11315 break;
11316 case 'h':
11317 if (!strcmp ("hint", p))
11318 result = PRAGMA_OMP_CLAUSE_HINT;
11319 else if (!strcmp ("host", p))
11320 result = PRAGMA_OACC_CLAUSE_HOST;
11321 break;
11322 case 'i':
11323 if (!strcmp ("inbranch", p))
11324 result = PRAGMA_OMP_CLAUSE_INBRANCH;
11325 else if (!strcmp ("independent", p))
11326 result = PRAGMA_OACC_CLAUSE_INDEPENDENT;
11327 else if (!strcmp ("is_device_ptr", p))
11328 result = PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR;
11329 break;
11330 case 'l':
11331 if (!strcmp ("lastprivate", p))
11332 result = PRAGMA_OMP_CLAUSE_LASTPRIVATE;
11333 else if (!strcmp ("linear", p))
11334 result = PRAGMA_OMP_CLAUSE_LINEAR;
11335 else if (!strcmp ("link", p))
11336 result = PRAGMA_OMP_CLAUSE_LINK;
11337 break;
11338 case 'm':
11339 if (!strcmp ("map", p))
11340 result = PRAGMA_OMP_CLAUSE_MAP;
11341 else if (!strcmp ("mergeable", p))
11342 result = PRAGMA_OMP_CLAUSE_MERGEABLE;
11343 break;
11344 case 'n':
11345 if (!strcmp ("nogroup", p))
11346 result = PRAGMA_OMP_CLAUSE_NOGROUP;
11347 else if (!strcmp ("notinbranch", p))
11348 result = PRAGMA_OMP_CLAUSE_NOTINBRANCH;
11349 else if (!strcmp ("nowait", p))
11350 result = PRAGMA_OMP_CLAUSE_NOWAIT;
11351 else if (!strcmp ("num_gangs", p))
11352 result = PRAGMA_OACC_CLAUSE_NUM_GANGS;
11353 else if (!strcmp ("num_tasks", p))
11354 result = PRAGMA_OMP_CLAUSE_NUM_TASKS;
11355 else if (!strcmp ("num_teams", p))
11356 result = PRAGMA_OMP_CLAUSE_NUM_TEAMS;
11357 else if (!strcmp ("num_threads", p))
11358 result = PRAGMA_OMP_CLAUSE_NUM_THREADS;
11359 else if (!strcmp ("num_workers", p))
11360 result = PRAGMA_OACC_CLAUSE_NUM_WORKERS;
11361 break;
11362 case 'o':
11363 if (!strcmp ("ordered", p))
11364 result = PRAGMA_OMP_CLAUSE_ORDERED;
11365 break;
11366 case 'p':
11367 if (!strcmp ("parallel", p))
11368 result = PRAGMA_OMP_CLAUSE_PARALLEL;
11369 else if (!strcmp ("present", p))
11370 result = PRAGMA_OACC_CLAUSE_PRESENT;
11371 else if (!strcmp ("present_or_copy", p)
11372 || !strcmp ("pcopy", p))
11373 result = PRAGMA_OACC_CLAUSE_PRESENT_OR_COPY;
11374 else if (!strcmp ("present_or_copyin", p)
11375 || !strcmp ("pcopyin", p))
11376 result = PRAGMA_OACC_CLAUSE_PRESENT_OR_COPYIN;
11377 else if (!strcmp ("present_or_copyout", p)
11378 || !strcmp ("pcopyout", p))
11379 result = PRAGMA_OACC_CLAUSE_PRESENT_OR_COPYOUT;
11380 else if (!strcmp ("present_or_create", p)
11381 || !strcmp ("pcreate", p))
11382 result = PRAGMA_OACC_CLAUSE_PRESENT_OR_CREATE;
11383 else if (!strcmp ("priority", p))
11384 result = PRAGMA_OMP_CLAUSE_PRIORITY;
11385 else if (!strcmp ("private", p))
11386 result = PRAGMA_OMP_CLAUSE_PRIVATE;
11387 else if (!strcmp ("proc_bind", p))
11388 result = PRAGMA_OMP_CLAUSE_PROC_BIND;
11389 break;
11390 case 'r':
11391 if (!strcmp ("reduction", p))
11392 result = PRAGMA_OMP_CLAUSE_REDUCTION;
11393 break;
11394 case 's':
11395 if (!strcmp ("safelen", p))
11396 result = PRAGMA_OMP_CLAUSE_SAFELEN;
11397 else if (!strcmp ("schedule", p))
11398 result = PRAGMA_OMP_CLAUSE_SCHEDULE;
11399 else if (!strcmp ("sections", p))
11400 result = PRAGMA_OMP_CLAUSE_SECTIONS;
11401 else if (!strcmp ("seq", p))
11402 result = PRAGMA_OACC_CLAUSE_SEQ;
11403 else if (!strcmp ("shared", p))
11404 result = PRAGMA_OMP_CLAUSE_SHARED;
11405 else if (!strcmp ("simd", p))
11406 result = PRAGMA_OMP_CLAUSE_SIMD;
11407 else if (!strcmp ("simdlen", p))
11408 result = PRAGMA_OMP_CLAUSE_SIMDLEN;
11409 else if (!strcmp ("self", p))
11410 result = PRAGMA_OACC_CLAUSE_SELF;
11411 break;
11412 case 't':
11413 if (!strcmp ("taskgroup", p))
11414 result = PRAGMA_OMP_CLAUSE_TASKGROUP;
11415 else if (!strcmp ("thread_limit", p))
11416 result = PRAGMA_OMP_CLAUSE_THREAD_LIMIT;
11417 else if (!strcmp ("threads", p))
11418 result = PRAGMA_OMP_CLAUSE_THREADS;
11419 else if (!strcmp ("tile", p))
11420 result = PRAGMA_OACC_CLAUSE_TILE;
11421 else if (!strcmp ("to", p))
11422 result = PRAGMA_OMP_CLAUSE_TO;
11423 break;
11424 case 'u':
11425 if (!strcmp ("uniform", p))
11426 result = PRAGMA_OMP_CLAUSE_UNIFORM;
11427 else if (!strcmp ("untied", p))
11428 result = PRAGMA_OMP_CLAUSE_UNTIED;
11429 else if (!strcmp ("use_device", p))
11430 result = PRAGMA_OACC_CLAUSE_USE_DEVICE;
11431 else if (!strcmp ("use_device_ptr", p))
11432 result = PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR;
11433 break;
11434 case 'v':
11435 if (!strcmp ("vector", p))
11436 result = PRAGMA_OACC_CLAUSE_VECTOR;
11437 else if (!strcmp ("vector_length", p))
11438 result = PRAGMA_OACC_CLAUSE_VECTOR_LENGTH;
11439 break;
11440 case 'w':
11441 if (!strcmp ("wait", p))
11442 result = PRAGMA_OACC_CLAUSE_WAIT;
11443 else if (!strcmp ("worker", p))
11444 result = PRAGMA_OACC_CLAUSE_WORKER;
11445 break;
11446 }
11447 }
11448
11449 if (result != PRAGMA_OMP_CLAUSE_NONE)
11450 c_parser_consume_token (parser);
11451
11452 return result;
11453 }
11454
11455 /* Validate that a clause of the given type does not already exist. */
11456
11457 static void
check_no_duplicate_clause(tree clauses,enum omp_clause_code code,const char * name)11458 check_no_duplicate_clause (tree clauses, enum omp_clause_code code,
11459 const char *name)
11460 {
11461 tree c;
11462
11463 for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
11464 if (OMP_CLAUSE_CODE (c) == code)
11465 {
11466 location_t loc = OMP_CLAUSE_LOCATION (c);
11467 error_at (loc, "too many %qs clauses", name);
11468 break;
11469 }
11470 }
11471
11472 /* OpenACC 2.0
11473 Parse wait clause or wait directive parameters. */
11474
11475 static tree
c_parser_oacc_wait_list(c_parser * parser,location_t clause_loc,tree list)11476 c_parser_oacc_wait_list (c_parser *parser, location_t clause_loc, tree list)
11477 {
11478 vec<tree, va_gc> *args;
11479 tree t, args_tree;
11480
11481 matching_parens parens;
11482 if (!parens.require_open (parser))
11483 return list;
11484
11485 args = c_parser_expr_list (parser, false, true, NULL, NULL, NULL, NULL);
11486
11487 if (args->length () == 0)
11488 {
11489 c_parser_error (parser, "expected integer expression before ')'");
11490 release_tree_vector (args);
11491 return list;
11492 }
11493
11494 args_tree = build_tree_list_vec (args);
11495
11496 for (t = args_tree; t; t = TREE_CHAIN (t))
11497 {
11498 tree targ = TREE_VALUE (t);
11499
11500 if (targ != error_mark_node)
11501 {
11502 if (!INTEGRAL_TYPE_P (TREE_TYPE (targ)))
11503 {
11504 c_parser_error (parser, "expression must be integral");
11505 targ = error_mark_node;
11506 }
11507 else
11508 {
11509 tree c = build_omp_clause (clause_loc, OMP_CLAUSE_WAIT);
11510
11511 OMP_CLAUSE_DECL (c) = targ;
11512 OMP_CLAUSE_CHAIN (c) = list;
11513 list = c;
11514 }
11515 }
11516 }
11517
11518 release_tree_vector (args);
11519 parens.require_close (parser);
11520 return list;
11521 }
11522
11523 /* OpenACC 2.0, OpenMP 2.5:
11524 variable-list:
11525 identifier
11526 variable-list , identifier
11527
11528 If KIND is nonzero, create the appropriate node and install the
11529 decl in OMP_CLAUSE_DECL and add the node to the head of the list.
11530 If KIND is nonzero, CLAUSE_LOC is the location of the clause.
11531
11532 If KIND is zero, create a TREE_LIST with the decl in TREE_PURPOSE;
11533 return the list created. */
11534
11535 static tree
c_parser_omp_variable_list(c_parser * parser,location_t clause_loc,enum omp_clause_code kind,tree list)11536 c_parser_omp_variable_list (c_parser *parser,
11537 location_t clause_loc,
11538 enum omp_clause_code kind, tree list)
11539 {
11540 if (c_parser_next_token_is_not (parser, CPP_NAME)
11541 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
11542 c_parser_error (parser, "expected identifier");
11543
11544 while (c_parser_next_token_is (parser, CPP_NAME)
11545 && c_parser_peek_token (parser)->id_kind == C_ID_ID)
11546 {
11547 tree t = lookup_name (c_parser_peek_token (parser)->value);
11548
11549 if (t == NULL_TREE)
11550 {
11551 undeclared_variable (c_parser_peek_token (parser)->location,
11552 c_parser_peek_token (parser)->value);
11553 t = error_mark_node;
11554 }
11555
11556 c_parser_consume_token (parser);
11557
11558 if (t == error_mark_node)
11559 ;
11560 else if (kind != 0)
11561 {
11562 switch (kind)
11563 {
11564 case OMP_CLAUSE__CACHE_:
11565 /* The OpenACC cache directive explicitly only allows "array
11566 elements or subarrays". */
11567 if (c_parser_peek_token (parser)->type != CPP_OPEN_SQUARE)
11568 {
11569 c_parser_error (parser, "expected %<[%>");
11570 t = error_mark_node;
11571 break;
11572 }
11573 /* FALLTHROUGH */
11574 case OMP_CLAUSE_MAP:
11575 case OMP_CLAUSE_FROM:
11576 case OMP_CLAUSE_TO:
11577 while (c_parser_next_token_is (parser, CPP_DOT))
11578 {
11579 location_t op_loc = c_parser_peek_token (parser)->location;
11580 c_parser_consume_token (parser);
11581 if (!c_parser_next_token_is (parser, CPP_NAME))
11582 {
11583 c_parser_error (parser, "expected identifier");
11584 t = error_mark_node;
11585 break;
11586 }
11587
11588 c_token *comp_tok = c_parser_peek_token (parser);
11589 tree ident = comp_tok->value;
11590 location_t comp_loc = comp_tok->location;
11591 c_parser_consume_token (parser);
11592 t = build_component_ref (op_loc, t, ident, comp_loc);
11593 }
11594 /* FALLTHROUGH */
11595 case OMP_CLAUSE_DEPEND:
11596 case OMP_CLAUSE_REDUCTION:
11597 while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
11598 {
11599 tree low_bound = NULL_TREE, length = NULL_TREE;
11600
11601 c_parser_consume_token (parser);
11602 if (!c_parser_next_token_is (parser, CPP_COLON))
11603 {
11604 location_t expr_loc
11605 = c_parser_peek_token (parser)->location;
11606 c_expr expr = c_parser_expression (parser);
11607 expr = convert_lvalue_to_rvalue (expr_loc, expr,
11608 false, true);
11609 low_bound = expr.value;
11610 }
11611 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
11612 length = integer_one_node;
11613 else
11614 {
11615 /* Look for `:'. */
11616 if (!c_parser_require (parser, CPP_COLON,
11617 "expected %<:%>"))
11618 {
11619 t = error_mark_node;
11620 break;
11621 }
11622 if (!c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
11623 {
11624 location_t expr_loc
11625 = c_parser_peek_token (parser)->location;
11626 c_expr expr = c_parser_expression (parser);
11627 expr = convert_lvalue_to_rvalue (expr_loc, expr,
11628 false, true);
11629 length = expr.value;
11630 }
11631 }
11632 /* Look for the closing `]'. */
11633 if (!c_parser_require (parser, CPP_CLOSE_SQUARE,
11634 "expected %<]%>"))
11635 {
11636 t = error_mark_node;
11637 break;
11638 }
11639
11640 t = tree_cons (low_bound, length, t);
11641 }
11642 break;
11643 default:
11644 break;
11645 }
11646
11647 if (t != error_mark_node)
11648 {
11649 tree u = build_omp_clause (clause_loc, kind);
11650 OMP_CLAUSE_DECL (u) = t;
11651 OMP_CLAUSE_CHAIN (u) = list;
11652 list = u;
11653 }
11654 }
11655 else
11656 list = tree_cons (t, NULL_TREE, list);
11657
11658 if (c_parser_next_token_is_not (parser, CPP_COMMA))
11659 break;
11660
11661 c_parser_consume_token (parser);
11662 }
11663
11664 return list;
11665 }
11666
11667 /* Similarly, but expect leading and trailing parenthesis. This is a very
11668 common case for OpenACC and OpenMP clauses. */
11669
11670 static tree
c_parser_omp_var_list_parens(c_parser * parser,enum omp_clause_code kind,tree list)11671 c_parser_omp_var_list_parens (c_parser *parser, enum omp_clause_code kind,
11672 tree list)
11673 {
11674 /* The clauses location. */
11675 location_t loc = c_parser_peek_token (parser)->location;
11676
11677 matching_parens parens;
11678 if (parens.require_open (parser))
11679 {
11680 list = c_parser_omp_variable_list (parser, loc, kind, list);
11681 parens.skip_until_found_close (parser);
11682 }
11683 return list;
11684 }
11685
11686 /* OpenACC 2.0:
11687 copy ( variable-list )
11688 copyin ( variable-list )
11689 copyout ( variable-list )
11690 create ( variable-list )
11691 delete ( variable-list )
11692 present ( variable-list )
11693 present_or_copy ( variable-list )
11694 pcopy ( variable-list )
11695 present_or_copyin ( variable-list )
11696 pcopyin ( variable-list )
11697 present_or_copyout ( variable-list )
11698 pcopyout ( variable-list )
11699 present_or_create ( variable-list )
11700 pcreate ( variable-list ) */
11701
11702 static tree
c_parser_oacc_data_clause(c_parser * parser,pragma_omp_clause c_kind,tree list)11703 c_parser_oacc_data_clause (c_parser *parser, pragma_omp_clause c_kind,
11704 tree list)
11705 {
11706 enum gomp_map_kind kind;
11707 switch (c_kind)
11708 {
11709 case PRAGMA_OACC_CLAUSE_COPY:
11710 kind = GOMP_MAP_FORCE_TOFROM;
11711 break;
11712 case PRAGMA_OACC_CLAUSE_COPYIN:
11713 kind = GOMP_MAP_FORCE_TO;
11714 break;
11715 case PRAGMA_OACC_CLAUSE_COPYOUT:
11716 kind = GOMP_MAP_FORCE_FROM;
11717 break;
11718 case PRAGMA_OACC_CLAUSE_CREATE:
11719 kind = GOMP_MAP_FORCE_ALLOC;
11720 break;
11721 case PRAGMA_OACC_CLAUSE_DELETE:
11722 kind = GOMP_MAP_DELETE;
11723 break;
11724 case PRAGMA_OACC_CLAUSE_DEVICE:
11725 kind = GOMP_MAP_FORCE_TO;
11726 break;
11727 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT:
11728 kind = GOMP_MAP_DEVICE_RESIDENT;
11729 break;
11730 case PRAGMA_OACC_CLAUSE_HOST:
11731 case PRAGMA_OACC_CLAUSE_SELF:
11732 kind = GOMP_MAP_FORCE_FROM;
11733 break;
11734 case PRAGMA_OACC_CLAUSE_LINK:
11735 kind = GOMP_MAP_LINK;
11736 break;
11737 case PRAGMA_OACC_CLAUSE_PRESENT:
11738 kind = GOMP_MAP_FORCE_PRESENT;
11739 break;
11740 case PRAGMA_OACC_CLAUSE_PRESENT_OR_COPY:
11741 kind = GOMP_MAP_TOFROM;
11742 break;
11743 case PRAGMA_OACC_CLAUSE_PRESENT_OR_COPYIN:
11744 kind = GOMP_MAP_TO;
11745 break;
11746 case PRAGMA_OACC_CLAUSE_PRESENT_OR_COPYOUT:
11747 kind = GOMP_MAP_FROM;
11748 break;
11749 case PRAGMA_OACC_CLAUSE_PRESENT_OR_CREATE:
11750 kind = GOMP_MAP_ALLOC;
11751 break;
11752 default:
11753 gcc_unreachable ();
11754 }
11755 tree nl, c;
11756 nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_MAP, list);
11757
11758 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
11759 OMP_CLAUSE_SET_MAP_KIND (c, kind);
11760
11761 return nl;
11762 }
11763
11764 /* OpenACC 2.0:
11765 deviceptr ( variable-list ) */
11766
11767 static tree
c_parser_oacc_data_clause_deviceptr(c_parser * parser,tree list)11768 c_parser_oacc_data_clause_deviceptr (c_parser *parser, tree list)
11769 {
11770 location_t loc = c_parser_peek_token (parser)->location;
11771 tree vars, t;
11772
11773 /* Can't use OMP_CLAUSE_MAP here (that is, can't use the generic
11774 c_parser_oacc_data_clause), as for PRAGMA_OACC_CLAUSE_DEVICEPTR,
11775 variable-list must only allow for pointer variables. */
11776 vars = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
11777 for (t = vars; t && t; t = TREE_CHAIN (t))
11778 {
11779 tree v = TREE_PURPOSE (t);
11780
11781 /* FIXME diagnostics: Ideally we should keep individual
11782 locations for all the variables in the var list to make the
11783 following errors more precise. Perhaps
11784 c_parser_omp_var_list_parens() should construct a list of
11785 locations to go along with the var list. */
11786
11787 if (!VAR_P (v) && TREE_CODE (v) != PARM_DECL)
11788 error_at (loc, "%qD is not a variable", v);
11789 else if (TREE_TYPE (v) == error_mark_node)
11790 ;
11791 else if (!POINTER_TYPE_P (TREE_TYPE (v)))
11792 error_at (loc, "%qD is not a pointer variable", v);
11793
11794 tree u = build_omp_clause (loc, OMP_CLAUSE_MAP);
11795 OMP_CLAUSE_SET_MAP_KIND (u, GOMP_MAP_FORCE_DEVICEPTR);
11796 OMP_CLAUSE_DECL (u) = v;
11797 OMP_CLAUSE_CHAIN (u) = list;
11798 list = u;
11799 }
11800
11801 return list;
11802 }
11803
11804 /* OpenACC 2.0, OpenMP 3.0:
11805 collapse ( constant-expression ) */
11806
11807 static tree
c_parser_omp_clause_collapse(c_parser * parser,tree list)11808 c_parser_omp_clause_collapse (c_parser *parser, tree list)
11809 {
11810 tree c, num = error_mark_node;
11811 HOST_WIDE_INT n;
11812 location_t loc;
11813
11814 check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse");
11815 check_no_duplicate_clause (list, OMP_CLAUSE_TILE, "tile");
11816
11817 loc = c_parser_peek_token (parser)->location;
11818 matching_parens parens;
11819 if (parens.require_open (parser))
11820 {
11821 num = c_parser_expr_no_commas (parser, NULL).value;
11822 parens.skip_until_found_close (parser);
11823 }
11824 if (num == error_mark_node)
11825 return list;
11826 mark_exp_read (num);
11827 num = c_fully_fold (num, false, NULL);
11828 if (!INTEGRAL_TYPE_P (TREE_TYPE (num))
11829 || !tree_fits_shwi_p (num)
11830 || (n = tree_to_shwi (num)) <= 0
11831 || (int) n != n)
11832 {
11833 error_at (loc,
11834 "collapse argument needs positive constant integer expression");
11835 return list;
11836 }
11837 c = build_omp_clause (loc, OMP_CLAUSE_COLLAPSE);
11838 OMP_CLAUSE_COLLAPSE_EXPR (c) = num;
11839 OMP_CLAUSE_CHAIN (c) = list;
11840 return c;
11841 }
11842
11843 /* OpenMP 2.5:
11844 copyin ( variable-list ) */
11845
11846 static tree
c_parser_omp_clause_copyin(c_parser * parser,tree list)11847 c_parser_omp_clause_copyin (c_parser *parser, tree list)
11848 {
11849 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_COPYIN, list);
11850 }
11851
11852 /* OpenMP 2.5:
11853 copyprivate ( variable-list ) */
11854
11855 static tree
c_parser_omp_clause_copyprivate(c_parser * parser,tree list)11856 c_parser_omp_clause_copyprivate (c_parser *parser, tree list)
11857 {
11858 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_COPYPRIVATE, list);
11859 }
11860
11861 /* OpenMP 2.5:
11862 default ( none | shared )
11863
11864 OpenACC:
11865 default ( none | present ) */
11866
11867 static tree
c_parser_omp_clause_default(c_parser * parser,tree list,bool is_oacc)11868 c_parser_omp_clause_default (c_parser *parser, tree list, bool is_oacc)
11869 {
11870 enum omp_clause_default_kind kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED;
11871 location_t loc = c_parser_peek_token (parser)->location;
11872 tree c;
11873
11874 matching_parens parens;
11875 if (!parens.require_open (parser))
11876 return list;
11877 if (c_parser_next_token_is (parser, CPP_NAME))
11878 {
11879 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
11880
11881 switch (p[0])
11882 {
11883 case 'n':
11884 if (strcmp ("none", p) != 0)
11885 goto invalid_kind;
11886 kind = OMP_CLAUSE_DEFAULT_NONE;
11887 break;
11888
11889 case 'p':
11890 if (strcmp ("present", p) != 0 || !is_oacc)
11891 goto invalid_kind;
11892 kind = OMP_CLAUSE_DEFAULT_PRESENT;
11893 break;
11894
11895 case 's':
11896 if (strcmp ("shared", p) != 0 || is_oacc)
11897 goto invalid_kind;
11898 kind = OMP_CLAUSE_DEFAULT_SHARED;
11899 break;
11900
11901 default:
11902 goto invalid_kind;
11903 }
11904
11905 c_parser_consume_token (parser);
11906 }
11907 else
11908 {
11909 invalid_kind:
11910 if (is_oacc)
11911 c_parser_error (parser, "expected %<none%> or %<present%>");
11912 else
11913 c_parser_error (parser, "expected %<none%> or %<shared%>");
11914 }
11915 parens.skip_until_found_close (parser);
11916
11917 if (kind == OMP_CLAUSE_DEFAULT_UNSPECIFIED)
11918 return list;
11919
11920 check_no_duplicate_clause (list, OMP_CLAUSE_DEFAULT, "default");
11921 c = build_omp_clause (loc, OMP_CLAUSE_DEFAULT);
11922 OMP_CLAUSE_CHAIN (c) = list;
11923 OMP_CLAUSE_DEFAULT_KIND (c) = kind;
11924
11925 return c;
11926 }
11927
11928 /* OpenMP 2.5:
11929 firstprivate ( variable-list ) */
11930
11931 static tree
c_parser_omp_clause_firstprivate(c_parser * parser,tree list)11932 c_parser_omp_clause_firstprivate (c_parser *parser, tree list)
11933 {
11934 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_FIRSTPRIVATE, list);
11935 }
11936
11937 /* OpenMP 3.1:
11938 final ( expression ) */
11939
11940 static tree
c_parser_omp_clause_final(c_parser * parser,tree list)11941 c_parser_omp_clause_final (c_parser *parser, tree list)
11942 {
11943 location_t loc = c_parser_peek_token (parser)->location;
11944 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
11945 {
11946 tree t = c_parser_paren_condition (parser);
11947 tree c;
11948
11949 check_no_duplicate_clause (list, OMP_CLAUSE_FINAL, "final");
11950
11951 c = build_omp_clause (loc, OMP_CLAUSE_FINAL);
11952 OMP_CLAUSE_FINAL_EXPR (c) = t;
11953 OMP_CLAUSE_CHAIN (c) = list;
11954 list = c;
11955 }
11956 else
11957 c_parser_error (parser, "expected %<(%>");
11958
11959 return list;
11960 }
11961
11962 /* OpenACC, OpenMP 2.5:
11963 if ( expression )
11964
11965 OpenMP 4.5:
11966 if ( directive-name-modifier : expression )
11967
11968 directive-name-modifier:
11969 parallel | task | taskloop | target data | target | target update
11970 | target enter data | target exit data */
11971
11972 static tree
c_parser_omp_clause_if(c_parser * parser,tree list,bool is_omp)11973 c_parser_omp_clause_if (c_parser *parser, tree list, bool is_omp)
11974 {
11975 location_t location = c_parser_peek_token (parser)->location;
11976 enum tree_code if_modifier = ERROR_MARK;
11977
11978 matching_parens parens;
11979 if (!parens.require_open (parser))
11980 return list;
11981
11982 if (is_omp && c_parser_next_token_is (parser, CPP_NAME))
11983 {
11984 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
11985 int n = 2;
11986 if (strcmp (p, "parallel") == 0)
11987 if_modifier = OMP_PARALLEL;
11988 else if (strcmp (p, "task") == 0)
11989 if_modifier = OMP_TASK;
11990 else if (strcmp (p, "taskloop") == 0)
11991 if_modifier = OMP_TASKLOOP;
11992 else if (strcmp (p, "target") == 0)
11993 {
11994 if_modifier = OMP_TARGET;
11995 if (c_parser_peek_2nd_token (parser)->type == CPP_NAME)
11996 {
11997 p = IDENTIFIER_POINTER (c_parser_peek_2nd_token (parser)->value);
11998 if (strcmp ("data", p) == 0)
11999 if_modifier = OMP_TARGET_DATA;
12000 else if (strcmp ("update", p) == 0)
12001 if_modifier = OMP_TARGET_UPDATE;
12002 else if (strcmp ("enter", p) == 0)
12003 if_modifier = OMP_TARGET_ENTER_DATA;
12004 else if (strcmp ("exit", p) == 0)
12005 if_modifier = OMP_TARGET_EXIT_DATA;
12006 if (if_modifier != OMP_TARGET)
12007 {
12008 n = 3;
12009 c_parser_consume_token (parser);
12010 }
12011 else
12012 {
12013 location_t loc = c_parser_peek_2nd_token (parser)->location;
12014 error_at (loc, "expected %<data%>, %<update%>, %<enter%> "
12015 "or %<exit%>");
12016 if_modifier = ERROR_MARK;
12017 }
12018 if (if_modifier == OMP_TARGET_ENTER_DATA
12019 || if_modifier == OMP_TARGET_EXIT_DATA)
12020 {
12021 if (c_parser_peek_2nd_token (parser)->type == CPP_NAME)
12022 {
12023 p = IDENTIFIER_POINTER
12024 (c_parser_peek_2nd_token (parser)->value);
12025 if (strcmp ("data", p) == 0)
12026 n = 4;
12027 }
12028 if (n == 4)
12029 c_parser_consume_token (parser);
12030 else
12031 {
12032 location_t loc
12033 = c_parser_peek_2nd_token (parser)->location;
12034 error_at (loc, "expected %<data%>");
12035 if_modifier = ERROR_MARK;
12036 }
12037 }
12038 }
12039 }
12040 if (if_modifier != ERROR_MARK)
12041 {
12042 if (c_parser_peek_2nd_token (parser)->type == CPP_COLON)
12043 {
12044 c_parser_consume_token (parser);
12045 c_parser_consume_token (parser);
12046 }
12047 else
12048 {
12049 if (n > 2)
12050 {
12051 location_t loc = c_parser_peek_2nd_token (parser)->location;
12052 error_at (loc, "expected %<:%>");
12053 }
12054 if_modifier = ERROR_MARK;
12055 }
12056 }
12057 }
12058
12059 tree t = c_parser_condition (parser), c;
12060 parens.skip_until_found_close (parser);
12061
12062 for (c = list; c ; c = OMP_CLAUSE_CHAIN (c))
12063 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IF)
12064 {
12065 if (if_modifier != ERROR_MARK
12066 && OMP_CLAUSE_IF_MODIFIER (c) == if_modifier)
12067 {
12068 const char *p = NULL;
12069 switch (if_modifier)
12070 {
12071 case OMP_PARALLEL: p = "parallel"; break;
12072 case OMP_TASK: p = "task"; break;
12073 case OMP_TASKLOOP: p = "taskloop"; break;
12074 case OMP_TARGET_DATA: p = "target data"; break;
12075 case OMP_TARGET: p = "target"; break;
12076 case OMP_TARGET_UPDATE: p = "target update"; break;
12077 case OMP_TARGET_ENTER_DATA: p = "enter data"; break;
12078 case OMP_TARGET_EXIT_DATA: p = "exit data"; break;
12079 default: gcc_unreachable ();
12080 }
12081 error_at (location, "too many %<if%> clauses with %qs modifier",
12082 p);
12083 return list;
12084 }
12085 else if (OMP_CLAUSE_IF_MODIFIER (c) == if_modifier)
12086 {
12087 if (!is_omp)
12088 error_at (location, "too many %<if%> clauses");
12089 else
12090 error_at (location, "too many %<if%> clauses without modifier");
12091 return list;
12092 }
12093 else if (if_modifier == ERROR_MARK
12094 || OMP_CLAUSE_IF_MODIFIER (c) == ERROR_MARK)
12095 {
12096 error_at (location, "if any %<if%> clause has modifier, then all "
12097 "%<if%> clauses have to use modifier");
12098 return list;
12099 }
12100 }
12101
12102 c = build_omp_clause (location, OMP_CLAUSE_IF);
12103 OMP_CLAUSE_IF_MODIFIER (c) = if_modifier;
12104 OMP_CLAUSE_IF_EXPR (c) = t;
12105 OMP_CLAUSE_CHAIN (c) = list;
12106 return c;
12107 }
12108
12109 /* OpenMP 2.5:
12110 lastprivate ( variable-list ) */
12111
12112 static tree
c_parser_omp_clause_lastprivate(c_parser * parser,tree list)12113 c_parser_omp_clause_lastprivate (c_parser *parser, tree list)
12114 {
12115 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_LASTPRIVATE, list);
12116 }
12117
12118 /* OpenMP 3.1:
12119 mergeable */
12120
12121 static tree
c_parser_omp_clause_mergeable(c_parser * parser ATTRIBUTE_UNUSED,tree list)12122 c_parser_omp_clause_mergeable (c_parser *parser ATTRIBUTE_UNUSED, tree list)
12123 {
12124 tree c;
12125
12126 /* FIXME: Should we allow duplicates? */
12127 check_no_duplicate_clause (list, OMP_CLAUSE_MERGEABLE, "mergeable");
12128
12129 c = build_omp_clause (c_parser_peek_token (parser)->location,
12130 OMP_CLAUSE_MERGEABLE);
12131 OMP_CLAUSE_CHAIN (c) = list;
12132
12133 return c;
12134 }
12135
12136 /* OpenMP 2.5:
12137 nowait */
12138
12139 static tree
c_parser_omp_clause_nowait(c_parser * parser ATTRIBUTE_UNUSED,tree list)12140 c_parser_omp_clause_nowait (c_parser *parser ATTRIBUTE_UNUSED, tree list)
12141 {
12142 tree c;
12143 location_t loc = c_parser_peek_token (parser)->location;
12144
12145 check_no_duplicate_clause (list, OMP_CLAUSE_NOWAIT, "nowait");
12146
12147 c = build_omp_clause (loc, OMP_CLAUSE_NOWAIT);
12148 OMP_CLAUSE_CHAIN (c) = list;
12149 return c;
12150 }
12151
12152 /* OpenMP 2.5:
12153 num_threads ( expression ) */
12154
12155 static tree
c_parser_omp_clause_num_threads(c_parser * parser,tree list)12156 c_parser_omp_clause_num_threads (c_parser *parser, tree list)
12157 {
12158 location_t num_threads_loc = c_parser_peek_token (parser)->location;
12159 matching_parens parens;
12160 if (parens.require_open (parser))
12161 {
12162 location_t expr_loc = c_parser_peek_token (parser)->location;
12163 c_expr expr = c_parser_expression (parser);
12164 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
12165 tree c, t = expr.value;
12166 t = c_fully_fold (t, false, NULL);
12167
12168 parens.skip_until_found_close (parser);
12169
12170 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
12171 {
12172 c_parser_error (parser, "expected integer expression");
12173 return list;
12174 }
12175
12176 /* Attempt to statically determine when the number isn't positive. */
12177 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
12178 build_int_cst (TREE_TYPE (t), 0));
12179 protected_set_expr_location (c, expr_loc);
12180 if (c == boolean_true_node)
12181 {
12182 warning_at (expr_loc, 0,
12183 "%<num_threads%> value must be positive");
12184 t = integer_one_node;
12185 }
12186
12187 check_no_duplicate_clause (list, OMP_CLAUSE_NUM_THREADS, "num_threads");
12188
12189 c = build_omp_clause (num_threads_loc, OMP_CLAUSE_NUM_THREADS);
12190 OMP_CLAUSE_NUM_THREADS_EXPR (c) = t;
12191 OMP_CLAUSE_CHAIN (c) = list;
12192 list = c;
12193 }
12194
12195 return list;
12196 }
12197
12198 /* OpenMP 4.5:
12199 num_tasks ( expression ) */
12200
12201 static tree
c_parser_omp_clause_num_tasks(c_parser * parser,tree list)12202 c_parser_omp_clause_num_tasks (c_parser *parser, tree list)
12203 {
12204 location_t num_tasks_loc = c_parser_peek_token (parser)->location;
12205 matching_parens parens;
12206 if (parens.require_open (parser))
12207 {
12208 location_t expr_loc = c_parser_peek_token (parser)->location;
12209 c_expr expr = c_parser_expression (parser);
12210 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
12211 tree c, t = expr.value;
12212 t = c_fully_fold (t, false, NULL);
12213
12214 parens.skip_until_found_close (parser);
12215
12216 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
12217 {
12218 c_parser_error (parser, "expected integer expression");
12219 return list;
12220 }
12221
12222 /* Attempt to statically determine when the number isn't positive. */
12223 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
12224 build_int_cst (TREE_TYPE (t), 0));
12225 if (CAN_HAVE_LOCATION_P (c))
12226 SET_EXPR_LOCATION (c, expr_loc);
12227 if (c == boolean_true_node)
12228 {
12229 warning_at (expr_loc, 0, "%<num_tasks%> value must be positive");
12230 t = integer_one_node;
12231 }
12232
12233 check_no_duplicate_clause (list, OMP_CLAUSE_NUM_TASKS, "num_tasks");
12234
12235 c = build_omp_clause (num_tasks_loc, OMP_CLAUSE_NUM_TASKS);
12236 OMP_CLAUSE_NUM_TASKS_EXPR (c) = t;
12237 OMP_CLAUSE_CHAIN (c) = list;
12238 list = c;
12239 }
12240
12241 return list;
12242 }
12243
12244 /* OpenMP 4.5:
12245 grainsize ( expression ) */
12246
12247 static tree
c_parser_omp_clause_grainsize(c_parser * parser,tree list)12248 c_parser_omp_clause_grainsize (c_parser *parser, tree list)
12249 {
12250 location_t grainsize_loc = c_parser_peek_token (parser)->location;
12251 matching_parens parens;
12252 if (parens.require_open (parser))
12253 {
12254 location_t expr_loc = c_parser_peek_token (parser)->location;
12255 c_expr expr = c_parser_expression (parser);
12256 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
12257 tree c, t = expr.value;
12258 t = c_fully_fold (t, false, NULL);
12259
12260 parens.skip_until_found_close (parser);
12261
12262 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
12263 {
12264 c_parser_error (parser, "expected integer expression");
12265 return list;
12266 }
12267
12268 /* Attempt to statically determine when the number isn't positive. */
12269 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
12270 build_int_cst (TREE_TYPE (t), 0));
12271 if (CAN_HAVE_LOCATION_P (c))
12272 SET_EXPR_LOCATION (c, expr_loc);
12273 if (c == boolean_true_node)
12274 {
12275 warning_at (expr_loc, 0, "%<grainsize%> value must be positive");
12276 t = integer_one_node;
12277 }
12278
12279 check_no_duplicate_clause (list, OMP_CLAUSE_GRAINSIZE, "grainsize");
12280
12281 c = build_omp_clause (grainsize_loc, OMP_CLAUSE_GRAINSIZE);
12282 OMP_CLAUSE_GRAINSIZE_EXPR (c) = t;
12283 OMP_CLAUSE_CHAIN (c) = list;
12284 list = c;
12285 }
12286
12287 return list;
12288 }
12289
12290 /* OpenMP 4.5:
12291 priority ( expression ) */
12292
12293 static tree
c_parser_omp_clause_priority(c_parser * parser,tree list)12294 c_parser_omp_clause_priority (c_parser *parser, tree list)
12295 {
12296 location_t priority_loc = c_parser_peek_token (parser)->location;
12297 matching_parens parens;
12298 if (parens.require_open (parser))
12299 {
12300 location_t expr_loc = c_parser_peek_token (parser)->location;
12301 c_expr expr = c_parser_expression (parser);
12302 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
12303 tree c, t = expr.value;
12304 t = c_fully_fold (t, false, NULL);
12305
12306 parens.skip_until_found_close (parser);
12307
12308 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
12309 {
12310 c_parser_error (parser, "expected integer expression");
12311 return list;
12312 }
12313
12314 /* Attempt to statically determine when the number isn't
12315 non-negative. */
12316 c = fold_build2_loc (expr_loc, LT_EXPR, boolean_type_node, t,
12317 build_int_cst (TREE_TYPE (t), 0));
12318 if (CAN_HAVE_LOCATION_P (c))
12319 SET_EXPR_LOCATION (c, expr_loc);
12320 if (c == boolean_true_node)
12321 {
12322 warning_at (expr_loc, 0, "%<priority%> value must be non-negative");
12323 t = integer_one_node;
12324 }
12325
12326 check_no_duplicate_clause (list, OMP_CLAUSE_PRIORITY, "priority");
12327
12328 c = build_omp_clause (priority_loc, OMP_CLAUSE_PRIORITY);
12329 OMP_CLAUSE_PRIORITY_EXPR (c) = t;
12330 OMP_CLAUSE_CHAIN (c) = list;
12331 list = c;
12332 }
12333
12334 return list;
12335 }
12336
12337 /* OpenMP 4.5:
12338 hint ( expression ) */
12339
12340 static tree
c_parser_omp_clause_hint(c_parser * parser,tree list)12341 c_parser_omp_clause_hint (c_parser *parser, tree list)
12342 {
12343 location_t hint_loc = c_parser_peek_token (parser)->location;
12344 matching_parens parens;
12345 if (parens.require_open (parser))
12346 {
12347 location_t expr_loc = c_parser_peek_token (parser)->location;
12348 c_expr expr = c_parser_expression (parser);
12349 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
12350 tree c, t = expr.value;
12351 t = c_fully_fold (t, false, NULL);
12352
12353 parens.skip_until_found_close (parser);
12354
12355 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
12356 {
12357 c_parser_error (parser, "expected integer expression");
12358 return list;
12359 }
12360
12361 check_no_duplicate_clause (list, OMP_CLAUSE_HINT, "hint");
12362
12363 c = build_omp_clause (hint_loc, OMP_CLAUSE_HINT);
12364 OMP_CLAUSE_HINT_EXPR (c) = t;
12365 OMP_CLAUSE_CHAIN (c) = list;
12366 list = c;
12367 }
12368
12369 return list;
12370 }
12371
12372 /* OpenMP 4.5:
12373 defaultmap ( tofrom : scalar ) */
12374
12375 static tree
c_parser_omp_clause_defaultmap(c_parser * parser,tree list)12376 c_parser_omp_clause_defaultmap (c_parser *parser, tree list)
12377 {
12378 location_t loc = c_parser_peek_token (parser)->location;
12379 tree c;
12380 const char *p;
12381
12382 matching_parens parens;
12383 if (!parens.require_open (parser))
12384 return list;
12385 if (!c_parser_next_token_is (parser, CPP_NAME))
12386 {
12387 c_parser_error (parser, "expected %<tofrom%>");
12388 goto out_err;
12389 }
12390 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
12391 if (strcmp (p, "tofrom") != 0)
12392 {
12393 c_parser_error (parser, "expected %<tofrom%>");
12394 goto out_err;
12395 }
12396 c_parser_consume_token (parser);
12397 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
12398 goto out_err;
12399 if (!c_parser_next_token_is (parser, CPP_NAME))
12400 {
12401 c_parser_error (parser, "expected %<scalar%>");
12402 goto out_err;
12403 }
12404 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
12405 if (strcmp (p, "scalar") != 0)
12406 {
12407 c_parser_error (parser, "expected %<scalar%>");
12408 goto out_err;
12409 }
12410 c_parser_consume_token (parser);
12411 parens.skip_until_found_close (parser);
12412 check_no_duplicate_clause (list, OMP_CLAUSE_DEFAULTMAP, "defaultmap");
12413 c = build_omp_clause (loc, OMP_CLAUSE_DEFAULTMAP);
12414 OMP_CLAUSE_CHAIN (c) = list;
12415 return c;
12416
12417 out_err:
12418 parens.skip_until_found_close (parser);
12419 return list;
12420 }
12421
12422 /* OpenACC 2.0:
12423 use_device ( variable-list )
12424
12425 OpenMP 4.5:
12426 use_device_ptr ( variable-list ) */
12427
12428 static tree
c_parser_omp_clause_use_device_ptr(c_parser * parser,tree list)12429 c_parser_omp_clause_use_device_ptr (c_parser *parser, tree list)
12430 {
12431 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_USE_DEVICE_PTR,
12432 list);
12433 }
12434
12435 /* OpenMP 4.5:
12436 is_device_ptr ( variable-list ) */
12437
12438 static tree
c_parser_omp_clause_is_device_ptr(c_parser * parser,tree list)12439 c_parser_omp_clause_is_device_ptr (c_parser *parser, tree list)
12440 {
12441 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_IS_DEVICE_PTR, list);
12442 }
12443
12444 /* OpenACC:
12445 num_gangs ( expression )
12446 num_workers ( expression )
12447 vector_length ( expression ) */
12448
12449 static tree
c_parser_oacc_single_int_clause(c_parser * parser,omp_clause_code code,tree list)12450 c_parser_oacc_single_int_clause (c_parser *parser, omp_clause_code code,
12451 tree list)
12452 {
12453 location_t loc = c_parser_peek_token (parser)->location;
12454
12455 matching_parens parens;
12456 if (!parens.require_open (parser))
12457 return list;
12458
12459 location_t expr_loc = c_parser_peek_token (parser)->location;
12460 c_expr expr = c_parser_expression (parser);
12461 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
12462 tree c, t = expr.value;
12463 t = c_fully_fold (t, false, NULL);
12464
12465 parens.skip_until_found_close (parser);
12466
12467 if (t == error_mark_node)
12468 return list;
12469 else if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
12470 {
12471 error_at (expr_loc, "%qs expression must be integral",
12472 omp_clause_code_name[code]);
12473 return list;
12474 }
12475
12476 /* Attempt to statically determine when the number isn't positive. */
12477 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
12478 build_int_cst (TREE_TYPE (t), 0));
12479 protected_set_expr_location (c, expr_loc);
12480 if (c == boolean_true_node)
12481 {
12482 warning_at (expr_loc, 0,
12483 "%qs value must be positive",
12484 omp_clause_code_name[code]);
12485 t = integer_one_node;
12486 }
12487
12488 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
12489
12490 c = build_omp_clause (loc, code);
12491 OMP_CLAUSE_OPERAND (c, 0) = t;
12492 OMP_CLAUSE_CHAIN (c) = list;
12493 return c;
12494 }
12495
12496 /* OpenACC:
12497
12498 gang [( gang-arg-list )]
12499 worker [( [num:] int-expr )]
12500 vector [( [length:] int-expr )]
12501
12502 where gang-arg is one of:
12503
12504 [num:] int-expr
12505 static: size-expr
12506
12507 and size-expr may be:
12508
12509 *
12510 int-expr
12511 */
12512
12513 static tree
c_parser_oacc_shape_clause(c_parser * parser,omp_clause_code kind,const char * str,tree list)12514 c_parser_oacc_shape_clause (c_parser *parser, omp_clause_code kind,
12515 const char *str, tree list)
12516 {
12517 const char *id = "num";
12518 tree ops[2] = { NULL_TREE, NULL_TREE }, c;
12519 location_t loc = c_parser_peek_token (parser)->location;
12520
12521 if (kind == OMP_CLAUSE_VECTOR)
12522 id = "length";
12523
12524 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
12525 {
12526 c_parser_consume_token (parser);
12527
12528 do
12529 {
12530 c_token *next = c_parser_peek_token (parser);
12531 int idx = 0;
12532
12533 /* Gang static argument. */
12534 if (kind == OMP_CLAUSE_GANG
12535 && c_parser_next_token_is_keyword (parser, RID_STATIC))
12536 {
12537 c_parser_consume_token (parser);
12538
12539 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
12540 goto cleanup_error;
12541
12542 idx = 1;
12543 if (ops[idx] != NULL_TREE)
12544 {
12545 c_parser_error (parser, "too many %<static%> arguments");
12546 goto cleanup_error;
12547 }
12548
12549 /* Check for the '*' argument. */
12550 if (c_parser_next_token_is (parser, CPP_MULT)
12551 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
12552 || c_parser_peek_2nd_token (parser)->type
12553 == CPP_CLOSE_PAREN))
12554 {
12555 c_parser_consume_token (parser);
12556 ops[idx] = integer_minus_one_node;
12557
12558 if (c_parser_next_token_is (parser, CPP_COMMA))
12559 {
12560 c_parser_consume_token (parser);
12561 continue;
12562 }
12563 else
12564 break;
12565 }
12566 }
12567 /* Worker num: argument and vector length: arguments. */
12568 else if (c_parser_next_token_is (parser, CPP_NAME)
12569 && strcmp (id, IDENTIFIER_POINTER (next->value)) == 0
12570 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
12571 {
12572 c_parser_consume_token (parser); /* id */
12573 c_parser_consume_token (parser); /* ':' */
12574 }
12575
12576 /* Now collect the actual argument. */
12577 if (ops[idx] != NULL_TREE)
12578 {
12579 c_parser_error (parser, "unexpected argument");
12580 goto cleanup_error;
12581 }
12582
12583 location_t expr_loc = c_parser_peek_token (parser)->location;
12584 c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
12585 cexpr = convert_lvalue_to_rvalue (expr_loc, cexpr, false, true);
12586 tree expr = cexpr.value;
12587 if (expr == error_mark_node)
12588 goto cleanup_error;
12589
12590 expr = c_fully_fold (expr, false, NULL);
12591
12592 /* Attempt to statically determine when the number isn't a
12593 positive integer. */
12594
12595 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr)))
12596 {
12597 c_parser_error (parser, "expected integer expression");
12598 return list;
12599 }
12600
12601 tree c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, expr,
12602 build_int_cst (TREE_TYPE (expr), 0));
12603 if (c == boolean_true_node)
12604 {
12605 warning_at (loc, 0,
12606 "%qs value must be positive", str);
12607 expr = integer_one_node;
12608 }
12609
12610 ops[idx] = expr;
12611
12612 if (kind == OMP_CLAUSE_GANG
12613 && c_parser_next_token_is (parser, CPP_COMMA))
12614 {
12615 c_parser_consume_token (parser);
12616 continue;
12617 }
12618 break;
12619 }
12620 while (1);
12621
12622 if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
12623 goto cleanup_error;
12624 }
12625
12626 check_no_duplicate_clause (list, kind, str);
12627
12628 c = build_omp_clause (loc, kind);
12629
12630 if (ops[1])
12631 OMP_CLAUSE_OPERAND (c, 1) = ops[1];
12632
12633 OMP_CLAUSE_OPERAND (c, 0) = ops[0];
12634 OMP_CLAUSE_CHAIN (c) = list;
12635
12636 return c;
12637
12638 cleanup_error:
12639 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
12640 return list;
12641 }
12642
12643 /* OpenACC:
12644 auto
12645 independent
12646 nohost
12647 seq */
12648
12649 static tree
c_parser_oacc_simple_clause(c_parser * parser,enum omp_clause_code code,tree list)12650 c_parser_oacc_simple_clause (c_parser *parser, enum omp_clause_code code,
12651 tree list)
12652 {
12653 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
12654
12655 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
12656 OMP_CLAUSE_CHAIN (c) = list;
12657
12658 return c;
12659 }
12660
12661 /* OpenACC:
12662 async [( int-expr )] */
12663
12664 static tree
c_parser_oacc_clause_async(c_parser * parser,tree list)12665 c_parser_oacc_clause_async (c_parser *parser, tree list)
12666 {
12667 tree c, t;
12668 location_t loc = c_parser_peek_token (parser)->location;
12669
12670 t = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL);
12671
12672 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
12673 {
12674 c_parser_consume_token (parser);
12675
12676 t = c_parser_expression (parser).value;
12677 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
12678 c_parser_error (parser, "expected integer expression");
12679 else if (t == error_mark_node
12680 || !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
12681 return list;
12682 }
12683 else
12684 t = c_fully_fold (t, false, NULL);
12685
12686 check_no_duplicate_clause (list, OMP_CLAUSE_ASYNC, "async");
12687
12688 c = build_omp_clause (loc, OMP_CLAUSE_ASYNC);
12689 OMP_CLAUSE_ASYNC_EXPR (c) = t;
12690 OMP_CLAUSE_CHAIN (c) = list;
12691 list = c;
12692
12693 return list;
12694 }
12695
12696 /* OpenACC 2.0:
12697 tile ( size-expr-list ) */
12698
12699 static tree
c_parser_oacc_clause_tile(c_parser * parser,tree list)12700 c_parser_oacc_clause_tile (c_parser *parser, tree list)
12701 {
12702 tree c, expr = error_mark_node;
12703 location_t loc;
12704 tree tile = NULL_TREE;
12705
12706 check_no_duplicate_clause (list, OMP_CLAUSE_TILE, "tile");
12707 check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse");
12708
12709 loc = c_parser_peek_token (parser)->location;
12710 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
12711 return list;
12712
12713 do
12714 {
12715 if (tile && !c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
12716 return list;
12717
12718 if (c_parser_next_token_is (parser, CPP_MULT)
12719 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
12720 || c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_PAREN))
12721 {
12722 c_parser_consume_token (parser);
12723 expr = integer_zero_node;
12724 }
12725 else
12726 {
12727 location_t expr_loc = c_parser_peek_token (parser)->location;
12728 c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
12729 cexpr = convert_lvalue_to_rvalue (expr_loc, cexpr, false, true);
12730 expr = cexpr.value;
12731
12732 if (expr == error_mark_node)
12733 {
12734 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
12735 "expected %<)%>");
12736 return list;
12737 }
12738
12739 expr = c_fully_fold (expr, false, NULL);
12740
12741 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr))
12742 || !tree_fits_shwi_p (expr)
12743 || tree_to_shwi (expr) <= 0)
12744 {
12745 error_at (expr_loc, "%<tile%> argument needs positive"
12746 " integral constant");
12747 expr = integer_zero_node;
12748 }
12749 }
12750
12751 tile = tree_cons (NULL_TREE, expr, tile);
12752 }
12753 while (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN));
12754
12755 /* Consume the trailing ')'. */
12756 c_parser_consume_token (parser);
12757
12758 c = build_omp_clause (loc, OMP_CLAUSE_TILE);
12759 tile = nreverse (tile);
12760 OMP_CLAUSE_TILE_LIST (c) = tile;
12761 OMP_CLAUSE_CHAIN (c) = list;
12762 return c;
12763 }
12764
12765 /* OpenACC:
12766 wait ( int-expr-list ) */
12767
12768 static tree
c_parser_oacc_clause_wait(c_parser * parser,tree list)12769 c_parser_oacc_clause_wait (c_parser *parser, tree list)
12770 {
12771 location_t clause_loc = c_parser_peek_token (parser)->location;
12772
12773 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
12774 list = c_parser_oacc_wait_list (parser, clause_loc, list);
12775
12776 return list;
12777 }
12778
12779 /* OpenMP 2.5:
12780 ordered
12781
12782 OpenMP 4.5:
12783 ordered ( constant-expression ) */
12784
12785 static tree
c_parser_omp_clause_ordered(c_parser * parser,tree list)12786 c_parser_omp_clause_ordered (c_parser *parser, tree list)
12787 {
12788 check_no_duplicate_clause (list, OMP_CLAUSE_ORDERED, "ordered");
12789
12790 tree c, num = NULL_TREE;
12791 HOST_WIDE_INT n;
12792 location_t loc = c_parser_peek_token (parser)->location;
12793 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
12794 {
12795 matching_parens parens;
12796 parens.consume_open (parser);
12797 num = c_parser_expr_no_commas (parser, NULL).value;
12798 parens.skip_until_found_close (parser);
12799 }
12800 if (num == error_mark_node)
12801 return list;
12802 if (num)
12803 {
12804 mark_exp_read (num);
12805 num = c_fully_fold (num, false, NULL);
12806 if (!INTEGRAL_TYPE_P (TREE_TYPE (num))
12807 || !tree_fits_shwi_p (num)
12808 || (n = tree_to_shwi (num)) <= 0
12809 || (int) n != n)
12810 {
12811 error_at (loc, "ordered argument needs positive "
12812 "constant integer expression");
12813 return list;
12814 }
12815 }
12816 c = build_omp_clause (loc, OMP_CLAUSE_ORDERED);
12817 OMP_CLAUSE_ORDERED_EXPR (c) = num;
12818 OMP_CLAUSE_CHAIN (c) = list;
12819 return c;
12820 }
12821
12822 /* OpenMP 2.5:
12823 private ( variable-list ) */
12824
12825 static tree
c_parser_omp_clause_private(c_parser * parser,tree list)12826 c_parser_omp_clause_private (c_parser *parser, tree list)
12827 {
12828 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_PRIVATE, list);
12829 }
12830
12831 /* OpenMP 2.5:
12832 reduction ( reduction-operator : variable-list )
12833
12834 reduction-operator:
12835 One of: + * - & ^ | && ||
12836
12837 OpenMP 3.1:
12838
12839 reduction-operator:
12840 One of: + * - & ^ | && || max min
12841
12842 OpenMP 4.0:
12843
12844 reduction-operator:
12845 One of: + * - & ^ | && ||
12846 identifier */
12847
12848 static tree
c_parser_omp_clause_reduction(c_parser * parser,tree list)12849 c_parser_omp_clause_reduction (c_parser *parser, tree list)
12850 {
12851 location_t clause_loc = c_parser_peek_token (parser)->location;
12852 matching_parens parens;
12853 if (parens.require_open (parser))
12854 {
12855 enum tree_code code = ERROR_MARK;
12856 tree reduc_id = NULL_TREE;
12857
12858 switch (c_parser_peek_token (parser)->type)
12859 {
12860 case CPP_PLUS:
12861 code = PLUS_EXPR;
12862 break;
12863 case CPP_MULT:
12864 code = MULT_EXPR;
12865 break;
12866 case CPP_MINUS:
12867 code = MINUS_EXPR;
12868 break;
12869 case CPP_AND:
12870 code = BIT_AND_EXPR;
12871 break;
12872 case CPP_XOR:
12873 code = BIT_XOR_EXPR;
12874 break;
12875 case CPP_OR:
12876 code = BIT_IOR_EXPR;
12877 break;
12878 case CPP_AND_AND:
12879 code = TRUTH_ANDIF_EXPR;
12880 break;
12881 case CPP_OR_OR:
12882 code = TRUTH_ORIF_EXPR;
12883 break;
12884 case CPP_NAME:
12885 {
12886 const char *p
12887 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
12888 if (strcmp (p, "min") == 0)
12889 {
12890 code = MIN_EXPR;
12891 break;
12892 }
12893 if (strcmp (p, "max") == 0)
12894 {
12895 code = MAX_EXPR;
12896 break;
12897 }
12898 reduc_id = c_parser_peek_token (parser)->value;
12899 break;
12900 }
12901 default:
12902 c_parser_error (parser,
12903 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
12904 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
12905 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
12906 return list;
12907 }
12908 c_parser_consume_token (parser);
12909 reduc_id = c_omp_reduction_id (code, reduc_id);
12910 if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
12911 {
12912 tree nl, c;
12913
12914 nl = c_parser_omp_variable_list (parser, clause_loc,
12915 OMP_CLAUSE_REDUCTION, list);
12916 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
12917 {
12918 tree d = OMP_CLAUSE_DECL (c), type;
12919 if (TREE_CODE (d) != TREE_LIST)
12920 type = TREE_TYPE (d);
12921 else
12922 {
12923 int cnt = 0;
12924 tree t;
12925 for (t = d; TREE_CODE (t) == TREE_LIST; t = TREE_CHAIN (t))
12926 cnt++;
12927 type = TREE_TYPE (t);
12928 while (cnt > 0)
12929 {
12930 if (TREE_CODE (type) != POINTER_TYPE
12931 && TREE_CODE (type) != ARRAY_TYPE)
12932 break;
12933 type = TREE_TYPE (type);
12934 cnt--;
12935 }
12936 }
12937 while (TREE_CODE (type) == ARRAY_TYPE)
12938 type = TREE_TYPE (type);
12939 OMP_CLAUSE_REDUCTION_CODE (c) = code;
12940 if (code == ERROR_MARK
12941 || !(INTEGRAL_TYPE_P (type)
12942 || TREE_CODE (type) == REAL_TYPE
12943 || TREE_CODE (type) == COMPLEX_TYPE))
12944 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)
12945 = c_omp_reduction_lookup (reduc_id,
12946 TYPE_MAIN_VARIANT (type));
12947 }
12948
12949 list = nl;
12950 }
12951 parens.skip_until_found_close (parser);
12952 }
12953 return list;
12954 }
12955
12956 /* OpenMP 2.5:
12957 schedule ( schedule-kind )
12958 schedule ( schedule-kind , expression )
12959
12960 schedule-kind:
12961 static | dynamic | guided | runtime | auto
12962
12963 OpenMP 4.5:
12964 schedule ( schedule-modifier : schedule-kind )
12965 schedule ( schedule-modifier [ , schedule-modifier ] : schedule-kind , expression )
12966
12967 schedule-modifier:
12968 simd
12969 monotonic
12970 nonmonotonic */
12971
12972 static tree
c_parser_omp_clause_schedule(c_parser * parser,tree list)12973 c_parser_omp_clause_schedule (c_parser *parser, tree list)
12974 {
12975 tree c, t;
12976 location_t loc = c_parser_peek_token (parser)->location;
12977 int modifiers = 0, nmodifiers = 0;
12978
12979 matching_parens parens;
12980 if (!parens.require_open (parser))
12981 return list;
12982
12983 c = build_omp_clause (loc, OMP_CLAUSE_SCHEDULE);
12984
12985 while (c_parser_next_token_is (parser, CPP_NAME))
12986 {
12987 tree kind = c_parser_peek_token (parser)->value;
12988 const char *p = IDENTIFIER_POINTER (kind);
12989 if (strcmp ("simd", p) == 0)
12990 OMP_CLAUSE_SCHEDULE_SIMD (c) = 1;
12991 else if (strcmp ("monotonic", p) == 0)
12992 modifiers |= OMP_CLAUSE_SCHEDULE_MONOTONIC;
12993 else if (strcmp ("nonmonotonic", p) == 0)
12994 modifiers |= OMP_CLAUSE_SCHEDULE_NONMONOTONIC;
12995 else
12996 break;
12997 c_parser_consume_token (parser);
12998 if (nmodifiers++ == 0
12999 && c_parser_next_token_is (parser, CPP_COMMA))
13000 c_parser_consume_token (parser);
13001 else
13002 {
13003 c_parser_require (parser, CPP_COLON, "expected %<:%>");
13004 break;
13005 }
13006 }
13007
13008 if ((modifiers & (OMP_CLAUSE_SCHEDULE_MONOTONIC
13009 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC))
13010 == (OMP_CLAUSE_SCHEDULE_MONOTONIC
13011 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC))
13012 {
13013 error_at (loc, "both %<monotonic%> and %<nonmonotonic%> modifiers "
13014 "specified");
13015 modifiers = 0;
13016 }
13017
13018 if (c_parser_next_token_is (parser, CPP_NAME))
13019 {
13020 tree kind = c_parser_peek_token (parser)->value;
13021 const char *p = IDENTIFIER_POINTER (kind);
13022
13023 switch (p[0])
13024 {
13025 case 'd':
13026 if (strcmp ("dynamic", p) != 0)
13027 goto invalid_kind;
13028 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_DYNAMIC;
13029 break;
13030
13031 case 'g':
13032 if (strcmp ("guided", p) != 0)
13033 goto invalid_kind;
13034 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_GUIDED;
13035 break;
13036
13037 case 'r':
13038 if (strcmp ("runtime", p) != 0)
13039 goto invalid_kind;
13040 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_RUNTIME;
13041 break;
13042
13043 default:
13044 goto invalid_kind;
13045 }
13046 }
13047 else if (c_parser_next_token_is_keyword (parser, RID_STATIC))
13048 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_STATIC;
13049 else if (c_parser_next_token_is_keyword (parser, RID_AUTO))
13050 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_AUTO;
13051 else
13052 goto invalid_kind;
13053
13054 c_parser_consume_token (parser);
13055 if (c_parser_next_token_is (parser, CPP_COMMA))
13056 {
13057 location_t here;
13058 c_parser_consume_token (parser);
13059
13060 here = c_parser_peek_token (parser)->location;
13061 c_expr expr = c_parser_expr_no_commas (parser, NULL);
13062 expr = convert_lvalue_to_rvalue (here, expr, false, true);
13063 t = expr.value;
13064 t = c_fully_fold (t, false, NULL);
13065
13066 if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_RUNTIME)
13067 error_at (here, "schedule %<runtime%> does not take "
13068 "a %<chunk_size%> parameter");
13069 else if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_AUTO)
13070 error_at (here,
13071 "schedule %<auto%> does not take "
13072 "a %<chunk_size%> parameter");
13073 else if (TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE)
13074 {
13075 /* Attempt to statically determine when the number isn't
13076 positive. */
13077 tree s = fold_build2_loc (loc, LE_EXPR, boolean_type_node, t,
13078 build_int_cst (TREE_TYPE (t), 0));
13079 protected_set_expr_location (s, loc);
13080 if (s == boolean_true_node)
13081 {
13082 warning_at (loc, 0,
13083 "chunk size value must be positive");
13084 t = integer_one_node;
13085 }
13086 OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = t;
13087 }
13088 else
13089 c_parser_error (parser, "expected integer expression");
13090
13091 parens.skip_until_found_close (parser);
13092 }
13093 else
13094 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
13095 "expected %<,%> or %<)%>");
13096
13097 OMP_CLAUSE_SCHEDULE_KIND (c)
13098 = (enum omp_clause_schedule_kind)
13099 (OMP_CLAUSE_SCHEDULE_KIND (c) | modifiers);
13100
13101 check_no_duplicate_clause (list, OMP_CLAUSE_SCHEDULE, "schedule");
13102 OMP_CLAUSE_CHAIN (c) = list;
13103 return c;
13104
13105 invalid_kind:
13106 c_parser_error (parser, "invalid schedule kind");
13107 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
13108 return list;
13109 }
13110
13111 /* OpenMP 2.5:
13112 shared ( variable-list ) */
13113
13114 static tree
c_parser_omp_clause_shared(c_parser * parser,tree list)13115 c_parser_omp_clause_shared (c_parser *parser, tree list)
13116 {
13117 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_SHARED, list);
13118 }
13119
13120 /* OpenMP 3.0:
13121 untied */
13122
13123 static tree
c_parser_omp_clause_untied(c_parser * parser ATTRIBUTE_UNUSED,tree list)13124 c_parser_omp_clause_untied (c_parser *parser ATTRIBUTE_UNUSED, tree list)
13125 {
13126 tree c;
13127
13128 /* FIXME: Should we allow duplicates? */
13129 check_no_duplicate_clause (list, OMP_CLAUSE_UNTIED, "untied");
13130
13131 c = build_omp_clause (c_parser_peek_token (parser)->location,
13132 OMP_CLAUSE_UNTIED);
13133 OMP_CLAUSE_CHAIN (c) = list;
13134
13135 return c;
13136 }
13137
13138 /* OpenMP 4.0:
13139 inbranch
13140 notinbranch */
13141
13142 static tree
c_parser_omp_clause_branch(c_parser * parser ATTRIBUTE_UNUSED,enum omp_clause_code code,tree list)13143 c_parser_omp_clause_branch (c_parser *parser ATTRIBUTE_UNUSED,
13144 enum omp_clause_code code, tree list)
13145 {
13146 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
13147
13148 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
13149 OMP_CLAUSE_CHAIN (c) = list;
13150
13151 return c;
13152 }
13153
13154 /* OpenMP 4.0:
13155 parallel
13156 for
13157 sections
13158 taskgroup */
13159
13160 static tree
c_parser_omp_clause_cancelkind(c_parser * parser ATTRIBUTE_UNUSED,enum omp_clause_code code,tree list)13161 c_parser_omp_clause_cancelkind (c_parser *parser ATTRIBUTE_UNUSED,
13162 enum omp_clause_code code, tree list)
13163 {
13164 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
13165 OMP_CLAUSE_CHAIN (c) = list;
13166
13167 return c;
13168 }
13169
13170 /* OpenMP 4.5:
13171 nogroup */
13172
13173 static tree
c_parser_omp_clause_nogroup(c_parser * parser ATTRIBUTE_UNUSED,tree list)13174 c_parser_omp_clause_nogroup (c_parser *parser ATTRIBUTE_UNUSED, tree list)
13175 {
13176 check_no_duplicate_clause (list, OMP_CLAUSE_NOGROUP, "nogroup");
13177 tree c = build_omp_clause (c_parser_peek_token (parser)->location,
13178 OMP_CLAUSE_NOGROUP);
13179 OMP_CLAUSE_CHAIN (c) = list;
13180 return c;
13181 }
13182
13183 /* OpenMP 4.5:
13184 simd
13185 threads */
13186
13187 static tree
c_parser_omp_clause_orderedkind(c_parser * parser ATTRIBUTE_UNUSED,enum omp_clause_code code,tree list)13188 c_parser_omp_clause_orderedkind (c_parser *parser ATTRIBUTE_UNUSED,
13189 enum omp_clause_code code, tree list)
13190 {
13191 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
13192 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
13193 OMP_CLAUSE_CHAIN (c) = list;
13194 return c;
13195 }
13196
13197 /* OpenMP 4.0:
13198 num_teams ( expression ) */
13199
13200 static tree
c_parser_omp_clause_num_teams(c_parser * parser,tree list)13201 c_parser_omp_clause_num_teams (c_parser *parser, tree list)
13202 {
13203 location_t num_teams_loc = c_parser_peek_token (parser)->location;
13204 matching_parens parens;
13205 if (parens.require_open (parser))
13206 {
13207 location_t expr_loc = c_parser_peek_token (parser)->location;
13208 c_expr expr = c_parser_expression (parser);
13209 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
13210 tree c, t = expr.value;
13211 t = c_fully_fold (t, false, NULL);
13212
13213 parens.skip_until_found_close (parser);
13214
13215 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
13216 {
13217 c_parser_error (parser, "expected integer expression");
13218 return list;
13219 }
13220
13221 /* Attempt to statically determine when the number isn't positive. */
13222 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
13223 build_int_cst (TREE_TYPE (t), 0));
13224 protected_set_expr_location (c, expr_loc);
13225 if (c == boolean_true_node)
13226 {
13227 warning_at (expr_loc, 0, "%<num_teams%> value must be positive");
13228 t = integer_one_node;
13229 }
13230
13231 check_no_duplicate_clause (list, OMP_CLAUSE_NUM_TEAMS, "num_teams");
13232
13233 c = build_omp_clause (num_teams_loc, OMP_CLAUSE_NUM_TEAMS);
13234 OMP_CLAUSE_NUM_TEAMS_EXPR (c) = t;
13235 OMP_CLAUSE_CHAIN (c) = list;
13236 list = c;
13237 }
13238
13239 return list;
13240 }
13241
13242 /* OpenMP 4.0:
13243 thread_limit ( expression ) */
13244
13245 static tree
c_parser_omp_clause_thread_limit(c_parser * parser,tree list)13246 c_parser_omp_clause_thread_limit (c_parser *parser, tree list)
13247 {
13248 location_t num_thread_limit_loc = c_parser_peek_token (parser)->location;
13249 matching_parens parens;
13250 if (parens.require_open (parser))
13251 {
13252 location_t expr_loc = c_parser_peek_token (parser)->location;
13253 c_expr expr = c_parser_expression (parser);
13254 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
13255 tree c, t = expr.value;
13256 t = c_fully_fold (t, false, NULL);
13257
13258 parens.skip_until_found_close (parser);
13259
13260 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
13261 {
13262 c_parser_error (parser, "expected integer expression");
13263 return list;
13264 }
13265
13266 /* Attempt to statically determine when the number isn't positive. */
13267 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
13268 build_int_cst (TREE_TYPE (t), 0));
13269 protected_set_expr_location (c, expr_loc);
13270 if (c == boolean_true_node)
13271 {
13272 warning_at (expr_loc, 0, "%<thread_limit%> value must be positive");
13273 t = integer_one_node;
13274 }
13275
13276 check_no_duplicate_clause (list, OMP_CLAUSE_THREAD_LIMIT,
13277 "thread_limit");
13278
13279 c = build_omp_clause (num_thread_limit_loc, OMP_CLAUSE_THREAD_LIMIT);
13280 OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = t;
13281 OMP_CLAUSE_CHAIN (c) = list;
13282 list = c;
13283 }
13284
13285 return list;
13286 }
13287
13288 /* OpenMP 4.0:
13289 aligned ( variable-list )
13290 aligned ( variable-list : constant-expression ) */
13291
13292 static tree
c_parser_omp_clause_aligned(c_parser * parser,tree list)13293 c_parser_omp_clause_aligned (c_parser *parser, tree list)
13294 {
13295 location_t clause_loc = c_parser_peek_token (parser)->location;
13296 tree nl, c;
13297
13298 matching_parens parens;
13299 if (!parens.require_open (parser))
13300 return list;
13301
13302 nl = c_parser_omp_variable_list (parser, clause_loc,
13303 OMP_CLAUSE_ALIGNED, list);
13304
13305 if (c_parser_next_token_is (parser, CPP_COLON))
13306 {
13307 c_parser_consume_token (parser);
13308 location_t expr_loc = c_parser_peek_token (parser)->location;
13309 c_expr expr = c_parser_expr_no_commas (parser, NULL);
13310 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
13311 tree alignment = expr.value;
13312 alignment = c_fully_fold (alignment, false, NULL);
13313 if (TREE_CODE (alignment) != INTEGER_CST
13314 || !INTEGRAL_TYPE_P (TREE_TYPE (alignment))
13315 || tree_int_cst_sgn (alignment) != 1)
13316 {
13317 error_at (clause_loc, "%<aligned%> clause alignment expression must "
13318 "be positive constant integer expression");
13319 alignment = NULL_TREE;
13320 }
13321
13322 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
13323 OMP_CLAUSE_ALIGNED_ALIGNMENT (c) = alignment;
13324 }
13325
13326 parens.skip_until_found_close (parser);
13327 return nl;
13328 }
13329
13330 /* OpenMP 4.0:
13331 linear ( variable-list )
13332 linear ( variable-list : expression )
13333
13334 OpenMP 4.5:
13335 linear ( modifier ( variable-list ) )
13336 linear ( modifier ( variable-list ) : expression ) */
13337
13338 static tree
c_parser_omp_clause_linear(c_parser * parser,tree list)13339 c_parser_omp_clause_linear (c_parser *parser, tree list)
13340 {
13341 location_t clause_loc = c_parser_peek_token (parser)->location;
13342 tree nl, c, step;
13343 enum omp_clause_linear_kind kind = OMP_CLAUSE_LINEAR_DEFAULT;
13344
13345 matching_parens parens;
13346 if (!parens.require_open (parser))
13347 return list;
13348
13349 if (c_parser_next_token_is (parser, CPP_NAME))
13350 {
13351 c_token *tok = c_parser_peek_token (parser);
13352 const char *p = IDENTIFIER_POINTER (tok->value);
13353 if (strcmp ("val", p) == 0)
13354 kind = OMP_CLAUSE_LINEAR_VAL;
13355 if (c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN)
13356 kind = OMP_CLAUSE_LINEAR_DEFAULT;
13357 if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
13358 {
13359 c_parser_consume_token (parser);
13360 c_parser_consume_token (parser);
13361 }
13362 }
13363
13364 nl = c_parser_omp_variable_list (parser, clause_loc,
13365 OMP_CLAUSE_LINEAR, list);
13366
13367 if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
13368 parens.skip_until_found_close (parser);
13369
13370 if (c_parser_next_token_is (parser, CPP_COLON))
13371 {
13372 c_parser_consume_token (parser);
13373 location_t expr_loc = c_parser_peek_token (parser)->location;
13374 c_expr expr = c_parser_expression (parser);
13375 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
13376 step = expr.value;
13377 step = c_fully_fold (step, false, NULL);
13378 if (!INTEGRAL_TYPE_P (TREE_TYPE (step)))
13379 {
13380 error_at (clause_loc, "%<linear%> clause step expression must "
13381 "be integral");
13382 step = integer_one_node;
13383 }
13384
13385 }
13386 else
13387 step = integer_one_node;
13388
13389 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
13390 {
13391 OMP_CLAUSE_LINEAR_STEP (c) = step;
13392 OMP_CLAUSE_LINEAR_KIND (c) = kind;
13393 }
13394
13395 parens.skip_until_found_close (parser);
13396 return nl;
13397 }
13398
13399 /* OpenMP 4.0:
13400 safelen ( constant-expression ) */
13401
13402 static tree
c_parser_omp_clause_safelen(c_parser * parser,tree list)13403 c_parser_omp_clause_safelen (c_parser *parser, tree list)
13404 {
13405 location_t clause_loc = c_parser_peek_token (parser)->location;
13406 tree c, t;
13407
13408 matching_parens parens;
13409 if (!parens.require_open (parser))
13410 return list;
13411
13412 location_t expr_loc = c_parser_peek_token (parser)->location;
13413 c_expr expr = c_parser_expr_no_commas (parser, NULL);
13414 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
13415 t = expr.value;
13416 t = c_fully_fold (t, false, NULL);
13417 if (TREE_CODE (t) != INTEGER_CST
13418 || !INTEGRAL_TYPE_P (TREE_TYPE (t))
13419 || tree_int_cst_sgn (t) != 1)
13420 {
13421 error_at (clause_loc, "%<safelen%> clause expression must "
13422 "be positive constant integer expression");
13423 t = NULL_TREE;
13424 }
13425
13426 parens.skip_until_found_close (parser);
13427 if (t == NULL_TREE || t == error_mark_node)
13428 return list;
13429
13430 check_no_duplicate_clause (list, OMP_CLAUSE_SAFELEN, "safelen");
13431
13432 c = build_omp_clause (clause_loc, OMP_CLAUSE_SAFELEN);
13433 OMP_CLAUSE_SAFELEN_EXPR (c) = t;
13434 OMP_CLAUSE_CHAIN (c) = list;
13435 return c;
13436 }
13437
13438 /* OpenMP 4.0:
13439 simdlen ( constant-expression ) */
13440
13441 static tree
c_parser_omp_clause_simdlen(c_parser * parser,tree list)13442 c_parser_omp_clause_simdlen (c_parser *parser, tree list)
13443 {
13444 location_t clause_loc = c_parser_peek_token (parser)->location;
13445 tree c, t;
13446
13447 matching_parens parens;
13448 if (!parens.require_open (parser))
13449 return list;
13450
13451 location_t expr_loc = c_parser_peek_token (parser)->location;
13452 c_expr expr = c_parser_expr_no_commas (parser, NULL);
13453 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
13454 t = expr.value;
13455 t = c_fully_fold (t, false, NULL);
13456 if (TREE_CODE (t) != INTEGER_CST
13457 || !INTEGRAL_TYPE_P (TREE_TYPE (t))
13458 || tree_int_cst_sgn (t) != 1)
13459 {
13460 error_at (clause_loc, "%<simdlen%> clause expression must "
13461 "be positive constant integer expression");
13462 t = NULL_TREE;
13463 }
13464
13465 parens.skip_until_found_close (parser);
13466 if (t == NULL_TREE || t == error_mark_node)
13467 return list;
13468
13469 check_no_duplicate_clause (list, OMP_CLAUSE_SIMDLEN, "simdlen");
13470
13471 c = build_omp_clause (clause_loc, OMP_CLAUSE_SIMDLEN);
13472 OMP_CLAUSE_SIMDLEN_EXPR (c) = t;
13473 OMP_CLAUSE_CHAIN (c) = list;
13474 return c;
13475 }
13476
13477 /* OpenMP 4.5:
13478 vec:
13479 identifier [+/- integer]
13480 vec , identifier [+/- integer]
13481 */
13482
13483 static tree
c_parser_omp_clause_depend_sink(c_parser * parser,location_t clause_loc,tree list)13484 c_parser_omp_clause_depend_sink (c_parser *parser, location_t clause_loc,
13485 tree list)
13486 {
13487 tree vec = NULL;
13488 if (c_parser_next_token_is_not (parser, CPP_NAME)
13489 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
13490 {
13491 c_parser_error (parser, "expected identifier");
13492 return list;
13493 }
13494
13495 while (c_parser_next_token_is (parser, CPP_NAME)
13496 && c_parser_peek_token (parser)->id_kind == C_ID_ID)
13497 {
13498 tree t = lookup_name (c_parser_peek_token (parser)->value);
13499 tree addend = NULL;
13500
13501 if (t == NULL_TREE)
13502 {
13503 undeclared_variable (c_parser_peek_token (parser)->location,
13504 c_parser_peek_token (parser)->value);
13505 t = error_mark_node;
13506 }
13507
13508 c_parser_consume_token (parser);
13509
13510 bool neg = false;
13511 if (c_parser_next_token_is (parser, CPP_MINUS))
13512 neg = true;
13513 else if (!c_parser_next_token_is (parser, CPP_PLUS))
13514 {
13515 addend = integer_zero_node;
13516 neg = false;
13517 goto add_to_vector;
13518 }
13519 c_parser_consume_token (parser);
13520
13521 if (c_parser_next_token_is_not (parser, CPP_NUMBER))
13522 {
13523 c_parser_error (parser, "expected integer");
13524 return list;
13525 }
13526
13527 addend = c_parser_peek_token (parser)->value;
13528 if (TREE_CODE (addend) != INTEGER_CST)
13529 {
13530 c_parser_error (parser, "expected integer");
13531 return list;
13532 }
13533 c_parser_consume_token (parser);
13534
13535 add_to_vector:
13536 if (t != error_mark_node)
13537 {
13538 vec = tree_cons (addend, t, vec);
13539 if (neg)
13540 OMP_CLAUSE_DEPEND_SINK_NEGATIVE (vec) = 1;
13541 }
13542
13543 if (c_parser_next_token_is_not (parser, CPP_COMMA))
13544 break;
13545
13546 c_parser_consume_token (parser);
13547 }
13548
13549 if (vec == NULL_TREE)
13550 return list;
13551
13552 tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DEPEND);
13553 OMP_CLAUSE_DEPEND_KIND (u) = OMP_CLAUSE_DEPEND_SINK;
13554 OMP_CLAUSE_DECL (u) = nreverse (vec);
13555 OMP_CLAUSE_CHAIN (u) = list;
13556 return u;
13557 }
13558
13559 /* OpenMP 4.0:
13560 depend ( depend-kind: variable-list )
13561
13562 depend-kind:
13563 in | out | inout
13564
13565 OpenMP 4.5:
13566 depend ( source )
13567
13568 depend ( sink : vec ) */
13569
13570 static tree
c_parser_omp_clause_depend(c_parser * parser,tree list)13571 c_parser_omp_clause_depend (c_parser *parser, tree list)
13572 {
13573 location_t clause_loc = c_parser_peek_token (parser)->location;
13574 enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_INOUT;
13575 tree nl, c;
13576
13577 matching_parens parens;
13578 if (!parens.require_open (parser))
13579 return list;
13580
13581 if (c_parser_next_token_is (parser, CPP_NAME))
13582 {
13583 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
13584 if (strcmp ("in", p) == 0)
13585 kind = OMP_CLAUSE_DEPEND_IN;
13586 else if (strcmp ("inout", p) == 0)
13587 kind = OMP_CLAUSE_DEPEND_INOUT;
13588 else if (strcmp ("out", p) == 0)
13589 kind = OMP_CLAUSE_DEPEND_OUT;
13590 else if (strcmp ("source", p) == 0)
13591 kind = OMP_CLAUSE_DEPEND_SOURCE;
13592 else if (strcmp ("sink", p) == 0)
13593 kind = OMP_CLAUSE_DEPEND_SINK;
13594 else
13595 goto invalid_kind;
13596 }
13597 else
13598 goto invalid_kind;
13599
13600 c_parser_consume_token (parser);
13601
13602 if (kind == OMP_CLAUSE_DEPEND_SOURCE)
13603 {
13604 c = build_omp_clause (clause_loc, OMP_CLAUSE_DEPEND);
13605 OMP_CLAUSE_DEPEND_KIND (c) = kind;
13606 OMP_CLAUSE_DECL (c) = NULL_TREE;
13607 OMP_CLAUSE_CHAIN (c) = list;
13608 parens.skip_until_found_close (parser);
13609 return c;
13610 }
13611
13612 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
13613 goto resync_fail;
13614
13615 if (kind == OMP_CLAUSE_DEPEND_SINK)
13616 nl = c_parser_omp_clause_depend_sink (parser, clause_loc, list);
13617 else
13618 {
13619 nl = c_parser_omp_variable_list (parser, clause_loc,
13620 OMP_CLAUSE_DEPEND, list);
13621
13622 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
13623 OMP_CLAUSE_DEPEND_KIND (c) = kind;
13624 }
13625
13626 parens.skip_until_found_close (parser);
13627 return nl;
13628
13629 invalid_kind:
13630 c_parser_error (parser, "invalid depend kind");
13631 resync_fail:
13632 parens.skip_until_found_close (parser);
13633 return list;
13634 }
13635
13636 /* OpenMP 4.0:
13637 map ( map-kind: variable-list )
13638 map ( variable-list )
13639
13640 map-kind:
13641 alloc | to | from | tofrom
13642
13643 OpenMP 4.5:
13644 map-kind:
13645 alloc | to | from | tofrom | release | delete
13646
13647 map ( always [,] map-kind: variable-list ) */
13648
13649 static tree
c_parser_omp_clause_map(c_parser * parser,tree list)13650 c_parser_omp_clause_map (c_parser *parser, tree list)
13651 {
13652 location_t clause_loc = c_parser_peek_token (parser)->location;
13653 enum gomp_map_kind kind = GOMP_MAP_TOFROM;
13654 int always = 0;
13655 enum c_id_kind always_id_kind = C_ID_NONE;
13656 location_t always_loc = UNKNOWN_LOCATION;
13657 tree always_id = NULL_TREE;
13658 tree nl, c;
13659
13660 matching_parens parens;
13661 if (!parens.require_open (parser))
13662 return list;
13663
13664 if (c_parser_next_token_is (parser, CPP_NAME))
13665 {
13666 c_token *tok = c_parser_peek_token (parser);
13667 const char *p = IDENTIFIER_POINTER (tok->value);
13668 always_id_kind = tok->id_kind;
13669 always_loc = tok->location;
13670 always_id = tok->value;
13671 if (strcmp ("always", p) == 0)
13672 {
13673 c_token *sectok = c_parser_peek_2nd_token (parser);
13674 if (sectok->type == CPP_COMMA)
13675 {
13676 c_parser_consume_token (parser);
13677 c_parser_consume_token (parser);
13678 always = 2;
13679 }
13680 else if (sectok->type == CPP_NAME)
13681 {
13682 p = IDENTIFIER_POINTER (sectok->value);
13683 if (strcmp ("alloc", p) == 0
13684 || strcmp ("to", p) == 0
13685 || strcmp ("from", p) == 0
13686 || strcmp ("tofrom", p) == 0
13687 || strcmp ("release", p) == 0
13688 || strcmp ("delete", p) == 0)
13689 {
13690 c_parser_consume_token (parser);
13691 always = 1;
13692 }
13693 }
13694 }
13695 }
13696
13697 if (c_parser_next_token_is (parser, CPP_NAME)
13698 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
13699 {
13700 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
13701 if (strcmp ("alloc", p) == 0)
13702 kind = GOMP_MAP_ALLOC;
13703 else if (strcmp ("to", p) == 0)
13704 kind = always ? GOMP_MAP_ALWAYS_TO : GOMP_MAP_TO;
13705 else if (strcmp ("from", p) == 0)
13706 kind = always ? GOMP_MAP_ALWAYS_FROM : GOMP_MAP_FROM;
13707 else if (strcmp ("tofrom", p) == 0)
13708 kind = always ? GOMP_MAP_ALWAYS_TOFROM : GOMP_MAP_TOFROM;
13709 else if (strcmp ("release", p) == 0)
13710 kind = GOMP_MAP_RELEASE;
13711 else if (strcmp ("delete", p) == 0)
13712 kind = GOMP_MAP_DELETE;
13713 else
13714 {
13715 c_parser_error (parser, "invalid map kind");
13716 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
13717 "expected %<)%>");
13718 return list;
13719 }
13720 c_parser_consume_token (parser);
13721 c_parser_consume_token (parser);
13722 }
13723 else if (always)
13724 {
13725 if (always_id_kind != C_ID_ID)
13726 {
13727 c_parser_error (parser, "expected identifier");
13728 parens.skip_until_found_close (parser);
13729 return list;
13730 }
13731
13732 tree t = lookup_name (always_id);
13733 if (t == NULL_TREE)
13734 {
13735 undeclared_variable (always_loc, always_id);
13736 t = error_mark_node;
13737 }
13738 if (t != error_mark_node)
13739 {
13740 tree u = build_omp_clause (clause_loc, OMP_CLAUSE_MAP);
13741 OMP_CLAUSE_DECL (u) = t;
13742 OMP_CLAUSE_CHAIN (u) = list;
13743 OMP_CLAUSE_SET_MAP_KIND (u, kind);
13744 list = u;
13745 }
13746 if (always == 1)
13747 {
13748 parens.skip_until_found_close (parser);
13749 return list;
13750 }
13751 }
13752
13753 nl = c_parser_omp_variable_list (parser, clause_loc, OMP_CLAUSE_MAP, list);
13754
13755 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
13756 OMP_CLAUSE_SET_MAP_KIND (c, kind);
13757
13758 parens.skip_until_found_close (parser);
13759 return nl;
13760 }
13761
13762 /* OpenMP 4.0:
13763 device ( expression ) */
13764
13765 static tree
c_parser_omp_clause_device(c_parser * parser,tree list)13766 c_parser_omp_clause_device (c_parser *parser, tree list)
13767 {
13768 location_t clause_loc = c_parser_peek_token (parser)->location;
13769 matching_parens parens;
13770 if (parens.require_open (parser))
13771 {
13772 location_t expr_loc = c_parser_peek_token (parser)->location;
13773 c_expr expr = c_parser_expr_no_commas (parser, NULL);
13774 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
13775 tree c, t = expr.value;
13776 t = c_fully_fold (t, false, NULL);
13777
13778 parens.skip_until_found_close (parser);
13779
13780 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
13781 {
13782 c_parser_error (parser, "expected integer expression");
13783 return list;
13784 }
13785
13786 check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE, "device");
13787
13788 c = build_omp_clause (clause_loc, OMP_CLAUSE_DEVICE);
13789 OMP_CLAUSE_DEVICE_ID (c) = t;
13790 OMP_CLAUSE_CHAIN (c) = list;
13791 list = c;
13792 }
13793
13794 return list;
13795 }
13796
13797 /* OpenMP 4.0:
13798 dist_schedule ( static )
13799 dist_schedule ( static , expression ) */
13800
13801 static tree
c_parser_omp_clause_dist_schedule(c_parser * parser,tree list)13802 c_parser_omp_clause_dist_schedule (c_parser *parser, tree list)
13803 {
13804 tree c, t = NULL_TREE;
13805 location_t loc = c_parser_peek_token (parser)->location;
13806
13807 matching_parens parens;
13808 if (!parens.require_open (parser))
13809 return list;
13810
13811 if (!c_parser_next_token_is_keyword (parser, RID_STATIC))
13812 {
13813 c_parser_error (parser, "invalid dist_schedule kind");
13814 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
13815 "expected %<)%>");
13816 return list;
13817 }
13818
13819 c_parser_consume_token (parser);
13820 if (c_parser_next_token_is (parser, CPP_COMMA))
13821 {
13822 c_parser_consume_token (parser);
13823
13824 location_t expr_loc = c_parser_peek_token (parser)->location;
13825 c_expr expr = c_parser_expr_no_commas (parser, NULL);
13826 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
13827 t = expr.value;
13828 t = c_fully_fold (t, false, NULL);
13829 parens.skip_until_found_close (parser);
13830 }
13831 else
13832 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
13833 "expected %<,%> or %<)%>");
13834
13835 check_no_duplicate_clause (list, OMP_CLAUSE_SCHEDULE, "schedule");
13836 if (t == error_mark_node)
13837 return list;
13838
13839 c = build_omp_clause (loc, OMP_CLAUSE_DIST_SCHEDULE);
13840 OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c) = t;
13841 OMP_CLAUSE_CHAIN (c) = list;
13842 return c;
13843 }
13844
13845 /* OpenMP 4.0:
13846 proc_bind ( proc-bind-kind )
13847
13848 proc-bind-kind:
13849 master | close | spread */
13850
13851 static tree
c_parser_omp_clause_proc_bind(c_parser * parser,tree list)13852 c_parser_omp_clause_proc_bind (c_parser *parser, tree list)
13853 {
13854 location_t clause_loc = c_parser_peek_token (parser)->location;
13855 enum omp_clause_proc_bind_kind kind;
13856 tree c;
13857
13858 matching_parens parens;
13859 if (!parens.require_open (parser))
13860 return list;
13861
13862 if (c_parser_next_token_is (parser, CPP_NAME))
13863 {
13864 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
13865 if (strcmp ("master", p) == 0)
13866 kind = OMP_CLAUSE_PROC_BIND_MASTER;
13867 else if (strcmp ("close", p) == 0)
13868 kind = OMP_CLAUSE_PROC_BIND_CLOSE;
13869 else if (strcmp ("spread", p) == 0)
13870 kind = OMP_CLAUSE_PROC_BIND_SPREAD;
13871 else
13872 goto invalid_kind;
13873 }
13874 else
13875 goto invalid_kind;
13876
13877 c_parser_consume_token (parser);
13878 parens.skip_until_found_close (parser);
13879 c = build_omp_clause (clause_loc, OMP_CLAUSE_PROC_BIND);
13880 OMP_CLAUSE_PROC_BIND_KIND (c) = kind;
13881 OMP_CLAUSE_CHAIN (c) = list;
13882 return c;
13883
13884 invalid_kind:
13885 c_parser_error (parser, "invalid proc_bind kind");
13886 parens.skip_until_found_close (parser);
13887 return list;
13888 }
13889
13890 /* OpenMP 4.0:
13891 to ( variable-list ) */
13892
13893 static tree
c_parser_omp_clause_to(c_parser * parser,tree list)13894 c_parser_omp_clause_to (c_parser *parser, tree list)
13895 {
13896 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_TO, list);
13897 }
13898
13899 /* OpenMP 4.0:
13900 from ( variable-list ) */
13901
13902 static tree
c_parser_omp_clause_from(c_parser * parser,tree list)13903 c_parser_omp_clause_from (c_parser *parser, tree list)
13904 {
13905 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_FROM, list);
13906 }
13907
13908 /* OpenMP 4.0:
13909 uniform ( variable-list ) */
13910
13911 static tree
c_parser_omp_clause_uniform(c_parser * parser,tree list)13912 c_parser_omp_clause_uniform (c_parser *parser, tree list)
13913 {
13914 /* The clauses location. */
13915 location_t loc = c_parser_peek_token (parser)->location;
13916
13917 matching_parens parens;
13918 if (parens.require_open (parser))
13919 {
13920 list = c_parser_omp_variable_list (parser, loc, OMP_CLAUSE_UNIFORM,
13921 list);
13922 parens.skip_until_found_close (parser);
13923 }
13924 return list;
13925 }
13926
13927 /* Parse all OpenACC clauses. The set clauses allowed by the directive
13928 is a bitmask in MASK. Return the list of clauses found. */
13929
13930 static tree
13931 c_parser_oacc_all_clauses (c_parser *parser, omp_clause_mask mask,
13932 const char *where, bool finish_p = true)
13933 {
13934 tree clauses = NULL;
13935 bool first = true;
13936
13937 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
13938 {
13939 location_t here;
13940 pragma_omp_clause c_kind;
13941 const char *c_name;
13942 tree prev = clauses;
13943
13944 if (!first && c_parser_next_token_is (parser, CPP_COMMA))
13945 c_parser_consume_token (parser);
13946
13947 here = c_parser_peek_token (parser)->location;
13948 c_kind = c_parser_omp_clause_name (parser);
13949
13950 switch (c_kind)
13951 {
13952 case PRAGMA_OACC_CLAUSE_ASYNC:
13953 clauses = c_parser_oacc_clause_async (parser, clauses);
13954 c_name = "async";
13955 break;
13956 case PRAGMA_OACC_CLAUSE_AUTO:
13957 clauses = c_parser_oacc_simple_clause (parser, OMP_CLAUSE_AUTO,
13958 clauses);
13959 c_name = "auto";
13960 break;
13961 case PRAGMA_OACC_CLAUSE_COLLAPSE:
13962 clauses = c_parser_omp_clause_collapse (parser, clauses);
13963 c_name = "collapse";
13964 break;
13965 case PRAGMA_OACC_CLAUSE_COPY:
13966 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
13967 c_name = "copy";
13968 break;
13969 case PRAGMA_OACC_CLAUSE_COPYIN:
13970 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
13971 c_name = "copyin";
13972 break;
13973 case PRAGMA_OACC_CLAUSE_COPYOUT:
13974 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
13975 c_name = "copyout";
13976 break;
13977 case PRAGMA_OACC_CLAUSE_CREATE:
13978 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
13979 c_name = "create";
13980 break;
13981 case PRAGMA_OACC_CLAUSE_DELETE:
13982 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
13983 c_name = "delete";
13984 break;
13985 case PRAGMA_OMP_CLAUSE_DEFAULT:
13986 clauses = c_parser_omp_clause_default (parser, clauses, true);
13987 c_name = "default";
13988 break;
13989 case PRAGMA_OACC_CLAUSE_DEVICE:
13990 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
13991 c_name = "device";
13992 break;
13993 case PRAGMA_OACC_CLAUSE_DEVICEPTR:
13994 clauses = c_parser_oacc_data_clause_deviceptr (parser, clauses);
13995 c_name = "deviceptr";
13996 break;
13997 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT:
13998 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
13999 c_name = "device_resident";
14000 break;
14001 case PRAGMA_OACC_CLAUSE_FIRSTPRIVATE:
14002 clauses = c_parser_omp_clause_firstprivate (parser, clauses);
14003 c_name = "firstprivate";
14004 break;
14005 case PRAGMA_OACC_CLAUSE_GANG:
14006 c_name = "gang";
14007 clauses = c_parser_oacc_shape_clause (parser, OMP_CLAUSE_GANG,
14008 c_name, clauses);
14009 break;
14010 case PRAGMA_OACC_CLAUSE_HOST:
14011 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
14012 c_name = "host";
14013 break;
14014 case PRAGMA_OACC_CLAUSE_IF:
14015 clauses = c_parser_omp_clause_if (parser, clauses, false);
14016 c_name = "if";
14017 break;
14018 case PRAGMA_OACC_CLAUSE_INDEPENDENT:
14019 clauses = c_parser_oacc_simple_clause (parser, OMP_CLAUSE_INDEPENDENT,
14020 clauses);
14021 c_name = "independent";
14022 break;
14023 case PRAGMA_OACC_CLAUSE_LINK:
14024 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
14025 c_name = "link";
14026 break;
14027 case PRAGMA_OACC_CLAUSE_NUM_GANGS:
14028 clauses = c_parser_oacc_single_int_clause (parser,
14029 OMP_CLAUSE_NUM_GANGS,
14030 clauses);
14031 c_name = "num_gangs";
14032 break;
14033 case PRAGMA_OACC_CLAUSE_NUM_WORKERS:
14034 clauses = c_parser_oacc_single_int_clause (parser,
14035 OMP_CLAUSE_NUM_WORKERS,
14036 clauses);
14037 c_name = "num_workers";
14038 break;
14039 case PRAGMA_OACC_CLAUSE_PRESENT:
14040 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
14041 c_name = "present";
14042 break;
14043 case PRAGMA_OACC_CLAUSE_PRESENT_OR_COPY:
14044 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
14045 c_name = "present_or_copy";
14046 break;
14047 case PRAGMA_OACC_CLAUSE_PRESENT_OR_COPYIN:
14048 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
14049 c_name = "present_or_copyin";
14050 break;
14051 case PRAGMA_OACC_CLAUSE_PRESENT_OR_COPYOUT:
14052 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
14053 c_name = "present_or_copyout";
14054 break;
14055 case PRAGMA_OACC_CLAUSE_PRESENT_OR_CREATE:
14056 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
14057 c_name = "present_or_create";
14058 break;
14059 case PRAGMA_OACC_CLAUSE_PRIVATE:
14060 clauses = c_parser_omp_clause_private (parser, clauses);
14061 c_name = "private";
14062 break;
14063 case PRAGMA_OACC_CLAUSE_REDUCTION:
14064 clauses = c_parser_omp_clause_reduction (parser, clauses);
14065 c_name = "reduction";
14066 break;
14067 case PRAGMA_OACC_CLAUSE_SELF:
14068 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
14069 c_name = "self";
14070 break;
14071 case PRAGMA_OACC_CLAUSE_SEQ:
14072 clauses = c_parser_oacc_simple_clause (parser, OMP_CLAUSE_SEQ,
14073 clauses);
14074 c_name = "seq";
14075 break;
14076 case PRAGMA_OACC_CLAUSE_TILE:
14077 clauses = c_parser_oacc_clause_tile (parser, clauses);
14078 c_name = "tile";
14079 break;
14080 case PRAGMA_OACC_CLAUSE_USE_DEVICE:
14081 clauses = c_parser_omp_clause_use_device_ptr (parser, clauses);
14082 c_name = "use_device";
14083 break;
14084 case PRAGMA_OACC_CLAUSE_VECTOR:
14085 c_name = "vector";
14086 clauses = c_parser_oacc_shape_clause (parser, OMP_CLAUSE_VECTOR,
14087 c_name, clauses);
14088 break;
14089 case PRAGMA_OACC_CLAUSE_VECTOR_LENGTH:
14090 clauses = c_parser_oacc_single_int_clause (parser,
14091 OMP_CLAUSE_VECTOR_LENGTH,
14092 clauses);
14093 c_name = "vector_length";
14094 break;
14095 case PRAGMA_OACC_CLAUSE_WAIT:
14096 clauses = c_parser_oacc_clause_wait (parser, clauses);
14097 c_name = "wait";
14098 break;
14099 case PRAGMA_OACC_CLAUSE_WORKER:
14100 c_name = "worker";
14101 clauses = c_parser_oacc_shape_clause (parser, OMP_CLAUSE_WORKER,
14102 c_name, clauses);
14103 break;
14104 default:
14105 c_parser_error (parser, "expected %<#pragma acc%> clause");
14106 goto saw_error;
14107 }
14108
14109 first = false;
14110
14111 if (((mask >> c_kind) & 1) == 0)
14112 {
14113 /* Remove the invalid clause(s) from the list to avoid
14114 confusing the rest of the compiler. */
14115 clauses = prev;
14116 error_at (here, "%qs is not valid for %qs", c_name, where);
14117 }
14118 }
14119
14120 saw_error:
14121 c_parser_skip_to_pragma_eol (parser);
14122
14123 if (finish_p)
14124 return c_finish_omp_clauses (clauses, C_ORT_ACC);
14125
14126 return clauses;
14127 }
14128
14129 /* Parse all OpenMP clauses. The set clauses allowed by the directive
14130 is a bitmask in MASK. Return the list of clauses found. */
14131
14132 static tree
14133 c_parser_omp_all_clauses (c_parser *parser, omp_clause_mask mask,
14134 const char *where, bool finish_p = true)
14135 {
14136 tree clauses = NULL;
14137 bool first = true;
14138
14139 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
14140 {
14141 location_t here;
14142 pragma_omp_clause c_kind;
14143 const char *c_name;
14144 tree prev = clauses;
14145
14146 if (!first && c_parser_next_token_is (parser, CPP_COMMA))
14147 c_parser_consume_token (parser);
14148
14149 here = c_parser_peek_token (parser)->location;
14150 c_kind = c_parser_omp_clause_name (parser);
14151
14152 switch (c_kind)
14153 {
14154 case PRAGMA_OMP_CLAUSE_COLLAPSE:
14155 clauses = c_parser_omp_clause_collapse (parser, clauses);
14156 c_name = "collapse";
14157 break;
14158 case PRAGMA_OMP_CLAUSE_COPYIN:
14159 clauses = c_parser_omp_clause_copyin (parser, clauses);
14160 c_name = "copyin";
14161 break;
14162 case PRAGMA_OMP_CLAUSE_COPYPRIVATE:
14163 clauses = c_parser_omp_clause_copyprivate (parser, clauses);
14164 c_name = "copyprivate";
14165 break;
14166 case PRAGMA_OMP_CLAUSE_DEFAULT:
14167 clauses = c_parser_omp_clause_default (parser, clauses, false);
14168 c_name = "default";
14169 break;
14170 case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE:
14171 clauses = c_parser_omp_clause_firstprivate (parser, clauses);
14172 c_name = "firstprivate";
14173 break;
14174 case PRAGMA_OMP_CLAUSE_FINAL:
14175 clauses = c_parser_omp_clause_final (parser, clauses);
14176 c_name = "final";
14177 break;
14178 case PRAGMA_OMP_CLAUSE_GRAINSIZE:
14179 clauses = c_parser_omp_clause_grainsize (parser, clauses);
14180 c_name = "grainsize";
14181 break;
14182 case PRAGMA_OMP_CLAUSE_HINT:
14183 clauses = c_parser_omp_clause_hint (parser, clauses);
14184 c_name = "hint";
14185 break;
14186 case PRAGMA_OMP_CLAUSE_DEFAULTMAP:
14187 clauses = c_parser_omp_clause_defaultmap (parser, clauses);
14188 c_name = "defaultmap";
14189 break;
14190 case PRAGMA_OMP_CLAUSE_IF:
14191 clauses = c_parser_omp_clause_if (parser, clauses, true);
14192 c_name = "if";
14193 break;
14194 case PRAGMA_OMP_CLAUSE_LASTPRIVATE:
14195 clauses = c_parser_omp_clause_lastprivate (parser, clauses);
14196 c_name = "lastprivate";
14197 break;
14198 case PRAGMA_OMP_CLAUSE_MERGEABLE:
14199 clauses = c_parser_omp_clause_mergeable (parser, clauses);
14200 c_name = "mergeable";
14201 break;
14202 case PRAGMA_OMP_CLAUSE_NOWAIT:
14203 clauses = c_parser_omp_clause_nowait (parser, clauses);
14204 c_name = "nowait";
14205 break;
14206 case PRAGMA_OMP_CLAUSE_NUM_TASKS:
14207 clauses = c_parser_omp_clause_num_tasks (parser, clauses);
14208 c_name = "num_tasks";
14209 break;
14210 case PRAGMA_OMP_CLAUSE_NUM_THREADS:
14211 clauses = c_parser_omp_clause_num_threads (parser, clauses);
14212 c_name = "num_threads";
14213 break;
14214 case PRAGMA_OMP_CLAUSE_ORDERED:
14215 clauses = c_parser_omp_clause_ordered (parser, clauses);
14216 c_name = "ordered";
14217 break;
14218 case PRAGMA_OMP_CLAUSE_PRIORITY:
14219 clauses = c_parser_omp_clause_priority (parser, clauses);
14220 c_name = "priority";
14221 break;
14222 case PRAGMA_OMP_CLAUSE_PRIVATE:
14223 clauses = c_parser_omp_clause_private (parser, clauses);
14224 c_name = "private";
14225 break;
14226 case PRAGMA_OMP_CLAUSE_REDUCTION:
14227 clauses = c_parser_omp_clause_reduction (parser, clauses);
14228 c_name = "reduction";
14229 break;
14230 case PRAGMA_OMP_CLAUSE_SCHEDULE:
14231 clauses = c_parser_omp_clause_schedule (parser, clauses);
14232 c_name = "schedule";
14233 break;
14234 case PRAGMA_OMP_CLAUSE_SHARED:
14235 clauses = c_parser_omp_clause_shared (parser, clauses);
14236 c_name = "shared";
14237 break;
14238 case PRAGMA_OMP_CLAUSE_UNTIED:
14239 clauses = c_parser_omp_clause_untied (parser, clauses);
14240 c_name = "untied";
14241 break;
14242 case PRAGMA_OMP_CLAUSE_INBRANCH:
14243 clauses = c_parser_omp_clause_branch (parser, OMP_CLAUSE_INBRANCH,
14244 clauses);
14245 c_name = "inbranch";
14246 break;
14247 case PRAGMA_OMP_CLAUSE_NOTINBRANCH:
14248 clauses = c_parser_omp_clause_branch (parser, OMP_CLAUSE_NOTINBRANCH,
14249 clauses);
14250 c_name = "notinbranch";
14251 break;
14252 case PRAGMA_OMP_CLAUSE_PARALLEL:
14253 clauses
14254 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_PARALLEL,
14255 clauses);
14256 c_name = "parallel";
14257 if (!first)
14258 {
14259 clause_not_first:
14260 error_at (here, "%qs must be the first clause of %qs",
14261 c_name, where);
14262 clauses = prev;
14263 }
14264 break;
14265 case PRAGMA_OMP_CLAUSE_FOR:
14266 clauses
14267 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_FOR,
14268 clauses);
14269 c_name = "for";
14270 if (!first)
14271 goto clause_not_first;
14272 break;
14273 case PRAGMA_OMP_CLAUSE_SECTIONS:
14274 clauses
14275 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_SECTIONS,
14276 clauses);
14277 c_name = "sections";
14278 if (!first)
14279 goto clause_not_first;
14280 break;
14281 case PRAGMA_OMP_CLAUSE_TASKGROUP:
14282 clauses
14283 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_TASKGROUP,
14284 clauses);
14285 c_name = "taskgroup";
14286 if (!first)
14287 goto clause_not_first;
14288 break;
14289 case PRAGMA_OMP_CLAUSE_LINK:
14290 clauses
14291 = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_LINK, clauses);
14292 c_name = "link";
14293 break;
14294 case PRAGMA_OMP_CLAUSE_TO:
14295 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK)) != 0)
14296 clauses
14297 = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_TO_DECLARE,
14298 clauses);
14299 else
14300 clauses = c_parser_omp_clause_to (parser, clauses);
14301 c_name = "to";
14302 break;
14303 case PRAGMA_OMP_CLAUSE_FROM:
14304 clauses = c_parser_omp_clause_from (parser, clauses);
14305 c_name = "from";
14306 break;
14307 case PRAGMA_OMP_CLAUSE_UNIFORM:
14308 clauses = c_parser_omp_clause_uniform (parser, clauses);
14309 c_name = "uniform";
14310 break;
14311 case PRAGMA_OMP_CLAUSE_NUM_TEAMS:
14312 clauses = c_parser_omp_clause_num_teams (parser, clauses);
14313 c_name = "num_teams";
14314 break;
14315 case PRAGMA_OMP_CLAUSE_THREAD_LIMIT:
14316 clauses = c_parser_omp_clause_thread_limit (parser, clauses);
14317 c_name = "thread_limit";
14318 break;
14319 case PRAGMA_OMP_CLAUSE_ALIGNED:
14320 clauses = c_parser_omp_clause_aligned (parser, clauses);
14321 c_name = "aligned";
14322 break;
14323 case PRAGMA_OMP_CLAUSE_LINEAR:
14324 clauses = c_parser_omp_clause_linear (parser, clauses);
14325 c_name = "linear";
14326 break;
14327 case PRAGMA_OMP_CLAUSE_DEPEND:
14328 clauses = c_parser_omp_clause_depend (parser, clauses);
14329 c_name = "depend";
14330 break;
14331 case PRAGMA_OMP_CLAUSE_MAP:
14332 clauses = c_parser_omp_clause_map (parser, clauses);
14333 c_name = "map";
14334 break;
14335 case PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR:
14336 clauses = c_parser_omp_clause_use_device_ptr (parser, clauses);
14337 c_name = "use_device_ptr";
14338 break;
14339 case PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR:
14340 clauses = c_parser_omp_clause_is_device_ptr (parser, clauses);
14341 c_name = "is_device_ptr";
14342 break;
14343 case PRAGMA_OMP_CLAUSE_DEVICE:
14344 clauses = c_parser_omp_clause_device (parser, clauses);
14345 c_name = "device";
14346 break;
14347 case PRAGMA_OMP_CLAUSE_DIST_SCHEDULE:
14348 clauses = c_parser_omp_clause_dist_schedule (parser, clauses);
14349 c_name = "dist_schedule";
14350 break;
14351 case PRAGMA_OMP_CLAUSE_PROC_BIND:
14352 clauses = c_parser_omp_clause_proc_bind (parser, clauses);
14353 c_name = "proc_bind";
14354 break;
14355 case PRAGMA_OMP_CLAUSE_SAFELEN:
14356 clauses = c_parser_omp_clause_safelen (parser, clauses);
14357 c_name = "safelen";
14358 break;
14359 case PRAGMA_OMP_CLAUSE_SIMDLEN:
14360 clauses = c_parser_omp_clause_simdlen (parser, clauses);
14361 c_name = "simdlen";
14362 break;
14363 case PRAGMA_OMP_CLAUSE_NOGROUP:
14364 clauses = c_parser_omp_clause_nogroup (parser, clauses);
14365 c_name = "nogroup";
14366 break;
14367 case PRAGMA_OMP_CLAUSE_THREADS:
14368 clauses
14369 = c_parser_omp_clause_orderedkind (parser, OMP_CLAUSE_THREADS,
14370 clauses);
14371 c_name = "threads";
14372 break;
14373 case PRAGMA_OMP_CLAUSE_SIMD:
14374 clauses
14375 = c_parser_omp_clause_orderedkind (parser, OMP_CLAUSE_SIMD,
14376 clauses);
14377 c_name = "simd";
14378 break;
14379 default:
14380 c_parser_error (parser, "expected %<#pragma omp%> clause");
14381 goto saw_error;
14382 }
14383
14384 first = false;
14385
14386 if (((mask >> c_kind) & 1) == 0)
14387 {
14388 /* Remove the invalid clause(s) from the list to avoid
14389 confusing the rest of the compiler. */
14390 clauses = prev;
14391 error_at (here, "%qs is not valid for %qs", c_name, where);
14392 }
14393 }
14394
14395 saw_error:
14396 c_parser_skip_to_pragma_eol (parser);
14397
14398 if (finish_p)
14399 {
14400 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM)) != 0)
14401 return c_finish_omp_clauses (clauses, C_ORT_OMP_DECLARE_SIMD);
14402 return c_finish_omp_clauses (clauses, C_ORT_OMP);
14403 }
14404
14405 return clauses;
14406 }
14407
14408 /* OpenACC 2.0, OpenMP 2.5:
14409 structured-block:
14410 statement
14411
14412 In practice, we're also interested in adding the statement to an
14413 outer node. So it is convenient if we work around the fact that
14414 c_parser_statement calls add_stmt. */
14415
14416 static tree
c_parser_omp_structured_block(c_parser * parser,bool * if_p)14417 c_parser_omp_structured_block (c_parser *parser, bool *if_p)
14418 {
14419 tree stmt = push_stmt_list ();
14420 c_parser_statement (parser, if_p);
14421 return pop_stmt_list (stmt);
14422 }
14423
14424 /* OpenACC 2.0:
14425 # pragma acc cache (variable-list) new-line
14426
14427 LOC is the location of the #pragma token.
14428 */
14429
14430 static tree
c_parser_oacc_cache(location_t loc,c_parser * parser)14431 c_parser_oacc_cache (location_t loc, c_parser *parser)
14432 {
14433 tree stmt, clauses;
14434
14435 clauses = c_parser_omp_var_list_parens (parser, OMP_CLAUSE__CACHE_, NULL);
14436 clauses = c_finish_omp_clauses (clauses, C_ORT_ACC);
14437
14438 c_parser_skip_to_pragma_eol (parser);
14439
14440 stmt = make_node (OACC_CACHE);
14441 TREE_TYPE (stmt) = void_type_node;
14442 OACC_CACHE_CLAUSES (stmt) = clauses;
14443 SET_EXPR_LOCATION (stmt, loc);
14444 add_stmt (stmt);
14445
14446 return stmt;
14447 }
14448
14449 /* OpenACC 2.0:
14450 # pragma acc data oacc-data-clause[optseq] new-line
14451 structured-block
14452
14453 LOC is the location of the #pragma token.
14454 */
14455
14456 #define OACC_DATA_CLAUSE_MASK \
14457 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
14458 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
14459 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
14460 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
14461 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
14462 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
14463 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
14464 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT_OR_COPY) \
14465 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT_OR_COPYIN) \
14466 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT_OR_COPYOUT) \
14467 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT_OR_CREATE) )
14468
14469 static tree
c_parser_oacc_data(location_t loc,c_parser * parser,bool * if_p)14470 c_parser_oacc_data (location_t loc, c_parser *parser, bool *if_p)
14471 {
14472 tree stmt, clauses, block;
14473
14474 clauses = c_parser_oacc_all_clauses (parser, OACC_DATA_CLAUSE_MASK,
14475 "#pragma acc data");
14476
14477 block = c_begin_omp_parallel ();
14478 add_stmt (c_parser_omp_structured_block (parser, if_p));
14479
14480 stmt = c_finish_oacc_data (loc, clauses, block);
14481
14482 return stmt;
14483 }
14484
14485 /* OpenACC 2.0:
14486 # pragma acc declare oacc-data-clause[optseq] new-line
14487 */
14488
14489 #define OACC_DECLARE_CLAUSE_MASK \
14490 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
14491 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
14492 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
14493 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
14494 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
14495 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT) \
14496 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_LINK) \
14497 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
14498 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT_OR_COPY) \
14499 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT_OR_COPYIN) \
14500 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT_OR_COPYOUT) \
14501 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT_OR_CREATE) )
14502
14503 static void
c_parser_oacc_declare(c_parser * parser)14504 c_parser_oacc_declare (c_parser *parser)
14505 {
14506 location_t pragma_loc = c_parser_peek_token (parser)->location;
14507 tree clauses, stmt, t, decl;
14508
14509 bool error = false;
14510
14511 c_parser_consume_pragma (parser);
14512
14513 clauses = c_parser_oacc_all_clauses (parser, OACC_DECLARE_CLAUSE_MASK,
14514 "#pragma acc declare");
14515 if (!clauses)
14516 {
14517 error_at (pragma_loc,
14518 "no valid clauses specified in %<#pragma acc declare%>");
14519 return;
14520 }
14521
14522 for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t))
14523 {
14524 location_t loc = OMP_CLAUSE_LOCATION (t);
14525 decl = OMP_CLAUSE_DECL (t);
14526 if (!DECL_P (decl))
14527 {
14528 error_at (loc, "array section in %<#pragma acc declare%>");
14529 error = true;
14530 continue;
14531 }
14532
14533 switch (OMP_CLAUSE_MAP_KIND (t))
14534 {
14535 case GOMP_MAP_FIRSTPRIVATE_POINTER:
14536 case GOMP_MAP_FORCE_ALLOC:
14537 case GOMP_MAP_FORCE_TO:
14538 case GOMP_MAP_FORCE_DEVICEPTR:
14539 case GOMP_MAP_DEVICE_RESIDENT:
14540 break;
14541
14542 case GOMP_MAP_LINK:
14543 if (!global_bindings_p ()
14544 && (TREE_STATIC (decl)
14545 || !DECL_EXTERNAL (decl)))
14546 {
14547 error_at (loc,
14548 "%qD must be a global variable in "
14549 "%<#pragma acc declare link%>",
14550 decl);
14551 error = true;
14552 continue;
14553 }
14554 break;
14555
14556 default:
14557 if (global_bindings_p ())
14558 {
14559 error_at (loc, "invalid OpenACC clause at file scope");
14560 error = true;
14561 continue;
14562 }
14563 if (DECL_EXTERNAL (decl))
14564 {
14565 error_at (loc,
14566 "invalid use of %<extern%> variable %qD "
14567 "in %<#pragma acc declare%>", decl);
14568 error = true;
14569 continue;
14570 }
14571 else if (TREE_PUBLIC (decl))
14572 {
14573 error_at (loc,
14574 "invalid use of %<global%> variable %qD "
14575 "in %<#pragma acc declare%>", decl);
14576 error = true;
14577 continue;
14578 }
14579 break;
14580 }
14581
14582 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl))
14583 || lookup_attribute ("omp declare target link",
14584 DECL_ATTRIBUTES (decl)))
14585 {
14586 error_at (loc, "variable %qD used more than once with "
14587 "%<#pragma acc declare%>", decl);
14588 error = true;
14589 continue;
14590 }
14591
14592 if (!error)
14593 {
14594 tree id;
14595
14596 if (OMP_CLAUSE_MAP_KIND (t) == GOMP_MAP_LINK)
14597 id = get_identifier ("omp declare target link");
14598 else
14599 id = get_identifier ("omp declare target");
14600
14601 DECL_ATTRIBUTES (decl)
14602 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (decl));
14603
14604 if (global_bindings_p ())
14605 {
14606 symtab_node *node = symtab_node::get (decl);
14607 if (node != NULL)
14608 {
14609 node->offloadable = 1;
14610 if (ENABLE_OFFLOADING)
14611 {
14612 g->have_offload = true;
14613 if (is_a <varpool_node *> (node))
14614 vec_safe_push (offload_vars, decl);
14615 }
14616 }
14617 }
14618 }
14619 }
14620
14621 if (error || global_bindings_p ())
14622 return;
14623
14624 stmt = make_node (OACC_DECLARE);
14625 TREE_TYPE (stmt) = void_type_node;
14626 OACC_DECLARE_CLAUSES (stmt) = clauses;
14627 SET_EXPR_LOCATION (stmt, pragma_loc);
14628
14629 add_stmt (stmt);
14630
14631 return;
14632 }
14633
14634 /* OpenACC 2.0:
14635 # pragma acc enter data oacc-enter-data-clause[optseq] new-line
14636
14637 or
14638
14639 # pragma acc exit data oacc-exit-data-clause[optseq] new-line
14640
14641
14642 LOC is the location of the #pragma token.
14643 */
14644
14645 #define OACC_ENTER_DATA_CLAUSE_MASK \
14646 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
14647 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
14648 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
14649 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
14650 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT_OR_COPYIN) \
14651 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT_OR_CREATE) \
14652 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
14653
14654 #define OACC_EXIT_DATA_CLAUSE_MASK \
14655 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
14656 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
14657 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
14658 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DELETE) \
14659 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
14660
14661 static void
c_parser_oacc_enter_exit_data(c_parser * parser,bool enter)14662 c_parser_oacc_enter_exit_data (c_parser *parser, bool enter)
14663 {
14664 location_t loc = c_parser_peek_token (parser)->location;
14665 tree clauses, stmt;
14666 const char *p = "";
14667
14668 c_parser_consume_pragma (parser);
14669
14670 if (c_parser_next_token_is (parser, CPP_NAME))
14671 {
14672 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14673 c_parser_consume_token (parser);
14674 }
14675
14676 if (strcmp (p, "data") != 0)
14677 {
14678 error_at (loc, "expected %<data%> after %<#pragma acc %s%>",
14679 enter ? "enter" : "exit");
14680 parser->error = true;
14681 c_parser_skip_to_pragma_eol (parser);
14682 return;
14683 }
14684
14685 if (enter)
14686 clauses = c_parser_oacc_all_clauses (parser, OACC_ENTER_DATA_CLAUSE_MASK,
14687 "#pragma acc enter data");
14688 else
14689 clauses = c_parser_oacc_all_clauses (parser, OACC_EXIT_DATA_CLAUSE_MASK,
14690 "#pragma acc exit data");
14691
14692 if (omp_find_clause (clauses, OMP_CLAUSE_MAP) == NULL_TREE)
14693 {
14694 error_at (loc, "%<#pragma acc %s data%> has no data movement clause",
14695 enter ? "enter" : "exit");
14696 return;
14697 }
14698
14699 stmt = enter ? make_node (OACC_ENTER_DATA) : make_node (OACC_EXIT_DATA);
14700 TREE_TYPE (stmt) = void_type_node;
14701 OMP_STANDALONE_CLAUSES (stmt) = clauses;
14702 SET_EXPR_LOCATION (stmt, loc);
14703 add_stmt (stmt);
14704 }
14705
14706
14707 /* OpenACC 2.0:
14708 # pragma acc host_data oacc-data-clause[optseq] new-line
14709 structured-block
14710 */
14711
14712 #define OACC_HOST_DATA_CLAUSE_MASK \
14713 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_USE_DEVICE) )
14714
14715 static tree
c_parser_oacc_host_data(location_t loc,c_parser * parser,bool * if_p)14716 c_parser_oacc_host_data (location_t loc, c_parser *parser, bool *if_p)
14717 {
14718 tree stmt, clauses, block;
14719
14720 clauses = c_parser_oacc_all_clauses (parser, OACC_HOST_DATA_CLAUSE_MASK,
14721 "#pragma acc host_data");
14722
14723 block = c_begin_omp_parallel ();
14724 add_stmt (c_parser_omp_structured_block (parser, if_p));
14725 stmt = c_finish_oacc_host_data (loc, clauses, block);
14726 return stmt;
14727 }
14728
14729
14730 /* OpenACC 2.0:
14731
14732 # pragma acc loop oacc-loop-clause[optseq] new-line
14733 structured-block
14734
14735 LOC is the location of the #pragma token.
14736 */
14737
14738 #define OACC_LOOP_CLAUSE_MASK \
14739 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COLLAPSE) \
14740 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
14741 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
14742 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
14743 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
14744 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
14745 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_AUTO) \
14746 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_INDEPENDENT) \
14747 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \
14748 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_TILE) )
14749 static tree
c_parser_oacc_loop(location_t loc,c_parser * parser,char * p_name,omp_clause_mask mask,tree * cclauses,bool * if_p)14750 c_parser_oacc_loop (location_t loc, c_parser *parser, char *p_name,
14751 omp_clause_mask mask, tree *cclauses, bool *if_p)
14752 {
14753 bool is_parallel = ((mask >> PRAGMA_OACC_CLAUSE_REDUCTION) & 1) == 1;
14754
14755 strcat (p_name, " loop");
14756 mask |= OACC_LOOP_CLAUSE_MASK;
14757
14758 tree clauses = c_parser_oacc_all_clauses (parser, mask, p_name,
14759 cclauses == NULL);
14760 if (cclauses)
14761 {
14762 clauses = c_oacc_split_loop_clauses (clauses, cclauses, is_parallel);
14763 if (*cclauses)
14764 *cclauses = c_finish_omp_clauses (*cclauses, C_ORT_ACC);
14765 if (clauses)
14766 clauses = c_finish_omp_clauses (clauses, C_ORT_ACC);
14767 }
14768
14769 tree block = c_begin_compound_stmt (true);
14770 tree stmt = c_parser_omp_for_loop (loc, parser, OACC_LOOP, clauses, NULL,
14771 if_p);
14772 block = c_end_compound_stmt (loc, block, true);
14773 add_stmt (block);
14774
14775 return stmt;
14776 }
14777
14778 /* OpenACC 2.0:
14779 # pragma acc kernels oacc-kernels-clause[optseq] new-line
14780 structured-block
14781
14782 or
14783
14784 # pragma acc parallel oacc-parallel-clause[optseq] new-line
14785 structured-block
14786
14787 LOC is the location of the #pragma token.
14788 */
14789
14790 #define OACC_KERNELS_CLAUSE_MASK \
14791 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
14792 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
14793 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
14794 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
14795 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
14796 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
14797 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
14798 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
14799 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
14800 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
14801 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
14802 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT_OR_COPY) \
14803 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT_OR_COPYIN) \
14804 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT_OR_COPYOUT) \
14805 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT_OR_CREATE) \
14806 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
14807 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
14808
14809 #define OACC_PARALLEL_CLAUSE_MASK \
14810 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
14811 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
14812 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
14813 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
14814 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
14815 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
14816 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
14817 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
14818 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
14819 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
14820 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
14821 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
14822 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
14823 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT_OR_COPY) \
14824 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT_OR_COPYIN) \
14825 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT_OR_COPYOUT) \
14826 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT_OR_CREATE) \
14827 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
14828 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
14829 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
14830
14831 static tree
c_parser_oacc_kernels_parallel(location_t loc,c_parser * parser,enum pragma_kind p_kind,char * p_name,bool * if_p)14832 c_parser_oacc_kernels_parallel (location_t loc, c_parser *parser,
14833 enum pragma_kind p_kind, char *p_name,
14834 bool *if_p)
14835 {
14836 omp_clause_mask mask;
14837 enum tree_code code;
14838 switch (p_kind)
14839 {
14840 case PRAGMA_OACC_KERNELS:
14841 strcat (p_name, " kernels");
14842 mask = OACC_KERNELS_CLAUSE_MASK;
14843 code = OACC_KERNELS;
14844 break;
14845 case PRAGMA_OACC_PARALLEL:
14846 strcat (p_name, " parallel");
14847 mask = OACC_PARALLEL_CLAUSE_MASK;
14848 code = OACC_PARALLEL;
14849 break;
14850 default:
14851 gcc_unreachable ();
14852 }
14853
14854 if (c_parser_next_token_is (parser, CPP_NAME))
14855 {
14856 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14857 if (strcmp (p, "loop") == 0)
14858 {
14859 c_parser_consume_token (parser);
14860 tree block = c_begin_omp_parallel ();
14861 tree clauses;
14862 c_parser_oacc_loop (loc, parser, p_name, mask, &clauses, if_p);
14863 return c_finish_omp_construct (loc, code, block, clauses);
14864 }
14865 }
14866
14867 tree clauses = c_parser_oacc_all_clauses (parser, mask, p_name);
14868
14869 tree block = c_begin_omp_parallel ();
14870 add_stmt (c_parser_omp_structured_block (parser, if_p));
14871
14872 return c_finish_omp_construct (loc, code, block, clauses);
14873 }
14874
14875 /* OpenACC 2.0:
14876 # pragma acc routine oacc-routine-clause[optseq] new-line
14877 function-definition
14878
14879 # pragma acc routine ( name ) oacc-routine-clause[optseq] new-line
14880 */
14881
14882 #define OACC_ROUTINE_CLAUSE_MASK \
14883 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
14884 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
14885 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
14886 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) )
14887
14888 /* Parse an OpenACC routine directive. For named directives, we apply
14889 immediately to the named function. For unnamed ones we then parse
14890 a declaration or definition, which must be for a function. */
14891
14892 static void
c_parser_oacc_routine(c_parser * parser,enum pragma_context context)14893 c_parser_oacc_routine (c_parser *parser, enum pragma_context context)
14894 {
14895 gcc_checking_assert (context == pragma_external);
14896
14897 oacc_routine_data data;
14898 data.error_seen = false;
14899 data.fndecl_seen = false;
14900 data.clauses = NULL_TREE;
14901 data.loc = c_parser_peek_token (parser)->location;
14902
14903 c_parser_consume_pragma (parser);
14904
14905 /* Look for optional '( name )'. */
14906 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
14907 {
14908 c_parser_consume_token (parser); /* '(' */
14909
14910 tree decl = NULL_TREE;
14911 c_token *name_token = c_parser_peek_token (parser);
14912 location_t name_loc = name_token->location;
14913 if (name_token->type == CPP_NAME
14914 && (name_token->id_kind == C_ID_ID
14915 || name_token->id_kind == C_ID_TYPENAME))
14916 {
14917 decl = lookup_name (name_token->value);
14918 if (!decl)
14919 error_at (name_loc,
14920 "%qE has not been declared", name_token->value);
14921 c_parser_consume_token (parser);
14922 }
14923 else
14924 c_parser_error (parser, "expected function name");
14925
14926 if (!decl
14927 || !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
14928 {
14929 c_parser_skip_to_pragma_eol (parser, false);
14930 return;
14931 }
14932
14933 data.clauses
14934 = c_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK,
14935 "#pragma acc routine");
14936
14937 if (TREE_CODE (decl) != FUNCTION_DECL)
14938 {
14939 error_at (name_loc, "%qD does not refer to a function", decl);
14940 return;
14941 }
14942
14943 c_finish_oacc_routine (&data, decl, false);
14944 }
14945 else /* No optional '( name )'. */
14946 {
14947 data.clauses
14948 = c_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK,
14949 "#pragma acc routine");
14950
14951 /* Emit a helpful diagnostic if there's another pragma following this
14952 one. Also don't allow a static assertion declaration, as in the
14953 following we'll just parse a *single* "declaration or function
14954 definition", and the static assertion counts an one. */
14955 if (c_parser_next_token_is (parser, CPP_PRAGMA)
14956 || c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
14957 {
14958 error_at (data.loc,
14959 "%<#pragma acc routine%> not immediately followed by"
14960 " function declaration or definition");
14961 /* ..., and then just keep going. */
14962 return;
14963 }
14964
14965 /* We only have to consider the pragma_external case here. */
14966 if (c_parser_next_token_is (parser, CPP_KEYWORD)
14967 && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
14968 {
14969 int ext = disable_extension_diagnostics ();
14970 do
14971 c_parser_consume_token (parser);
14972 while (c_parser_next_token_is (parser, CPP_KEYWORD)
14973 && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
14974 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
14975 NULL, vNULL, &data);
14976 restore_extension_diagnostics (ext);
14977 }
14978 else
14979 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
14980 NULL, vNULL, &data);
14981 }
14982 }
14983
14984 /* Finalize an OpenACC routine pragma, applying it to FNDECL.
14985 IS_DEFN is true if we're applying it to the definition. */
14986
14987 static void
c_finish_oacc_routine(struct oacc_routine_data * data,tree fndecl,bool is_defn)14988 c_finish_oacc_routine (struct oacc_routine_data *data, tree fndecl,
14989 bool is_defn)
14990 {
14991 /* Keep going if we're in error reporting mode. */
14992 if (data->error_seen
14993 || fndecl == error_mark_node)
14994 return;
14995
14996 if (data->fndecl_seen)
14997 {
14998 error_at (data->loc,
14999 "%<#pragma acc routine%> not immediately followed by"
15000 " a single function declaration or definition");
15001 data->error_seen = true;
15002 return;
15003 }
15004 if (fndecl == NULL_TREE || TREE_CODE (fndecl) != FUNCTION_DECL)
15005 {
15006 error_at (data->loc,
15007 "%<#pragma acc routine%> not immediately followed by"
15008 " function declaration or definition");
15009 data->error_seen = true;
15010 return;
15011 }
15012
15013 if (oacc_get_fn_attrib (fndecl))
15014 {
15015 error_at (data->loc,
15016 "%<#pragma acc routine%> already applied to %qD", fndecl);
15017 data->error_seen = true;
15018 return;
15019 }
15020
15021 if (TREE_USED (fndecl) || (!is_defn && DECL_SAVED_TREE (fndecl)))
15022 {
15023 error_at (data->loc,
15024 TREE_USED (fndecl)
15025 ? G_("%<#pragma acc routine%> must be applied before use")
15026 : G_("%<#pragma acc routine%> must be applied before "
15027 "definition"));
15028 data->error_seen = true;
15029 return;
15030 }
15031
15032 /* Process the routine's dimension clauses. */
15033 tree dims = oacc_build_routine_dims (data->clauses);
15034 oacc_replace_fn_attrib (fndecl, dims);
15035
15036 /* Add an "omp declare target" attribute. */
15037 DECL_ATTRIBUTES (fndecl)
15038 = tree_cons (get_identifier ("omp declare target"),
15039 NULL_TREE, DECL_ATTRIBUTES (fndecl));
15040
15041 /* Remember that we've used this "#pragma acc routine". */
15042 data->fndecl_seen = true;
15043 }
15044
15045 /* OpenACC 2.0:
15046 # pragma acc update oacc-update-clause[optseq] new-line
15047 */
15048
15049 #define OACC_UPDATE_CLAUSE_MASK \
15050 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
15051 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE) \
15052 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_HOST) \
15053 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
15054 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SELF) \
15055 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
15056
15057 static void
c_parser_oacc_update(c_parser * parser)15058 c_parser_oacc_update (c_parser *parser)
15059 {
15060 location_t loc = c_parser_peek_token (parser)->location;
15061
15062 c_parser_consume_pragma (parser);
15063
15064 tree clauses = c_parser_oacc_all_clauses (parser, OACC_UPDATE_CLAUSE_MASK,
15065 "#pragma acc update");
15066 if (omp_find_clause (clauses, OMP_CLAUSE_MAP) == NULL_TREE)
15067 {
15068 error_at (loc,
15069 "%<#pragma acc update%> must contain at least one "
15070 "%<device%> or %<host%> or %<self%> clause");
15071 return;
15072 }
15073
15074 if (parser->error)
15075 return;
15076
15077 tree stmt = make_node (OACC_UPDATE);
15078 TREE_TYPE (stmt) = void_type_node;
15079 OACC_UPDATE_CLAUSES (stmt) = clauses;
15080 SET_EXPR_LOCATION (stmt, loc);
15081 add_stmt (stmt);
15082 }
15083
15084 /* OpenACC 2.0:
15085 # pragma acc wait [(intseq)] oacc-wait-clause[optseq] new-line
15086
15087 LOC is the location of the #pragma token.
15088 */
15089
15090 #define OACC_WAIT_CLAUSE_MASK \
15091 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) )
15092
15093 static tree
c_parser_oacc_wait(location_t loc,c_parser * parser,char * p_name)15094 c_parser_oacc_wait (location_t loc, c_parser *parser, char *p_name)
15095 {
15096 tree clauses, list = NULL_TREE, stmt = NULL_TREE;
15097
15098 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
15099 list = c_parser_oacc_wait_list (parser, loc, list);
15100
15101 strcpy (p_name, " wait");
15102 clauses = c_parser_oacc_all_clauses (parser, OACC_WAIT_CLAUSE_MASK, p_name);
15103 stmt = c_finish_oacc_wait (loc, list, clauses);
15104 add_stmt (stmt);
15105
15106 return stmt;
15107 }
15108
15109 /* OpenMP 2.5:
15110 # pragma omp atomic new-line
15111 expression-stmt
15112
15113 expression-stmt:
15114 x binop= expr | x++ | ++x | x-- | --x
15115 binop:
15116 +, *, -, /, &, ^, |, <<, >>
15117
15118 where x is an lvalue expression with scalar type.
15119
15120 OpenMP 3.1:
15121 # pragma omp atomic new-line
15122 update-stmt
15123
15124 # pragma omp atomic read new-line
15125 read-stmt
15126
15127 # pragma omp atomic write new-line
15128 write-stmt
15129
15130 # pragma omp atomic update new-line
15131 update-stmt
15132
15133 # pragma omp atomic capture new-line
15134 capture-stmt
15135
15136 # pragma omp atomic capture new-line
15137 capture-block
15138
15139 read-stmt:
15140 v = x
15141 write-stmt:
15142 x = expr
15143 update-stmt:
15144 expression-stmt | x = x binop expr
15145 capture-stmt:
15146 v = expression-stmt
15147 capture-block:
15148 { v = x; update-stmt; } | { update-stmt; v = x; }
15149
15150 OpenMP 4.0:
15151 update-stmt:
15152 expression-stmt | x = x binop expr | x = expr binop x
15153 capture-stmt:
15154 v = update-stmt
15155 capture-block:
15156 { v = x; update-stmt; } | { update-stmt; v = x; } | { v = x; x = expr; }
15157
15158 where x and v are lvalue expressions with scalar type.
15159
15160 LOC is the location of the #pragma token. */
15161
15162 static void
c_parser_omp_atomic(location_t loc,c_parser * parser)15163 c_parser_omp_atomic (location_t loc, c_parser *parser)
15164 {
15165 tree lhs = NULL_TREE, rhs = NULL_TREE, v = NULL_TREE;
15166 tree lhs1 = NULL_TREE, rhs1 = NULL_TREE;
15167 tree stmt, orig_lhs, unfolded_lhs = NULL_TREE, unfolded_lhs1 = NULL_TREE;
15168 enum tree_code code = OMP_ATOMIC, opcode = NOP_EXPR;
15169 struct c_expr expr;
15170 location_t eloc;
15171 bool structured_block = false;
15172 bool swapped = false;
15173 bool seq_cst = false;
15174 bool non_lvalue_p;
15175
15176 if (c_parser_next_token_is (parser, CPP_NAME))
15177 {
15178 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
15179 if (!strcmp (p, "seq_cst"))
15180 {
15181 seq_cst = true;
15182 c_parser_consume_token (parser);
15183 if (c_parser_next_token_is (parser, CPP_COMMA)
15184 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
15185 c_parser_consume_token (parser);
15186 }
15187 }
15188 if (c_parser_next_token_is (parser, CPP_NAME))
15189 {
15190 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
15191
15192 if (!strcmp (p, "read"))
15193 code = OMP_ATOMIC_READ;
15194 else if (!strcmp (p, "write"))
15195 code = NOP_EXPR;
15196 else if (!strcmp (p, "update"))
15197 code = OMP_ATOMIC;
15198 else if (!strcmp (p, "capture"))
15199 code = OMP_ATOMIC_CAPTURE_NEW;
15200 else
15201 p = NULL;
15202 if (p)
15203 c_parser_consume_token (parser);
15204 }
15205 if (!seq_cst)
15206 {
15207 if (c_parser_next_token_is (parser, CPP_COMMA)
15208 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
15209 c_parser_consume_token (parser);
15210
15211 if (c_parser_next_token_is (parser, CPP_NAME))
15212 {
15213 const char *p
15214 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
15215 if (!strcmp (p, "seq_cst"))
15216 {
15217 seq_cst = true;
15218 c_parser_consume_token (parser);
15219 }
15220 }
15221 }
15222 c_parser_skip_to_pragma_eol (parser);
15223
15224 switch (code)
15225 {
15226 case OMP_ATOMIC_READ:
15227 case NOP_EXPR: /* atomic write */
15228 v = c_parser_cast_expression (parser, NULL).value;
15229 non_lvalue_p = !lvalue_p (v);
15230 v = c_fully_fold (v, false, NULL, true);
15231 if (v == error_mark_node)
15232 goto saw_error;
15233 if (non_lvalue_p)
15234 v = non_lvalue (v);
15235 loc = c_parser_peek_token (parser)->location;
15236 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
15237 goto saw_error;
15238 if (code == NOP_EXPR)
15239 {
15240 lhs = c_parser_expression (parser).value;
15241 lhs = c_fully_fold (lhs, false, NULL);
15242 if (lhs == error_mark_node)
15243 goto saw_error;
15244 }
15245 else
15246 {
15247 lhs = c_parser_cast_expression (parser, NULL).value;
15248 non_lvalue_p = !lvalue_p (lhs);
15249 lhs = c_fully_fold (lhs, false, NULL, true);
15250 if (lhs == error_mark_node)
15251 goto saw_error;
15252 if (non_lvalue_p)
15253 lhs = non_lvalue (lhs);
15254 }
15255 if (code == NOP_EXPR)
15256 {
15257 /* atomic write is represented by OMP_ATOMIC with NOP_EXPR
15258 opcode. */
15259 code = OMP_ATOMIC;
15260 rhs = lhs;
15261 lhs = v;
15262 v = NULL_TREE;
15263 }
15264 goto done;
15265 case OMP_ATOMIC_CAPTURE_NEW:
15266 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
15267 {
15268 c_parser_consume_token (parser);
15269 structured_block = true;
15270 }
15271 else
15272 {
15273 v = c_parser_cast_expression (parser, NULL).value;
15274 non_lvalue_p = !lvalue_p (v);
15275 v = c_fully_fold (v, false, NULL, true);
15276 if (v == error_mark_node)
15277 goto saw_error;
15278 if (non_lvalue_p)
15279 v = non_lvalue (v);
15280 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
15281 goto saw_error;
15282 }
15283 break;
15284 default:
15285 break;
15286 }
15287
15288 /* For structured_block case we don't know yet whether
15289 old or new x should be captured. */
15290 restart:
15291 eloc = c_parser_peek_token (parser)->location;
15292 expr = c_parser_cast_expression (parser, NULL);
15293 lhs = expr.value;
15294 expr = default_function_array_conversion (eloc, expr);
15295 unfolded_lhs = expr.value;
15296 lhs = c_fully_fold (lhs, false, NULL, true);
15297 orig_lhs = lhs;
15298 switch (TREE_CODE (lhs))
15299 {
15300 case ERROR_MARK:
15301 saw_error:
15302 c_parser_skip_to_end_of_block_or_statement (parser);
15303 if (structured_block)
15304 {
15305 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
15306 c_parser_consume_token (parser);
15307 else if (code == OMP_ATOMIC_CAPTURE_NEW)
15308 {
15309 c_parser_skip_to_end_of_block_or_statement (parser);
15310 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
15311 c_parser_consume_token (parser);
15312 }
15313 }
15314 return;
15315
15316 case POSTINCREMENT_EXPR:
15317 if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
15318 code = OMP_ATOMIC_CAPTURE_OLD;
15319 /* FALLTHROUGH */
15320 case PREINCREMENT_EXPR:
15321 lhs = TREE_OPERAND (lhs, 0);
15322 unfolded_lhs = NULL_TREE;
15323 opcode = PLUS_EXPR;
15324 rhs = integer_one_node;
15325 break;
15326
15327 case POSTDECREMENT_EXPR:
15328 if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
15329 code = OMP_ATOMIC_CAPTURE_OLD;
15330 /* FALLTHROUGH */
15331 case PREDECREMENT_EXPR:
15332 lhs = TREE_OPERAND (lhs, 0);
15333 unfolded_lhs = NULL_TREE;
15334 opcode = MINUS_EXPR;
15335 rhs = integer_one_node;
15336 break;
15337
15338 case COMPOUND_EXPR:
15339 if (TREE_CODE (TREE_OPERAND (lhs, 0)) == SAVE_EXPR
15340 && TREE_CODE (TREE_OPERAND (lhs, 1)) == COMPOUND_EXPR
15341 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (lhs, 1), 0)) == MODIFY_EXPR
15342 && TREE_OPERAND (TREE_OPERAND (lhs, 1), 1) == TREE_OPERAND (lhs, 0)
15343 && TREE_CODE (TREE_TYPE (TREE_OPERAND (TREE_OPERAND
15344 (TREE_OPERAND (lhs, 1), 0), 0)))
15345 == BOOLEAN_TYPE)
15346 /* Undo effects of boolean_increment for post {in,de}crement. */
15347 lhs = TREE_OPERAND (TREE_OPERAND (lhs, 1), 0);
15348 /* FALLTHRU */
15349 case MODIFY_EXPR:
15350 if (TREE_CODE (lhs) == MODIFY_EXPR
15351 && TREE_CODE (TREE_TYPE (TREE_OPERAND (lhs, 0))) == BOOLEAN_TYPE)
15352 {
15353 /* Undo effects of boolean_increment. */
15354 if (integer_onep (TREE_OPERAND (lhs, 1)))
15355 {
15356 /* This is pre or post increment. */
15357 rhs = TREE_OPERAND (lhs, 1);
15358 lhs = TREE_OPERAND (lhs, 0);
15359 unfolded_lhs = NULL_TREE;
15360 opcode = NOP_EXPR;
15361 if (code == OMP_ATOMIC_CAPTURE_NEW
15362 && !structured_block
15363 && TREE_CODE (orig_lhs) == COMPOUND_EXPR)
15364 code = OMP_ATOMIC_CAPTURE_OLD;
15365 break;
15366 }
15367 if (TREE_CODE (TREE_OPERAND (lhs, 1)) == TRUTH_NOT_EXPR
15368 && TREE_OPERAND (lhs, 0)
15369 == TREE_OPERAND (TREE_OPERAND (lhs, 1), 0))
15370 {
15371 /* This is pre or post decrement. */
15372 rhs = TREE_OPERAND (lhs, 1);
15373 lhs = TREE_OPERAND (lhs, 0);
15374 unfolded_lhs = NULL_TREE;
15375 opcode = NOP_EXPR;
15376 if (code == OMP_ATOMIC_CAPTURE_NEW
15377 && !structured_block
15378 && TREE_CODE (orig_lhs) == COMPOUND_EXPR)
15379 code = OMP_ATOMIC_CAPTURE_OLD;
15380 break;
15381 }
15382 }
15383 /* FALLTHRU */
15384 default:
15385 if (!lvalue_p (unfolded_lhs))
15386 lhs = non_lvalue (lhs);
15387 switch (c_parser_peek_token (parser)->type)
15388 {
15389 case CPP_MULT_EQ:
15390 opcode = MULT_EXPR;
15391 break;
15392 case CPP_DIV_EQ:
15393 opcode = TRUNC_DIV_EXPR;
15394 break;
15395 case CPP_PLUS_EQ:
15396 opcode = PLUS_EXPR;
15397 break;
15398 case CPP_MINUS_EQ:
15399 opcode = MINUS_EXPR;
15400 break;
15401 case CPP_LSHIFT_EQ:
15402 opcode = LSHIFT_EXPR;
15403 break;
15404 case CPP_RSHIFT_EQ:
15405 opcode = RSHIFT_EXPR;
15406 break;
15407 case CPP_AND_EQ:
15408 opcode = BIT_AND_EXPR;
15409 break;
15410 case CPP_OR_EQ:
15411 opcode = BIT_IOR_EXPR;
15412 break;
15413 case CPP_XOR_EQ:
15414 opcode = BIT_XOR_EXPR;
15415 break;
15416 case CPP_EQ:
15417 c_parser_consume_token (parser);
15418 eloc = c_parser_peek_token (parser)->location;
15419 expr = c_parser_expr_no_commas (parser, NULL, unfolded_lhs);
15420 rhs1 = expr.value;
15421 switch (TREE_CODE (rhs1))
15422 {
15423 case MULT_EXPR:
15424 case TRUNC_DIV_EXPR:
15425 case RDIV_EXPR:
15426 case PLUS_EXPR:
15427 case MINUS_EXPR:
15428 case LSHIFT_EXPR:
15429 case RSHIFT_EXPR:
15430 case BIT_AND_EXPR:
15431 case BIT_IOR_EXPR:
15432 case BIT_XOR_EXPR:
15433 if (c_tree_equal (TREE_OPERAND (rhs1, 0), unfolded_lhs))
15434 {
15435 opcode = TREE_CODE (rhs1);
15436 rhs = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
15437 true);
15438 rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 0), false, NULL,
15439 true);
15440 goto stmt_done;
15441 }
15442 if (c_tree_equal (TREE_OPERAND (rhs1, 1), unfolded_lhs))
15443 {
15444 opcode = TREE_CODE (rhs1);
15445 rhs = c_fully_fold (TREE_OPERAND (rhs1, 0), false, NULL,
15446 true);
15447 rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
15448 true);
15449 swapped = !commutative_tree_code (opcode);
15450 goto stmt_done;
15451 }
15452 break;
15453 case ERROR_MARK:
15454 goto saw_error;
15455 default:
15456 break;
15457 }
15458 if (c_parser_peek_token (parser)->type == CPP_SEMICOLON)
15459 {
15460 if (structured_block && code == OMP_ATOMIC_CAPTURE_NEW)
15461 {
15462 code = OMP_ATOMIC_CAPTURE_OLD;
15463 v = lhs;
15464 lhs = NULL_TREE;
15465 expr = default_function_array_read_conversion (eloc, expr);
15466 unfolded_lhs1 = expr.value;
15467 lhs1 = c_fully_fold (unfolded_lhs1, false, NULL, true);
15468 rhs1 = NULL_TREE;
15469 c_parser_consume_token (parser);
15470 goto restart;
15471 }
15472 if (structured_block)
15473 {
15474 opcode = NOP_EXPR;
15475 expr = default_function_array_read_conversion (eloc, expr);
15476 rhs = c_fully_fold (expr.value, false, NULL, true);
15477 rhs1 = NULL_TREE;
15478 goto stmt_done;
15479 }
15480 }
15481 c_parser_error (parser, "invalid form of %<#pragma omp atomic%>");
15482 goto saw_error;
15483 default:
15484 c_parser_error (parser,
15485 "invalid operator for %<#pragma omp atomic%>");
15486 goto saw_error;
15487 }
15488
15489 /* Arrange to pass the location of the assignment operator to
15490 c_finish_omp_atomic. */
15491 loc = c_parser_peek_token (parser)->location;
15492 c_parser_consume_token (parser);
15493 eloc = c_parser_peek_token (parser)->location;
15494 expr = c_parser_expression (parser);
15495 expr = default_function_array_read_conversion (eloc, expr);
15496 rhs = expr.value;
15497 rhs = c_fully_fold (rhs, false, NULL, true);
15498 break;
15499 }
15500 stmt_done:
15501 if (structured_block && code == OMP_ATOMIC_CAPTURE_NEW)
15502 {
15503 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
15504 goto saw_error;
15505 v = c_parser_cast_expression (parser, NULL).value;
15506 non_lvalue_p = !lvalue_p (v);
15507 v = c_fully_fold (v, false, NULL, true);
15508 if (v == error_mark_node)
15509 goto saw_error;
15510 if (non_lvalue_p)
15511 v = non_lvalue (v);
15512 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
15513 goto saw_error;
15514 eloc = c_parser_peek_token (parser)->location;
15515 expr = c_parser_cast_expression (parser, NULL);
15516 lhs1 = expr.value;
15517 expr = default_function_array_read_conversion (eloc, expr);
15518 unfolded_lhs1 = expr.value;
15519 lhs1 = c_fully_fold (lhs1, false, NULL, true);
15520 if (lhs1 == error_mark_node)
15521 goto saw_error;
15522 if (!lvalue_p (unfolded_lhs1))
15523 lhs1 = non_lvalue (lhs1);
15524 }
15525 if (structured_block)
15526 {
15527 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
15528 c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>");
15529 }
15530 done:
15531 if (unfolded_lhs && unfolded_lhs1
15532 && !c_tree_equal (unfolded_lhs, unfolded_lhs1))
15533 {
15534 error ("%<#pragma omp atomic capture%> uses two different "
15535 "expressions for memory");
15536 stmt = error_mark_node;
15537 }
15538 else
15539 stmt = c_finish_omp_atomic (loc, code, opcode, lhs, rhs, v, lhs1, rhs1,
15540 swapped, seq_cst);
15541 if (stmt != error_mark_node)
15542 add_stmt (stmt);
15543
15544 if (!structured_block)
15545 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
15546 }
15547
15548
15549 /* OpenMP 2.5:
15550 # pragma omp barrier new-line
15551 */
15552
15553 static void
c_parser_omp_barrier(c_parser * parser)15554 c_parser_omp_barrier (c_parser *parser)
15555 {
15556 location_t loc = c_parser_peek_token (parser)->location;
15557 c_parser_consume_pragma (parser);
15558 c_parser_skip_to_pragma_eol (parser);
15559
15560 c_finish_omp_barrier (loc);
15561 }
15562
15563 /* OpenMP 2.5:
15564 # pragma omp critical [(name)] new-line
15565 structured-block
15566
15567 OpenMP 4.5:
15568 # pragma omp critical [(name) [hint(expression)]] new-line
15569
15570 LOC is the location of the #pragma itself. */
15571
15572 #define OMP_CRITICAL_CLAUSE_MASK \
15573 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HINT) )
15574
15575 static tree
c_parser_omp_critical(location_t loc,c_parser * parser,bool * if_p)15576 c_parser_omp_critical (location_t loc, c_parser *parser, bool *if_p)
15577 {
15578 tree stmt, name = NULL_TREE, clauses = NULL_TREE;
15579
15580 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
15581 {
15582 c_parser_consume_token (parser);
15583 if (c_parser_next_token_is (parser, CPP_NAME))
15584 {
15585 name = c_parser_peek_token (parser)->value;
15586 c_parser_consume_token (parser);
15587 c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>");
15588 }
15589 else
15590 c_parser_error (parser, "expected identifier");
15591
15592 clauses = c_parser_omp_all_clauses (parser,
15593 OMP_CRITICAL_CLAUSE_MASK,
15594 "#pragma omp critical");
15595 }
15596 else
15597 {
15598 if (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
15599 c_parser_error (parser, "expected %<(%> or end of line");
15600 c_parser_skip_to_pragma_eol (parser);
15601 }
15602
15603 stmt = c_parser_omp_structured_block (parser, if_p);
15604 return c_finish_omp_critical (loc, stmt, name, clauses);
15605 }
15606
15607 /* OpenMP 2.5:
15608 # pragma omp flush flush-vars[opt] new-line
15609
15610 flush-vars:
15611 ( variable-list ) */
15612
15613 static void
c_parser_omp_flush(c_parser * parser)15614 c_parser_omp_flush (c_parser *parser)
15615 {
15616 location_t loc = c_parser_peek_token (parser)->location;
15617 c_parser_consume_pragma (parser);
15618 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
15619 c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
15620 else if (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
15621 c_parser_error (parser, "expected %<(%> or end of line");
15622 c_parser_skip_to_pragma_eol (parser);
15623
15624 c_finish_omp_flush (loc);
15625 }
15626
15627 /* Parse the restricted form of loop statements allowed by OpenACC and OpenMP.
15628 The real trick here is to determine the loop control variable early
15629 so that we can push a new decl if necessary to make it private.
15630 LOC is the location of the "acc" or "omp" in "#pragma acc" or "#pragma omp",
15631 respectively. */
15632
15633 static tree
c_parser_omp_for_loop(location_t loc,c_parser * parser,enum tree_code code,tree clauses,tree * cclauses,bool * if_p)15634 c_parser_omp_for_loop (location_t loc, c_parser *parser, enum tree_code code,
15635 tree clauses, tree *cclauses, bool *if_p)
15636 {
15637 tree decl, cond, incr, save_break, save_cont, body, init, stmt, cl;
15638 tree declv, condv, incrv, initv, ret = NULL_TREE;
15639 tree pre_body = NULL_TREE, this_pre_body;
15640 tree ordered_cl = NULL_TREE;
15641 bool fail = false, open_brace_parsed = false;
15642 int i, collapse = 1, ordered = 0, count, nbraces = 0;
15643 location_t for_loc;
15644 bool tiling = false;
15645 vec<tree, va_gc> *for_block = make_tree_vector ();
15646
15647 for (cl = clauses; cl; cl = OMP_CLAUSE_CHAIN (cl))
15648 if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_COLLAPSE)
15649 collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (cl));
15650 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_TILE)
15651 {
15652 tiling = true;
15653 collapse = list_length (OMP_CLAUSE_TILE_LIST (cl));
15654 }
15655 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_ORDERED
15656 && OMP_CLAUSE_ORDERED_EXPR (cl))
15657 {
15658 ordered_cl = cl;
15659 ordered = tree_to_shwi (OMP_CLAUSE_ORDERED_EXPR (cl));
15660 }
15661
15662 if (ordered && ordered < collapse)
15663 {
15664 error_at (OMP_CLAUSE_LOCATION (ordered_cl),
15665 "%<ordered%> clause parameter is less than %<collapse%>");
15666 OMP_CLAUSE_ORDERED_EXPR (ordered_cl)
15667 = build_int_cst (NULL_TREE, collapse);
15668 ordered = collapse;
15669 }
15670 if (ordered)
15671 {
15672 for (tree *pc = &clauses; *pc; )
15673 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_LINEAR)
15674 {
15675 error_at (OMP_CLAUSE_LOCATION (*pc),
15676 "%<linear%> clause may not be specified together "
15677 "with %<ordered%> clause with a parameter");
15678 *pc = OMP_CLAUSE_CHAIN (*pc);
15679 }
15680 else
15681 pc = &OMP_CLAUSE_CHAIN (*pc);
15682 }
15683
15684 gcc_assert (tiling || (collapse >= 1 && ordered >= 0));
15685 count = ordered ? ordered : collapse;
15686
15687 declv = make_tree_vec (count);
15688 initv = make_tree_vec (count);
15689 condv = make_tree_vec (count);
15690 incrv = make_tree_vec (count);
15691
15692 if (!c_parser_next_token_is_keyword (parser, RID_FOR))
15693 {
15694 c_parser_error (parser, "for statement expected");
15695 return NULL;
15696 }
15697 for_loc = c_parser_peek_token (parser)->location;
15698 c_parser_consume_token (parser);
15699
15700 for (i = 0; i < count; i++)
15701 {
15702 int bracecount = 0;
15703
15704 matching_parens parens;
15705 if (!parens.require_open (parser))
15706 goto pop_scopes;
15707
15708 /* Parse the initialization declaration or expression. */
15709 if (c_parser_next_tokens_start_declaration (parser))
15710 {
15711 if (i > 0)
15712 vec_safe_push (for_block, c_begin_compound_stmt (true));
15713 this_pre_body = push_stmt_list ();
15714 c_parser_declaration_or_fndef (parser, true, true, true, true, true,
15715 NULL, vNULL);
15716 if (this_pre_body)
15717 {
15718 this_pre_body = pop_stmt_list (this_pre_body);
15719 if (pre_body)
15720 {
15721 tree t = pre_body;
15722 pre_body = push_stmt_list ();
15723 add_stmt (t);
15724 add_stmt (this_pre_body);
15725 pre_body = pop_stmt_list (pre_body);
15726 }
15727 else
15728 pre_body = this_pre_body;
15729 }
15730 decl = check_for_loop_decls (for_loc, flag_isoc99);
15731 if (decl == NULL)
15732 goto error_init;
15733 if (DECL_INITIAL (decl) == error_mark_node)
15734 decl = error_mark_node;
15735 init = decl;
15736 }
15737 else if (c_parser_next_token_is (parser, CPP_NAME)
15738 && c_parser_peek_2nd_token (parser)->type == CPP_EQ)
15739 {
15740 struct c_expr decl_exp;
15741 struct c_expr init_exp;
15742 location_t init_loc;
15743
15744 decl_exp = c_parser_postfix_expression (parser);
15745 decl = decl_exp.value;
15746
15747 c_parser_require (parser, CPP_EQ, "expected %<=%>");
15748
15749 init_loc = c_parser_peek_token (parser)->location;
15750 init_exp = c_parser_expr_no_commas (parser, NULL);
15751 init_exp = default_function_array_read_conversion (init_loc,
15752 init_exp);
15753 init = build_modify_expr (init_loc, decl, decl_exp.original_type,
15754 NOP_EXPR, init_loc, init_exp.value,
15755 init_exp.original_type);
15756 init = c_process_expr_stmt (init_loc, init);
15757
15758 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
15759 }
15760 else
15761 {
15762 error_init:
15763 c_parser_error (parser,
15764 "expected iteration declaration or initialization");
15765 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
15766 "expected %<)%>");
15767 fail = true;
15768 goto parse_next;
15769 }
15770
15771 /* Parse the loop condition. */
15772 cond = NULL_TREE;
15773 if (c_parser_next_token_is_not (parser, CPP_SEMICOLON))
15774 {
15775 location_t cond_loc = c_parser_peek_token (parser)->location;
15776 struct c_expr cond_expr
15777 = c_parser_binary_expression (parser, NULL, NULL_TREE);
15778
15779 cond = cond_expr.value;
15780 cond = c_objc_common_truthvalue_conversion (cond_loc, cond);
15781 if (COMPARISON_CLASS_P (cond))
15782 {
15783 tree op0 = TREE_OPERAND (cond, 0), op1 = TREE_OPERAND (cond, 1);
15784 op0 = c_fully_fold (op0, false, NULL);
15785 op1 = c_fully_fold (op1, false, NULL);
15786 TREE_OPERAND (cond, 0) = op0;
15787 TREE_OPERAND (cond, 1) = op1;
15788 }
15789 switch (cond_expr.original_code)
15790 {
15791 case GT_EXPR:
15792 case GE_EXPR:
15793 case LT_EXPR:
15794 case LE_EXPR:
15795 break;
15796 default:
15797 /* Can't be cond = error_mark_node, because we want to preserve
15798 the location until c_finish_omp_for. */
15799 cond = build1 (NOP_EXPR, boolean_type_node, error_mark_node);
15800 break;
15801 }
15802 protected_set_expr_location (cond, cond_loc);
15803 }
15804 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
15805
15806 /* Parse the increment expression. */
15807 incr = NULL_TREE;
15808 if (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN))
15809 {
15810 location_t incr_loc = c_parser_peek_token (parser)->location;
15811
15812 incr = c_process_expr_stmt (incr_loc,
15813 c_parser_expression (parser).value);
15814 }
15815 parens.skip_until_found_close (parser);
15816
15817 if (decl == NULL || decl == error_mark_node || init == error_mark_node)
15818 fail = true;
15819 else
15820 {
15821 TREE_VEC_ELT (declv, i) = decl;
15822 TREE_VEC_ELT (initv, i) = init;
15823 TREE_VEC_ELT (condv, i) = cond;
15824 TREE_VEC_ELT (incrv, i) = incr;
15825 }
15826
15827 parse_next:
15828 if (i == count - 1)
15829 break;
15830
15831 /* FIXME: OpenMP 3.0 draft isn't very clear on what exactly is allowed
15832 in between the collapsed for loops to be still considered perfectly
15833 nested. Hopefully the final version clarifies this.
15834 For now handle (multiple) {'s and empty statements. */
15835 do
15836 {
15837 if (c_parser_next_token_is_keyword (parser, RID_FOR))
15838 {
15839 c_parser_consume_token (parser);
15840 break;
15841 }
15842 else if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
15843 {
15844 c_parser_consume_token (parser);
15845 bracecount++;
15846 }
15847 else if (bracecount
15848 && c_parser_next_token_is (parser, CPP_SEMICOLON))
15849 c_parser_consume_token (parser);
15850 else
15851 {
15852 c_parser_error (parser, "not enough perfectly nested loops");
15853 if (bracecount)
15854 {
15855 open_brace_parsed = true;
15856 bracecount--;
15857 }
15858 fail = true;
15859 count = 0;
15860 break;
15861 }
15862 }
15863 while (1);
15864
15865 nbraces += bracecount;
15866 }
15867
15868 if (nbraces)
15869 if_p = NULL;
15870
15871 save_break = c_break_label;
15872 c_break_label = size_one_node;
15873 save_cont = c_cont_label;
15874 c_cont_label = NULL_TREE;
15875 body = push_stmt_list ();
15876
15877 if (open_brace_parsed)
15878 {
15879 location_t here = c_parser_peek_token (parser)->location;
15880 stmt = c_begin_compound_stmt (true);
15881 c_parser_compound_statement_nostart (parser);
15882 add_stmt (c_end_compound_stmt (here, stmt, true));
15883 }
15884 else
15885 add_stmt (c_parser_c99_block_statement (parser, if_p));
15886 if (c_cont_label)
15887 {
15888 tree t = build1 (LABEL_EXPR, void_type_node, c_cont_label);
15889 SET_EXPR_LOCATION (t, loc);
15890 add_stmt (t);
15891 }
15892
15893 body = pop_stmt_list (body);
15894 c_break_label = save_break;
15895 c_cont_label = save_cont;
15896
15897 while (nbraces)
15898 {
15899 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
15900 {
15901 c_parser_consume_token (parser);
15902 nbraces--;
15903 }
15904 else if (c_parser_next_token_is (parser, CPP_SEMICOLON))
15905 c_parser_consume_token (parser);
15906 else
15907 {
15908 c_parser_error (parser, "collapsed loops not perfectly nested");
15909 while (nbraces)
15910 {
15911 location_t here = c_parser_peek_token (parser)->location;
15912 stmt = c_begin_compound_stmt (true);
15913 add_stmt (body);
15914 c_parser_compound_statement_nostart (parser);
15915 body = c_end_compound_stmt (here, stmt, true);
15916 nbraces--;
15917 }
15918 goto pop_scopes;
15919 }
15920 }
15921
15922 /* Only bother calling c_finish_omp_for if we haven't already generated
15923 an error from the initialization parsing. */
15924 if (!fail)
15925 {
15926 stmt = c_finish_omp_for (loc, code, declv, NULL, initv, condv,
15927 incrv, body, pre_body);
15928
15929 /* Check for iterators appearing in lb, b or incr expressions. */
15930 if (stmt && !c_omp_check_loop_iv (stmt, declv, NULL))
15931 stmt = NULL_TREE;
15932
15933 if (stmt)
15934 {
15935 add_stmt (stmt);
15936
15937 if (cclauses != NULL
15938 && cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] != NULL)
15939 {
15940 tree *c;
15941 for (c = &cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL]; *c ; )
15942 if (OMP_CLAUSE_CODE (*c) != OMP_CLAUSE_FIRSTPRIVATE
15943 && OMP_CLAUSE_CODE (*c) != OMP_CLAUSE_LASTPRIVATE)
15944 c = &OMP_CLAUSE_CHAIN (*c);
15945 else
15946 {
15947 for (i = 0; i < count; i++)
15948 if (TREE_VEC_ELT (declv, i) == OMP_CLAUSE_DECL (*c))
15949 break;
15950 if (i == count)
15951 c = &OMP_CLAUSE_CHAIN (*c);
15952 else if (OMP_CLAUSE_CODE (*c) == OMP_CLAUSE_FIRSTPRIVATE)
15953 {
15954 error_at (loc,
15955 "iteration variable %qD should not be firstprivate",
15956 OMP_CLAUSE_DECL (*c));
15957 *c = OMP_CLAUSE_CHAIN (*c);
15958 }
15959 else
15960 {
15961 /* Move lastprivate (decl) clause to OMP_FOR_CLAUSES. */
15962 tree l = *c;
15963 *c = OMP_CLAUSE_CHAIN (*c);
15964 if (code == OMP_SIMD)
15965 {
15966 OMP_CLAUSE_CHAIN (l)
15967 = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
15968 cclauses[C_OMP_CLAUSE_SPLIT_FOR] = l;
15969 }
15970 else
15971 {
15972 OMP_CLAUSE_CHAIN (l) = clauses;
15973 clauses = l;
15974 }
15975 }
15976 }
15977 }
15978 OMP_FOR_CLAUSES (stmt) = clauses;
15979 }
15980 ret = stmt;
15981 }
15982 pop_scopes:
15983 while (!for_block->is_empty ())
15984 {
15985 /* FIXME diagnostics: LOC below should be the actual location of
15986 this particular for block. We need to build a list of
15987 locations to go along with FOR_BLOCK. */
15988 stmt = c_end_compound_stmt (loc, for_block->pop (), true);
15989 add_stmt (stmt);
15990 }
15991 release_tree_vector (for_block);
15992 return ret;
15993 }
15994
15995 /* Helper function for OpenMP parsing, split clauses and call
15996 finish_omp_clauses on each of the set of clauses afterwards. */
15997
15998 static void
omp_split_clauses(location_t loc,enum tree_code code,omp_clause_mask mask,tree clauses,tree * cclauses)15999 omp_split_clauses (location_t loc, enum tree_code code,
16000 omp_clause_mask mask, tree clauses, tree *cclauses)
16001 {
16002 int i;
16003 c_omp_split_clauses (loc, code, mask, clauses, cclauses);
16004 for (i = 0; i < C_OMP_CLAUSE_SPLIT_COUNT; i++)
16005 if (cclauses[i])
16006 cclauses[i] = c_finish_omp_clauses (cclauses[i], C_ORT_OMP);
16007 }
16008
16009 /* OpenMP 4.0:
16010 #pragma omp simd simd-clause[optseq] new-line
16011 for-loop
16012
16013 LOC is the location of the #pragma token.
16014 */
16015
16016 #define OMP_SIMD_CLAUSE_MASK \
16017 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SAFELEN) \
16018 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
16019 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
16020 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
16021 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
16022 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
16023 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
16024 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE))
16025
16026 static tree
c_parser_omp_simd(location_t loc,c_parser * parser,char * p_name,omp_clause_mask mask,tree * cclauses,bool * if_p)16027 c_parser_omp_simd (location_t loc, c_parser *parser,
16028 char *p_name, omp_clause_mask mask, tree *cclauses,
16029 bool *if_p)
16030 {
16031 tree block, clauses, ret;
16032
16033 strcat (p_name, " simd");
16034 mask |= OMP_SIMD_CLAUSE_MASK;
16035
16036 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
16037 if (cclauses)
16038 {
16039 omp_split_clauses (loc, OMP_SIMD, mask, clauses, cclauses);
16040 clauses = cclauses[C_OMP_CLAUSE_SPLIT_SIMD];
16041 tree c = omp_find_clause (cclauses[C_OMP_CLAUSE_SPLIT_FOR],
16042 OMP_CLAUSE_ORDERED);
16043 if (c && OMP_CLAUSE_ORDERED_EXPR (c))
16044 {
16045 error_at (OMP_CLAUSE_LOCATION (c),
16046 "%<ordered%> clause with parameter may not be specified "
16047 "on %qs construct", p_name);
16048 OMP_CLAUSE_ORDERED_EXPR (c) = NULL_TREE;
16049 }
16050 }
16051
16052 block = c_begin_compound_stmt (true);
16053 ret = c_parser_omp_for_loop (loc, parser, OMP_SIMD, clauses, cclauses, if_p);
16054 block = c_end_compound_stmt (loc, block, true);
16055 add_stmt (block);
16056
16057 return ret;
16058 }
16059
16060 /* OpenMP 2.5:
16061 #pragma omp for for-clause[optseq] new-line
16062 for-loop
16063
16064 OpenMP 4.0:
16065 #pragma omp for simd for-simd-clause[optseq] new-line
16066 for-loop
16067
16068 LOC is the location of the #pragma token.
16069 */
16070
16071 #define OMP_FOR_CLAUSE_MASK \
16072 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
16073 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
16074 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
16075 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
16076 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
16077 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED) \
16078 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE) \
16079 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
16080 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
16081
16082 static tree
c_parser_omp_for(location_t loc,c_parser * parser,char * p_name,omp_clause_mask mask,tree * cclauses,bool * if_p)16083 c_parser_omp_for (location_t loc, c_parser *parser,
16084 char *p_name, omp_clause_mask mask, tree *cclauses,
16085 bool *if_p)
16086 {
16087 tree block, clauses, ret;
16088
16089 strcat (p_name, " for");
16090 mask |= OMP_FOR_CLAUSE_MASK;
16091 /* parallel for{, simd} disallows nowait clause, but for
16092 target {teams distribute ,}parallel for{, simd} it should be accepted. */
16093 if (cclauses && (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) == 0)
16094 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT);
16095 /* Composite distribute parallel for{, simd} disallows ordered clause. */
16096 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
16097 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED);
16098
16099 if (c_parser_next_token_is (parser, CPP_NAME))
16100 {
16101 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16102
16103 if (strcmp (p, "simd") == 0)
16104 {
16105 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
16106 if (cclauses == NULL)
16107 cclauses = cclauses_buf;
16108
16109 c_parser_consume_token (parser);
16110 if (!flag_openmp) /* flag_openmp_simd */
16111 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
16112 if_p);
16113 block = c_begin_compound_stmt (true);
16114 ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses, if_p);
16115 block = c_end_compound_stmt (loc, block, true);
16116 if (ret == NULL_TREE)
16117 return ret;
16118 ret = make_node (OMP_FOR);
16119 TREE_TYPE (ret) = void_type_node;
16120 OMP_FOR_BODY (ret) = block;
16121 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
16122 SET_EXPR_LOCATION (ret, loc);
16123 add_stmt (ret);
16124 return ret;
16125 }
16126 }
16127 if (!flag_openmp) /* flag_openmp_simd */
16128 {
16129 c_parser_skip_to_pragma_eol (parser, false);
16130 return NULL_TREE;
16131 }
16132
16133 /* Composite distribute parallel for disallows linear clause. */
16134 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
16135 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR);
16136
16137 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
16138 if (cclauses)
16139 {
16140 omp_split_clauses (loc, OMP_FOR, mask, clauses, cclauses);
16141 clauses = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
16142 }
16143
16144 block = c_begin_compound_stmt (true);
16145 ret = c_parser_omp_for_loop (loc, parser, OMP_FOR, clauses, cclauses, if_p);
16146 block = c_end_compound_stmt (loc, block, true);
16147 add_stmt (block);
16148
16149 return ret;
16150 }
16151
16152 /* OpenMP 2.5:
16153 # pragma omp master new-line
16154 structured-block
16155
16156 LOC is the location of the #pragma token.
16157 */
16158
16159 static tree
c_parser_omp_master(location_t loc,c_parser * parser,bool * if_p)16160 c_parser_omp_master (location_t loc, c_parser *parser, bool *if_p)
16161 {
16162 c_parser_skip_to_pragma_eol (parser);
16163 return c_finish_omp_master (loc, c_parser_omp_structured_block (parser,
16164 if_p));
16165 }
16166
16167 /* OpenMP 2.5:
16168 # pragma omp ordered new-line
16169 structured-block
16170
16171 OpenMP 4.5:
16172 # pragma omp ordered ordered-clauses new-line
16173 structured-block
16174
16175 # pragma omp ordered depend-clauses new-line */
16176
16177 #define OMP_ORDERED_CLAUSE_MASK \
16178 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREADS) \
16179 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMD))
16180
16181 #define OMP_ORDERED_DEPEND_CLAUSE_MASK \
16182 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)
16183
16184 static bool
c_parser_omp_ordered(c_parser * parser,enum pragma_context context,bool * if_p)16185 c_parser_omp_ordered (c_parser *parser, enum pragma_context context,
16186 bool *if_p)
16187 {
16188 location_t loc = c_parser_peek_token (parser)->location;
16189 c_parser_consume_pragma (parser);
16190
16191 if (context != pragma_stmt && context != pragma_compound)
16192 {
16193 c_parser_error (parser, "expected declaration specifiers");
16194 c_parser_skip_to_pragma_eol (parser, false);
16195 return false;
16196 }
16197
16198 if (c_parser_next_token_is (parser, CPP_NAME))
16199 {
16200 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16201
16202 if (!strcmp ("depend", p))
16203 {
16204 if (!flag_openmp) /* flag_openmp_simd */
16205 {
16206 c_parser_skip_to_pragma_eol (parser, false);
16207 return false;
16208 }
16209 if (context == pragma_stmt)
16210 {
16211 error_at (loc,
16212 "%<#pragma omp ordered%> with %<depend%> clause may "
16213 "only be used in compound statements");
16214 c_parser_skip_to_pragma_eol (parser, false);
16215 return false;
16216 }
16217
16218 tree clauses
16219 = c_parser_omp_all_clauses (parser,
16220 OMP_ORDERED_DEPEND_CLAUSE_MASK,
16221 "#pragma omp ordered");
16222 c_finish_omp_ordered (loc, clauses, NULL_TREE);
16223 return false;
16224 }
16225 }
16226
16227 tree clauses = c_parser_omp_all_clauses (parser, OMP_ORDERED_CLAUSE_MASK,
16228 "#pragma omp ordered");
16229
16230 if (!flag_openmp /* flag_openmp_simd */
16231 && omp_find_clause (clauses, OMP_CLAUSE_SIMD) == NULL_TREE)
16232 return false;
16233
16234 c_finish_omp_ordered (loc, clauses,
16235 c_parser_omp_structured_block (parser, if_p));
16236 return true;
16237 }
16238
16239 /* OpenMP 2.5:
16240
16241 section-scope:
16242 { section-sequence }
16243
16244 section-sequence:
16245 section-directive[opt] structured-block
16246 section-sequence section-directive structured-block
16247
16248 SECTIONS_LOC is the location of the #pragma omp sections. */
16249
16250 static tree
c_parser_omp_sections_scope(location_t sections_loc,c_parser * parser)16251 c_parser_omp_sections_scope (location_t sections_loc, c_parser *parser)
16252 {
16253 tree stmt, substmt;
16254 bool error_suppress = false;
16255 location_t loc;
16256
16257 loc = c_parser_peek_token (parser)->location;
16258 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
16259 {
16260 /* Avoid skipping until the end of the block. */
16261 parser->error = false;
16262 return NULL_TREE;
16263 }
16264
16265 stmt = push_stmt_list ();
16266
16267 if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_SECTION)
16268 {
16269 substmt = c_parser_omp_structured_block (parser, NULL);
16270 substmt = build1 (OMP_SECTION, void_type_node, substmt);
16271 SET_EXPR_LOCATION (substmt, loc);
16272 add_stmt (substmt);
16273 }
16274
16275 while (1)
16276 {
16277 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
16278 break;
16279 if (c_parser_next_token_is (parser, CPP_EOF))
16280 break;
16281
16282 loc = c_parser_peek_token (parser)->location;
16283 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SECTION)
16284 {
16285 c_parser_consume_pragma (parser);
16286 c_parser_skip_to_pragma_eol (parser);
16287 error_suppress = false;
16288 }
16289 else if (!error_suppress)
16290 {
16291 error_at (loc, "expected %<#pragma omp section%> or %<}%>");
16292 error_suppress = true;
16293 }
16294
16295 substmt = c_parser_omp_structured_block (parser, NULL);
16296 substmt = build1 (OMP_SECTION, void_type_node, substmt);
16297 SET_EXPR_LOCATION (substmt, loc);
16298 add_stmt (substmt);
16299 }
16300 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE,
16301 "expected %<#pragma omp section%> or %<}%>");
16302
16303 substmt = pop_stmt_list (stmt);
16304
16305 stmt = make_node (OMP_SECTIONS);
16306 SET_EXPR_LOCATION (stmt, sections_loc);
16307 TREE_TYPE (stmt) = void_type_node;
16308 OMP_SECTIONS_BODY (stmt) = substmt;
16309
16310 return add_stmt (stmt);
16311 }
16312
16313 /* OpenMP 2.5:
16314 # pragma omp sections sections-clause[optseq] newline
16315 sections-scope
16316
16317 LOC is the location of the #pragma token.
16318 */
16319
16320 #define OMP_SECTIONS_CLAUSE_MASK \
16321 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
16322 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
16323 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
16324 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
16325 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
16326
16327 static tree
c_parser_omp_sections(location_t loc,c_parser * parser,char * p_name,omp_clause_mask mask,tree * cclauses)16328 c_parser_omp_sections (location_t loc, c_parser *parser,
16329 char *p_name, omp_clause_mask mask, tree *cclauses)
16330 {
16331 tree block, clauses, ret;
16332
16333 strcat (p_name, " sections");
16334 mask |= OMP_SECTIONS_CLAUSE_MASK;
16335 if (cclauses)
16336 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT);
16337
16338 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
16339 if (cclauses)
16340 {
16341 omp_split_clauses (loc, OMP_SECTIONS, mask, clauses, cclauses);
16342 clauses = cclauses[C_OMP_CLAUSE_SPLIT_SECTIONS];
16343 }
16344
16345 block = c_begin_compound_stmt (true);
16346 ret = c_parser_omp_sections_scope (loc, parser);
16347 if (ret)
16348 OMP_SECTIONS_CLAUSES (ret) = clauses;
16349 block = c_end_compound_stmt (loc, block, true);
16350 add_stmt (block);
16351
16352 return ret;
16353 }
16354
16355 /* OpenMP 2.5:
16356 # pragma omp parallel parallel-clause[optseq] new-line
16357 structured-block
16358 # pragma omp parallel for parallel-for-clause[optseq] new-line
16359 structured-block
16360 # pragma omp parallel sections parallel-sections-clause[optseq] new-line
16361 structured-block
16362
16363 OpenMP 4.0:
16364 # pragma omp parallel for simd parallel-for-simd-clause[optseq] new-line
16365 structured-block
16366
16367 LOC is the location of the #pragma token.
16368 */
16369
16370 #define OMP_PARALLEL_CLAUSE_MASK \
16371 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
16372 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
16373 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
16374 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
16375 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
16376 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN) \
16377 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
16378 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS) \
16379 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PROC_BIND))
16380
16381 static tree
c_parser_omp_parallel(location_t loc,c_parser * parser,char * p_name,omp_clause_mask mask,tree * cclauses,bool * if_p)16382 c_parser_omp_parallel (location_t loc, c_parser *parser,
16383 char *p_name, omp_clause_mask mask, tree *cclauses,
16384 bool *if_p)
16385 {
16386 tree stmt, clauses, block;
16387
16388 strcat (p_name, " parallel");
16389 mask |= OMP_PARALLEL_CLAUSE_MASK;
16390 /* #pragma omp target parallel{, for, for simd} disallow copyin clause. */
16391 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) != 0
16392 && (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) == 0)
16393 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN);
16394
16395 if (c_parser_next_token_is_keyword (parser, RID_FOR))
16396 {
16397 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
16398 if (cclauses == NULL)
16399 cclauses = cclauses_buf;
16400
16401 c_parser_consume_token (parser);
16402 if (!flag_openmp) /* flag_openmp_simd */
16403 return c_parser_omp_for (loc, parser, p_name, mask, cclauses, if_p);
16404 block = c_begin_omp_parallel ();
16405 tree ret = c_parser_omp_for (loc, parser, p_name, mask, cclauses, if_p);
16406 stmt
16407 = c_finish_omp_parallel (loc, cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
16408 block);
16409 if (ret == NULL_TREE)
16410 return ret;
16411 OMP_PARALLEL_COMBINED (stmt) = 1;
16412 return stmt;
16413 }
16414 /* When combined with distribute, parallel has to be followed by for.
16415 #pragma omp target parallel is allowed though. */
16416 else if (cclauses
16417 && (mask & (OMP_CLAUSE_MASK_1
16418 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
16419 {
16420 error_at (loc, "expected %<for%> after %qs", p_name);
16421 c_parser_skip_to_pragma_eol (parser);
16422 return NULL_TREE;
16423 }
16424 else if (!flag_openmp) /* flag_openmp_simd */
16425 {
16426 c_parser_skip_to_pragma_eol (parser, false);
16427 return NULL_TREE;
16428 }
16429 else if (cclauses == NULL && c_parser_next_token_is (parser, CPP_NAME))
16430 {
16431 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16432 if (strcmp (p, "sections") == 0)
16433 {
16434 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
16435 if (cclauses == NULL)
16436 cclauses = cclauses_buf;
16437
16438 c_parser_consume_token (parser);
16439 block = c_begin_omp_parallel ();
16440 c_parser_omp_sections (loc, parser, p_name, mask, cclauses);
16441 stmt = c_finish_omp_parallel (loc,
16442 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
16443 block);
16444 OMP_PARALLEL_COMBINED (stmt) = 1;
16445 return stmt;
16446 }
16447 }
16448
16449 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
16450 if (cclauses)
16451 {
16452 omp_split_clauses (loc, OMP_PARALLEL, mask, clauses, cclauses);
16453 clauses = cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL];
16454 }
16455
16456 block = c_begin_omp_parallel ();
16457 c_parser_statement (parser, if_p);
16458 stmt = c_finish_omp_parallel (loc, clauses, block);
16459
16460 return stmt;
16461 }
16462
16463 /* OpenMP 2.5:
16464 # pragma omp single single-clause[optseq] new-line
16465 structured-block
16466
16467 LOC is the location of the #pragma.
16468 */
16469
16470 #define OMP_SINGLE_CLAUSE_MASK \
16471 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
16472 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
16473 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYPRIVATE) \
16474 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
16475
16476 static tree
c_parser_omp_single(location_t loc,c_parser * parser,bool * if_p)16477 c_parser_omp_single (location_t loc, c_parser *parser, bool *if_p)
16478 {
16479 tree stmt = make_node (OMP_SINGLE);
16480 SET_EXPR_LOCATION (stmt, loc);
16481 TREE_TYPE (stmt) = void_type_node;
16482
16483 OMP_SINGLE_CLAUSES (stmt)
16484 = c_parser_omp_all_clauses (parser, OMP_SINGLE_CLAUSE_MASK,
16485 "#pragma omp single");
16486 OMP_SINGLE_BODY (stmt) = c_parser_omp_structured_block (parser, if_p);
16487
16488 return add_stmt (stmt);
16489 }
16490
16491 /* OpenMP 3.0:
16492 # pragma omp task task-clause[optseq] new-line
16493
16494 LOC is the location of the #pragma.
16495 */
16496
16497 #define OMP_TASK_CLAUSE_MASK \
16498 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
16499 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
16500 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
16501 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
16502 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
16503 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
16504 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
16505 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
16506 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
16507 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY))
16508
16509 static tree
c_parser_omp_task(location_t loc,c_parser * parser,bool * if_p)16510 c_parser_omp_task (location_t loc, c_parser *parser, bool *if_p)
16511 {
16512 tree clauses, block;
16513
16514 clauses = c_parser_omp_all_clauses (parser, OMP_TASK_CLAUSE_MASK,
16515 "#pragma omp task");
16516
16517 block = c_begin_omp_task ();
16518 c_parser_statement (parser, if_p);
16519 return c_finish_omp_task (loc, clauses, block);
16520 }
16521
16522 /* OpenMP 3.0:
16523 # pragma omp taskwait new-line
16524 */
16525
16526 static void
c_parser_omp_taskwait(c_parser * parser)16527 c_parser_omp_taskwait (c_parser *parser)
16528 {
16529 location_t loc = c_parser_peek_token (parser)->location;
16530 c_parser_consume_pragma (parser);
16531 c_parser_skip_to_pragma_eol (parser);
16532
16533 c_finish_omp_taskwait (loc);
16534 }
16535
16536 /* OpenMP 3.1:
16537 # pragma omp taskyield new-line
16538 */
16539
16540 static void
c_parser_omp_taskyield(c_parser * parser)16541 c_parser_omp_taskyield (c_parser *parser)
16542 {
16543 location_t loc = c_parser_peek_token (parser)->location;
16544 c_parser_consume_pragma (parser);
16545 c_parser_skip_to_pragma_eol (parser);
16546
16547 c_finish_omp_taskyield (loc);
16548 }
16549
16550 /* OpenMP 4.0:
16551 # pragma omp taskgroup new-line
16552 */
16553
16554 static tree
c_parser_omp_taskgroup(c_parser * parser,bool * if_p)16555 c_parser_omp_taskgroup (c_parser *parser, bool *if_p)
16556 {
16557 location_t loc = c_parser_peek_token (parser)->location;
16558 c_parser_skip_to_pragma_eol (parser);
16559 return c_finish_omp_taskgroup (loc, c_parser_omp_structured_block (parser,
16560 if_p));
16561 }
16562
16563 /* OpenMP 4.0:
16564 # pragma omp cancel cancel-clause[optseq] new-line
16565
16566 LOC is the location of the #pragma.
16567 */
16568
16569 #define OMP_CANCEL_CLAUSE_MASK \
16570 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
16571 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
16572 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
16573 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP) \
16574 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF))
16575
16576 static void
c_parser_omp_cancel(c_parser * parser)16577 c_parser_omp_cancel (c_parser *parser)
16578 {
16579 location_t loc = c_parser_peek_token (parser)->location;
16580
16581 c_parser_consume_pragma (parser);
16582 tree clauses = c_parser_omp_all_clauses (parser, OMP_CANCEL_CLAUSE_MASK,
16583 "#pragma omp cancel");
16584
16585 c_finish_omp_cancel (loc, clauses);
16586 }
16587
16588 /* OpenMP 4.0:
16589 # pragma omp cancellation point cancelpt-clause[optseq] new-line
16590
16591 LOC is the location of the #pragma.
16592 */
16593
16594 #define OMP_CANCELLATION_POINT_CLAUSE_MASK \
16595 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
16596 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
16597 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
16598 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP))
16599
16600 static void
c_parser_omp_cancellation_point(c_parser * parser,enum pragma_context context)16601 c_parser_omp_cancellation_point (c_parser *parser, enum pragma_context context)
16602 {
16603 location_t loc = c_parser_peek_token (parser)->location;
16604 tree clauses;
16605 bool point_seen = false;
16606
16607 c_parser_consume_pragma (parser);
16608 if (c_parser_next_token_is (parser, CPP_NAME))
16609 {
16610 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16611 if (strcmp (p, "point") == 0)
16612 {
16613 c_parser_consume_token (parser);
16614 point_seen = true;
16615 }
16616 }
16617 if (!point_seen)
16618 {
16619 c_parser_error (parser, "expected %<point%>");
16620 c_parser_skip_to_pragma_eol (parser);
16621 return;
16622 }
16623
16624 if (context != pragma_compound)
16625 {
16626 if (context == pragma_stmt)
16627 error_at (loc,
16628 "%<#pragma %s%> may only be used in compound statements",
16629 "omp cancellation point");
16630 else
16631 c_parser_error (parser, "expected declaration specifiers");
16632 c_parser_skip_to_pragma_eol (parser, false);
16633 return;
16634 }
16635
16636 clauses
16637 = c_parser_omp_all_clauses (parser, OMP_CANCELLATION_POINT_CLAUSE_MASK,
16638 "#pragma omp cancellation point");
16639
16640 c_finish_omp_cancellation_point (loc, clauses);
16641 }
16642
16643 /* OpenMP 4.0:
16644 #pragma omp distribute distribute-clause[optseq] new-line
16645 for-loop */
16646
16647 #define OMP_DISTRIBUTE_CLAUSE_MASK \
16648 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
16649 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
16650 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
16651 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)\
16652 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE))
16653
16654 static tree
c_parser_omp_distribute(location_t loc,c_parser * parser,char * p_name,omp_clause_mask mask,tree * cclauses,bool * if_p)16655 c_parser_omp_distribute (location_t loc, c_parser *parser,
16656 char *p_name, omp_clause_mask mask, tree *cclauses,
16657 bool *if_p)
16658 {
16659 tree clauses, block, ret;
16660
16661 strcat (p_name, " distribute");
16662 mask |= OMP_DISTRIBUTE_CLAUSE_MASK;
16663
16664 if (c_parser_next_token_is (parser, CPP_NAME))
16665 {
16666 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16667 bool simd = false;
16668 bool parallel = false;
16669
16670 if (strcmp (p, "simd") == 0)
16671 simd = true;
16672 else
16673 parallel = strcmp (p, "parallel") == 0;
16674 if (parallel || simd)
16675 {
16676 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
16677 if (cclauses == NULL)
16678 cclauses = cclauses_buf;
16679 c_parser_consume_token (parser);
16680 if (!flag_openmp) /* flag_openmp_simd */
16681 {
16682 if (simd)
16683 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
16684 if_p);
16685 else
16686 return c_parser_omp_parallel (loc, parser, p_name, mask,
16687 cclauses, if_p);
16688 }
16689 block = c_begin_compound_stmt (true);
16690 if (simd)
16691 ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
16692 if_p);
16693 else
16694 ret = c_parser_omp_parallel (loc, parser, p_name, mask, cclauses,
16695 if_p);
16696 block = c_end_compound_stmt (loc, block, true);
16697 if (ret == NULL)
16698 return ret;
16699 ret = make_node (OMP_DISTRIBUTE);
16700 TREE_TYPE (ret) = void_type_node;
16701 OMP_FOR_BODY (ret) = block;
16702 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE];
16703 SET_EXPR_LOCATION (ret, loc);
16704 add_stmt (ret);
16705 return ret;
16706 }
16707 }
16708 if (!flag_openmp) /* flag_openmp_simd */
16709 {
16710 c_parser_skip_to_pragma_eol (parser, false);
16711 return NULL_TREE;
16712 }
16713
16714 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
16715 if (cclauses)
16716 {
16717 omp_split_clauses (loc, OMP_DISTRIBUTE, mask, clauses, cclauses);
16718 clauses = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE];
16719 }
16720
16721 block = c_begin_compound_stmt (true);
16722 ret = c_parser_omp_for_loop (loc, parser, OMP_DISTRIBUTE, clauses, NULL,
16723 if_p);
16724 block = c_end_compound_stmt (loc, block, true);
16725 add_stmt (block);
16726
16727 return ret;
16728 }
16729
16730 /* OpenMP 4.0:
16731 # pragma omp teams teams-clause[optseq] new-line
16732 structured-block */
16733
16734 #define OMP_TEAMS_CLAUSE_MASK \
16735 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
16736 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
16737 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
16738 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
16739 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS) \
16740 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \
16741 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT))
16742
16743 static tree
c_parser_omp_teams(location_t loc,c_parser * parser,char * p_name,omp_clause_mask mask,tree * cclauses,bool * if_p)16744 c_parser_omp_teams (location_t loc, c_parser *parser,
16745 char *p_name, omp_clause_mask mask, tree *cclauses,
16746 bool *if_p)
16747 {
16748 tree clauses, block, ret;
16749
16750 strcat (p_name, " teams");
16751 mask |= OMP_TEAMS_CLAUSE_MASK;
16752
16753 if (c_parser_next_token_is (parser, CPP_NAME))
16754 {
16755 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16756 if (strcmp (p, "distribute") == 0)
16757 {
16758 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
16759 if (cclauses == NULL)
16760 cclauses = cclauses_buf;
16761
16762 c_parser_consume_token (parser);
16763 if (!flag_openmp) /* flag_openmp_simd */
16764 return c_parser_omp_distribute (loc, parser, p_name, mask,
16765 cclauses, if_p);
16766 block = c_begin_compound_stmt (true);
16767 ret = c_parser_omp_distribute (loc, parser, p_name, mask, cclauses,
16768 if_p);
16769 block = c_end_compound_stmt (loc, block, true);
16770 if (ret == NULL)
16771 return ret;
16772 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
16773 ret = make_node (OMP_TEAMS);
16774 TREE_TYPE (ret) = void_type_node;
16775 OMP_TEAMS_CLAUSES (ret) = clauses;
16776 OMP_TEAMS_BODY (ret) = block;
16777 OMP_TEAMS_COMBINED (ret) = 1;
16778 return add_stmt (ret);
16779 }
16780 }
16781 if (!flag_openmp) /* flag_openmp_simd */
16782 {
16783 c_parser_skip_to_pragma_eol (parser, false);
16784 return NULL_TREE;
16785 }
16786
16787 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
16788 if (cclauses)
16789 {
16790 omp_split_clauses (loc, OMP_TEAMS, mask, clauses, cclauses);
16791 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
16792 }
16793
16794 tree stmt = make_node (OMP_TEAMS);
16795 TREE_TYPE (stmt) = void_type_node;
16796 OMP_TEAMS_CLAUSES (stmt) = clauses;
16797 OMP_TEAMS_BODY (stmt) = c_parser_omp_structured_block (parser, if_p);
16798
16799 return add_stmt (stmt);
16800 }
16801
16802 /* OpenMP 4.0:
16803 # pragma omp target data target-data-clause[optseq] new-line
16804 structured-block */
16805
16806 #define OMP_TARGET_DATA_CLAUSE_MASK \
16807 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
16808 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
16809 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
16810 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR))
16811
16812 static tree
c_parser_omp_target_data(location_t loc,c_parser * parser,bool * if_p)16813 c_parser_omp_target_data (location_t loc, c_parser *parser, bool *if_p)
16814 {
16815 tree clauses
16816 = c_parser_omp_all_clauses (parser, OMP_TARGET_DATA_CLAUSE_MASK,
16817 "#pragma omp target data");
16818 int map_seen = 0;
16819 for (tree *pc = &clauses; *pc;)
16820 {
16821 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
16822 switch (OMP_CLAUSE_MAP_KIND (*pc))
16823 {
16824 case GOMP_MAP_TO:
16825 case GOMP_MAP_ALWAYS_TO:
16826 case GOMP_MAP_FROM:
16827 case GOMP_MAP_ALWAYS_FROM:
16828 case GOMP_MAP_TOFROM:
16829 case GOMP_MAP_ALWAYS_TOFROM:
16830 case GOMP_MAP_ALLOC:
16831 map_seen = 3;
16832 break;
16833 case GOMP_MAP_FIRSTPRIVATE_POINTER:
16834 case GOMP_MAP_ALWAYS_POINTER:
16835 break;
16836 default:
16837 map_seen |= 1;
16838 error_at (OMP_CLAUSE_LOCATION (*pc),
16839 "%<#pragma omp target data%> with map-type other "
16840 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
16841 "on %<map%> clause");
16842 *pc = OMP_CLAUSE_CHAIN (*pc);
16843 continue;
16844 }
16845 pc = &OMP_CLAUSE_CHAIN (*pc);
16846 }
16847
16848 if (map_seen != 3)
16849 {
16850 if (map_seen == 0)
16851 error_at (loc,
16852 "%<#pragma omp target data%> must contain at least "
16853 "one %<map%> clause");
16854 return NULL_TREE;
16855 }
16856
16857 tree stmt = make_node (OMP_TARGET_DATA);
16858 TREE_TYPE (stmt) = void_type_node;
16859 OMP_TARGET_DATA_CLAUSES (stmt) = clauses;
16860 keep_next_level ();
16861 tree block = c_begin_compound_stmt (true);
16862 add_stmt (c_parser_omp_structured_block (parser, if_p));
16863 OMP_TARGET_DATA_BODY (stmt) = c_end_compound_stmt (loc, block, true);
16864
16865 SET_EXPR_LOCATION (stmt, loc);
16866 return add_stmt (stmt);
16867 }
16868
16869 /* OpenMP 4.0:
16870 # pragma omp target update target-update-clause[optseq] new-line */
16871
16872 #define OMP_TARGET_UPDATE_CLAUSE_MASK \
16873 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FROM) \
16874 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
16875 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
16876 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
16877 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
16878 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
16879
16880 static bool
c_parser_omp_target_update(location_t loc,c_parser * parser,enum pragma_context context)16881 c_parser_omp_target_update (location_t loc, c_parser *parser,
16882 enum pragma_context context)
16883 {
16884 if (context == pragma_stmt)
16885 {
16886 error_at (loc, "%<#pragma %s%> may only be used in compound statements",
16887 "omp target update");
16888 c_parser_skip_to_pragma_eol (parser, false);
16889 return false;
16890 }
16891
16892 tree clauses
16893 = c_parser_omp_all_clauses (parser, OMP_TARGET_UPDATE_CLAUSE_MASK,
16894 "#pragma omp target update");
16895 if (omp_find_clause (clauses, OMP_CLAUSE_TO) == NULL_TREE
16896 && omp_find_clause (clauses, OMP_CLAUSE_FROM) == NULL_TREE)
16897 {
16898 error_at (loc,
16899 "%<#pragma omp target update%> must contain at least one "
16900 "%<from%> or %<to%> clauses");
16901 return false;
16902 }
16903
16904 tree stmt = make_node (OMP_TARGET_UPDATE);
16905 TREE_TYPE (stmt) = void_type_node;
16906 OMP_TARGET_UPDATE_CLAUSES (stmt) = clauses;
16907 SET_EXPR_LOCATION (stmt, loc);
16908 add_stmt (stmt);
16909 return false;
16910 }
16911
16912 /* OpenMP 4.5:
16913 # pragma omp target enter data target-data-clause[optseq] new-line */
16914
16915 #define OMP_TARGET_ENTER_DATA_CLAUSE_MASK \
16916 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
16917 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
16918 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
16919 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
16920 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
16921
16922 static tree
c_parser_omp_target_enter_data(location_t loc,c_parser * parser,enum pragma_context context)16923 c_parser_omp_target_enter_data (location_t loc, c_parser *parser,
16924 enum pragma_context context)
16925 {
16926 bool data_seen = false;
16927 if (c_parser_next_token_is (parser, CPP_NAME))
16928 {
16929 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16930 if (strcmp (p, "data") == 0)
16931 {
16932 c_parser_consume_token (parser);
16933 data_seen = true;
16934 }
16935 }
16936 if (!data_seen)
16937 {
16938 c_parser_error (parser, "expected %<data%>");
16939 c_parser_skip_to_pragma_eol (parser);
16940 return NULL_TREE;
16941 }
16942
16943 if (context == pragma_stmt)
16944 {
16945 error_at (loc, "%<#pragma %s%> may only be used in compound statements",
16946 "omp target enter data");
16947 c_parser_skip_to_pragma_eol (parser, false);
16948 return NULL_TREE;
16949 }
16950
16951 tree clauses
16952 = c_parser_omp_all_clauses (parser, OMP_TARGET_ENTER_DATA_CLAUSE_MASK,
16953 "#pragma omp target enter data");
16954 int map_seen = 0;
16955 for (tree *pc = &clauses; *pc;)
16956 {
16957 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
16958 switch (OMP_CLAUSE_MAP_KIND (*pc))
16959 {
16960 case GOMP_MAP_TO:
16961 case GOMP_MAP_ALWAYS_TO:
16962 case GOMP_MAP_ALLOC:
16963 map_seen = 3;
16964 break;
16965 case GOMP_MAP_FIRSTPRIVATE_POINTER:
16966 case GOMP_MAP_ALWAYS_POINTER:
16967 break;
16968 default:
16969 map_seen |= 1;
16970 error_at (OMP_CLAUSE_LOCATION (*pc),
16971 "%<#pragma omp target enter data%> with map-type other "
16972 "than %<to%> or %<alloc%> on %<map%> clause");
16973 *pc = OMP_CLAUSE_CHAIN (*pc);
16974 continue;
16975 }
16976 pc = &OMP_CLAUSE_CHAIN (*pc);
16977 }
16978
16979 if (map_seen != 3)
16980 {
16981 if (map_seen == 0)
16982 error_at (loc,
16983 "%<#pragma omp target enter data%> must contain at least "
16984 "one %<map%> clause");
16985 return NULL_TREE;
16986 }
16987
16988 tree stmt = make_node (OMP_TARGET_ENTER_DATA);
16989 TREE_TYPE (stmt) = void_type_node;
16990 OMP_TARGET_ENTER_DATA_CLAUSES (stmt) = clauses;
16991 SET_EXPR_LOCATION (stmt, loc);
16992 add_stmt (stmt);
16993 return stmt;
16994 }
16995
16996 /* OpenMP 4.5:
16997 # pragma omp target exit data target-data-clause[optseq] new-line */
16998
16999 #define OMP_TARGET_EXIT_DATA_CLAUSE_MASK \
17000 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
17001 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
17002 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
17003 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
17004 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
17005
17006 static tree
c_parser_omp_target_exit_data(location_t loc,c_parser * parser,enum pragma_context context)17007 c_parser_omp_target_exit_data (location_t loc, c_parser *parser,
17008 enum pragma_context context)
17009 {
17010 bool data_seen = false;
17011 if (c_parser_next_token_is (parser, CPP_NAME))
17012 {
17013 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17014 if (strcmp (p, "data") == 0)
17015 {
17016 c_parser_consume_token (parser);
17017 data_seen = true;
17018 }
17019 }
17020 if (!data_seen)
17021 {
17022 c_parser_error (parser, "expected %<data%>");
17023 c_parser_skip_to_pragma_eol (parser);
17024 return NULL_TREE;
17025 }
17026
17027 if (context == pragma_stmt)
17028 {
17029 error_at (loc, "%<#pragma %s%> may only be used in compound statements",
17030 "omp target exit data");
17031 c_parser_skip_to_pragma_eol (parser, false);
17032 return NULL_TREE;
17033 }
17034
17035 tree clauses
17036 = c_parser_omp_all_clauses (parser, OMP_TARGET_EXIT_DATA_CLAUSE_MASK,
17037 "#pragma omp target exit data");
17038
17039 int map_seen = 0;
17040 for (tree *pc = &clauses; *pc;)
17041 {
17042 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
17043 switch (OMP_CLAUSE_MAP_KIND (*pc))
17044 {
17045 case GOMP_MAP_FROM:
17046 case GOMP_MAP_ALWAYS_FROM:
17047 case GOMP_MAP_RELEASE:
17048 case GOMP_MAP_DELETE:
17049 map_seen = 3;
17050 break;
17051 case GOMP_MAP_FIRSTPRIVATE_POINTER:
17052 case GOMP_MAP_ALWAYS_POINTER:
17053 break;
17054 default:
17055 map_seen |= 1;
17056 error_at (OMP_CLAUSE_LOCATION (*pc),
17057 "%<#pragma omp target exit data%> with map-type other "
17058 "than %<from%>, %<release%> or %<delete%> on %<map%>"
17059 " clause");
17060 *pc = OMP_CLAUSE_CHAIN (*pc);
17061 continue;
17062 }
17063 pc = &OMP_CLAUSE_CHAIN (*pc);
17064 }
17065
17066 if (map_seen != 3)
17067 {
17068 if (map_seen == 0)
17069 error_at (loc,
17070 "%<#pragma omp target exit data%> must contain at least one "
17071 "%<map%> clause");
17072 return NULL_TREE;
17073 }
17074
17075 tree stmt = make_node (OMP_TARGET_EXIT_DATA);
17076 TREE_TYPE (stmt) = void_type_node;
17077 OMP_TARGET_EXIT_DATA_CLAUSES (stmt) = clauses;
17078 SET_EXPR_LOCATION (stmt, loc);
17079 add_stmt (stmt);
17080 return stmt;
17081 }
17082
17083 /* OpenMP 4.0:
17084 # pragma omp target target-clause[optseq] new-line
17085 structured-block */
17086
17087 #define OMP_TARGET_CLAUSE_MASK \
17088 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
17089 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
17090 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
17091 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
17092 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
17093 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
17094 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
17095 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULTMAP) \
17096 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR))
17097
17098 static bool
c_parser_omp_target(c_parser * parser,enum pragma_context context,bool * if_p)17099 c_parser_omp_target (c_parser *parser, enum pragma_context context, bool *if_p)
17100 {
17101 location_t loc = c_parser_peek_token (parser)->location;
17102 c_parser_consume_pragma (parser);
17103 tree *pc = NULL, stmt, block;
17104
17105 if (context != pragma_stmt && context != pragma_compound)
17106 {
17107 c_parser_error (parser, "expected declaration specifiers");
17108 c_parser_skip_to_pragma_eol (parser);
17109 return false;
17110 }
17111
17112 if (c_parser_next_token_is (parser, CPP_NAME))
17113 {
17114 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17115 enum tree_code ccode = ERROR_MARK;
17116
17117 if (strcmp (p, "teams") == 0)
17118 ccode = OMP_TEAMS;
17119 else if (strcmp (p, "parallel") == 0)
17120 ccode = OMP_PARALLEL;
17121 else if (strcmp (p, "simd") == 0)
17122 ccode = OMP_SIMD;
17123 if (ccode != ERROR_MARK)
17124 {
17125 tree cclauses[C_OMP_CLAUSE_SPLIT_COUNT];
17126 char p_name[sizeof ("#pragma omp target teams distribute "
17127 "parallel for simd")];
17128
17129 c_parser_consume_token (parser);
17130 strcpy (p_name, "#pragma omp target");
17131 if (!flag_openmp) /* flag_openmp_simd */
17132 {
17133 tree stmt;
17134 switch (ccode)
17135 {
17136 case OMP_TEAMS:
17137 stmt = c_parser_omp_teams (loc, parser, p_name,
17138 OMP_TARGET_CLAUSE_MASK,
17139 cclauses, if_p);
17140 break;
17141 case OMP_PARALLEL:
17142 stmt = c_parser_omp_parallel (loc, parser, p_name,
17143 OMP_TARGET_CLAUSE_MASK,
17144 cclauses, if_p);
17145 break;
17146 case OMP_SIMD:
17147 stmt = c_parser_omp_simd (loc, parser, p_name,
17148 OMP_TARGET_CLAUSE_MASK,
17149 cclauses, if_p);
17150 break;
17151 default:
17152 gcc_unreachable ();
17153 }
17154 return stmt != NULL_TREE;
17155 }
17156 keep_next_level ();
17157 tree block = c_begin_compound_stmt (true), ret;
17158 switch (ccode)
17159 {
17160 case OMP_TEAMS:
17161 ret = c_parser_omp_teams (loc, parser, p_name,
17162 OMP_TARGET_CLAUSE_MASK, cclauses,
17163 if_p);
17164 break;
17165 case OMP_PARALLEL:
17166 ret = c_parser_omp_parallel (loc, parser, p_name,
17167 OMP_TARGET_CLAUSE_MASK, cclauses,
17168 if_p);
17169 break;
17170 case OMP_SIMD:
17171 ret = c_parser_omp_simd (loc, parser, p_name,
17172 OMP_TARGET_CLAUSE_MASK, cclauses,
17173 if_p);
17174 break;
17175 default:
17176 gcc_unreachable ();
17177 }
17178 block = c_end_compound_stmt (loc, block, true);
17179 if (ret == NULL_TREE)
17180 return false;
17181 if (ccode == OMP_TEAMS)
17182 {
17183 /* For combined target teams, ensure the num_teams and
17184 thread_limit clause expressions are evaluated on the host,
17185 before entering the target construct. */
17186 tree c;
17187 for (c = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
17188 c; c = OMP_CLAUSE_CHAIN (c))
17189 if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS
17190 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
17191 && TREE_CODE (OMP_CLAUSE_OPERAND (c, 0)) != INTEGER_CST)
17192 {
17193 tree expr = OMP_CLAUSE_OPERAND (c, 0);
17194 tree tmp = create_tmp_var_raw (TREE_TYPE (expr));
17195 expr = build4 (TARGET_EXPR, TREE_TYPE (expr), tmp,
17196 expr, NULL_TREE, NULL_TREE);
17197 add_stmt (expr);
17198 OMP_CLAUSE_OPERAND (c, 0) = expr;
17199 tree tc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
17200 OMP_CLAUSE_FIRSTPRIVATE);
17201 OMP_CLAUSE_DECL (tc) = tmp;
17202 OMP_CLAUSE_CHAIN (tc)
17203 = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
17204 cclauses[C_OMP_CLAUSE_SPLIT_TARGET] = tc;
17205 }
17206 }
17207 tree stmt = make_node (OMP_TARGET);
17208 TREE_TYPE (stmt) = void_type_node;
17209 OMP_TARGET_CLAUSES (stmt) = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
17210 OMP_TARGET_BODY (stmt) = block;
17211 OMP_TARGET_COMBINED (stmt) = 1;
17212 add_stmt (stmt);
17213 pc = &OMP_TARGET_CLAUSES (stmt);
17214 goto check_clauses;
17215 }
17216 else if (!flag_openmp) /* flag_openmp_simd */
17217 {
17218 c_parser_skip_to_pragma_eol (parser, false);
17219 return false;
17220 }
17221 else if (strcmp (p, "data") == 0)
17222 {
17223 c_parser_consume_token (parser);
17224 c_parser_omp_target_data (loc, parser, if_p);
17225 return true;
17226 }
17227 else if (strcmp (p, "enter") == 0)
17228 {
17229 c_parser_consume_token (parser);
17230 c_parser_omp_target_enter_data (loc, parser, context);
17231 return false;
17232 }
17233 else if (strcmp (p, "exit") == 0)
17234 {
17235 c_parser_consume_token (parser);
17236 c_parser_omp_target_exit_data (loc, parser, context);
17237 return false;
17238 }
17239 else if (strcmp (p, "update") == 0)
17240 {
17241 c_parser_consume_token (parser);
17242 return c_parser_omp_target_update (loc, parser, context);
17243 }
17244 }
17245 if (!flag_openmp) /* flag_openmp_simd */
17246 {
17247 c_parser_skip_to_pragma_eol (parser, false);
17248 return false;
17249 }
17250
17251 stmt = make_node (OMP_TARGET);
17252 TREE_TYPE (stmt) = void_type_node;
17253
17254 OMP_TARGET_CLAUSES (stmt)
17255 = c_parser_omp_all_clauses (parser, OMP_TARGET_CLAUSE_MASK,
17256 "#pragma omp target");
17257 pc = &OMP_TARGET_CLAUSES (stmt);
17258 keep_next_level ();
17259 block = c_begin_compound_stmt (true);
17260 add_stmt (c_parser_omp_structured_block (parser, if_p));
17261 OMP_TARGET_BODY (stmt) = c_end_compound_stmt (loc, block, true);
17262
17263 SET_EXPR_LOCATION (stmt, loc);
17264 add_stmt (stmt);
17265
17266 check_clauses:
17267 while (*pc)
17268 {
17269 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
17270 switch (OMP_CLAUSE_MAP_KIND (*pc))
17271 {
17272 case GOMP_MAP_TO:
17273 case GOMP_MAP_ALWAYS_TO:
17274 case GOMP_MAP_FROM:
17275 case GOMP_MAP_ALWAYS_FROM:
17276 case GOMP_MAP_TOFROM:
17277 case GOMP_MAP_ALWAYS_TOFROM:
17278 case GOMP_MAP_ALLOC:
17279 case GOMP_MAP_FIRSTPRIVATE_POINTER:
17280 case GOMP_MAP_ALWAYS_POINTER:
17281 break;
17282 default:
17283 error_at (OMP_CLAUSE_LOCATION (*pc),
17284 "%<#pragma omp target%> with map-type other "
17285 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
17286 "on %<map%> clause");
17287 *pc = OMP_CLAUSE_CHAIN (*pc);
17288 continue;
17289 }
17290 pc = &OMP_CLAUSE_CHAIN (*pc);
17291 }
17292 return true;
17293 }
17294
17295 /* OpenMP 4.0:
17296 # pragma omp declare simd declare-simd-clauses[optseq] new-line */
17297
17298 #define OMP_DECLARE_SIMD_CLAUSE_MASK \
17299 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
17300 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
17301 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
17302 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM) \
17303 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INBRANCH) \
17304 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOTINBRANCH))
17305
17306 static void
c_parser_omp_declare_simd(c_parser * parser,enum pragma_context context)17307 c_parser_omp_declare_simd (c_parser *parser, enum pragma_context context)
17308 {
17309 auto_vec<c_token> clauses;
17310 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
17311 {
17312 c_token *token = c_parser_peek_token (parser);
17313 if (token->type == CPP_EOF)
17314 {
17315 c_parser_skip_to_pragma_eol (parser);
17316 return;
17317 }
17318 clauses.safe_push (*token);
17319 c_parser_consume_token (parser);
17320 }
17321 clauses.safe_push (*c_parser_peek_token (parser));
17322 c_parser_skip_to_pragma_eol (parser);
17323
17324 while (c_parser_next_token_is (parser, CPP_PRAGMA))
17325 {
17326 if (c_parser_peek_token (parser)->pragma_kind
17327 != PRAGMA_OMP_DECLARE
17328 || c_parser_peek_2nd_token (parser)->type != CPP_NAME
17329 || strcmp (IDENTIFIER_POINTER
17330 (c_parser_peek_2nd_token (parser)->value),
17331 "simd") != 0)
17332 {
17333 c_parser_error (parser,
17334 "%<#pragma omp declare simd%> must be followed by "
17335 "function declaration or definition or another "
17336 "%<#pragma omp declare simd%>");
17337 return;
17338 }
17339 c_parser_consume_pragma (parser);
17340 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
17341 {
17342 c_token *token = c_parser_peek_token (parser);
17343 if (token->type == CPP_EOF)
17344 {
17345 c_parser_skip_to_pragma_eol (parser);
17346 return;
17347 }
17348 clauses.safe_push (*token);
17349 c_parser_consume_token (parser);
17350 }
17351 clauses.safe_push (*c_parser_peek_token (parser));
17352 c_parser_skip_to_pragma_eol (parser);
17353 }
17354
17355 /* Make sure nothing tries to read past the end of the tokens. */
17356 c_token eof_token;
17357 memset (&eof_token, 0, sizeof (eof_token));
17358 eof_token.type = CPP_EOF;
17359 clauses.safe_push (eof_token);
17360 clauses.safe_push (eof_token);
17361
17362 switch (context)
17363 {
17364 case pragma_external:
17365 if (c_parser_next_token_is (parser, CPP_KEYWORD)
17366 && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
17367 {
17368 int ext = disable_extension_diagnostics ();
17369 do
17370 c_parser_consume_token (parser);
17371 while (c_parser_next_token_is (parser, CPP_KEYWORD)
17372 && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
17373 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
17374 NULL, clauses);
17375 restore_extension_diagnostics (ext);
17376 }
17377 else
17378 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
17379 NULL, clauses);
17380 break;
17381 case pragma_struct:
17382 case pragma_param:
17383 case pragma_stmt:
17384 c_parser_error (parser, "%<#pragma omp declare simd%> must be followed by "
17385 "function declaration or definition");
17386 break;
17387 case pragma_compound:
17388 if (c_parser_next_token_is (parser, CPP_KEYWORD)
17389 && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
17390 {
17391 int ext = disable_extension_diagnostics ();
17392 do
17393 c_parser_consume_token (parser);
17394 while (c_parser_next_token_is (parser, CPP_KEYWORD)
17395 && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
17396 if (c_parser_next_tokens_start_declaration (parser))
17397 {
17398 c_parser_declaration_or_fndef (parser, true, true, true, true,
17399 true, NULL, clauses);
17400 restore_extension_diagnostics (ext);
17401 break;
17402 }
17403 restore_extension_diagnostics (ext);
17404 }
17405 else if (c_parser_next_tokens_start_declaration (parser))
17406 {
17407 c_parser_declaration_or_fndef (parser, true, true, true, true, true,
17408 NULL, clauses);
17409 break;
17410 }
17411 c_parser_error (parser, "%<#pragma omp declare simd%> must be followed by "
17412 "function declaration or definition");
17413 break;
17414 default:
17415 gcc_unreachable ();
17416 }
17417 }
17418
17419 /* Finalize #pragma omp declare simd clauses after FNDECL has been parsed,
17420 and put that into "omp declare simd" attribute. */
17421
17422 static void
c_finish_omp_declare_simd(c_parser * parser,tree fndecl,tree parms,vec<c_token> clauses)17423 c_finish_omp_declare_simd (c_parser *parser, tree fndecl, tree parms,
17424 vec<c_token> clauses)
17425 {
17426 /* Normally first token is CPP_NAME "simd". CPP_EOF there indicates
17427 error has been reported and CPP_PRAGMA that c_finish_omp_declare_simd
17428 has already processed the tokens. */
17429 if (clauses.exists () && clauses[0].type == CPP_EOF)
17430 return;
17431 if (fndecl == NULL_TREE || TREE_CODE (fndecl) != FUNCTION_DECL)
17432 {
17433 error ("%<#pragma omp declare simd%> not immediately followed by "
17434 "a function declaration or definition");
17435 clauses[0].type = CPP_EOF;
17436 return;
17437 }
17438 if (clauses.exists () && clauses[0].type != CPP_NAME)
17439 {
17440 error_at (DECL_SOURCE_LOCATION (fndecl),
17441 "%<#pragma omp declare simd%> not immediately followed by "
17442 "a single function declaration or definition");
17443 clauses[0].type = CPP_EOF;
17444 return;
17445 }
17446
17447 if (parms == NULL_TREE)
17448 parms = DECL_ARGUMENTS (fndecl);
17449
17450 unsigned int tokens_avail = parser->tokens_avail;
17451 gcc_assert (parser->tokens == &parser->tokens_buf[0]);
17452
17453
17454 parser->tokens = clauses.address ();
17455 parser->tokens_avail = clauses.length ();
17456
17457 /* c_parser_omp_declare_simd pushed 2 extra CPP_EOF tokens at the end. */
17458 while (parser->tokens_avail > 3)
17459 {
17460 c_token *token = c_parser_peek_token (parser);
17461 gcc_assert (token->type == CPP_NAME
17462 && strcmp (IDENTIFIER_POINTER (token->value), "simd") == 0);
17463 c_parser_consume_token (parser);
17464 parser->in_pragma = true;
17465
17466 tree c = NULL_TREE;
17467 c = c_parser_omp_all_clauses (parser, OMP_DECLARE_SIMD_CLAUSE_MASK,
17468 "#pragma omp declare simd");
17469 c = c_omp_declare_simd_clauses_to_numbers (parms, c);
17470 if (c != NULL_TREE)
17471 c = tree_cons (NULL_TREE, c, NULL_TREE);
17472 c = build_tree_list (get_identifier ("omp declare simd"), c);
17473 TREE_CHAIN (c) = DECL_ATTRIBUTES (fndecl);
17474 DECL_ATTRIBUTES (fndecl) = c;
17475 }
17476
17477 parser->tokens = &parser->tokens_buf[0];
17478 parser->tokens_avail = tokens_avail;
17479 if (clauses.exists ())
17480 clauses[0].type = CPP_PRAGMA;
17481 }
17482
17483
17484 /* OpenMP 4.0:
17485 # pragma omp declare target new-line
17486 declarations and definitions
17487 # pragma omp end declare target new-line
17488
17489 OpenMP 4.5:
17490 # pragma omp declare target ( extended-list ) new-line
17491
17492 # pragma omp declare target declare-target-clauses[seq] new-line */
17493
17494 #define OMP_DECLARE_TARGET_CLAUSE_MASK \
17495 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
17496 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK))
17497
17498 static void
c_parser_omp_declare_target(c_parser * parser)17499 c_parser_omp_declare_target (c_parser *parser)
17500 {
17501 location_t loc = c_parser_peek_token (parser)->location;
17502 tree clauses = NULL_TREE;
17503 if (c_parser_next_token_is (parser, CPP_NAME))
17504 clauses = c_parser_omp_all_clauses (parser, OMP_DECLARE_TARGET_CLAUSE_MASK,
17505 "#pragma omp declare target");
17506 else if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
17507 {
17508 clauses = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_TO_DECLARE,
17509 clauses);
17510 clauses = c_finish_omp_clauses (clauses, C_ORT_OMP);
17511 c_parser_skip_to_pragma_eol (parser);
17512 }
17513 else
17514 {
17515 c_parser_skip_to_pragma_eol (parser);
17516 current_omp_declare_target_attribute++;
17517 return;
17518 }
17519 if (current_omp_declare_target_attribute)
17520 error_at (loc, "%<#pragma omp declare target%> with clauses in between "
17521 "%<#pragma omp declare target%> without clauses and "
17522 "%<#pragma omp end declare target%>");
17523 for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
17524 {
17525 tree t = OMP_CLAUSE_DECL (c), id;
17526 tree at1 = lookup_attribute ("omp declare target", DECL_ATTRIBUTES (t));
17527 tree at2 = lookup_attribute ("omp declare target link",
17528 DECL_ATTRIBUTES (t));
17529 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINK)
17530 {
17531 id = get_identifier ("omp declare target link");
17532 std::swap (at1, at2);
17533 }
17534 else
17535 id = get_identifier ("omp declare target");
17536 if (at2)
17537 {
17538 error_at (OMP_CLAUSE_LOCATION (c),
17539 "%qD specified both in declare target %<link%> and %<to%>"
17540 " clauses", t);
17541 continue;
17542 }
17543 if (!at1)
17544 {
17545 DECL_ATTRIBUTES (t) = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
17546 if (TREE_CODE (t) != FUNCTION_DECL && !is_global_var (t))
17547 continue;
17548
17549 symtab_node *node = symtab_node::get (t);
17550 if (node != NULL)
17551 {
17552 node->offloadable = 1;
17553 if (ENABLE_OFFLOADING)
17554 {
17555 g->have_offload = true;
17556 if (is_a <varpool_node *> (node))
17557 vec_safe_push (offload_vars, t);
17558 }
17559 }
17560 }
17561 }
17562 }
17563
17564 static void
c_parser_omp_end_declare_target(c_parser * parser)17565 c_parser_omp_end_declare_target (c_parser *parser)
17566 {
17567 location_t loc = c_parser_peek_token (parser)->location;
17568 c_parser_consume_pragma (parser);
17569 if (c_parser_next_token_is (parser, CPP_NAME)
17570 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
17571 "declare") == 0)
17572 {
17573 c_parser_consume_token (parser);
17574 if (c_parser_next_token_is (parser, CPP_NAME)
17575 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
17576 "target") == 0)
17577 c_parser_consume_token (parser);
17578 else
17579 {
17580 c_parser_error (parser, "expected %<target%>");
17581 c_parser_skip_to_pragma_eol (parser);
17582 return;
17583 }
17584 }
17585 else
17586 {
17587 c_parser_error (parser, "expected %<declare%>");
17588 c_parser_skip_to_pragma_eol (parser);
17589 return;
17590 }
17591 c_parser_skip_to_pragma_eol (parser);
17592 if (!current_omp_declare_target_attribute)
17593 error_at (loc, "%<#pragma omp end declare target%> without corresponding "
17594 "%<#pragma omp declare target%>");
17595 else
17596 current_omp_declare_target_attribute--;
17597 }
17598
17599
17600 /* OpenMP 4.0
17601 #pragma omp declare reduction (reduction-id : typename-list : expression) \
17602 initializer-clause[opt] new-line
17603
17604 initializer-clause:
17605 initializer (omp_priv = initializer)
17606 initializer (function-name (argument-list)) */
17607
17608 static void
c_parser_omp_declare_reduction(c_parser * parser,enum pragma_context context)17609 c_parser_omp_declare_reduction (c_parser *parser, enum pragma_context context)
17610 {
17611 unsigned int tokens_avail = 0, i;
17612 vec<tree> types = vNULL;
17613 vec<c_token> clauses = vNULL;
17614 enum tree_code reduc_code = ERROR_MARK;
17615 tree reduc_id = NULL_TREE;
17616 tree type;
17617 location_t rloc = c_parser_peek_token (parser)->location;
17618
17619 if (context == pragma_struct || context == pragma_param)
17620 {
17621 error ("%<#pragma omp declare reduction%> not at file or block scope");
17622 goto fail;
17623 }
17624
17625 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
17626 goto fail;
17627
17628 switch (c_parser_peek_token (parser)->type)
17629 {
17630 case CPP_PLUS:
17631 reduc_code = PLUS_EXPR;
17632 break;
17633 case CPP_MULT:
17634 reduc_code = MULT_EXPR;
17635 break;
17636 case CPP_MINUS:
17637 reduc_code = MINUS_EXPR;
17638 break;
17639 case CPP_AND:
17640 reduc_code = BIT_AND_EXPR;
17641 break;
17642 case CPP_XOR:
17643 reduc_code = BIT_XOR_EXPR;
17644 break;
17645 case CPP_OR:
17646 reduc_code = BIT_IOR_EXPR;
17647 break;
17648 case CPP_AND_AND:
17649 reduc_code = TRUTH_ANDIF_EXPR;
17650 break;
17651 case CPP_OR_OR:
17652 reduc_code = TRUTH_ORIF_EXPR;
17653 break;
17654 case CPP_NAME:
17655 const char *p;
17656 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17657 if (strcmp (p, "min") == 0)
17658 {
17659 reduc_code = MIN_EXPR;
17660 break;
17661 }
17662 if (strcmp (p, "max") == 0)
17663 {
17664 reduc_code = MAX_EXPR;
17665 break;
17666 }
17667 reduc_id = c_parser_peek_token (parser)->value;
17668 break;
17669 default:
17670 c_parser_error (parser,
17671 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
17672 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
17673 goto fail;
17674 }
17675
17676 tree orig_reduc_id, reduc_decl;
17677 orig_reduc_id = reduc_id;
17678 reduc_id = c_omp_reduction_id (reduc_code, reduc_id);
17679 reduc_decl = c_omp_reduction_decl (reduc_id);
17680 c_parser_consume_token (parser);
17681
17682 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
17683 goto fail;
17684
17685 while (true)
17686 {
17687 location_t loc = c_parser_peek_token (parser)->location;
17688 struct c_type_name *ctype = c_parser_type_name (parser);
17689 if (ctype != NULL)
17690 {
17691 type = groktypename (ctype, NULL, NULL);
17692 if (type == error_mark_node)
17693 ;
17694 else if ((INTEGRAL_TYPE_P (type)
17695 || TREE_CODE (type) == REAL_TYPE
17696 || TREE_CODE (type) == COMPLEX_TYPE)
17697 && orig_reduc_id == NULL_TREE)
17698 error_at (loc, "predeclared arithmetic type in "
17699 "%<#pragma omp declare reduction%>");
17700 else if (TREE_CODE (type) == FUNCTION_TYPE
17701 || TREE_CODE (type) == ARRAY_TYPE)
17702 error_at (loc, "function or array type in "
17703 "%<#pragma omp declare reduction%>");
17704 else if (TYPE_ATOMIC (type))
17705 error_at (loc, "%<_Atomic%> qualified type in "
17706 "%<#pragma omp declare reduction%>");
17707 else if (TYPE_QUALS_NO_ADDR_SPACE (type))
17708 error_at (loc, "const, volatile or restrict qualified type in "
17709 "%<#pragma omp declare reduction%>");
17710 else
17711 {
17712 tree t;
17713 for (t = DECL_INITIAL (reduc_decl); t; t = TREE_CHAIN (t))
17714 if (comptypes (TREE_PURPOSE (t), type))
17715 {
17716 error_at (loc, "redeclaration of %qs "
17717 "%<#pragma omp declare reduction%> for "
17718 "type %qT",
17719 IDENTIFIER_POINTER (reduc_id)
17720 + sizeof ("omp declare reduction ") - 1,
17721 type);
17722 location_t ploc
17723 = DECL_SOURCE_LOCATION (TREE_VEC_ELT (TREE_VALUE (t),
17724 0));
17725 error_at (ploc, "previous %<#pragma omp declare "
17726 "reduction%>");
17727 break;
17728 }
17729 if (t == NULL_TREE)
17730 types.safe_push (type);
17731 }
17732 if (c_parser_next_token_is (parser, CPP_COMMA))
17733 c_parser_consume_token (parser);
17734 else
17735 break;
17736 }
17737 else
17738 break;
17739 }
17740
17741 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>")
17742 || types.is_empty ())
17743 {
17744 fail:
17745 clauses.release ();
17746 types.release ();
17747 while (true)
17748 {
17749 c_token *token = c_parser_peek_token (parser);
17750 if (token->type == CPP_EOF || token->type == CPP_PRAGMA_EOL)
17751 break;
17752 c_parser_consume_token (parser);
17753 }
17754 c_parser_skip_to_pragma_eol (parser);
17755 return;
17756 }
17757
17758 if (types.length () > 1)
17759 {
17760 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
17761 {
17762 c_token *token = c_parser_peek_token (parser);
17763 if (token->type == CPP_EOF)
17764 goto fail;
17765 clauses.safe_push (*token);
17766 c_parser_consume_token (parser);
17767 }
17768 clauses.safe_push (*c_parser_peek_token (parser));
17769 c_parser_skip_to_pragma_eol (parser);
17770
17771 /* Make sure nothing tries to read past the end of the tokens. */
17772 c_token eof_token;
17773 memset (&eof_token, 0, sizeof (eof_token));
17774 eof_token.type = CPP_EOF;
17775 clauses.safe_push (eof_token);
17776 clauses.safe_push (eof_token);
17777 }
17778
17779 int errs = errorcount;
17780 FOR_EACH_VEC_ELT (types, i, type)
17781 {
17782 tokens_avail = parser->tokens_avail;
17783 gcc_assert (parser->tokens == &parser->tokens_buf[0]);
17784 if (!clauses.is_empty ())
17785 {
17786 parser->tokens = clauses.address ();
17787 parser->tokens_avail = clauses.length ();
17788 parser->in_pragma = true;
17789 }
17790
17791 bool nested = current_function_decl != NULL_TREE;
17792 if (nested)
17793 c_push_function_context ();
17794 tree fndecl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
17795 reduc_id, default_function_type);
17796 current_function_decl = fndecl;
17797 allocate_struct_function (fndecl, true);
17798 push_scope ();
17799 tree stmt = push_stmt_list ();
17800 /* Intentionally BUILTINS_LOCATION, so that -Wshadow doesn't
17801 warn about these. */
17802 tree omp_out = build_decl (BUILTINS_LOCATION, VAR_DECL,
17803 get_identifier ("omp_out"), type);
17804 DECL_ARTIFICIAL (omp_out) = 1;
17805 DECL_CONTEXT (omp_out) = fndecl;
17806 pushdecl (omp_out);
17807 tree omp_in = build_decl (BUILTINS_LOCATION, VAR_DECL,
17808 get_identifier ("omp_in"), type);
17809 DECL_ARTIFICIAL (omp_in) = 1;
17810 DECL_CONTEXT (omp_in) = fndecl;
17811 pushdecl (omp_in);
17812 struct c_expr combiner = c_parser_expression (parser);
17813 struct c_expr initializer;
17814 tree omp_priv = NULL_TREE, omp_orig = NULL_TREE;
17815 bool bad = false;
17816 initializer.set_error ();
17817 if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
17818 bad = true;
17819 else if (c_parser_next_token_is (parser, CPP_NAME)
17820 && strcmp (IDENTIFIER_POINTER
17821 (c_parser_peek_token (parser)->value),
17822 "initializer") == 0)
17823 {
17824 c_parser_consume_token (parser);
17825 pop_scope ();
17826 push_scope ();
17827 omp_priv = build_decl (BUILTINS_LOCATION, VAR_DECL,
17828 get_identifier ("omp_priv"), type);
17829 DECL_ARTIFICIAL (omp_priv) = 1;
17830 DECL_INITIAL (omp_priv) = error_mark_node;
17831 DECL_CONTEXT (omp_priv) = fndecl;
17832 pushdecl (omp_priv);
17833 omp_orig = build_decl (BUILTINS_LOCATION, VAR_DECL,
17834 get_identifier ("omp_orig"), type);
17835 DECL_ARTIFICIAL (omp_orig) = 1;
17836 DECL_CONTEXT (omp_orig) = fndecl;
17837 pushdecl (omp_orig);
17838 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
17839 bad = true;
17840 else if (!c_parser_next_token_is (parser, CPP_NAME))
17841 {
17842 c_parser_error (parser, "expected %<omp_priv%> or "
17843 "function-name");
17844 bad = true;
17845 }
17846 else if (strcmp (IDENTIFIER_POINTER
17847 (c_parser_peek_token (parser)->value),
17848 "omp_priv") != 0)
17849 {
17850 if (c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN
17851 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
17852 {
17853 c_parser_error (parser, "expected function-name %<(%>");
17854 bad = true;
17855 }
17856 else
17857 initializer = c_parser_postfix_expression (parser);
17858 if (initializer.value
17859 && TREE_CODE (initializer.value) == CALL_EXPR)
17860 {
17861 int j;
17862 tree c = initializer.value;
17863 for (j = 0; j < call_expr_nargs (c); j++)
17864 {
17865 tree a = CALL_EXPR_ARG (c, j);
17866 STRIP_NOPS (a);
17867 if (TREE_CODE (a) == ADDR_EXPR
17868 && TREE_OPERAND (a, 0) == omp_priv)
17869 break;
17870 }
17871 if (j == call_expr_nargs (c))
17872 error ("one of the initializer call arguments should be "
17873 "%<&omp_priv%>");
17874 }
17875 }
17876 else
17877 {
17878 c_parser_consume_token (parser);
17879 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
17880 bad = true;
17881 else
17882 {
17883 tree st = push_stmt_list ();
17884 location_t loc = c_parser_peek_token (parser)->location;
17885 rich_location richloc (line_table, loc);
17886 start_init (omp_priv, NULL_TREE, 0, &richloc);
17887 struct c_expr init = c_parser_initializer (parser);
17888 finish_init ();
17889 finish_decl (omp_priv, loc, init.value,
17890 init.original_type, NULL_TREE);
17891 pop_stmt_list (st);
17892 }
17893 }
17894 if (!bad
17895 && !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
17896 bad = true;
17897 }
17898
17899 if (!bad)
17900 {
17901 c_parser_skip_to_pragma_eol (parser);
17902
17903 tree t = tree_cons (type, make_tree_vec (omp_priv ? 6 : 3),
17904 DECL_INITIAL (reduc_decl));
17905 DECL_INITIAL (reduc_decl) = t;
17906 DECL_SOURCE_LOCATION (omp_out) = rloc;
17907 TREE_VEC_ELT (TREE_VALUE (t), 0) = omp_out;
17908 TREE_VEC_ELT (TREE_VALUE (t), 1) = omp_in;
17909 TREE_VEC_ELT (TREE_VALUE (t), 2) = combiner.value;
17910 walk_tree (&combiner.value, c_check_omp_declare_reduction_r,
17911 &TREE_VEC_ELT (TREE_VALUE (t), 0), NULL);
17912 if (omp_priv)
17913 {
17914 DECL_SOURCE_LOCATION (omp_priv) = rloc;
17915 TREE_VEC_ELT (TREE_VALUE (t), 3) = omp_priv;
17916 TREE_VEC_ELT (TREE_VALUE (t), 4) = omp_orig;
17917 TREE_VEC_ELT (TREE_VALUE (t), 5) = initializer.value;
17918 walk_tree (&initializer.value, c_check_omp_declare_reduction_r,
17919 &TREE_VEC_ELT (TREE_VALUE (t), 3), NULL);
17920 walk_tree (&DECL_INITIAL (omp_priv),
17921 c_check_omp_declare_reduction_r,
17922 &TREE_VEC_ELT (TREE_VALUE (t), 3), NULL);
17923 }
17924 }
17925
17926 pop_stmt_list (stmt);
17927 pop_scope ();
17928 if (cfun->language != NULL)
17929 {
17930 ggc_free (cfun->language);
17931 cfun->language = NULL;
17932 }
17933 set_cfun (NULL);
17934 current_function_decl = NULL_TREE;
17935 if (nested)
17936 c_pop_function_context ();
17937
17938 if (!clauses.is_empty ())
17939 {
17940 parser->tokens = &parser->tokens_buf[0];
17941 parser->tokens_avail = tokens_avail;
17942 }
17943 if (bad)
17944 goto fail;
17945 if (errs != errorcount)
17946 break;
17947 }
17948
17949 clauses.release ();
17950 types.release ();
17951 }
17952
17953
17954 /* OpenMP 4.0
17955 #pragma omp declare simd declare-simd-clauses[optseq] new-line
17956 #pragma omp declare reduction (reduction-id : typename-list : expression) \
17957 initializer-clause[opt] new-line
17958 #pragma omp declare target new-line */
17959
17960 static void
c_parser_omp_declare(c_parser * parser,enum pragma_context context)17961 c_parser_omp_declare (c_parser *parser, enum pragma_context context)
17962 {
17963 c_parser_consume_pragma (parser);
17964 if (c_parser_next_token_is (parser, CPP_NAME))
17965 {
17966 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17967 if (strcmp (p, "simd") == 0)
17968 {
17969 /* c_parser_consume_token (parser); done in
17970 c_parser_omp_declare_simd. */
17971 c_parser_omp_declare_simd (parser, context);
17972 return;
17973 }
17974 if (strcmp (p, "reduction") == 0)
17975 {
17976 c_parser_consume_token (parser);
17977 c_parser_omp_declare_reduction (parser, context);
17978 return;
17979 }
17980 if (!flag_openmp) /* flag_openmp_simd */
17981 {
17982 c_parser_skip_to_pragma_eol (parser, false);
17983 return;
17984 }
17985 if (strcmp (p, "target") == 0)
17986 {
17987 c_parser_consume_token (parser);
17988 c_parser_omp_declare_target (parser);
17989 return;
17990 }
17991 }
17992
17993 c_parser_error (parser, "expected %<simd%> or %<reduction%> "
17994 "or %<target%>");
17995 c_parser_skip_to_pragma_eol (parser);
17996 }
17997
17998 /* OpenMP 4.5:
17999 #pragma omp taskloop taskloop-clause[optseq] new-line
18000 for-loop
18001
18002 #pragma omp taskloop simd taskloop-simd-clause[optseq] new-line
18003 for-loop */
18004
18005 #define OMP_TASKLOOP_CLAUSE_MASK \
18006 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
18007 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
18008 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
18009 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
18010 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
18011 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_GRAINSIZE) \
18012 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TASKS) \
18013 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
18014 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
18015 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
18016 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
18017 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
18018 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP) \
18019 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY))
18020
18021 static tree
c_parser_omp_taskloop(location_t loc,c_parser * parser,char * p_name,omp_clause_mask mask,tree * cclauses,bool * if_p)18022 c_parser_omp_taskloop (location_t loc, c_parser *parser,
18023 char *p_name, omp_clause_mask mask, tree *cclauses,
18024 bool *if_p)
18025 {
18026 tree clauses, block, ret;
18027
18028 strcat (p_name, " taskloop");
18029 mask |= OMP_TASKLOOP_CLAUSE_MASK;
18030
18031 if (c_parser_next_token_is (parser, CPP_NAME))
18032 {
18033 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18034
18035 if (strcmp (p, "simd") == 0)
18036 {
18037 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
18038 if (cclauses == NULL)
18039 cclauses = cclauses_buf;
18040 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION);
18041 c_parser_consume_token (parser);
18042 if (!flag_openmp) /* flag_openmp_simd */
18043 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
18044 if_p);
18045 block = c_begin_compound_stmt (true);
18046 ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses, if_p);
18047 block = c_end_compound_stmt (loc, block, true);
18048 if (ret == NULL)
18049 return ret;
18050 ret = make_node (OMP_TASKLOOP);
18051 TREE_TYPE (ret) = void_type_node;
18052 OMP_FOR_BODY (ret) = block;
18053 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
18054 SET_EXPR_LOCATION (ret, loc);
18055 add_stmt (ret);
18056 return ret;
18057 }
18058 }
18059 if (!flag_openmp) /* flag_openmp_simd */
18060 {
18061 c_parser_skip_to_pragma_eol (parser, false);
18062 return NULL_TREE;
18063 }
18064
18065 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
18066 if (cclauses)
18067 {
18068 omp_split_clauses (loc, OMP_TASKLOOP, mask, clauses, cclauses);
18069 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
18070 }
18071
18072 block = c_begin_compound_stmt (true);
18073 ret = c_parser_omp_for_loop (loc, parser, OMP_TASKLOOP, clauses, NULL, if_p);
18074 block = c_end_compound_stmt (loc, block, true);
18075 add_stmt (block);
18076
18077 return ret;
18078 }
18079
18080 /* Main entry point to parsing most OpenMP pragmas. */
18081
18082 static void
c_parser_omp_construct(c_parser * parser,bool * if_p)18083 c_parser_omp_construct (c_parser *parser, bool *if_p)
18084 {
18085 enum pragma_kind p_kind;
18086 location_t loc;
18087 tree stmt;
18088 char p_name[sizeof "#pragma omp teams distribute parallel for simd"];
18089 omp_clause_mask mask (0);
18090
18091 loc = c_parser_peek_token (parser)->location;
18092 p_kind = c_parser_peek_token (parser)->pragma_kind;
18093 c_parser_consume_pragma (parser);
18094
18095 switch (p_kind)
18096 {
18097 case PRAGMA_OACC_ATOMIC:
18098 c_parser_omp_atomic (loc, parser);
18099 return;
18100 case PRAGMA_OACC_CACHE:
18101 strcpy (p_name, "#pragma acc");
18102 stmt = c_parser_oacc_cache (loc, parser);
18103 break;
18104 case PRAGMA_OACC_DATA:
18105 stmt = c_parser_oacc_data (loc, parser, if_p);
18106 break;
18107 case PRAGMA_OACC_HOST_DATA:
18108 stmt = c_parser_oacc_host_data (loc, parser, if_p);
18109 break;
18110 case PRAGMA_OACC_KERNELS:
18111 case PRAGMA_OACC_PARALLEL:
18112 strcpy (p_name, "#pragma acc");
18113 stmt = c_parser_oacc_kernels_parallel (loc, parser, p_kind, p_name,
18114 if_p);
18115 break;
18116 case PRAGMA_OACC_LOOP:
18117 strcpy (p_name, "#pragma acc");
18118 stmt = c_parser_oacc_loop (loc, parser, p_name, mask, NULL, if_p);
18119 break;
18120 case PRAGMA_OACC_WAIT:
18121 strcpy (p_name, "#pragma wait");
18122 stmt = c_parser_oacc_wait (loc, parser, p_name);
18123 break;
18124 case PRAGMA_OMP_ATOMIC:
18125 c_parser_omp_atomic (loc, parser);
18126 return;
18127 case PRAGMA_OMP_CRITICAL:
18128 stmt = c_parser_omp_critical (loc, parser, if_p);
18129 break;
18130 case PRAGMA_OMP_DISTRIBUTE:
18131 strcpy (p_name, "#pragma omp");
18132 stmt = c_parser_omp_distribute (loc, parser, p_name, mask, NULL, if_p);
18133 break;
18134 case PRAGMA_OMP_FOR:
18135 strcpy (p_name, "#pragma omp");
18136 stmt = c_parser_omp_for (loc, parser, p_name, mask, NULL, if_p);
18137 break;
18138 case PRAGMA_OMP_MASTER:
18139 stmt = c_parser_omp_master (loc, parser, if_p);
18140 break;
18141 case PRAGMA_OMP_PARALLEL:
18142 strcpy (p_name, "#pragma omp");
18143 stmt = c_parser_omp_parallel (loc, parser, p_name, mask, NULL, if_p);
18144 break;
18145 case PRAGMA_OMP_SECTIONS:
18146 strcpy (p_name, "#pragma omp");
18147 stmt = c_parser_omp_sections (loc, parser, p_name, mask, NULL);
18148 break;
18149 case PRAGMA_OMP_SIMD:
18150 strcpy (p_name, "#pragma omp");
18151 stmt = c_parser_omp_simd (loc, parser, p_name, mask, NULL, if_p);
18152 break;
18153 case PRAGMA_OMP_SINGLE:
18154 stmt = c_parser_omp_single (loc, parser, if_p);
18155 break;
18156 case PRAGMA_OMP_TASK:
18157 stmt = c_parser_omp_task (loc, parser, if_p);
18158 break;
18159 case PRAGMA_OMP_TASKGROUP:
18160 stmt = c_parser_omp_taskgroup (parser, if_p);
18161 break;
18162 case PRAGMA_OMP_TASKLOOP:
18163 strcpy (p_name, "#pragma omp");
18164 stmt = c_parser_omp_taskloop (loc, parser, p_name, mask, NULL, if_p);
18165 break;
18166 case PRAGMA_OMP_TEAMS:
18167 strcpy (p_name, "#pragma omp");
18168 stmt = c_parser_omp_teams (loc, parser, p_name, mask, NULL, if_p);
18169 break;
18170 default:
18171 gcc_unreachable ();
18172 }
18173
18174 if (stmt)
18175 gcc_assert (EXPR_LOCATION (stmt) != UNKNOWN_LOCATION);
18176 }
18177
18178
18179 /* OpenMP 2.5:
18180 # pragma omp threadprivate (variable-list) */
18181
18182 static void
c_parser_omp_threadprivate(c_parser * parser)18183 c_parser_omp_threadprivate (c_parser *parser)
18184 {
18185 tree vars, t;
18186 location_t loc;
18187
18188 c_parser_consume_pragma (parser);
18189 loc = c_parser_peek_token (parser)->location;
18190 vars = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
18191
18192 /* Mark every variable in VARS to be assigned thread local storage. */
18193 for (t = vars; t; t = TREE_CHAIN (t))
18194 {
18195 tree v = TREE_PURPOSE (t);
18196
18197 /* FIXME diagnostics: Ideally we should keep individual
18198 locations for all the variables in the var list to make the
18199 following errors more precise. Perhaps
18200 c_parser_omp_var_list_parens() should construct a list of
18201 locations to go along with the var list. */
18202
18203 /* If V had already been marked threadprivate, it doesn't matter
18204 whether it had been used prior to this point. */
18205 if (!VAR_P (v))
18206 error_at (loc, "%qD is not a variable", v);
18207 else if (TREE_USED (v) && !C_DECL_THREADPRIVATE_P (v))
18208 error_at (loc, "%qE declared %<threadprivate%> after first use", v);
18209 else if (! is_global_var (v))
18210 error_at (loc, "automatic variable %qE cannot be %<threadprivate%>", v);
18211 else if (TREE_TYPE (v) == error_mark_node)
18212 ;
18213 else if (! COMPLETE_TYPE_P (TREE_TYPE (v)))
18214 error_at (loc, "%<threadprivate%> %qE has incomplete type", v);
18215 else
18216 {
18217 if (! DECL_THREAD_LOCAL_P (v))
18218 {
18219 set_decl_tls_model (v, decl_default_tls_model (v));
18220 /* If rtl has been already set for this var, call
18221 make_decl_rtl once again, so that encode_section_info
18222 has a chance to look at the new decl flags. */
18223 if (DECL_RTL_SET_P (v))
18224 make_decl_rtl (v);
18225 }
18226 C_DECL_THREADPRIVATE_P (v) = 1;
18227 }
18228 }
18229
18230 c_parser_skip_to_pragma_eol (parser);
18231 }
18232
18233 /* Parse a transaction attribute (GCC Extension).
18234
18235 transaction-attribute:
18236 attributes
18237 [ [ any-word ] ]
18238
18239 The transactional memory language description is written for C++,
18240 and uses the C++0x attribute syntax. For compatibility, allow the
18241 bracket style for transactions in C as well. */
18242
18243 static tree
c_parser_transaction_attributes(c_parser * parser)18244 c_parser_transaction_attributes (c_parser *parser)
18245 {
18246 tree attr_name, attr = NULL;
18247
18248 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
18249 return c_parser_attributes (parser);
18250
18251 if (!c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
18252 return NULL_TREE;
18253 c_parser_consume_token (parser);
18254 if (!c_parser_require (parser, CPP_OPEN_SQUARE, "expected %<[%>"))
18255 goto error1;
18256
18257 attr_name = c_parser_attribute_any_word (parser);
18258 if (attr_name)
18259 {
18260 c_parser_consume_token (parser);
18261 attr = build_tree_list (attr_name, NULL_TREE);
18262 }
18263 else
18264 c_parser_error (parser, "expected identifier");
18265
18266 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
18267 error1:
18268 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
18269 return attr;
18270 }
18271
18272 /* Parse a __transaction_atomic or __transaction_relaxed statement
18273 (GCC Extension).
18274
18275 transaction-statement:
18276 __transaction_atomic transaction-attribute[opt] compound-statement
18277 __transaction_relaxed compound-statement
18278
18279 Note that the only valid attribute is: "outer".
18280 */
18281
18282 static tree
c_parser_transaction(c_parser * parser,enum rid keyword)18283 c_parser_transaction (c_parser *parser, enum rid keyword)
18284 {
18285 unsigned int old_in = parser->in_transaction;
18286 unsigned int this_in = 1, new_in;
18287 location_t loc = c_parser_peek_token (parser)->location;
18288 tree stmt, attrs;
18289
18290 gcc_assert ((keyword == RID_TRANSACTION_ATOMIC
18291 || keyword == RID_TRANSACTION_RELAXED)
18292 && c_parser_next_token_is_keyword (parser, keyword));
18293 c_parser_consume_token (parser);
18294
18295 if (keyword == RID_TRANSACTION_RELAXED)
18296 this_in |= TM_STMT_ATTR_RELAXED;
18297 else
18298 {
18299 attrs = c_parser_transaction_attributes (parser);
18300 if (attrs)
18301 this_in |= parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER);
18302 }
18303
18304 /* Keep track if we're in the lexical scope of an outer transaction. */
18305 new_in = this_in | (old_in & TM_STMT_ATTR_OUTER);
18306
18307 parser->in_transaction = new_in;
18308 stmt = c_parser_compound_statement (parser);
18309 parser->in_transaction = old_in;
18310
18311 if (flag_tm)
18312 stmt = c_finish_transaction (loc, stmt, this_in);
18313 else
18314 error_at (loc, (keyword == RID_TRANSACTION_ATOMIC ?
18315 "%<__transaction_atomic%> without transactional memory support enabled"
18316 : "%<__transaction_relaxed %> "
18317 "without transactional memory support enabled"));
18318
18319 return stmt;
18320 }
18321
18322 /* Parse a __transaction_atomic or __transaction_relaxed expression
18323 (GCC Extension).
18324
18325 transaction-expression:
18326 __transaction_atomic ( expression )
18327 __transaction_relaxed ( expression )
18328 */
18329
18330 static struct c_expr
c_parser_transaction_expression(c_parser * parser,enum rid keyword)18331 c_parser_transaction_expression (c_parser *parser, enum rid keyword)
18332 {
18333 struct c_expr ret;
18334 unsigned int old_in = parser->in_transaction;
18335 unsigned int this_in = 1;
18336 location_t loc = c_parser_peek_token (parser)->location;
18337 tree attrs;
18338
18339 gcc_assert ((keyword == RID_TRANSACTION_ATOMIC
18340 || keyword == RID_TRANSACTION_RELAXED)
18341 && c_parser_next_token_is_keyword (parser, keyword));
18342 c_parser_consume_token (parser);
18343
18344 if (keyword == RID_TRANSACTION_RELAXED)
18345 this_in |= TM_STMT_ATTR_RELAXED;
18346 else
18347 {
18348 attrs = c_parser_transaction_attributes (parser);
18349 if (attrs)
18350 this_in |= parse_tm_stmt_attr (attrs, 0);
18351 }
18352
18353 parser->in_transaction = this_in;
18354 matching_parens parens;
18355 if (parens.require_open (parser))
18356 {
18357 tree expr = c_parser_expression (parser).value;
18358 ret.original_type = TREE_TYPE (expr);
18359 ret.value = build1 (TRANSACTION_EXPR, ret.original_type, expr);
18360 if (this_in & TM_STMT_ATTR_RELAXED)
18361 TRANSACTION_EXPR_RELAXED (ret.value) = 1;
18362 SET_EXPR_LOCATION (ret.value, loc);
18363 ret.original_code = TRANSACTION_EXPR;
18364 if (!parens.require_close (parser))
18365 {
18366 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
18367 goto error;
18368 }
18369 }
18370 else
18371 {
18372 error:
18373 ret.set_error ();
18374 ret.original_code = ERROR_MARK;
18375 ret.original_type = NULL;
18376 }
18377 parser->in_transaction = old_in;
18378
18379 if (!flag_tm)
18380 error_at (loc, (keyword == RID_TRANSACTION_ATOMIC ?
18381 "%<__transaction_atomic%> without transactional memory support enabled"
18382 : "%<__transaction_relaxed %> "
18383 "without transactional memory support enabled"));
18384
18385 set_c_expr_source_range (&ret, loc, loc);
18386
18387 return ret;
18388 }
18389
18390 /* Parse a __transaction_cancel statement (GCC Extension).
18391
18392 transaction-cancel-statement:
18393 __transaction_cancel transaction-attribute[opt] ;
18394
18395 Note that the only valid attribute is "outer".
18396 */
18397
18398 static tree
c_parser_transaction_cancel(c_parser * parser)18399 c_parser_transaction_cancel (c_parser *parser)
18400 {
18401 location_t loc = c_parser_peek_token (parser)->location;
18402 tree attrs;
18403 bool is_outer = false;
18404
18405 gcc_assert (c_parser_next_token_is_keyword (parser, RID_TRANSACTION_CANCEL));
18406 c_parser_consume_token (parser);
18407
18408 attrs = c_parser_transaction_attributes (parser);
18409 if (attrs)
18410 is_outer = (parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER) != 0);
18411
18412 if (!flag_tm)
18413 {
18414 error_at (loc, "%<__transaction_cancel%> without "
18415 "transactional memory support enabled");
18416 goto ret_error;
18417 }
18418 else if (parser->in_transaction & TM_STMT_ATTR_RELAXED)
18419 {
18420 error_at (loc, "%<__transaction_cancel%> within a "
18421 "%<__transaction_relaxed%>");
18422 goto ret_error;
18423 }
18424 else if (is_outer)
18425 {
18426 if ((parser->in_transaction & TM_STMT_ATTR_OUTER) == 0
18427 && !is_tm_may_cancel_outer (current_function_decl))
18428 {
18429 error_at (loc, "outer %<__transaction_cancel%> not "
18430 "within outer %<__transaction_atomic%>");
18431 error_at (loc, " or a %<transaction_may_cancel_outer%> function");
18432 goto ret_error;
18433 }
18434 }
18435 else if (parser->in_transaction == 0)
18436 {
18437 error_at (loc, "%<__transaction_cancel%> not within "
18438 "%<__transaction_atomic%>");
18439 goto ret_error;
18440 }
18441
18442 return add_stmt (build_tm_abort_call (loc, is_outer));
18443
18444 ret_error:
18445 return build1 (NOP_EXPR, void_type_node, error_mark_node);
18446 }
18447
18448 /* Parse a single source file. */
18449
18450 void
c_parse_file(void)18451 c_parse_file (void)
18452 {
18453 /* Use local storage to begin. If the first token is a pragma, parse it.
18454 If it is #pragma GCC pch_preprocess, then this will load a PCH file
18455 which will cause garbage collection. */
18456 c_parser tparser;
18457
18458 memset (&tparser, 0, sizeof tparser);
18459 tparser.tokens = &tparser.tokens_buf[0];
18460 the_parser = &tparser;
18461
18462 if (c_parser_peek_token (&tparser)->pragma_kind == PRAGMA_GCC_PCH_PREPROCESS)
18463 c_parser_pragma_pch_preprocess (&tparser);
18464
18465 the_parser = ggc_alloc<c_parser> ();
18466 *the_parser = tparser;
18467 if (tparser.tokens == &tparser.tokens_buf[0])
18468 the_parser->tokens = &the_parser->tokens_buf[0];
18469
18470 /* Initialize EH, if we've been told to do so. */
18471 if (flag_exceptions)
18472 using_eh_for_cleanups ();
18473
18474 c_parser_translation_unit (the_parser);
18475 the_parser = NULL;
18476 }
18477
18478 /* Parse the body of a function declaration marked with "__RTL".
18479
18480 The RTL parser works on the level of characters read from a
18481 FILE *, whereas c_parser works at the level of tokens.
18482 Square this circle by consuming all of the tokens up to and
18483 including the closing brace, recording the start/end of the RTL
18484 fragment, and reopening the file and re-reading the relevant
18485 lines within the RTL parser.
18486
18487 This requires the opening and closing braces of the C function
18488 to be on separate lines from the RTL they wrap.
18489
18490 Take ownership of START_WITH_PASS, if non-NULL. */
18491
18492 void
c_parser_parse_rtl_body(c_parser * parser,char * start_with_pass)18493 c_parser_parse_rtl_body (c_parser *parser, char *start_with_pass)
18494 {
18495 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
18496 {
18497 free (start_with_pass);
18498 return;
18499 }
18500
18501 location_t start_loc = c_parser_peek_token (parser)->location;
18502
18503 /* Consume all tokens, up to the closing brace, handling
18504 matching pairs of braces in the rtl dump. */
18505 int num_open_braces = 1;
18506 while (1)
18507 {
18508 switch (c_parser_peek_token (parser)->type)
18509 {
18510 case CPP_OPEN_BRACE:
18511 num_open_braces++;
18512 break;
18513 case CPP_CLOSE_BRACE:
18514 if (--num_open_braces == 0)
18515 goto found_closing_brace;
18516 break;
18517 case CPP_EOF:
18518 error_at (start_loc, "no closing brace");
18519 free (start_with_pass);
18520 return;
18521 default:
18522 break;
18523 }
18524 c_parser_consume_token (parser);
18525 }
18526
18527 found_closing_brace:
18528 /* At the closing brace; record its location. */
18529 location_t end_loc = c_parser_peek_token (parser)->location;
18530
18531 /* Consume the closing brace. */
18532 c_parser_consume_token (parser);
18533
18534 /* Invoke the RTL parser. */
18535 if (!read_rtl_function_body_from_file_range (start_loc, end_loc))
18536 {
18537 free (start_with_pass);
18538 return;
18539 }
18540
18541 /* If a pass name was provided for START_WITH_PASS, run the backend
18542 accordingly now, on the cfun created above, transferring
18543 ownership of START_WITH_PASS. */
18544 if (start_with_pass)
18545 run_rtl_passes (start_with_pass);
18546 }
18547
18548 #include "gt-c-c-parser.h"
18549