Branch data Line data Source code
1 : : /* Parser for C and Objective-C.
2 : : Copyright (C) 1987-2024 Free Software Foundation, Inc.
3 : :
4 : : Parser actions based on the old Bison parser; structure somewhat
5 : : influenced by and fragments based on the C++ parser.
6 : :
7 : : This file is part of GCC.
8 : :
9 : : GCC is free software; you can redistribute it and/or modify it under
10 : : the terms of the GNU General Public License as published by the Free
11 : : Software Foundation; either version 3, or (at your option) any later
12 : : version.
13 : :
14 : : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 : : WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 : : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 : : for more details.
18 : :
19 : : You should have received a copy of the GNU General Public License
20 : : along with GCC; see the file COPYING3. If not see
21 : : <http://www.gnu.org/licenses/>. */
22 : :
23 : : /* TODO:
24 : :
25 : : Make sure all relevant comments, and all relevant code from all
26 : : actions, brought over from old parser. Verify exact correspondence
27 : : of syntax accepted.
28 : :
29 : : Add testcases covering every input symbol in every state in old and
30 : : new parsers.
31 : :
32 : : Include full syntax for GNU C, including erroneous cases accepted
33 : : with error messages, in syntax productions in comments.
34 : :
35 : : Make more diagnostics in the front end generally take an explicit
36 : : location rather than implicitly using input_location. */
37 : :
38 : : #include "config.h"
39 : : #define INCLUDE_MEMORY
40 : : #include "system.h"
41 : : #include "coretypes.h"
42 : : #include "target.h"
43 : : #include "function.h"
44 : : #include "c-tree.h"
45 : : #include "timevar.h"
46 : : #include "stringpool.h"
47 : : #include "cgraph.h"
48 : : #include "attribs.h"
49 : : #include "stor-layout.h"
50 : : #include "varasm.h"
51 : : #include "trans-mem.h"
52 : : #include "c-family/c-pragma.h"
53 : : #include "c-lang.h"
54 : : #include "c-family/c-objc.h"
55 : : #include "plugin.h"
56 : : #include "omp-general.h"
57 : : #include "omp-offload.h"
58 : : #include "builtins.h"
59 : : #include "gomp-constants.h"
60 : : #include "c-family/c-indentation.h"
61 : : #include "gimple-expr.h"
62 : : #include "context.h"
63 : : #include "gcc-rich-location.h"
64 : : #include "c-parser.h"
65 : : #include "gimple-parser.h"
66 : : #include "read-rtl-function.h"
67 : : #include "run-rtl-passes.h"
68 : : #include "intl.h"
69 : : #include "c-family/name-hint.h"
70 : : #include "tree-iterator.h"
71 : : #include "tree-pretty-print.h"
72 : : #include "memmodel.h"
73 : : #include "c-family/known-headers.h"
74 : : #include "bitmap.h"
75 : : #include "analyzer/analyzer-language.h"
76 : : #include "toplev.h"
77 : :
78 : : /* We need to walk over decls with incomplete struct/union/enum types
79 : : after parsing the whole translation unit.
80 : : In finish_decl(), if the decl is static, has incomplete
81 : : struct/union/enum type, it is appended to incomplete_record_decls.
82 : : In c_parser_translation_unit(), we iterate over incomplete_record_decls
83 : : and report error if any of the decls are still incomplete. */
84 : :
85 : : vec<tree> incomplete_record_decls;
86 : :
87 : : void
88 : 182873127 : set_c_expr_source_range (c_expr *expr,
89 : : location_t start, location_t finish)
90 : : {
91 : 182873127 : expr->src_range.m_start = start;
92 : 182873127 : expr->src_range.m_finish = finish;
93 : 182873127 : if (expr->value)
94 : 182873013 : set_source_range (expr->value, start, finish);
95 : 182873127 : }
96 : :
97 : : void
98 : 207840414 : set_c_expr_source_range (c_expr *expr,
99 : : source_range src_range)
100 : : {
101 : 207840414 : expr->src_range = src_range;
102 : 207840414 : if (expr->value)
103 : 207840414 : set_source_range (expr->value, src_range);
104 : 207840414 : }
105 : :
106 : :
107 : : /* Initialization routine for this file. */
108 : :
109 : : void
110 : 104748 : c_parse_init (void)
111 : : {
112 : : /* The only initialization required is of the reserved word
113 : : identifiers. */
114 : 104748 : unsigned int i;
115 : 104748 : tree id;
116 : 104748 : int mask = 0;
117 : :
118 : : /* Make sure RID_MAX hasn't grown past the 8 bits used to hold the keyword in
119 : : the c_token structure. */
120 : 104748 : gcc_assert (RID_MAX <= 255);
121 : :
122 : 104748 : mask |= D_CXXONLY;
123 : 104748 : if (!flag_isoc99)
124 : 6128 : mask |= D_C99;
125 : 104748 : if (!flag_isoc23)
126 : 103958 : mask |= D_C23;
127 : 104748 : if (flag_no_asm)
128 : : {
129 : 4884 : mask |= D_ASM | D_EXT;
130 : 4884 : if (!flag_isoc99)
131 : 3180 : mask |= D_EXT89;
132 : 4884 : if (!flag_isoc23)
133 : 4253 : mask |= D_EXT11;
134 : : }
135 : 104748 : if (!c_dialect_objc ())
136 : 104748 : mask |= D_OBJC | D_CXX_OBJC;
137 : :
138 : 104748 : ridpointers = ggc_cleared_vec_alloc<tree> ((int) RID_MAX);
139 : 23149308 : for (i = 0; i < num_c_common_reswords; i++)
140 : : {
141 : : /* If a keyword is disabled, do not enter it into the table
142 : : and so create a canonical spelling that isn't a keyword. */
143 : 23044560 : if (c_common_reswords[i].disable & mask)
144 : : {
145 : 9871509 : if (warn_cxx_compat
146 : 101031 : && (c_common_reswords[i].disable & D_CXXWARN))
147 : : {
148 : 52608 : id = get_identifier (c_common_reswords[i].word);
149 : 52608 : C_SET_RID_CODE (id, RID_CXX_COMPAT_WARN);
150 : 52608 : C_IS_RESERVED_WORD (id) = 1;
151 : : }
152 : 9871509 : continue;
153 : : }
154 : :
155 : 13173051 : id = get_identifier (c_common_reswords[i].word);
156 : 13173051 : C_SET_RID_CODE (id, c_common_reswords[i].rid);
157 : 13173051 : C_IS_RESERVED_WORD (id) = 1;
158 : 13173051 : ridpointers [(int) c_common_reswords[i].rid] = id;
159 : : }
160 : :
161 : 209496 : for (i = 0; i < NUM_INT_N_ENTS; i++)
162 : : {
163 : : /* We always create the symbols but they aren't always supported. */
164 : 104748 : char name[50];
165 : 104748 : sprintf (name, "__int%d", int_n_data[i].bitsize);
166 : 104748 : id = get_identifier (name);
167 : 104748 : C_SET_RID_CODE (id, RID_FIRST_INT_N + i);
168 : 104748 : C_IS_RESERVED_WORD (id) = 1;
169 : :
170 : 104748 : sprintf (name, "__int%d__", int_n_data[i].bitsize);
171 : 104748 : id = get_identifier (name);
172 : 104748 : C_SET_RID_CODE (id, RID_FIRST_INT_N + i);
173 : 104748 : C_IS_RESERVED_WORD (id) = 1;
174 : : }
175 : :
176 : 104748 : if (flag_openmp)
177 : : {
178 : 1866 : id = get_identifier ("omp_all_memory");
179 : 1866 : C_SET_RID_CODE (id, RID_OMP_ALL_MEMORY);
180 : 1866 : C_IS_RESERVED_WORD (id) = 1;
181 : 1866 : ridpointers [RID_OMP_ALL_MEMORY] = id;
182 : : }
183 : 104748 : }
184 : :
185 : : /* A parser structure recording information about the state and
186 : : context of parsing. Includes lexer information with up to two
187 : : tokens of look-ahead; more are not needed for C. */
188 : : struct GTY(()) c_parser {
189 : : /* The look-ahead tokens. */
190 : : c_token * GTY((skip)) tokens;
191 : : /* Buffer for look-ahead tokens. */
192 : : c_token tokens_buf[4];
193 : : /* How many look-ahead tokens are available (0 - 4, or
194 : : more if parsing from pre-lexed tokens). */
195 : : unsigned int tokens_avail;
196 : : /* Raw look-ahead tokens, used only for checking in Objective-C
197 : : whether '[[' starts attributes. */
198 : : vec<c_token, va_gc> *raw_tokens;
199 : : /* The number of raw look-ahead tokens that have since been fully
200 : : lexed. */
201 : : unsigned int raw_tokens_used;
202 : : /* True if a syntax error is being recovered from; false otherwise.
203 : : c_parser_error sets this flag. It should clear this flag when
204 : : enough tokens have been consumed to recover from the error. */
205 : : BOOL_BITFIELD error : 1;
206 : : /* True if we're processing a pragma, and shouldn't automatically
207 : : consume CPP_PRAGMA_EOL. */
208 : : BOOL_BITFIELD in_pragma : 1;
209 : : /* True if we're parsing the outermost block of an if statement. */
210 : : BOOL_BITFIELD in_if_block : 1;
211 : : /* True if we want to lex a translated, joined string (for an
212 : : initial #pragma pch_preprocess). Otherwise the parser is
213 : : responsible for concatenating strings and translating to the
214 : : execution character set as needed. */
215 : : BOOL_BITFIELD lex_joined_string : 1;
216 : : /* True if, when the parser is concatenating string literals, it
217 : : should translate them to the execution character set (false
218 : : inside attributes). */
219 : : BOOL_BITFIELD translate_strings_p : 1;
220 : :
221 : : /* Objective-C specific parser/lexer information. */
222 : :
223 : : /* True if we are in a context where the Objective-C "PQ" keywords
224 : : are considered keywords. */
225 : : BOOL_BITFIELD objc_pq_context : 1;
226 : : /* True if we are parsing a (potential) Objective-C foreach
227 : : statement. This is set to true after we parsed 'for (' and while
228 : : we wait for 'in' or ';' to decide if it's a standard C for loop or an
229 : : Objective-C foreach loop. */
230 : : BOOL_BITFIELD objc_could_be_foreach_context : 1;
231 : : /* The following flag is needed to contextualize Objective-C lexical
232 : : analysis. In some cases (e.g., 'int NSObject;'), it is
233 : : undesirable to bind an identifier to an Objective-C class, even
234 : : if a class with that name exists. */
235 : : BOOL_BITFIELD objc_need_raw_identifier : 1;
236 : : /* Nonzero if we're processing a __transaction statement. The value
237 : : is 1 | TM_STMT_ATTR_*. */
238 : : unsigned int in_transaction : 4;
239 : : /* True if we are in a context where the Objective-C "Property attribute"
240 : : keywords are valid. */
241 : : BOOL_BITFIELD objc_property_attr_context : 1;
242 : :
243 : : /* Whether we have just seen/constructed a string-literal. Set when
244 : : returning a string-literal from c_parser_string_literal. Reset
245 : : in consume_token. Useful when we get a parse error and see an
246 : : unknown token, which could have been a string-literal constant
247 : : macro. */
248 : : BOOL_BITFIELD seen_string_literal : 1;
249 : :
250 : : /* TRUE if omp::directive, omp::decl or omp::sequence attributes may not
251 : : appear. */
252 : : BOOL_BITFIELD omp_attrs_forbidden_p : 1;
253 : :
254 : : /* Location of the last consumed token. */
255 : : location_t last_token_location;
256 : :
257 : : /* Holds state for parsing collapsed OMP_FOR loops. Managed by
258 : : c_parser_omp_for_loop. */
259 : : struct omp_for_parse_data * GTY((skip)) omp_for_parse_state;
260 : :
261 : : /* If we're in the context of OpenMP directives written as C23
262 : : attributes turned into pragma, vector of tokens created from that,
263 : : otherwise NULL. */
264 : : vec<c_token, va_gc> *in_omp_attribute_pragma;
265 : :
266 : : /* Set for omp::decl attribute parsing to the decl to which it
267 : : appertains. */
268 : : tree in_omp_decl_attribute;
269 : : };
270 : :
271 : : /* Return a pointer to the Nth token in PARSERs tokens_buf. */
272 : :
273 : : c_token *
274 : 195 : c_parser_tokens_buf (c_parser *parser, unsigned n)
275 : : {
276 : 195 : return &parser->tokens_buf[n];
277 : : }
278 : :
279 : : /* Return the error state of PARSER. */
280 : :
281 : : bool
282 : 3162 : c_parser_error (c_parser *parser)
283 : : {
284 : 3162 : return parser->error;
285 : : }
286 : :
287 : : /* Set the error state of PARSER to ERR. */
288 : :
289 : : void
290 : 0 : c_parser_set_error (c_parser *parser, bool err)
291 : : {
292 : 0 : parser->error = err;
293 : 0 : }
294 : :
295 : :
296 : : /* The actual parser and external interface. ??? Does this need to be
297 : : garbage-collected? */
298 : :
299 : : static GTY (()) c_parser *the_parser;
300 : :
301 : : /* Read in and lex a single token, storing it in *TOKEN. If RAW,
302 : : context-sensitive postprocessing of the token is not done. */
303 : :
304 : : static void
305 : 2042816265 : c_lex_one_token (c_parser *parser, c_token *token, bool raw = false)
306 : : {
307 : 2042816265 : timevar_push (TV_LEX);
308 : :
309 : 2042816265 : if (raw || vec_safe_length (parser->raw_tokens) == 0)
310 : : {
311 : 2042795664 : token->type = c_lex_with_flags (&token->value, &token->location,
312 : : &token->flags,
313 : 2042795664 : (parser->lex_joined_string
314 : : ? 0 : C_LEX_STRING_NO_JOIN));
315 : 2042795521 : token->id_kind = C_ID_NONE;
316 : 2042795521 : token->keyword = RID_MAX;
317 : 2042795521 : token->pragma_kind = PRAGMA_NONE;
318 : : }
319 : : else
320 : : {
321 : : /* Use a token previously lexed as a raw look-ahead token, and
322 : : complete the processing on it. */
323 : 20601 : *token = (*parser->raw_tokens)[parser->raw_tokens_used];
324 : 20601 : ++parser->raw_tokens_used;
325 : 20601 : if (parser->raw_tokens_used == vec_safe_length (parser->raw_tokens))
326 : : {
327 : 2197 : vec_free (parser->raw_tokens);
328 : 2197 : parser->raw_tokens_used = 0;
329 : : }
330 : : }
331 : :
332 : 2042816122 : if (raw)
333 : 20601 : goto out;
334 : :
335 : 2042795521 : switch (token->type)
336 : : {
337 : 915453999 : case CPP_NAME:
338 : 915453999 : {
339 : 915453999 : tree decl;
340 : :
341 : 915453999 : bool objc_force_identifier = parser->objc_need_raw_identifier;
342 : 915453999 : if (c_dialect_objc ())
343 : 0 : parser->objc_need_raw_identifier = false;
344 : :
345 : 915453999 : if (C_IS_RESERVED_WORD (token->value))
346 : : {
347 : 254831176 : enum rid rid_code = C_RID_CODE (token->value);
348 : :
349 : 254831176 : if (rid_code == RID_CXX_COMPAT_WARN)
350 : : {
351 : 35 : warning_at (token->location,
352 : : OPT_Wc___compat,
353 : : "identifier %qE conflicts with C++ keyword",
354 : : token->value);
355 : : }
356 : 254831141 : else if (rid_code >= RID_FIRST_ADDR_SPACE
357 : 254831141 : && rid_code <= RID_LAST_ADDR_SPACE)
358 : : {
359 : 164 : addr_space_t as;
360 : 164 : as = (addr_space_t) (rid_code - RID_FIRST_ADDR_SPACE);
361 : 164 : targetm.addr_space.diagnose_usage (as, token->location);
362 : 164 : token->id_kind = C_ID_ADDRSPACE;
363 : 164 : token->keyword = rid_code;
364 : 164 : break;
365 : : }
366 : 254830977 : else if (c_dialect_objc () && OBJC_IS_PQ_KEYWORD (rid_code))
367 : : {
368 : : /* We found an Objective-C "pq" keyword (in, out,
369 : : inout, bycopy, byref, oneway). They need special
370 : : care because the interpretation depends on the
371 : : context. */
372 : 0 : if (parser->objc_pq_context)
373 : : {
374 : 0 : token->type = CPP_KEYWORD;
375 : 0 : token->keyword = rid_code;
376 : 0 : break;
377 : : }
378 : 0 : else if (parser->objc_could_be_foreach_context
379 : 0 : && rid_code == RID_IN)
380 : : {
381 : : /* We are in Objective-C, inside a (potential)
382 : : foreach context (which means after having
383 : : parsed 'for (', but before having parsed ';'),
384 : : and we found 'in'. We consider it the keyword
385 : : which terminates the declaration at the
386 : : beginning of a foreach-statement. Note that
387 : : this means you can't use 'in' for anything else
388 : : in that context; in particular, in Objective-C
389 : : you can't use 'in' as the name of the running
390 : : variable in a C for loop. We could potentially
391 : : try to add code here to disambiguate, but it
392 : : seems a reasonable limitation. */
393 : 0 : token->type = CPP_KEYWORD;
394 : 0 : token->keyword = rid_code;
395 : 0 : break;
396 : : }
397 : : /* Else, "pq" keywords outside of the "pq" context are
398 : : not keywords, and we fall through to the code for
399 : : normal tokens. */
400 : : }
401 : 254830977 : else if (c_dialect_objc () && OBJC_IS_PATTR_KEYWORD (rid_code))
402 : : {
403 : : /* We found an Objective-C "property attribute"
404 : : keyword (getter, setter, readonly, etc). These are
405 : : only valid in the property context. */
406 : 0 : if (parser->objc_property_attr_context)
407 : : {
408 : 0 : token->type = CPP_KEYWORD;
409 : 0 : token->keyword = rid_code;
410 : 0 : break;
411 : : }
412 : : /* Else they are not special keywords.
413 : : */
414 : : }
415 : 254830977 : else if (c_dialect_objc ()
416 : 0 : && (OBJC_IS_AT_KEYWORD (rid_code)
417 : : || OBJC_IS_CXX_KEYWORD (rid_code)))
418 : : {
419 : : /* We found one of the Objective-C "@" keywords (defs,
420 : : selector, synchronized, etc) or one of the
421 : : Objective-C "cxx" keywords (class, private,
422 : : protected, public, try, catch, throw) without a
423 : : preceding '@' sign. Do nothing and fall through to
424 : : the code for normal tokens (in C++ we would still
425 : : consider the CXX ones keywords, but not in C). */
426 : : ;
427 : : }
428 : : else
429 : : {
430 : 254830977 : token->type = CPP_KEYWORD;
431 : 254830977 : token->keyword = rid_code;
432 : 254830977 : break;
433 : : }
434 : : }
435 : :
436 : 660622858 : decl = lookup_name (token->value);
437 : 660622858 : if (decl)
438 : : {
439 : 370211796 : if (TREE_CODE (decl) == TYPE_DECL)
440 : : {
441 : 213632802 : token->id_kind = C_ID_TYPENAME;
442 : 213632802 : break;
443 : : }
444 : : }
445 : 290411062 : else if (c_dialect_objc ())
446 : : {
447 : 0 : tree objc_interface_decl = objc_is_class_name (token->value);
448 : : /* Objective-C class names are in the same namespace as
449 : : variables and typedefs, and hence are shadowed by local
450 : : declarations. */
451 : 0 : if (objc_interface_decl
452 : 0 : && (!objc_force_identifier || global_bindings_p ()))
453 : : {
454 : 0 : token->value = objc_interface_decl;
455 : 0 : token->id_kind = C_ID_CLASSNAME;
456 : 0 : break;
457 : : }
458 : : }
459 : 446990056 : token->id_kind = C_ID_ID;
460 : : }
461 : 446990056 : break;
462 : 0 : case CPP_AT_NAME:
463 : : /* This only happens in Objective-C; it must be a keyword. */
464 : 0 : token->type = CPP_KEYWORD;
465 : 0 : switch (C_RID_CODE (token->value))
466 : : {
467 : : /* Replace 'class' with '@class', 'private' with '@private',
468 : : etc. This prevents confusion with the C++ keyword
469 : : 'class', and makes the tokens consistent with other
470 : : Objective-C 'AT' keywords. For example '@class' is
471 : : reported as RID_AT_CLASS which is consistent with
472 : : '@synchronized', which is reported as
473 : : RID_AT_SYNCHRONIZED.
474 : : */
475 : 0 : case RID_CLASS: token->keyword = RID_AT_CLASS; break;
476 : 0 : case RID_PRIVATE: token->keyword = RID_AT_PRIVATE; break;
477 : 0 : case RID_PROTECTED: token->keyword = RID_AT_PROTECTED; break;
478 : 0 : case RID_PUBLIC: token->keyword = RID_AT_PUBLIC; break;
479 : 0 : case RID_THROW: token->keyword = RID_AT_THROW; break;
480 : 0 : case RID_TRY: token->keyword = RID_AT_TRY; break;
481 : 0 : case RID_CATCH: token->keyword = RID_AT_CATCH; break;
482 : 0 : case RID_SYNCHRONIZED: token->keyword = RID_AT_SYNCHRONIZED; break;
483 : 0 : default: token->keyword = C_RID_CODE (token->value);
484 : : }
485 : : break;
486 : 614652728 : case CPP_COLON:
487 : 614652728 : case CPP_COMMA:
488 : 614652728 : case CPP_CLOSE_PAREN:
489 : 614652728 : case CPP_SEMICOLON:
490 : : /* These tokens may affect the interpretation of any identifiers
491 : : following, if doing Objective-C. */
492 : 614652728 : if (c_dialect_objc ())
493 : 0 : parser->objc_need_raw_identifier = false;
494 : : break;
495 : 1791148 : case CPP_PRAGMA:
496 : : /* We smuggled the cpp_token->u.pragma value in an INTEGER_CST. */
497 : 1791148 : token->pragma_kind = (enum pragma_kind) TREE_INT_CST_LOW (token->value);
498 : 1791148 : token->value = NULL;
499 : 1791148 : break;
500 : : default:
501 : : break;
502 : : }
503 : 2042816122 : out:
504 : 2042816122 : timevar_pop (TV_LEX);
505 : 2042816122 : }
506 : :
507 : : /* Return a pointer to the next token from PARSER, reading it in if
508 : : necessary. */
509 : :
510 : : c_token *
511 : 15456104840 : c_parser_peek_token (c_parser *parser)
512 : : {
513 : 15456104840 : if (parser->tokens_avail == 0)
514 : : {
515 : 1675717824 : c_lex_one_token (parser, &parser->tokens[0]);
516 : 1675717681 : parser->tokens_avail = 1;
517 : : }
518 : 15456104697 : return &parser->tokens[0];
519 : : }
520 : :
521 : : /* Return a pointer to the next-but-one token from PARSER, reading it
522 : : in if necessary. The next token is already read in. */
523 : :
524 : : c_token *
525 : 160420424 : c_parser_peek_2nd_token (c_parser *parser)
526 : : {
527 : 160420424 : if (parser->tokens_avail >= 2)
528 : 27707029 : return &parser->tokens[1];
529 : 132713395 : gcc_assert (parser->tokens_avail == 1);
530 : 132713395 : gcc_assert (parser->tokens[0].type != CPP_EOF);
531 : 132713395 : gcc_assert (parser->tokens[0].type != CPP_PRAGMA_EOL);
532 : 132713395 : c_lex_one_token (parser, &parser->tokens[1]);
533 : 132713395 : parser->tokens_avail = 2;
534 : 132713395 : return &parser->tokens[1];
535 : : }
536 : :
537 : : /* Return a pointer to the Nth token from PARSER, reading it
538 : : in if necessary. The N-1th token is already read in. */
539 : :
540 : : c_token *
541 : 785709977 : c_parser_peek_nth_token (c_parser *parser, unsigned int n)
542 : : {
543 : : /* N is 1-based, not zero-based. */
544 : 785709977 : gcc_assert (n > 0);
545 : :
546 : 785709977 : if (parser->tokens_avail >= n)
547 : 551345532 : return &parser->tokens[n - 1];
548 : 234364445 : gcc_assert (parser->tokens_avail == n - 1);
549 : 234364445 : c_lex_one_token (parser, &parser->tokens[n - 1]);
550 : 234364445 : parser->tokens_avail = n;
551 : 234364445 : return &parser->tokens[n - 1];
552 : : }
553 : :
554 : : /* Return a pointer to the Nth token from PARSER, reading it in as a
555 : : raw look-ahead token if necessary. The N-1th token is already read
556 : : in. Raw look-ahead tokens remain available for when the non-raw
557 : : functions above are called. */
558 : :
559 : : c_token *
560 : 26098 : c_parser_peek_nth_token_raw (c_parser *parser, unsigned int n)
561 : : {
562 : : /* N is 1-based, not zero-based. */
563 : 26098 : gcc_assert (n > 0);
564 : :
565 : 26098 : if (parser->tokens_avail >= n)
566 : 732 : return &parser->tokens[n - 1];
567 : 25366 : unsigned int raw_len = vec_safe_length (parser->raw_tokens);
568 : 25366 : unsigned int raw_avail
569 : 25366 : = parser->tokens_avail + raw_len - parser->raw_tokens_used;
570 : 25366 : gcc_assert (raw_avail >= n - 1);
571 : 25366 : if (raw_avail >= n)
572 : 4765 : return &(*parser->raw_tokens)[parser->raw_tokens_used
573 : 4765 : + n - 1 - parser->tokens_avail];
574 : 20601 : vec_safe_reserve (parser->raw_tokens, 1);
575 : 20601 : parser->raw_tokens->quick_grow (raw_len + 1);
576 : 20601 : c_lex_one_token (parser, &(*parser->raw_tokens)[raw_len], true);
577 : 20601 : return &(*parser->raw_tokens)[raw_len];
578 : : }
579 : :
580 : : bool
581 : 39211013 : c_keyword_starts_typename (enum rid keyword)
582 : : {
583 : 39211013 : switch (keyword)
584 : : {
585 : : case RID_UNSIGNED:
586 : : case RID_LONG:
587 : : case RID_SHORT:
588 : : case RID_SIGNED:
589 : : case RID_COMPLEX:
590 : : case RID_INT:
591 : : case RID_CHAR:
592 : : case RID_FLOAT:
593 : : case RID_DOUBLE:
594 : : case RID_VOID:
595 : : case RID_DFLOAT32:
596 : : case RID_DFLOAT64:
597 : : case RID_DFLOAT128:
598 : : CASE_RID_FLOATN_NX:
599 : : case RID_BOOL:
600 : : case RID_BITINT:
601 : : case RID_ENUM:
602 : : case RID_STRUCT:
603 : : case RID_UNION:
604 : : case RID_TYPEOF:
605 : : case RID_TYPEOF_UNQUAL:
606 : : case RID_CONST:
607 : : case RID_ATOMIC:
608 : : case RID_VOLATILE:
609 : : case RID_RESTRICT:
610 : : case RID_ATTRIBUTE:
611 : : case RID_FRACT:
612 : : case RID_ACCUM:
613 : : case RID_SAT:
614 : : case RID_AUTO_TYPE:
615 : : case RID_ALIGNAS:
616 : : return true;
617 : 32017760 : default:
618 : 32017760 : if (keyword >= RID_FIRST_INT_N
619 : : && keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS
620 : 487 : && int_n_enabled_p[keyword - RID_FIRST_INT_N])
621 : : return true;
622 : : return false;
623 : : }
624 : : }
625 : :
626 : : /* Return true if TOKEN can start a type name,
627 : : false otherwise. */
628 : : bool
629 : 390465907 : c_token_starts_typename (c_token *token)
630 : : {
631 : 390465907 : switch (token->type)
632 : : {
633 : 345647549 : case CPP_NAME:
634 : 345647549 : switch (token->id_kind)
635 : : {
636 : : case C_ID_ID:
637 : : return false;
638 : : case C_ID_ADDRSPACE:
639 : : return true;
640 : : case C_ID_TYPENAME:
641 : : return true;
642 : 0 : case C_ID_CLASSNAME:
643 : 0 : gcc_assert (c_dialect_objc ());
644 : : return true;
645 : 0 : default:
646 : 0 : gcc_unreachable ();
647 : : }
648 : 39163273 : case CPP_KEYWORD:
649 : 39163273 : return c_keyword_starts_typename (token->keyword);
650 : 0 : case CPP_LESS:
651 : 0 : if (c_dialect_objc ())
652 : : return true;
653 : : return false;
654 : : default:
655 : : return false;
656 : : }
657 : : }
658 : :
659 : : /* Return true if the next token from PARSER can start a type name,
660 : : false otherwise. LA specifies how to do lookahead in order to
661 : : detect unknown type names. If unsure, pick CLA_PREFER_ID. */
662 : :
663 : : static inline bool
664 : 278324289 : c_parser_next_tokens_start_typename (c_parser *parser, enum c_lookahead_kind la)
665 : : {
666 : 278324289 : c_token *token = c_parser_peek_token (parser);
667 : 278324289 : if (c_token_starts_typename (token))
668 : : return true;
669 : :
670 : : /* Try a bit harder to detect an unknown typename. */
671 : 61406648 : if (la != cla_prefer_id
672 : : && token->type == CPP_NAME
673 : 38252446 : && token->id_kind == C_ID_ID
674 : :
675 : : /* Do not try too hard when we could have "object in array". */
676 : 5409551 : && !parser->objc_could_be_foreach_context
677 : :
678 : 5409551 : && (la == cla_prefer_type
679 : 5409459 : || c_parser_peek_2nd_token (parser)->type == CPP_NAME
680 : 5409399 : || c_parser_peek_2nd_token (parser)->type == CPP_MULT)
681 : :
682 : : /* Only unknown identifiers. */
683 : 61407935 : && !lookup_name (token->value))
684 : : return true;
685 : :
686 : : return false;
687 : : }
688 : :
689 : : /* Return true if TOKEN, after an open parenthesis, can start a
690 : : compound literal (either a storage class specifier allowed in that
691 : : context, or a type name), false otherwise. */
692 : : static bool
693 : 112137973 : c_token_starts_compound_literal (c_token *token)
694 : : {
695 : 112137973 : switch (token->type)
696 : : {
697 : 4088168 : case CPP_KEYWORD:
698 : 4088168 : switch (token->keyword)
699 : : {
700 : : case RID_CONSTEXPR:
701 : : case RID_REGISTER:
702 : : case RID_STATIC:
703 : : case RID_THREAD:
704 : : return true;
705 : : default:
706 : : break;
707 : : }
708 : : /* Fall through. */
709 : 112137684 : default:
710 : 112137684 : return c_token_starts_typename (token);
711 : : }
712 : : }
713 : :
714 : : /* Return true if TOKEN is a type qualifier, false otherwise. */
715 : : static bool
716 : 381566486 : c_token_is_qualifier (c_token *token)
717 : : {
718 : 381566486 : switch (token->type)
719 : : {
720 : 378180133 : case CPP_NAME:
721 : 378180133 : switch (token->id_kind)
722 : : {
723 : : case C_ID_ADDRSPACE:
724 : : return true;
725 : : default:
726 : : return false;
727 : : }
728 : 3386353 : case CPP_KEYWORD:
729 : 3386353 : switch (token->keyword)
730 : : {
731 : : case RID_CONST:
732 : : case RID_VOLATILE:
733 : : case RID_RESTRICT:
734 : : case RID_ATTRIBUTE:
735 : : case RID_ATOMIC:
736 : : return true;
737 : : default:
738 : : return false;
739 : : }
740 : : case CPP_LESS:
741 : : return false;
742 : 0 : default:
743 : 0 : gcc_unreachable ();
744 : : }
745 : : }
746 : :
747 : : /* Return true if the next token from PARSER is a type qualifier,
748 : : false otherwise. */
749 : : static inline bool
750 : 381566486 : c_parser_next_token_is_qualifier (c_parser *parser)
751 : : {
752 : 381566486 : c_token *token = c_parser_peek_token (parser);
753 : 381566486 : return c_token_is_qualifier (token);
754 : : }
755 : :
756 : : /* Return true if TOKEN can start declaration specifiers (not
757 : : including standard attributes), false otherwise. */
758 : : static bool
759 : 154198000 : c_token_starts_declspecs (c_token *token)
760 : : {
761 : 154198000 : switch (token->type)
762 : : {
763 : 85764690 : case CPP_NAME:
764 : 85764690 : switch (token->id_kind)
765 : : {
766 : : case C_ID_ID:
767 : : return false;
768 : : case C_ID_ADDRSPACE:
769 : : return true;
770 : : case C_ID_TYPENAME:
771 : : return true;
772 : 0 : case C_ID_CLASSNAME:
773 : 0 : gcc_assert (c_dialect_objc ());
774 : : return true;
775 : 0 : default:
776 : 0 : gcc_unreachable ();
777 : : }
778 : 67194326 : case CPP_KEYWORD:
779 : 67194326 : switch (token->keyword)
780 : : {
781 : : case RID_STATIC:
782 : : case RID_EXTERN:
783 : : case RID_REGISTER:
784 : : case RID_TYPEDEF:
785 : : case RID_INLINE:
786 : : case RID_NORETURN:
787 : : case RID_AUTO:
788 : : case RID_THREAD:
789 : : case RID_UNSIGNED:
790 : : case RID_LONG:
791 : : case RID_SHORT:
792 : : case RID_SIGNED:
793 : : case RID_COMPLEX:
794 : : case RID_INT:
795 : : case RID_CHAR:
796 : : case RID_FLOAT:
797 : : case RID_DOUBLE:
798 : : case RID_VOID:
799 : : case RID_DFLOAT32:
800 : : case RID_DFLOAT64:
801 : : case RID_DFLOAT128:
802 : : CASE_RID_FLOATN_NX:
803 : : case RID_BOOL:
804 : : case RID_BITINT:
805 : : case RID_ENUM:
806 : : case RID_STRUCT:
807 : : case RID_UNION:
808 : : case RID_TYPEOF:
809 : : case RID_TYPEOF_UNQUAL:
810 : : case RID_CONST:
811 : : case RID_VOLATILE:
812 : : case RID_RESTRICT:
813 : : case RID_ATTRIBUTE:
814 : : case RID_FRACT:
815 : : case RID_ACCUM:
816 : : case RID_SAT:
817 : : case RID_ALIGNAS:
818 : : case RID_ATOMIC:
819 : : case RID_AUTO_TYPE:
820 : : case RID_CONSTEXPR:
821 : : return true;
822 : 31686938 : default:
823 : 31686938 : if (token->keyword >= RID_FIRST_INT_N
824 : : && token->keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS
825 : 392 : && int_n_enabled_p[token->keyword - RID_FIRST_INT_N])
826 : : return true;
827 : : return false;
828 : : }
829 : 2 : case CPP_LESS:
830 : 2 : if (c_dialect_objc ())
831 : : return true;
832 : : return false;
833 : : default:
834 : : return false;
835 : : }
836 : : }
837 : :
838 : :
839 : : /* Return true if TOKEN can start declaration specifiers (not
840 : : including standard attributes) or a static assertion, false
841 : : otherwise. */
842 : : static bool
843 : 44815376 : c_token_starts_declaration (c_token *token)
844 : : {
845 : 44815376 : if (c_token_starts_declspecs (token)
846 : 44815376 : || token->keyword == RID_STATIC_ASSERT)
847 : 7404991 : return true;
848 : : else
849 : : return false;
850 : : }
851 : :
852 : : /* Return true if the next token from PARSER can start declaration
853 : : specifiers (not including standard attributes), false
854 : : otherwise. */
855 : : bool
856 : 109382624 : c_parser_next_token_starts_declspecs (c_parser *parser)
857 : : {
858 : 109382624 : c_token *token = c_parser_peek_token (parser);
859 : :
860 : : /* In Objective-C, a classname normally starts a declspecs unless it
861 : : is immediately followed by a dot. In that case, it is the
862 : : Objective-C 2.0 "dot-syntax" for class objects, ie, calls the
863 : : setter/getter on the class. c_token_starts_declspecs() can't
864 : : differentiate between the two cases because it only checks the
865 : : current token, so we have a special check here. */
866 : 109382624 : if (c_dialect_objc ()
867 : : && token->type == CPP_NAME
868 : 0 : && token->id_kind == C_ID_CLASSNAME
869 : 109382624 : && c_parser_peek_2nd_token (parser)->type == CPP_DOT)
870 : : return false;
871 : :
872 : 109382624 : return c_token_starts_declspecs (token);
873 : : }
874 : :
875 : : /* Return true if the next tokens from PARSER can start declaration
876 : : specifiers (not including standard attributes) or a static
877 : : assertion, false otherwise. */
878 : : bool
879 : 44814614 : c_parser_next_tokens_start_declaration (c_parser *parser)
880 : : {
881 : 44814614 : c_token *token = c_parser_peek_token (parser);
882 : :
883 : : /* Same as above. */
884 : 44814614 : if (c_dialect_objc ()
885 : : && token->type == CPP_NAME
886 : 0 : && token->id_kind == C_ID_CLASSNAME
887 : 44814614 : && c_parser_peek_2nd_token (parser)->type == CPP_DOT)
888 : : return false;
889 : :
890 : : /* Labels do not start declarations. */
891 : 44814614 : if (token->type == CPP_NAME
892 : 44814614 : && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
893 : : return false;
894 : :
895 : 44814596 : if (c_token_starts_declaration (token))
896 : : return true;
897 : :
898 : 37409676 : if (c_parser_next_tokens_start_typename (parser, cla_nonabstract_decl))
899 : : return true;
900 : :
901 : : return false;
902 : : }
903 : :
904 : : /* Consume the next token from PARSER. */
905 : :
906 : : void
907 : 2040934620 : c_parser_consume_token (c_parser *parser)
908 : : {
909 : 2040934620 : gcc_assert (parser->tokens_avail >= 1);
910 : 2040934620 : gcc_assert (parser->tokens[0].type != CPP_EOF);
911 : 2040934620 : gcc_assert (!parser->in_pragma || parser->tokens[0].type != CPP_PRAGMA_EOL);
912 : 2040934620 : gcc_assert (parser->error || parser->tokens[0].type != CPP_PRAGMA);
913 : 2040934620 : parser->last_token_location = parser->tokens[0].location;
914 : 2040934620 : if (parser->tokens != &parser->tokens_buf[0])
915 : 30200 : parser->tokens++;
916 : 2040904420 : else if (parser->tokens_avail >= 2)
917 : : {
918 : 133775481 : parser->tokens[0] = parser->tokens[1];
919 : 133775481 : if (parser->tokens_avail >= 3)
920 : : {
921 : 488 : parser->tokens[1] = parser->tokens[2];
922 : 488 : if (parser->tokens_avail >= 4)
923 : 55 : parser->tokens[2] = parser->tokens[3];
924 : : }
925 : : }
926 : 2040934620 : parser->tokens_avail--;
927 : 2040934620 : parser->seen_string_literal = false;
928 : 2040934620 : }
929 : :
930 : : /* Expect the current token to be a #pragma. Consume it and remember
931 : : that we've begun parsing a pragma. */
932 : :
933 : : static void
934 : 1791529 : c_parser_consume_pragma (c_parser *parser)
935 : : {
936 : 1791529 : gcc_assert (!parser->in_pragma);
937 : 1791529 : gcc_assert (parser->tokens_avail >= 1);
938 : 1791529 : gcc_assert (parser->tokens[0].type == CPP_PRAGMA);
939 : 1791529 : if (parser->tokens != &parser->tokens_buf[0])
940 : 487 : parser->tokens++;
941 : 1791042 : else if (parser->tokens_avail >= 2)
942 : : {
943 : 103 : parser->tokens[0] = parser->tokens[1];
944 : 103 : if (parser->tokens_avail >= 3)
945 : 0 : parser->tokens[1] = parser->tokens[2];
946 : : }
947 : 1791529 : parser->tokens_avail--;
948 : 1791529 : parser->in_pragma = true;
949 : 1791529 : }
950 : :
951 : : /* Update the global input_location from TOKEN. */
952 : : static inline void
953 : 7578049 : c_parser_set_source_position_from_token (c_token *token)
954 : : {
955 : 7578049 : if (token->type != CPP_EOF)
956 : : {
957 : 7577996 : input_location = token->location;
958 : : }
959 : : }
960 : :
961 : : /* Helper function for c_parser_error.
962 : : Having peeked a token of kind TOK1_KIND that might signify
963 : : a conflict marker, peek successor tokens to determine
964 : : if we actually do have a conflict marker.
965 : : Specifically, we consider a run of 7 '<', '=' or '>' characters
966 : : at the start of a line as a conflict marker.
967 : : These come through the lexer as three pairs and a single,
968 : : e.g. three CPP_LSHIFT ("<<") and a CPP_LESS ('<').
969 : : If it returns true, *OUT_LOC is written to with the location/range
970 : : of the marker. */
971 : :
972 : : static bool
973 : 30 : c_parser_peek_conflict_marker (c_parser *parser, enum cpp_ttype tok1_kind,
974 : : location_t *out_loc)
975 : : {
976 : 30 : c_token *token2 = c_parser_peek_2nd_token (parser);
977 : 30 : if (token2->type != tok1_kind)
978 : : return false;
979 : 25 : c_token *token3 = c_parser_peek_nth_token (parser, 3);
980 : 25 : if (token3->type != tok1_kind)
981 : : return false;
982 : 22 : c_token *token4 = c_parser_peek_nth_token (parser, 4);
983 : 22 : if (token4->type != conflict_marker_get_final_tok_kind (tok1_kind))
984 : : return false;
985 : :
986 : : /* It must be at the start of the line. */
987 : 15 : location_t start_loc = c_parser_peek_token (parser)->location;
988 : 15 : if (LOCATION_COLUMN (start_loc) != 1)
989 : : return false;
990 : :
991 : : /* We have a conflict marker. Construct a location of the form:
992 : : <<<<<<<
993 : : ^~~~~~~
994 : : with start == caret, finishing at the end of the marker. */
995 : 12 : location_t finish_loc = get_finish (token4->location);
996 : 12 : *out_loc = make_location (start_loc, start_loc, finish_loc);
997 : :
998 : 12 : return true;
999 : : }
1000 : :
1001 : : /* Issue a diagnostic of the form
1002 : : FILE:LINE: MESSAGE before TOKEN
1003 : : where TOKEN is the next token in the input stream of PARSER.
1004 : : MESSAGE (specified by the caller) is usually of the form "expected
1005 : : OTHER-TOKEN".
1006 : :
1007 : : Use RICHLOC as the location of the diagnostic.
1008 : :
1009 : : Do not issue a diagnostic if still recovering from an error.
1010 : :
1011 : : Return true iff an error was actually emitted.
1012 : :
1013 : : ??? This is taken from the C++ parser, but building up messages in
1014 : : this way is not i18n-friendly and some other approach should be
1015 : : used. */
1016 : :
1017 : : static bool
1018 : 2667 : c_parser_error_richloc (c_parser *parser, const char *gmsgid,
1019 : : rich_location *richloc)
1020 : : {
1021 : 2667 : c_token *token = c_parser_peek_token (parser);
1022 : 2667 : if (parser->error)
1023 : : return false;
1024 : 2064 : parser->error = true;
1025 : 2064 : if (!gmsgid)
1026 : : return false;
1027 : :
1028 : : /* If this is actually a conflict marker, report it as such. */
1029 : 1953 : if (token->type == CPP_LSHIFT
1030 : 1953 : || token->type == CPP_RSHIFT
1031 : 1934 : || token->type == CPP_EQ_EQ)
1032 : : {
1033 : 30 : location_t loc;
1034 : 30 : if (c_parser_peek_conflict_marker (parser, token->type, &loc))
1035 : : {
1036 : 12 : error_at (loc, "version control conflict marker in file");
1037 : 12 : return true;
1038 : : }
1039 : : }
1040 : :
1041 : : /* If we were parsing a string-literal and there is an unknown name
1042 : : token right after, then check to see if that could also have been
1043 : : a literal string by checking the name against a list of known
1044 : : standard string literal constants defined in header files. If
1045 : : there is one, then add that as an hint to the error message. */
1046 : 1941 : auto_diagnostic_group d;
1047 : 1941 : name_hint h;
1048 : 1941 : if (parser->seen_string_literal && token->type == CPP_NAME)
1049 : : {
1050 : 16 : tree name = token->value;
1051 : 16 : const char *token_name = IDENTIFIER_POINTER (name);
1052 : 16 : const char *header_hint
1053 : 16 : = get_c_stdlib_header_for_string_macro_name (token_name);
1054 : 16 : if (header_hint != NULL)
1055 : 32 : h = name_hint (NULL, new suggest_missing_header (token->location,
1056 : : token_name,
1057 : 16 : header_hint));
1058 : : }
1059 : :
1060 : 1941 : c_parse_error (gmsgid,
1061 : : /* Because c_parse_error does not understand
1062 : : CPP_KEYWORD, keywords are treated like
1063 : : identifiers. */
1064 : 1941 : (token->type == CPP_KEYWORD ? CPP_NAME : token->type),
1065 : : /* ??? The C parser does not save the cpp flags of a
1066 : : token, we need to pass 0 here and we will not get
1067 : : the source spelling of some tokens but rather the
1068 : : canonical spelling. */
1069 : : token->value, /*flags=*/0, richloc);
1070 : 1941 : return true;
1071 : 1941 : }
1072 : :
1073 : : /* As c_parser_error_richloc, but issue the message at the
1074 : : location of PARSER's next token, or at input_location
1075 : : if the next token is EOF. */
1076 : :
1077 : : bool
1078 : 1650 : c_parser_error (c_parser *parser, const char *gmsgid)
1079 : : {
1080 : 1650 : c_token *token = c_parser_peek_token (parser);
1081 : 1650 : c_parser_set_source_position_from_token (token);
1082 : 1650 : rich_location richloc (line_table, input_location);
1083 : 1650 : return c_parser_error_richloc (parser, gmsgid, &richloc);
1084 : 1650 : }
1085 : :
1086 : : /* Some tokens naturally come in pairs e.g.'(' and ')'.
1087 : : This class is for tracking such a matching pair of symbols.
1088 : : In particular, it tracks the location of the first token,
1089 : : so that if the second token is missing, we can highlight the
1090 : : location of the first token when notifying the user about the
1091 : : problem. */
1092 : :
1093 : : template <typename traits_t>
1094 : : class token_pair
1095 : : {
1096 : : public:
1097 : : /* token_pair's ctor. */
1098 : 153749870 : token_pair () : m_open_loc (UNKNOWN_LOCATION) {}
1099 : :
1100 : : /* If the next token is the opening symbol for this pair, consume it and
1101 : : return true.
1102 : : Otherwise, issue an error and return false.
1103 : : In either case, record the location of the opening token. */
1104 : :
1105 : 4073391 : bool require_open (c_parser *parser)
1106 : : {
1107 : 4073391 : c_token *token = c_parser_peek_token (parser);
1108 : 4073391 : if (token)
1109 : 4073391 : m_open_loc = token->location;
1110 : :
1111 : 4073391 : return c_parser_require (parser, traits_t::open_token_type,
1112 : 4073391 : traits_t::open_gmsgid);
1113 : : }
1114 : :
1115 : : /* Consume the next token from PARSER, recording its location as
1116 : : that of the opening token within the pair. */
1117 : :
1118 : 149676838 : void consume_open (c_parser *parser)
1119 : : {
1120 : 149676838 : c_token *token = c_parser_peek_token (parser);
1121 : 149676838 : gcc_assert (token->type == traits_t::open_token_type);
1122 : 149676838 : m_open_loc = token->location;
1123 : 149676838 : c_parser_consume_token (parser);
1124 : 149676838 : }
1125 : :
1126 : : /* If the next token is the closing symbol for this pair, consume it
1127 : : and return true.
1128 : : Otherwise, issue an error, highlighting the location of the
1129 : : corresponding opening token, and return false. */
1130 : :
1131 : 1575053 : bool require_close (c_parser *parser) const
1132 : : {
1133 : 1575053 : return c_parser_require (parser, traits_t::close_token_type,
1134 : 1575053 : traits_t::close_gmsgid, m_open_loc);
1135 : : }
1136 : :
1137 : : /* Like token_pair::require_close, except that tokens will be skipped
1138 : : until the desired token is found. An error message is still produced
1139 : : if the next token is not as expected. */
1140 : :
1141 : 150839286 : void skip_until_found_close (c_parser *parser) const
1142 : : {
1143 : 150839286 : c_parser_skip_until_found (parser, traits_t::close_token_type,
1144 : 150839286 : traits_t::close_gmsgid, m_open_loc);
1145 : 310698 : }
1146 : :
1147 : : private:
1148 : : location_t m_open_loc;
1149 : : };
1150 : :
1151 : : /* Traits for token_pair<T> for tracking matching pairs of parentheses. */
1152 : :
1153 : : struct matching_paren_traits
1154 : : {
1155 : : static const enum cpp_ttype open_token_type = CPP_OPEN_PAREN;
1156 : : static const char * const open_gmsgid;
1157 : : static const enum cpp_ttype close_token_type = CPP_CLOSE_PAREN;
1158 : : static const char * const close_gmsgid;
1159 : : };
1160 : :
1161 : : const char * const matching_paren_traits::open_gmsgid = "expected %<(%>";
1162 : : const char * const matching_paren_traits::close_gmsgid = "expected %<)%>";
1163 : :
1164 : : /* "matching_parens" is a token_pair<T> class for tracking matching
1165 : : pairs of parentheses. */
1166 : :
1167 : : typedef token_pair<matching_paren_traits> matching_parens;
1168 : :
1169 : : /* Traits for token_pair<T> for tracking matching pairs of braces. */
1170 : :
1171 : : struct matching_brace_traits
1172 : : {
1173 : : static const enum cpp_ttype open_token_type = CPP_OPEN_BRACE;
1174 : : static const char * const open_gmsgid;
1175 : : static const enum cpp_ttype close_token_type = CPP_CLOSE_BRACE;
1176 : : static const char * const close_gmsgid;
1177 : : };
1178 : :
1179 : : const char * const matching_brace_traits::open_gmsgid = "expected %<{%>";
1180 : : const char * const matching_brace_traits::close_gmsgid = "expected %<}%>";
1181 : :
1182 : : /* "matching_braces" is a token_pair<T> class for tracking matching
1183 : : pairs of braces. */
1184 : :
1185 : : typedef token_pair<matching_brace_traits> matching_braces;
1186 : :
1187 : : /* Get a description of the matching symbol to TYPE e.g. "(" for
1188 : : CPP_CLOSE_PAREN. */
1189 : :
1190 : : static const char *
1191 : 4 : get_matching_symbol (enum cpp_ttype type)
1192 : : {
1193 : 4 : switch (type)
1194 : : {
1195 : 0 : default:
1196 : 0 : gcc_unreachable ();
1197 : : case CPP_CLOSE_PAREN:
1198 : : return "(";
1199 : 1 : case CPP_CLOSE_BRACE:
1200 : 1 : return "{";
1201 : : }
1202 : : }
1203 : :
1204 : : /* If the next token is of the indicated TYPE, consume it. Otherwise,
1205 : : issue the error MSGID. If MSGID is NULL then a message has already
1206 : : been produced and no message will be produced this time. Returns
1207 : : true if found, false otherwise.
1208 : :
1209 : : If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1210 : : within any error as the location of an "opening" token matching
1211 : : the close token TYPE (e.g. the location of the '(' when TYPE is
1212 : : CPP_CLOSE_PAREN).
1213 : :
1214 : : If TYPE_IS_UNIQUE is true (the default) then msgid describes exactly
1215 : : one type (e.g. "expected %<)%>") and thus it may be reasonable to
1216 : : attempt to generate a fix-it hint for the problem.
1217 : : Otherwise msgid describes multiple token types (e.g.
1218 : : "expected %<;%>, %<,%> or %<)%>"), and thus we shouldn't attempt to
1219 : : generate a fix-it hint. */
1220 : :
1221 : : bool
1222 : 397160192 : c_parser_require (c_parser *parser,
1223 : : enum cpp_ttype type,
1224 : : const char *msgid,
1225 : : location_t matching_location,
1226 : : bool type_is_unique)
1227 : : {
1228 : 397160192 : if (c_parser_next_token_is (parser, type))
1229 : : {
1230 : 397159175 : c_parser_consume_token (parser);
1231 : 397159175 : return true;
1232 : : }
1233 : : else
1234 : : {
1235 : 1017 : location_t next_token_loc = c_parser_peek_token (parser)->location;
1236 : 1017 : gcc_rich_location richloc (next_token_loc);
1237 : :
1238 : : /* Potentially supply a fix-it hint, suggesting to add the
1239 : : missing token immediately after the *previous* token.
1240 : : This may move the primary location within richloc. */
1241 : 1017 : if (!parser->error && type_is_unique)
1242 : 597 : maybe_suggest_missing_token_insertion (&richloc, type,
1243 : : parser->last_token_location);
1244 : :
1245 : : /* If matching_location != UNKNOWN_LOCATION, highlight it.
1246 : : Attempt to consolidate diagnostics by printing it as a
1247 : : secondary range within the main diagnostic. */
1248 : 1017 : bool added_matching_location = false;
1249 : 1017 : if (matching_location != UNKNOWN_LOCATION)
1250 : 347 : added_matching_location
1251 : 347 : = richloc.add_location_if_nearby (matching_location);
1252 : :
1253 : 1017 : if (c_parser_error_richloc (parser, msgid, &richloc))
1254 : : /* If we weren't able to consolidate matching_location, then
1255 : : print it as a secondary diagnostic. */
1256 : 494 : if (matching_location != UNKNOWN_LOCATION && !added_matching_location)
1257 : 4 : inform (matching_location, "to match this %qs",
1258 : : get_matching_symbol (type));
1259 : :
1260 : 1017 : return false;
1261 : 1017 : }
1262 : : }
1263 : :
1264 : : /* If the next token is the indicated keyword, consume it. Otherwise,
1265 : : issue the error MSGID. Returns true if found, false otherwise. */
1266 : :
1267 : : static bool
1268 : 135030 : c_parser_require_keyword (c_parser *parser,
1269 : : enum rid keyword,
1270 : : const char *msgid)
1271 : : {
1272 : 135030 : if (c_parser_next_token_is_keyword (parser, keyword))
1273 : : {
1274 : 135029 : c_parser_consume_token (parser);
1275 : 135029 : return true;
1276 : : }
1277 : : else
1278 : : {
1279 : 1 : c_parser_error (parser, msgid);
1280 : 1 : return false;
1281 : : }
1282 : : }
1283 : :
1284 : : /* Like c_parser_require, except that tokens will be skipped until the
1285 : : desired token is found. An error message is still produced if the
1286 : : next token is not as expected. If MSGID is NULL then a message has
1287 : : already been produced and no message will be produced this
1288 : : time.
1289 : :
1290 : : If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1291 : : within any error as the location of an "opening" token matching
1292 : : the close token TYPE (e.g. the location of the '(' when TYPE is
1293 : : CPP_CLOSE_PAREN). */
1294 : :
1295 : : void
1296 : 197555124 : c_parser_skip_until_found (c_parser *parser,
1297 : : enum cpp_ttype type,
1298 : : const char *msgid,
1299 : : location_t matching_location)
1300 : : {
1301 : 197555124 : unsigned nesting_depth = 0;
1302 : :
1303 : 197555124 : if (c_parser_require (parser, type, msgid, matching_location))
1304 : : {
1305 : 197554306 : if (UNLIKELY (type == CPP_PRAGMA_EOL) && parser->in_omp_attribute_pragma)
1306 : : {
1307 : 0 : c_token *token = c_parser_peek_token (parser);
1308 : 0 : if (token->type == CPP_EOF)
1309 : : {
1310 : 0 : parser->tokens = &parser->tokens_buf[0];
1311 : 0 : parser->tokens_avail = token->flags;
1312 : 0 : parser->in_omp_attribute_pragma = NULL;
1313 : : }
1314 : : }
1315 : 197554306 : return;
1316 : : }
1317 : :
1318 : : /* Skip tokens until the desired token is found. */
1319 : 5444 : while (true)
1320 : : {
1321 : : /* Peek at the next token. */
1322 : 3131 : c_token *token = c_parser_peek_token (parser);
1323 : : /* If we've reached the token we want, consume it and stop. */
1324 : 3131 : if (token->type == type && !nesting_depth)
1325 : : {
1326 : 618 : c_parser_consume_token (parser);
1327 : 618 : if (UNLIKELY (type == CPP_PRAGMA_EOL)
1328 : 104 : && parser->in_omp_attribute_pragma)
1329 : : {
1330 : 1 : c_token *token = c_parser_peek_token (parser);
1331 : 1 : if (token->type == CPP_EOF)
1332 : : {
1333 : 1 : parser->tokens = &parser->tokens_buf[0];
1334 : 1 : parser->tokens_avail = token->flags;
1335 : 1 : parser->in_omp_attribute_pragma = NULL;
1336 : : }
1337 : : }
1338 : : break;
1339 : : }
1340 : :
1341 : : /* If we've run out of tokens, stop. */
1342 : 2513 : if (token->type == CPP_EOF)
1343 : : return;
1344 : 2495 : if (token->type == CPP_PRAGMA_EOL && parser->in_pragma)
1345 : : return;
1346 : 2432 : if (token->type == CPP_OPEN_BRACE
1347 : : || token->type == CPP_OPEN_PAREN
1348 : : || token->type == CPP_OPEN_SQUARE)
1349 : 272 : ++nesting_depth;
1350 : : else if (token->type == CPP_CLOSE_BRACE
1351 : : || token->type == CPP_CLOSE_PAREN
1352 : : || token->type == CPP_CLOSE_SQUARE)
1353 : : {
1354 : 390 : if (nesting_depth-- == 0)
1355 : : break;
1356 : : }
1357 : : /* Consume this token. */
1358 : 2313 : c_parser_consume_token (parser);
1359 : 2313 : }
1360 : 737 : parser->error = false;
1361 : : }
1362 : :
1363 : : /* Skip tokens until the end of a parameter is found, but do not
1364 : : consume the comma, semicolon or closing delimiter. */
1365 : :
1366 : : static void
1367 : 99 : c_parser_skip_to_end_of_parameter (c_parser *parser)
1368 : : {
1369 : 99 : unsigned nesting_depth = 0;
1370 : :
1371 : 511 : while (true)
1372 : : {
1373 : 305 : c_token *token = c_parser_peek_token (parser);
1374 : 305 : if ((token->type == CPP_COMMA || token->type == CPP_SEMICOLON)
1375 : 26 : && !nesting_depth)
1376 : : break;
1377 : : /* If we've run out of tokens, stop. */
1378 : 279 : if (token->type == CPP_EOF)
1379 : : return;
1380 : 279 : if (token->type == CPP_PRAGMA_EOL && parser->in_pragma)
1381 : : return;
1382 : 279 : if (token->type == CPP_OPEN_BRACE
1383 : : || token->type == CPP_OPEN_PAREN
1384 : : || token->type == CPP_OPEN_SQUARE)
1385 : 3 : ++nesting_depth;
1386 : : else if (token->type == CPP_CLOSE_BRACE
1387 : : || token->type == CPP_CLOSE_PAREN
1388 : : || token->type == CPP_CLOSE_SQUARE)
1389 : : {
1390 : 76 : if (nesting_depth-- == 0)
1391 : : break;
1392 : : }
1393 : : /* Consume this token. */
1394 : 206 : c_parser_consume_token (parser);
1395 : 206 : }
1396 : 99 : parser->error = false;
1397 : : }
1398 : :
1399 : : /* Expect to be at the end of the pragma directive and consume an
1400 : : end of line marker. */
1401 : :
1402 : : static void
1403 : 1792247 : c_parser_skip_to_pragma_eol (c_parser *parser, bool error_if_not_eol = true)
1404 : : {
1405 : 1792247 : gcc_assert (parser->in_pragma);
1406 : 1792247 : parser->in_pragma = false;
1407 : :
1408 : 1792247 : if (error_if_not_eol && c_parser_peek_token (parser)->type != CPP_PRAGMA_EOL)
1409 : 138 : c_parser_error (parser, "expected end of line");
1410 : :
1411 : 1792972 : cpp_ttype token_type;
1412 : 1792972 : do
1413 : : {
1414 : 1792972 : c_token *token = c_parser_peek_token (parser);
1415 : 1792972 : token_type = token->type;
1416 : 1792972 : if (token_type == CPP_EOF)
1417 : : break;
1418 : 1792972 : c_parser_consume_token (parser);
1419 : : }
1420 : 1792972 : while (token_type != CPP_PRAGMA_EOL);
1421 : :
1422 : 1792247 : if (parser->in_omp_attribute_pragma)
1423 : : {
1424 : 487 : c_token *token = c_parser_peek_token (parser);
1425 : 487 : if (token->type == CPP_EOF)
1426 : : {
1427 : 444 : parser->tokens = &parser->tokens_buf[0];
1428 : 444 : parser->tokens_avail = token->flags;
1429 : 444 : parser->in_omp_attribute_pragma = NULL;
1430 : : }
1431 : : }
1432 : :
1433 : 1792247 : parser->error = false;
1434 : 1792247 : }
1435 : :
1436 : : /* Skip tokens until we have consumed an entire block, or until we
1437 : : have consumed a non-nested ';'. */
1438 : :
1439 : : static void
1440 : 458 : c_parser_skip_to_end_of_block_or_statement (c_parser *parser)
1441 : : {
1442 : 458 : unsigned nesting_depth = 0;
1443 : 458 : bool save_error = parser->error;
1444 : :
1445 : 1590 : while (true)
1446 : : {
1447 : 1590 : c_token *token;
1448 : :
1449 : : /* Peek at the next token. */
1450 : 1590 : token = c_parser_peek_token (parser);
1451 : :
1452 : 1590 : switch (token->type)
1453 : : {
1454 : : case CPP_EOF:
1455 : : return;
1456 : :
1457 : 0 : case CPP_PRAGMA_EOL:
1458 : 0 : if (parser->in_pragma)
1459 : : return;
1460 : : break;
1461 : :
1462 : 414 : case CPP_SEMICOLON:
1463 : : /* If the next token is a ';', we have reached the
1464 : : end of the statement. */
1465 : 414 : if (!nesting_depth)
1466 : : {
1467 : : /* Consume the ';'. */
1468 : 352 : c_parser_consume_token (parser);
1469 : 352 : goto finished;
1470 : : }
1471 : : break;
1472 : :
1473 : 89 : case CPP_CLOSE_BRACE:
1474 : : /* If the next token is a non-nested '}', then we have
1475 : : reached the end of the current block. */
1476 : 89 : if (nesting_depth == 0 || --nesting_depth == 0)
1477 : : {
1478 : 89 : c_parser_consume_token (parser);
1479 : 89 : goto finished;
1480 : : }
1481 : : break;
1482 : :
1483 : 62 : case CPP_OPEN_BRACE:
1484 : : /* If it the next token is a '{', then we are entering a new
1485 : : block. Consume the entire block. */
1486 : 62 : ++nesting_depth;
1487 : 62 : break;
1488 : :
1489 : 6 : case CPP_PRAGMA:
1490 : : /* If we see a pragma, consume the whole thing at once. We
1491 : : have some safeguards against consuming pragmas willy-nilly.
1492 : : Normally, we'd expect to be here with parser->error set,
1493 : : which disables these safeguards. But it's possible to get
1494 : : here for secondary error recovery, after parser->error has
1495 : : been cleared. */
1496 : 6 : c_parser_consume_pragma (parser);
1497 : 6 : c_parser_skip_to_pragma_eol (parser);
1498 : 6 : parser->error = save_error;
1499 : 6 : continue;
1500 : :
1501 : : default:
1502 : : break;
1503 : : }
1504 : :
1505 : 1126 : c_parser_consume_token (parser);
1506 : : }
1507 : :
1508 : 441 : finished:
1509 : 441 : parser->error = false;
1510 : : }
1511 : :
1512 : : /* CPP's options (initialized by c-opts.cc). */
1513 : : extern cpp_options *cpp_opts;
1514 : :
1515 : : /* Save the warning flags which are controlled by __extension__. */
1516 : :
1517 : : static inline int
1518 : 851363 : disable_extension_diagnostics (void)
1519 : : {
1520 : 1702726 : int ret = (pedantic
1521 : 851363 : | (warn_pointer_arith << 1)
1522 : 851363 : | (warn_traditional << 2)
1523 : 851363 : | (flag_iso << 3)
1524 : 851363 : | (warn_long_long << 4)
1525 : 851363 : | (warn_cxx_compat << 5)
1526 : 851363 : | (warn_overlength_strings << 6)
1527 : : /* warn_c90_c99_compat has three states: -1/0/1, so we must
1528 : : play tricks to properly restore it. */
1529 : 851363 : | ((warn_c90_c99_compat == 1) << 7)
1530 : 851363 : | ((warn_c90_c99_compat == -1) << 8)
1531 : : /* Similarly for warn_c99_c11_compat. */
1532 : 851363 : | ((warn_c99_c11_compat == 1) << 9)
1533 : 851363 : | ((warn_c99_c11_compat == -1) << 10)
1534 : : /* Similarly for warn_c11_c23_compat. */
1535 : 851363 : | ((warn_c11_c23_compat == 1) << 11)
1536 : 851363 : | ((warn_c11_c23_compat == -1) << 12)
1537 : : );
1538 : 851363 : cpp_opts->cpp_pedantic = pedantic = 0;
1539 : 851363 : warn_pointer_arith = 0;
1540 : 851363 : cpp_opts->cpp_warn_traditional = warn_traditional = 0;
1541 : 851363 : flag_iso = 0;
1542 : 851363 : cpp_opts->cpp_warn_long_long = warn_long_long = 0;
1543 : 851363 : warn_cxx_compat = 0;
1544 : 851363 : warn_overlength_strings = 0;
1545 : 851363 : warn_c90_c99_compat = 0;
1546 : 851363 : warn_c99_c11_compat = 0;
1547 : 851363 : warn_c11_c23_compat = 0;
1548 : 851363 : return ret;
1549 : : }
1550 : :
1551 : : /* Restore the warning flags which are controlled by __extension__.
1552 : : FLAGS is the return value from disable_extension_diagnostics. */
1553 : :
1554 : : static inline void
1555 : 851363 : restore_extension_diagnostics (int flags)
1556 : : {
1557 : 851363 : cpp_opts->cpp_pedantic = pedantic = flags & 1;
1558 : 851363 : warn_pointer_arith = (flags >> 1) & 1;
1559 : 851363 : cpp_opts->cpp_warn_traditional = warn_traditional = (flags >> 2) & 1;
1560 : 851363 : flag_iso = (flags >> 3) & 1;
1561 : 851363 : cpp_opts->cpp_warn_long_long = warn_long_long = (flags >> 4) & 1;
1562 : 851363 : warn_cxx_compat = (flags >> 5) & 1;
1563 : 851363 : warn_overlength_strings = (flags >> 6) & 1;
1564 : : /* See above for why is this needed. */
1565 : 851363 : warn_c90_c99_compat = (flags >> 7) & 1 ? 1 : ((flags >> 8) & 1 ? -1 : 0);
1566 : 851363 : warn_c99_c11_compat = (flags >> 9) & 1 ? 1 : ((flags >> 10) & 1 ? -1 : 0);
1567 : 851363 : warn_c11_c23_compat = (flags >> 11) & 1 ? 1 : ((flags >> 12) & 1 ? -1 : 0);
1568 : 851363 : }
1569 : :
1570 : : /* Helper data structure for parsing #pragma acc routine. */
1571 : : struct oacc_routine_data {
1572 : : bool error_seen; /* Set if error has been reported. */
1573 : : bool fndecl_seen; /* Set if one fn decl/definition has been seen already. */
1574 : : tree clauses;
1575 : : location_t loc;
1576 : : };
1577 : :
1578 : : /* Used for parsing objc foreach statements. */
1579 : : static tree objc_foreach_break_label, objc_foreach_continue_label;
1580 : :
1581 : : /* Used for parsing OMP for loops.
1582 : :
1583 : : Some notes on flags used for context:
1584 : : parser->omp_for_parse_state is non-null anywhere inside the OMP FOR
1585 : : construct, except for the final-loop-body.
1586 : : The want_nested_loop flag is true if inside a {} sequence where
1587 : : a loop-nest (or another {} sequence containing a loop-nest) is expected,
1588 : : but has not yet been seen. It's false when parsing intervening code
1589 : : statements or their substatements that cannot contain a loop-nest.
1590 : : The in_intervening_code flag is true when parsing any intervening code,
1591 : : including substatements, and whether or not want_nested_loop is true.
1592 : :
1593 : : And, about error handling:
1594 : : The saw_intervening_code flag is set if the loop is not perfectly
1595 : : nested, even in the usual case where this is not an error.
1596 : : perfect_nesting_fail is set if an error has been diagnosed because an
1597 : : imperfectly-nested loop was found where a perfectly-nested one is
1598 : : required (we diagnose this only once).
1599 : : fail is set if any kind of structural error in the loop nest
1600 : : has been found and diagnosed.
1601 : : */
1602 : : struct omp_for_parse_data {
1603 : : enum tree_code code;
1604 : : tree declv, condv, incrv, initv;
1605 : : tree pre_body;
1606 : : tree bindings;
1607 : : int count; /* Expected nesting depth. */
1608 : : int depth; /* Current nesting depth. */
1609 : : location_t for_loc;
1610 : : bool ordered : 1;
1611 : : bool inscan : 1;
1612 : : bool want_nested_loop : 1;
1613 : : bool in_intervening_code : 1;
1614 : : bool saw_intervening_code: 1;
1615 : : bool perfect_nesting_fail : 1;
1616 : : bool fail : 1;
1617 : : };
1618 : :
1619 : : static bool c_parser_nth_token_starts_std_attributes (c_parser *,
1620 : : unsigned int);
1621 : : static tree c_parser_std_attribute_specifier_sequence (c_parser *);
1622 : : static void c_parser_external_declaration (c_parser *);
1623 : : static void c_parser_asm_definition (c_parser *);
1624 : : static void c_parser_declaration_or_fndef (c_parser *, bool, bool, bool,
1625 : : bool, bool, tree * = NULL,
1626 : : vec<c_token> * = NULL,
1627 : : bool have_attrs = false,
1628 : : tree attrs = NULL,
1629 : : struct oacc_routine_data * = NULL,
1630 : : bool * = NULL);
1631 : : static bool c_parser_handle_statement_omp_attributes (c_parser *, tree &,
1632 : : bool *);
1633 : : static void c_parser_static_assert_declaration_no_semi (c_parser *);
1634 : : static void c_parser_static_assert_declaration (c_parser *);
1635 : : static struct c_typespec c_parser_enum_specifier (c_parser *);
1636 : : static struct c_typespec c_parser_struct_or_union_specifier (c_parser *);
1637 : : static tree c_parser_struct_declaration (c_parser *, tree *);
1638 : : static struct c_typespec c_parser_typeof_specifier (c_parser *);
1639 : : static tree c_parser_alignas_specifier (c_parser *);
1640 : : static struct c_declarator *c_parser_direct_declarator (c_parser *, bool,
1641 : : c_dtr_syn, bool *);
1642 : : static struct c_declarator *c_parser_direct_declarator_inner (c_parser *,
1643 : : bool,
1644 : : struct c_declarator *);
1645 : : static struct c_arg_info *c_parser_parms_declarator (c_parser *, bool, tree,
1646 : : bool);
1647 : : static struct c_arg_info *c_parser_parms_list_declarator (c_parser *, tree,
1648 : : tree, bool);
1649 : : static struct c_parm *c_parser_parameter_declaration (c_parser *, tree, bool);
1650 : : static tree c_parser_simple_asm_expr (c_parser *);
1651 : : static tree c_parser_gnu_attributes (c_parser *);
1652 : : static struct c_expr c_parser_initializer (c_parser *, tree);
1653 : : static struct c_expr c_parser_braced_init (c_parser *, tree, bool,
1654 : : struct obstack *, tree);
1655 : : static void c_parser_initelt (c_parser *, struct obstack *);
1656 : : static void c_parser_initval (c_parser *, struct c_expr *,
1657 : : struct obstack *);
1658 : : static tree c_parser_compound_statement (c_parser *, location_t * = NULL);
1659 : : static location_t c_parser_compound_statement_nostart (c_parser *);
1660 : : static void c_parser_label (c_parser *, tree);
1661 : : static void c_parser_statement (c_parser *, bool *, location_t * = NULL);
1662 : : static void c_parser_statement_after_labels (c_parser *, bool *,
1663 : : vec<tree> * = NULL);
1664 : : static tree c_parser_c99_block_statement (c_parser *, bool *,
1665 : : location_t * = NULL);
1666 : : static void c_parser_if_statement (c_parser *, bool *, vec<tree> *);
1667 : : static void c_parser_switch_statement (c_parser *, bool *);
1668 : : static void c_parser_while_statement (c_parser *, bool, unsigned short, bool,
1669 : : bool *);
1670 : : static void c_parser_do_statement (c_parser *, bool, unsigned short, bool);
1671 : : static void c_parser_for_statement (c_parser *, bool, unsigned short, bool,
1672 : : bool *);
1673 : : static tree c_parser_asm_statement (c_parser *);
1674 : : static tree c_parser_asm_operands (c_parser *);
1675 : : static tree c_parser_asm_goto_operands (c_parser *);
1676 : : static tree c_parser_asm_clobbers (c_parser *);
1677 : : static struct c_expr c_parser_expr_no_commas (c_parser *, struct c_expr *,
1678 : : tree = NULL_TREE);
1679 : : static struct c_expr c_parser_conditional_expression (c_parser *,
1680 : : struct c_expr *, tree);
1681 : : static struct c_expr c_parser_binary_expression (c_parser *, struct c_expr *,
1682 : : tree);
1683 : : static struct c_expr c_parser_cast_expression (c_parser *, struct c_expr *);
1684 : : static struct c_expr c_parser_unary_expression (c_parser *);
1685 : : static struct c_expr c_parser_sizeof_expression (c_parser *);
1686 : : static struct c_expr c_parser_alignof_expression (c_parser *);
1687 : : static struct c_expr c_parser_postfix_expression (c_parser *);
1688 : : static struct c_expr c_parser_postfix_expression_after_paren_type (c_parser *,
1689 : : struct c_declspecs *,
1690 : : struct c_type_name *,
1691 : : location_t);
1692 : : static struct c_expr c_parser_postfix_expression_after_primary (c_parser *,
1693 : : location_t loc,
1694 : : struct c_expr);
1695 : : static tree c_parser_transaction (c_parser *, enum rid);
1696 : : static struct c_expr c_parser_transaction_expression (c_parser *, enum rid);
1697 : : static tree c_parser_transaction_cancel (c_parser *);
1698 : : static struct c_expr c_parser_expression (c_parser *);
1699 : : static struct c_expr c_parser_expression_conv (c_parser *);
1700 : : static vec<tree, va_gc> *c_parser_expr_list (c_parser *, bool, bool,
1701 : : vec<tree, va_gc> **, location_t *,
1702 : : tree *, vec<location_t> *,
1703 : : unsigned int * = NULL);
1704 : : static struct c_expr c_parser_has_attribute_expression (c_parser *);
1705 : :
1706 : : static void c_parser_oacc_declare (c_parser *);
1707 : : static void c_parser_oacc_enter_exit_data (c_parser *, bool);
1708 : : static void c_parser_oacc_update (c_parser *);
1709 : : static void c_parser_omp_construct (c_parser *, bool *);
1710 : : static void c_parser_omp_threadprivate (c_parser *);
1711 : : static void c_parser_omp_barrier (c_parser *);
1712 : : static void c_parser_omp_depobj (c_parser *);
1713 : : static void c_parser_omp_flush (c_parser *);
1714 : : static tree c_parser_omp_loop_nest (c_parser *, bool *);
1715 : : static tree c_parser_omp_for_loop (location_t, c_parser *, enum tree_code,
1716 : : tree, tree *, bool *);
1717 : : static void c_parser_omp_taskwait (c_parser *);
1718 : : static void c_parser_omp_taskyield (c_parser *);
1719 : : static void c_parser_omp_cancel (c_parser *);
1720 : : static void c_parser_omp_nothing (c_parser *);
1721 : :
1722 : : enum pragma_context { pragma_external, pragma_struct, pragma_param,
1723 : : pragma_stmt, pragma_compound };
1724 : : static bool c_parser_pragma (c_parser *, enum pragma_context, bool *);
1725 : : static bool c_parser_omp_cancellation_point (c_parser *, enum pragma_context);
1726 : : static bool c_parser_omp_target (c_parser *, enum pragma_context, bool *);
1727 : : static void c_parser_omp_begin (c_parser *);
1728 : : static void c_parser_omp_end (c_parser *);
1729 : : static bool c_parser_omp_declare (c_parser *, enum pragma_context);
1730 : : static void c_parser_omp_requires (c_parser *);
1731 : : static bool c_parser_omp_error (c_parser *, enum pragma_context);
1732 : : static void c_parser_omp_assumption_clauses (c_parser *, bool);
1733 : : static void c_parser_omp_allocate (c_parser *);
1734 : : static void c_parser_omp_assumes (c_parser *);
1735 : : static bool c_parser_omp_ordered (c_parser *, enum pragma_context, bool *);
1736 : : static void c_parser_oacc_routine (c_parser *, enum pragma_context);
1737 : :
1738 : : /* These Objective-C parser functions are only ever called when
1739 : : compiling Objective-C. */
1740 : : static void c_parser_objc_class_definition (c_parser *, tree);
1741 : : static void c_parser_objc_class_instance_variables (c_parser *);
1742 : : static void c_parser_objc_class_declaration (c_parser *);
1743 : : static void c_parser_objc_alias_declaration (c_parser *);
1744 : : static void c_parser_objc_protocol_definition (c_parser *, tree);
1745 : : static bool c_parser_objc_method_type (c_parser *);
1746 : : static void c_parser_objc_method_definition (c_parser *);
1747 : : static void c_parser_objc_methodprotolist (c_parser *);
1748 : : static void c_parser_objc_methodproto (c_parser *);
1749 : : static tree c_parser_objc_method_decl (c_parser *, bool, tree *, tree *);
1750 : : static tree c_parser_objc_type_name (c_parser *);
1751 : : static tree c_parser_objc_protocol_refs (c_parser *);
1752 : : static void c_parser_objc_try_catch_finally_statement (c_parser *);
1753 : : static void c_parser_objc_synchronized_statement (c_parser *);
1754 : : static tree c_parser_objc_selector (c_parser *);
1755 : : static tree c_parser_objc_selector_arg (c_parser *);
1756 : : static tree c_parser_objc_receiver (c_parser *);
1757 : : static tree c_parser_objc_message_args (c_parser *);
1758 : : static tree c_parser_objc_keywordexpr (c_parser *);
1759 : : static void c_parser_objc_at_property_declaration (c_parser *);
1760 : : static void c_parser_objc_at_synthesize_declaration (c_parser *);
1761 : : static void c_parser_objc_at_dynamic_declaration (c_parser *);
1762 : : static bool c_parser_objc_diagnose_bad_element_prefix
1763 : : (c_parser *, struct c_declspecs *);
1764 : : static location_t c_parser_parse_rtl_body (c_parser *, char *);
1765 : :
1766 : : #if ENABLE_ANALYZER
1767 : :
1768 : : namespace ana {
1769 : :
1770 : : /* Concrete implementation of ana::translation_unit for the C frontend. */
1771 : :
1772 : : class c_translation_unit : public translation_unit
1773 : : {
1774 : : public:
1775 : : /* Implementation of translation_unit::lookup_constant_by_id for use by the
1776 : : analyzer to look up named constants in the user's source code. */
1777 : 6920 : tree lookup_constant_by_id (tree id) const final override
1778 : : {
1779 : : /* Consider decls. */
1780 : 6920 : if (tree decl = lookup_name (id))
1781 : 42 : if (TREE_CODE (decl) == CONST_DECL)
1782 : 42 : if (tree value = DECL_INITIAL (decl))
1783 : 42 : if (TREE_CODE (value) == INTEGER_CST)
1784 : : return value;
1785 : :
1786 : : /* Consider macros. */
1787 : 6878 : cpp_hashnode *hashnode = C_CPP_HASHNODE (id);
1788 : 6878 : if (cpp_macro_p (hashnode))
1789 : 48 : if (tree value = consider_macro (hashnode->value.macro))
1790 : : return value;
1791 : :
1792 : : return NULL_TREE;
1793 : : }
1794 : :
1795 : : tree
1796 : 4 : lookup_type_by_id (tree id) const final override
1797 : : {
1798 : 4 : if (tree type_decl = lookup_name (id))
1799 : 0 : if (TREE_CODE (type_decl) == TYPE_DECL)
1800 : : {
1801 : 0 : tree record_type = TREE_TYPE (type_decl);
1802 : 0 : if (TREE_CODE (record_type) == RECORD_TYPE)
1803 : 0 : return record_type;
1804 : : }
1805 : :
1806 : : return NULL_TREE;
1807 : : }
1808 : :
1809 : : tree
1810 : 2 : lookup_global_var_by_id (tree id) const final override
1811 : : {
1812 : 2 : if (tree var_decl = lookup_name (id))
1813 : 0 : if (TREE_CODE (var_decl) == VAR_DECL)
1814 : 0 : return var_decl;
1815 : :
1816 : : return NULL_TREE;
1817 : : }
1818 : :
1819 : : private:
1820 : : /* Attempt to get an INTEGER_CST from MACRO.
1821 : : Only handle the simplest cases: where MACRO's definition is a single
1822 : : token containing a number, by lexing the number again.
1823 : : This will handle e.g.
1824 : : #define NAME 42
1825 : : and other bases but not negative numbers, parentheses or e.g.
1826 : : #define NAME 1 << 7
1827 : : as doing so would require a parser. */
1828 : 48 : tree consider_macro (cpp_macro *macro) const
1829 : : {
1830 : 48 : if (macro->paramc > 0)
1831 : : return NULL_TREE;
1832 : 45 : if (macro->kind != cmk_macro)
1833 : : return NULL_TREE;
1834 : 45 : if (macro->count != 1)
1835 : : return NULL_TREE;
1836 : 39 : const cpp_token &tok = macro->exp.tokens[0];
1837 : 39 : if (tok.type != CPP_NUMBER)
1838 : : return NULL_TREE;
1839 : :
1840 : 36 : cpp_reader *old_parse_in = parse_in;
1841 : 36 : parse_in = cpp_create_reader (CLK_GNUC89, NULL, line_table);
1842 : :
1843 : 36 : pretty_printer pp;
1844 : 36 : pp_string (&pp, (const char *) tok.val.str.text);
1845 : 36 : pp_newline (&pp);
1846 : 72 : cpp_push_buffer (parse_in,
1847 : 36 : (const unsigned char *) pp_formatted_text (&pp),
1848 : : strlen (pp_formatted_text (&pp)),
1849 : : 0);
1850 : :
1851 : 36 : tree value;
1852 : 36 : location_t loc;
1853 : 36 : unsigned char cpp_flags;
1854 : 36 : c_lex_with_flags (&value, &loc, &cpp_flags, 0);
1855 : :
1856 : 36 : cpp_destroy (parse_in);
1857 : 36 : parse_in = old_parse_in;
1858 : :
1859 : 36 : if (value && TREE_CODE (value) == INTEGER_CST)
1860 : 36 : return value;
1861 : :
1862 : : return NULL_TREE;
1863 : 36 : }
1864 : : };
1865 : :
1866 : : } // namespace ana
1867 : :
1868 : : #endif /* #if ENABLE_ANALYZER */
1869 : :
1870 : : /* Parse a translation unit (C90 6.7, C99 6.9, C11 6.9).
1871 : :
1872 : : translation-unit:
1873 : : external-declarations
1874 : :
1875 : : external-declarations:
1876 : : external-declaration
1877 : : external-declarations external-declaration
1878 : :
1879 : : GNU extensions:
1880 : :
1881 : : translation-unit:
1882 : : empty
1883 : : */
1884 : :
1885 : : static void
1886 : 100145 : c_parser_translation_unit (c_parser *parser)
1887 : : {
1888 : 100145 : if (c_parser_next_token_is (parser, CPP_EOF))
1889 : : {
1890 : 1243 : pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
1891 : : "ISO C forbids an empty translation unit");
1892 : : }
1893 : : else
1894 : : {
1895 : 98902 : void *obstack_position = obstack_alloc (&parser_obstack, 0);
1896 : 98902 : mark_valid_location_for_stdc_pragma (false);
1897 : 50958395 : do
1898 : : {
1899 : 50958395 : ggc_collect ();
1900 : 50958395 : c_parser_external_declaration (parser);
1901 : 50958391 : obstack_free (&parser_obstack, obstack_position);
1902 : : }
1903 : 50958391 : while (c_parser_next_token_is_not (parser, CPP_EOF));
1904 : : }
1905 : :
1906 : : unsigned int i;
1907 : : tree decl;
1908 : 100150 : FOR_EACH_VEC_ELT (incomplete_record_decls, i, decl)
1909 : 94 : if (DECL_SIZE (decl) == NULL_TREE && TREE_TYPE (decl) != error_mark_node)
1910 : 17 : error ("storage size of %q+D isn%'t known", decl);
1911 : :
1912 : 100056 : if (vec_safe_length (current_omp_declare_target_attribute))
1913 : : {
1914 : 4 : c_omp_declare_target_attr
1915 : 4 : a = current_omp_declare_target_attribute->pop ();
1916 : 4 : if (!errorcount)
1917 : 3 : error ("%qs without corresponding %qs",
1918 : : a.device_type >= 0 ? "#pragma omp begin declare target"
1919 : : : "#pragma omp declare target",
1920 : : "#pragma omp end declare target");
1921 : 8 : vec_safe_truncate (current_omp_declare_target_attribute, 0);
1922 : : }
1923 : 100056 : if (vec_safe_length (current_omp_begin_assumes))
1924 : : {
1925 : 1 : if (!errorcount)
1926 : 1 : error ("%qs without corresponding %qs",
1927 : : "#pragma omp begin assumes", "#pragma omp end assumes");
1928 : 1 : vec_safe_truncate (current_omp_begin_assumes, 0);
1929 : : }
1930 : :
1931 : : #if ENABLE_ANALYZER
1932 : 100056 : if (flag_analyzer)
1933 : : {
1934 : 1384 : ana::c_translation_unit tu;
1935 : 1384 : ana::on_finish_translation_unit (tu);
1936 : : }
1937 : : #endif
1938 : 100056 : }
1939 : :
1940 : : /* Parse an external declaration (C90 6.7, C99 6.9, C11 6.9).
1941 : :
1942 : : external-declaration:
1943 : : function-definition
1944 : : declaration
1945 : :
1946 : : GNU extensions:
1947 : :
1948 : : external-declaration:
1949 : : asm-definition
1950 : : ;
1951 : : __extension__ external-declaration
1952 : :
1953 : : Objective-C:
1954 : :
1955 : : external-declaration:
1956 : : objc-class-definition
1957 : : objc-class-declaration
1958 : : objc-alias-declaration
1959 : : objc-protocol-definition
1960 : : objc-method-definition
1961 : : @end
1962 : : */
1963 : :
1964 : : static void
1965 : 51326253 : c_parser_external_declaration (c_parser *parser)
1966 : : {
1967 : 51326253 : int ext;
1968 : 51326253 : switch (c_parser_peek_token (parser)->type)
1969 : : {
1970 : 49649497 : case CPP_KEYWORD:
1971 : 49649497 : switch (c_parser_peek_token (parser)->keyword)
1972 : : {
1973 : 367858 : case RID_EXTENSION:
1974 : 367858 : ext = disable_extension_diagnostics ();
1975 : 367858 : c_parser_consume_token (parser);
1976 : 367858 : c_parser_external_declaration (parser);
1977 : 367858 : restore_extension_diagnostics (ext);
1978 : 367858 : break;
1979 : 141 : case RID_ASM:
1980 : 141 : c_parser_asm_definition (parser);
1981 : 141 : break;
1982 : 0 : case RID_AT_INTERFACE:
1983 : 0 : case RID_AT_IMPLEMENTATION:
1984 : 0 : gcc_assert (c_dialect_objc ());
1985 : 0 : c_parser_objc_class_definition (parser, NULL_TREE);
1986 : 0 : break;
1987 : 0 : case RID_AT_CLASS:
1988 : 0 : gcc_assert (c_dialect_objc ());
1989 : 0 : c_parser_objc_class_declaration (parser);
1990 : 0 : break;
1991 : 0 : case RID_AT_ALIAS:
1992 : 0 : gcc_assert (c_dialect_objc ());
1993 : 0 : c_parser_objc_alias_declaration (parser);
1994 : 0 : break;
1995 : 0 : case RID_AT_PROTOCOL:
1996 : 0 : gcc_assert (c_dialect_objc ());
1997 : 0 : c_parser_objc_protocol_definition (parser, NULL_TREE);
1998 : 0 : break;
1999 : 0 : case RID_AT_PROPERTY:
2000 : 0 : gcc_assert (c_dialect_objc ());
2001 : 0 : c_parser_objc_at_property_declaration (parser);
2002 : 0 : break;
2003 : 0 : case RID_AT_SYNTHESIZE:
2004 : 0 : gcc_assert (c_dialect_objc ());
2005 : 0 : c_parser_objc_at_synthesize_declaration (parser);
2006 : 0 : break;
2007 : 0 : case RID_AT_DYNAMIC:
2008 : 0 : gcc_assert (c_dialect_objc ());
2009 : 0 : c_parser_objc_at_dynamic_declaration (parser);
2010 : 0 : break;
2011 : 0 : case RID_AT_END:
2012 : 0 : gcc_assert (c_dialect_objc ());
2013 : 0 : c_parser_consume_token (parser);
2014 : 0 : objc_finish_implementation ();
2015 : 0 : break;
2016 : 49281498 : default:
2017 : 49281498 : goto decl_or_fndef;
2018 : : }
2019 : : break;
2020 : 2114 : case CPP_SEMICOLON:
2021 : 2114 : pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
2022 : : "ISO C does not allow extra %<;%> outside of a function");
2023 : 2114 : c_parser_consume_token (parser);
2024 : 2114 : break;
2025 : 1465890 : case CPP_PRAGMA:
2026 : 1465890 : mark_valid_location_for_stdc_pragma (true);
2027 : 1465890 : c_parser_pragma (parser, pragma_external, NULL);
2028 : 1465890 : mark_valid_location_for_stdc_pragma (false);
2029 : 1465890 : break;
2030 : 1 : case CPP_PLUS:
2031 : 1 : case CPP_MINUS:
2032 : 1 : if (c_dialect_objc ())
2033 : : {
2034 : 0 : c_parser_objc_method_definition (parser);
2035 : 0 : break;
2036 : : }
2037 : : /* Else fall through, and yield a syntax error trying to parse
2038 : : as a declaration or function definition. */
2039 : : /* FALLTHRU */
2040 : 49490250 : default:
2041 : 1 : decl_or_fndef:
2042 : : /* A declaration or a function definition (or, in Objective-C,
2043 : : an @interface or @protocol with prefix attributes). We can
2044 : : only tell which after parsing the declaration specifiers, if
2045 : : any, and the first declarator. */
2046 : 49490250 : c_parser_declaration_or_fndef (parser, true, true, true, false, true);
2047 : 49490250 : break;
2048 : : }
2049 : 51326249 : }
2050 : :
2051 : : static void c_parser_handle_directive_omp_attributes (tree &, vec<c_token> *&,
2052 : : vec<c_token> *);
2053 : : static void c_finish_omp_declare_simd (c_parser *, tree, tree, vec<c_token> *);
2054 : : static void c_finish_oacc_routine (struct oacc_routine_data *, tree, bool);
2055 : :
2056 : : /* Build and add a DEBUG_BEGIN_STMT statement with location LOC. */
2057 : :
2058 : : static void
2059 : 94921436 : add_debug_begin_stmt (location_t loc)
2060 : : {
2061 : : /* Don't add DEBUG_BEGIN_STMTs outside of functions, see PR84721. */
2062 : 94921436 : if (!MAY_HAVE_DEBUG_MARKER_STMTS || !building_stmt_list_p ())
2063 : 92344845 : return;
2064 : :
2065 : 2576591 : tree stmt = build0 (DEBUG_BEGIN_STMT, void_type_node);
2066 : 2576591 : SET_EXPR_LOCATION (stmt, loc);
2067 : 2576591 : add_stmt (stmt);
2068 : : }
2069 : :
2070 : : /* Helper function for c_parser_declaration_or_fndef and
2071 : : Handle assume attribute(s). */
2072 : :
2073 : : static tree
2074 : 34 : handle_assume_attribute (location_t here, tree attrs, bool nested)
2075 : : {
2076 : 34 : if (nested)
2077 : 70 : for (tree attr = lookup_attribute ("gnu", "assume", attrs); attr;
2078 : 37 : attr = lookup_attribute ("gnu", "assume", TREE_CHAIN (attr)))
2079 : : {
2080 : 37 : tree args = TREE_VALUE (attr);
2081 : 37 : int nargs = list_length (args);
2082 : 37 : if (nargs != 1)
2083 : : {
2084 : 6 : error_at (here, "wrong number of arguments specified "
2085 : : "for %qE attribute",
2086 : : get_attribute_name (attr));
2087 : 6 : inform (here, "expected %i, found %i", 1, nargs);
2088 : : }
2089 : : else
2090 : : {
2091 : 31 : tree arg = TREE_VALUE (args);
2092 : 31 : arg = c_objc_common_truthvalue_conversion (here, arg);
2093 : 31 : arg = c_fully_fold (arg, false, NULL);
2094 : 31 : if (arg != error_mark_node)
2095 : : {
2096 : 29 : tree fn = build_call_expr_internal_loc (here, IFN_ASSUME,
2097 : : void_type_node, 1,
2098 : : arg);
2099 : 29 : add_stmt (fn);
2100 : : }
2101 : : }
2102 : : }
2103 : : else
2104 : 1 : pedwarn (here, OPT_Wattributes,
2105 : : "%<assume%> attribute at top level");
2106 : :
2107 : 34 : return remove_attribute ("gnu", "assume", attrs);
2108 : : }
2109 : :
2110 : : /* Parse a declaration or function definition (C90 6.5, 6.7.1, C99
2111 : : 6.7, 6.9.1, C11 6.7, 6.9.1). If FNDEF_OK is true, a function definition
2112 : : is accepted; otherwise (old-style parameter declarations) only other
2113 : : declarations are accepted. If STATIC_ASSERT_OK is true, a static
2114 : : assertion is accepted; otherwise (old-style parameter declarations)
2115 : : it is not. If NESTED is true, we are inside a function or parsing
2116 : : old-style parameter declarations; any functions encountered are
2117 : : nested functions and declaration specifiers are required; otherwise
2118 : : we are at top level and functions are normal functions and
2119 : : declaration specifiers may be optional. If EMPTY_OK is true, empty
2120 : : declarations are OK (subject to all other constraints); otherwise
2121 : : (old-style parameter declarations) they are diagnosed. If
2122 : : START_ATTR_OK is true, the declaration specifiers may start with
2123 : : attributes (GNU or standard); otherwise they may not.
2124 : : OBJC_FOREACH_OBJECT_DECLARATION can be used to get back the parsed
2125 : : declaration when parsing an Objective-C foreach statement.
2126 : : FALLTHRU_ATTR_P is used to signal whether this function parsed
2127 : : "__attribute__((fallthrough));". ATTRS are any standard attributes
2128 : : parsed in the caller (in contexts where such attributes had to be
2129 : : parsed to determine whether what follows is a declaration or a
2130 : : statement); HAVE_ATTRS says whether there were any such attributes
2131 : : (even empty).
2132 : :
2133 : : declaration:
2134 : : declaration-specifiers init-declarator-list[opt] ;
2135 : : static_assert-declaration
2136 : :
2137 : : function-definition:
2138 : : declaration-specifiers[opt] declarator declaration-list[opt]
2139 : : compound-statement
2140 : :
2141 : : declaration-list:
2142 : : declaration
2143 : : declaration-list declaration
2144 : :
2145 : : init-declarator-list:
2146 : : init-declarator
2147 : : init-declarator-list , init-declarator
2148 : :
2149 : : init-declarator:
2150 : : declarator simple-asm-expr[opt] gnu-attributes[opt]
2151 : : declarator simple-asm-expr[opt] gnu-attributes[opt] = initializer
2152 : :
2153 : : GNU extensions:
2154 : :
2155 : : nested-function-definition:
2156 : : declaration-specifiers declarator declaration-list[opt]
2157 : : compound-statement
2158 : :
2159 : : attribute ;
2160 : :
2161 : : Objective-C:
2162 : : gnu-attributes objc-class-definition
2163 : : gnu-attributes objc-category-definition
2164 : : gnu-attributes objc-protocol-definition
2165 : :
2166 : : The simple-asm-expr and gnu-attributes are GNU extensions.
2167 : :
2168 : : This function does not handle __extension__; that is handled in its
2169 : : callers. ??? Following the old parser, __extension__ may start
2170 : : external declarations, declarations in functions and declarations
2171 : : at the start of "for" loops, but not old-style parameter
2172 : : declarations.
2173 : :
2174 : : C99 requires declaration specifiers in a function definition; the
2175 : : absence is diagnosed through the diagnosis of implicit int. In GNU
2176 : : C we also allow but diagnose declarations without declaration
2177 : : specifiers, but only at top level (elsewhere they conflict with
2178 : : other syntax).
2179 : :
2180 : : In Objective-C, declarations of the looping variable in a foreach
2181 : : statement are exceptionally terminated by 'in' (for example, 'for
2182 : : (NSObject *object in array) { ... }').
2183 : :
2184 : : OpenMP:
2185 : :
2186 : : declaration:
2187 : : threadprivate-directive
2188 : :
2189 : : GIMPLE:
2190 : :
2191 : : gimple-function-definition:
2192 : : declaration-specifiers[opt] __GIMPLE (gimple-or-rtl-pass-list) declarator
2193 : : declaration-list[opt] compound-statement
2194 : :
2195 : : rtl-function-definition:
2196 : : declaration-specifiers[opt] __RTL (gimple-or-rtl-pass-list) declarator
2197 : : declaration-list[opt] compound-statement */
2198 : :
2199 : : static void
2200 : 56908315 : c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
2201 : : bool static_assert_ok, bool empty_ok,
2202 : : bool nested, bool start_attr_ok,
2203 : : tree *objc_foreach_object_declaration
2204 : : /* = NULL */,
2205 : : vec<c_token> *omp_declare_simd_clauses
2206 : : /* = NULL */,
2207 : : bool have_attrs /* = false */,
2208 : : tree attrs /* = NULL_TREE */,
2209 : : struct oacc_routine_data *oacc_routine_data
2210 : : /* = NULL */,
2211 : : bool *fallthru_attr_p /* = NULL */)
2212 : : {
2213 : 56908315 : struct c_declspecs *specs;
2214 : 56908315 : tree prefix_attrs;
2215 : 56908315 : tree all_prefix_attrs;
2216 : 56908315 : bool diagnosed_no_specs = false;
2217 : 56908315 : location_t here = c_parser_peek_token (parser)->location;
2218 : :
2219 : 56908315 : add_debug_begin_stmt (c_parser_peek_token (parser)->location);
2220 : :
2221 : 56908315 : if (static_assert_ok
2222 : 113803489 : && c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
2223 : : {
2224 : 1668 : c_parser_static_assert_declaration (parser);
2225 : 25144768 : return;
2226 : : }
2227 : 56906647 : specs = build_null_declspecs ();
2228 : :
2229 : : /* Handle any standard attributes parsed in the caller. */
2230 : 56906647 : if (have_attrs)
2231 : : {
2232 : 114 : declspecs_add_attrs (here, specs, attrs);
2233 : 114 : specs->non_std_attrs_seen_p = false;
2234 : : }
2235 : :
2236 : : /* Try to detect an unknown type name when we have "A B" or "A *B". */
2237 : 56906647 : if (c_parser_peek_token (parser)->type == CPP_NAME
2238 : 5701023 : && c_parser_peek_token (parser)->id_kind == C_ID_ID
2239 : 9266 : && (c_parser_peek_2nd_token (parser)->type == CPP_NAME
2240 : 9180 : || c_parser_peek_2nd_token (parser)->type == CPP_MULT)
2241 : 56906757 : && (!nested || !lookup_name (c_parser_peek_token (parser)->value)))
2242 : : {
2243 : 110 : tree name = c_parser_peek_token (parser)->value;
2244 : :
2245 : : /* Issue a warning about NAME being an unknown type name, perhaps
2246 : : with some kind of hint.
2247 : : If the user forgot a "struct" etc, suggest inserting
2248 : : it. Otherwise, attempt to look for misspellings. */
2249 : 110 : gcc_rich_location richloc (here);
2250 : 110 : if (tag_exists_p (RECORD_TYPE, name))
2251 : : {
2252 : : /* This is not C++ with its implicit typedef. */
2253 : 3 : richloc.add_fixit_insert_before ("struct ");
2254 : 3 : error_at (&richloc,
2255 : : "unknown type name %qE;"
2256 : : " use %<struct%> keyword to refer to the type",
2257 : : name);
2258 : : }
2259 : 107 : else if (tag_exists_p (UNION_TYPE, name))
2260 : : {
2261 : 3 : richloc.add_fixit_insert_before ("union ");
2262 : 3 : error_at (&richloc,
2263 : : "unknown type name %qE;"
2264 : : " use %<union%> keyword to refer to the type",
2265 : : name);
2266 : : }
2267 : 104 : else if (tag_exists_p (ENUMERAL_TYPE, name))
2268 : : {
2269 : 3 : richloc.add_fixit_insert_before ("enum ");
2270 : 3 : error_at (&richloc,
2271 : : "unknown type name %qE;"
2272 : : " use %<enum%> keyword to refer to the type",
2273 : : name);
2274 : : }
2275 : : else
2276 : : {
2277 : 101 : auto_diagnostic_group d;
2278 : 101 : name_hint hint = lookup_name_fuzzy (name, FUZZY_LOOKUP_TYPENAME,
2279 : 101 : here);
2280 : 101 : if (const char *suggestion = hint.suggestion ())
2281 : : {
2282 : 12 : richloc.add_fixit_replace (suggestion);
2283 : 12 : error_at (&richloc,
2284 : : "unknown type name %qE; did you mean %qs?",
2285 : : name, suggestion);
2286 : : }
2287 : : else
2288 : 89 : error_at (here, "unknown type name %qE", name);
2289 : 101 : }
2290 : :
2291 : : /* Parse declspecs normally to get a correct pointer type, but avoid
2292 : : a further "fails to be a type name" error. Refuse nested functions
2293 : : since it is not how the user likely wants us to recover. */
2294 : 110 : c_parser_peek_token (parser)->type = CPP_KEYWORD;
2295 : 110 : c_parser_peek_token (parser)->keyword = RID_VOID;
2296 : 110 : c_parser_peek_token (parser)->value = error_mark_node;
2297 : 110 : fndef_ok = !nested;
2298 : 110 : }
2299 : :
2300 : : /* When there are standard attributes at the start of the
2301 : : declaration (to apply to the entity being declared), an
2302 : : init-declarator-list or function definition must be present. */
2303 : 56906647 : if (c_parser_nth_token_starts_std_attributes (parser, 1))
2304 : 333 : have_attrs = true;
2305 : :
2306 : 56906647 : c_parser_declspecs (parser, specs, true, true, start_attr_ok,
2307 : : true, true, start_attr_ok, true, cla_nonabstract_decl);
2308 : 56906647 : if (parser->error)
2309 : : {
2310 : 33 : c_parser_skip_to_end_of_block_or_statement (parser);
2311 : 33 : return;
2312 : : }
2313 : 56906614 : if (nested && !specs->declspecs_seen_p)
2314 : : {
2315 : 61 : c_parser_error (parser, "expected declaration specifiers");
2316 : 61 : c_parser_skip_to_end_of_block_or_statement (parser);
2317 : 61 : return;
2318 : : }
2319 : :
2320 : 56906553 : finish_declspecs (specs);
2321 : 56906553 : bool gnu_auto_type_p = specs->typespec_word == cts_auto_type;
2322 : 56906553 : bool std_auto_type_p = specs->c23_auto_p;
2323 : 56906553 : bool any_auto_type_p = gnu_auto_type_p || std_auto_type_p;
2324 : 56906553 : gcc_assert (!(gnu_auto_type_p && std_auto_type_p));
2325 : 56906553 : const char *auto_type_keyword = gnu_auto_type_p ? "__auto_type" : "auto";
2326 : 56906553 : if (specs->constexpr_p)
2327 : : {
2328 : : /* An underspecified declaration may not declare tags or members
2329 : : or structures or unions; it is undefined behavior to declare
2330 : : the members of an enumeration. Where the structure, union or
2331 : : enumeration type is declared within an initializer, this is
2332 : : diagnosed elsewhere. Diagnose here the case of declaring
2333 : : such a type in the type specifiers of a constexpr
2334 : : declaration. */
2335 : 330 : switch (specs->typespec_kind)
2336 : : {
2337 : 6 : case ctsk_tagfirstref:
2338 : 6 : case ctsk_tagfirstref_attrs:
2339 : 6 : error_at (here, "%qT declared in underspecified object declaration",
2340 : : specs->type);
2341 : 6 : break;
2342 : :
2343 : 10 : case ctsk_tagdef:
2344 : 10 : error_at (here, "%qT defined in underspecified object declaration",
2345 : : specs->type);
2346 : 10 : break;
2347 : :
2348 : : default:
2349 : : break;
2350 : : }
2351 : : }
2352 : 56906553 : if (c_parser_next_token_is (parser, CPP_SEMICOLON))
2353 : : {
2354 : 470258 : bool handled_assume = false;
2355 : 470258 : if (specs->attrs
2356 : 365 : && !nested
2357 : 117 : && specs->typespec_kind == ctsk_none
2358 : 470357 : && c_parser_handle_statement_omp_attributes (parser, specs->attrs,
2359 : : NULL))
2360 : : {
2361 : 82 : if (specs->attrs)
2362 : 0 : c_warn_unused_attributes (specs->attrs);
2363 : 165 : while (parser->in_omp_attribute_pragma)
2364 : : {
2365 : 83 : gcc_assert (c_parser_next_token_is (parser, CPP_PRAGMA));
2366 : 83 : c_parser_pragma (parser, pragma_external, NULL);
2367 : : }
2368 : 82 : c_parser_consume_token (parser);
2369 : 82 : return;
2370 : : }
2371 : 470176 : if (specs->typespec_kind == ctsk_none
2372 : 470176 : && lookup_attribute ("gnu", "assume", specs->attrs))
2373 : : {
2374 : 34 : handled_assume = true;
2375 : 34 : specs->attrs
2376 : 34 : = handle_assume_attribute (here, specs->attrs, nested);
2377 : : }
2378 : 470176 : if (any_auto_type_p)
2379 : 2 : error_at (here, "%qs in empty declaration", auto_type_keyword);
2380 : 470174 : else if (specs->typespec_kind == ctsk_none
2381 : 470174 : && attribute_fallthrough_p (specs->attrs))
2382 : : {
2383 : 206 : if (fallthru_attr_p != NULL)
2384 : 205 : *fallthru_attr_p = true;
2385 : 206 : if (nested)
2386 : : {
2387 : 205 : tree fn = build_call_expr_internal_loc (here, IFN_FALLTHROUGH,
2388 : : void_type_node, 0);
2389 : 205 : add_stmt (fn);
2390 : : }
2391 : : else
2392 : 1 : pedwarn (here, OPT_Wattributes,
2393 : : "%<fallthrough%> attribute at top level");
2394 : : }
2395 : 469968 : else if (empty_ok
2396 : 469955 : && !(have_attrs && specs->non_std_attrs_seen_p)
2397 : 469952 : && !handled_assume)
2398 : 469918 : shadow_tag (specs);
2399 : : else
2400 : : {
2401 : 50 : shadow_tag_warned (specs, 1);
2402 : 50 : if (!handled_assume)
2403 : 16 : pedwarn (here, 0, "empty declaration");
2404 : : }
2405 : : /* We still have to evaluate size expressions. */
2406 : 470176 : if (specs->expr)
2407 : 97 : add_stmt (fold_convert (void_type_node, specs->expr));
2408 : 470176 : c_parser_consume_token (parser);
2409 : 470176 : if (oacc_routine_data)
2410 : 0 : c_finish_oacc_routine (oacc_routine_data, NULL_TREE, false);
2411 : 470176 : return;
2412 : : }
2413 : :
2414 : : /* Provide better error recovery. Note that a type name here is usually
2415 : : better diagnosed as a redeclaration. */
2416 : 56436295 : if (empty_ok
2417 : 56423341 : && specs->typespec_kind == ctsk_tagdef
2418 : 690259 : && c_parser_next_token_starts_declspecs (parser)
2419 : 56436309 : && !c_parser_next_token_is (parser, CPP_NAME))
2420 : : {
2421 : 6 : c_parser_error (parser, "expected %<;%>, identifier or %<(%>");
2422 : 6 : parser->error = false;
2423 : 6 : shadow_tag_warned (specs, 1);
2424 : 6 : return;
2425 : : }
2426 : 56436289 : else if (c_dialect_objc () && !any_auto_type_p)
2427 : : {
2428 : : /* Prefix attributes are an error on method decls. */
2429 : 0 : switch (c_parser_peek_token (parser)->type)
2430 : : {
2431 : 0 : case CPP_PLUS:
2432 : 0 : case CPP_MINUS:
2433 : 0 : if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2434 : : return;
2435 : 0 : if (specs->attrs)
2436 : : {
2437 : 0 : warning_at (c_parser_peek_token (parser)->location,
2438 : : OPT_Wattributes,
2439 : : "prefix attributes are ignored for methods");
2440 : 0 : specs->attrs = NULL_TREE;
2441 : : }
2442 : 0 : if (fndef_ok)
2443 : 0 : c_parser_objc_method_definition (parser);
2444 : : else
2445 : 0 : c_parser_objc_methodproto (parser);
2446 : 0 : return;
2447 : 0 : break;
2448 : 0 : default:
2449 : 0 : break;
2450 : : }
2451 : : /* This is where we parse 'attributes @interface ...',
2452 : : 'attributes @implementation ...', 'attributes @protocol ...'
2453 : : (where attributes could be, for example, __attribute__
2454 : : ((deprecated)).
2455 : : */
2456 : 0 : switch (c_parser_peek_token (parser)->keyword)
2457 : : {
2458 : 0 : case RID_AT_INTERFACE:
2459 : 0 : {
2460 : 0 : if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2461 : : return;
2462 : 0 : c_parser_objc_class_definition (parser, specs->attrs);
2463 : 0 : return;
2464 : : }
2465 : 0 : break;
2466 : 0 : case RID_AT_IMPLEMENTATION:
2467 : 0 : {
2468 : 0 : if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2469 : : return;
2470 : 0 : if (specs->attrs)
2471 : : {
2472 : 0 : warning_at (c_parser_peek_token (parser)->location,
2473 : : OPT_Wattributes,
2474 : : "prefix attributes are ignored for implementations");
2475 : 0 : specs->attrs = NULL_TREE;
2476 : : }
2477 : 0 : c_parser_objc_class_definition (parser, NULL_TREE);
2478 : 0 : return;
2479 : : }
2480 : 0 : break;
2481 : 0 : case RID_AT_PROTOCOL:
2482 : 0 : {
2483 : 0 : if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2484 : : return;
2485 : 0 : c_parser_objc_protocol_definition (parser, specs->attrs);
2486 : 0 : return;
2487 : : }
2488 : 0 : break;
2489 : 0 : case RID_AT_ALIAS:
2490 : 0 : case RID_AT_CLASS:
2491 : 0 : case RID_AT_END:
2492 : 0 : case RID_AT_PROPERTY:
2493 : 0 : if (specs->attrs)
2494 : : {
2495 : 0 : c_parser_error (parser, "unexpected attribute");
2496 : 0 : specs->attrs = NULL;
2497 : : }
2498 : : break;
2499 : : default:
2500 : : break;
2501 : : }
2502 : : }
2503 : 56436289 : else if (attribute_fallthrough_p (specs->attrs))
2504 : 5 : warning_at (here, OPT_Wattributes,
2505 : : "%<fallthrough%> attribute not followed by %<;%>");
2506 : 56436284 : else if (lookup_attribute ("gnu", "assume", specs->attrs))
2507 : 2 : warning_at (here, OPT_Wattributes,
2508 : : "%<assume%> attribute not followed by %<;%>");
2509 : :
2510 : 88201500 : auto_vec<c_token> omp_declare_simd_attr_clauses;
2511 : 56436289 : c_parser_handle_directive_omp_attributes (specs->attrs,
2512 : : omp_declare_simd_clauses,
2513 : : &omp_declare_simd_attr_clauses);
2514 : 56436289 : pending_xref_error ();
2515 : 56436289 : prefix_attrs = specs->attrs;
2516 : 56436289 : all_prefix_attrs = prefix_attrs;
2517 : 56436289 : specs->attrs = NULL_TREE;
2518 : 57320563 : while (true)
2519 : : {
2520 : 56878426 : struct c_declarator *declarator;
2521 : 56878426 : bool dummy = false;
2522 : 56878426 : timevar_id_t tv;
2523 : 56878426 : tree fnbody = NULL_TREE;
2524 : 56878426 : tree underspec_name = NULL_TREE;
2525 : 56878426 : auto_vec<c_token> omp_dsimd_idattr_clauses;
2526 : : /* Declaring either one or more declarators (in which case we
2527 : : should diagnose if there were no declaration specifiers) or a
2528 : : function definition (in which case the diagnostic for
2529 : : implicit int suffices). */
2530 : 113756852 : declarator = c_parser_declarator (parser,
2531 : 56878426 : specs->typespec_kind != ctsk_none,
2532 : : C_DTR_NORMAL, &dummy);
2533 : 56878426 : if (declarator == NULL)
2534 : : {
2535 : 194 : if (omp_declare_simd_clauses)
2536 : 1 : c_finish_omp_declare_simd (parser, NULL_TREE, NULL_TREE,
2537 : : omp_declare_simd_clauses);
2538 : 194 : if (oacc_routine_data)
2539 : 0 : c_finish_oacc_routine (oacc_routine_data, NULL_TREE, false);
2540 : 194 : c_parser_skip_to_end_of_block_or_statement (parser);
2541 : 194 : return;
2542 : : }
2543 : 56878232 : if (flag_openmp || flag_openmp_simd)
2544 : : {
2545 : : struct c_declarator *d = declarator;
2546 : 711387 : while (d->kind != cdk_id)
2547 : 302814 : d = d->declarator;
2548 : 408573 : vec<c_token> *dummy = NULL;
2549 : 408573 : c_parser_handle_directive_omp_attributes (d->u.id.attrs, dummy,
2550 : : &omp_dsimd_idattr_clauses);
2551 : : }
2552 : 56878232 : if (gnu_auto_type_p && declarator->kind != cdk_id)
2553 : : {
2554 : 1 : error_at (here,
2555 : : "%<__auto_type%> requires a plain identifier"
2556 : : " as declarator");
2557 : 1 : c_parser_skip_to_end_of_block_or_statement (parser);
2558 : 1 : return;
2559 : : }
2560 : 56878231 : if (std_auto_type_p)
2561 : : {
2562 : : struct c_declarator *d = declarator;
2563 : 66 : while (d->kind == cdk_attrs)
2564 : 0 : d = d->declarator;
2565 : 66 : if (d->kind != cdk_id)
2566 : : {
2567 : 1 : error_at (here,
2568 : : "%<auto%> requires a plain identifier, possibly with"
2569 : : " attributes, as declarator");
2570 : 1 : c_parser_skip_to_end_of_block_or_statement (parser);
2571 : 1 : return;
2572 : : }
2573 : 65 : underspec_name = d->u.id.id;
2574 : : }
2575 : 56878165 : else if (specs->constexpr_p)
2576 : : {
2577 : : struct c_declarator *d = declarator;
2578 : 386 : while (d->kind != cdk_id)
2579 : 71 : d = d->declarator;
2580 : 315 : underspec_name = d->u.id.id;
2581 : : }
2582 : 56878230 : if (c_parser_next_token_is (parser, CPP_EQ)
2583 : 50746938 : || c_parser_next_token_is (parser, CPP_COMMA)
2584 : 50419839 : || c_parser_next_token_is (parser, CPP_SEMICOLON)
2585 : 42869060 : || c_parser_next_token_is_keyword (parser, RID_ASM)
2586 : 42180875 : || c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)
2587 : 88643478 : || c_parser_next_token_is_keyword (parser, RID_IN))
2588 : : {
2589 : 25112982 : tree asm_name = NULL_TREE;
2590 : 25112982 : tree postfix_attrs = NULL_TREE;
2591 : 25112982 : if (!diagnosed_no_specs && !specs->declspecs_seen_p)
2592 : : {
2593 : 75 : diagnosed_no_specs = true;
2594 : 75 : pedwarn (here, 0, "data definition has no type or storage class");
2595 : : }
2596 : : /* Having seen a data definition, there cannot now be a
2597 : : function definition. */
2598 : 25112982 : fndef_ok = false;
2599 : 25112982 : if (c_parser_next_token_is_keyword (parser, RID_ASM))
2600 : 688185 : asm_name = c_parser_simple_asm_expr (parser);
2601 : 25112982 : if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
2602 : : {
2603 : 11061143 : postfix_attrs = c_parser_gnu_attributes (parser);
2604 : 11061143 : if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
2605 : : {
2606 : : /* This means there is an attribute specifier after
2607 : : the declarator in a function definition. Provide
2608 : : some more information for the user. */
2609 : 1 : error_at (here, "attributes should be specified before the "
2610 : : "declarator in a function definition");
2611 : 1 : c_parser_skip_to_end_of_block_or_statement (parser);
2612 : 1 : return;
2613 : : }
2614 : : }
2615 : 25112981 : if (c_parser_next_token_is (parser, CPP_EQ))
2616 : : {
2617 : 6132658 : tree d;
2618 : 6132658 : struct c_expr init;
2619 : 6132658 : location_t init_loc;
2620 : 6132658 : c_parser_consume_token (parser);
2621 : 6132658 : if (any_auto_type_p)
2622 : : {
2623 : 1847 : init_loc = c_parser_peek_token (parser)->location;
2624 : 1847 : rich_location richloc (line_table, init_loc);
2625 : 1847 : unsigned int underspec_state = 0;
2626 : 1847 : if (std_auto_type_p)
2627 : 63 : underspec_state =
2628 : 63 : start_underspecified_init (init_loc, underspec_name);
2629 : 1847 : start_init (NULL_TREE, asm_name,
2630 : 1847 : (global_bindings_p ()
2631 : 1783 : || specs->storage_class == csc_static
2632 : 3628 : || specs->constexpr_p),
2633 : 1847 : specs->constexpr_p, &richloc);
2634 : : /* A parameter is initialized, which is invalid. Don't
2635 : : attempt to instrument the initializer. */
2636 : 1847 : int flag_sanitize_save = flag_sanitize;
2637 : 1847 : if (nested && !empty_ok)
2638 : 14 : flag_sanitize = 0;
2639 : 1847 : init = c_parser_expr_no_commas (parser, NULL);
2640 : 1847 : if (std_auto_type_p)
2641 : 63 : finish_underspecified_init (underspec_name,
2642 : : underspec_state);
2643 : 1847 : flag_sanitize = flag_sanitize_save;
2644 : 1847 : if (gnu_auto_type_p
2645 : 1784 : && TREE_CODE (init.value) == COMPONENT_REF
2646 : 1848 : && DECL_C_BIT_FIELD (TREE_OPERAND (init.value, 1)))
2647 : 1 : error_at (here,
2648 : : "%<__auto_type%> used with a bit-field"
2649 : : " initializer");
2650 : 1847 : init = convert_lvalue_to_rvalue (init_loc, init, true, true,
2651 : : true);
2652 : 1847 : tree init_type = TREE_TYPE (init.value);
2653 : 1847 : bool vm_type = c_type_variably_modified_p (init_type);
2654 : 1847 : if (vm_type)
2655 : 94 : init.value = save_expr (init.value);
2656 : 1847 : finish_init ();
2657 : 1847 : specs->typespec_kind = ctsk_typeof;
2658 : 1847 : specs->locations[cdw_typedef] = init_loc;
2659 : 1847 : specs->typedef_p = true;
2660 : 1847 : specs->type = init_type;
2661 : 1847 : if (specs->postfix_attrs)
2662 : : {
2663 : : /* Postfix [[]] attributes are valid with C23
2664 : : auto, although not with __auto_type, and
2665 : : modify the type given by the initializer. */
2666 : 4 : specs->postfix_attrs =
2667 : 2 : c_warn_type_attributes (specs->postfix_attrs);
2668 : 2 : decl_attributes (&specs->type, specs->postfix_attrs, 0);
2669 : 2 : specs->postfix_attrs = NULL_TREE;
2670 : : }
2671 : 1847 : if (vm_type)
2672 : : {
2673 : 94 : bool maybe_const = true;
2674 : 94 : tree type_expr = c_fully_fold (init.value, false,
2675 : : &maybe_const);
2676 : 94 : specs->expr_const_operands &= maybe_const;
2677 : 94 : if (specs->expr)
2678 : 0 : specs->expr = build2 (COMPOUND_EXPR,
2679 : 0 : TREE_TYPE (type_expr),
2680 : : specs->expr, type_expr);
2681 : : else
2682 : 94 : specs->expr = type_expr;
2683 : : }
2684 : 1847 : d = start_decl (declarator, specs, true,
2685 : : chainon (postfix_attrs, all_prefix_attrs));
2686 : 1847 : if (!d)
2687 : 12 : d = error_mark_node;
2688 : 1847 : if (omp_declare_simd_clauses)
2689 : 0 : c_finish_omp_declare_simd (parser, d, NULL_TREE,
2690 : : omp_declare_simd_clauses);
2691 : 1847 : if (!omp_dsimd_idattr_clauses.is_empty ())
2692 : 0 : c_finish_omp_declare_simd (parser, d, NULL_TREE,
2693 : : &omp_dsimd_idattr_clauses);
2694 : 1847 : }
2695 : : else
2696 : : {
2697 : : /* The declaration of the variable is in effect while
2698 : : its initializer is parsed, except for a constexpr
2699 : : variable. */
2700 : 6130811 : init_loc = c_parser_peek_token (parser)->location;
2701 : 6130811 : rich_location richloc (line_table, init_loc);
2702 : 6130811 : unsigned int underspec_state = 0;
2703 : 6130811 : if (specs->constexpr_p)
2704 : 311 : underspec_state =
2705 : 311 : start_underspecified_init (init_loc, underspec_name);
2706 : 6130811 : d = start_decl (declarator, specs, true,
2707 : : chainon (postfix_attrs,
2708 : : all_prefix_attrs),
2709 : 6130811 : !specs->constexpr_p);
2710 : 6130811 : if (!d)
2711 : 4 : d = error_mark_node;
2712 : 6130811 : if (!specs->constexpr_p && omp_declare_simd_clauses)
2713 : 0 : c_finish_omp_declare_simd (parser, d, NULL_TREE,
2714 : : omp_declare_simd_clauses);
2715 : 6130811 : if (!specs->constexpr_p
2716 : 6130811 : && !omp_dsimd_idattr_clauses.is_empty ())
2717 : 0 : c_finish_omp_declare_simd (parser, d, NULL_TREE,
2718 : : &omp_dsimd_idattr_clauses);
2719 : 6130811 : start_init (d, asm_name,
2720 : 5958176 : TREE_STATIC (d) || specs->constexpr_p,
2721 : 6130811 : specs->constexpr_p, &richloc);
2722 : : /* A parameter is initialized, which is invalid. Don't
2723 : : attempt to instrument the initializer. */
2724 : 6130811 : int flag_sanitize_save = flag_sanitize;
2725 : 6130811 : if (TREE_CODE (d) == PARM_DECL)
2726 : 35 : flag_sanitize = 0;
2727 : 6130811 : init = c_parser_initializer (parser, d);
2728 : 6130809 : flag_sanitize = flag_sanitize_save;
2729 : 6130809 : if (specs->constexpr_p)
2730 : : {
2731 : 311 : finish_underspecified_init (underspec_name,
2732 : : underspec_state);
2733 : 311 : d = pushdecl (d);
2734 : 311 : if (omp_declare_simd_clauses)
2735 : 0 : c_finish_omp_declare_simd (parser, d, NULL_TREE,
2736 : : omp_declare_simd_clauses);
2737 : 311 : if (!specs->constexpr_p
2738 : 311 : && !omp_dsimd_idattr_clauses.is_empty ())
2739 : 0 : c_finish_omp_declare_simd (parser, d, NULL_TREE,
2740 : : &omp_dsimd_idattr_clauses);
2741 : : }
2742 : 6130809 : finish_init ();
2743 : 6130809 : }
2744 : 6132656 : if (oacc_routine_data)
2745 : 0 : c_finish_oacc_routine (oacc_routine_data, d, false);
2746 : 6132656 : if (d != error_mark_node)
2747 : : {
2748 : 6132640 : maybe_warn_string_init (init_loc, TREE_TYPE (d), init);
2749 : 6132640 : finish_decl (d, init_loc, init.value,
2750 : : init.original_type, asm_name);
2751 : : }
2752 : : }
2753 : : else
2754 : : {
2755 : 18980323 : if (any_auto_type_p || specs->constexpr_p)
2756 : : {
2757 : 6 : error_at (here,
2758 : : "%qs requires an initialized data declaration",
2759 : : any_auto_type_p ? auto_type_keyword : "constexpr");
2760 : 4 : c_parser_skip_to_end_of_block_or_statement (parser);
2761 : 4 : return;
2762 : : }
2763 : :
2764 : 18980319 : location_t lastloc = UNKNOWN_LOCATION;
2765 : 18980319 : tree attrs = chainon (postfix_attrs, all_prefix_attrs);
2766 : 18980319 : tree d = start_decl (declarator, specs, false, attrs, true,
2767 : : &lastloc);
2768 : 18980319 : if (d && TREE_CODE (d) == FUNCTION_DECL)
2769 : : {
2770 : : /* Find the innermost declarator that is neither cdk_id
2771 : : nor cdk_attrs. */
2772 : : const struct c_declarator *decl = declarator;
2773 : : const struct c_declarator *last_non_id_attrs = NULL;
2774 : :
2775 : 25202621 : while (decl)
2776 : 25202621 : switch (decl->kind)
2777 : : {
2778 : 12789531 : case cdk_array:
2779 : 12789531 : case cdk_function:
2780 : 12789531 : case cdk_pointer:
2781 : 12789531 : last_non_id_attrs = decl;
2782 : 12789531 : decl = decl->declarator;
2783 : 12789531 : break;
2784 : :
2785 : 68 : case cdk_attrs:
2786 : 68 : decl = decl->declarator;
2787 : 68 : break;
2788 : :
2789 : : case cdk_id:
2790 : : decl = 0;
2791 : : break;
2792 : :
2793 : 0 : default:
2794 : 0 : gcc_unreachable ();
2795 : : }
2796 : :
2797 : : /* If it exists and is cdk_function declaration whose
2798 : : arguments have not been set yet, use its arguments. */
2799 : 12413022 : if (last_non_id_attrs
2800 : 11885283 : && last_non_id_attrs->kind == cdk_function)
2801 : : {
2802 : 11885283 : tree parms = last_non_id_attrs->u.arg_info->parms;
2803 : 11885283 : if (DECL_ARGUMENTS (d) == NULL_TREE
2804 : 11885283 : && DECL_INITIAL (d) == NULL_TREE)
2805 : 11756185 : DECL_ARGUMENTS (d) = parms;
2806 : :
2807 : 11885283 : warn_parm_array_mismatch (lastloc, d, parms);
2808 : : }
2809 : : }
2810 : 18980319 : if (omp_declare_simd_clauses
2811 : 18980319 : || !omp_dsimd_idattr_clauses.is_empty ())
2812 : : {
2813 : 410 : tree parms = NULL_TREE;
2814 : 410 : if (d && TREE_CODE (d) == FUNCTION_DECL)
2815 : : {
2816 : : struct c_declarator *ce = declarator;
2817 : 398 : while (ce != NULL)
2818 : 398 : if (ce->kind == cdk_function)
2819 : : {
2820 : 396 : parms = ce->u.arg_info->parms;
2821 : 396 : break;
2822 : : }
2823 : : else
2824 : 2 : ce = ce->declarator;
2825 : : }
2826 : 396 : if (parms)
2827 : 187 : temp_store_parm_decls (d, parms);
2828 : 410 : if (omp_declare_simd_clauses)
2829 : 390 : c_finish_omp_declare_simd (parser, d, parms,
2830 : : omp_declare_simd_clauses);
2831 : 410 : if (!specs->constexpr_p
2832 : 410 : && !omp_dsimd_idattr_clauses.is_empty ())
2833 : 22 : c_finish_omp_declare_simd (parser, d, parms,
2834 : : &omp_dsimd_idattr_clauses);
2835 : 410 : if (parms)
2836 : 187 : temp_pop_parm_decls ();
2837 : : }
2838 : 18980319 : if (oacc_routine_data)
2839 : 72 : c_finish_oacc_routine (oacc_routine_data, d, false);
2840 : 18980319 : if (d)
2841 : 18980312 : finish_decl (d, UNKNOWN_LOCATION, NULL_TREE,
2842 : : NULL_TREE, asm_name);
2843 : :
2844 : 18980319 : if (c_parser_next_token_is_keyword (parser, RID_IN))
2845 : : {
2846 : 0 : if (d)
2847 : 0 : *objc_foreach_object_declaration = d;
2848 : : else
2849 : 0 : *objc_foreach_object_declaration = error_mark_node;
2850 : : }
2851 : : }
2852 : 25112975 : if (c_parser_next_token_is (parser, CPP_COMMA))
2853 : : {
2854 : 442140 : if (any_auto_type_p || specs->constexpr_p)
2855 : : {
2856 : 4 : error_at (here,
2857 : : "%qs may only be used with a single declarator",
2858 : : any_auto_type_p ? auto_type_keyword : "constexpr");
2859 : 3 : c_parser_skip_to_end_of_block_or_statement (parser);
2860 : 3 : return;
2861 : : }
2862 : 442137 : c_parser_consume_token (parser);
2863 : 442137 : if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
2864 : 19 : all_prefix_attrs = chainon (c_parser_gnu_attributes (parser),
2865 : : prefix_attrs);
2866 : : else
2867 : : all_prefix_attrs = prefix_attrs;
2868 : 442137 : continue;
2869 : : }
2870 : 24670835 : else if (c_parser_next_token_is (parser, CPP_SEMICOLON))
2871 : : {
2872 : 24670787 : c_parser_consume_token (parser);
2873 : 24670787 : return;
2874 : : }
2875 : 48 : else if (c_parser_next_token_is_keyword (parser, RID_IN))
2876 : : {
2877 : : /* This can only happen in Objective-C: we found the
2878 : : 'in' that terminates the declaration inside an
2879 : : Objective-C foreach statement. Do not consume the
2880 : : token, so that the caller can use it to determine
2881 : : that this indeed is a foreach context. */
2882 : : return;
2883 : : }
2884 : : else
2885 : : {
2886 : 48 : c_parser_error (parser, "expected %<,%> or %<;%>");
2887 : 48 : c_parser_skip_to_end_of_block_or_statement (parser);
2888 : 48 : return;
2889 : : }
2890 : : }
2891 : 31765248 : else if (any_auto_type_p || specs->constexpr_p)
2892 : : {
2893 : 4 : error_at (here,
2894 : : "%qs requires an initialized data declaration",
2895 : : any_auto_type_p ? auto_type_keyword : "constexpr");
2896 : 4 : c_parser_skip_to_end_of_block_or_statement (parser);
2897 : 4 : return;
2898 : : }
2899 : 31765244 : else if (!fndef_ok)
2900 : : {
2901 : 14 : c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, "
2902 : : "%<asm%> or %<__attribute__%>");
2903 : 14 : c_parser_skip_to_end_of_block_or_statement (parser);
2904 : 14 : return;
2905 : : }
2906 : : /* Function definition (nested or otherwise). */
2907 : 31765230 : if (nested)
2908 : : {
2909 : 1512 : pedwarn (here, OPT_Wpedantic, "ISO C forbids nested functions");
2910 : 1512 : c_push_function_context ();
2911 : : }
2912 : 31765230 : if (!start_function (specs, declarator, all_prefix_attrs))
2913 : : {
2914 : : /* At this point we've consumed:
2915 : : declaration-specifiers declarator
2916 : : and the next token isn't CPP_EQ, CPP_COMMA, CPP_SEMICOLON,
2917 : : RID_ASM, RID_ATTRIBUTE, or RID_IN,
2918 : : but the
2919 : : declaration-specifiers declarator
2920 : : aren't grokkable as a function definition, so we have
2921 : : an error. */
2922 : 38 : gcc_assert (!c_parser_next_token_is (parser, CPP_SEMICOLON));
2923 : 38 : if (c_parser_next_token_starts_declspecs (parser))
2924 : : {
2925 : : /* If we have
2926 : : declaration-specifiers declarator decl-specs
2927 : : then assume we have a missing semicolon, which would
2928 : : give us:
2929 : : declaration-specifiers declarator decl-specs
2930 : : ^
2931 : : ;
2932 : : <~~~~~~~~~ declaration ~~~~~~~~~~>
2933 : : Use c_parser_require to get an error with a fix-it hint. */
2934 : 13 : c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>");
2935 : 13 : parser->error = false;
2936 : : }
2937 : : else
2938 : : {
2939 : : /* This can appear in many cases looking nothing like a
2940 : : function definition, so we don't give a more specific
2941 : : error suggesting there was one. */
2942 : 25 : c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, %<asm%> "
2943 : : "or %<__attribute__%>");
2944 : : }
2945 : 38 : if (nested)
2946 : 1 : c_pop_function_context ();
2947 : : break;
2948 : : }
2949 : :
2950 : 31765192 : if (DECL_DECLARED_INLINE_P (current_function_decl))
2951 : : tv = TV_PARSE_INLINE;
2952 : : else
2953 : 653660 : tv = TV_PARSE_FUNC;
2954 : 31765192 : auto_timevar at (g_timer, tv);
2955 : :
2956 : : /* Parse old-style parameter declarations. ??? Attributes are
2957 : : not allowed to start declaration specifiers here because of a
2958 : : syntax conflict between a function declaration with attribute
2959 : : suffix and a function definition with an attribute prefix on
2960 : : first old-style parameter declaration. Following the old
2961 : : parser, they are not accepted on subsequent old-style
2962 : : parameter declarations either. However, there is no
2963 : : ambiguity after the first declaration, nor indeed on the
2964 : : first as long as we don't allow postfix attributes after a
2965 : : declarator with a nonempty identifier list in a definition;
2966 : : and postfix attributes have never been accepted here in
2967 : : function definitions either. */
2968 : 31765192 : int save_debug_nonbind_markers_p = debug_nonbind_markers_p;
2969 : 31765192 : debug_nonbind_markers_p = 0;
2970 : 31765192 : while (c_parser_next_token_is_not (parser, CPP_EOF)
2971 : 63556424 : && c_parser_next_token_is_not (parser, CPP_OPEN_BRACE))
2972 : 13028 : c_parser_declaration_or_fndef (parser, false, false, false,
2973 : : true, false);
2974 : 31765192 : debug_nonbind_markers_p = save_debug_nonbind_markers_p;
2975 : 31765192 : store_parm_decls ();
2976 : 31765192 : if (omp_declare_simd_clauses)
2977 : 198 : c_finish_omp_declare_simd (parser, current_function_decl, NULL_TREE,
2978 : : omp_declare_simd_clauses);
2979 : 31765192 : if (!omp_dsimd_idattr_clauses.is_empty ())
2980 : 4 : c_finish_omp_declare_simd (parser, current_function_decl, NULL_TREE,
2981 : : &omp_dsimd_idattr_clauses);
2982 : 31765192 : if (oacc_routine_data)
2983 : 117 : c_finish_oacc_routine (oacc_routine_data, current_function_decl, true);
2984 : 31765192 : location_t startloc = c_parser_peek_token (parser)->location;
2985 : 31765192 : DECL_STRUCT_FUNCTION (current_function_decl)->function_start_locus
2986 : 31765192 : = startloc;
2987 : 31765192 : location_t endloc = startloc;
2988 : :
2989 : : /* If the definition was marked with __RTL, use the RTL parser now,
2990 : : consuming the function body. */
2991 : 31765192 : if (specs->declspec_il == cdil_rtl)
2992 : : {
2993 : 18 : endloc = c_parser_parse_rtl_body (parser, specs->gimple_or_rtl_pass);
2994 : :
2995 : : /* Normally, store_parm_decls sets next_is_function_body,
2996 : : anticipating a function body. We need a push_scope/pop_scope
2997 : : pair to flush out this state, or subsequent function parsing
2998 : : will go wrong. */
2999 : 17 : push_scope ();
3000 : 17 : pop_scope ();
3001 : :
3002 : 17 : finish_function (endloc);
3003 : 17 : return;
3004 : : }
3005 : : /* If the definition was marked with __GIMPLE then parse the
3006 : : function body as GIMPLE. */
3007 : 31765174 : else if (specs->declspec_il != cdil_none)
3008 : : {
3009 : 181 : bool saved = in_late_binary_op;
3010 : 181 : in_late_binary_op = true;
3011 : 181 : c_parser_parse_gimple_body (parser, specs->gimple_or_rtl_pass,
3012 : 181 : specs->declspec_il,
3013 : : specs->entry_bb_count);
3014 : 181 : in_late_binary_op = saved;
3015 : : }
3016 : : else
3017 : 31764993 : fnbody = c_parser_compound_statement (parser, &endloc);
3018 : 31765173 : tree fndecl = current_function_decl;
3019 : 31765173 : if (nested)
3020 : : {
3021 : 1511 : tree decl = current_function_decl;
3022 : : /* Mark nested functions as needing static-chain initially.
3023 : : lower_nested_functions will recompute it but the
3024 : : DECL_STATIC_CHAIN flag is also used before that happens,
3025 : : by initializer_constant_valid_p. See gcc.dg/nested-fn-2.c. */
3026 : 1511 : DECL_STATIC_CHAIN (decl) = 1;
3027 : 1511 : add_stmt (fnbody);
3028 : 1511 : finish_function (endloc);
3029 : 1511 : c_pop_function_context ();
3030 : 1511 : add_stmt (build_stmt (DECL_SOURCE_LOCATION (decl), DECL_EXPR, decl));
3031 : : }
3032 : : else
3033 : : {
3034 : 31763662 : if (fnbody)
3035 : 31763481 : add_stmt (fnbody);
3036 : 31763662 : finish_function (endloc);
3037 : : }
3038 : : /* Get rid of the empty stmt list for GIMPLE/RTL. */
3039 : 31765173 : if (specs->declspec_il != cdil_none)
3040 : 181 : DECL_SAVED_TREE (fndecl) = NULL_TREE;
3041 : :
3042 : 31765173 : break;
3043 : 56878422 : }
3044 : : }
3045 : :
3046 : : /* Parse an asm-definition (asm() outside a function body). This is a
3047 : : GNU extension.
3048 : :
3049 : : asm-definition:
3050 : : simple-asm-expr ;
3051 : : */
3052 : :
3053 : : static void
3054 : 141 : c_parser_asm_definition (c_parser *parser)
3055 : : {
3056 : 141 : tree asm_str = c_parser_simple_asm_expr (parser);
3057 : 141 : if (asm_str)
3058 : 135 : symtab->finalize_toplevel_asm (asm_str);
3059 : 141 : c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
3060 : 141 : }
3061 : :
3062 : : /* Parse a static assertion (C11 6.7.10).
3063 : :
3064 : : static_assert-declaration:
3065 : : static_assert-declaration-no-semi ;
3066 : : */
3067 : :
3068 : : static void
3069 : 1668 : c_parser_static_assert_declaration (c_parser *parser)
3070 : : {
3071 : 1668 : c_parser_static_assert_declaration_no_semi (parser);
3072 : 1668 : if (parser->error
3073 : 1668 : || !c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
3074 : 8 : c_parser_skip_to_end_of_block_or_statement (parser);
3075 : 1668 : }
3076 : :
3077 : : /* Parse a static assertion (C11 6.7.10), without the trailing
3078 : : semicolon.
3079 : :
3080 : : static_assert-declaration-no-semi:
3081 : : _Static_assert ( constant-expression , string-literal )
3082 : :
3083 : : C23:
3084 : : static_assert-declaration-no-semi:
3085 : : _Static_assert ( constant-expression )
3086 : : */
3087 : :
3088 : : static void
3089 : 1678 : c_parser_static_assert_declaration_no_semi (c_parser *parser)
3090 : : {
3091 : 1678 : location_t assert_loc, value_loc;
3092 : 1678 : tree value;
3093 : 1678 : tree string = NULL_TREE;
3094 : :
3095 : 1678 : gcc_assert (c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT));
3096 : 1678 : tree spelling = c_parser_peek_token (parser)->value;
3097 : 1678 : assert_loc = c_parser_peek_token (parser)->location;
3098 : 1678 : if (flag_isoc99)
3099 : 1675 : pedwarn_c99 (assert_loc, OPT_Wpedantic,
3100 : : "ISO C99 does not support %qE", spelling);
3101 : : else
3102 : 3 : pedwarn_c99 (assert_loc, OPT_Wpedantic,
3103 : : "ISO C90 does not support %qE", spelling);
3104 : 1678 : c_parser_consume_token (parser);
3105 : 1678 : matching_parens parens;
3106 : 1678 : if (!parens.require_open (parser))
3107 : 11 : return;
3108 : 1677 : location_t value_tok_loc = c_parser_peek_token (parser)->location;
3109 : 1677 : value = convert_lvalue_to_rvalue (value_tok_loc,
3110 : : c_parser_expr_no_commas (parser, NULL),
3111 : : true, true).value;
3112 : 1677 : value_loc = EXPR_LOC_OR_LOC (value, value_tok_loc);
3113 : 1677 : if (c_parser_next_token_is (parser, CPP_COMMA))
3114 : : {
3115 : 1429 : c_parser_consume_token (parser);
3116 : 1429 : switch (c_parser_peek_token (parser)->type)
3117 : : {
3118 : 1426 : case CPP_STRING:
3119 : 1426 : case CPP_STRING16:
3120 : 1426 : case CPP_STRING32:
3121 : 1426 : case CPP_WSTRING:
3122 : 1426 : case CPP_UTF8STRING:
3123 : 1426 : string = c_parser_string_literal (parser, false, true).value;
3124 : 1426 : break;
3125 : 3 : default:
3126 : 3 : c_parser_error (parser, "expected string literal");
3127 : 3 : return;
3128 : : }
3129 : : }
3130 : 248 : else if (flag_isoc11)
3131 : : /* If pedantic for pre-C11, the use of _Static_assert itself will
3132 : : have been diagnosed, so do not also diagnose the use of this
3133 : : new C23 feature of _Static_assert. */
3134 : 247 : pedwarn_c11 (assert_loc, OPT_Wpedantic,
3135 : : "ISO C11 does not support omitting the string in "
3136 : : "%qE", spelling);
3137 : 1674 : parens.require_close (parser);
3138 : :
3139 : 1674 : if (!INTEGRAL_TYPE_P (TREE_TYPE (value)))
3140 : : {
3141 : 3 : error_at (value_loc, "expression in static assertion is not an integer");
3142 : 3 : return;
3143 : : }
3144 : 1671 : if (TREE_CODE (value) != INTEGER_CST)
3145 : : {
3146 : 9 : value = c_fully_fold (value, false, NULL);
3147 : : /* Strip no-op conversions. */
3148 : 18 : STRIP_TYPE_NOPS (value);
3149 : 9 : if (TREE_CODE (value) == INTEGER_CST)
3150 : 5 : pedwarn (value_loc, OPT_Wpedantic, "expression in static assertion "
3151 : : "is not an integer constant expression");
3152 : : }
3153 : 1671 : if (TREE_CODE (value) != INTEGER_CST)
3154 : : {
3155 : 4 : error_at (value_loc, "expression in static assertion is not constant");
3156 : 4 : return;
3157 : : }
3158 : 1667 : constant_expression_warning (value);
3159 : 1667 : if (integer_zerop (value))
3160 : : {
3161 : 11 : if (string)
3162 : 9 : error_at (assert_loc, "static assertion failed: %E", string);
3163 : : else
3164 : 2 : error_at (assert_loc, "static assertion failed");
3165 : : }
3166 : : }
3167 : :
3168 : : /* Parse some declaration specifiers (possibly none) (C90 6.5, C99
3169 : : 6.7, C11 6.7), adding them to SPECS (which may already include some).
3170 : : Storage class specifiers are accepted iff SCSPEC_OK; type
3171 : : specifiers are accepted iff TYPESPEC_OK; alignment specifiers are
3172 : : accepted iff ALIGNSPEC_OK; gnu-attributes are accepted at the start
3173 : : iff START_ATTR_OK; __auto_type is accepted iff AUTO_TYPE_OK. In
3174 : : addition to the syntax shown, standard attributes are accepted at
3175 : : the start iff START_STD_ATTR_OK and at the end iff END_STD_ATTR_OK;
3176 : : unlike gnu-attributes, they are not accepted in the middle of the
3177 : : list. (This combines various different syntax productions in the C
3178 : : standard, and in some cases gnu-attributes and standard attributes
3179 : : at the start may already have been parsed before this function is
3180 : : called.)
3181 : :
3182 : : declaration-specifiers:
3183 : : storage-class-specifier declaration-specifiers[opt]
3184 : : type-specifier declaration-specifiers[opt]
3185 : : type-qualifier declaration-specifiers[opt]
3186 : : function-specifier declaration-specifiers[opt]
3187 : : alignment-specifier declaration-specifiers[opt]
3188 : :
3189 : : Function specifiers (inline) are from C99, and are currently
3190 : : handled as storage class specifiers, as is __thread. Alignment
3191 : : specifiers are from C11.
3192 : :
3193 : : C90 6.5.1, C99 6.7.1, C11 6.7.1:
3194 : : storage-class-specifier:
3195 : : typedef
3196 : : extern
3197 : : static
3198 : : auto
3199 : : register
3200 : : _Thread_local
3201 : :
3202 : : (_Thread_local is new in C11.)
3203 : :
3204 : : C99 6.7.4, C11 6.7.4:
3205 : : function-specifier:
3206 : : inline
3207 : : _Noreturn
3208 : :
3209 : : (_Noreturn is new in C11.)
3210 : :
3211 : : C90 6.5.2, C99 6.7.2, C11 6.7.2:
3212 : : type-specifier:
3213 : : void
3214 : : char
3215 : : short
3216 : : int
3217 : : long
3218 : : float
3219 : : double
3220 : : signed
3221 : : unsigned
3222 : : _Bool
3223 : : _Complex
3224 : : [_Imaginary removed in C99 TC2]
3225 : : _BitInt ( constant-expression )
3226 : : struct-or-union-specifier
3227 : : enum-specifier
3228 : : typedef-name
3229 : : atomic-type-specifier
3230 : :
3231 : : (_Bool and _Complex are new in C99.)
3232 : : (atomic-type-specifier is new in C11.)
3233 : : (_BitInt is new in C23.)
3234 : :
3235 : : C90 6.5.3, C99 6.7.3, C11 6.7.3:
3236 : :
3237 : : type-qualifier:
3238 : : const
3239 : : restrict
3240 : : volatile
3241 : : address-space-qualifier
3242 : : _Atomic
3243 : :
3244 : : (restrict is new in C99.)
3245 : : (_Atomic is new in C11.)
3246 : :
3247 : : GNU extensions:
3248 : :
3249 : : declaration-specifiers:
3250 : : gnu-attributes declaration-specifiers[opt]
3251 : :
3252 : : type-qualifier:
3253 : : address-space
3254 : :
3255 : : address-space:
3256 : : identifier recognized by the target
3257 : :
3258 : : storage-class-specifier:
3259 : : __thread
3260 : :
3261 : : type-specifier:
3262 : : typeof-specifier
3263 : : __auto_type
3264 : : __intN
3265 : : _Decimal32
3266 : : _Decimal64
3267 : : _Decimal128
3268 : : _Fract
3269 : : _Accum
3270 : : _Sat
3271 : :
3272 : : (_Fract, _Accum, and _Sat are new from ISO/IEC DTR 18037:
3273 : : http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1169.pdf)
3274 : :
3275 : : atomic-type-specifier
3276 : : _Atomic ( type-name )
3277 : :
3278 : : Objective-C:
3279 : :
3280 : : type-specifier:
3281 : : class-name objc-protocol-refs[opt]
3282 : : typedef-name objc-protocol-refs
3283 : : objc-protocol-refs
3284 : : */
3285 : :
3286 : : void
3287 : 292013713 : c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
3288 : : bool scspec_ok, bool typespec_ok, bool start_attr_ok,
3289 : : bool alignspec_ok, bool auto_type_ok,
3290 : : bool start_std_attr_ok, bool end_std_attr_ok,
3291 : : enum c_lookahead_kind la)
3292 : : {
3293 : 292013713 : bool attrs_ok = start_attr_ok;
3294 : 292013713 : bool seen_type = specs->typespec_kind != ctsk_none;
3295 : :
3296 : 292013713 : if (!typespec_ok)
3297 : 17633681 : gcc_assert (la == cla_prefer_id);
3298 : :
3299 : 292013713 : if (start_std_attr_ok
3300 : 292013713 : && c_parser_nth_token_starts_std_attributes (parser, 1))
3301 : : {
3302 : 365 : gcc_assert (!specs->non_std_attrs_seen_p);
3303 : 365 : location_t loc = c_parser_peek_token (parser)->location;
3304 : 365 : tree attrs = c_parser_std_attribute_specifier_sequence (parser);
3305 : 365 : declspecs_add_attrs (loc, specs, attrs);
3306 : 365 : specs->non_std_attrs_seen_p = false;
3307 : : }
3308 : :
3309 : 706356426 : while (c_parser_next_token_is (parser, CPP_NAME)
3310 : 328176130 : || c_parser_next_token_is (parser, CPP_KEYWORD)
3311 : 833717551 : || (c_dialect_objc () && c_parser_next_token_is (parser, CPP_LESS)))
3312 : : {
3313 : 578995301 : struct c_typespec t;
3314 : 578995301 : tree attrs;
3315 : 578995301 : tree align;
3316 : 578995301 : location_t loc = c_parser_peek_token (parser)->location;
3317 : :
3318 : : /* If we cannot accept a type, exit if the next token must start
3319 : : one. Also, if we already have seen a tagged definition,
3320 : : a typename would be an error anyway and likely the user
3321 : : has simply forgotten a semicolon, so we exit. */
3322 : 564367314 : if ((!typespec_ok || specs->typespec_kind == ctsk_tagdef)
3323 : 15460957 : && c_parser_next_tokens_start_typename (parser, la)
3324 : 3386387 : && !c_parser_next_token_is_qualifier (parser)
3325 : 578995352 : && !c_parser_next_token_is_keyword (parser, RID_ALIGNAS))
3326 : : break;
3327 : :
3328 : 578995259 : if (c_parser_next_token_is (parser, CPP_NAME))
3329 : : {
3330 : 378180263 : c_token *name_token = c_parser_peek_token (parser);
3331 : 378180263 : tree value = name_token->value;
3332 : 378180263 : c_id_kind kind = name_token->id_kind;
3333 : :
3334 : 378180263 : if (kind == C_ID_ADDRSPACE)
3335 : : {
3336 : 164 : addr_space_t as
3337 : 164 : = name_token->keyword - RID_FIRST_ADDR_SPACE;
3338 : 164 : declspecs_add_addrspace (name_token->location, specs, as);
3339 : 164 : c_parser_consume_token (parser);
3340 : 164 : attrs_ok = true;
3341 : 213530437 : continue;
3342 : 164 : }
3343 : :
3344 : 378180099 : gcc_assert (!c_parser_next_token_is_qualifier (parser));
3345 : :
3346 : : /* If we cannot accept a type, and the next token must start one,
3347 : : exit. Do the same if we already have seen a tagged definition,
3348 : : since it would be an error anyway and likely the user has simply
3349 : : forgotten a semicolon. */
3350 : 378180099 : if (seen_type || !c_parser_next_tokens_start_typename (parser, la))
3351 : : break;
3352 : :
3353 : : /* Now at an unknown typename (C_ID_ID), a C_ID_TYPENAME or
3354 : : a C_ID_CLASSNAME. */
3355 : 213530273 : c_parser_consume_token (parser);
3356 : 213530273 : seen_type = true;
3357 : 213530273 : attrs_ok = true;
3358 : 213530273 : if (kind == C_ID_ID)
3359 : : {
3360 : 48 : auto_diagnostic_group d;
3361 : 48 : name_hint hint = lookup_name_fuzzy (value, FUZZY_LOOKUP_TYPENAME,
3362 : 48 : loc);
3363 : 48 : if (const char *suggestion = hint.suggestion ())
3364 : : {
3365 : 2 : gcc_rich_location richloc (loc);
3366 : 2 : richloc.add_fixit_replace (suggestion);
3367 : 2 : error_at (&richloc,
3368 : : "unknown type name %qE; did you mean %qs?",
3369 : : value, suggestion);
3370 : 2 : }
3371 : : else
3372 : 46 : error_at (loc, "unknown type name %qE", value);
3373 : 48 : t.kind = ctsk_typedef;
3374 : 48 : t.spec = error_mark_node;
3375 : 48 : }
3376 : 213530225 : else if (kind == C_ID_TYPENAME
3377 : 213530225 : && (!c_dialect_objc ()
3378 : 0 : || c_parser_next_token_is_not (parser, CPP_LESS)))
3379 : : {
3380 : 213530225 : t.kind = ctsk_typedef;
3381 : : /* For a typedef name, record the meaning, not the name.
3382 : : In case of 'foo foo, bar;'. */
3383 : 213530225 : t.spec = lookup_name (value);
3384 : : }
3385 : : else
3386 : : {
3387 : 0 : tree proto = NULL_TREE;
3388 : 0 : gcc_assert (c_dialect_objc ());
3389 : 0 : t.kind = ctsk_objc;
3390 : 0 : if (c_parser_next_token_is (parser, CPP_LESS))
3391 : 0 : proto = c_parser_objc_protocol_refs (parser);
3392 : 0 : t.spec = objc_get_protocol_qualified_type (value, proto);
3393 : : }
3394 : 213530273 : t.expr = NULL_TREE;
3395 : 213530273 : t.expr_const_operands = true;
3396 : 213530273 : t.has_enum_type_specifier = false;
3397 : 213530273 : declspecs_add_type (name_token->location, specs, t);
3398 : 213530273 : continue;
3399 : 213530273 : }
3400 : 200814996 : if (c_parser_next_token_is (parser, CPP_LESS))
3401 : : {
3402 : : /* Make "<SomeProtocol>" equivalent to "id <SomeProtocol>" -
3403 : : nisse@lysator.liu.se. */
3404 : 0 : tree proto;
3405 : 0 : gcc_assert (c_dialect_objc ());
3406 : 0 : if (!typespec_ok || seen_type)
3407 : : break;
3408 : 0 : proto = c_parser_objc_protocol_refs (parser);
3409 : 0 : t.kind = ctsk_objc;
3410 : 0 : t.spec = objc_get_protocol_qualified_type (NULL_TREE, proto);
3411 : 0 : t.expr = NULL_TREE;
3412 : 0 : t.expr_const_operands = true;
3413 : 0 : t.has_enum_type_specifier = false;
3414 : 0 : declspecs_add_type (loc, specs, t);
3415 : 0 : continue;
3416 : 0 : }
3417 : 200814996 : gcc_assert (c_parser_next_token_is (parser, CPP_KEYWORD));
3418 : 200814996 : switch (c_parser_peek_token (parser)->keyword)
3419 : : {
3420 : 78764563 : case RID_STATIC:
3421 : 78764563 : case RID_EXTERN:
3422 : 78764563 : case RID_REGISTER:
3423 : 78764563 : case RID_TYPEDEF:
3424 : 78764563 : case RID_INLINE:
3425 : 78764563 : case RID_NORETURN:
3426 : 78764563 : case RID_AUTO:
3427 : 78764563 : case RID_THREAD:
3428 : 78764563 : case RID_CONSTEXPR:
3429 : 78764563 : if (!scspec_ok)
3430 : 2720 : goto out;
3431 : 78764440 : attrs_ok = true;
3432 : : /* TODO: Distinguish between function specifiers (inline, noreturn)
3433 : : and storage class specifiers, either here or in
3434 : : declspecs_add_scspec. */
3435 : 78764440 : declspecs_add_scspec (loc, specs,
3436 : 78764440 : c_parser_peek_token (parser)->value);
3437 : 78764440 : c_parser_consume_token (parser);
3438 : 78764440 : break;
3439 : 1794 : case RID_AUTO_TYPE:
3440 : 1794 : if (!auto_type_ok)
3441 : 0 : goto out;
3442 : : /* Fall through. */
3443 : 73231823 : case RID_UNSIGNED:
3444 : 73231823 : case RID_LONG:
3445 : 73231823 : case RID_SHORT:
3446 : 73231823 : case RID_SIGNED:
3447 : 73231823 : case RID_COMPLEX:
3448 : 73231823 : case RID_INT:
3449 : 73231823 : case RID_CHAR:
3450 : 73231823 : case RID_FLOAT:
3451 : 73231823 : case RID_DOUBLE:
3452 : 73231823 : case RID_VOID:
3453 : 73231823 : case RID_DFLOAT32:
3454 : 73231823 : case RID_DFLOAT64:
3455 : 73231823 : case RID_DFLOAT128:
3456 : 73231823 : CASE_RID_FLOATN_NX:
3457 : 73231823 : case RID_BOOL:
3458 : 73231823 : case RID_FRACT:
3459 : 73231823 : case RID_ACCUM:
3460 : 73231823 : case RID_SAT:
3461 : 73231823 : case RID_INT_N_0:
3462 : 73231823 : case RID_INT_N_1:
3463 : 73231823 : case RID_INT_N_2:
3464 : 73231823 : case RID_INT_N_3:
3465 : 73231823 : if (!typespec_ok)
3466 : 0 : goto out;
3467 : 73231823 : attrs_ok = true;
3468 : 73231823 : seen_type = true;
3469 : 73231823 : if (c_dialect_objc ())
3470 : 0 : parser->objc_need_raw_identifier = true;
3471 : 73231823 : t.kind = ctsk_resword;
3472 : 73231823 : t.spec = c_parser_peek_token (parser)->value;
3473 : 73231823 : t.expr = NULL_TREE;
3474 : 73231823 : t.expr_const_operands = true;
3475 : 73231823 : t.has_enum_type_specifier = false;
3476 : 73231823 : declspecs_add_type (loc, specs, t);
3477 : 73231823 : c_parser_consume_token (parser);
3478 : 73231823 : break;
3479 : 216701 : case RID_ENUM:
3480 : 216701 : if (!typespec_ok)
3481 : 0 : goto out;
3482 : 216701 : attrs_ok = true;
3483 : 216701 : seen_type = true;
3484 : 216701 : t = c_parser_enum_specifier (parser);
3485 : 216701 : invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, t.spec);
3486 : 216701 : declspecs_add_type (loc, specs, t);
3487 : 216701 : break;
3488 : 2021553 : case RID_STRUCT:
3489 : 2021553 : case RID_UNION:
3490 : 2021553 : if (!typespec_ok)
3491 : 0 : goto out;
3492 : 2021553 : attrs_ok = true;
3493 : 2021553 : seen_type = true;
3494 : 2021553 : t = c_parser_struct_or_union_specifier (parser);
3495 : 2021553 : invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, t.spec);
3496 : 2021553 : declspecs_add_type (loc, specs, t);
3497 : 2021553 : break;
3498 : 671774 : case RID_TYPEOF:
3499 : 671774 : case RID_TYPEOF_UNQUAL:
3500 : : /* ??? The old parser rejected typeof after other type
3501 : : specifiers, but is a syntax error the best way of
3502 : : handling this? */
3503 : 671774 : if (!typespec_ok || seen_type)
3504 : 2 : goto out;
3505 : 671772 : attrs_ok = true;
3506 : 671772 : seen_type = true;
3507 : 671772 : t = c_parser_typeof_specifier (parser);
3508 : 671772 : declspecs_add_type (loc, specs, t);
3509 : 671772 : break;
3510 : 44897 : case RID_BITINT:
3511 : 44897 : if (!typespec_ok)
3512 : 0 : goto out;
3513 : : else
3514 : : {
3515 : 44897 : attrs_ok = true;
3516 : 44897 : seen_type = true;
3517 : 44897 : t.kind = ctsk_resword;
3518 : 44897 : t.spec = c_parser_peek_token (parser)->value;
3519 : 44897 : t.expr = error_mark_node;
3520 : 44897 : t.expr_const_operands = true;
3521 : 44897 : t.has_enum_type_specifier = false;
3522 : 44897 : c_parser_consume_token (parser);
3523 : 44897 : matching_parens parens;
3524 : 44897 : if (parens.require_open (parser))
3525 : : {
3526 : 44897 : c_expr expr = c_parser_expr_no_commas (parser, NULL);
3527 : 44897 : t.expr = convert_lvalue_to_rvalue (loc, expr, true,
3528 : 44897 : true).value;
3529 : 44897 : parens.skip_until_found_close (parser);
3530 : : }
3531 : 44897 : declspecs_add_type (loc, specs, t);
3532 : : }
3533 : 44897 : break;
3534 : 32249 : case RID_ATOMIC:
3535 : : /* C parser handling of Objective-C constructs needs
3536 : : checking for correct lvalue-to-rvalue conversions, and
3537 : : the code in build_modify_expr handling various
3538 : : Objective-C cases, and that in build_unary_op handling
3539 : : Objective-C cases for increment / decrement, also needs
3540 : : updating; uses of TYPE_MAIN_VARIANT in objc_compare_types
3541 : : and objc_types_are_equivalent may also need updates. */
3542 : 32249 : if (c_dialect_objc ())
3543 : 0 : sorry ("%<_Atomic%> in Objective-C");
3544 : 32249 : if (flag_isoc99)
3545 : 32198 : pedwarn_c99 (loc, OPT_Wpedantic,
3546 : : "ISO C99 does not support the %<_Atomic%> qualifier");
3547 : : else
3548 : 51 : pedwarn_c99 (loc, OPT_Wpedantic,
3549 : : "ISO C90 does not support the %<_Atomic%> qualifier");
3550 : 32249 : attrs_ok = true;
3551 : 32249 : tree value;
3552 : 32249 : value = c_parser_peek_token (parser)->value;
3553 : 32249 : c_parser_consume_token (parser);
3554 : 64298 : if (typespec_ok && c_parser_next_token_is (parser, CPP_OPEN_PAREN))
3555 : : {
3556 : : /* _Atomic ( type-name ). */
3557 : 13430 : seen_type = true;
3558 : 13430 : c_parser_consume_token (parser);
3559 : 13430 : struct c_type_name *type = c_parser_type_name (parser);
3560 : 13430 : t.kind = ctsk_typeof;
3561 : 13430 : t.spec = error_mark_node;
3562 : 13430 : t.expr = NULL_TREE;
3563 : 13430 : t.expr_const_operands = true;
3564 : 13430 : t.has_enum_type_specifier = false;
3565 : 13430 : if (type != NULL)
3566 : 13429 : t.spec = groktypename (type, &t.expr,
3567 : : &t.expr_const_operands);
3568 : 13430 : c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
3569 : : "expected %<)%>");
3570 : 13430 : if (t.spec != error_mark_node)
3571 : : {
3572 : 13429 : if (TREE_CODE (t.spec) == ARRAY_TYPE)
3573 : 1 : error_at (loc, "%<_Atomic%>-qualified array type");
3574 : 13428 : else if (TREE_CODE (t.spec) == FUNCTION_TYPE)
3575 : 1 : error_at (loc, "%<_Atomic%>-qualified function type");
3576 : 13427 : else if (TYPE_QUALS (t.spec) != TYPE_UNQUALIFIED)
3577 : 4 : error_at (loc, "%<_Atomic%> applied to a qualified type");
3578 : : else
3579 : 13423 : t.spec = c_build_qualified_type (t.spec, TYPE_QUAL_ATOMIC);
3580 : : }
3581 : 13430 : declspecs_add_type (loc, specs, t);
3582 : : }
3583 : : else
3584 : 18819 : declspecs_add_qual (loc, specs, value);
3585 : : break;
3586 : 14421787 : case RID_CONST:
3587 : 14421787 : case RID_VOLATILE:
3588 : 14421787 : case RID_RESTRICT:
3589 : 14421787 : attrs_ok = true;
3590 : 14421787 : declspecs_add_qual (loc, specs, c_parser_peek_token (parser)->value);
3591 : 14421787 : c_parser_consume_token (parser);
3592 : 14421787 : break;
3593 : 31406660 : case RID_ATTRIBUTE:
3594 : 31406660 : if (!attrs_ok)
3595 : 0 : goto out;
3596 : 31406660 : attrs = c_parser_gnu_attributes (parser);
3597 : 31406660 : declspecs_add_attrs (loc, specs, attrs);
3598 : 31406660 : break;
3599 : 210 : case RID_ALIGNAS:
3600 : 210 : if (!alignspec_ok)
3601 : 16 : goto out;
3602 : 194 : align = c_parser_alignas_specifier (parser);
3603 : 194 : declspecs_add_alignas (loc, specs, align);
3604 : 194 : break;
3605 : 182 : case RID_GIMPLE:
3606 : 182 : if (! flag_gimple)
3607 : 0 : error_at (loc, "%<__GIMPLE%> only valid with %<-fgimple%>");
3608 : 182 : c_parser_consume_token (parser);
3609 : 182 : specs->declspec_il = cdil_gimple;
3610 : 182 : specs->locations[cdw_gimple] = loc;
3611 : 182 : c_parser_gimple_or_rtl_pass_list (parser, specs);
3612 : 182 : break;
3613 : 18 : case RID_RTL:
3614 : 18 : c_parser_consume_token (parser);
3615 : 18 : specs->declspec_il = cdil_rtl;
3616 : 18 : specs->locations[cdw_rtl] = loc;
3617 : 18 : c_parser_gimple_or_rtl_pass_list (parser, specs);
3618 : 18 : break;
3619 : 2579 : default:
3620 : 2579 : goto out;
3621 : : }
3622 : : }
3623 : 292013713 : out:
3624 : 292013713 : if (end_std_attr_ok
3625 : 292013713 : && c_parser_nth_token_starts_std_attributes (parser, 1))
3626 : 100 : specs->postfix_attrs = c_parser_std_attribute_specifier_sequence (parser);
3627 : 292013713 : }
3628 : :
3629 : : /* Parse an enum specifier (C90 6.5.2.2, C99 6.7.2.2, C11 6.7.2.2).
3630 : :
3631 : : enum-specifier:
3632 : : enum gnu-attributes[opt] identifier[opt] enum-type-specifier[opt]
3633 : : { enumerator-list } gnu-attributes[opt]
3634 : : enum gnu-attributes[opt] identifier[opt] enum-type-specifier[opt]
3635 : : { enumerator-list , } gnu-attributes[opt] enum-type-specifier[opt]
3636 : : enum gnu-attributes[opt] identifier
3637 : :
3638 : : The form with trailing comma is new in C99; enum-type-specifiers
3639 : : are new in C23. The forms with gnu-attributes are GNU extensions.
3640 : : In GNU C, we accept any expression without commas in the syntax
3641 : : (assignment expressions, not just conditional expressions);
3642 : : assignment expressions will be diagnosed as non-constant.
3643 : :
3644 : : enum-type-specifier:
3645 : : : specifier-qualifier-list
3646 : :
3647 : : enumerator-list:
3648 : : enumerator
3649 : : enumerator-list , enumerator
3650 : :
3651 : : enumerator:
3652 : : enumeration-constant attribute-specifier-sequence[opt]
3653 : : enumeration-constant attribute-specifier-sequence[opt]
3654 : : = constant-expression
3655 : :
3656 : : GNU Extensions:
3657 : :
3658 : : enumerator:
3659 : : enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt]
3660 : : enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt]
3661 : : = constant-expression
3662 : :
3663 : : */
3664 : :
3665 : : static struct c_typespec
3666 : 216701 : c_parser_enum_specifier (c_parser *parser)
3667 : : {
3668 : 216701 : struct c_typespec ret;
3669 : 216701 : bool have_std_attrs;
3670 : 216701 : bool potential_nesting_p = false;
3671 : 216701 : tree std_attrs = NULL_TREE;
3672 : 216701 : tree attrs;
3673 : 216701 : tree ident = NULL_TREE;
3674 : 216701 : tree fixed_underlying_type = NULL_TREE;
3675 : 216701 : location_t enum_loc;
3676 : 216701 : location_t ident_loc = UNKNOWN_LOCATION; /* Quiet warning. */
3677 : 216701 : gcc_assert (c_parser_next_token_is_keyword (parser, RID_ENUM));
3678 : 216701 : c_parser_consume_token (parser);
3679 : 216701 : have_std_attrs = c_parser_nth_token_starts_std_attributes (parser, 1);
3680 : 216701 : if (have_std_attrs)
3681 : 11 : std_attrs = c_parser_std_attribute_specifier_sequence (parser);
3682 : 216701 : attrs = c_parser_gnu_attributes (parser);
3683 : 216701 : enum_loc = c_parser_peek_token (parser)->location;
3684 : : /* Set the location in case we create a decl now. */
3685 : 216701 : c_parser_set_source_position_from_token (c_parser_peek_token (parser));
3686 : 216701 : if (c_parser_next_token_is (parser, CPP_NAME))
3687 : : {
3688 : 120610 : ident = c_parser_peek_token (parser)->value;
3689 : 120610 : ident_loc = c_parser_peek_token (parser)->location;
3690 : 120610 : enum_loc = ident_loc;
3691 : 120610 : c_parser_consume_token (parser);
3692 : : }
3693 : 216701 : if (c_parser_next_token_is (parser, CPP_COLON)
3694 : : /* Distinguish an enum-type-specifier from a bit-field
3695 : : declaration of the form "enum e : constant-expression;". */
3696 : 216701 : && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
3697 : : {
3698 : 158 : pedwarn_c11 (enum_loc, OPT_Wpedantic,
3699 : : "ISO C does not support specifying %<enum%> underlying "
3700 : : "types before C23");
3701 : 158 : if (ident)
3702 : : {
3703 : : /* The tag is in scope during the enum-type-specifier (which
3704 : : may refer to the tag inside typeof). */
3705 : 154 : ret = parser_xref_tag (ident_loc, ENUMERAL_TYPE, ident,
3706 : : have_std_attrs, std_attrs, true);
3707 : 154 : if (!ENUM_FIXED_UNDERLYING_TYPE_P (ret.spec))
3708 : 3 : error_at (enum_loc, "%<enum%> declared both with and without "
3709 : : "fixed underlying type");
3710 : 154 : potential_nesting_p = NULL_TREE == TYPE_VALUES (ret.spec);
3711 : : }
3712 : : else
3713 : : {
3714 : : /* There must be an enum definition, so this initialization
3715 : : (to avoid possible warnings about uninitialized data)
3716 : : will be replaced later (either with the results of that
3717 : : definition, or with the results of error handling for the
3718 : : case of no tag and no definition). */
3719 : 4 : ret.spec = NULL_TREE;
3720 : 4 : ret.kind = ctsk_tagdef;
3721 : 4 : ret.expr = NULL_TREE;
3722 : 4 : ret.expr_const_operands = true;
3723 : 4 : ret.has_enum_type_specifier = true;
3724 : : }
3725 : 158 : c_parser_consume_token (parser);
3726 : 158 : struct c_declspecs *specs = build_null_declspecs ();
3727 : 158 : c_parser_declspecs (parser, specs, false, true, false, false, false,
3728 : : false, true, cla_prefer_id);
3729 : 158 : finish_declspecs (specs);
3730 : 158 : if (specs->default_int_p)
3731 : 1 : error_at (enum_loc, "no %<enum%> underlying type specified");
3732 : 157 : else if (TREE_CODE (specs->type) != INTEGER_TYPE
3733 : 157 : && TREE_CODE (specs->type) != BOOLEAN_TYPE)
3734 : : {
3735 : 9 : error_at (enum_loc, "invalid %<enum%> underlying type");
3736 : 9 : specs->type = integer_type_node;
3737 : : }
3738 : 148 : else if (specs->restrict_p)
3739 : 1 : error_at (enum_loc, "invalid use of %<restrict%>");
3740 : 158 : fixed_underlying_type = TYPE_MAIN_VARIANT (specs->type);
3741 : 158 : if (ident)
3742 : : {
3743 : : /* The type specified must be consistent with any previously
3744 : : specified underlying type. If this is a newly declared
3745 : : type, it is now a complete type. */
3746 : 154 : if (ENUM_FIXED_UNDERLYING_TYPE_P (ret.spec)
3747 : 154 : && ENUM_UNDERLYING_TYPE (ret.spec) == NULL_TREE)
3748 : : {
3749 : 408 : TYPE_MIN_VALUE (ret.spec) =
3750 : 136 : TYPE_MIN_VALUE (fixed_underlying_type);
3751 : 408 : TYPE_MAX_VALUE (ret.spec) =
3752 : 136 : TYPE_MAX_VALUE (fixed_underlying_type);
3753 : 136 : TYPE_UNSIGNED (ret.spec) = TYPE_UNSIGNED (fixed_underlying_type);
3754 : 136 : SET_TYPE_ALIGN (ret.spec, TYPE_ALIGN (fixed_underlying_type));
3755 : 136 : TYPE_SIZE (ret.spec) = NULL_TREE;
3756 : 136 : TYPE_PRECISION (ret.spec) =
3757 : 136 : TYPE_PRECISION (fixed_underlying_type);
3758 : 136 : ENUM_UNDERLYING_TYPE (ret.spec) = fixed_underlying_type;
3759 : 136 : layout_type (ret.spec);
3760 : : }
3761 : 18 : else if (ENUM_FIXED_UNDERLYING_TYPE_P (ret.spec)
3762 : 31 : && !comptypes (fixed_underlying_type,
3763 : 13 : ENUM_UNDERLYING_TYPE (ret.spec)))
3764 : : {
3765 : 3 : error_at (enum_loc, "%<enum%> underlying type incompatible with "
3766 : : "previous declaration");
3767 : 3 : fixed_underlying_type = ENUM_UNDERLYING_TYPE (ret.spec);
3768 : : }
3769 : : }
3770 : : }
3771 : 216701 : if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
3772 : : {
3773 : : /* Parse an enum definition. */
3774 : 160831 : struct c_enum_contents the_enum;
3775 : 160831 : tree type;
3776 : 160831 : tree postfix_attrs;
3777 : : /* We chain the enumerators in reverse order, then put them in
3778 : : forward order at the end. */
3779 : 160831 : tree values;
3780 : 160831 : timevar_push (TV_PARSE_ENUM);
3781 : 160831 : type = start_enum (enum_loc, &the_enum, ident, fixed_underlying_type,
3782 : : potential_nesting_p);
3783 : 160831 : values = NULL_TREE;
3784 : 160831 : c_parser_consume_token (parser);
3785 : 5338055 : while (true)
3786 : : {
3787 : 5338055 : tree enum_id;
3788 : 5338055 : tree enum_value;
3789 : 5338055 : tree enum_decl;
3790 : 5338055 : bool seen_comma;
3791 : 5338055 : c_token *token;
3792 : 5338055 : location_t comma_loc = UNKNOWN_LOCATION; /* Quiet warning. */
3793 : 5338055 : location_t decl_loc, value_loc;
3794 : 5338055 : if (c_parser_next_token_is_not (parser, CPP_NAME))
3795 : : {
3796 : : /* Give a nicer error for "enum {}". */
3797 : 9 : if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)
3798 : 9 : && !parser->error)
3799 : : {
3800 : 6 : error_at (c_parser_peek_token (parser)->location,
3801 : : "empty enum is invalid");
3802 : 6 : parser->error = true;
3803 : : }
3804 : : else
3805 : 3 : c_parser_error (parser, "expected identifier");
3806 : 9 : c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
3807 : 9 : values = error_mark_node;
3808 : 9 : break;
3809 : : }
3810 : 5338046 : token = c_parser_peek_token (parser);
3811 : 5338046 : enum_id = token->value;
3812 : : /* Set the location in case we create a decl now. */
3813 : 5338046 : c_parser_set_source_position_from_token (token);
3814 : 5338046 : decl_loc = value_loc = token->location;
3815 : 5338046 : c_parser_consume_token (parser);
3816 : : /* Parse any specified attributes. */
3817 : 5338046 : tree std_attrs = NULL_TREE;
3818 : 5338046 : if (c_parser_nth_token_starts_std_attributes (parser, 1))
3819 : 12 : std_attrs = c_parser_std_attribute_specifier_sequence (parser);
3820 : 5338046 : tree enum_attrs = chainon (std_attrs,
3821 : : c_parser_gnu_attributes (parser));
3822 : 5338046 : if (c_parser_next_token_is (parser, CPP_EQ))
3823 : : {
3824 : 3280604 : c_parser_consume_token (parser);
3825 : 3280604 : value_loc = c_parser_peek_token (parser)->location;
3826 : 3280604 : enum_value = convert_lvalue_to_rvalue (value_loc,
3827 : : (c_parser_expr_no_commas
3828 : : (parser, NULL)),
3829 : : true, true).value;
3830 : : }
3831 : : else
3832 : : enum_value = NULL_TREE;
3833 : 5338046 : enum_decl = build_enumerator (decl_loc, value_loc,
3834 : : &the_enum, enum_id, enum_value);
3835 : 5338046 : if (enum_attrs)
3836 : 20 : decl_attributes (&TREE_PURPOSE (enum_decl), enum_attrs, 0);
3837 : 5338046 : TREE_CHAIN (enum_decl) = values;
3838 : 5338046 : values = enum_decl;
3839 : 5338046 : seen_comma = false;
3840 : 5338046 : if (c_parser_next_token_is (parser, CPP_COMMA))
3841 : : {
3842 : 5195352 : comma_loc = c_parser_peek_token (parser)->location;
3843 : 5195352 : seen_comma = true;
3844 : 5195352 : c_parser_consume_token (parser);
3845 : : }
3846 : 5338046 : if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3847 : : {
3848 : 160807 : if (seen_comma)
3849 : 18128 : pedwarn_c90 (comma_loc, OPT_Wpedantic,
3850 : : "comma at end of enumerator list");
3851 : 160807 : c_parser_consume_token (parser);
3852 : 160807 : break;
3853 : : }
3854 : 5177239 : if (!seen_comma)
3855 : : {
3856 : 15 : c_parser_error (parser, "expected %<,%> or %<}%>");
3857 : 15 : c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
3858 : 15 : values = error_mark_node;
3859 : 15 : break;
3860 : : }
3861 : : }
3862 : 160831 : postfix_attrs = c_parser_gnu_attributes (parser);
3863 : 160831 : ret.spec = finish_enum (type, nreverse (values),
3864 : : chainon (std_attrs,
3865 : : chainon (attrs, postfix_attrs)));
3866 : 160831 : ret.kind = ctsk_tagdef;
3867 : 160831 : ret.expr = NULL_TREE;
3868 : 160831 : ret.expr_const_operands = true;
3869 : 160831 : ret.has_enum_type_specifier = fixed_underlying_type != NULL_TREE;
3870 : 160831 : timevar_pop (TV_PARSE_ENUM);
3871 : 160831 : return ret;
3872 : : }
3873 : 55870 : else if (!ident)
3874 : : {
3875 : 1 : c_parser_error (parser, "expected %<{%>");
3876 : 1 : ret.spec = error_mark_node;
3877 : 1 : ret.kind = ctsk_tagref;
3878 : 1 : ret.expr = NULL_TREE;
3879 : 1 : ret.expr_const_operands = true;
3880 : 1 : ret.has_enum_type_specifier = false;
3881 : 1 : return ret;
3882 : : }
3883 : : /* Attributes may only appear when the members are defined or in
3884 : : certain forward declarations (treat enum forward declarations in
3885 : : GNU C analogously to struct and union forward declarations in
3886 : : standard C). */
3887 : 55870 : if (have_std_attrs && c_parser_next_token_is_not (parser, CPP_SEMICOLON))
3888 : 1 : c_parser_error (parser, "expected %<;%>");
3889 : 55869 : if (fixed_underlying_type == NULL_TREE)
3890 : : {
3891 : 55820 : ret = parser_xref_tag (ident_loc, ENUMERAL_TYPE, ident, have_std_attrs,
3892 : : std_attrs, false);
3893 : : /* In ISO C, enumerated types without a fixed underlying type
3894 : : can be referred to only if already defined. */
3895 : 55820 : if (pedantic && !COMPLETE_TYPE_P (ret.spec))
3896 : : {
3897 : 11 : gcc_assert (ident);
3898 : 11 : pedwarn (enum_loc, OPT_Wpedantic,
3899 : : "ISO C forbids forward references to %<enum%> types");
3900 : : }
3901 : : }
3902 : : return ret;
3903 : : }
3904 : :
3905 : : /* Parse a struct or union specifier (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1).
3906 : :
3907 : : struct-or-union-specifier:
3908 : : struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
3909 : : identifier[opt] { struct-contents } gnu-attributes[opt]
3910 : : struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
3911 : : identifier
3912 : :
3913 : : struct-contents:
3914 : : struct-declaration-list
3915 : :
3916 : : struct-declaration-list:
3917 : : struct-declaration ;
3918 : : struct-declaration-list struct-declaration ;
3919 : :
3920 : : GNU extensions:
3921 : :
3922 : : struct-contents:
3923 : : empty
3924 : : struct-declaration
3925 : : struct-declaration-list struct-declaration
3926 : :
3927 : : struct-declaration-list:
3928 : : struct-declaration-list ;
3929 : : ;
3930 : :
3931 : : (Note that in the syntax here, unlike that in ISO C, the semicolons
3932 : : are included here rather than in struct-declaration, in order to
3933 : : describe the syntax with extra semicolons and missing semicolon at
3934 : : end.)
3935 : :
3936 : : Objective-C:
3937 : :
3938 : : struct-declaration-list:
3939 : : @defs ( class-name )
3940 : :
3941 : : (Note this does not include a trailing semicolon, but can be
3942 : : followed by further declarations, and gets a pedwarn-if-pedantic
3943 : : when followed by a semicolon.) */
3944 : :
3945 : : static struct c_typespec
3946 : 2021553 : c_parser_struct_or_union_specifier (c_parser *parser)
3947 : : {
3948 : 2021553 : struct c_typespec ret;
3949 : 2021553 : bool have_std_attrs;
3950 : 2021553 : tree std_attrs = NULL_TREE;
3951 : 2021553 : tree attrs;
3952 : 2021553 : tree ident = NULL_TREE;
3953 : 2021553 : location_t struct_loc;
3954 : 2021553 : location_t ident_loc = UNKNOWN_LOCATION;
3955 : 2021553 : enum tree_code code;
3956 : 2021553 : switch (c_parser_peek_token (parser)->keyword)
3957 : : {
3958 : : case RID_STRUCT:
3959 : : code = RECORD_TYPE;
3960 : : break;
3961 : 384211 : case RID_UNION:
3962 : 384211 : code = UNION_TYPE;
3963 : 384211 : break;
3964 : 0 : default:
3965 : 0 : gcc_unreachable ();
3966 : : }
3967 : 2021553 : struct_loc = c_parser_peek_token (parser)->location;
3968 : 2021553 : c_parser_consume_token (parser);
3969 : 2021553 : have_std_attrs = c_parser_nth_token_starts_std_attributes (parser, 1);
3970 : 2021553 : if (have_std_attrs)
3971 : 33 : std_attrs = c_parser_std_attribute_specifier_sequence (parser);
3972 : 2021553 : attrs = c_parser_gnu_attributes (parser);
3973 : :
3974 : : /* Set the location in case we create a decl now. */
3975 : 2021553 : c_parser_set_source_position_from_token (c_parser_peek_token (parser));
3976 : :
3977 : 2021553 : if (c_parser_next_token_is (parser, CPP_NAME))
3978 : : {
3979 : 1408571 : ident = c_parser_peek_token (parser)->value;
3980 : 1408571 : ident_loc = c_parser_peek_token (parser)->location;
3981 : 1408571 : struct_loc = ident_loc;
3982 : 1408571 : c_parser_consume_token (parser);
3983 : : }
3984 : 2021553 : if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
3985 : : {
3986 : : /* Parse a struct or union definition. Start the scope of the
3987 : : tag before parsing components. */
3988 : 1071169 : class c_struct_parse_info *struct_info;
3989 : 1071169 : tree type = start_struct (struct_loc, code, ident, &struct_info);
3990 : 1071169 : tree postfix_attrs;
3991 : : /* We chain the components in reverse order, then put them in
3992 : : forward order at the end. Each struct-declaration may
3993 : : declare multiple components (comma-separated), so we must use
3994 : : chainon to join them, although when parsing each
3995 : : struct-declaration we can use TREE_CHAIN directly.
3996 : :
3997 : : The theory behind all this is that there will be more
3998 : : semicolon separated fields than comma separated fields, and
3999 : : so we'll be minimizing the number of node traversals required
4000 : : by chainon. */
4001 : 1071169 : tree contents;
4002 : 1071169 : tree expr = NULL;
4003 : 1071169 : timevar_push (TV_PARSE_STRUCT);
4004 : 1071169 : contents = NULL_TREE;
4005 : 1071169 : c_parser_consume_token (parser);
4006 : : /* Handle the Objective-C @defs construct,
4007 : : e.g. foo(sizeof(struct{ @defs(ClassName) }));. */
4008 : 1071169 : if (c_parser_next_token_is_keyword (parser, RID_AT_DEFS))
4009 : : {
4010 : 0 : tree name;
4011 : 0 : gcc_assert (c_dialect_objc ());
4012 : 0 : c_parser_consume_token (parser);
4013 : 0 : matching_parens parens;
4014 : 0 : if (!parens.require_open (parser))
4015 : 0 : goto end_at_defs;
4016 : 0 : if (c_parser_next_token_is (parser, CPP_NAME)
4017 : 0 : && c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME)
4018 : : {
4019 : 0 : name = c_parser_peek_token (parser)->value;
4020 : 0 : c_parser_consume_token (parser);
4021 : : }
4022 : : else
4023 : : {
4024 : 0 : c_parser_error (parser, "expected class name");
4025 : 0 : c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4026 : 0 : goto end_at_defs;
4027 : : }
4028 : 0 : parens.skip_until_found_close (parser);
4029 : 0 : contents = nreverse (objc_get_class_ivars (name));
4030 : : }
4031 : 1071169 : end_at_defs:
4032 : : /* Parse the struct-declarations and semicolons. Problems with
4033 : : semicolons are diagnosed here; empty structures are diagnosed
4034 : : elsewhere. */
4035 : 4860507 : while (true)
4036 : : {
4037 : 4860507 : tree decls;
4038 : : /* Parse any stray semicolon. */
4039 : 4860507 : if (c_parser_next_token_is (parser, CPP_SEMICOLON))
4040 : : {
4041 : 13 : location_t semicolon_loc
4042 : 13 : = c_parser_peek_token (parser)->location;
4043 : 13 : gcc_rich_location richloc (semicolon_loc);
4044 : 13 : richloc.add_fixit_remove ();
4045 : 13 : pedwarn (&richloc, OPT_Wpedantic,
4046 : : "extra semicolon in struct or union specified");
4047 : 13 : c_parser_consume_token (parser);
4048 : 13 : continue;
4049 : 13 : }
4050 : : /* Stop if at the end of the struct or union contents. */
4051 : 4860494 : if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
4052 : : {
4053 : 1071160 : c_parser_consume_token (parser);
4054 : 1071160 : break;
4055 : : }
4056 : : /* Accept #pragmas at struct scope. */
4057 : 3789334 : if (c_parser_next_token_is (parser, CPP_PRAGMA))
4058 : : {
4059 : 18 : c_parser_pragma (parser, pragma_struct, NULL);
4060 : 18 : continue;
4061 : : }
4062 : : /* Parse some comma-separated declarations, but not the
4063 : : trailing semicolon if any. */
4064 : 3789316 : decls = c_parser_struct_declaration (parser, &expr);
4065 : 3789316 : contents = chainon (decls, contents);
4066 : : /* If no semicolon follows, either we have a parse error or
4067 : : are at the end of the struct or union and should
4068 : : pedwarn. */
4069 : 3789316 : if (c_parser_next_token_is (parser, CPP_SEMICOLON))
4070 : 3789282 : c_parser_consume_token (parser);
4071 : : else
4072 : : {
4073 : 34 : if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
4074 : 23 : pedwarn (c_parser_peek_token (parser)->location, 0,
4075 : : "no semicolon at end of struct or union");
4076 : 11 : else if (parser->error
4077 : 11 : || !c_parser_next_token_starts_declspecs (parser))
4078 : : {
4079 : 9 : c_parser_error (parser, "expected %<;%>");
4080 : 9 : c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
4081 : 9 : break;
4082 : : }
4083 : :
4084 : : /* If we come here, we have already emitted an error
4085 : : for an expected `;', identifier or `(', and we also
4086 : : recovered already. Go on with the next field. */
4087 : : }
4088 : : }
4089 : 1071169 : postfix_attrs = c_parser_gnu_attributes (parser);
4090 : 1071169 : ret.spec = finish_struct (struct_loc, type, nreverse (contents),
4091 : : chainon (std_attrs,
4092 : : chainon (attrs, postfix_attrs)),
4093 : : struct_info, &expr);
4094 : 1071169 : ret.kind = ctsk_tagdef;
4095 : 1071169 : ret.expr = expr;
4096 : 1071169 : ret.expr_const_operands = true;
4097 : 1071169 : ret.has_enum_type_specifier = false;
4098 : 1071169 : timevar_pop (TV_PARSE_STRUCT);
4099 : 1071169 : return ret;
4100 : : }
4101 : 950384 : else if (!ident)
4102 : : {
4103 : 10 : c_parser_error (parser, "expected %<{%>");
4104 : 10 : ret.spec = error_mark_node;
4105 : 10 : ret.kind = ctsk_tagref;
4106 : 10 : ret.expr = NULL_TREE;
4107 : 10 : ret.expr_const_operands = true;
4108 : 10 : ret.has_enum_type_specifier = false;
4109 : 10 : return ret;
4110 : : }
4111 : : /* Attributes may only appear when the members are defined or in
4112 : : certain forward declarations. */
4113 : 950384 : if (have_std_attrs && c_parser_next_token_is_not (parser, CPP_SEMICOLON))
4114 : 2 : c_parser_error (parser, "expected %<;%>");
4115 : : /* ??? Existing practice is that GNU attributes are ignored after
4116 : : the struct or union keyword when not defining the members. */
4117 : 950374 : ret = parser_xref_tag (ident_loc, code, ident, have_std_attrs, std_attrs,
4118 : : false);
4119 : 950374 : return ret;
4120 : : }
4121 : :
4122 : : /* Parse a struct-declaration (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1),
4123 : : *without* the trailing semicolon.
4124 : :
4125 : : struct-declaration:
4126 : : attribute-specifier-sequence[opt] specifier-qualifier-list
4127 : : attribute-specifier-sequence[opt] struct-declarator-list
4128 : : static_assert-declaration-no-semi
4129 : :
4130 : : specifier-qualifier-list:
4131 : : type-specifier specifier-qualifier-list[opt]
4132 : : type-qualifier specifier-qualifier-list[opt]
4133 : : alignment-specifier specifier-qualifier-list[opt]
4134 : : gnu-attributes specifier-qualifier-list[opt]
4135 : :
4136 : : struct-declarator-list:
4137 : : struct-declarator
4138 : : struct-declarator-list , gnu-attributes[opt] struct-declarator
4139 : :
4140 : : struct-declarator:
4141 : : declarator gnu-attributes[opt]
4142 : : declarator[opt] : constant-expression gnu-attributes[opt]
4143 : :
4144 : : GNU extensions:
4145 : :
4146 : : struct-declaration:
4147 : : __extension__ struct-declaration
4148 : : specifier-qualifier-list
4149 : :
4150 : : Unlike the ISO C syntax, semicolons are handled elsewhere. The use
4151 : : of gnu-attributes where shown is a GNU extension. In GNU C, we accept
4152 : : any expression without commas in the syntax (assignment
4153 : : expressions, not just conditional expressions); assignment
4154 : : expressions will be diagnosed as non-constant. */
4155 : :
4156 : : static tree
4157 : 3849785 : c_parser_struct_declaration (c_parser *parser, tree *expr)
4158 : : {
4159 : 3849785 : struct c_declspecs *specs;
4160 : 3849785 : tree prefix_attrs;
4161 : 3849785 : tree all_prefix_attrs;
4162 : 3849785 : tree decls;
4163 : 3849785 : location_t decl_loc;
4164 : 3849785 : if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
4165 : : {
4166 : 60469 : int ext;
4167 : 60469 : tree decl;
4168 : 60469 : ext = disable_extension_diagnostics ();
4169 : 60469 : c_parser_consume_token (parser);
4170 : 60469 : decl = c_parser_struct_declaration (parser, expr);
4171 : 60469 : restore_extension_diagnostics (ext);
4172 : 60469 : return decl;
4173 : : }
4174 : 3789316 : if (c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
4175 : : {
4176 : 10 : c_parser_static_assert_declaration_no_semi (parser);
4177 : 10 : return NULL_TREE;
4178 : : }
4179 : 3789306 : specs = build_null_declspecs ();
4180 : 3789306 : decl_loc = c_parser_peek_token (parser)->location;
4181 : : /* Strictly by the standard, we shouldn't allow _Alignas here,
4182 : : but it appears to have been intended to allow it there, so
4183 : : we're keeping it as it is until WG14 reaches a conclusion
4184 : : of N1731.
4185 : : <http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1731.pdf> */
4186 : 3789306 : c_parser_declspecs (parser, specs, false, true, true,
4187 : : true, false, true, true, cla_nonabstract_decl);
4188 : 3789306 : if (parser->error)
4189 : : return NULL_TREE;
4190 : 3789298 : if (!specs->declspecs_seen_p)
4191 : : {
4192 : 1 : c_parser_error (parser, "expected specifier-qualifier-list");
4193 : 1 : return NULL_TREE;
4194 : : }
4195 : 3789297 : finish_declspecs (specs);
4196 : 3789297 : if (c_parser_next_token_is (parser, CPP_SEMICOLON)
4197 : 7568501 : || c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
4198 : : {
4199 : 10095 : tree ret;
4200 : 10095 : if (specs->typespec_kind == ctsk_none)
4201 : : {
4202 : 3 : pedwarn (decl_loc, OPT_Wpedantic,
4203 : : "ISO C forbids member declarations with no members");
4204 : 3 : shadow_tag_warned (specs, pedantic);
4205 : 3 : ret = NULL_TREE;
4206 : : }
4207 : : else
4208 : : {
4209 : : /* Support for unnamed structs or unions as members of
4210 : : structs or unions (which is [a] useful and [b] supports
4211 : : MS P-SDK). */
4212 : 10092 : tree attrs = NULL;
4213 : :
4214 : 10092 : ret = grokfield (c_parser_peek_token (parser)->location,
4215 : : build_id_declarator (NULL_TREE), specs,
4216 : : NULL_TREE, &attrs, expr);
4217 : 10092 : if (ret)
4218 : 10065 : decl_attributes (&ret, attrs, 0);
4219 : : }
4220 : 10095 : return ret;
4221 : : }
4222 : :
4223 : : /* Provide better error recovery. Note that a type name here is valid,
4224 : : and will be treated as a field name. */
4225 : 3779202 : if (specs->typespec_kind == ctsk_tagdef
4226 : 143466 : && TREE_CODE (specs->type) != ENUMERAL_TYPE
4227 : 143313 : && c_parser_next_token_starts_declspecs (parser)
4228 : 3779204 : && !c_parser_next_token_is (parser, CPP_NAME))
4229 : : {
4230 : 2 : c_parser_error (parser, "expected %<;%>, identifier or %<(%>");
4231 : 2 : parser->error = false;
4232 : 2 : return NULL_TREE;
4233 : : }
4234 : :
4235 : 3779200 : pending_xref_error ();
4236 : 3779200 : prefix_attrs = specs->attrs;
4237 : 3779200 : all_prefix_attrs = prefix_attrs;
4238 : 3779200 : specs->attrs = NULL_TREE;
4239 : 3779200 : decls = NULL_TREE;
4240 : 54762 : while (true)
4241 : : {
4242 : : /* Declaring one or more declarators or un-named bit-fields. */
4243 : 3833962 : struct c_declarator *declarator;
4244 : 3833962 : bool dummy = false;
4245 : 3833962 : if (c_parser_next_token_is (parser, CPP_COLON))
4246 : 8888 : declarator = build_id_declarator (NULL_TREE);
4247 : : else
4248 : 3825074 : declarator = c_parser_declarator (parser,
4249 : 3825074 : specs->typespec_kind != ctsk_none,
4250 : : C_DTR_NORMAL, &dummy);
4251 : 3833962 : if (declarator == NULL)
4252 : : {
4253 : 1 : c_parser_skip_to_end_of_block_or_statement (parser);
4254 : 1 : break;
4255 : : }
4256 : 3833961 : if (c_parser_next_token_is (parser, CPP_COLON)
4257 : 3794535 : || c_parser_next_token_is (parser, CPP_COMMA)
4258 : 3741888 : || c_parser_next_token_is (parser, CPP_SEMICOLON)
4259 : 31005 : || c_parser_next_token_is (parser, CPP_CLOSE_BRACE)
4260 : 3864946 : || c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
4261 : : {
4262 : 3833961 : tree postfix_attrs = NULL_TREE;
4263 : 3833961 : tree width = NULL_TREE;
4264 : 3833961 : tree d;
4265 : 3833961 : if (c_parser_next_token_is (parser, CPP_COLON))
4266 : : {
4267 : 39426 : c_parser_consume_token (parser);
4268 : 39426 : location_t loc = c_parser_peek_token (parser)->location;
4269 : 39426 : width = convert_lvalue_to_rvalue (loc,
4270 : : (c_parser_expr_no_commas
4271 : : (parser, NULL)),
4272 : : true, true).value;
4273 : : }
4274 : 3833961 : if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
4275 : 31166 : postfix_attrs = c_parser_gnu_attributes (parser);
4276 : 3833961 : d = grokfield (c_parser_peek_token (parser)->location,
4277 : : declarator, specs, width, &all_prefix_attrs, expr);
4278 : 3833961 : decl_attributes (&d, chainon (postfix_attrs,
4279 : : all_prefix_attrs), 0);
4280 : 3833961 : DECL_CHAIN (d) = decls;
4281 : 3833961 : decls = d;
4282 : 3833961 : if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
4283 : 0 : all_prefix_attrs = chainon (c_parser_gnu_attributes (parser),
4284 : : prefix_attrs);
4285 : : else
4286 : 3833961 : all_prefix_attrs = prefix_attrs;
4287 : 3833961 : if (c_parser_next_token_is (parser, CPP_COMMA))
4288 : 54762 : c_parser_consume_token (parser);
4289 : 3779199 : else if (c_parser_next_token_is (parser, CPP_SEMICOLON)
4290 : 3779219 : || c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
4291 : : {
4292 : : /* Semicolon consumed in caller. */
4293 : : break;
4294 : : }
4295 : : else
4296 : : {
4297 : 0 : c_parser_error (parser, "expected %<,%>, %<;%> or %<}%>");
4298 : 0 : break;
4299 : : }
4300 : : }
4301 : : else
4302 : : {
4303 : 0 : c_parser_error (parser,
4304 : : "expected %<:%>, %<,%>, %<;%>, %<}%> or "
4305 : : "%<__attribute__%>");
4306 : 0 : break;
4307 : : }
4308 : : }
4309 : 3779200 : return decls;
4310 : : }
4311 : :
4312 : : /* Parse a typeof specifier (a GNU extension adopted in C23).
4313 : :
4314 : : typeof-specifier:
4315 : : typeof ( expression )
4316 : : typeof ( type-name )
4317 : : typeof_unqual ( expression )
4318 : : typeof_unqual ( type-name )
4319 : : */
4320 : :
4321 : : static struct c_typespec
4322 : 671772 : c_parser_typeof_specifier (c_parser *parser)
4323 : : {
4324 : 671772 : bool is_unqual;
4325 : 671772 : bool is_std;
4326 : 671772 : struct c_typespec ret;
4327 : 671772 : ret.kind = ctsk_typeof;
4328 : 671772 : ret.spec = error_mark_node;
4329 : 671772 : ret.expr = NULL_TREE;
4330 : 671772 : ret.expr_const_operands = true;
4331 : 671772 : ret.has_enum_type_specifier = false;
4332 : 671772 : if (c_parser_next_token_is_keyword (parser, RID_TYPEOF))
4333 : : {
4334 : 671688 : is_unqual = false;
4335 : 671688 : tree spelling = c_parser_peek_token (parser)->value;
4336 : 671688 : is_std = (flag_isoc23
4337 : 692436 : && strcmp (IDENTIFIER_POINTER (spelling), "typeof") == 0);
4338 : : }
4339 : : else
4340 : : {
4341 : 84 : gcc_assert (c_parser_next_token_is_keyword (parser, RID_TYPEOF_UNQUAL));
4342 : 84 : is_unqual = true;
4343 : 84 : tree spelling = c_parser_peek_token (parser)->value;
4344 : 84 : is_std = strcmp (IDENTIFIER_POINTER (spelling), "typeof_unqual") == 0;
4345 : : }
4346 : 671772 : c_parser_consume_token (parser);
4347 : 671772 : c_inhibit_evaluation_warnings++;
4348 : 671772 : in_typeof++;
4349 : 671772 : matching_parens parens;
4350 : 671772 : if (!parens.require_open (parser))
4351 : : {
4352 : 0 : c_inhibit_evaluation_warnings--;
4353 : 0 : in_typeof--;
4354 : 0 : return ret;
4355 : : }
4356 : 671772 : if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
4357 : : {
4358 : 676 : struct c_type_name *type = c_parser_type_name (parser);
4359 : 676 : c_inhibit_evaluation_warnings--;
4360 : 676 : in_typeof--;
4361 : 676 : if (type != NULL)
4362 : : {
4363 : 676 : ret.spec = groktypename (type, &ret.expr, &ret.expr_const_operands);
4364 : 676 : pop_maybe_used (c_type_variably_modified_p (ret.spec));
4365 : : }
4366 : : }
4367 : : else
4368 : : {
4369 : 671096 : bool was_vm;
4370 : 671096 : location_t here = c_parser_peek_token (parser)->location;
4371 : 671096 : struct c_expr expr = c_parser_expression (parser);
4372 : 671096 : c_inhibit_evaluation_warnings--;
4373 : 671096 : in_typeof--;
4374 : 671096 : if (TREE_CODE (expr.value) == COMPONENT_REF
4375 : 671096 : && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
4376 : 13 : error_at (here, "%<typeof%> applied to a bit-field");
4377 : 671096 : mark_exp_read (expr.value);
4378 : 671096 : ret.spec = TREE_TYPE (expr.value);
4379 : 671096 : was_vm = c_type_variably_modified_p (ret.spec);
4380 : : /* This is returned with the type so that when the type is
4381 : : evaluated, this can be evaluated. */
4382 : 671096 : if (was_vm)
4383 : 202 : ret.expr = c_fully_fold (expr.value, false, &ret.expr_const_operands);
4384 : 671096 : pop_maybe_used (was_vm);
4385 : : }
4386 : 671772 : parens.skip_until_found_close (parser);
4387 : 671772 : if (ret.spec != error_mark_node)
4388 : : {
4389 : 671761 : if (is_unqual && TYPE_QUALS (ret.spec) != TYPE_UNQUALIFIED)
4390 : 45 : ret.spec = TYPE_MAIN_VARIANT (ret.spec);
4391 : 671761 : if (is_std)
4392 : : {
4393 : : /* In ISO C terms, _Noreturn is not part of the type of
4394 : : expressions such as &abort, but in GCC it is represented
4395 : : internally as a type qualifier. */
4396 : 258 : if (TREE_CODE (ret.spec) == FUNCTION_TYPE
4397 : 258 : && TYPE_QUALS (ret.spec) != TYPE_UNQUALIFIED)
4398 : 2 : ret.spec = TYPE_MAIN_VARIANT (ret.spec);
4399 : 30 : else if (FUNCTION_POINTER_TYPE_P (ret.spec)
4400 : 259 : && TYPE_QUALS (TREE_TYPE (ret.spec)) != TYPE_UNQUALIFIED)
4401 : 2 : ret.spec
4402 : 2 : = build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (ret.spec)));
4403 : : }
4404 : : }
4405 : : return ret;
4406 : : }
4407 : :
4408 : : /* Parse an alignment-specifier.
4409 : :
4410 : : C11 6.7.5:
4411 : :
4412 : : alignment-specifier:
4413 : : _Alignas ( type-name )
4414 : : _Alignas ( constant-expression )
4415 : : */
4416 : :
4417 : : static tree
4418 : 194 : c_parser_alignas_specifier (c_parser * parser)
4419 : : {
4420 : 194 : tree ret = error_mark_node;
4421 : 194 : location_t loc = c_parser_peek_token (parser)->location;
4422 : 194 : gcc_assert (c_parser_next_token_is_keyword (parser, RID_ALIGNAS));
4423 : 194 : tree spelling = c_parser_peek_token (parser)->value;
4424 : 194 : c_parser_consume_token (parser);
4425 : 194 : if (flag_isoc99)
4426 : 191 : pedwarn_c99 (loc, OPT_Wpedantic,
4427 : : "ISO C99 does not support %qE", spelling);
4428 : : else
4429 : 3 : pedwarn_c99 (loc, OPT_Wpedantic,
4430 : : "ISO C90 does not support %qE", spelling);
4431 : 194 : matching_parens parens;
4432 : 194 : if (!parens.require_open (parser))
4433 : : return ret;
4434 : 194 : if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
4435 : : {
4436 : 126 : struct c_type_name *type = c_parser_type_name (parser);
4437 : 126 : if (type != NULL)
4438 : 125 : ret = c_sizeof_or_alignof_type (loc, groktypename (type, NULL, NULL),
4439 : : false, true, 1);
4440 : : }
4441 : : else
4442 : 68 : ret = convert_lvalue_to_rvalue (loc,
4443 : : c_parser_expr_no_commas (parser, NULL),
4444 : : true, true).value;
4445 : 194 : parens.skip_until_found_close (parser);
4446 : 194 : return ret;
4447 : : }
4448 : :
4449 : : /* Parse a declarator, possibly an abstract declarator (C90 6.5.4,
4450 : : 6.5.5, C99 6.7.5, 6.7.6, C11 6.7.6, 6.7.7). If TYPE_SEEN_P then
4451 : : a typedef name may be redeclared; otherwise it may not. KIND
4452 : : indicates which kind of declarator is wanted. Returns a valid
4453 : : declarator except in the case of a syntax error in which case NULL is
4454 : : returned. *SEEN_ID is set to true if an identifier being declared is
4455 : : seen; this is used to diagnose bad forms of abstract array declarators
4456 : : and to determine whether an identifier list is syntactically permitted.
4457 : :
4458 : : declarator:
4459 : : pointer[opt] direct-declarator
4460 : :
4461 : : direct-declarator:
4462 : : identifier
4463 : : ( gnu-attributes[opt] declarator )
4464 : : direct-declarator array-declarator
4465 : : direct-declarator ( parameter-type-list )
4466 : : direct-declarator ( identifier-list[opt] )
4467 : :
4468 : : pointer:
4469 : : * type-qualifier-list[opt]
4470 : : * type-qualifier-list[opt] pointer
4471 : :
4472 : : type-qualifier-list:
4473 : : type-qualifier
4474 : : gnu-attributes
4475 : : type-qualifier-list type-qualifier
4476 : : type-qualifier-list gnu-attributes
4477 : :
4478 : : array-declarator:
4479 : : [ type-qualifier-list[opt] assignment-expression[opt] ]
4480 : : [ static type-qualifier-list[opt] assignment-expression ]
4481 : : [ type-qualifier-list static assignment-expression ]
4482 : : [ type-qualifier-list[opt] * ]
4483 : :
4484 : : parameter-type-list:
4485 : : parameter-list
4486 : : parameter-list , ...
4487 : :
4488 : : parameter-list:
4489 : : parameter-declaration
4490 : : parameter-list , parameter-declaration
4491 : :
4492 : : parameter-declaration:
4493 : : declaration-specifiers declarator gnu-attributes[opt]
4494 : : declaration-specifiers abstract-declarator[opt] gnu-attributes[opt]
4495 : :
4496 : : identifier-list:
4497 : : identifier
4498 : : identifier-list , identifier
4499 : :
4500 : : abstract-declarator:
4501 : : pointer
4502 : : pointer[opt] direct-abstract-declarator
4503 : :
4504 : : direct-abstract-declarator:
4505 : : ( gnu-attributes[opt] abstract-declarator )
4506 : : direct-abstract-declarator[opt] array-declarator
4507 : : direct-abstract-declarator[opt] ( parameter-type-list[opt] )
4508 : :
4509 : : GNU extensions:
4510 : :
4511 : : direct-declarator:
4512 : : direct-declarator ( parameter-forward-declarations
4513 : : parameter-type-list[opt] )
4514 : :
4515 : : direct-abstract-declarator:
4516 : : direct-abstract-declarator[opt] ( parameter-forward-declarations
4517 : : parameter-type-list[opt] )
4518 : :
4519 : : parameter-forward-declarations:
4520 : : parameter-list ;
4521 : : parameter-forward-declarations parameter-list ;
4522 : :
4523 : : The uses of gnu-attributes shown above are GNU extensions.
4524 : :
4525 : : Some forms of array declarator are not included in C99 in the
4526 : : syntax for abstract declarators; these are disallowed elsewhere.
4527 : : This may be a defect (DR#289).
4528 : :
4529 : : This function also accepts an omitted abstract declarator as being
4530 : : an abstract declarator, although not part of the formal syntax. */
4531 : :
4532 : : struct c_declarator *
4533 : 291169591 : c_parser_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
4534 : : bool *seen_id)
4535 : : {
4536 : : /* Parse any initial pointer part. */
4537 : 291169591 : if (c_parser_next_token_is (parser, CPP_MULT))
4538 : : {
4539 : 16573234 : struct c_declspecs *quals_attrs = build_null_declspecs ();
4540 : 16573234 : struct c_declarator *inner;
4541 : 16573234 : c_parser_consume_token (parser);
4542 : 16573234 : c_parser_declspecs (parser, quals_attrs, false, false, true,
4543 : : false, false, true, false, cla_prefer_id);
4544 : 16573234 : inner = c_parser_declarator (parser, type_seen_p, kind, seen_id);
4545 : 16573234 : if (inner == NULL)
4546 : : return NULL;
4547 : : else
4548 : 16573225 : return make_pointer_declarator (quals_attrs, inner);
4549 : : }
4550 : : /* Now we have a direct declarator, direct abstract declarator or
4551 : : nothing (which counts as a direct abstract declarator here). */
4552 : 274596357 : return c_parser_direct_declarator (parser, type_seen_p, kind, seen_id);
4553 : : }
4554 : :
4555 : : /* Parse a direct declarator or direct abstract declarator; arguments
4556 : : as c_parser_declarator. */
4557 : :
4558 : : static struct c_declarator *
4559 : 274596357 : c_parser_direct_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
4560 : : bool *seen_id)
4561 : : {
4562 : : /* The direct declarator must start with an identifier (possibly
4563 : : omitted) or a parenthesized declarator (possibly abstract). In
4564 : : an ordinary declarator, initial parentheses must start a
4565 : : parenthesized declarator. In an abstract declarator or parameter
4566 : : declarator, they could start a parenthesized declarator or a
4567 : : parameter list. To tell which, the open parenthesis and any
4568 : : following gnu-attributes must be read. If a declaration
4569 : : specifier or standard attributes follow, then it is a parameter
4570 : : list; if the specifier is a typedef name, there might be an
4571 : : ambiguity about redeclaring it, which is resolved in the
4572 : : direction of treating it as a typedef name. If a close
4573 : : parenthesis follows, it is also an empty parameter list, as the
4574 : : syntax does not permit empty abstract declarators. Otherwise, it
4575 : : is a parenthesized declarator (in which case the analysis may be
4576 : : repeated inside it, recursively).
4577 : :
4578 : : ??? There is an ambiguity in a parameter declaration "int
4579 : : (__attribute__((foo)) x)", where x is not a typedef name: it
4580 : : could be an abstract declarator for a function, or declare x with
4581 : : parentheses. The proper resolution of this ambiguity needs
4582 : : documenting. At present we follow an accident of the old
4583 : : parser's implementation, whereby the first parameter must have
4584 : : some declaration specifiers other than just gnu-attributes. Thus as
4585 : : a parameter declaration it is treated as a parenthesized
4586 : : parameter named x, and as an abstract declarator it is
4587 : : rejected.
4588 : :
4589 : : ??? Also following the old parser, gnu-attributes inside an empty
4590 : : parameter list are ignored, making it a list not yielding a
4591 : : prototype, rather than giving an error or making it have one
4592 : : parameter with implicit type int.
4593 : :
4594 : : ??? Also following the old parser, typedef names may be
4595 : : redeclared in declarators, but not Objective-C class names. */
4596 : :
4597 : 274596357 : if (kind != C_DTR_ABSTRACT
4598 : 169375953 : && c_parser_next_token_is (parser, CPP_NAME)
4599 : 439702085 : && ((type_seen_p
4600 : 165095894 : && (c_parser_peek_token (parser)->id_kind == C_ID_TYPENAME
4601 : 164999099 : || c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME))
4602 : 165008933 : || c_parser_peek_token (parser)->id_kind == C_ID_ID))
4603 : : {
4604 : 165105728 : struct c_declarator *inner
4605 : 165105728 : = build_id_declarator (c_parser_peek_token (parser)->value);
4606 : 165105728 : *seen_id = true;
4607 : 165105728 : inner->id_loc = c_parser_peek_token (parser)->location;
4608 : 165105728 : c_parser_consume_token (parser);
4609 : 165105728 : if (c_parser_nth_token_starts_std_attributes (parser, 1))
4610 : 78 : inner->u.id.attrs = c_parser_std_attribute_specifier_sequence (parser);
4611 : 165105728 : return c_parser_direct_declarator_inner (parser, *seen_id, inner);
4612 : : }
4613 : :
4614 : 109490629 : if (kind != C_DTR_NORMAL
4615 : 109361497 : && c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
4616 : 109513751 : && !c_parser_nth_token_starts_std_attributes (parser, 1))
4617 : : {
4618 : 23122 : struct c_declarator *inner = build_id_declarator (NULL_TREE);
4619 : 23122 : inner->id_loc = c_parser_peek_token (parser)->location;
4620 : 23122 : return c_parser_direct_declarator_inner (parser, *seen_id, inner);
4621 : : }
4622 : :
4623 : : /* Either we are at the end of an abstract declarator, or we have
4624 : : parentheses. */
4625 : :
4626 : 109467507 : if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
4627 : : {
4628 : 208988 : tree attrs;
4629 : 208988 : struct c_declarator *inner;
4630 : 208988 : c_parser_consume_token (parser);
4631 : 208988 : bool have_gnu_attrs = c_parser_next_token_is_keyword (parser,
4632 : : RID_ATTRIBUTE);
4633 : 208988 : attrs = c_parser_gnu_attributes (parser);
4634 : 208988 : if (kind != C_DTR_NORMAL
4635 : 208988 : && (c_parser_next_token_starts_declspecs (parser)
4636 : 79901 : || (!have_gnu_attrs
4637 : 79742 : && (c_parser_nth_token_starts_std_attributes (parser, 1)
4638 : 79742 : || c_parser_next_token_is (parser, CPP_ELLIPSIS)))
4639 : 79896 : || c_parser_next_token_is (parser, CPP_CLOSE_PAREN)))
4640 : : {
4641 : 48 : struct c_arg_info *args
4642 : 48 : = c_parser_parms_declarator (parser, kind == C_DTR_NORMAL,
4643 : : attrs, have_gnu_attrs);
4644 : 48 : if (args == NULL)
4645 : : return NULL;
4646 : : else
4647 : : {
4648 : 48 : inner = build_id_declarator (NULL_TREE);
4649 : 73 : if (!(args->types
4650 : 25 : && args->types != error_mark_node
4651 : 25 : && TREE_CODE (TREE_VALUE (args->types)) == IDENTIFIER_NODE)
4652 : 73 : && c_parser_nth_token_starts_std_attributes (parser, 1))
4653 : : {
4654 : 4 : tree std_attrs
4655 : 4 : = c_parser_std_attribute_specifier_sequence (parser);
4656 : 4 : if (std_attrs)
4657 : 2 : inner = build_attrs_declarator (std_attrs, inner);
4658 : : }
4659 : 48 : inner = build_function_declarator (args, inner);
4660 : 48 : return c_parser_direct_declarator_inner (parser, *seen_id,
4661 : 48 : inner);
4662 : : }
4663 : : }
4664 : : /* A parenthesized declarator. */
4665 : 208940 : inner = c_parser_declarator (parser, type_seen_p, kind, seen_id);
4666 : 208940 : if (inner != NULL && attrs != NULL)
4667 : 181 : inner = build_attrs_declarator (attrs, inner);
4668 : 208940 : if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4669 : : {
4670 : 208927 : c_parser_consume_token (parser);
4671 : 208927 : if (inner == NULL)
4672 : : return NULL;
4673 : : else
4674 : 208927 : return c_parser_direct_declarator_inner (parser, *seen_id, inner);
4675 : : }
4676 : : else
4677 : : {
4678 : 13 : c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4679 : : "expected %<)%>");
4680 : 13 : return NULL;
4681 : : }
4682 : : }
4683 : : else
4684 : : {
4685 : 109258519 : if (kind == C_DTR_NORMAL)
4686 : : {
4687 : 70 : c_parser_error (parser, "expected identifier or %<(%>");
4688 : 70 : return NULL;
4689 : : }
4690 : : else
4691 : 109258449 : return build_id_declarator (NULL_TREE);
4692 : : }
4693 : : }
4694 : :
4695 : : /* Parse part of a direct declarator or direct abstract declarator,
4696 : : given that some (in INNER) has already been parsed; ID_PRESENT is
4697 : : true if an identifier is present, false for an abstract
4698 : : declarator. */
4699 : :
4700 : : static struct c_declarator *
4701 : 210226243 : c_parser_direct_declarator_inner (c_parser *parser, bool id_present,
4702 : : struct c_declarator *inner)
4703 : : {
4704 : : /* Parse a sequence of array declarators and parameter lists. */
4705 : 210226243 : if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
4706 : 210226243 : && !c_parser_nth_token_starts_std_attributes (parser, 1))
4707 : : {
4708 : 1060344 : location_t brace_loc = c_parser_peek_token (parser)->location;
4709 : 1060344 : struct c_declarator *declarator;
4710 : 1060344 : struct c_declspecs *quals_attrs = build_null_declspecs ();
4711 : 1060344 : bool static_seen;
4712 : 1060344 : bool star_seen;
4713 : 1060344 : struct c_expr dimen;
4714 : 1060344 : dimen.value = NULL_TREE;
4715 : 1060344 : dimen.original_code = ERROR_MARK;
4716 : 1060344 : dimen.original_type = NULL_TREE;
4717 : 1060344 : c_parser_consume_token (parser);
4718 : 1060344 : c_parser_declspecs (parser, quals_attrs, false, false, true,
4719 : : false, false, false, false, cla_prefer_id);
4720 : 1060344 : static_seen = c_parser_next_token_is_keyword (parser, RID_STATIC);
4721 : 1060344 : if (static_seen)
4722 : 121 : c_parser_consume_token (parser);
4723 : 121 : if (static_seen && !quals_attrs->declspecs_seen_p)
4724 : 103 : c_parser_declspecs (parser, quals_attrs, false, false, true,
4725 : : false, false, false, false, cla_prefer_id);
4726 : 1060344 : if (!quals_attrs->declspecs_seen_p)
4727 : 1059597 : quals_attrs = NULL;
4728 : : /* If "static" is present, there must be an array dimension.
4729 : : Otherwise, there may be a dimension, "*", or no
4730 : : dimension. */
4731 : 1060344 : if (static_seen)
4732 : : {
4733 : 121 : star_seen = false;
4734 : 121 : dimen = c_parser_expr_no_commas (parser, NULL);
4735 : : }
4736 : : else
4737 : : {
4738 : 1060223 : if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
4739 : : {
4740 : : dimen.value = NULL_TREE;
4741 : : star_seen = false;
4742 : : }
4743 : 918593 : else if (c_parser_next_token_is (parser, CPP_MULT))
4744 : : {
4745 : 159 : if (c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_SQUARE)
4746 : : {
4747 : 137 : dimen.value = NULL_TREE;
4748 : 137 : star_seen = true;
4749 : 137 : c_parser_consume_token (parser);
4750 : : }
4751 : : else
4752 : : {
4753 : 22 : star_seen = false;
4754 : 22 : dimen = c_parser_expr_no_commas (parser, NULL);
4755 : : }
4756 : : }
4757 : : else
4758 : : {
4759 : 918434 : star_seen = false;
4760 : 918434 : dimen = c_parser_expr_no_commas (parser, NULL);
4761 : : }
4762 : : }
4763 : 1060344 : if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
4764 : 1060330 : c_parser_consume_token (parser);
4765 : : else
4766 : : {
4767 : 14 : c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
4768 : : "expected %<]%>");
4769 : 14 : return NULL;
4770 : : }
4771 : 1060330 : if (dimen.value)
4772 : 918563 : dimen = convert_lvalue_to_rvalue (brace_loc, dimen, true, true);
4773 : 1060330 : declarator = build_array_declarator (brace_loc, dimen.value, quals_attrs,
4774 : : static_seen, star_seen);
4775 : 1060330 : if (declarator == NULL)
4776 : : return NULL;
4777 : 1060326 : if (c_parser_nth_token_starts_std_attributes (parser, 1))
4778 : : {
4779 : 14 : tree std_attrs
4780 : 14 : = c_parser_std_attribute_specifier_sequence (parser);
4781 : 14 : if (std_attrs)
4782 : 8 : inner = build_attrs_declarator (std_attrs, inner);
4783 : : }
4784 : 1060326 : inner = set_array_declarator_inner (declarator, inner);
4785 : 1060326 : return c_parser_direct_declarator_inner (parser, id_present, inner);
4786 : : }
4787 : 209165899 : else if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
4788 : : {
4789 : 43828201 : tree attrs;
4790 : 43828201 : struct c_arg_info *args;
4791 : 43828201 : c_parser_consume_token (parser);
4792 : 43828201 : bool have_gnu_attrs = c_parser_next_token_is_keyword (parser,
4793 : : RID_ATTRIBUTE);
4794 : 43828201 : attrs = c_parser_gnu_attributes (parser);
4795 : 43828201 : args = c_parser_parms_declarator (parser, id_present, attrs,
4796 : : have_gnu_attrs);
4797 : 43828201 : if (args == NULL)
4798 : : return NULL;
4799 : : else
4800 : : {
4801 : 86889427 : if (!(args->types
4802 : 43061335 : && args->types != error_mark_node
4803 : 43061335 : && TREE_CODE (TREE_VALUE (args->types)) == IDENTIFIER_NODE)
4804 : 86880734 : && c_parser_nth_token_starts_std_attributes (parser, 1))
4805 : : {
4806 : 21 : tree std_attrs
4807 : 21 : = c_parser_std_attribute_specifier_sequence (parser);
4808 : 21 : if (std_attrs)
4809 : 12 : inner = build_attrs_declarator (std_attrs, inner);
4810 : : }
4811 : 43828092 : inner = build_function_declarator (args, inner);
4812 : 43828092 : return c_parser_direct_declarator_inner (parser, id_present, inner);
4813 : : }
4814 : : }
4815 : : return inner;
4816 : : }
4817 : :
4818 : : /* Parse a parameter list or identifier list, including the closing
4819 : : parenthesis but not the opening one. ATTRS are the gnu-attributes
4820 : : at the start of the list. ID_LIST_OK is true if an identifier list
4821 : : is acceptable; such a list must not have attributes at the start.
4822 : : HAVE_GNU_ATTRS says whether any gnu-attributes (including empty
4823 : : attributes) were present (in which case standard attributes cannot
4824 : : occur). */
4825 : :
4826 : : static struct c_arg_info *
4827 : 43828249 : c_parser_parms_declarator (c_parser *parser, bool id_list_ok, tree attrs,
4828 : : bool have_gnu_attrs)
4829 : : {
4830 : 43828249 : push_scope ();
4831 : 43828249 : declare_parm_level ();
4832 : : /* If the list starts with an identifier, it is an identifier list.
4833 : : Otherwise, it is either a prototype list or an empty list. */
4834 : 43828249 : if (id_list_ok
4835 : 43828249 : && !attrs
4836 : 43816413 : && c_parser_next_token_is (parser, CPP_NAME)
4837 : 29326599 : && c_parser_peek_token (parser)->id_kind == C_ID_ID
4838 : :
4839 : : /* Look ahead to detect typos in type names. */
4840 : 8705 : && c_parser_peek_2nd_token (parser)->type != CPP_NAME
4841 : 8697 : && c_parser_peek_2nd_token (parser)->type != CPP_MULT
4842 : 8696 : && c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN
4843 : 8695 : && c_parser_peek_2nd_token (parser)->type != CPP_OPEN_SQUARE
4844 : 43836943 : && c_parser_peek_2nd_token (parser)->type != CPP_KEYWORD)
4845 : : {
4846 : 8693 : tree list = NULL_TREE, *nextp = &list;
4847 : 8693 : while (c_parser_next_token_is (parser, CPP_NAME)
4848 : 34334 : && c_parser_peek_token (parser)->id_kind == C_ID_ID)
4849 : : {
4850 : 34334 : *nextp = build_tree_list (NULL_TREE,
4851 : 34334 : c_parser_peek_token (parser)->value);
4852 : 34334 : nextp = & TREE_CHAIN (*nextp);
4853 : 34334 : c_parser_consume_token (parser);
4854 : 34334 : if (c_parser_next_token_is_not (parser, CPP_COMMA))
4855 : : break;
4856 : 25641 : c_parser_consume_token (parser);
4857 : 25641 : if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4858 : : {
4859 : 0 : c_parser_error (parser, "expected identifier");
4860 : 0 : break;
4861 : : }
4862 : : }
4863 : 8693 : if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4864 : : {
4865 : 8693 : struct c_arg_info *ret = build_arg_info ();
4866 : 8693 : ret->types = list;
4867 : 8693 : c_parser_consume_token (parser);
4868 : 8693 : pop_scope ();
4869 : 8693 : return ret;
4870 : : }
4871 : : else
4872 : : {
4873 : 0 : c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4874 : : "expected %<)%>");
4875 : 0 : pop_scope ();
4876 : 0 : return NULL;
4877 : : }
4878 : : }
4879 : : else
4880 : : {
4881 : 43819556 : struct c_arg_info *ret
4882 : 43819556 : = c_parser_parms_list_declarator (parser, attrs, NULL, have_gnu_attrs);
4883 : 43819556 : pop_scope ();
4884 : 43819556 : return ret;
4885 : : }
4886 : : }
4887 : :
4888 : : /* Parse a parameter list (possibly empty), including the closing
4889 : : parenthesis but not the opening one. ATTRS are the gnu-attributes
4890 : : at the start of the list; if HAVE_GNU_ATTRS, there were some such
4891 : : attributes (possibly empty, in which case ATTRS is NULL_TREE),
4892 : : which means standard attributes cannot start the list. EXPR is
4893 : : NULL or an expression that needs to be evaluated for the side
4894 : : effects of array size expressions in the parameters. */
4895 : :
4896 : : static struct c_arg_info *
4897 : 43819593 : c_parser_parms_list_declarator (c_parser *parser, tree attrs, tree expr,
4898 : : bool have_gnu_attrs)
4899 : : {
4900 : 43819593 : bool bad_parm = false;
4901 : :
4902 : : /* ??? Following the old parser, forward parameter declarations may
4903 : : use abstract declarators, and if no real parameter declarations
4904 : : follow the forward declarations then this is not diagnosed. Also
4905 : : note as above that gnu-attributes are ignored as the only contents of
4906 : : the parentheses, or as the only contents after forward
4907 : : declarations. */
4908 : 43819593 : if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4909 : : {
4910 : 766666 : struct c_arg_info *ret = build_arg_info ();
4911 : 766666 : c_parser_consume_token (parser);
4912 : 766666 : return ret;
4913 : : }
4914 : 43052927 : if (c_parser_next_token_is (parser, CPP_ELLIPSIS) && !have_gnu_attrs)
4915 : : {
4916 : 114 : struct c_arg_info *ret = build_arg_info ();
4917 : :
4918 : 114 : ret->types = NULL_TREE;
4919 : 114 : pedwarn_c11 (c_parser_peek_token (parser)->location, OPT_Wpedantic,
4920 : : "ISO C requires a named argument before %<...%> "
4921 : : "before C23");
4922 : 114 : c_parser_consume_token (parser);
4923 : 114 : if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4924 : : {
4925 : 114 : ret->no_named_args_stdarg_p = true;
4926 : 114 : c_parser_consume_token (parser);
4927 : 114 : return ret;
4928 : : }
4929 : : else
4930 : : {
4931 : 0 : c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4932 : : "expected %<)%>");
4933 : 0 : return NULL;
4934 : : }
4935 : : }
4936 : : /* Nonempty list of parameters, either terminated with semicolon
4937 : : (forward declarations; recurse) or with close parenthesis (normal
4938 : : function) or with ", ... )" (variadic function). */
4939 : 108468319 : while (true)
4940 : : {
4941 : : /* Parse a parameter. */
4942 : 108468319 : struct c_parm *parm = c_parser_parameter_declaration (parser, attrs,
4943 : : have_gnu_attrs);
4944 : 108468319 : attrs = NULL_TREE;
4945 : 108468319 : have_gnu_attrs = false;
4946 : 108468319 : if (parm == NULL)
4947 : : bad_parm = true;
4948 : : else
4949 : 108468208 : push_parm_decl (parm, &expr);
4950 : 108468319 : if (c_parser_next_token_is (parser, CPP_SEMICOLON))
4951 : : {
4952 : 37 : tree new_attrs;
4953 : 37 : c_parser_consume_token (parser);
4954 : 37 : mark_forward_parm_decls ();
4955 : 37 : bool new_have_gnu_attrs
4956 : 37 : = c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE);
4957 : 37 : new_attrs = c_parser_gnu_attributes (parser);
4958 : 37 : return c_parser_parms_list_declarator (parser, new_attrs, expr,
4959 : 37 : new_have_gnu_attrs);
4960 : : }
4961 : 108468282 : if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4962 : : {
4963 : 42851872 : c_parser_consume_token (parser);
4964 : 42851872 : if (bad_parm)
4965 : : return NULL;
4966 : : else
4967 : 42851786 : return get_parm_info (false, expr);
4968 : : }
4969 : 65616410 : if (!c_parser_require (parser, CPP_COMMA,
4970 : : "expected %<;%>, %<,%> or %<)%>",
4971 : : UNKNOWN_LOCATION, false))
4972 : : {
4973 : 8 : c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4974 : 8 : return NULL;
4975 : : }
4976 : 65616402 : if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
4977 : : {
4978 : 200896 : c_parser_consume_token (parser);
4979 : 200896 : if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4980 : : {
4981 : 200889 : c_parser_consume_token (parser);
4982 : 200889 : if (bad_parm)
4983 : : return NULL;
4984 : : else
4985 : 200881 : return get_parm_info (true, expr);
4986 : : }
4987 : : else
4988 : : {
4989 : 7 : c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4990 : : "expected %<)%>");
4991 : 7 : return NULL;
4992 : : }
4993 : : }
4994 : : }
4995 : : }
4996 : :
4997 : : /* Parse a parameter declaration. ATTRS are the gnu-attributes at the
4998 : : start of the declaration if it is the first parameter;
4999 : : HAVE_GNU_ATTRS is true if there were any gnu-attributes there (even
5000 : : empty) there. */
5001 : :
5002 : : static struct c_parm *
5003 : 108468319 : c_parser_parameter_declaration (c_parser *parser, tree attrs,
5004 : : bool have_gnu_attrs)
5005 : : {
5006 : 108468319 : struct c_declspecs *specs;
5007 : 108468319 : struct c_declarator *declarator;
5008 : 108468319 : tree prefix_attrs;
5009 : 108468319 : tree postfix_attrs = NULL_TREE;
5010 : 108468319 : bool dummy = false;
5011 : :
5012 : : /* Accept #pragmas between parameter declarations. */
5013 : 108468321 : while (c_parser_next_token_is (parser, CPP_PRAGMA))
5014 : 2 : c_parser_pragma (parser, pragma_param, NULL);
5015 : :
5016 : 108468319 : if (!c_parser_next_token_starts_declspecs (parser)
5017 : 108468319 : && !c_parser_nth_token_starts_std_attributes (parser, 1))
5018 : : {
5019 : 99 : c_token *token = c_parser_peek_token (parser);
5020 : 99 : if (parser->error)
5021 : : return NULL;
5022 : 99 : c_parser_set_source_position_from_token (token);
5023 : 99 : if (c_parser_next_tokens_start_typename (parser, cla_prefer_type))
5024 : : {
5025 : 81 : auto_diagnostic_group d;
5026 : 81 : name_hint hint = lookup_name_fuzzy (token->value,
5027 : : FUZZY_LOOKUP_TYPENAME,
5028 : 81 : token->location);
5029 : 81 : if (const char *suggestion = hint.suggestion ())
5030 : : {
5031 : 30 : gcc_rich_location richloc (token->location);
5032 : 30 : richloc.add_fixit_replace (suggestion);
5033 : 30 : error_at (&richloc,
5034 : : "unknown type name %qE; did you mean %qs?",
5035 : : token->value, suggestion);
5036 : 30 : }
5037 : : else
5038 : 51 : error_at (token->location, "unknown type name %qE", token->value);
5039 : 81 : parser->error = true;
5040 : 81 : }
5041 : : /* ??? In some Objective-C cases '...' isn't applicable so there
5042 : : should be a different message. */
5043 : : else
5044 : 18 : c_parser_error (parser,
5045 : : "expected declaration specifiers or %<...%>");
5046 : 99 : c_parser_skip_to_end_of_parameter (parser);
5047 : 99 : return NULL;
5048 : : }
5049 : :
5050 : 108468220 : location_t start_loc = c_parser_peek_token (parser)->location;
5051 : :
5052 : 108468220 : specs = build_null_declspecs ();
5053 : 108468220 : if (attrs)
5054 : : {
5055 : 328 : declspecs_add_attrs (input_location, specs, attrs);
5056 : 328 : attrs = NULL_TREE;
5057 : : }
5058 : 108468220 : c_parser_declspecs (parser, specs, true, true, true, true, false,
5059 : 108468220 : !have_gnu_attrs, true, cla_nonabstract_decl);
5060 : 108468220 : finish_declspecs (specs);
5061 : 108468220 : pending_xref_error ();
5062 : 108468220 : prefix_attrs = specs->attrs;
5063 : 108468220 : specs->attrs = NULL_TREE;
5064 : 216936440 : declarator = c_parser_declarator (parser,
5065 : 108468220 : specs->typespec_kind != ctsk_none,
5066 : : C_DTR_PARM, &dummy);
5067 : 108468220 : if (declarator == NULL)
5068 : : {
5069 : 12 : c_parser_skip_until_found (parser, CPP_COMMA, NULL);
5070 : 12 : return NULL;
5071 : : }
5072 : 108468208 : if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
5073 : 17069 : postfix_attrs = c_parser_gnu_attributes (parser);
5074 : :
5075 : : /* Generate a location for the parameter, ranging from the start of the
5076 : : initial token to the end of the final token.
5077 : :
5078 : : If we have a identifier, then use it for the caret location, e.g.
5079 : :
5080 : : extern int callee (int one, int (*two)(int, int), float three);
5081 : : ~~~~~~^~~~~~~~~~~~~~
5082 : :
5083 : : otherwise, reuse the start location for the caret location e.g.:
5084 : :
5085 : : extern int callee (int one, int (*)(int, int), float three);
5086 : : ^~~~~~~~~~~~~~~~~
5087 : : */
5088 : 108468208 : location_t end_loc = parser->last_token_location;
5089 : :
5090 : : /* Find any cdk_id declarator; determine if we have an identifier. */
5091 : 108468208 : c_declarator *id_declarator = declarator;
5092 : 120186399 : while (id_declarator && id_declarator->kind != cdk_id)
5093 : 11718191 : id_declarator = id_declarator->declarator;
5094 : 216936416 : location_t caret_loc = (id_declarator->u.id.id
5095 : 108468208 : ? id_declarator->id_loc
5096 : : : start_loc);
5097 : 108468208 : location_t param_loc = make_location (caret_loc, start_loc, end_loc);
5098 : :
5099 : 108468208 : return build_c_parm (specs, chainon (postfix_attrs, prefix_attrs),
5100 : 108468208 : declarator, param_loc);
5101 : : }
5102 : :
5103 : : /* Parse a string literal in an asm expression. It should not be
5104 : : translated, and wide string literals are an error although
5105 : : permitted by the syntax. This is a GNU extension.
5106 : :
5107 : : asm-string-literal:
5108 : : string-literal
5109 : : */
5110 : :
5111 : : static tree
5112 : 1747551 : c_parser_asm_string_literal (c_parser *parser)
5113 : : {
5114 : 1747551 : tree str;
5115 : 1747551 : int save_flag = warn_overlength_strings;
5116 : 1747551 : warn_overlength_strings = 0;
5117 : 1747551 : str = c_parser_string_literal (parser, false, false).value;
5118 : 1747551 : warn_overlength_strings = save_flag;
5119 : 1747551 : return str;
5120 : : }
5121 : :
5122 : : /* Parse a simple asm expression. This is used in restricted
5123 : : contexts, where a full expression with inputs and outputs does not
5124 : : make sense. This is a GNU extension.
5125 : :
5126 : : simple-asm-expr:
5127 : : asm ( asm-string-literal )
5128 : : */
5129 : :
5130 : : static tree
5131 : 688326 : c_parser_simple_asm_expr (c_parser *parser)
5132 : : {
5133 : 688326 : tree str;
5134 : 688326 : gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
5135 : 688326 : c_parser_consume_token (parser);
5136 : 688326 : matching_parens parens;
5137 : 688326 : if (!parens.require_open (parser))
5138 : : return NULL_TREE;
5139 : 688321 : str = c_parser_asm_string_literal (parser);
5140 : 688321 : if (!parens.require_close (parser))
5141 : : {
5142 : 1 : c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
5143 : 1 : return NULL_TREE;
5144 : : }
5145 : : return str;
5146 : : }
5147 : :
5148 : : static tree
5149 : 117867121 : c_parser_gnu_attribute_any_word (c_parser *parser)
5150 : : {
5151 : 117867121 : tree attr_name = NULL_TREE;
5152 : :
5153 : 117867121 : if (c_parser_next_token_is (parser, CPP_KEYWORD))
5154 : : {
5155 : : /* ??? See comment above about what keywords are accepted here. */
5156 : 1218797 : bool ok;
5157 : 1218797 : switch (c_parser_peek_token (parser)->keyword)
5158 : : {
5159 : : case RID_STATIC:
5160 : : case RID_UNSIGNED:
5161 : : case RID_LONG:
5162 : : case RID_CONST:
5163 : : case RID_EXTERN:
5164 : : case RID_REGISTER:
5165 : : case RID_TYPEDEF:
5166 : : case RID_SHORT:
5167 : : case RID_INLINE:
5168 : : case RID_NORETURN:
5169 : : case RID_VOLATILE:
5170 : : case RID_SIGNED:
5171 : : case RID_AUTO:
5172 : : case RID_RESTRICT:
5173 : : case RID_COMPLEX:
5174 : : case RID_THREAD:
5175 : : case RID_INT:
5176 : : case RID_CHAR:
5177 : : case RID_FLOAT:
5178 : : case RID_DOUBLE:
5179 : : case RID_VOID:
5180 : : case RID_DFLOAT32:
5181 : : case RID_DFLOAT64:
5182 : : case RID_DFLOAT128:
5183 : : CASE_RID_FLOATN_NX:
5184 : : case RID_BOOL:
5185 : : case RID_BITINT:
5186 : : case RID_FRACT:
5187 : : case RID_ACCUM:
5188 : : case RID_SAT:
5189 : : case RID_TRANSACTION_ATOMIC:
5190 : : case RID_TRANSACTION_CANCEL:
5191 : : case RID_ATOMIC:
5192 : : case RID_AUTO_TYPE:
5193 : : case RID_CONSTEXPR:
5194 : : case RID_INT_N_0:
5195 : : case RID_INT_N_1:
5196 : : case RID_INT_N_2:
5197 : : case RID_INT_N_3:
5198 : : ok = true;
5199 : : break;
5200 : : default:
5201 : 3 : ok = false;
5202 : : break;
5203 : : }
5204 : 1218797 : if (!ok)
5205 : : return NULL_TREE;
5206 : :
5207 : : /* Accept __attribute__((__const)) as __attribute__((const)) etc. */
5208 : 1218797 : attr_name = ridpointers[(int) c_parser_peek_token (parser)->keyword];
5209 : : }
5210 : 116648324 : else if (c_parser_next_token_is (parser, CPP_NAME))
5211 : 116648321 : attr_name = c_parser_peek_token (parser)->value;
5212 : :
5213 : : return attr_name;
5214 : : }
5215 : :
5216 : : /* Parse attribute arguments. This is a common form of syntax
5217 : : covering all currently valid GNU and standard attributes.
5218 : :
5219 : : gnu-attribute-arguments:
5220 : : identifier
5221 : : identifier , nonempty-expr-list
5222 : : expr-list
5223 : :
5224 : : where the "identifier" must not be declared as a type. ??? Why not
5225 : : allow identifiers declared as types to start the arguments? */
5226 : :
5227 : : static tree
5228 : 4153509 : c_parser_attribute_arguments (c_parser *parser, bool takes_identifier,
5229 : : bool require_string, bool assume_attr,
5230 : : bool allow_empty_args)
5231 : : {
5232 : 4153509 : vec<tree, va_gc> *expr_list;
5233 : 4153509 : tree attr_args;
5234 : : /* Parse the attribute contents. If they start with an
5235 : : identifier which is followed by a comma or close
5236 : : parenthesis, then the arguments start with that
5237 : : identifier; otherwise they are an expression list.
5238 : : In objective-c the identifier may be a classname. */
5239 : 4153509 : if (c_parser_next_token_is (parser, CPP_NAME)
5240 : 537643 : && (c_parser_peek_token (parser)->id_kind == C_ID_ID
5241 : 1 : || (c_dialect_objc ()
5242 : 0 : && c_parser_peek_token (parser)->id_kind
5243 : : == C_ID_CLASSNAME))
5244 : 537642 : && ((c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
5245 : 41213 : || (c_parser_peek_2nd_token (parser)->type
5246 : : == CPP_CLOSE_PAREN))
5247 : 4691112 : && (takes_identifier
5248 : 138754 : || (c_dialect_objc ()
5249 : 0 : && !assume_attr
5250 : 0 : && c_parser_peek_token (parser)->id_kind
5251 : : == C_ID_CLASSNAME)))
5252 : : {
5253 : 398849 : tree arg1 = c_parser_peek_token (parser)->value;
5254 : 398849 : c_parser_consume_token (parser);
5255 : 398849 : if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
5256 : 33957 : attr_args = build_tree_list (NULL_TREE, arg1);
5257 : : else
5258 : : {
5259 : 364892 : tree tree_list;
5260 : 364892 : c_parser_consume_token (parser);
5261 : 364892 : expr_list = c_parser_expr_list (parser, false, true,
5262 : : NULL, NULL, NULL, NULL);
5263 : 364892 : tree_list = build_tree_list_vec (expr_list);
5264 : 364892 : attr_args = tree_cons (NULL_TREE, arg1, tree_list);
5265 : 364892 : release_tree_vector (expr_list);
5266 : : }
5267 : : }
5268 : : else
5269 : : {
5270 : 3754660 : if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
5271 : : {
5272 : 16 : if (!allow_empty_args)
5273 : 3 : error_at (c_parser_peek_token (parser)->location,
5274 : : "parentheses must be omitted if "
5275 : : "attribute argument list is empty");
5276 : : attr_args = NULL_TREE;
5277 : : }
5278 : 3754644 : else if (require_string)
5279 : : {
5280 : : /* The only valid argument for this attribute is a string
5281 : : literal. Handle this specially here to avoid accepting
5282 : : string literals with excess parentheses. */
5283 : 19 : tree string = c_parser_string_literal (parser, false, true).value;
5284 : 19 : attr_args = build_tree_list (NULL_TREE, string);
5285 : : }
5286 : 3754625 : else if (assume_attr)
5287 : : {
5288 : 41 : tree cond
5289 : 41 : = c_parser_conditional_expression (parser, NULL, NULL_TREE).value;
5290 : 41 : if (!c_parser_next_token_is (parser, CPP_COMMA))
5291 : 39 : attr_args = build_tree_list (NULL_TREE, cond);
5292 : : else
5293 : : {
5294 : 2 : tree tree_list;
5295 : 2 : c_parser_consume_token (parser);
5296 : 2 : expr_list = c_parser_expr_list (parser, false, true,
5297 : : NULL, NULL, NULL, NULL);
5298 : 2 : tree_list = build_tree_list_vec (expr_list);
5299 : 2 : attr_args = tree_cons (NULL_TREE, cond, tree_list);
5300 : 2 : release_tree_vector (expr_list);
5301 : : }
5302 : : }
5303 : : else
5304 : : {
5305 : 3754584 : expr_list = c_parser_expr_list (parser, false, true,
5306 : : NULL, NULL, NULL, NULL);
5307 : 3754584 : attr_args = build_tree_list_vec (expr_list);
5308 : 3754584 : release_tree_vector (expr_list);
5309 : : }
5310 : : }
5311 : 4153509 : return attr_args;
5312 : : }
5313 : :
5314 : : /* Parse (possibly empty) gnu-attributes. This is a GNU extension.
5315 : :
5316 : : gnu-attributes:
5317 : : empty
5318 : : gnu-attributes gnu-attribute
5319 : :
5320 : : gnu-attribute:
5321 : : __attribute__ ( ( gnu-attribute-list ) )
5322 : :
5323 : : gnu-attribute-list:
5324 : : gnu-attrib
5325 : : gnu-attribute_list , gnu-attrib
5326 : :
5327 : : gnu-attrib:
5328 : : empty
5329 : : any-word
5330 : : any-word ( gnu-attribute-arguments )
5331 : :
5332 : : where "any-word" may be any identifier (including one declared as a
5333 : : type), a reserved word storage class specifier, type specifier or
5334 : : type qualifier. ??? This still leaves out most reserved keywords
5335 : : (following the old parser), shouldn't we include them?
5336 : : When EXPECT_COMMA is true, expect the attribute to be preceded
5337 : : by a comma and fail if it isn't.
5338 : : When EMPTY_OK is true, allow and consume any number of consecutive
5339 : : commas with no attributes in between. */
5340 : :
5341 : : static tree
5342 : 164344081 : c_parser_gnu_attribute (c_parser *parser, tree attrs,
5343 : : bool expect_comma = false, bool empty_ok = true)
5344 : : {
5345 : 164344081 : bool comma_first = c_parser_next_token_is (parser, CPP_COMMA);
5346 : 164344081 : if (!comma_first
5347 : 92954671 : && !c_parser_next_token_is (parser, CPP_NAME)
5348 : 212039738 : && !c_parser_next_token_is (parser, CPP_KEYWORD))
5349 : : return NULL_TREE;
5350 : :
5351 : 189256538 : while (c_parser_next_token_is (parser, CPP_COMMA))
5352 : : {
5353 : 71389417 : c_parser_consume_token (parser);
5354 : 71389417 : if (!empty_ok)
5355 : : return attrs;
5356 : : }
5357 : :
5358 : 117867121 : tree attr_name = c_parser_gnu_attribute_any_word (parser);
5359 : 117867121 : if (attr_name == NULL_TREE)
5360 : : return NULL_TREE;
5361 : :
5362 : 117867118 : attr_name = canonicalize_attr_name (attr_name);
5363 : 117867118 : c_parser_consume_token (parser);
5364 : :
5365 : 117867118 : tree attr;
5366 : 117867118 : if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
5367 : : {
5368 : 113713688 : if (expect_comma && !comma_first)
5369 : : {
5370 : : /* A comma is missing between the last attribute on the chain
5371 : : and this one. */
5372 : 7 : c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
5373 : : "expected %<)%>");
5374 : 7 : return error_mark_node;
5375 : : }
5376 : 113713681 : attr = build_tree_list (attr_name, NULL_TREE);
5377 : : /* Add this attribute to the list. */
5378 : 113713681 : attrs = chainon (attrs, attr);
5379 : 113713681 : return attrs;
5380 : : }
5381 : 4153430 : c_parser_consume_token (parser);
5382 : :
5383 : 4153430 : tree attr_args
5384 : 4153430 : = c_parser_attribute_arguments (parser,
5385 : 4153430 : attribute_takes_identifier_p (attr_name),
5386 : : false,
5387 : 4153430 : is_attribute_p ("assume", attr_name),
5388 : : true);
5389 : :
5390 : 4153430 : attr = build_tree_list (attr_name, attr_args);
5391 : 4153430 : if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
5392 : 4153428 : c_parser_consume_token (parser);
5393 : : else
5394 : : {
5395 : 2 : c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
5396 : : "expected %<)%>");
5397 : 2 : return error_mark_node;
5398 : : }
5399 : :
5400 : 4153428 : if (expect_comma && !comma_first)
5401 : : {
5402 : : /* A comma is missing between the last attribute on the chain
5403 : : and this one. */
5404 : 0 : c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
5405 : : "expected %<)%>");
5406 : 0 : return error_mark_node;
5407 : : }
5408 : :
5409 : : /* Add this attribute to the list. */
5410 : 4153428 : attrs = chainon (attrs, attr);
5411 : 4153428 : return attrs;
5412 : : }
5413 : :
5414 : : static tree
5415 : 95384167 : c_parser_gnu_attributes (c_parser *parser)
5416 : : {
5417 : 95384167 : tree attrs = NULL_TREE;
5418 : 141861126 : while (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
5419 : : {
5420 : 46476969 : bool save_translate_strings_p = parser->translate_strings_p;
5421 : 46476969 : parser->translate_strings_p = false;
5422 : : /* Consume the `__attribute__' keyword. */
5423 : 46476969 : c_parser_consume_token (parser);
5424 : : /* Look for the two `(' tokens. */
5425 : 46476969 : if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
5426 : : {
5427 : 0 : parser->translate_strings_p = save_translate_strings_p;
5428 : 0 : return attrs;
5429 : : }
5430 : 46476969 : if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
5431 : : {
5432 : 0 : parser->translate_strings_p = save_translate_strings_p;
5433 : 0 : c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
5434 : 0 : return attrs;
5435 : : }
5436 : : /* Parse the attribute list. Require a comma between successive
5437 : : (possibly empty) attributes. */
5438 : : for (bool expect_comma = false; ; expect_comma = true)
5439 : : {
5440 : : /* Parse a single attribute. */
5441 : 164343329 : tree attr = c_parser_gnu_attribute (parser, attrs, expect_comma);
5442 : 164343329 : if (attr == error_mark_node)
5443 : 9 : return attrs;
5444 : 164343320 : if (!attr)
5445 : : break;
5446 : : attrs = attr;
5447 : : }
5448 : :
5449 : : /* Look for the two `)' tokens. */
5450 : 46476960 : if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
5451 : 46476960 : c_parser_consume_token (parser);
5452 : : else
5453 : : {
5454 : 0 : parser->translate_strings_p = save_translate_strings_p;
5455 : 0 : c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
5456 : : "expected %<)%>");
5457 : 0 : return attrs;
5458 : : }
5459 : 46476960 : if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
5460 : 46476959 : c_parser_consume_token (parser);
5461 : : else
5462 : : {
5463 : 1 : parser->translate_strings_p = save_translate_strings_p;
5464 : 1 : c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
5465 : : "expected %<)%>");
5466 : 1 : return attrs;
5467 : : }
5468 : 46476959 : parser->translate_strings_p = save_translate_strings_p;
5469 : : }
5470 : :
5471 : : return attrs;
5472 : : }
5473 : :
5474 : : /* Parse an optional balanced token sequence.
5475 : :
5476 : : balanced-token-sequence:
5477 : : balanced-token
5478 : : balanced-token-sequence balanced-token
5479 : :
5480 : : balanced-token:
5481 : : ( balanced-token-sequence[opt] )
5482 : : [ balanced-token-sequence[opt] ]
5483 : : { balanced-token-sequence[opt] }
5484 : : any token other than ()[]{}
5485 : : */
5486 : :
5487 : : static void
5488 : 142 : c_parser_balanced_token_sequence (c_parser *parser)
5489 : : {
5490 : 551 : while (true)
5491 : : {
5492 : 551 : c_token *token = c_parser_peek_token (parser);
5493 : 551 : switch (token->type)
5494 : : {
5495 : 4 : case CPP_OPEN_BRACE:
5496 : 4 : {
5497 : 4 : matching_braces braces;
5498 : 4 : braces.consume_open (parser);
5499 : 4 : c_parser_balanced_token_sequence (parser);
5500 : 4 : braces.require_close (parser);
5501 : 4 : break;
5502 : : }
5503 : :
5504 : 42 : case CPP_OPEN_PAREN:
5505 : 42 : {
5506 : 42 : matching_parens parens;
5507 : 42 : parens.consume_open (parser);
5508 : 42 : c_parser_balanced_token_sequence (parser);
5509 : 42 : parens.require_close (parser);
5510 : 42 : break;
5511 : : }
5512 : :
5513 : 33 : case CPP_OPEN_SQUARE:
5514 : 33 : c_parser_consume_token (parser);
5515 : 33 : c_parser_balanced_token_sequence (parser);
5516 : 33 : c_parser_require (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
5517 : 33 : break;
5518 : :
5519 : 142 : case CPP_CLOSE_BRACE:
5520 : 142 : case CPP_CLOSE_PAREN:
5521 : 142 : case CPP_CLOSE_SQUARE:
5522 : 142 : case CPP_EOF:
5523 : 142 : return;
5524 : :
5525 : 1 : case CPP_PRAGMA:
5526 : 1 : c_parser_consume_pragma (parser);
5527 : 1 : c_parser_skip_to_pragma_eol (parser, false);
5528 : 1 : break;
5529 : :
5530 : 329 : default:
5531 : 329 : c_parser_consume_token (parser);
5532 : 329 : break;
5533 : : }
5534 : : }
5535 : : }
5536 : :
5537 : : static bool c_parser_check_balanced_raw_token_sequence (c_parser *,
5538 : : unsigned int *);
5539 : :
5540 : : /* Parse arguments of omp::directive or omp::decl attribute.
5541 : :
5542 : : directive-name ,[opt] clause-list[opt]
5543 : :
5544 : : For directive just remember the tokens in a vector for subsequent
5545 : : parsing. */
5546 : :
5547 : : static void
5548 : 643 : c_parser_omp_directive_args (c_parser *parser, tree attribute, bool decl_p)
5549 : : {
5550 : 643 : unsigned int n = 1;
5551 : 643 : c_token *first = c_parser_peek_token (parser);
5552 : 643 : if (!c_parser_check_balanced_raw_token_sequence (parser, &n)
5553 : 643 : || (c_parser_peek_nth_token_raw (parser, n)->type
5554 : : != CPP_CLOSE_PAREN))
5555 : : {
5556 : 1 : c_parser_balanced_token_sequence (parser);
5557 : 1 : TREE_VALUE (attribute) = NULL_TREE;
5558 : 3 : return;
5559 : : }
5560 : 642 : if (n == 1)
5561 : : {
5562 : 2 : error_at (first->location, "expected OpenMP directive name");
5563 : 2 : TREE_VALUE (attribute) = NULL_TREE;
5564 : 2 : return;
5565 : : }
5566 : 640 : vec<c_token, va_gc> *v;
5567 : 640 : vec_alloc (v, n - 1);
5568 : 16635 : for (--n; n; --n)
5569 : : {
5570 : 15995 : c_token *tok = c_parser_peek_token (parser);
5571 : 15995 : v->quick_push (*tok);
5572 : 15995 : c_parser_consume_token (parser);
5573 : : }
5574 : 640 : tree arg = make_node (C_TOKEN_VEC);
5575 : 640 : C_TOKEN_VEC_TOKENS (arg) = v;
5576 : 640 : if (decl_p)
5577 : 52 : TREE_PUBLIC (arg) = 1;
5578 : 640 : TREE_VALUE (attribute) = tree_cons (NULL_TREE, arg, TREE_VALUE (attribute));
5579 : : }
5580 : :
5581 : : /* Parse arguments of omp::sequence attribute.
5582 : :
5583 : : omp::[opt] directive-attr [ , omp::[opt] directive-attr ]... */
5584 : :
5585 : : static void
5586 : 87 : c_parser_omp_sequence_args (c_parser *parser, tree attribute)
5587 : : {
5588 : 141 : do
5589 : : {
5590 : 141 : c_token *token = c_parser_peek_token (parser);
5591 : 141 : if (token->type == CPP_NAME
5592 : 140 : && strcmp (IDENTIFIER_POINTER (token->value), "omp") == 0
5593 : 205 : && c_parser_peek_2nd_token (parser)->type == CPP_SCOPE)
5594 : : {
5595 : 64 : c_parser_consume_token (parser);
5596 : 64 : c_parser_consume_token (parser);
5597 : 64 : token = c_parser_peek_token (parser);
5598 : : }
5599 : 141 : bool directive = false;
5600 : 141 : const char *p;
5601 : 141 : if (token->type != CPP_NAME)
5602 : : p = "";
5603 : : else
5604 : 140 : p = IDENTIFIER_POINTER (token->value);
5605 : 141 : if (strcmp (p, "directive") == 0)
5606 : : directive = true;
5607 : 12 : else if (strcmp (p, "sequence") != 0)
5608 : : {
5609 : 7 : error_at (token->location, "expected %<directive%> or %<sequence%>");
5610 : 7 : unsigned nesting_depth = 0;
5611 : :
5612 : 47 : while (true)
5613 : : {
5614 : : /* Peek at the next token. */
5615 : 27 : token = c_parser_peek_token (parser);
5616 : : /* If we've reached the token we want, consume it and stop. */
5617 : 27 : if ((token->type == CPP_CLOSE_PAREN || token->type == CPP_COMMA)
5618 : 13 : && !nesting_depth)
5619 : : break;
5620 : : /* If we've run out of tokens, stop. */
5621 : 20 : if (token->type == CPP_EOF)
5622 : : break;
5623 : 20 : if (token->type == CPP_PRAGMA_EOL && parser->in_pragma)
5624 : : break;
5625 : 20 : if (token->type == CPP_OPEN_BRACE
5626 : : || token->type == CPP_OPEN_PAREN
5627 : : || token->type == CPP_OPEN_SQUARE)
5628 : 6 : ++nesting_depth;
5629 : : else if (token->type == CPP_CLOSE_BRACE
5630 : : || token->type == CPP_CLOSE_PAREN
5631 : : || token->type == CPP_CLOSE_SQUARE)
5632 : : {
5633 : 6 : if (nesting_depth-- == 0)
5634 : : break;
5635 : : }
5636 : : /* Consume this token. */
5637 : 20 : c_parser_consume_token (parser);
5638 : : }
5639 : 7 : if (c_parser_next_token_is_not (parser, CPP_COMMA))
5640 : : break;
5641 : 0 : c_parser_consume_token (parser);
5642 : 0 : continue;
5643 : 0 : }
5644 : 134 : c_parser_consume_token (parser);
5645 : 134 : matching_parens parens;
5646 : 134 : if (parens.require_open (parser))
5647 : : {
5648 : 132 : if (directive)
5649 : 128 : c_parser_omp_directive_args (parser, attribute, false);
5650 : : else
5651 : 4 : c_parser_omp_sequence_args (parser, attribute);
5652 : 132 : parens.skip_until_found_close (parser);
5653 : 132 : if (c_parser_next_token_is_not (parser, CPP_COMMA))
5654 : : break;
5655 : 54 : c_parser_consume_token (parser);
5656 : : }
5657 : 2 : else if (c_parser_next_token_is_not (parser, CPP_COMMA))
5658 : : break;
5659 : : else
5660 : 0 : c_parser_consume_token (parser);
5661 : : }
5662 : : while (1);
5663 : 87 : }
5664 : :
5665 : : /* Parse standard (C23) attributes (including GNU attributes in the
5666 : : gnu:: namespace).
5667 : :
5668 : : attribute-specifier-sequence:
5669 : : attribute-specifier-sequence[opt] attribute-specifier
5670 : :
5671 : : attribute-specifier:
5672 : : [ [ attribute-list ] ]
5673 : :
5674 : : attribute-list:
5675 : : attribute[opt]
5676 : : attribute-list, attribute[opt]
5677 : :
5678 : : attribute:
5679 : : attribute-token attribute-argument-clause[opt]
5680 : :
5681 : : attribute-token:
5682 : : standard-attribute
5683 : : attribute-prefixed-token
5684 : :
5685 : : standard-attribute:
5686 : : identifier
5687 : :
5688 : : attribute-prefixed-token:
5689 : : attribute-prefix :: identifier
5690 : :
5691 : : attribute-prefix:
5692 : : identifier
5693 : :
5694 : : attribute-argument-clause:
5695 : : ( balanced-token-sequence[opt] )
5696 : :
5697 : : Keywords are accepted as identifiers for this purpose.
5698 : :
5699 : : As an extension, we permit an attribute-specifier to be:
5700 : :
5701 : : [ [ __extension__ attribute-list ] ]
5702 : :
5703 : : Two colons are then accepted as a synonym for ::. No attempt is made
5704 : : to check whether the colons are immediately adjacent. LOOSE_SCOPE_P
5705 : : indicates whether this relaxation is in effect. */
5706 : :
5707 : : static tree
5708 : 1187 : c_parser_std_attribute (c_parser *parser, bool for_tm)
5709 : : {
5710 : 1187 : c_token *token = c_parser_peek_token (parser);
5711 : 1187 : tree ns, name, attribute;
5712 : :
5713 : : /* Parse the attribute-token. */
5714 : 1187 : if (token->type != CPP_NAME && token->type != CPP_KEYWORD)
5715 : : {
5716 : 2 : c_parser_error (parser, "expected identifier");
5717 : 2 : return error_mark_node;
5718 : : }
5719 : 1185 : name = canonicalize_attr_name (token->value);
5720 : 1185 : c_parser_consume_token (parser);
5721 : 1185 : if (c_parser_next_token_is (parser, CPP_SCOPE)
5722 : 1500 : || (c_parser_next_token_is (parser, CPP_COLON)
5723 : 36 : && (c_parser_peek_token (parser)->flags & COLON_SCOPE) != 0
5724 : 10 : && c_parser_peek_2nd_token (parser)->type == CPP_COLON))
5725 : : {
5726 : 880 : ns = name;
5727 : 880 : if (c_parser_next_token_is (parser, CPP_COLON))
5728 : 10 : c_parser_consume_token (parser);
5729 : 880 : c_parser_consume_token (parser);
5730 : 880 : token = c_parser_peek_token (parser);
5731 : 880 : if (token->type != CPP_NAME && token->type != CPP_KEYWORD)
5732 : : {
5733 : 0 : c_parser_error (parser, "expected identifier");
5734 : 0 : return error_mark_node;
5735 : : }
5736 : 880 : name = canonicalize_attr_name (token->value);
5737 : 880 : c_parser_consume_token (parser);
5738 : : }
5739 : : else
5740 : : ns = NULL_TREE;
5741 : 1185 : attribute = build_tree_list (build_tree_list (ns, name), NULL_TREE);
5742 : :
5743 : : /* Parse the arguments, if any. */
5744 : 1185 : const attribute_spec *as = lookup_attribute_spec (TREE_PURPOSE (attribute));
5745 : 1185 : if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
5746 : : {
5747 : 434 : if ((flag_openmp || flag_openmp_simd)
5748 : 9 : && ns
5749 : 7 : && is_attribute_p ("omp", ns)
5750 : 446 : && (is_attribute_p ("directive", name)
5751 : 2 : || is_attribute_p ("sequence", name)
5752 : 1 : || is_attribute_p ("decl", name)))
5753 : : {
5754 : 3 : error ("%<omp::%E%> attribute requires argument", name);
5755 : 3 : return error_mark_node;
5756 : : }
5757 : 440 : goto out;
5758 : : }
5759 : 742 : {
5760 : 742 : location_t open_loc = c_parser_peek_token (parser)->location;
5761 : 742 : matching_parens parens;
5762 : 742 : parens.consume_open (parser);
5763 : 102 : if ((as && as->max_length == 0)
5764 : : /* Special-case the transactional-memory attribute "outer",
5765 : : which is specially handled but not registered as an
5766 : : attribute, to avoid allowing arbitrary balanced token
5767 : : sequences as arguments. */
5768 : 834 : || is_attribute_p ("outer", name))
5769 : : {
5770 : 11 : error_at (open_loc, "%qE attribute does not take any arguments", name);
5771 : 11 : parens.skip_until_found_close (parser);
5772 : 609 : return error_mark_node;
5773 : : }
5774 : : /* If this is a fake attribute created to handle -Wno-attributes,
5775 : : we must skip parsing the arguments. */
5776 : 731 : if (as && !attribute_ignored_p (as))
5777 : : {
5778 : 79 : bool takes_identifier
5779 : : = (ns != NULL_TREE
5780 : 58 : && strcmp (IDENTIFIER_POINTER (ns), "gnu") == 0
5781 : 137 : && attribute_takes_identifier_p (name));
5782 : 21 : bool require_string
5783 : : = (ns == NULL_TREE
5784 : 21 : && (strcmp (IDENTIFIER_POINTER (name), "deprecated") == 0
5785 : 11 : || strcmp (IDENTIFIER_POINTER (name), "nodiscard") == 0));
5786 : 58 : bool assume_attr
5787 : : = (ns != NULL_TREE
5788 : 58 : && strcmp (IDENTIFIER_POINTER (ns), "gnu") == 0
5789 : 58 : && strcmp (IDENTIFIER_POINTER (name), "assume") == 0);
5790 : 158 : TREE_VALUE (attribute)
5791 : 79 : = c_parser_attribute_arguments (parser, takes_identifier,
5792 : : require_string, assume_attr, false);
5793 : : }
5794 : : else
5795 : : {
5796 : 54 : if ((flag_openmp || flag_openmp_simd)
5797 : 598 : && ns
5798 : 1250 : && is_attribute_p ("omp", ns))
5799 : : {
5800 : 598 : if (is_attribute_p ("directive", name))
5801 : : {
5802 : 462 : c_parser_omp_directive_args (parser, attribute, false);
5803 : 462 : parens.skip_until_found_close (parser);
5804 : 462 : return attribute;
5805 : : }
5806 : 136 : else if (is_attribute_p ("decl", name))
5807 : : {
5808 : 53 : TREE_VALUE (TREE_PURPOSE (attribute))
5809 : 53 : = get_identifier ("directive");
5810 : 53 : c_parser_omp_directive_args (parser, attribute, true);
5811 : 53 : parens.skip_until_found_close (parser);
5812 : 53 : return attribute;
5813 : : }
5814 : 83 : else if (is_attribute_p ("sequence", name))
5815 : : {
5816 : 83 : TREE_VALUE (TREE_PURPOSE (attribute))
5817 : 83 : = get_identifier ("directive");
5818 : 83 : c_parser_omp_sequence_args (parser, attribute);
5819 : 83 : parens.skip_until_found_close (parser);
5820 : 83 : TREE_VALUE (attribute) = nreverse (TREE_VALUE (attribute));
5821 : 83 : return attribute;
5822 : : }
5823 : : }
5824 : 54 : c_parser_balanced_token_sequence (parser);
5825 : : }
5826 : 133 : parens.require_close (parser);
5827 : : }
5828 : 573 : out:
5829 : 573 : if (ns == NULL_TREE && !for_tm && !as)
5830 : : {
5831 : : /* An attribute with standard syntax and no namespace specified
5832 : : is a constraint violation if it is not one of the known
5833 : : standard attributes. Diagnose it here with a pedwarn and
5834 : : then discard it to prevent a duplicate warning later. */
5835 : 68 : pedwarn (input_location, OPT_Wattributes, "%qE attribute ignored",
5836 : : name);
5837 : 68 : return error_mark_node;
5838 : : }
5839 : : return attribute;
5840 : : }
5841 : :
5842 : : static tree
5843 : 1218 : c_parser_std_attribute_list (c_parser *parser, bool for_tm)
5844 : : {
5845 : 1218 : tree attributes = NULL_TREE;
5846 : 1406 : while (true)
5847 : : {
5848 : 1406 : c_token *token = c_parser_peek_token (parser);
5849 : 1406 : if (token->type == CPP_CLOSE_SQUARE)
5850 : : break;
5851 : 1292 : if (token->type == CPP_COMMA)
5852 : : {
5853 : 105 : c_parser_consume_token (parser);
5854 : 105 : continue;
5855 : : }
5856 : 1187 : tree attribute = c_parser_std_attribute (parser, for_tm);
5857 : 1187 : if (attribute != error_mark_node)
5858 : : {
5859 : 1103 : TREE_CHAIN (attribute) = attributes;
5860 : 1103 : attributes = attribute;
5861 : : }
5862 : 1187 : if (c_parser_next_token_is_not (parser, CPP_COMMA))
5863 : : break;
5864 : : }
5865 : 1218 : return attributes;
5866 : : }
5867 : :
5868 : : static tree
5869 : 1218 : c_parser_std_attribute_specifier (c_parser *parser, bool for_tm)
5870 : : {
5871 : 1218 : location_t loc = c_parser_peek_token (parser)->location;
5872 : 1218 : if (!c_parser_require (parser, CPP_OPEN_SQUARE, "expected %<[%>"))
5873 : : return NULL_TREE;
5874 : 1218 : if (!c_parser_require (parser, CPP_OPEN_SQUARE, "expected %<[%>"))
5875 : : {
5876 : 0 : c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
5877 : 0 : return NULL_TREE;
5878 : : }
5879 : 1218 : tree attributes;
5880 : 1218 : if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
5881 : : {
5882 : 42 : auto ext = disable_extension_diagnostics ();
5883 : 42 : c_parser_consume_token (parser);
5884 : 42 : attributes = c_parser_std_attribute_list (parser, for_tm);
5885 : 42 : restore_extension_diagnostics (ext);
5886 : : }
5887 : : else
5888 : : {
5889 : 1176 : if (!for_tm)
5890 : 1156 : pedwarn_c11 (loc, OPT_Wpedantic,
5891 : : "ISO C does not support %<[[]]%> attributes before C23");
5892 : 1176 : attributes = c_parser_std_attribute_list (parser, for_tm);
5893 : : }
5894 : 1218 : c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
5895 : 1218 : c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
5896 : 1218 : return nreverse (attributes);
5897 : : }
5898 : :
5899 : : /* Look past an optional balanced token sequence of raw look-ahead
5900 : : tokens starting with the *Nth token. *N is updated to point to the
5901 : : following token. Return true if such a sequence was found, false
5902 : : if the tokens parsed were not balanced. */
5903 : :
5904 : : static bool
5905 : 3739 : c_parser_check_balanced_raw_token_sequence (c_parser *parser, unsigned int *n)
5906 : : {
5907 : 17862 : while (true)
5908 : : {
5909 : 17862 : c_token *token = c_parser_peek_nth_token_raw (parser, *n);
5910 : 17862 : switch (token->type)
5911 : : {
5912 : 9 : case CPP_OPEN_BRACE:
5913 : 9 : {
5914 : 9 : ++*n;
5915 : 9 : if (c_parser_check_balanced_raw_token_sequence (parser, n))
5916 : : {
5917 : 9 : token = c_parser_peek_nth_token_raw (parser, *n);
5918 : 9 : if (token->type == CPP_CLOSE_BRACE)
5919 : 9 : ++*n;
5920 : : else
5921 : : return false;
5922 : : }
5923 : : else
5924 : : return false;
5925 : 9 : break;
5926 : : }
5927 : :
5928 : 2851 : case CPP_OPEN_PAREN:
5929 : 2851 : {
5930 : 2851 : ++*n;
5931 : 2851 : if (c_parser_check_balanced_raw_token_sequence (parser, n))
5932 : : {
5933 : 2851 : token = c_parser_peek_nth_token_raw (parser, *n);
5934 : 2851 : if (token->type == CPP_CLOSE_PAREN)
5935 : 2851 : ++*n;
5936 : : else
5937 : : return false;
5938 : : }
5939 : : else
5940 : : return false;
5941 : 2851 : break;
5942 : : }
5943 : :
5944 : 51 : case CPP_OPEN_SQUARE:
5945 : 51 : {
5946 : 51 : ++*n;
5947 : 51 : if (c_parser_check_balanced_raw_token_sequence (parser, n))
5948 : : {
5949 : 51 : token = c_parser_peek_nth_token_raw (parser, *n);
5950 : 51 : if (token->type == CPP_CLOSE_SQUARE)
5951 : 51 : ++*n;
5952 : : else
5953 : : return false;
5954 : : }
5955 : : else
5956 : : return false;
5957 : 51 : break;
5958 : : }
5959 : :
5960 : : case CPP_CLOSE_BRACE:
5961 : : case CPP_CLOSE_PAREN:
5962 : : case CPP_CLOSE_SQUARE:
5963 : : case CPP_EOF:
5964 : : return true;
5965 : :
5966 : 11212 : default:
5967 : 11212 : ++*n;
5968 : 11212 : break;
5969 : : }
5970 : : }
5971 : : }
5972 : :
5973 : : /* Return whether standard attributes start with the Nth token. */
5974 : :
5975 : : static bool
5976 : 783568560 : c_parser_nth_token_starts_std_attributes (c_parser *parser, unsigned int n)
5977 : : {
5978 : 783568560 : if (!(c_parser_peek_nth_token (parser, n)->type == CPP_OPEN_SQUARE
5979 : 2138420 : && c_parser_peek_nth_token (parser, n + 1)->type == CPP_OPEN_SQUARE))
5980 : 783567005 : return false;
5981 : : /* In C, '[[' must start attributes. In Objective-C, we need to
5982 : : check whether '[[' is matched by ']]'. */
5983 : 1555 : if (!c_dialect_objc ())
5984 : : return true;
5985 : 0 : n += 2;
5986 : 0 : if (!c_parser_check_balanced_raw_token_sequence (parser, &n))
5987 : : return false;
5988 : 0 : c_token *token = c_parser_peek_nth_token_raw (parser, n);
5989 : 0 : if (token->type != CPP_CLOSE_SQUARE)
5990 : : return false;
5991 : 0 : token = c_parser_peek_nth_token_raw (parser, n + 1);
5992 : 0 : return token->type == CPP_CLOSE_SQUARE;
5993 : : }
5994 : :
5995 : : static tree
5996 : 1179 : c_parser_std_attribute_specifier_sequence (c_parser *parser)
5997 : : {
5998 : 1179 : tree attributes = NULL_TREE;
5999 : 1198 : do
6000 : : {
6001 : 1198 : tree attrs = c_parser_std_attribute_specifier (parser, false);
6002 : 1198 : attributes = chainon (attributes, attrs);
6003 : : }
6004 : 1198 : while (c_parser_nth_token_starts_std_attributes (parser, 1));
6005 : 1179 : return attributes;
6006 : : }
6007 : :
6008 : : /* Parse a type name (C90 6.5.5, C99 6.7.6, C11 6.7.7). ALIGNAS_OK
6009 : : says whether alignment specifiers are OK (only in cases that might
6010 : : be the type name of a compound literal).
6011 : :
6012 : : type-name:
6013 : : specifier-qualifier-list abstract-declarator[opt]
6014 : : */
6015 : :
6016 : : struct c_type_name *
6017 : 105214934 : c_parser_type_name (c_parser *parser, bool alignas_ok)
6018 : : {
6019 : 105214934 : struct c_declspecs *specs = build_null_declspecs ();
6020 : 105214934 : struct c_declarator *declarator;
6021 : 105214934 : struct c_type_name *ret;
6022 : 105214934 : bool dummy = false;
6023 : 105214934 : c_parser_declspecs (parser, specs, false, true, true, alignas_ok, false,
6024 : : false, true, cla_prefer_type);
6025 : 105214934 : if (!specs->declspecs_seen_p)
6026 : : {
6027 : 4 : c_parser_error (parser, "expected specifier-qualifier-list");
6028 : 4 : return NULL;
6029 : : }
6030 : 105214930 : if (specs->type != error_mark_node)
6031 : : {
6032 : 105214916 : pending_xref_error ();
6033 : 105214916 : finish_declspecs (specs);
6034 : : }
6035 : 210429860 : declarator = c_parser_declarator (parser,
6036 : 105214930 : specs->typespec_kind != ctsk_none,
6037 : : C_DTR_ABSTRACT, &dummy);
6038 : 105214930 : if (declarator == NULL)
6039 : : return NULL;
6040 : 105214929 : ret = XOBNEW (&parser_obstack, struct c_type_name);
6041 : 105214929 : ret->specs = specs;
6042 : 105214929 : ret->declarator = declarator;
6043 : 105214929 : return ret;
6044 : : }
6045 : :
6046 : : /* Parse an initializer (C90 6.5.7, C99 6.7.8, C11 6.7.9).
6047 : :
6048 : : initializer:
6049 : : assignment-expression
6050 : : { initializer-list }
6051 : : { initializer-list , }
6052 : :
6053 : : initializer-list:
6054 : : designation[opt] initializer
6055 : : initializer-list , designation[opt] initializer
6056 : :
6057 : : designation:
6058 : : designator-list =
6059 : :
6060 : : designator-list:
6061 : : designator
6062 : : designator-list designator
6063 : :
6064 : : designator:
6065 : : array-designator
6066 : : . identifier
6067 : :
6068 : : array-designator:
6069 : : [ constant-expression ]
6070 : :
6071 : : GNU extensions:
6072 : :
6073 : : initializer:
6074 : : { }
6075 : :
6076 : : designation:
6077 : : array-designator
6078 : : identifier :
6079 : :
6080 : : array-designator:
6081 : : [ constant-expression ... constant-expression ]
6082 : :
6083 : : Any expression without commas is accepted in the syntax for the
6084 : : constant-expressions, with non-constant expressions rejected later.
6085 : :
6086 : : DECL is the declaration we're parsing this initializer for.
6087 : :
6088 : : This function is only used for top-level initializers; for nested
6089 : : ones, see c_parser_initval. */
6090 : :
6091 : : static struct c_expr
6092 : 6130866 : c_parser_initializer (c_parser *parser, tree decl)
6093 : : {
6094 : 6130866 : if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
6095 : 102183 : return c_parser_braced_init (parser, NULL_TREE, false, NULL, decl);
6096 : : else
6097 : : {
6098 : 6028683 : struct c_expr ret;
6099 : 6028683 : location_t loc = c_parser_peek_token (parser)->location;
6100 : 6028683 : ret = c_parser_expr_no_commas (parser, NULL);
6101 : 6028681 : if (decl != error_mark_node && C_DECL_VARIABLE_SIZE (decl))
6102 : : {
6103 : 2 : error_at (loc,
6104 : : "variable-sized object may not be initialized except "
6105 : : "with an empty initializer");
6106 : 2 : ret.set_error ();
6107 : : }
6108 : : /* This is handled mostly by gimplify.cc, but we have to deal with
6109 : : not warning about int x = x; as it is a GCC extension to turn off
6110 : : this warning but only if warn_init_self is zero. */
6111 : 6028681 : if (VAR_P (decl)
6112 : 6028637 : && !DECL_EXTERNAL (decl)
6113 : 6028637 : && !TREE_STATIC (decl)
6114 : 5912166 : && ret.value == decl
6115 : 6115199 : && !warning_enabled_at (DECL_SOURCE_LOCATION (decl), OPT_Winit_self))
6116 : 86511 : suppress_warning (decl, OPT_Winit_self);
6117 : 6028681 : if (TREE_CODE (ret.value) != STRING_CST
6118 : 6028681 : && (TREE_CODE (ret.value) != COMPOUND_LITERAL_EXPR
6119 : 92736 : || C_DECL_DECLARED_CONSTEXPR (COMPOUND_LITERAL_EXPR_DECL
6120 : : (ret.value))))
6121 : 5923750 : ret = convert_lvalue_to_rvalue (loc, ret, true, true, true);
6122 : 6028681 : return ret;
6123 : : }
6124 : : }
6125 : :
6126 : : /* The location of the last comma within the current initializer list,
6127 : : or UNKNOWN_LOCATION if not within one. */
6128 : :
6129 : : location_t last_init_list_comma;
6130 : :
6131 : : /* Parse a braced initializer list. TYPE is the type specified for a
6132 : : compound literal, and NULL_TREE for other initializers and for
6133 : : nested braced lists. NESTED_P is true for nested braced lists,
6134 : : false for the list of a compound literal or the list that is the
6135 : : top-level initializer in a declaration. DECL is the declaration for
6136 : : the top-level initializer for a declaration, otherwise NULL_TREE. */
6137 : :
6138 : : static struct c_expr
6139 : 1309842 : c_parser_braced_init (c_parser *parser, tree type, bool nested_p,
6140 : : struct obstack *outer_obstack, tree decl)
6141 : : {
6142 : 1309842 : struct c_expr ret;
6143 : 1309842 : struct obstack braced_init_obstack;
6144 : 1309842 : location_t brace_loc = c_parser_peek_token (parser)->location;
6145 : 1309842 : gcc_obstack_init (&braced_init_obstack);
6146 : 1309842 : gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE));
6147 : 1309842 : bool save_c_omp_array_section_p = c_omp_array_section_p;
6148 : 1309842 : c_omp_array_section_p = false;
6149 : 1309842 : matching_braces braces;
6150 : 1309842 : braces.consume_open (parser);
6151 : 1309842 : if (nested_p)
6152 : : {
6153 : 338435 : finish_implicit_inits (brace_loc, outer_obstack);
6154 : 338435 : push_init_level (brace_loc, 0, &braced_init_obstack);
6155 : : }
6156 : : else
6157 : 971407 : really_start_incremental_init (type);
6158 : 1309842 : if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
6159 : : {
6160 : 2292 : pedwarn_c11 (brace_loc, OPT_Wpedantic,
6161 : : "ISO C forbids empty initializer braces before C23");
6162 : : }
6163 : : else
6164 : : {
6165 : 1307550 : if (decl && decl != error_mark_node && C_DECL_VARIABLE_SIZE (decl))
6166 : 51 : error_at (brace_loc,
6167 : : "variable-sized object may not be initialized except "
6168 : : "with an empty initializer");
6169 : : /* Parse a non-empty initializer list, possibly with a trailing
6170 : : comma. */
6171 : 8655955 : while (true)
6172 : : {
6173 : 8655955 : c_parser_initelt (parser, &braced_init_obstack);
6174 : 8655955 : if (parser->error)
6175 : : break;
6176 : 8655925 : if (c_parser_next_token_is (parser, CPP_COMMA))
6177 : : {
6178 : 7350982 : last_init_list_comma = c_parser_peek_token (parser)->location;
6179 : 7350982 : c_parser_consume_token (parser);
6180 : : }
6181 : : else
6182 : : break;
6183 : 7350982 : if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
6184 : : break;
6185 : : }
6186 : : }
6187 : 1309842 : c_omp_array_section_p = save_c_omp_array_section_p;
6188 : 1309842 : c_token *next_tok = c_parser_peek_token (parser);
6189 : 1309842 : if (next_tok->type != CPP_CLOSE_BRACE)
6190 : : {
6191 : 31 : ret.set_error ();
6192 : 31 : ret.original_code = ERROR_MARK;
6193 : 31 : ret.original_type = NULL;
6194 : 31 : braces.skip_until_found_close (parser);
6195 : 31 : pop_init_level (brace_loc, 0, &braced_init_obstack, last_init_list_comma);
6196 : 31 : obstack_free (&braced_init_obstack, NULL);
6197 : : return ret;
6198 : : }
6199 : 1309811 : location_t close_loc = next_tok->location;
6200 : 1309811 : c_parser_consume_token (parser);
6201 : 1309811 : ret = pop_init_level (brace_loc, 0, &braced_init_obstack, close_loc);
6202 : 1309811 : obstack_free (&braced_init_obstack, NULL);
6203 : 1309811 : set_c_expr_source_range (&ret, brace_loc, close_loc);
6204 : 1309811 : return ret;
6205 : : }
6206 : :
6207 : : /* Parse a nested initializer, including designators. */
6208 : :
6209 : : static void
6210 : 8655955 : c_parser_initelt (c_parser *parser, struct obstack * braced_init_obstack)
6211 : : {
6212 : : /* Parse any designator or designator list. A single array
6213 : : designator may have the subsequent "=" omitted in GNU C, but a
6214 : : longer list or a structure member designator may not. */
6215 : 8655955 : if (c_parser_next_token_is (parser, CPP_NAME)
6216 : 8655955 : && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
6217 : : {
6218 : : /* Old-style structure member designator. */
6219 : 156 : set_init_label (c_parser_peek_token (parser)->location,
6220 : 156 : c_parser_peek_token (parser)->value,
6221 : 156 : c_parser_peek_token (parser)->location,
6222 : : braced_init_obstack);
6223 : : /* Use the colon as the error location. */
6224 : 156 : pedwarn (c_parser_peek_2nd_token (parser)->location, OPT_Wpedantic,
6225 : : "obsolete use of designated initializer with %<:%>");
6226 : 156 : c_parser_consume_token (parser);
6227 : 156 : c_parser_consume_token (parser);
6228 : : }
6229 : : else
6230 : : {
6231 : : /* des_seen is 0 if there have been no designators, 1 if there
6232 : : has been a single array designator and 2 otherwise. */
6233 : : int des_seen = 0;
6234 : : /* Location of a designator. */
6235 : : location_t des_loc = UNKNOWN_LOCATION; /* Quiet warning. */
6236 : 8687376 : while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
6237 : 17374227 : || c_parser_next_token_is (parser, CPP_DOT))
6238 : : {
6239 : 31577 : int des_prev = des_seen;
6240 : 31577 : if (!des_seen)
6241 : 31260 : des_loc = c_parser_peek_token (parser)->location;
6242 : 31577 : if (des_seen < 2)
6243 : 31324 : des_seen++;
6244 : 31577 : if (c_parser_next_token_is (parser, CPP_DOT))
6245 : : {
6246 : 31052 : des_seen = 2;
6247 : 31052 : c_parser_consume_token (parser);
6248 : 31052 : if (c_parser_next_token_is (parser, CPP_NAME))
6249 : : {
6250 : 31052 : set_init_label (des_loc, c_parser_peek_token (parser)->value,
6251 : 31052 : c_parser_peek_token (parser)->location,
6252 : : braced_init_obstack);
6253 : 31052 : c_parser_consume_token (parser);
6254 : : }
6255 : : else
6256 : : {
6257 : 0 : struct c_expr init;
6258 : 0 : init.set_error ();
6259 : 0 : init.original_code = ERROR_MARK;
6260 : 0 : init.original_type = NULL;
6261 : 0 : c_parser_error (parser, "expected identifier");
6262 : 0 : c_parser_skip_until_found (parser, CPP_COMMA, NULL);
6263 : 0 : process_init_element (input_location, init, false,
6264 : : braced_init_obstack);
6265 : 0 : return;
6266 : : }
6267 : : }
6268 : : else
6269 : : {
6270 : 525 : struct c_expr first_expr;
6271 : 525 : tree first, second;
6272 : 525 : location_t ellipsis_loc = UNKNOWN_LOCATION; /* Quiet warning. */
6273 : 525 : location_t array_index_loc = UNKNOWN_LOCATION;
6274 : : /* ??? Following the old parser, [ objc-receiver
6275 : : objc-message-args ] is accepted as an initializer,
6276 : : being distinguished from a designator by what follows
6277 : : the first assignment expression inside the square
6278 : : brackets, but after a first array designator a
6279 : : subsequent square bracket is for Objective-C taken to
6280 : : start an expression, using the obsolete form of
6281 : : designated initializer without '=', rather than
6282 : : possibly being a second level of designation: in LALR
6283 : : terms, the '[' is shifted rather than reducing
6284 : : designator to designator-list. */
6285 : 525 : if (des_prev == 1 && c_dialect_objc ())
6286 : : {
6287 : 0 : des_seen = des_prev;
6288 : 0 : break;
6289 : : }
6290 : 525 : if (des_prev == 0 && c_dialect_objc ())
6291 : : {
6292 : : /* This might be an array designator or an
6293 : : Objective-C message expression. If the former,
6294 : : continue parsing here; if the latter, parse the
6295 : : remainder of the initializer given the starting
6296 : : primary-expression. ??? It might make sense to
6297 : : distinguish when des_prev == 1 as well; see
6298 : : previous comment. */
6299 : 0 : tree rec, args;
6300 : 0 : struct c_expr mexpr;
6301 : 0 : c_parser_consume_token (parser);
6302 : 0 : if (c_parser_peek_token (parser)->type == CPP_NAME
6303 : 0 : && ((c_parser_peek_token (parser)->id_kind
6304 : : == C_ID_TYPENAME)
6305 : 0 : || (c_parser_peek_token (parser)->id_kind
6306 : : == C_ID_CLASSNAME)))
6307 : : {
6308 : : /* Type name receiver. */
6309 : 0 : tree id = c_parser_peek_token (parser)->value;
6310 : 0 : c_parser_consume_token (parser);
6311 : 0 : rec = objc_get_class_reference (id);
6312 : 0 : goto parse_message_args;
6313 : : }
6314 : 0 : array_index_loc = c_parser_peek_token (parser)->location;
6315 : 0 : first_expr = c_parser_expr_no_commas (parser, NULL);
6316 : 0 : mark_exp_read (first_expr.value);
6317 : 0 : if (c_parser_next_token_is (parser, CPP_ELLIPSIS)
6318 : 0 : || c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
6319 : 0 : goto array_desig_after_first;
6320 : 0 : first = first_expr.value;
6321 : : /* Expression receiver. So far only one part
6322 : : without commas has been parsed; there might be
6323 : : more of the expression. */
6324 : : rec = first;
6325 : 0 : while (c_parser_next_token_is (parser, CPP_COMMA))
6326 : : {
6327 : 0 : struct c_expr next;
6328 : 0 : location_t comma_loc, exp_loc;
6329 : 0 : comma_loc = c_parser_peek_token (parser)->location;
6330 : 0 : c_parser_consume_token (parser);
6331 : 0 : exp_loc = c_parser_peek_token (parser)->location;
6332 : 0 : next = c_parser_expr_no_commas (parser, NULL);
6333 : 0 : next = convert_lvalue_to_rvalue (exp_loc, next,
6334 : : true, true);
6335 : 0 : rec = build_compound_expr (comma_loc, rec, next.value);
6336 : : }
6337 : 0 : parse_message_args:
6338 : : /* Now parse the objc-message-args. */
6339 : 0 : args = c_parser_objc_message_args (parser);
6340 : 0 : c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
6341 : : "expected %<]%>");
6342 : 0 : mexpr.value
6343 : 0 : = objc_build_message_expr (rec, args);
6344 : 0 : mexpr.original_code = ERROR_MARK;
6345 : 0 : mexpr.original_type = NULL;
6346 : 0 : mexpr.m_decimal = 0;
6347 : : /* Now parse and process the remainder of the
6348 : : initializer, starting with this message
6349 : : expression as a primary-expression. */
6350 : 0 : c_parser_initval (parser, &mexpr, braced_init_obstack);
6351 : 0 : return;
6352 : : }
6353 : 525 : c_parser_consume_token (parser);
6354 : 525 : array_index_loc = c_parser_peek_token (parser)->location;
6355 : 525 : first_expr = c_parser_expr_no_commas (parser, NULL);
6356 : 525 : mark_exp_read (first_expr.value);
6357 : 525 : array_desig_after_first:
6358 : 525 : first_expr = convert_lvalue_to_rvalue (array_index_loc,
6359 : : first_expr,
6360 : : true, true);
6361 : 525 : first = first_expr.value;
6362 : 525 : if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
6363 : : {
6364 : 55 : ellipsis_loc = c_parser_peek_token (parser)->location;
6365 : 55 : c_parser_consume_token (parser);
6366 : 55 : second = convert_lvalue_to_rvalue (ellipsis_loc,
6367 : : (c_parser_expr_no_commas
6368 : : (parser, NULL)),
6369 : : true, true).value;
6370 : 55 : mark_exp_read (second);
6371 : : }
6372 : : else
6373 : : second = NULL_TREE;
6374 : 525 : if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
6375 : : {
6376 : 525 : c_parser_consume_token (parser);
6377 : 525 : set_init_index (array_index_loc, first, second,
6378 : : braced_init_obstack);
6379 : 525 : if (second)
6380 : 55 : pedwarn (ellipsis_loc, OPT_Wpedantic,
6381 : : "ISO C forbids specifying range of elements to initialize");
6382 : : }
6383 : : else
6384 : 0 : c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
6385 : : "expected %<]%>");
6386 : : }
6387 : : }
6388 : 8655799 : if (des_seen >= 1)
6389 : : {
6390 : 31260 : if (c_parser_next_token_is (parser, CPP_EQ))
6391 : : {
6392 : 31239 : pedwarn_c90 (des_loc, OPT_Wpedantic,
6393 : : "ISO C90 forbids specifying subobject "
6394 : : "to initialize");
6395 : 31239 : c_parser_consume_token (parser);
6396 : : }
6397 : : else
6398 : : {
6399 : 21 : if (des_seen == 1)
6400 : 19 : pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
6401 : : "obsolete use of designated initializer without %<=%>");
6402 : : else
6403 : : {
6404 : 2 : struct c_expr init;
6405 : 2 : init.set_error ();
6406 : 2 : init.original_code = ERROR_MARK;
6407 : 2 : init.original_type = NULL;
6408 : 2 : c_parser_error (parser, "expected %<=%>");
6409 : 2 : c_parser_skip_until_found (parser, CPP_COMMA, NULL);
6410 : 2 : process_init_element (input_location, init, false,
6411 : : braced_init_obstack);
6412 : 2 : return;
6413 : : }
6414 : : }
6415 : : }
6416 : : }
6417 : 8655953 : c_parser_initval (parser, NULL, braced_init_obstack);
6418 : : }
6419 : :
6420 : : /* Parse a nested initializer; as c_parser_initializer but parses
6421 : : initializers within braced lists, after any designators have been
6422 : : applied. If AFTER is not NULL then it is an Objective-C message
6423 : : expression which is the primary-expression starting the
6424 : : initializer. */
6425 : :
6426 : : static void
6427 : 8655953 : c_parser_initval (c_parser *parser, struct c_expr *after,
6428 : : struct obstack * braced_init_obstack)
6429 : : {
6430 : 8655953 : struct c_expr init;
6431 : 8655953 : gcc_assert (!after || c_dialect_objc ());
6432 : 8655953 : location_t loc = c_parser_peek_token (parser)->location;
6433 : :
6434 : 8655953 : if (c_parser_next_token_is (parser, CPP_OPEN_BRACE) && !after)
6435 : 338435 : init = c_parser_braced_init (parser, NULL_TREE, true,
6436 : : braced_init_obstack, NULL_TREE);
6437 : : else
6438 : : {
6439 : 8317518 : init = c_parser_expr_no_commas (parser, after);
6440 : 8317518 : if (init.value != NULL_TREE
6441 : 8317518 : && TREE_CODE (init.value) != STRING_CST
6442 : 16593798 : && (TREE_CODE (init.value) != COMPOUND_LITERAL_EXPR
6443 : 173 : || C_DECL_DECLARED_CONSTEXPR (COMPOUND_LITERAL_EXPR_DECL
6444 : : (init.value))))
6445 : 8276112 : init = convert_lvalue_to_rvalue (loc, init, true, true, true);
6446 : : }
6447 : 8655953 : process_init_element (loc, init, false, braced_init_obstack);
6448 : 8655953 : }
6449 : :
6450 : : /* Parse a compound statement (possibly a function body) (C90 6.6.2,
6451 : : C99 6.8.2, C11 6.8.2, C23 6.8.2).
6452 : :
6453 : : compound-statement:
6454 : : { block-item-list[opt] }
6455 : : { label-declarations block-item-list }
6456 : :
6457 : : block-item-list:
6458 : : block-item
6459 : : block-item-list block-item
6460 : :
6461 : : block-item:
6462 : : label
6463 : : nested-declaration
6464 : : statement
6465 : :
6466 : : nested-declaration:
6467 : : declaration
6468 : :
6469 : : GNU extensions:
6470 : :
6471 : : compound-statement:
6472 : : { label-declarations block-item-list }
6473 : :
6474 : : nested-declaration:
6475 : : __extension__ nested-declaration
6476 : : nested-function-definition
6477 : :
6478 : : label-declarations:
6479 : : label-declaration
6480 : : label-declarations label-declaration
6481 : :
6482 : : label-declaration:
6483 : : __label__ identifier-list ;
6484 : :
6485 : : Allowing the mixing of declarations and code is new in C99. The
6486 : : GNU syntax also permits (not shown above) labels at the end of
6487 : : compound statements, which yield an error. We don't allow labels
6488 : : on declarations; this might seem like a natural extension, but
6489 : : there would be a conflict between gnu-attributes on the label and
6490 : : prefix gnu-attributes on the declaration. ??? The syntax follows the
6491 : : old parser in requiring something after label declarations.
6492 : : Although they are erroneous if the labels declared aren't defined,
6493 : : is it useful for the syntax to be this way?
6494 : :
6495 : : OpenACC:
6496 : :
6497 : : block-item:
6498 : : openacc-directive
6499 : :
6500 : : openacc-directive:
6501 : : update-directive
6502 : :
6503 : : OpenMP:
6504 : :
6505 : : block-item:
6506 : : openmp-directive
6507 : :
6508 : : openmp-directive:
6509 : : barrier-directive
6510 : : flush-directive
6511 : : taskwait-directive
6512 : : taskyield-directive
6513 : : cancel-directive
6514 : : cancellation-point-directive */
6515 : :
6516 : : static tree
6517 : 32615445 : c_parser_compound_statement (c_parser *parser, location_t *endlocp)
6518 : : {
6519 : 32615445 : tree stmt;
6520 : 32615445 : location_t brace_loc;
6521 : 32615445 : brace_loc = c_parser_peek_token (parser)->location;
6522 : 32615445 : if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
6523 : : {
6524 : : /* Ensure a scope is entered and left anyway to avoid confusion
6525 : : if we have just prepared to enter a function body. */
6526 : 16 : stmt = c_begin_compound_stmt (true);
6527 : 16 : c_end_compound_stmt (brace_loc, stmt, true);
6528 : 16 : return error_mark_node;
6529 : : }
6530 : 32615429 : stmt = c_begin_compound_stmt (true);
6531 : 32615429 : location_t end_loc = c_parser_compound_statement_nostart (parser);
6532 : 32615428 : if (endlocp)
6533 : 31764976 : *endlocp = end_loc;
6534 : :
6535 : 32615428 : return c_end_compound_stmt (brace_loc, stmt, true);
6536 : : }
6537 : :
6538 : : /* Diagnose errors related to imperfectly nested loops in an OMP
6539 : : loop construct. This function is called when such code is seen.
6540 : : Only issue one such diagnostic no matter how much invalid
6541 : : intervening code there is in the loop.
6542 : : FIXME: maybe the location associated with the diagnostic should
6543 : : be the current parser token instead of the location of the outer loop
6544 : : nest. */
6545 : :
6546 : : static void
6547 : 269 : check_omp_intervening_code (c_parser *parser)
6548 : : {
6549 : 269 : struct omp_for_parse_data *omp_for_parse_state = parser->omp_for_parse_state;
6550 : 269 : gcc_assert (omp_for_parse_state);
6551 : :
6552 : 269 : if (!omp_for_parse_state->in_intervening_code)
6553 : : return;
6554 : 248 : omp_for_parse_state->saw_intervening_code = true;
6555 : :
6556 : : /* Only diagnose errors related to perfect nesting once. */
6557 : 248 : if (!omp_for_parse_state->perfect_nesting_fail)
6558 : : {
6559 : :
6560 : : /* OpenACC does not (yet) permit intervening code, in
6561 : : addition to situations forbidden by the OpenMP spec. */
6562 : 226 : if (omp_for_parse_state->code == OACC_LOOP)
6563 : : {
6564 : 3 : error_at (omp_for_parse_state->for_loc,
6565 : : "inner loops must be perfectly nested in "
6566 : : "%<#pragma acc loop%>");
6567 : 3 : omp_for_parse_state->perfect_nesting_fail = true;
6568 : : }
6569 : 223 : else if (omp_for_parse_state->ordered)
6570 : : {
6571 : 12 : error_at (omp_for_parse_state->for_loc,
6572 : : "inner loops must be perfectly nested with "
6573 : : "%<ordered%> clause");
6574 : 12 : omp_for_parse_state->perfect_nesting_fail = true;
6575 : : }
6576 : 211 : else if (omp_for_parse_state->inscan)
6577 : : {
6578 : 2 : error_at (omp_for_parse_state->for_loc,
6579 : : "inner loops must be perfectly nested with "
6580 : : "%<reduction%> %<inscan%> clause");
6581 : 2 : omp_for_parse_state->perfect_nesting_fail = true;
6582 : : }
6583 : : /* TODO: Also reject loops with TILE directive. */
6584 : 226 : if (omp_for_parse_state->perfect_nesting_fail)
6585 : 17 : omp_for_parse_state->fail = true;
6586 : : }
6587 : : }
6588 : :
6589 : : /* Helper function for below: wrap an OMP_STRUCTURED_BLOCK around SL
6590 : : and add the statement to the current list. If SL is an empty statement
6591 : : list, do nothing. */
6592 : : static void
6593 : 242 : add_structured_block_stmt (tree sl)
6594 : : {
6595 : 242 : if (TREE_CODE (sl) != STATEMENT_LIST
6596 : 242 : || !tsi_end_p (tsi_start (sl)))
6597 : 124 : add_stmt (build1 (OMP_STRUCTURED_BLOCK, void_type_node, sl));
6598 : 242 : }
6599 : :
6600 : : struct c_omp_attribute_data
6601 : : {
6602 : : vec<c_token, va_gc> *tokens;
6603 : : const c_omp_directive *dir;
6604 : : c_omp_directive_kind kind;
6605 : : };
6606 : :
6607 : : /* Handle omp::directive and omp::sequence attributes in ATTRS
6608 : : (if any) at the start of a statement or in attribute-declaration. */
6609 : :
6610 : : static bool
6611 : 537 : c_parser_handle_statement_omp_attributes (c_parser *parser, tree &attrs,
6612 : : bool *have_std_attrs)
6613 : : {
6614 : 537 : if (!flag_openmp && !flag_openmp_simd)
6615 : : return false;
6616 : :
6617 : 452 : auto_vec<c_omp_attribute_data, 16> vd;
6618 : 452 : int cnt = 0;
6619 : 452 : int tokens = 0;
6620 : 452 : bool bad = false;
6621 : 901 : for (tree *pa = &attrs; *pa; )
6622 : 449 : if (is_attribute_namespace_p ("omp", *pa)
6623 : 449 : && is_attribute_p ("directive", get_attribute_name (*pa)))
6624 : : {
6625 : 448 : cnt++;
6626 : 933 : for (tree a = TREE_VALUE (*pa); a; a = TREE_CHAIN (a))
6627 : : {
6628 : 485 : tree d = TREE_VALUE (a);
6629 : 485 : gcc_assert (TREE_CODE (d) == C_TOKEN_VEC);
6630 : 485 : vec<c_token, va_gc> *toks = C_TOKEN_VEC_TOKENS (d);
6631 : 485 : c_token *first = toks->address ();
6632 : 485 : c_token *last = first + toks->length ();
6633 : 485 : if (parser->omp_attrs_forbidden_p)
6634 : : {
6635 : 14 : error_at (first->location,
6636 : : "mixing OpenMP directives with attribute and pragma "
6637 : : "syntax on the same statement");
6638 : 14 : parser->omp_attrs_forbidden_p = false;
6639 : 14 : bad = true;
6640 : : }
6641 : 471 : else if (TREE_PUBLIC (d))
6642 : : {
6643 : 3 : error_at (first->location,
6644 : : "OpenMP %<omp::decl%> attribute on a statement");
6645 : 3 : bad = true;
6646 : : }
6647 : 485 : const char *directive[3] = {};
6648 : 1435 : for (int i = 0; i < 3; i++)
6649 : : {
6650 : 1271 : tree id = NULL_TREE;
6651 : 1271 : if (first + i == last)
6652 : : break;
6653 : 1119 : if (first[i].type == CPP_NAME)
6654 : 901 : id = first[i].value;
6655 : 218 : else if (first[i].type == CPP_KEYWORD)
6656 : 49 : id = ridpointers[(int) first[i].keyword];
6657 : : else
6658 : : break;
6659 : 950 : directive[i] = IDENTIFIER_POINTER (id);
6660 : : }
6661 : 485 : const c_omp_directive *dir = NULL;
6662 : 485 : if (directive[0])
6663 : 485 : dir = c_omp_categorize_directive (directive[0], directive[1],
6664 : : directive[2]);
6665 : 485 : if (dir == NULL)
6666 : : {
6667 : 1 : error_at (first->location,
6668 : : "unknown OpenMP directive name in %qs attribute "
6669 : : "argument",
6670 : 1 : TREE_PUBLIC (d) ? "omp::decl" : "omp::directive");
6671 : 1 : continue;
6672 : : }
6673 : 484 : c_omp_directive_kind kind = dir->kind;
6674 : 484 : if (dir->id == PRAGMA_OMP_ORDERED)
6675 : : {
6676 : : /* ordered is C_OMP_DIR_CONSTRUCT only if it doesn't contain
6677 : : depend/doacross clause. */
6678 : 8 : if (directive[1]
6679 : 4 : && (strcmp (directive[1], "depend") == 0
6680 : 2 : || strcmp (directive[1], "doacross") == 0))
6681 : : kind = C_OMP_DIR_STANDALONE;
6682 : 6 : else if (first + 2 < last
6683 : 4 : && first[1].type == CPP_COMMA
6684 : 4 : && first[2].type == CPP_NAME
6685 : 10 : && (strcmp (IDENTIFIER_POINTER (first[2].value),
6686 : : "depend") == 0
6687 : 2 : || strcmp (IDENTIFIER_POINTER (first[2].value),
6688 : : "doacross") == 0))
6689 : : kind = C_OMP_DIR_STANDALONE;
6690 : : }
6691 : 476 : else if (dir->id == PRAGMA_OMP_ERROR)
6692 : : {
6693 : : /* error with at(execution) clause is C_OMP_DIR_STANDALONE. */
6694 : : int paren_depth = 0;
6695 : 99 : for (int i = 1; first + i < last; i++)
6696 : 84 : if (first[i].type == CPP_OPEN_PAREN)
6697 : 18 : paren_depth++;
6698 : 66 : else if (first[i].type == CPP_CLOSE_PAREN)
6699 : 18 : paren_depth--;
6700 : 48 : else if (paren_depth == 0
6701 : 30 : && first + i + 2 < last
6702 : 30 : && first[i].type == CPP_NAME
6703 : 21 : && first[i + 1].type == CPP_OPEN_PAREN
6704 : 21 : && first[i + 2].type == CPP_NAME
6705 : 15 : && !strcmp (IDENTIFIER_POINTER (first[i].value),
6706 : : "at")
6707 : 57 : && !strcmp (IDENTIFIER_POINTER (first[i
6708 : : + 2].value),
6709 : : "execution"))
6710 : : {
6711 : : kind = C_OMP_DIR_STANDALONE;
6712 : : break;
6713 : : }
6714 : : }
6715 : 484 : c_omp_attribute_data v = { toks, dir, kind };
6716 : 484 : vd.safe_push (v);
6717 : 484 : if (flag_openmp || dir->simd)
6718 : 484 : tokens += (last - first) + 1;
6719 : : }
6720 : 448 : c_omp_attribute_data v = {};
6721 : 448 : vd.safe_push (v);
6722 : 448 : *pa = TREE_CHAIN (*pa);
6723 : : }
6724 : : else
6725 : 1 : pa = &TREE_CHAIN (*pa);
6726 : :
6727 : 452 : if (bad)
6728 : : {
6729 : 17 : fail:
6730 : 27 : if (have_std_attrs && attrs == NULL)
6731 : 26 : *have_std_attrs = false;
6732 : 27 : return false;
6733 : : }
6734 : :
6735 : : unsigned int i;
6736 : : c_omp_attribute_data *v;
6737 : : c_omp_attribute_data *construct_seen = nullptr;
6738 : : c_omp_attribute_data *standalone_seen = nullptr;
6739 : : c_omp_attribute_data *prev_standalone_seen = nullptr;
6740 : 1332 : FOR_EACH_VEC_ELT (vd, i, v)
6741 : 897 : if (v->tokens)
6742 : : {
6743 : 466 : if (v->kind == C_OMP_DIR_CONSTRUCT && !construct_seen)
6744 : : construct_seen = v;
6745 : 219 : else if (v->kind == C_OMP_DIR_STANDALONE && !standalone_seen)
6746 : 69 : standalone_seen = v;
6747 : : }
6748 : : else
6749 : : {
6750 : 431 : if (standalone_seen && !prev_standalone_seen)
6751 : : {
6752 : 897 : prev_standalone_seen = standalone_seen;
6753 : 897 : standalone_seen = nullptr;
6754 : : }
6755 : : }
6756 : :
6757 : 435 : if (cnt > 1 && construct_seen)
6758 : : {
6759 : 2 : error_at ((*construct_seen->tokens)[0].location,
6760 : : "OpenMP construct among %<omp::directive%> attributes"
6761 : : " requires all %<omp::directive%> attributes on the"
6762 : : " same statement to be in the same %<omp::sequence%>");
6763 : 2 : goto fail;
6764 : : }
6765 : 433 : if (cnt > 1 && standalone_seen && prev_standalone_seen)
6766 : : {
6767 : 2 : error_at ((*standalone_seen->tokens)[0].location,
6768 : : "multiple OpenMP standalone directives among"
6769 : : " %<omp::directive%> attributes must be all within the"
6770 : : " same %<omp::sequence%>");
6771 : 2 : goto fail;
6772 : : }
6773 : :
6774 : 431 : if (prev_standalone_seen)
6775 : : standalone_seen = prev_standalone_seen;
6776 : 366 : if (standalone_seen
6777 : 431 : && !c_parser_next_token_is (parser, CPP_SEMICOLON))
6778 : : {
6779 : 2 : error_at (standalone_seen->tokens->address ()->location,
6780 : : "standalone OpenMP directives in %<omp::directive%> attribute"
6781 : : " can only appear on an empty statement");
6782 : 2 : goto fail;
6783 : : }
6784 : 850 : if (cnt && c_parser_next_token_is (parser, CPP_PRAGMA))
6785 : : {
6786 : 4 : c_token *token = c_parser_peek_token (parser);
6787 : 4 : enum pragma_kind kind = token->pragma_kind;
6788 : 4 : if (kind >= PRAGMA_OMP__START_ && kind <= PRAGMA_OMP__LAST_)
6789 : : {
6790 : 4 : error_at (token->location,
6791 : : "mixing OpenMP directives with attribute and pragma "
6792 : : "syntax on the same statement");
6793 : 4 : goto fail;
6794 : : }
6795 : : }
6796 : :
6797 : 425 : if (!tokens)
6798 : : return false;
6799 : :
6800 : 409 : unsigned int tokens_avail = parser->tokens_avail;
6801 : 409 : gcc_assert (parser->tokens == &parser->tokens_buf[0]);
6802 : :
6803 : 409 : tokens++;
6804 : 409 : vec<c_token, va_gc> *toks = NULL;
6805 : 409 : vec_safe_reserve (toks, tokens, true);
6806 : 1270 : FOR_EACH_VEC_ELT (vd, i, v)
6807 : : {
6808 : 861 : if (!v->tokens)
6809 : 409 : continue;
6810 : 452 : if (!flag_openmp && !v->dir->simd)
6811 : 0 : continue;
6812 : 452 : c_token *first = v->tokens->address ();
6813 : 452 : c_token *last = first + v->tokens->length ();
6814 : 452 : c_token tok = {};
6815 : 452 : tok.type = CPP_PRAGMA;
6816 : 452 : tok.keyword = RID_MAX;
6817 : 452 : tok.pragma_kind = pragma_kind (v->dir->id);
6818 : 452 : tok.location = first->location;
6819 : 452 : toks->quick_push (tok);
6820 : 15420 : while (++first < last)
6821 : 14516 : toks->quick_push (*first);
6822 : 452 : tok = {};
6823 : 452 : tok.type = CPP_PRAGMA_EOL;
6824 : 452 : tok.keyword = RID_MAX;
6825 : 452 : tok.location = last[-1].location;
6826 : 452 : toks->quick_push (tok);
6827 : : }
6828 : :
6829 : 409 : c_token tok = {};
6830 : 409 : tok.type = CPP_EOF;
6831 : 409 : tok.keyword = RID_MAX;
6832 : 409 : tok.location = toks->last ().location;
6833 : 409 : tok.flags = tokens_avail;
6834 : 409 : toks->quick_push (tok);
6835 : :
6836 : 409 : parser->tokens = toks->address ();
6837 : 409 : parser->tokens_avail = tokens;
6838 : 409 : parser->in_omp_attribute_pragma = toks;
6839 : 409 : return true;
6840 : 452 : }
6841 : :
6842 : : /* Handle omp::directive and omp::sequence attributes in ATTRS
6843 : : (if any) at the start or after declaration-id of a declaration. */
6844 : :
6845 : : static void
6846 : 56844862 : c_parser_handle_directive_omp_attributes (tree &attrs,
6847 : : vec<c_token> *&pragma_clauses,
6848 : : vec<c_token> *attr_clauses)
6849 : : {
6850 : 56844862 : if (!flag_openmp && !flag_openmp_simd)
6851 : : return;
6852 : :
6853 : 1391140 : for (tree *pa = &attrs; *pa; )
6854 : 581207 : if (is_attribute_namespace_p ("omp", *pa)
6855 : 581207 : && is_attribute_p ("directive", get_attribute_name (*pa)))
6856 : : {
6857 : 134 : int cnt = 0;
6858 : 267 : for (tree *pa2 = &TREE_VALUE (*pa); *pa2; )
6859 : : {
6860 : 135 : tree a = *pa2;
6861 : 135 : tree d = TREE_VALUE (a);
6862 : 135 : gcc_assert (TREE_CODE (d) == C_TOKEN_VEC);
6863 : 135 : vec<c_token, va_gc> *toks = C_TOKEN_VEC_TOKENS (d);
6864 : 135 : c_token *first = toks->address ();
6865 : 135 : c_token *last = first + toks->length ();
6866 : 135 : const char *directive[3] = {};
6867 : 409 : for (int i = 0; i < 3; i++)
6868 : : {
6869 : 375 : tree id = NULL_TREE;
6870 : 375 : if (first + i == last)
6871 : : break;
6872 : 321 : if (first[i].type == CPP_NAME)
6873 : 274 : id = first[i].value;
6874 : 47 : else if (first[i].type == CPP_KEYWORD)
6875 : 0 : id = ridpointers[(int) first[i].keyword];
6876 : : else
6877 : : break;
6878 : 274 : directive[i] = IDENTIFIER_POINTER (id);
6879 : : }
6880 : 135 : const c_omp_directive *dir = NULL;
6881 : 135 : if (directive[0])
6882 : 135 : dir = c_omp_categorize_directive (directive[0], directive[1],
6883 : : directive[2]);
6884 : 135 : if (dir == NULL)
6885 : : {
6886 : 9 : error_at (first->location,
6887 : : "unknown OpenMP directive name in "
6888 : : "%qs attribute argument",
6889 : 9 : TREE_PUBLIC (d) ? "omp::decl" : "omp::directive");
6890 : 9 : *pa2 = TREE_CHAIN (a);
6891 : : }
6892 : 126 : else if (dir->id == PRAGMA_OMP_DECLARE
6893 : 104 : && (strcmp (directive[1], "simd") == 0
6894 : 21 : || strcmp (directive[1], "variant") == 0))
6895 : : {
6896 : 91 : if (pragma_clauses)
6897 : : {
6898 : 2 : error_at (first->location,
6899 : : "mixing OpenMP directives with attribute and "
6900 : : "pragma syntax on the same declaration");
6901 : 6 : for (pa = &attrs; *pa; )
6902 : 2 : if (is_attribute_namespace_p ("omp", *pa)
6903 : 4 : && is_attribute_p ("directive",
6904 : 2 : get_attribute_name (*pa)))
6905 : 2 : *pa = TREE_CHAIN (*pa);
6906 : : else
6907 : 0 : pa = &TREE_CHAIN (*pa);
6908 : 2 : return;
6909 : : }
6910 : 89 : ++cnt;
6911 : 109 : attr_clauses->reserve (attr_clauses->length ()
6912 : 89 : + toks->length () + 2);
6913 : 807 : for (++first; first < last; ++first)
6914 : 718 : attr_clauses->quick_push (*first);
6915 : 89 : c_token tok = {};
6916 : 89 : tok.type = CPP_PRAGMA_EOL;
6917 : 89 : tok.keyword = RID_MAX;
6918 : 89 : tok.location = last[-1].location;
6919 : 89 : attr_clauses->quick_push (tok);
6920 : 89 : *pa2 = TREE_CHAIN (a);
6921 : 89 : }
6922 : : else
6923 : 35 : pa2 = &TREE_CHAIN (a);
6924 : : }
6925 : 132 : if (cnt && TREE_VALUE (*pa) == NULL_TREE)
6926 : 85 : *pa = TREE_CHAIN (*pa);
6927 : : else
6928 : 47 : pa = &TREE_CHAIN (*pa);
6929 : : }
6930 : : else
6931 : 581073 : pa = &TREE_CHAIN (*pa);
6932 : 809933 : if (attr_clauses->length ())
6933 : : {
6934 : 69 : c_token tok = {};
6935 : 69 : tok.type = CPP_EOF;
6936 : 69 : tok.keyword = RID_MAX;
6937 : 69 : tok.location = attr_clauses->last ().location;
6938 : 69 : attr_clauses->quick_push (tok);
6939 : 69 : attr_clauses->quick_push (tok);
6940 : 69 : pragma_clauses = attr_clauses;
6941 : : }
6942 : : }
6943 : :
6944 : : /* Parse a compound statement except for the opening brace. This is
6945 : : used for parsing both compound statements and statement expressions
6946 : : (which follow different paths to handling the opening). */
6947 : :
6948 : : static location_t
6949 : 32648509 : c_parser_compound_statement_nostart (c_parser *parser)
6950 : : {
6951 : 32648509 : bool last_stmt = false;
6952 : 32648509 : bool last_label = false;
6953 : 32648509 : bool save_valid_for_pragma = valid_location_for_stdc_pragma_p ();
6954 : 32648509 : location_t label_loc = UNKNOWN_LOCATION; /* Quiet warning. */
6955 : 32648509 : struct omp_for_parse_data *omp_for_parse_state
6956 : : = parser->omp_for_parse_state;
6957 : 65297018 : bool in_omp_loop_block
6958 : 32648509 : = omp_for_parse_state ? omp_for_parse_state->want_nested_loop : false;
6959 : 32648509 : tree sl = NULL_TREE;
6960 : :
6961 : 32648509 : if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
6962 : : {
6963 : 22921 : location_t endloc = c_parser_peek_token (parser)->location;
6964 : 22921 : add_debug_begin_stmt (endloc);
6965 : 22921 : c_parser_consume_token (parser);
6966 : 22921 : return endloc;
6967 : : }
6968 : :
6969 : : /* If we're parsing a {} sequence in an OMP_FOR body, start a
6970 : : statement list for intervening code. */
6971 : 32625588 : if (in_omp_loop_block)
6972 : 154 : sl = push_stmt_list ();
6973 : :
6974 : 32625588 : mark_valid_location_for_stdc_pragma (true);
6975 : 32625588 : if (c_parser_next_token_is_keyword (parser, RID_LABEL))
6976 : : {
6977 : : /* Read zero or more forward-declarations for labels that nested
6978 : : functions can jump to. */
6979 : 718 : mark_valid_location_for_stdc_pragma (false);
6980 : 718 : if (in_omp_loop_block)
6981 : 5 : check_omp_intervening_code (parser);
6982 : 1557 : while (c_parser_next_token_is_keyword (parser, RID_LABEL))
6983 : : {
6984 : 839 : label_loc = c_parser_peek_token (parser)->location;
6985 : 839 : c_parser_consume_token (parser);
6986 : : /* Any identifiers, including those declared as type names,
6987 : : are OK here. */
6988 : 1513 : while (true)
6989 : : {
6990 : 1176 : tree label;
6991 : 1176 : if (c_parser_next_token_is_not (parser, CPP_NAME))
6992 : : {
6993 : 0 : c_parser_error (parser, "expected identifier");
6994 : 0 : break;
6995 : : }
6996 : 1176 : label
6997 : 1176 : = declare_label (c_parser_peek_token (parser)->value);
6998 : 1176 : C_DECLARED_LABEL_FLAG (label) = 1;
6999 : 1176 : add_stmt (build_stmt (label_loc, DECL_EXPR, label));
7000 : 1176 : c_parser_consume_token (parser);
7001 : 1176 : if (c_parser_next_token_is (parser, CPP_COMMA))
7002 : 337 : c_parser_consume_token (parser);
7003 : : else
7004 : : break;
7005 : 337 : }
7006 : 839 : c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
7007 : : }
7008 : 718 : pedwarn (label_loc, OPT_Wpedantic, "ISO C forbids label declarations");
7009 : : }
7010 : : /* We must now have at least one statement, label or declaration. */
7011 : 32625588 : if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
7012 : : {
7013 : 0 : mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
7014 : 0 : c_parser_error (parser, "expected declaration or statement");
7015 : 0 : location_t endloc = c_parser_peek_token (parser)->location;
7016 : 0 : c_parser_consume_token (parser);
7017 : 0 : return endloc;
7018 : : }
7019 : 78214736 : while (c_parser_next_token_is_not (parser, CPP_CLOSE_BRACE))
7020 : : {
7021 : 45589185 : location_t loc = c_parser_peek_token (parser)->location;
7022 : 45589185 : loc = expansion_point_location_if_in_system_header (loc);
7023 : :
7024 : 91178370 : bool want_nested_loop = (omp_for_parse_state
7025 : 45589185 : ? omp_for_parse_state->want_nested_loop
7026 : : : false);
7027 : :
7028 : : /* First take care of special cases for OpenMP "canonical loop
7029 : : nest form", that do not allow standard attributes, labels, or
7030 : : __extension__ before the nested statement. */
7031 : 45589185 : if (in_omp_loop_block && !last_label)
7032 : : {
7033 : 429 : if (want_nested_loop
7034 : 598 : && c_parser_next_token_is_keyword (parser, RID_FOR))
7035 : : {
7036 : : /* Found the next nested loop. If there were intervening
7037 : : code statements collected before now, wrap them in an
7038 : : OMP_STRUCTURED_BLOCK node, and start a new structured
7039 : : block to hold statements that may come after the FOR. */
7040 : 90 : gcc_assert (sl);
7041 : 90 : add_structured_block_stmt (pop_stmt_list (sl));
7042 : 90 : omp_for_parse_state->depth++;
7043 : 90 : add_stmt (c_parser_omp_loop_nest (parser, NULL));
7044 : 90 : omp_for_parse_state->depth--;
7045 : 90 : sl = push_stmt_list ();
7046 : 90 : parser->error = false;
7047 : 141 : continue;
7048 : : }
7049 : 249 : else if (want_nested_loop
7050 : 418 : && c_parser_next_token_is (parser, CPP_OPEN_BRACE))
7051 : : {
7052 : : /* If this nested compound statement contains the nested loop,
7053 : : we need to separate the other statements in the current
7054 : : statement into separate blocks of intervening code. If
7055 : : there's no nested loop, it's all part of the same
7056 : : chunk of intervening code. */
7057 : 44 : tree pre_sl = pop_stmt_list (sl);
7058 : 44 : tree nested_sl = push_stmt_list ();
7059 : 44 : mark_valid_location_for_stdc_pragma (false);
7060 : 44 : c_parser_statement_after_labels (parser, NULL);
7061 : 44 : nested_sl = pop_stmt_list (nested_sl);
7062 : 44 : if (omp_for_parse_state->want_nested_loop)
7063 : : {
7064 : : /* This block didn't contain a loop-nest, so it's
7065 : : all part of the same chunk of intervening code. */
7066 : 13 : check_omp_intervening_code (parser);
7067 : 13 : sl = push_stmt_list ();
7068 : 13 : add_stmt (pre_sl);
7069 : 13 : add_stmt (nested_sl);
7070 : : }
7071 : : else
7072 : : {
7073 : : /* It contains the nested loop. */
7074 : 31 : add_structured_block_stmt (pre_sl);
7075 : 31 : add_stmt (nested_sl);
7076 : 31 : sl = push_stmt_list ();
7077 : : }
7078 : 44 : parser->error = false;
7079 : 44 : continue;
7080 : 44 : }
7081 : 205 : else if (c_parser_next_token_is (parser, CPP_SEMICOLON))
7082 : : {
7083 : : /* Prior to implementing the OpenMP 5.1 syntax for canonical
7084 : : loop form, GCC used to accept an empty statements that
7085 : : would now be flagged as intervening code. Continue to
7086 : : do that, as an extension. */
7087 : : /* FIXME: Maybe issue a warning or something here? */
7088 : 4 : c_parser_consume_token (parser);
7089 : 4 : continue;
7090 : : }
7091 : : }
7092 : :
7093 : : /* Standard attributes may start a label, statement or declaration. */
7094 : 45589047 : bool have_std_attrs
7095 : 45589047 : = c_parser_nth_token_starts_std_attributes (parser, 1);
7096 : 45589047 : tree std_attrs = NULL_TREE;
7097 : 45589047 : if (have_std_attrs)
7098 : 477 : std_attrs = c_parser_std_attribute_specifier_sequence (parser);
7099 : 45589047 : if (c_parser_next_token_is_keyword (parser, RID_CASE)
7100 : 44600406 : || c_parser_next_token_is_keyword (parser, RID_DEFAULT)
7101 : 90157150 : || (c_parser_next_token_is (parser, CPP_NAME)
7102 : 9833916 : && c_parser_peek_2nd_token (parser)->type == CPP_COLON))
7103 : : {
7104 : 1043172 : if (c_parser_next_token_is_keyword (parser, RID_CASE))
7105 : 988641 : label_loc = c_parser_peek_2nd_token (parser)->location;
7106 : : else
7107 : 54531 : label_loc = c_parser_peek_token (parser)->location;
7108 : 1043172 : last_label = true;
7109 : 1043172 : last_stmt = false;
7110 : 1043172 : mark_valid_location_for_stdc_pragma (false);
7111 : 1043172 : if (in_omp_loop_block)
7112 : 26 : check_omp_intervening_code (parser);
7113 : 1043172 : c_parser_label (parser, std_attrs);
7114 : : }
7115 : 44545875 : else if (c_parser_next_tokens_start_declaration (parser)
7116 : 44545875 : || (have_std_attrs
7117 : 391 : && !c_parser_handle_statement_omp_attributes
7118 : 391 : (parser, std_attrs, &have_std_attrs)
7119 : 97 : && c_parser_next_token_is (parser, CPP_SEMICOLON)
7120 : 61 : && (have_std_attrs = true)))
7121 : : {
7122 : 7382676 : if (last_label)
7123 : 52 : pedwarn_c11 (c_parser_peek_token (parser)->location, OPT_Wpedantic,
7124 : : "a label can only be part of a statement and "
7125 : : "a declaration is not a statement");
7126 : : /* It's unlikely we'll see a nested loop in a declaration in
7127 : : intervening code in an OMP loop, but disallow it anyway. */
7128 : 7382676 : if (in_omp_loop_block)
7129 : : {
7130 : 16 : check_omp_intervening_code (parser);
7131 : 16 : omp_for_parse_state->want_nested_loop = false;
7132 : : }
7133 : 7382676 : mark_valid_location_for_stdc_pragma (false);
7134 : 7382676 : bool fallthru_attr_p = false;
7135 : 7382676 : c_parser_declaration_or_fndef (parser, true, !have_std_attrs,
7136 : : true, true, true, NULL,
7137 : : NULL, have_std_attrs, std_attrs,
7138 : : NULL, &fallthru_attr_p);
7139 : :
7140 : 7382676 : if (in_omp_loop_block)
7141 : 16 : omp_for_parse_state->want_nested_loop = want_nested_loop;
7142 : 7382676 : if (last_stmt && !fallthru_attr_p)
7143 : 298930 : pedwarn_c90 (loc, OPT_Wdeclaration_after_statement,
7144 : : "ISO C90 forbids mixed declarations and code");
7145 : 7382676 : last_stmt = fallthru_attr_p;
7146 : 7382676 : last_label = false;
7147 : : }
7148 : 37163199 : else if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
7149 : : {
7150 : : /* __extension__ can start a declaration, but is also an
7151 : : unary operator that can start an expression. Consume all
7152 : : but the last of a possible series of __extension__ to
7153 : : determine which. If standard attributes have already
7154 : : been seen, it must start a statement, not a declaration,
7155 : : but standard attributes starting a declaration may appear
7156 : : after __extension__. */
7157 : 1560 : while (c_parser_peek_2nd_token (parser)->type == CPP_KEYWORD
7158 : 780 : && (c_parser_peek_2nd_token (parser)->keyword
7159 : : == RID_EXTENSION))
7160 : 0 : c_parser_consume_token (parser);
7161 : 780 : if (!have_std_attrs
7162 : 780 : && (c_token_starts_declaration (c_parser_peek_2nd_token (parser))
7163 : 709 : || c_parser_nth_token_starts_std_attributes (parser, 2)))
7164 : : {
7165 : 74 : int ext;
7166 : 74 : ext = disable_extension_diagnostics ();
7167 : 74 : c_parser_consume_token (parser);
7168 : 74 : last_label = false;
7169 : : /* It's unlikely we'll see a nested loop in a declaration in
7170 : : intervening code in an OMP loop, but disallow it anyway. */
7171 : 74 : if (in_omp_loop_block)
7172 : : {
7173 : 0 : check_omp_intervening_code (parser);
7174 : 0 : omp_for_parse_state->want_nested_loop = false;
7175 : : }
7176 : 74 : mark_valid_location_for_stdc_pragma (false);
7177 : 74 : c_parser_declaration_or_fndef (parser, true, true, true, true,
7178 : : true);
7179 : 74 : if (in_omp_loop_block)
7180 : 0 : omp_for_parse_state->want_nested_loop = want_nested_loop;
7181 : : /* Following the old parser, __extension__ does not
7182 : : disable this diagnostic. */
7183 : 74 : restore_extension_diagnostics (ext);
7184 : 74 : if (last_stmt)
7185 : 7 : pedwarn_c90 (loc, OPT_Wdeclaration_after_statement,
7186 : : "ISO C90 forbids mixed declarations and code");
7187 : : last_stmt = false;
7188 : : }
7189 : : else
7190 : 706 : goto statement;
7191 : : }
7192 : 37162419 : else if (c_parser_next_token_is (parser, CPP_PRAGMA))
7193 : : {
7194 : 322505 : if (have_std_attrs && !parser->in_omp_attribute_pragma)
7195 : 0 : c_parser_error (parser, "expected declaration or statement");
7196 : 322505 : else if (std_attrs)
7197 : 0 : c_warn_unused_attributes (std_attrs);
7198 : : /* External pragmas, and some omp pragmas, are not associated
7199 : : with regular c code, and so are not to be considered statements
7200 : : syntactically. This ensures that the user doesn't put them
7201 : : places that would turn into syntax errors if the directive
7202 : : were ignored. */
7203 : 322505 : if (omp_for_parse_state)
7204 : 8 : omp_for_parse_state->want_nested_loop = false;
7205 : 644946 : if (c_parser_pragma (parser,
7206 : : last_label ? pragma_stmt : pragma_compound,
7207 : : NULL))
7208 : : {
7209 : 21060 : last_label = false;
7210 : 21060 : last_stmt = true;
7211 : 21060 : if (omp_for_parse_state)
7212 : 2 : check_omp_intervening_code (parser);
7213 : : }
7214 : 322505 : if (omp_for_parse_state)
7215 : 8 : omp_for_parse_state->want_nested_loop = want_nested_loop;
7216 : : }
7217 : 36839914 : else if (c_parser_next_token_is (parser, CPP_EOF))
7218 : : {
7219 : 34 : mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
7220 : 34 : c_parser_error (parser, "expected declaration or statement");
7221 : 36 : return c_parser_peek_token (parser)->location;
7222 : : }
7223 : 36839880 : else if (c_parser_next_token_is_keyword (parser, RID_ELSE))
7224 : : {
7225 : 5 : if (parser->in_if_block)
7226 : : {
7227 : 2 : mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
7228 : 2 : error_at (loc, "expected %<}%> before %<else%>");
7229 : 2 : return c_parser_peek_token (parser)->location;
7230 : : }
7231 : : else
7232 : : {
7233 : 3 : error_at (loc, "%<else%> without a previous %<if%>");
7234 : 3 : c_parser_consume_token (parser);
7235 : 3 : continue;
7236 : : }
7237 : : }
7238 : : else
7239 : : {
7240 : 36839875 : statement:
7241 : 36840581 : c_warn_unused_attributes (std_attrs);
7242 : 36840581 : last_label = false;
7243 : 36840581 : last_stmt = true;
7244 : 36840581 : mark_valid_location_for_stdc_pragma (false);
7245 : 36840581 : if (!omp_for_parse_state)
7246 : 36840374 : c_parser_statement_after_labels (parser, NULL);
7247 : : else
7248 : : {
7249 : : /* In canonical loop nest form, nested loops can only appear
7250 : : directly, or in a directly nested compound statement. We
7251 : : already took care of those cases above, so now we have
7252 : : something else. This statement and everything inside
7253 : : it must be intervening code. */
7254 : 207 : omp_for_parse_state->want_nested_loop = false;
7255 : 207 : check_omp_intervening_code (parser);
7256 : 207 : c_parser_statement_after_labels (parser, NULL);
7257 : 207 : omp_for_parse_state->want_nested_loop = want_nested_loop;
7258 : : }
7259 : : }
7260 : :
7261 : 45589007 : parser->error = false;
7262 : : }
7263 : 32625551 : if (last_label)
7264 : 28 : pedwarn_c11 (label_loc, OPT_Wpedantic, "label at end of compound statement");
7265 : 32625551 : location_t endloc = c_parser_peek_token (parser)->location;
7266 : 32625551 : c_parser_consume_token (parser);
7267 : :
7268 : : /* Restore the value we started with. */
7269 : 32625551 : mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
7270 : :
7271 : : /* Package leftover intervening code, or the whole contents of the
7272 : : compound statement if we were looking for a nested loop in an OMP_FOR
7273 : : construct and didn't find one. */
7274 : 32625551 : if (sl)
7275 : : {
7276 : 154 : sl = pop_stmt_list (sl);
7277 : 154 : if (omp_for_parse_state->want_nested_loop)
7278 : 33 : add_stmt (sl);
7279 : : else
7280 : 121 : add_structured_block_stmt (sl);
7281 : : }
7282 : : return endloc;
7283 : : }
7284 : :
7285 : : /* Parse all consecutive labels, possibly preceded by standard
7286 : : attributes. In this context, a statement is required, not a
7287 : : declaration, so attributes must be followed by a statement that is
7288 : : not just a semicolon. */
7289 : :
7290 : : static void
7291 : 2004797 : c_parser_all_labels (c_parser *parser)
7292 : : {
7293 : 2004797 : bool have_std_attrs;
7294 : 2004797 : tree std_attrs = NULL;
7295 : 2004797 : if ((have_std_attrs = c_parser_nth_token_starts_std_attributes (parser, 1)))
7296 : 29 : std_attrs = c_parser_std_attribute_specifier_sequence (parser);
7297 : 2005629 : while (c_parser_next_token_is_keyword (parser, RID_CASE)
7298 : 2005159 : || c_parser_next_token_is_keyword (parser, RID_DEFAULT)
7299 : 4010777 : || (c_parser_next_token_is (parser, CPP_NAME)
7300 : 503859 : && c_parser_peek_2nd_token (parser)->type == CPP_COLON))
7301 : : {
7302 : 832 : c_parser_label (parser, std_attrs);
7303 : 832 : std_attrs = NULL;
7304 : 832 : if ((have_std_attrs = c_parser_nth_token_starts_std_attributes (parser,
7305 : : 1)))
7306 : 2 : std_attrs = c_parser_std_attribute_specifier_sequence (parser);
7307 : : }
7308 : 2004797 : if (std_attrs
7309 : 2004797 : && (!c_parser_handle_statement_omp_attributes (parser, std_attrs, &have_std_attrs)
7310 : 9 : || std_attrs))
7311 : : {
7312 : 16 : if (have_std_attrs && c_parser_next_token_is (parser, CPP_SEMICOLON))
7313 : 0 : c_parser_error (parser, "expected statement");
7314 : 15 : c_warn_unused_attributes (std_attrs);
7315 : : }
7316 : 2004796 : else if (have_std_attrs && c_parser_next_token_is (parser, CPP_SEMICOLON))
7317 : 1 : c_parser_error (parser, "expected statement");
7318 : 2004797 : }
7319 : :
7320 : : /* Parse a label (C90 6.6.1, C99 6.8.1, C11 6.8.1).
7321 : :
7322 : : label:
7323 : : identifier : gnu-attributes[opt]
7324 : : case constant-expression :
7325 : : default :
7326 : :
7327 : : GNU extensions:
7328 : :
7329 : : label:
7330 : : case constant-expression ... constant-expression :
7331 : :
7332 : : The use of gnu-attributes on labels is a GNU extension. The syntax in
7333 : : GNU C accepts any expressions without commas, non-constant
7334 : : expressions being rejected later. Any standard
7335 : : attribute-specifier-sequence before the first label has been parsed
7336 : : in the caller, to distinguish statements from declarations. Any
7337 : : attribute-specifier-sequence after the label is parsed in this
7338 : : function. */
7339 : : static void
7340 : 1044004 : c_parser_label (c_parser *parser, tree std_attrs)
7341 : : {
7342 : 1044004 : location_t loc1 = c_parser_peek_token (parser)->location;
7343 : 1044004 : tree label = NULL_TREE;
7344 : :
7345 : : /* Remember whether this case or a user-defined label is allowed to fall
7346 : : through to. */
7347 : 1044004 : bool fallthrough_p = c_parser_peek_token (parser)->flags & PREV_FALLTHROUGH;
7348 : :
7349 : 1044004 : if (c_parser_next_token_is_keyword (parser, RID_CASE))
7350 : : {
7351 : 989111 : tree exp1, exp2;
7352 : 989111 : c_parser_consume_token (parser);
7353 : 989111 : exp1 = convert_lvalue_to_rvalue (loc1,
7354 : : c_parser_expr_no_commas (parser, NULL),
7355 : : true, true).value;
7356 : 989111 : if (c_parser_next_token_is (parser, CPP_COLON))
7357 : : {
7358 : 988859 : c_parser_consume_token (parser);
7359 : 988859 : label = do_case (loc1, exp1, NULL_TREE, std_attrs);
7360 : : }
7361 : 252 : else if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
7362 : : {
7363 : 244 : c_parser_consume_token (parser);
7364 : 244 : exp2 = convert_lvalue_to_rvalue (loc1,
7365 : : c_parser_expr_no_commas (parser,
7366 : : NULL),
7367 : : true, true).value;
7368 : 244 : if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
7369 : 244 : label = do_case (loc1, exp1, exp2, std_attrs);
7370 : : }
7371 : : else
7372 : 8 : c_parser_error (parser, "expected %<:%> or %<...%>");
7373 : : }
7374 : 54893 : else if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
7375 : : {
7376 : 32314 : c_parser_consume_token (parser);
7377 : 32314 : if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
7378 : 32314 : label = do_case (loc1, NULL_TREE, NULL_TREE, std_attrs);
7379 : : }
7380 : : else
7381 : : {
7382 : 22579 : tree name = c_parser_peek_token (parser)->value;
7383 : 22579 : tree tlab;
7384 : 22579 : tree attrs;
7385 : 22579 : location_t loc2 = c_parser_peek_token (parser)->location;
7386 : 22579 : gcc_assert (c_parser_next_token_is (parser, CPP_NAME));
7387 : 22579 : c_parser_consume_token (parser);
7388 : 22579 : gcc_assert (c_parser_next_token_is (parser, CPP_COLON));
7389 : 22579 : c_parser_consume_token (parser);
7390 : 22579 : attrs = c_parser_gnu_attributes (parser);
7391 : 22579 : tlab = define_label (loc2, name);
7392 : 22579 : if (tlab)
7393 : : {
7394 : 22551 : decl_attributes (&tlab, attrs, 0);
7395 : 22551 : decl_attributes (&tlab, std_attrs, 0);
7396 : 22551 : label = add_stmt (build_stmt (loc1, LABEL_EXPR, tlab));
7397 : : }
7398 : 22579 : if (attrs
7399 : 22579 : && c_parser_next_tokens_start_declaration (parser))
7400 : 1 : warning_at (loc2, OPT_Wattributes, "GNU-style attribute between"
7401 : : " label and declaration appertains to the label");
7402 : : }
7403 : 1044004 : if (label)
7404 : : {
7405 : 1043865 : if (TREE_CODE (label) == LABEL_EXPR)
7406 : 22551 : FALLTHROUGH_LABEL_P (LABEL_EXPR_LABEL (label)) = fallthrough_p;
7407 : : else
7408 : 1021314 : FALLTHROUGH_LABEL_P (CASE_LABEL (label)) = fallthrough_p;
7409 : : }
7410 : 1044004 : }
7411 : :
7412 : : /* Parse a statement (C90 6.6, C99 6.8, C11 6.8).
7413 : :
7414 : : statement:
7415 : : labeled-statement
7416 : : attribute-specifier-sequence[opt] compound-statement
7417 : : expression-statement
7418 : : attribute-specifier-sequence[opt] selection-statement
7419 : : attribute-specifier-sequence[opt] iteration-statement
7420 : : attribute-specifier-sequence[opt] jump-statement
7421 : :
7422 : : labeled-statement:
7423 : : attribute-specifier-sequence[opt] label statement
7424 : :
7425 : : expression-statement:
7426 : : expression[opt] ;
7427 : : attribute-specifier-sequence expression ;
7428 : :
7429 : : selection-statement:
7430 : : if-statement
7431 : : switch-statement
7432 : :
7433 : : iteration-statement:
7434 : : while-statement
7435 : : do-statement
7436 : : for-statement
7437 : :
7438 : : jump-statement:
7439 : : goto identifier ;
7440 : : continue ;
7441 : : break ;
7442 : : return expression[opt] ;
7443 : :
7444 : : GNU extensions:
7445 : :
7446 : : statement:
7447 : : attribute-specifier-sequence[opt] asm-statement
7448 : :
7449 : : jump-statement:
7450 : : goto * expression ;
7451 : :
7452 : : expression-statement:
7453 : : gnu-attributes ;
7454 : :
7455 : : Objective-C:
7456 : :
7457 : : statement:
7458 : : attribute-specifier-sequence[opt] objc-throw-statement
7459 : : attribute-specifier-sequence[opt] objc-try-catch-statement
7460 : : attribute-specifier-sequence[opt] objc-synchronized-statement
7461 : :
7462 : : objc-throw-statement:
7463 : : @throw expression ;
7464 : : @throw ;
7465 : :
7466 : : OpenACC:
7467 : :
7468 : : statement:
7469 : : attribute-specifier-sequence[opt] openacc-construct
7470 : :
7471 : : openacc-construct:
7472 : : parallel-construct
7473 : : kernels-construct
7474 : : data-construct
7475 : : loop-construct
7476 : :
7477 : : parallel-construct:
7478 : : parallel-directive structured-block
7479 : :
7480 : : kernels-construct:
7481 : : kernels-directive structured-block
7482 : :
7483 : : data-construct:
7484 : : data-directive structured-block
7485 : :
7486 : : loop-construct:
7487 : : loop-directive structured-block
7488 : :
7489 : : OpenMP:
7490 : :
7491 : : statement:
7492 : : attribute-specifier-sequence[opt] openmp-construct
7493 : :
7494 : : openmp-construct:
7495 : : parallel-construct
7496 : : for-construct
7497 : : simd-construct
7498 : : for-simd-construct
7499 : : sections-construct
7500 : : single-construct
7501 : : parallel-for-construct
7502 : : parallel-for-simd-construct
7503 : : parallel-sections-construct
7504 : : master-construct
7505 : : critical-construct
7506 : : atomic-construct
7507 : : ordered-construct
7508 : :
7509 : : parallel-construct:
7510 : : parallel-directive structured-block
7511 : :
7512 : : for-construct:
7513 : : for-directive iteration-statement
7514 : :
7515 : : simd-construct:
7516 : : simd-directive iteration-statements
7517 : :
7518 : : for-simd-construct:
7519 : : for-simd-directive iteration-statements
7520 : :
7521 : : sections-construct:
7522 : : sections-directive section-scope
7523 : :
7524 : : single-construct:
7525 : : single-directive structured-block
7526 : :
7527 : : parallel-for-construct:
7528 : : parallel-for-directive iteration-statement
7529 : :
7530 : : parallel-for-simd-construct:
7531 : : parallel-for-simd-directive iteration-statement
7532 : :
7533 : : parallel-sections-construct:
7534 : : parallel-sections-directive section-scope
7535 : :
7536 : : master-construct:
7537 : : master-directive structured-block
7538 : :
7539 : : critical-construct:
7540 : : critical-directive structured-block
7541 : :
7542 : : atomic-construct:
7543 : : atomic-directive expression-statement
7544 : :
7545 : : ordered-construct:
7546 : : ordered-directive structured-block
7547 : :
7548 : : Transactional Memory:
7549 : :
7550 : : statement:
7551 : : attribute-specifier-sequence[opt] transaction-statement
7552 : : attribute-specifier-sequence[opt] transaction-cancel-statement
7553 : :
7554 : : IF_P is used to track whether there's a (possibly labeled) if statement
7555 : : which is not enclosed in braces and has an else clause. This is used to
7556 : : implement -Wparentheses. */
7557 : :
7558 : : static void
7559 : 494588 : c_parser_statement (c_parser *parser, bool *if_p, location_t *loc_after_labels)
7560 : : {
7561 : 494588 : c_parser_all_labels (parser);
7562 : 494588 : if (loc_after_labels)
7563 : 340744 : *loc_after_labels = c_parser_peek_token (parser)->location;
7564 : 494588 : parser->omp_attrs_forbidden_p = false;
7565 : 494588 : c_parser_statement_after_labels (parser, if_p, NULL);
7566 : 494588 : }
7567 : :
7568 : : /* Parse a statement, other than a labeled statement. CHAIN is a vector
7569 : : of if-else-if conditions. All labels and standard attributes have
7570 : : been parsed in the caller.
7571 : :
7572 : : IF_P is used to track whether there's a (possibly labeled) if statement
7573 : : which is not enclosed in braces and has an else clause. This is used to
7574 : : implement -Wparentheses. */
7575 : :
7576 : : static void
7577 : 38420600 : c_parser_statement_after_labels (c_parser *parser, bool *if_p,
7578 : : vec<tree> *chain)
7579 : : {
7580 : 38420600 : location_t loc = c_parser_peek_token (parser)->location;
7581 : 38420600 : tree stmt = NULL_TREE;
7582 : 38420600 : bool in_if_block = parser->in_if_block;
7583 : 38420600 : parser->in_if_block = false;
7584 : 38420600 : if (if_p != NULL)
7585 : 813777 : *if_p = false;
7586 : :
7587 : 38420600 : if (c_parser_peek_token (parser)->type != CPP_OPEN_BRACE)
7588 : 37990200 : add_debug_begin_stmt (loc);
7589 : :
7590 : 430400 : restart:
7591 : 38420632 : switch (c_parser_peek_token (parser)->type)
7592 : : {
7593 : 430404 : case CPP_OPEN_BRACE:
7594 : 430404 : add_stmt (c_parser_compound_statement (parser));
7595 : 430404 : break;
7596 : 32223500 : case CPP_KEYWORD:
7597 : 32223500 : switch (c_parser_peek_token (parser)->keyword)
7598 : : {
7599 : 1235787 : case RID_IF:
7600 : 1235787 : c_parser_if_statement (parser, if_p, chain);
7601 : 1235787 : break;
7602 : 36174 : case RID_SWITCH:
7603 : 36174 : c_parser_switch_statement (parser, if_p);
7604 : 36174 : break;
7605 : 41235 : case RID_WHILE:
7606 : 41235 : c_parser_while_statement (parser, false, 0, false, if_p);
7607 : 41235 : break;
7608 : 134970 : case RID_DO:
7609 : 134970 : c_parser_do_statement (parser, false, 0, false);
7610 : 134970 : break;
7611 : 260698 : case RID_FOR:
7612 : 260698 : c_parser_for_statement (parser, false, 0, false, if_p);
7613 : 260698 : break;
7614 : 82916 : case RID_GOTO:
7615 : 82916 : c_parser_consume_token (parser);
7616 : 82916 : if (c_parser_next_token_is (parser, CPP_NAME))
7617 : : {
7618 : 81991 : stmt = c_finish_goto_label (loc,
7619 : 81991 : c_parser_peek_token (parser)->value);
7620 : 81991 : c_parser_consume_token (parser);
7621 : : }
7622 : 925 : else if (c_parser_next_token_is (parser, CPP_MULT))
7623 : : {
7624 : 925 : struct c_expr val;
7625 : :
7626 : 925 : c_parser_consume_token (parser);
7627 : 925 : val = c_parser_expression (parser);
7628 : 925 : val = convert_lvalue_to_rvalue (loc, val, false, true);
7629 : 925 : stmt = c_finish_goto_ptr (loc, val);
7630 : : }
7631 : : else
7632 : 0 : c_parser_error (parser, "expected identifier or %<*%>");
7633 : 82916 : goto expect_semicolon;
7634 : 12795 : case RID_CONTINUE:
7635 : 12795 : c_parser_consume_token (parser);
7636 : 12795 : stmt = c_finish_bc_stmt (loc, objc_foreach_continue_label, false);
7637 : 12795 : goto expect_semicolon;
7638 : 168204 : case RID_BREAK:
7639 : 168204 : c_parser_consume_token (parser);
7640 : 168204 : stmt = c_finish_bc_stmt (loc, objc_foreach_break_label, true);
7641 : 168204 : goto expect_semicolon;
7642 : 30047604 : case RID_RETURN:
7643 : 30047604 : c_parser_consume_token (parser);
7644 : 30047604 : if (c_parser_next_token_is (parser, CPP_SEMICOLON))
7645 : : {
7646 : 19793 : stmt = c_finish_return (loc, NULL_TREE, NULL_TREE);
7647 : 19793 : c_parser_consume_token (parser);
7648 : : }
7649 : : else
7650 : : {
7651 : 30027811 : location_t xloc = c_parser_peek_token (parser)->location;
7652 : 30027811 : struct c_expr expr = c_parser_expression_conv (parser);
7653 : 30027811 : mark_exp_read (expr.value);
7654 : 30770819 : stmt = c_finish_return (EXPR_LOC_OR_LOC (expr.value, xloc),
7655 : : expr.value, expr.original_type);
7656 : 30027811 : goto expect_semicolon;
7657 : : }
7658 : 19793 : break;
7659 : 198423 : case RID_ASM:
7660 : 198423 : stmt = c_parser_asm_statement (parser);
7661 : 198423 : break;
7662 : 137 : case RID_TRANSACTION_ATOMIC:
7663 : 137 : case RID_TRANSACTION_RELAXED:
7664 : 274 : stmt = c_parser_transaction (parser,
7665 : 137 : c_parser_peek_token (parser)->keyword);
7666 : 137 : break;
7667 : 28 : case RID_TRANSACTION_CANCEL:
7668 : 28 : stmt = c_parser_transaction_cancel (parser);
7669 : 28 : goto expect_semicolon;
7670 : 0 : case RID_AT_THROW:
7671 : 0 : gcc_assert (c_dialect_objc ());
7672 : 0 : c_parser_consume_token (parser);
7673 : 0 : if (c_parser_next_token_is (parser, CPP_SEMICOLON))
7674 : : {
7675 : 0 : stmt = objc_build_throw_stmt (loc, NULL_TREE);
7676 : 0 : c_parser_consume_token (parser);
7677 : : }
7678 : : else
7679 : : {
7680 : 0 : struct c_expr expr = c_parser_expression (parser);
7681 : 0 : expr = convert_lvalue_to_rvalue (loc, expr, false, false);
7682 : 0 : expr.value = c_fully_fold (expr.value, false, NULL);
7683 : 0 : stmt = objc_build_throw_stmt (loc, expr.value);
7684 : 0 : goto expect_semicolon;
7685 : : }
7686 : 0 : break;
7687 : 0 : case RID_AT_TRY:
7688 : 0 : gcc_assert (c_dialect_objc ());
7689 : 0 : c_parser_objc_try_catch_finally_statement (parser);
7690 : 0 : break;
7691 : 0 : case RID_AT_SYNCHRONIZED:
7692 : 0 : gcc_assert (c_dialect_objc ());
7693 : 0 : c_parser_objc_synchronized_statement (parser);
7694 : 0 : break;
7695 : 5 : case RID_ATTRIBUTE:
7696 : 5 : {
7697 : : /* Allow '__attribute__((fallthrough));' or
7698 : : '__attribute__((assume(cond)));'. */
7699 : 5 : tree attrs = c_parser_gnu_attributes (parser);
7700 : 5 : bool has_assume = lookup_attribute ("assume", attrs);
7701 : 5 : if (has_assume)
7702 : : {
7703 : 0 : if (c_parser_next_token_is (parser, CPP_SEMICOLON))
7704 : 0 : attrs = handle_assume_attribute (loc, attrs, true);
7705 : : else
7706 : : {
7707 : 0 : warning_at (loc, OPT_Wattributes,
7708 : : "%<assume%> attribute not followed by %<;%>");
7709 : 0 : has_assume = false;
7710 : : }
7711 : : }
7712 : 5 : if (attribute_fallthrough_p (attrs))
7713 : : {
7714 : 5 : if (c_parser_next_token_is (parser, CPP_SEMICOLON))
7715 : : {
7716 : 5 : tree fn = build_call_expr_internal_loc (loc,
7717 : : IFN_FALLTHROUGH,
7718 : : void_type_node, 0);
7719 : 5 : add_stmt (fn);
7720 : : /* Eat the ';'. */
7721 : 5 : c_parser_consume_token (parser);
7722 : : }
7723 : : else
7724 : 0 : warning_at (loc, OPT_Wattributes,
7725 : : "%<fallthrough%> attribute not followed "
7726 : : "by %<;%>");
7727 : : }
7728 : 0 : else if (has_assume)
7729 : : /* Eat the ';'. */
7730 : 0 : c_parser_consume_token (parser);
7731 : 0 : else if (attrs != NULL_TREE)
7732 : 0 : warning_at (loc, OPT_Wattributes,
7733 : : "only attribute %<fallthrough%> or %<assume%> can "
7734 : : "be applied to a null statement");
7735 : : break;
7736 : : }
7737 : 4524 : default:
7738 : 4524 : goto expr_stmt;
7739 : : }
7740 : : break;
7741 : 204557 : case CPP_SEMICOLON:
7742 : 204557 : c_parser_consume_token (parser);
7743 : 204557 : break;
7744 : 5 : case CPP_CLOSE_PAREN:
7745 : 5 : case CPP_CLOSE_SQUARE:
7746 : : /* Avoid infinite loop in error recovery:
7747 : : c_parser_skip_until_found stops at a closing nesting
7748 : : delimiter without consuming it, but here we need to consume
7749 : : it to proceed further. */
7750 : 5 : c_parser_error (parser, "expected statement");
7751 : 5 : c_parser_consume_token (parser);
7752 : 5 : break;
7753 : 2488 : case CPP_PRAGMA:
7754 : 2488 : if (!c_parser_pragma (parser, pragma_stmt, if_p))
7755 : 32 : goto restart;
7756 : : break;
7757 : 5564202 : default:
7758 : 5564202 : expr_stmt:
7759 : 5564202 : stmt = c_finish_expr_stmt (loc, c_parser_expression_conv (parser).value);
7760 : 35855955 : expect_semicolon:
7761 : 35855955 : c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
7762 : 35855955 : break;
7763 : : }
7764 : : /* Two cases cannot and do not have line numbers associated: If stmt
7765 : : is degenerate, such as "2;", then stmt is an INTEGER_CST, which
7766 : : cannot hold line numbers. But that's OK because the statement
7767 : : will either be changed to a MODIFY_EXPR during gimplification of
7768 : : the statement expr, or discarded. If stmt was compound, but
7769 : : without new variables, we will have skipped the creation of a
7770 : : BIND and will have a bare STATEMENT_LIST. But that's OK because
7771 : : (recursively) all of the component statements should already have
7772 : : line numbers assigned. ??? Can we discard no-op statements
7773 : : earlier? */
7774 : 38420599 : if (EXPR_LOCATION (stmt) == UNKNOWN_LOCATION)
7775 : 2349680 : protected_set_expr_location (stmt, loc);
7776 : :
7777 : 38420599 : parser->in_if_block = in_if_block;
7778 : 38420599 : }
7779 : :
7780 : : /* Parse the condition from an if, do, while or for statements. */
7781 : :
7782 : : static tree
7783 : 1672508 : c_parser_condition (c_parser *parser)
7784 : : {
7785 : 1672508 : location_t loc = c_parser_peek_token (parser)->location;
7786 : 1672508 : tree cond;
7787 : 1672508 : cond = c_parser_expression_conv (parser).value;
7788 : 1672508 : cond = c_objc_common_truthvalue_conversion (loc, cond);
7789 : 1672508 : cond = c_fully_fold (cond, false, NULL);
7790 : 1672508 : if (warn_sequence_point)
7791 : 308994 : verify_sequence_points (cond);
7792 : 1672508 : return cond;
7793 : : }
7794 : :
7795 : : /* Parse a parenthesized condition from an if, do or while statement.
7796 : :
7797 : : condition:
7798 : : ( expression )
7799 : : */
7800 : : static tree
7801 : 1412060 : c_parser_paren_condition (c_parser *parser)
7802 : : {
7803 : 1412060 : tree cond;
7804 : 1412060 : matching_parens parens;
7805 : 1412060 : if (!parens.require_open (parser))
7806 : 1 : return error_mark_node;
7807 : 1412059 : cond = c_parser_condition (parser);
7808 : 1412059 : parens.skip_until_found_close (parser);
7809 : 1412059 : return cond;
7810 : : }
7811 : :
7812 : : /* Parse a statement which is a block in C99.
7813 : :
7814 : : IF_P is used to track whether there's a (possibly labeled) if statement
7815 : : which is not enclosed in braces and has an else clause. This is used to
7816 : : implement -Wparentheses. */
7817 : :
7818 : : static tree
7819 : 485581 : c_parser_c99_block_statement (c_parser *parser, bool *if_p,
7820 : : location_t *loc_after_labels)
7821 : : {
7822 : 485581 : tree block = c_begin_compound_stmt (flag_isoc99);
7823 : 485581 : location_t loc = c_parser_peek_token (parser)->location;
7824 : 485581 : c_parser_statement (parser, if_p, loc_after_labels);
7825 : 485581 : return c_end_compound_stmt (loc, block, flag_isoc99);
7826 : : }
7827 : :
7828 : : /* Parse the body of an if statement. This is just parsing a
7829 : : statement but (a) it is a block in C99, (b) we track whether the
7830 : : body is an if statement for the sake of -Wparentheses warnings, (c)
7831 : : we handle an empty body specially for the sake of -Wempty-body
7832 : : warnings, and (d) we call parser_compound_statement directly
7833 : : because c_parser_statement_after_labels resets
7834 : : parser->in_if_block.
7835 : :
7836 : : IF_P is used to track whether there's a (possibly labeled) if statement
7837 : : which is not enclosed in braces and has an else clause. This is used to
7838 : : implement -Wparentheses. */
7839 : :
7840 : : static tree
7841 : 1235787 : c_parser_if_body (c_parser *parser, bool *if_p,
7842 : : const token_indent_info &if_tinfo)
7843 : : {
7844 : 1235787 : tree block = c_begin_compound_stmt (flag_isoc99);
7845 : 1235787 : location_t body_loc = c_parser_peek_token (parser)->location;
7846 : 1235787 : location_t body_loc_after_labels = UNKNOWN_LOCATION;
7847 : 1235787 : token_indent_info body_tinfo
7848 : 1235787 : = get_token_indent_info (c_parser_peek_token (parser));
7849 : :
7850 : 1235787 : c_parser_all_labels (parser);
7851 : 1235787 : if (c_parser_next_token_is (parser, CPP_SEMICOLON))
7852 : : {
7853 : 4985 : location_t loc = c_parser_peek_token (parser)->location;
7854 : 4985 : add_stmt (build_empty_stmt (loc));
7855 : 4985 : c_parser_consume_token (parser);
7856 : 4985 : if (!c_parser_next_token_is_keyword (parser, RID_ELSE))
7857 : 356 : warning_at (loc, OPT_Wempty_body,
7858 : : "suggest braces around empty body in an %<if%> statement");
7859 : : }
7860 : 1230802 : else if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
7861 : 419808 : add_stmt (c_parser_compound_statement (parser));
7862 : : else
7863 : : {
7864 : 810994 : body_loc_after_labels = c_parser_peek_token (parser)->location;
7865 : 810994 : c_parser_statement_after_labels (parser, if_p);
7866 : : }
7867 : :
7868 : 1235787 : token_indent_info next_tinfo
7869 : 1235787 : = get_token_indent_info (c_parser_peek_token (parser));
7870 : 1235787 : warn_for_misleading_indentation (if_tinfo, body_tinfo, next_tinfo);
7871 : 1235787 : if (body_loc_after_labels != UNKNOWN_LOCATION
7872 : 810994 : && next_tinfo.type != CPP_SEMICOLON)
7873 : 806488 : warn_for_multistatement_macros (body_loc_after_labels, next_tinfo.location,
7874 : 806488 : if_tinfo.location, RID_IF);
7875 : :
7876 : 1235787 : return c_end_compound_stmt (body_loc, block, flag_isoc99);
7877 : : }
7878 : :
7879 : : /* Parse the else body of an if statement. This is just parsing a
7880 : : statement but (a) it is a block in C99, (b) we handle an empty body
7881 : : specially for the sake of -Wempty-body warnings. CHAIN is a vector
7882 : : of if-else-if conditions. */
7883 : :
7884 : : static tree
7885 : 274422 : c_parser_else_body (c_parser *parser, const token_indent_info &else_tinfo,
7886 : : vec<tree> *chain)
7887 : : {
7888 : 274422 : location_t body_loc = c_parser_peek_token (parser)->location;
7889 : 274422 : tree block = c_begin_compound_stmt (flag_isoc99);
7890 : 274422 : token_indent_info body_tinfo
7891 : 274422 : = get_token_indent_info (c_parser_peek_token (parser));
7892 : 274422 : location_t body_loc_after_labels = UNKNOWN_LOCATION;
7893 : :
7894 : 274422 : c_parser_all_labels (parser);
7895 : 274422 : if (c_parser_next_token_is (parser, CPP_SEMICOLON))
7896 : : {
7897 : 29 : location_t loc = c_parser_peek_token (parser)->location;
7898 : 29 : warning_at (loc,
7899 : : OPT_Wempty_body,
7900 : : "suggest braces around empty body in an %<else%> statement");
7901 : 29 : add_stmt (build_empty_stmt (loc));
7902 : 29 : c_parser_consume_token (parser);
7903 : : }
7904 : : else
7905 : : {
7906 : 274393 : if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE))
7907 : 227850 : body_loc_after_labels = c_parser_peek_token (parser)->location;
7908 : 274393 : c_parser_statement_after_labels (parser, NULL, chain);
7909 : : }
7910 : :
7911 : 274422 : token_indent_info next_tinfo
7912 : 274422 : = get_token_indent_info (c_parser_peek_token (parser));
7913 : 274422 : warn_for_misleading_indentation (else_tinfo, body_tinfo, next_tinfo);
7914 : 274422 : if (body_loc_after_labels != UNKNOWN_LOCATION
7915 : 227850 : && next_tinfo.type != CPP_SEMICOLON)
7916 : 227837 : warn_for_multistatement_macros (body_loc_after_labels, next_tinfo.location,
7917 : 227837 : else_tinfo.location, RID_ELSE);
7918 : :
7919 : 274422 : return c_end_compound_stmt (body_loc, block, flag_isoc99);
7920 : : }
7921 : :
7922 : : /* We might need to reclassify any previously-lexed identifier, e.g.
7923 : : when we've left a for loop with an if-statement without else in the
7924 : : body - we might have used a wrong scope for the token. See PR67784. */
7925 : :
7926 : : static void
7927 : 1576531 : c_parser_maybe_reclassify_token (c_parser *parser)
7928 : : {
7929 : 1576531 : if (c_parser_next_token_is (parser, CPP_NAME))
7930 : : {
7931 : 179915 : c_token *token = c_parser_peek_token (parser);
7932 : :
7933 : 179915 : if (token->id_kind != C_ID_CLASSNAME)
7934 : : {
7935 : 179915 : tree decl = lookup_name (token->value);
7936 : :
7937 : 179915 : token->id_kind = C_ID_ID;
7938 : 179915 : if (decl)
7939 : : {
7940 : 177202 : if (TREE_CODE (decl) == TYPE_DECL)
7941 : 1824 : token->id_kind = C_ID_TYPENAME;
7942 : : }
7943 : 2713 : else if (c_dialect_objc ())
7944 : : {
7945 : 0 : tree objc_interface_decl = objc_is_class_name (token->value);
7946 : : /* Objective-C class names are in the same namespace as
7947 : : variables and typedefs, and hence are shadowed by local
7948 : : declarations. */
7949 : 0 : if (objc_interface_decl)
7950 : : {
7951 : 0 : token->value = objc_interface_decl;
7952 : 0 : token->id_kind = C_ID_CLASSNAME;
7953 : : }
7954 : : }
7955 : : }
7956 : : }
7957 : 1576531 : }
7958 : :
7959 : : /* Parse an if statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
7960 : :
7961 : : if-statement:
7962 : : if ( expression ) statement
7963 : : if ( expression ) statement else statement
7964 : :
7965 : : CHAIN is a vector of if-else-if conditions.
7966 : : IF_P is used to track whether there's a (possibly labeled) if statement
7967 : : which is not enclosed in braces and has an else clause. This is used to
7968 : : implement -Wparentheses. */
7969 : :
7970 : : static void
7971 : 1235787 : c_parser_if_statement (c_parser *parser, bool *if_p, vec<tree> *chain)
7972 : : {
7973 : 1235787 : tree block;
7974 : 1235787 : location_t loc;
7975 : 1235787 : tree cond;
7976 : 1235787 : bool nested_if = false;
7977 : 1235787 : tree first_body, second_body;
7978 : 1235787 : bool in_if_block;
7979 : :
7980 : 1235787 : gcc_assert (c_parser_next_token_is_keyword (parser, RID_IF));
7981 : 1235787 : token_indent_info if_tinfo
7982 : 1235787 : = get_token_indent_info (c_parser_peek_token (parser));
7983 : 1235787 : c_parser_consume_token (parser);
7984 : 1235787 : block = c_begin_compound_stmt (flag_isoc99);
7985 : 1235787 : loc = c_parser_peek_token (parser)->location;
7986 : 1235787 : cond = c_parser_paren_condition (parser);
7987 : 1235787 : in_if_block = parser->in_if_block;
7988 : 1235787 : parser->in_if_block = true;
7989 : 1235787 : first_body = c_parser_if_body (parser, &nested_if, if_tinfo);
7990 : 1235787 : parser->in_if_block = in_if_block;
7991 : :
7992 : 1235787 : if (warn_duplicated_cond)
7993 : 62 : warn_duplicated_cond_add_or_warn (EXPR_LOCATION (cond), cond, &chain);
7994 : :
7995 : 1235787 : if (c_parser_next_token_is_keyword (parser, RID_ELSE))
7996 : : {
7997 : 274422 : token_indent_info else_tinfo
7998 : 274422 : = get_token_indent_info (c_parser_peek_token (parser));
7999 : 274422 : c_parser_consume_token (parser);
8000 : 274422 : if (warn_duplicated_cond)
8001 : : {
8002 : 43 : if (c_parser_next_token_is_keyword (parser, RID_IF)
8003 : 43 : && chain == NULL)
8004 : : {
8005 : : /* We've got "if (COND) else if (COND2)". Start the
8006 : : condition chain and add COND as the first element. */
8007 : 18 : chain = new vec<tree> ();
8008 : 18 : if (!CONSTANT_CLASS_P (cond) && !TREE_SIDE_EFFECTS (cond))
8009 : 12 : chain->safe_push (cond);
8010 : : }
8011 : 25 : else if (!c_parser_next_token_is_keyword (parser, RID_IF))
8012 : : /* This is if-else without subsequent if. Zap the condition
8013 : : chain; we would have already warned at this point. */
8014 : 4 : vec_free (chain);
8015 : : }
8016 : 274422 : second_body = c_parser_else_body (parser, else_tinfo, chain);
8017 : : /* Set IF_P to true to indicate that this if statement has an
8018 : : else clause. This may trigger the Wparentheses warning
8019 : : below when we get back up to the parent if statement. */
8020 : 274422 : if (if_p != NULL)
8021 : 186 : *if_p = true;
8022 : : }
8023 : : else
8024 : : {
8025 : 961365 : second_body = NULL_TREE;
8026 : :
8027 : : /* Diagnose an ambiguous else if if-then-else is nested inside
8028 : : if-then. */
8029 : 961365 : if (nested_if)
8030 : 140 : warning_at (loc, OPT_Wdangling_else,
8031 : : "suggest explicit braces to avoid ambiguous %<else%>");
8032 : :
8033 : 961365 : if (warn_duplicated_cond)
8034 : : /* This if statement does not have an else clause. We don't
8035 : : need the condition chain anymore. */
8036 : 19 : vec_free (chain);
8037 : : }
8038 : 1235787 : c_finish_if_stmt (loc, cond, first_body, second_body);
8039 : 1235787 : add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
8040 : :
8041 : 1235787 : c_parser_maybe_reclassify_token (parser);
8042 : 1235787 : }
8043 : :
8044 : : /* Parse a switch statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
8045 : :
8046 : : switch-statement:
8047 : : switch (expression) statement
8048 : : */
8049 : :
8050 : : static void
8051 : 36174 : c_parser_switch_statement (c_parser *parser, bool *if_p)
8052 : : {
8053 : 36174 : struct c_expr ce;
8054 : 36174 : tree block, expr, body;
8055 : 36174 : unsigned char save_in_statement;
8056 : 36174 : location_t switch_loc = c_parser_peek_token (parser)->location;
8057 : 36174 : location_t switch_cond_loc;
8058 : 36174 : gcc_assert (c_parser_next_token_is_keyword (parser, RID_SWITCH));
8059 : 36174 : c_parser_consume_token (parser);
8060 : 36174 : block = c_begin_compound_stmt (flag_isoc99);
8061 : 36174 : bool explicit_cast_p = false;
8062 : 36174 : matching_parens parens;
8063 : 36174 : if (parens.require_open (parser))
8064 : : {
8065 : 36167 : switch_cond_loc = c_parser_peek_token (parser)->location;
8066 : 36167 : if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
8067 : 36167 : && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
8068 : : explicit_cast_p = true;
8069 : 36167 : ce = c_parser_expression (parser);
8070 : 36167 : ce = convert_lvalue_to_rvalue (switch_cond_loc, ce, true, true);
8071 : 36167 : expr = ce.value;
8072 : : /* ??? expr has no valid location? */
8073 : 36167 : parens.skip_until_found_close (parser);
8074 : : }
8075 : : else
8076 : : {
8077 : 7 : switch_cond_loc = UNKNOWN_LOCATION;
8078 : 7 : expr = error_mark_node;
8079 : 7 : ce.original_type = error_mark_node;
8080 : : }
8081 : 36174 : c_start_switch (switch_loc, switch_cond_loc, expr, explicit_cast_p);
8082 : 36174 : save_in_statement = in_statement;
8083 : 36174 : in_statement |= IN_SWITCH_STMT;
8084 : 36174 : location_t loc_after_labels;
8085 : 36174 : bool open_brace_p = c_parser_peek_token (parser)->type == CPP_OPEN_BRACE;
8086 : 36174 : body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
8087 : 36174 : location_t next_loc = c_parser_peek_token (parser)->location;
8088 : 36174 : if (!open_brace_p && c_parser_peek_token (parser)->type != CPP_SEMICOLON)
8089 : 280 : warn_for_multistatement_macros (loc_after_labels, next_loc, switch_loc,
8090 : : RID_SWITCH);
8091 : 36174 : c_finish_switch (body, ce.original_type);
8092 : 36174 : in_statement = save_in_statement;
8093 : 36174 : add_stmt (c_end_compound_stmt (switch_loc, block, flag_isoc99));
8094 : 36174 : c_parser_maybe_reclassify_token (parser);
8095 : 36174 : }
8096 : :
8097 : : /* Parse a while statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
8098 : :
8099 : : while-statement:
8100 : : while (expression) statement
8101 : :
8102 : : IF_P is used to track whether there's a (possibly labeled) if statement
8103 : : which is not enclosed in braces and has an else clause. This is used to
8104 : : implement -Wparentheses. */
8105 : :
8106 : : static void
8107 : 41244 : c_parser_while_statement (c_parser *parser, bool ivdep, unsigned short unroll,
8108 : : bool novector, bool *if_p)
8109 : : {
8110 : 41244 : tree block, cond, body;
8111 : 41244 : unsigned char save_in_statement;
8112 : 41244 : location_t loc;
8113 : 41244 : gcc_assert (c_parser_next_token_is_keyword (parser, RID_WHILE));
8114 : 41244 : token_indent_info while_tinfo
8115 : 41244 : = get_token_indent_info (c_parser_peek_token (parser));
8116 : :
8117 : 41244 : if (parser->omp_for_parse_state)
8118 : : {
8119 : 1 : error_at (c_parser_peek_token (parser)->location,
8120 : : "loop not permitted in intervening code in OpenMP loop body");
8121 : 1 : parser->omp_for_parse_state->fail = true;
8122 : : }
8123 : :
8124 : 41244 : c_parser_consume_token (parser);
8125 : 41244 : block = c_begin_compound_stmt (flag_isoc99);
8126 : 41244 : loc = c_parser_peek_token (parser)->location;
8127 : 41244 : cond = c_parser_paren_condition (parser);
8128 : 41244 : if (ivdep && cond != error_mark_node)
8129 : 3 : cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
8130 : : build_int_cst (integer_type_node,
8131 : 3 : annot_expr_ivdep_kind),
8132 : : integer_zero_node);
8133 : 41244 : if (unroll && cond != error_mark_node)
8134 : 0 : cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
8135 : : build_int_cst (integer_type_node,
8136 : 0 : annot_expr_unroll_kind),
8137 : : build_int_cst (integer_type_node, unroll));
8138 : 41244 : if (novector && cond != error_mark_node)
8139 : 6 : cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
8140 : : build_int_cst (integer_type_node,
8141 : 6 : annot_expr_no_vector_kind),
8142 : : integer_zero_node);
8143 : 41244 : save_in_statement = in_statement;
8144 : 41244 : in_statement = IN_ITERATION_STMT;
8145 : :
8146 : 41244 : token_indent_info body_tinfo
8147 : 41244 : = get_token_indent_info (c_parser_peek_token (parser));
8148 : :
8149 : 41244 : location_t loc_after_labels;
8150 : 41244 : bool open_brace = c_parser_next_token_is (parser, CPP_OPEN_BRACE);
8151 : 41244 : body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
8152 : 41244 : add_stmt (build_stmt (loc, WHILE_STMT, cond, body));
8153 : 41244 : add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
8154 : 41244 : c_parser_maybe_reclassify_token (parser);
8155 : :
8156 : 41244 : token_indent_info next_tinfo
8157 : 41244 : = get_token_indent_info (c_parser_peek_token (parser));
8158 : 41244 : warn_for_misleading_indentation (while_tinfo, body_tinfo, next_tinfo);
8159 : :
8160 : 41244 : if (next_tinfo.type != CPP_SEMICOLON && !open_brace)
8161 : 10130 : warn_for_multistatement_macros (loc_after_labels, next_tinfo.location,
8162 : : while_tinfo.location, RID_WHILE);
8163 : :
8164 : 41244 : in_statement = save_in_statement;
8165 : 41244 : }
8166 : :
8167 : : /* Parse a do statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
8168 : :
8169 : : do-statement:
8170 : : do statement while ( expression ) ;
8171 : : */
8172 : :
8173 : : static void
8174 : 135029 : c_parser_do_statement (c_parser *parser, bool ivdep, unsigned short unroll,
8175 : : bool novector)
8176 : : {
8177 : 135029 : tree block, cond, body;
8178 : 135029 : unsigned char save_in_statement;
8179 : 135029 : location_t loc;
8180 : 135029 : gcc_assert (c_parser_next_token_is_keyword (parser, RID_DO));
8181 : :
8182 : 135029 : if (parser->omp_for_parse_state)
8183 : : {
8184 : 1 : error_at (c_parser_peek_token (parser)->location,
8185 : : "loop not permitted in intervening code in OpenMP loop body");
8186 : 1 : parser->omp_for_parse_state->fail = true;
8187 : : }
8188 : :
8189 : 135029 : c_parser_consume_token (parser);
8190 : 135029 : if (c_parser_next_token_is (parser, CPP_SEMICOLON))
8191 : 50 : warning_at (c_parser_peek_token (parser)->location,
8192 : : OPT_Wempty_body,
8193 : : "suggest braces around empty body in %<do%> statement");
8194 : 135029 : block = c_begin_compound_stmt (flag_isoc99);
8195 : 135029 : loc = c_parser_peek_token (parser)->location;
8196 : 135029 : save_in_statement = in_statement;
8197 : 135029 : in_statement = IN_ITERATION_STMT;
8198 : 135029 : body = c_parser_c99_block_statement (parser, NULL);
8199 : 135029 : c_parser_require_keyword (parser, RID_WHILE, "expected %<while%>");
8200 : 135029 : in_statement = save_in_statement;
8201 : 135029 : cond = c_parser_paren_condition (parser);
8202 : 135029 : if (ivdep && cond != error_mark_node)
8203 : 2 : cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
8204 : : build_int_cst (integer_type_node,
8205 : 2 : annot_expr_ivdep_kind),
8206 : : integer_zero_node);
8207 : 135029 : if (unroll && cond != error_mark_node)
8208 : 3 : cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
8209 : : build_int_cst (integer_type_node,
8210 : 3 : annot_expr_unroll_kind),
8211 : : build_int_cst (integer_type_node, unroll));
8212 : 135029 : if (novector && cond != error_mark_node)
8213 : 54 : cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
8214 : : build_int_cst (integer_type_node,
8215 : 54 : annot_expr_no_vector_kind),
8216 : : integer_zero_node);
8217 : 135029 : if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
8218 : 0 : c_parser_skip_to_end_of_block_or_statement (parser);
8219 : :
8220 : 135029 : add_stmt (build_stmt (loc, DO_STMT, cond, body));
8221 : 135029 : add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
8222 : 135029 : }
8223 : :
8224 : : /* Parse a for statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
8225 : :
8226 : : for-statement:
8227 : : for ( expression[opt] ; expression[opt] ; expression[opt] ) statement
8228 : : for ( nested-declaration expression[opt] ; expression[opt] ) statement
8229 : :
8230 : : The form with a declaration is new in C99.
8231 : :
8232 : : ??? In accordance with the old parser, the declaration may be a
8233 : : nested function, which is then rejected in check_for_loop_decls,
8234 : : but does it make any sense for this to be included in the grammar?
8235 : : Note in particular that the nested function does not include a
8236 : : trailing ';', whereas the "declaration" production includes one.
8237 : : Also, can we reject bad declarations earlier and cheaper than
8238 : : check_for_loop_decls?
8239 : :
8240 : : In Objective-C, there are two additional variants:
8241 : :
8242 : : foreach-statement:
8243 : : for ( expression in expresssion ) statement
8244 : : for ( declaration in expression ) statement
8245 : :
8246 : : This is inconsistent with C, because the second variant is allowed
8247 : : even if c99 is not enabled.
8248 : :
8249 : : The rest of the comment documents these Objective-C foreach-statement.
8250 : :
8251 : : Here is the canonical example of the first variant:
8252 : : for (object in array) { do something with object }
8253 : : we call the first expression ("object") the "object_expression" and
8254 : : the second expression ("array") the "collection_expression".
8255 : : object_expression must be an lvalue of type "id" (a generic Objective-C
8256 : : object) because the loop works by assigning to object_expression the
8257 : : various objects from the collection_expression. collection_expression
8258 : : must evaluate to something of type "id" which responds to the method
8259 : : countByEnumeratingWithState:objects:count:.
8260 : :
8261 : : The canonical example of the second variant is:
8262 : : for (id object in array) { do something with object }
8263 : : which is completely equivalent to
8264 : : {
8265 : : id object;
8266 : : for (object in array) { do something with object }
8267 : : }
8268 : : Note that initizializing 'object' in some way (eg, "for ((object =
8269 : : xxx) in array) { do something with object }") is possibly
8270 : : technically valid, but completely pointless as 'object' will be
8271 : : assigned to something else as soon as the loop starts. We should
8272 : : most likely reject it (TODO).
8273 : :
8274 : : The beginning of the Objective-C foreach-statement looks exactly
8275 : : like the beginning of the for-statement, and we can tell it is a
8276 : : foreach-statement only because the initial declaration or
8277 : : expression is terminated by 'in' instead of ';'.
8278 : :
8279 : : IF_P is used to track whether there's a (possibly labeled) if statement
8280 : : which is not enclosed in braces and has an else clause. This is used to
8281 : : implement -Wparentheses. */
8282 : :
8283 : : static void
8284 : 263326 : c_parser_for_statement (c_parser *parser, bool ivdep, unsigned short unroll,
8285 : : bool novector, bool *if_p)
8286 : : {
8287 : 263326 : tree block, cond, incr, body;
8288 : 263326 : unsigned char save_in_statement;
8289 : 263326 : tree save_objc_foreach_break_label, save_objc_foreach_continue_label;
8290 : : /* The following are only used when parsing an ObjC foreach statement. */
8291 : 263326 : tree object_expression;
8292 : : /* Silence the bogus uninitialized warning. */
8293 : 263326 : tree collection_expression = NULL;
8294 : 263326 : location_t loc = c_parser_peek_token (parser)->location;
8295 : 263326 : location_t for_loc = loc;
8296 : 263326 : bool is_foreach_statement = false;
8297 : 263326 : gcc_assert (c_parser_next_token_is_keyword (parser, RID_FOR));
8298 : 263326 : token_indent_info for_tinfo
8299 : 263326 : = get_token_indent_info (c_parser_peek_token (parser));
8300 : :
8301 : 263326 : if (parser->omp_for_parse_state)
8302 : : {
8303 : 14 : error_at (for_loc,
8304 : : "loop not permitted in intervening code in OpenMP loop body");
8305 : 14 : parser->omp_for_parse_state->fail = true;
8306 : : }
8307 : :
8308 : 263326 : c_parser_consume_token (parser);
8309 : : /* Open a compound statement in Objective-C as well, just in case this is
8310 : : as foreach expression. */
8311 : 525768 : block = c_begin_compound_stmt (flag_isoc99 || c_dialect_objc ());
8312 : 263326 : cond = error_mark_node;
8313 : 263326 : incr = error_mark_node;
8314 : 263326 : matching_parens parens;
8315 : 263326 : if (parens.require_open (parser))
8316 : : {
8317 : : /* Parse the initialization declaration or expression. */
8318 : 263325 : object_expression = error_mark_node;
8319 : 263325 : parser->objc_could_be_foreach_context = c_dialect_objc ();
8320 : 263325 : if (c_parser_next_token_is (parser, CPP_SEMICOLON))
8321 : : {
8322 : 10818 : parser->objc_could_be_foreach_context = false;
8323 : 10818 : c_parser_consume_token (parser);
8324 : 10818 : c_finish_expr_stmt (loc, NULL_TREE);
8325 : : }
8326 : 252507 : else if (c_parser_next_tokens_start_declaration (parser)
8327 : 252507 : || c_parser_nth_token_starts_std_attributes (parser, 1))
8328 : : {
8329 : 17524 : c_parser_declaration_or_fndef (parser, true, true, true, true, true,
8330 : : &object_expression);
8331 : 17524 : parser->objc_could_be_foreach_context = false;
8332 : :
8333 : 17524 : if (c_parser_next_token_is_keyword (parser, RID_IN))
8334 : : {
8335 : 0 : c_parser_consume_token (parser);
8336 : 0 : is_foreach_statement = true;
8337 : 0 : if (check_for_loop_decls (for_loc, true) == NULL_TREE)
8338 : 0 : c_parser_error (parser, "multiple iterating variables in "
8339 : : "fast enumeration");
8340 : : }
8341 : : else
8342 : 17524 : check_for_loop_decls (for_loc, flag_isoc99);
8343 : : }
8344 : 234983 : else if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
8345 : : {
8346 : : /* __extension__ can start a declaration, but is also an
8347 : : unary operator that can start an expression. Consume all
8348 : : but the last of a possible series of __extension__ to
8349 : : determine which. */
8350 : 0 : while (c_parser_peek_2nd_token (parser)->type == CPP_KEYWORD
8351 : 0 : && (c_parser_peek_2nd_token (parser)->keyword
8352 : : == RID_EXTENSION))
8353 : 0 : c_parser_consume_token (parser);
8354 : 0 : if (c_token_starts_declaration (c_parser_peek_2nd_token (parser))
8355 : 0 : || c_parser_nth_token_starts_std_attributes (parser, 2))
8356 : : {
8357 : 0 : int ext;
8358 : 0 : ext = disable_extension_diagnostics ();
8359 : 0 : c_parser_consume_token (parser);
8360 : 0 : c_parser_declaration_or_fndef (parser, true, true, true, true,
8361 : : true, &object_expression);
8362 : 0 : parser->objc_could_be_foreach_context = false;
8363 : :
8364 : 0 : restore_extension_diagnostics (ext);
8365 : 0 : if (c_parser_next_token_is_keyword (parser, RID_IN))
8366 : : {
8367 : 0 : c_parser_consume_token (parser);
8368 : 0 : is_foreach_statement = true;
8369 : 0 : if (check_for_loop_decls (for_loc, true) == NULL_TREE)
8370 : 0 : c_parser_error (parser, "multiple iterating variables in "
8371 : : "fast enumeration");
8372 : : }
8373 : : else
8374 : 0 : check_for_loop_decls (for_loc, flag_isoc99);
8375 : : }
8376 : : else
8377 : 0 : goto init_expr;
8378 : : }
8379 : : else
8380 : : {
8381 : 234983 : init_expr:
8382 : 234983 : {
8383 : 234983 : struct c_expr ce;
8384 : 234983 : tree init_expression;
8385 : 234983 : ce = c_parser_expression (parser);
8386 : 234983 : init_expression = ce.value;
8387 : 234983 : parser->objc_could_be_foreach_context = false;
8388 : 234983 : if (c_parser_next_token_is_keyword (parser, RID_IN))
8389 : : {
8390 : 0 : c_parser_consume_token (parser);
8391 : 0 : is_foreach_statement = true;
8392 : 0 : if (! lvalue_p (init_expression))
8393 : 0 : c_parser_error (parser, "invalid iterating variable in "
8394 : : "fast enumeration");
8395 : 0 : object_expression
8396 : 0 : = c_fully_fold (init_expression, false, NULL);
8397 : : }
8398 : : else
8399 : : {
8400 : 234983 : ce = convert_lvalue_to_rvalue (loc, ce, true, false);
8401 : 234983 : init_expression = ce.value;
8402 : 234983 : c_finish_expr_stmt (loc, init_expression);
8403 : 234983 : c_parser_skip_until_found (parser, CPP_SEMICOLON,
8404 : : "expected %<;%>");
8405 : : }
8406 : : }
8407 : : }
8408 : : /* Parse the loop condition. In the case of a foreach
8409 : : statement, there is no loop condition. */
8410 : 263325 : gcc_assert (!parser->objc_could_be_foreach_context);
8411 : 263325 : if (!is_foreach_statement)
8412 : : {
8413 : 263325 : if (c_parser_next_token_is (parser, CPP_SEMICOLON))
8414 : : {
8415 : 2876 : if (ivdep)
8416 : : {
8417 : 1 : c_parser_error (parser, "missing loop condition in loop "
8418 : : "with %<GCC ivdep%> pragma");
8419 : 1 : cond = error_mark_node;
8420 : : }
8421 : 2875 : else if (unroll)
8422 : : {
8423 : 0 : c_parser_error (parser, "missing loop condition in loop "
8424 : : "with %<GCC unroll%> pragma");
8425 : 0 : cond = error_mark_node;
8426 : : }
8427 : : else
8428 : : {
8429 : 2875 : c_parser_consume_token (parser);
8430 : 2875 : cond = NULL_TREE;
8431 : : }
8432 : : }
8433 : : else
8434 : : {
8435 : 260449 : cond = c_parser_condition (parser);
8436 : 260449 : c_parser_skip_until_found (parser, CPP_SEMICOLON,
8437 : : "expected %<;%>");
8438 : : }
8439 : 263325 : if (ivdep && cond != error_mark_node)
8440 : 122 : cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
8441 : : build_int_cst (integer_type_node,
8442 : 122 : annot_expr_ivdep_kind),
8443 : : integer_zero_node);
8444 : 263325 : if (unroll && cond != error_mark_node)
8445 : 222 : cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
8446 : : build_int_cst (integer_type_node,
8447 : 222 : annot_expr_unroll_kind),
8448 : : build_int_cst (integer_type_node, unroll));
8449 : 263325 : if (novector && cond && cond != error_mark_node)
8450 : 2294 : cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
8451 : : build_int_cst (integer_type_node,
8452 : 2294 : annot_expr_no_vector_kind),
8453 : : integer_zero_node);
8454 : : }
8455 : : /* Parse the increment expression (the third expression in a
8456 : : for-statement). In the case of a foreach-statement, this is
8457 : : the expression that follows the 'in'. */
8458 : 263325 : loc = c_parser_peek_token (parser)->location;
8459 : 263325 : if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
8460 : : {
8461 : 3990 : if (is_foreach_statement)
8462 : : {
8463 : 0 : c_parser_error (parser,
8464 : : "missing collection in fast enumeration");
8465 : 0 : collection_expression = error_mark_node;
8466 : : }
8467 : : else
8468 : 3990 : incr = c_process_expr_stmt (loc, NULL_TREE);
8469 : : }
8470 : : else
8471 : : {
8472 : 259335 : if (is_foreach_statement)
8473 : 0 : collection_expression
8474 : 0 : = c_fully_fold (c_parser_expression (parser).value, false, NULL);
8475 : : else
8476 : : {
8477 : 259335 : struct c_expr ce = c_parser_expression (parser);
8478 : 259335 : ce = convert_lvalue_to_rvalue (loc, ce, true, false);
8479 : 259335 : incr = c_process_expr_stmt (loc, ce.value);
8480 : : }
8481 : : }
8482 : 263325 : parens.skip_until_found_close (parser);
8483 : : }
8484 : 263326 : save_in_statement = in_statement;
8485 : 263326 : if (is_foreach_statement)
8486 : : {
8487 : 0 : in_statement = IN_OBJC_FOREACH;
8488 : 0 : save_objc_foreach_break_label = objc_foreach_break_label;
8489 : 0 : save_objc_foreach_continue_label = objc_foreach_continue_label;
8490 : 0 : objc_foreach_break_label = create_artificial_label (loc);
8491 : 0 : objc_foreach_continue_label = create_artificial_label (loc);
8492 : : }
8493 : : else
8494 : 263326 : in_statement = IN_ITERATION_STMT;
8495 : :
8496 : 263326 : token_indent_info body_tinfo
8497 : 263326 : = get_token_indent_info (c_parser_peek_token (parser));
8498 : :
8499 : 263326 : location_t loc_after_labels;
8500 : 263326 : bool open_brace = c_parser_next_token_is (parser, CPP_OPEN_BRACE);
8501 : 263326 : body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
8502 : :
8503 : 263326 : if (is_foreach_statement)
8504 : 0 : objc_finish_foreach_loop (for_loc, object_expression,
8505 : : collection_expression, body,
8506 : : objc_foreach_break_label,
8507 : : objc_foreach_continue_label);
8508 : : else
8509 : 263326 : add_stmt (build_stmt (for_loc, FOR_STMT, NULL_TREE, cond, incr,
8510 : : body, NULL_TREE));
8511 : 263326 : add_stmt (c_end_compound_stmt (for_loc, block,
8512 : 263326 : flag_isoc99 || c_dialect_objc ()));
8513 : 263326 : c_parser_maybe_reclassify_token (parser);
8514 : :
8515 : 263326 : token_indent_info next_tinfo
8516 : 263326 : = get_token_indent_info (c_parser_peek_token (parser));
8517 : 263326 : warn_for_misleading_indentation (for_tinfo, body_tinfo, next_tinfo);
8518 : :
8519 : 263326 : if (next_tinfo.type != CPP_SEMICOLON && !open_brace)
8520 : 162098 : warn_for_multistatement_macros (loc_after_labels, next_tinfo.location,
8521 : : for_tinfo.location, RID_FOR);
8522 : :
8523 : 263326 : in_statement = save_in_statement;
8524 : 263326 : if (is_foreach_statement)
8525 : : {
8526 : 0 : objc_foreach_break_label = save_objc_foreach_break_label;
8527 : 0 : objc_foreach_continue_label = save_objc_foreach_continue_label;
8528 : : }
8529 : 263326 : }
8530 : :
8531 : : /* Parse an asm statement, a GNU extension. This is a full-blown asm
8532 : : statement with inputs, outputs, clobbers, and volatile, inline, and goto
8533 : : tags allowed.
8534 : :
8535 : : asm-qualifier:
8536 : : volatile
8537 : : inline
8538 : : goto
8539 : :
8540 : : asm-qualifier-list:
8541 : : asm-qualifier-list asm-qualifier
8542 : : asm-qualifier
8543 : :
8544 : : asm-statement:
8545 : : asm asm-qualifier-list[opt] ( asm-argument ) ;
8546 : :
8547 : : asm-argument:
8548 : : asm-string-literal
8549 : : asm-string-literal : asm-operands[opt]
8550 : : asm-string-literal : asm-operands[opt] : asm-operands[opt]
8551 : : asm-string-literal : asm-operands[opt] : asm-operands[opt] \
8552 : : : asm-clobbers[opt]
8553 : : asm-string-literal : : asm-operands[opt] : asm-clobbers[opt] \
8554 : : : asm-goto-operands
8555 : :
8556 : : The form with asm-goto-operands is valid if and only if the
8557 : : asm-qualifier-list contains goto, and is the only allowed form in that case.
8558 : : Duplicate asm-qualifiers are not allowed.
8559 : :
8560 : : The :: token is considered equivalent to two consecutive : tokens. */
8561 : :
8562 : : static tree
8563 : 198423 : c_parser_asm_statement (c_parser *parser)
8564 : : {
8565 : 198423 : tree str, outputs, inputs, clobbers, labels, ret;
8566 : 198423 : bool simple;
8567 : 198423 : location_t asm_loc = c_parser_peek_token (parser)->location;
8568 : 198423 : int section, nsections;
8569 : :
8570 : 198423 : gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
8571 : 198423 : c_parser_consume_token (parser);
8572 : :
8573 : : /* Handle the asm-qualifier-list. */
8574 : 198423 : location_t volatile_loc = UNKNOWN_LOCATION;
8575 : 198423 : location_t inline_loc = UNKNOWN_LOCATION;
8576 : 198423 : location_t goto_loc = UNKNOWN_LOCATION;
8577 : 358137 : for (;;)
8578 : : {
8579 : 358137 : c_token *token = c_parser_peek_token (parser);
8580 : 358137 : location_t loc = token->location;
8581 : 358137 : switch (token->keyword)
8582 : : {
8583 : 159273 : case RID_VOLATILE:
8584 : 159273 : if (volatile_loc)
8585 : : {
8586 : 6 : error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
8587 : 6 : inform (volatile_loc, "first seen here");
8588 : : }
8589 : : else
8590 : : volatile_loc = loc;
8591 : 159273 : c_parser_consume_token (parser);
8592 : 159273 : continue;
8593 : :
8594 : 38 : case RID_INLINE:
8595 : 38 : if (inline_loc)
8596 : : {
8597 : 6 : error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
8598 : 6 : inform (inline_loc, "first seen here");
8599 : : }
8600 : : else
8601 : : inline_loc = loc;
8602 : 38 : c_parser_consume_token (parser);
8603 : 38 : continue;
8604 : :
8605 : 401 : case RID_GOTO:
8606 : 401 : if (goto_loc)
8607 : : {
8608 : 6 : error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
8609 : 6 : inform (goto_loc, "first seen here");
8610 : : }
8611 : : else
8612 : : goto_loc = loc;
8613 : 401 : c_parser_consume_token (parser);
8614 : 401 : continue;
8615 : :
8616 : 2 : case RID_CONST:
8617 : 2 : case RID_RESTRICT:
8618 : 2 : error_at (loc, "%qE is not a valid %<asm%> qualifier", token->value);
8619 : 2 : c_parser_consume_token (parser);
8620 : 2 : continue;
8621 : :
8622 : 198423 : default:
8623 : 198423 : break;
8624 : : }
8625 : 198423 : break;
8626 : : }
8627 : :
8628 : 198423 : bool is_volatile = (volatile_loc != UNKNOWN_LOCATION);
8629 : 198423 : bool is_inline = (inline_loc != UNKNOWN_LOCATION);
8630 : 198423 : bool is_goto = (goto_loc != UNKNOWN_LOCATION);
8631 : :
8632 : 198423 : ret = NULL;
8633 : :
8634 : 198423 : matching_parens parens;
8635 : 198423 : if (!parens.require_open (parser))
8636 : 0 : goto error;
8637 : :
8638 : 198423 : str = c_parser_asm_string_literal (parser);
8639 : 198423 : if (str == NULL_TREE)
8640 : 12 : goto error_close_paren;
8641 : :
8642 : 198411 : simple = true;
8643 : 198411 : outputs = NULL_TREE;
8644 : 198411 : inputs = NULL_TREE;
8645 : 198411 : clobbers = NULL_TREE;
8646 : 198411 : labels = NULL_TREE;
8647 : :
8648 : 198411 : if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN) && !is_goto)
8649 : 1730 : goto done_asm;
8650 : :
8651 : : /* Parse each colon-delimited section of operands. */
8652 : 196681 : nsections = 3 + is_goto;
8653 : 503431 : for (section = 0; section < nsections; ++section)
8654 : : {
8655 : 503046 : if (c_parser_next_token_is (parser, CPP_SCOPE))
8656 : : {
8657 : 34995 : ++section;
8658 : 34995 : if (section == nsections)
8659 : : {
8660 : 5 : c_parser_error (parser, "expected %<)%>");
8661 : 5 : goto error_close_paren;
8662 : : }
8663 : 34990 : c_parser_consume_token (parser);
8664 : : }
8665 : 934746 : else if (!c_parser_require (parser, CPP_COLON,
8666 : : is_goto
8667 : : ? G_("expected %<:%>")
8668 : : : G_("expected %<:%> or %<)%>"),
8669 : : UNKNOWN_LOCATION, is_goto))
8670 : 7 : goto error_close_paren;
8671 : :
8672 : : /* Once past any colon, we're no longer a simple asm. */
8673 : 503034 : simple = false;
8674 : :
8675 : 503034 : if ((!c_parser_next_token_is (parser, CPP_COLON)
8676 : 407576 : && !c_parser_next_token_is (parser, CPP_SCOPE)
8677 : 407527 : && !c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
8678 : 507833 : || section == 3)
8679 : 402778 : switch (section)
8680 : : {
8681 : 127179 : case 0:
8682 : 127179 : outputs = c_parser_asm_operands (parser);
8683 : 127179 : break;
8684 : 126600 : case 1:
8685 : 126600 : inputs = c_parser_asm_operands (parser);
8686 : 126600 : break;
8687 : 148614 : case 2:
8688 : 148614 : clobbers = c_parser_asm_clobbers (parser);
8689 : 148614 : break;
8690 : 385 : case 3:
8691 : 385 : labels = c_parser_asm_goto_operands (parser);
8692 : 385 : break;
8693 : 0 : default:
8694 : 0 : gcc_unreachable ();
8695 : : }
8696 : :
8697 : 503034 : if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN) && !is_goto)
8698 : 196284 : goto done_asm;
8699 : : }
8700 : :
8701 : 385 : done_asm:
8702 : 198399 : if (!parens.require_close (parser))
8703 : : {
8704 : 0 : c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8705 : 0 : goto error;
8706 : : }
8707 : :
8708 : 198399 : if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
8709 : 0 : c_parser_skip_to_end_of_block_or_statement (parser);
8710 : :
8711 : 198399 : ret = build_asm_stmt (is_volatile,
8712 : : build_asm_expr (asm_loc, str, outputs, inputs,
8713 : : clobbers, labels, simple, is_inline));
8714 : :
8715 : 198423 : error:
8716 : 198423 : return ret;
8717 : :
8718 : 24 : error_close_paren:
8719 : 24 : c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8720 : 24 : goto error;
8721 : : }
8722 : :
8723 : : /* Parse asm operands, a GNU extension.
8724 : :
8725 : : asm-operands:
8726 : : asm-operand
8727 : : asm-operands , asm-operand
8728 : :
8729 : : asm-operand:
8730 : : asm-string-literal ( expression )
8731 : : [ identifier ] asm-string-literal ( expression )
8732 : : */
8733 : :
8734 : : static tree
8735 : 253779 : c_parser_asm_operands (c_parser *parser)
8736 : : {
8737 : 253779 : tree list = NULL_TREE;
8738 : 1116683 : while (true)
8739 : : {
8740 : 685231 : tree name, str;
8741 : 685231 : struct c_expr expr;
8742 : 685231 : if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
8743 : : {
8744 : 472 : c_parser_consume_token (parser);
8745 : 472 : if (c_parser_next_token_is (parser, CPP_NAME))
8746 : : {
8747 : 472 : tree id = c_parser_peek_token (parser)->value;
8748 : 472 : c_parser_consume_token (parser);
8749 : 472 : name = build_string (IDENTIFIER_LENGTH (id),
8750 : 472 : IDENTIFIER_POINTER (id));
8751 : : }
8752 : : else
8753 : : {
8754 : 0 : c_parser_error (parser, "expected identifier");
8755 : 0 : c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL);
8756 : 0 : return NULL_TREE;
8757 : : }
8758 : 472 : c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
8759 : : "expected %<]%>");
8760 : : }
8761 : : else
8762 : : name = NULL_TREE;
8763 : 685231 : str = c_parser_asm_string_literal (parser);
8764 : 685231 : if (str == NULL_TREE)
8765 : : return NULL_TREE;
8766 : 685231 : matching_parens parens;
8767 : 685231 : if (!parens.require_open (parser))
8768 : : return NULL_TREE;
8769 : 685231 : expr = c_parser_expression (parser);
8770 : 685231 : mark_exp_read (expr.value);
8771 : 685231 : if (!parens.require_close (parser))
8772 : : {
8773 : 0 : c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8774 : 0 : return NULL_TREE;
8775 : : }
8776 : 685231 : list = chainon (list, build_tree_list (build_tree_list (name, str),
8777 : : expr.value));
8778 : 685231 : if (c_parser_next_token_is (parser, CPP_COMMA))
8779 : 431452 : c_parser_consume_token (parser);
8780 : : else
8781 : : break;
8782 : 431452 : }
8783 : 253779 : return list;
8784 : : }
8785 : :
8786 : : /* Parse asm clobbers, a GNU extension.
8787 : :
8788 : : asm-clobbers:
8789 : : asm-string-literal
8790 : : asm-clobbers , asm-string-literal
8791 : : */
8792 : :
8793 : : static tree
8794 : 148614 : c_parser_asm_clobbers (c_parser *parser)
8795 : : {
8796 : 148614 : tree list = NULL_TREE;
8797 : 202538 : while (true)
8798 : : {
8799 : 175576 : tree str = c_parser_asm_string_literal (parser);
8800 : 175576 : if (str)
8801 : 175576 : list = tree_cons (NULL_TREE, str, list);
8802 : : else
8803 : : return NULL_TREE;
8804 : 175576 : if (c_parser_next_token_is (parser, CPP_COMMA))
8805 : 26962 : c_parser_consume_token (parser);
8806 : : else
8807 : : break;
8808 : 26962 : }
8809 : : return list;
8810 : : }
8811 : :
8812 : : /* Parse asm goto labels, a GNU extension.
8813 : :
8814 : : asm-goto-operands:
8815 : : identifier
8816 : : asm-goto-operands , identifier
8817 : : */
8818 : :
8819 : : static tree
8820 : 385 : c_parser_asm_goto_operands (c_parser *parser)
8821 : : {
8822 : 385 : tree list = NULL_TREE;
8823 : 969 : while (true)
8824 : : {
8825 : 677 : tree name, label;
8826 : :
8827 : 677 : if (c_parser_next_token_is (parser, CPP_NAME))
8828 : : {
8829 : 676 : c_token *tok = c_parser_peek_token (parser);
8830 : 676 : name = tok->value;
8831 : 676 : label = lookup_label_for_goto (tok->location, name);
8832 : 676 : c_parser_consume_token (parser);
8833 : 676 : TREE_USED (label) = 1;
8834 : : }
8835 : : else
8836 : : {
8837 : 1 : c_parser_error (parser, "expected identifier");
8838 : 1 : return NULL_TREE;
8839 : : }
8840 : :
8841 : 676 : name = build_string (IDENTIFIER_LENGTH (name),
8842 : 676 : IDENTIFIER_POINTER (name));
8843 : 676 : list = tree_cons (name, label, list);
8844 : 676 : if (c_parser_next_token_is (parser, CPP_COMMA))
8845 : 292 : c_parser_consume_token (parser);
8846 : : else
8847 : 384 : return nreverse (list);
8848 : 292 : }
8849 : : }
8850 : :
8851 : : /* Parse a possibly concatenated sequence of string literals.
8852 : : TRANSLATE says whether to translate them to the execution character
8853 : : set; WIDE_OK says whether any kind of prefixed string literal is
8854 : : permitted in this context. This code is based on that in
8855 : : lex_string. */
8856 : :
8857 : : struct c_expr
8858 : 3399286 : c_parser_string_literal (c_parser *parser, bool translate, bool wide_ok)
8859 : : {
8860 : 3399286 : struct c_expr ret;
8861 : 3399286 : size_t count;
8862 : 3399286 : struct obstack str_ob;
8863 : 3399286 : struct obstack loc_ob;
8864 : 3399286 : cpp_string str, istr, *strs;
8865 : 3399286 : c_token *tok;
8866 : 3399286 : location_t loc, last_tok_loc;
8867 : 3399286 : enum cpp_ttype type;
8868 : 3399286 : tree value, string_tree;
8869 : :
8870 : 3399286 : tok = c_parser_peek_token (parser);
8871 : 3399286 : loc = tok->location;
8872 : 3399286 : last_tok_loc = linemap_resolve_location (line_table, loc,
8873 : : LRK_MACRO_DEFINITION_LOCATION,
8874 : : NULL);
8875 : 3399286 : type = tok->type;
8876 : 3399286 : switch (type)
8877 : : {
8878 : 3399269 : case CPP_STRING:
8879 : 3399269 : case CPP_WSTRING:
8880 : 3399269 : case CPP_STRING16:
8881 : 3399269 : case CPP_STRING32:
8882 : 3399269 : case CPP_UTF8STRING:
8883 : 3399269 : string_tree = tok->value;
8884 : 3399269 : break;
8885 : :
8886 : 17 : default:
8887 : 17 : c_parser_error (parser, "expected string literal");
8888 : 17 : ret.set_error ();
8889 : 17 : ret.value = NULL_TREE;
8890 : 17 : ret.original_code = ERROR_MARK;
8891 : 17 : ret.original_type = NULL_TREE;
8892 : 17 : return ret;
8893 : : }
8894 : :
8895 : : /* Try to avoid the overhead of creating and destroying an obstack
8896 : : for the common case of just one string. */
8897 : 3399269 : switch (c_parser_peek_2nd_token (parser)->type)
8898 : : {
8899 : 2702599 : default:
8900 : 2702599 : c_parser_consume_token (parser);
8901 : 2702599 : str.text = (const unsigned char *) TREE_STRING_POINTER (string_tree);
8902 : 2702599 : str.len = TREE_STRING_LENGTH (string_tree);
8903 : 2702599 : count = 1;
8904 : 2702599 : strs = &str;
8905 : 2702599 : break;
8906 : :
8907 : 696670 : case CPP_STRING:
8908 : 696670 : case CPP_WSTRING:
8909 : 696670 : case CPP_STRING16:
8910 : 696670 : case CPP_STRING32:
8911 : 696670 : case CPP_UTF8STRING:
8912 : 696670 : gcc_obstack_init (&str_ob);
8913 : 696670 : gcc_obstack_init (&loc_ob);
8914 : 696670 : count = 0;
8915 : 27503425 : do
8916 : : {
8917 : 27503425 : c_parser_consume_token (parser);
8918 : 27503425 : count++;
8919 : 27503425 : str.text = (const unsigned char *) TREE_STRING_POINTER (string_tree);
8920 : 27503425 : str.len = TREE_STRING_LENGTH (string_tree);
8921 : 27503425 : if (type != tok->type)
8922 : : {
8923 : 663 : if (type == CPP_STRING)
8924 : 29 : type = tok->type;
8925 : 634 : else if (tok->type != CPP_STRING)
8926 : 66 : error ("unsupported non-standard concatenation "
8927 : : "of string literals");
8928 : : }
8929 : 27503425 : obstack_grow (&str_ob, &str, sizeof (cpp_string));
8930 : 27503425 : obstack_grow (&loc_ob, &last_tok_loc, sizeof (location_t));
8931 : 27503425 : tok = c_parser_peek_token (parser);
8932 : 27503425 : string_tree = tok->value;
8933 : 27503425 : last_tok_loc
8934 : 27503425 : = linemap_resolve_location (line_table, tok->location,
8935 : : LRK_MACRO_DEFINITION_LOCATION, NULL);
8936 : : }
8937 : 27503425 : while (tok->type == CPP_STRING
8938 : : || tok->type == CPP_WSTRING
8939 : : || tok->type == CPP_STRING16
8940 : : || tok->type == CPP_STRING32
8941 : 27503425 : || tok->type == CPP_UTF8STRING);
8942 : 696670 : strs = (cpp_string *) obstack_finish (&str_ob);
8943 : : }
8944 : :
8945 : 3399269 : if (count > 1 && !in_system_header_at (input_location))
8946 : 559003 : warning (OPT_Wtraditional,
8947 : : "traditional C rejects string constant concatenation");
8948 : :
8949 : 3399269 : if ((type == CPP_STRING || wide_ok)
8950 : 6798528 : && ((translate
8951 : 3399259 : ? cpp_interpret_string : cpp_interpret_string_notranslate)
8952 : 3399259 : (parse_in, strs, count, &istr, type)))
8953 : : {
8954 : 3399259 : value = build_string (istr.len, (const char *) istr.text);
8955 : 3399259 : free (CONST_CAST (unsigned char *, istr.text));
8956 : 3399259 : if (count > 1)
8957 : : {
8958 : 696670 : location_t *locs = (location_t *) obstack_finish (&loc_ob);
8959 : 696670 : gcc_assert (g_string_concat_db);
8960 : 696670 : g_string_concat_db->record_string_concatenation (count, locs);
8961 : : }
8962 : : }
8963 : : else
8964 : : {
8965 : 10 : if (type != CPP_STRING && !wide_ok)
8966 : : {
8967 : 10 : error_at (loc, "a wide string is invalid in this context");
8968 : 10 : type = CPP_STRING;
8969 : : }
8970 : : /* Callers cannot generally handle error_mark_node in this
8971 : : context, so return the empty string instead. An error has
8972 : : been issued, either above or from cpp_interpret_string. */
8973 : 10 : switch (type)
8974 : : {
8975 : 10 : default:
8976 : 10 : case CPP_STRING:
8977 : 10 : case CPP_UTF8STRING:
8978 : 10 : if (type == CPP_UTF8STRING && flag_char8_t)
8979 : : {
8980 : 0 : value = build_string (TYPE_PRECISION (char8_type_node)
8981 : 0 : / TYPE_PRECISION (char_type_node),
8982 : : ""); /* char8_t is 8 bits */
8983 : : }
8984 : : else
8985 : 10 : value = build_string (1, "");
8986 : : break;
8987 : 0 : case CPP_STRING16:
8988 : 0 : value = build_string (TYPE_PRECISION (char16_type_node)
8989 : 0 : / TYPE_PRECISION (char_type_node),
8990 : : "\0"); /* char16_t is 16 bits */
8991 : 0 : break;
8992 : 0 : case CPP_STRING32:
8993 : 0 : value = build_string (TYPE_PRECISION (char32_type_node)
8994 : 0 : / TYPE_PRECISION (char_type_node),
8995 : : "\0\0\0"); /* char32_t is 32 bits */
8996 : 0 : break;
8997 : 0 : case CPP_WSTRING:
8998 : 0 : value = build_string (TYPE_PRECISION (wchar_type_node)
8999 : 0 : / TYPE_PRECISION (char_type_node),
9000 : : "\0\0\0"); /* widest supported wchar_t
9001 : : is 32 bits */
9002 : 0 : break;
9003 : : }
9004 : : }
9005 : :
9006 : 3399269 : switch (type)
9007 : : {
9008 : 3397716 : default:
9009 : 3397716 : case CPP_STRING:
9010 : 3397716 : TREE_TYPE (value) = char_array_type_node;
9011 : 3397716 : break;
9012 : 243 : case CPP_UTF8STRING:
9013 : 243 : if (flag_char8_t)
9014 : 60 : TREE_TYPE (value) = char8_array_type_node;
9015 : : else
9016 : 183 : TREE_TYPE (value) = char_array_type_node;
9017 : : break;
9018 : 207 : case CPP_STRING16:
9019 : 207 : TREE_TYPE (value) = char16_array_type_node;
9020 : 207 : break;
9021 : 603 : case CPP_STRING32:
9022 : 603 : TREE_TYPE (value) = char32_array_type_node;
9023 : 603 : break;
9024 : 500 : case CPP_WSTRING:
9025 : 500 : TREE_TYPE (value) = wchar_array_type_node;
9026 : : }
9027 : 3399269 : value = fix_string_type (value);
9028 : :
9029 : 3399269 : if (count > 1)
9030 : : {
9031 : 696670 : obstack_free (&str_ob, 0);
9032 : 696670 : obstack_free (&loc_ob, 0);
9033 : : }
9034 : :
9035 : 3399269 : ret.value = value;
9036 : 3399269 : ret.original_code = STRING_CST;
9037 : 3399269 : ret.original_type = NULL_TREE;
9038 : 3399269 : set_c_expr_source_range (&ret, get_range_from_loc (line_table, loc));
9039 : 3399269 : ret.m_decimal = 0;
9040 : 3399269 : parser->seen_string_literal = true;
9041 : 3399269 : return ret;
9042 : : }
9043 : :
9044 : : /* Parse an expression other than a compound expression; that is, an
9045 : : assignment expression (C90 6.3.16, C99 6.5.16, C11 6.5.16). If
9046 : : AFTER is not NULL then it is an Objective-C message expression which
9047 : : is the primary-expression starting the expression as an initializer.
9048 : :
9049 : : assignment-expression:
9050 : : conditional-expression
9051 : : unary-expression assignment-operator assignment-expression
9052 : :
9053 : : assignment-operator: one of
9054 : : = *= /= %= += -= <<= >>= &= ^= |=
9055 : :
9056 : : In GNU C we accept any conditional expression on the LHS and
9057 : : diagnose the invalid lvalue rather than producing a syntax
9058 : : error. */
9059 : :
9060 : : static struct c_expr
9061 : 204654474 : c_parser_expr_no_commas (c_parser *parser, struct c_expr *after,
9062 : : tree omp_atomic_lhs)
9063 : : {
9064 : 204654474 : struct c_expr lhs, rhs, ret;
9065 : 204654474 : enum tree_code code;
9066 : 204654474 : location_t op_location, exp_location;
9067 : 204654474 : bool save_in_omp_for = c_in_omp_for;
9068 : 204654474 : c_in_omp_for = false;
9069 : 204654474 : gcc_assert (!after || c_dialect_objc ());
9070 : 204654474 : lhs = c_parser_conditional_expression (parser, after, omp_atomic_lhs);
9071 : 204654472 : op_location = c_parser_peek_token (parser)->location;
9072 : 204654472 : switch (c_parser_peek_token (parser)->type)
9073 : : {
9074 : : case CPP_EQ:
9075 : : code = NOP_EXPR;
9076 : : break;
9077 : 11770 : case CPP_MULT_EQ:
9078 : 11770 : code = MULT_EXPR;
9079 : 11770 : break;
9080 : 8532 : case CPP_DIV_EQ:
9081 : 8532 : code = TRUNC_DIV_EXPR;
9082 : 8532 : break;
9083 : 2222 : case CPP_MOD_EQ:
9084 : 2222 : code = TRUNC_MOD_EXPR;
9085 : 2222 : break;
9086 : 85282 : case CPP_PLUS_EQ:
9087 : 85282 : code = PLUS_EXPR;
9088 : 85282 : break;
9089 : 27313 : case CPP_MINUS_EQ:
9090 : 27313 : code = MINUS_EXPR;
9091 : 27313 : break;
9092 : 3811 : case CPP_LSHIFT_EQ:
9093 : 3811 : code = LSHIFT_EXPR;
9094 : 3811 : break;
9095 : 3042 : case CPP_RSHIFT_EQ:
9096 : 3042 : code = RSHIFT_EXPR;
9097 : 3042 : break;
9098 : 24140 : case CPP_AND_EQ:
9099 : 24140 : code = BIT_AND_EXPR;
9100 : 24140 : break;
9101 : 2815 : case CPP_XOR_EQ:
9102 : 2815 : code = BIT_XOR_EXPR;
9103 : 2815 : break;
9104 : 19486 : case CPP_OR_EQ:
9105 : 19486 : code = BIT_IOR_EXPR;
9106 : 19486 : break;
9107 : 201878508 : default:
9108 : 201878508 : c_in_omp_for = save_in_omp_for;
9109 : 201878508 : return lhs;
9110 : : }
9111 : 2775964 : c_parser_consume_token (parser);
9112 : 2775964 : exp_location = c_parser_peek_token (parser)->location;
9113 : 2775964 : rhs = c_parser_expr_no_commas (parser, NULL);
9114 : 2775964 : rhs = convert_lvalue_to_rvalue (exp_location, rhs, true, true);
9115 : :
9116 : 2775964 : ret.value = build_modify_expr (op_location, lhs.value, lhs.original_type,
9117 : : code, exp_location, rhs.value,
9118 : : rhs.original_type);
9119 : 2775964 : ret.m_decimal = 0;
9120 : 2775964 : set_c_expr_source_range (&ret, lhs.get_start (), rhs.get_finish ());
9121 : 2775964 : if (code == NOP_EXPR)
9122 : 2587551 : ret.original_code = MODIFY_EXPR;
9123 : : else
9124 : : {
9125 : 188413 : suppress_warning (ret.value, OPT_Wparentheses);
9126 : 188413 : ret.original_code = ERROR_MARK;
9127 : : }
9128 : 2775964 : ret.original_type = NULL;
9129 : 2775964 : c_in_omp_for = save_in_omp_for;
9130 : 2775964 : return ret;
9131 : : }
9132 : :
9133 : : /* Parse a conditional expression (C90 6.3.15, C99 6.5.15, C11 6.5.15). If
9134 : : AFTER is not NULL then it is an Objective-C message expression which is
9135 : : the primary-expression starting the expression as an initializer.
9136 : :
9137 : : conditional-expression:
9138 : : logical-OR-expression
9139 : : logical-OR-expression ? expression : conditional-expression
9140 : :
9141 : : GNU extensions:
9142 : :
9143 : : conditional-expression:
9144 : : logical-OR-expression ? : conditional-expression
9145 : : */
9146 : :
9147 : : static struct c_expr
9148 : 205012272 : c_parser_conditional_expression (c_parser *parser, struct c_expr *after,
9149 : : tree omp_atomic_lhs)
9150 : : {
9151 : 205012272 : struct c_expr cond, exp1, exp2, ret;
9152 : 205012272 : location_t start, cond_loc, colon_loc;
9153 : 205012272 : bool save_c_omp_array_section_p = c_omp_array_section_p;
9154 : :
9155 : 205012272 : gcc_assert (!after || c_dialect_objc ());
9156 : :
9157 : 205012272 : cond = c_parser_binary_expression (parser, after, omp_atomic_lhs);
9158 : :
9159 : 205012270 : if (c_parser_next_token_is_not (parser, CPP_QUERY))
9160 : 204654504 : return cond;
9161 : 357766 : c_omp_array_section_p = false;
9162 : 357766 : if (cond.value != error_mark_node)
9163 : 357755 : start = cond.get_start ();
9164 : : else
9165 : : start = UNKNOWN_LOCATION;
9166 : 357766 : cond_loc = c_parser_peek_token (parser)->location;
9167 : 357766 : cond = convert_lvalue_to_rvalue (cond_loc, cond, true, true);
9168 : 357766 : c_parser_consume_token (parser);
9169 : 357766 : if (c_parser_next_token_is (parser, CPP_COLON))
9170 : : {
9171 : 705 : tree eptype = NULL_TREE;
9172 : :
9173 : 705 : location_t middle_loc = c_parser_peek_token (parser)->location;
9174 : 705 : pedwarn (middle_loc, OPT_Wpedantic,
9175 : : "ISO C forbids omitting the middle term of a %<?:%> expression");
9176 : 705 : if (TREE_CODE (cond.value) == EXCESS_PRECISION_EXPR)
9177 : : {
9178 : 1 : eptype = TREE_TYPE (cond.value);
9179 : 1 : cond.value = TREE_OPERAND (cond.value, 0);
9180 : : }
9181 : 705 : tree e = cond.value;
9182 : 708 : while (TREE_CODE (e) == COMPOUND_EXPR)
9183 : 3 : e = TREE_OPERAND (e, 1);
9184 : 705 : warn_for_omitted_condop (middle_loc, e);
9185 : : /* Make sure first operand is calculated only once. */
9186 : 705 : exp1.value = save_expr (default_conversion (cond.value));
9187 : 705 : if (eptype)
9188 : 1 : exp1.value = build1 (EXCESS_PRECISION_EXPR, eptype, exp1.value);
9189 : 705 : exp1.original_type = NULL;
9190 : 705 : exp1.src_range = cond.src_range;
9191 : 705 : cond.value = c_objc_common_truthvalue_conversion (cond_loc, exp1.value);
9192 : 705 : c_inhibit_evaluation_warnings += cond.value == truthvalue_true_node;
9193 : : }
9194 : : else
9195 : : {
9196 : 357061 : cond.value
9197 : 357061 : = c_objc_common_truthvalue_conversion
9198 : 357061 : (cond_loc, default_conversion (cond.value));
9199 : 357061 : c_inhibit_evaluation_warnings += cond.value == truthvalue_false_node;
9200 : 357061 : exp1 = c_parser_expression_conv (parser);
9201 : 357061 : mark_exp_read (exp1.value);
9202 : 357061 : c_inhibit_evaluation_warnings +=
9203 : 357061 : ((cond.value == truthvalue_true_node)
9204 : 357061 : - (cond.value == truthvalue_false_node));
9205 : : }
9206 : :
9207 : 357766 : colon_loc = c_parser_peek_token (parser)->location;
9208 : 357766 : if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
9209 : : {
9210 : 9 : c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node;
9211 : 9 : ret.set_error ();
9212 : 9 : ret.original_code = ERROR_MARK;
9213 : 9 : ret.original_type = NULL;
9214 : 9 : c_omp_array_section_p = save_c_omp_array_section_p;
9215 : 9 : return ret;
9216 : : }
9217 : 357757 : {
9218 : 357757 : location_t exp2_loc = c_parser_peek_token (parser)->location;
9219 : 357757 : exp2 = c_parser_conditional_expression (parser, NULL, NULL_TREE);
9220 : 357757 : exp2 = convert_lvalue_to_rvalue (exp2_loc, exp2, true, true);
9221 : : }
9222 : 357757 : c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node;
9223 : 357757 : location_t loc1 = make_location (exp1.get_start (), exp1.src_range);
9224 : 357757 : location_t loc2 = make_location (exp2.get_start (), exp2.src_range);
9225 : 357757 : if (UNLIKELY (omp_atomic_lhs != NULL)
9226 : 69 : && (TREE_CODE (cond.value) == GT_EXPR
9227 : : || TREE_CODE (cond.value) == LT_EXPR
9228 : : || TREE_CODE (cond.value) == EQ_EXPR)
9229 : 63 : && c_tree_equal (exp2.value, omp_atomic_lhs)
9230 : 357815 : && (c_tree_equal (TREE_OPERAND (cond.value, 0), omp_atomic_lhs)
9231 : 19 : || c_tree_equal (TREE_OPERAND (cond.value, 1), omp_atomic_lhs)))
9232 : 55 : ret.value = build3_loc (colon_loc, COND_EXPR, TREE_TYPE (omp_atomic_lhs),
9233 : : cond.value, exp1.value, exp2.value);
9234 : : else
9235 : 357702 : ret.value
9236 : 357702 : = build_conditional_expr (colon_loc, cond.value,
9237 : 357702 : cond.original_code == C_MAYBE_CONST_EXPR,
9238 : : exp1.value, exp1.original_type, loc1,
9239 : : exp2.value, exp2.original_type, loc2);
9240 : 357757 : ret.original_code = ERROR_MARK;
9241 : 357757 : if (exp1.value == error_mark_node || exp2.value == error_mark_node)
9242 : 15 : ret.original_type = NULL;
9243 : : else
9244 : : {
9245 : 357742 : tree t1, t2;
9246 : :
9247 : : /* If both sides are enum type, the default conversion will have
9248 : : made the type of the result be an integer type. We want to
9249 : : remember the enum types we started with. */
9250 : 357742 : t1 = exp1.original_type ? exp1.original_type : TREE_TYPE (exp1.value);
9251 : 357742 : t2 = exp2.original_type ? exp2.original_type : TREE_TYPE (exp2.value);
9252 : 357742 : ret.original_type = ((t1 != error_mark_node
9253 : 357742 : && t2 != error_mark_node
9254 : 357742 : && (TYPE_MAIN_VARIANT (t1)
9255 : 357742 : == TYPE_MAIN_VARIANT (t2)))
9256 : 357742 : ? t1
9257 : : : NULL);
9258 : : }
9259 : 357757 : set_c_expr_source_range (&ret, start, exp2.get_finish ());
9260 : 357757 : ret.m_decimal = 0;
9261 : 357757 : c_omp_array_section_p = save_c_omp_array_section_p;
9262 : 357757 : return ret;
9263 : : }
9264 : :
9265 : : /* Parse a binary expression; that is, a logical-OR-expression (C90
9266 : : 6.3.5-6.3.14, C99 6.5.5-6.5.14, C11 6.5.5-6.5.14). If AFTER is not
9267 : : NULL then it is an Objective-C message expression which is the
9268 : : primary-expression starting the expression as an initializer.
9269 : :
9270 : : OMP_ATOMIC_LHS is NULL, unless parsing OpenMP #pragma omp atomic,
9271 : : when it should be the unfolded lhs. In a valid OpenMP source,
9272 : : one of the operands of the toplevel binary expression must be equal
9273 : : to it. In that case, just return a build2 created binary operation
9274 : : rather than result of parser_build_binary_op.
9275 : :
9276 : : multiplicative-expression:
9277 : : cast-expression
9278 : : multiplicative-expression * cast-expression
9279 : : multiplicative-expression / cast-expression
9280 : : multiplicative-expression % cast-expression
9281 : :
9282 : : additive-expression:
9283 : : multiplicative-expression
9284 : : additive-expression + multiplicative-expression
9285 : : additive-expression - multiplicative-expression
9286 : :
9287 : : shift-expression:
9288 : : additive-expression
9289 : : shift-expression << additive-expression
9290 : : shift-expression >> additive-expression
9291 : :
9292 : : relational-expression:
9293 : : shift-expression
9294 : : relational-expression < shift-expression
9295 : : relational-expression > shift-expression
9296 : : relational-expression <= shift-expression
9297 : : relational-expression >= shift-expression
9298 : :
9299 : : equality-expression:
9300 : : relational-expression
9301 : : equality-expression == relational-expression
9302 : : equality-expression != relational-expression
9303 : :
9304 : : AND-expression:
9305 : : equality-expression
9306 : : AND-expression & equality-expression
9307 : :
9308 : : exclusive-OR-expression:
9309 : : AND-expression
9310 : : exclusive-OR-expression ^ AND-expression
9311 : :
9312 : : inclusive-OR-expression:
9313 : : exclusive-OR-expression
9314 : : inclusive-OR-expression | exclusive-OR-expression
9315 : :
9316 : : logical-AND-expression:
9317 : : inclusive-OR-expression
9318 : : logical-AND-expression && inclusive-OR-expression
9319 : :
9320 : : logical-OR-expression:
9321 : : logical-AND-expression
9322 : : logical-OR-expression || logical-AND-expression
9323 : : */
9324 : :
9325 : : static struct c_expr
9326 : 205027587 : c_parser_binary_expression (c_parser *parser, struct c_expr *after,
9327 : : tree omp_atomic_lhs)
9328 : : {
9329 : : /* A binary expression is parsed using operator-precedence parsing,
9330 : : with the operands being cast expressions. All the binary
9331 : : operators are left-associative. Thus a binary expression is of
9332 : : form:
9333 : :
9334 : : E0 op1 E1 op2 E2 ...
9335 : :
9336 : : which we represent on a stack. On the stack, the precedence
9337 : : levels are strictly increasing. When a new operator is
9338 : : encountered of higher precedence than that at the top of the
9339 : : stack, it is pushed; its LHS is the top expression, and its RHS
9340 : : is everything parsed until it is popped. When a new operator is
9341 : : encountered with precedence less than or equal to that at the top
9342 : : of the stack, triples E[i-1] op[i] E[i] are popped and replaced
9343 : : by the result of the operation until the operator at the top of
9344 : : the stack has lower precedence than the new operator or there is
9345 : : only one element on the stack; then the top expression is the LHS
9346 : : of the new operator. In the case of logical AND and OR
9347 : : expressions, we also need to adjust c_inhibit_evaluation_warnings
9348 : : as appropriate when the operators are pushed and popped. */
9349 : :
9350 : 205027587 : struct {
9351 : : /* The expression at this stack level. */
9352 : : struct c_expr expr;
9353 : : /* The precedence of the operator on its left, PREC_NONE at the
9354 : : bottom of the stack. */
9355 : : enum c_parser_prec prec;
9356 : : /* The operation on its left. */
9357 : : enum tree_code op;
9358 : : /* The source location of this operation. */
9359 : : location_t loc;
9360 : : /* The sizeof argument if expr.original_code == {PAREN_,}SIZEOF_EXPR. */
9361 : : tree sizeof_arg;
9362 : : } stack[NUM_PRECS];
9363 : 205027587 : int sp;
9364 : : /* Location of the binary operator. */
9365 : 205027587 : location_t binary_loc = UNKNOWN_LOCATION; /* Quiet warning. */
9366 : : #define POP \
9367 : : do { \
9368 : : switch (stack[sp].op) \
9369 : : { \
9370 : : case TRUTH_ANDIF_EXPR: \
9371 : : c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
9372 : : == truthvalue_false_node); \
9373 : : break; \
9374 : : case TRUTH_ORIF_EXPR: \
9375 : : c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
9376 : : == truthvalue_true_node); \
9377 : : break; \
9378 : : case TRUNC_DIV_EXPR: \
9379 : : if ((stack[sp - 1].expr.original_code == SIZEOF_EXPR \
9380 : : || stack[sp - 1].expr.original_code == PAREN_SIZEOF_EXPR) \
9381 : : && (stack[sp].expr.original_code == SIZEOF_EXPR \
9382 : : || stack[sp].expr.original_code == PAREN_SIZEOF_EXPR)) \
9383 : : { \
9384 : : tree type0 = stack[sp - 1].sizeof_arg; \
9385 : : tree type1 = stack[sp].sizeof_arg; \
9386 : : tree first_arg = type0; \
9387 : : if (!TYPE_P (type0)) \
9388 : : type0 = TREE_TYPE (type0); \
9389 : : if (!TYPE_P (type1)) \
9390 : : type1 = TREE_TYPE (type1); \
9391 : : if (POINTER_TYPE_P (type0) \
9392 : : && comptypes (TREE_TYPE (type0), type1) \
9393 : : && !(TREE_CODE (first_arg) == PARM_DECL \
9394 : : && C_ARRAY_PARAMETER (first_arg) \
9395 : : && warn_sizeof_array_argument)) \
9396 : : { \
9397 : : auto_diagnostic_group d; \
9398 : : if (warning_at (stack[sp].loc, OPT_Wsizeof_pointer_div, \
9399 : : "division %<sizeof (%T) / sizeof (%T)%> " \
9400 : : "does not compute the number of array " \
9401 : : "elements", \
9402 : : type0, type1)) \
9403 : : if (DECL_P (first_arg)) \
9404 : : inform (DECL_SOURCE_LOCATION (first_arg), \
9405 : : "first %<sizeof%> operand was declared here"); \
9406 : : } \
9407 : : else if (TREE_CODE (type0) == ARRAY_TYPE \
9408 : : && !char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type0))) \
9409 : : && stack[sp].expr.original_code != PAREN_SIZEOF_EXPR) \
9410 : : maybe_warn_sizeof_array_div (stack[sp].loc, first_arg, type0, \
9411 : : stack[sp].sizeof_arg, type1); \
9412 : : } \
9413 : : break; \
9414 : : default: \
9415 : : break; \
9416 : : } \
9417 : : stack[sp - 1].expr \
9418 : : = convert_lvalue_to_rvalue (stack[sp - 1].loc, \
9419 : : stack[sp - 1].expr, true, true); \
9420 : : stack[sp].expr \
9421 : : = convert_lvalue_to_rvalue (stack[sp].loc, \
9422 : : stack[sp].expr, true, true); \
9423 : : if (UNLIKELY (omp_atomic_lhs != NULL_TREE) && sp == 1 \
9424 : : && ((c_parser_next_token_is (parser, CPP_SEMICOLON) \
9425 : : && ((1 << stack[sp].prec) \
9426 : : & ((1 << PREC_BITOR) | (1 << PREC_BITXOR) \
9427 : : | (1 << PREC_BITAND) | (1 << PREC_SHIFT) \
9428 : : | (1 << PREC_ADD) | (1 << PREC_MULT) \
9429 : : | (1 << PREC_EQ)))) \
9430 : : || ((c_parser_next_token_is (parser, CPP_QUERY) \
9431 : : || (omp_atomic_lhs == void_list_node \
9432 : : && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))) \
9433 : : && (stack[sp].prec == PREC_REL || stack[sp].prec == PREC_EQ)))\
9434 : : && stack[sp].op != TRUNC_MOD_EXPR \
9435 : : && stack[sp].op != GE_EXPR \
9436 : : && stack[sp].op != LE_EXPR \
9437 : : && stack[sp].op != NE_EXPR \
9438 : : && stack[0].expr.value != error_mark_node \
9439 : : && stack[1].expr.value != error_mark_node \
9440 : : && (omp_atomic_lhs == void_list_node \
9441 : : || c_tree_equal (stack[0].expr.value, omp_atomic_lhs) \
9442 : : || c_tree_equal (stack[1].expr.value, omp_atomic_lhs) \
9443 : : || (stack[sp].op == EQ_EXPR \
9444 : : && c_parser_peek_2nd_token (parser)->keyword == RID_IF))) \
9445 : : { \
9446 : : tree t = make_node (stack[1].op); \
9447 : : TREE_TYPE (t) = TREE_TYPE (stack[0].expr.value); \
9448 : : TREE_OPERAND (t, 0) = stack[0].expr.value; \
9449 : : TREE_OPERAND (t, 1) = stack[1].expr.value; \
9450 : : stack[0].expr.value = t; \
9451 : : stack[0].expr.m_decimal = 0; \
9452 : : } \
9453 : : else \
9454 : : stack[sp - 1].expr = parser_build_binary_op (stack[sp].loc, \
9455 : : stack[sp].op, \
9456 : : stack[sp - 1].expr, \
9457 : : stack[sp].expr); \
9458 : : sp--; \
9459 : : } while (0)
9460 : 205027587 : gcc_assert (!after || c_dialect_objc ());
9461 : 205027587 : stack[0].loc = c_parser_peek_token (parser)->location;
9462 : 205027587 : stack[0].expr = c_parser_cast_expression (parser, after);
9463 : 205027587 : stack[0].prec = PREC_NONE;
9464 : 205027587 : stack[0].sizeof_arg = c_last_sizeof_arg;
9465 : 205027587 : sp = 0;
9466 : 222748165 : while (true)
9467 : : {
9468 : 213887876 : enum c_parser_prec oprec;
9469 : 213887876 : enum tree_code ocode;
9470 : 213887876 : source_range src_range;
9471 : 213887876 : if (parser->error)
9472 : 1038 : goto out;
9473 : 213886838 : switch (c_parser_peek_token (parser)->type)
9474 : : {
9475 : : case CPP_MULT:
9476 : : oprec = PREC_MULT;
9477 : : ocode = MULT_EXPR;
9478 : : break;
9479 : 271314 : case CPP_DIV:
9480 : 271314 : oprec = PREC_MULT;
9481 : 271314 : ocode = TRUNC_DIV_EXPR;
9482 : 271314 : break;
9483 : 53926 : case CPP_MOD:
9484 : 53926 : oprec = PREC_MULT;
9485 : 53926 : ocode = TRUNC_MOD_EXPR;
9486 : 53926 : break;
9487 : 1786175 : case CPP_PLUS:
9488 : 1786175 : oprec = PREC_ADD;
9489 : 1786175 : ocode = PLUS_EXPR;
9490 : 1786175 : break;
9491 : 744699 : case CPP_MINUS:
9492 : 744699 : oprec = PREC_ADD;
9493 : 744699 : ocode = MINUS_EXPR;
9494 : 744699 : break;
9495 : 708358 : case CPP_LSHIFT:
9496 : 708358 : oprec = PREC_SHIFT;
9497 : 708358 : ocode = LSHIFT_EXPR;
9498 : 708358 : break;
9499 : 190684 : case CPP_RSHIFT:
9500 : 190684 : oprec = PREC_SHIFT;
9501 : 190684 : ocode = RSHIFT_EXPR;
9502 : 190684 : break;
9503 : 462375 : case CPP_LESS:
9504 : 462375 : oprec = PREC_REL;
9505 : 462375 : ocode = LT_EXPR;
9506 : 462375 : break;
9507 : 188835 : case CPP_GREATER:
9508 : 188835 : oprec = PREC_REL;
9509 : 188835 : ocode = GT_EXPR;
9510 : 188835 : break;
9511 : 124849 : case CPP_LESS_EQ:
9512 : 124849 : oprec = PREC_REL;
9513 : 124849 : ocode = LE_EXPR;
9514 : 124849 : break;
9515 : 160698 : case CPP_GREATER_EQ:
9516 : 160698 : oprec = PREC_REL;
9517 : 160698 : ocode = GE_EXPR;
9518 : 160698 : break;
9519 : 367545 : case CPP_EQ_EQ:
9520 : 367545 : oprec = PREC_EQ;
9521 : 367545 : ocode = EQ_EXPR;
9522 : 367545 : break;
9523 : 757731 : case CPP_NOT_EQ:
9524 : 757731 : oprec = PREC_EQ;
9525 : 757731 : ocode = NE_EXPR;
9526 : 757731 : break;
9527 : 563055 : case CPP_AND:
9528 : 563055 : oprec = PREC_BITAND;
9529 : 563055 : ocode = BIT_AND_EXPR;
9530 : 563055 : break;
9531 : 71385 : case CPP_XOR:
9532 : 71385 : oprec = PREC_BITXOR;
9533 : 71385 : ocode = BIT_XOR_EXPR;
9534 : 71385 : break;
9535 : 785507 : case CPP_OR:
9536 : 785507 : oprec = PREC_BITOR;
9537 : 785507 : ocode = BIT_IOR_EXPR;
9538 : 785507 : break;
9539 : 163790 : case CPP_AND_AND:
9540 : 163790 : oprec = PREC_LOGAND;
9541 : 163790 : ocode = TRUTH_ANDIF_EXPR;
9542 : 163790 : break;
9543 : 316688 : case CPP_OR_OR:
9544 : 316688 : oprec = PREC_LOGOR;
9545 : 316688 : ocode = TRUTH_ORIF_EXPR;
9546 : 316688 : break;
9547 : 205026549 : default:
9548 : : /* Not a binary operator, so end of the binary
9549 : : expression. */
9550 : 205026549 : goto out;
9551 : : }
9552 : 8860289 : binary_loc = c_parser_peek_token (parser)->location;
9553 : 8860289 : while (oprec <= stack[sp].prec)
9554 : 10274402 : POP;
9555 : 8860289 : c_parser_consume_token (parser);
9556 : 8860289 : switch (ocode)
9557 : : {
9558 : 163790 : case TRUTH_ANDIF_EXPR:
9559 : 163790 : src_range = stack[sp].expr.src_range;
9560 : 163790 : stack[sp].expr
9561 : 163790 : = convert_lvalue_to_rvalue (stack[sp].loc,
9562 : : stack[sp].expr, true, true);
9563 : 327580 : stack[sp].expr.value = c_objc_common_truthvalue_conversion
9564 : 163790 : (stack[sp].loc, default_conversion (stack[sp].expr.value));
9565 : 163790 : c_inhibit_evaluation_warnings += (stack[sp].expr.value
9566 : 163790 : == truthvalue_false_node);
9567 : 163790 : set_c_expr_source_range (&stack[sp].expr, src_range);
9568 : 163790 : break;
9569 : 316688 : case TRUTH_ORIF_EXPR:
9570 : 316688 : src_range = stack[sp].expr.src_range;
9571 : 316688 : stack[sp].expr
9572 : 316688 : = convert_lvalue_to_rvalue (stack[sp].loc,
9573 : : stack[sp].expr, true, true);
9574 : 633376 : stack[sp].expr.value = c_objc_common_truthvalue_conversion
9575 : 316688 : (stack[sp].loc, default_conversion (stack[sp].expr.value));
9576 : 316688 : c_inhibit_evaluation_warnings += (stack[sp].expr.value
9577 : 316688 : == truthvalue_true_node);
9578 : 316688 : set_c_expr_source_range (&stack[sp].expr, src_range);
9579 : 316688 : break;
9580 : : default:
9581 : : break;
9582 : : }
9583 : 8860289 : sp++;
9584 : 8860289 : stack[sp].loc = binary_loc;
9585 : 8860289 : stack[sp].expr = c_parser_cast_expression (parser, NULL);
9586 : 8860289 : stack[sp].prec = oprec;
9587 : 8860289 : stack[sp].op = ocode;
9588 : 8860289 : stack[sp].sizeof_arg = c_last_sizeof_arg;
9589 : 8860289 : }
9590 : 205027587 : out:
9591 : 205027587 : while (sp > 0)
9592 : 212474484 : POP;
9593 : 205027585 : return stack[0].expr;
9594 : : #undef POP
9595 : : }
9596 : :
9597 : : /* Parse any storage class specifiers after an open parenthesis in a
9598 : : context where a compound literal is permitted. */
9599 : :
9600 : : static struct c_declspecs *
9601 : 105174392 : c_parser_compound_literal_scspecs (c_parser *parser)
9602 : : {
9603 : 105174392 : bool seen_scspec = false;
9604 : 105174392 : struct c_declspecs *specs = build_null_declspecs ();
9605 : 210349106 : while (c_parser_next_token_is (parser, CPP_KEYWORD))
9606 : : {
9607 : 3795560 : switch (c_parser_peek_token (parser)->keyword)
9608 : : {
9609 : 322 : case RID_CONSTEXPR:
9610 : 322 : case RID_REGISTER:
9611 : 322 : case RID_STATIC:
9612 : 322 : case RID_THREAD:
9613 : 322 : seen_scspec = true;
9614 : 322 : declspecs_add_scspec (c_parser_peek_token (parser)->location,
9615 : 322 : specs, c_parser_peek_token (parser)->value);
9616 : 322 : c_parser_consume_token (parser);
9617 : 322 : break;
9618 : 3795238 : default:
9619 : 3795238 : goto out;
9620 : : }
9621 : : }
9622 : 101379154 : out:
9623 : 105174392 : return seen_scspec ? specs : NULL;
9624 : : }
9625 : :
9626 : : /* Parse a cast expression (C90 6.3.4, C99 6.5.4, C11 6.5.4). If AFTER
9627 : : is not NULL then it is an Objective-C message expression which is the
9628 : : primary-expression starting the expression as an initializer.
9629 : :
9630 : : cast-expression:
9631 : : unary-expression
9632 : : ( type-name ) unary-expression
9633 : : */
9634 : :
9635 : : static struct c_expr
9636 : 326400234 : c_parser_cast_expression (c_parser *parser, struct c_expr *after)
9637 : : {
9638 : 326400234 : location_t cast_loc = c_parser_peek_token (parser)->location;
9639 : 326400234 : gcc_assert (!after || c_dialect_objc ());
9640 : 0 : if (after)
9641 : 0 : return c_parser_postfix_expression_after_primary (parser,
9642 : 0 : cast_loc, *after);
9643 : : /* If the expression begins with a parenthesized type name, it may
9644 : : be either a cast or a compound literal; we need to see whether
9645 : : the next character is '{' to tell the difference. If not, it is
9646 : : an unary expression. Full detection of unknown typenames here
9647 : : would require a 3-token lookahead. */
9648 : 326400234 : if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
9649 : 326400234 : && c_token_starts_compound_literal (c_parser_peek_2nd_token (parser)))
9650 : : {
9651 : 104809203 : struct c_declspecs *scspecs;
9652 : 104809203 : struct c_type_name *type_name;
9653 : 104809203 : struct c_expr ret;
9654 : 104809203 : struct c_expr expr;
9655 : 104809203 : matching_parens parens;
9656 : 104809203 : parens.consume_open (parser);
9657 : 104809203 : scspecs = c_parser_compound_literal_scspecs (parser);
9658 : 104809203 : type_name = c_parser_type_name (parser, true);
9659 : 104809203 : parens.skip_until_found_close (parser);
9660 : 104809203 : if (type_name == NULL)
9661 : : {
9662 : 1 : ret.set_error ();
9663 : 1 : ret.original_code = ERROR_MARK;
9664 : 1 : ret.original_type = NULL;
9665 : 1 : return ret;
9666 : : }
9667 : :
9668 : : /* Save casted types in the function's used types hash table. */
9669 : 104809202 : used_types_insert (type_name->specs->type);
9670 : :
9671 : 104809202 : if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
9672 : 869197 : return c_parser_postfix_expression_after_paren_type (parser, scspecs,
9673 : : type_name,
9674 : 869197 : cast_loc);
9675 : 103940005 : if (scspecs)
9676 : 1 : error_at (cast_loc, "storage class specifier in cast");
9677 : 103940005 : if (type_name->specs->alignas_p)
9678 : 1 : error_at (type_name->specs->locations[cdw_alignas],
9679 : : "alignment specified for type name in cast");
9680 : 103940005 : {
9681 : 103940005 : location_t expr_loc = c_parser_peek_token (parser)->location;
9682 : 103940005 : expr = c_parser_cast_expression (parser, NULL);
9683 : 103940005 : expr = convert_lvalue_to_rvalue (expr_loc, expr, true, true);
9684 : : }
9685 : 103940005 : ret.value = c_cast_expr (cast_loc, type_name, expr.value);
9686 : 103940005 : if (ret.value && expr.value)
9687 : 103940005 : set_c_expr_source_range (&ret, cast_loc, expr.get_finish ());
9688 : 103940005 : ret.original_code = ERROR_MARK;
9689 : 103940005 : ret.original_type = NULL;
9690 : 103940005 : ret.m_decimal = 0;
9691 : 103940005 : return ret;
9692 : : }
9693 : : else
9694 : 221591031 : return c_parser_unary_expression (parser);
9695 : : }
9696 : :
9697 : : /* Parse an unary expression (C90 6.3.3, C99 6.5.3, C11 6.5.3).
9698 : :
9699 : : unary-expression:
9700 : : postfix-expression
9701 : : ++ unary-expression
9702 : : -- unary-expression
9703 : : unary-operator cast-expression
9704 : : sizeof unary-expression
9705 : : sizeof ( type-name )
9706 : :
9707 : : unary-operator: one of
9708 : : & * + - ~ !
9709 : :
9710 : : GNU extensions:
9711 : :
9712 : : unary-expression:
9713 : : __alignof__ unary-expression
9714 : : __alignof__ ( type-name )
9715 : : && identifier
9716 : :
9717 : : (C11 permits _Alignof with type names only.)
9718 : :
9719 : : unary-operator: one of
9720 : : __extension__ __real__ __imag__
9721 : :
9722 : : Transactional Memory:
9723 : :
9724 : : unary-expression:
9725 : : transaction-expression
9726 : :
9727 : : In addition, the GNU syntax treats ++ and -- as unary operators, so
9728 : : they may be applied to cast expressions with errors for non-lvalues
9729 : : given later. */
9730 : :
9731 : : static struct c_expr
9732 : 221944284 : c_parser_unary_expression (c_parser *parser)
9733 : : {
9734 : 221944284 : int ext;
9735 : 221944284 : struct c_expr ret, op;
9736 : 221944284 : location_t op_loc = c_parser_peek_token (parser)->location;
9737 : 221944284 : location_t exp_loc;
9738 : 221944284 : location_t finish;
9739 : 221944284 : ret.original_code = ERROR_MARK;
9740 : 221944284 : ret.original_type = NULL;
9741 : 221944284 : switch (c_parser_peek_token (parser)->type)
9742 : : {
9743 : 218467 : case CPP_PLUS_PLUS:
9744 : 218467 : c_parser_consume_token (parser);
9745 : 218467 : exp_loc = c_parser_peek_token (parser)->location;
9746 : 218467 : op = c_parser_cast_expression (parser, NULL);
9747 : :
9748 : 218467 : op = default_function_array_read_conversion (exp_loc, op);
9749 : 218467 : return parser_build_unary_op (op_loc, PREINCREMENT_EXPR, op);
9750 : 6515 : case CPP_MINUS_MINUS:
9751 : 6515 : c_parser_consume_token (parser);
9752 : 6515 : exp_loc = c_parser_peek_token (parser)->location;
9753 : 6515 : op = c_parser_cast_expression (parser, NULL);
9754 : :
9755 : 6515 : op = default_function_array_read_conversion (exp_loc, op);
9756 : 6515 : return parser_build_unary_op (op_loc, PREDECREMENT_EXPR, op);
9757 : 442767 : case CPP_AND:
9758 : 442767 : c_parser_consume_token (parser);
9759 : 442767 : op = c_parser_cast_expression (parser, NULL);
9760 : 442767 : mark_exp_read (op.value);
9761 : 442767 : return parser_build_unary_op (op_loc, ADDR_EXPR, op);
9762 : 1144294 : case CPP_MULT:
9763 : 1144294 : {
9764 : 1144294 : c_parser_consume_token (parser);
9765 : 1144294 : exp_loc = c_parser_peek_token (parser)->location;
9766 : 1144294 : op = c_parser_cast_expression (parser, NULL);
9767 : 1144294 : finish = op.get_finish ();
9768 : 1144294 : op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
9769 : 1144294 : location_t combined_loc = make_location (op_loc, op_loc, finish);
9770 : 1144294 : ret.value = build_indirect_ref (combined_loc, op.value, RO_UNARY_STAR);
9771 : 1144294 : ret.src_range.m_start = op_loc;
9772 : 1144294 : ret.src_range.m_finish = finish;
9773 : 1144294 : ret.m_decimal = 0;
9774 : 1144294 : return ret;
9775 : : }
9776 : 28534 : case CPP_PLUS:
9777 : 28534 : if (!c_dialect_objc () && !in_system_header_at (input_location))
9778 : 28532 : warning_at (op_loc,
9779 : : OPT_Wtraditional,
9780 : : "traditional C rejects the unary plus operator");
9781 : 28534 : c_parser_consume_token (parser);
9782 : 28534 : exp_loc = c_parser_peek_token (parser)->location;
9783 : 28534 : op = c_parser_cast_expression (parser, NULL);
9784 : 28534 : op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
9785 : 28534 : return parser_build_unary_op (op_loc, CONVERT_EXPR, op);
9786 : 5608548 : case CPP_MINUS:
9787 : 5608548 : c_parser_consume_token (parser);
9788 : 5608548 : exp_loc = c_parser_peek_token (parser)->location;
9789 : 5608548 : op = c_parser_cast_expression (parser, NULL);
9790 : 5608548 : op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
9791 : 5608548 : return parser_build_unary_op (op_loc, NEGATE_EXPR, op);
9792 : 284930 : case CPP_COMPL:
9793 : 284930 : c_parser_consume_token (parser);
9794 : 284930 : exp_loc = c_parser_peek_token (parser)->location;
9795 : 284930 : op = c_parser_cast_expression (parser, NULL);
9796 : 284930 : op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
9797 : 284930 : return parser_build_unary_op (op_loc, BIT_NOT_EXPR, op);
9798 : 336174 : case CPP_NOT:
9799 : 336174 : c_parser_consume_token (parser);
9800 : 336174 : exp_loc = c_parser_peek_token (parser)->location;
9801 : 336174 : op = c_parser_cast_expression (parser, NULL);
9802 : 336174 : op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
9803 : 336174 : return parser_build_unary_op (op_loc, TRUTH_NOT_EXPR, op);
9804 : 1821 : case CPP_AND_AND:
9805 : : /* Refer to the address of a label as a pointer. */
9806 : 1821 : c_parser_consume_token (parser);
9807 : 1821 : if (c_parser_next_token_is (parser, CPP_NAME))
9808 : : {
9809 : 3628 : ret.value = finish_label_address_expr
9810 : 1814 : (c_parser_peek_token (parser)->value, op_loc);
9811 : 1814 : set_c_expr_source_range (&ret, op_loc,
9812 : : c_parser_peek_token (parser)->get_finish ());
9813 : 1814 : c_parser_consume_token (parser);
9814 : : }
9815 : : else
9816 : : {
9817 : 7 : c_parser_error (parser, "expected identifier");
9818 : 7 : ret.set_error ();
9819 : : }
9820 : 1821 : return ret;
9821 : 2770845 : case CPP_KEYWORD:
9822 : 2770845 : switch (c_parser_peek_token (parser)->keyword)
9823 : : {
9824 : 647417 : case RID_SIZEOF:
9825 : 647417 : return c_parser_sizeof_expression (parser);
9826 : 71025 : case RID_ALIGNOF:
9827 : 71025 : return c_parser_alignof_expression (parser);
9828 : 756 : case RID_BUILTIN_HAS_ATTRIBUTE:
9829 : 756 : return c_parser_has_attribute_expression (parser);
9830 : 422915 : case RID_EXTENSION:
9831 : 422915 : c_parser_consume_token (parser);
9832 : 422915 : ext = disable_extension_diagnostics ();
9833 : 422915 : ret = c_parser_cast_expression (parser, NULL);
9834 : 422915 : restore_extension_diagnostics (ext);
9835 : 422915 : return ret;
9836 : 38342 : case RID_REALPART:
9837 : 38342 : c_parser_consume_token (parser);
9838 : 38342 : exp_loc = c_parser_peek_token (parser)->location;
9839 : 38342 : op = c_parser_cast_expression (parser, NULL);
9840 : 38342 : op = default_function_array_conversion (exp_loc, op);
9841 : 38342 : return parser_build_unary_op (op_loc, REALPART_EXPR, op);
9842 : 38298 : case RID_IMAGPART:
9843 : 38298 : c_parser_consume_token (parser);
9844 : 38298 : exp_loc = c_parser_peek_token (parser)->location;
9845 : 38298 : op = c_parser_cast_expression (parser, NULL);
9846 : 38298 : op = default_function_array_conversion (exp_loc, op);
9847 : 38298 : return parser_build_unary_op (op_loc, IMAGPART_EXPR, op);
9848 : 7 : case RID_TRANSACTION_ATOMIC:
9849 : 7 : case RID_TRANSACTION_RELAXED:
9850 : 14 : return c_parser_transaction_expression (parser,
9851 : 7 : c_parser_peek_token (parser)->keyword);
9852 : 1552085 : default:
9853 : 1552085 : return c_parser_postfix_expression (parser);
9854 : : }
9855 : 211101389 : default:
9856 : 211101389 : return c_parser_postfix_expression (parser);
9857 : : }
9858 : : }
9859 : :
9860 : : /* Parse a sizeof expression. */
9861 : :
9862 : : static struct c_expr
9863 : 647417 : c_parser_sizeof_expression (c_parser *parser)
9864 : : {
9865 : 647417 : struct c_expr expr;
9866 : 647417 : struct c_expr result;
9867 : 647417 : location_t expr_loc;
9868 : 647417 : gcc_assert (c_parser_next_token_is_keyword (parser, RID_SIZEOF));
9869 : :
9870 : 647417 : location_t start;
9871 : 647417 : location_t finish = UNKNOWN_LOCATION;
9872 : :
9873 : 647417 : start = c_parser_peek_token (parser)->location;
9874 : :
9875 : 647417 : c_parser_consume_token (parser);
9876 : 647417 : c_inhibit_evaluation_warnings++;
9877 : 647417 : in_sizeof++;
9878 : 647417 : if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
9879 : 647417 : && c_token_starts_compound_literal (c_parser_peek_2nd_token (parser)))
9880 : : {
9881 : : /* Either sizeof ( type-name ) or sizeof unary-expression
9882 : : starting with a compound literal. */
9883 : 334925 : struct c_declspecs *scspecs;
9884 : 334925 : struct c_type_name *type_name;
9885 : 334925 : matching_parens parens;
9886 : 334925 : parens.consume_open (parser);
9887 : 334925 : expr_loc = c_parser_peek_token (parser)->location;
9888 : 334925 : scspecs = c_parser_compound_literal_scspecs (parser);
9889 : 334925 : type_name = c_parser_type_name (parser, true);
9890 : 334925 : parens.skip_until_found_close (parser);
9891 : 334925 : finish = parser->tokens_buf[0].location;
9892 : 334925 : if (type_name == NULL)
9893 : : {
9894 : 0 : struct c_expr ret;
9895 : 0 : c_inhibit_evaluation_warnings--;
9896 : 0 : in_sizeof--;
9897 : 0 : ret.set_error ();
9898 : 0 : ret.original_code = ERROR_MARK;
9899 : 0 : ret.original_type = NULL;
9900 : 0 : return ret;
9901 : : }
9902 : 334925 : if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
9903 : : {
9904 : 25 : expr = c_parser_postfix_expression_after_paren_type (parser, scspecs,
9905 : : type_name,
9906 : : expr_loc);
9907 : 25 : finish = expr.get_finish ();
9908 : 25 : goto sizeof_expr;
9909 : : }
9910 : : /* sizeof ( type-name ). */
9911 : 334900 : if (scspecs)
9912 : 1 : error_at (expr_loc, "storage class specifier in %<sizeof%>");
9913 : 334900 : if (type_name->specs->alignas_p)
9914 : 2 : error_at (type_name->specs->locations[cdw_alignas],
9915 : : "alignment specified for type name in %<sizeof%>");
9916 : 334900 : c_inhibit_evaluation_warnings--;
9917 : 334900 : in_sizeof--;
9918 : 334900 : result = c_expr_sizeof_type (expr_loc, type_name);
9919 : : }
9920 : : else
9921 : : {
9922 : 312492 : expr_loc = c_parser_peek_token (parser)->location;
9923 : 312492 : expr = c_parser_unary_expression (parser);
9924 : 312492 : finish = expr.get_finish ();
9925 : 312517 : sizeof_expr:
9926 : 312517 : c_inhibit_evaluation_warnings--;
9927 : 312517 : in_sizeof--;
9928 : 312517 : mark_exp_read (expr.value);
9929 : 312517 : if (TREE_CODE (expr.value) == COMPONENT_REF
9930 : 312517 : && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
9931 : 1 : error_at (expr_loc, "%<sizeof%> applied to a bit-field");
9932 : 312517 : result = c_expr_sizeof_expr (expr_loc, expr);
9933 : : }
9934 : 647417 : if (finish == UNKNOWN_LOCATION)
9935 : 0 : finish = start;
9936 : 647417 : set_c_expr_source_range (&result, start, finish);
9937 : 647417 : return result;
9938 : : }
9939 : :
9940 : : /* Parse an alignof expression. */
9941 : :
9942 : : static struct c_expr
9943 : 71025 : c_parser_alignof_expression (c_parser *parser)
9944 : : {
9945 : 71025 : struct c_expr expr;
9946 : 71025 : location_t start_loc = c_parser_peek_token (parser)->location;
9947 : 71025 : location_t end_loc;
9948 : 71025 : tree alignof_spelling = c_parser_peek_token (parser)->value;
9949 : 71025 : gcc_assert (c_parser_next_token_is_keyword (parser, RID_ALIGNOF));
9950 : 71025 : bool is_c11_alignof = (strcmp (IDENTIFIER_POINTER (alignof_spelling),
9951 : : "_Alignof") == 0
9952 : 71025 : || strcmp (IDENTIFIER_POINTER (alignof_spelling),
9953 : 71230 : "alignof") == 0);
9954 : : /* A diagnostic is not required for the use of this identifier in
9955 : : the implementation namespace; only diagnose it for the C11 or C23
9956 : : spelling because of existing code using the other spellings. */
9957 : 205 : if (is_c11_alignof)
9958 : : {
9959 : 205 : if (flag_isoc99)
9960 : 201 : pedwarn_c99 (start_loc, OPT_Wpedantic, "ISO C99 does not support %qE",
9961 : : alignof_spelling);
9962 : : else
9963 : 4 : pedwarn_c99 (start_loc, OPT_Wpedantic, "ISO C90 does not support %qE",
9964 : : alignof_spelling);
9965 : : }
9966 : 71025 : c_parser_consume_token (parser);
9967 : 71025 : c_inhibit_evaluation_warnings++;
9968 : 71025 : in_alignof++;
9969 : 71025 : if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
9970 : 71025 : && c_token_starts_compound_literal (c_parser_peek_2nd_token (parser)))
9971 : : {
9972 : : /* Either __alignof__ ( type-name ) or __alignof__
9973 : : unary-expression starting with a compound literal. */
9974 : 30264 : location_t loc;
9975 : 30264 : struct c_declspecs *scspecs;
9976 : 30264 : struct c_type_name *type_name;
9977 : 30264 : struct c_expr ret;
9978 : 30264 : matching_parens parens;
9979 : 30264 : parens.consume_open (parser);
9980 : 30264 : loc = c_parser_peek_token (parser)->location;
9981 : 30264 : scspecs = c_parser_compound_literal_scspecs (parser);
9982 : 30264 : type_name = c_parser_type_name (parser, true);
9983 : 30264 : end_loc = c_parser_peek_token (parser)->location;
9984 : 30264 : parens.skip_until_found_close (parser);
9985 : 30264 : if (type_name == NULL)
9986 : : {
9987 : 0 : struct c_expr ret;
9988 : 0 : c_inhibit_evaluation_warnings--;
9989 : 0 : in_alignof--;
9990 : 0 : ret.set_error ();
9991 : 0 : ret.original_code = ERROR_MARK;
9992 : 0 : ret.original_type = NULL;
9993 : 0 : return ret;
9994 : : }
9995 : 30264 : if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
9996 : : {
9997 : 2 : expr = c_parser_postfix_expression_after_paren_type (parser, scspecs,
9998 : : type_name,
9999 : : loc);
10000 : 2 : goto alignof_expr;
10001 : : }
10002 : : /* alignof ( type-name ). */
10003 : 30262 : if (scspecs)
10004 : 1 : error_at (loc, "storage class specifier in %qE", alignof_spelling);
10005 : 30262 : if (type_name->specs->alignas_p)
10006 : 1 : error_at (type_name->specs->locations[cdw_alignas],
10007 : : "alignment specified for type name in %qE",
10008 : : alignof_spelling);
10009 : 30262 : c_inhibit_evaluation_warnings--;
10010 : 30262 : in_alignof--;
10011 : 30262 : ret.value = c_sizeof_or_alignof_type (loc, groktypename (type_name,
10012 : : NULL, NULL),
10013 : : false, is_c11_alignof, 1);
10014 : 30262 : ret.original_code = ERROR_MARK;
10015 : 30262 : ret.original_type = NULL;
10016 : 30262 : set_c_expr_source_range (&ret, start_loc, end_loc);
10017 : 30262 : ret.m_decimal = 0;
10018 : 30262 : return ret;
10019 : : }
10020 : : else
10021 : : {
10022 : 40761 : struct c_expr ret;
10023 : 40761 : expr = c_parser_unary_expression (parser);
10024 : 40761 : end_loc = expr.src_range.m_finish;
10025 : 40763 : alignof_expr:
10026 : 40763 : mark_exp_read (expr.value);
10027 : 40763 : c_inhibit_evaluation_warnings--;
10028 : 40763 : in_alignof--;
10029 : 40763 : if (is_c11_alignof)
10030 : 26 : pedwarn (start_loc,
10031 : : OPT_Wpedantic, "ISO C does not allow %<%E (expression)%>",
10032 : : alignof_spelling);
10033 : 40763 : ret.value = c_alignof_expr (start_loc, expr.value);
10034 : 40763 : ret.original_code = ERROR_MARK;
10035 : 40763 : ret.original_type = NULL;
10036 : 40763 : set_c_expr_source_range (&ret, start_loc, end_loc);
10037 : 40763 : ret.m_decimal = 0;
10038 : 40763 : return ret;
10039 : : }
10040 : : }
10041 : :
10042 : : /* Parse the __builtin_has_attribute ([expr|type], attribute-spec)
10043 : : expression. */
10044 : :
10045 : : static struct c_expr
10046 : 756 : c_parser_has_attribute_expression (c_parser *parser)
10047 : : {
10048 : 756 : gcc_assert (c_parser_next_token_is_keyword (parser,
10049 : : RID_BUILTIN_HAS_ATTRIBUTE));
10050 : 756 : location_t start = c_parser_peek_token (parser)->location;
10051 : 756 : c_parser_consume_token (parser);
10052 : :
10053 : 756 : c_inhibit_evaluation_warnings++;
10054 : :
10055 : 756 : matching_parens parens;
10056 : 756 : if (!parens.require_open (parser))
10057 : : {
10058 : 0 : c_inhibit_evaluation_warnings--;
10059 : 0 : in_typeof--;
10060 : :
10061 : 0 : struct c_expr result;
10062 : 0 : result.set_error ();
10063 : 0 : result.original_code = ERROR_MARK;
10064 : 0 : result.original_type = NULL;
10065 : 0 : return result;
10066 : : }
10067 : :
10068 : : /* Treat the type argument the same way as in typeof for the purposes
10069 : : of warnings. FIXME: Generalize this so the warning refers to
10070 : : __builtin_has_attribute rather than typeof. */
10071 : 756 : in_typeof++;
10072 : :
10073 : : /* The first operand: one of DECL, EXPR, or TYPE. */
10074 : 756 : tree oper = NULL_TREE;
10075 : 756 : if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
10076 : : {
10077 : 148 : struct c_type_name *tname = c_parser_type_name (parser);
10078 : 148 : in_typeof--;
10079 : 148 : if (tname)
10080 : : {
10081 : 148 : oper = groktypename (tname, NULL, NULL);
10082 : 148 : pop_maybe_used (c_type_variably_modified_p (oper));
10083 : : }
10084 : : }
10085 : : else
10086 : : {
10087 : 608 : struct c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
10088 : 608 : c_inhibit_evaluation_warnings--;
10089 : 608 : in_typeof--;
10090 : 608 : if (cexpr.value != error_mark_node)
10091 : : {
10092 : 605 : mark_exp_read (cexpr.value);
10093 : 605 : oper = cexpr.value;
10094 : 605 : tree etype = TREE_TYPE (oper);
10095 : 605 : bool was_vm = c_type_variably_modified_p (etype);
10096 : : /* This is returned with the type so that when the type is
10097 : : evaluated, this can be evaluated. */
10098 : 605 : if (was_vm)
10099 : 0 : oper = c_fully_fold (oper, false, NULL);
10100 : 605 : pop_maybe_used (was_vm);
10101 : : }
10102 : : }
10103 : :
10104 : 756 : struct c_expr result;
10105 : 756 : result.original_code = ERROR_MARK;
10106 : 756 : result.original_type = NULL;
10107 : :
10108 : 756 : if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
10109 : : {
10110 : : /* Consume the closing parenthesis if that's the next token
10111 : : in the likely case the built-in was invoked with fewer
10112 : : than two arguments. */
10113 : 4 : if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
10114 : 4 : c_parser_consume_token (parser);
10115 : 4 : c_inhibit_evaluation_warnings--;
10116 : 4 : result.set_error ();
10117 : 4 : return result;
10118 : : }
10119 : :
10120 : 752 : bool save_translate_strings_p = parser->translate_strings_p;
10121 : :
10122 : 752 : location_t atloc = c_parser_peek_token (parser)->location;
10123 : : /* Parse a single attribute. Require no leading comma and do not
10124 : : allow empty attributes. */
10125 : 752 : tree attr = c_parser_gnu_attribute (parser, NULL_TREE, false, false);
10126 : :
10127 : 752 : parser->translate_strings_p = save_translate_strings_p;
10128 : :
10129 : 752 : location_t finish = c_parser_peek_token (parser)->location;
10130 : 752 : if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
10131 : 749 : c_parser_consume_token (parser);
10132 : : else
10133 : : {
10134 : 3 : c_parser_error (parser, "expected identifier");
10135 : 3 : c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10136 : :
10137 : 3 : result.set_error ();
10138 : 3 : return result;
10139 : : }
10140 : :
10141 : 749 : if (!attr)
10142 : : {
10143 : 0 : error_at (atloc, "expected identifier");
10144 : 0 : c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
10145 : : "expected %<)%>");
10146 : 0 : result.set_error ();
10147 : 0 : return result;
10148 : : }
10149 : :
10150 : 749 : result.original_code = INTEGER_CST;
10151 : 749 : result.original_type = boolean_type_node;
10152 : :
10153 : 749 : if (has_attribute (atloc, oper, attr, default_conversion))
10154 : 288 : result.value = boolean_true_node;
10155 : : else
10156 : 461 : result.value = boolean_false_node;
10157 : :
10158 : 749 : set_c_expr_source_range (&result, start, finish);
10159 : 749 : result.m_decimal = 0;
10160 : 749 : return result;
10161 : : }
10162 : :
10163 : : /* Helper function to read arguments of builtins which are interfaces
10164 : : for the middle-end nodes like COMPLEX_EXPR, VEC_PERM_EXPR and
10165 : : others. The name of the builtin is passed using BNAME parameter.
10166 : : Function returns true if there were no errors while parsing and
10167 : : stores the arguments in CEXPR_LIST. If it returns true,
10168 : : *OUT_CLOSE_PAREN_LOC is written to with the location of the closing
10169 : : parenthesis. */
10170 : : static bool
10171 : 1515951 : c_parser_get_builtin_args (c_parser *parser, const char *bname,
10172 : : vec<c_expr_t, va_gc> **ret_cexpr_list,
10173 : : bool choose_expr_p,
10174 : : location_t *out_close_paren_loc)
10175 : : {
10176 : 1515951 : location_t loc = c_parser_peek_token (parser)->location;
10177 : 1515951 : vec<c_expr_t, va_gc> *cexpr_list;
10178 : 1515951 : c_expr_t expr;
10179 : 1515951 : bool saved_force_folding_builtin_constant_p;
10180 : :
10181 : 1515951 : *ret_cexpr_list = NULL;
10182 : 1515951 : if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
10183 : : {
10184 : 1 : error_at (loc, "cannot take address of %qs", bname);
10185 : 1 : return false;
10186 : : }
10187 : :
10188 : 1515950 : c_parser_consume_token (parser);
10189 : :
10190 : 1515950 : if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
10191 : : {
10192 : 15 : *out_close_paren_loc = c_parser_peek_token (parser)->location;
10193 : 15 : c_parser_consume_token (parser);
10194 : 15 : return true;
10195 : : }
10196 : :
10197 : 1515935 : saved_force_folding_builtin_constant_p
10198 : 1515935 : = force_folding_builtin_constant_p;
10199 : 1515935 : force_folding_builtin_constant_p |= choose_expr_p;
10200 : 1515935 : expr = c_parser_expr_no_commas (parser, NULL);
10201 : 1515935 : force_folding_builtin_constant_p
10202 : 1515935 : = saved_force_folding_builtin_constant_p;
10203 : 1515935 : vec_alloc (cexpr_list, 1);
10204 : 1515935 : vec_safe_push (cexpr_list, expr);
10205 : 17724321 : while (c_parser_next_token_is (parser, CPP_COMMA))
10206 : : {
10207 : 14692451 : c_parser_consume_token (parser);
10208 : 14692451 : expr = c_parser_expr_no_commas (parser, NULL);
10209 : 14692451 : vec_safe_push (cexpr_list, expr);
10210 : : }
10211 : :
10212 : 1515935 : *out_close_paren_loc = c_parser_peek_token (parser)->location;
10213 : 1515935 : if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
10214 : : return false;
10215 : :
10216 : 1515935 : *ret_cexpr_list = cexpr_list;
10217 : 1515935 : return true;
10218 : : }
10219 : :
10220 : : /* This represents a single generic-association. */
10221 : :
10222 : : struct c_generic_association
10223 : : {
10224 : : /* The location of the starting token of the type. */
10225 : : location_t type_location;
10226 : : /* The association's type, or NULL_TREE for 'default'. */
10227 : : tree type;
10228 : : /* The association's expression. */
10229 : : struct c_expr expression;
10230 : : };
10231 : :
10232 : : /* Parse a generic-selection. (C11 6.5.1.1).
10233 : :
10234 : : generic-selection:
10235 : : _Generic ( assignment-expression , generic-assoc-list )
10236 : :
10237 : : generic-assoc-list:
10238 : : generic-association
10239 : : generic-assoc-list , generic-association
10240 : :
10241 : : generic-association:
10242 : : type-name : assignment-expression
10243 : : default : assignment-expression
10244 : : */
10245 : :
10246 : : static struct c_expr
10247 : 456 : c_parser_generic_selection (c_parser *parser)
10248 : : {
10249 : 456 : struct c_expr selector, error_expr;
10250 : 456 : tree selector_type;
10251 : 456 : struct c_generic_association matched_assoc;
10252 : 456 : int match_found = -1;
10253 : 456 : location_t generic_loc, selector_loc;
10254 : :
10255 : 456 : error_expr.original_code = ERROR_MARK;
10256 : 456 : error_expr.original_type = NULL;
10257 : 456 : error_expr.set_error ();
10258 : 456 : matched_assoc.type_location = UNKNOWN_LOCATION;
10259 : 456 : matched_assoc.type = NULL_TREE;
10260 : 456 : matched_assoc.expression = error_expr;
10261 : :
10262 : 456 : gcc_assert (c_parser_next_token_is_keyword (parser, RID_GENERIC));
10263 : 456 : generic_loc = c_parser_peek_token (parser)->location;
10264 : 456 : c_parser_consume_token (parser);
10265 : 456 : if (flag_isoc99)
10266 : 454 : pedwarn_c99 (generic_loc, OPT_Wpedantic,
10267 : : "ISO C99 does not support %<_Generic%>");
10268 : : else
10269 : 2 : pedwarn_c99 (generic_loc, OPT_Wpedantic,
10270 : : "ISO C90 does not support %<_Generic%>");
10271 : :
10272 : 456 : matching_parens parens;
10273 : 456 : if (!parens.require_open (parser))
10274 : 0 : return error_expr;
10275 : :
10276 : 456 : c_inhibit_evaluation_warnings++;
10277 : 456 : selector_loc = c_parser_peek_token (parser)->location;
10278 : 456 : selector = c_parser_expr_no_commas (parser, NULL);
10279 : 456 : selector = default_function_array_conversion (selector_loc, selector);
10280 : 456 : c_inhibit_evaluation_warnings--;
10281 : :
10282 : 456 : if (selector.value == error_mark_node)
10283 : : {
10284 : 0 : c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10285 : 0 : return selector;
10286 : : }
10287 : 456 : mark_exp_read (selector.value);
10288 : 456 : selector_type = TREE_TYPE (selector.value);
10289 : : /* In ISO C terms, rvalues (including the controlling expression of
10290 : : _Generic) do not have qualified types. */
10291 : 456 : if (TREE_CODE (selector_type) != ARRAY_TYPE)
10292 : 456 : selector_type = TYPE_MAIN_VARIANT (selector_type);
10293 : : /* In ISO C terms, _Noreturn is not part of the type of expressions
10294 : : such as &abort, but in GCC it is represented internally as a type
10295 : : qualifier. */
10296 : 33 : if (FUNCTION_POINTER_TYPE_P (selector_type)
10297 : 460 : && TYPE_QUALS (TREE_TYPE (selector_type)) != TYPE_UNQUALIFIED)
10298 : 1 : selector_type
10299 : 1 : = build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (selector_type)));
10300 : :
10301 : 456 : if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
10302 : : {
10303 : 0 : c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10304 : 0 : return error_expr;
10305 : : }
10306 : :
10307 : 456 : auto_vec<c_generic_association> associations;
10308 : 1520 : while (1)
10309 : : {
10310 : 988 : struct c_generic_association assoc, *iter;
10311 : 988 : unsigned int ix;
10312 : 988 : c_token *token = c_parser_peek_token (parser);
10313 : :
10314 : 988 : assoc.type_location = token->location;
10315 : 988 : if (token->type == CPP_KEYWORD && token->keyword == RID_DEFAULT)
10316 : : {
10317 : 392 : c_parser_consume_token (parser);
10318 : 392 : assoc.type = NULL_TREE;
10319 : : }
10320 : : else
10321 : : {
10322 : 596 : struct c_type_name *type_name;
10323 : :
10324 : 596 : type_name = c_parser_type_name (parser);
10325 : 596 : if (type_name == NULL)
10326 : : {
10327 : 1 : c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10328 : 1 : return error_expr;
10329 : : }
10330 : 595 : assoc.type = groktypename (type_name, NULL, NULL);
10331 : 595 : if (assoc.type == error_mark_node)
10332 : : {
10333 : 0 : c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10334 : 0 : return error_expr;
10335 : : }
10336 : :
10337 : 595 : if (TREE_CODE (assoc.type) == FUNCTION_TYPE)
10338 : 1 : error_at (assoc.type_location,
10339 : : "%<_Generic%> association has function type");
10340 : 594 : else if (!COMPLETE_TYPE_P (assoc.type))
10341 : 5 : error_at (assoc.type_location,
10342 : : "%<_Generic%> association has incomplete type");
10343 : :
10344 : 595 : if (c_type_variably_modified_p (assoc.type))
10345 : 1 : error_at (assoc.type_location,
10346 : : "%<_Generic%> association has "
10347 : : "variable length type");
10348 : : }
10349 : :
10350 : 987 : if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
10351 : : {
10352 : 0 : c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10353 : 0 : return error_expr;
10354 : : }
10355 : :
10356 : 987 : bool match = assoc.type == NULL_TREE
10357 : 987 : || comptypes (assoc.type, selector_type);
10358 : :
10359 : 183 : if (!match)
10360 : 183 : c_inhibit_evaluation_warnings++;
10361 : :
10362 : 987 : assoc.expression = c_parser_expr_no_commas (parser, NULL);
10363 : :
10364 : 987 : if (!match)
10365 : 183 : c_inhibit_evaluation_warnings--;
10366 : :
10367 : 987 : if (assoc.expression.value == error_mark_node)
10368 : : {
10369 : 0 : c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10370 : 0 : return error_expr;
10371 : : }
10372 : :
10373 : 1823 : for (ix = 0; associations.iterate (ix, &iter); ++ix)
10374 : : {
10375 : 836 : if (assoc.type == NULL_TREE)
10376 : : {
10377 : 209 : if (iter->type == NULL_TREE)
10378 : : {
10379 : 1 : error_at (assoc.type_location,
10380 : : "duplicate %<default%> case in %<_Generic%>");
10381 : 1 : inform (iter->type_location, "original %<default%> is here");
10382 : : }
10383 : : }
10384 : 627 : else if (iter->type != NULL_TREE)
10385 : : {
10386 : 320 : if (comptypes (assoc.type, iter->type))
10387 : : {
10388 : 1 : error_at (assoc.type_location,
10389 : : "%<_Generic%> specifies two compatible types");
10390 : 1 : inform (iter->type_location, "compatible type is here");
10391 : : }
10392 : : }
10393 : : }
10394 : :
10395 : 987 : if (assoc.type == NULL_TREE)
10396 : : {
10397 : 392 : if (match_found < 0)
10398 : : {
10399 : 254 : matched_assoc = assoc;
10400 : 290 : match_found = associations.length ();
10401 : : }
10402 : : }
10403 : 595 : else if (match)
10404 : : {
10405 : 412 : if (match_found < 0 || matched_assoc.type == NULL_TREE)
10406 : : {
10407 : 412 : matched_assoc = assoc;
10408 : 634 : match_found = associations.length ();
10409 : : }
10410 : : else
10411 : : {
10412 : 0 : error_at (assoc.type_location,
10413 : : "%<_Generic%> selector matches multiple associations");
10414 : 0 : inform (matched_assoc.type_location,
10415 : : "other match is here");
10416 : : }
10417 : : }
10418 : :
10419 : 987 : associations.safe_push (assoc);
10420 : :
10421 : 987 : if (c_parser_peek_token (parser)->type != CPP_COMMA)
10422 : : break;
10423 : 532 : c_parser_consume_token (parser);
10424 : 532 : }
10425 : :
10426 : 455 : unsigned int ix;
10427 : 455 : struct c_generic_association *iter;
10428 : 1441 : FOR_EACH_VEC_ELT (associations, ix, iter)
10429 : 986 : if (ix != (unsigned) match_found)
10430 : 535 : mark_exp_read (iter->expression.value);
10431 : :
10432 : 455 : if (!parens.require_close (parser))
10433 : : {
10434 : 0 : c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10435 : 0 : return error_expr;
10436 : : }
10437 : :
10438 : 455 : if (match_found < 0)
10439 : : {
10440 : 4 : error_at (selector_loc, "%<_Generic%> selector of type %qT is not "
10441 : : "compatible with any association",
10442 : : selector_type);
10443 : 4 : return error_expr;
10444 : : }
10445 : :
10446 : 451 : return matched_assoc.expression;
10447 : 456 : }
10448 : :
10449 : : /* Check the validity of a function pointer argument *EXPR (argument
10450 : : position POS) to __builtin_tgmath. Return the number of function
10451 : : arguments if possibly valid; return 0 having reported an error if
10452 : : not valid. */
10453 : :
10454 : : static unsigned int
10455 : 1755 : check_tgmath_function (c_expr *expr, unsigned int pos)
10456 : : {
10457 : 1755 : tree type = TREE_TYPE (expr->value);
10458 : 1755 : if (!FUNCTION_POINTER_TYPE_P (type))
10459 : : {
10460 : 2 : error_at (expr->get_location (),
10461 : : "argument %u of %<__builtin_tgmath%> is not a function pointer",
10462 : : pos);
10463 : 2 : return 0;
10464 : : }
10465 : 1753 : type = TREE_TYPE (type);
10466 : 1753 : if (!prototype_p (type))
10467 : : {
10468 : 2 : error_at (expr->get_location (),
10469 : : "argument %u of %<__builtin_tgmath%> is unprototyped", pos);
10470 : 2 : return 0;
10471 : : }
10472 : 1751 : if (stdarg_p (type))
10473 : : {
10474 : 2 : error_at (expr->get_location (),
10475 : : "argument %u of %<__builtin_tgmath%> has variable arguments",
10476 : : pos);
10477 : 2 : return 0;
10478 : : }
10479 : 1749 : unsigned int nargs = 0;
10480 : 1749 : function_args_iterator iter;
10481 : 1749 : tree t;
10482 : 4176 : FOREACH_FUNCTION_ARGS (type, t, iter)
10483 : : {
10484 : 4176 : if (t == void_type_node)
10485 : : break;
10486 : 2427 : nargs++;
10487 : : }
10488 : 1749 : if (nargs == 0)
10489 : : {
10490 : 2 : error_at (expr->get_location (),
10491 : : "argument %u of %<__builtin_tgmath%> has no arguments", pos);
10492 : 2 : return 0;
10493 : : }
10494 : : return nargs;
10495 : : }
10496 : :
10497 : : /* Ways in which a parameter or return value of a type-generic macro
10498 : : may vary between the different functions the macro may call. */
10499 : : enum tgmath_parm_kind
10500 : : {
10501 : : tgmath_fixed, tgmath_real, tgmath_complex
10502 : : };
10503 : :
10504 : : /* Helper function for c_parser_postfix_expression. Parse predefined
10505 : : identifiers. */
10506 : :
10507 : : static struct c_expr
10508 : 11212 : c_parser_predefined_identifier (c_parser *parser)
10509 : : {
10510 : 11212 : location_t loc = c_parser_peek_token (parser)->location;
10511 : 11212 : switch (c_parser_peek_token (parser)->keyword)
10512 : : {
10513 : 553 : case RID_FUNCTION_NAME:
10514 : 553 : pedwarn (loc, OPT_Wpedantic, "ISO C does not support %qs predefined "
10515 : : "identifier", "__FUNCTION__");
10516 : 553 : break;
10517 : 4588 : case RID_PRETTY_FUNCTION_NAME:
10518 : 4588 : pedwarn (loc, OPT_Wpedantic, "ISO C does not support %qs predefined "
10519 : : "identifier", "__PRETTY_FUNCTION__");
10520 : 4588 : break;
10521 : 6071 : case RID_C99_FUNCTION_NAME:
10522 : 6071 : pedwarn_c90 (loc, OPT_Wpedantic, "ISO C90 does not support "
10523 : : "%<__func__%> predefined identifier");
10524 : 6071 : break;
10525 : 0 : default:
10526 : 0 : gcc_unreachable ();
10527 : : }
10528 : :
10529 : 11212 : struct c_expr expr;
10530 : 11212 : expr.original_code = ERROR_MARK;
10531 : 11212 : expr.original_type = NULL;
10532 : 11212 : expr.value = fname_decl (loc, c_parser_peek_token (parser)->keyword,
10533 : 11212 : c_parser_peek_token (parser)->value);
10534 : 11212 : set_c_expr_source_range (&expr, loc, loc);
10535 : 11212 : expr.m_decimal = 0;
10536 : 11212 : c_parser_consume_token (parser);
10537 : 11212 : return expr;
10538 : : }
10539 : :
10540 : : /* Parse a postfix expression (C90 6.3.1-6.3.2, C99 6.5.1-6.5.2,
10541 : : C11 6.5.1-6.5.2). Compound literals aren't handled here; callers have to
10542 : : call c_parser_postfix_expression_after_paren_type on encountering them.
10543 : :
10544 : : postfix-expression:
10545 : : primary-expression
10546 : : postfix-expression [ expression ]
10547 : : postfix-expression ( argument-expression-list[opt] )
10548 : : postfix-expression . identifier
10549 : : postfix-expression -> identifier
10550 : : postfix-expression ++
10551 : : postfix-expression --
10552 : : ( storage-class-specifiers[opt] type-name ) { initializer-list[opt] }
10553 : : ( storage-class-specifiers[opt] type-name ) { initializer-list , }
10554 : :
10555 : : argument-expression-list:
10556 : : argument-expression
10557 : : argument-expression-list , argument-expression
10558 : :
10559 : : primary-expression:
10560 : : identifier
10561 : : constant
10562 : : string-literal
10563 : : ( expression )
10564 : : generic-selection
10565 : :
10566 : : GNU extensions:
10567 : :
10568 : : primary-expression:
10569 : : __func__
10570 : : (treated as a keyword in GNU C)
10571 : : __FUNCTION__
10572 : : __PRETTY_FUNCTION__
10573 : : ( compound-statement )
10574 : : __builtin_va_arg ( assignment-expression , type-name )
10575 : : __builtin_offsetof ( type-name , offsetof-member-designator )
10576 : : __builtin_choose_expr ( assignment-expression ,
10577 : : assignment-expression ,
10578 : : assignment-expression )
10579 : : __builtin_types_compatible_p ( type-name , type-name )
10580 : : __builtin_tgmath ( expr-list )
10581 : : __builtin_complex ( assignment-expression , assignment-expression )
10582 : : __builtin_shuffle ( assignment-expression , assignment-expression )
10583 : : __builtin_shuffle ( assignment-expression ,
10584 : : assignment-expression ,
10585 : : assignment-expression, )
10586 : : __builtin_convertvector ( assignment-expression , type-name )
10587 : : __builtin_assoc_barrier ( assignment-expression )
10588 : :
10589 : : offsetof-member-designator:
10590 : : identifier
10591 : : offsetof-member-designator . identifier
10592 : : offsetof-member-designator [ expression ]
10593 : :
10594 : : Objective-C:
10595 : :
10596 : : primary-expression:
10597 : : [ objc-receiver objc-message-args ]
10598 : : @selector ( objc-selector-arg )
10599 : : @protocol ( identifier )
10600 : : @encode ( type-name )
10601 : : objc-string-literal
10602 : : Classname . identifier
10603 : : */
10604 : :
10605 : : static struct c_expr
10606 : 212664696 : c_parser_postfix_expression (c_parser *parser)
10607 : : {
10608 : 212664696 : struct c_expr expr, e1;
10609 : 212664696 : struct c_type_name *t1, *t2;
10610 : 212664696 : location_t loc = c_parser_peek_token (parser)->location;
10611 : 212664696 : source_range tok_range = c_parser_peek_token (parser)->get_range ();
10612 : 212664696 : expr.original_code = ERROR_MARK;
10613 : 212664696 : expr.original_type = NULL;
10614 : 212664696 : expr.m_decimal = 0;
10615 : 212664696 : switch (c_parser_peek_token (parser)->type)
10616 : : {
10617 : 47682071 : case CPP_NUMBER:
10618 : 47682071 : expr.value = c_parser_peek_token (parser)->value;
10619 : 47682071 : set_c_expr_source_range (&expr, tok_range);
10620 : 47682071 : loc = c_parser_peek_token (parser)->location;
10621 : 47682071 : expr.m_decimal = c_parser_peek_token (parser)->flags & DECIMAL_INT;
10622 : 47682071 : c_parser_consume_token (parser);
10623 : 47682071 : if (TREE_CODE (expr.value) == FIXED_CST
10624 : 47682071 : && !targetm.fixed_point_supported_p ())
10625 : : {
10626 : 5 : error_at (loc, "fixed-point types not supported for this target");
10627 : 5 : expr.set_error ();
10628 : : }
10629 : : break;
10630 : 111996 : case CPP_CHAR:
10631 : 111996 : case CPP_CHAR16:
10632 : 111996 : case CPP_CHAR32:
10633 : 111996 : case CPP_UTF8CHAR:
10634 : 111996 : case CPP_WCHAR:
10635 : 111996 : expr.value = c_parser_peek_token (parser)->value;
10636 : : /* For the purpose of warning when a pointer is compared with
10637 : : a zero character constant. */
10638 : 111996 : expr.original_type = char_type_node;
10639 : 111996 : set_c_expr_source_range (&expr, tok_range);
10640 : 111996 : c_parser_consume_token (parser);
10641 : 111996 : break;
10642 : 1060542 : case CPP_STRING:
10643 : 1060542 : case CPP_STRING16:
10644 : 1060542 : case CPP_STRING32:
10645 : 1060542 : case CPP_WSTRING:
10646 : 1060542 : case CPP_UTF8STRING:
10647 : 1060542 : expr = c_parser_string_literal (parser, parser->translate_strings_p,
10648 : : true);
10649 : 1060542 : break;
10650 : 0 : case CPP_OBJC_STRING:
10651 : 0 : gcc_assert (c_dialect_objc ());
10652 : 0 : expr.value
10653 : 0 : = objc_build_string_object (c_parser_peek_token (parser)->value);
10654 : 0 : set_c_expr_source_range (&expr, tok_range);
10655 : 0 : c_parser_consume_token (parser);
10656 : 0 : break;
10657 : 155293656 : case CPP_NAME:
10658 : 155293656 : switch (c_parser_peek_token (parser)->id_kind)
10659 : : {
10660 : 155293654 : case C_ID_ID:
10661 : 155293654 : {
10662 : 155293654 : tree id = c_parser_peek_token (parser)->value;
10663 : 155293654 : c_parser_consume_token (parser);
10664 : 465880962 : expr.value = build_external_ref (loc, id,
10665 : 155293654 : (c_parser_peek_token (parser)->type
10666 : : == CPP_OPEN_PAREN),
10667 : : &expr.original_type);
10668 : 155293654 : set_c_expr_source_range (&expr, tok_range);
10669 : 155293654 : break;
10670 : : }
10671 : 0 : case C_ID_CLASSNAME:
10672 : 0 : {
10673 : : /* Here we parse the Objective-C 2.0 Class.name dot
10674 : : syntax. */
10675 : 0 : tree class_name = c_parser_peek_token (parser)->value;
10676 : 0 : tree component;
10677 : 0 : c_parser_consume_token (parser);
10678 : 0 : gcc_assert (c_dialect_objc ());
10679 : 0 : if (!c_parser_require (parser, CPP_DOT, "expected %<.%>"))
10680 : : {
10681 : 0 : expr.set_error ();
10682 : 0 : break;
10683 : : }
10684 : 0 : if (c_parser_next_token_is_not (parser, CPP_NAME))
10685 : : {
10686 : 0 : c_parser_error (parser, "expected identifier");
10687 : 0 : expr.set_error ();
10688 : 0 : break;
10689 : : }
10690 : 0 : c_token *component_tok = c_parser_peek_token (parser);
10691 : 0 : component = component_tok->value;
10692 : 0 : location_t end_loc = component_tok->get_finish ();
10693 : 0 : c_parser_consume_token (parser);
10694 : 0 : expr.value = objc_build_class_component_ref (class_name,
10695 : : component);
10696 : 0 : set_c_expr_source_range (&expr, loc, end_loc);
10697 : 0 : break;
10698 : : }
10699 : 2 : default:
10700 : 2 : c_parser_error (parser, "expected expression");
10701 : 2 : expr.set_error ();
10702 : 2 : break;
10703 : : }
10704 : : break;
10705 : 6963581 : case CPP_OPEN_PAREN:
10706 : : /* A parenthesized expression, statement expression or compound
10707 : : literal. */
10708 : 6963581 : if (c_parser_peek_2nd_token (parser)->type == CPP_OPEN_BRACE)
10709 : : {
10710 : : /* A statement expression. */
10711 : 33104 : tree stmt;
10712 : 33104 : location_t brace_loc;
10713 : 33104 : bool save_c_omp_array_section_p = c_omp_array_section_p;
10714 : 33104 : c_parser_consume_token (parser);
10715 : 33104 : brace_loc = c_parser_peek_token (parser)->location;
10716 : 33104 : c_parser_consume_token (parser);
10717 : : /* If we've not yet started the current function's statement list,
10718 : : or we're in the parameter scope of an old-style function
10719 : : declaration, statement expressions are not allowed. */
10720 : 33104 : if (!building_stmt_list_p () || old_style_parameter_scope ())
10721 : : {
10722 : 24 : error_at (loc, "braced-group within expression allowed "
10723 : : "only inside a function");
10724 : 24 : parser->error = true;
10725 : 24 : c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
10726 : 24 : c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10727 : 24 : expr.set_error ();
10728 : 24 : break;
10729 : : }
10730 : 33080 : c_omp_array_section_p = false;
10731 : 33080 : stmt = c_begin_stmt_expr ();
10732 : 33080 : c_parser_compound_statement_nostart (parser);
10733 : 33080 : location_t close_loc = c_parser_peek_token (parser)->location;
10734 : 33080 : c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
10735 : : "expected %<)%>");
10736 : 33080 : pedwarn (loc, OPT_Wpedantic,
10737 : : "ISO C forbids braced-groups within expressions");
10738 : 33080 : expr.value = c_finish_stmt_expr (brace_loc, stmt);
10739 : 33080 : set_c_expr_source_range (&expr, loc, close_loc);
10740 : 33080 : mark_exp_read (expr.value);
10741 : 33080 : c_omp_array_section_p = save_c_omp_array_section_p;
10742 : : }
10743 : : else
10744 : : {
10745 : : /* A parenthesized expression. */
10746 : 6930477 : location_t loc_open_paren = c_parser_peek_token (parser)->location;
10747 : 6930477 : c_parser_consume_token (parser);
10748 : 6930477 : expr = c_parser_expression (parser);
10749 : 6930477 : if (TREE_CODE (expr.value) == MODIFY_EXPR)
10750 : 36173 : suppress_warning (expr.value, OPT_Wparentheses);
10751 : 6930477 : if (expr.original_code != C_MAYBE_CONST_EXPR
10752 : 6930465 : && expr.original_code != SIZEOF_EXPR)
10753 : 6925635 : expr.original_code = ERROR_MARK;
10754 : : /* Remember that we saw ( ) around the sizeof. */
10755 : 6930477 : if (expr.original_code == SIZEOF_EXPR)
10756 : 4830 : expr.original_code = PAREN_SIZEOF_EXPR;
10757 : : /* Don't change EXPR.ORIGINAL_TYPE. */
10758 : 6930477 : location_t loc_close_paren = c_parser_peek_token (parser)->location;
10759 : 6930477 : set_c_expr_source_range (&expr, loc_open_paren, loc_close_paren);
10760 : 6930477 : c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
10761 : : "expected %<)%>", loc_open_paren);
10762 : : }
10763 : : break;
10764 : 1552085 : case CPP_KEYWORD:
10765 : 1552085 : switch (c_parser_peek_token (parser)->keyword)
10766 : : {
10767 : 11192 : case RID_FUNCTION_NAME:
10768 : 11192 : case RID_PRETTY_FUNCTION_NAME:
10769 : 11192 : case RID_C99_FUNCTION_NAME:
10770 : 11192 : expr = c_parser_predefined_identifier (parser);
10771 : 11192 : break;
10772 : 19895 : case RID_VA_ARG:
10773 : 19895 : {
10774 : 19895 : location_t start_loc = loc;
10775 : 19895 : c_parser_consume_token (parser);
10776 : 19895 : matching_parens parens;
10777 : 19895 : if (!parens.require_open (parser))
10778 : : {
10779 : 0 : expr.set_error ();
10780 : 0 : break;
10781 : : }
10782 : 19895 : e1 = c_parser_expr_no_commas (parser, NULL);
10783 : 19895 : mark_exp_read (e1.value);
10784 : 19895 : e1.value = c_fully_fold (e1.value, false, NULL);
10785 : 19895 : if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
10786 : : {
10787 : 0 : c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10788 : 0 : expr.set_error ();
10789 : 0 : break;
10790 : : }
10791 : 19895 : loc = c_parser_peek_token (parser)->location;
10792 : 19895 : t1 = c_parser_type_name (parser);
10793 : 19895 : location_t end_loc = c_parser_peek_token (parser)->get_finish ();
10794 : 19895 : c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
10795 : : "expected %<)%>");
10796 : 19895 : if (t1 == NULL)
10797 : : {
10798 : 0 : expr.set_error ();
10799 : : }
10800 : : else
10801 : : {
10802 : 19895 : tree type_expr = NULL_TREE;
10803 : 19895 : expr.value = c_build_va_arg (start_loc, e1.value, loc,
10804 : : groktypename (t1, &type_expr, NULL));
10805 : 19895 : if (type_expr)
10806 : : {
10807 : 24 : expr.value = build2 (C_MAYBE_CONST_EXPR,
10808 : 24 : TREE_TYPE (expr.value), type_expr,
10809 : : expr.value);
10810 : 24 : C_MAYBE_CONST_EXPR_NON_CONST (expr.value) = true;
10811 : : }
10812 : 19895 : set_c_expr_source_range (&expr, start_loc, end_loc);
10813 : : }
10814 : : }
10815 : 19895 : break;
10816 : 3513 : case RID_OFFSETOF:
10817 : 3513 : {
10818 : 3513 : c_parser_consume_token (parser);
10819 : 3513 : matching_parens parens;
10820 : 3513 : if (!parens.require_open (parser))
10821 : : {
10822 : 0 : expr.set_error ();
10823 : 1 : break;
10824 : : }
10825 : 3513 : t1 = c_parser_type_name (parser);
10826 : 3513 : if (t1 == NULL)
10827 : 0 : parser->error = true;
10828 : 3513 : if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
10829 : 1 : gcc_assert (parser->error);
10830 : 3513 : if (parser->error)
10831 : : {
10832 : 1 : c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10833 : 1 : expr.set_error ();
10834 : 1 : break;
10835 : : }
10836 : 3512 : tree type = groktypename (t1, NULL, NULL);
10837 : 3512 : tree offsetof_ref;
10838 : 3512 : if (type == error_mark_node)
10839 : : offsetof_ref = error_mark_node;
10840 : : else
10841 : : {
10842 : 3511 : offsetof_ref = build1 (INDIRECT_REF, type, null_pointer_node);
10843 : 3511 : SET_EXPR_LOCATION (offsetof_ref, loc);
10844 : : }
10845 : : /* Parse the second argument to __builtin_offsetof. We
10846 : : must have one identifier, and beyond that we want to
10847 : : accept sub structure and sub array references. */
10848 : 3512 : if (c_parser_next_token_is (parser, CPP_NAME))
10849 : : {
10850 : 3512 : c_token *comp_tok = c_parser_peek_token (parser);
10851 : 3512 : offsetof_ref
10852 : 3512 : = build_component_ref (loc, offsetof_ref, comp_tok->value,
10853 : : comp_tok->location, UNKNOWN_LOCATION);
10854 : 3512 : c_parser_consume_token (parser);
10855 : 3512 : while (c_parser_next_token_is (parser, CPP_DOT)
10856 : 3958 : || c_parser_next_token_is (parser,
10857 : : CPP_OPEN_SQUARE)
10858 : 7706 : || c_parser_next_token_is (parser,
10859 : : CPP_DEREF))
10860 : : {
10861 : 681 : if (c_parser_next_token_is (parser, CPP_DEREF))
10862 : : {
10863 : 1 : loc = c_parser_peek_token (parser)->location;
10864 : 1 : offsetof_ref = build_array_ref (loc,
10865 : : offsetof_ref,
10866 : : integer_zero_node);
10867 : 1 : goto do_dot;
10868 : : }
10869 : 680 : else if (c_parser_next_token_is (parser, CPP_DOT))
10870 : : {
10871 : 235 : do_dot:
10872 : 236 : c_parser_consume_token (parser);
10873 : 236 : if (c_parser_next_token_is_not (parser,
10874 : : CPP_NAME))
10875 : : {
10876 : 0 : c_parser_error (parser, "expected identifier");
10877 : 0 : break;
10878 : : }
10879 : 236 : c_token *comp_tok = c_parser_peek_token (parser);
10880 : 236 : offsetof_ref
10881 : 236 : = build_component_ref (loc, offsetof_ref,
10882 : : comp_tok->value,
10883 : : comp_tok->location,
10884 : : UNKNOWN_LOCATION);
10885 : 236 : c_parser_consume_token (parser);
10886 : : }
10887 : : else
10888 : : {
10889 : 445 : struct c_expr ce;
10890 : 445 : tree idx;
10891 : 445 : loc = c_parser_peek_token (parser)->location;
10892 : 445 : c_parser_consume_token (parser);
10893 : 445 : ce = c_parser_expression (parser);
10894 : 445 : ce = convert_lvalue_to_rvalue (loc, ce, false, false);
10895 : 445 : idx = ce.value;
10896 : 445 : idx = c_fully_fold (idx, false, NULL);
10897 : 445 : c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
10898 : : "expected %<]%>");
10899 : 445 : offsetof_ref = build_array_ref (loc, offsetof_ref, idx);
10900 : : }
10901 : : }
10902 : : }
10903 : : else
10904 : 0 : c_parser_error (parser, "expected identifier");
10905 : 3512 : location_t end_loc = c_parser_peek_token (parser)->get_finish ();
10906 : 3512 : c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
10907 : : "expected %<)%>");
10908 : 3512 : expr.value = fold_offsetof (offsetof_ref);
10909 : 3512 : set_c_expr_source_range (&expr, loc, end_loc);
10910 : : }
10911 : 3512 : break;
10912 : 1183 : case RID_CHOOSE_EXPR:
10913 : 1183 : {
10914 : 1183 : vec<c_expr_t, va_gc> *cexpr_list;
10915 : 1183 : c_expr_t *e1_p, *e2_p, *e3_p;
10916 : 1183 : tree c;
10917 : 1183 : location_t close_paren_loc;
10918 : :
10919 : 1183 : c_parser_consume_token (parser);
10920 : 1183 : if (!c_parser_get_builtin_args (parser,
10921 : : "__builtin_choose_expr",
10922 : : &cexpr_list, true,
10923 : : &close_paren_loc))
10924 : : {
10925 : 0 : expr.set_error ();
10926 : 0 : break;
10927 : : }
10928 : :
10929 : 1183 : if (vec_safe_length (cexpr_list) != 3)
10930 : : {
10931 : 0 : error_at (loc, "wrong number of arguments to "
10932 : : "%<__builtin_choose_expr%>");
10933 : 0 : expr.set_error ();
10934 : 0 : break;
10935 : : }
10936 : :
10937 : 1183 : e1_p = &(*cexpr_list)[0];
10938 : 1183 : e2_p = &(*cexpr_list)[1];
10939 : 1183 : e3_p = &(*cexpr_list)[2];
10940 : :
10941 : 1183 : c = e1_p->value;
10942 : 1183 : mark_exp_read (e2_p->value);
10943 : 1183 : mark_exp_read (e3_p->value);
10944 : 1183 : if (TREE_CODE (c) != INTEGER_CST
10945 : 1183 : || !INTEGRAL_TYPE_P (TREE_TYPE (c)))
10946 : 7 : error_at (loc,
10947 : : "first argument to %<__builtin_choose_expr%> not"
10948 : : " a constant");
10949 : 1183 : constant_expression_warning (c);
10950 : 1183 : expr = integer_zerop (c) ? *e3_p : *e2_p;
10951 : 1183 : set_c_expr_source_range (&expr, loc, close_paren_loc);
10952 : 1183 : break;
10953 : : }
10954 : 667 : case RID_TYPES_COMPATIBLE_P:
10955 : 667 : {
10956 : 667 : c_parser_consume_token (parser);
10957 : 667 : matching_parens parens;
10958 : 667 : if (!parens.require_open (parser))
10959 : : {
10960 : 0 : expr.set_error ();
10961 : 2 : break;
10962 : : }
10963 : 667 : t1 = c_parser_type_name (parser);
10964 : 667 : if (t1 == NULL)
10965 : : {
10966 : 0 : expr.set_error ();
10967 : 0 : break;
10968 : : }
10969 : 667 : if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
10970 : : {
10971 : 1 : c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10972 : 1 : expr.set_error ();
10973 : 1 : break;
10974 : : }
10975 : 666 : t2 = c_parser_type_name (parser);
10976 : 666 : if (t2 == NULL)
10977 : : {
10978 : 0 : expr.set_error ();
10979 : 0 : break;
10980 : : }
10981 : 666 : location_t close_paren_loc = c_parser_peek_token (parser)->location;
10982 : 666 : parens.skip_until_found_close (parser);
10983 : 666 : tree e1, e2;
10984 : 666 : e1 = groktypename (t1, NULL, NULL);
10985 : 666 : e2 = groktypename (t2, NULL, NULL);
10986 : 666 : if (e1 == error_mark_node || e2 == error_mark_node)
10987 : : {
10988 : 1 : expr.set_error ();
10989 : 1 : break;
10990 : : }
10991 : :
10992 : 665 : e1 = TYPE_MAIN_VARIANT (e1);
10993 : 665 : e2 = TYPE_MAIN_VARIANT (e2);
10994 : :
10995 : 665 : expr.value
10996 : 665 : = comptypes (e1, e2) ? integer_one_node : integer_zero_node;
10997 : 665 : set_c_expr_source_range (&expr, loc, close_paren_loc);
10998 : : }
10999 : 665 : break;
11000 : 356 : case RID_BUILTIN_TGMATH:
11001 : 356 : {
11002 : 356 : vec<c_expr_t, va_gc> *cexpr_list;
11003 : 356 : location_t close_paren_loc;
11004 : :
11005 : 356 : c_parser_consume_token (parser);
11006 : 356 : if (!c_parser_get_builtin_args (parser,
11007 : : "__builtin_tgmath",
11008 : : &cexpr_list, false,
11009 : : &close_paren_loc))
11010 : : {
11011 : 0 : expr.set_error ();
11012 : 327 : break;
11013 : : }
11014 : :
11015 : 356 : if (vec_safe_length (cexpr_list) < 3)
11016 : : {
11017 : 3 : error_at (loc, "too few arguments to %<__builtin_tgmath%>");
11018 : 3 : expr.set_error ();
11019 : 3 : break;
11020 : : }
11021 : :
11022 : : unsigned int i;
11023 : : c_expr_t *p;
11024 : 2587 : FOR_EACH_VEC_ELT (*cexpr_list, i, p)
11025 : 2234 : *p = convert_lvalue_to_rvalue (loc, *p, true, true);
11026 : 353 : unsigned int nargs = check_tgmath_function (&(*cexpr_list)[0], 1);
11027 : 353 : if (nargs == 0)
11028 : : {
11029 : 4 : expr.set_error ();
11030 : 4 : break;
11031 : : }
11032 : 698 : if (vec_safe_length (cexpr_list) < nargs)
11033 : : {
11034 : 1 : error_at (loc, "too few arguments to %<__builtin_tgmath%>");
11035 : 1 : expr.set_error ();
11036 : 1 : break;
11037 : : }
11038 : 348 : unsigned int num_functions = vec_safe_length (cexpr_list) - nargs;
11039 : 348 : if (num_functions < 2)
11040 : : {
11041 : 1 : error_at (loc, "too few arguments to %<__builtin_tgmath%>");
11042 : 1 : expr.set_error ();
11043 : 1 : break;
11044 : : }
11045 : :
11046 : : /* The first NUM_FUNCTIONS expressions are the function
11047 : : pointers. The remaining NARGS expressions are the
11048 : : arguments that are to be passed to one of those
11049 : : functions, chosen following <tgmath.h> rules. */
11050 : 1744 : for (unsigned int j = 1; j < num_functions; j++)
11051 : : {
11052 : 1402 : unsigned int this_nargs
11053 : 1402 : = check_tgmath_function (&(*cexpr_list)[j], j + 1);
11054 : 1402 : if (this_nargs == 0)
11055 : : {
11056 : 4 : expr.set_error ();
11057 : 29 : goto out;
11058 : : }
11059 : 1398 : if (this_nargs != nargs)
11060 : : {
11061 : 1 : error_at ((*cexpr_list)[j].get_location (),
11062 : : "argument %u of %<__builtin_tgmath%> has "
11063 : : "wrong number of arguments", j + 1);
11064 : 1 : expr.set_error ();
11065 : 1 : goto out;
11066 : : }
11067 : : }
11068 : :
11069 : : /* The functions all have the same number of arguments.
11070 : : Determine whether arguments and return types vary in
11071 : : ways permitted for <tgmath.h> functions. */
11072 : : /* The first entry in each of these vectors is for the
11073 : : return type, subsequent entries for parameter
11074 : : types. */
11075 : 342 : auto_vec<enum tgmath_parm_kind> parm_kind (nargs + 1);
11076 : 342 : auto_vec<tree> parm_first (nargs + 1);
11077 : 342 : auto_vec<bool> parm_complex (nargs + 1);
11078 : 342 : auto_vec<bool> parm_varies (nargs + 1);
11079 : 342 : tree first_type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[0].value));
11080 : 342 : tree first_ret = TYPE_MAIN_VARIANT (TREE_TYPE (first_type));
11081 : 342 : parm_first.quick_push (first_ret);
11082 : 342 : parm_complex.quick_push (TREE_CODE (first_ret) == COMPLEX_TYPE);
11083 : 342 : parm_varies.quick_push (false);
11084 : 342 : function_args_iterator iter;
11085 : 342 : tree t;
11086 : 342 : unsigned int argpos;
11087 : 802 : FOREACH_FUNCTION_ARGS (first_type, t, iter)
11088 : : {
11089 : 802 : if (t == void_type_node)
11090 : : break;
11091 : 460 : parm_first.quick_push (TYPE_MAIN_VARIANT (t));
11092 : 460 : parm_complex.quick_push (TREE_CODE (t) == COMPLEX_TYPE);
11093 : 460 : parm_varies.quick_push (false);
11094 : : }
11095 : 1727 : for (unsigned int j = 1; j < num_functions; j++)
11096 : : {
11097 : 1397 : tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
11098 : 1397 : tree ret = TYPE_MAIN_VARIANT (TREE_TYPE (type));
11099 : 1397 : if (ret != parm_first[0])
11100 : : {
11101 : 1294 : parm_varies[0] = true;
11102 : 1294 : if (!SCALAR_FLOAT_TYPE_P (parm_first[0])
11103 : 1294 : && !COMPLEX_FLOAT_TYPE_P (parm_first[0]))
11104 : : {
11105 : 3 : error_at ((*cexpr_list)[0].get_location (),
11106 : : "invalid type-generic return type for "
11107 : : "argument %u of %<__builtin_tgmath%>",
11108 : : 1);
11109 : 3 : expr.set_error ();
11110 : 3 : goto out;
11111 : : }
11112 : 1291 : if (!SCALAR_FLOAT_TYPE_P (ret)
11113 : 1291 : && !COMPLEX_FLOAT_TYPE_P (ret))
11114 : : {
11115 : 3 : error_at ((*cexpr_list)[j].get_location (),
11116 : : "invalid type-generic return type for "
11117 : : "argument %u of %<__builtin_tgmath%>",
11118 : : j + 1);
11119 : 3 : expr.set_error ();
11120 : 3 : goto out;
11121 : : }
11122 : : }
11123 : 1391 : if (TREE_CODE (ret) == COMPLEX_TYPE)
11124 : 342 : parm_complex[0] = true;
11125 : 1391 : argpos = 1;
11126 : 3329 : FOREACH_FUNCTION_ARGS (type, t, iter)
11127 : : {
11128 : 3329 : if (t == void_type_node)
11129 : : break;
11130 : 1944 : t = TYPE_MAIN_VARIANT (t);
11131 : 1944 : if (t != parm_first[argpos])
11132 : : {
11133 : 1919 : parm_varies[argpos] = true;
11134 : 1919 : if (!SCALAR_FLOAT_TYPE_P (parm_first[argpos])
11135 : 1919 : && !COMPLEX_FLOAT_TYPE_P (parm_first[argpos]))
11136 : : {
11137 : 3 : error_at ((*cexpr_list)[0].get_location (),
11138 : : "invalid type-generic type for "
11139 : : "argument %u of argument %u of "
11140 : : "%<__builtin_tgmath%>", argpos, 1);
11141 : 3 : expr.set_error ();
11142 : 3 : goto out;
11143 : : }
11144 : 1916 : if (!SCALAR_FLOAT_TYPE_P (t)
11145 : 1916 : && !COMPLEX_FLOAT_TYPE_P (t))
11146 : : {
11147 : 3 : error_at ((*cexpr_list)[j].get_location (),
11148 : : "invalid type-generic type for "
11149 : : "argument %u of argument %u of "
11150 : : "%<__builtin_tgmath%>", argpos, j + 1);
11151 : 3 : expr.set_error ();
11152 : 3 : goto out;
11153 : : }
11154 : : }
11155 : 1938 : if (TREE_CODE (t) == COMPLEX_TYPE)
11156 : 674 : parm_complex[argpos] = true;
11157 : 1938 : argpos++;
11158 : : }
11159 : : }
11160 : : enum tgmath_parm_kind max_variation = tgmath_fixed;
11161 : 1108 : for (unsigned int j = 0; j <= nargs; j++)
11162 : : {
11163 : 778 : enum tgmath_parm_kind this_kind;
11164 : 778 : if (parm_varies[j])
11165 : : {
11166 : 731 : if (parm_complex[j])
11167 : 394 : max_variation = this_kind = tgmath_complex;
11168 : : else
11169 : : {
11170 : 337 : this_kind = tgmath_real;
11171 : 337 : if (max_variation != tgmath_complex)
11172 : 778 : max_variation = tgmath_real;
11173 : : }
11174 : : }
11175 : : else
11176 : 47 : this_kind = tgmath_fixed;
11177 : 778 : parm_kind.quick_push (this_kind);
11178 : : }
11179 : 330 : if (max_variation == tgmath_fixed)
11180 : : {
11181 : 1 : error_at (loc, "function arguments of %<__builtin_tgmath%> "
11182 : : "all have the same type");
11183 : 1 : expr.set_error ();
11184 : 1 : break;
11185 : : }
11186 : :
11187 : : /* Identify a parameter (not the return type) that varies,
11188 : : including with complex types if any variation includes
11189 : : complex types; there must be at least one such
11190 : : parameter. */
11191 : 341 : unsigned int tgarg = 0;
11192 : 341 : for (unsigned int j = 1; j <= nargs; j++)
11193 : 339 : if (parm_kind[j] == max_variation)
11194 : : {
11195 : : tgarg = j;
11196 : : break;
11197 : : }
11198 : 329 : if (tgarg == 0)
11199 : : {
11200 : 2 : error_at (loc, "function arguments of %<__builtin_tgmath%> "
11201 : : "lack type-generic parameter");
11202 : 2 : expr.set_error ();
11203 : 2 : break;
11204 : : }
11205 : :
11206 : : /* Determine the type of the relevant parameter for each
11207 : : function. */
11208 : 327 : auto_vec<tree> tg_type (num_functions);
11209 : 2035 : for (unsigned int j = 0; j < num_functions; j++)
11210 : : {
11211 : 1708 : tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
11212 : 1708 : argpos = 1;
11213 : 1738 : FOREACH_FUNCTION_ARGS (type, t, iter)
11214 : : {
11215 : 1738 : if (argpos == tgarg)
11216 : : {
11217 : 1708 : tg_type.quick_push (TYPE_MAIN_VARIANT (t));
11218 : 1708 : break;
11219 : : }
11220 : 30 : argpos++;
11221 : : }
11222 : : }
11223 : :
11224 : : /* Verify that the corresponding types are different for
11225 : : all the listed functions. Also determine whether all
11226 : : the types are complex, whether all the types are
11227 : : standard or binary, and whether all the types are
11228 : : decimal. */
11229 : 327 : bool all_complex = true;
11230 : 327 : bool all_binary = true;
11231 : 327 : bool all_decimal = true;
11232 : 327 : hash_set<tree> tg_types;
11233 : 2687 : FOR_EACH_VEC_ELT (tg_type, i, t)
11234 : : {
11235 : 1708 : if (TREE_CODE (t) == COMPLEX_TYPE)
11236 : : all_decimal = false;
11237 : : else
11238 : : {
11239 : 1186 : all_complex = false;
11240 : 1186 : if (DECIMAL_FLOAT_TYPE_P (t))
11241 : : all_binary = false;
11242 : : else
11243 : : all_decimal = false;
11244 : : }
11245 : 1708 : if (tg_types.add (t))
11246 : : {
11247 : 1 : error_at ((*cexpr_list)[i].get_location (),
11248 : : "duplicate type-generic parameter type for "
11249 : : "function argument %u of %<__builtin_tgmath%>",
11250 : : i + 1);
11251 : 1 : expr.set_error ();
11252 : 1 : goto out;
11253 : : }
11254 : : }
11255 : :
11256 : : /* Verify that other parameters and the return type whose
11257 : : types vary have their types varying in the correct
11258 : : way. */
11259 : 2029 : for (unsigned int j = 0; j < num_functions; j++)
11260 : : {
11261 : 1705 : tree exp_type = tg_type[j];
11262 : 1705 : tree exp_real_type = exp_type;
11263 : 1705 : if (TREE_CODE (exp_type) == COMPLEX_TYPE)
11264 : 522 : exp_real_type = TREE_TYPE (exp_type);
11265 : 1705 : tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
11266 : 1705 : tree ret = TYPE_MAIN_VARIANT (TREE_TYPE (type));
11267 : 2606 : if ((parm_kind[0] == tgmath_complex && ret != exp_type)
11268 : 2606 : || (parm_kind[0] == tgmath_real && ret != exp_real_type))
11269 : : {
11270 : 1 : error_at ((*cexpr_list)[j].get_location (),
11271 : : "bad return type for function argument %u "
11272 : : "of %<__builtin_tgmath%>", j + 1);
11273 : 1 : expr.set_error ();
11274 : 1 : goto out;
11275 : : }
11276 : 1704 : argpos = 1;
11277 : 4078 : FOREACH_FUNCTION_ARGS (type, t, iter)
11278 : : {
11279 : 4078 : if (t == void_type_node)
11280 : : break;
11281 : 2375 : t = TYPE_MAIN_VARIANT (t);
11282 : 2375 : if ((parm_kind[argpos] == tgmath_complex
11283 : 1787 : && t != exp_type)
11284 : 4162 : || (parm_kind[argpos] == tgmath_real
11285 : 558 : && t != exp_real_type))
11286 : : {
11287 : 1 : error_at ((*cexpr_list)[j].get_location (),
11288 : : "bad type for argument %u of "
11289 : : "function argument %u of "
11290 : : "%<__builtin_tgmath%>", argpos, j + 1);
11291 : 1 : expr.set_error ();
11292 : 1 : goto out;
11293 : : }
11294 : 2374 : argpos++;
11295 : : }
11296 : : }
11297 : :
11298 : : /* The functions listed are a valid set of functions for a
11299 : : <tgmath.h> macro to select between. Identify the
11300 : : matching function, if any. First, the argument types
11301 : : must be combined following <tgmath.h> rules. Integer
11302 : : types are treated as _Decimal64 if any type-generic
11303 : : argument is decimal, or if the only alternatives for
11304 : : type-generic arguments are of decimal types, and are
11305 : : otherwise treated as _Float32x (or _Complex _Float32x
11306 : : for complex integer types) if any type-generic argument
11307 : : has _FloatNx type, otherwise as double (or _Complex
11308 : : double for complex integer types). After that
11309 : : adjustment, types are combined following the usual
11310 : : arithmetic conversions. If the function only accepts
11311 : : complex arguments, a complex type is produced. */
11312 : : bool arg_complex = all_complex;
11313 : : bool arg_binary = all_binary;
11314 : : bool arg_int_decimal = all_decimal;
11315 : : bool arg_int_floatnx = false;
11316 : 756 : for (unsigned int j = 1; j <= nargs; j++)
11317 : : {
11318 : 441 : if (parm_kind[j] == tgmath_fixed)
11319 : 10 : continue;
11320 : 431 : c_expr_t *ce = &(*cexpr_list)[num_functions + j - 1];
11321 : 431 : tree type = TREE_TYPE (ce->value);
11322 : 431 : if (!INTEGRAL_TYPE_P (type)
11323 : 431 : && !SCALAR_FLOAT_TYPE_P (type)
11324 : 89 : && TREE_CODE (type) != COMPLEX_TYPE)
11325 : : {
11326 : 1 : error_at (ce->get_location (),
11327 : : "invalid type of argument %u of type-generic "
11328 : : "function", j);
11329 : 1 : expr.set_error ();
11330 : 1 : goto out;
11331 : : }
11332 : 430 : if (DECIMAL_FLOAT_TYPE_P (type))
11333 : : {
11334 : 68 : arg_int_decimal = true;
11335 : 68 : if (all_complex)
11336 : : {
11337 : 1 : error_at (ce->get_location (),
11338 : : "decimal floating-point argument %u to "
11339 : : "complex-only type-generic function", j);
11340 : 1 : expr.set_error ();
11341 : 1 : goto out;
11342 : : }
11343 : 67 : else if (all_binary)
11344 : : {
11345 : 1 : error_at (ce->get_location (),
11346 : : "decimal floating-point argument %u to "
11347 : : "binary-only type-generic function", j);
11348 : 1 : expr.set_error ();
11349 : 1 : goto out;
11350 : : }
11351 : 66 : else if (arg_complex)
11352 : : {
11353 : 1 : error_at (ce->get_location (),
11354 : : "both complex and decimal floating-point "
11355 : : "arguments to type-generic function");
11356 : 1 : expr.set_error ();
11357 : 1 : goto out;
11358 : : }
11359 : 65 : else if (arg_binary)
11360 : : {
11361 : 1 : error_at (ce->get_location (),
11362 : : "both binary and decimal floating-point "
11363 : : "arguments to type-generic function");
11364 : 1 : expr.set_error ();
11365 : 1 : goto out;
11366 : : }
11367 : : }
11368 : 362 : else if (TREE_CODE (type) == COMPLEX_TYPE)
11369 : : {
11370 : 88 : arg_complex = true;
11371 : 88 : if (COMPLEX_FLOAT_TYPE_P (type))
11372 : : arg_binary = true;
11373 : 88 : if (all_decimal)
11374 : : {
11375 : 1 : error_at (ce->get_location (),
11376 : : "complex argument %u to "
11377 : : "decimal-only type-generic function", j);
11378 : 1 : expr.set_error ();
11379 : 1 : goto out;
11380 : : }
11381 : 87 : else if (arg_int_decimal)
11382 : : {
11383 : 1 : error_at (ce->get_location (),
11384 : : "both complex and decimal floating-point "
11385 : : "arguments to type-generic function");
11386 : 1 : expr.set_error ();
11387 : 1 : goto out;
11388 : : }
11389 : : }
11390 : 274 : else if (SCALAR_FLOAT_TYPE_P (type))
11391 : : {
11392 : 180 : arg_binary = true;
11393 : 180 : if (all_decimal)
11394 : : {
11395 : 1 : error_at (ce->get_location (),
11396 : : "binary argument %u to "
11397 : : "decimal-only type-generic function", j);
11398 : 1 : expr.set_error ();
11399 : 1 : goto out;
11400 : : }
11401 : 179 : else if (arg_int_decimal)
11402 : : {
11403 : 1 : error_at (ce->get_location (),
11404 : : "both binary and decimal floating-point "
11405 : : "arguments to type-generic function");
11406 : 1 : expr.set_error ();
11407 : 1 : goto out;
11408 : : }
11409 : : }
11410 : 422 : tree rtype = TYPE_MAIN_VARIANT (type);
11411 : 422 : if (TREE_CODE (rtype) == COMPLEX_TYPE)
11412 : 86 : rtype = TREE_TYPE (rtype);
11413 : 422 : if (SCALAR_FLOAT_TYPE_P (rtype))
11414 : 1208 : for (unsigned int j = 0; j < NUM_FLOATNX_TYPES; j++)
11415 : 908 : if (rtype == FLOATNX_TYPE_NODE (j))
11416 : : {
11417 : : arg_int_floatnx = true;
11418 : : break;
11419 : : }
11420 : : }
11421 : : tree arg_real = NULL_TREE;
11422 : 743 : for (unsigned int j = 1; j <= nargs; j++)
11423 : : {
11424 : 428 : if (parm_kind[j] == tgmath_fixed)
11425 : 10 : continue;
11426 : 418 : c_expr_t *ce = &(*cexpr_list)[num_functions + j - 1];
11427 : 418 : tree type = TYPE_MAIN_VARIANT (TREE_TYPE (ce->value));
11428 : 418 : if (TREE_CODE (type) == COMPLEX_TYPE)
11429 : 85 : type = TREE_TYPE (type);
11430 : 418 : if (INTEGRAL_TYPE_P (type))
11431 : 114 : type = (arg_int_decimal
11432 : 114 : ? dfloat64_type_node
11433 : : : arg_int_floatnx
11434 : 98 : ? float32x_type_node
11435 : : : double_type_node);
11436 : 418 : if (arg_real == NULL_TREE)
11437 : : arg_real = type;
11438 : : else
11439 : 103 : arg_real = common_type (arg_real, type);
11440 : 418 : if (arg_real == error_mark_node)
11441 : : {
11442 : 0 : expr.set_error ();
11443 : 0 : goto out;
11444 : : }
11445 : : }
11446 : 315 : tree arg_type = (arg_complex
11447 : 315 : ? build_complex_type (arg_real)
11448 : 315 : : arg_real);
11449 : :
11450 : : /* Look for a function to call with type-generic parameter
11451 : : type ARG_TYPE. */
11452 : 315 : c_expr_t *fn = NULL;
11453 : 976 : for (unsigned int j = 0; j < num_functions; j++)
11454 : : {
11455 : 970 : if (tg_type[j] == arg_type)
11456 : : {
11457 : 309 : fn = &(*cexpr_list)[j];
11458 : 309 : break;
11459 : : }
11460 : : }
11461 : 315 : if (fn == NULL
11462 : 6 : && parm_kind[0] == tgmath_fixed
11463 : 319 : && SCALAR_FLOAT_TYPE_P (parm_first[0]))
11464 : : {
11465 : : /* Presume this is a macro that rounds its result to a
11466 : : narrower type, and look for the first function with
11467 : : at least the range and precision of the argument
11468 : : type. */
11469 : 4 : for (unsigned int j = 0; j < num_functions; j++)
11470 : : {
11471 : 8 : if (arg_complex
11472 : 4 : != (TREE_CODE (tg_type[j]) == COMPLEX_TYPE))
11473 : 0 : continue;
11474 : 4 : tree real_tg_type = (arg_complex
11475 : 4 : ? TREE_TYPE (tg_type[j])
11476 : 4 : : tg_type[j]);
11477 : 8 : if (DECIMAL_FLOAT_TYPE_P (arg_real)
11478 : 4 : != DECIMAL_FLOAT_TYPE_P (real_tg_type))
11479 : 0 : continue;
11480 : 4 : scalar_float_mode arg_mode
11481 : 4 : = SCALAR_FLOAT_TYPE_MODE (arg_real);
11482 : 4 : scalar_float_mode tg_mode
11483 : 4 : = SCALAR_FLOAT_TYPE_MODE (real_tg_type);
11484 : 4 : const real_format *arg_fmt = REAL_MODE_FORMAT (arg_mode);
11485 : 4 : const real_format *tg_fmt = REAL_MODE_FORMAT (tg_mode);
11486 : 4 : if (arg_fmt->b == tg_fmt->b
11487 : 4 : && arg_fmt->p <= tg_fmt->p
11488 : 4 : && arg_fmt->emax <= tg_fmt->emax
11489 : 4 : && (arg_fmt->emin - arg_fmt->p
11490 : 4 : >= tg_fmt->emin - tg_fmt->p))
11491 : : {
11492 : 4 : fn = &(*cexpr_list)[j];
11493 : 4 : break;
11494 : : }
11495 : : }
11496 : : }
11497 : 315 : if (fn == NULL)
11498 : : {
11499 : 2 : error_at (loc, "no matching function for type-generic call");
11500 : 2 : expr.set_error ();
11501 : 2 : break;
11502 : : }
11503 : :
11504 : : /* Construct a call to FN. */
11505 : 313 : vec<tree, va_gc> *args;
11506 : 313 : vec_alloc (args, nargs);
11507 : 313 : vec<tree, va_gc> *origtypes;
11508 : 313 : vec_alloc (origtypes, nargs);
11509 : 313 : auto_vec<location_t> arg_loc (nargs);
11510 : 739 : for (unsigned int j = 0; j < nargs; j++)
11511 : : {
11512 : 426 : c_expr_t *ce = &(*cexpr_list)[num_functions + j];
11513 : 426 : args->quick_push (ce->value);
11514 : 426 : arg_loc.quick_push (ce->get_location ());
11515 : 426 : origtypes->quick_push (ce->original_type);
11516 : : }
11517 : 313 : expr.value = c_build_function_call_vec (loc, arg_loc, fn->value,
11518 : : args, origtypes);
11519 : 313 : set_c_expr_source_range (&expr, loc, close_paren_loc);
11520 : 313 : break;
11521 : 982 : }
11522 : 22 : case RID_BUILTIN_CALL_WITH_STATIC_CHAIN:
11523 : 22 : {
11524 : 22 : vec<c_expr_t, va_gc> *cexpr_list;
11525 : 22 : c_expr_t *e2_p;
11526 : 22 : tree chain_value;
11527 : 22 : location_t close_paren_loc;
11528 : :
11529 : 22 : c_parser_consume_token (parser);
11530 : 22 : if (!c_parser_get_builtin_args (parser,
11531 : : "__builtin_call_with_static_chain",
11532 : : &cexpr_list, false,
11533 : : &close_paren_loc))
11534 : : {
11535 : 0 : expr.set_error ();
11536 : 0 : break;
11537 : : }
11538 : 22 : if (vec_safe_length (cexpr_list) != 2)
11539 : : {
11540 : 0 : error_at (loc, "wrong number of arguments to "
11541 : : "%<__builtin_call_with_static_chain%>");
11542 : 0 : expr.set_error ();
11543 : 0 : break;
11544 : : }
11545 : :
11546 : 22 : expr = (*cexpr_list)[0];
11547 : 22 : e2_p = &(*cexpr_list)[1];
11548 : 22 : *e2_p = convert_lvalue_to_rvalue (loc, *e2_p, true, true);
11549 : 22 : chain_value = e2_p->value;
11550 : 22 : mark_exp_read (chain_value);
11551 : :
11552 : 22 : if (TREE_CODE (expr.value) != CALL_EXPR)
11553 : 3 : error_at (loc, "first argument to "
11554 : : "%<__builtin_call_with_static_chain%> "
11555 : : "must be a call expression");
11556 : 19 : else if (TREE_CODE (TREE_TYPE (chain_value)) != POINTER_TYPE)
11557 : 1 : error_at (loc, "second argument to "
11558 : : "%<__builtin_call_with_static_chain%> "
11559 : : "must be a pointer type");
11560 : : else
11561 : 18 : CALL_EXPR_STATIC_CHAIN (expr.value) = chain_value;
11562 : 22 : set_c_expr_source_range (&expr, loc, close_paren_loc);
11563 : 22 : break;
11564 : : }
11565 : 12056 : case RID_BUILTIN_COMPLEX:
11566 : 12056 : {
11567 : 12056 : vec<c_expr_t, va_gc> *cexpr_list;
11568 : 12056 : c_expr_t *e1_p, *e2_p;
11569 : 12056 : location_t close_paren_loc;
11570 : :
11571 : 12056 : c_parser_consume_token (parser);
11572 : 12056 : if (!c_parser_get_builtin_args (parser,
11573 : : "__builtin_complex",
11574 : : &cexpr_list, false,
11575 : : &close_paren_loc))
11576 : : {
11577 : 1 : expr.set_error ();
11578 : 1 : break;
11579 : : }
11580 : :
11581 : 12055 : if (vec_safe_length (cexpr_list) != 2)
11582 : : {
11583 : 2 : error_at (loc, "wrong number of arguments to "
11584 : : "%<__builtin_complex%>");
11585 : 2 : expr.set_error ();
11586 : 2 : break;
11587 : : }
11588 : :
11589 : 12053 : e1_p = &(*cexpr_list)[0];
11590 : 12053 : e2_p = &(*cexpr_list)[1];
11591 : :
11592 : 12053 : *e1_p = convert_lvalue_to_rvalue (loc, *e1_p, true, true);
11593 : 12053 : if (TREE_CODE (e1_p->value) == EXCESS_PRECISION_EXPR)
11594 : 56 : e1_p->value = convert (TREE_TYPE (e1_p->value),
11595 : 56 : TREE_OPERAND (e1_p->value, 0));
11596 : 12053 : *e2_p = convert_lvalue_to_rvalue (loc, *e2_p, true, true);
11597 : 12053 : if (TREE_CODE (e2_p->value) == EXCESS_PRECISION_EXPR)
11598 : 56 : e2_p->value = convert (TREE_TYPE (e2_p->value),
11599 : 56 : TREE_OPERAND (e2_p->value, 0));
11600 : 12053 : if (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (e1_p->value))
11601 : 12052 : || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e1_p->value))
11602 : 12051 : || !SCALAR_FLOAT_TYPE_P (TREE_TYPE (e2_p->value))
11603 : 24103 : || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e2_p->value)))
11604 : : {
11605 : 3 : error_at (loc, "%<__builtin_complex%> operand "
11606 : : "not of real binary floating-point type");
11607 : 3 : expr.set_error ();
11608 : 3 : break;
11609 : : }
11610 : 12050 : if (TYPE_MAIN_VARIANT (TREE_TYPE (e1_p->value))
11611 : 12050 : != TYPE_MAIN_VARIANT (TREE_TYPE (e2_p->value)))
11612 : : {
11613 : 1 : error_at (loc,
11614 : : "%<__builtin_complex%> operands of different types");
11615 : 1 : expr.set_error ();
11616 : 1 : break;
11617 : : }
11618 : 12049 : pedwarn_c90 (loc, OPT_Wpedantic,
11619 : : "ISO C90 does not support complex types");
11620 : 12049 : expr.value = build2_loc (loc, COMPLEX_EXPR,
11621 : : build_complex_type
11622 : 12049 : (TYPE_MAIN_VARIANT
11623 : : (TREE_TYPE (e1_p->value))),
11624 : : e1_p->value, e2_p->value);
11625 : 12049 : set_c_expr_source_range (&expr, loc, close_paren_loc);
11626 : 12049 : break;
11627 : : }
11628 : 456747 : case RID_BUILTIN_SHUFFLE:
11629 : 456747 : {
11630 : 456747 : vec<c_expr_t, va_gc> *cexpr_list;
11631 : 456747 : unsigned int i;
11632 : 456747 : c_expr_t *p;
11633 : 456747 : location_t close_paren_loc;
11634 : :
11635 : 456747 : c_parser_consume_token (parser);
11636 : 456747 : if (!c_parser_get_builtin_args (parser,
11637 : : "__builtin_shuffle",
11638 : : &cexpr_list, false,
11639 : : &close_paren_loc))
11640 : : {
11641 : 0 : expr.set_error ();
11642 : 0 : break;
11643 : : }
11644 : :
11645 : 1411346 : FOR_EACH_VEC_SAFE_ELT (cexpr_list, i, p)
11646 : 954599 : *p = convert_lvalue_to_rvalue (loc, *p, true, true);
11647 : :
11648 : 456747 : if (vec_safe_length (cexpr_list) == 2)
11649 : 415642 : expr.value = c_build_vec_perm_expr (loc, (*cexpr_list)[0].value,
11650 : : NULL_TREE,
11651 : 415642 : (*cexpr_list)[1].value);
11652 : :
11653 : 41105 : else if (vec_safe_length (cexpr_list) == 3)
11654 : 41105 : expr.value = c_build_vec_perm_expr (loc, (*cexpr_list)[0].value,
11655 : 41105 : (*cexpr_list)[1].value,
11656 : 41105 : (*cexpr_list)[2].value);
11657 : : else
11658 : : {
11659 : 0 : error_at (loc, "wrong number of arguments to "
11660 : : "%<__builtin_shuffle%>");
11661 : 0 : expr.set_error ();
11662 : : }
11663 : 456747 : set_c_expr_source_range (&expr, loc, close_paren_loc);
11664 : 456747 : break;
11665 : : }
11666 : 1044816 : case RID_BUILTIN_SHUFFLEVECTOR:
11667 : 1044816 : {
11668 : 1044816 : vec<c_expr_t, va_gc> *cexpr_list;
11669 : 1044816 : unsigned int i;
11670 : 1044816 : c_expr_t *p;
11671 : 1044816 : location_t close_paren_loc;
11672 : :
11673 : 1044816 : c_parser_consume_token (parser);
11674 : 1044816 : if (!c_parser_get_builtin_args (parser,
11675 : : "__builtin_shufflevector",
11676 : : &cexpr_list, false,
11677 : : &close_paren_loc))
11678 : : {
11679 : 0 : expr.set_error ();
11680 : 0 : break;
11681 : : }
11682 : :
11683 : 16267892 : FOR_EACH_VEC_SAFE_ELT (cexpr_list, i, p)
11684 : 15223076 : *p = convert_lvalue_to_rvalue (loc, *p, true, true);
11685 : :
11686 : 1044816 : if (vec_safe_length (cexpr_list) < 3)
11687 : : {
11688 : 0 : error_at (loc, "wrong number of arguments to "
11689 : : "%<__builtin_shuffle%>");
11690 : 0 : expr.set_error ();
11691 : : }
11692 : : else
11693 : : {
11694 : 1044816 : auto_vec<tree, 16> mask;
11695 : 14178260 : for (i = 2; i < cexpr_list->length (); ++i)
11696 : 13133444 : mask.safe_push ((*cexpr_list)[i].value);
11697 : 1044816 : expr.value = c_build_shufflevector (loc, (*cexpr_list)[0].value,
11698 : 1044816 : (*cexpr_list)[1].value,
11699 : : mask);
11700 : 1044816 : }
11701 : 1044816 : set_c_expr_source_range (&expr, loc, close_paren_loc);
11702 : 1044816 : break;
11703 : : }
11704 : 125 : case RID_BUILTIN_CONVERTVECTOR:
11705 : 125 : {
11706 : 125 : location_t start_loc = loc;
11707 : 125 : c_parser_consume_token (parser);
11708 : 125 : matching_parens parens;
11709 : 125 : if (!parens.require_open (parser))
11710 : : {
11711 : 0 : expr.set_error ();
11712 : 2 : break;
11713 : : }
11714 : 125 : e1 = c_parser_expr_no_commas (parser, NULL);
11715 : 125 : mark_exp_read (e1.value);
11716 : 125 : if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
11717 : : {
11718 : 2 : c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
11719 : 2 : expr.set_error ();
11720 : 2 : break;
11721 : : }
11722 : 123 : loc = c_parser_peek_token (parser)->location;
11723 : 123 : t1 = c_parser_type_name (parser);
11724 : 123 : location_t end_loc = c_parser_peek_token (parser)->get_finish ();
11725 : 123 : c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
11726 : : "expected %<)%>");
11727 : 123 : if (t1 == NULL)
11728 : 1 : expr.set_error ();
11729 : : else
11730 : : {
11731 : 122 : tree type_expr = NULL_TREE;
11732 : 122 : expr.value = c_build_vec_convert (start_loc, e1.value, loc,
11733 : : groktypename (t1, &type_expr,
11734 : : NULL));
11735 : 122 : set_c_expr_source_range (&expr, start_loc, end_loc);
11736 : : }
11737 : : }
11738 : 123 : break;
11739 : 2 : case RID_BUILTIN_ASSOC_BARRIER:
11740 : 2 : {
11741 : 2 : location_t start_loc = loc;
11742 : 2 : c_parser_consume_token (parser);
11743 : 2 : matching_parens parens;
11744 : 2 : if (!parens.require_open (parser))
11745 : : {
11746 : 0 : expr.set_error ();
11747 : 0 : break;
11748 : : }
11749 : 2 : e1 = c_parser_expr_no_commas (parser, NULL);
11750 : 2 : mark_exp_read (e1.value);
11751 : 2 : location_t end_loc = c_parser_peek_token (parser)->get_finish ();
11752 : 2 : parens.skip_until_found_close (parser);
11753 : 2 : expr = parser_build_unary_op (loc, PAREN_EXPR, e1);
11754 : 2 : set_c_expr_source_range (&expr, start_loc, end_loc);
11755 : : }
11756 : 2 : break;
11757 : 771 : case RID_BUILTIN_STDC:
11758 : 771 : {
11759 : 771 : vec<c_expr_t, va_gc> *cexpr_list;
11760 : 771 : c_expr_t *arg_p;
11761 : 771 : location_t close_paren_loc;
11762 : 771 : enum c_builtin_stdc {
11763 : : C_BUILTIN_STDC_BIT_CEIL,
11764 : : C_BUILTIN_STDC_BIT_FLOOR,
11765 : : C_BUILTIN_STDC_BIT_WIDTH,
11766 : : C_BUILTIN_STDC_COUNT_ONES,
11767 : : C_BUILTIN_STDC_COUNT_ZEROS,
11768 : : C_BUILTIN_STDC_FIRST_LEADING_ONE,
11769 : : C_BUILTIN_STDC_FIRST_LEADING_ZERO,
11770 : : C_BUILTIN_STDC_FIRST_TRAILING_ONE,
11771 : : C_BUILTIN_STDC_FIRST_TRAILING_ZERO,
11772 : : C_BUILTIN_STDC_HAS_SINGLE_BIT,
11773 : : C_BUILTIN_STDC_LEADING_ONES,
11774 : : C_BUILTIN_STDC_LEADING_ZEROS,
11775 : : C_BUILTIN_STDC_TRAILING_ONES,
11776 : : C_BUILTIN_STDC_TRAILING_ZEROS,
11777 : : C_BUILTIN_STDC_MAX
11778 : 771 : } stdc_rid = C_BUILTIN_STDC_MAX;
11779 : 771 : const char *name
11780 : 771 : = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
11781 : 771 : switch (name[sizeof ("__builtin_stdc_") - 1])
11782 : : {
11783 : 199 : case 'b':
11784 : 199 : switch (name[sizeof ("__builtin_stdc_bit_") - 1])
11785 : : {
11786 : : case 'c':
11787 : : stdc_rid = C_BUILTIN_STDC_BIT_CEIL;
11788 : : break;
11789 : 63 : case 'f':
11790 : 63 : stdc_rid = C_BUILTIN_STDC_BIT_FLOOR;
11791 : 63 : break;
11792 : 57 : default:
11793 : 57 : stdc_rid = C_BUILTIN_STDC_BIT_WIDTH;
11794 : 57 : break;
11795 : : }
11796 : : break;
11797 : 104 : case 'c':
11798 : 104 : if (name[sizeof ("__builtin_stdc_count_") - 1] == 'o')
11799 : : stdc_rid = C_BUILTIN_STDC_COUNT_ONES;
11800 : : else
11801 : 52 : stdc_rid = C_BUILTIN_STDC_COUNT_ZEROS;
11802 : : break;
11803 : 208 : case 'f':
11804 : 208 : switch (name[sizeof ("__builtin_stdc_first_trailing_") - 1])
11805 : : {
11806 : : case 'n':
11807 : : stdc_rid = C_BUILTIN_STDC_FIRST_LEADING_ONE;
11808 : : break;
11809 : : case 'e':
11810 : : stdc_rid = C_BUILTIN_STDC_FIRST_LEADING_ZERO;
11811 : : break;
11812 : : case 'o':
11813 : : stdc_rid = C_BUILTIN_STDC_FIRST_TRAILING_ONE;
11814 : : break;
11815 : : default:
11816 : : stdc_rid = C_BUILTIN_STDC_FIRST_TRAILING_ZERO;
11817 : : break;
11818 : : }
11819 : : break;
11820 : : case 'h':
11821 : : stdc_rid = C_BUILTIN_STDC_HAS_SINGLE_BIT;
11822 : : break;
11823 : 104 : case 'l':
11824 : 104 : if (name[sizeof ("__builtin_stdc_leading_") - 1] == 'o')
11825 : : stdc_rid = C_BUILTIN_STDC_LEADING_ONES;
11826 : : else
11827 : 52 : stdc_rid = C_BUILTIN_STDC_LEADING_ZEROS;
11828 : : break;
11829 : 104 : case 't':
11830 : 104 : if (name[sizeof ("__builtin_stdc_trailing_") - 1] == 'o')
11831 : : stdc_rid = C_BUILTIN_STDC_TRAILING_ONES;
11832 : : else
11833 : 52 : stdc_rid = C_BUILTIN_STDC_TRAILING_ZEROS;
11834 : : break;
11835 : : }
11836 : 276 : gcc_checking_assert (stdc_rid != C_BUILTIN_STDC_MAX);
11837 : :
11838 : 771 : c_parser_consume_token (parser);
11839 : 771 : if (!c_parser_get_builtin_args (parser, name,
11840 : : &cexpr_list, false,
11841 : : &close_paren_loc))
11842 : : {
11843 : 0 : expr.set_error ();
11844 : 0 : break;
11845 : : }
11846 : :
11847 : 771 : if (vec_safe_length (cexpr_list) != 1)
11848 : : {
11849 : 28 : error_at (loc, "wrong number of arguments to %qs", name);
11850 : 28 : expr.set_error ();
11851 : 28 : break;
11852 : : }
11853 : :
11854 : 743 : arg_p = &(*cexpr_list)[0];
11855 : 743 : *arg_p = convert_lvalue_to_rvalue (loc, *arg_p, true, true);
11856 : 743 : if (!INTEGRAL_TYPE_P (TREE_TYPE (arg_p->value)))
11857 : : {
11858 : 70 : error_at (loc, "%qs operand not an integral type", name);
11859 : 70 : expr.set_error ();
11860 : 70 : break;
11861 : : }
11862 : 673 : if (TREE_CODE (TREE_TYPE (arg_p->value)) == ENUMERAL_TYPE)
11863 : : {
11864 : 14 : error_at (loc, "argument %u in call to function "
11865 : : "%qs has enumerated type", 1, name);
11866 : 14 : expr.set_error ();
11867 : 14 : break;
11868 : : }
11869 : 659 : if (TREE_CODE (TREE_TYPE (arg_p->value)) == BOOLEAN_TYPE)
11870 : : {
11871 : 14 : error_at (loc, "argument %u in call to function "
11872 : : "%qs has boolean type", 1, name);
11873 : 14 : expr.set_error ();
11874 : 14 : break;
11875 : : }
11876 : 645 : if (!TYPE_UNSIGNED (TREE_TYPE (arg_p->value)))
11877 : : {
11878 : 14 : error_at (loc, "argument 1 in call to function "
11879 : : "%qs has signed type", name);
11880 : 14 : expr.set_error ();
11881 : 14 : break;
11882 : : }
11883 : 631 : tree arg = arg_p->value;
11884 : 631 : tree type = TYPE_MAIN_VARIANT (TREE_TYPE (arg));
11885 : : /* Expand:
11886 : : __builtin_stdc_leading_zeros (arg) as
11887 : : (unsigned int) __builtin_clzg (arg, prec)
11888 : : __builtin_stdc_leading_ones (arg) as
11889 : : (unsigned int) __builtin_clzg ((type) ~arg, prec)
11890 : : __builtin_stdc_trailing_zeros (arg) as
11891 : : (unsigned int) __builtin_ctzg (arg, prec)
11892 : : __builtin_stdc_trailing_ones (arg) as
11893 : : (unsigned int) __builtin_ctzg ((type) ~arg, prec)
11894 : : __builtin_stdc_first_leading_zero (arg) as
11895 : : __builtin_clzg ((type) ~arg, -1) + 1U
11896 : : __builtin_stdc_first_leading_one (arg) as
11897 : : __builtin_clzg (arg, -1) + 1U
11898 : : __builtin_stdc_first_trailing_zero (arg) as
11899 : : __builtin_ctzg ((type) ~arg, -1) + 1U
11900 : : __builtin_stdc_first_trailing_one (arg) as
11901 : : __builtin_ctzg (arg, -1) + 1U
11902 : : __builtin_stdc_count_zeros (arg) as
11903 : : (unsigned int) __builtin_popcountg ((type) ~arg)
11904 : : __builtin_stdc_count_ones (arg) as
11905 : : (unsigned int) __builtin_popcountg (arg)
11906 : : __builtin_stdc_has_single_bit (arg) as
11907 : : (_Bool) (__builtin_popcountg (arg) == 1)
11908 : : __builtin_stdc_bit_width (arg) as
11909 : : (unsigned int) (prec - __builtin_clzg (arg, prec))
11910 : : __builtin_stdc_bit_floor (arg) as
11911 : : arg == 0 ? (type) 0
11912 : : : (type) 1 << (prec - 1 - __builtin_clzg (arg))
11913 : : __builtin_stdc_bit_ceil (arg) as
11914 : : arg <= 1 ? (type) 1
11915 : : : (type) 2 << (prec - 1 - __builtin_clzg (arg - 1))
11916 : : without evaluating arg multiple times, type being
11917 : : __typeof (arg) and prec __builtin_popcountg ((type) ~0)). */
11918 : 631 : int prec = TYPE_PRECISION (type);
11919 : 631 : tree barg1 = arg;
11920 : 631 : switch (stdc_rid)
11921 : : {
11922 : 69 : case C_BUILTIN_STDC_BIT_CEIL:
11923 : 69 : arg = save_expr (arg);
11924 : 69 : barg1 = build2_loc (loc, PLUS_EXPR, type, arg,
11925 : 69 : build_int_cst (type, -1));
11926 : 69 : break;
11927 : 53 : case C_BUILTIN_STDC_BIT_FLOOR:
11928 : 53 : barg1 = arg = save_expr (arg);
11929 : 53 : break;
11930 : 210 : case C_BUILTIN_STDC_COUNT_ZEROS:
11931 : 210 : case C_BUILTIN_STDC_FIRST_LEADING_ZERO:
11932 : 210 : case C_BUILTIN_STDC_FIRST_TRAILING_ZERO:
11933 : 210 : case C_BUILTIN_STDC_LEADING_ONES:
11934 : 210 : case C_BUILTIN_STDC_TRAILING_ONES:
11935 : 210 : barg1 = build1_loc (loc, BIT_NOT_EXPR, type, arg);
11936 : 210 : break;
11937 : : default:
11938 : : break;
11939 : : }
11940 : 631 : tree barg2 = NULL_TREE;
11941 : 631 : switch (stdc_rid)
11942 : : {
11943 : 215 : case C_BUILTIN_STDC_BIT_WIDTH:
11944 : 215 : case C_BUILTIN_STDC_LEADING_ONES:
11945 : 215 : case C_BUILTIN_STDC_LEADING_ZEROS:
11946 : 215 : case C_BUILTIN_STDC_TRAILING_ONES:
11947 : 215 : case C_BUILTIN_STDC_TRAILING_ZEROS:
11948 : 215 : barg2 = build_int_cst (integer_type_node, prec);
11949 : 215 : break;
11950 : 168 : case C_BUILTIN_STDC_FIRST_LEADING_ONE:
11951 : 168 : case C_BUILTIN_STDC_FIRST_LEADING_ZERO:
11952 : 168 : case C_BUILTIN_STDC_FIRST_TRAILING_ONE:
11953 : 168 : case C_BUILTIN_STDC_FIRST_TRAILING_ZERO:
11954 : 168 : barg2 = integer_minus_one_node;
11955 : 168 : break;
11956 : : default:
11957 : : break;
11958 : : }
11959 : 631 : tree fndecl = NULL_TREE;
11960 : 631 : switch (stdc_rid)
11961 : : {
11962 : 337 : case C_BUILTIN_STDC_BIT_CEIL:
11963 : 337 : case C_BUILTIN_STDC_BIT_FLOOR:
11964 : 337 : case C_BUILTIN_STDC_BIT_WIDTH:
11965 : 337 : case C_BUILTIN_STDC_FIRST_LEADING_ONE:
11966 : 337 : case C_BUILTIN_STDC_FIRST_LEADING_ZERO:
11967 : 337 : case C_BUILTIN_STDC_LEADING_ONES:
11968 : 337 : case C_BUILTIN_STDC_LEADING_ZEROS:
11969 : 337 : fndecl = builtin_decl_explicit (BUILT_IN_CLZG);
11970 : 337 : break;
11971 : 168 : case C_BUILTIN_STDC_FIRST_TRAILING_ONE:
11972 : 168 : case C_BUILTIN_STDC_FIRST_TRAILING_ZERO:
11973 : 168 : case C_BUILTIN_STDC_TRAILING_ONES:
11974 : 168 : case C_BUILTIN_STDC_TRAILING_ZEROS:
11975 : 168 : fndecl = builtin_decl_explicit (BUILT_IN_CTZG);
11976 : 168 : break;
11977 : 126 : case C_BUILTIN_STDC_COUNT_ONES:
11978 : 126 : case C_BUILTIN_STDC_COUNT_ZEROS:
11979 : 126 : case C_BUILTIN_STDC_HAS_SINGLE_BIT:
11980 : 126 : fndecl = builtin_decl_explicit (BUILT_IN_POPCOUNTG);
11981 : 126 : break;
11982 : : default:
11983 : : gcc_unreachable ();
11984 : : }
11985 : : /* Construct a call to __builtin_{clz,ctz,popcount}g. */
11986 : 631 : int nargs = barg2 != NULL_TREE ? 2 : 1;
11987 : 631 : vec<tree, va_gc> *args;
11988 : 631 : vec_alloc (args, nargs);
11989 : 631 : vec<tree, va_gc> *origtypes;
11990 : 631 : vec_alloc (origtypes, nargs);
11991 : 1262 : auto_vec<location_t> arg_loc (nargs);
11992 : 631 : args->quick_push (barg1);
11993 : 631 : arg_loc.quick_push (arg_p->get_location ());
11994 : 631 : origtypes->quick_push (arg_p->original_type);
11995 : 631 : if (nargs == 2)
11996 : : {
11997 : 383 : args->quick_push (barg2);
11998 : 383 : arg_loc.quick_push (loc);
11999 : 383 : origtypes->quick_push (integer_type_node);
12000 : : }
12001 : 631 : expr.value = c_build_function_call_vec (loc, arg_loc, fndecl,
12002 : : args, origtypes);
12003 : 631 : set_c_expr_source_range (&expr, loc, close_paren_loc);
12004 : 631 : if (expr.value == error_mark_node)
12005 : : break;
12006 : 631 : switch (stdc_rid)
12007 : : {
12008 : 122 : case C_BUILTIN_STDC_BIT_CEIL:
12009 : 122 : case C_BUILTIN_STDC_BIT_FLOOR:
12010 : 122 : --prec;
12011 : : /* FALLTHRU */
12012 : 169 : case C_BUILTIN_STDC_BIT_WIDTH:
12013 : 169 : expr.value = build2_loc (loc, MINUS_EXPR, integer_type_node,
12014 : : build_int_cst (integer_type_node,
12015 : : prec), expr.value);
12016 : 169 : break;
12017 : 168 : case C_BUILTIN_STDC_FIRST_LEADING_ONE:
12018 : 168 : case C_BUILTIN_STDC_FIRST_LEADING_ZERO:
12019 : 168 : case C_BUILTIN_STDC_FIRST_TRAILING_ONE:
12020 : 168 : case C_BUILTIN_STDC_FIRST_TRAILING_ZERO:
12021 : 168 : expr.value = build2_loc (loc, PLUS_EXPR, integer_type_node,
12022 : : expr.value, integer_one_node);
12023 : 168 : break;
12024 : 42 : case C_BUILTIN_STDC_HAS_SINGLE_BIT:
12025 : 42 : expr.value = build2_loc (loc, EQ_EXPR, boolean_type_node,
12026 : : expr.value, integer_one_node);
12027 : 42 : break;
12028 : : default:
12029 : : break;
12030 : : }
12031 : :
12032 : 379 : if (stdc_rid != C_BUILTIN_STDC_BIT_CEIL
12033 : : && stdc_rid != C_BUILTIN_STDC_BIT_FLOOR)
12034 : : {
12035 : 509 : if (stdc_rid != C_BUILTIN_STDC_HAS_SINGLE_BIT)
12036 : 467 : expr.value = fold_convert_loc (loc, unsigned_type_node,
12037 : : expr.value);
12038 : : break;
12039 : : }
12040 : : /* For __builtin_stdc_bit_ceil (0U) or __builtin_stdc_bit_ceil (1U)
12041 : : or __builtin_stdc_bit_floor (0U) avoid bogus -Wshift-count-*
12042 : : warnings. The LSHIFT_EXPR is in dead code in that case. */
12043 : 122 : if (integer_zerop (arg)
12044 : 122 : || (stdc_rid == C_BUILTIN_STDC_BIT_CEIL && integer_onep (arg)))
12045 : 42 : expr.value = build_int_cst (type, 0);
12046 : : else
12047 : 80 : expr.value
12048 : 80 : = build2_loc (loc, LSHIFT_EXPR, type,
12049 : : build_int_cst (type,
12050 : : (stdc_rid
12051 : : == C_BUILTIN_STDC_BIT_CEIL
12052 : 114 : ? 2 : 1)), expr.value);
12053 : 122 : if (stdc_rid == C_BUILTIN_STDC_BIT_CEIL)
12054 : 69 : expr.value = build3_loc (loc, COND_EXPR, type,
12055 : : build2_loc (loc, LE_EXPR,
12056 : : boolean_type_node, arg,
12057 : 69 : build_int_cst (type, 1)),
12058 : 69 : build_int_cst (type, 1),
12059 : : expr.value);
12060 : : else
12061 : 53 : expr.value = build3_loc (loc, COND_EXPR, type,
12062 : : build2_loc (loc, EQ_EXPR,
12063 : : boolean_type_node, arg,
12064 : 53 : build_int_cst (type, 0)),
12065 : 53 : build_int_cst (type, 0),
12066 : : expr.value);
12067 : : break;
12068 : : }
12069 : 0 : case RID_AT_SELECTOR:
12070 : 0 : {
12071 : 0 : gcc_assert (c_dialect_objc ());
12072 : 0 : c_parser_consume_token (parser);
12073 : 0 : matching_parens parens;
12074 : 0 : if (!parens.require_open (parser))
12075 : : {
12076 : 0 : expr.set_error ();
12077 : 0 : break;
12078 : : }
12079 : 0 : tree sel = c_parser_objc_selector_arg (parser);
12080 : 0 : location_t close_loc = c_parser_peek_token (parser)->location;
12081 : 0 : parens.skip_until_found_close (parser);
12082 : 0 : expr.value = objc_build_selector_expr (loc, sel);
12083 : 0 : set_c_expr_source_range (&expr, loc, close_loc);
12084 : : }
12085 : 0 : break;
12086 : 0 : case RID_AT_PROTOCOL:
12087 : 0 : {
12088 : 0 : gcc_assert (c_dialect_objc ());
12089 : 0 : c_parser_consume_token (parser);
12090 : 0 : matching_parens parens;
12091 : 0 : if (!parens.require_open (parser))
12092 : : {
12093 : 0 : expr.set_error ();
12094 : 0 : break;
12095 : : }
12096 : 0 : if (c_parser_next_token_is_not (parser, CPP_NAME))
12097 : : {
12098 : 0 : c_parser_error (parser, "expected identifier");
12099 : 0 : c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
12100 : 0 : expr.set_error ();
12101 : 0 : break;
12102 : : }
12103 : 0 : tree id = c_parser_peek_token (parser)->value;
12104 : 0 : c_parser_consume_token (parser);
12105 : 0 : location_t close_loc = c_parser_peek_token (parser)->location;
12106 : 0 : parens.skip_until_found_close (parser);
12107 : 0 : expr.value = objc_build_protocol_expr (id);
12108 : 0 : set_c_expr_source_range (&expr, loc, close_loc);
12109 : : }
12110 : 0 : break;
12111 : 0 : case RID_AT_ENCODE:
12112 : 0 : {
12113 : : /* Extension to support C-structures in the archiver. */
12114 : 0 : gcc_assert (c_dialect_objc ());
12115 : 0 : c_parser_consume_token (parser);
12116 : 0 : matching_parens parens;
12117 : 0 : if (!parens.require_open (parser))
12118 : : {
12119 : 0 : expr.set_error ();
12120 : 0 : break;
12121 : : }
12122 : 0 : t1 = c_parser_type_name (parser);
12123 : 0 : if (t1 == NULL)
12124 : : {
12125 : 0 : expr.set_error ();
12126 : 0 : c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
12127 : 0 : break;
12128 : : }
12129 : 0 : location_t close_loc = c_parser_peek_token (parser)->location;
12130 : 0 : parens.skip_until_found_close (parser);
12131 : 0 : tree type = groktypename (t1, NULL, NULL);
12132 : 0 : expr.value = objc_build_encode_expr (type);
12133 : 0 : set_c_expr_source_range (&expr, loc, close_loc);
12134 : : }
12135 : 0 : break;
12136 : 456 : case RID_GENERIC:
12137 : 456 : expr = c_parser_generic_selection (parser);
12138 : 456 : break;
12139 : 3 : case RID_OMP_ALL_MEMORY:
12140 : 3 : gcc_assert (flag_openmp);
12141 : 3 : c_parser_consume_token (parser);
12142 : 3 : error_at (loc, "%<omp_all_memory%> may only be used in OpenMP "
12143 : : "%<depend%> clause");
12144 : 3 : expr.set_error ();
12145 : 3 : break;
12146 : : /* C23 'nullptr' literal. */
12147 : 225 : case RID_NULLPTR:
12148 : 225 : c_parser_consume_token (parser);
12149 : 225 : expr.value = nullptr_node;
12150 : 225 : set_c_expr_source_range (&expr, tok_range);
12151 : 225 : pedwarn_c11 (loc, OPT_Wpedantic,
12152 : : "ISO C does not support %qs before C23", "nullptr");
12153 : 225 : break;
12154 : 11 : case RID_TRUE:
12155 : 11 : c_parser_consume_token (parser);
12156 : 11 : expr.value = boolean_true_node;
12157 : 11 : set_c_expr_source_range (&expr, tok_range);
12158 : 11 : break;
12159 : 11 : case RID_FALSE:
12160 : 11 : c_parser_consume_token (parser);
12161 : 11 : expr.value = boolean_false_node;
12162 : 11 : set_c_expr_source_range (&expr, tok_range);
12163 : 11 : break;
12164 : 34 : default:
12165 : 34 : c_parser_error (parser, "expected expression");
12166 : 34 : expr.set_error ();
12167 : 34 : break;
12168 : : }
12169 : : break;
12170 : 2 : case CPP_OPEN_SQUARE:
12171 : 2 : if (c_dialect_objc ())
12172 : : {
12173 : 0 : tree receiver, args;
12174 : 0 : c_parser_consume_token (parser);
12175 : 0 : receiver = c_parser_objc_receiver (parser);
12176 : 0 : args = c_parser_objc_message_args (parser);
12177 : 0 : location_t close_loc = c_parser_peek_token (parser)->location;
12178 : 0 : c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
12179 : : "expected %<]%>");
12180 : 0 : expr.value = objc_build_message_expr (receiver, args);
12181 : 0 : set_c_expr_source_range (&expr, loc, close_loc);
12182 : 0 : break;
12183 : : }
12184 : : /* Else fall through to report error. */
12185 : : /* FALLTHRU */
12186 : 765 : default:
12187 : 765 : c_parser_error (parser, "expected expression");
12188 : 765 : expr.set_error ();
12189 : 765 : break;
12190 : : }
12191 : 212664696 : out:
12192 : 212664696 : return c_parser_postfix_expression_after_primary
12193 : 212664696 : (parser, EXPR_LOC_OR_LOC (expr.value, loc), expr);
12194 : : }
12195 : :
12196 : : /* Parse a postfix expression after a parenthesized type name: the
12197 : : brace-enclosed initializer of a compound literal, possibly followed
12198 : : by some postfix operators. This is separate because it is not
12199 : : possible to tell until after the type name whether a cast
12200 : : expression has a cast or a compound literal, or whether the operand
12201 : : of sizeof is a parenthesized type name or starts with a compound
12202 : : literal. TYPE_LOC is the location where TYPE_NAME starts--the
12203 : : location of the first token after the parentheses around the type
12204 : : name. */
12205 : :
12206 : : static struct c_expr
12207 : 869224 : c_parser_postfix_expression_after_paren_type (c_parser *parser,
12208 : : struct c_declspecs *scspecs,
12209 : : struct c_type_name *type_name,
12210 : : location_t type_loc)
12211 : : {
12212 : 869224 : tree type;
12213 : 869224 : struct c_expr init;
12214 : 869224 : bool non_const;
12215 : 869224 : struct c_expr expr;
12216 : 869224 : location_t start_loc;
12217 : 869224 : tree type_expr = NULL_TREE;
12218 : 869224 : bool type_expr_const = true;
12219 : 869224 : bool constexpr_p = scspecs ? scspecs->constexpr_p : false;
12220 : 869224 : unsigned int underspec_state = 0;
12221 : 869224 : check_compound_literal_type (type_loc, type_name);
12222 : 869224 : rich_location richloc (line_table, type_loc);
12223 : 869224 : start_loc = c_parser_peek_token (parser)->location;
12224 : 869224 : if (constexpr_p)
12225 : : {
12226 : 232 : underspec_state = start_underspecified_init (start_loc, NULL_TREE);
12227 : : /* A constexpr compound literal is subject to the constraints on
12228 : : underspecified declarations, which may not declare tags or
12229 : : members or structures or unions; it is undefined behavior to
12230 : : declare the members of an enumeration. Where the structure,
12231 : : union or enumeration type is declared within the compound
12232 : : literal initializer, this is diagnosed elsewhere as a result
12233 : : of the above call to start_underspecified_init. Diagnose
12234 : : here the case of declaring such a type in the type specifiers
12235 : : of the compound literal. */
12236 : 232 : switch (type_name->specs->typespec_kind)
12237 : : {
12238 : 2 : case ctsk_tagfirstref:
12239 : 2 : case ctsk_tagfirstref_attrs:
12240 : 2 : error_at (type_loc, "%qT declared in %<constexpr%> compound literal",
12241 : : type_name->specs->type);
12242 : 2 : break;
12243 : :
12244 : 4 : case ctsk_tagdef:
12245 : 4 : error_at (type_loc, "%qT defined in %<constexpr%> compound literal",
12246 : : type_name->specs->type);
12247 : 4 : break;
12248 : :
12249 : : default:
12250 : : break;
12251 : : }
12252 : : }
12253 : 869224 : start_init (NULL_TREE, NULL,
12254 : 869224 : (global_bindings_p ()
12255 : 868976 : || (scspecs && scspecs->storage_class == csc_static)
12256 : 1738172 : || constexpr_p), constexpr_p, &richloc);
12257 : 869224 : type = groktypename (type_name, &type_expr, &type_expr_const);
12258 : 869224 : if (type != error_mark_node && C_TYPE_VARIABLE_SIZE (type))
12259 : : {
12260 : 9 : error_at (type_loc, "compound literal has variable size");
12261 : 9 : type = error_mark_node;
12262 : : }
12263 : 869215 : else if (TREE_CODE (type) == FUNCTION_TYPE)
12264 : : {
12265 : 3 : error_at (type_loc, "compound literal has function type");
12266 : 3 : type = error_mark_node;
12267 : : }
12268 : 869224 : if (constexpr_p && type != error_mark_node)
12269 : : {
12270 : 232 : tree type_no_array = strip_array_types (type);
12271 : : /* The type of a constexpr object must not be variably modified
12272 : : (which applies to all compound literals), volatile, atomic or
12273 : : restrict qualified or have a member with such a qualifier.
12274 : : const qualification is implicitly added. */
12275 : 232 : if (TYPE_QUALS (type_no_array)
12276 : 232 : & (TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT | TYPE_QUAL_ATOMIC))
12277 : 9 : error_at (type_loc, "invalid qualifiers for %<constexpr%> object");
12278 : 223 : else if (RECORD_OR_UNION_TYPE_P (type_no_array)
12279 : 223 : && C_TYPE_FIELDS_NON_CONSTEXPR (type_no_array))
12280 : 8 : error_at (type_loc, "invalid qualifiers for field of "
12281 : : "%<constexpr%> object");
12282 : 464 : type = c_build_qualified_type (type,
12283 : 232 : (TYPE_QUALS (type_no_array)
12284 : : | TYPE_QUAL_CONST));
12285 : : }
12286 : 869224 : init = c_parser_braced_init (parser, type, false, NULL, NULL_TREE);
12287 : 869224 : if (constexpr_p)
12288 : 232 : finish_underspecified_init (NULL_TREE, underspec_state);
12289 : 869224 : finish_init ();
12290 : 869224 : maybe_warn_string_init (type_loc, type, init);
12291 : :
12292 : 869224 : if (type != error_mark_node
12293 : 869208 : && !ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (type))
12294 : 869224 : && current_function_decl)
12295 : : {
12296 : 0 : error ("compound literal qualified by address-space qualifier");
12297 : 0 : type = error_mark_node;
12298 : : }
12299 : :
12300 : 869224 : if (!pedwarn_c90 (start_loc, OPT_Wpedantic,
12301 : 869224 : "ISO C90 forbids compound literals") && scspecs)
12302 : 284 : pedwarn_c11 (start_loc, OPT_Wpedantic,
12303 : : "ISO C forbids storage class specifiers in compound literals "
12304 : : "before C23");
12305 : 869224 : non_const = ((init.value && TREE_CODE (init.value) == CONSTRUCTOR)
12306 : 1738014 : ? CONSTRUCTOR_NON_CONST (init.value)
12307 : 434 : : init.original_code == C_MAYBE_CONST_EXPR);
12308 : 869224 : non_const |= !type_expr_const;
12309 : 869224 : unsigned int alignas_align = 0;
12310 : 869224 : if (type != error_mark_node
12311 : 869208 : && type_name->specs->align_log != -1)
12312 : : {
12313 : 4 : alignas_align = 1U << type_name->specs->align_log;
12314 : 4 : if (alignas_align < min_align_of_type (type))
12315 : : {
12316 : 1 : error_at (type_name->specs->locations[cdw_alignas],
12317 : : "%<_Alignas%> specifiers cannot reduce "
12318 : : "alignment of compound literal");
12319 : 1 : alignas_align = 0;
12320 : : }
12321 : : }
12322 : 869224 : expr.value = build_compound_literal (start_loc, type, init.value, non_const,
12323 : : alignas_align, scspecs);
12324 : 869224 : set_c_expr_source_range (&expr, init.src_range);
12325 : 869224 : expr.m_decimal = 0;
12326 : 869224 : expr.original_code = ERROR_MARK;
12327 : 869224 : expr.original_type = NULL;
12328 : 869224 : if (type != error_mark_node
12329 : 869208 : && expr.value != error_mark_node
12330 : 869136 : && type_expr)
12331 : : {
12332 : 30 : if (TREE_CODE (expr.value) == C_MAYBE_CONST_EXPR)
12333 : : {
12334 : 18 : gcc_assert (C_MAYBE_CONST_EXPR_PRE (expr.value) == NULL_TREE);
12335 : 18 : C_MAYBE_CONST_EXPR_PRE (expr.value) = type_expr;
12336 : : }
12337 : : else
12338 : : {
12339 : 12 : gcc_assert (!non_const);
12340 : 12 : expr.value = build2 (C_MAYBE_CONST_EXPR, type,
12341 : : type_expr, expr.value);
12342 : : }
12343 : : }
12344 : 869224 : return c_parser_postfix_expression_after_primary (parser, start_loc, expr);
12345 : 869224 : }
12346 : :
12347 : : /* Callback function for sizeof_pointer_memaccess_warning to compare
12348 : : types. */
12349 : :
12350 : : static bool
12351 : 3439 : sizeof_ptr_memacc_comptypes (tree type1, tree type2)
12352 : : {
12353 : 3439 : return comptypes (type1, type2) == 1;
12354 : : }
12355 : :
12356 : : /* Warn for patterns where abs-like function appears to be used incorrectly,
12357 : : gracefully ignore any non-abs-like function. The warning location should
12358 : : be LOC. FNDECL is the declaration of called function, it must be a
12359 : : BUILT_IN_NORMAL function. ARG is the first and only argument of the
12360 : : call. */
12361 : :
12362 : : static void
12363 : 56157 : warn_for_abs (location_t loc, tree fndecl, tree arg)
12364 : : {
12365 : : /* Avoid warning in unreachable subexpressions. */
12366 : 56157 : if (c_inhibit_evaluation_warnings)
12367 : : return;
12368 : :
12369 : 29819 : tree atype = TREE_TYPE (arg);
12370 : :
12371 : : /* Casts from pointers (and thus arrays and fndecls) will generate
12372 : : -Wint-conversion warnings. Most other wrong types hopefully lead to type
12373 : : mismatch errors. TODO: Think about what to do with FIXED_POINT_TYPE_P
12374 : : types and possibly other exotic types. */
12375 : 29819 : if (!INTEGRAL_TYPE_P (atype)
12376 : 29819 : && !SCALAR_FLOAT_TYPE_P (atype)
12377 : 5075 : && TREE_CODE (atype) != COMPLEX_TYPE)
12378 : : return;
12379 : :
12380 : 25222 : enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
12381 : :
12382 : 25222 : switch (fcode)
12383 : : {
12384 : 35 : case BUILT_IN_ABS:
12385 : 35 : case BUILT_IN_LABS:
12386 : 35 : case BUILT_IN_LLABS:
12387 : 35 : case BUILT_IN_IMAXABS:
12388 : 35 : if (!INTEGRAL_TYPE_P (atype))
12389 : : {
12390 : 4 : if (SCALAR_FLOAT_TYPE_P (atype))
12391 : 3 : warning_at (loc, OPT_Wabsolute_value,
12392 : : "using integer absolute value function %qD when "
12393 : : "argument is of floating-point type %qT",
12394 : : fndecl, atype);
12395 : 1 : else if (TREE_CODE (atype) == COMPLEX_TYPE)
12396 : 1 : warning_at (loc, OPT_Wabsolute_value,
12397 : : "using integer absolute value function %qD when "
12398 : : "argument is of complex type %qT", fndecl, atype);
12399 : : else
12400 : : gcc_unreachable ();
12401 : 4 : return;
12402 : : }
12403 : 31 : if (TYPE_UNSIGNED (atype))
12404 : 9 : warning_at (loc, OPT_Wabsolute_value,
12405 : : "taking the absolute value of unsigned type %qT "
12406 : : "has no effect", atype);
12407 : : break;
12408 : :
12409 : 334 : CASE_FLT_FN (BUILT_IN_FABS):
12410 : 334 : CASE_FLT_FN_FLOATN_NX (BUILT_IN_FABS):
12411 : 334 : if (!SCALAR_FLOAT_TYPE_P (atype)
12412 : 334 : || DECIMAL_FLOAT_MODE_P (TYPE_MODE (atype)))
12413 : : {
12414 : 4 : if (INTEGRAL_TYPE_P (atype))
12415 : 2 : warning_at (loc, OPT_Wabsolute_value,
12416 : : "using floating-point absolute value function %qD "
12417 : : "when argument is of integer type %qT", fndecl, atype);
12418 : 2 : else if (DECIMAL_FLOAT_TYPE_P (atype))
12419 : 1 : warning_at (loc, OPT_Wabsolute_value,
12420 : : "using floating-point absolute value function %qD "
12421 : : "when argument is of decimal floating-point type %qT",
12422 : : fndecl, atype);
12423 : 1 : else if (TREE_CODE (atype) == COMPLEX_TYPE)
12424 : 1 : warning_at (loc, OPT_Wabsolute_value,
12425 : : "using floating-point absolute value function %qD when "
12426 : : "argument is of complex type %qT", fndecl, atype);
12427 : : else
12428 : 0 : gcc_unreachable ();
12429 : 4 : return;
12430 : : }
12431 : : break;
12432 : :
12433 : 7 : CASE_FLT_FN (BUILT_IN_CABS):
12434 : 7 : if (TREE_CODE (atype) != COMPLEX_TYPE)
12435 : : {
12436 : 4 : if (INTEGRAL_TYPE_P (atype))
12437 : 2 : warning_at (loc, OPT_Wabsolute_value,
12438 : : "using complex absolute value function %qD when "
12439 : : "argument is of integer type %qT", fndecl, atype);
12440 : 2 : else if (SCALAR_FLOAT_TYPE_P (atype))
12441 : 2 : warning_at (loc, OPT_Wabsolute_value,
12442 : : "using complex absolute value function %qD when "
12443 : : "argument is of floating-point type %qT",
12444 : : fndecl, atype);
12445 : : else
12446 : : gcc_unreachable ();
12447 : :
12448 : 4 : return;
12449 : : }
12450 : : break;
12451 : :
12452 : 6 : case BUILT_IN_FABSD32:
12453 : 6 : case BUILT_IN_FABSD64:
12454 : 6 : case BUILT_IN_FABSD128:
12455 : 6 : if (!DECIMAL_FLOAT_TYPE_P (atype))
12456 : : {
12457 : 4 : if (INTEGRAL_TYPE_P (atype))
12458 : 1 : warning_at (loc, OPT_Wabsolute_value,
12459 : : "using decimal floating-point absolute value "
12460 : : "function %qD when argument is of integer type %qT",
12461 : : fndecl, atype);
12462 : 3 : else if (SCALAR_FLOAT_TYPE_P (atype))
12463 : 2 : warning_at (loc, OPT_Wabsolute_value,
12464 : : "using decimal floating-point absolute value "
12465 : : "function %qD when argument is of floating-point "
12466 : : "type %qT", fndecl, atype);
12467 : 1 : else if (TREE_CODE (atype) == COMPLEX_TYPE)
12468 : 1 : warning_at (loc, OPT_Wabsolute_value,
12469 : : "using decimal floating-point absolute value "
12470 : : "function %qD when argument is of complex type %qT",
12471 : : fndecl, atype);
12472 : : else
12473 : 0 : gcc_unreachable ();
12474 : 4 : return;
12475 : : }
12476 : : break;
12477 : :
12478 : : default:
12479 : : return;
12480 : : }
12481 : :
12482 : 366 : if (!TYPE_ARG_TYPES (TREE_TYPE (fndecl)))
12483 : : return;
12484 : :
12485 : 365 : tree ftype = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
12486 : 365 : if (TREE_CODE (atype) == COMPLEX_TYPE)
12487 : : {
12488 : 3 : gcc_assert (TREE_CODE (ftype) == COMPLEX_TYPE);
12489 : 3 : atype = TREE_TYPE (atype);
12490 : 3 : ftype = TREE_TYPE (ftype);
12491 : : }
12492 : :
12493 : 365 : if (TYPE_PRECISION (ftype) < TYPE_PRECISION (atype))
12494 : 9 : warning_at (loc, OPT_Wabsolute_value,
12495 : : "absolute value function %qD given an argument of type %qT "
12496 : : "but has parameter of type %qT which may cause truncation "
12497 : : "of value", fndecl, atype, ftype);
12498 : : }
12499 : :
12500 : :
12501 : : /* Parse a postfix expression after the initial primary or compound
12502 : : literal; that is, parse a series of postfix operators.
12503 : :
12504 : : EXPR_LOC is the location of the primary expression. */
12505 : :
12506 : : static struct c_expr
12507 : 213533920 : c_parser_postfix_expression_after_primary (c_parser *parser,
12508 : : location_t expr_loc,
12509 : : struct c_expr expr)
12510 : : {
12511 : 213533920 : struct c_expr orig_expr;
12512 : 213533920 : tree ident, idx, len;
12513 : 213533920 : location_t sizeof_arg_loc[6], comp_loc;
12514 : 213533920 : tree sizeof_arg[6];
12515 : 213533920 : unsigned int literal_zero_mask;
12516 : 213533920 : unsigned int i;
12517 : 213533920 : vec<tree, va_gc> *exprlist;
12518 : 213533920 : vec<tree, va_gc> *origtypes = NULL;
12519 : 213533920 : vec<location_t> arg_loc = vNULL;
12520 : 262924969 : location_t start;
12521 : 262924969 : location_t finish;
12522 : :
12523 : 262924969 : while (true)
12524 : : {
12525 : 262924969 : location_t op_loc = c_parser_peek_token (parser)->location;
12526 : 262924969 : switch (c_parser_peek_token (parser)->type)
12527 : : {
12528 : 3327637 : case CPP_OPEN_SQUARE:
12529 : : /* Array reference. */
12530 : 3327637 : c_parser_consume_token (parser);
12531 : 3327637 : idx = len = NULL_TREE;
12532 : 3327637 : if (!c_omp_array_section_p
12533 : 3328197 : || c_parser_next_token_is_not (parser, CPP_COLON))
12534 : 3327504 : idx = c_parser_expression (parser).value;
12535 : :
12536 : 3327637 : if (c_omp_array_section_p
12537 : 3328197 : && c_parser_next_token_is (parser, CPP_COLON))
12538 : : {
12539 : 445 : c_parser_consume_token (parser);
12540 : 445 : if (c_parser_next_token_is_not (parser, CPP_CLOSE_SQUARE))
12541 : 410 : len = c_parser_expression (parser).value;
12542 : :
12543 : 445 : expr.value = build_omp_array_section (op_loc, expr.value, idx,
12544 : : len);
12545 : : }
12546 : : else
12547 : 3327192 : expr.value = build_array_ref (op_loc, expr.value, idx);
12548 : :
12549 : 3327637 : c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
12550 : : "expected %<]%>");
12551 : :
12552 : 3327637 : start = expr.get_start ();
12553 : 3327637 : finish = parser->tokens_buf[0].location;
12554 : 3327637 : set_c_expr_source_range (&expr, start, finish);
12555 : 3327637 : expr.original_code = ERROR_MARK;
12556 : 3327637 : expr.original_type = NULL;
12557 : 3327637 : expr.m_decimal = 0;
12558 : 3327637 : break;
12559 : 43191611 : case CPP_OPEN_PAREN:
12560 : : /* Function call. */
12561 : 43191611 : {
12562 : 43191611 : matching_parens parens;
12563 : 43191611 : parens.consume_open (parser);
12564 : 345532888 : for (i = 0; i < 6; i++)
12565 : : {
12566 : 259149666 : sizeof_arg[i] = NULL_TREE;
12567 : 259149666 : sizeof_arg_loc[i] = UNKNOWN_LOCATION;
12568 : : }
12569 : 43191611 : literal_zero_mask = 0;
12570 : 43191611 : if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
12571 : : exprlist = NULL;
12572 : 33459701 : else if (TREE_CODE (expr.value) == FUNCTION_DECL
12573 : 33393490 : && fndecl_built_in_p (expr.value, BUILT_IN_CLASSIFY_TYPE)
12574 : 33461497 : && c_parser_next_tokens_start_typename (parser,
12575 : : cla_prefer_id))
12576 : : {
12577 : : /* __builtin_classify_type (type) */
12578 : 29 : c_inhibit_evaluation_warnings++;
12579 : 29 : in_alignof++;
12580 : 29 : struct c_type_name *type = c_parser_type_name (parser);
12581 : 29 : c_inhibit_evaluation_warnings--;
12582 : 29 : in_alignof--;
12583 : 29 : struct c_typespec ret;
12584 : 29 : ret.expr = NULL_TREE;
12585 : 29 : ret.spec = error_mark_node;
12586 : 29 : ret.expr_const_operands = false;
12587 : 29 : if (type != NULL)
12588 : 29 : ret.spec = groktypename (type, &ret.expr,
12589 : : &ret.expr_const_operands);
12590 : 29 : parens.skip_until_found_close (parser);
12591 : 29 : expr.value = build_int_cst (integer_type_node,
12592 : 29 : type_to_class (ret.spec));
12593 : 29 : break;
12594 : : }
12595 : : else
12596 : 33459672 : exprlist = c_parser_expr_list (parser, true, false, &origtypes,
12597 : : sizeof_arg_loc, sizeof_arg,
12598 : : &arg_loc, &literal_zero_mask);
12599 : 43191582 : parens.skip_until_found_close (parser);
12600 : : }
12601 : 43191582 : orig_expr = expr;
12602 : 43191582 : mark_exp_read (expr.value);
12603 : 43191582 : if (warn_sizeof_pointer_memaccess)
12604 : 4090402 : sizeof_pointer_memaccess_warning (sizeof_arg_loc,
12605 : : expr.value, exprlist,
12606 : : sizeof_arg,
12607 : : sizeof_ptr_memacc_comptypes);
12608 : 43191582 : if (TREE_CODE (expr.value) == FUNCTION_DECL)
12609 : : {
12610 : 43115671 : if (fndecl_built_in_p (expr.value, BUILT_IN_MEMSET)
12611 : 43146274 : && vec_safe_length (exprlist) == 3)
12612 : : {
12613 : 30603 : tree arg0 = (*exprlist)[0];
12614 : 30603 : tree arg2 = (*exprlist)[2];
12615 : 30603 : warn_for_memset (expr_loc, arg0, arg2, literal_zero_mask);
12616 : : }
12617 : 43115671 : if (warn_absolute_value
12618 : 3841163 : && fndecl_built_in_p (expr.value, BUILT_IN_NORMAL)
12619 : 43249040 : && vec_safe_length (exprlist) == 1)
12620 : 56157 : warn_for_abs (expr_loc, expr.value, (*exprlist)[0]);
12621 : 43115671 : if (parser->omp_for_parse_state
12622 : 151 : && parser->omp_for_parse_state->in_intervening_code
12623 : 43115787 : && omp_runtime_api_call (expr.value))
12624 : : {
12625 : 2 : error_at (expr_loc, "calls to the OpenMP runtime API are "
12626 : : "not permitted in intervening code");
12627 : 2 : parser->omp_for_parse_state->fail = true;
12628 : : }
12629 : 43115671 : if (warn_calloc_transposed_args)
12630 : 3841138 : if (tree attr = lookup_attribute ("alloc_size",
12631 : 3841138 : TYPE_ATTRIBUTES
12632 : : (TREE_TYPE (expr.value))))
12633 : 1235 : if (TREE_VALUE (attr) && TREE_CHAIN (TREE_VALUE (attr)))
12634 : 126 : warn_for_calloc (sizeof_arg_loc, expr.value, exprlist,
12635 : : sizeof_arg, attr);
12636 : : }
12637 : :
12638 : 43191582 : start = expr.get_start ();
12639 : 43191582 : finish = parser->tokens_buf[0].get_finish ();
12640 : 43191582 : expr.value
12641 : 43191582 : = c_build_function_call_vec (expr_loc, arg_loc, expr.value,
12642 : : exprlist, origtypes);
12643 : 43191582 : set_c_expr_source_range (&expr, start, finish);
12644 : 43191582 : expr.m_decimal = 0;
12645 : :
12646 : 43191582 : expr.original_code = ERROR_MARK;
12647 : 43191582 : if (TREE_CODE (expr.value) == INTEGER_CST
12648 : 12436 : && TREE_CODE (orig_expr.value) == FUNCTION_DECL
12649 : 43204018 : && fndecl_built_in_p (orig_expr.value, BUILT_IN_CONSTANT_P))
12650 : 1465 : expr.original_code = C_MAYBE_CONST_EXPR;
12651 : 43191582 : expr.original_type = NULL;
12652 : 43191582 : if (exprlist)
12653 : : {
12654 : 33459672 : release_tree_vector (exprlist);
12655 : 33459672 : release_tree_vector (origtypes);
12656 : : }
12657 : 43191582 : arg_loc.release ();
12658 : 43191582 : break;
12659 : 1739336 : case CPP_DOT:
12660 : : /* Structure element reference. */
12661 : 1739336 : c_parser_consume_token (parser);
12662 : 1739336 : expr = default_function_array_conversion (expr_loc, expr);
12663 : 1739336 : if (c_parser_next_token_is (parser, CPP_NAME))
12664 : : {
12665 : 1739336 : c_token *comp_tok = c_parser_peek_token (parser);
12666 : 1739336 : ident = comp_tok->value;
12667 : 1739336 : comp_loc = comp_tok->location;
12668 : : }
12669 : : else
12670 : : {
12671 : 0 : c_parser_error (parser, "expected identifier");
12672 : 0 : expr.set_error ();
12673 : 0 : expr.original_code = ERROR_MARK;
12674 : 0 : expr.original_type = NULL;
12675 : 0 : return expr;
12676 : : }
12677 : 1739336 : start = expr.get_start ();
12678 : 1739336 : finish = c_parser_peek_token (parser)->get_finish ();
12679 : 1739336 : c_parser_consume_token (parser);
12680 : 1739336 : expr.value = build_component_ref (op_loc, expr.value, ident,
12681 : : comp_loc, UNKNOWN_LOCATION);
12682 : 1739336 : set_c_expr_source_range (&expr, start, finish);
12683 : 1739336 : expr.original_code = ERROR_MARK;
12684 : 1739336 : if (TREE_CODE (expr.value) != COMPONENT_REF)
12685 : 30 : expr.original_type = NULL;
12686 : : else
12687 : : {
12688 : : /* Remember the original type of a bitfield. */
12689 : 1739306 : tree field = TREE_OPERAND (expr.value, 1);
12690 : 1739306 : if (TREE_CODE (field) != FIELD_DECL)
12691 : 0 : expr.original_type = NULL;
12692 : : else
12693 : 1739306 : expr.original_type = DECL_BIT_FIELD_TYPE (field);
12694 : : }
12695 : 1739336 : expr.m_decimal = 0;
12696 : 1739336 : break;
12697 : 469169 : case CPP_DEREF:
12698 : : /* Structure element reference. */
12699 : 469169 : c_parser_consume_token (parser);
12700 : 469169 : expr = convert_lvalue_to_rvalue (expr_loc, expr, true, false);
12701 : 469169 : if (c_parser_next_token_is (parser, CPP_NAME))
12702 : : {
12703 : 469137 : c_token *comp_tok = c_parser_peek_token (parser);
12704 : 469137 : ident = comp_tok->value;
12705 : 469137 : comp_loc = comp_tok->location;
12706 : : }
12707 : : else
12708 : : {
12709 : 32 : c_parser_error (parser, "expected identifier");
12710 : 32 : expr.set_error ();
12711 : 32 : expr.original_code = ERROR_MARK;
12712 : 32 : expr.original_type = NULL;
12713 : 32 : return expr;
12714 : : }
12715 : 469137 : start = expr.get_start ();
12716 : 469137 : finish = c_parser_peek_token (parser)->get_finish ();
12717 : 469137 : c_parser_consume_token (parser);
12718 : 469137 : expr.value = build_component_ref (op_loc,
12719 : : build_indirect_ref (op_loc,
12720 : : expr.value,
12721 : : RO_ARROW),
12722 : : ident, comp_loc,
12723 : : expr.get_location ());
12724 : 469137 : set_c_expr_source_range (&expr, start, finish);
12725 : 469137 : expr.original_code = ERROR_MARK;
12726 : 469137 : if (TREE_CODE (expr.value) != COMPONENT_REF)
12727 : 119 : expr.original_type = NULL;
12728 : : else
12729 : : {
12730 : : /* Remember the original type of a bitfield. */
12731 : 469018 : tree field = TREE_OPERAND (expr.value, 1);
12732 : 469018 : if (TREE_CODE (field) != FIELD_DECL)
12733 : 0 : expr.original_type = NULL;
12734 : : else
12735 : 469018 : expr.original_type = DECL_BIT_FIELD_TYPE (field);
12736 : : }
12737 : 469137 : expr.m_decimal = 0;
12738 : 469137 : break;
12739 : 646581 : case CPP_PLUS_PLUS:
12740 : : /* Postincrement. */
12741 : 646581 : start = expr.get_start ();
12742 : 646581 : finish = c_parser_peek_token (parser)->get_finish ();
12743 : 646581 : c_parser_consume_token (parser);
12744 : 646581 : expr = default_function_array_read_conversion (expr_loc, expr);
12745 : 646581 : expr.value = build_unary_op (op_loc, POSTINCREMENT_EXPR,
12746 : : expr.value, false);
12747 : 646581 : set_c_expr_source_range (&expr, start, finish);
12748 : 646581 : expr.original_code = ERROR_MARK;
12749 : 646581 : expr.original_type = NULL;
12750 : 646581 : break;
12751 : 16747 : case CPP_MINUS_MINUS:
12752 : : /* Postdecrement. */
12753 : 16747 : start = expr.get_start ();
12754 : 16747 : finish = c_parser_peek_token (parser)->get_finish ();
12755 : 16747 : c_parser_consume_token (parser);
12756 : 16747 : expr = default_function_array_read_conversion (expr_loc, expr);
12757 : 16747 : expr.value = build_unary_op (op_loc, POSTDECREMENT_EXPR,
12758 : : expr.value, false);
12759 : 16747 : set_c_expr_source_range (&expr, start, finish);
12760 : 16747 : expr.original_code = ERROR_MARK;
12761 : 16747 : expr.original_type = NULL;
12762 : 16747 : break;
12763 : 213533888 : default:
12764 : 213533888 : return expr;
12765 : : }
12766 : : }
12767 : : }
12768 : :
12769 : : /* Parse an expression (C90 6.3.17, C99 6.5.17, C11 6.5.17).
12770 : :
12771 : : expression:
12772 : : assignment-expression
12773 : : expression , assignment-expression
12774 : : */
12775 : :
12776 : : static struct c_expr
12777 : 49789317 : c_parser_expression (c_parser *parser)
12778 : : {
12779 : 49789317 : location_t tloc = c_parser_peek_token (parser)->location;
12780 : 49789317 : struct c_expr expr;
12781 : 49789317 : expr = c_parser_expr_no_commas (parser, NULL);
12782 : 49789317 : if (c_parser_next_token_is (parser, CPP_COMMA))
12783 : 85641 : expr = convert_lvalue_to_rvalue (tloc, expr, true, false);
12784 : 49887799 : while (c_parser_next_token_is (parser, CPP_COMMA))
12785 : : {
12786 : 98482 : struct c_expr next;
12787 : 98482 : tree lhsval;
12788 : 98482 : location_t loc = c_parser_peek_token (parser)->location;
12789 : 98482 : location_t expr_loc;
12790 : 98482 : c_parser_consume_token (parser);
12791 : 98482 : expr_loc = c_parser_peek_token (parser)->location;
12792 : 98482 : lhsval = expr.value;
12793 : 98482 : while (TREE_CODE (lhsval) == COMPOUND_EXPR
12794 : 112177 : || TREE_CODE (lhsval) == NOP_EXPR)
12795 : : {
12796 : 13695 : if (TREE_CODE (lhsval) == COMPOUND_EXPR)
12797 : 13605 : lhsval = TREE_OPERAND (lhsval, 1);
12798 : : else
12799 : 90 : lhsval = TREE_OPERAND (lhsval, 0);
12800 : : }
12801 : 98482 : if (DECL_P (lhsval) || handled_component_p (lhsval))
12802 : 80 : mark_exp_read (lhsval);
12803 : 98482 : next = c_parser_expr_no_commas (parser, NULL);
12804 : 98482 : next = convert_lvalue_to_rvalue (expr_loc, next, true, false);
12805 : 98482 : expr.value = build_compound_expr (loc, expr.value, next.value);
12806 : 98482 : expr.original_code = COMPOUND_EXPR;
12807 : 98482 : expr.original_type = next.original_type;
12808 : 98482 : expr.m_decimal = 0;
12809 : : }
12810 : 49789317 : return expr;
12811 : : }
12812 : :
12813 : : /* Parse an expression and convert functions or arrays to pointers and
12814 : : lvalues to rvalues. */
12815 : :
12816 : : static struct c_expr
12817 : 37621582 : c_parser_expression_conv (c_parser *parser)
12818 : : {
12819 : 37621582 : struct c_expr expr;
12820 : 37621582 : location_t loc = c_parser_peek_token (parser)->location;
12821 : 37621582 : expr = c_parser_expression (parser);
12822 : 37621582 : expr = convert_lvalue_to_rvalue (loc, expr, true, false);
12823 : 37621582 : return expr;
12824 : : }
12825 : :
12826 : : /* Helper function of c_parser_expr_list. Check if IDXth (0 based)
12827 : : argument is a literal zero alone and if so, set it in literal_zero_mask. */
12828 : :
12829 : : static inline void
12830 : 110724943 : c_parser_check_literal_zero (c_parser *parser, unsigned *literal_zero_mask,
12831 : : unsigned int idx)
12832 : : {
12833 : 110724943 : if (idx >= HOST_BITS_PER_INT)
12834 : : return;
12835 : :
12836 : 110703367 : c_token *tok = c_parser_peek_token (parser);
12837 : 110703367 : switch (tok->type)
12838 : : {
12839 : 6459133 : case CPP_NUMBER:
12840 : 6459133 : case CPP_CHAR:
12841 : 6459133 : case CPP_WCHAR:
12842 : 6459133 : case CPP_CHAR16:
12843 : 6459133 : case CPP_CHAR32:
12844 : 6459133 : case CPP_UTF8CHAR:
12845 : : /* If a parameter is literal zero alone, remember it
12846 : : for -Wmemset-transposed-args warning. */
12847 : 6459133 : if (integer_zerop (tok->value)
12848 : 1173710 : && !TREE_OVERFLOW (tok->value)
12849 : 7632843 : && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
12850 : 841473 : || c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_PAREN))
12851 : 1172887 : *literal_zero_mask |= 1U << idx;
12852 : : default:
12853 : : break;
12854 : : }
12855 : : }
12856 : :
12857 : : /* Parse a non-empty list of expressions. If CONVERT_P, convert
12858 : : functions and arrays to pointers and lvalues to rvalues. If
12859 : : FOLD_P, fold the expressions. If LOCATIONS is non-NULL, save the
12860 : : locations of function arguments into this vector.
12861 : :
12862 : : nonempty-expr-list:
12863 : : assignment-expression
12864 : : nonempty-expr-list , assignment-expression
12865 : : */
12866 : :
12867 : : static vec<tree, va_gc> *
12868 : 37579267 : c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p,
12869 : : vec<tree, va_gc> **p_orig_types,
12870 : : location_t *sizeof_arg_loc, tree *sizeof_arg,
12871 : : vec<location_t> *locations,
12872 : : unsigned int *literal_zero_mask)
12873 : : {
12874 : 37579267 : vec<tree, va_gc> *ret;
12875 : 37579267 : vec<tree, va_gc> *orig_types;
12876 : 37579267 : struct c_expr expr;
12877 : 37579267 : unsigned int idx = 0;
12878 : 37579267 : bool save_c_omp_array_section_p = c_omp_array_section_p;
12879 : 37579267 : c_omp_array_section_p = false;
12880 : :
12881 : 37579267 : ret = make_tree_vector ();
12882 : 37579267 : if (p_orig_types == NULL)
12883 : 4119595 : orig_types = NULL;
12884 : : else
12885 : 33459672 : orig_types = make_tree_vector ();
12886 : :
12887 : 37579267 : if (literal_zero_mask)
12888 : 33459672 : c_parser_check_literal_zero (parser, literal_zero_mask, 0);
12889 : 37579267 : expr = c_parser_expr_no_commas (parser, NULL);
12890 : 37579267 : if (convert_p)
12891 : 33459672 : expr = convert_lvalue_to_rvalue (expr.get_location (), expr, true, true);
12892 : 37579267 : if (fold_p)
12893 : 4119595 : expr.value = c_fully_fold (expr.value, false, NULL);
12894 : 37579267 : ret->quick_push (expr.value);
12895 : 37579267 : if (orig_types)
12896 : 33459672 : orig_types->quick_push (expr.original_type);
12897 : 37579267 : if (locations)
12898 : 33459672 : locations->safe_push (expr.get_location ());
12899 : 37579267 : if (sizeof_arg != NULL
12900 : 33459672 : && (expr.original_code == SIZEOF_EXPR
12901 : 33459672 : || expr.original_code == PAREN_SIZEOF_EXPR))
12902 : : {
12903 : 1940 : sizeof_arg[0] = c_last_sizeof_arg;
12904 : 1940 : sizeof_arg_loc[0] = c_last_sizeof_loc;
12905 : : }
12906 : 116111901 : while (c_parser_next_token_is (parser, CPP_COMMA))
12907 : : {
12908 : 78532634 : c_parser_consume_token (parser);
12909 : 78532634 : if (literal_zero_mask)
12910 : 77265271 : c_parser_check_literal_zero (parser, literal_zero_mask, idx + 1);
12911 : 78532634 : expr = c_parser_expr_no_commas (parser, NULL);
12912 : 78532634 : if (convert_p)
12913 : 77265271 : expr = convert_lvalue_to_rvalue (expr.get_location (), expr, true,
12914 : : true);
12915 : 78532634 : if (fold_p)
12916 : 1267363 : expr.value = c_fully_fold (expr.value, false, NULL);
12917 : 78532634 : vec_safe_push (ret, expr.value);
12918 : 78532634 : if (orig_types)
12919 : 77265271 : vec_safe_push (orig_types, expr.original_type);
12920 : 78532634 : if (locations)
12921 : 77265271 : locations->safe_push (expr.get_location ());
12922 : 78532634 : if (++idx < 6
12923 : 76917259 : && sizeof_arg != NULL
12924 : 78532634 : && (expr.original_code == SIZEOF_EXPR
12925 : 75649908 : || expr.original_code == PAREN_SIZEOF_EXPR))
12926 : : {
12927 : 77832 : sizeof_arg[idx] = c_last_sizeof_arg;
12928 : 77832 : sizeof_arg_loc[idx] = c_last_sizeof_loc;
12929 : : }
12930 : : }
12931 : 37579267 : if (orig_types)
12932 : 33459672 : *p_orig_types = orig_types;
12933 : 37579267 : c_omp_array_section_p = save_c_omp_array_section_p;
12934 : 37579267 : return ret;
12935 : : }
12936 : :
12937 : : /* Parse Objective-C-specific constructs. */
12938 : :
12939 : : /* Parse an objc-class-definition.
12940 : :
12941 : : objc-class-definition:
12942 : : @interface identifier objc-superclass[opt] objc-protocol-refs[opt]
12943 : : objc-class-instance-variables[opt] objc-methodprotolist @end
12944 : : @implementation identifier objc-superclass[opt]
12945 : : objc-class-instance-variables[opt]
12946 : : @interface identifier ( identifier ) objc-protocol-refs[opt]
12947 : : objc-methodprotolist @end
12948 : : @interface identifier ( ) objc-protocol-refs[opt]
12949 : : objc-methodprotolist @end
12950 : : @implementation identifier ( identifier )
12951 : :
12952 : : objc-superclass:
12953 : : : identifier
12954 : :
12955 : : "@interface identifier (" must start "@interface identifier (
12956 : : identifier ) ...": objc-methodprotolist in the first production may
12957 : : not start with a parenthesized identifier as a declarator of a data
12958 : : definition with no declaration specifiers if the objc-superclass,
12959 : : objc-protocol-refs and objc-class-instance-variables are omitted. */
12960 : :
12961 : : static void
12962 : 0 : c_parser_objc_class_definition (c_parser *parser, tree attributes)
12963 : : {
12964 : 0 : bool iface_p;
12965 : 0 : tree id1;
12966 : 0 : tree superclass;
12967 : 0 : if (c_parser_next_token_is_keyword (parser, RID_AT_INTERFACE))
12968 : : iface_p = true;
12969 : 0 : else if (c_parser_next_token_is_keyword (parser, RID_AT_IMPLEMENTATION))
12970 : : iface_p = false;
12971 : : else
12972 : 0 : gcc_unreachable ();
12973 : :
12974 : 0 : c_parser_consume_token (parser);
12975 : 0 : if (c_parser_next_token_is_not (parser, CPP_NAME))
12976 : : {
12977 : 0 : c_parser_error (parser, "expected identifier");
12978 : 0 : return;
12979 : : }
12980 : 0 : id1 = c_parser_peek_token (parser)->value;
12981 : 0 : location_t loc1 = c_parser_peek_token (parser)->location;
12982 : 0 : c_parser_consume_token (parser);
12983 : 0 : if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
12984 : : {
12985 : : /* We have a category or class extension. */
12986 : 0 : tree id2;
12987 : 0 : tree proto = NULL_TREE;
12988 : 0 : matching_parens parens;
12989 : 0 : parens.consume_open (parser);
12990 : 0 : if (c_parser_next_token_is_not (parser, CPP_NAME))
12991 : : {
12992 : 0 : if (iface_p && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
12993 : : {
12994 : : /* We have a class extension. */
12995 : : id2 = NULL_TREE;
12996 : : }
12997 : : else
12998 : : {
12999 : 0 : c_parser_error (parser, "expected identifier or %<)%>");
13000 : 0 : c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
13001 : 0 : return;
13002 : : }
13003 : : }
13004 : : else
13005 : : {
13006 : 0 : id2 = c_parser_peek_token (parser)->value;
13007 : 0 : c_parser_consume_token (parser);
13008 : : }
13009 : 0 : parens.skip_until_found_close (parser);
13010 : 0 : if (!iface_p)
13011 : : {
13012 : 0 : objc_start_category_implementation (id1, id2);
13013 : 0 : return;
13014 : : }
13015 : 0 : if (c_parser_next_token_is (parser, CPP_LESS))
13016 : 0 : proto = c_parser_objc_protocol_refs (parser);
13017 : 0 : objc_start_category_interface (id1, id2, proto, attributes);
13018 : 0 : c_parser_objc_methodprotolist (parser);
13019 : 0 : c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
13020 : 0 : objc_finish_interface ();
13021 : 0 : return;
13022 : : }
13023 : 0 : if (c_parser_next_token_is (parser, CPP_COLON))
13024 : : {
13025 : 0 : c_parser_consume_token (parser);
13026 : 0 : if (c_parser_next_token_is_not (parser, CPP_NAME))
13027 : : {
13028 : 0 : c_parser_error (parser, "expected identifier");
13029 : 0 : return;
13030 : : }
13031 : 0 : superclass = c_parser_peek_token (parser)->value;
13032 : 0 : c_parser_consume_token (parser);
13033 : : }
13034 : : else
13035 : : superclass = NULL_TREE;
13036 : 0 : if (iface_p)
13037 : : {
13038 : 0 : tree proto = NULL_TREE;
13039 : 0 : if (c_parser_next_token_is (parser, CPP_LESS))
13040 : 0 : proto = c_parser_objc_protocol_refs (parser);
13041 : 0 : objc_start_class_interface (id1, loc1, superclass, proto, attributes);
13042 : : }
13043 : : else
13044 : 0 : objc_start_class_implementation (id1, superclass);
13045 : 0 : if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
13046 : 0 : c_parser_objc_class_instance_variables (parser);
13047 : 0 : if (iface_p)
13048 : : {
13049 : 0 : objc_continue_interface ();
13050 : 0 : c_parser_objc_methodprotolist (parser);
13051 : 0 : c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
13052 : 0 : objc_finish_interface ();
13053 : : }
13054 : : else
13055 : : {
13056 : 0 : objc_continue_implementation ();
13057 : 0 : return;
13058 : : }
13059 : : }
13060 : :
13061 : : /* Parse objc-class-instance-variables.
13062 : :
13063 : : objc-class-instance-variables:
13064 : : { objc-instance-variable-decl-list[opt] }
13065 : :
13066 : : objc-instance-variable-decl-list:
13067 : : objc-visibility-spec
13068 : : objc-instance-variable-decl ;
13069 : : ;
13070 : : objc-instance-variable-decl-list objc-visibility-spec
13071 : : objc-instance-variable-decl-list objc-instance-variable-decl ;
13072 : : objc-instance-variable-decl-list ;
13073 : :
13074 : : objc-visibility-spec:
13075 : : @private
13076 : : @protected
13077 : : @public
13078 : :
13079 : : objc-instance-variable-decl:
13080 : : struct-declaration
13081 : : */
13082 : :
13083 : : static void
13084 : 0 : c_parser_objc_class_instance_variables (c_parser *parser)
13085 : : {
13086 : 0 : gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE));
13087 : 0 : c_parser_consume_token (parser);
13088 : 0 : while (c_parser_next_token_is_not (parser, CPP_EOF))
13089 : : {
13090 : 0 : tree decls;
13091 : : /* Parse any stray semicolon. */
13092 : 0 : if (c_parser_next_token_is (parser, CPP_SEMICOLON))
13093 : : {
13094 : 0 : pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
13095 : : "extra semicolon");
13096 : 0 : c_parser_consume_token (parser);
13097 : 0 : continue;
13098 : : }
13099 : : /* Stop if at the end of the instance variables. */
13100 : 0 : if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
13101 : : {
13102 : 0 : c_parser_consume_token (parser);
13103 : 0 : break;
13104 : : }
13105 : : /* Parse any objc-visibility-spec. */
13106 : 0 : if (c_parser_next_token_is_keyword (parser, RID_AT_PRIVATE))
13107 : : {
13108 : 0 : c_parser_consume_token (parser);
13109 : 0 : objc_set_visibility (OBJC_IVAR_VIS_PRIVATE);
13110 : 0 : continue;
13111 : : }
13112 : 0 : else if (c_parser_next_token_is_keyword (parser, RID_AT_PROTECTED))
13113 : : {
13114 : 0 : c_parser_consume_token (parser);
13115 : 0 : objc_set_visibility (OBJC_IVAR_VIS_PROTECTED);
13116 : 0 : continue;
13117 : : }
13118 : 0 : else if (c_parser_next_token_is_keyword (parser, RID_AT_PUBLIC))
13119 : : {
13120 : 0 : c_parser_consume_token (parser);
13121 : 0 : objc_set_visibility (OBJC_IVAR_VIS_PUBLIC);
13122 : 0 : continue;
13123 : : }
13124 : 0 : else if (c_parser_next_token_is_keyword (parser, RID_AT_PACKAGE))
13125 : : {
13126 : 0 : c_parser_consume_token (parser);
13127 : 0 : objc_set_visibility (OBJC_IVAR_VIS_PACKAGE);
13128 : 0 : continue;
13129 : : }
13130 : 0 : else if (c_parser_next_token_is (parser, CPP_PRAGMA))
13131 : : {
13132 : 0 : c_parser_pragma (parser, pragma_external, NULL);
13133 : 0 : continue;
13134 : : }
13135 : :
13136 : : /* Parse some comma-separated declarations. */
13137 : 0 : decls = c_parser_struct_declaration (parser, NULL);
13138 : 0 : if (decls == NULL)
13139 : : {
13140 : : /* There is a syntax error. We want to skip the offending
13141 : : tokens up to the next ';' (included) or '}'
13142 : : (excluded). */
13143 : :
13144 : : /* First, skip manually a ')' or ']'. This is because they
13145 : : reduce the nesting level, so c_parser_skip_until_found()
13146 : : wouldn't be able to skip past them. */
13147 : 0 : c_token *token = c_parser_peek_token (parser);
13148 : 0 : if (token->type == CPP_CLOSE_PAREN || token->type == CPP_CLOSE_SQUARE)
13149 : 0 : c_parser_consume_token (parser);
13150 : :
13151 : : /* Then, do the standard skipping. */
13152 : 0 : c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
13153 : :
13154 : : /* We hopefully recovered. Start normal parsing again. */
13155 : 0 : parser->error = false;
13156 : 0 : continue;
13157 : 0 : }
13158 : : else
13159 : : {
13160 : : /* Comma-separated instance variables are chained together
13161 : : in reverse order; add them one by one. */
13162 : 0 : tree ivar = nreverse (decls);
13163 : 0 : for (; ivar; ivar = DECL_CHAIN (ivar))
13164 : 0 : objc_add_instance_variable (copy_node (ivar));
13165 : : }
13166 : 0 : c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
13167 : : }
13168 : 0 : }
13169 : :
13170 : : /* Parse an objc-class-declaration.
13171 : :
13172 : : objc-class-declaration:
13173 : : @class identifier-list ;
13174 : : */
13175 : :
13176 : : static void
13177 : 0 : c_parser_objc_class_declaration (c_parser *parser)
13178 : : {
13179 : 0 : gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_CLASS));
13180 : 0 : c_parser_consume_token (parser);
13181 : : /* Any identifiers, including those declared as type names, are OK
13182 : : here. */
13183 : 0 : while (true)
13184 : : {
13185 : 0 : tree id;
13186 : 0 : if (c_parser_next_token_is_not (parser, CPP_NAME))
13187 : : {
13188 : 0 : c_parser_error (parser, "expected identifier");
13189 : 0 : c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
13190 : 0 : parser->error = false;
13191 : 0 : return;
13192 : : }
13193 : 0 : id = c_parser_peek_token (parser)->value;
13194 : 0 : objc_declare_class (id);
13195 : 0 : c_parser_consume_token (parser);
13196 : 0 : if (c_parser_next_token_is (parser, CPP_COMMA))
13197 : 0 : c_parser_consume_token (parser);
13198 : : else
13199 : : break;
13200 : 0 : }
13201 : 0 : c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
13202 : : }
13203 : :
13204 : : /* Parse an objc-alias-declaration.
13205 : :
13206 : : objc-alias-declaration:
13207 : : @compatibility_alias identifier identifier ;
13208 : : */
13209 : :
13210 : : static void
13211 : 0 : c_parser_objc_alias_declaration (c_parser *parser)
13212 : : {
13213 : 0 : tree id1, id2;
13214 : 0 : gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_ALIAS));
13215 : 0 : c_parser_consume_token (parser);
13216 : 0 : if (c_parser_next_token_is_not (parser, CPP_NAME))
13217 : : {
13218 : 0 : c_parser_error (parser, "expected identifier");
13219 : 0 : c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
13220 : 0 : return;
13221 : : }
13222 : 0 : id1 = c_parser_peek_token (parser)->value;
13223 : 0 : c_parser_consume_token (parser);
13224 : 0 : if (c_parser_next_token_is_not (parser, CPP_NAME))
13225 : : {
13226 : 0 : c_parser_error (parser, "expected identifier");
13227 : 0 : c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
13228 : 0 : return;
13229 : : }
13230 : 0 : id2 = c_parser_peek_token (parser)->value;
13231 : 0 : c_parser_consume_token (parser);
13232 : 0 : c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
13233 : 0 : objc_declare_alias (id1, id2);
13234 : : }
13235 : :
13236 : : /* Parse an objc-protocol-definition.
13237 : :
13238 : : objc-protocol-definition:
13239 : : @protocol identifier objc-protocol-refs[opt] objc-methodprotolist @end
13240 : : @protocol identifier-list ;
13241 : :
13242 : : "@protocol identifier ;" should be resolved as "@protocol
13243 : : identifier-list ;": objc-methodprotolist may not start with a
13244 : : semicolon in the first alternative if objc-protocol-refs are
13245 : : omitted. */
13246 : :
13247 : : static void
13248 : 0 : c_parser_objc_protocol_definition (c_parser *parser, tree attributes)
13249 : : {
13250 : 0 : gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_PROTOCOL));
13251 : :
13252 : 0 : c_parser_consume_token (parser);
13253 : 0 : if (c_parser_next_token_is_not (parser, CPP_NAME))
13254 : : {
13255 : 0 : c_parser_error (parser, "expected identifier");
13256 : 0 : return;
13257 : : }
13258 : 0 : if (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
13259 : 0 : || c_parser_peek_2nd_token (parser)->type == CPP_SEMICOLON)
13260 : : {
13261 : : /* Any identifiers, including those declared as type names, are
13262 : : OK here. */
13263 : 0 : while (true)
13264 : : {
13265 : 0 : tree id;
13266 : 0 : if (c_parser_next_token_is_not (parser, CPP_NAME))
13267 : : {
13268 : 0 : c_parser_error (parser, "expected identifier");
13269 : 0 : break;
13270 : : }
13271 : 0 : id = c_parser_peek_token (parser)->value;
13272 : 0 : objc_declare_protocol (id, attributes);
13273 : 0 : c_parser_consume_token (parser);
13274 : 0 : if (c_parser_next_token_is (parser, CPP_COMMA))
13275 : 0 : c_parser_consume_token (parser);
13276 : : else
13277 : : break;
13278 : 0 : }
13279 : 0 : c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
13280 : : }
13281 : : else
13282 : : {
13283 : 0 : tree id = c_parser_peek_token (parser)->value;
13284 : 0 : tree proto = NULL_TREE;
13285 : 0 : c_parser_consume_token (parser);
13286 : 0 : if (c_parser_next_token_is (parser, CPP_LESS))
13287 : 0 : proto = c_parser_objc_protocol_refs (parser);
13288 : 0 : parser->objc_pq_context = true;
13289 : 0 : objc_start_protocol (id, proto, attributes);
13290 : 0 : c_parser_objc_methodprotolist (parser);
13291 : 0 : c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
13292 : 0 : parser->objc_pq_context = false;
13293 : 0 : objc_finish_interface ();
13294 : : }
13295 : : }
13296 : :
13297 : : /* Parse an objc-method-type.
13298 : :
13299 : : objc-method-type:
13300 : : +
13301 : : -
13302 : :
13303 : : Return true if it is a class method (+) and false if it is
13304 : : an instance method (-).
13305 : : */
13306 : : static inline bool
13307 : 0 : c_parser_objc_method_type (c_parser *parser)
13308 : : {
13309 : 0 : switch (c_parser_peek_token (parser)->type)
13310 : : {
13311 : 0 : case CPP_PLUS:
13312 : 0 : c_parser_consume_token (parser);
13313 : 0 : return true;
13314 : 0 : case CPP_MINUS:
13315 : 0 : c_parser_consume_token (parser);
13316 : 0 : return false;
13317 : 0 : default:
13318 : 0 : gcc_unreachable ();
13319 : : }
13320 : : }
13321 : :
13322 : : /* Parse an objc-method-definition.
13323 : :
13324 : : objc-method-definition:
13325 : : objc-method-type objc-method-decl ;[opt] compound-statement
13326 : : */
13327 : :
13328 : : static void
13329 : 0 : c_parser_objc_method_definition (c_parser *parser)
13330 : : {
13331 : 0 : bool is_class_method = c_parser_objc_method_type (parser);
13332 : 0 : tree decl, attributes = NULL_TREE, expr = NULL_TREE;
13333 : 0 : parser->objc_pq_context = true;
13334 : 0 : decl = c_parser_objc_method_decl (parser, is_class_method, &attributes,
13335 : : &expr);
13336 : 0 : if (decl == error_mark_node)
13337 : 0 : return; /* Bail here. */
13338 : :
13339 : 0 : if (c_parser_next_token_is (parser, CPP_SEMICOLON))
13340 : : {
13341 : 0 : c_parser_consume_token (parser);
13342 : 0 : pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
13343 : : "extra semicolon in method definition specified");
13344 : : }
13345 : :
13346 : 0 : if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE))
13347 : : {
13348 : 0 : c_parser_error (parser, "expected %<{%>");
13349 : 0 : return;
13350 : : }
13351 : :
13352 : 0 : parser->objc_pq_context = false;
13353 : 0 : if (objc_start_method_definition (is_class_method, decl, attributes, expr))
13354 : : {
13355 : 0 : add_stmt (c_parser_compound_statement (parser));
13356 : 0 : objc_finish_method_definition (current_function_decl);
13357 : : }
13358 : : else
13359 : : {
13360 : : /* This code is executed when we find a method definition
13361 : : outside of an @implementation context (or invalid for other
13362 : : reasons). Parse the method (to keep going) but do not emit
13363 : : any code.
13364 : : */
13365 : 0 : c_parser_compound_statement (parser);
13366 : : }
13367 : : }
13368 : :
13369 : : /* Parse an objc-methodprotolist.
13370 : :
13371 : : objc-methodprotolist:
13372 : : empty
13373 : : objc-methodprotolist objc-methodproto
13374 : : objc-methodprotolist declaration
13375 : : objc-methodprotolist ;
13376 : : @optional
13377 : : @required
13378 : :
13379 : : The declaration is a data definition, which may be missing
13380 : : declaration specifiers under the same rules and diagnostics as
13381 : : other data definitions outside functions, and the stray semicolon
13382 : : is diagnosed the same way as a stray semicolon outside a
13383 : : function. */
13384 : :
13385 : : static void
13386 : 0 : c_parser_objc_methodprotolist (c_parser *parser)
13387 : : {
13388 : 0 : while (true)
13389 : : {
13390 : : /* The list is terminated by @end. */
13391 : 0 : switch (c_parser_peek_token (parser)->type)
13392 : : {
13393 : 0 : case CPP_SEMICOLON:
13394 : 0 : pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
13395 : : "ISO C does not allow extra %<;%> outside of a function");
13396 : 0 : c_parser_consume_token (parser);
13397 : 0 : break;
13398 : 0 : case CPP_PLUS:
13399 : 0 : case CPP_MINUS:
13400 : 0 : c_parser_objc_methodproto (parser);
13401 : 0 : break;
13402 : 0 : case CPP_PRAGMA:
13403 : 0 : c_parser_pragma (parser, pragma_external, NULL);
13404 : 0 : break;
13405 : : case CPP_EOF:
13406 : : return;
13407 : 0 : default:
13408 : 0 : if (c_parser_next_token_is_keyword (parser, RID_AT_END))
13409 : : return;
13410 : 0 : else if (c_parser_next_token_is_keyword (parser, RID_AT_PROPERTY))
13411 : 0 : c_parser_objc_at_property_declaration (parser);
13412 : 0 : else if (c_parser_next_token_is_keyword (parser, RID_AT_OPTIONAL))
13413 : : {
13414 : 0 : objc_set_method_opt (true);
13415 : 0 : c_parser_consume_token (parser);
13416 : : }
13417 : 0 : else if (c_parser_next_token_is_keyword (parser, RID_AT_REQUIRED))
13418 : : {
13419 : 0 : objc_set_method_opt (false);
13420 : 0 : c_parser_consume_token (parser);
13421 : : }
13422 : : else
13423 : 0 : c_parser_declaration_or_fndef (parser, false, false, true,
13424 : : false, true);
13425 : : break;
13426 : : }
13427 : : }
13428 : : }
13429 : :
13430 : : /* Parse an objc-methodproto.
13431 : :
13432 : : objc-methodproto:
13433 : : objc-method-type objc-method-decl ;
13434 : : */
13435 : :
13436 : : static void
13437 : 0 : c_parser_objc_methodproto (c_parser *parser)
13438 : : {
13439 : 0 : bool is_class_method = c_parser_objc_method_type (parser);
13440 : 0 : tree decl, attributes = NULL_TREE;
13441 : :
13442 : : /* Remember protocol qualifiers in prototypes. */
13443 : 0 : parser->objc_pq_context = true;
13444 : 0 : decl = c_parser_objc_method_decl (parser, is_class_method, &attributes,
13445 : : NULL);
13446 : : /* Forget protocol qualifiers now. */
13447 : 0 : parser->objc_pq_context = false;
13448 : :
13449 : : /* Do not allow the presence of attributes to hide an erroneous
13450 : : method implementation in the interface section. */
13451 : 0 : if (!c_parser_next_token_is (parser, CPP_SEMICOLON))
13452 : : {
13453 : 0 : c_parser_error (parser, "expected %<;%>");
13454 : 0 : return;
13455 : : }
13456 : :
13457 : 0 : if (decl != error_mark_node)
13458 : 0 : objc_add_method_declaration (is_class_method, decl, attributes);
13459 : :
13460 : 0 : c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
13461 : : }
13462 : :
13463 : : /* If we are at a position that method attributes may be present, check that
13464 : : there are not any parsed already (a syntax error) and then collect any
13465 : : specified at the current location. Finally, if new attributes were present,
13466 : : check that the next token is legal ( ';' for decls and '{' for defs). */
13467 : :
13468 : : static bool
13469 : 0 : c_parser_objc_maybe_method_attributes (c_parser* parser, tree* attributes)
13470 : : {
13471 : 0 : bool bad = false;
13472 : 0 : if (*attributes)
13473 : : {
13474 : 0 : c_parser_error (parser,
13475 : : "method attributes must be specified at the end only");
13476 : 0 : *attributes = NULL_TREE;
13477 : 0 : bad = true;
13478 : : }
13479 : :
13480 : 0 : if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
13481 : 0 : *attributes = c_parser_gnu_attributes (parser);
13482 : :
13483 : : /* If there were no attributes here, just report any earlier error. */
13484 : 0 : if (*attributes == NULL_TREE || bad)
13485 : : return bad;
13486 : :
13487 : : /* If the attributes are followed by a ; or {, then just report any earlier
13488 : : error. */
13489 : 0 : if (c_parser_next_token_is (parser, CPP_SEMICOLON)
13490 : 0 : || c_parser_next_token_is (parser, CPP_OPEN_BRACE))
13491 : 0 : return bad;
13492 : :
13493 : : /* We've got attributes, but not at the end. */
13494 : 0 : c_parser_error (parser,
13495 : : "expected %<;%> or %<{%> after method attribute definition");
13496 : 0 : return true;
13497 : : }
13498 : :
13499 : : /* Parse an objc-method-decl.
13500 : :
13501 : : objc-method-decl:
13502 : : ( objc-type-name ) objc-selector
13503 : : objc-selector
13504 : : ( objc-type-name ) objc-keyword-selector objc-optparmlist
13505 : : objc-keyword-selector objc-optparmlist
13506 : : gnu-attributes
13507 : :
13508 : : objc-keyword-selector:
13509 : : objc-keyword-decl
13510 : : objc-keyword-selector objc-keyword-decl
13511 : :
13512 : : objc-keyword-decl:
13513 : : objc-selector : ( objc-type-name ) identifier
13514 : : objc-selector : identifier
13515 : : : ( objc-type-name ) identifier
13516 : : : identifier
13517 : :
13518 : : objc-optparmlist:
13519 : : objc-optparms objc-optellipsis
13520 : :
13521 : : objc-optparms:
13522 : : empty
13523 : : objc-opt-parms , parameter-declaration
13524 : :
13525 : : objc-optellipsis:
13526 : : empty
13527 : : , ...
13528 : : */
13529 : :
13530 : : static tree
13531 : 0 : c_parser_objc_method_decl (c_parser *parser, bool is_class_method,
13532 : : tree *attributes, tree *expr)
13533 : : {
13534 : 0 : tree type = NULL_TREE;
13535 : 0 : tree sel;
13536 : 0 : tree parms = NULL_TREE;
13537 : 0 : bool ellipsis = false;
13538 : 0 : bool attr_err = false;
13539 : :
13540 : 0 : *attributes = NULL_TREE;
13541 : 0 : if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
13542 : : {
13543 : 0 : matching_parens parens;
13544 : 0 : parens.consume_open (parser);
13545 : 0 : type = c_parser_objc_type_name (parser);
13546 : 0 : parens.skip_until_found_close (parser);
13547 : : }
13548 : 0 : sel = c_parser_objc_selector (parser);
13549 : : /* If there is no selector, or a colon follows, we have an
13550 : : objc-keyword-selector. If there is a selector, and a colon does
13551 : : not follow, that selector ends the objc-method-decl. */
13552 : 0 : if (!sel || c_parser_next_token_is (parser, CPP_COLON))
13553 : : {
13554 : : tree tsel = sel;
13555 : : tree list = NULL_TREE;
13556 : 0 : while (true)
13557 : : {
13558 : 0 : tree atype = NULL_TREE, id, keyworddecl;
13559 : 0 : tree param_attr = NULL_TREE;
13560 : 0 : if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
13561 : : break;
13562 : 0 : if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
13563 : : {
13564 : 0 : c_parser_consume_token (parser);
13565 : 0 : atype = c_parser_objc_type_name (parser);
13566 : 0 : c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
13567 : : "expected %<)%>");
13568 : : }
13569 : : /* New ObjC allows attributes on method parameters. */
13570 : 0 : if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
13571 : 0 : param_attr = c_parser_gnu_attributes (parser);
13572 : 0 : if (c_parser_next_token_is_not (parser, CPP_NAME))
13573 : : {
13574 : 0 : c_parser_error (parser, "expected identifier");
13575 : 0 : return error_mark_node;
13576 : : }
13577 : 0 : id = c_parser_peek_token (parser)->value;
13578 : 0 : c_parser_consume_token (parser);
13579 : 0 : keyworddecl = objc_build_keyword_decl (tsel, atype, id, param_attr);
13580 : 0 : list = chainon (list, keyworddecl);
13581 : 0 : tsel = c_parser_objc_selector (parser);
13582 : 0 : if (!tsel && c_parser_next_token_is_not (parser, CPP_COLON))
13583 : : break;
13584 : : }
13585 : :
13586 : 0 : attr_err |= c_parser_objc_maybe_method_attributes (parser, attributes) ;
13587 : :
13588 : : /* Parse the optional parameter list. Optional Objective-C
13589 : : method parameters follow the C syntax, and may include '...'
13590 : : to denote a variable number of arguments. */
13591 : 0 : parms = make_node (TREE_LIST);
13592 : 0 : while (c_parser_next_token_is (parser, CPP_COMMA))
13593 : : {
13594 : 0 : struct c_parm *parm;
13595 : 0 : c_parser_consume_token (parser);
13596 : 0 : if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
13597 : : {
13598 : 0 : ellipsis = true;
13599 : 0 : c_parser_consume_token (parser);
13600 : 0 : attr_err |= c_parser_objc_maybe_method_attributes
13601 : 0 : (parser, attributes) ;
13602 : 0 : break;
13603 : : }
13604 : 0 : parm = c_parser_parameter_declaration (parser, NULL_TREE, false);
13605 : 0 : if (parm == NULL)
13606 : : break;
13607 : 0 : parms = chainon (parms,
13608 : : build_tree_list (NULL_TREE, grokparm (parm, expr)));
13609 : : }
13610 : : sel = list;
13611 : : }
13612 : : else
13613 : 0 : attr_err |= c_parser_objc_maybe_method_attributes (parser, attributes) ;
13614 : :
13615 : 0 : if (sel == NULL)
13616 : : {
13617 : 0 : c_parser_error (parser, "objective-c method declaration is expected");
13618 : 0 : return error_mark_node;
13619 : : }
13620 : :
13621 : 0 : if (attr_err)
13622 : 0 : return error_mark_node;
13623 : :
13624 : 0 : return objc_build_method_signature (is_class_method, type, sel, parms, ellipsis);
13625 : : }
13626 : :
13627 : : /* Parse an objc-type-name.
13628 : :
13629 : : objc-type-name:
13630 : : objc-type-qualifiers[opt] type-name
13631 : : objc-type-qualifiers[opt]
13632 : :
13633 : : objc-type-qualifiers:
13634 : : objc-type-qualifier
13635 : : objc-type-qualifiers objc-type-qualifier
13636 : :
13637 : : objc-type-qualifier: one of
13638 : : in out inout bycopy byref oneway
13639 : : */
13640 : :
13641 : : static tree
13642 : 0 : c_parser_objc_type_name (c_parser *parser)
13643 : : {
13644 : 0 : tree quals = NULL_TREE;
13645 : 0 : struct c_type_name *type_name = NULL;
13646 : 0 : tree type = NULL_TREE;
13647 : 0 : while (true)
13648 : : {
13649 : 0 : c_token *token = c_parser_peek_token (parser);
13650 : 0 : if (token->type == CPP_KEYWORD
13651 : 0 : && (token->keyword == RID_IN
13652 : : || token->keyword == RID_OUT
13653 : : || token->keyword == RID_INOUT
13654 : : || token->keyword == RID_BYCOPY
13655 : : || token->keyword == RID_BYREF
13656 : 0 : || token->keyword == RID_ONEWAY))
13657 : : {
13658 : 0 : quals = chainon (build_tree_list (NULL_TREE, token->value), quals);
13659 : 0 : c_parser_consume_token (parser);
13660 : : }
13661 : : else
13662 : : break;
13663 : 0 : }
13664 : 0 : if (c_parser_next_tokens_start_typename (parser, cla_prefer_type))
13665 : 0 : type_name = c_parser_type_name (parser);
13666 : 0 : if (type_name)
13667 : 0 : type = groktypename (type_name, NULL, NULL);
13668 : :
13669 : : /* If the type is unknown, and error has already been produced and
13670 : : we need to recover from the error. In that case, use NULL_TREE
13671 : : for the type, as if no type had been specified; this will use the
13672 : : default type ('id') which is good for error recovery. */
13673 : 0 : if (type == error_mark_node)
13674 : 0 : type = NULL_TREE;
13675 : :
13676 : 0 : return build_tree_list (quals, type);
13677 : : }
13678 : :
13679 : : /* Parse objc-protocol-refs.
13680 : :
13681 : : objc-protocol-refs:
13682 : : < identifier-list >
13683 : : */
13684 : :
13685 : : static tree
13686 : 0 : c_parser_objc_protocol_refs (c_parser *parser)
13687 : : {
13688 : 0 : tree list = NULL_TREE;
13689 : 0 : gcc_assert (c_parser_next_token_is (parser, CPP_LESS));
13690 : 0 : c_parser_consume_token (parser);
13691 : : /* Any identifiers, including those declared as type names, are OK
13692 : : here. */
13693 : 0 : while (true)
13694 : : {
13695 : 0 : tree id;
13696 : 0 : if (c_parser_next_token_is_not (parser, CPP_NAME))
13697 : : {
13698 : 0 : c_parser_error (parser, "expected identifier");
13699 : 0 : break;
13700 : : }
13701 : 0 : id = c_parser_peek_token (parser)->value;
13702 : 0 : list = chainon (list, build_tree_list (NULL_TREE, id));
13703 : 0 : c_parser_consume_token (parser);
13704 : 0 : if (c_parser_next_token_is (parser, CPP_COMMA))
13705 : 0 : c_parser_consume_token (parser);
13706 : : else
13707 : : break;
13708 : 0 : }
13709 : 0 : c_parser_require (parser, CPP_GREATER, "expected %<>%>");
13710 : 0 : return list;
13711 : : }
13712 : :
13713 : : /* Parse an objc-try-catch-finally-statement.
13714 : :
13715 : : objc-try-catch-finally-statement:
13716 : : @try compound-statement objc-catch-list[opt]
13717 : : @try compound-statement objc-catch-list[opt] @finally compound-statement
13718 : :
13719 : : objc-catch-list:
13720 : : @catch ( objc-catch-parameter-declaration ) compound-statement
13721 : : objc-catch-list @catch ( objc-catch-parameter-declaration ) compound-statement
13722 : :
13723 : : objc-catch-parameter-declaration:
13724 : : parameter-declaration
13725 : : '...'
13726 : :
13727 : : where '...' is to be interpreted literally, that is, it means CPP_ELLIPSIS.
13728 : :
13729 : : PS: This function is identical to cp_parser_objc_try_catch_finally_statement
13730 : : for C++. Keep them in sync. */
13731 : :
13732 : : static void
13733 : 0 : c_parser_objc_try_catch_finally_statement (c_parser *parser)
13734 : : {
13735 : 0 : location_t location;
13736 : 0 : tree stmt;
13737 : :
13738 : 0 : gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_TRY));
13739 : 0 : c_parser_consume_token (parser);
13740 : 0 : location = c_parser_peek_token (parser)->location;
13741 : 0 : objc_maybe_warn_exceptions (location);
13742 : 0 : stmt = c_parser_compound_statement (parser);
13743 : 0 : objc_begin_try_stmt (location, stmt);
13744 : :
13745 : 0 : while (c_parser_next_token_is_keyword (parser, RID_AT_CATCH))
13746 : : {
13747 : 0 : struct c_parm *parm;
13748 : 0 : tree parameter_declaration = error_mark_node;
13749 : 0 : bool seen_open_paren = false;
13750 : :
13751 : 0 : c_parser_consume_token (parser);
13752 : 0 : matching_parens parens;
13753 : 0 : if (!parens.require_open (parser))
13754 : 0 : seen_open_paren = true;
13755 : 0 : if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
13756 : : {
13757 : : /* We have "@catch (...)" (where the '...' are literally
13758 : : what is in the code). Skip the '...'.
13759 : : parameter_declaration is set to NULL_TREE, and
13760 : : objc_being_catch_clauses() knows that that means
13761 : : '...'. */
13762 : 0 : c_parser_consume_token (parser);
13763 : 0 : parameter_declaration = NULL_TREE;
13764 : : }
13765 : : else
13766 : : {
13767 : : /* We have "@catch (NSException *exception)" or something
13768 : : like that. Parse the parameter declaration. */
13769 : 0 : parm = c_parser_parameter_declaration (parser, NULL_TREE, false);
13770 : 0 : if (parm == NULL)
13771 : 0 : parameter_declaration = error_mark_node;
13772 : : else
13773 : 0 : parameter_declaration = grokparm (parm, NULL);
13774 : : }
13775 : 0 : if (seen_open_paren)
13776 : 0 : parens.require_close (parser);
13777 : : else
13778 : : {
13779 : : /* If there was no open parenthesis, we are recovering from
13780 : : an error, and we are trying to figure out what mistake
13781 : : the user has made. */
13782 : :
13783 : : /* If there is an immediate closing parenthesis, the user
13784 : : probably forgot the opening one (ie, they typed "@catch
13785 : : NSException *e)". Parse the closing parenthesis and keep
13786 : : going. */
13787 : 0 : if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
13788 : 0 : c_parser_consume_token (parser);
13789 : :
13790 : : /* If these is no immediate closing parenthesis, the user
13791 : : probably doesn't know that parenthesis are required at
13792 : : all (ie, they typed "@catch NSException *e"). So, just
13793 : : forget about the closing parenthesis and keep going. */
13794 : : }
13795 : 0 : objc_begin_catch_clause (parameter_declaration);
13796 : 0 : if (c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
13797 : 0 : c_parser_compound_statement_nostart (parser);
13798 : 0 : objc_finish_catch_clause ();
13799 : : }
13800 : 0 : if (c_parser_next_token_is_keyword (parser, RID_AT_FINALLY))
13801 : : {
13802 : 0 : c_parser_consume_token (parser);
13803 : 0 : location = c_parser_peek_token (parser)->location;
13804 : 0 : stmt = c_parser_compound_statement (parser);
13805 : 0 : objc_build_finally_clause (location, stmt);
13806 : : }
13807 : 0 : objc_finish_try_stmt ();
13808 : 0 : }
13809 : :
13810 : : /* Parse an objc-synchronized-statement.
13811 : :
13812 : : objc-synchronized-statement:
13813 : : @synchronized ( expression ) compound-statement
13814 : : */
13815 : :
13816 : : static void
13817 : 0 : c_parser_objc_synchronized_statement (c_parser *parser)
13818 : : {
13819 : 0 : location_t loc;
13820 : 0 : tree expr, stmt;
13821 : 0 : gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_SYNCHRONIZED));
13822 : 0 : c_parser_consume_token (parser);
13823 : 0 : loc = c_parser_peek_token (parser)->location;
13824 : 0 : objc_maybe_warn_exceptions (loc);
13825 : 0 : matching_parens parens;
13826 : 0 : if (parens.require_open (parser))
13827 : : {
13828 : 0 : struct c_expr ce = c_parser_expression (parser);
13829 : 0 : ce = convert_lvalue_to_rvalue (loc, ce, false, false);
13830 : 0 : expr = ce.value;
13831 : 0 : expr = c_fully_fold (expr, false, NULL);
13832 : 0 : parens.skip_until_found_close (parser);
13833 : : }
13834 : : else
13835 : 0 : expr = error_mark_node;
13836 : 0 : stmt = c_parser_compound_statement (parser);
13837 : 0 : objc_build_synchronized (loc, expr, stmt);
13838 : 0 : }
13839 : :
13840 : : /* Parse an objc-selector; return NULL_TREE without an error if the
13841 : : next token is not an objc-selector.
13842 : :
13843 : : objc-selector:
13844 : : identifier
13845 : : one of
13846 : : enum struct union if else while do for switch case default
13847 : : break continue return goto asm sizeof typeof typeof_unqual __alignof
13848 : : unsigned long const short volatile signed restrict _Complex
13849 : : in out inout bycopy byref oneway int char float double void _Bool
13850 : : _Atomic
13851 : :
13852 : : ??? Why this selection of keywords but not, for example, storage
13853 : : class specifiers? */
13854 : :
13855 : : static tree
13856 : 0 : c_parser_objc_selector (c_parser *parser)
13857 : : {
13858 : 0 : c_token *token = c_parser_peek_token (parser);
13859 : 0 : tree value = token->value;
13860 : 0 : if (token->type == CPP_NAME)
13861 : : {
13862 : 0 : c_parser_consume_token (parser);
13863 : 0 : return value;
13864 : : }
13865 : 0 : if (token->type != CPP_KEYWORD)
13866 : : return NULL_TREE;
13867 : 0 : switch (token->keyword)
13868 : : {
13869 : 0 : case RID_ENUM:
13870 : 0 : case RID_STRUCT:
13871 : 0 : case RID_UNION:
13872 : 0 : case RID_IF:
13873 : 0 : case RID_ELSE:
13874 : 0 : case RID_WHILE:
13875 : 0 : case RID_DO:
13876 : 0 : case RID_FOR:
13877 : 0 : case RID_SWITCH:
13878 : 0 : case RID_CASE:
13879 : 0 : case RID_DEFAULT:
13880 : 0 : case RID_BREAK:
13881 : 0 : case RID_CONTINUE:
13882 : 0 : case RID_RETURN:
13883 : 0 : case RID_GOTO:
13884 : 0 : case RID_ASM:
13885 : 0 : case RID_SIZEOF:
13886 : 0 : case RID_TYPEOF:
13887 : 0 : case RID_TYPEOF_UNQUAL:
13888 : 0 : case RID_ALIGNOF:
13889 : 0 : case RID_UNSIGNED:
13890 : 0 : case RID_LONG:
13891 : 0 : case RID_CONST:
13892 : 0 : case RID_SHORT:
13893 : 0 : case RID_VOLATILE:
13894 : 0 : case RID_SIGNED:
13895 : 0 : case RID_RESTRICT:
13896 : 0 : case RID_COMPLEX:
13897 : 0 : case RID_IN:
13898 : 0 : case RID_OUT:
13899 : 0 : case RID_INOUT:
13900 : 0 : case RID_BYCOPY:
13901 : 0 : case RID_BYREF:
13902 : 0 : case RID_ONEWAY:
13903 : 0 : case RID_INT:
13904 : 0 : case RID_CHAR:
13905 : 0 : case RID_FLOAT:
13906 : 0 : case RID_DOUBLE:
13907 : 0 : CASE_RID_FLOATN_NX:
13908 : 0 : case RID_VOID:
13909 : 0 : case RID_BOOL:
13910 : 0 : case RID_ATOMIC:
13911 : 0 : case RID_AUTO_TYPE:
13912 : 0 : case RID_INT_N_0:
13913 : 0 : case RID_INT_N_1:
13914 : 0 : case RID_INT_N_2:
13915 : 0 : case RID_INT_N_3:
13916 : 0 : c_parser_consume_token (parser);
13917 : 0 : return value;
13918 : : default:
13919 : : return NULL_TREE;
13920 : : }
13921 : : }
13922 : :
13923 : : /* Parse an objc-selector-arg.
13924 : :
13925 : : objc-selector-arg:
13926 : : objc-selector
13927 : : objc-keywordname-list
13928 : :
13929 : : objc-keywordname-list:
13930 : : objc-keywordname
13931 : : objc-keywordname-list objc-keywordname
13932 : :
13933 : : objc-keywordname:
13934 : : objc-selector :
13935 : : :
13936 : : */
13937 : :
13938 : : static tree
13939 : 0 : c_parser_objc_selector_arg (c_parser *parser)
13940 : : {
13941 : 0 : tree sel = c_parser_objc_selector (parser);
13942 : 0 : tree list = NULL_TREE;
13943 : 0 : if (sel
13944 : 0 : && c_parser_next_token_is_not (parser, CPP_COLON)
13945 : 0 : && c_parser_next_token_is_not (parser, CPP_SCOPE))
13946 : : return sel;
13947 : 0 : while (true)
13948 : : {
13949 : 0 : if (c_parser_next_token_is (parser, CPP_SCOPE))
13950 : : {
13951 : 0 : c_parser_consume_token (parser);
13952 : 0 : list = chainon (list, build_tree_list (sel, NULL_TREE));
13953 : 0 : list = chainon (list, build_tree_list (NULL_TREE, NULL_TREE));
13954 : : }
13955 : : else
13956 : : {
13957 : 0 : if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
13958 : 0 : return list;
13959 : 0 : list = chainon (list, build_tree_list (sel, NULL_TREE));
13960 : : }
13961 : 0 : sel = c_parser_objc_selector (parser);
13962 : 0 : if (!sel
13963 : 0 : && c_parser_next_token_is_not (parser, CPP_COLON)
13964 : 0 : && c_parser_next_token_is_not (parser, CPP_SCOPE))
13965 : : break;
13966 : : }
13967 : : return list;
13968 : : }
13969 : :
13970 : : /* Parse an objc-receiver.
13971 : :
13972 : : objc-receiver:
13973 : : expression
13974 : : class-name
13975 : : type-name
13976 : : */
13977 : :
13978 : : static tree
13979 : 0 : c_parser_objc_receiver (c_parser *parser)
13980 : : {
13981 : 0 : location_t loc = c_parser_peek_token (parser)->location;
13982 : :
13983 : 0 : if (c_parser_peek_token (parser)->type == CPP_NAME
13984 : 0 : && (c_parser_peek_token (parser)->id_kind == C_ID_TYPENAME
13985 : 0 : || c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME))
13986 : : {
13987 : 0 : tree id = c_parser_peek_token (parser)->value;
13988 : 0 : c_parser_consume_token (parser);
13989 : 0 : return objc_get_class_reference (id);
13990 : : }
13991 : 0 : struct c_expr ce = c_parser_expression (parser);
13992 : 0 : ce = convert_lvalue_to_rvalue (loc, ce, false, false);
13993 : 0 : return c_fully_fold (ce.value, false, NULL);
13994 : : }
13995 : :
13996 : : /* Parse objc-message-args.
13997 : :
13998 : : objc-message-args:
13999 : : objc-selector
14000 : : objc-keywordarg-list
14001 : :
14002 : : objc-keywordarg-list:
14003 : : objc-keywordarg
14004 : : objc-keywordarg-list objc-keywordarg
14005 : :
14006 : : objc-keywordarg:
14007 : : objc-selector : objc-keywordexpr
14008 : : : objc-keywordexpr
14009 : : */
14010 : :
14011 : : static tree
14012 : 0 : c_parser_objc_message_args (c_parser *parser)
14013 : : {
14014 : 0 : tree sel = c_parser_objc_selector (parser);
14015 : 0 : tree list = NULL_TREE;
14016 : 0 : if (sel && c_parser_next_token_is_not (parser, CPP_COLON))
14017 : : return sel;
14018 : 0 : while (true)
14019 : : {
14020 : 0 : tree keywordexpr;
14021 : 0 : if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
14022 : 0 : return error_mark_node;
14023 : 0 : keywordexpr = c_parser_objc_keywordexpr (parser);
14024 : 0 : list = chainon (list, build_tree_list (sel, keywordexpr));
14025 : 0 : sel = c_parser_objc_selector (parser);
14026 : 0 : if (!sel && c_parser_next_token_is_not (parser, CPP_COLON))
14027 : : break;
14028 : : }
14029 : : return list;
14030 : : }
14031 : :
14032 : : /* Parse an objc-keywordexpr.
14033 : :
14034 : : objc-keywordexpr:
14035 : : nonempty-expr-list
14036 : : */
14037 : :
14038 : : static tree
14039 : 0 : c_parser_objc_keywordexpr (c_parser *parser)
14040 : : {
14041 : 0 : tree ret;
14042 : 0 : vec<tree, va_gc> *expr_list = c_parser_expr_list (parser, true, true,
14043 : : NULL, NULL, NULL, NULL);
14044 : 0 : if (vec_safe_length (expr_list) == 1)
14045 : : {
14046 : : /* Just return the expression, remove a level of
14047 : : indirection. */
14048 : 0 : ret = (*expr_list)[0];
14049 : : }
14050 : : else
14051 : : {
14052 : : /* We have a comma expression, we will collapse later. */
14053 : 0 : ret = build_tree_list_vec (expr_list);
14054 : : }
14055 : 0 : release_tree_vector (expr_list);
14056 : 0 : return ret;
14057 : : }
14058 : :
14059 : : /* A check, needed in several places, that ObjC interface, implementation or
14060 : : method definitions are not prefixed by incorrect items. */
14061 : : static bool
14062 : 0 : c_parser_objc_diagnose_bad_element_prefix (c_parser *parser,
14063 : : struct c_declspecs *specs)
14064 : : {
14065 : 0 : if (!specs->declspecs_seen_p || specs->non_sc_seen_p
14066 : 0 : || specs->typespec_kind != ctsk_none)
14067 : : {
14068 : 0 : c_parser_error (parser,
14069 : : "no type or storage class may be specified here,");
14070 : 0 : c_parser_skip_to_end_of_block_or_statement (parser);
14071 : 0 : return true;
14072 : : }
14073 : : return false;
14074 : : }
14075 : :
14076 : : /* Parse an Objective-C @property declaration. The syntax is:
14077 : :
14078 : : objc-property-declaration:
14079 : : '@property' objc-property-attributes[opt] struct-declaration ;
14080 : :
14081 : : objc-property-attributes:
14082 : : '(' objc-property-attribute-list ')'
14083 : :
14084 : : objc-property-attribute-list:
14085 : : objc-property-attribute
14086 : : objc-property-attribute-list, objc-property-attribute
14087 : :
14088 : : objc-property-attribute
14089 : : 'getter' = identifier
14090 : : 'setter' = identifier
14091 : : 'readonly'
14092 : : 'readwrite'
14093 : : 'assign'
14094 : : 'retain'
14095 : : 'copy'
14096 : : 'nonatomic'
14097 : :
14098 : : For example:
14099 : : @property NSString *name;
14100 : : @property (readonly) id object;
14101 : : @property (retain, nonatomic, getter=getTheName) id name;
14102 : : @property int a, b, c;
14103 : :
14104 : : PS: This function is identical to cp_parser_objc_at_propery_declaration
14105 : : for C++. Keep them in sync. */
14106 : : static void
14107 : 0 : c_parser_objc_at_property_declaration (c_parser *parser)
14108 : : {
14109 : 0 : gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_PROPERTY));
14110 : 0 : location_t loc = c_parser_peek_token (parser)->location;
14111 : 0 : c_parser_consume_token (parser); /* Eat '@property'. */
14112 : :
14113 : : /* Parse the optional attribute list.
14114 : :
14115 : : A list of parsed, but not verified, attributes. */
14116 : 0 : vec<property_attribute_info *> prop_attr_list = vNULL;
14117 : :
14118 : 0 : bool syntax_error = false;
14119 : 0 : if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
14120 : : {
14121 : 0 : matching_parens parens;
14122 : :
14123 : 0 : location_t attr_start = c_parser_peek_token (parser)->location;
14124 : : /* Eat the '(' */
14125 : 0 : parens.consume_open (parser);
14126 : :
14127 : : /* Property attribute keywords are valid now. */
14128 : 0 : parser->objc_property_attr_context = true;
14129 : :
14130 : : /* Allow @property (), with a warning. */
14131 : 0 : location_t attr_end = c_parser_peek_token (parser)->location;
14132 : :
14133 : 0 : if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
14134 : : {
14135 : 0 : location_t attr_comb = make_location (attr_end, attr_start, attr_end);
14136 : 0 : warning_at (attr_comb, OPT_Wattributes,
14137 : : "empty property attribute list");
14138 : : }
14139 : : else
14140 : 0 : while (true)
14141 : : {
14142 : 0 : c_token *token = c_parser_peek_token (parser);
14143 : 0 : attr_start = token->location;
14144 : 0 : attr_end = get_finish (token->location);
14145 : 0 : location_t attr_comb = make_location (attr_start, attr_start,
14146 : : attr_end);
14147 : :
14148 : 0 : if (token->type == CPP_CLOSE_PAREN || token->type == CPP_COMMA)
14149 : : {
14150 : 0 : warning_at (attr_comb, OPT_Wattributes,
14151 : : "missing property attribute");
14152 : 0 : if (token->type == CPP_CLOSE_PAREN)
14153 : : break;
14154 : 0 : c_parser_consume_token (parser);
14155 : 0 : continue;
14156 : : }
14157 : :
14158 : 0 : tree attr_name = NULL_TREE;
14159 : 0 : enum rid keyword = RID_MAX; /* Not a valid property attribute. */
14160 : 0 : bool add_at = false;
14161 : 0 : if (token->type == CPP_KEYWORD)
14162 : : {
14163 : 0 : keyword = token->keyword;
14164 : 0 : if (OBJC_IS_AT_KEYWORD (keyword))
14165 : : {
14166 : : /* For '@' keywords the token value has the keyword,
14167 : : prepend the '@' for diagnostics. */
14168 : 0 : attr_name = token->value;
14169 : 0 : add_at = true;
14170 : : }
14171 : : else
14172 : 0 : attr_name = ridpointers[(int)keyword];
14173 : : }
14174 : 0 : else if (token->type == CPP_NAME)
14175 : 0 : attr_name = token->value;
14176 : 0 : c_parser_consume_token (parser);
14177 : :
14178 : 0 : enum objc_property_attribute_kind prop_kind
14179 : 0 : = objc_prop_attr_kind_for_rid (keyword);
14180 : 0 : property_attribute_info *prop
14181 : 0 : = new property_attribute_info (attr_name, attr_comb, prop_kind);
14182 : 0 : prop_attr_list.safe_push (prop);
14183 : :
14184 : 0 : tree meth_name;
14185 : 0 : switch (prop->prop_kind)
14186 : : {
14187 : : default: break;
14188 : 0 : case OBJC_PROPERTY_ATTR_UNKNOWN:
14189 : 0 : if (attr_name)
14190 : 0 : error_at (attr_comb, "unknown property attribute %<%s%s%>",
14191 : 0 : add_at ? "@" : "", IDENTIFIER_POINTER (attr_name));
14192 : : else
14193 : 0 : error_at (attr_comb, "unknown property attribute");
14194 : 0 : prop->parse_error = syntax_error = true;
14195 : 0 : break;
14196 : :
14197 : 0 : case OBJC_PROPERTY_ATTR_GETTER:
14198 : 0 : case OBJC_PROPERTY_ATTR_SETTER:
14199 : 0 : if (c_parser_next_token_is_not (parser, CPP_EQ))
14200 : : {
14201 : 0 : attr_comb = make_location (attr_end, attr_start, attr_end);
14202 : 0 : error_at (attr_comb, "expected %<=%> after Objective-C %qE",
14203 : : attr_name);
14204 : 0 : prop->parse_error = syntax_error = true;
14205 : 0 : break;
14206 : : }
14207 : 0 : token = c_parser_peek_token (parser);
14208 : 0 : attr_end = token->location;
14209 : 0 : c_parser_consume_token (parser); /* eat the = */
14210 : 0 : if (c_parser_next_token_is_not (parser, CPP_NAME))
14211 : : {
14212 : 0 : attr_comb = make_location (attr_end, attr_start, attr_end);
14213 : 0 : error_at (attr_comb, "expected %qE selector name",
14214 : : attr_name);
14215 : 0 : prop->parse_error = syntax_error = true;
14216 : 0 : break;
14217 : : }
14218 : : /* Get the end of the method name, and consume the name. */
14219 : 0 : token = c_parser_peek_token (parser);
14220 : 0 : attr_end = get_finish (token->location);
14221 : 0 : meth_name = token->value;
14222 : 0 : c_parser_consume_token (parser);
14223 : 0 : if (prop->prop_kind == OBJC_PROPERTY_ATTR_SETTER)
14224 : : {
14225 : 0 : if (c_parser_next_token_is_not (parser, CPP_COLON))
14226 : : {
14227 : 0 : attr_comb = make_location (attr_end, attr_start,
14228 : : attr_end);
14229 : 0 : error_at (attr_comb, "setter method names must"
14230 : : " terminate with %<:%>");
14231 : 0 : prop->parse_error = syntax_error = true;
14232 : : }
14233 : : else
14234 : : {
14235 : 0 : attr_end = get_finish (c_parser_peek_token
14236 : 0 : (parser)->location);
14237 : 0 : c_parser_consume_token (parser);
14238 : : }
14239 : 0 : attr_comb = make_location (attr_start, attr_start,
14240 : : attr_end);
14241 : : }
14242 : : else
14243 : 0 : attr_comb = make_location (attr_start, attr_start,
14244 : : attr_end);
14245 : 0 : prop->ident = meth_name;
14246 : : /* Updated location including all that was successfully
14247 : : parsed. */
14248 : 0 : prop->prop_loc = attr_comb;
14249 : 0 : break;
14250 : : }
14251 : :
14252 : : /* If we see a comma here, then keep going - even if we already
14253 : : saw a syntax error. For simple mistakes e.g. (asign, getter=x)
14254 : : this makes a more useful output and avoid spurious warnings about
14255 : : missing attributes that are, in fact, specified after the one with
14256 : : the syntax error. */
14257 : 0 : if (c_parser_next_token_is (parser, CPP_COMMA))
14258 : 0 : c_parser_consume_token (parser);
14259 : : else
14260 : : break;
14261 : : }
14262 : 0 : parser->objc_property_attr_context = false;
14263 : :
14264 : 0 : if (syntax_error && c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN))
14265 : : /* We don't really want to chew the whole of the file looking for a
14266 : : matching closing parenthesis, so we will try to read the decl and
14267 : : let the error handling for that close out the statement. */
14268 : : ;
14269 : : else
14270 : 0 : syntax_error = false, parens.skip_until_found_close (parser);
14271 : : }
14272 : :
14273 : : /* 'properties' is the list of properties that we read. Usually a
14274 : : single one, but maybe more (eg, in "@property int a, b, c;" there
14275 : : are three). */
14276 : 0 : tree properties = c_parser_struct_declaration (parser, NULL);
14277 : :
14278 : 0 : if (properties == error_mark_node)
14279 : 0 : c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
14280 : : else
14281 : : {
14282 : 0 : if (properties == NULL_TREE)
14283 : 0 : c_parser_error (parser, "expected identifier");
14284 : : else
14285 : : {
14286 : : /* Comma-separated properties are chained together in reverse order;
14287 : : add them one by one. */
14288 : 0 : properties = nreverse (properties);
14289 : 0 : for (; properties; properties = TREE_CHAIN (properties))
14290 : 0 : objc_add_property_declaration (loc, copy_node (properties),
14291 : : prop_attr_list);
14292 : : }
14293 : 0 : c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
14294 : : }
14295 : :
14296 : 0 : while (!prop_attr_list.is_empty())
14297 : 0 : delete prop_attr_list.pop ();
14298 : 0 : prop_attr_list.release ();
14299 : 0 : parser->error = false;
14300 : 0 : }
14301 : :
14302 : : /* Parse an Objective-C @synthesize declaration. The syntax is:
14303 : :
14304 : : objc-synthesize-declaration:
14305 : : @synthesize objc-synthesize-identifier-list ;
14306 : :
14307 : : objc-synthesize-identifier-list:
14308 : : objc-synthesize-identifier
14309 : : objc-synthesize-identifier-list, objc-synthesize-identifier
14310 : :
14311 : : objc-synthesize-identifier
14312 : : identifier
14313 : : identifier = identifier
14314 : :
14315 : : For example:
14316 : : @synthesize MyProperty;
14317 : : @synthesize OneProperty, AnotherProperty=MyIvar, YetAnotherProperty;
14318 : :
14319 : : PS: This function is identical to cp_parser_objc_at_synthesize_declaration
14320 : : for C++. Keep them in sync.
14321 : : */
14322 : : static void
14323 : 0 : c_parser_objc_at_synthesize_declaration (c_parser *parser)
14324 : : {
14325 : 0 : tree list = NULL_TREE;
14326 : 0 : location_t loc;
14327 : 0 : gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_SYNTHESIZE));
14328 : 0 : loc = c_parser_peek_token (parser)->location;
14329 : :
14330 : 0 : c_parser_consume_token (parser);
14331 : 0 : while (true)
14332 : : {
14333 : 0 : tree property, ivar;
14334 : 0 : if (c_parser_next_token_is_not (parser, CPP_NAME))
14335 : : {
14336 : 0 : c_parser_error (parser, "expected identifier");
14337 : 0 : c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
14338 : : /* Once we find the semicolon, we can resume normal parsing.
14339 : : We have to reset parser->error manually because
14340 : : c_parser_skip_until_found() won't reset it for us if the
14341 : : next token is precisely a semicolon. */
14342 : 0 : parser->error = false;
14343 : 0 : return;
14344 : : }
14345 : 0 : property = c_parser_peek_token (parser)->value;
14346 : 0 : c_parser_consume_token (parser);
14347 : 0 : if (c_parser_next_token_is (parser, CPP_EQ))
14348 : : {
14349 : 0 : c_parser_consume_token (parser);
14350 : 0 : if (c_parser_next_token_is_not (parser, CPP_NAME))
14351 : : {
14352 : 0 : c_parser_error (parser, "expected identifier");
14353 : 0 : c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
14354 : 0 : parser->error = false;
14355 : 0 : return;
14356 : : }
14357 : 0 : ivar = c_parser_peek_token (parser)->value;
14358 : 0 : c_parser_consume_token (parser);
14359 : : }
14360 : : else
14361 : : ivar = NULL_TREE;
14362 : 0 : list = chainon (list, build_tree_list (ivar, property));
14363 : 0 : if (c_parser_next_token_is (parser, CPP_COMMA))
14364 : 0 : c_parser_consume_token (parser);
14365 : : else
14366 : : break;
14367 : 0 : }
14368 : 0 : c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
14369 : 0 : objc_add_synthesize_declaration (loc, list);
14370 : : }
14371 : :
14372 : : /* Parse an Objective-C @dynamic declaration. The syntax is:
14373 : :
14374 : : objc-dynamic-declaration:
14375 : : @dynamic identifier-list ;
14376 : :
14377 : : For example:
14378 : : @dynamic MyProperty;
14379 : : @dynamic MyProperty, AnotherProperty;
14380 : :
14381 : : PS: This function is identical to cp_parser_objc_at_dynamic_declaration
14382 : : for C++. Keep them in sync.
14383 : : */
14384 : : static void
14385 : 0 : c_parser_objc_at_dynamic_declaration (c_parser *parser)
14386 : : {
14387 : 0 : tree list = NULL_TREE;
14388 : 0 : location_t loc;
14389 : 0 : gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_DYNAMIC));
14390 : 0 : loc = c_parser_peek_token (parser)->location;
14391 : :
14392 : 0 : c_parser_consume_token (parser);
14393 : 0 : while (true)
14394 : : {
14395 : 0 : tree property;
14396 : 0 : if (c_parser_next_token_is_not (parser, CPP_NAME))
14397 : : {
14398 : 0 : c_parser_error (parser, "expected identifier");
14399 : 0 : c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
14400 : 0 : parser->error = false;
14401 : 0 : return;
14402 : : }
14403 : 0 : property = c_parser_peek_token (parser)->value;
14404 : 0 : list = chainon (list, build_tree_list (NULL_TREE, property));
14405 : 0 : c_parser_consume_token (parser);
14406 : 0 : if (c_parser_next_token_is (parser, CPP_COMMA))
14407 : 0 : c_parser_consume_token (parser);
14408 : : else
14409 : : break;
14410 : 0 : }
14411 : 0 : c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
14412 : 0 : objc_add_dynamic_declaration (loc, list);
14413 : : }
14414 : :
14415 : :
14416 : : /* Parse a pragma GCC ivdep. */
14417 : :
14418 : : static bool
14419 : 128 : c_parse_pragma_ivdep (c_parser *parser)
14420 : : {
14421 : 0 : c_parser_consume_pragma (parser);
14422 : 0 : c_parser_skip_to_pragma_eol (parser);
14423 : 128 : return true;
14424 : : }
14425 : :
14426 : : /* Parse a pragma GCC novector. */
14427 : :
14428 : : static bool
14429 : 2355 : c_parse_pragma_novector (c_parser *parser)
14430 : : {
14431 : 0 : c_parser_consume_pragma (parser);
14432 : 0 : c_parser_skip_to_pragma_eol (parser);
14433 : 2355 : return true;
14434 : : }
14435 : :
14436 : : /* Parse a pragma GCC unroll. */
14437 : :
14438 : : static unsigned short
14439 : 229 : c_parser_pragma_unroll (c_parser *parser)
14440 : : {
14441 : 229 : unsigned short unroll;
14442 : 229 : c_parser_consume_pragma (parser);
14443 : 229 : location_t location = c_parser_peek_token (parser)->location;
14444 : 229 : tree expr = c_parser_expr_no_commas (parser, NULL).value;
14445 : 229 : mark_exp_read (expr);
14446 : 229 : expr = c_fully_fold (expr, false, NULL);
14447 : 229 : HOST_WIDE_INT lunroll = 0;
14448 : 458 : if (!INTEGRAL_TYPE_P (TREE_TYPE (expr))
14449 : 228 : || TREE_CODE (expr) != INTEGER_CST
14450 : 227 : || (lunroll = tree_to_shwi (expr)) < 0
14451 : 455 : || lunroll >= USHRT_MAX)
14452 : : {
14453 : 4 : error_at (location, "%<#pragma GCC unroll%> requires an"
14454 : : " assignment-expression that evaluates to a non-negative"
14455 : : " integral constant less than %u", USHRT_MAX);
14456 : 4 : unroll = 0;
14457 : : }
14458 : : else
14459 : : {
14460 : 225 : unroll = (unsigned short)lunroll;
14461 : 225 : if (unroll == 0)
14462 : : unroll = 1;
14463 : : }
14464 : :
14465 : 229 : c_parser_skip_to_pragma_eol (parser);
14466 : 229 : return unroll;
14467 : : }
14468 : :
14469 : : /* Handle pragmas. Some OpenMP pragmas are associated with, and therefore
14470 : : should be considered, statements. ALLOW_STMT is true if we're within
14471 : : the context of a function and such pragmas are to be allowed. Returns
14472 : : true if we actually parsed such a pragma. */
14473 : :
14474 : : static bool
14475 : 1791022 : c_parser_pragma (c_parser *parser, enum pragma_context context, bool *if_p)
14476 : : {
14477 : 1791022 : unsigned int id;
14478 : 1791022 : const char *construct = NULL;
14479 : :
14480 : 1791022 : input_location = c_parser_peek_token (parser)->location;
14481 : 1791022 : id = c_parser_peek_token (parser)->pragma_kind;
14482 : 1791022 : gcc_assert (id != PRAGMA_NONE);
14483 : 1791022 : if (parser->omp_for_parse_state
14484 : 8 : && parser->omp_for_parse_state->in_intervening_code
14485 : : && id >= PRAGMA_OMP__START_
14486 : 8 : && id <= PRAGMA_OMP__LAST_)
14487 : : {
14488 : 2 : error_at (input_location,
14489 : : "intervening code must not contain OpenMP directives");
14490 : 2 : parser->omp_for_parse_state->fail = true;
14491 : 2 : c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
14492 : 2 : return false;
14493 : : }
14494 : :
14495 : 1791020 : switch (id)
14496 : : {
14497 : 142 : case PRAGMA_OACC_DECLARE:
14498 : 142 : c_parser_oacc_declare (parser);
14499 : 142 : return false;
14500 : :
14501 : 134 : case PRAGMA_OACC_ENTER_DATA:
14502 : 134 : if (context != pragma_compound)
14503 : : {
14504 : : construct = "acc enter data";
14505 : 62 : in_compound:
14506 : 62 : if (context == pragma_stmt)
14507 : : {
14508 : 59 : error_at (c_parser_peek_token (parser)->location,
14509 : : "%<#pragma %s%> may only be used in compound "
14510 : : "statements", construct);
14511 : 59 : c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
14512 : 59 : return true;
14513 : : }
14514 : 3 : goto bad_stmt;
14515 : : }
14516 : 131 : c_parser_oacc_enter_exit_data (parser, true);
14517 : 131 : return false;
14518 : :
14519 : 130 : case PRAGMA_OACC_EXIT_DATA:
14520 : 130 : if (context != pragma_compound)
14521 : : {
14522 : 3 : construct = "acc exit data";
14523 : 3 : goto in_compound;
14524 : : }
14525 : 127 : c_parser_oacc_enter_exit_data (parser, false);
14526 : 127 : return false;
14527 : :
14528 : 337 : case PRAGMA_OACC_ROUTINE:
14529 : 337 : if (context != pragma_external)
14530 : : {
14531 : 5 : error_at (c_parser_peek_token (parser)->location,
14532 : : "%<#pragma acc routine%> must be at file scope");
14533 : 5 : c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
14534 : 5 : return false;
14535 : : }
14536 : 332 : c_parser_oacc_routine (parser, context);
14537 : 332 : return false;
14538 : :
14539 : 99 : case PRAGMA_OACC_UPDATE:
14540 : 99 : if (context != pragma_compound)
14541 : : {
14542 : 8 : construct = "acc update";
14543 : 8 : goto in_compound;
14544 : : }
14545 : 91 : c_parser_oacc_update (parser);
14546 : 91 : return false;
14547 : :
14548 : 355 : case PRAGMA_OMP_BARRIER:
14549 : 355 : if (context != pragma_compound)
14550 : : {
14551 : 11 : construct = "omp barrier";
14552 : 11 : goto in_compound;
14553 : : }
14554 : 344 : c_parser_omp_barrier (parser);
14555 : 344 : return false;
14556 : :
14557 : 74 : case PRAGMA_OMP_DEPOBJ:
14558 : 74 : if (context != pragma_compound)
14559 : : {
14560 : 1 : construct = "omp depobj";
14561 : 1 : goto in_compound;
14562 : : }
14563 : 73 : c_parser_omp_depobj (parser);
14564 : 73 : return false;
14565 : :
14566 : 67 : case PRAGMA_OMP_FLUSH:
14567 : 67 : if (context != pragma_compound)
14568 : : {
14569 : 9 : construct = "omp flush";
14570 : 9 : goto in_compound;
14571 : : }
14572 : 58 : c_parser_omp_flush (parser);
14573 : 58 : return false;
14574 : :
14575 : 99 : case PRAGMA_OMP_TASKWAIT:
14576 : 99 : if (context != pragma_compound)
14577 : : {
14578 : 8 : construct = "omp taskwait";
14579 : 8 : goto in_compound;
14580 : : }
14581 : 91 : c_parser_omp_taskwait (parser);
14582 : 91 : return false;
14583 : :
14584 : 14 : case PRAGMA_OMP_TASKYIELD:
14585 : 14 : if (context != pragma_compound)
14586 : : {
14587 : 8 : construct = "omp taskyield";
14588 : 8 : goto in_compound;
14589 : : }
14590 : 6 : c_parser_omp_taskyield (parser);
14591 : 6 : return false;
14592 : :
14593 : 221 : case PRAGMA_OMP_CANCEL:
14594 : 221 : if (context != pragma_compound)
14595 : : {
14596 : 8 : construct = "omp cancel";
14597 : 8 : goto in_compound;
14598 : : }
14599 : 213 : c_parser_omp_cancel (parser);
14600 : 213 : return false;
14601 : :
14602 : 179 : case PRAGMA_OMP_CANCELLATION_POINT:
14603 : 179 : return c_parser_omp_cancellation_point (parser, context);
14604 : :
14605 : 77 : case PRAGMA_OMP_THREADPRIVATE:
14606 : 77 : c_parser_omp_threadprivate (parser);
14607 : 77 : return false;
14608 : :
14609 : 7139 : case PRAGMA_OMP_TARGET:
14610 : 7139 : return c_parser_omp_target (parser, context, if_p);
14611 : :
14612 : 88 : case PRAGMA_OMP_BEGIN:
14613 : 88 : c_parser_omp_begin (parser);
14614 : 88 : return false;
14615 : :
14616 : 189 : case PRAGMA_OMP_END:
14617 : 189 : c_parser_omp_end (parser);
14618 : 189 : return false;
14619 : :
14620 : 18 : case PRAGMA_OMP_SCAN:
14621 : 18 : error_at (c_parser_peek_token (parser)->location,
14622 : : "%<#pragma omp scan%> may only be used in "
14623 : : "a loop construct with %<inscan%> %<reduction%> clause");
14624 : 18 : c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
14625 : 18 : return false;
14626 : :
14627 : 5 : case PRAGMA_OMP_SECTION:
14628 : 5 : error_at (c_parser_peek_token (parser)->location,
14629 : : "%<#pragma omp section%> may only be used in "
14630 : : "%<#pragma omp sections%> construct");
14631 : 5 : c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
14632 : 5 : return false;
14633 : :
14634 : 968 : case PRAGMA_OMP_DECLARE:
14635 : 968 : return c_parser_omp_declare (parser, context);
14636 : :
14637 : 67 : case PRAGMA_OMP_REQUIRES:
14638 : 67 : if (context != pragma_external)
14639 : : {
14640 : 8 : error_at (c_parser_peek_token (parser)->location,
14641 : : "%<#pragma %s%> may only be used at file scope",
14642 : : "omp requires");
14643 : 8 : c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
14644 : 8 : return false;
14645 : : }
14646 : 59 : c_parser_omp_requires (parser);
14647 : 59 : return false;
14648 : :
14649 : 57 : case PRAGMA_OMP_ALLOCATE:
14650 : 57 : c_parser_omp_allocate (parser);
14651 : 57 : return false;
14652 : :
14653 : 38 : case PRAGMA_OMP_ASSUMES:
14654 : 38 : if (context != pragma_external)
14655 : : {
14656 : 1 : error_at (c_parser_peek_token (parser)->location,
14657 : : "%<#pragma %s%> may only be used at file scope",
14658 : : "omp assumes");
14659 : 1 : c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
14660 : 1 : return false;
14661 : : }
14662 : 37 : c_parser_omp_assumes (parser);
14663 : 37 : return false;
14664 : :
14665 : 23 : case PRAGMA_OMP_NOTHING:
14666 : 23 : c_parser_omp_nothing (parser);
14667 : 23 : return false;
14668 : :
14669 : 90 : case PRAGMA_OMP_ERROR:
14670 : 90 : return c_parser_omp_error (parser, context);
14671 : :
14672 : 512 : case PRAGMA_OMP_ORDERED:
14673 : 512 : return c_parser_omp_ordered (parser, context, if_p);
14674 : :
14675 : 2696 : case PRAGMA_NOVECTOR:
14676 : 2696 : case PRAGMA_UNROLL:
14677 : 2696 : case PRAGMA_IVDEP:
14678 : 2696 : {
14679 : 2696 : bool novector = false;
14680 : 2696 : unsigned short unroll = 0;
14681 : 2696 : bool ivdep = false;
14682 : :
14683 : 2696 : switch (id)
14684 : : {
14685 : 2351 : case PRAGMA_NOVECTOR:
14686 : 2351 : novector = c_parse_pragma_novector (parser);
14687 : 2351 : break;
14688 : 220 : case PRAGMA_UNROLL:
14689 : 220 : unroll = c_parser_pragma_unroll (parser);
14690 : 220 : break;
14691 : 125 : case PRAGMA_IVDEP:
14692 : 125 : ivdep = c_parse_pragma_ivdep (parser);
14693 : 125 : break;
14694 : : default:
14695 : : gcc_unreachable ();
14696 : : }
14697 : :
14698 : 2696 : c_token *tok = c_parser_peek_token (parser);
14699 : 2696 : bool has_more = tok->type == CPP_PRAGMA;
14700 : 2712 : while (has_more)
14701 : : {
14702 : 16 : switch (tok->pragma_kind)
14703 : : {
14704 : 3 : case PRAGMA_IVDEP:
14705 : 3 : ivdep = c_parse_pragma_ivdep (parser);
14706 : 3 : break;
14707 : 9 : case PRAGMA_UNROLL:
14708 : 9 : unroll = c_parser_pragma_unroll (parser);
14709 : 9 : break;
14710 : 4 : case PRAGMA_NOVECTOR:
14711 : 4 : novector = c_parse_pragma_novector (parser);
14712 : 4 : break;
14713 : : default:
14714 : : has_more = false;
14715 : : break;
14716 : : }
14717 : 16 : tok = c_parser_peek_token (parser);
14718 : 16 : has_more = has_more && tok->type == CPP_PRAGMA;
14719 : : }
14720 : 2696 : if (!c_parser_next_token_is_keyword (parser, RID_FOR)
14721 : 68 : && !c_parser_next_token_is_keyword (parser, RID_WHILE)
14722 : 2755 : && !c_parser_next_token_is_keyword (parser, RID_DO))
14723 : : {
14724 : 0 : c_parser_error (parser, "for, while or do statement expected");
14725 : 0 : return false;
14726 : : }
14727 : 2696 : if (c_parser_next_token_is_keyword (parser, RID_FOR))
14728 : 2628 : c_parser_for_statement (parser, ivdep, unroll, novector, if_p);
14729 : 68 : else if (c_parser_next_token_is_keyword (parser, RID_WHILE))
14730 : 9 : c_parser_while_statement (parser, ivdep, unroll, novector, if_p);
14731 : : else
14732 : 59 : c_parser_do_statement (parser, ivdep, unroll, novector);
14733 : : }
14734 : : return true;
14735 : :
14736 : 1 : case PRAGMA_GCC_PCH_PREPROCESS:
14737 : 1 : c_parser_error (parser, "%<#pragma GCC pch_preprocess%> must be first");
14738 : 1 : c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
14739 : 1 : return false;
14740 : :
14741 : 83 : case PRAGMA_OACC_WAIT:
14742 : 83 : if (context != pragma_compound)
14743 : : {
14744 : 3 : construct = "acc wait";
14745 : 3 : goto in_compound;
14746 : : }
14747 : : /* FALL THROUGH. */
14748 : :
14749 : 1777198 : default:
14750 : 1777198 : if (id < PRAGMA_FIRST_EXTERNAL)
14751 : : {
14752 : 16033 : if (context != pragma_stmt && context != pragma_compound)
14753 : : {
14754 : 2 : bad_stmt:
14755 : 5 : c_parser_error (parser, "expected declaration specifiers");
14756 : 5 : c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
14757 : 5 : return false;
14758 : : }
14759 : 16031 : c_parser_omp_construct (parser, if_p);
14760 : 16031 : return true;
14761 : : }
14762 : 1761165 : break;
14763 : : }
14764 : :
14765 : 1761165 : c_parser_consume_pragma (parser);
14766 : 1761165 : c_invoke_pragma_handler (id);
14767 : :
14768 : : /* Skip to EOL, but suppress any error message. Those will have been
14769 : : generated by the handler routine through calling error, as opposed
14770 : : to calling c_parser_error. */
14771 : 1761165 : parser->error = true;
14772 : 1761165 : c_parser_skip_to_pragma_eol (parser);
14773 : :
14774 : 1761165 : return false;
14775 : : }
14776 : :
14777 : : /* The interface the pragma parsers have to the lexer. */
14778 : :
14779 : : enum cpp_ttype
14780 : 3342946 : pragma_lex (tree *value, location_t *loc)
14781 : : {
14782 : 3342946 : c_token *tok = c_parser_peek_token (the_parser);
14783 : 3342946 : enum cpp_ttype ret = tok->type;
14784 : :
14785 : 3342946 : *value = tok->value;
14786 : 3342946 : if (loc)
14787 : 1377662 : *loc = tok->location;
14788 : :
14789 : 3342946 : if (ret == CPP_PRAGMA_EOL || ret == CPP_EOF)
14790 : : ret = CPP_EOF;
14791 : 1872192 : else if (ret == CPP_STRING)
14792 : 589578 : *value = c_parser_string_literal (the_parser, false, false).value;
14793 : : else
14794 : : {
14795 : 1282614 : if (ret == CPP_KEYWORD)
14796 : 344 : ret = CPP_NAME;
14797 : 1282614 : c_parser_consume_token (the_parser);
14798 : : }
14799 : :
14800 : 3342946 : return ret;
14801 : : }
14802 : :
14803 : : void
14804 : 8542 : pragma_lex_discard_to_eol ()
14805 : : {
14806 : 8542 : cpp_ttype type;
14807 : 8542 : do
14808 : : {
14809 : 8542 : type = c_parser_peek_token (the_parser)->type;
14810 : 8542 : gcc_assert (type != CPP_EOF);
14811 : 8542 : c_parser_consume_token (the_parser);
14812 : 8542 : } while (type != CPP_PRAGMA_EOL);
14813 : 8542 : }
14814 : :
14815 : : static void
14816 : 12 : c_parser_pragma_pch_preprocess (c_parser *parser)
14817 : : {
14818 : 12 : tree name = NULL;
14819 : :
14820 : 12 : parser->lex_joined_string = true;
14821 : 12 : c_parser_consume_pragma (parser);
14822 : 12 : if (c_parser_next_token_is (parser, CPP_STRING))
14823 : : {
14824 : 12 : name = c_parser_peek_token (parser)->value;
14825 : 12 : c_parser_consume_token (parser);
14826 : : }
14827 : : else
14828 : 0 : c_parser_error (parser, "expected string literal");
14829 : 12 : c_parser_skip_to_pragma_eol (parser);
14830 : 12 : parser->lex_joined_string = false;
14831 : :
14832 : 12 : if (name)
14833 : 12 : c_common_pch_pragma (parse_in, TREE_STRING_POINTER (name));
14834 : 12 : }
14835 : :
14836 : : /* OpenACC and OpenMP parsing routines. */
14837 : :
14838 : : /* Returns name of the next clause.
14839 : : If the clause is not recognized PRAGMA_OMP_CLAUSE_NONE is returned and
14840 : : the token is not consumed. Otherwise appropriate pragma_omp_clause is
14841 : : returned and the token is consumed. */
14842 : :
14843 : : static pragma_omp_clause
14844 : 32262 : c_parser_omp_clause_name (c_parser *parser)
14845 : : {
14846 : 32262 : pragma_omp_clause result = PRAGMA_OMP_CLAUSE_NONE;
14847 : :
14848 : 32262 : if (c_parser_next_token_is_keyword (parser, RID_AUTO))
14849 : : result = PRAGMA_OACC_CLAUSE_AUTO;
14850 : 32155 : else if (c_parser_next_token_is_keyword (parser, RID_IF))
14851 : : result = PRAGMA_OMP_CLAUSE_IF;
14852 : 31283 : else if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
14853 : : result = PRAGMA_OMP_CLAUSE_DEFAULT;
14854 : 30591 : else if (c_parser_next_token_is_keyword (parser, RID_FOR))
14855 : : result = PRAGMA_OMP_CLAUSE_FOR;
14856 : 30507 : else if (c_parser_next_token_is (parser, CPP_NAME))
14857 : : {
14858 : 30448 : const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14859 : :
14860 : 30448 : switch (p[0])
14861 : : {
14862 : 1101 : case 'a':
14863 : 1101 : if (!strcmp ("affinity", p))
14864 : : result = PRAGMA_OMP_CLAUSE_AFFINITY;
14865 : 955 : else if (!strcmp ("aligned", p))
14866 : : result = PRAGMA_OMP_CLAUSE_ALIGNED;
14867 : 727 : else if (!strcmp ("allocate", p))
14868 : : result = PRAGMA_OMP_CLAUSE_ALLOCATE;
14869 : 265 : else if (!strcmp ("async", p))
14870 : : result = PRAGMA_OACC_CLAUSE_ASYNC;
14871 : 29 : else if (!strcmp ("attach", p))
14872 : 32262 : result = PRAGMA_OACC_CLAUSE_ATTACH;
14873 : : break;
14874 : 116 : case 'b':
14875 : 116 : if (!strcmp ("bind", p))
14876 : 32262 : result = PRAGMA_OMP_CLAUSE_BIND;
14877 : : break;
14878 : 4408 : case 'c':
14879 : 4408 : if (!strcmp ("collapse", p))
14880 : : result = PRAGMA_OMP_CLAUSE_COLLAPSE;
14881 : 1618 : else if (!strcmp ("copy", p))
14882 : : result = PRAGMA_OACC_CLAUSE_COPY;
14883 : 844 : else if (!strcmp ("copyin", p))
14884 : : result = PRAGMA_OMP_CLAUSE_COPYIN;
14885 : 413 : else if (!strcmp ("copyout", p))
14886 : : result = PRAGMA_OACC_CLAUSE_COPYOUT;
14887 : 94 : else if (!strcmp ("copyprivate", p))
14888 : : result = PRAGMA_OMP_CLAUSE_COPYPRIVATE;
14889 : 73 : else if (!strcmp ("create", p))
14890 : 32262 : result = PRAGMA_OACC_CLAUSE_CREATE;
14891 : : break;
14892 : 3307 : case 'd':
14893 : 3307 : if (!strcmp ("defaultmap", p))
14894 : : result = PRAGMA_OMP_CLAUSE_DEFAULTMAP;
14895 : 3069 : else if (!strcmp ("delete", p))
14896 : : result = PRAGMA_OACC_CLAUSE_DELETE;
14897 : 3002 : else if (!strcmp ("depend", p))
14898 : : result = PRAGMA_OMP_CLAUSE_DEPEND;
14899 : 2191 : else if (!strcmp ("detach", p))
14900 : : result = PRAGMA_OACC_CLAUSE_DETACH;
14901 : 2137 : else if (!strcmp ("device", p))
14902 : : result = PRAGMA_OMP_CLAUSE_DEVICE;
14903 : 1827 : else if (!strcmp ("deviceptr", p))
14904 : : result = PRAGMA_OACC_CLAUSE_DEVICEPTR;
14905 : 1773 : else if (!strcmp ("device_resident", p))
14906 : : result = PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT;
14907 : 1758 : else if (!strcmp ("device_type", p))
14908 : : result = PRAGMA_OMP_CLAUSE_DEVICE_TYPE;
14909 : 1716 : else if (!strcmp ("dist_schedule", p))
14910 : : result = PRAGMA_OMP_CLAUSE_DIST_SCHEDULE;
14911 : 134 : else if (!strcmp ("doacross", p))
14912 : 32262 : result = PRAGMA_OMP_CLAUSE_DOACROSS;
14913 : : break;
14914 : 39 : case 'e':
14915 : 39 : if (!strcmp ("enter", p))
14916 : 32262 : result = PRAGMA_OMP_CLAUSE_ENTER;
14917 : : break;
14918 : 3384 : case 'f':
14919 : 3384 : if (!strcmp ("filter", p))
14920 : : result = PRAGMA_OMP_CLAUSE_FILTER;
14921 : 3322 : else if (!strcmp ("final", p))
14922 : : result = PRAGMA_OMP_CLAUSE_FINAL;
14923 : 3224 : else if (!strcmp ("finalize", p))
14924 : : result = PRAGMA_OACC_CLAUSE_FINALIZE;
14925 : 3212 : else if (!strcmp ("firstprivate", p))
14926 : : result = PRAGMA_OMP_CLAUSE_FIRSTPRIVATE;
14927 : 2447 : else if (!strcmp ("from", p))
14928 : 32262 : result = PRAGMA_OMP_CLAUSE_FROM;
14929 : : break;
14930 : 623 : case 'g':
14931 : 623 : if (!strcmp ("gang", p))
14932 : : result = PRAGMA_OACC_CLAUSE_GANG;
14933 : 62 : else if (!strcmp ("grainsize", p))
14934 : 32262 : result = PRAGMA_OMP_CLAUSE_GRAINSIZE;
14935 : : break;
14936 : 155 : case 'h':
14937 : 155 : if (!strcmp ("has_device_addr", p))
14938 : : result = PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR;
14939 : 69 : else if (!strcmp ("hint", p))
14940 : : result = PRAGMA_OMP_CLAUSE_HINT;
14941 : 40 : else if (!strcmp ("host", p))
14942 : 32262 : result = PRAGMA_OACC_CLAUSE_HOST;
14943 : : break;
14944 : 552 : case 'i':
14945 : 552 : if (!strcmp ("if_present", p))
14946 : : result = PRAGMA_OACC_CLAUSE_IF_PRESENT;
14947 : 534 : else if (!strcmp ("in_reduction", p))
14948 : : result = PRAGMA_OMP_CLAUSE_IN_REDUCTION;
14949 : 214 : else if (!strcmp ("inbranch", p))
14950 : : result = PRAGMA_OMP_CLAUSE_INBRANCH;
14951 : 154 : else if (!strcmp ("independent", p))
14952 : : result = PRAGMA_OACC_CLAUSE_INDEPENDENT;
14953 : 111 : else if (!strcmp ("indirect", p))
14954 : : result = PRAGMA_OMP_CLAUSE_INDIRECT;
14955 : 85 : else if (!strcmp ("is_device_ptr", p))
14956 : 32262 : result = PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR;
14957 : : break;
14958 : 1244 : case 'l':
14959 : 1244 : if (!strcmp ("lastprivate", p))
14960 : : result = PRAGMA_OMP_CLAUSE_LASTPRIVATE;
14961 : 516 : else if (!strcmp ("linear", p))
14962 : : result = PRAGMA_OMP_CLAUSE_LINEAR;
14963 : 42 : else if (!strcmp ("link", p))
14964 : 32262 : result = PRAGMA_OMP_CLAUSE_LINK;
14965 : : break;
14966 : 1551 : case 'm':
14967 : 1551 : if (!strcmp ("map", p))
14968 : : result = PRAGMA_OMP_CLAUSE_MAP;
14969 : 78 : else if (!strcmp ("mergeable", p))
14970 : 32262 : result = PRAGMA_OMP_CLAUSE_MERGEABLE;
14971 : : break;
14972 : 1846 : case 'n':
14973 : 1846 : if (!strcmp ("no_create", p))
14974 : : result = PRAGMA_OACC_CLAUSE_NO_CREATE;
14975 : 1836 : else if (!strcmp ("nogroup", p))
14976 : : result = PRAGMA_OMP_CLAUSE_NOGROUP;
14977 : 1818 : else if (!strcmp ("nohost", p))
14978 : : result = PRAGMA_OACC_CLAUSE_NOHOST;
14979 : 1793 : else if (!strcmp ("nontemporal", p))
14980 : : result = PRAGMA_OMP_CLAUSE_NONTEMPORAL;
14981 : 1672 : else if (!strcmp ("notinbranch", p))
14982 : : result = PRAGMA_OMP_CLAUSE_NOTINBRANCH;
14983 : 1536 : else if (!strcmp ("nowait", p))
14984 : : result = PRAGMA_OMP_CLAUSE_NOWAIT;
14985 : 1172 : else if (!strcmp ("num_gangs", p))
14986 : : result = PRAGMA_OACC_CLAUSE_NUM_GANGS;
14987 : 870 : else if (!strcmp ("num_tasks", p))
14988 : : result = PRAGMA_OMP_CLAUSE_NUM_TASKS;
14989 : 821 : else if (!strcmp ("num_teams", p))
14990 : : result = PRAGMA_OMP_CLAUSE_NUM_TEAMS;
14991 : 631 : else if (!strcmp ("num_threads", p))
14992 : : result = PRAGMA_OMP_CLAUSE_NUM_THREADS;
14993 : 207 : else if (!strcmp ("num_workers", p))
14994 : 32262 : result = PRAGMA_OACC_CLAUSE_NUM_WORKERS;
14995 : : break;
14996 : 667 : case 'o':
14997 : 667 : if (!strcmp ("ordered", p))
14998 : : result = PRAGMA_OMP_CLAUSE_ORDERED;
14999 : 376 : else if (!strcmp ("order", p))
15000 : 32262 : result = PRAGMA_OMP_CLAUSE_ORDER;
15001 : : break;
15002 : 1368 : case 'p':
15003 : 1368 : if (!strcmp ("parallel", p))
15004 : : result = PRAGMA_OMP_CLAUSE_PARALLEL;
15005 : 1261 : else if (!strcmp ("present", p))
15006 : : result = PRAGMA_OACC_CLAUSE_PRESENT;
15007 : : /* As of OpenACC 2.5, these are now aliases of the non-present_or
15008 : : clauses. */
15009 : 1135 : else if (!strcmp ("present_or_copy", p)
15010 : 1122 : || !strcmp ("pcopy", p))
15011 : : result = PRAGMA_OACC_CLAUSE_COPY;
15012 : 1114 : else if (!strcmp ("present_or_copyin", p)
15013 : 1098 : || !strcmp ("pcopyin", p))
15014 : : result = PRAGMA_OACC_CLAUSE_COPYIN;
15015 : 1090 : else if (!strcmp ("present_or_copyout", p)
15016 : 1037 : || !strcmp ("pcopyout", p))
15017 : : result = PRAGMA_OACC_CLAUSE_COPYOUT;
15018 : 1025 : else if (!strcmp ("present_or_create", p)
15019 : 1011 : || !strcmp ("pcreate", p))
15020 : : result = PRAGMA_OACC_CLAUSE_CREATE;
15021 : 1007 : else if (!strcmp ("priority", p))
15022 : : result = PRAGMA_OMP_CLAUSE_PRIORITY;
15023 : 910 : else if (!strcmp ("private", p))
15024 : : result = PRAGMA_OMP_CLAUSE_PRIVATE;
15025 : 194 : else if (!strcmp ("proc_bind", p))
15026 : 32262 : result = PRAGMA_OMP_CLAUSE_PROC_BIND;
15027 : : break;
15028 : 2461 : case 'r':
15029 : 2461 : if (!strcmp ("reduction", p))
15030 : 32262 : result = PRAGMA_OMP_CLAUSE_REDUCTION;
15031 : : break;
15032 : 5130 : case 's':
15033 : 5130 : if (!strcmp ("safelen", p))
15034 : : result = PRAGMA_OMP_CLAUSE_SAFELEN;
15035 : 4903 : else if (!strcmp ("schedule", p))
15036 : : result = PRAGMA_OMP_CLAUSE_SCHEDULE;
15037 : 1452 : else if (!strcmp ("sections", p))
15038 : : result = PRAGMA_OMP_CLAUSE_SECTIONS;
15039 : 1374 : else if (!strcmp ("self", p))
15040 : : result = PRAGMA_OACC_CLAUSE_SELF;
15041 : 1308 : else if (!strcmp ("seq", p))
15042 : : result = PRAGMA_OACC_CLAUSE_SEQ;
15043 : 1059 : else if (!strcmp ("shared", p))
15044 : : result = PRAGMA_OMP_CLAUSE_SHARED;
15045 : 370 : else if (!strcmp ("simd", p))
15046 : : result = PRAGMA_OMP_CLAUSE_SIMD;
15047 : 315 : else if (!strcmp ("simdlen", p))
15048 : 32262 : result = PRAGMA_OMP_CLAUSE_SIMDLEN;
15049 : : break;
15050 : 981 : case 't':
15051 : 981 : if (!strcmp ("task_reduction", p))
15052 : : result = PRAGMA_OMP_CLAUSE_TASK_REDUCTION;
15053 : 895 : else if (!strcmp ("taskgroup", p))
15054 : : result = PRAGMA_OMP_CLAUSE_TASKGROUP;
15055 : 785 : else if (!strcmp ("thread_limit", p))
15056 : : result = PRAGMA_OMP_CLAUSE_THREAD_LIMIT;
15057 : 631 : else if (!strcmp ("threads", p))
15058 : : result = PRAGMA_OMP_CLAUSE_THREADS;
15059 : 589 : else if (!strcmp ("tile", p))
15060 : : result = PRAGMA_OACC_CLAUSE_TILE;
15061 : 467 : else if (!strcmp ("to", p))
15062 : 32262 : result = PRAGMA_OMP_CLAUSE_TO;
15063 : : break;
15064 : 276 : case 'u':
15065 : 276 : if (!strcmp ("uniform", p))
15066 : : result = PRAGMA_OMP_CLAUSE_UNIFORM;
15067 : 161 : else if (!strcmp ("untied", p))
15068 : : result = PRAGMA_OMP_CLAUSE_UNTIED;
15069 : 65 : else if (!strcmp ("use_device", p))
15070 : : result = PRAGMA_OACC_CLAUSE_USE_DEVICE;
15071 : 44 : else if (!strcmp ("use_device_addr", p))
15072 : : result = PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR;
15073 : 9 : else if (!strcmp ("use_device_ptr", p))
15074 : 32262 : result = PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR;
15075 : : break;
15076 : 718 : case 'v':
15077 : 718 : if (!strcmp ("vector", p))
15078 : : result = PRAGMA_OACC_CLAUSE_VECTOR;
15079 : 223 : else if (!strcmp ("vector_length", p))
15080 : 32262 : result = PRAGMA_OACC_CLAUSE_VECTOR_LENGTH;
15081 : : break;
15082 : 520 : case 'w':
15083 : 520 : if (!strcmp ("wait", p))
15084 : : result = PRAGMA_OACC_CLAUSE_WAIT;
15085 : 431 : else if (!strcmp ("worker", p))
15086 : 32262 : result = PRAGMA_OACC_CLAUSE_WORKER;
15087 : : break;
15088 : : }
15089 : : }
15090 : :
15091 : 32262 : if (result != PRAGMA_OMP_CLAUSE_NONE)
15092 : 32195 : c_parser_consume_token (parser);
15093 : :
15094 : 32262 : return result;
15095 : : }
15096 : :
15097 : : /* Validate that a clause of the given type does not already exist. */
15098 : :
15099 : : static void
15100 : 16522 : check_no_duplicate_clause (tree clauses, enum omp_clause_code code,
15101 : : const char *name)
15102 : : {
15103 : 16522 : if (tree c = omp_find_clause (clauses, code))
15104 : 338 : error_at (OMP_CLAUSE_LOCATION (c), "too many %qs clauses", name);
15105 : 16522 : }
15106 : :
15107 : : /* OpenACC 2.0
15108 : : Parse wait clause or wait directive parameters. */
15109 : :
15110 : : static tree
15111 : 117 : c_parser_oacc_wait_list (c_parser *parser, location_t clause_loc, tree list)
15112 : : {
15113 : 117 : vec<tree, va_gc> *args;
15114 : 117 : tree t, args_tree;
15115 : :
15116 : 117 : matching_parens parens;
15117 : 117 : if (!parens.require_open (parser))
15118 : : return list;
15119 : :
15120 : 117 : args = c_parser_expr_list (parser, false, true, NULL, NULL, NULL, NULL);
15121 : 117 : args_tree = build_tree_list_vec (args);
15122 : :
15123 : 277 : for (t = args_tree; t; t = TREE_CHAIN (t))
15124 : : {
15125 : 160 : tree targ = TREE_VALUE (t);
15126 : :
15127 : 160 : if (targ != error_mark_node)
15128 : : {
15129 : 146 : if (!INTEGRAL_TYPE_P (TREE_TYPE (targ)))
15130 : : {
15131 : 6 : c_parser_error (parser, "expression must be integral");
15132 : 6 : targ = error_mark_node;
15133 : : }
15134 : : else
15135 : : {
15136 : 140 : tree c = build_omp_clause (clause_loc, OMP_CLAUSE_WAIT);
15137 : :
15138 : 140 : OMP_CLAUSE_DECL (c) = targ;
15139 : 140 : OMP_CLAUSE_CHAIN (c) = list;
15140 : 140 : list = c;
15141 : : }
15142 : : }
15143 : : }
15144 : :
15145 : 117 : release_tree_vector (args);
15146 : 117 : parens.require_close (parser);
15147 : 117 : return list;
15148 : : }
15149 : :
15150 : : /* OpenACC 2.0, OpenMP 2.5:
15151 : : variable-list:
15152 : : identifier
15153 : : variable-list , identifier
15154 : :
15155 : : If KIND is nonzero, create the appropriate node and install the
15156 : : decl in OMP_CLAUSE_DECL and add the node to the head of the list.
15157 : : If KIND is nonzero, CLAUSE_LOC is the location of the clause.
15158 : :
15159 : : If KIND is zero, create a TREE_LIST with the decl in TREE_PURPOSE;
15160 : : return the list created.
15161 : :
15162 : : The optional ALLOW_DEREF argument is true if list items can use the deref
15163 : : (->) operator. */
15164 : :
15165 : : struct omp_dim
15166 : : {
15167 : : tree low_bound, length;
15168 : : location_t loc;
15169 : : bool no_colon;
15170 : 3129 : omp_dim (tree lb, tree len, location_t lo, bool nc)
15171 : 3129 : : low_bound (lb), length (len), loc (lo), no_colon (nc) {}
15172 : : };
15173 : :
15174 : : static tree
15175 : 15315 : c_parser_omp_variable_list (c_parser *parser,
15176 : : location_t clause_loc,
15177 : : enum omp_clause_code kind, tree list,
15178 : : bool map_lvalue = false)
15179 : : {
15180 : 15315 : auto_vec<omp_dim> dims;
15181 : 15315 : bool array_section_p;
15182 : 15315 : auto_vec<c_token> tokens;
15183 : 15315 : unsigned int tokens_avail = 0;
15184 : 15315 : c_token *saved_tokens = NULL;
15185 : 15315 : bool first = true;
15186 : :
15187 : 18278 : while (1)
15188 : : {
15189 : 18278 : tree t = NULL_TREE;
15190 : :
15191 : 18278 : if (kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
15192 : : {
15193 : 855 : if (c_parser_next_token_is_not (parser, CPP_NAME)
15194 : 855 : || c_parser_peek_token (parser)->id_kind != C_ID_ID)
15195 : : {
15196 : 29 : struct c_expr expr;
15197 : 29 : if (kind == OMP_CLAUSE_DEPEND
15198 : 27 : && c_parser_next_token_is_keyword (parser,
15199 : : RID_OMP_ALL_MEMORY)
15200 : 45 : && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
15201 : 13 : || (c_parser_peek_2nd_token (parser)->type
15202 : : == CPP_CLOSE_PAREN)))
15203 : : {
15204 : 15 : expr.value = ridpointers[RID_OMP_ALL_MEMORY];
15205 : 15 : c_parser_consume_token (parser);
15206 : : }
15207 : : else
15208 : 14 : expr = c_parser_expr_no_commas (parser, NULL);
15209 : 29 : if (expr.value != error_mark_node)
15210 : : {
15211 : 27 : tree u = build_omp_clause (clause_loc, kind);
15212 : 27 : OMP_CLAUSE_DECL (u) = expr.value;
15213 : 27 : OMP_CLAUSE_CHAIN (u) = list;
15214 : 27 : list = u;
15215 : : }
15216 : :
15217 : 29 : if (c_parser_next_token_is_not (parser, CPP_COMMA))
15218 : : break;
15219 : :
15220 : 4 : c_parser_consume_token (parser);
15221 : 4 : first = false;
15222 : 4 : continue;
15223 : 4 : }
15224 : :
15225 : 826 : tokens.truncate (0);
15226 : 826 : unsigned int nesting_depth = 0;
15227 : 11072 : while (1)
15228 : : {
15229 : 5949 : c_token *token = c_parser_peek_token (parser);
15230 : 5949 : switch (token->type)
15231 : : {
15232 : : case CPP_EOF:
15233 : : case CPP_PRAGMA_EOL:
15234 : : break;
15235 : 923 : case CPP_OPEN_BRACE:
15236 : 923 : case CPP_OPEN_PAREN:
15237 : 923 : case CPP_OPEN_SQUARE:
15238 : 923 : ++nesting_depth;
15239 : 923 : goto add;
15240 : 1683 : case CPP_CLOSE_BRACE:
15241 : 1683 : case CPP_CLOSE_PAREN:
15242 : 1683 : case CPP_CLOSE_SQUARE:
15243 : 1683 : if (nesting_depth-- == 0)
15244 : : break;
15245 : 923 : goto add;
15246 : 138 : case CPP_COMMA:
15247 : 138 : if (nesting_depth == 0)
15248 : : break;
15249 : 72 : goto add;
15250 : 5123 : default:
15251 : 5123 : add:
15252 : 5123 : tokens.safe_push (*token);
15253 : 5123 : c_parser_consume_token (parser);
15254 : 5123 : continue;
15255 : : }
15256 : 826 : break;
15257 : 5123 : }
15258 : :
15259 : : /* Make sure nothing tries to read past the end of the tokens. */
15260 : 826 : c_token eof_token;
15261 : 826 : memset (&eof_token, 0, sizeof (eof_token));
15262 : 826 : eof_token.type = CPP_EOF;
15263 : 826 : tokens.safe_push (eof_token);
15264 : 826 : tokens.safe_push (eof_token);
15265 : :
15266 : 826 : saved_tokens = parser->tokens;
15267 : 826 : tokens_avail = parser->tokens_avail;
15268 : 826 : parser->tokens = tokens.address ();
15269 : 1652 : parser->tokens_avail = tokens.length ();
15270 : : }
15271 : 17423 : else if (map_lvalue
15272 : 1787 : && (kind == OMP_CLAUSE_MAP
15273 : : || kind == OMP_CLAUSE_TO
15274 : 1787 : || kind == OMP_CLAUSE_FROM))
15275 : : {
15276 : 1787 : location_t loc = c_parser_peek_token (parser)->location;
15277 : 1787 : bool save_c_omp_array_section_p = c_omp_array_section_p;
15278 : 1787 : c_omp_array_section_p = true;
15279 : 1787 : c_expr expr = c_parser_expr_no_commas (parser, NULL);
15280 : 1787 : if (expr.value != error_mark_node)
15281 : 1781 : mark_exp_read (expr.value);
15282 : 1787 : c_omp_array_section_p = save_c_omp_array_section_p;
15283 : 1787 : tree decl = expr.value;
15284 : :
15285 : : /* This code rewrites a parsed expression containing various tree
15286 : : codes used to represent array accesses into a more uniform nest of
15287 : : OMP_ARRAY_SECTION nodes before it is processed by
15288 : : c-typeck.cc:handle_omp_array_sections_1. It might be more
15289 : : efficient to move this logic to that function instead, analysing
15290 : : the parsed expression directly rather than this preprocessed
15291 : : form. (See also equivalent code in cp/parser.cc,
15292 : : cp/semantics.cc). */
15293 : 1787 : dims.truncate (0);
15294 : 1787 : if (TREE_CODE (decl) == OMP_ARRAY_SECTION)
15295 : : {
15296 : 804 : while (TREE_CODE (decl) == OMP_ARRAY_SECTION)
15297 : : {
15298 : 432 : tree low_bound = TREE_OPERAND (decl, 1);
15299 : 432 : tree length = TREE_OPERAND (decl, 2);
15300 : 432 : dims.safe_push (omp_dim (low_bound, length, loc, false));
15301 : 432 : decl = TREE_OPERAND (decl, 0);
15302 : : }
15303 : :
15304 : 388 : while (TREE_CODE (decl) == ARRAY_REF
15305 : : || TREE_CODE (decl) == INDIRECT_REF
15306 : 388 : || TREE_CODE (decl) == COMPOUND_EXPR)
15307 : : {
15308 : 16 : if (TREE_CODE (decl) == COMPOUND_EXPR)
15309 : : {
15310 : 2 : decl = TREE_OPERAND (decl, 1);
15311 : 2 : STRIP_NOPS (decl);
15312 : : }
15313 : 14 : else if (TREE_CODE (decl) == INDIRECT_REF)
15314 : : {
15315 : 7 : dims.safe_push (omp_dim (integer_zero_node,
15316 : : integer_one_node, loc, true));
15317 : 7 : decl = TREE_OPERAND (decl, 0);
15318 : : }
15319 : : else /* ARRAY_REF. */
15320 : : {
15321 : 7 : tree index = TREE_OPERAND (decl, 1);
15322 : 7 : dims.safe_push (omp_dim (index, integer_one_node, loc,
15323 : : true));
15324 : 7 : decl = TREE_OPERAND (decl, 0);
15325 : : }
15326 : : }
15327 : :
15328 : 1190 : for (int i = dims.length () - 1; i >= 0; i--)
15329 : 446 : decl = build_omp_array_section (loc, decl, dims[i].low_bound,
15330 : 446 : dims[i].length);
15331 : : }
15332 : 1415 : else if (TREE_CODE (decl) == INDIRECT_REF)
15333 : : {
15334 : : /* Turn indirection of a pointer "*foo" into "foo[0:1]". */
15335 : 37 : decl = TREE_OPERAND (decl, 0);
15336 : 37 : STRIP_NOPS (decl);
15337 : :
15338 : 37 : decl = build_omp_array_section (loc, decl, integer_zero_node,
15339 : : integer_one_node);
15340 : : }
15341 : 1378 : else if (TREE_CODE (decl) == ARRAY_REF)
15342 : : {
15343 : 12 : tree idx = TREE_OPERAND (decl, 1);
15344 : :
15345 : 12 : decl = TREE_OPERAND (decl, 0);
15346 : 12 : STRIP_NOPS (decl);
15347 : :
15348 : 12 : decl = build_omp_array_section (loc, decl, idx, integer_one_node);
15349 : : }
15350 : 1366 : else if (TREE_CODE (decl) == NON_LVALUE_EXPR
15351 : 1366 : || CONVERT_EXPR_P (decl))
15352 : 0 : decl = TREE_OPERAND (decl, 0);
15353 : :
15354 : 1787 : tree u = build_omp_clause (clause_loc, kind);
15355 : 1787 : OMP_CLAUSE_DECL (u) = decl;
15356 : 1787 : OMP_CLAUSE_CHAIN (u) = list;
15357 : 1787 : list = u;
15358 : :
15359 : 1787 : goto next_item;
15360 : : }
15361 : :
15362 : 16462 : if (c_parser_next_token_is (parser, CPP_NAME)
15363 : 16462 : && c_parser_peek_token (parser)->id_kind == C_ID_ID)
15364 : : {
15365 : 16433 : t = lookup_name (c_parser_peek_token (parser)->value);
15366 : :
15367 : 16433 : if (t == NULL_TREE)
15368 : : {
15369 : 10 : undeclared_variable (c_parser_peek_token (parser)->location,
15370 : 10 : c_parser_peek_token (parser)->value);
15371 : 10 : t = error_mark_node;
15372 : : }
15373 : :
15374 : 16433 : c_parser_consume_token (parser);
15375 : : }
15376 : 29 : else if (c_parser_next_token_is (parser, CPP_KEYWORD)
15377 : 29 : && (c_parser_peek_token (parser)->keyword == RID_FUNCTION_NAME
15378 : 15 : || (c_parser_peek_token (parser)->keyword
15379 : : == RID_PRETTY_FUNCTION_NAME)
15380 : 9 : || (c_parser_peek_token (parser)->keyword
15381 : : == RID_C99_FUNCTION_NAME)))
15382 : 20 : t = c_parser_predefined_identifier (parser).value;
15383 : : else
15384 : : {
15385 : 9 : if (first)
15386 : 8 : c_parser_error (parser, "expected identifier");
15387 : : break;
15388 : : }
15389 : :
15390 : 16453 : if (t == error_mark_node)
15391 : : ;
15392 : 16441 : else if (kind != 0)
15393 : : {
15394 : 16286 : switch (kind)
15395 : : {
15396 : 139 : case OMP_CLAUSE__CACHE_:
15397 : : /* The OpenACC cache directive explicitly only allows "array
15398 : : elements or subarrays". */
15399 : 139 : if (c_parser_peek_token (parser)->type != CPP_OPEN_SQUARE)
15400 : : {
15401 : 3 : c_parser_error (parser, "expected %<[%>");
15402 : 3 : t = error_mark_node;
15403 : 3 : break;
15404 : : }
15405 : : /* FALLTHROUGH */
15406 : : case OMP_CLAUSE_MAP:
15407 : : case OMP_CLAUSE_FROM:
15408 : : case OMP_CLAUSE_TO:
15409 : 136 : start_component_ref:
15410 : 5907 : while (c_parser_next_token_is (parser, CPP_DOT)
15411 : 11607 : || c_parser_next_token_is (parser, CPP_DEREF))
15412 : : {
15413 : 314 : location_t op_loc = c_parser_peek_token (parser)->location;
15414 : 314 : location_t arrow_loc = UNKNOWN_LOCATION;
15415 : 314 : if (c_parser_next_token_is (parser, CPP_DEREF))
15416 : : {
15417 : 107 : c_expr t_expr;
15418 : 107 : t_expr.value = t;
15419 : 107 : t_expr.original_code = ERROR_MARK;
15420 : 107 : t_expr.original_type = NULL;
15421 : 107 : set_c_expr_source_range (&t_expr, op_loc, op_loc);
15422 : 107 : t_expr.m_decimal = 0;
15423 : 107 : t_expr = convert_lvalue_to_rvalue (op_loc, t_expr,
15424 : : true, false);
15425 : 107 : t = build_indirect_ref (op_loc, t_expr.value, RO_ARROW);
15426 : 107 : arrow_loc = t_expr.get_location ();
15427 : : }
15428 : 314 : c_parser_consume_token (parser);
15429 : 314 : if (!c_parser_next_token_is (parser, CPP_NAME))
15430 : : {
15431 : 0 : c_parser_error (parser, "expected identifier");
15432 : 0 : t = error_mark_node;
15433 : 0 : break;
15434 : : }
15435 : :
15436 : 314 : c_token *comp_tok = c_parser_peek_token (parser);
15437 : 314 : tree ident = comp_tok->value;
15438 : 314 : location_t comp_loc = comp_tok->location;
15439 : 314 : c_parser_consume_token (parser);
15440 : 314 : t = build_component_ref (op_loc, t, ident, comp_loc,
15441 : : arrow_loc);
15442 : : }
15443 : : /* FALLTHROUGH */
15444 : 9964 : case OMP_CLAUSE_AFFINITY:
15445 : 9964 : case OMP_CLAUSE_DEPEND:
15446 : 9964 : case OMP_CLAUSE_REDUCTION:
15447 : 9964 : case OMP_CLAUSE_IN_REDUCTION:
15448 : 9964 : case OMP_CLAUSE_TASK_REDUCTION:
15449 : 9964 : case OMP_CLAUSE_HAS_DEVICE_ADDR:
15450 : 9964 : array_section_p = false;
15451 : 9964 : dims.truncate (0);
15452 : 22611 : while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
15453 : : {
15454 : 2683 : location_t loc = UNKNOWN_LOCATION;
15455 : 2683 : tree low_bound = NULL_TREE, length = NULL_TREE;
15456 : 2683 : bool no_colon = false;
15457 : :
15458 : 2683 : c_parser_consume_token (parser);
15459 : 2683 : if (!c_parser_next_token_is (parser, CPP_COLON))
15460 : : {
15461 : 2279 : location_t expr_loc
15462 : 2279 : = c_parser_peek_token (parser)->location;
15463 : 2279 : c_expr expr = c_parser_expression (parser);
15464 : 2279 : expr = convert_lvalue_to_rvalue (expr_loc, expr,
15465 : : false, true);
15466 : 2279 : low_bound = expr.value;
15467 : 2279 : loc = expr_loc;
15468 : : }
15469 : 2683 : if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
15470 : : {
15471 : 417 : length = integer_one_node;
15472 : 417 : no_colon = true;
15473 : : }
15474 : : else
15475 : : {
15476 : : /* Look for `:'. */
15477 : 2266 : if (!c_parser_require (parser, CPP_COLON,
15478 : : "expected %<:%>"))
15479 : : {
15480 : 0 : t = error_mark_node;
15481 : 0 : break;
15482 : : }
15483 : 2266 : array_section_p = true;
15484 : 2266 : if (!c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
15485 : : {
15486 : 2081 : location_t expr_loc
15487 : 2081 : = c_parser_peek_token (parser)->location;
15488 : 2081 : c_expr expr = c_parser_expression (parser);
15489 : 2081 : expr = convert_lvalue_to_rvalue (expr_loc, expr,
15490 : : false, true);
15491 : 2081 : length = expr.value;
15492 : : }
15493 : : }
15494 : : /* Look for the closing `]'. */
15495 : 2683 : if (!c_parser_require (parser, CPP_CLOSE_SQUARE,
15496 : : "expected %<]%>"))
15497 : : {
15498 : 0 : t = error_mark_node;
15499 : 0 : break;
15500 : : }
15501 : :
15502 : 2683 : dims.safe_push (omp_dim (low_bound, length, loc, no_colon));
15503 : : }
15504 : :
15505 : 9964 : if (t != error_mark_node)
15506 : : {
15507 : 9964 : if ((kind == OMP_CLAUSE_MAP
15508 : 9964 : || kind == OMP_CLAUSE_FROM
15509 : 4902 : || kind == OMP_CLAUSE_TO)
15510 : 5457 : && !array_section_p
15511 : 14180 : && (c_parser_next_token_is (parser, CPP_DOT)
15512 : 4212 : || c_parser_next_token_is (parser, CPP_DEREF)))
15513 : : {
15514 : 16 : for (unsigned i = 0; i < dims.length (); i++)
15515 : : {
15516 : 4 : gcc_assert (dims[i].length == integer_one_node);
15517 : 4 : t = build_array_ref (dims[i].loc,
15518 : 4 : t, dims[i].low_bound);
15519 : : }
15520 : 4 : goto start_component_ref;
15521 : : }
15522 : : else
15523 : 17719 : for (unsigned i = 0; i < dims.length (); i++)
15524 : 5358 : t = build_omp_array_section (clause_loc, t,
15525 : 2679 : dims[i].low_bound,
15526 : 2679 : dims[i].length);
15527 : : }
15528 : :
15529 : 9960 : if ((kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
15530 : 822 : && t != error_mark_node
15531 : 822 : && parser->tokens_avail != 2)
15532 : : {
15533 : 44 : if (array_section_p)
15534 : : {
15535 : 12 : error_at (c_parser_peek_token (parser)->location,
15536 : : "expected %<)%> or %<,%>");
15537 : 12 : t = error_mark_node;
15538 : : }
15539 : : else
15540 : : {
15541 : 32 : parser->tokens = tokens.address ();
15542 : 32 : parser->tokens_avail = tokens.length ();
15543 : :
15544 : 32 : t = c_parser_expr_no_commas (parser, NULL).value;
15545 : 32 : if (t != error_mark_node && parser->tokens_avail != 2)
15546 : : {
15547 : 0 : error_at (c_parser_peek_token (parser)->location,
15548 : : "expected %<)%> or %<,%>");
15549 : 0 : t = error_mark_node;
15550 : : }
15551 : : }
15552 : : }
15553 : : break;
15554 : : default:
15555 : : break;
15556 : : }
15557 : :
15558 : 16286 : if (t != error_mark_node)
15559 : : {
15560 : 16271 : tree u = build_omp_clause (clause_loc, kind);
15561 : 16271 : OMP_CLAUSE_DECL (u) = t;
15562 : 16271 : OMP_CLAUSE_CHAIN (u) = list;
15563 : 16271 : list = u;
15564 : : }
15565 : : }
15566 : : else
15567 : 155 : list = tree_cons (t, NULL_TREE, list);
15568 : :
15569 : 16453 : if (kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
15570 : : {
15571 : 826 : parser->tokens = saved_tokens;
15572 : 826 : parser->tokens_avail = tokens_avail;
15573 : : }
15574 : :
15575 : 15627 : next_item:
15576 : 18240 : if (c_parser_next_token_is_not (parser, CPP_COMMA))
15577 : : break;
15578 : :
15579 : 2959 : c_parser_consume_token (parser);
15580 : 2959 : first = false;
15581 : : }
15582 : :
15583 : 15315 : return list;
15584 : 15315 : }
15585 : :
15586 : : /* Similarly, but expect leading and trailing parenthesis. This is a very
15587 : : common case for OpenACC and OpenMP clauses. The optional ALLOW_DEREF
15588 : : argument is true if list items can use the deref (->) operator. */
15589 : :
15590 : : static tree
15591 : 3280 : c_parser_omp_var_list_parens (c_parser *parser, enum omp_clause_code kind,
15592 : : tree list, bool map_lvalue = false)
15593 : : {
15594 : : /* The clauses location. */
15595 : 3280 : location_t loc = c_parser_peek_token (parser)->location;
15596 : :
15597 : 3280 : if (parser->in_omp_decl_attribute)
15598 : : {
15599 : 35 : if (kind)
15600 : : {
15601 : 20 : tree u = build_omp_clause (loc, kind);
15602 : 20 : OMP_CLAUSE_DECL (u) = parser->in_omp_decl_attribute;
15603 : 20 : OMP_CLAUSE_CHAIN (u) = list;
15604 : 20 : return u;
15605 : : }
15606 : : else
15607 : 15 : return tree_cons (parser->in_omp_decl_attribute, NULL_TREE, list);
15608 : : }
15609 : :
15610 : 3245 : matching_parens parens;
15611 : 3245 : if (parens.require_open (parser))
15612 : : {
15613 : 3241 : list = c_parser_omp_variable_list (parser, loc, kind, list, map_lvalue);
15614 : 3241 : parens.skip_until_found_close (parser);
15615 : : }
15616 : : return list;
15617 : : }
15618 : :
15619 : : /* OpenACC 2.0:
15620 : : copy ( variable-list )
15621 : : copyin ( variable-list )
15622 : : copyout ( variable-list )
15623 : : create ( variable-list )
15624 : : delete ( variable-list )
15625 : : present ( variable-list )
15626 : :
15627 : : OpenACC 2.6:
15628 : : no_create ( variable-list )
15629 : : attach ( variable-list )
15630 : : detach ( variable-list )
15631 : :
15632 : : OpenACC 2.7:
15633 : : copyin (readonly : variable-list )
15634 : : */
15635 : :
15636 : : static tree
15637 : 1996 : c_parser_oacc_data_clause (c_parser *parser, pragma_omp_clause c_kind,
15638 : : tree list)
15639 : : {
15640 : 1996 : enum gomp_map_kind kind;
15641 : 1996 : switch (c_kind)
15642 : : {
15643 : : case PRAGMA_OACC_CLAUSE_ATTACH:
15644 : : kind = GOMP_MAP_ATTACH;
15645 : : break;
15646 : 795 : case PRAGMA_OACC_CLAUSE_COPY:
15647 : 795 : kind = GOMP_MAP_TOFROM;
15648 : 795 : break;
15649 : 354 : case PRAGMA_OACC_CLAUSE_COPYIN:
15650 : 354 : kind = GOMP_MAP_TO;
15651 : 354 : break;
15652 : 384 : case PRAGMA_OACC_CLAUSE_COPYOUT:
15653 : 384 : kind = GOMP_MAP_FROM;
15654 : 384 : break;
15655 : 91 : case PRAGMA_OACC_CLAUSE_CREATE:
15656 : 91 : kind = GOMP_MAP_ALLOC;
15657 : 91 : break;
15658 : 67 : case PRAGMA_OACC_CLAUSE_DELETE:
15659 : 67 : kind = GOMP_MAP_RELEASE;
15660 : 67 : break;
15661 : 20 : case PRAGMA_OACC_CLAUSE_DETACH:
15662 : 20 : kind = GOMP_MAP_DETACH;
15663 : 20 : break;
15664 : 36 : case PRAGMA_OACC_CLAUSE_DEVICE:
15665 : 36 : kind = GOMP_MAP_FORCE_TO;
15666 : 36 : break;
15667 : 15 : case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT:
15668 : 15 : kind = GOMP_MAP_DEVICE_RESIDENT;
15669 : 15 : break;
15670 : 13 : case PRAGMA_OACC_CLAUSE_LINK:
15671 : 13 : kind = GOMP_MAP_LINK;
15672 : 13 : break;
15673 : 10 : case PRAGMA_OACC_CLAUSE_NO_CREATE:
15674 : 10 : kind = GOMP_MAP_IF_PRESENT;
15675 : 10 : break;
15676 : 126 : case PRAGMA_OACC_CLAUSE_PRESENT:
15677 : 126 : kind = GOMP_MAP_FORCE_PRESENT;
15678 : 126 : break;
15679 : 58 : case PRAGMA_OACC_CLAUSE_SELF:
15680 : : /* "The 'host' clause is a synonym for the 'self' clause." */
15681 : 58 : case PRAGMA_OACC_CLAUSE_HOST:
15682 : 58 : kind = GOMP_MAP_FORCE_FROM;
15683 : 58 : break;
15684 : 0 : default:
15685 : 0 : gcc_unreachable ();
15686 : : }
15687 : :
15688 : 1996 : tree nl = list;
15689 : 1996 : bool readonly = false;
15690 : 1996 : location_t open_loc = c_parser_peek_token (parser)->location;
15691 : 1996 : matching_parens parens;
15692 : 1996 : if (parens.require_open (parser))
15693 : : {
15694 : : /* Turn on readonly modifier parsing for copyin clause. */
15695 : 1996 : if (c_kind == PRAGMA_OACC_CLAUSE_COPYIN)
15696 : : {
15697 : 354 : c_token *token = c_parser_peek_token (parser);
15698 : 354 : if (token->type == CPP_NAME
15699 : 354 : && !strcmp (IDENTIFIER_POINTER (token->value), "readonly")
15700 : 361 : && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
15701 : : {
15702 : 7 : c_parser_consume_token (parser);
15703 : 7 : c_parser_consume_token (parser);
15704 : 7 : readonly = true;
15705 : : }
15706 : : }
15707 : 1996 : nl = c_parser_omp_variable_list (parser, open_loc, OMP_CLAUSE_MAP, list,
15708 : : false);
15709 : 1996 : parens.skip_until_found_close (parser);
15710 : : }
15711 : :
15712 : 4601 : for (tree c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
15713 : : {
15714 : 2605 : OMP_CLAUSE_SET_MAP_KIND (c, kind);
15715 : 2605 : if (readonly)
15716 : 13 : OMP_CLAUSE_MAP_READONLY (c) = 1;
15717 : : }
15718 : :
15719 : 1996 : return nl;
15720 : : }
15721 : :
15722 : : /* OpenACC 2.0:
15723 : : deviceptr ( variable-list ) */
15724 : :
15725 : : static tree
15726 : 54 : c_parser_oacc_data_clause_deviceptr (c_parser *parser, tree list)
15727 : : {
15728 : 54 : location_t loc = c_parser_peek_token (parser)->location;
15729 : 54 : tree vars, t;
15730 : :
15731 : : /* Can't use OMP_CLAUSE_MAP here (that is, can't use the generic
15732 : : c_parser_oacc_data_clause), as for PRAGMA_OACC_CLAUSE_DEVICEPTR,
15733 : : variable-list must only allow for pointer variables. */
15734 : 54 : vars = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
15735 : 110 : for (t = vars; t && t; t = TREE_CHAIN (t))
15736 : : {
15737 : 56 : tree v = TREE_PURPOSE (t);
15738 : :
15739 : : /* FIXME diagnostics: Ideally we should keep individual
15740 : : locations for all the variables in the var list to make the
15741 : : following errors more precise. Perhaps
15742 : : c_parser_omp_var_list_parens() should construct a list of
15743 : : locations to go along with the var list. */
15744 : :
15745 : 56 : if (!VAR_P (v) && TREE_CODE (v) != PARM_DECL)
15746 : 3 : error_at (loc, "%qD is not a variable", v);
15747 : 53 : else if (TREE_TYPE (v) == error_mark_node)
15748 : : ;
15749 : 52 : else if (!POINTER_TYPE_P (TREE_TYPE (v)))
15750 : 7 : error_at (loc, "%qD is not a pointer variable", v);
15751 : :
15752 : 56 : tree u = build_omp_clause (loc, OMP_CLAUSE_MAP);
15753 : 56 : OMP_CLAUSE_SET_MAP_KIND (u, GOMP_MAP_FORCE_DEVICEPTR);
15754 : 56 : OMP_CLAUSE_DECL (u) = v;
15755 : 56 : OMP_CLAUSE_CHAIN (u) = list;
15756 : 56 : list = u;
15757 : : }
15758 : :
15759 : 54 : return list;
15760 : : }
15761 : :
15762 : : /* OpenACC 2.0, OpenMP 3.0:
15763 : : collapse ( constant-expression ) */
15764 : :
15765 : : static tree
15766 : 2790 : c_parser_omp_clause_collapse (c_parser *parser, tree list)
15767 : : {
15768 : 2790 : tree c, num = error_mark_node;
15769 : 2790 : HOST_WIDE_INT n;
15770 : 2790 : location_t loc;
15771 : :
15772 : 2790 : check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse");
15773 : 2790 : check_no_duplicate_clause (list, OMP_CLAUSE_TILE, "tile");
15774 : :
15775 : 2790 : loc = c_parser_peek_token (parser)->location;
15776 : 2790 : matching_parens parens;
15777 : 2790 : if (parens.require_open (parser))
15778 : : {
15779 : 2790 : num = c_parser_expr_no_commas (parser, NULL).value;
15780 : 2790 : parens.skip_until_found_close (parser);
15781 : : }
15782 : 2790 : if (num == error_mark_node)
15783 : : return list;
15784 : 2790 : mark_exp_read (num);
15785 : 2790 : num = c_fully_fold (num, false, NULL);
15786 : 5580 : if (!INTEGRAL_TYPE_P (TREE_TYPE (num))
15787 : 2790 : || !tree_fits_shwi_p (num)
15788 : 2790 : || (n = tree_to_shwi (num)) <= 0
15789 : 5580 : || (int) n != n)
15790 : : {
15791 : 0 : error_at (loc,
15792 : : "collapse argument needs positive constant integer expression");
15793 : 0 : return list;
15794 : : }
15795 : 2790 : c = build_omp_clause (loc, OMP_CLAUSE_COLLAPSE);
15796 : 2790 : OMP_CLAUSE_COLLAPSE_EXPR (c) = num;
15797 : 2790 : OMP_CLAUSE_CHAIN (c) = list;
15798 : 2790 : return c;
15799 : : }
15800 : :
15801 : : /* OpenMP 2.5:
15802 : : copyin ( variable-list ) */
15803 : :
15804 : : static tree
15805 : 101 : c_parser_omp_clause_copyin (c_parser *parser, tree list)
15806 : : {
15807 : 0 : return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_COPYIN, list);
15808 : : }
15809 : :
15810 : : /* OpenMP 2.5:
15811 : : copyprivate ( variable-list ) */
15812 : :
15813 : : static tree
15814 : 21 : c_parser_omp_clause_copyprivate (c_parser *parser, tree list)
15815 : : {
15816 : 0 : return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_COPYPRIVATE, list);
15817 : : }
15818 : :
15819 : : /* OpenMP 2.5:
15820 : : default ( none | shared )
15821 : :
15822 : : OpenMP 5.1:
15823 : : default ( private | firstprivate )
15824 : :
15825 : : OpenACC:
15826 : : default ( none | present ) */
15827 : :
15828 : : static tree
15829 : 692 : c_parser_omp_clause_default (c_parser *parser, tree list, bool is_oacc)
15830 : : {
15831 : 692 : enum omp_clause_default_kind kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED;
15832 : 692 : location_t loc = c_parser_peek_token (parser)->location;
15833 : 692 : tree c;
15834 : :
15835 : 692 : matching_parens parens;
15836 : 692 : if (!parens.require_open (parser))
15837 : : return list;
15838 : 690 : if (c_parser_next_token_is (parser, CPP_NAME))
15839 : : {
15840 : 682 : const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
15841 : :
15842 : 682 : switch (p[0])
15843 : : {
15844 : 367 : case 'n':
15845 : 367 : if (strcmp ("none", p) != 0)
15846 : 0 : goto invalid_kind;
15847 : : kind = OMP_CLAUSE_DEFAULT_NONE;
15848 : : break;
15849 : :
15850 : 18 : case 'p':
15851 : 18 : if (is_oacc)
15852 : : {
15853 : 13 : if (strcmp ("present", p) != 0)
15854 : 2 : goto invalid_kind;
15855 : : kind = OMP_CLAUSE_DEFAULT_PRESENT;
15856 : : }
15857 : : else
15858 : : {
15859 : 5 : if (strcmp ("private", p) != 0)
15860 : 0 : goto invalid_kind;
15861 : : kind = OMP_CLAUSE_DEFAULT_PRIVATE;
15862 : : }
15863 : : break;
15864 : :
15865 : 8 : case 'f':
15866 : 8 : if (strcmp ("firstprivate", p) != 0 || is_oacc)
15867 : 0 : goto invalid_kind;
15868 : : kind = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
15869 : : break;
15870 : :
15871 : 285 : case 's':
15872 : 285 : if (strcmp ("shared", p) != 0 || is_oacc)
15873 : 0 : goto invalid_kind;
15874 : : kind = OMP_CLAUSE_DEFAULT_SHARED;
15875 : : break;
15876 : :
15877 : 4 : default:
15878 : 4 : goto invalid_kind;
15879 : : }
15880 : :
15881 : 672 : c_parser_consume_token (parser);
15882 : : }
15883 : : else
15884 : : {
15885 : 18 : invalid_kind:
15886 : 18 : if (is_oacc)
15887 : 14 : c_parser_error (parser, "expected %<none%> or %<present%>");
15888 : : else
15889 : 4 : c_parser_error (parser, "expected %<none%>, %<shared%>, "
15890 : : "%<private%> or %<firstprivate%>");
15891 : : }
15892 : 690 : parens.skip_until_found_close (parser);
15893 : :
15894 : 690 : if (kind == OMP_CLAUSE_DEFAULT_UNSPECIFIED)
15895 : : return list;
15896 : :
15897 : 672 : check_no_duplicate_clause (list, OMP_CLAUSE_DEFAULT, "default");
15898 : 672 : c = build_omp_clause (loc, OMP_CLAUSE_DEFAULT);
15899 : 672 : OMP_CLAUSE_CHAIN (c) = list;
15900 : 672 : OMP_CLAUSE_DEFAULT_KIND (c) = kind;
15901 : :
15902 : 672 : return c;
15903 : : }
15904 : :
15905 : : /* OpenMP 2.5:
15906 : : firstprivate ( variable-list ) */
15907 : :
15908 : : static tree
15909 : 765 : c_parser_omp_clause_firstprivate (c_parser *parser, tree list)
15910 : : {
15911 : 0 : return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_FIRSTPRIVATE, list);
15912 : : }
15913 : :
15914 : : /* OpenMP 3.1:
15915 : : final ( expression ) */
15916 : :
15917 : : static tree
15918 : 98 : c_parser_omp_clause_final (c_parser *parser, tree list)
15919 : : {
15920 : 98 : location_t loc = c_parser_peek_token (parser)->location;
15921 : 98 : if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
15922 : : {
15923 : 98 : matching_parens parens;
15924 : 98 : tree t, c;
15925 : 98 : if (!parens.require_open (parser))
15926 : 0 : t = error_mark_node;
15927 : : else
15928 : : {
15929 : 98 : location_t eloc = c_parser_peek_token (parser)->location;
15930 : 98 : c_expr expr = c_parser_expr_no_commas (parser, NULL);
15931 : 98 : t = convert_lvalue_to_rvalue (eloc, expr, true, true).value;
15932 : 98 : t = c_objc_common_truthvalue_conversion (eloc, t);
15933 : 98 : t = c_fully_fold (t, false, NULL);
15934 : 98 : parens.skip_until_found_close (parser);
15935 : : }
15936 : :
15937 : 98 : check_no_duplicate_clause (list, OMP_CLAUSE_FINAL, "final");
15938 : :
15939 : 98 : c = build_omp_clause (loc, OMP_CLAUSE_FINAL);
15940 : 98 : OMP_CLAUSE_FINAL_EXPR (c) = t;
15941 : 98 : OMP_CLAUSE_CHAIN (c) = list;
15942 : 98 : list = c;
15943 : : }
15944 : : else
15945 : 0 : c_parser_error (parser, "expected %<(%>");
15946 : :
15947 : 98 : return list;
15948 : : }
15949 : :
15950 : : /* OpenMP 5.1:
15951 : : indirect [( expression )]
15952 : : */
15953 : :
15954 : : static tree
15955 : 26 : c_parser_omp_clause_indirect (c_parser *parser, tree list)
15956 : : {
15957 : 26 : location_t location = c_parser_peek_token (parser)->location;
15958 : 26 : tree t;
15959 : :
15960 : 26 : if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
15961 : : {
15962 : 17 : matching_parens parens;
15963 : 17 : if (!parens.require_open (parser))
15964 : 1 : return list;
15965 : :
15966 : 17 : location_t loc = c_parser_peek_token (parser)->location;
15967 : 17 : c_expr expr = c_parser_expr_no_commas (parser, NULL);
15968 : 17 : expr = convert_lvalue_to_rvalue (loc, expr, true, true);
15969 : 17 : t = c_objc_common_truthvalue_conversion (loc, expr.value);
15970 : 17 : t = c_fully_fold (t, false, NULL);
15971 : 34 : if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
15972 : 34 : || TREE_CODE (t) != INTEGER_CST)
15973 : : {
15974 : 1 : c_parser_error (parser, "expected constant logical expression");
15975 : 1 : return list;
15976 : : }
15977 : 16 : parens.skip_until_found_close (parser);
15978 : : }
15979 : : else
15980 : 9 : t = integer_one_node;
15981 : :
15982 : 25 : check_no_duplicate_clause (list, OMP_CLAUSE_INDIRECT, "indirect");
15983 : :
15984 : 25 : tree c = build_omp_clause (location, OMP_CLAUSE_INDIRECT);
15985 : 25 : OMP_CLAUSE_INDIRECT_EXPR (c) = t;
15986 : 25 : OMP_CLAUSE_CHAIN (c) = list;
15987 : :
15988 : 25 : return c;
15989 : : }
15990 : :
15991 : : /* OpenACC, OpenMP 2.5:
15992 : : if ( expression )
15993 : :
15994 : : OpenMP 4.5:
15995 : : if ( directive-name-modifier : expression )
15996 : :
15997 : : directive-name-modifier:
15998 : : parallel | task | taskloop | target data | target | target update
15999 : : | target enter data | target exit data
16000 : :
16001 : : OpenMP 5.0:
16002 : : directive-name-modifier:
16003 : : ... | simd | cancel */
16004 : :
16005 : : static tree
16006 : 872 : c_parser_omp_clause_if (c_parser *parser, tree list, bool is_omp)
16007 : : {
16008 : 872 : location_t location = c_parser_peek_token (parser)->location;
16009 : 872 : enum tree_code if_modifier = ERROR_MARK;
16010 : :
16011 : 872 : matching_parens parens;
16012 : 872 : if (!parens.require_open (parser))
16013 : : return list;
16014 : :
16015 : 1648 : if (is_omp && c_parser_next_token_is (parser, CPP_NAME))
16016 : : {
16017 : 635 : const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16018 : 635 : int n = 2;
16019 : 635 : if (strcmp (p, "cancel") == 0)
16020 : : if_modifier = VOID_CST;
16021 : 620 : else if (strcmp (p, "parallel") == 0)
16022 : : if_modifier = OMP_PARALLEL;
16023 : 481 : else if (strcmp (p, "simd") == 0)
16024 : : if_modifier = OMP_SIMD;
16025 : 375 : else if (strcmp (p, "task") == 0)
16026 : : if_modifier = OMP_TASK;
16027 : 364 : else if (strcmp (p, "taskloop") == 0)
16028 : : if_modifier = OMP_TASKLOOP;
16029 : 313 : else if (strcmp (p, "target") == 0)
16030 : : {
16031 : 102 : if_modifier = OMP_TARGET;
16032 : 102 : if (c_parser_peek_2nd_token (parser)->type == CPP_NAME)
16033 : : {
16034 : 37 : p = IDENTIFIER_POINTER (c_parser_peek_2nd_token (parser)->value);
16035 : 37 : if (strcmp ("data", p) == 0)
16036 : : if_modifier = OMP_TARGET_DATA;
16037 : 29 : else if (strcmp ("update", p) == 0)
16038 : : if_modifier = OMP_TARGET_UPDATE;
16039 : 18 : else if (strcmp ("enter", p) == 0)
16040 : : if_modifier = OMP_TARGET_ENTER_DATA;
16041 : 10 : else if (strcmp ("exit", p) == 0)
16042 : : if_modifier = OMP_TARGET_EXIT_DATA;
16043 : 0 : if (if_modifier != OMP_TARGET)
16044 : : {
16045 : 37 : n = 3;
16046 : 37 : c_parser_consume_token (parser);
16047 : : }
16048 : : else
16049 : : {
16050 : 0 : location_t loc = c_parser_peek_2nd_token (parser)->location;
16051 : 0 : error_at (loc, "expected %<data%>, %<update%>, %<enter%> "
16052 : : "or %<exit%>");
16053 : 0 : if_modifier = ERROR_MARK;
16054 : : }
16055 : 37 : if (if_modifier == OMP_TARGET_ENTER_DATA
16056 : 37 : || if_modifier == OMP_TARGET_EXIT_DATA)
16057 : : {
16058 : 18 : if (c_parser_peek_2nd_token (parser)->type == CPP_NAME)
16059 : : {
16060 : 18 : p = IDENTIFIER_POINTER
16061 : : (c_parser_peek_2nd_token (parser)->value);
16062 : 18 : if (strcmp ("data", p) == 0)
16063 : 18 : n = 4;
16064 : : }
16065 : 18 : if (n == 4)
16066 : 18 : c_parser_consume_token (parser);
16067 : : else
16068 : : {
16069 : 0 : location_t loc
16070 : 0 : = c_parser_peek_2nd_token (parser)->location;
16071 : 0 : error_at (loc, "expected %<data%>");
16072 : 0 : if_modifier = ERROR_MARK;
16073 : : }
16074 : : }
16075 : : }
16076 : : }
16077 : 37 : if (if_modifier != ERROR_MARK)
16078 : : {
16079 : 424 : if (c_parser_peek_2nd_token (parser)->type == CPP_COLON)
16080 : : {
16081 : 423 : c_parser_consume_token (parser);
16082 : 423 : c_parser_consume_token (parser);
16083 : : }
16084 : : else
16085 : : {
16086 : 1 : if (n > 2)
16087 : : {
16088 : 0 : location_t loc = c_parser_peek_2nd_token (parser)->location;
16089 : 0 : error_at (loc, "expected %<:%>");
16090 : : }
16091 : : if_modifier = ERROR_MARK;
16092 : : }
16093 : : }
16094 : : }
16095 : :
16096 : 872 : location_t loc = c_parser_peek_token (parser)->location;
16097 : 872 : c_expr expr = c_parser_expr_no_commas (parser, NULL);
16098 : 872 : expr = convert_lvalue_to_rvalue (loc, expr, true, true);
16099 : 872 : tree t = c_objc_common_truthvalue_conversion (loc, expr.value), c;
16100 : 872 : t = c_fully_fold (t, false, NULL);
16101 : 872 : parens.skip_until_found_close (parser);
16102 : :
16103 : 3962 : for (c = list; c ; c = OMP_CLAUSE_CHAIN (c))
16104 : 3130 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IF)
16105 : : {
16106 : 174 : if (if_modifier != ERROR_MARK
16107 : 174 : && OMP_CLAUSE_IF_MODIFIER (c) == if_modifier)
16108 : : {
16109 : 9 : const char *p = NULL;
16110 : 9 : switch (if_modifier)
16111 : : {
16112 : : case VOID_CST: p = "cancel"; break;
16113 : 1 : case OMP_PARALLEL: p = "parallel"; break;
16114 : 0 : case OMP_SIMD: p = "simd"; break;
16115 : 1 : case OMP_TASK: p = "task"; break;
16116 : 1 : case OMP_TASKLOOP: p = "taskloop"; break;
16117 : 1 : case OMP_TARGET_DATA: p = "target data"; break;
16118 : 1 : case OMP_TARGET: p = "target"; break;
16119 : 1 : case OMP_TARGET_UPDATE: p = "target update"; break;
16120 : 1 : case OMP_TARGET_ENTER_DATA: p = "target enter data"; break;
16121 : 1 : case OMP_TARGET_EXIT_DATA: p = "target exit data"; break;
16122 : 0 : default: gcc_unreachable ();
16123 : : }
16124 : 9 : error_at (location, "too many %<if%> clauses with %qs modifier",
16125 : : p);
16126 : 9 : return list;
16127 : : }
16128 : 165 : else if (OMP_CLAUSE_IF_MODIFIER (c) == if_modifier)
16129 : : {
16130 : 13 : if (!is_omp)
16131 : 1 : error_at (location, "too many %<if%> clauses");
16132 : : else
16133 : 12 : error_at (location, "too many %<if%> clauses without modifier");
16134 : 13 : return list;
16135 : : }
16136 : 152 : else if (if_modifier == ERROR_MARK
16137 : 152 : || OMP_CLAUSE_IF_MODIFIER (c) == ERROR_MARK)
16138 : : {
16139 : 18 : error_at (location, "if any %<if%> clause has modifier, then all "
16140 : : "%<if%> clauses have to use modifier");
16141 : 18 : return list;
16142 : : }
16143 : : }
16144 : :
16145 : 832 : c = build_omp_clause (location, OMP_CLAUSE_IF);
16146 : 832 : OMP_CLAUSE_IF_MODIFIER (c) = if_modifier;
16147 : 832 : OMP_CLAUSE_IF_EXPR (c) = t;
16148 : 832 : OMP_CLAUSE_CHAIN (c) = list;
16149 : 832 : return c;
16150 : : }
16151 : :
16152 : : /* OpenMP 2.5:
16153 : : lastprivate ( variable-list )
16154 : :
16155 : : OpenMP 5.0:
16156 : : lastprivate ( [ lastprivate-modifier : ] variable-list ) */
16157 : :
16158 : : static tree
16159 : 728 : c_parser_omp_clause_lastprivate (c_parser *parser, tree list)
16160 : : {
16161 : : /* The clauses location. */
16162 : 728 : location_t loc = c_parser_peek_token (parser)->location;
16163 : :
16164 : 728 : if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
16165 : : {
16166 : 728 : bool conditional = false;
16167 : 728 : if (c_parser_next_token_is (parser, CPP_NAME)
16168 : 728 : && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
16169 : : {
16170 : 107 : const char *p
16171 : 107 : = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16172 : 107 : if (strcmp (p, "conditional") == 0)
16173 : : {
16174 : 107 : conditional = true;
16175 : 107 : c_parser_consume_token (parser);
16176 : 107 : c_parser_consume_token (parser);
16177 : : }
16178 : : }
16179 : 728 : tree nlist = c_parser_omp_variable_list (parser, loc,
16180 : : OMP_CLAUSE_LASTPRIVATE, list);
16181 : 728 : c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
16182 : 728 : if (conditional)
16183 : 246 : for (tree c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
16184 : 139 : OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 1;
16185 : 728 : return nlist;
16186 : : }
16187 : : return list;
16188 : : }
16189 : :
16190 : : /* OpenMP 3.1:
16191 : : mergeable */
16192 : :
16193 : : static tree
16194 : 78 : c_parser_omp_clause_mergeable (c_parser *parser ATTRIBUTE_UNUSED, tree list)
16195 : : {
16196 : 78 : tree c;
16197 : :
16198 : : /* FIXME: Should we allow duplicates? */
16199 : 78 : check_no_duplicate_clause (list, OMP_CLAUSE_MERGEABLE, "mergeable");
16200 : :
16201 : 78 : c = build_omp_clause (c_parser_peek_token (parser)->location,
16202 : : OMP_CLAUSE_MERGEABLE);
16203 : 78 : OMP_CLAUSE_CHAIN (c) = list;
16204 : :
16205 : 78 : return c;
16206 : : }
16207 : :
16208 : : /* OpenMP 2.5:
16209 : : nowait */
16210 : :
16211 : : static tree
16212 : 364 : c_parser_omp_clause_nowait (c_parser *parser ATTRIBUTE_UNUSED, tree list)
16213 : : {
16214 : 364 : tree c;
16215 : 364 : location_t loc = c_parser_peek_token (parser)->location;
16216 : :
16217 : 364 : check_no_duplicate_clause (list, OMP_CLAUSE_NOWAIT, "nowait");
16218 : :
16219 : 364 : c = build_omp_clause (loc, OMP_CLAUSE_NOWAIT);
16220 : 364 : OMP_CLAUSE_CHAIN (c) = list;
16221 : 364 : return c;
16222 : : }
16223 : :
16224 : : /* OpenMP 2.5:
16225 : : num_threads ( expression ) */
16226 : :
16227 : : static tree
16228 : 424 : c_parser_omp_clause_num_threads (c_parser *parser, tree list)
16229 : : {
16230 : 424 : location_t num_threads_loc = c_parser_peek_token (parser)->location;
16231 : 424 : matching_parens parens;
16232 : 424 : if (parens.require_open (parser))
16233 : : {
16234 : 424 : location_t expr_loc = c_parser_peek_token (parser)->location;
16235 : 424 : c_expr expr = c_parser_expr_no_commas (parser, NULL);
16236 : 424 : expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
16237 : 424 : tree c, t = expr.value;
16238 : 424 : t = c_fully_fold (t, false, NULL);
16239 : :
16240 : 424 : parens.skip_until_found_close (parser);
16241 : :
16242 : 424 : if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
16243 : : {
16244 : 0 : c_parser_error (parser, "expected integer expression");
16245 : 0 : return list;
16246 : : }
16247 : :
16248 : : /* Attempt to statically determine when the number isn't positive. */
16249 : 424 : c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
16250 : 424 : build_int_cst (TREE_TYPE (t), 0));
16251 : 424 : protected_set_expr_location (c, expr_loc);
16252 : 424 : if (c == boolean_true_node)
16253 : : {
16254 : 1 : warning_at (expr_loc, OPT_Wopenmp,
16255 : : "%<num_threads%> value must be positive");
16256 : 1 : t = integer_one_node;
16257 : : }
16258 : :
16259 : 424 : check_no_duplicate_clause (list, OMP_CLAUSE_NUM_THREADS, "num_threads");
16260 : :
16261 : 424 : c = build_omp_clause (num_threads_loc, OMP_CLAUSE_NUM_THREADS);
16262 : 424 : OMP_CLAUSE_NUM_THREADS_EXPR (c) = t;
16263 : 424 : OMP_CLAUSE_CHAIN (c) = list;
16264 : 424 : list = c;
16265 : : }
16266 : :
16267 : : return list;
16268 : : }
16269 : :
16270 : : /* OpenMP 4.5:
16271 : : num_tasks ( expression )
16272 : :
16273 : : OpenMP 5.1:
16274 : : num_tasks ( strict : expression ) */
16275 : :
16276 : : static tree
16277 : 49 : c_parser_omp_clause_num_tasks (c_parser *parser, tree list)
16278 : : {
16279 : 49 : location_t num_tasks_loc = c_parser_peek_token (parser)->location;
16280 : 49 : matching_parens parens;
16281 : 49 : if (parens.require_open (parser))
16282 : : {
16283 : 49 : bool strict = false;
16284 : 49 : if (c_parser_next_token_is (parser, CPP_NAME)
16285 : 39 : && c_parser_peek_2nd_token (parser)->type == CPP_COLON
16286 : 50 : && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
16287 : : "strict") == 0)
16288 : : {
16289 : 1 : strict = true;
16290 : 1 : c_parser_consume_token (parser);
16291 : 1 : c_parser_consume_token (parser);
16292 : : }
16293 : :
16294 : 49 : location_t expr_loc = c_parser_peek_token (parser)->location;
16295 : 49 : c_expr expr = c_parser_expr_no_commas (parser, NULL);
16296 : 49 : expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
16297 : 49 : tree c, t = expr.value;
16298 : 49 : t = c_fully_fold (t, false, NULL);
16299 : :
16300 : 49 : parens.skip_until_found_close (parser);
16301 : :
16302 : 49 : if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
16303 : : {
16304 : 0 : c_parser_error (parser, "expected integer expression");
16305 : 0 : return list;
16306 : : }
16307 : :
16308 : : /* Attempt to statically determine when the number isn't positive. */
16309 : 49 : c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
16310 : 49 : build_int_cst (TREE_TYPE (t), 0));
16311 : 49 : if (CAN_HAVE_LOCATION_P (c))
16312 : 39 : SET_EXPR_LOCATION (c, expr_loc);
16313 : 49 : if (c == boolean_true_node)
16314 : : {
16315 : 0 : warning_at (expr_loc, OPT_Wopenmp,
16316 : : "%<num_tasks%> value must be positive");
16317 : 0 : t = integer_one_node;
16318 : : }
16319 : :
16320 : 49 : check_no_duplicate_clause (list, OMP_CLAUSE_NUM_TASKS, "num_tasks");
16321 : :
16322 : 49 : c = build_omp_clause (num_tasks_loc, OMP_CLAUSE_NUM_TASKS);
16323 : 49 : OMP_CLAUSE_NUM_TASKS_EXPR (c) = t;
16324 : 49 : OMP_CLAUSE_NUM_TASKS_STRICT (c) = strict;
16325 : 49 : OMP_CLAUSE_CHAIN (c) = list;
16326 : 49 : list = c;
16327 : : }
16328 : :
16329 : : return list;
16330 : : }
16331 : :
16332 : : /* OpenMP 4.5:
16333 : : grainsize ( expression )
16334 : :
16335 : : OpenMP 5.1:
16336 : : grainsize ( strict : expression ) */
16337 : :
16338 : : static tree
16339 : 62 : c_parser_omp_clause_grainsize (c_parser *parser, tree list)
16340 : : {
16341 : 62 : location_t grainsize_loc = c_parser_peek_token (parser)->location;
16342 : 62 : matching_parens parens;
16343 : 62 : if (parens.require_open (parser))
16344 : : {
16345 : 62 : bool strict = false;
16346 : 62 : if (c_parser_next_token_is (parser, CPP_NAME)
16347 : 47 : && c_parser_peek_2nd_token (parser)->type == CPP_COLON
16348 : 63 : && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
16349 : : "strict") == 0)
16350 : : {
16351 : 1 : strict = true;
16352 : 1 : c_parser_consume_token (parser);
16353 : 1 : c_parser_consume_token (parser);
16354 : : }
16355 : :
16356 : 62 : location_t expr_loc = c_parser_peek_token (parser)->location;
16357 : 62 : c_expr expr = c_parser_expr_no_commas (parser, NULL);
16358 : 62 : expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
16359 : 62 : tree c, t = expr.value;
16360 : 62 : t = c_fully_fold (t, false, NULL);
16361 : :
16362 : 62 : parens.skip_until_found_close (parser);
16363 : :
16364 : 62 : if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
16365 : : {
16366 : 0 : c_parser_error (parser, "expected integer expression");
16367 : 0 : return list;
16368 : : }
16369 : :
16370 : : /* Attempt to statically determine when the number isn't positive. */
16371 : 62 : c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
16372 : 62 : build_int_cst (TREE_TYPE (t), 0));
16373 : 62 : if (CAN_HAVE_LOCATION_P (c))
16374 : 47 : SET_EXPR_LOCATION (c, expr_loc);
16375 : 62 : if (c == boolean_true_node)
16376 : : {
16377 : 0 : warning_at (expr_loc, OPT_Wopenmp,
16378 : : "%<grainsize%> value must be positive");
16379 : 0 : t = integer_one_node;
16380 : : }
16381 : :
16382 : 62 : check_no_duplicate_clause (list, OMP_CLAUSE_GRAINSIZE, "grainsize");
16383 : :
16384 : 62 : c = build_omp_clause (grainsize_loc, OMP_CLAUSE_GRAINSIZE);
16385 : 62 : OMP_CLAUSE_GRAINSIZE_EXPR (c) = t;
16386 : 62 : OMP_CLAUSE_GRAINSIZE_STRICT (c) = strict;
16387 : 62 : OMP_CLAUSE_CHAIN (c) = list;
16388 : 62 : list = c;
16389 : : }
16390 : :
16391 : : return list;
16392 : : }
16393 : :
16394 : : /* OpenMP 4.5:
16395 : : priority ( expression ) */
16396 : :
16397 : : static tree
16398 : 97 : c_parser_omp_clause_priority (c_parser *parser, tree list)
16399 : : {
16400 : 97 : location_t priority_loc = c_parser_peek_token (parser)->location;
16401 : 97 : matching_parens parens;
16402 : 97 : if (parens.require_open (parser))
16403 : : {
16404 : 97 : location_t expr_loc = c_parser_peek_token (parser)->location;
16405 : 97 : c_expr expr = c_parser_expr_no_commas (parser, NULL);
16406 : 97 : expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
16407 : 97 : tree c, t = expr.value;
16408 : 97 : t = c_fully_fold (t, false, NULL);
16409 : :
16410 : 97 : parens.skip_until_found_close (parser);
16411 : :
16412 : 97 : if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
16413 : : {
16414 : 0 : c_parser_error (parser, "expected integer expression");
16415 : 0 : return list;
16416 : : }
16417 : :
16418 : : /* Attempt to statically determine when the number isn't
16419 : : non-negative. */
16420 : 97 : c = fold_build2_loc (expr_loc, LT_EXPR, boolean_type_node, t,
16421 : 97 : build_int_cst (TREE_TYPE (t), 0));
16422 : 97 : if (CAN_HAVE_LOCATION_P (c))
16423 : 86 : SET_EXPR_LOCATION (c, expr_loc);
16424 : 97 : if (c == boolean_true_node)
16425 : : {
16426 : 0 : warning_at (expr_loc, OPT_Wopenmp,
16427 : : "%<priority%> value must be non-negative");
16428 : 0 : t = integer_one_node;
16429 : : }
16430 : :
16431 : 97 : check_no_duplicate_clause (list, OMP_CLAUSE_PRIORITY, "priority");
16432 : :
16433 : 97 : c = build_omp_clause (priority_loc, OMP_CLAUSE_PRIORITY);
16434 : 97 : OMP_CLAUSE_PRIORITY_EXPR (c) = t;
16435 : 97 : OMP_CLAUSE_CHAIN (c) = list;
16436 : 97 : list = c;
16437 : : }
16438 : :
16439 : : return list;
16440 : : }
16441 : :
16442 : : /* OpenMP 4.5:
16443 : : hint ( expression ) */
16444 : :
16445 : : static tree
16446 : 58 : c_parser_omp_clause_hint (c_parser *parser, tree list)
16447 : : {
16448 : 58 : location_t hint_loc = c_parser_peek_token (parser)->location;
16449 : 58 : matching_parens parens;
16450 : 58 : if (parens.require_open (parser))
16451 : : {
16452 : 58 : location_t expr_loc = c_parser_peek_token (parser)->location;
16453 : 58 : c_expr expr = c_parser_expr_no_commas (parser, NULL);
16454 : 58 : expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
16455 : 58 : tree c, t = expr.value;
16456 : 58 : t = c_fully_fold (t, false, NULL);
16457 : 116 : if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
16458 : 57 : || TREE_CODE (t) != INTEGER_CST
16459 : 111 : || tree_int_cst_sgn (t) == -1)
16460 : : {
16461 : 6 : c_parser_error (parser, "expected constant integer expression "
16462 : : "with valid sync-hint value");
16463 : 6 : return list;
16464 : : }
16465 : 52 : parens.skip_until_found_close (parser);
16466 : 52 : check_no_duplicate_clause (list, OMP_CLAUSE_HINT, "hint");
16467 : :
16468 : 52 : c = build_omp_clause (hint_loc, OMP_CLAUSE_HINT);
16469 : 52 : OMP_CLAUSE_HINT_EXPR (c) = t;
16470 : 52 : OMP_CLAUSE_CHAIN (c) = list;
16471 : 52 : list = c;
16472 : : }
16473 : :
16474 : : return list;
16475 : : }
16476 : :
16477 : : /* OpenMP 5.1:
16478 : : filter ( integer-expression ) */
16479 : :
16480 : : static tree
16481 : 62 : c_parser_omp_clause_filter (c_parser *parser, tree list)
16482 : : {
16483 : 62 : location_t hint_loc = c_parser_peek_token (parser)->location;
16484 : 62 : matching_parens parens;
16485 : 62 : if (parens.require_open (parser))
16486 : : {
16487 : 62 : location_t expr_loc = c_parser_peek_token (parser)->location;
16488 : 62 : c_expr expr = c_parser_expr_no_commas (parser, NULL);
16489 : 62 : expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
16490 : 62 : tree c, t = expr.value;
16491 : 62 : t = c_fully_fold (t, false, NULL);
16492 : 62 : if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
16493 : : {
16494 : 2 : c_parser_error (parser, "expected integer expression");
16495 : 2 : return list;
16496 : : }
16497 : 60 : parens.skip_until_found_close (parser);
16498 : 60 : check_no_duplicate_clause (list, OMP_CLAUSE_FILTER, "filter");
16499 : :
16500 : 60 : c = build_omp_clause (hint_loc, OMP_CLAUSE_FILTER);
16501 : 60 : OMP_CLAUSE_FILTER_EXPR (c) = t;
16502 : 60 : OMP_CLAUSE_CHAIN (c) = list;
16503 : 60 : list = c;
16504 : : }
16505 : :
16506 : : return list;
16507 : : }
16508 : :
16509 : : /* OpenMP 4.5:
16510 : : defaultmap ( tofrom : scalar )
16511 : :
16512 : : OpenMP 5.0:
16513 : : defaultmap ( implicit-behavior [ : variable-category ] ) */
16514 : :
16515 : : static tree
16516 : 238 : c_parser_omp_clause_defaultmap (c_parser *parser, tree list)
16517 : : {
16518 : 238 : location_t loc = c_parser_peek_token (parser)->location;
16519 : 238 : tree c;
16520 : 238 : const char *p;
16521 : 238 : enum omp_clause_defaultmap_kind behavior = OMP_CLAUSE_DEFAULTMAP_DEFAULT;
16522 : 238 : enum omp_clause_defaultmap_kind category
16523 : : = OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED;
16524 : :
16525 : 238 : matching_parens parens;
16526 : 238 : if (!parens.require_open (parser))
16527 : : return list;
16528 : 238 : if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
16529 : : p = "default";
16530 : 230 : else if (!c_parser_next_token_is (parser, CPP_NAME))
16531 : : {
16532 : 2 : invalid_behavior:
16533 : 3 : c_parser_error (parser, "expected %<alloc%>, %<to%>, %<from%>, "
16534 : : "%<tofrom%>, %<firstprivate%>, %<none%> "
16535 : : "or %<default%>");
16536 : 3 : goto out_err;
16537 : : }
16538 : : else
16539 : 228 : p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16540 : :
16541 : 236 : switch (p[0])
16542 : : {
16543 : 6 : case 'a':
16544 : 6 : if (strcmp ("alloc", p) == 0)
16545 : : behavior = OMP_CLAUSE_DEFAULTMAP_ALLOC;
16546 : : else
16547 : 0 : goto invalid_behavior;
16548 : : break;
16549 : :
16550 : 8 : case 'd':
16551 : 8 : if (strcmp ("default", p) == 0)
16552 : : behavior = OMP_CLAUSE_DEFAULTMAP_DEFAULT;
16553 : : else
16554 : 0 : goto invalid_behavior;
16555 : : break;
16556 : :
16557 : 27 : case 'f':
16558 : 27 : if (strcmp ("firstprivate", p) == 0)
16559 : : behavior = OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE;
16560 : 3 : else if (strcmp ("from", p) == 0)
16561 : : behavior = OMP_CLAUSE_DEFAULTMAP_FROM;
16562 : : else
16563 : 0 : goto invalid_behavior;
16564 : : break;
16565 : :
16566 : 101 : case 'n':
16567 : 101 : if (strcmp ("none", p) == 0)
16568 : : behavior = OMP_CLAUSE_DEFAULTMAP_NONE;
16569 : : else
16570 : 0 : goto invalid_behavior;
16571 : : break;
16572 : :
16573 : 4 : case 'p':
16574 : 4 : if (strcmp ("present", p) == 0)
16575 : : behavior = OMP_CLAUSE_DEFAULTMAP_PRESENT;
16576 : : else
16577 : 0 : goto invalid_behavior;
16578 : : break;
16579 : :
16580 : 89 : case 't':
16581 : 89 : if (strcmp ("tofrom", p) == 0)
16582 : : behavior = OMP_CLAUSE_DEFAULTMAP_TOFROM;
16583 : 4 : else if (strcmp ("to", p) == 0)
16584 : : behavior = OMP_CLAUSE_DEFAULTMAP_TO;
16585 : : else
16586 : 0 : goto invalid_behavior;
16587 : : break;
16588 : :
16589 : 1 : default:
16590 : 1 : goto invalid_behavior;
16591 : : }
16592 : 235 : c_parser_consume_token (parser);
16593 : :
16594 : 235 : if (!c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
16595 : : {
16596 : 132 : if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
16597 : 3 : goto out_err;
16598 : 129 : if (!c_parser_next_token_is (parser, CPP_NAME))
16599 : : {
16600 : 1 : invalid_category:
16601 : 2 : c_parser_error (parser, "expected %<scalar%>, %<aggregate%>, "
16602 : : "%<pointer%> or %<all%>");
16603 : 2 : goto out_err;
16604 : : }
16605 : 128 : p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16606 : 128 : switch (p[0])
16607 : : {
16608 : 22 : case 'a':
16609 : 22 : if (strcmp ("aggregate", p) == 0)
16610 : : category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE;
16611 : 8 : else if (strcmp ("all", p) == 0)
16612 : : category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL;
16613 : : else
16614 : 0 : goto invalid_category;
16615 : : break;
16616 : :
16617 : 15 : case 'p':
16618 : 15 : if (strcmp ("pointer", p) == 0)
16619 : : category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER;
16620 : : else
16621 : 0 : goto invalid_category;
16622 : : break;
16623 : :
16624 : 90 : case 's':
16625 : 90 : if (strcmp ("scalar", p) == 0)
16626 : : category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR;
16627 : : else
16628 : 0 : goto invalid_category;
16629 : : break;
16630 : :
16631 : 1 : default:
16632 : 1 : goto invalid_category;
16633 : : }
16634 : :
16635 : 127 : c_parser_consume_token (parser);
16636 : : }
16637 : 230 : parens.skip_until_found_close (parser);
16638 : :
16639 : 959 : for (c = list; c ; c = OMP_CLAUSE_CHAIN (c))
16640 : 512 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEFAULTMAP
16641 : 512 : && (category == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
16642 : : || category == OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL
16643 : 32 : || OMP_CLAUSE_DEFAULTMAP_CATEGORY (c) == category
16644 : 31 : || (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c)
16645 : : == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)
16646 : 29 : || (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c)
16647 : : == OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL)))
16648 : : {
16649 : 13 : enum omp_clause_defaultmap_kind cat = category;
16650 : 13 : location_t loc = OMP_CLAUSE_LOCATION (c);
16651 : 13 : if (cat == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
16652 : 13 : || (cat == OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL
16653 : 3 : && (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c)
16654 : : != OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)))
16655 : 8 : cat = OMP_CLAUSE_DEFAULTMAP_CATEGORY (c);
16656 : 13 : p = NULL;
16657 : 13 : switch (cat)
16658 : : {
16659 : : case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED:
16660 : : p = NULL;
16661 : : break;
16662 : 3 : case OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL:
16663 : 3 : p = "all";
16664 : 3 : break;
16665 : 2 : case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE:
16666 : 2 : p = "aggregate";
16667 : 2 : break;
16668 : 3 : case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER:
16669 : 3 : p = "pointer";
16670 : 3 : break;
16671 : : case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR:
16672 : : p = "scalar";
16673 : : break;
16674 : 0 : default:
16675 : 0 : gcc_unreachable ();
16676 : : }
16677 : 8 : if (p)
16678 : 10 : error_at (loc, "too many %<defaultmap%> clauses with %qs category",
16679 : : p);
16680 : : else
16681 : 3 : error_at (loc, "too many %<defaultmap%> clauses with unspecified "
16682 : : "category");
16683 : : break;
16684 : : }
16685 : :
16686 : 230 : c = build_omp_clause (loc, OMP_CLAUSE_DEFAULTMAP);
16687 : 230 : OMP_CLAUSE_DEFAULTMAP_SET_KIND (c, behavior, category);
16688 : 230 : OMP_CLAUSE_CHAIN (c) = list;
16689 : 230 : return c;
16690 : :
16691 : 8 : out_err:
16692 : 8 : parens.skip_until_found_close (parser);
16693 : 8 : return list;
16694 : : }
16695 : :
16696 : : /* OpenACC 2.0:
16697 : : use_device ( variable-list )
16698 : :
16699 : : OpenMP 4.5:
16700 : : use_device_ptr ( variable-list ) */
16701 : :
16702 : : static tree
16703 : 30 : c_parser_omp_clause_use_device_ptr (c_parser *parser, tree list)
16704 : : {
16705 : 0 : return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_USE_DEVICE_PTR,
16706 : 0 : list);
16707 : : }
16708 : :
16709 : : /* OpenMP 5.0:
16710 : : use_device_addr ( variable-list ) */
16711 : :
16712 : : static tree
16713 : 35 : c_parser_omp_clause_use_device_addr (c_parser *parser, tree list)
16714 : : {
16715 : 0 : return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_USE_DEVICE_ADDR,
16716 : 0 : list);
16717 : : }
16718 : :
16719 : : /* OpenMP 5.1:
16720 : : has_device_addr ( variable-list ) */
16721 : :
16722 : : static tree
16723 : 86 : c_parser_omp_clause_has_device_addr (c_parser *parser, tree list)
16724 : : {
16725 : 0 : return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_HAS_DEVICE_ADDR,
16726 : 0 : list);
16727 : : }
16728 : :
16729 : : /* OpenMP 4.5:
16730 : : is_device_ptr ( variable-list ) */
16731 : :
16732 : : static tree
16733 : 85 : c_parser_omp_clause_is_device_ptr (c_parser *parser, tree list)
16734 : : {
16735 : 0 : return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_IS_DEVICE_PTR, list);
16736 : : }
16737 : :
16738 : : /* OpenACC:
16739 : : num_gangs ( expression )
16740 : : num_workers ( expression )
16741 : : vector_length ( expression ) */
16742 : :
16743 : : static tree
16744 : 732 : c_parser_oacc_single_int_clause (c_parser *parser, omp_clause_code code,
16745 : : tree list)
16746 : : {
16747 : 732 : location_t loc = c_parser_peek_token (parser)->location;
16748 : :
16749 : 732 : matching_parens parens;
16750 : 732 : if (!parens.require_open (parser))
16751 : : return list;
16752 : :
16753 : 726 : location_t expr_loc = c_parser_peek_token (parser)->location;
16754 : 726 : c_expr expr = c_parser_expression (parser);
16755 : 726 : expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
16756 : 726 : tree c, t = expr.value;
16757 : 726 : t = c_fully_fold (t, false, NULL);
16758 : :
16759 : 726 : parens.skip_until_found_close (parser);
16760 : :
16761 : 726 : if (t == error_mark_node)
16762 : : return list;
16763 : 702 : else if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
16764 : : {
16765 : 16 : error_at (expr_loc, "%qs expression must be integral",
16766 : 16 : omp_clause_code_name[code]);
16767 : 16 : return list;
16768 : : }
16769 : :
16770 : : /* Attempt to statically determine when the number isn't positive. */
16771 : 686 : c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
16772 : 686 : build_int_cst (TREE_TYPE (t), 0));
16773 : 686 : protected_set_expr_location (c, expr_loc);
16774 : 686 : if (c == boolean_true_node)
16775 : : {
16776 : 18 : warning_at (expr_loc, 0,
16777 : : "%qs value must be positive",
16778 : 18 : omp_clause_code_name[code]);
16779 : 18 : t = integer_one_node;
16780 : : }
16781 : :
16782 : 686 : check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
16783 : :
16784 : 686 : c = build_omp_clause (loc, code);
16785 : 686 : OMP_CLAUSE_OPERAND (c, 0) = t;
16786 : 686 : OMP_CLAUSE_CHAIN (c) = list;
16787 : 686 : return c;
16788 : : }
16789 : :
16790 : : /* OpenACC:
16791 : :
16792 : : gang [( gang-arg-list )]
16793 : : worker [( [num:] int-expr )]
16794 : : vector [( [length:] int-expr )]
16795 : :
16796 : : where gang-arg is one of:
16797 : :
16798 : : [num:] int-expr
16799 : : static: size-expr
16800 : :
16801 : : and size-expr may be:
16802 : :
16803 : : *
16804 : : int-expr
16805 : : */
16806 : :
16807 : : static tree
16808 : 1487 : c_parser_oacc_shape_clause (c_parser *parser, location_t loc,
16809 : : omp_clause_code kind,
16810 : : const char *str, tree list)
16811 : : {
16812 : 1487 : const char *id = "num";
16813 : 1487 : tree ops[2] = { NULL_TREE, NULL_TREE }, c;
16814 : :
16815 : 1487 : if (kind == OMP_CLAUSE_VECTOR)
16816 : 495 : id = "length";
16817 : :
16818 : 1487 : if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
16819 : : {
16820 : 228 : c_parser_consume_token (parser);
16821 : :
16822 : 258 : do
16823 : : {
16824 : 243 : c_token *next = c_parser_peek_token (parser);
16825 : 243 : int idx = 0;
16826 : :
16827 : : /* Gang static argument. */
16828 : 243 : if (kind == OMP_CLAUSE_GANG
16829 : 375 : && c_parser_next_token_is_keyword (parser, RID_STATIC))
16830 : : {
16831 : 64 : c_parser_consume_token (parser);
16832 : :
16833 : 64 : if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
16834 : 12 : goto cleanup_error;
16835 : :
16836 : 64 : idx = 1;
16837 : 64 : if (ops[idx] != NULL_TREE)
16838 : : {
16839 : 0 : c_parser_error (parser, "too many %<static%> arguments");
16840 : 0 : goto cleanup_error;
16841 : : }
16842 : :
16843 : : /* Check for the '*' argument. */
16844 : 64 : if (c_parser_next_token_is (parser, CPP_MULT)
16845 : 64 : && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
16846 : 27 : || c_parser_peek_2nd_token (parser)->type
16847 : : == CPP_CLOSE_PAREN))
16848 : : {
16849 : 26 : c_parser_consume_token (parser);
16850 : 26 : ops[idx] = integer_minus_one_node;
16851 : :
16852 : 26 : if (c_parser_next_token_is (parser, CPP_COMMA))
16853 : : {
16854 : 1 : c_parser_consume_token (parser);
16855 : 1 : continue;
16856 : : }
16857 : : else
16858 : : break;
16859 : : }
16860 : : }
16861 : : /* Worker num: argument and vector length: arguments. */
16862 : 179 : else if (c_parser_next_token_is (parser, CPP_NAME)
16863 : 143 : && strcmp (id, IDENTIFIER_POINTER (next->value)) == 0
16864 : 306 : && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
16865 : : {
16866 : 121 : c_parser_consume_token (parser); /* id */
16867 : 121 : c_parser_consume_token (parser); /* ':' */
16868 : : }
16869 : :
16870 : : /* Now collect the actual argument. */
16871 : 217 : if (ops[idx] != NULL_TREE)
16872 : : {
16873 : 5 : c_parser_error (parser, "unexpected argument");
16874 : 5 : goto cleanup_error;
16875 : : }
16876 : :
16877 : 212 : location_t expr_loc = c_parser_peek_token (parser)->location;
16878 : 212 : c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
16879 : 212 : cexpr = convert_lvalue_to_rvalue (expr_loc, cexpr, false, true);
16880 : 212 : tree expr = cexpr.value;
16881 : 212 : if (expr == error_mark_node)
16882 : 7 : goto cleanup_error;
16883 : :
16884 : 205 : expr = c_fully_fold (expr, false, NULL);
16885 : :
16886 : : /* Attempt to statically determine when the number isn't a
16887 : : positive integer. */
16888 : :
16889 : 205 : if (!INTEGRAL_TYPE_P (TREE_TYPE (expr)))
16890 : : {
16891 : 14 : c_parser_error (parser, "expected integer expression");
16892 : 14 : return list;
16893 : : }
16894 : :
16895 : 191 : tree c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, expr,
16896 : 191 : build_int_cst (TREE_TYPE (expr), 0));
16897 : 191 : if (c == boolean_true_node)
16898 : : {
16899 : 1 : warning_at (loc, 0,
16900 : : "%qs value must be positive", str);
16901 : 1 : expr = integer_one_node;
16902 : : }
16903 : :
16904 : 191 : ops[idx] = expr;
16905 : :
16906 : 205 : if (kind == OMP_CLAUSE_GANG
16907 : 283 : && c_parser_next_token_is (parser, CPP_COMMA))
16908 : : {
16909 : 14 : c_parser_consume_token (parser);
16910 : 14 : continue;
16911 : : }
16912 : : break;
16913 : 15 : }
16914 : : while (1);
16915 : :
16916 : 202 : if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
16917 : 7 : goto cleanup_error;
16918 : : }
16919 : :
16920 : 1454 : check_no_duplicate_clause (list, kind, str);
16921 : :
16922 : 1454 : c = build_omp_clause (loc, kind);
16923 : :
16924 : 1454 : if (ops[1])
16925 : 61 : OMP_CLAUSE_OPERAND (c, 1) = ops[1];
16926 : :
16927 : 1454 : OMP_CLAUSE_OPERAND (c, 0) = ops[0];
16928 : 1454 : OMP_CLAUSE_CHAIN (c) = list;
16929 : :
16930 : 1454 : return c;
16931 : :
16932 : 19 : cleanup_error:
16933 : 19 : c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
16934 : 19 : return list;
16935 : : }
16936 : :
16937 : : /* OpenACC 2.5:
16938 : : auto
16939 : : finalize
16940 : : independent
16941 : : nohost
16942 : : seq */
16943 : :
16944 : : static tree
16945 : 454 : c_parser_oacc_simple_clause (location_t loc, enum omp_clause_code code,
16946 : : tree list)
16947 : : {
16948 : 454 : check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
16949 : :
16950 : 454 : tree c = build_omp_clause (loc, code);
16951 : 454 : OMP_CLAUSE_CHAIN (c) = list;
16952 : :
16953 : 454 : return c;
16954 : : }
16955 : :
16956 : : /* OpenACC:
16957 : : async [( int-expr )] */
16958 : :
16959 : : static tree
16960 : 236 : c_parser_oacc_clause_async (c_parser *parser, tree list)
16961 : : {
16962 : 236 : tree c, t;
16963 : 236 : location_t loc = c_parser_peek_token (parser)->location;
16964 : :
16965 : 236 : t = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL);
16966 : :
16967 : 236 : if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
16968 : : {
16969 : 185 : c_parser_consume_token (parser);
16970 : :
16971 : 185 : t = c_parser_expr_no_commas (parser, NULL).value;
16972 : 185 : if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
16973 : 9 : c_parser_error (parser, "expected integer expression");
16974 : 176 : else if (t == error_mark_node
16975 : 176 : || !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
16976 : 14 : return list;
16977 : : }
16978 : : else
16979 : 51 : t = c_fully_fold (t, false, NULL);
16980 : :
16981 : 222 : check_no_duplicate_clause (list, OMP_CLAUSE_ASYNC, "async");
16982 : :
16983 : 222 : c = build_omp_clause (loc, OMP_CLAUSE_ASYNC);
16984 : 222 : OMP_CLAUSE_ASYNC_EXPR (c) = t;
16985 : 222 : OMP_CLAUSE_CHAIN (c) = list;
16986 : 222 : list = c;
16987 : :
16988 : 222 : return list;
16989 : : }
16990 : :
16991 : : /* OpenACC 2.0:
16992 : : tile ( size-expr-list ) */
16993 : :
16994 : : static tree
16995 : 122 : c_parser_oacc_clause_tile (c_parser *parser, tree list)
16996 : : {
16997 : 122 : tree c, expr = error_mark_node;
16998 : 122 : location_t loc;
16999 : 122 : tree tile = NULL_TREE;
17000 : :
17001 : 122 : check_no_duplicate_clause (list, OMP_CLAUSE_TILE, "tile");
17002 : 122 : check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse");
17003 : :
17004 : 122 : loc = c_parser_peek_token (parser)->location;
17005 : 122 : if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
17006 : : return list;
17007 : :
17008 : 161 : do
17009 : : {
17010 : 161 : if (tile && !c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
17011 : : return list;
17012 : :
17013 : 161 : if (c_parser_next_token_is (parser, CPP_MULT)
17014 : 161 : && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
17015 : 53 : || c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_PAREN))
17016 : : {
17017 : 60 : c_parser_consume_token (parser);
17018 : 60 : expr = integer_zero_node;
17019 : : }
17020 : : else
17021 : : {
17022 : 101 : location_t expr_loc = c_parser_peek_token (parser)->location;
17023 : 101 : c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
17024 : 101 : cexpr = convert_lvalue_to_rvalue (expr_loc, cexpr, false, true);
17025 : 101 : expr = cexpr.value;
17026 : :
17027 : 101 : if (expr == error_mark_node)
17028 : : {
17029 : 7 : c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
17030 : : "expected %<)%>");
17031 : 7 : return list;
17032 : : }
17033 : :
17034 : 94 : expr = c_fully_fold (expr, false, NULL);
17035 : :
17036 : 188 : if (!INTEGRAL_TYPE_P (TREE_TYPE (expr))
17037 : 93 : || !tree_fits_shwi_p (expr)
17038 : 179 : || tree_to_shwi (expr) <= 0)
17039 : : {
17040 : 16 : error_at (expr_loc, "%<tile%> argument needs positive"
17041 : : " integral constant");
17042 : 16 : expr = integer_zero_node;
17043 : : }
17044 : : }
17045 : :
17046 : 154 : tile = tree_cons (NULL_TREE, expr, tile);
17047 : : }
17048 : 154 : while (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN));
17049 : :
17050 : : /* Consume the trailing ')'. */
17051 : 110 : c_parser_consume_token (parser);
17052 : :
17053 : 110 : c = build_omp_clause (loc, OMP_CLAUSE_TILE);
17054 : 110 : tile = nreverse (tile);
17055 : 110 : OMP_CLAUSE_TILE_LIST (c) = tile;
17056 : 110 : OMP_CLAUSE_CHAIN (c) = list;
17057 : 110 : return c;
17058 : : }
17059 : :
17060 : : /* OpenACC:
17061 : : wait [( int-expr-list )] */
17062 : :
17063 : : static tree
17064 : 89 : c_parser_oacc_clause_wait (c_parser *parser, tree list)
17065 : : {
17066 : 89 : location_t clause_loc = c_parser_peek_token (parser)->location;
17067 : :
17068 : 89 : if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
17069 : 74 : list = c_parser_oacc_wait_list (parser, clause_loc, list);
17070 : : else
17071 : : {
17072 : 15 : tree c = build_omp_clause (clause_loc, OMP_CLAUSE_WAIT);
17073 : :
17074 : 15 : OMP_CLAUSE_DECL (c) = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL);
17075 : 15 : OMP_CLAUSE_CHAIN (c) = list;
17076 : 15 : list = c;
17077 : : }
17078 : :
17079 : 89 : return list;
17080 : : }
17081 : :
17082 : : /* OpenACC 2.7:
17083 : : self [( expression )] */
17084 : :
17085 : : static tree
17086 : 48 : c_parser_oacc_compute_clause_self (c_parser *parser, tree list)
17087 : : {
17088 : 48 : tree t;
17089 : 48 : location_t location = c_parser_peek_token (parser)->location;
17090 : 48 : if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
17091 : : {
17092 : 42 : matching_parens parens;
17093 : 42 : parens.consume_open (parser);
17094 : :
17095 : 42 : location_t loc = c_parser_peek_token (parser)->location;
17096 : 42 : c_expr expr = c_parser_expr_no_commas (parser, NULL);
17097 : 42 : expr = convert_lvalue_to_rvalue (loc, expr, true, true);
17098 : 42 : t = c_objc_common_truthvalue_conversion (loc, expr.value);
17099 : 42 : t = c_fully_fold (t, false, NULL);
17100 : 42 : parens.skip_until_found_close (parser);
17101 : : }
17102 : : else
17103 : 6 : t = truthvalue_true_node;
17104 : :
17105 : 78 : for (tree c = list; c; c = OMP_CLAUSE_CHAIN (c))
17106 : 36 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SELF)
17107 : : {
17108 : 6 : error_at (location, "too many %<self%> clauses");
17109 : 6 : return list;
17110 : : }
17111 : :
17112 : 42 : tree c = build_omp_clause (location, OMP_CLAUSE_SELF);
17113 : 42 : OMP_CLAUSE_SELF_EXPR (c) = t;
17114 : 42 : OMP_CLAUSE_CHAIN (c) = list;
17115 : 42 : return c;
17116 : : }
17117 : :
17118 : : /* OpenMP 5.0:
17119 : : order ( concurrent )
17120 : :
17121 : : OpenMP 5.1:
17122 : : order ( order-modifier : concurrent )
17123 : :
17124 : : order-modifier:
17125 : : reproducible
17126 : : unconstrained */
17127 : :
17128 : : static tree
17129 : 375 : c_parser_omp_clause_order (c_parser *parser, tree list)
17130 : : {
17131 : 375 : location_t loc = c_parser_peek_token (parser)->location;
17132 : 375 : tree c;
17133 : 375 : const char *p;
17134 : 375 : bool unconstrained = false;
17135 : 375 : bool reproducible = false;
17136 : :
17137 : 375 : matching_parens parens;
17138 : 375 : if (!parens.require_open (parser))
17139 : : return list;
17140 : 373 : if (c_parser_next_token_is (parser, CPP_NAME)
17141 : 373 : && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
17142 : : {
17143 : 107 : p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17144 : 107 : if (strcmp (p, "unconstrained") == 0)
17145 : : unconstrained = true;
17146 : 56 : else if (strcmp (p, "reproducible") == 0)
17147 : : reproducible = true;
17148 : : else
17149 : : {
17150 : 1 : c_parser_error (parser, "expected %<reproducible%> or "
17151 : : "%<unconstrained%>");
17152 : 1 : goto out_err;
17153 : : }
17154 : 106 : c_parser_consume_token (parser);
17155 : 106 : c_parser_consume_token (parser);
17156 : : }
17157 : 372 : if (!c_parser_next_token_is (parser, CPP_NAME))
17158 : : {
17159 : 0 : c_parser_error (parser, "expected %<concurrent%>");
17160 : 0 : goto out_err;
17161 : : }
17162 : 372 : p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17163 : 372 : if (strcmp (p, "concurrent") != 0)
17164 : : {
17165 : 1 : c_parser_error (parser, "expected %<concurrent%>");
17166 : 1 : goto out_err;
17167 : : }
17168 : 371 : c_parser_consume_token (parser);
17169 : 371 : parens.skip_until_found_close (parser);
17170 : 371 : check_no_duplicate_clause (list, OMP_CLAUSE_ORDER, "order");
17171 : 371 : c = build_omp_clause (loc, OMP_CLAUSE_ORDER);
17172 : 371 : OMP_CLAUSE_ORDER_UNCONSTRAINED (c) = unconstrained;
17173 : 371 : OMP_CLAUSE_ORDER_REPRODUCIBLE (c) = reproducible;
17174 : 371 : OMP_CLAUSE_CHAIN (c) = list;
17175 : 371 : return c;
17176 : :
17177 : 2 : out_err:
17178 : 2 : parens.skip_until_found_close (parser);
17179 : 2 : return list;
17180 : : }
17181 : :
17182 : :
17183 : : /* OpenMP 5.0:
17184 : : bind ( teams | parallel | thread ) */
17185 : :
17186 : : static tree
17187 : 115 : c_parser_omp_clause_bind (c_parser *parser, tree list)
17188 : : {
17189 : 115 : location_t loc = c_parser_peek_token (parser)->location;
17190 : 115 : tree c;
17191 : 115 : const char *p;
17192 : 115 : enum omp_clause_bind_kind kind = OMP_CLAUSE_BIND_THREAD;
17193 : :
17194 : 115 : matching_parens parens;
17195 : 115 : if (!parens.require_open (parser))
17196 : : return list;
17197 : 113 : if (!c_parser_next_token_is (parser, CPP_NAME))
17198 : : {
17199 : 3 : invalid:
17200 : 4 : c_parser_error (parser,
17201 : : "expected %<teams%>, %<parallel%> or %<thread%>");
17202 : 4 : parens.skip_until_found_close (parser);
17203 : 4 : return list;
17204 : : }
17205 : 110 : p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17206 : 110 : if (strcmp (p, "teams") == 0)
17207 : : kind = OMP_CLAUSE_BIND_TEAMS;
17208 : 72 : else if (strcmp (p, "parallel") == 0)
17209 : : kind = OMP_CLAUSE_BIND_PARALLEL;
17210 : 35 : else if (strcmp (p, "thread") != 0)
17211 : 1 : goto invalid;
17212 : 109 : c_parser_consume_token (parser);
17213 : 109 : parens.skip_until_found_close (parser);
17214 : : /* check_no_duplicate_clause (list, OMP_CLAUSE_BIND, "bind"); */
17215 : 109 : c = build_omp_clause (loc, OMP_CLAUSE_BIND);
17216 : 109 : OMP_CLAUSE_BIND_KIND (c) = kind;
17217 : 109 : OMP_CLAUSE_CHAIN (c) = list;
17218 : 109 : return c;
17219 : : }
17220 : :
17221 : :
17222 : : /* OpenMP 2.5:
17223 : : ordered
17224 : :
17225 : : OpenMP 4.5:
17226 : : ordered ( constant-expression ) */
17227 : :
17228 : : static tree
17229 : 291 : c_parser_omp_clause_ordered (c_parser *parser, tree list)
17230 : : {
17231 : 291 : check_no_duplicate_clause (list, OMP_CLAUSE_ORDERED, "ordered");
17232 : :
17233 : 291 : tree c, num = NULL_TREE;
17234 : 291 : HOST_WIDE_INT n;
17235 : 291 : location_t loc = c_parser_peek_token (parser)->location;
17236 : 291 : if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
17237 : : {
17238 : 160 : matching_parens parens;
17239 : 160 : parens.consume_open (parser);
17240 : 160 : num = c_parser_expr_no_commas (parser, NULL).value;
17241 : 160 : parens.skip_until_found_close (parser);
17242 : : }
17243 : 291 : if (num == error_mark_node)
17244 : : return list;
17245 : 291 : if (num)
17246 : : {
17247 : 160 : mark_exp_read (num);
17248 : 160 : num = c_fully_fold (num, false, NULL);
17249 : 320 : if (!INTEGRAL_TYPE_P (TREE_TYPE (num))
17250 : 160 : || !tree_fits_shwi_p (num)
17251 : 160 : || (n = tree_to_shwi (num)) <= 0
17252 : 320 : || (int) n != n)
17253 : : {
17254 : 0 : error_at (loc, "ordered argument needs positive "
17255 : : "constant integer expression");
17256 : 0 : return list;
17257 : : }
17258 : : }
17259 : 291 : c = build_omp_clause (loc, OMP_CLAUSE_ORDERED);
17260 : 291 : OMP_CLAUSE_ORDERED_EXPR (c) = num;
17261 : 291 : OMP_CLAUSE_CHAIN (c) = list;
17262 : 291 : return c;
17263 : : }
17264 : :
17265 : : /* OpenMP 2.5:
17266 : : private ( variable-list ) */
17267 : :
17268 : : static tree
17269 : 716 : c_parser_omp_clause_private (c_parser *parser, tree list)
17270 : : {
17271 : 0 : return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_PRIVATE, list);
17272 : : }
17273 : :
17274 : : /* OpenMP 2.5:
17275 : : reduction ( reduction-operator : variable-list )
17276 : :
17277 : : reduction-operator:
17278 : : One of: + * - & ^ | && ||
17279 : :
17280 : : OpenMP 3.1:
17281 : :
17282 : : reduction-operator:
17283 : : One of: + * - & ^ | && || max min
17284 : :
17285 : : OpenMP 4.0:
17286 : :
17287 : : reduction-operator:
17288 : : One of: + * - & ^ | && ||
17289 : : identifier
17290 : :
17291 : : OpenMP 5.0:
17292 : : reduction ( reduction-modifier, reduction-operator : variable-list )
17293 : : in_reduction ( reduction-operator : variable-list )
17294 : : task_reduction ( reduction-operator : variable-list ) */
17295 : :
17296 : : static tree
17297 : 2867 : c_parser_omp_clause_reduction (c_parser *parser, enum omp_clause_code kind,
17298 : : bool is_omp, tree list)
17299 : : {
17300 : 2867 : location_t clause_loc = c_parser_peek_token (parser)->location;
17301 : 2867 : matching_parens parens;
17302 : 2867 : if (parens.require_open (parser))
17303 : : {
17304 : 2867 : bool task = false;
17305 : 2867 : bool inscan = false;
17306 : 2867 : enum tree_code code = ERROR_MARK;
17307 : 2867 : tree reduc_id = NULL_TREE;
17308 : :
17309 : 2867 : if (kind == OMP_CLAUSE_REDUCTION && is_omp)
17310 : : {
17311 : 1761 : if (c_parser_next_token_is_keyword (parser, RID_DEFAULT)
17312 : 1761 : && c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
17313 : : {
17314 : 86 : c_parser_consume_token (parser);
17315 : 86 : c_parser_consume_token (parser);
17316 : : }
17317 : 1675 : else if (c_parser_next_token_is (parser, CPP_NAME)
17318 : 1675 : && c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
17319 : : {
17320 : 461 : const char *p
17321 : 461 : = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17322 : 461 : if (strcmp (p, "task") == 0)
17323 : : task = true;
17324 : 281 : else if (strcmp (p, "inscan") == 0)
17325 : 281 : inscan = true;
17326 : 461 : if (task || inscan)
17327 : : {
17328 : 461 : c_parser_consume_token (parser);
17329 : 461 : c_parser_consume_token (parser);
17330 : : }
17331 : : }
17332 : : }
17333 : :
17334 : 2867 : switch (c_parser_peek_token (parser)->type)
17335 : : {
17336 : : case CPP_PLUS:
17337 : : code = PLUS_EXPR;
17338 : : break;
17339 : 240 : case CPP_MULT:
17340 : 240 : code = MULT_EXPR;
17341 : 240 : break;
17342 : 105 : case CPP_MINUS:
17343 : 105 : code = MINUS_EXPR;
17344 : 105 : break;
17345 : 25 : case CPP_AND:
17346 : 25 : code = BIT_AND_EXPR;
17347 : 25 : break;
17348 : 12 : case CPP_XOR:
17349 : 12 : code = BIT_XOR_EXPR;
17350 : 12 : break;
17351 : 80 : case CPP_OR:
17352 : 80 : code = BIT_IOR_EXPR;
17353 : 80 : break;
17354 : 65 : case CPP_AND_AND:
17355 : 65 : code = TRUTH_ANDIF_EXPR;
17356 : 65 : break;
17357 : 76 : case CPP_OR_OR:
17358 : 76 : code = TRUTH_ORIF_EXPR;
17359 : 76 : break;
17360 : 245 : case CPP_NAME:
17361 : 245 : {
17362 : 245 : const char *p
17363 : 245 : = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17364 : 245 : if (strcmp (p, "min") == 0)
17365 : : {
17366 : : code = MIN_EXPR;
17367 : : break;
17368 : : }
17369 : 207 : if (strcmp (p, "max") == 0)
17370 : : {
17371 : : code = MAX_EXPR;
17372 : : break;
17373 : : }
17374 : 130 : reduc_id = c_parser_peek_token (parser)->value;
17375 : 130 : break;
17376 : : }
17377 : 0 : default:
17378 : 0 : c_parser_error (parser,
17379 : : "expected %<+%>, %<*%>, %<-%>, %<&%>, "
17380 : : "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
17381 : 0 : c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
17382 : 0 : return list;
17383 : : }
17384 : 2867 : c_parser_consume_token (parser);
17385 : 2867 : reduc_id = c_omp_reduction_id (code, reduc_id);
17386 : 2867 : if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
17387 : : {
17388 : 2867 : tree nl, c;
17389 : :
17390 : 2867 : nl = c_parser_omp_variable_list (parser, clause_loc, kind, list);
17391 : 6329 : for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
17392 : : {
17393 : 3462 : tree d = OMP_CLAUSE_DECL (c), type;
17394 : 3462 : if (TREE_CODE (d) != OMP_ARRAY_SECTION)
17395 : 2943 : type = TREE_TYPE (d);
17396 : : else
17397 : : {
17398 : : int cnt = 0;
17399 : : tree t;
17400 : 636 : for (t = d;
17401 : 1155 : TREE_CODE (t) == OMP_ARRAY_SECTION;
17402 : 636 : t = TREE_OPERAND (t, 0))
17403 : 636 : cnt++;
17404 : 519 : type = TREE_TYPE (t);
17405 : 1153 : while (cnt > 0)
17406 : : {
17407 : 636 : if (TREE_CODE (type) != POINTER_TYPE
17408 : 399 : && TREE_CODE (type) != ARRAY_TYPE)
17409 : : break;
17410 : 634 : type = TREE_TYPE (type);
17411 : 634 : cnt--;
17412 : : }
17413 : : }
17414 : 3555 : while (TREE_CODE (type) == ARRAY_TYPE)
17415 : 93 : type = TREE_TYPE (type);
17416 : 3462 : OMP_CLAUSE_REDUCTION_CODE (c) = code;
17417 : 3462 : if (task)
17418 : 212 : OMP_CLAUSE_REDUCTION_TASK (c) = 1;
17419 : 3250 : else if (inscan)
17420 : 396 : OMP_CLAUSE_REDUCTION_INSCAN (c) = 1;
17421 : 3462 : if (code == ERROR_MARK
17422 : 215 : || !(INTEGRAL_TYPE_P (type)
17423 : 3322 : || SCALAR_FLOAT_TYPE_P (type)
17424 : : || TREE_CODE (type) == COMPLEX_TYPE))
17425 : 273 : OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)
17426 : 546 : = c_omp_reduction_lookup (reduc_id,
17427 : 273 : TYPE_MAIN_VARIANT (type));
17428 : : }
17429 : :
17430 : : list = nl;
17431 : : }
17432 : 2867 : parens.skip_until_found_close (parser);
17433 : : }
17434 : : return list;
17435 : : }
17436 : :
17437 : : /* OpenMP 2.5:
17438 : : schedule ( schedule-kind )
17439 : : schedule ( schedule-kind , expression )
17440 : :
17441 : : schedule-kind:
17442 : : static | dynamic | guided | runtime | auto
17443 : :
17444 : : OpenMP 4.5:
17445 : : schedule ( schedule-modifier : schedule-kind )
17446 : : schedule ( schedule-modifier [ , schedule-modifier ] : schedule-kind , expression )
17447 : :
17448 : : schedule-modifier:
17449 : : simd
17450 : : monotonic
17451 : : nonmonotonic */
17452 : :
17453 : : static tree
17454 : 3451 : c_parser_omp_clause_schedule (c_parser *parser, tree list)
17455 : : {
17456 : 3451 : tree c, t;
17457 : 3451 : location_t loc = c_parser_peek_token (parser)->location;
17458 : 3451 : int modifiers = 0, nmodifiers = 0;
17459 : :
17460 : 3451 : matching_parens parens;
17461 : 3451 : if (!parens.require_open (parser))
17462 : : return list;
17463 : :
17464 : 3449 : c = build_omp_clause (loc, OMP_CLAUSE_SCHEDULE);
17465 : :
17466 : 3449 : location_t comma = UNKNOWN_LOCATION;
17467 : 6912 : while (c_parser_next_token_is (parser, CPP_NAME))
17468 : : {
17469 : 1770 : tree kind = c_parser_peek_token (parser)->value;
17470 : 1770 : const char *p = IDENTIFIER_POINTER (kind);
17471 : 1770 : if (strcmp ("simd", p) == 0)
17472 : 27 : OMP_CLAUSE_SCHEDULE_SIMD (c) = 1;
17473 : 1743 : else if (strcmp ("monotonic", p) == 0)
17474 : 74 : modifiers |= OMP_CLAUSE_SCHEDULE_MONOTONIC;
17475 : 1669 : else if (strcmp ("nonmonotonic", p) == 0)
17476 : 84 : modifiers |= OMP_CLAUSE_SCHEDULE_NONMONOTONIC;
17477 : : else
17478 : : break;
17479 : 185 : comma = UNKNOWN_LOCATION;
17480 : 185 : c_parser_consume_token (parser);
17481 : 185 : if (nmodifiers++ == 0
17482 : 359 : && c_parser_next_token_is (parser, CPP_COMMA))
17483 : : {
17484 : 14 : comma = c_parser_peek_token (parser)->location;
17485 : 14 : c_parser_consume_token (parser);
17486 : : }
17487 : : else
17488 : : {
17489 : 171 : c_parser_require (parser, CPP_COLON, "expected %<:%>");
17490 : 171 : break;
17491 : : }
17492 : : }
17493 : 3449 : if (comma != UNKNOWN_LOCATION)
17494 : 3 : error_at (comma, "expected %<:%>");
17495 : :
17496 : 3449 : if ((modifiers & (OMP_CLAUSE_SCHEDULE_MONOTONIC
17497 : : | OMP_CLAUSE_SCHEDULE_NONMONOTONIC))
17498 : : == (OMP_CLAUSE_SCHEDULE_MONOTONIC
17499 : : | OMP_CLAUSE_SCHEDULE_NONMONOTONIC))
17500 : : {
17501 : 2 : error_at (loc, "both %<monotonic%> and %<nonmonotonic%> modifiers "
17502 : : "specified");
17503 : 2 : modifiers = 0;
17504 : : }
17505 : :
17506 : 3449 : if (c_parser_next_token_is (parser, CPP_NAME))
17507 : : {
17508 : 1700 : tree kind = c_parser_peek_token (parser)->value;
17509 : 1700 : const char *p = IDENTIFIER_POINTER (kind);
17510 : :
17511 : 1700 : switch (p[0])
17512 : : {
17513 : 167 : case 'd':
17514 : 167 : if (strcmp ("dynamic", p) != 0)
17515 : 0 : goto invalid_kind;
17516 : 167 : OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_DYNAMIC;
17517 : 167 : break;
17518 : :
17519 : 755 : case 'g':
17520 : 755 : if (strcmp ("guided", p) != 0)
17521 : 0 : goto invalid_kind;
17522 : 755 : OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_GUIDED;
17523 : 755 : break;
17524 : :
17525 : 777 : case 'r':
17526 : 777 : if (strcmp ("runtime", p) != 0)
17527 : 0 : goto invalid_kind;
17528 : 777 : OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_RUNTIME;
17529 : 777 : break;
17530 : :
17531 : 1 : default:
17532 : 1 : goto invalid_kind;
17533 : : }
17534 : : }
17535 : 1749 : else if (c_parser_next_token_is_keyword (parser, RID_STATIC))
17536 : 1068 : OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_STATIC;
17537 : 681 : else if (c_parser_next_token_is_keyword (parser, RID_AUTO))
17538 : 680 : OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_AUTO;
17539 : : else
17540 : 1 : goto invalid_kind;
17541 : :
17542 : 3447 : c_parser_consume_token (parser);
17543 : 3447 : if (c_parser_next_token_is (parser, CPP_COMMA))
17544 : : {
17545 : 1791 : location_t here;
17546 : 1791 : c_parser_consume_token (parser);
17547 : :
17548 : 1791 : here = c_parser_peek_token (parser)->location;
17549 : 1791 : c_expr expr = c_parser_expr_no_commas (parser, NULL);
17550 : 1791 : expr = convert_lvalue_to_rvalue (here, expr, false, true);
17551 : 1791 : t = expr.value;
17552 : 1791 : t = c_fully_fold (t, false, NULL);
17553 : :
17554 : 1791 : if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_RUNTIME)
17555 : 1 : error_at (here, "schedule %<runtime%> does not take "
17556 : : "a %<chunk_size%> parameter");
17557 : 1790 : else if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_AUTO)
17558 : 0 : error_at (here,
17559 : : "schedule %<auto%> does not take "
17560 : : "a %<chunk_size%> parameter");
17561 : 1790 : else if (TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE
17562 : 1790 : || TREE_CODE (TREE_TYPE (t)) == BITINT_TYPE)
17563 : : {
17564 : : /* Attempt to statically determine when the number isn't
17565 : : positive. */
17566 : 1789 : tree s = fold_build2_loc (loc, LE_EXPR, boolean_type_node, t,
17567 : 1789 : build_int_cst (TREE_TYPE (t), 0));
17568 : 1789 : protected_set_expr_location (s, loc);
17569 : 1789 : if (s == boolean_true_node)
17570 : : {
17571 : 2 : warning_at (loc, OPT_Wopenmp,
17572 : : "chunk size value must be positive");
17573 : 2 : t = integer_one_node;
17574 : : }
17575 : 1789 : OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = t;
17576 : : }
17577 : : else
17578 : 1 : c_parser_error (parser, "expected integer expression");
17579 : :
17580 : 1791 : parens.skip_until_found_close (parser);
17581 : : }
17582 : : else
17583 : 1656 : c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
17584 : : "expected %<,%> or %<)%>");
17585 : :
17586 : 6894 : OMP_CLAUSE_SCHEDULE_KIND (c)
17587 : 6894 : = (enum omp_clause_schedule_kind)
17588 : 3447 : (OMP_CLAUSE_SCHEDULE_KIND (c) | modifiers);
17589 : :
17590 : 3447 : check_no_duplicate_clause (list, OMP_CLAUSE_SCHEDULE, "schedule");
17591 : 3447 : OMP_CLAUSE_CHAIN (c) = list;
17592 : 3447 : return c;
17593 : :
17594 : 2 : invalid_kind:
17595 : 2 : c_parser_error (parser, "invalid schedule kind");
17596 : 2 : c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
17597 : 2 : return list;
17598 : : }
17599 : :
17600 : : /* OpenMP 2.5:
17601 : : shared ( variable-list ) */
17602 : :
17603 : : static tree
17604 : 689 : c_parser_omp_clause_shared (c_parser *parser, tree list)
17605 : : {
17606 : 0 : return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_SHARED, list);
17607 : : }
17608 : :
17609 : : /* OpenMP 3.0:
17610 : : untied */
17611 : :
17612 : : static tree
17613 : 96 : c_parser_omp_clause_untied (c_parser *parser ATTRIBUTE_UNUSED, tree list)
17614 : : {
17615 : 96 : tree c;
17616 : :
17617 : : /* FIXME: Should we allow duplicates? */
17618 : 96 : check_no_duplicate_clause (list, OMP_CLAUSE_UNTIED, "untied");
17619 : :
17620 : 96 : c = build_omp_clause (c_parser_peek_token (parser)->location,
17621 : : OMP_CLAUSE_UNTIED);
17622 : 96 : OMP_CLAUSE_CHAIN (c) = list;
17623 : :
17624 : 96 : return c;
17625 : : }
17626 : :
17627 : : /* OpenMP 4.0:
17628 : : inbranch
17629 : : notinbranch */
17630 : :
17631 : : static tree
17632 : 196 : c_parser_omp_clause_branch (c_parser *parser ATTRIBUTE_UNUSED,
17633 : : enum omp_clause_code code, tree list)
17634 : : {
17635 : 196 : check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
17636 : :
17637 : 196 : tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
17638 : 196 : OMP_CLAUSE_CHAIN (c) = list;
17639 : :
17640 : 196 : return c;
17641 : : }
17642 : :
17643 : : /* OpenMP 4.0:
17644 : : parallel
17645 : : for
17646 : : sections
17647 : : taskgroup */
17648 : :
17649 : : static tree
17650 : 379 : c_parser_omp_clause_cancelkind (c_parser *parser ATTRIBUTE_UNUSED,
17651 : : enum omp_clause_code code, tree list)
17652 : : {
17653 : 379 : tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
17654 : 379 : OMP_CLAUSE_CHAIN (c) = list;
17655 : :
17656 : 379 : return c;
17657 : : }
17658 : :
17659 : : /* OpenMP 4.5:
17660 : : nogroup */
17661 : :
17662 : : static tree
17663 : 18 : c_parser_omp_clause_nogroup (c_parser *parser ATTRIBUTE_UNUSED, tree list)
17664 : : {
17665 : 18 : check_no_duplicate_clause (list, OMP_CLAUSE_NOGROUP, "nogroup");
17666 : 18 : tree c = build_omp_clause (c_parser_peek_token (parser)->location,
17667 : : OMP_CLAUSE_NOGROUP);
17668 : 18 : OMP_CLAUSE_CHAIN (c) = list;
17669 : 18 : return c;
17670 : : }
17671 : :
17672 : : /* OpenMP 4.5:
17673 : : simd
17674 : : threads */
17675 : :
17676 : : static tree
17677 : 97 : c_parser_omp_clause_orderedkind (c_parser *parser ATTRIBUTE_UNUSED,
17678 : : enum omp_clause_code code, tree list)
17679 : : {
17680 : 97 : check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
17681 : 97 : tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
17682 : 97 : OMP_CLAUSE_CHAIN (c) = list;
17683 : 97 : return c;
17684 : : }
17685 : :
17686 : : /* OpenMP 4.0:
17687 : : num_teams ( expression )
17688 : :
17689 : : OpenMP 5.1:
17690 : : num_teams ( expression : expression ) */
17691 : :
17692 : : static tree
17693 : 190 : c_parser_omp_clause_num_teams (c_parser *parser, tree list)
17694 : : {
17695 : 190 : location_t num_teams_loc = c_parser_peek_token (parser)->location;
17696 : 190 : matching_parens parens;
17697 : 190 : if (parens.require_open (parser))
17698 : : {
17699 : 190 : location_t upper_loc = c_parser_peek_token (parser)->location;
17700 : 190 : location_t lower_loc = UNKNOWN_LOCATION;
17701 : 190 : c_expr expr = c_parser_expr_no_commas (parser, NULL);
17702 : 190 : expr = convert_lvalue_to_rvalue (upper_loc, expr, false, true);
17703 : 190 : tree c, upper = expr.value, lower = NULL_TREE;
17704 : 190 : upper = c_fully_fold (upper, false, NULL);
17705 : :
17706 : 190 : if (c_parser_next_token_is (parser, CPP_COLON))
17707 : : {
17708 : 51 : c_parser_consume_token (parser);
17709 : 51 : lower_loc = upper_loc;
17710 : 51 : lower = upper;
17711 : 51 : upper_loc = c_parser_peek_token (parser)->location;
17712 : 51 : expr = c_parser_expr_no_commas (parser, NULL);
17713 : 51 : expr = convert_lvalue_to_rvalue (upper_loc, expr, false, true);
17714 : 51 : upper = expr.value;
17715 : 51 : upper = c_fully_fold (upper, false, NULL);
17716 : : }
17717 : :
17718 : 190 : parens.skip_until_found_close (parser);
17719 : :
17720 : 380 : if (!INTEGRAL_TYPE_P (TREE_TYPE (upper))
17721 : 380 : || (lower && !INTEGRAL_TYPE_P (TREE_TYPE (lower))))
17722 : : {
17723 : 0 : c_parser_error (parser, "expected integer expression");
17724 : 0 : return list;
17725 : : }
17726 : :
17727 : : /* Attempt to statically determine when the number isn't positive. */
17728 : 190 : c = fold_build2_loc (upper_loc, LE_EXPR, boolean_type_node, upper,
17729 : 190 : build_int_cst (TREE_TYPE (upper), 0));
17730 : 190 : protected_set_expr_location (c, upper_loc);
17731 : 190 : if (c == boolean_true_node)
17732 : : {
17733 : 4 : warning_at (upper_loc, OPT_Wopenmp,
17734 : : "%<num_teams%> value must be positive");
17735 : 4 : upper = integer_one_node;
17736 : : }
17737 : 190 : if (lower)
17738 : : {
17739 : 51 : c = fold_build2_loc (lower_loc, LE_EXPR, boolean_type_node, lower,
17740 : 51 : build_int_cst (TREE_TYPE (lower), 0));
17741 : 51 : protected_set_expr_location (c, lower_loc);
17742 : 51 : if (c == boolean_true_node)
17743 : : {
17744 : 2 : warning_at (lower_loc, OPT_Wopenmp,
17745 : : "%<num_teams%> value must be positive");
17746 : 2 : lower = NULL_TREE;
17747 : : }
17748 : 49 : else if (TREE_CODE (lower) == INTEGER_CST
17749 : 7 : && TREE_CODE (upper) == INTEGER_CST
17750 : 54 : && tree_int_cst_lt (upper, lower))
17751 : : {
17752 : 2 : warning_at (lower_loc, OPT_Wopenmp,
17753 : : "%<num_teams%> lower bound %qE bigger than upper "
17754 : : "bound %qE", lower, upper);
17755 : 2 : lower = NULL_TREE;
17756 : : }
17757 : : }
17758 : :
17759 : 190 : check_no_duplicate_clause (list, OMP_CLAUSE_NUM_TEAMS, "num_teams");
17760 : :
17761 : 190 : c = build_omp_clause (num_teams_loc, OMP_CLAUSE_NUM_TEAMS);
17762 : 190 : OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (c) = upper;
17763 : 190 : OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c) = lower;
17764 : 190 : OMP_CLAUSE_CHAIN (c) = list;
17765 : 190 : list = c;
17766 : : }
17767 : :
17768 : : return list;
17769 : : }
17770 : :
17771 : : /* OpenMP 4.0:
17772 : : thread_limit ( expression ) */
17773 : :
17774 : : static tree
17775 : 154 : c_parser_omp_clause_thread_limit (c_parser *parser, tree list)
17776 : : {
17777 : 154 : location_t num_thread_limit_loc = c_parser_peek_token (parser)->location;
17778 : 154 : matching_parens parens;
17779 : 154 : if (parens.require_open (parser))
17780 : : {
17781 : 154 : location_t expr_loc = c_parser_peek_token (parser)->location;
17782 : 154 : c_expr expr = c_parser_expr_no_commas (parser, NULL);
17783 : 154 : expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
17784 : 154 : tree c, t = expr.value;
17785 : 154 : t = c_fully_fold (t, false, NULL);
17786 : :
17787 : 154 : parens.skip_until_found_close (parser);
17788 : :
17789 : 154 : if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
17790 : : {
17791 : 0 : c_parser_error (parser, "expected integer expression");
17792 : 0 : return list;
17793 : : }
17794 : :
17795 : : /* Attempt to statically determine when the number isn't positive. */
17796 : 154 : c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
17797 : 154 : build_int_cst (TREE_TYPE (t), 0));
17798 : 154 : protected_set_expr_location (c, expr_loc);
17799 : 154 : if (c == boolean_true_node)
17800 : : {
17801 : 0 : warning_at (expr_loc, OPT_Wopenmp,
17802 : : "%<thread_limit%> value must be positive");
17803 : 0 : t = integer_one_node;
17804 : : }
17805 : :
17806 : 154 : check_no_duplicate_clause (list, OMP_CLAUSE_THREAD_LIMIT,
17807 : : "thread_limit");
17808 : :
17809 : 154 : c = build_omp_clause (num_thread_limit_loc, OMP_CLAUSE_THREAD_LIMIT);
17810 : 154 : OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = t;
17811 : 154 : OMP_CLAUSE_CHAIN (c) = list;
17812 : 154 : list = c;
17813 : : }
17814 : :
17815 : : return list;
17816 : : }
17817 : :
17818 : : /* OpenMP 4.0:
17819 : : aligned ( variable-list )
17820 : : aligned ( variable-list : constant-expression ) */
17821 : :
17822 : : static tree
17823 : 228 : c_parser_omp_clause_aligned (c_parser *parser, tree list)
17824 : : {
17825 : 228 : location_t clause_loc = c_parser_peek_token (parser)->location;
17826 : 228 : tree nl, c;
17827 : :
17828 : 228 : matching_parens parens;
17829 : 228 : if (!parens.require_open (parser))
17830 : : return list;
17831 : :
17832 : 228 : nl = c_parser_omp_variable_list (parser, clause_loc,
17833 : : OMP_CLAUSE_ALIGNED, list);
17834 : :
17835 : 228 : if (c_parser_next_token_is (parser, CPP_COLON))
17836 : : {
17837 : 212 : c_parser_consume_token (parser);
17838 : 212 : location_t expr_loc = c_parser_peek_token (parser)->location;
17839 : 212 : c_expr expr = c_parser_expr_no_commas (parser, NULL);
17840 : 212 : expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
17841 : 212 : tree alignment = expr.value;
17842 : 212 : alignment = c_fully_fold (alignment, false, NULL);
17843 : 212 : if (TREE_CODE (alignment) != INTEGER_CST
17844 : 210 : || !INTEGRAL_TYPE_P (TREE_TYPE (alignment))
17845 : 422 : || tree_int_cst_sgn (alignment) != 1)
17846 : : {
17847 : 4 : error_at (clause_loc, "%<aligned%> clause alignment expression must "
17848 : : "be positive constant integer expression");
17849 : 4 : alignment = NULL_TREE;
17850 : : }
17851 : :
17852 : 444 : for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
17853 : 232 : OMP_CLAUSE_ALIGNED_ALIGNMENT (c) = alignment;
17854 : : }
17855 : :
17856 : 228 : parens.skip_until_found_close (parser);
17857 : 228 : return nl;
17858 : : }
17859 : :
17860 : : /* OpenMP 5.0:
17861 : : allocate ( variable-list )
17862 : : allocate ( expression : variable-list )
17863 : :
17864 : : OpenMP 5.1:
17865 : : allocate ( allocator-modifier : variable-list )
17866 : : allocate ( allocator-modifier , allocator-modifier : variable-list )
17867 : :
17868 : : allocator-modifier:
17869 : : allocator ( expression )
17870 : : align ( expression ) */
17871 : :
17872 : : static tree
17873 : 462 : c_parser_omp_clause_allocate (c_parser *parser, tree list)
17874 : : {
17875 : 462 : location_t clause_loc = c_parser_peek_token (parser)->location;
17876 : 462 : tree nl, c;
17877 : 462 : tree allocator = NULL_TREE;
17878 : 462 : tree align = NULL_TREE;
17879 : :
17880 : 462 : matching_parens parens;
17881 : 462 : if (!parens.require_open (parser))
17882 : : return list;
17883 : :
17884 : 462 : if ((c_parser_next_token_is_not (parser, CPP_NAME)
17885 : 5 : && c_parser_next_token_is_not (parser, CPP_KEYWORD))
17886 : 462 : || (c_parser_peek_2nd_token (parser)->type != CPP_COMMA
17887 : 443 : && c_parser_peek_2nd_token (parser)->type != CPP_CLOSE_PAREN))
17888 : : {
17889 : 197 : bool has_modifiers = false;
17890 : 197 : tree orig_type = NULL_TREE;
17891 : 197 : if (c_parser_next_token_is (parser, CPP_NAME)
17892 : 197 : && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN)
17893 : : {
17894 : 61 : unsigned int n = 3;
17895 : 61 : const char *p
17896 : 61 : = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17897 : 29 : if ((strcmp (p, "allocator") == 0 || strcmp (p, "align") == 0)
17898 : 59 : && c_parser_check_balanced_raw_token_sequence (parser, &n)
17899 : 120 : && (c_parser_peek_nth_token_raw (parser, n)->type
17900 : : == CPP_CLOSE_PAREN))
17901 : : {
17902 : 59 : if (c_parser_peek_nth_token_raw (parser, n + 1)->type
17903 : : == CPP_COLON)
17904 : : has_modifiers = true;
17905 : 27 : else if (c_parser_peek_nth_token_raw (parser, n + 1)->type
17906 : : == CPP_COMMA
17907 : 27 : && (c_parser_peek_nth_token_raw (parser, n + 2)->type
17908 : : == CPP_NAME)
17909 : 54 : && (c_parser_peek_nth_token_raw (parser, n + 3)->type
17910 : : == CPP_OPEN_PAREN))
17911 : : {
17912 : 27 : c_token *tok = c_parser_peek_nth_token_raw (parser, n + 2);
17913 : 27 : const char *q = IDENTIFIER_POINTER (tok->value);
17914 : 27 : n += 4;
17915 : 27 : if ((strcmp (q, "allocator") == 0
17916 : 14 : || strcmp (q, "align") == 0)
17917 : 27 : && c_parser_check_balanced_raw_token_sequence (parser,
17918 : : &n)
17919 : 27 : && (c_parser_peek_nth_token_raw (parser, n)->type
17920 : : == CPP_CLOSE_PAREN)
17921 : 54 : && (c_parser_peek_nth_token_raw (parser, n + 1)->type
17922 : : == CPP_COLON))
17923 : : has_modifiers = true;
17924 : : }
17925 : : }
17926 : : if (has_modifiers)
17927 : : {
17928 : 59 : c_parser_consume_token (parser);
17929 : 59 : matching_parens parens2;;
17930 : 59 : parens2.require_open (parser);
17931 : 59 : location_t expr_loc = c_parser_peek_token (parser)->location;
17932 : 59 : c_expr expr = c_parser_expr_no_commas (parser, NULL);
17933 : 59 : expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
17934 : 59 : if (expr.value == error_mark_node)
17935 : : ;
17936 : 58 : else if (strcmp (p, "allocator") == 0)
17937 : : {
17938 : 31 : allocator = expr.value;
17939 : 31 : allocator = c_fully_fold (allocator, false, NULL);
17940 : 62 : orig_type = expr.original_type
17941 : 31 : ? expr.original_type : TREE_TYPE (allocator);
17942 : 31 : orig_type = TYPE_MAIN_VARIANT (orig_type);
17943 : : }
17944 : : else
17945 : : {
17946 : 27 : align = expr.value;
17947 : 27 : align = c_fully_fold (align, false, NULL);
17948 : : }
17949 : 59 : parens2.skip_until_found_close (parser);
17950 : 59 : if (c_parser_next_token_is (parser, CPP_COMMA))
17951 : : {
17952 : 27 : c_parser_consume_token (parser);
17953 : 27 : c_token *tok = c_parser_peek_token (parser);
17954 : 27 : const char *q = "";
17955 : 27 : if (c_parser_next_token_is (parser, CPP_NAME))
17956 : 27 : q = IDENTIFIER_POINTER (tok->value);
17957 : 27 : if (strcmp (q, "allocator") != 0 && strcmp (q, "align") != 0)
17958 : : {
17959 : 0 : c_parser_error (parser, "expected %<allocator%> or "
17960 : : "%<align%>");
17961 : 0 : parens.skip_until_found_close (parser);
17962 : 2 : return list;
17963 : : }
17964 : 27 : else if (strcmp (p, q) == 0)
17965 : : {
17966 : 2 : error_at (tok->location, "duplicate %qs modifier", p);
17967 : 2 : parens.skip_until_found_close (parser);
17968 : 2 : return list;
17969 : : }
17970 : 25 : c_parser_consume_token (parser);
17971 : 25 : if (!parens2.require_open (parser))
17972 : : {
17973 : 0 : parens.skip_until_found_close (parser);
17974 : 0 : return list;
17975 : : }
17976 : 25 : expr_loc = c_parser_peek_token (parser)->location;
17977 : 25 : expr = c_parser_expr_no_commas (parser, NULL);
17978 : 25 : expr = convert_lvalue_to_rvalue (expr_loc, expr, false,
17979 : : true);
17980 : 25 : if (strcmp (q, "allocator") == 0)
17981 : : {
17982 : 12 : allocator = expr.value;
17983 : 12 : allocator = c_fully_fold (allocator, false, NULL);
17984 : 24 : orig_type = expr.original_type
17985 : 12 : ? expr.original_type : TREE_TYPE (allocator);
17986 : 12 : orig_type = TYPE_MAIN_VARIANT (orig_type);
17987 : : }
17988 : : else
17989 : : {
17990 : 13 : align = expr.value;
17991 : 13 : align = c_fully_fold (align, false, NULL);
17992 : : }
17993 : 25 : parens2.skip_until_found_close (parser);
17994 : : }
17995 : : }
17996 : : }
17997 : 195 : if (!has_modifiers)
17998 : : {
17999 : 138 : location_t expr_loc = c_parser_peek_token (parser)->location;
18000 : 138 : c_expr expr = c_parser_expr_no_commas (parser, NULL);
18001 : 138 : expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
18002 : 138 : allocator = expr.value;
18003 : 138 : allocator = c_fully_fold (allocator, false, NULL);
18004 : 276 : orig_type = expr.original_type
18005 : 138 : ? expr.original_type : TREE_TYPE (allocator);
18006 : 138 : orig_type = TYPE_MAIN_VARIANT (orig_type);
18007 : : }
18008 : 195 : if (allocator
18009 : 195 : && (!INTEGRAL_TYPE_P (TREE_TYPE (allocator))
18010 : 178 : || TREE_CODE (orig_type) != ENUMERAL_TYPE
18011 : 352 : || (TYPE_NAME (orig_type)
18012 : 176 : != get_identifier ("omp_allocator_handle_t"))))
18013 : : {
18014 : 8 : error_at (clause_loc, "%<allocate%> clause allocator expression "
18015 : : "has type %qT rather than "
18016 : : "%<omp_allocator_handle_t%>",
18017 : 4 : TREE_TYPE (allocator));
18018 : 4 : allocator = NULL_TREE;
18019 : : }
18020 : 195 : if (align
18021 : 195 : && (!INTEGRAL_TYPE_P (TREE_TYPE (align))
18022 : 38 : || !tree_fits_uhwi_p (align)
18023 : 37 : || !integer_pow2p (align)))
18024 : : {
18025 : 4 : error_at (clause_loc, "%<allocate%> clause %<align%> modifier "
18026 : : "argument needs to be positive constant "
18027 : : "power of two integer expression");
18028 : 4 : align = NULL_TREE;
18029 : : }
18030 : 195 : if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
18031 : : {
18032 : 0 : parens.skip_until_found_close (parser);
18033 : 0 : return list;
18034 : : }
18035 : : }
18036 : :
18037 : 460 : nl = c_parser_omp_variable_list (parser, clause_loc,
18038 : : OMP_CLAUSE_ALLOCATE, list);
18039 : :
18040 : 460 : if (allocator || align)
18041 : 455 : for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
18042 : : {
18043 : 269 : OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) = allocator;
18044 : 269 : OMP_CLAUSE_ALLOCATE_ALIGN (c) = align;
18045 : : }
18046 : :
18047 : 460 : parens.skip_until_found_close (parser);
18048 : 460 : return nl;
18049 : : }
18050 : :
18051 : : /* OpenMP 4.0:
18052 : : linear ( variable-list )
18053 : : linear ( variable-list : expression )
18054 : :
18055 : : OpenMP 4.5:
18056 : : linear ( modifier ( variable-list ) )
18057 : : linear ( modifier ( variable-list ) : expression )
18058 : :
18059 : : modifier:
18060 : : val
18061 : :
18062 : : OpenMP 5.2:
18063 : : linear ( variable-list : modifiers-list )
18064 : :
18065 : : modifiers:
18066 : : val
18067 : : step ( expression ) */
18068 : :
18069 : : static tree
18070 : 474 : c_parser_omp_clause_linear (c_parser *parser, tree list)
18071 : : {
18072 : 474 : location_t clause_loc = c_parser_peek_token (parser)->location;
18073 : 474 : tree nl, c, step;
18074 : 474 : enum omp_clause_linear_kind kind = OMP_CLAUSE_LINEAR_DEFAULT;
18075 : 474 : bool old_linear_modifier = false;
18076 : :
18077 : 474 : matching_parens parens;
18078 : 474 : if (!parens.require_open (parser))
18079 : : return list;
18080 : :
18081 : 474 : if (c_parser_next_token_is (parser, CPP_NAME))
18082 : : {
18083 : 474 : c_token *tok = c_parser_peek_token (parser);
18084 : 474 : const char *p = IDENTIFIER_POINTER (tok->value);
18085 : 474 : if (strcmp ("val", p) == 0)
18086 : 12 : kind = OMP_CLAUSE_LINEAR_VAL;
18087 : 474 : if (c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN)
18088 : : kind = OMP_CLAUSE_LINEAR_DEFAULT;
18089 : 12 : if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
18090 : : {
18091 : 12 : old_linear_modifier = true;
18092 : 12 : c_parser_consume_token (parser);
18093 : 12 : c_parser_consume_token (parser);
18094 : : }
18095 : : }
18096 : :
18097 : 474 : nl = c_parser_omp_variable_list (parser, clause_loc,
18098 : : OMP_CLAUSE_LINEAR, list);
18099 : :
18100 : 474 : if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
18101 : 12 : parens.skip_until_found_close (parser);
18102 : :
18103 : 474 : if (c_parser_next_token_is (parser, CPP_COLON))
18104 : : {
18105 : 348 : c_parser_consume_token (parser);
18106 : 348 : location_t expr_loc = c_parser_peek_token (parser)->location;
18107 : 348 : bool has_modifiers = false;
18108 : 348 : if (kind == OMP_CLAUSE_LINEAR_DEFAULT
18109 : 684 : && c_parser_next_token_is (parser, CPP_NAME))
18110 : : {
18111 : 72 : c_token *tok = c_parser_peek_token (parser);
18112 : 72 : const char *p = IDENTIFIER_POINTER (tok->value);
18113 : 72 : unsigned int pos = 0;
18114 : 72 : if (strcmp ("val", p) == 0)
18115 : 7 : pos = 2;
18116 : 65 : else if (strcmp ("step", p) == 0
18117 : 65 : && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN)
18118 : : {
18119 : 13 : pos = 3;
18120 : 13 : if (c_parser_check_balanced_raw_token_sequence (parser, &pos)
18121 : 13 : && (c_parser_peek_nth_token_raw (parser, pos)->type
18122 : : == CPP_CLOSE_PAREN))
18123 : 13 : ++pos;
18124 : : else
18125 : 0 : pos = 0;
18126 : : }
18127 : 72 : if (pos)
18128 : : {
18129 : 20 : tok = c_parser_peek_nth_token_raw (parser, pos);
18130 : 20 : if (tok->type == CPP_COMMA || tok->type == CPP_CLOSE_PAREN)
18131 : 17 : has_modifiers = true;
18132 : : }
18133 : : }
18134 : 72 : if (has_modifiers)
18135 : : {
18136 : : step = NULL_TREE;
18137 : 25 : while (c_parser_next_token_is (parser, CPP_NAME))
18138 : : {
18139 : 25 : c_token *tok = c_parser_peek_token (parser);
18140 : 25 : const char *p = IDENTIFIER_POINTER (tok->value);
18141 : 25 : if (strcmp ("val", p) == 0)
18142 : : {
18143 : 9 : if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
18144 : : error_at (tok->location, "multiple linear modifiers");
18145 : 9 : kind = OMP_CLAUSE_LINEAR_DEFAULT;
18146 : 9 : c_parser_consume_token (parser);
18147 : : }
18148 : 16 : else if (strcmp ("step", p) == 0)
18149 : : {
18150 : 16 : c_parser_consume_token (parser);
18151 : 16 : matching_parens parens2;
18152 : 16 : if (parens2.require_open (parser))
18153 : : {
18154 : 16 : if (step)
18155 : 0 : error_at (tok->location,
18156 : : "multiple %<step%> modifiers");
18157 : 16 : expr_loc = c_parser_peek_token (parser)->location;
18158 : 16 : c_expr expr = c_parser_expr_no_commas (parser, NULL);
18159 : 16 : expr = convert_lvalue_to_rvalue (expr_loc, expr, false,
18160 : : true);
18161 : 16 : step = c_fully_fold (expr.value, false, NULL);
18162 : 16 : if (!INTEGRAL_TYPE_P (TREE_TYPE (step)))
18163 : : {
18164 : 0 : error_at (clause_loc, "%<linear%> clause step "
18165 : : "expression must be integral");
18166 : 0 : step = integer_one_node;
18167 : : }
18168 : 16 : parens2.skip_until_found_close (parser);
18169 : : }
18170 : : else
18171 : : break;
18172 : : }
18173 : : else
18174 : : break;
18175 : 25 : if (c_parser_next_token_is (parser, CPP_COMMA))
18176 : : {
18177 : 8 : c_parser_consume_token (parser);
18178 : 8 : continue;
18179 : : }
18180 : : break;
18181 : : }
18182 : 17 : if (!step)
18183 : 1 : step = integer_one_node;
18184 : : }
18185 : : else
18186 : : {
18187 : 331 : c_expr expr = c_parser_expr_no_commas (parser, NULL);
18188 : 331 : expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
18189 : 331 : step = c_fully_fold (expr.value, false, NULL);
18190 : 331 : if (!INTEGRAL_TYPE_P (TREE_TYPE (step)))
18191 : : {
18192 : 2 : error_at (clause_loc, "%<linear%> clause step expression must "
18193 : : "be integral");
18194 : 2 : step = integer_one_node;
18195 : : }
18196 : : }
18197 : :
18198 : : }
18199 : : else
18200 : 126 : step = integer_one_node;
18201 : :
18202 : 957 : for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
18203 : : {
18204 : 483 : OMP_CLAUSE_LINEAR_STEP (c) = step;
18205 : 483 : OMP_CLAUSE_LINEAR_KIND (c) = kind;
18206 : 483 : OMP_CLAUSE_LINEAR_OLD_LINEAR_MODIFIER (c) = old_linear_modifier;
18207 : : }
18208 : :
18209 : 474 : parens.skip_until_found_close (parser);
18210 : 474 : return nl;
18211 : : }
18212 : :
18213 : : /* OpenMP 5.0:
18214 : : nontemporal ( variable-list ) */
18215 : :
18216 : : static tree
18217 : 121 : c_parser_omp_clause_nontemporal (c_parser *parser, tree list)
18218 : : {
18219 : 0 : return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_NONTEMPORAL, list);
18220 : : }
18221 : :
18222 : : /* OpenMP 4.0:
18223 : : safelen ( constant-expression ) */
18224 : :
18225 : : static tree
18226 : 227 : c_parser_omp_clause_safelen (c_parser *parser, tree list)
18227 : : {
18228 : 227 : location_t clause_loc = c_parser_peek_token (parser)->location;
18229 : 227 : tree c, t;
18230 : :
18231 : 227 : matching_parens parens;
18232 : 227 : if (!parens.require_open (parser))
18233 : : return list;
18234 : :
18235 : 227 : location_t expr_loc = c_parser_peek_token (parser)->location;
18236 : 227 : c_expr expr = c_parser_expr_no_commas (parser, NULL);
18237 : 227 : expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
18238 : 227 : t = expr.value;
18239 : 227 : t = c_fully_fold (t, false, NULL);
18240 : 227 : if (TREE_CODE (t) != INTEGER_CST
18241 : 225 : || !INTEGRAL_TYPE_P (TREE_TYPE (t))
18242 : 452 : || tree_int_cst_sgn (t) != 1)
18243 : : {
18244 : 4 : error_at (clause_loc, "%<safelen%> clause expression must "
18245 : : "be positive constant integer expression");
18246 : 4 : t = NULL_TREE;
18247 : : }
18248 : :
18249 : 227 : parens.skip_until_found_close (parser);
18250 : 227 : if (t == NULL_TREE || t == error_mark_node)
18251 : : return list;
18252 : :
18253 : 223 : check_no_duplicate_clause (list, OMP_CLAUSE_SAFELEN, "safelen");
18254 : :
18255 : 223 : c = build_omp_clause (clause_loc, OMP_CLAUSE_SAFELEN);
18256 : 223 : OMP_CLAUSE_SAFELEN_EXPR (c) = t;
18257 : 223 : OMP_CLAUSE_CHAIN (c) = list;
18258 : 223 : return c;
18259 : : }
18260 : :
18261 : : /* OpenMP 4.0:
18262 : : simdlen ( constant-expression ) */
18263 : :
18264 : : static tree
18265 : 315 : c_parser_omp_clause_simdlen (c_parser *parser, tree list)
18266 : : {
18267 : 315 : location_t clause_loc = c_parser_peek_token (parser)->location;
18268 : 315 : tree c, t;
18269 : :
18270 : 315 : matching_parens parens;
18271 : 315 : if (!parens.require_open (parser))
18272 : : return list;
18273 : :
18274 : 315 : location_t expr_loc = c_parser_peek_token (parser)->location;
18275 : 315 : c_expr expr = c_parser_expr_no_commas (parser, NULL);
18276 : 315 : expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
18277 : 315 : t = expr.value;
18278 : 315 : t = c_fully_fold (t, false, NULL);
18279 : 315 : if (TREE_CODE (t) != INTEGER_CST
18280 : 313 : || !INTEGRAL_TYPE_P (TREE_TYPE (t))
18281 : 628 : || tree_int_cst_sgn (t) != 1)
18282 : : {
18283 : 4 : error_at (clause_loc, "%<simdlen%> clause expression must "
18284 : : "be positive constant integer expression");
18285 : 4 : t = NULL_TREE;
18286 : : }
18287 : :
18288 : 315 : parens.skip_until_found_close (parser);
18289 : 315 : if (t == NULL_TREE || t == error_mark_node)
18290 : : return list;
18291 : :
18292 : 311 : check_no_duplicate_clause (list, OMP_CLAUSE_SIMDLEN, "simdlen");
18293 : :
18294 : 311 : c = build_omp_clause (clause_loc, OMP_CLAUSE_SIMDLEN);
18295 : 311 : OMP_CLAUSE_SIMDLEN_EXPR (c) = t;
18296 : 311 : OMP_CLAUSE_CHAIN (c) = list;
18297 : 311 : return c;
18298 : : }
18299 : :
18300 : : /* OpenMP 4.5:
18301 : : vec:
18302 : : identifier [+/- integer]
18303 : : vec , identifier [+/- integer]
18304 : : */
18305 : :
18306 : : static tree
18307 : 194 : c_parser_omp_clause_doacross_sink (c_parser *parser, location_t clause_loc,
18308 : : tree list, bool depend_p)
18309 : : {
18310 : 194 : tree vec = NULL;
18311 : 194 : if (c_parser_next_token_is_not (parser, CPP_NAME)
18312 : 194 : || c_parser_peek_token (parser)->id_kind != C_ID_ID)
18313 : : {
18314 : 0 : c_parser_error (parser, "expected identifier");
18315 : 0 : return list;
18316 : : }
18317 : :
18318 : 194 : if (!depend_p)
18319 : : {
18320 : 77 : const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18321 : 77 : if (strcmp (p, "omp_cur_iteration") == 0
18322 : 36 : && c_parser_peek_2nd_token (parser)->type == CPP_MINUS
18323 : 34 : && c_parser_peek_nth_token (parser, 3)->type == CPP_NUMBER
18324 : 110 : && c_parser_peek_nth_token (parser, 4)->type == CPP_CLOSE_PAREN)
18325 : : {
18326 : 33 : tree val = c_parser_peek_nth_token (parser, 3)->value;
18327 : 33 : if (integer_onep (val))
18328 : : {
18329 : 33 : c_parser_consume_token (parser);
18330 : 33 : c_parser_consume_token (parser);
18331 : 33 : c_parser_consume_token (parser);
18332 : 33 : tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DOACROSS);
18333 : 33 : OMP_CLAUSE_DOACROSS_KIND (u) = OMP_CLAUSE_DOACROSS_SINK;
18334 : 33 : OMP_CLAUSE_CHAIN (u) = list;
18335 : 33 : return u;
18336 : : }
18337 : : }
18338 : : }
18339 : :
18340 : :
18341 : :
18342 : 1139 : while (c_parser_next_token_is (parser, CPP_NAME)
18343 : 1139 : && c_parser_peek_token (parser)->id_kind == C_ID_ID)
18344 : : {
18345 : 1139 : tree t = lookup_name (c_parser_peek_token (parser)->value);
18346 : 1139 : tree addend = NULL;
18347 : :
18348 : 1139 : if (t == NULL_TREE)
18349 : : {
18350 : 6 : undeclared_variable (c_parser_peek_token (parser)->location,
18351 : 6 : c_parser_peek_token (parser)->value);
18352 : 6 : t = error_mark_node;
18353 : : }
18354 : :
18355 : 1139 : c_parser_consume_token (parser);
18356 : :
18357 : 1139 : bool neg = false;
18358 : 1139 : if (c_parser_next_token_is (parser, CPP_MINUS))
18359 : : neg = true;
18360 : 920 : else if (!c_parser_next_token_is (parser, CPP_PLUS))
18361 : : {
18362 : 857 : addend = integer_zero_node;
18363 : 857 : neg = false;
18364 : 857 : goto add_to_vector;
18365 : : }
18366 : 282 : c_parser_consume_token (parser);
18367 : :
18368 : 282 : if (c_parser_next_token_is_not (parser, CPP_NUMBER))
18369 : : {
18370 : 1 : c_parser_error (parser, "expected integer");
18371 : 1 : return list;
18372 : : }
18373 : :
18374 : 281 : addend = c_parser_peek_token (parser)->value;
18375 : 281 : if (TREE_CODE (addend) != INTEGER_CST)
18376 : : {
18377 : 0 : c_parser_error (parser, "expected integer");
18378 : 0 : return list;
18379 : : }
18380 : 281 : c_parser_consume_token (parser);
18381 : :
18382 : 1138 : add_to_vector:
18383 : 1138 : if (t != error_mark_node)
18384 : : {
18385 : 1133 : vec = tree_cons (addend, t, vec);
18386 : 1133 : if (neg)
18387 : 216 : OMP_CLAUSE_DOACROSS_SINK_NEGATIVE (vec) = 1;
18388 : : }
18389 : :
18390 : 1138 : if (c_parser_next_token_is_not (parser, CPP_COMMA)
18391 : 979 : || c_parser_peek_2nd_token (parser)->type != CPP_NAME
18392 : 2116 : || c_parser_peek_2nd_token (parser)->id_kind != C_ID_ID)
18393 : : break;
18394 : :
18395 : 978 : c_parser_consume_token (parser);
18396 : : }
18397 : :
18398 : 160 : if (vec == NULL_TREE)
18399 : : return list;
18400 : :
18401 : 156 : tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DOACROSS);
18402 : 156 : OMP_CLAUSE_DOACROSS_KIND (u) = OMP_CLAUSE_DOACROSS_SINK;
18403 : 156 : OMP_CLAUSE_DOACROSS_DEPEND (u) = depend_p;
18404 : 156 : OMP_CLAUSE_DECL (u) = nreverse (vec);
18405 : 156 : OMP_CLAUSE_CHAIN (u) = list;
18406 : 156 : return u;
18407 : : }
18408 : :
18409 : : /* OpenMP 5.0:
18410 : : iterators ( iterators-definition )
18411 : :
18412 : : iterators-definition:
18413 : : iterator-specifier
18414 : : iterator-specifier , iterators-definition
18415 : :
18416 : : iterator-specifier:
18417 : : identifier = range-specification
18418 : : iterator-type identifier = range-specification
18419 : :
18420 : : range-specification:
18421 : : begin : end
18422 : : begin : end : step */
18423 : :
18424 : : static tree
18425 : 124 : c_parser_omp_iterators (c_parser *parser)
18426 : : {
18427 : 124 : tree ret = NULL_TREE, *last = &ret;
18428 : 124 : c_parser_consume_token (parser);
18429 : :
18430 : 124 : push_scope ();
18431 : :
18432 : 124 : matching_parens parens;
18433 : 124 : if (!parens.require_open (parser))
18434 : 1 : return error_mark_node;
18435 : :
18436 : 173 : do
18437 : : {
18438 : 148 : tree iter_type = NULL_TREE, type_expr = NULL_TREE;
18439 : 148 : if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
18440 : : {
18441 : 50 : struct c_type_name *type = c_parser_type_name (parser);
18442 : 50 : if (type != NULL)
18443 : 50 : iter_type = groktypename (type, &type_expr, NULL);
18444 : : }
18445 : 50 : if (iter_type == NULL_TREE)
18446 : 98 : iter_type = integer_type_node;
18447 : :
18448 : 148 : location_t loc = c_parser_peek_token (parser)->location;
18449 : 148 : if (!c_parser_next_token_is (parser, CPP_NAME))
18450 : : {
18451 : 8 : c_parser_error (parser, "expected identifier");
18452 : 8 : break;
18453 : : }
18454 : :
18455 : 140 : tree id = c_parser_peek_token (parser)->value;
18456 : 140 : c_parser_consume_token (parser);
18457 : :
18458 : 140 : if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
18459 : : break;
18460 : :
18461 : 138 : location_t eloc = c_parser_peek_token (parser)->location;
18462 : 138 : c_expr expr = c_parser_expr_no_commas (parser, NULL);
18463 : 138 : expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
18464 : 138 : tree begin = expr.value;
18465 : :
18466 : 138 : if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
18467 : : break;
18468 : :
18469 : 136 : eloc = c_parser_peek_token (parser)->location;
18470 : 136 : expr = c_parser_expr_no_commas (parser, NULL);
18471 : 136 : expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
18472 : 136 : tree end = expr.value;
18473 : :
18474 : 136 : tree step = integer_one_node;
18475 : 136 : if (c_parser_next_token_is (parser, CPP_COLON))
18476 : : {
18477 : 57 : c_parser_consume_token (parser);
18478 : 57 : eloc = c_parser_peek_token (parser)->location;
18479 : 57 : expr = c_parser_expr_no_commas (parser, NULL);
18480 : 57 : expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
18481 : 57 : step = expr.value;
18482 : : }
18483 : :
18484 : 136 : tree iter_var = build_decl (loc, VAR_DECL, id, iter_type);
18485 : 136 : DECL_ARTIFICIAL (iter_var) = 1;
18486 : 136 : DECL_CONTEXT (iter_var) = current_function_decl;
18487 : 136 : pushdecl (iter_var);
18488 : :
18489 : 136 : *last = make_tree_vec (6);
18490 : 136 : TREE_VEC_ELT (*last, 0) = iter_var;
18491 : 136 : TREE_VEC_ELT (*last, 1) = begin;
18492 : 136 : TREE_VEC_ELT (*last, 2) = end;
18493 : 136 : TREE_VEC_ELT (*last, 3) = step;
18494 : 136 : last = &TREE_CHAIN (*last);
18495 : :
18496 : 136 : if (c_parser_next_token_is (parser, CPP_COMMA))
18497 : : {
18498 : 25 : c_parser_consume_token (parser);
18499 : 25 : continue;
18500 : : }
18501 : : break;
18502 : : }
18503 : : while (1);
18504 : :
18505 : 123 : parens.skip_until_found_close (parser);
18506 : 123 : return ret ? ret : error_mark_node;
18507 : : }
18508 : :
18509 : : /* OpenMP 5.0:
18510 : : affinity ( [aff-modifier :] variable-list )
18511 : : aff-modifier:
18512 : : iterator ( iterators-definition ) */
18513 : :
18514 : : static tree
18515 : 146 : c_parser_omp_clause_affinity (c_parser *parser, tree list)
18516 : : {
18517 : 146 : location_t clause_loc = c_parser_peek_token (parser)->location;
18518 : 146 : tree nl, iterators = NULL_TREE;
18519 : :
18520 : 146 : matching_parens parens;
18521 : 146 : if (!parens.require_open (parser))
18522 : : return list;
18523 : :
18524 : 146 : if (c_parser_next_token_is (parser, CPP_NAME))
18525 : : {
18526 : 144 : const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18527 : 144 : bool parse_iter = ((strcmp ("iterator", p) == 0)
18528 : 144 : && (c_parser_peek_2nd_token (parser)->type
18529 : 50 : == CPP_OPEN_PAREN));
18530 : 50 : if (parse_iter)
18531 : : {
18532 : 50 : unsigned n = 3;
18533 : 50 : parse_iter = (c_parser_check_balanced_raw_token_sequence (parser, &n)
18534 : 50 : && (c_parser_peek_nth_token_raw (parser, n)->type
18535 : : == CPP_CLOSE_PAREN)
18536 : 100 : && (c_parser_peek_nth_token_raw (parser, n + 1)->type
18537 : : == CPP_COLON));
18538 : : }
18539 : 3 : if (parse_iter)
18540 : : {
18541 : 47 : iterators = c_parser_omp_iterators (parser);
18542 : 47 : if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
18543 : : {
18544 : 0 : if (iterators)
18545 : 0 : pop_scope ();
18546 : 0 : parens.skip_until_found_close (parser);
18547 : 0 : return list;
18548 : : }
18549 : : }
18550 : : }
18551 : 146 : nl = c_parser_omp_variable_list (parser, clause_loc, OMP_CLAUSE_AFFINITY,
18552 : : list);
18553 : 146 : if (iterators)
18554 : : {
18555 : 47 : tree block = pop_scope ();
18556 : 47 : if (iterators != error_mark_node)
18557 : : {
18558 : 43 : TREE_VEC_ELT (iterators, 5) = block;
18559 : 99 : for (tree c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
18560 : 112 : OMP_CLAUSE_DECL (c) = build_tree_list (iterators,
18561 : 56 : OMP_CLAUSE_DECL (c));
18562 : : }
18563 : : }
18564 : :
18565 : 146 : parens.skip_until_found_close (parser);
18566 : 146 : return nl;
18567 : : }
18568 : :
18569 : :
18570 : : /* OpenMP 4.0:
18571 : : depend ( depend-kind: variable-list )
18572 : :
18573 : : depend-kind:
18574 : : in | out | inout
18575 : :
18576 : : OpenMP 4.5:
18577 : : depend ( source )
18578 : :
18579 : : depend ( sink : vec )
18580 : :
18581 : : OpenMP 5.0:
18582 : : depend ( depend-modifier , depend-kind: variable-list )
18583 : :
18584 : : depend-kind:
18585 : : in | out | inout | mutexinoutset | depobj | inoutset
18586 : :
18587 : : depend-modifier:
18588 : : iterator ( iterators-definition ) */
18589 : :
18590 : : static tree
18591 : 848 : c_parser_omp_clause_depend (c_parser *parser, tree list)
18592 : : {
18593 : 848 : location_t clause_loc = c_parser_peek_token (parser)->location;
18594 : 848 : enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_LAST;
18595 : 848 : enum omp_clause_doacross_kind dkind = OMP_CLAUSE_DOACROSS_LAST;
18596 : 848 : tree nl, c, iterators = NULL_TREE;
18597 : :
18598 : 848 : matching_parens parens;
18599 : 848 : if (!parens.require_open (parser))
18600 : : return list;
18601 : :
18602 : 1002 : do
18603 : : {
18604 : 925 : if (c_parser_next_token_is_not (parser, CPP_NAME))
18605 : 0 : goto invalid_kind;
18606 : :
18607 : 925 : const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18608 : 925 : if (strcmp ("iterator", p) == 0 && iterators == NULL_TREE)
18609 : : {
18610 : 77 : iterators = c_parser_omp_iterators (parser);
18611 : 77 : c_parser_require (parser, CPP_COMMA, "expected %<,%>");
18612 : 77 : continue;
18613 : : }
18614 : 848 : if (strcmp ("in", p) == 0)
18615 : : kind = OMP_CLAUSE_DEPEND_IN;
18616 : 602 : else if (strcmp ("inout", p) == 0)
18617 : : kind = OMP_CLAUSE_DEPEND_INOUT;
18618 : 403 : else if (strcmp ("inoutset", p) == 0)
18619 : : kind = OMP_CLAUSE_DEPEND_INOUTSET;
18620 : 389 : else if (strcmp ("mutexinoutset", p) == 0)
18621 : : kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET;
18622 : 368 : else if (strcmp ("out", p) == 0)
18623 : : kind = OMP_CLAUSE_DEPEND_OUT;
18624 : 227 : else if (strcmp ("depobj", p) == 0)
18625 : : kind = OMP_CLAUSE_DEPEND_DEPOBJ;
18626 : 209 : else if (strcmp ("sink", p) == 0)
18627 : : dkind = OMP_CLAUSE_DOACROSS_SINK;
18628 : 92 : else if (strcmp ("source", p) == 0)
18629 : : dkind = OMP_CLAUSE_DOACROSS_SOURCE;
18630 : : else
18631 : 2 : goto invalid_kind;
18632 : 846 : break;
18633 : 77 : }
18634 : : while (1);
18635 : :
18636 : 846 : c_parser_consume_token (parser);
18637 : :
18638 : 846 : if (iterators
18639 : 846 : && (dkind == OMP_CLAUSE_DOACROSS_SOURCE
18640 : 846 : || dkind == OMP_CLAUSE_DOACROSS_SINK))
18641 : : {
18642 : 2 : pop_scope ();
18643 : 2 : error_at (clause_loc, "%<iterator%> modifier incompatible with %qs",
18644 : : dkind == OMP_CLAUSE_DOACROSS_SOURCE ? "source" : "sink");
18645 : 2 : iterators = NULL_TREE;
18646 : : }
18647 : :
18648 : 846 : if (dkind == OMP_CLAUSE_DOACROSS_SOURCE)
18649 : : {
18650 : 90 : c = build_omp_clause (clause_loc, OMP_CLAUSE_DOACROSS);
18651 : 90 : OMP_CLAUSE_DOACROSS_KIND (c) = dkind;
18652 : 90 : OMP_CLAUSE_DOACROSS_DEPEND (c) = 1;
18653 : 90 : OMP_CLAUSE_DECL (c) = NULL_TREE;
18654 : 90 : OMP_CLAUSE_CHAIN (c) = list;
18655 : 90 : parens.skip_until_found_close (parser);
18656 : 90 : return c;
18657 : : }
18658 : :
18659 : 756 : if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
18660 : 0 : goto resync_fail;
18661 : :
18662 : 756 : if (dkind == OMP_CLAUSE_DOACROSS_SINK)
18663 : 117 : nl = c_parser_omp_clause_doacross_sink (parser, clause_loc, list, true);
18664 : : else
18665 : : {
18666 : 639 : nl = c_parser_omp_variable_list (parser, clause_loc,
18667 : : OMP_CLAUSE_DEPEND, list);
18668 : :
18669 : 639 : if (iterators)
18670 : : {
18671 : 73 : tree block = pop_scope ();
18672 : 73 : if (iterators == error_mark_node)
18673 : : iterators = NULL_TREE;
18674 : : else
18675 : 68 : TREE_VEC_ELT (iterators, 5) = block;
18676 : : }
18677 : :
18678 : 1319 : for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
18679 : : {
18680 : 680 : OMP_CLAUSE_DEPEND_KIND (c) = kind;
18681 : 680 : if (iterators)
18682 : 150 : OMP_CLAUSE_DECL (c)
18683 : 150 : = build_tree_list (iterators, OMP_CLAUSE_DECL (c));
18684 : : }
18685 : : }
18686 : :
18687 : 756 : parens.skip_until_found_close (parser);
18688 : 756 : return nl;
18689 : :
18690 : 2 : invalid_kind:
18691 : 2 : c_parser_error (parser, "invalid depend kind");
18692 : 2 : resync_fail:
18693 : 2 : parens.skip_until_found_close (parser);
18694 : 2 : if (iterators)
18695 : 2 : pop_scope ();
18696 : : return list;
18697 : : }
18698 : :
18699 : : /* OpenMP 5.2:
18700 : : doacross ( source : )
18701 : : doacross ( source : omp_cur_iteration )
18702 : :
18703 : : doacross ( sink : vec )
18704 : : doacross ( sink : omp_cur_iteration - logical_iteration ) */
18705 : :
18706 : : static tree
18707 : 133 : c_parser_omp_clause_doacross (c_parser *parser, tree list)
18708 : : {
18709 : 133 : location_t clause_loc = c_parser_peek_token (parser)->location;
18710 : 133 : enum omp_clause_doacross_kind kind = OMP_CLAUSE_DOACROSS_LAST;
18711 : 133 : tree nl;
18712 : 133 : const char *p;
18713 : :
18714 : 133 : matching_parens parens;
18715 : 133 : if (!parens.require_open (parser))
18716 : : return list;
18717 : :
18718 : 133 : if (c_parser_next_token_is_not (parser, CPP_NAME))
18719 : 0 : goto invalid_kind;
18720 : :
18721 : 133 : p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18722 : 133 : if (strcmp ("sink", p) == 0)
18723 : : kind = OMP_CLAUSE_DOACROSS_SINK;
18724 : 54 : else if (strcmp ("source", p) == 0)
18725 : : kind = OMP_CLAUSE_DOACROSS_SOURCE;
18726 : : else
18727 : 0 : goto invalid_kind;
18728 : :
18729 : 133 : c_parser_consume_token (parser);
18730 : :
18731 : 133 : if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
18732 : 4 : goto resync_fail;
18733 : :
18734 : 129 : if (kind == OMP_CLAUSE_DOACROSS_SOURCE)
18735 : : {
18736 : 52 : if (c_parser_next_token_is (parser, CPP_NAME)
18737 : 52 : && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
18738 : : "omp_cur_iteration") == 0)
18739 : 24 : c_parser_consume_token (parser);
18740 : 52 : nl = build_omp_clause (clause_loc, OMP_CLAUSE_DOACROSS);
18741 : 52 : OMP_CLAUSE_DOACROSS_KIND (nl) = OMP_CLAUSE_DOACROSS_SOURCE;
18742 : 52 : OMP_CLAUSE_DECL (nl) = NULL_TREE;
18743 : 52 : OMP_CLAUSE_CHAIN (nl) = list;
18744 : : }
18745 : : else
18746 : 77 : nl = c_parser_omp_clause_doacross_sink (parser, clause_loc, list, false);
18747 : :
18748 : 129 : parens.skip_until_found_close (parser);
18749 : 129 : return nl;
18750 : :
18751 : 0 : invalid_kind:
18752 : 0 : c_parser_error (parser, "invalid doacross kind");
18753 : 4 : resync_fail:
18754 : 4 : parens.skip_until_found_close (parser);
18755 : 4 : return list;
18756 : : }
18757 : :
18758 : : /* OpenMP 4.0:
18759 : : map ( map-kind: variable-list )
18760 : : map ( variable-list )
18761 : :
18762 : : map-kind:
18763 : : alloc | to | from | tofrom
18764 : :
18765 : : OpenMP 4.5:
18766 : : map-kind:
18767 : : alloc | to | from | tofrom | release | delete
18768 : :
18769 : : map ( always [,] map-kind: variable-list )
18770 : :
18771 : : OpenMP 5.0:
18772 : : map ( [map-type-modifier[,] ...] map-kind: variable-list )
18773 : :
18774 : : map-type-modifier:
18775 : : always | close */
18776 : :
18777 : : static tree
18778 : 1473 : c_parser_omp_clause_map (c_parser *parser, tree list)
18779 : : {
18780 : 1473 : location_t clause_loc = c_parser_peek_token (parser)->location;
18781 : 1473 : enum gomp_map_kind kind = GOMP_MAP_TOFROM;
18782 : 1473 : tree nl, c;
18783 : :
18784 : 1473 : matching_parens parens;
18785 : 1473 : if (!parens.require_open (parser))
18786 : : return list;
18787 : :
18788 : : int pos = 1;
18789 : 1940 : int map_kind_pos = 0;
18790 : 1940 : while (c_parser_peek_nth_token_raw (parser, pos)->type == CPP_NAME)
18791 : : {
18792 : 1688 : if (c_parser_peek_nth_token_raw (parser, pos + 1)->type == CPP_COLON)
18793 : : {
18794 : : map_kind_pos = pos;
18795 : : break;
18796 : : }
18797 : :
18798 : 467 : if (c_parser_peek_nth_token_raw (parser, pos + 1)->type == CPP_COMMA)
18799 : 162 : pos++;
18800 : 467 : pos++;
18801 : : }
18802 : :
18803 : 1473 : int always_modifier = 0;
18804 : 1473 : int close_modifier = 0;
18805 : 1473 : int present_modifier = 0;
18806 : 1775 : for (int pos = 1; pos < map_kind_pos; ++pos)
18807 : : {
18808 : 319 : c_token *tok = c_parser_peek_token (parser);
18809 : :
18810 : 319 : if (tok->type == CPP_COMMA)
18811 : : {
18812 : 130 : c_parser_consume_token (parser);
18813 : 130 : continue;
18814 : : }
18815 : :
18816 : 189 : const char *p = IDENTIFIER_POINTER (tok->value);
18817 : 189 : if (strcmp ("always", p) == 0)
18818 : : {
18819 : 72 : if (always_modifier)
18820 : : {
18821 : 4 : c_parser_error (parser, "too many %<always%> modifiers");
18822 : 4 : parens.skip_until_found_close (parser);
18823 : 4 : return list;
18824 : : }
18825 : : always_modifier++;
18826 : : }
18827 : 117 : else if (strcmp ("close", p) == 0)
18828 : : {
18829 : 61 : if (close_modifier)
18830 : : {
18831 : 4 : c_parser_error (parser, "too many %<close%> modifiers");
18832 : 4 : parens.skip_until_found_close (parser);
18833 : 4 : return list;
18834 : : }
18835 : : close_modifier++;
18836 : : }
18837 : 56 : else if (strcmp ("present", p) == 0)
18838 : : {
18839 : 51 : if (present_modifier)
18840 : : {
18841 : 4 : c_parser_error (parser, "too many %<present%> modifiers");
18842 : 4 : parens.skip_until_found_close (parser);
18843 : 4 : return list;
18844 : : }
18845 : : present_modifier++;
18846 : : }
18847 : : else
18848 : : {
18849 : 5 : c_parser_error (parser, "%<map%> clause with map-type modifier other "
18850 : : "than %<always%>, %<close%> or %<present%>");
18851 : 5 : parens.skip_until_found_close (parser);
18852 : 5 : return list;
18853 : : }
18854 : :
18855 : 172 : c_parser_consume_token (parser);
18856 : : }
18857 : :
18858 : 1456 : if (c_parser_next_token_is (parser, CPP_NAME)
18859 : 1456 : && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
18860 : : {
18861 : 1204 : const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18862 : 1204 : int always_present_modifier = always_modifier && present_modifier;
18863 : :
18864 : 1204 : if (strcmp ("alloc", p) == 0)
18865 : 127 : kind = present_modifier ? GOMP_MAP_PRESENT_ALLOC : GOMP_MAP_ALLOC;
18866 : 1077 : else if (strcmp ("to", p) == 0)
18867 : 405 : kind = (always_present_modifier ? GOMP_MAP_ALWAYS_PRESENT_TO
18868 : 402 : : present_modifier ? GOMP_MAP_PRESENT_TO
18869 : 394 : : always_modifier ? GOMP_MAP_ALWAYS_TO
18870 : : : GOMP_MAP_TO);
18871 : 672 : else if (strcmp ("from", p) == 0)
18872 : 380 : kind = (always_present_modifier ? GOMP_MAP_ALWAYS_PRESENT_FROM
18873 : 375 : : present_modifier ? GOMP_MAP_PRESENT_FROM
18874 : 372 : : always_modifier ? GOMP_MAP_ALWAYS_FROM
18875 : : : GOMP_MAP_FROM);
18876 : 292 : else if (strcmp ("tofrom", p) == 0)
18877 : 243 : kind = (always_present_modifier ? GOMP_MAP_ALWAYS_PRESENT_TOFROM
18878 : 239 : : present_modifier ? GOMP_MAP_PRESENT_TOFROM
18879 : 233 : : always_modifier ? GOMP_MAP_ALWAYS_TOFROM
18880 : : : GOMP_MAP_TOFROM);
18881 : 49 : else if (strcmp ("release", p) == 0)
18882 : : kind = GOMP_MAP_RELEASE;
18883 : 15 : else if (strcmp ("delete", p) == 0)
18884 : : kind = GOMP_MAP_DELETE;
18885 : : else
18886 : : {
18887 : 0 : c_parser_error (parser, "invalid map kind");
18888 : 0 : c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
18889 : : "expected %<)%>");
18890 : 0 : return list;
18891 : : }
18892 : 1204 : c_parser_consume_token (parser);
18893 : 1204 : c_parser_consume_token (parser);
18894 : : }
18895 : :
18896 : 1456 : nl = c_parser_omp_variable_list (parser, clause_loc, OMP_CLAUSE_MAP, list,
18897 : : true);
18898 : :
18899 : 4699 : for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
18900 : 1787 : OMP_CLAUSE_SET_MAP_KIND (c, kind);
18901 : :
18902 : 1456 : parens.skip_until_found_close (parser);
18903 : 1456 : return nl;
18904 : : }
18905 : :
18906 : : /* OpenMP 4.0:
18907 : : device ( expression )
18908 : :
18909 : : OpenMP 5.0:
18910 : : device ( [device-modifier :] integer-expression )
18911 : :
18912 : : device-modifier:
18913 : : ancestor | device_num */
18914 : :
18915 : : static tree
18916 : 274 : c_parser_omp_clause_device (c_parser *parser, tree list)
18917 : : {
18918 : 274 : location_t clause_loc = c_parser_peek_token (parser)->location;
18919 : 274 : location_t expr_loc;
18920 : 274 : c_expr expr;
18921 : 274 : tree c, t;
18922 : 274 : bool ancestor = false;
18923 : :
18924 : 274 : matching_parens parens;
18925 : 274 : if (!parens.require_open (parser))
18926 : : return list;
18927 : :
18928 : 274 : if (c_parser_next_token_is (parser, CPP_NAME)
18929 : 274 : && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
18930 : : {
18931 : 46 : c_token *tok = c_parser_peek_token (parser);
18932 : 46 : const char *p = IDENTIFIER_POINTER (tok->value);
18933 : 46 : if (strcmp ("ancestor", p) == 0)
18934 : : {
18935 : : /* A requires directive with the reverse_offload clause must be
18936 : : specified. */
18937 : 25 : if ((omp_requires_mask & OMP_REQUIRES_REVERSE_OFFLOAD) == 0)
18938 : : {
18939 : 1 : error_at (tok->location, "%<ancestor%> device modifier not "
18940 : : "preceded by %<requires%> directive "
18941 : : "with %<reverse_offload%> clause");
18942 : 1 : parens.skip_until_found_close (parser);
18943 : 1 : return list;
18944 : : }
18945 : : ancestor = true;
18946 : : }
18947 : 21 : else if (strcmp ("device_num", p) == 0)
18948 : : ;
18949 : : else
18950 : : {
18951 : 1 : error_at (tok->location, "expected %<ancestor%> or %<device_num%>");
18952 : 1 : parens.skip_until_found_close (parser);
18953 : 1 : return list;
18954 : : }
18955 : 44 : c_parser_consume_token (parser);
18956 : 44 : c_parser_consume_token (parser);
18957 : : }
18958 : :
18959 : 272 : expr_loc = c_parser_peek_token (parser)->location;
18960 : 272 : expr = c_parser_expr_no_commas (parser, NULL);
18961 : 272 : expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
18962 : 272 : t = expr.value;
18963 : 272 : t = c_fully_fold (t, false, NULL);
18964 : :
18965 : 272 : parens.skip_until_found_close (parser);
18966 : :
18967 : 272 : if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
18968 : : {
18969 : 0 : c_parser_error (parser, "expected integer expression");
18970 : 0 : return list;
18971 : : }
18972 : 272 : if (ancestor && TREE_CODE (t) == INTEGER_CST && !integer_onep (t))
18973 : : {
18974 : 1 : error_at (expr_loc, "the %<device%> clause expression must evaluate to "
18975 : : "%<1%>");
18976 : 1 : return list;
18977 : : }
18978 : :
18979 : 271 : check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE, "device");
18980 : :
18981 : 271 : c = build_omp_clause (clause_loc, OMP_CLAUSE_DEVICE);
18982 : :
18983 : 271 : OMP_CLAUSE_DEVICE_ID (c) = t;
18984 : 271 : OMP_CLAUSE_CHAIN (c) = list;
18985 : 271 : OMP_CLAUSE_DEVICE_ANCESTOR (c) = ancestor;
18986 : :
18987 : 271 : list = c;
18988 : 271 : return list;
18989 : : }
18990 : :
18991 : : /* OpenMP 4.0:
18992 : : dist_schedule ( static )
18993 : : dist_schedule ( static , expression ) */
18994 : :
18995 : : static tree
18996 : 1582 : c_parser_omp_clause_dist_schedule (c_parser *parser, tree list)
18997 : : {
18998 : 1582 : tree c, t = NULL_TREE;
18999 : 1582 : location_t loc = c_parser_peek_token (parser)->location;
19000 : :
19001 : 1582 : matching_parens parens;
19002 : 1582 : if (!parens.require_open (parser))
19003 : : return list;
19004 : :
19005 : 1582 : if (!c_parser_next_token_is_keyword (parser, RID_STATIC))
19006 : : {
19007 : 0 : c_parser_error (parser, "invalid dist_schedule kind");
19008 : 0 : c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
19009 : : "expected %<)%>");
19010 : 0 : return list;
19011 : : }
19012 : :
19013 : 1582 : c_parser_consume_token (parser);
19014 : 1582 : if (c_parser_next_token_is (parser, CPP_COMMA))
19015 : : {
19016 : 1575 : c_parser_consume_token (parser);
19017 : :
19018 : 1575 : location_t expr_loc = c_parser_peek_token (parser)->location;
19019 : 1575 : c_expr expr = c_parser_expr_no_commas (parser, NULL);
19020 : 1575 : expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
19021 : 1575 : t = expr.value;
19022 : 1575 : t = c_fully_fold (t, false, NULL);
19023 : 1575 : parens.skip_until_found_close (parser);
19024 : : }
19025 : : else
19026 : 7 : c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
19027 : : "expected %<,%> or %<)%>");
19028 : :
19029 : : /* check_no_duplicate_clause (list, OMP_CLAUSE_DIST_SCHEDULE,
19030 : : "dist_schedule"); */
19031 : 1582 : if (omp_find_clause (list, OMP_CLAUSE_DIST_SCHEDULE))
19032 : 2 : warning_at (loc, OPT_Wopenmp, "too many %qs clauses", "dist_schedule");
19033 : 1582 : if (t == error_mark_node)
19034 : : return list;
19035 : :
19036 : 1582 : c = build_omp_clause (loc, OMP_CLAUSE_DIST_SCHEDULE);
19037 : 1582 : OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c) = t;
19038 : 1582 : OMP_CLAUSE_CHAIN (c) = list;
19039 : 1582 : return c;
19040 : : }
19041 : :
19042 : : /* OpenMP 4.0:
19043 : : proc_bind ( proc-bind-kind )
19044 : :
19045 : : proc-bind-kind:
19046 : : primary | master | close | spread
19047 : : where OpenMP 5.1 added 'primary' and deprecated the alias 'master'. */
19048 : :
19049 : : static tree
19050 : 194 : c_parser_omp_clause_proc_bind (c_parser *parser, tree list)
19051 : : {
19052 : 194 : location_t clause_loc = c_parser_peek_token (parser)->location;
19053 : 194 : enum omp_clause_proc_bind_kind kind;
19054 : 194 : tree c;
19055 : :
19056 : 194 : matching_parens parens;
19057 : 194 : if (!parens.require_open (parser))
19058 : : return list;
19059 : :
19060 : 194 : if (c_parser_next_token_is (parser, CPP_NAME))
19061 : : {
19062 : 194 : const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19063 : 194 : if (strcmp ("primary", p) == 0)
19064 : : kind = OMP_CLAUSE_PROC_BIND_PRIMARY;
19065 : 193 : else if (strcmp ("master", p) == 0)
19066 : : kind = OMP_CLAUSE_PROC_BIND_MASTER;
19067 : 177 : else if (strcmp ("close", p) == 0)
19068 : : kind = OMP_CLAUSE_PROC_BIND_CLOSE;
19069 : 165 : else if (strcmp ("spread", p) == 0)
19070 : : kind = OMP_CLAUSE_PROC_BIND_SPREAD;
19071 : : else
19072 : 0 : goto invalid_kind;
19073 : : }
19074 : : else
19075 : 0 : goto invalid_kind;
19076 : :
19077 : 194 : check_no_duplicate_clause (list, OMP_CLAUSE_PROC_BIND, "proc_bind");
19078 : 194 : c_parser_consume_token (parser);
19079 : 194 : parens.skip_until_found_close (parser);
19080 : 194 : c = build_omp_clause (clause_loc, OMP_CLAUSE_PROC_BIND);
19081 : 194 : OMP_CLAUSE_PROC_BIND_KIND (c) = kind;
19082 : 194 : OMP_CLAUSE_CHAIN (c) = list;
19083 : 194 : return c;
19084 : :
19085 : 0 : invalid_kind:
19086 : 0 : c_parser_error (parser, "invalid proc_bind kind");
19087 : 0 : parens.skip_until_found_close (parser);
19088 : 0 : return list;
19089 : : }
19090 : :
19091 : : /* OpenMP 5.0:
19092 : : device_type ( host | nohost | any ) */
19093 : :
19094 : : static tree
19095 : 42 : c_parser_omp_clause_device_type (c_parser *parser, tree list)
19096 : : {
19097 : 42 : location_t clause_loc = c_parser_peek_token (parser)->location;
19098 : 42 : enum omp_clause_device_type_kind kind;
19099 : 42 : tree c;
19100 : :
19101 : 42 : matching_parens parens;
19102 : 42 : if (!parens.require_open (parser))
19103 : : return list;
19104 : :
19105 : 42 : if (c_parser_next_token_is (parser, CPP_NAME))
19106 : : {
19107 : 42 : const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19108 : 42 : if (strcmp ("host", p) == 0)
19109 : : kind = OMP_CLAUSE_DEVICE_TYPE_HOST;
19110 : 26 : else if (strcmp ("nohost", p) == 0)
19111 : : kind = OMP_CLAUSE_DEVICE_TYPE_NOHOST;
19112 : 17 : else if (strcmp ("any", p) == 0)
19113 : : kind = OMP_CLAUSE_DEVICE_TYPE_ANY;
19114 : : else
19115 : 0 : goto invalid_kind;
19116 : : }
19117 : : else
19118 : 0 : goto invalid_kind;
19119 : :
19120 : 42 : check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE_TYPE,
19121 : : "device_type");
19122 : 42 : c_parser_consume_token (parser);
19123 : 42 : parens.skip_until_found_close (parser);
19124 : 42 : c = build_omp_clause (clause_loc, OMP_CLAUSE_DEVICE_TYPE);
19125 : 42 : OMP_CLAUSE_DEVICE_TYPE_KIND (c) = kind;
19126 : 42 : OMP_CLAUSE_CHAIN (c) = list;
19127 : 42 : return c;
19128 : :
19129 : 0 : invalid_kind:
19130 : 0 : c_parser_error (parser, "expected %<host%>, %<nohost%> or %<any%>");
19131 : 0 : parens.skip_until_found_close (parser);
19132 : 0 : return list;
19133 : : }
19134 : :
19135 : : /* OpenMP 4.0:
19136 : : from ( variable-list )
19137 : : to ( variable-list )
19138 : :
19139 : : OpenMP 5.1:
19140 : : from ( [present :] variable-list )
19141 : : to ( [present :] variable-list ) */
19142 : :
19143 : : static tree
19144 : 2830 : c_parser_omp_clause_from_to (c_parser *parser, enum omp_clause_code kind,
19145 : : tree list)
19146 : : {
19147 : 2830 : location_t loc = c_parser_peek_token (parser)->location;
19148 : 2830 : matching_parens parens;
19149 : 2830 : if (!parens.require_open (parser))
19150 : : return list;
19151 : :
19152 : 2830 : bool present = false;
19153 : 2830 : c_token *token = c_parser_peek_token (parser);
19154 : :
19155 : 2830 : if (token->type == CPP_NAME
19156 : 2830 : && strcmp (IDENTIFIER_POINTER (token->value), "present") == 0
19157 : 2835 : && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
19158 : : {
19159 : 5 : present = true;
19160 : 5 : c_parser_consume_token (parser);
19161 : 5 : c_parser_consume_token (parser);
19162 : : }
19163 : :
19164 : 2830 : tree nl = c_parser_omp_variable_list (parser, loc, kind, list);
19165 : 2830 : parens.skip_until_found_close (parser);
19166 : :
19167 : 2830 : if (present)
19168 : 10 : for (tree c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
19169 : 5 : OMP_CLAUSE_MOTION_PRESENT (c) = 1;
19170 : :
19171 : : return nl;
19172 : : }
19173 : :
19174 : : /* OpenMP 4.0:
19175 : : uniform ( variable-list ) */
19176 : :
19177 : : static tree
19178 : 115 : c_parser_omp_clause_uniform (c_parser *parser, tree list)
19179 : : {
19180 : : /* The clauses location. */
19181 : 115 : location_t loc = c_parser_peek_token (parser)->location;
19182 : :
19183 : 115 : matching_parens parens;
19184 : 115 : if (parens.require_open (parser))
19185 : : {
19186 : 115 : list = c_parser_omp_variable_list (parser, loc, OMP_CLAUSE_UNIFORM,
19187 : : list);
19188 : 115 : parens.skip_until_found_close (parser);
19189 : : }
19190 : 115 : return list;
19191 : : }
19192 : :
19193 : : /* OpenMP 5.0:
19194 : : detach ( event-handle ) */
19195 : :
19196 : : static tree
19197 : 34 : c_parser_omp_clause_detach (c_parser *parser, tree list)
19198 : : {
19199 : 34 : matching_parens parens;
19200 : 34 : location_t clause_loc = c_parser_peek_token (parser)->location;
19201 : :
19202 : 34 : if (!parens.require_open (parser))
19203 : : return list;
19204 : :
19205 : 34 : if (c_parser_next_token_is_not (parser, CPP_NAME)
19206 : 34 : || c_parser_peek_token (parser)->id_kind != C_ID_ID)
19207 : : {
19208 : 1 : c_parser_error (parser, "expected identifier");
19209 : 1 : parens.skip_until_found_close (parser);
19210 : 1 : return list;
19211 : : }
19212 : :
19213 : 33 : tree t = lookup_name (c_parser_peek_token (parser)->value);
19214 : 33 : if (t == NULL_TREE)
19215 : : {
19216 : 0 : undeclared_variable (c_parser_peek_token (parser)->location,
19217 : 0 : c_parser_peek_token (parser)->value);
19218 : 0 : parens.skip_until_found_close (parser);
19219 : 0 : return list;
19220 : : }
19221 : 33 : c_parser_consume_token (parser);
19222 : :
19223 : 33 : tree type = TYPE_MAIN_VARIANT (TREE_TYPE (t));
19224 : 33 : if (!INTEGRAL_TYPE_P (type)
19225 : : || TREE_CODE (type) != ENUMERAL_TYPE
19226 : 33 : || TYPE_NAME (type) != get_identifier ("omp_event_handle_t"))
19227 : : {
19228 : 1 : error_at (clause_loc, "%<detach%> clause event handle "
19229 : : "has type %qT rather than "
19230 : : "%<omp_event_handle_t%>",
19231 : : type);
19232 : 1 : parens.skip_until_found_close (parser);
19233 : 1 : return list;
19234 : : }
19235 : :
19236 : 32 : tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DETACH);
19237 : 32 : OMP_CLAUSE_DECL (u) = t;
19238 : 32 : OMP_CLAUSE_CHAIN (u) = list;
19239 : 32 : parens.skip_until_found_close (parser);
19240 : 32 : return u;
19241 : : }
19242 : :
19243 : : /* Parse all OpenACC clauses. The set clauses allowed by the directive
19244 : : is a bitmask in MASK. Return the list of clauses found. */
19245 : :
19246 : : static tree
19247 : 4877 : c_parser_oacc_all_clauses (c_parser *parser, omp_clause_mask mask,
19248 : : const char *where, bool finish_p = true,
19249 : : bool target_p = false)
19250 : : {
19251 : 4877 : tree clauses = NULL;
19252 : 4877 : bool first = true;
19253 : :
19254 : 11185 : while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
19255 : : {
19256 : 6354 : location_t here;
19257 : 6354 : pragma_omp_clause c_kind;
19258 : 6354 : const char *c_name;
19259 : 6354 : tree prev = clauses;
19260 : :
19261 : 8897 : if (!first && c_parser_next_token_is (parser, CPP_COMMA))
19262 : 11 : c_parser_consume_token (parser);
19263 : :
19264 : 6354 : here = c_parser_peek_token (parser)->location;
19265 : 6354 : c_kind = c_parser_omp_clause_name (parser);
19266 : :
19267 : 6354 : switch (c_kind)
19268 : : {
19269 : 236 : case PRAGMA_OACC_CLAUSE_ASYNC:
19270 : 236 : clauses = c_parser_oacc_clause_async (parser, clauses);
19271 : 236 : c_name = "async";
19272 : 236 : break;
19273 : 107 : case PRAGMA_OACC_CLAUSE_AUTO:
19274 : 107 : clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_AUTO,
19275 : : clauses);
19276 : 107 : c_name = "auto";
19277 : 107 : break;
19278 : 27 : case PRAGMA_OACC_CLAUSE_ATTACH:
19279 : 27 : clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
19280 : 27 : c_name = "attach";
19281 : 27 : break;
19282 : 50 : case PRAGMA_OACC_CLAUSE_COLLAPSE:
19283 : 50 : clauses = c_parser_omp_clause_collapse (parser, clauses);
19284 : 50 : c_name = "collapse";
19285 : 50 : break;
19286 : 795 : case PRAGMA_OACC_CLAUSE_COPY:
19287 : 795 : clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
19288 : 795 : c_name = "copy";
19289 : 795 : break;
19290 : 354 : case PRAGMA_OACC_CLAUSE_COPYIN:
19291 : 354 : clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
19292 : 354 : c_name = "copyin";
19293 : 354 : break;
19294 : 384 : case PRAGMA_OACC_CLAUSE_COPYOUT:
19295 : 384 : clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
19296 : 384 : c_name = "copyout";
19297 : 384 : break;
19298 : 91 : case PRAGMA_OACC_CLAUSE_CREATE:
19299 : 91 : clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
19300 : 91 : c_name = "create";
19301 : 91 : break;
19302 : 67 : case PRAGMA_OACC_CLAUSE_DELETE:
19303 : 67 : clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
19304 : 67 : c_name = "delete";
19305 : 67 : break;
19306 : 52 : case PRAGMA_OMP_CLAUSE_DEFAULT:
19307 : 52 : clauses = c_parser_omp_clause_default (parser, clauses, true);
19308 : 52 : c_name = "default";
19309 : 52 : break;
19310 : 20 : case PRAGMA_OACC_CLAUSE_DETACH:
19311 : 20 : clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
19312 : 20 : c_name = "detach";
19313 : 20 : break;
19314 : 36 : case PRAGMA_OACC_CLAUSE_DEVICE:
19315 : 36 : clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
19316 : 36 : c_name = "device";
19317 : 36 : break;
19318 : 54 : case PRAGMA_OACC_CLAUSE_DEVICEPTR:
19319 : 54 : clauses = c_parser_oacc_data_clause_deviceptr (parser, clauses);
19320 : 54 : c_name = "deviceptr";
19321 : 54 : break;
19322 : 15 : case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT:
19323 : 15 : clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
19324 : 15 : c_name = "device_resident";
19325 : 15 : break;
19326 : 12 : case PRAGMA_OACC_CLAUSE_FINALIZE:
19327 : 12 : clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_FINALIZE,
19328 : : clauses);
19329 : 12 : c_name = "finalize";
19330 : 12 : break;
19331 : 109 : case PRAGMA_OACC_CLAUSE_FIRSTPRIVATE:
19332 : 109 : clauses = c_parser_omp_clause_firstprivate (parser, clauses);
19333 : 109 : c_name = "firstprivate";
19334 : 109 : break;
19335 : 561 : case PRAGMA_OACC_CLAUSE_GANG:
19336 : 561 : c_name = "gang";
19337 : 561 : clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_GANG,
19338 : : c_name, clauses);
19339 : 561 : break;
19340 : 40 : case PRAGMA_OACC_CLAUSE_HOST:
19341 : 40 : clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
19342 : 40 : c_name = "host";
19343 : 40 : break;
19344 : 96 : case PRAGMA_OACC_CLAUSE_IF:
19345 : 96 : clauses = c_parser_omp_clause_if (parser, clauses, false);
19346 : 96 : c_name = "if";
19347 : 96 : break;
19348 : 18 : case PRAGMA_OACC_CLAUSE_IF_PRESENT:
19349 : 18 : clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_IF_PRESENT,
19350 : : clauses);
19351 : 18 : c_name = "if_present";
19352 : 18 : break;
19353 : 43 : case PRAGMA_OACC_CLAUSE_INDEPENDENT:
19354 : 43 : clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_INDEPENDENT,
19355 : : clauses);
19356 : 43 : c_name = "independent";
19357 : 43 : break;
19358 : 13 : case PRAGMA_OACC_CLAUSE_LINK:
19359 : 13 : clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
19360 : 13 : c_name = "link";
19361 : 13 : break;
19362 : 10 : case PRAGMA_OACC_CLAUSE_NO_CREATE:
19363 : 10 : clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
19364 : 10 : c_name = "no_create";
19365 : 10 : break;
19366 : 25 : case PRAGMA_OACC_CLAUSE_NOHOST:
19367 : 25 : clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_NOHOST,
19368 : : clauses);
19369 : 25 : c_name = "nohost";
19370 : 25 : break;
19371 : 302 : case PRAGMA_OACC_CLAUSE_NUM_GANGS:
19372 : 302 : clauses = c_parser_oacc_single_int_clause (parser,
19373 : : OMP_CLAUSE_NUM_GANGS,
19374 : : clauses);
19375 : 302 : c_name = "num_gangs";
19376 : 302 : break;
19377 : 207 : case PRAGMA_OACC_CLAUSE_NUM_WORKERS:
19378 : 207 : clauses = c_parser_oacc_single_int_clause (parser,
19379 : : OMP_CLAUSE_NUM_WORKERS,
19380 : : clauses);
19381 : 207 : c_name = "num_workers";
19382 : 207 : break;
19383 : 126 : case PRAGMA_OACC_CLAUSE_PRESENT:
19384 : 126 : clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
19385 : 126 : c_name = "present";
19386 : 126 : break;
19387 : 62 : case PRAGMA_OACC_CLAUSE_PRIVATE:
19388 : 62 : clauses = c_parser_omp_clause_private (parser, clauses);
19389 : 62 : c_name = "private";
19390 : 62 : break;
19391 : 700 : case PRAGMA_OACC_CLAUSE_REDUCTION:
19392 : 700 : clauses
19393 : 700 : = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
19394 : : false, clauses);
19395 : 700 : c_name = "reduction";
19396 : 700 : break;
19397 : 66 : case PRAGMA_OACC_CLAUSE_SELF:
19398 : 66 : if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_HOST)) == 0)
19399 : : /* OpenACC compute construct */
19400 : 48 : clauses = c_parser_oacc_compute_clause_self (parser, clauses);
19401 : : else
19402 : : /* OpenACC 'update' directive */
19403 : 18 : clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
19404 : : c_name = "self";
19405 : : break;
19406 : 249 : case PRAGMA_OACC_CLAUSE_SEQ:
19407 : 249 : clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_SEQ,
19408 : : clauses);
19409 : 249 : c_name = "seq";
19410 : 249 : break;
19411 : 122 : case PRAGMA_OACC_CLAUSE_TILE:
19412 : 122 : clauses = c_parser_oacc_clause_tile (parser, clauses);
19413 : 122 : c_name = "tile";
19414 : 122 : break;
19415 : 21 : case PRAGMA_OACC_CLAUSE_USE_DEVICE:
19416 : 21 : clauses = c_parser_omp_clause_use_device_ptr (parser, clauses);
19417 : 21 : c_name = "use_device";
19418 : 21 : break;
19419 : 495 : case PRAGMA_OACC_CLAUSE_VECTOR:
19420 : 495 : c_name = "vector";
19421 : 495 : clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_VECTOR,
19422 : : c_name, clauses);
19423 : 495 : break;
19424 : 223 : case PRAGMA_OACC_CLAUSE_VECTOR_LENGTH:
19425 : 223 : clauses = c_parser_oacc_single_int_clause (parser,
19426 : : OMP_CLAUSE_VECTOR_LENGTH,
19427 : : clauses);
19428 : 223 : c_name = "vector_length";
19429 : 223 : break;
19430 : 89 : case PRAGMA_OACC_CLAUSE_WAIT:
19431 : 89 : clauses = c_parser_oacc_clause_wait (parser, clauses);
19432 : 89 : c_name = "wait";
19433 : 89 : break;
19434 : 431 : case PRAGMA_OACC_CLAUSE_WORKER:
19435 : 431 : c_name = "worker";
19436 : 431 : clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_WORKER,
19437 : : c_name, clauses);
19438 : 431 : break;
19439 : 46 : default:
19440 : 46 : c_parser_error (parser, "expected an OpenACC clause");
19441 : 46 : goto saw_error;
19442 : : }
19443 : :
19444 : 6308 : first = false;
19445 : :
19446 : 6308 : if (((mask >> c_kind) & 1) == 0)
19447 : : {
19448 : : /* Remove the invalid clause(s) from the list to avoid
19449 : : confusing the rest of the compiler. */
19450 : 17 : clauses = prev;
19451 : 17 : error_at (here, "%qs is not valid for %qs", c_name, where);
19452 : : }
19453 : : }
19454 : :
19455 : 4831 : saw_error:
19456 : 4877 : c_parser_skip_to_pragma_eol (parser);
19457 : :
19458 : 4877 : if (finish_p)
19459 : 7100 : return c_finish_omp_clauses (clauses, target_p ? C_ORT_ACC_TARGET
19460 : 4228 : : C_ORT_ACC);
19461 : :
19462 : : return clauses;
19463 : : }
19464 : :
19465 : : /* Parse all OpenMP clauses. The set clauses allowed by the directive
19466 : : is a bitmask in MASK. Return the list of clauses found.
19467 : : FINISH_P set if c_finish_omp_clauses should be called.
19468 : : NESTED non-zero if clauses should be terminated by closing paren instead
19469 : : of end of pragma. If it is 2, additionally commas are required in between
19470 : : the clauses. */
19471 : :
19472 : : static tree
19473 : 18596 : c_parser_omp_all_clauses (c_parser *parser, omp_clause_mask mask,
19474 : : const char *where, bool finish_p = true,
19475 : : int nested = 0)
19476 : : {
19477 : 18596 : tree clauses = NULL;
19478 : 18596 : bool first = true;
19479 : :
19480 : 44483 : while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
19481 : : {
19482 : 25930 : location_t here;
19483 : 25930 : pragma_omp_clause c_kind;
19484 : 25930 : const char *c_name;
19485 : 25930 : tree prev = clauses;
19486 : :
19487 : 26027 : if (nested && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
19488 : : break;
19489 : :
19490 : 25908 : if (!first || nested != 2)
19491 : : {
19492 : 25885 : if (c_parser_next_token_is (parser, CPP_COMMA))
19493 : 2652 : c_parser_consume_token (parser);
19494 : 23233 : else if (nested == 2)
19495 : 3 : error_at (c_parser_peek_token (parser)->location,
19496 : : "clauses in %<simd%> trait should be separated "
19497 : : "by %<,%>");
19498 : : }
19499 : :
19500 : 25908 : here = c_parser_peek_token (parser)->location;
19501 : 25908 : c_kind = c_parser_omp_clause_name (parser);
19502 : :
19503 : 25908 : switch (c_kind)
19504 : : {
19505 : 115 : case PRAGMA_OMP_CLAUSE_BIND:
19506 : 115 : clauses = c_parser_omp_clause_bind (parser, clauses);
19507 : 115 : c_name = "bind";
19508 : 115 : break;
19509 : 2740 : case PRAGMA_OMP_CLAUSE_COLLAPSE:
19510 : 2740 : clauses = c_parser_omp_clause_collapse (parser, clauses);
19511 : 2740 : c_name = "collapse";
19512 : 2740 : break;
19513 : 101 : case PRAGMA_OMP_CLAUSE_COPYIN:
19514 : 101 : clauses = c_parser_omp_clause_copyin (parser, clauses);
19515 : 101 : c_name = "copyin";
19516 : 101 : break;
19517 : 21 : case PRAGMA_OMP_CLAUSE_COPYPRIVATE:
19518 : 21 : clauses = c_parser_omp_clause_copyprivate (parser, clauses);
19519 : 21 : c_name = "copyprivate";
19520 : 21 : break;
19521 : 640 : case PRAGMA_OMP_CLAUSE_DEFAULT:
19522 : 640 : clauses = c_parser_omp_clause_default (parser, clauses, false);
19523 : 640 : c_name = "default";
19524 : 640 : break;
19525 : 34 : case PRAGMA_OMP_CLAUSE_DETACH:
19526 : 34 : clauses = c_parser_omp_clause_detach (parser, clauses);
19527 : 34 : c_name = "detach";
19528 : 34 : break;
19529 : 62 : case PRAGMA_OMP_CLAUSE_FILTER:
19530 : 62 : clauses = c_parser_omp_clause_filter (parser, clauses);
19531 : 62 : c_name = "filter";
19532 : 62 : break;
19533 : 656 : case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE:
19534 : 656 : clauses = c_parser_omp_clause_firstprivate (parser, clauses);
19535 : 656 : c_name = "firstprivate";
19536 : 656 : break;
19537 : 98 : case PRAGMA_OMP_CLAUSE_FINAL:
19538 : 98 : clauses = c_parser_omp_clause_final (parser, clauses);
19539 : 98 : c_name = "final";
19540 : 98 : break;
19541 : 62 : case PRAGMA_OMP_CLAUSE_GRAINSIZE:
19542 : 62 : clauses = c_parser_omp_clause_grainsize (parser, clauses);
19543 : 62 : c_name = "grainsize";
19544 : 62 : break;
19545 : 29 : case PRAGMA_OMP_CLAUSE_HINT:
19546 : 29 : clauses = c_parser_omp_clause_hint (parser, clauses);
19547 : 29 : c_name = "hint";
19548 : 29 : break;
19549 : 238 : case PRAGMA_OMP_CLAUSE_DEFAULTMAP:
19550 : 238 : clauses = c_parser_omp_clause_defaultmap (parser, clauses);
19551 : 238 : c_name = "defaultmap";
19552 : 238 : break;
19553 : 776 : case PRAGMA_OMP_CLAUSE_IF:
19554 : 776 : clauses = c_parser_omp_clause_if (parser, clauses, true);
19555 : 776 : c_name = "if";
19556 : 776 : break;
19557 : 320 : case PRAGMA_OMP_CLAUSE_IN_REDUCTION:
19558 : 320 : clauses
19559 : 320 : = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_IN_REDUCTION,
19560 : : true, clauses);
19561 : 320 : c_name = "in_reduction";
19562 : 320 : break;
19563 : 26 : case PRAGMA_OMP_CLAUSE_INDIRECT:
19564 : 26 : clauses = c_parser_omp_clause_indirect (parser, clauses);
19565 : 26 : c_name = "indirect";
19566 : 26 : break;
19567 : 728 : case PRAGMA_OMP_CLAUSE_LASTPRIVATE:
19568 : 728 : clauses = c_parser_omp_clause_lastprivate (parser, clauses);
19569 : 728 : c_name = "lastprivate";
19570 : 728 : break;
19571 : 78 : case PRAGMA_OMP_CLAUSE_MERGEABLE:
19572 : 78 : clauses = c_parser_omp_clause_mergeable (parser, clauses);
19573 : 78 : c_name = "mergeable";
19574 : 78 : break;
19575 : 364 : case PRAGMA_OMP_CLAUSE_NOWAIT:
19576 : 364 : clauses = c_parser_omp_clause_nowait (parser, clauses);
19577 : 364 : c_name = "nowait";
19578 : 364 : break;
19579 : 49 : case PRAGMA_OMP_CLAUSE_NUM_TASKS:
19580 : 49 : clauses = c_parser_omp_clause_num_tasks (parser, clauses);
19581 : 49 : c_name = "num_tasks";
19582 : 49 : break;
19583 : 424 : case PRAGMA_OMP_CLAUSE_NUM_THREADS:
19584 : 424 : clauses = c_parser_omp_clause_num_threads (parser, clauses);
19585 : 424 : c_name = "num_threads";
19586 : 424 : break;
19587 : 375 : case PRAGMA_OMP_CLAUSE_ORDER:
19588 : 375 : clauses = c_parser_omp_clause_order (parser, clauses);
19589 : 375 : c_name = "order";
19590 : 375 : break;
19591 : 291 : case PRAGMA_OMP_CLAUSE_ORDERED:
19592 : 291 : clauses = c_parser_omp_clause_ordered (parser, clauses);
19593 : 291 : c_name = "ordered";
19594 : 291 : break;
19595 : 97 : case PRAGMA_OMP_CLAUSE_PRIORITY:
19596 : 97 : clauses = c_parser_omp_clause_priority (parser, clauses);
19597 : 97 : c_name = "priority";
19598 : 97 : break;
19599 : 654 : case PRAGMA_OMP_CLAUSE_PRIVATE:
19600 : 654 : clauses = c_parser_omp_clause_private (parser, clauses);
19601 : 654 : c_name = "private";
19602 : 654 : break;
19603 : 1761 : case PRAGMA_OMP_CLAUSE_REDUCTION:
19604 : 1761 : clauses
19605 : 1761 : = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
19606 : : true, clauses);
19607 : 1761 : c_name = "reduction";
19608 : 1761 : break;
19609 : 3451 : case PRAGMA_OMP_CLAUSE_SCHEDULE:
19610 : 3451 : clauses = c_parser_omp_clause_schedule (parser, clauses);
19611 : 3451 : c_name = "schedule";
19612 : 3451 : break;
19613 : 689 : case PRAGMA_OMP_CLAUSE_SHARED:
19614 : 689 : clauses = c_parser_omp_clause_shared (parser, clauses);
19615 : 689 : c_name = "shared";
19616 : 689 : break;
19617 : 86 : case PRAGMA_OMP_CLAUSE_TASK_REDUCTION:
19618 : 86 : clauses
19619 : 86 : = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_TASK_REDUCTION,
19620 : : true, clauses);
19621 : 86 : c_name = "task_reduction";
19622 : 86 : break;
19623 : 96 : case PRAGMA_OMP_CLAUSE_UNTIED:
19624 : 96 : clauses = c_parser_omp_clause_untied (parser, clauses);
19625 : 96 : c_name = "untied";
19626 : 96 : break;
19627 : 60 : case PRAGMA_OMP_CLAUSE_INBRANCH:
19628 : 60 : clauses = c_parser_omp_clause_branch (parser, OMP_CLAUSE_INBRANCH,
19629 : : clauses);
19630 : 60 : c_name = "inbranch";
19631 : 60 : break;
19632 : 121 : case PRAGMA_OMP_CLAUSE_NONTEMPORAL:
19633 : 121 : clauses = c_parser_omp_clause_nontemporal (parser, clauses);
19634 : 121 : c_name = "nontemporal";
19635 : 121 : break;
19636 : 136 : case PRAGMA_OMP_CLAUSE_NOTINBRANCH:
19637 : 136 : clauses = c_parser_omp_clause_branch (parser, OMP_CLAUSE_NOTINBRANCH,
19638 : : clauses);
19639 : 136 : c_name = "notinbranch";
19640 : 136 : break;
19641 : 107 : case PRAGMA_OMP_CLAUSE_PARALLEL:
19642 : 107 : clauses
19643 : 107 : = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_PARALLEL,
19644 : : clauses);
19645 : 107 : c_name = "parallel";
19646 : 107 : if (!first)
19647 : : {
19648 : 0 : clause_not_first:
19649 : 0 : error_at (here, "%qs must be the first clause of %qs",
19650 : : c_name, where);
19651 : 0 : clauses = prev;
19652 : : }
19653 : : break;
19654 : 84 : case PRAGMA_OMP_CLAUSE_FOR:
19655 : 84 : clauses
19656 : 84 : = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_FOR,
19657 : : clauses);
19658 : 84 : c_name = "for";
19659 : 84 : if (!first)
19660 : 0 : goto clause_not_first;
19661 : : break;
19662 : 78 : case PRAGMA_OMP_CLAUSE_SECTIONS:
19663 : 78 : clauses
19664 : 78 : = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_SECTIONS,
19665 : : clauses);
19666 : 78 : c_name = "sections";
19667 : 78 : if (!first)
19668 : 0 : goto clause_not_first;
19669 : : break;
19670 : 110 : case PRAGMA_OMP_CLAUSE_TASKGROUP:
19671 : 110 : clauses
19672 : 110 : = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_TASKGROUP,
19673 : : clauses);
19674 : 110 : c_name = "taskgroup";
19675 : 110 : if (!first)
19676 : 0 : goto clause_not_first;
19677 : : break;
19678 : 29 : case PRAGMA_OMP_CLAUSE_LINK:
19679 : 29 : clauses
19680 : 29 : = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_LINK, clauses);
19681 : 29 : c_name = "link";
19682 : 29 : break;
19683 : 466 : case PRAGMA_OMP_CLAUSE_TO:
19684 : 466 : if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK)) != 0)
19685 : : {
19686 : 83 : tree nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ENTER,
19687 : : clauses);
19688 : 185 : for (tree c = nl; c != clauses; c = OMP_CLAUSE_CHAIN (c))
19689 : 102 : OMP_CLAUSE_ENTER_TO (c) = 1;
19690 : : clauses = nl;
19691 : : }
19692 : : else
19693 : 383 : clauses = c_parser_omp_clause_from_to (parser, OMP_CLAUSE_TO,
19694 : : clauses);
19695 : : c_name = "to";
19696 : : break;
19697 : 2447 : case PRAGMA_OMP_CLAUSE_FROM:
19698 : 2447 : clauses = c_parser_omp_clause_from_to (parser, OMP_CLAUSE_FROM,
19699 : : clauses);
19700 : 2447 : c_name = "from";
19701 : 2447 : break;
19702 : 115 : case PRAGMA_OMP_CLAUSE_UNIFORM:
19703 : 115 : clauses = c_parser_omp_clause_uniform (parser, clauses);
19704 : 115 : c_name = "uniform";
19705 : 115 : break;
19706 : 190 : case PRAGMA_OMP_CLAUSE_NUM_TEAMS:
19707 : 190 : clauses = c_parser_omp_clause_num_teams (parser, clauses);
19708 : 190 : c_name = "num_teams";
19709 : 190 : break;
19710 : 154 : case PRAGMA_OMP_CLAUSE_THREAD_LIMIT:
19711 : 154 : clauses = c_parser_omp_clause_thread_limit (parser, clauses);
19712 : 154 : c_name = "thread_limit";
19713 : 154 : break;
19714 : 228 : case PRAGMA_OMP_CLAUSE_ALIGNED:
19715 : 228 : clauses = c_parser_omp_clause_aligned (parser, clauses);
19716 : 228 : c_name = "aligned";
19717 : 228 : break;
19718 : 462 : case PRAGMA_OMP_CLAUSE_ALLOCATE:
19719 : 462 : clauses = c_parser_omp_clause_allocate (parser, clauses);
19720 : 462 : c_name = "allocate";
19721 : 462 : break;
19722 : 474 : case PRAGMA_OMP_CLAUSE_LINEAR:
19723 : 474 : clauses = c_parser_omp_clause_linear (parser, clauses);
19724 : 474 : c_name = "linear";
19725 : 474 : break;
19726 : 146 : case PRAGMA_OMP_CLAUSE_AFFINITY:
19727 : 146 : clauses = c_parser_omp_clause_affinity (parser, clauses);
19728 : 146 : c_name = "affinity";
19729 : 146 : break;
19730 : 811 : case PRAGMA_OMP_CLAUSE_DEPEND:
19731 : 811 : clauses = c_parser_omp_clause_depend (parser, clauses);
19732 : 811 : c_name = "depend";
19733 : 811 : break;
19734 : 133 : case PRAGMA_OMP_CLAUSE_DOACROSS:
19735 : 133 : clauses = c_parser_omp_clause_doacross (parser, clauses);
19736 : 133 : c_name = "doacross";
19737 : 133 : break;
19738 : 1473 : case PRAGMA_OMP_CLAUSE_MAP:
19739 : 1473 : clauses = c_parser_omp_clause_map (parser, clauses);
19740 : 1473 : c_name = "map";
19741 : 1473 : break;
19742 : 9 : case PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR:
19743 : 9 : clauses = c_parser_omp_clause_use_device_ptr (parser, clauses);
19744 : 9 : c_name = "use_device_ptr";
19745 : 9 : break;
19746 : 35 : case PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR:
19747 : 35 : clauses = c_parser_omp_clause_use_device_addr (parser, clauses);
19748 : 35 : c_name = "use_device_addr";
19749 : 35 : break;
19750 : 86 : case PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR:
19751 : 86 : clauses = c_parser_omp_clause_has_device_addr (parser, clauses);
19752 : 86 : c_name = "has_device_addr";
19753 : 86 : break;
19754 : 85 : case PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR:
19755 : 85 : clauses = c_parser_omp_clause_is_device_ptr (parser, clauses);
19756 : 85 : c_name = "is_device_ptr";
19757 : 85 : break;
19758 : 274 : case PRAGMA_OMP_CLAUSE_DEVICE:
19759 : 274 : clauses = c_parser_omp_clause_device (parser, clauses);
19760 : 274 : c_name = "device";
19761 : 274 : break;
19762 : 1582 : case PRAGMA_OMP_CLAUSE_DIST_SCHEDULE:
19763 : 1582 : clauses = c_parser_omp_clause_dist_schedule (parser, clauses);
19764 : 1582 : c_name = "dist_schedule";
19765 : 1582 : break;
19766 : 194 : case PRAGMA_OMP_CLAUSE_PROC_BIND:
19767 : 194 : clauses = c_parser_omp_clause_proc_bind (parser, clauses);
19768 : 194 : c_name = "proc_bind";
19769 : 194 : break;
19770 : 42 : case PRAGMA_OMP_CLAUSE_DEVICE_TYPE:
19771 : 42 : clauses = c_parser_omp_clause_device_type (parser, clauses);
19772 : 42 : c_name = "device_type";
19773 : 42 : break;
19774 : 227 : case PRAGMA_OMP_CLAUSE_SAFELEN:
19775 : 227 : clauses = c_parser_omp_clause_safelen (parser, clauses);
19776 : 227 : c_name = "safelen";
19777 : 227 : break;
19778 : 315 : case PRAGMA_OMP_CLAUSE_SIMDLEN:
19779 : 315 : clauses = c_parser_omp_clause_simdlen (parser, clauses);
19780 : 315 : c_name = "simdlen";
19781 : 315 : break;
19782 : 18 : case PRAGMA_OMP_CLAUSE_NOGROUP:
19783 : 18 : clauses = c_parser_omp_clause_nogroup (parser, clauses);
19784 : 18 : c_name = "nogroup";
19785 : 18 : break;
19786 : 42 : case PRAGMA_OMP_CLAUSE_THREADS:
19787 : 42 : clauses
19788 : 42 : = c_parser_omp_clause_orderedkind (parser, OMP_CLAUSE_THREADS,
19789 : : clauses);
19790 : 42 : c_name = "threads";
19791 : 42 : break;
19792 : 55 : case PRAGMA_OMP_CLAUSE_SIMD:
19793 : 55 : clauses
19794 : 55 : = c_parser_omp_clause_orderedkind (parser, OMP_CLAUSE_SIMD,
19795 : : clauses);
19796 : 55 : c_name = "simd";
19797 : 55 : break;
19798 : 38 : case PRAGMA_OMP_CLAUSE_ENTER:
19799 : 38 : clauses
19800 : 38 : = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ENTER,
19801 : : clauses);
19802 : 38 : c_name = "enter";
19803 : 38 : break;
19804 : 21 : default:
19805 : 21 : c_parser_error (parser, "expected an OpenMP clause");
19806 : 21 : goto saw_error;
19807 : : }
19808 : :
19809 : 25887 : first = false;
19810 : :
19811 : 25887 : if (((mask >> c_kind) & 1) == 0)
19812 : : {
19813 : : /* Remove the invalid clause(s) from the list to avoid
19814 : : confusing the rest of the compiler. */
19815 : 24 : clauses = prev;
19816 : 24 : error_at (here, "%qs is not valid for %qs", c_name, where);
19817 : : }
19818 : : }
19819 : :
19820 : 18553 : saw_error:
19821 : 18596 : if (!nested)
19822 : 18573 : c_parser_skip_to_pragma_eol (parser);
19823 : :
19824 : 18596 : if (finish_p)
19825 : : {
19826 : 10455 : if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM)) != 0)
19827 : 381 : return c_finish_omp_clauses (clauses, C_ORT_OMP_DECLARE_SIMD);
19828 : 10074 : return c_finish_omp_clauses (clauses, C_ORT_OMP);
19829 : : }
19830 : :
19831 : : return clauses;
19832 : : }
19833 : :
19834 : : /* OpenACC 2.0, OpenMP 2.5:
19835 : : structured-block:
19836 : : statement
19837 : :
19838 : : In practice, we're also interested in adding the statement to an
19839 : : outer node. So it is convenient if we work around the fact that
19840 : : c_parser_statement calls add_stmt. */
19841 : :
19842 : : static tree
19843 : 6180 : c_parser_omp_structured_block (c_parser *parser, bool *if_p)
19844 : : {
19845 : 6180 : tree stmt = push_stmt_list ();
19846 : 6180 : parser->omp_attrs_forbidden_p = true;
19847 : 6180 : c_parser_statement (parser, if_p);
19848 : 6180 : return pop_stmt_list (stmt);
19849 : : }
19850 : :
19851 : : /* OpenACC 2.0:
19852 : : # pragma acc cache (variable-list) new-line
19853 : :
19854 : : OpenACC 2.7:
19855 : : # pragma acc cache (readonly: variable-list) new-line
19856 : :
19857 : : LOC is the location of the #pragma token.
19858 : : */
19859 : :
19860 : : static tree
19861 : 137 : c_parser_oacc_cache (location_t loc, c_parser *parser)
19862 : : {
19863 : 137 : tree stmt, clauses = NULL_TREE;
19864 : 137 : bool readonly = false;
19865 : 137 : location_t open_loc = c_parser_peek_token (parser)->location;
19866 : 137 : matching_parens parens;
19867 : 137 : if (parens.require_open (parser))
19868 : : {
19869 : 135 : c_token *token = c_parser_peek_token (parser);
19870 : 135 : if (token->type == CPP_NAME
19871 : 131 : && !strcmp (IDENTIFIER_POINTER (token->value), "readonly")
19872 : 139 : && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
19873 : : {
19874 : 4 : c_parser_consume_token (parser);
19875 : 4 : c_parser_consume_token (parser);
19876 : 4 : readonly = true;
19877 : : }
19878 : 135 : clauses = c_parser_omp_variable_list (parser, open_loc,
19879 : : OMP_CLAUSE__CACHE_, NULL_TREE);
19880 : 135 : parens.skip_until_found_close (parser);
19881 : : }
19882 : :
19883 : 135 : if (readonly)
19884 : 8 : for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
19885 : 4 : OMP_CLAUSE__CACHE__READONLY (c) = 1;
19886 : :
19887 : 137 : clauses = c_finish_omp_clauses (clauses, C_ORT_ACC);
19888 : :
19889 : 137 : c_parser_skip_to_pragma_eol (parser);
19890 : :
19891 : 137 : stmt = make_node (OACC_CACHE);
19892 : 137 : TREE_TYPE (stmt) = void_type_node;
19893 : 137 : OACC_CACHE_CLAUSES (stmt) = clauses;
19894 : 137 : SET_EXPR_LOCATION (stmt, loc);
19895 : 137 : add_stmt (stmt);
19896 : :
19897 : 137 : return stmt;
19898 : : }
19899 : :
19900 : : /* OpenACC 2.0:
19901 : : # pragma acc data oacc-data-clause[optseq] new-line
19902 : : structured-block
19903 : :
19904 : : LOC is the location of the #pragma token.
19905 : : */
19906 : :
19907 : : #define OACC_DATA_CLAUSE_MASK \
19908 : : ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
19909 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
19910 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
19911 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
19912 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
19913 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
19914 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
19915 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
19916 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
19917 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
19918 : :
19919 : : static tree
19920 : 465 : c_parser_oacc_data (location_t loc, c_parser *parser, bool *if_p)
19921 : : {
19922 : 465 : tree stmt, clauses, block;
19923 : :
19924 : 465 : clauses = c_parser_oacc_all_clauses (parser, OACC_DATA_CLAUSE_MASK,
19925 : : "#pragma acc data");
19926 : :
19927 : 465 : block = c_begin_omp_parallel ();
19928 : 465 : add_stmt (c_parser_omp_structured_block (parser, if_p));
19929 : :
19930 : 465 : stmt = c_finish_oacc_data (loc, clauses, block);
19931 : :
19932 : 465 : return stmt;
19933 : : }
19934 : :
19935 : : /* OpenACC 2.0:
19936 : : # pragma acc declare oacc-data-clause[optseq] new-line
19937 : : */
19938 : :
19939 : : #define OACC_DECLARE_CLAUSE_MASK \
19940 : : ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
19941 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
19942 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
19943 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
19944 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
19945 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT) \
19946 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_LINK) \
19947 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
19948 : :
19949 : : static void
19950 : 142 : c_parser_oacc_declare (c_parser *parser)
19951 : : {
19952 : 142 : location_t pragma_loc = c_parser_peek_token (parser)->location;
19953 : 142 : tree clauses, stmt, t, decl;
19954 : :
19955 : 142 : bool error = false;
19956 : :
19957 : 142 : c_parser_consume_pragma (parser);
19958 : :
19959 : 142 : clauses = c_parser_oacc_all_clauses (parser, OACC_DECLARE_CLAUSE_MASK,
19960 : : "#pragma acc declare");
19961 : 142 : if (!clauses)
19962 : : {
19963 : 2 : error_at (pragma_loc,
19964 : : "no valid clauses specified in %<#pragma acc declare%>");
19965 : 2 : return;
19966 : : }
19967 : :
19968 : 292 : for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t))
19969 : : {
19970 : 152 : location_t loc = OMP_CLAUSE_LOCATION (t);
19971 : 152 : decl = OMP_CLAUSE_DECL (t);
19972 : 152 : if (!DECL_P (decl))
19973 : : {
19974 : 1 : error_at (loc, "array section in %<#pragma acc declare%>");
19975 : 1 : error = true;
19976 : 1 : continue;
19977 : : }
19978 : :
19979 : 151 : switch (OMP_CLAUSE_MAP_KIND (t))
19980 : : {
19981 : : case GOMP_MAP_FIRSTPRIVATE_POINTER:
19982 : : case GOMP_MAP_ALLOC:
19983 : : case GOMP_MAP_TO:
19984 : : case GOMP_MAP_FORCE_DEVICEPTR:
19985 : : case GOMP_MAP_DEVICE_RESIDENT:
19986 : : break;
19987 : :
19988 : 13 : case GOMP_MAP_LINK:
19989 : 13 : if (!global_bindings_p ()
19990 : 13 : && (TREE_STATIC (decl)
19991 : 6 : || !DECL_EXTERNAL (decl)))
19992 : : {
19993 : 2 : error_at (loc,
19994 : : "%qD must be a global variable in "
19995 : : "%<#pragma acc declare link%>",
19996 : : decl);
19997 : 2 : error = true;
19998 : 2 : continue;
19999 : : }
20000 : : break;
20001 : :
20002 : 42 : default:
20003 : 42 : if (global_bindings_p ())
20004 : : {
20005 : 5 : error_at (loc, "invalid OpenACC clause at file scope");
20006 : 5 : error = true;
20007 : 5 : continue;
20008 : : }
20009 : 37 : if (DECL_EXTERNAL (decl))
20010 : : {
20011 : 10 : error_at (loc,
20012 : : "invalid use of %<extern%> variable %qD "
20013 : : "in %<#pragma acc declare%>", decl);
20014 : 10 : error = true;
20015 : 10 : continue;
20016 : : }
20017 : 27 : else if (TREE_PUBLIC (decl))
20018 : : {
20019 : 2 : error_at (loc,
20020 : : "invalid use of %<global%> variable %qD "
20021 : : "in %<#pragma acc declare%>", decl);
20022 : 2 : error = true;
20023 : 2 : continue;
20024 : : }
20025 : : break;
20026 : : }
20027 : :
20028 : 132 : if (!c_check_in_current_scope (decl))
20029 : : {
20030 : 2 : error_at (loc,
20031 : : "%qD must be a variable declared in the same scope as "
20032 : : "%<#pragma acc declare%>", decl);
20033 : 2 : error = true;
20034 : 2 : continue;
20035 : : }
20036 : :
20037 : 130 : if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl))
20038 : 246 : || lookup_attribute ("omp declare target link",
20039 : 116 : DECL_ATTRIBUTES (decl)))
20040 : : {
20041 : 17 : error_at (loc, "variable %qD used more than once with "
20042 : : "%<#pragma acc declare%>", decl);
20043 : 17 : error = true;
20044 : 17 : continue;
20045 : : }
20046 : :
20047 : 113 : if (!error)
20048 : : {
20049 : 113 : tree id;
20050 : :
20051 : 113 : if (OMP_CLAUSE_MAP_KIND (t) == GOMP_MAP_LINK)
20052 : 7 : id = get_identifier ("omp declare target link");
20053 : : else
20054 : 106 : id = get_identifier ("omp declare target");
20055 : :
20056 : 113 : DECL_ATTRIBUTES (decl)
20057 : 113 : = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (decl));
20058 : :
20059 : 113 : if (global_bindings_p ())
20060 : : {
20061 : 43 : symtab_node *node = symtab_node::get (decl);
20062 : 43 : if (node != NULL)
20063 : : {
20064 : 31 : node->offloadable = 1;
20065 : 31 : if (ENABLE_OFFLOADING)
20066 : : {
20067 : : g->have_offload = true;
20068 : : if (is_a <varpool_node *> (node))
20069 : : vec_safe_push (offload_vars, decl);
20070 : : }
20071 : : }
20072 : : }
20073 : : }
20074 : : }
20075 : :
20076 : 140 : if (error || global_bindings_p ())
20077 : 72 : return;
20078 : :
20079 : 68 : stmt = make_node (OACC_DECLARE);
20080 : 68 : TREE_TYPE (stmt) = void_type_node;
20081 : 68 : OACC_DECLARE_CLAUSES (stmt) = clauses;
20082 : 68 : SET_EXPR_LOCATION (stmt, pragma_loc);
20083 : :
20084 : 68 : add_stmt (stmt);
20085 : :
20086 : 68 : return;
20087 : : }
20088 : :
20089 : : /* OpenACC 2.0:
20090 : : # pragma acc enter data oacc-enter-data-clause[optseq] new-line
20091 : :
20092 : : or
20093 : :
20094 : : # pragma acc exit data oacc-exit-data-clause[optseq] new-line
20095 : :
20096 : :
20097 : : LOC is the location of the #pragma token.
20098 : : */
20099 : :
20100 : : #define OACC_ENTER_DATA_CLAUSE_MASK \
20101 : : ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
20102 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
20103 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
20104 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
20105 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
20106 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
20107 : :
20108 : : #define OACC_EXIT_DATA_CLAUSE_MASK \
20109 : : ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
20110 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
20111 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
20112 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DELETE) \
20113 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DETACH) \
20114 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FINALIZE) \
20115 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
20116 : :
20117 : : static void
20118 : 258 : c_parser_oacc_enter_exit_data (c_parser *parser, bool enter)
20119 : : {
20120 : 258 : location_t loc = c_parser_peek_token (parser)->location;
20121 : 258 : tree clauses, stmt;
20122 : 258 : const char *p = "";
20123 : :
20124 : 258 : c_parser_consume_pragma (parser);
20125 : :
20126 : 258 : if (c_parser_next_token_is (parser, CPP_NAME))
20127 : : {
20128 : 255 : p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20129 : 255 : c_parser_consume_token (parser);
20130 : : }
20131 : :
20132 : 258 : if (strcmp (p, "data") != 0)
20133 : : {
20134 : 8 : error_at (loc, "expected %<data%> after %<#pragma acc %s%>",
20135 : : enter ? "enter" : "exit");
20136 : 6 : parser->error = true;
20137 : 6 : c_parser_skip_to_pragma_eol (parser);
20138 : 6 : return;
20139 : : }
20140 : :
20141 : 252 : if (enter)
20142 : 127 : clauses = c_parser_oacc_all_clauses (parser, OACC_ENTER_DATA_CLAUSE_MASK,
20143 : : "#pragma acc enter data");
20144 : : else
20145 : 125 : clauses = c_parser_oacc_all_clauses (parser, OACC_EXIT_DATA_CLAUSE_MASK,
20146 : : "#pragma acc exit data");
20147 : :
20148 : 252 : if (omp_find_clause (clauses, OMP_CLAUSE_MAP) == NULL_TREE)
20149 : : {
20150 : 15 : error_at (loc, "%<#pragma acc %s data%> has no data movement clause",
20151 : : enter ? "enter" : "exit");
20152 : 15 : return;
20153 : : }
20154 : :
20155 : 237 : stmt = enter ? make_node (OACC_ENTER_DATA) : make_node (OACC_EXIT_DATA);
20156 : 237 : TREE_TYPE (stmt) = void_type_node;
20157 : 237 : OMP_STANDALONE_CLAUSES (stmt) = clauses;
20158 : 237 : SET_EXPR_LOCATION (stmt, loc);
20159 : 237 : add_stmt (stmt);
20160 : : }
20161 : :
20162 : :
20163 : : /* OpenACC 2.0:
20164 : : # pragma acc host_data oacc-data-clause[optseq] new-line
20165 : : structured-block
20166 : : */
20167 : :
20168 : : #define OACC_HOST_DATA_CLAUSE_MASK \
20169 : : ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_USE_DEVICE) \
20170 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
20171 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) )
20172 : :
20173 : : static tree
20174 : 23 : c_parser_oacc_host_data (location_t loc, c_parser *parser, bool *if_p)
20175 : : {
20176 : 23 : tree stmt, clauses, block;
20177 : :
20178 : 23 : clauses = c_parser_oacc_all_clauses (parser, OACC_HOST_DATA_CLAUSE_MASK,
20179 : : "#pragma acc host_data", false);
20180 : 23 : if (!omp_find_clause (clauses, OMP_CLAUSE_USE_DEVICE_PTR))
20181 : : {
20182 : 2 : error_at (loc, "%<host_data%> construct requires %<use_device%> clause");
20183 : 2 : return error_mark_node;
20184 : : }
20185 : 21 : clauses = c_finish_omp_clauses (clauses, C_ORT_ACC);
20186 : 21 : block = c_begin_omp_parallel ();
20187 : 21 : add_stmt (c_parser_omp_structured_block (parser, if_p));
20188 : 21 : stmt = c_finish_oacc_host_data (loc, clauses, block);
20189 : 21 : return stmt;
20190 : : }
20191 : :
20192 : :
20193 : : /* OpenACC 2.0:
20194 : :
20195 : : # pragma acc loop oacc-loop-clause[optseq] new-line
20196 : : structured-block
20197 : :
20198 : : LOC is the location of the #pragma token.
20199 : : */
20200 : :
20201 : : #define OACC_LOOP_CLAUSE_MASK \
20202 : : ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COLLAPSE) \
20203 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
20204 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
20205 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
20206 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
20207 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
20208 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_AUTO) \
20209 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_INDEPENDENT) \
20210 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \
20211 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_TILE) )
20212 : : static tree
20213 : 2151 : c_parser_oacc_loop (location_t loc, c_parser *parser, char *p_name,
20214 : : omp_clause_mask mask, tree *cclauses, bool *if_p)
20215 : : {
20216 : 2151 : bool is_parallel = ((mask >> PRAGMA_OACC_CLAUSE_REDUCTION) & 1) == 1;
20217 : :
20218 : 2151 : strcat (p_name, " loop");
20219 : 2151 : mask |= OACC_LOOP_CLAUSE_MASK;
20220 : :
20221 : 2151 : tree clauses = c_parser_oacc_all_clauses (parser, mask, p_name,
20222 : : /*finish_p=*/cclauses == NULL,
20223 : : /*target=*/is_parallel);
20224 : 2151 : if (cclauses)
20225 : : {
20226 : 626 : clauses = c_oacc_split_loop_clauses (clauses, cclauses, is_parallel);
20227 : 626 : if (*cclauses)
20228 : 145 : *cclauses = c_finish_omp_clauses (*cclauses, C_ORT_ACC_TARGET);
20229 : 626 : if (clauses)
20230 : 230 : clauses = c_finish_omp_clauses (clauses, C_ORT_ACC);
20231 : : }
20232 : :
20233 : 2151 : tree block = c_begin_compound_stmt (true);
20234 : 2151 : tree stmt = c_parser_omp_for_loop (loc, parser, OACC_LOOP, clauses, NULL,
20235 : : if_p);
20236 : 2151 : block = c_end_compound_stmt (loc, block, true);
20237 : 2151 : add_stmt (block);
20238 : :
20239 : 2151 : return stmt;
20240 : : }
20241 : :
20242 : : /* OpenACC 2.0:
20243 : : # pragma acc kernels oacc-kernels-clause[optseq] new-line
20244 : : structured-block
20245 : :
20246 : : or
20247 : :
20248 : : # pragma acc parallel oacc-parallel-clause[optseq] new-line
20249 : : structured-block
20250 : :
20251 : : OpenACC 2.6:
20252 : :
20253 : : # pragma acc serial oacc-serial-clause[optseq] new-line
20254 : : structured-block
20255 : :
20256 : : LOC is the location of the #pragma token.
20257 : : */
20258 : :
20259 : : #define OACC_KERNELS_CLAUSE_MASK \
20260 : : ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
20261 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
20262 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
20263 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
20264 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
20265 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
20266 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
20267 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
20268 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
20269 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
20270 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
20271 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
20272 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
20273 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SELF) \
20274 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
20275 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
20276 : :
20277 : : #define OACC_PARALLEL_CLAUSE_MASK \
20278 : : ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
20279 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
20280 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
20281 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
20282 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
20283 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
20284 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
20285 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
20286 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
20287 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
20288 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
20289 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
20290 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
20291 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
20292 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
20293 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
20294 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SELF) \
20295 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
20296 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
20297 : :
20298 : : #define OACC_SERIAL_CLAUSE_MASK \
20299 : : ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
20300 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
20301 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
20302 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
20303 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
20304 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
20305 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
20306 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
20307 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
20308 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
20309 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
20310 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
20311 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
20312 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
20313 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SELF) \
20314 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
20315 : :
20316 : : static tree
20317 : 1982 : c_parser_oacc_compute (location_t loc, c_parser *parser,
20318 : : enum pragma_kind p_kind, char *p_name, bool *if_p)
20319 : : {
20320 : 1982 : omp_clause_mask mask;
20321 : 1982 : enum tree_code code;
20322 : 1982 : switch (p_kind)
20323 : : {
20324 : 515 : case PRAGMA_OACC_KERNELS:
20325 : 515 : strcat (p_name, " kernels");
20326 : 515 : mask = OACC_KERNELS_CLAUSE_MASK;
20327 : 515 : code = OACC_KERNELS;
20328 : 515 : break;
20329 : 1444 : case PRAGMA_OACC_PARALLEL:
20330 : 1444 : strcat (p_name, " parallel");
20331 : 1444 : mask = OACC_PARALLEL_CLAUSE_MASK;
20332 : 1444 : code = OACC_PARALLEL;
20333 : 1444 : break;
20334 : 23 : case PRAGMA_OACC_SERIAL:
20335 : 23 : strcat (p_name, " serial");
20336 : 23 : mask = OACC_SERIAL_CLAUSE_MASK;
20337 : 23 : code = OACC_SERIAL;
20338 : 23 : break;
20339 : 0 : default:
20340 : 0 : gcc_unreachable ();
20341 : : }
20342 : :
20343 : 1982 : if (c_parser_next_token_is (parser, CPP_NAME))
20344 : : {
20345 : 1623 : const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20346 : 1623 : if (strcmp (p, "loop") == 0)
20347 : : {
20348 : 626 : c_parser_consume_token (parser);
20349 : 626 : tree block = c_begin_omp_parallel ();
20350 : 626 : tree clauses;
20351 : 626 : c_parser_oacc_loop (loc, parser, p_name, mask, &clauses, if_p);
20352 : 626 : return c_finish_omp_construct (loc, code, block, clauses);
20353 : : }
20354 : : }
20355 : :
20356 : 1356 : tree clauses = c_parser_oacc_all_clauses (parser, mask, p_name,
20357 : : /*finish_p=*/true,
20358 : : /*target=*/true);
20359 : :
20360 : 1356 : tree block = c_begin_omp_parallel ();
20361 : 1356 : add_stmt (c_parser_omp_structured_block (parser, if_p));
20362 : :
20363 : 1356 : return c_finish_omp_construct (loc, code, block, clauses);
20364 : : }
20365 : :
20366 : : /* OpenACC 2.0:
20367 : : # pragma acc routine oacc-routine-clause[optseq] new-line
20368 : : function-definition
20369 : :
20370 : : # pragma acc routine ( name ) oacc-routine-clause[optseq] new-line
20371 : : */
20372 : :
20373 : : #define OACC_ROUTINE_CLAUSE_MASK \
20374 : : ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
20375 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
20376 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
20377 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \
20378 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NOHOST) )
20379 : :
20380 : : /* Parse an OpenACC routine directive. For named directives, we apply
20381 : : immediately to the named function. For unnamed ones we then parse
20382 : : a declaration or definition, which must be for a function. */
20383 : :
20384 : : static void
20385 : 332 : c_parser_oacc_routine (c_parser *parser, enum pragma_context context)
20386 : : {
20387 : 332 : gcc_checking_assert (context == pragma_external);
20388 : :
20389 : 332 : oacc_routine_data data;
20390 : 332 : data.error_seen = false;
20391 : 332 : data.fndecl_seen = false;
20392 : 332 : data.loc = c_parser_peek_token (parser)->location;
20393 : :
20394 : 332 : c_parser_consume_pragma (parser);
20395 : :
20396 : : /* Look for optional '( name )'. */
20397 : 332 : if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
20398 : : {
20399 : 143 : c_parser_consume_token (parser); /* '(' */
20400 : :
20401 : 143 : tree decl = NULL_TREE;
20402 : 143 : c_token *name_token = c_parser_peek_token (parser);
20403 : 143 : location_t name_loc = name_token->location;
20404 : 143 : if (name_token->type == CPP_NAME
20405 : 135 : && (name_token->id_kind == C_ID_ID
20406 : : || name_token->id_kind == C_ID_TYPENAME))
20407 : : {
20408 : 135 : decl = lookup_name (name_token->value);
20409 : 135 : if (!decl)
20410 : 5 : error_at (name_loc,
20411 : : "%qE has not been declared", name_token->value);
20412 : 135 : c_parser_consume_token (parser);
20413 : : }
20414 : : else
20415 : 8 : c_parser_error (parser, "expected function name");
20416 : :
20417 : 8 : if (!decl
20418 : 135 : || !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
20419 : : {
20420 : 15 : c_parser_skip_to_pragma_eol (parser, false);
20421 : 43 : return;
20422 : : }
20423 : :
20424 : 128 : data.clauses
20425 : 128 : = c_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK,
20426 : : "#pragma acc routine");
20427 : : /* The clauses are in reverse order; fix that to make later diagnostic
20428 : : emission easier. */
20429 : 128 : data.clauses = nreverse (data.clauses);
20430 : :
20431 : 128 : if (TREE_CODE (decl) != FUNCTION_DECL)
20432 : : {
20433 : 3 : error_at (name_loc, "%qD does not refer to a function", decl);
20434 : 3 : return;
20435 : : }
20436 : :
20437 : 125 : c_finish_oacc_routine (&data, decl, false);
20438 : : }
20439 : : else /* No optional '( name )'. */
20440 : : {
20441 : 189 : data.clauses
20442 : 189 : = c_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK,
20443 : : "#pragma acc routine");
20444 : : /* The clauses are in reverse order; fix that to make later diagnostic
20445 : : emission easier. */
20446 : 189 : data.clauses = nreverse (data.clauses);
20447 : :
20448 : : /* Emit a helpful diagnostic if there's another pragma following this
20449 : : one. Also don't allow a static assertion declaration, as in the
20450 : : following we'll just parse a *single* "declaration or function
20451 : : definition", and the static assertion counts an one. */
20452 : 189 : if (c_parser_next_token_is (parser, CPP_PRAGMA)
20453 : 369 : || c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
20454 : : {
20455 : 10 : error_at (data.loc,
20456 : : "%<#pragma acc routine%> not immediately followed by"
20457 : : " function declaration or definition");
20458 : : /* ..., and then just keep going. */
20459 : 10 : return;
20460 : : }
20461 : :
20462 : : /* We only have to consider the pragma_external case here. */
20463 : 179 : if (c_parser_next_token_is (parser, CPP_KEYWORD)
20464 : 179 : && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
20465 : : {
20466 : 3 : int ext = disable_extension_diagnostics ();
20467 : 7 : do
20468 : 7 : c_parser_consume_token (parser);
20469 : 7 : while (c_parser_next_token_is (parser, CPP_KEYWORD)
20470 : 10 : && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
20471 : 3 : c_parser_declaration_or_fndef (parser, true, true, true, false, true,
20472 : : NULL, NULL, false, NULL, &data);
20473 : 3 : restore_extension_diagnostics (ext);
20474 : : }
20475 : : else
20476 : 176 : c_parser_declaration_or_fndef (parser, true, true, true, false, true,
20477 : : NULL, NULL, false, NULL, &data);
20478 : : }
20479 : : }
20480 : :
20481 : : /* Finalize an OpenACC routine pragma, applying it to FNDECL.
20482 : : IS_DEFN is true if we're applying it to the definition. */
20483 : :
20484 : : static void
20485 : 314 : c_finish_oacc_routine (struct oacc_routine_data *data, tree fndecl,
20486 : : bool is_defn)
20487 : : {
20488 : : /* Keep going if we're in error reporting mode. */
20489 : 314 : if (data->error_seen
20490 : 308 : || fndecl == error_mark_node)
20491 : : return;
20492 : :
20493 : 308 : if (data->fndecl_seen)
20494 : : {
20495 : 4 : error_at (data->loc,
20496 : : "%<#pragma acc routine%> not immediately followed by"
20497 : : " a single function declaration or definition");
20498 : 4 : data->error_seen = true;
20499 : 4 : return;
20500 : : }
20501 : 304 : if (fndecl == NULL_TREE || TREE_CODE (fndecl) != FUNCTION_DECL)
20502 : : {
20503 : 10 : error_at (data->loc,
20504 : : "%<#pragma acc routine%> not immediately followed by"
20505 : : " function declaration or definition");
20506 : 10 : data->error_seen = true;
20507 : 10 : return;
20508 : : }
20509 : :
20510 : 294 : int compatible
20511 : 294 : = oacc_verify_routine_clauses (fndecl, &data->clauses, data->loc,
20512 : : "#pragma acc routine");
20513 : 294 : if (compatible < 0)
20514 : : {
20515 : 47 : data->error_seen = true;
20516 : 47 : return;
20517 : : }
20518 : 247 : if (compatible > 0)
20519 : : {
20520 : : }
20521 : : else
20522 : : {
20523 : 256 : if (TREE_USED (fndecl) || (!is_defn && DECL_SAVED_TREE (fndecl)))
20524 : : {
20525 : 3 : error_at (data->loc,
20526 : : TREE_USED (fndecl)
20527 : : ? G_("%<#pragma acc routine%> must be applied before use")
20528 : : : G_("%<#pragma acc routine%> must be applied before"
20529 : : " definition"));
20530 : 2 : data->error_seen = true;
20531 : 2 : return;
20532 : : }
20533 : :
20534 : : /* Set the routine's level of parallelism. */
20535 : 184 : tree dims = oacc_build_routine_dims (data->clauses);
20536 : 184 : oacc_replace_fn_attrib (fndecl, dims);
20537 : :
20538 : : /* Add an "omp declare target" attribute. */
20539 : 184 : DECL_ATTRIBUTES (fndecl)
20540 : 368 : = tree_cons (get_identifier ("omp declare target"),
20541 : 184 : data->clauses, DECL_ATTRIBUTES (fndecl));
20542 : : }
20543 : :
20544 : : /* Remember that we've used this "#pragma acc routine". */
20545 : 245 : data->fndecl_seen = true;
20546 : : }
20547 : :
20548 : : /* OpenACC 2.0:
20549 : : # pragma acc update oacc-update-clause[optseq] new-line
20550 : : */
20551 : :
20552 : : #define OACC_UPDATE_CLAUSE_MASK \
20553 : : ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
20554 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE) \
20555 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_HOST) \
20556 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
20557 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) \
20558 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SELF) \
20559 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
20560 : :
20561 : : static void
20562 : 91 : c_parser_oacc_update (c_parser *parser)
20563 : : {
20564 : 91 : location_t loc = c_parser_peek_token (parser)->location;
20565 : :
20566 : 91 : c_parser_consume_pragma (parser);
20567 : :
20568 : 91 : tree clauses = c_parser_oacc_all_clauses (parser, OACC_UPDATE_CLAUSE_MASK,
20569 : : "#pragma acc update");
20570 : 91 : if (omp_find_clause (clauses, OMP_CLAUSE_MAP) == NULL_TREE)
20571 : : {
20572 : 1 : error_at (loc,
20573 : : "%<#pragma acc update%> must contain at least one "
20574 : : "%<device%> or %<host%> or %<self%> clause");
20575 : 1 : return;
20576 : : }
20577 : :
20578 : 90 : if (parser->error)
20579 : : return;
20580 : :
20581 : 90 : tree stmt = make_node (OACC_UPDATE);
20582 : 90 : TREE_TYPE (stmt) = void_type_node;
20583 : 90 : OACC_UPDATE_CLAUSES (stmt) = clauses;
20584 : 90 : SET_EXPR_LOCATION (stmt, loc);
20585 : 90 : add_stmt (stmt);
20586 : : }
20587 : :
20588 : : /* OpenACC 2.0:
20589 : : # pragma acc wait [(intseq)] oacc-wait-clause[optseq] new-line
20590 : :
20591 : : LOC is the location of the #pragma token.
20592 : : */
20593 : :
20594 : : #define OACC_WAIT_CLAUSE_MASK \
20595 : : ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) )
20596 : :
20597 : : static tree
20598 : 80 : c_parser_oacc_wait (location_t loc, c_parser *parser, char *p_name)
20599 : : {
20600 : 80 : tree clauses, list = NULL_TREE, stmt = NULL_TREE;
20601 : :
20602 : 80 : if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
20603 : 43 : list = c_parser_oacc_wait_list (parser, loc, list);
20604 : :
20605 : 80 : strcpy (p_name, " wait");
20606 : 80 : clauses = c_parser_oacc_all_clauses (parser, OACC_WAIT_CLAUSE_MASK, p_name);
20607 : 80 : stmt = c_finish_oacc_wait (loc, list, clauses);
20608 : 80 : add_stmt (stmt);
20609 : :
20610 : 80 : return stmt;
20611 : : }
20612 : :
20613 : : struct c_omp_loc_tree
20614 : : {
20615 : : location_t loc;
20616 : : tree var;
20617 : : };
20618 : :
20619 : : /* Check whether the expression used in the allocator clause is declared or
20620 : : modified between the variable declaration and its allocate directive. */
20621 : : static tree
20622 : 29 : c_check_omp_allocate_allocator_r (tree *tp, int *, void *data)
20623 : : {
20624 : 29 : tree var = ((struct c_omp_loc_tree *) data)->var;
20625 : 29 : location_t loc = ((struct c_omp_loc_tree *) data)->loc;
20626 : 29 : if (TREE_CODE (*tp) == VAR_DECL && c_check_in_current_scope (*tp))
20627 : : {
20628 : 10 : if (linemap_location_before_p (line_table, DECL_SOURCE_LOCATION (var),
20629 : 10 : DECL_SOURCE_LOCATION (*tp)))
20630 : : {
20631 : 2 : error_at (loc, "variable %qD used in the %<allocator%> clause must "
20632 : : "be declared before %qD", *tp, var);
20633 : 2 : inform (DECL_SOURCE_LOCATION (*tp), "declared here");
20634 : 2 : inform (DECL_SOURCE_LOCATION (var),
20635 : : "to be allocated variable declared here");
20636 : 2 : return *tp;
20637 : : }
20638 : : else
20639 : : {
20640 : 8 : gcc_assert (cur_stmt_list
20641 : : && TREE_CODE (cur_stmt_list) == STATEMENT_LIST);
20642 : :
20643 : 8 : tree_stmt_iterator l = tsi_last (cur_stmt_list);
20644 : 9 : while (!tsi_end_p (l))
20645 : : {
20646 : 9 : if (linemap_location_before_p (line_table, EXPR_LOCATION (*l),
20647 : 9 : DECL_SOURCE_LOCATION (var)))
20648 : : break;
20649 : 3 : if (TREE_CODE (*l) == MODIFY_EXPR
20650 : 3 : && TREE_OPERAND (*l, 0) == *tp)
20651 : : {
20652 : 2 : error_at (loc,
20653 : : "variable %qD used in the %<allocator%> clause "
20654 : : "must not be modified between declaration of %qD "
20655 : : "and its %<allocate%> directive", *tp, var);
20656 : 2 : inform (EXPR_LOCATION (*l), "modified here");
20657 : 2 : inform (DECL_SOURCE_LOCATION (var),
20658 : : "to be allocated variable declared here");
20659 : 2 : return *tp;
20660 : : }
20661 : 1 : --l;
20662 : : }
20663 : : }
20664 : : }
20665 : : return NULL_TREE;
20666 : : }
20667 : :
20668 : : /* OpenMP 5.x:
20669 : : # pragma omp allocate (list) clauses
20670 : :
20671 : : OpenMP 5.0 clause:
20672 : : allocator (omp_allocator_handle_t expression)
20673 : :
20674 : : OpenMP 5.1 additional clause:
20675 : : align (constant-expression)] */
20676 : :
20677 : : static void
20678 : 57 : c_parser_omp_allocate (c_parser *parser)
20679 : : {
20680 : 57 : tree alignment = NULL_TREE;
20681 : 57 : tree allocator = NULL_TREE;
20682 : 57 : c_parser_consume_pragma (parser);
20683 : 57 : location_t loc = c_parser_peek_token (parser)->location;
20684 : 57 : location_t allocator_loc = UNKNOWN_LOCATION;
20685 : 57 : tree nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ALLOCATE, NULL_TREE);
20686 : 159 : do
20687 : : {
20688 : 108 : if (c_parser_next_token_is (parser, CPP_COMMA)
20689 : 108 : && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
20690 : 5 : c_parser_consume_token (parser);
20691 : 108 : if (!c_parser_next_token_is (parser, CPP_NAME))
20692 : : break;
20693 : 54 : matching_parens parens;
20694 : 54 : const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20695 : 54 : c_parser_consume_token (parser);
20696 : 54 : location_t expr_loc = c_parser_peek_token (parser)->location;
20697 : 54 : if (strcmp ("align", p) != 0 && strcmp ("allocator", p) != 0)
20698 : : {
20699 : 1 : error_at (c_parser_peek_token (parser)->location,
20700 : : "expected %<allocator%> or %<align%>");
20701 : 1 : break;
20702 : : }
20703 : 53 : if (!parens.require_open (parser))
20704 : : break;
20705 : :
20706 : 53 : c_expr expr = c_parser_expr_no_commas (parser, NULL);
20707 : 53 : expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
20708 : 53 : expr_loc = c_parser_peek_token (parser)->location;
20709 : 53 : if (expr.value == error_mark_node)
20710 : : ;
20711 : 52 : else if (p[2] == 'i' && alignment)
20712 : : {
20713 : 1 : error_at (expr_loc, "too many %qs clauses", "align");
20714 : 1 : break;
20715 : : }
20716 : 51 : else if (p[2] == 'i')
20717 : : {
20718 : 21 : alignment = c_fully_fold (expr.value, false, NULL);
20719 : 21 : if (TREE_CODE (alignment) != INTEGER_CST
20720 : 20 : || !INTEGRAL_TYPE_P (TREE_TYPE (alignment))
20721 : 20 : || tree_int_cst_sgn (alignment) != 1
20722 : 40 : || !integer_pow2p (alignment))
20723 : : {
20724 : 4 : error_at (expr_loc, "%<align%> clause argument needs to be "
20725 : : "positive constant power of two integer "
20726 : : "expression");
20727 : 4 : alignment = NULL_TREE;
20728 : : }
20729 : : }
20730 : 30 : else if (allocator)
20731 : : {
20732 : 1 : error_at (expr_loc, "too many %qs clauses", "allocator");
20733 : 1 : break;
20734 : : }
20735 : : else
20736 : : {
20737 : 29 : allocator = c_fully_fold (expr.value, false, NULL);
20738 : 29 : allocator_loc = expr_loc;
20739 : 29 : tree orig_type
20740 : 29 : = expr.original_type ? expr.original_type : TREE_TYPE (allocator);
20741 : 29 : orig_type = TYPE_MAIN_VARIANT (orig_type);
20742 : 30 : if (!INTEGRAL_TYPE_P (TREE_TYPE (allocator))
20743 : 29 : || TREE_CODE (orig_type) != ENUMERAL_TYPE
20744 : 85 : || TYPE_NAME (orig_type)
20745 : 28 : != get_identifier ("omp_allocator_handle_t"))
20746 : : {
20747 : 1 : error_at (expr_loc,
20748 : : "%<allocator%> clause allocator expression has type "
20749 : : "%qT rather than %<omp_allocator_handle_t%>",
20750 : 1 : TREE_TYPE (allocator));
20751 : 1 : allocator = NULL_TREE;
20752 : : }
20753 : : }
20754 : 51 : parens.skip_until_found_close (parser);
20755 : 51 : } while (true);
20756 : 57 : c_parser_skip_to_pragma_eol (parser);
20757 : :
20758 : 57 : c_mark_decl_jump_unsafe_in_current_scope ();
20759 : 124 : for (tree c = nl; c != NULL_TREE; c = OMP_CLAUSE_CHAIN (c))
20760 : : {
20761 : 67 : tree var = OMP_CLAUSE_DECL (c);
20762 : 67 : if (TREE_CODE (var) == PARM_DECL)
20763 : : {
20764 : 1 : error_at (OMP_CLAUSE_LOCATION (nl),
20765 : : "function parameter %qD may not appear as list item in an "
20766 : : "%<allocate%> directive", var);
20767 : 1 : continue;
20768 : : }
20769 : 66 : if (!c_check_in_current_scope (var))
20770 : : {
20771 : 2 : error_at (OMP_CLAUSE_LOCATION (nl),
20772 : : "%<allocate%> directive must be in the same scope as %qD",
20773 : : var);
20774 : 2 : inform (DECL_SOURCE_LOCATION (var), "declared here");
20775 : 2 : continue;
20776 : : }
20777 : 64 : if (lookup_attribute ("omp allocate", DECL_ATTRIBUTES (var)))
20778 : : {
20779 : 1 : error_at (OMP_CLAUSE_LOCATION (nl),
20780 : : "%qD already appeared as list item in an "
20781 : : "%<allocate%> directive", var);
20782 : 1 : continue;
20783 : : }
20784 : 63 : if (TREE_STATIC (var))
20785 : : {
20786 : 10 : if (allocator == NULL_TREE && allocator_loc == UNKNOWN_LOCATION)
20787 : 3 : error_at (loc, "%<allocator%> clause required for "
20788 : : "static variable %qD", var);
20789 : 7 : else if (allocator
20790 : 7 : && (wi::to_widest (allocator) < 1
20791 : 6 : || wi::to_widest (allocator) > 8))
20792 : : /* 8 = largest predefined memory allocator. */
20793 : 3 : error_at (allocator_loc,
20794 : : "%<allocator%> clause requires a predefined allocator as "
20795 : : "%qD is static", var);
20796 : : else
20797 : 4 : sorry_at (OMP_CLAUSE_LOCATION (nl),
20798 : : "%<#pragma omp allocate%> for static variables like "
20799 : : "%qD not yet supported", var);
20800 : 10 : continue;
20801 : : }
20802 : 53 : if (allocator)
20803 : : {
20804 : 21 : struct c_omp_loc_tree data
20805 : 40 : = {EXPR_LOC_OR_LOC (allocator, OMP_CLAUSE_LOCATION (nl)), var};
20806 : 21 : walk_tree (&allocator, c_check_omp_allocate_allocator_r, &data, NULL);
20807 : : }
20808 : 53 : DECL_ATTRIBUTES (var) = tree_cons (get_identifier ("omp allocate"),
20809 : : build_tree_list (allocator, alignment),
20810 : 53 : DECL_ATTRIBUTES (var));
20811 : : }
20812 : 57 : }
20813 : :
20814 : : /* OpenMP 2.5:
20815 : : # pragma omp atomic new-line
20816 : : expression-stmt
20817 : :
20818 : : expression-stmt:
20819 : : x binop= expr | x++ | ++x | x-- | --x
20820 : : binop:
20821 : : +, *, -, /, &, ^, |, <<, >>
20822 : :
20823 : : where x is an lvalue expression with scalar type.
20824 : :
20825 : : OpenMP 3.1:
20826 : : # pragma omp atomic new-line
20827 : : update-stmt
20828 : :
20829 : : # pragma omp atomic read new-line
20830 : : read-stmt
20831 : :
20832 : : # pragma omp atomic write new-line
20833 : : write-stmt
20834 : :
20835 : : # pragma omp atomic update new-line
20836 : : update-stmt
20837 : :
20838 : : # pragma omp atomic capture new-line
20839 : : capture-stmt
20840 : :
20841 : : # pragma omp atomic capture new-line
20842 : : capture-block
20843 : :
20844 : : read-stmt:
20845 : : v = x
20846 : : write-stmt:
20847 : : x = expr
20848 : : update-stmt:
20849 : : expression-stmt | x = x binop expr
20850 : : capture-stmt:
20851 : : v = expression-stmt
20852 : : capture-block:
20853 : : { v = x; update-stmt; } | { update-stmt; v = x; }
20854 : :
20855 : : OpenMP 4.0:
20856 : : update-stmt:
20857 : : expression-stmt | x = x binop expr | x = expr binop x
20858 : : capture-stmt:
20859 : : v = update-stmt
20860 : : capture-block:
20861 : : { v = x; update-stmt; } | { update-stmt; v = x; } | { v = x; x = expr; }
20862 : :
20863 : : OpenMP 5.1:
20864 : : # pragma omp atomic compare new-line
20865 : : conditional-update-atomic
20866 : :
20867 : : # pragma omp atomic compare capture new-line
20868 : : conditional-update-capture-atomic
20869 : :
20870 : : conditional-update-atomic:
20871 : : cond-expr-stmt | cond-update-stmt
20872 : : cond-expr-stmt:
20873 : : x = expr ordop x ? expr : x;
20874 : : x = x ordop expr ? expr : x;
20875 : : x = x == e ? d : x;
20876 : : cond-update-stmt:
20877 : : if (expr ordop x) { x = expr; }
20878 : : if (x ordop expr) { x = expr; }
20879 : : if (x == e) { x = d; }
20880 : : ordop:
20881 : : <, >
20882 : : conditional-update-capture-atomic:
20883 : : v = cond-expr-stmt
20884 : : { v = x; cond-expr-stmt }
20885 : : { cond-expr-stmt v = x; }
20886 : : { v = x; cond-update-stmt }
20887 : : { cond-update-stmt v = x; }
20888 : : if (x == e) { x = d; } else { v = x; }
20889 : : { r = x == e; if (r) { x = d; } }
20890 : : { r = x == e; if (r) { x = d; } else { v = x; } }
20891 : :
20892 : : where x, r and v are lvalue expressions with scalar type,
20893 : : expr, e and d are expressions with scalar type and e might be
20894 : : the same as v.
20895 : :
20896 : : LOC is the location of the #pragma token. */
20897 : :
20898 : : static void
20899 : 1708 : c_parser_omp_atomic (location_t loc, c_parser *parser, bool openacc)
20900 : : {
20901 : 1708 : tree lhs = NULL_TREE, rhs = NULL_TREE, v = NULL_TREE, r = NULL_TREE;
20902 : 1708 : tree lhs1 = NULL_TREE, rhs1 = NULL_TREE;
20903 : 1708 : tree stmt, orig_lhs, unfolded_lhs = NULL_TREE, unfolded_lhs1 = NULL_TREE;
20904 : 1708 : enum tree_code code = ERROR_MARK, opcode = NOP_EXPR;
20905 : 1708 : enum omp_memory_order memory_order = OMP_MEMORY_ORDER_UNSPECIFIED;
20906 : 1708 : struct c_expr expr;
20907 : 1708 : location_t eloc;
20908 : 1708 : bool structured_block = false;
20909 : 1708 : bool swapped = false;
20910 : 1708 : bool non_lvalue_p;
20911 : 1708 : tree clauses = NULL_TREE;
20912 : 1708 : bool capture = false;
20913 : 1708 : bool compare = false;
20914 : 1708 : bool weak = false;
20915 : 1708 : enum omp_memory_order fail = OMP_MEMORY_ORDER_UNSPECIFIED;
20916 : 1708 : bool no_semicolon = false;
20917 : 1708 : bool extra_scope = false;
20918 : :
20919 : 3181 : while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
20920 : : {
20921 : 1483 : if (c_parser_next_token_is (parser, CPP_COMMA)
20922 : 1483 : && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
20923 : 82 : c_parser_consume_token (parser);
20924 : :
20925 : 1483 : if (c_parser_next_token_is (parser, CPP_NAME))
20926 : : {
20927 : 1479 : const char *p
20928 : 1479 : = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20929 : 1479 : location_t cloc = c_parser_peek_token (parser)->location;
20930 : 1479 : enum tree_code new_code = ERROR_MARK;
20931 : 1479 : enum omp_memory_order new_memory_order
20932 : : = OMP_MEMORY_ORDER_UNSPECIFIED;
20933 : 1479 : bool new_capture = false;
20934 : 1479 : bool new_compare = false;
20935 : 1479 : bool new_weak = false;
20936 : 1479 : enum omp_memory_order new_fail = OMP_MEMORY_ORDER_UNSPECIFIED;
20937 : :
20938 : 1479 : if (!strcmp (p, "read"))
20939 : : new_code = OMP_ATOMIC_READ;
20940 : 1222 : else if (!strcmp (p, "write"))
20941 : : new_code = NOP_EXPR;
20942 : 1047 : else if (!strcmp (p, "update"))
20943 : : new_code = OMP_ATOMIC;
20944 : 890 : else if (openacc && !strcmp (p, "capture"))
20945 : : new_code = OMP_ATOMIC_CAPTURE_NEW;
20946 : 4 : else if (openacc)
20947 : : {
20948 : 4 : p = NULL;
20949 : 4 : error_at (cloc, "expected %<read%>, %<write%>, %<update%>, "
20950 : : "or %<capture%> clause");
20951 : : }
20952 : 652 : else if (!strcmp (p, "capture"))
20953 : : new_capture = true;
20954 : 408 : else if (!strcmp (p, "compare"))
20955 : : new_compare = true;
20956 : 235 : else if (!strcmp (p, "weak"))
20957 : : new_weak = true;
20958 : 222 : else if (!strcmp (p, "fail"))
20959 : : {
20960 : 33 : matching_parens parens;
20961 : :
20962 : 33 : c_parser_consume_token (parser);
20963 : 33 : if (!parens.require_open (parser))
20964 : 1 : continue;
20965 : :
20966 : 32 : if (c_parser_next_token_is (parser, CPP_NAME))
20967 : : {
20968 : 30 : const char *q
20969 : 30 : = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20970 : :
20971 : 30 : if (!strcmp (q, "seq_cst"))
20972 : : new_fail = OMP_MEMORY_ORDER_SEQ_CST;
20973 : 24 : else if (!strcmp (q, "acquire"))
20974 : : new_fail = OMP_MEMORY_ORDER_ACQUIRE;
20975 : 17 : else if (!strcmp (q, "relaxed"))
20976 : : new_fail = OMP_MEMORY_ORDER_RELAXED;
20977 : : }
20978 : :
20979 : : if (new_fail != OMP_MEMORY_ORDER_UNSPECIFIED)
20980 : : {
20981 : 27 : c_parser_consume_token (parser);
20982 : 27 : if (fail != OMP_MEMORY_ORDER_UNSPECIFIED)
20983 : 2 : error_at (cloc, "too many %qs clauses", "fail");
20984 : : else
20985 : : fail = new_fail;
20986 : : }
20987 : : else
20988 : 5 : c_parser_error (parser, "expected %<seq_cst%>, %<acquire%> "
20989 : : "or %<relaxed%>");
20990 : 32 : parens.skip_until_found_close (parser);
20991 : 32 : continue;
20992 : 32 : }
20993 : 189 : else if (!strcmp (p, "seq_cst"))
20994 : : new_memory_order = OMP_MEMORY_ORDER_SEQ_CST;
20995 : 112 : else if (!strcmp (p, "acq_rel"))
20996 : : new_memory_order = OMP_MEMORY_ORDER_ACQ_REL;
20997 : 100 : else if (!strcmp (p, "release"))
20998 : : new_memory_order = OMP_MEMORY_ORDER_RELEASE;
20999 : 70 : else if (!strcmp (p, "acquire"))
21000 : : new_memory_order = OMP_MEMORY_ORDER_ACQUIRE;
21001 : 57 : else if (!strcmp (p, "relaxed"))
21002 : : new_memory_order = OMP_MEMORY_ORDER_RELAXED;
21003 : 31 : else if (!strcmp (p, "hint"))
21004 : : {
21005 : 29 : c_parser_consume_token (parser);
21006 : 29 : clauses = c_parser_omp_clause_hint (parser, clauses);
21007 : 29 : continue;
21008 : : }
21009 : : else
21010 : : {
21011 : 2 : p = NULL;
21012 : 2 : error_at (cloc, "expected %<read%>, %<write%>, %<update%>, "
21013 : : "%<capture%>, %<compare%>, %<weak%>, %<fail%>, "
21014 : : "%<seq_cst%>, %<acq_rel%>, %<release%>, "
21015 : : "%<relaxed%> or %<hint%> clause");
21016 : : }
21017 : 1417 : if (p)
21018 : : {
21019 : 1411 : if (new_code != ERROR_MARK)
21020 : : {
21021 : : /* OpenACC permits 'update capture'. */
21022 : 823 : if (openacc
21023 : 823 : && code == OMP_ATOMIC
21024 : 4 : && new_code == OMP_ATOMIC_CAPTURE_NEW)
21025 : : code = new_code;
21026 : 820 : else if (code != ERROR_MARK)
21027 : 5 : error_at (cloc, "too many atomic clauses");
21028 : : else
21029 : : code = new_code;
21030 : : }
21031 : 588 : else if (new_memory_order != OMP_MEMORY_ORDER_UNSPECIFIED)
21032 : : {
21033 : 158 : if (memory_order != OMP_MEMORY_ORDER_UNSPECIFIED)
21034 : 35 : error_at (cloc, "too many memory order clauses");
21035 : : else
21036 : : memory_order = new_memory_order;
21037 : : }
21038 : 430 : else if (new_capture)
21039 : : {
21040 : 244 : if (capture)
21041 : 1 : error_at (cloc, "too many %qs clauses", "capture");
21042 : : else
21043 : : capture = true;
21044 : : }
21045 : 186 : else if (new_compare)
21046 : : {
21047 : 173 : if (compare)
21048 : 1 : error_at (cloc, "too many %qs clauses", "compare");
21049 : : else
21050 : : compare = true;
21051 : : }
21052 : 13 : else if (new_weak)
21053 : : {
21054 : 13 : if (weak)
21055 : 1 : error_at (cloc, "too many %qs clauses", "weak");
21056 : : else
21057 : : weak = true;
21058 : : }
21059 : 1411 : c_parser_consume_token (parser);
21060 : 1411 : continue;
21061 : : }
21062 : : }
21063 : : break;
21064 : : }
21065 : 1708 : c_parser_skip_to_pragma_eol (parser);
21066 : :
21067 : 1708 : if (code == ERROR_MARK)
21068 : 893 : code = OMP_ATOMIC;
21069 : 1708 : if (capture)
21070 : : {
21071 : 243 : if (code != OMP_ATOMIC)
21072 : 2 : error_at (loc, "%qs clause is incompatible with %<read%> or %<write%> "
21073 : : "clauses", "capture");
21074 : : else
21075 : : code = OMP_ATOMIC_CAPTURE_NEW;
21076 : : }
21077 : 1708 : if (compare && code != OMP_ATOMIC && code != OMP_ATOMIC_CAPTURE_NEW)
21078 : : {
21079 : 2 : error_at (loc, "%qs clause is incompatible with %<read%> or %<write%> "
21080 : : "clauses", "compare");
21081 : 2 : compare = false;
21082 : : }
21083 : 1708 : if (fail != OMP_MEMORY_ORDER_UNSPECIFIED && !compare)
21084 : : {
21085 : 5 : error_at (loc, "%qs clause requires %qs clause", "fail", "compare");
21086 : 5 : fail = OMP_MEMORY_ORDER_UNSPECIFIED;
21087 : : }
21088 : 1708 : if (weak && !compare)
21089 : : {
21090 : 5 : error_at (loc, "%qs clause requires %qs clause", "weak", "compare");
21091 : 5 : weak = false;
21092 : : }
21093 : 1708 : if (openacc)
21094 : : memory_order = OMP_MEMORY_ORDER_RELAXED;
21095 : 1399 : else if (memory_order == OMP_MEMORY_ORDER_UNSPECIFIED)
21096 : : {
21097 : 1276 : omp_requires_mask
21098 : 1276 : = (enum omp_requires) (omp_requires_mask
21099 : : | OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED);
21100 : 1276 : switch ((enum omp_memory_order)
21101 : : (omp_requires_mask & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER))
21102 : : {
21103 : : case OMP_MEMORY_ORDER_UNSPECIFIED:
21104 : : case OMP_MEMORY_ORDER_RELAXED:
21105 : : memory_order = OMP_MEMORY_ORDER_RELAXED;
21106 : : break;
21107 : : case OMP_MEMORY_ORDER_SEQ_CST:
21108 : 9 : memory_order = OMP_MEMORY_ORDER_SEQ_CST;
21109 : : break;
21110 : 4 : case OMP_MEMORY_ORDER_ACQUIRE:
21111 : 4 : if (code == NOP_EXPR) /* atomic write */
21112 : : {
21113 : 1 : error_at (loc, "%<#pragma omp atomic write%> incompatible with "
21114 : : "%<acquire%> clause implicitly provided by a "
21115 : : "%<requires%> directive");
21116 : 1 : memory_order = OMP_MEMORY_ORDER_SEQ_CST;
21117 : : }
21118 : : else
21119 : : memory_order = OMP_MEMORY_ORDER_ACQUIRE;
21120 : : break;
21121 : 3 : case OMP_MEMORY_ORDER_RELEASE:
21122 : 3 : if (code == OMP_ATOMIC_READ)
21123 : : {
21124 : 1 : error_at (loc, "%<#pragma omp atomic read%> incompatible with "
21125 : : "%<release%> clause implicitly provided by a "
21126 : : "%<requires%> directive");
21127 : 1 : memory_order = OMP_MEMORY_ORDER_SEQ_CST;
21128 : : }
21129 : : else
21130 : : memory_order = OMP_MEMORY_ORDER_RELEASE;
21131 : : break;
21132 : 9 : case OMP_MEMORY_ORDER_ACQ_REL:
21133 : 9 : switch (code)
21134 : : {
21135 : : case OMP_ATOMIC_READ:
21136 : : memory_order = OMP_MEMORY_ORDER_ACQUIRE;
21137 : : break;
21138 : : case NOP_EXPR: /* atomic write */
21139 : 5 : memory_order = OMP_MEMORY_ORDER_RELEASE;
21140 : : break;
21141 : : default:
21142 : 1708 : memory_order = OMP_MEMORY_ORDER_ACQ_REL;
21143 : : break;
21144 : : }
21145 : : break;
21146 : 0 : default:
21147 : 0 : gcc_unreachable ();
21148 : : }
21149 : : }
21150 : : else
21151 : 123 : switch (code)
21152 : : {
21153 : 25 : case OMP_ATOMIC_READ:
21154 : 25 : if (memory_order == OMP_MEMORY_ORDER_RELEASE)
21155 : : {
21156 : 1 : error_at (loc, "%<#pragma omp atomic read%> incompatible with "
21157 : : "%<release%> clause");
21158 : 1 : memory_order = OMP_MEMORY_ORDER_SEQ_CST;
21159 : : }
21160 : 24 : else if (memory_order == OMP_MEMORY_ORDER_ACQ_REL)
21161 : 6 : memory_order = OMP_MEMORY_ORDER_ACQUIRE;
21162 : : break;
21163 : 16 : case NOP_EXPR: /* atomic write */
21164 : 16 : if (memory_order == OMP_MEMORY_ORDER_ACQUIRE)
21165 : : {
21166 : 1 : error_at (loc, "%<#pragma omp atomic write%> incompatible with "
21167 : : "%<acquire%> clause");
21168 : 1 : memory_order = OMP_MEMORY_ORDER_SEQ_CST;
21169 : : }
21170 : 15 : else if (memory_order == OMP_MEMORY_ORDER_ACQ_REL)
21171 : 5 : memory_order = OMP_MEMORY_ORDER_RELEASE;
21172 : : break;
21173 : : default:
21174 : : break;
21175 : : }
21176 : 1708 : if (fail != OMP_MEMORY_ORDER_UNSPECIFIED)
21177 : 20 : memory_order
21178 : 20 : = (enum omp_memory_order) (memory_order
21179 : : | (fail << OMP_FAIL_MEMORY_ORDER_SHIFT));
21180 : :
21181 : 1708 : switch (code)
21182 : : {
21183 : 431 : case OMP_ATOMIC_READ:
21184 : 431 : case NOP_EXPR: /* atomic write */
21185 : 431 : v = c_parser_cast_expression (parser, NULL).value;
21186 : 431 : non_lvalue_p = !lvalue_p (v);
21187 : 431 : v = c_fully_fold (v, false, NULL, true);
21188 : 431 : if (v == error_mark_node)
21189 : 0 : goto saw_error;
21190 : 431 : if (non_lvalue_p)
21191 : 4 : v = non_lvalue (v);
21192 : 431 : loc = c_parser_peek_token (parser)->location;
21193 : 431 : if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
21194 : 0 : goto saw_error;
21195 : 431 : if (code == NOP_EXPR)
21196 : : {
21197 : 174 : lhs = c_parser_expression (parser).value;
21198 : 174 : lhs = c_fully_fold (lhs, false, NULL);
21199 : 174 : if (lhs == error_mark_node)
21200 : 0 : goto saw_error;
21201 : : }
21202 : : else
21203 : : {
21204 : 257 : lhs = c_parser_cast_expression (parser, NULL).value;
21205 : 257 : non_lvalue_p = !lvalue_p (lhs);
21206 : 257 : lhs = c_fully_fold (lhs, false, NULL, true);
21207 : 257 : if (lhs == error_mark_node)
21208 : 0 : goto saw_error;
21209 : 257 : if (non_lvalue_p)
21210 : 2 : lhs = non_lvalue (lhs);
21211 : : }
21212 : 431 : if (code == NOP_EXPR)
21213 : : {
21214 : : /* atomic write is represented by OMP_ATOMIC with NOP_EXPR
21215 : : opcode. */
21216 : 174 : code = OMP_ATOMIC;
21217 : 174 : rhs = lhs;
21218 : 174 : lhs = v;
21219 : 174 : v = NULL_TREE;
21220 : : }
21221 : 431 : goto done;
21222 : 473 : case OMP_ATOMIC_CAPTURE_NEW:
21223 : 473 : if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
21224 : : {
21225 : 314 : c_parser_consume_token (parser);
21226 : 314 : structured_block = true;
21227 : : }
21228 : 159 : else if (compare
21229 : 188 : && c_parser_next_token_is_keyword (parser, RID_IF))
21230 : : break;
21231 : : else
21232 : : {
21233 : 142 : v = c_parser_cast_expression (parser, NULL).value;
21234 : 142 : non_lvalue_p = !lvalue_p (v);
21235 : 142 : v = c_fully_fold (v, false, NULL, true);
21236 : 142 : if (v == error_mark_node)
21237 : 0 : goto saw_error;
21238 : 142 : if (non_lvalue_p)
21239 : 2 : v = non_lvalue (v);
21240 : 142 : if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
21241 : 0 : goto saw_error;
21242 : 154 : if (compare && c_parser_next_token_is_keyword (parser, RID_IF))
21243 : : {
21244 : 1 : eloc = c_parser_peek_token (parser)->location;
21245 : 1 : error_at (eloc, "expected expression");
21246 : 1 : goto saw_error;
21247 : : }
21248 : : }
21249 : : break;
21250 : : default:
21251 : : break;
21252 : : }
21253 : :
21254 : : /* For structured_block case we don't know yet whether
21255 : : old or new x should be captured. */
21256 : 1276 : restart:
21257 : 1668 : if (compare && c_parser_next_token_is_keyword (parser, RID_IF))
21258 : : {
21259 : 85 : c_parser_consume_token (parser);
21260 : :
21261 : 85 : matching_parens parens;
21262 : 85 : if (!parens.require_open (parser))
21263 : 34 : goto saw_error;
21264 : 84 : eloc = c_parser_peek_token (parser)->location;
21265 : 84 : c_expr cmp_expr;
21266 : 84 : if (r)
21267 : : {
21268 : 17 : cmp_expr = c_parser_cast_expression (parser, NULL);
21269 : 17 : cmp_expr = default_function_array_conversion (eloc, cmp_expr);
21270 : : }
21271 : : else
21272 : 67 : cmp_expr = c_parser_binary_expression (parser, NULL, void_list_node);
21273 : 84 : parens.skip_until_found_close (parser);
21274 : 84 : if (cmp_expr.value == error_mark_node)
21275 : 0 : goto saw_error;
21276 : 84 : if (r)
21277 : : {
21278 : 17 : if (!c_tree_equal (cmp_expr.value, unfolded_lhs))
21279 : 1 : goto bad_if;
21280 : 16 : cmp_expr.value = rhs1;
21281 : 16 : rhs1 = NULL_TREE;
21282 : 16 : gcc_assert (TREE_CODE (cmp_expr.value) == EQ_EXPR);
21283 : : }
21284 : 83 : if (TREE_CODE (cmp_expr.value) == EQ_EXPR)
21285 : : ;
21286 : 36 : else if (!structured_block && code == OMP_ATOMIC_CAPTURE_NEW)
21287 : : {
21288 : 4 : error_at (EXPR_LOC_OR_LOC (cmp_expr.value, eloc),
21289 : : "expected %<==%> comparison in %<if%> condition");
21290 : 2 : goto saw_error;
21291 : : }
21292 : 34 : else if (TREE_CODE (cmp_expr.value) != GT_EXPR
21293 : 25 : && TREE_CODE (cmp_expr.value) != LT_EXPR)
21294 : : {
21295 : 16 : error_at (EXPR_LOC_OR_LOC (cmp_expr.value, eloc),
21296 : : "expected %<==%>, %<<%> or %<>%> comparison in %<if%> "
21297 : : "condition");
21298 : 10 : goto saw_error;
21299 : : }
21300 : 71 : if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
21301 : 2 : goto saw_error;
21302 : :
21303 : 69 : extra_scope = true;
21304 : 69 : eloc = c_parser_peek_token (parser)->location;
21305 : 69 : expr = c_parser_cast_expression (parser, NULL);
21306 : 69 : lhs = expr.value;
21307 : 69 : expr = default_function_array_conversion (eloc, expr);
21308 : 69 : unfolded_lhs = expr.value;
21309 : 69 : lhs = c_fully_fold (lhs, false, NULL, true);
21310 : 69 : orig_lhs = lhs;
21311 : 69 : if (lhs == error_mark_node)
21312 : 0 : goto saw_error;
21313 : 69 : if (!lvalue_p (unfolded_lhs))
21314 : 0 : lhs = non_lvalue (lhs);
21315 : 69 : if (!c_parser_next_token_is (parser, CPP_EQ))
21316 : : {
21317 : 1 : c_parser_error (parser, "expected %<=%>");
21318 : 1 : goto saw_error;
21319 : : }
21320 : 68 : c_parser_consume_token (parser);
21321 : 68 : eloc = c_parser_peek_token (parser)->location;
21322 : 68 : expr = c_parser_expr_no_commas (parser, NULL);
21323 : 68 : rhs1 = expr.value;
21324 : :
21325 : 68 : if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
21326 : 1 : goto saw_error;
21327 : :
21328 : 67 : if (!c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>"))
21329 : 1 : goto saw_error;
21330 : :
21331 : 66 : extra_scope = false;
21332 : 66 : no_semicolon = true;
21333 : :
21334 : 66 : if (c_tree_equal (TREE_OPERAND (cmp_expr.value, 0), unfolded_lhs))
21335 : : {
21336 : 59 : if (TREE_CODE (cmp_expr.value) == EQ_EXPR)
21337 : : {
21338 : 44 : opcode = COND_EXPR;
21339 : 44 : rhs = c_fully_fold (TREE_OPERAND (cmp_expr.value, 1),
21340 : : false, NULL, true);
21341 : 44 : rhs1 = c_fully_fold (rhs1, false, NULL, true);
21342 : : }
21343 : 15 : else if (c_tree_equal (TREE_OPERAND (cmp_expr.value, 1), rhs1))
21344 : : {
21345 : 26 : opcode = (TREE_CODE (cmp_expr.value) == GT_EXPR
21346 : 13 : ? MIN_EXPR : MAX_EXPR);
21347 : 13 : rhs = c_fully_fold (rhs1, false, NULL, true);
21348 : 13 : rhs1 = c_fully_fold (TREE_OPERAND (cmp_expr.value, 0),
21349 : : false, NULL, true);
21350 : : }
21351 : : else
21352 : 2 : goto bad_if;
21353 : : }
21354 : 7 : else if (TREE_CODE (cmp_expr.value) == EQ_EXPR)
21355 : 2 : goto bad_if;
21356 : 5 : else if (c_tree_equal (TREE_OPERAND (cmp_expr.value, 1), unfolded_lhs)
21357 : 5 : && c_tree_equal (TREE_OPERAND (cmp_expr.value, 0), rhs1))
21358 : : {
21359 : 6 : opcode = (TREE_CODE (cmp_expr.value) == GT_EXPR
21360 : 3 : ? MAX_EXPR : MIN_EXPR);
21361 : 3 : rhs = c_fully_fold (rhs1, false, NULL, true);
21362 : 3 : rhs1 = c_fully_fold (TREE_OPERAND (cmp_expr.value, 1),
21363 : : false, NULL, true);
21364 : : }
21365 : : else
21366 : : {
21367 : 8 : bad_if:
21368 : 8 : c_parser_error (parser,
21369 : : "invalid form of %<#pragma omp atomic compare%>");
21370 : 8 : goto saw_error;
21371 : : }
21372 : :
21373 : 60 : if (c_parser_next_token_is_keyword (parser, RID_ELSE))
21374 : : {
21375 : 24 : if (code != OMP_ATOMIC_CAPTURE_NEW
21376 : 22 : || (structured_block && r == NULL_TREE)
21377 : 21 : || TREE_CODE (cmp_expr.value) != EQ_EXPR)
21378 : : {
21379 : 3 : eloc = c_parser_peek_token (parser)->location;
21380 : 3 : error_at (eloc, "unexpected %<else%>");
21381 : 3 : goto saw_error;
21382 : : }
21383 : :
21384 : 21 : c_parser_consume_token (parser);
21385 : :
21386 : 21 : if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
21387 : 1 : goto saw_error;
21388 : :
21389 : 20 : extra_scope = true;
21390 : 20 : v = c_parser_cast_expression (parser, NULL).value;
21391 : 20 : non_lvalue_p = !lvalue_p (v);
21392 : 20 : v = c_fully_fold (v, false, NULL, true);
21393 : 20 : if (v == error_mark_node)
21394 : 0 : goto saw_error;
21395 : 20 : if (non_lvalue_p)
21396 : 0 : v = non_lvalue (v);
21397 : 20 : if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
21398 : 1 : goto saw_error;
21399 : :
21400 : 19 : expr = c_parser_expr_no_commas (parser, NULL);
21401 : :
21402 : 19 : if (!c_tree_equal (expr.value, unfolded_lhs))
21403 : 1 : goto bad_if;
21404 : :
21405 : 18 : if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
21406 : 1 : goto saw_error;
21407 : :
21408 : 17 : if (!c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>"))
21409 : 0 : goto saw_error;
21410 : :
21411 : 17 : extra_scope = false;
21412 : 17 : code = OMP_ATOMIC_CAPTURE_OLD;
21413 : 17 : if (r == NULL_TREE)
21414 : : /* Signal to c_finish_omp_atomic that in
21415 : : if (x == e) { x = d; } else { v = x; }
21416 : : case the store to v should be conditional. */
21417 : 10 : r = void_list_node;
21418 : : }
21419 : 36 : else if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
21420 : : {
21421 : 1 : c_parser_require_keyword (parser, RID_ELSE, "expected %<else%>");
21422 : 1 : goto saw_error;
21423 : : }
21424 : 35 : else if (code == OMP_ATOMIC_CAPTURE_NEW
21425 : 35 : && r != NULL_TREE
21426 : 9 : && v == NULL_TREE)
21427 : 52 : code = OMP_ATOMIC;
21428 : 52 : goto stmt_done;
21429 : : }
21430 : 1375 : eloc = c_parser_peek_token (parser)->location;
21431 : 1375 : expr = c_parser_cast_expression (parser, NULL);
21432 : 1375 : lhs = expr.value;
21433 : 1375 : expr = default_function_array_conversion (eloc, expr);
21434 : 1375 : unfolded_lhs = expr.value;
21435 : 1375 : lhs = c_fully_fold (lhs, false, NULL, true);
21436 : 1375 : orig_lhs = lhs;
21437 : 1375 : switch (TREE_CODE (lhs))
21438 : : {
21439 : 4 : invalid_compare:
21440 : 4 : error_at (eloc, "invalid form of %<pragma omp atomic compare%>");
21441 : : /* FALLTHRU */
21442 : 84 : case ERROR_MARK:
21443 : 84 : saw_error:
21444 : 84 : c_parser_skip_to_end_of_block_or_statement (parser);
21445 : 90 : if (extra_scope && c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
21446 : 4 : c_parser_consume_token (parser);
21447 : 84 : if (structured_block)
21448 : : {
21449 : 10 : if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
21450 : 9 : c_parser_consume_token (parser);
21451 : 1 : else if (code == OMP_ATOMIC_CAPTURE_NEW)
21452 : : {
21453 : 1 : c_parser_skip_to_end_of_block_or_statement (parser);
21454 : 1 : if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
21455 : 1 : c_parser_consume_token (parser);
21456 : : }
21457 : : }
21458 : 84 : return;
21459 : :
21460 : 154 : case POSTINCREMENT_EXPR:
21461 : 154 : if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
21462 : 20 : code = OMP_ATOMIC_CAPTURE_OLD;
21463 : : /* FALLTHROUGH */
21464 : 216 : case PREINCREMENT_EXPR:
21465 : 216 : lhs = TREE_OPERAND (lhs, 0);
21466 : 216 : unfolded_lhs = NULL_TREE;
21467 : 216 : opcode = PLUS_EXPR;
21468 : 216 : rhs = integer_one_node;
21469 : 216 : if (compare)
21470 : 2 : goto invalid_compare;
21471 : : break;
21472 : :
21473 : 24 : case POSTDECREMENT_EXPR:
21474 : 24 : if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
21475 : 2 : code = OMP_ATOMIC_CAPTURE_OLD;
21476 : : /* FALLTHROUGH */
21477 : 52 : case PREDECREMENT_EXPR:
21478 : 52 : lhs = TREE_OPERAND (lhs, 0);
21479 : 52 : unfolded_lhs = NULL_TREE;
21480 : 52 : opcode = MINUS_EXPR;
21481 : 52 : rhs = integer_one_node;
21482 : 52 : if (compare)
21483 : 2 : goto invalid_compare;
21484 : : break;
21485 : :
21486 : 12 : case COMPOUND_EXPR:
21487 : 12 : if (TREE_CODE (TREE_OPERAND (lhs, 0)) == SAVE_EXPR
21488 : 12 : && TREE_CODE (TREE_OPERAND (lhs, 1)) == COMPOUND_EXPR
21489 : 12 : && TREE_CODE (TREE_OPERAND (TREE_OPERAND (lhs, 1), 0)) == MODIFY_EXPR
21490 : 12 : && TREE_OPERAND (TREE_OPERAND (lhs, 1), 1) == TREE_OPERAND (lhs, 0)
21491 : 24 : && C_BOOLEAN_TYPE_P (TREE_TYPE (TREE_OPERAND (TREE_OPERAND
21492 : : (TREE_OPERAND (lhs, 1), 0), 0))))
21493 : : /* Undo effects of boolean_increment for post {in,de}crement. */
21494 : 12 : lhs = TREE_OPERAND (TREE_OPERAND (lhs, 1), 0);
21495 : : /* FALLTHRU */
21496 : 24 : case MODIFY_EXPR:
21497 : 24 : if (TREE_CODE (lhs) == MODIFY_EXPR
21498 : 24 : && C_BOOLEAN_TYPE_P (TREE_TYPE (TREE_OPERAND (lhs, 0))))
21499 : : {
21500 : : /* Undo effects of boolean_increment. */
21501 : 24 : if (integer_onep (TREE_OPERAND (lhs, 1)))
21502 : : {
21503 : : /* This is pre or post increment. */
21504 : 12 : rhs = TREE_OPERAND (lhs, 1);
21505 : 12 : lhs = TREE_OPERAND (lhs, 0);
21506 : 12 : unfolded_lhs = NULL_TREE;
21507 : 12 : opcode = NOP_EXPR;
21508 : 12 : if (code == OMP_ATOMIC_CAPTURE_NEW
21509 : 12 : && !structured_block
21510 : 2 : && TREE_CODE (orig_lhs) == COMPOUND_EXPR)
21511 : 1 : code = OMP_ATOMIC_CAPTURE_OLD;
21512 : 12 : if (compare)
21513 : 0 : goto invalid_compare;
21514 : : break;
21515 : : }
21516 : 12 : if (TREE_CODE (TREE_OPERAND (lhs, 1)) == TRUTH_NOT_EXPR
21517 : 12 : && TREE_OPERAND (lhs, 0)
21518 : 12 : == TREE_OPERAND (TREE_OPERAND (lhs, 1), 0))
21519 : : {
21520 : : /* This is pre or post decrement. */
21521 : 12 : rhs = TREE_OPERAND (lhs, 1);
21522 : 12 : lhs = TREE_OPERAND (lhs, 0);
21523 : 12 : unfolded_lhs = NULL_TREE;
21524 : 12 : opcode = NOP_EXPR;
21525 : 12 : if (code == OMP_ATOMIC_CAPTURE_NEW
21526 : 12 : && !structured_block
21527 : 2 : && TREE_CODE (orig_lhs) == COMPOUND_EXPR)
21528 : 1 : code = OMP_ATOMIC_CAPTURE_OLD;
21529 : 12 : if (compare)
21530 : 0 : goto invalid_compare;
21531 : : break;
21532 : : }
21533 : : }
21534 : : /* FALLTHRU */
21535 : 1079 : default:
21536 : 1079 : if (!lvalue_p (unfolded_lhs))
21537 : 5 : lhs = non_lvalue (lhs);
21538 : 1198 : if (compare && !c_parser_next_token_is (parser, CPP_EQ))
21539 : : {
21540 : 7 : c_parser_error (parser, "expected %<=%>");
21541 : 7 : goto saw_error;
21542 : : }
21543 : 1072 : switch (c_parser_peek_token (parser)->type)
21544 : : {
21545 : : case CPP_MULT_EQ:
21546 : : opcode = MULT_EXPR;
21547 : : break;
21548 : : case CPP_DIV_EQ:
21549 : : opcode = TRUNC_DIV_EXPR;
21550 : : break;
21551 : : case CPP_PLUS_EQ:
21552 : : opcode = PLUS_EXPR;
21553 : : break;
21554 : : case CPP_MINUS_EQ:
21555 : : opcode = MINUS_EXPR;
21556 : : break;
21557 : : case CPP_LSHIFT_EQ:
21558 : : opcode = LSHIFT_EXPR;
21559 : : break;
21560 : : case CPP_RSHIFT_EQ:
21561 : : opcode = RSHIFT_EXPR;
21562 : : break;
21563 : : case CPP_AND_EQ:
21564 : : opcode = BIT_AND_EXPR;
21565 : : break;
21566 : : case CPP_OR_EQ:
21567 : : opcode = BIT_IOR_EXPR;
21568 : : break;
21569 : : case CPP_XOR_EQ:
21570 : : opcode = BIT_XOR_EXPR;
21571 : : break;
21572 : 556 : case CPP_EQ:
21573 : 556 : c_parser_consume_token (parser);
21574 : 556 : eloc = c_parser_peek_token (parser)->location;
21575 : 556 : expr = c_parser_expr_no_commas (parser, NULL, unfolded_lhs);
21576 : 556 : rhs1 = expr.value;
21577 : 556 : switch (TREE_CODE (rhs1))
21578 : : {
21579 : 289 : case MULT_EXPR:
21580 : 289 : case TRUNC_DIV_EXPR:
21581 : 289 : case RDIV_EXPR:
21582 : 289 : case PLUS_EXPR:
21583 : 289 : case MINUS_EXPR:
21584 : 289 : case LSHIFT_EXPR:
21585 : 289 : case RSHIFT_EXPR:
21586 : 289 : case BIT_AND_EXPR:
21587 : 289 : case BIT_IOR_EXPR:
21588 : 289 : case BIT_XOR_EXPR:
21589 : 289 : if (compare)
21590 : : break;
21591 : 282 : if (c_tree_equal (TREE_OPERAND (rhs1, 0), unfolded_lhs))
21592 : : {
21593 : 147 : opcode = TREE_CODE (rhs1);
21594 : 147 : rhs = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
21595 : : true);
21596 : 147 : rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 0), false, NULL,
21597 : : true);
21598 : 147 : goto stmt_done;
21599 : : }
21600 : 135 : if (c_tree_equal (TREE_OPERAND (rhs1, 1), unfolded_lhs))
21601 : : {
21602 : 117 : opcode = TREE_CODE (rhs1);
21603 : 117 : rhs = c_fully_fold (TREE_OPERAND (rhs1, 0), false, NULL,
21604 : : true);
21605 : 117 : rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
21606 : : true);
21607 : 117 : swapped = !commutative_tree_code (opcode);
21608 : 117 : goto stmt_done;
21609 : : }
21610 : : break;
21611 : 69 : case COND_EXPR:
21612 : 69 : if (!compare)
21613 : : break;
21614 : 66 : if (TREE_CODE (TREE_OPERAND (rhs1, 0)) != GT_EXPR
21615 : 44 : && TREE_CODE (TREE_OPERAND (rhs1, 0)) != LT_EXPR
21616 : 97 : && TREE_CODE (TREE_OPERAND (rhs1, 0)) != EQ_EXPR)
21617 : : break;
21618 : 63 : if (!TREE_OPERAND (rhs1, 1))
21619 : : break;
21620 : 63 : if (!c_tree_equal (TREE_OPERAND (rhs1, 2), unfolded_lhs))
21621 : : break;
21622 : 58 : if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 0),
21623 : : unfolded_lhs))
21624 : : {
21625 : 39 : if (TREE_CODE (TREE_OPERAND (rhs1, 0)) == EQ_EXPR)
21626 : : {
21627 : 23 : opcode = COND_EXPR;
21628 : 23 : rhs = c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1,
21629 : : 0), 1),
21630 : : false, NULL, true);
21631 : 23 : rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 1), false,
21632 : : NULL, true);
21633 : 23 : goto stmt_done;
21634 : : }
21635 : 16 : if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 1),
21636 : 16 : TREE_OPERAND (rhs1, 1)))
21637 : : {
21638 : 14 : opcode = (TREE_CODE (TREE_OPERAND (rhs1, 0)) == GT_EXPR
21639 : 14 : ? MIN_EXPR : MAX_EXPR);
21640 : 14 : rhs = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
21641 : : true);
21642 : 14 : rhs1 = c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1,
21643 : : 0), 0),
21644 : : false, NULL, true);
21645 : 14 : goto stmt_done;
21646 : : }
21647 : : }
21648 : 19 : else if (TREE_CODE (TREE_OPERAND (rhs1, 0)) == EQ_EXPR)
21649 : : break;
21650 : 17 : else if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 1),
21651 : : unfolded_lhs))
21652 : : {
21653 : 15 : if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 0),
21654 : 15 : TREE_OPERAND (rhs1, 1)))
21655 : : {
21656 : 15 : opcode = (TREE_CODE (TREE_OPERAND (rhs1, 0)) == GT_EXPR
21657 : 15 : ? MAX_EXPR : MIN_EXPR);
21658 : 15 : rhs = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
21659 : : true);
21660 : 15 : rhs1 = c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1,
21661 : : 0), 1),
21662 : : false, NULL, true);
21663 : 15 : goto stmt_done;
21664 : : }
21665 : : }
21666 : : break;
21667 : 17 : case EQ_EXPR:
21668 : 17 : if (!compare
21669 : 17 : || code != OMP_ATOMIC_CAPTURE_NEW
21670 : 17 : || !structured_block
21671 : 17 : || v
21672 : 17 : || r)
21673 : : break;
21674 : 17 : if (c_parser_next_token_is (parser, CPP_SEMICOLON)
21675 : 17 : && c_parser_peek_2nd_token (parser)->keyword == RID_IF)
21676 : : {
21677 : 17 : r = lhs;
21678 : 17 : lhs = NULL_TREE;
21679 : 17 : c_parser_consume_token (parser);
21680 : 17 : goto restart;
21681 : : }
21682 : : break;
21683 : 0 : case ERROR_MARK:
21684 : 0 : goto saw_error;
21685 : : default:
21686 : : break;
21687 : : }
21688 : 223 : if (c_parser_peek_token (parser)->type == CPP_SEMICOLON)
21689 : : {
21690 : 223 : if (structured_block && code == OMP_ATOMIC_CAPTURE_NEW)
21691 : : {
21692 : 167 : code = OMP_ATOMIC_CAPTURE_OLD;
21693 : 167 : v = lhs;
21694 : 167 : lhs = NULL_TREE;
21695 : 167 : expr = default_function_array_read_conversion (eloc, expr);
21696 : 167 : unfolded_lhs1 = expr.value;
21697 : 167 : lhs1 = c_fully_fold (unfolded_lhs1, false, NULL, true);
21698 : 167 : rhs1 = NULL_TREE;
21699 : 167 : c_parser_consume_token (parser);
21700 : 167 : goto restart;
21701 : : }
21702 : 56 : if (structured_block && !compare)
21703 : : {
21704 : 26 : opcode = NOP_EXPR;
21705 : 26 : expr = default_function_array_read_conversion (eloc, expr);
21706 : 26 : rhs = c_fully_fold (expr.value, false, NULL, true);
21707 : 26 : rhs1 = NULL_TREE;
21708 : 26 : goto stmt_done;
21709 : : }
21710 : : }
21711 : 30 : c_parser_error (parser, "invalid form of %<#pragma omp atomic%>");
21712 : 30 : goto saw_error;
21713 : 5 : default:
21714 : 5 : c_parser_error (parser,
21715 : : "invalid operator for %<#pragma omp atomic%>");
21716 : 5 : goto saw_error;
21717 : : }
21718 : :
21719 : : /* Arrange to pass the location of the assignment operator to
21720 : : c_finish_omp_atomic. */
21721 : 511 : loc = c_parser_peek_token (parser)->location;
21722 : 511 : c_parser_consume_token (parser);
21723 : 511 : eloc = c_parser_peek_token (parser)->location;
21724 : 511 : expr = c_parser_expression (parser);
21725 : 511 : expr = default_function_array_read_conversion (eloc, expr);
21726 : 511 : rhs = expr.value;
21727 : 511 : rhs = c_fully_fold (rhs, false, NULL, true);
21728 : 511 : break;
21729 : : }
21730 : 1193 : stmt_done:
21731 : 1193 : if (structured_block && code == OMP_ATOMIC_CAPTURE_NEW && r == NULL_TREE)
21732 : : {
21733 : 129 : if (!no_semicolon
21734 : 129 : && !c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
21735 : 0 : goto saw_error;
21736 : 129 : no_semicolon = false;
21737 : 129 : v = c_parser_cast_expression (parser, NULL).value;
21738 : 129 : non_lvalue_p = !lvalue_p (v);
21739 : 129 : v = c_fully_fold (v, false, NULL, true);
21740 : 129 : if (v == error_mark_node)
21741 : 0 : goto saw_error;
21742 : 129 : if (non_lvalue_p)
21743 : 2 : v = non_lvalue (v);
21744 : 129 : if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
21745 : 0 : goto saw_error;
21746 : 129 : eloc = c_parser_peek_token (parser)->location;
21747 : 129 : expr = c_parser_cast_expression (parser, NULL);
21748 : 129 : lhs1 = expr.value;
21749 : 129 : expr = default_function_array_read_conversion (eloc, expr);
21750 : 129 : unfolded_lhs1 = expr.value;
21751 : 129 : lhs1 = c_fully_fold (lhs1, false, NULL, true);
21752 : 129 : if (lhs1 == error_mark_node)
21753 : 0 : goto saw_error;
21754 : 129 : if (!lvalue_p (unfolded_lhs1))
21755 : 2 : lhs1 = non_lvalue (lhs1);
21756 : : }
21757 : 1193 : if (structured_block)
21758 : : {
21759 : 304 : if (!no_semicolon)
21760 : 280 : c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
21761 : 304 : c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>");
21762 : : }
21763 : 889 : done:
21764 : 1624 : if (weak && opcode != COND_EXPR)
21765 : : {
21766 : 1 : error_at (loc, "%<weak%> clause requires atomic equality comparison");
21767 : 1 : weak = false;
21768 : : }
21769 : 1624 : if (unfolded_lhs && unfolded_lhs1
21770 : 1624 : && !c_tree_equal (unfolded_lhs, unfolded_lhs1))
21771 : : {
21772 : 5 : error ("%<#pragma omp atomic capture%> uses two different "
21773 : : "expressions for memory");
21774 : 5 : stmt = error_mark_node;
21775 : : }
21776 : : else
21777 : 1619 : stmt = c_finish_omp_atomic (loc, code, opcode, lhs, rhs, v, lhs1, rhs1, r,
21778 : : swapped, memory_order, weak);
21779 : 1624 : if (stmt != error_mark_node)
21780 : 1594 : add_stmt (stmt);
21781 : :
21782 : 1624 : if (!structured_block && !no_semicolon)
21783 : 1301 : c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
21784 : : }
21785 : :
21786 : :
21787 : : /* OpenMP 2.5:
21788 : : # pragma omp barrier new-line
21789 : : */
21790 : :
21791 : : static void
21792 : 344 : c_parser_omp_barrier (c_parser *parser)
21793 : : {
21794 : 344 : location_t loc = c_parser_peek_token (parser)->location;
21795 : 344 : c_parser_consume_pragma (parser);
21796 : 344 : c_parser_skip_to_pragma_eol (parser);
21797 : :
21798 : 344 : c_finish_omp_barrier (loc);
21799 : 344 : }
21800 : :
21801 : : /* OpenMP 2.5:
21802 : : # pragma omp critical [(name)] new-line
21803 : : structured-block
21804 : :
21805 : : OpenMP 4.5:
21806 : : # pragma omp critical [(name) [hint(expression)]] new-line
21807 : :
21808 : : LOC is the location of the #pragma itself. */
21809 : :
21810 : : #define OMP_CRITICAL_CLAUSE_MASK \
21811 : : ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HINT) )
21812 : :
21813 : : static tree
21814 : 143 : c_parser_omp_critical (location_t loc, c_parser *parser, bool *if_p)
21815 : : {
21816 : 143 : tree stmt, name = NULL_TREE, clauses = NULL_TREE;
21817 : :
21818 : 143 : if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
21819 : : {
21820 : 49 : c_parser_consume_token (parser);
21821 : 49 : if (c_parser_next_token_is (parser, CPP_NAME))
21822 : : {
21823 : 48 : name = c_parser_peek_token (parser)->value;
21824 : 48 : c_parser_consume_token (parser);
21825 : 48 : c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>");
21826 : : }
21827 : : else
21828 : 1 : c_parser_error (parser, "expected identifier");
21829 : :
21830 : 49 : if (c_parser_next_token_is (parser, CPP_COMMA)
21831 : 49 : && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
21832 : 4 : c_parser_consume_token (parser);
21833 : : }
21834 : 143 : clauses = c_parser_omp_all_clauses (parser, OMP_CRITICAL_CLAUSE_MASK,
21835 : : "#pragma omp critical");
21836 : 143 : stmt = c_parser_omp_structured_block (parser, if_p);
21837 : 143 : return c_finish_omp_critical (loc, stmt, name, clauses);
21838 : : }
21839 : :
21840 : : /* OpenMP 5.0:
21841 : : # pragma omp depobj ( depobj ) depobj-clause new-line
21842 : :
21843 : : depobj-clause:
21844 : : depend (dependence-type : locator)
21845 : : destroy
21846 : : update (dependence-type)
21847 : :
21848 : : OpenMP 5.2 additionally:
21849 : : destroy ( depobj )
21850 : :
21851 : : dependence-type:
21852 : : in
21853 : : out
21854 : : inout
21855 : : mutexinout */
21856 : :
21857 : : static void
21858 : 73 : c_parser_omp_depobj (c_parser *parser)
21859 : : {
21860 : 73 : location_t loc = c_parser_peek_token (parser)->location;
21861 : 73 : c_parser_consume_pragma (parser);
21862 : 73 : matching_parens parens;
21863 : 73 : if (!parens.require_open (parser))
21864 : : {
21865 : 3 : c_parser_skip_to_pragma_eol (parser);
21866 : 3 : return;
21867 : : }
21868 : :
21869 : 70 : tree depobj = c_parser_expr_no_commas (parser, NULL).value;
21870 : 70 : if (depobj != error_mark_node)
21871 : : {
21872 : 69 : if (!lvalue_p (depobj))
21873 : : {
21874 : 1 : error_at (EXPR_LOC_OR_LOC (depobj, loc),
21875 : : "%<depobj%> expression is not lvalue expression");
21876 : 1 : depobj = error_mark_node;
21877 : : }
21878 : : else
21879 : : {
21880 : 119 : tree addr = build_unary_op (EXPR_LOC_OR_LOC (depobj, loc), ADDR_EXPR,
21881 : : depobj, false);
21882 : 68 : if (addr == error_mark_node)
21883 : : depobj = error_mark_node;
21884 : : else
21885 : 119 : depobj = build_indirect_ref (EXPR_LOC_OR_LOC (depobj, loc),
21886 : : addr, RO_UNARY_STAR);
21887 : : }
21888 : : }
21889 : :
21890 : 70 : parens.skip_until_found_close (parser);
21891 : 70 : tree clause = NULL_TREE;
21892 : 70 : enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_INVALID;
21893 : 70 : if (c_parser_next_token_is (parser, CPP_COMMA))
21894 : 3 : c_parser_consume_token (parser);
21895 : 70 : location_t c_loc = c_parser_peek_token (parser)->location;
21896 : 70 : if (c_parser_next_token_is (parser, CPP_NAME))
21897 : : {
21898 : 69 : const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21899 : :
21900 : 69 : c_parser_consume_token (parser);
21901 : 69 : if (!strcmp ("depend", p))
21902 : : {
21903 : 37 : clause = c_parser_omp_clause_depend (parser, NULL_TREE);
21904 : 37 : clause = c_finish_omp_clauses (clause, C_ORT_OMP);
21905 : 37 : if (!clause)
21906 : 2 : clause = error_mark_node;
21907 : : }
21908 : 32 : else if (!strcmp ("destroy", p))
21909 : : {
21910 : 21 : matching_parens c_parens;
21911 : 21 : kind = OMP_CLAUSE_DEPEND_LAST;
21912 : 21 : if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
21913 : 21 : && c_parens.require_open (parser))
21914 : : {
21915 : 7 : tree destobj = c_parser_expr_no_commas (parser, NULL).value;
21916 : 7 : if (!lvalue_p (destobj))
21917 : 1 : error_at (EXPR_LOC_OR_LOC (destobj, c_loc),
21918 : : "%<destroy%> expression is not lvalue expression");
21919 : 6 : else if (depobj != error_mark_node
21920 : 6 : && !operand_equal_p (destobj, depobj,
21921 : : OEP_MATCH_SIDE_EFFECTS
21922 : : | OEP_LEXICOGRAPHIC))
21923 : 4 : warning_at (EXPR_LOC_OR_LOC (destobj, c_loc), OPT_Wopenmp,
21924 : : "the %<destroy%> expression %qE should be the same "
21925 : : "as the %<depobj%> argument %qE", destobj, depobj);
21926 : 7 : c_parens.skip_until_found_close (parser);
21927 : : }
21928 : : }
21929 : 11 : else if (!strcmp ("update", p))
21930 : : {
21931 : 10 : matching_parens c_parens;
21932 : 10 : if (c_parens.require_open (parser))
21933 : : {
21934 : 10 : location_t c2_loc = c_parser_peek_token (parser)->location;
21935 : 10 : if (c_parser_next_token_is (parser, CPP_NAME))
21936 : : {
21937 : 10 : const char *p2
21938 : 10 : = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21939 : :
21940 : 10 : c_parser_consume_token (parser);
21941 : 10 : if (!strcmp ("in", p2))
21942 : : kind = OMP_CLAUSE_DEPEND_IN;
21943 : 8 : else if (!strcmp ("out", p2))
21944 : : kind = OMP_CLAUSE_DEPEND_OUT;
21945 : 7 : else if (!strcmp ("inout", p2))
21946 : : kind = OMP_CLAUSE_DEPEND_INOUT;
21947 : 4 : else if (!strcmp ("mutexinoutset", p2))
21948 : : kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET;
21949 : 3 : else if (!strcmp ("inoutset", p2))
21950 : : kind = OMP_CLAUSE_DEPEND_INOUTSET;
21951 : : }
21952 : : if (kind == OMP_CLAUSE_DEPEND_INVALID)
21953 : : {
21954 : 1 : clause = error_mark_node;
21955 : 1 : error_at (c2_loc, "expected %<in%>, %<out%>, %<inout%>, "
21956 : : "%<mutexinoutset%> or %<inoutset%>");
21957 : : }
21958 : 10 : c_parens.skip_until_found_close (parser);
21959 : : }
21960 : : else
21961 : 0 : clause = error_mark_node;
21962 : : }
21963 : : }
21964 : 70 : if (!clause && kind == OMP_CLAUSE_DEPEND_INVALID)
21965 : : {
21966 : 2 : clause = error_mark_node;
21967 : 2 : error_at (c_loc, "expected %<depend%>, %<destroy%> or %<update%> clause");
21968 : : }
21969 : 70 : c_parser_skip_to_pragma_eol (parser);
21970 : :
21971 : 70 : c_finish_omp_depobj (loc, depobj, kind, clause);
21972 : : }
21973 : :
21974 : :
21975 : : /* OpenMP 2.5:
21976 : : # pragma omp flush flush-vars[opt] new-line
21977 : :
21978 : : flush-vars:
21979 : : ( variable-list )
21980 : :
21981 : : OpenMP 5.0:
21982 : : # pragma omp flush memory-order-clause new-line */
21983 : :
21984 : : static void
21985 : 58 : c_parser_omp_flush (c_parser *parser)
21986 : : {
21987 : 58 : location_t loc = c_parser_peek_token (parser)->location;
21988 : 58 : c_parser_consume_pragma (parser);
21989 : 58 : enum memmodel mo = MEMMODEL_LAST;
21990 : 58 : if (c_parser_next_token_is (parser, CPP_COMMA)
21991 : 58 : && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
21992 : 8 : c_parser_consume_token (parser);
21993 : 58 : if (c_parser_next_token_is (parser, CPP_NAME))
21994 : : {
21995 : 27 : const char *p
21996 : 27 : = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21997 : :
21998 : 27 : if (!strcmp (p, "seq_cst"))
21999 : : mo = MEMMODEL_SEQ_CST;
22000 : 21 : else if (!strcmp (p, "acq_rel"))
22001 : : mo = MEMMODEL_ACQ_REL;
22002 : 15 : else if (!strcmp (p, "release"))
22003 : : mo = MEMMODEL_RELEASE;
22004 : 9 : else if (!strcmp (p, "acquire"))
22005 : : mo = MEMMODEL_ACQUIRE;
22006 : : else
22007 : 3 : error_at (c_parser_peek_token (parser)->location,
22008 : : "expected %<seq_cst%>, %<acq_rel%>, %<release%> or "
22009 : : "%<acquire%>");
22010 : 27 : c_parser_consume_token (parser);
22011 : : }
22012 : 58 : if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
22013 : : {
22014 : 19 : if (mo != MEMMODEL_LAST)
22015 : 4 : error_at (c_parser_peek_token (parser)->location,
22016 : : "%<flush%> list specified together with memory order "
22017 : : "clause");
22018 : 19 : c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
22019 : : }
22020 : 39 : else if (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
22021 : 1 : c_parser_error (parser, "expected %<(%> or end of line");
22022 : 58 : c_parser_skip_to_pragma_eol (parser);
22023 : :
22024 : 58 : c_finish_omp_flush (loc, mo);
22025 : 58 : }
22026 : :
22027 : : /* Return true if next tokens contain a standard attribute that contains
22028 : : omp::directive (DIRECTIVE). */
22029 : :
22030 : : static bool
22031 : 361 : c_parser_omp_section_scan (c_parser *parser, const char *directive,
22032 : : bool tentative)
22033 : : {
22034 : 361 : if (!c_parser_nth_token_starts_std_attributes (parser, 1))
22035 : : return false;
22036 : 36 : unsigned int n = 3;
22037 : 36 : if (!c_parser_check_balanced_raw_token_sequence (parser, &n))
22038 : : return false;
22039 : 36 : c_token *token = c_parser_peek_nth_token_raw (parser, n);
22040 : 36 : if (token->type != CPP_CLOSE_SQUARE)
22041 : : return false;
22042 : 36 : token = c_parser_peek_nth_token_raw (parser, n + 1);
22043 : 36 : if (token->type != CPP_CLOSE_SQUARE)
22044 : : return false;
22045 : 36 : if (n < 9)
22046 : : return false;
22047 : 35 : if (c_parser_peek_nth_token_raw (parser, 3)->type == CPP_NAME
22048 : 35 : && c_parser_peek_nth_token_raw (parser, 4)->type == CPP_OPEN_PAREN
22049 : 35 : && c_parser_peek_nth_token_raw (parser, 5)->type == CPP_NAME)
22050 : : {
22051 : 0 : tree first = c_parser_peek_nth_token_raw (parser, 3)->value;
22052 : 0 : tree second = c_parser_peek_nth_token_raw (parser, 5)->value;
22053 : 0 : if (strcmp (IDENTIFIER_POINTER (first), "directive")
22054 : 0 : && strcmp (IDENTIFIER_POINTER (first), "__directive__"))
22055 : : return false;
22056 : 0 : if (strcmp (IDENTIFIER_POINTER (second), directive))
22057 : : return false;
22058 : : }
22059 : 35 : if (tentative)
22060 : : return true;
22061 : 32 : location_t first_loc = c_parser_peek_token (parser)->location;
22062 : 32 : location_t last_loc = c_parser_peek_nth_token_raw (parser, n + 1)->location;
22063 : 32 : location_t middle_loc = UNKNOWN_LOCATION;
22064 : 32 : tree std_attrs = c_parser_std_attribute_specifier_sequence (parser);
22065 : 32 : bool seen = false;
22066 : 32 : int cnt = 0;
22067 : 67 : for (tree attr = std_attrs; attr; attr = TREE_CHAIN (attr))
22068 : 35 : if (is_attribute_namespace_p ("omp", attr)
22069 : 35 : && is_attribute_p ("directive", get_attribute_name (attr)))
22070 : : {
22071 : 68 : for (tree a = TREE_VALUE (attr); a; a = TREE_CHAIN (a))
22072 : : {
22073 : 36 : tree d = TREE_VALUE (a);
22074 : 36 : gcc_assert (TREE_CODE (d) == C_TOKEN_VEC);
22075 : 36 : c_token *first = C_TOKEN_VEC_TOKENS (d)->address ();
22076 : 36 : cnt++;
22077 : 36 : if (first->type == CPP_NAME
22078 : 36 : && strcmp (IDENTIFIER_POINTER (first->value),
22079 : : directive) == 0)
22080 : : {
22081 : 31 : seen = true;
22082 : 31 : if (middle_loc == UNKNOWN_LOCATION)
22083 : 31 : middle_loc = first->location;
22084 : : }
22085 : : }
22086 : : }
22087 : 32 : if (!seen)
22088 : : return false;
22089 : 31 : if (cnt != 1 || TREE_CHAIN (std_attrs))
22090 : : {
22091 : 7 : error_at (make_location (first_loc, last_loc, middle_loc),
22092 : : "%<[[omp::directive(%s)]]%> must be the only specified "
22093 : : "attribute on a statement", directive);
22094 : 7 : return false;
22095 : : }
22096 : 24 : c_parser_handle_statement_omp_attributes (parser, std_attrs, NULL);
22097 : 24 : return true;
22098 : : }
22099 : :
22100 : : /* Parse an OpenMP structured block sequence. KIND is the corresponding
22101 : : separating directive. */
22102 : :
22103 : : static tree
22104 : 813 : c_parser_omp_structured_block_sequence (c_parser *parser,
22105 : : enum pragma_kind kind)
22106 : : {
22107 : 813 : tree stmt = push_stmt_list ();
22108 : 813 : c_parser_statement (parser, NULL);
22109 : 907 : do
22110 : : {
22111 : 860 : if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
22112 : : break;
22113 : 460 : if (c_parser_next_token_is (parser, CPP_EOF))
22114 : : break;
22115 : :
22116 : 460 : if (kind != PRAGMA_NONE
22117 : 460 : && c_parser_peek_token (parser)->pragma_kind == kind)
22118 : : break;
22119 : :
22120 : 69 : if (kind != PRAGMA_NONE
22121 : 104 : && c_parser_omp_section_scan (parser,
22122 : : kind == PRAGMA_OMP_SCAN
22123 : : ? "scan" : "section", false))
22124 : : break;
22125 : :
22126 : 47 : c_parser_statement (parser, NULL);
22127 : : }
22128 : : while (1);
22129 : 813 : return pop_stmt_list (stmt);
22130 : : }
22131 : :
22132 : : /* OpenMP 5.0:
22133 : :
22134 : : scan-loop-body:
22135 : : { structured-block scan-directive structured-block } */
22136 : :
22137 : : static void
22138 : 264 : c_parser_omp_scan_loop_body (c_parser *parser, bool open_brace_parsed)
22139 : : {
22140 : 264 : tree substmt;
22141 : 264 : location_t loc;
22142 : 264 : tree clauses = NULL_TREE;
22143 : 264 : bool found_scan = false;
22144 : :
22145 : 264 : loc = c_parser_peek_token (parser)->location;
22146 : 264 : if (!open_brace_parsed
22147 : 264 : && !c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
22148 : : {
22149 : : /* Avoid skipping until the end of the block. */
22150 : 1 : parser->error = false;
22151 : 1 : return;
22152 : : }
22153 : :
22154 : 263 : if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_SCAN)
22155 : 261 : substmt = c_parser_omp_structured_block_sequence (parser, PRAGMA_OMP_SCAN);
22156 : : else
22157 : : {
22158 : 2 : warning_at (c_parser_peek_token (parser)->location, OPT_Wopenmp,
22159 : : "%<#pragma omp scan%> with zero preceding executable "
22160 : : "statements");
22161 : 2 : substmt = build_empty_stmt (loc);
22162 : : }
22163 : 263 : substmt = build2 (OMP_SCAN, void_type_node, substmt, NULL_TREE);
22164 : 263 : SET_EXPR_LOCATION (substmt, loc);
22165 : 263 : add_stmt (substmt);
22166 : :
22167 : 263 : loc = c_parser_peek_token (parser)->location;
22168 : 263 : if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SCAN)
22169 : : {
22170 : 256 : enum omp_clause_code clause = OMP_CLAUSE_ERROR;
22171 : 256 : found_scan = true;
22172 : :
22173 : 256 : c_parser_consume_pragma (parser);
22174 : :
22175 : 256 : if (c_parser_next_token_is (parser, CPP_COMMA))
22176 : 4 : c_parser_consume_token (parser);
22177 : :
22178 : 256 : if (c_parser_next_token_is (parser, CPP_NAME))
22179 : : {
22180 : 254 : const char *p
22181 : 254 : = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
22182 : 254 : if (strcmp (p, "inclusive") == 0)
22183 : : clause = OMP_CLAUSE_INCLUSIVE;
22184 : 126 : else if (strcmp (p, "exclusive") == 0)
22185 : : clause = OMP_CLAUSE_EXCLUSIVE;
22186 : : }
22187 : : if (clause != OMP_CLAUSE_ERROR)
22188 : : {
22189 : 254 : c_parser_consume_token (parser);
22190 : 254 : clauses = c_parser_omp_var_list_parens (parser, clause, NULL_TREE);
22191 : : }
22192 : : else
22193 : 2 : c_parser_error (parser, "expected %<inclusive%> or "
22194 : : "%<exclusive%> clause");
22195 : 256 : c_parser_skip_to_pragma_eol (parser);
22196 : : }
22197 : : else
22198 : 7 : error ("expected %<#pragma omp scan%>");
22199 : :
22200 : 263 : clauses = c_finish_omp_clauses (clauses, C_ORT_OMP);
22201 : 263 : if (!c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
22202 : 254 : substmt = c_parser_omp_structured_block_sequence (parser, PRAGMA_NONE);
22203 : : else
22204 : : {
22205 : 9 : if (found_scan)
22206 : 2 : warning_at (loc, OPT_Wopenmp,
22207 : : "%<#pragma omp scan%> with zero succeeding executable "
22208 : : "statements");
22209 : 9 : substmt = build_empty_stmt (loc);
22210 : : }
22211 : 263 : substmt = build2 (OMP_SCAN, void_type_node, substmt, clauses);
22212 : 263 : SET_EXPR_LOCATION (substmt, loc);
22213 : 263 : add_stmt (substmt);
22214 : :
22215 : 263 : c_parser_skip_until_found (parser, CPP_CLOSE_BRACE,
22216 : : "expected %<}%>");
22217 : : }
22218 : :
22219 : :
22220 : : /* This function parses a single level of a loop nest, invoking itself
22221 : : recursively if necessary.
22222 : :
22223 : : loop-nest :: for (...) loop-body
22224 : : loop-body :: loop-nest
22225 : : | { [intervening-code] loop-body [intervening-code] }
22226 : : | final-loop-body
22227 : : intervening-code :: structured-block-sequence
22228 : : final-loop-body :: structured-block
22229 : :
22230 : : For a collapsed loop nest, only a single OMP_FOR is built, pulling out
22231 : : all the iterator information from the inner loops into the
22232 : : parser->omp_for_parse_state structure.
22233 : :
22234 : : The iterator decl, init, cond, and incr are stored in vectors.
22235 : :
22236 : : Initialization code for iterator variables is collected into
22237 : : parser->omp_for_parse_state->pre_body and ends up inserted directly
22238 : : into the OMP_FOR structure. */
22239 : :
22240 : : static tree
22241 : 15252 : c_parser_omp_loop_nest (c_parser *parser, bool *if_p)
22242 : : {
22243 : 15252 : tree decl, cond, incr, init;
22244 : 15252 : tree body = NULL_TREE;
22245 : 15252 : matching_parens parens;
22246 : 15252 : bool moreloops;
22247 : 15252 : unsigned char save_in_statement;
22248 : 15252 : tree loop_scope;
22249 : 15252 : location_t loc;
22250 : 15252 : struct omp_for_parse_data *omp_for_parse_state
22251 : : = parser->omp_for_parse_state;
22252 : 15252 : gcc_assert (omp_for_parse_state);
22253 : 15252 : int depth = omp_for_parse_state->depth;
22254 : :
22255 : : /* We have already matched the FOR token but not consumed it yet. */
22256 : 15252 : loc = c_parser_peek_token (parser)->location;
22257 : 15252 : gcc_assert (c_parser_next_token_is_keyword (parser, RID_FOR));
22258 : 15252 : c_parser_consume_token (parser);
22259 : :
22260 : : /* Forbid break/continue in the loop initializer, condition, and
22261 : : increment expressions. */
22262 : 15252 : save_in_statement = in_statement;
22263 : 15252 : in_statement = IN_OMP_BLOCK;
22264 : :
22265 : : /* We are not in intervening code now. */
22266 : 15252 : omp_for_parse_state->in_intervening_code = false;
22267 : :
22268 : 15252 : if (!parens.require_open (parser))
22269 : : {
22270 : 0 : omp_for_parse_state->fail = true;
22271 : 0 : return NULL_TREE;
22272 : : }
22273 : :
22274 : : /* An implicit scope block surrounds each level of FOR loop, for
22275 : : declarations of iteration variables at this loop depth. */
22276 : 15252 : loop_scope = c_begin_compound_stmt (true);
22277 : :
22278 : : /* Parse the initialization declaration or expression. */
22279 : 15252 : if (c_parser_next_tokens_start_declaration (parser))
22280 : : {
22281 : : /* This is a declaration, which must be added to the pre_body code. */
22282 : 4048 : tree this_pre_body = push_stmt_list ();
22283 : 4048 : c_in_omp_for = true;
22284 : 4048 : c_parser_declaration_or_fndef (parser, true, true, true, true, true);
22285 : 4048 : c_in_omp_for = false;
22286 : 4048 : this_pre_body = pop_stmt_list (this_pre_body);
22287 : 4048 : append_to_statement_list_force (this_pre_body,
22288 : : &(omp_for_parse_state->pre_body));
22289 : 4048 : decl = check_for_loop_decls (omp_for_parse_state->for_loc, flag_isoc99);
22290 : 4048 : if (decl == NULL)
22291 : 0 : goto error_init;
22292 : 4048 : if (DECL_INITIAL (decl) == error_mark_node)
22293 : 1 : decl = error_mark_node;
22294 : : init = decl;
22295 : : }
22296 : 11204 : else if (c_parser_next_token_is (parser, CPP_NAME)
22297 : 11204 : && c_parser_peek_2nd_token (parser)->type == CPP_EQ)
22298 : : {
22299 : 11202 : struct c_expr decl_exp;
22300 : 11202 : struct c_expr init_exp;
22301 : 11202 : location_t init_loc;
22302 : :
22303 : 11202 : decl_exp = c_parser_postfix_expression (parser);
22304 : 11202 : decl = decl_exp.value;
22305 : :
22306 : 11202 : c_parser_require (parser, CPP_EQ, "expected %<=%>");
22307 : :
22308 : 11202 : init_loc = c_parser_peek_token (parser)->location;
22309 : 11202 : init_exp = c_parser_expr_no_commas (parser, NULL);
22310 : 11202 : init_exp = default_function_array_read_conversion (init_loc,
22311 : : init_exp);
22312 : 11202 : c_in_omp_for = true;
22313 : 11202 : init = build_modify_expr (init_loc, decl, decl_exp.original_type,
22314 : : NOP_EXPR, init_loc, init_exp.value,
22315 : : init_exp.original_type);
22316 : 11202 : c_in_omp_for = false;
22317 : 11202 : init = c_process_expr_stmt (init_loc, init);
22318 : :
22319 : 11202 : c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
22320 : : }
22321 : : else
22322 : : {
22323 : 2 : error_init:
22324 : 2 : c_parser_error (parser,
22325 : : "expected iteration declaration or initialization");
22326 : 2 : c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
22327 : : "expected %<)%>");
22328 : 2 : omp_for_parse_state->fail = true;
22329 : 2 : goto parse_next;
22330 : : }
22331 : :
22332 : : /* Parse the loop condition. */
22333 : 15250 : cond = NULL_TREE;
22334 : 15250 : if (c_parser_next_token_is_not (parser, CPP_SEMICOLON))
22335 : : {
22336 : 15248 : location_t cond_loc = c_parser_peek_token (parser)->location;
22337 : 15248 : c_in_omp_for = true;
22338 : 15248 : struct c_expr cond_expr
22339 : 15248 : = c_parser_binary_expression (parser, NULL, NULL_TREE);
22340 : 15248 : c_in_omp_for = false;
22341 : :
22342 : 15248 : cond = cond_expr.value;
22343 : 15248 : cond = c_objc_common_truthvalue_conversion (cond_loc, cond);
22344 : 15248 : switch (cond_expr.original_code)
22345 : : {
22346 : : case GT_EXPR:
22347 : : case GE_EXPR:
22348 : : case LT_EXPR:
22349 : : case LE_EXPR:
22350 : : break;
22351 : 2335 : case NE_EXPR:
22352 : 2335 : if (omp_for_parse_state->code != OACC_LOOP)
22353 : : break;
22354 : : /* FALLTHRU. */
22355 : 7 : default:
22356 : : /* Can't be cond = error_mark_node, because we want to preserve
22357 : : the location until c_finish_omp_for. */
22358 : 7 : cond = build1 (NOP_EXPR, boolean_type_node, error_mark_node);
22359 : 7 : break;
22360 : : }
22361 : 15248 : protected_set_expr_location (cond, cond_loc);
22362 : : }
22363 : 15250 : c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
22364 : :
22365 : : /* Parse the increment expression. */
22366 : 15250 : incr = NULL_TREE;
22367 : 15250 : if (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN))
22368 : : {
22369 : 15250 : location_t incr_loc = c_parser_peek_token (parser)->location;
22370 : :
22371 : 15250 : incr = c_process_expr_stmt (incr_loc,
22372 : 30500 : c_parser_expression (parser).value);
22373 : : }
22374 : 15250 : parens.skip_until_found_close (parser);
22375 : :
22376 : 15250 : if (decl == NULL || decl == error_mark_node || init == error_mark_node)
22377 : 3 : omp_for_parse_state->fail = true;
22378 : : else
22379 : : {
22380 : 15247 : TREE_VEC_ELT (omp_for_parse_state->declv, depth) = decl;
22381 : 15247 : TREE_VEC_ELT (omp_for_parse_state->initv, depth) = init;
22382 : 15247 : TREE_VEC_ELT (omp_for_parse_state->condv, depth) = cond;
22383 : 15247 : TREE_VEC_ELT (omp_for_parse_state->incrv, depth) = incr;
22384 : : }
22385 : :
22386 : 15252 : parse_next:
22387 : 15252 : moreloops = depth < omp_for_parse_state->count - 1;
22388 : 15252 : omp_for_parse_state->want_nested_loop = moreloops;
22389 : 20435 : if (moreloops && c_parser_next_token_is_keyword (parser, RID_FOR))
22390 : : {
22391 : 5077 : omp_for_parse_state->depth++;
22392 : 5077 : body = c_parser_omp_loop_nest (parser, if_p);
22393 : 5077 : omp_for_parse_state->depth--;
22394 : : }
22395 : 10281 : else if (moreloops && c_parser_next_token_is (parser, CPP_OPEN_BRACE))
22396 : : {
22397 : : /* This is the open brace in the loop-body grammar production. Rather
22398 : : than trying to special-case braces, just parse it as a compound
22399 : : statement and handle the nested loop-body case there. Note that
22400 : : when we see a further open brace inside the compound statement
22401 : : loop-body, we don't know whether it is the start of intervening
22402 : : code that is a compound statement, or a level of braces
22403 : : surrounding a nested loop-body. Use the WANT_NESTED_LOOP state
22404 : : bit to ensure we have only one nested loop at each level. */
22405 : 103 : omp_for_parse_state->in_intervening_code = true;
22406 : 103 : body = c_parser_compound_statement (parser, NULL);
22407 : 103 : omp_for_parse_state->in_intervening_code = false;
22408 : 103 : if (omp_for_parse_state->want_nested_loop)
22409 : : {
22410 : : /* We have already parsed the whole loop body and not found a
22411 : : nested loop. */
22412 : 13 : error_at (omp_for_parse_state->for_loc,
22413 : : "not enough nested loops");
22414 : 13 : omp_for_parse_state->fail = true;
22415 : : }
22416 : 15252 : if_p = NULL;
22417 : : }
22418 : : else
22419 : : {
22420 : : /* This is the final-loop-body case in the grammar: we have
22421 : : something that is not a FOR and not an open brace. */
22422 : 10072 : if (moreloops)
22423 : : {
22424 : : /* If we were expecting a nested loop, give an error and mark
22425 : : that parsing has failed, and try to recover by parsing the
22426 : : body as regular code without further collapsing. */
22427 : 3 : error_at (omp_for_parse_state->for_loc,
22428 : : "not enough nested loops");
22429 : 3 : omp_for_parse_state->fail = true;
22430 : : }
22431 : 10072 : in_statement = IN_OMP_FOR;
22432 : 10072 : parser->omp_for_parse_state = NULL;
22433 : 10072 : body = push_stmt_list ();
22434 : 10072 : if (omp_for_parse_state->inscan)
22435 : 264 : c_parser_omp_scan_loop_body (parser, false);
22436 : : else
22437 : 9808 : add_stmt (c_parser_c99_block_statement (parser, if_p));
22438 : 10072 : body = pop_stmt_list (body);
22439 : 10072 : parser->omp_for_parse_state = omp_for_parse_state;
22440 : : }
22441 : 15252 : in_statement = save_in_statement;
22442 : 15252 : omp_for_parse_state->want_nested_loop = false;
22443 : 15252 : omp_for_parse_state->in_intervening_code = true;
22444 : :
22445 : : /* Pop and return the implicit scope surrounding this level of loop.
22446 : : If the iteration variable at this depth was bound in the for loop,
22447 : : pull out and save the binding. Later in c_parser_omp_for_loop,
22448 : : these bindings will be moved to the scope surrounding the entire
22449 : : OMP_FOR. That keeps the gimplifier happy later on, and meanwhile
22450 : : we have already resolved all references to the iteration variable
22451 : : in its true scope. */
22452 : 15252 : add_stmt (body);
22453 : 15252 : body = c_end_compound_stmt (loc, loop_scope, true);
22454 : 15252 : if (decl && TREE_CODE (body) == BIND_EXPR)
22455 : : {
22456 : 4434 : tree t = BIND_EXPR_VARS (body);
22457 : 4434 : tree prev = NULL_TREE, next = NULL_TREE;
22458 : 4870 : while (t)
22459 : : {
22460 : 4483 : next = DECL_CHAIN (t);
22461 : 4483 : if (t == decl)
22462 : : {
22463 : 4047 : if (prev)
22464 : 0 : DECL_CHAIN (prev) = next;
22465 : : else
22466 : : {
22467 : 4047 : BIND_EXPR_VARS (body) = next;
22468 : 4047 : BLOCK_VARS (BIND_EXPR_BLOCK (body)) = next;
22469 : : }
22470 : 4047 : DECL_CHAIN (t) = omp_for_parse_state->bindings;
22471 : 4047 : omp_for_parse_state->bindings = t;
22472 : 4047 : break;
22473 : : }
22474 : : else
22475 : : {
22476 : : prev = t;
22477 : : t = next;
22478 : : }
22479 : : }
22480 : 4434 : if (BIND_EXPR_VARS (body) == NULL_TREE)
22481 : 4047 : body = BIND_EXPR_BODY (body);
22482 : : }
22483 : :
22484 : : return body;
22485 : : }
22486 : :
22487 : : /* Parse the restricted form of loop statements allowed by OpenACC and OpenMP.
22488 : : The real trick here is to determine the loop control variable early
22489 : : so that we can push a new decl if necessary to make it private.
22490 : : LOC is the location of the "acc" or "omp" in "#pragma acc" or "#pragma omp",
22491 : : respectively. */
22492 : :
22493 : : static tree
22494 : 10093 : c_parser_omp_for_loop (location_t loc, c_parser *parser, enum tree_code code,
22495 : : tree clauses, tree *cclauses, bool *if_p)
22496 : : {
22497 : 10093 : tree body, stmt, cl;
22498 : 10093 : tree ret = NULL_TREE;
22499 : 10093 : tree ordered_cl = NULL_TREE;
22500 : 10093 : int i, collapse = 1, ordered = 0, count;
22501 : 10093 : bool tiling = false;
22502 : 10093 : bool inscan = false;
22503 : 10093 : struct omp_for_parse_data data;
22504 : 10093 : struct omp_for_parse_data *save_data = parser->omp_for_parse_state;
22505 : :
22506 : 24578 : for (cl = clauses; cl; cl = OMP_CLAUSE_CHAIN (cl))
22507 : 14485 : if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_COLLAPSE)
22508 : 2790 : collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (cl));
22509 : 11695 : else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_TILE)
22510 : : {
22511 : 110 : tiling = true;
22512 : 110 : collapse = list_length (OMP_CLAUSE_TILE_LIST (cl));
22513 : : }
22514 : 11585 : else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_ORDERED
22515 : 11585 : && OMP_CLAUSE_ORDERED_EXPR (cl))
22516 : : {
22517 : 156 : ordered_cl = cl;
22518 : 156 : ordered = tree_to_shwi (OMP_CLAUSE_ORDERED_EXPR (cl));
22519 : : }
22520 : 11429 : else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_REDUCTION
22521 : 1924 : && OMP_CLAUSE_REDUCTION_INSCAN (cl)
22522 : 11810 : && (code == OMP_SIMD || code == OMP_FOR))
22523 : : inscan = true;
22524 : :
22525 : 10093 : if (ordered && ordered < collapse)
22526 : : {
22527 : 2 : error_at (OMP_CLAUSE_LOCATION (ordered_cl),
22528 : : "%<ordered%> clause parameter is less than %<collapse%>");
22529 : 2 : OMP_CLAUSE_ORDERED_EXPR (ordered_cl)
22530 : 2 : = build_int_cst (NULL_TREE, collapse);
22531 : 2 : ordered = collapse;
22532 : : }
22533 : :
22534 : 10093 : gcc_assert (tiling || (collapse >= 1 && ordered >= 0));
22535 : 10093 : count = ordered ? ordered : collapse;
22536 : :
22537 : 10093 : if (!c_parser_next_token_is_keyword (parser, RID_FOR))
22538 : : {
22539 : 8 : c_parser_error (parser, "for statement expected");
22540 : 8 : return NULL;
22541 : : }
22542 : :
22543 : : /* Initialize parse state for recursive descent. */
22544 : 10085 : data.declv = make_tree_vec (count);
22545 : 10085 : data.initv = make_tree_vec (count);
22546 : 10085 : data.condv = make_tree_vec (count);
22547 : 10085 : data.incrv = make_tree_vec (count);
22548 : 10085 : data.pre_body = NULL_TREE;;
22549 : 10085 : data.bindings = NULL_TREE;
22550 : 10085 : data.for_loc = c_parser_peek_token (parser)->location;
22551 : 10085 : data.count = count;
22552 : 10085 : data.depth = 0;
22553 : 10085 : data.want_nested_loop = true;
22554 : 10085 : data.ordered = ordered > 0;
22555 : 10085 : data.in_intervening_code = false;
22556 : 10085 : data.perfect_nesting_fail = false;
22557 : 10085 : data.fail = false;
22558 : 10085 : data.inscan = inscan;
22559 : 10085 : data.saw_intervening_code = false;
22560 : 10085 : data.code = code;
22561 : 10085 : parser->omp_for_parse_state = &data;
22562 : :
22563 : 10085 : body = c_parser_omp_loop_nest (parser, if_p);
22564 : :
22565 : : /* Add saved bindings for iteration variables that were declared in
22566 : : the nested for loop to the scope surrounding the entire loop. */
22567 : 14132 : for (tree t = data.bindings; t; )
22568 : : {
22569 : 4047 : tree n = TREE_CHAIN (t);
22570 : 4047 : TREE_CHAIN (t) = NULL_TREE;
22571 : 4047 : pushdecl (t);
22572 : 4047 : t = n;
22573 : : }
22574 : :
22575 : : /* Only bother calling c_finish_omp_for if we haven't already generated
22576 : : an error from the initialization parsing. */
22577 : 10085 : if (!data.fail)
22578 : : {
22579 : 10050 : c_in_omp_for = true;
22580 : 10050 : stmt = c_finish_omp_for (loc, code, data.declv, NULL, data.initv,
22581 : : data.condv, data.incrv,
22582 : : body, data.pre_body, true);
22583 : 10050 : c_in_omp_for = false;
22584 : :
22585 : : /* Check for iterators appearing in lb, b or incr expressions. */
22586 : 10050 : if (stmt && !c_omp_check_loop_iv (stmt, data.declv, NULL))
22587 : : stmt = NULL_TREE;
22588 : :
22589 : : /* Check for errors involving lb/ub/incr expressions referencing
22590 : : variables declared in intervening code. */
22591 : 10050 : if (data.saw_intervening_code
22592 : 10050 : && !c_omp_check_loop_binding_exprs (stmt, NULL))
22593 : : stmt = NULL_TREE;
22594 : :
22595 : 10044 : if (stmt)
22596 : : {
22597 : 9908 : add_stmt (stmt);
22598 : :
22599 : 24915 : for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (stmt)); i++)
22600 : : {
22601 : 15007 : tree init = TREE_VEC_ELT (OMP_FOR_INIT (stmt), i);
22602 : 15007 : gcc_assert (TREE_CODE (init) == MODIFY_EXPR);
22603 : 15007 : tree decl = TREE_OPERAND (init, 0);
22604 : 15007 : tree cond = TREE_VEC_ELT (OMP_FOR_COND (stmt), i);
22605 : 15007 : gcc_assert (COMPARISON_CLASS_P (cond));
22606 : 15007 : gcc_assert (TREE_OPERAND (cond, 0) == decl);
22607 : :
22608 : 15007 : tree op0 = TREE_OPERAND (init, 1);
22609 : 15007 : if (!OMP_FOR_NON_RECTANGULAR (stmt)
22610 : 15007 : || TREE_CODE (op0) != TREE_VEC)
22611 : 14827 : TREE_OPERAND (init, 1) = c_fully_fold (op0, false, NULL);
22612 : : else
22613 : : {
22614 : 180 : TREE_VEC_ELT (op0, 1)
22615 : 180 : = c_fully_fold (TREE_VEC_ELT (op0, 1), false, NULL);
22616 : 180 : TREE_VEC_ELT (op0, 2)
22617 : 360 : = c_fully_fold (TREE_VEC_ELT (op0, 2), false, NULL);
22618 : : }
22619 : :
22620 : 15007 : tree op1 = TREE_OPERAND (cond, 1);
22621 : 15007 : if (!OMP_FOR_NON_RECTANGULAR (stmt)
22622 : 15007 : || TREE_CODE (op1) != TREE_VEC)
22623 : 14808 : TREE_OPERAND (cond, 1) = c_fully_fold (op1, false, NULL);
22624 : : else
22625 : : {
22626 : 199 : TREE_VEC_ELT (op1, 1)
22627 : 199 : = c_fully_fold (TREE_VEC_ELT (op1, 1), false, NULL);
22628 : 199 : TREE_VEC_ELT (op1, 2)
22629 : 398 : = c_fully_fold (TREE_VEC_ELT (op1, 2), false, NULL);
22630 : : }
22631 : : }
22632 : :
22633 : 9908 : if (cclauses != NULL
22634 : 5090 : && cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] != NULL)
22635 : : {
22636 : 743 : tree *c;
22637 : 3284 : for (c = &cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL]; *c ; )
22638 : 2541 : if (OMP_CLAUSE_CODE (*c) != OMP_CLAUSE_FIRSTPRIVATE
22639 : 2541 : && OMP_CLAUSE_CODE (*c) != OMP_CLAUSE_LASTPRIVATE)
22640 : 1844 : c = &OMP_CLAUSE_CHAIN (*c);
22641 : : else
22642 : : {
22643 : 1435 : for (i = 0; i < count; i++)
22644 : 920 : if (TREE_VEC_ELT (data.declv, i) == OMP_CLAUSE_DECL (*c))
22645 : : break;
22646 : 697 : if (i == count)
22647 : 515 : c = &OMP_CLAUSE_CHAIN (*c);
22648 : 182 : else if (OMP_CLAUSE_CODE (*c) == OMP_CLAUSE_FIRSTPRIVATE)
22649 : : {
22650 : 1 : error_at (loc,
22651 : : "iteration variable %qD should not be firstprivate",
22652 : 1 : OMP_CLAUSE_DECL (*c));
22653 : 1 : *c = OMP_CLAUSE_CHAIN (*c);
22654 : : }
22655 : : else
22656 : : {
22657 : : /* Move lastprivate (decl) clause to
22658 : : OMP_FOR_CLAUSES. */
22659 : 181 : tree l = *c;
22660 : 181 : *c = OMP_CLAUSE_CHAIN (*c);
22661 : 181 : if (code == OMP_SIMD)
22662 : : {
22663 : 46 : OMP_CLAUSE_CHAIN (l)
22664 : 46 : = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
22665 : 46 : cclauses[C_OMP_CLAUSE_SPLIT_FOR] = l;
22666 : : }
22667 : : else
22668 : : {
22669 : 135 : OMP_CLAUSE_CHAIN (l) = clauses;
22670 : 135 : clauses = l;
22671 : : }
22672 : : }
22673 : : }
22674 : : }
22675 : 9908 : OMP_FOR_CLAUSES (stmt) = clauses;
22676 : : }
22677 : : ret = stmt;
22678 : : }
22679 : :
22680 : 10085 : parser->omp_for_parse_state = save_data;
22681 : 10085 : return ret;
22682 : : }
22683 : :
22684 : : /* Helper function for OpenMP parsing, split clauses and call
22685 : : finish_omp_clauses on each of the set of clauses afterwards. */
22686 : :
22687 : : static void
22688 : 6332 : omp_split_clauses (location_t loc, enum tree_code code,
22689 : : omp_clause_mask mask, tree clauses, tree *cclauses)
22690 : : {
22691 : 6332 : int i;
22692 : 6332 : c_omp_split_clauses (loc, code, mask, clauses, cclauses);
22693 : 50656 : for (i = 0; i < C_OMP_CLAUSE_SPLIT_COUNT; i++)
22694 : 37992 : if (cclauses[i])
22695 : 19717 : cclauses[i] = c_finish_omp_clauses (cclauses[i],
22696 : : i == C_OMP_CLAUSE_SPLIT_TARGET
22697 : : ? C_ORT_OMP_TARGET : C_ORT_OMP);
22698 : 6332 : }
22699 : :
22700 : : /* OpenMP 5.0:
22701 : : #pragma omp loop loop-clause[optseq] new-line
22702 : : for-loop
22703 : :
22704 : : LOC is the location of the #pragma token.
22705 : : */
22706 : :
22707 : : #define OMP_LOOP_CLAUSE_MASK \
22708 : : ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
22709 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
22710 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
22711 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
22712 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_BIND) \
22713 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
22714 : :
22715 : : static tree
22716 : 233 : c_parser_omp_loop (location_t loc, c_parser *parser,
22717 : : char *p_name, omp_clause_mask mask, tree *cclauses,
22718 : : bool *if_p)
22719 : : {
22720 : 233 : tree block, clauses, ret;
22721 : :
22722 : 233 : strcat (p_name, " loop");
22723 : 233 : mask |= OMP_LOOP_CLAUSE_MASK;
22724 : :
22725 : 233 : clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
22726 : 233 : if (cclauses)
22727 : : {
22728 : 76 : omp_split_clauses (loc, OMP_LOOP, mask, clauses, cclauses);
22729 : 76 : clauses = cclauses[C_OMP_CLAUSE_SPLIT_LOOP];
22730 : : }
22731 : :
22732 : 233 : block = c_begin_compound_stmt (true);
22733 : 233 : ret = c_parser_omp_for_loop (loc, parser, OMP_LOOP, clauses, cclauses, if_p);
22734 : 233 : block = c_end_compound_stmt (loc, block, true);
22735 : 233 : add_stmt (block);
22736 : :
22737 : 233 : return ret;
22738 : : }
22739 : :
22740 : : /* OpenMP 4.0:
22741 : : #pragma omp simd simd-clause[optseq] new-line
22742 : : for-loop
22743 : :
22744 : : LOC is the location of the #pragma token.
22745 : : */
22746 : :
22747 : : #define OMP_SIMD_CLAUSE_MASK \
22748 : : ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SAFELEN) \
22749 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
22750 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
22751 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
22752 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
22753 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
22754 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
22755 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
22756 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
22757 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NONTEMPORAL) \
22758 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
22759 : :
22760 : : static tree
22761 : 3462 : c_parser_omp_simd (location_t loc, c_parser *parser,
22762 : : char *p_name, omp_clause_mask mask, tree *cclauses,
22763 : : bool *if_p)
22764 : : {
22765 : 3462 : tree block, clauses, ret;
22766 : :
22767 : 3462 : strcat (p_name, " simd");
22768 : 3462 : mask |= OMP_SIMD_CLAUSE_MASK;
22769 : :
22770 : 3462 : clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
22771 : 3462 : if (cclauses)
22772 : : {
22773 : 2752 : omp_split_clauses (loc, OMP_SIMD, mask, clauses, cclauses);
22774 : 2752 : clauses = cclauses[C_OMP_CLAUSE_SPLIT_SIMD];
22775 : : }
22776 : :
22777 : 3462 : block = c_begin_compound_stmt (true);
22778 : 3462 : ret = c_parser_omp_for_loop (loc, parser, OMP_SIMD, clauses, cclauses, if_p);
22779 : 3462 : block = c_end_compound_stmt (loc, block, true);
22780 : 3462 : add_stmt (block);
22781 : :
22782 : 3462 : return ret;
22783 : : }
22784 : :
22785 : : /* OpenMP 2.5:
22786 : : #pragma omp for for-clause[optseq] new-line
22787 : : for-loop
22788 : :
22789 : : OpenMP 4.0:
22790 : : #pragma omp for simd for-simd-clause[optseq] new-line
22791 : : for-loop
22792 : :
22793 : : LOC is the location of the #pragma token.
22794 : : */
22795 : :
22796 : : #define OMP_FOR_CLAUSE_MASK \
22797 : : ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
22798 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
22799 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
22800 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
22801 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
22802 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED) \
22803 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE) \
22804 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
22805 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
22806 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
22807 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
22808 : :
22809 : : static tree
22810 : 5874 : c_parser_omp_for (location_t loc, c_parser *parser,
22811 : : char *p_name, omp_clause_mask mask, tree *cclauses,
22812 : : bool *if_p)
22813 : : {
22814 : 5874 : tree block, clauses, ret;
22815 : :
22816 : 5874 : strcat (p_name, " for");
22817 : 5874 : mask |= OMP_FOR_CLAUSE_MASK;
22818 : : /* parallel for{, simd} disallows nowait clause, but for
22819 : : target {teams distribute ,}parallel for{, simd} it should be accepted. */
22820 : 5874 : if (cclauses && (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) == 0)
22821 : 3095 : mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT);
22822 : : /* Composite distribute parallel for{, simd} disallows ordered clause. */
22823 : 5874 : if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
22824 : 2701 : mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED);
22825 : :
22826 : 5874 : if (c_parser_next_token_is (parser, CPP_NAME))
22827 : : {
22828 : 5275 : const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
22829 : :
22830 : 5275 : if (strcmp (p, "simd") == 0)
22831 : : {
22832 : 2188 : tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
22833 : 2188 : if (cclauses == NULL)
22834 : 294 : cclauses = cclauses_buf;
22835 : :
22836 : 2188 : c_parser_consume_token (parser);
22837 : 2188 : if (!flag_openmp) /* flag_openmp_simd */
22838 : 14 : return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
22839 : 14 : if_p);
22840 : 2174 : block = c_begin_compound_stmt (true);
22841 : 2174 : ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses, if_p);
22842 : 2174 : block = c_end_compound_stmt (loc, block, true);
22843 : 2174 : if (ret == NULL_TREE)
22844 : : return ret;
22845 : 2163 : ret = make_node (OMP_FOR);
22846 : 2163 : TREE_TYPE (ret) = void_type_node;
22847 : 2163 : OMP_FOR_BODY (ret) = block;
22848 : 2163 : OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
22849 : 2163 : SET_EXPR_LOCATION (ret, loc);
22850 : 2163 : add_stmt (ret);
22851 : 2163 : return ret;
22852 : : }
22853 : : }
22854 : 3686 : if (!flag_openmp) /* flag_openmp_simd */
22855 : : {
22856 : 9 : c_parser_skip_to_pragma_eol (parser, false);
22857 : 9 : return NULL_TREE;
22858 : : }
22859 : :
22860 : : /* Composite distribute parallel for disallows linear clause. */
22861 : 3677 : if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
22862 : 1349 : mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR);
22863 : :
22864 : 3677 : clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
22865 : 3677 : if (cclauses)
22866 : : {
22867 : 2284 : omp_split_clauses (loc, OMP_FOR, mask, clauses, cclauses);
22868 : 2284 : clauses = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
22869 : : }
22870 : :
22871 : 3677 : block = c_begin_compound_stmt (true);
22872 : 3677 : ret = c_parser_omp_for_loop (loc, parser, OMP_FOR, clauses, cclauses, if_p);
22873 : 3677 : block = c_end_compound_stmt (loc, block, true);
22874 : 3677 : add_stmt (block);
22875 : :
22876 : 3677 : return ret;
22877 : : }
22878 : :
22879 : : static tree c_parser_omp_taskloop (location_t, c_parser *, char *,
22880 : : omp_clause_mask, tree *, bool *);
22881 : :
22882 : : /* OpenMP 2.5:
22883 : : # pragma omp master new-line
22884 : : structured-block
22885 : :
22886 : : LOC is the location of the #pragma token.
22887 : : */
22888 : :
22889 : : static tree
22890 : 229 : c_parser_omp_master (location_t loc, c_parser *parser,
22891 : : char *p_name, omp_clause_mask mask, tree *cclauses,
22892 : : bool *if_p)
22893 : : {
22894 : 229 : tree block, clauses, ret;
22895 : :
22896 : 229 : strcat (p_name, " master");
22897 : :
22898 : 229 : if (c_parser_next_token_is (parser, CPP_NAME))
22899 : : {
22900 : 122 : const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
22901 : :
22902 : 122 : if (strcmp (p, "taskloop") == 0)
22903 : : {
22904 : 93 : tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
22905 : 93 : if (cclauses == NULL)
22906 : 47 : cclauses = cclauses_buf;
22907 : :
22908 : 93 : c_parser_consume_token (parser);
22909 : 93 : if (!flag_openmp) /* flag_openmp_simd */
22910 : 4 : return c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
22911 : 4 : if_p);
22912 : 89 : block = c_begin_compound_stmt (true);
22913 : 89 : ret = c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
22914 : : if_p);
22915 : 89 : block = c_end_compound_stmt (loc, block, true);
22916 : 89 : if (ret == NULL_TREE)
22917 : : return ret;
22918 : 89 : ret = c_finish_omp_master (loc, block);
22919 : 89 : OMP_MASTER_COMBINED (ret) = 1;
22920 : 89 : return ret;
22921 : : }
22922 : : }
22923 : 136 : if (!flag_openmp) /* flag_openmp_simd */
22924 : : {
22925 : 2 : c_parser_skip_to_pragma_eol (parser, false);
22926 : 2 : return NULL_TREE;
22927 : : }
22928 : :
22929 : 134 : if (cclauses)
22930 : : {
22931 : 41 : clauses = c_parser_omp_all_clauses (parser, mask, p_name, false);
22932 : 41 : omp_split_clauses (loc, OMP_MASTER, mask, clauses, cclauses);
22933 : : }
22934 : : else
22935 : 93 : c_parser_skip_to_pragma_eol (parser);
22936 : :
22937 : 134 : return c_finish_omp_master (loc, c_parser_omp_structured_block (parser,
22938 : 134 : if_p));
22939 : : }
22940 : :
22941 : : /* OpenMP 5.1:
22942 : : # pragma omp masked masked-clauses new-line
22943 : : structured-block
22944 : :
22945 : : LOC is the location of the #pragma token.
22946 : : */
22947 : :
22948 : : #define OMP_MASKED_CLAUSE_MASK \
22949 : : (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FILTER)
22950 : :
22951 : : static tree
22952 : 86 : c_parser_omp_masked (location_t loc, c_parser *parser,
22953 : : char *p_name, omp_clause_mask mask, tree *cclauses,
22954 : : bool *if_p)
22955 : : {
22956 : 86 : tree block, clauses, ret;
22957 : :
22958 : 86 : strcat (p_name, " masked");
22959 : 86 : mask |= OMP_MASKED_CLAUSE_MASK;
22960 : :
22961 : 86 : if (c_parser_next_token_is (parser, CPP_NAME))
22962 : : {
22963 : 60 : const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
22964 : :
22965 : 60 : if (strcmp (p, "taskloop") == 0)
22966 : : {
22967 : 41 : tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
22968 : 41 : if (cclauses == NULL)
22969 : 20 : cclauses = cclauses_buf;
22970 : :
22971 : 41 : c_parser_consume_token (parser);
22972 : 41 : if (!flag_openmp) /* flag_openmp_simd */
22973 : 0 : return c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
22974 : 0 : if_p);
22975 : 41 : block = c_begin_compound_stmt (true);
22976 : 41 : ret = c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
22977 : : if_p);
22978 : 41 : block = c_end_compound_stmt (loc, block, true);
22979 : 41 : if (ret == NULL_TREE)
22980 : : return ret;
22981 : 41 : ret = c_finish_omp_masked (loc, block,
22982 : : cclauses[C_OMP_CLAUSE_SPLIT_MASKED]);
22983 : 41 : OMP_MASKED_COMBINED (ret) = 1;
22984 : 41 : return ret;
22985 : : }
22986 : : }
22987 : 45 : if (!flag_openmp) /* flag_openmp_simd */
22988 : : {
22989 : 0 : c_parser_skip_to_pragma_eol (parser, false);
22990 : 0 : return NULL_TREE;
22991 : : }
22992 : :
22993 : 45 : clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
22994 : 45 : if (cclauses)
22995 : : {
22996 : 9 : omp_split_clauses (loc, OMP_MASKED, mask, clauses, cclauses);
22997 : 9 : clauses = cclauses[C_OMP_CLAUSE_SPLIT_MASKED];
22998 : : }
22999 : :
23000 : 45 : return c_finish_omp_masked (loc, c_parser_omp_structured_block (parser,
23001 : : if_p),
23002 : 45 : clauses);
23003 : : }
23004 : :
23005 : : /* OpenMP 2.5:
23006 : : # pragma omp ordered new-line
23007 : : structured-block
23008 : :
23009 : : OpenMP 4.5:
23010 : : # pragma omp ordered ordered-clauses new-line
23011 : : structured-block
23012 : :
23013 : : # pragma omp ordered depend-clauses new-line
23014 : :
23015 : : OpenMP 5.2
23016 : : # pragma omp ordered doacross-clauses new-line */
23017 : :
23018 : : #define OMP_ORDERED_CLAUSE_MASK \
23019 : : ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREADS) \
23020 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMD))
23021 : :
23022 : : #define OMP_ORDERED_DEPEND_CLAUSE_MASK \
23023 : : ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
23024 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DOACROSS))
23025 : :
23026 : : static bool
23027 : 512 : c_parser_omp_ordered (c_parser *parser, enum pragma_context context,
23028 : : bool *if_p)
23029 : : {
23030 : 512 : location_t loc = c_parser_peek_token (parser)->location;
23031 : 512 : c_parser_consume_pragma (parser);
23032 : :
23033 : 512 : if (context != pragma_stmt && context != pragma_compound)
23034 : : {
23035 : 1 : c_parser_error (parser, "expected declaration specifiers");
23036 : 1 : c_parser_skip_to_pragma_eol (parser, false);
23037 : 1 : return false;
23038 : : }
23039 : :
23040 : 511 : int n = 1;
23041 : 511 : if (c_parser_next_token_is (parser, CPP_COMMA))
23042 : 8 : n = 2;
23043 : :
23044 : 511 : if (c_parser_peek_nth_token (parser, n)->type == CPP_NAME)
23045 : : {
23046 : 403 : const char *p
23047 : 403 : = IDENTIFIER_POINTER (c_parser_peek_nth_token (parser, n)->value);
23048 : :
23049 : 403 : if (!strcmp ("depend", p) || !strcmp ("doacross", p))
23050 : : {
23051 : 323 : if (!flag_openmp) /* flag_openmp_simd */
23052 : : {
23053 : 2 : c_parser_skip_to_pragma_eol (parser, false);
23054 : 2 : return false;
23055 : : }
23056 : 321 : if (context == pragma_stmt)
23057 : : {
23058 : 16 : error_at (loc,
23059 : : "%<#pragma omp ordered%> with %qs clause may "
23060 : : "only be used in compound statements", p);
23061 : 16 : c_parser_skip_to_pragma_eol (parser, false);
23062 : 16 : return true;
23063 : : }
23064 : :
23065 : 305 : tree clauses
23066 : 305 : = c_parser_omp_all_clauses (parser,
23067 : 305 : OMP_ORDERED_DEPEND_CLAUSE_MASK,
23068 : : "#pragma omp ordered");
23069 : 305 : c_finish_omp_ordered (loc, clauses, NULL_TREE);
23070 : 305 : return false;
23071 : : }
23072 : : }
23073 : :
23074 : 188 : tree clauses = c_parser_omp_all_clauses (parser, OMP_ORDERED_CLAUSE_MASK,
23075 : : "#pragma omp ordered");
23076 : :
23077 : 188 : if (!flag_openmp /* flag_openmp_simd */
23078 : 188 : && omp_find_clause (clauses, OMP_CLAUSE_SIMD) == NULL_TREE)
23079 : : return false;
23080 : :
23081 : 186 : c_finish_omp_ordered (loc, clauses,
23082 : : c_parser_omp_structured_block (parser, if_p));
23083 : 186 : return true;
23084 : : }
23085 : :
23086 : : /* OpenMP 2.5:
23087 : :
23088 : : section-scope:
23089 : : { section-sequence }
23090 : :
23091 : : section-sequence:
23092 : : section-directive[opt] structured-block
23093 : : section-sequence section-directive structured-block
23094 : :
23095 : : OpenMP 5.1 allows structured-block-sequence instead of structured-block.
23096 : :
23097 : : SECTIONS_LOC is the location of the #pragma omp sections. */
23098 : :
23099 : : static tree
23100 : 141 : c_parser_omp_sections_scope (location_t sections_loc, c_parser *parser)
23101 : : {
23102 : 141 : tree stmt, substmt;
23103 : 141 : bool error_suppress = false;
23104 : 141 : location_t loc;
23105 : :
23106 : 141 : loc = c_parser_peek_token (parser)->location;
23107 : 141 : if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
23108 : : {
23109 : : /* Avoid skipping until the end of the block. */
23110 : 2 : parser->error = false;
23111 : 2 : return NULL_TREE;
23112 : : }
23113 : :
23114 : 139 : stmt = push_stmt_list ();
23115 : :
23116 : 139 : if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_SECTION
23117 : 139 : && !c_parser_omp_section_scan (parser, "section", true))
23118 : : {
23119 : 80 : substmt = c_parser_omp_structured_block_sequence (parser,
23120 : : PRAGMA_OMP_SECTION);
23121 : 80 : substmt = build1 (OMP_SECTION, void_type_node, substmt);
23122 : 80 : SET_EXPR_LOCATION (substmt, loc);
23123 : 80 : add_stmt (substmt);
23124 : : }
23125 : :
23126 : 575 : while (1)
23127 : : {
23128 : 357 : if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
23129 : : break;
23130 : 218 : if (c_parser_next_token_is (parser, CPP_EOF))
23131 : : break;
23132 : :
23133 : 218 : loc = c_parser_peek_token (parser)->location;
23134 : 218 : c_parser_omp_section_scan (parser, "section", false);
23135 : 218 : if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SECTION)
23136 : : {
23137 : 217 : c_parser_consume_pragma (parser);
23138 : 217 : c_parser_skip_to_pragma_eol (parser);
23139 : 217 : error_suppress = false;
23140 : : }
23141 : 1 : else if (!error_suppress)
23142 : : {
23143 : 1 : error_at (loc, "expected %<#pragma omp section%> or %<}%>");
23144 : 1 : error_suppress = true;
23145 : : }
23146 : :
23147 : 218 : substmt = c_parser_omp_structured_block_sequence (parser,
23148 : : PRAGMA_OMP_SECTION);
23149 : 218 : substmt = build1 (OMP_SECTION, void_type_node, substmt);
23150 : 218 : SET_EXPR_LOCATION (substmt, loc);
23151 : 218 : add_stmt (substmt);
23152 : : }
23153 : 139 : c_parser_skip_until_found (parser, CPP_CLOSE_BRACE,
23154 : : "expected %<#pragma omp section%> or %<}%>");
23155 : :
23156 : 139 : substmt = pop_stmt_list (stmt);
23157 : :
23158 : 139 : stmt = make_node (OMP_SECTIONS);
23159 : 139 : SET_EXPR_LOCATION (stmt, sections_loc);
23160 : 139 : TREE_TYPE (stmt) = void_type_node;
23161 : 139 : OMP_SECTIONS_BODY (stmt) = substmt;
23162 : :
23163 : 139 : return add_stmt (stmt);
23164 : : }
23165 : :
23166 : : /* OpenMP 2.5:
23167 : : # pragma omp sections sections-clause[optseq] newline
23168 : : sections-scope
23169 : :
23170 : : LOC is the location of the #pragma token.
23171 : : */
23172 : :
23173 : : #define OMP_SECTIONS_CLAUSE_MASK \
23174 : : ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
23175 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
23176 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
23177 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
23178 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23179 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
23180 : :
23181 : : static tree
23182 : 141 : c_parser_omp_sections (location_t loc, c_parser *parser,
23183 : : char *p_name, omp_clause_mask mask, tree *cclauses)
23184 : : {
23185 : 141 : tree block, clauses, ret;
23186 : :
23187 : 141 : strcat (p_name, " sections");
23188 : 141 : mask |= OMP_SECTIONS_CLAUSE_MASK;
23189 : 141 : if (cclauses)
23190 : 36 : mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT);
23191 : :
23192 : 141 : clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
23193 : 141 : if (cclauses)
23194 : : {
23195 : 36 : omp_split_clauses (loc, OMP_SECTIONS, mask, clauses, cclauses);
23196 : 36 : clauses = cclauses[C_OMP_CLAUSE_SPLIT_SECTIONS];
23197 : : }
23198 : :
23199 : 141 : block = c_begin_compound_stmt (true);
23200 : 141 : ret = c_parser_omp_sections_scope (loc, parser);
23201 : 141 : if (ret)
23202 : 139 : OMP_SECTIONS_CLAUSES (ret) = clauses;
23203 : 141 : block = c_end_compound_stmt (loc, block, true);
23204 : 141 : add_stmt (block);
23205 : :
23206 : 141 : return ret;
23207 : : }
23208 : :
23209 : : /* OpenMP 2.5:
23210 : : # pragma omp parallel parallel-clause[optseq] new-line
23211 : : structured-block
23212 : : # pragma omp parallel for parallel-for-clause[optseq] new-line
23213 : : structured-block
23214 : : # pragma omp parallel sections parallel-sections-clause[optseq] new-line
23215 : : structured-block
23216 : :
23217 : : OpenMP 4.0:
23218 : : # pragma omp parallel for simd parallel-for-simd-clause[optseq] new-line
23219 : : structured-block
23220 : :
23221 : : LOC is the location of the #pragma token.
23222 : : */
23223 : :
23224 : : #define OMP_PARALLEL_CLAUSE_MASK \
23225 : : ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
23226 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
23227 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
23228 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
23229 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
23230 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN) \
23231 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
23232 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS) \
23233 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23234 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PROC_BIND))
23235 : :
23236 : : static tree
23237 : 5460 : c_parser_omp_parallel (location_t loc, c_parser *parser,
23238 : : char *p_name, omp_clause_mask mask, tree *cclauses,
23239 : : bool *if_p)
23240 : : {
23241 : 5460 : tree stmt, clauses, block;
23242 : :
23243 : 5460 : strcat (p_name, " parallel");
23244 : 5460 : mask |= OMP_PARALLEL_CLAUSE_MASK;
23245 : : /* #pragma omp target parallel{, for, for simd} disallow copyin clause. */
23246 : 5460 : if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) != 0
23247 : 1131 : && (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) == 0)
23248 : 460 : mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN);
23249 : :
23250 : 5460 : if (c_parser_next_token_is_keyword (parser, RID_FOR))
23251 : : {
23252 : 4186 : tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
23253 : 4186 : if (cclauses == NULL)
23254 : 1065 : cclauses = cclauses_buf;
23255 : :
23256 : 4186 : c_parser_consume_token (parser);
23257 : 4186 : if (!flag_openmp) /* flag_openmp_simd */
23258 : 20 : return c_parser_omp_for (loc, parser, p_name, mask, cclauses, if_p);
23259 : 4166 : block = c_begin_omp_parallel ();
23260 : 4166 : tree ret = c_parser_omp_for (loc, parser, p_name, mask, cclauses, if_p);
23261 : 4166 : stmt
23262 : 4166 : = c_finish_omp_parallel (loc, cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
23263 : : block);
23264 : 4166 : if (ret == NULL_TREE)
23265 : : return ret;
23266 : 4146 : OMP_PARALLEL_COMBINED (stmt) = 1;
23267 : 4146 : return stmt;
23268 : : }
23269 : : /* When combined with distribute, parallel has to be followed by for.
23270 : : #pragma omp target parallel is allowed though. */
23271 : 1274 : else if (cclauses
23272 : 1274 : && (mask & (OMP_CLAUSE_MASK_1
23273 : 40 : << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
23274 : : {
23275 : 0 : error_at (loc, "expected %<for%> after %qs", p_name);
23276 : 0 : c_parser_skip_to_pragma_eol (parser);
23277 : 0 : return NULL_TREE;
23278 : : }
23279 : 1274 : else if (c_parser_next_token_is (parser, CPP_NAME))
23280 : : {
23281 : 681 : const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
23282 : 681 : if (cclauses == NULL && strcmp (p, "masked") == 0)
23283 : : {
23284 : 30 : tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
23285 : 30 : cclauses = cclauses_buf;
23286 : :
23287 : 30 : c_parser_consume_token (parser);
23288 : 30 : if (!flag_openmp) /* flag_openmp_simd */
23289 : 0 : return c_parser_omp_masked (loc, parser, p_name, mask, cclauses,
23290 : 0 : if_p);
23291 : 30 : block = c_begin_omp_parallel ();
23292 : 30 : tree ret = c_parser_omp_masked (loc, parser, p_name, mask, cclauses,
23293 : : if_p);
23294 : 30 : stmt = c_finish_omp_parallel (loc,
23295 : : cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
23296 : : block);
23297 : 30 : if (ret == NULL)
23298 : : return ret;
23299 : : /* masked does have just filter clause, but during gimplification
23300 : : isn't represented by a gimplification omp context, so for
23301 : : #pragma omp parallel masked don't set OMP_PARALLEL_COMBINED,
23302 : : so that
23303 : : #pragma omp parallel masked
23304 : : #pragma omp taskloop simd lastprivate (x)
23305 : : isn't confused with
23306 : : #pragma omp parallel masked taskloop simd lastprivate (x) */
23307 : 30 : if (OMP_MASKED_COMBINED (ret))
23308 : 21 : OMP_PARALLEL_COMBINED (stmt) = 1;
23309 : 30 : return stmt;
23310 : : }
23311 : 616 : else if (cclauses == NULL && strcmp (p, "master") == 0)
23312 : : {
23313 : 88 : tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
23314 : 88 : cclauses = cclauses_buf;
23315 : :
23316 : 88 : c_parser_consume_token (parser);
23317 : 88 : if (!flag_openmp) /* flag_openmp_simd */
23318 : 3 : return c_parser_omp_master (loc, parser, p_name, mask, cclauses,
23319 : 3 : if_p);
23320 : 85 : block = c_begin_omp_parallel ();
23321 : 85 : tree ret = c_parser_omp_master (loc, parser, p_name, mask, cclauses,
23322 : : if_p);
23323 : 85 : stmt = c_finish_omp_parallel (loc,
23324 : : cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
23325 : : block);
23326 : 85 : if (ret == NULL)
23327 : : return ret;
23328 : : /* master doesn't have any clauses and during gimplification
23329 : : isn't represented by a gimplification omp context, so for
23330 : : #pragma omp parallel master don't set OMP_PARALLEL_COMBINED,
23331 : : so that
23332 : : #pragma omp parallel master
23333 : : #pragma omp taskloop simd lastprivate (x)
23334 : : isn't confused with
23335 : : #pragma omp parallel master taskloop simd lastprivate (x) */
23336 : 85 : if (OMP_MASTER_COMBINED (ret))
23337 : 44 : OMP_PARALLEL_COMBINED (stmt) = 1;
23338 : 85 : return stmt;
23339 : : }
23340 : 563 : else if (strcmp (p, "loop") == 0)
23341 : : {
23342 : 43 : tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
23343 : 43 : if (cclauses == NULL)
23344 : 24 : cclauses = cclauses_buf;
23345 : :
23346 : 43 : c_parser_consume_token (parser);
23347 : 43 : if (!flag_openmp) /* flag_openmp_simd */
23348 : 2 : return c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
23349 : 2 : if_p);
23350 : 41 : block = c_begin_omp_parallel ();
23351 : 41 : tree ret = c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
23352 : : if_p);
23353 : 41 : stmt
23354 : 41 : = c_finish_omp_parallel (loc,
23355 : : cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
23356 : : block);
23357 : 41 : if (ret == NULL_TREE)
23358 : : return ret;
23359 : 41 : OMP_PARALLEL_COMBINED (stmt) = 1;
23360 : 41 : return stmt;
23361 : : }
23362 : 520 : else if (!flag_openmp) /* flag_openmp_simd */
23363 : : {
23364 : 1 : c_parser_skip_to_pragma_eol (parser, false);
23365 : 1 : return NULL_TREE;
23366 : : }
23367 : 519 : else if (cclauses == NULL && strcmp (p, "sections") == 0)
23368 : : {
23369 : 36 : tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
23370 : 36 : cclauses = cclauses_buf;
23371 : :
23372 : 36 : c_parser_consume_token (parser);
23373 : 36 : block = c_begin_omp_parallel ();
23374 : 36 : c_parser_omp_sections (loc, parser, p_name, mask, cclauses);
23375 : 36 : stmt = c_finish_omp_parallel (loc,
23376 : : cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
23377 : : block);
23378 : 36 : OMP_PARALLEL_COMBINED (stmt) = 1;
23379 : 36 : return stmt;
23380 : : }
23381 : : }
23382 : 593 : else if (!flag_openmp) /* flag_openmp_simd */
23383 : : {
23384 : 1 : c_parser_skip_to_pragma_eol (parser, false);
23385 : 1 : return NULL_TREE;
23386 : : }
23387 : :
23388 : 1075 : clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
23389 : 1075 : if (cclauses)
23390 : : {
23391 : 20 : omp_split_clauses (loc, OMP_PARALLEL, mask, clauses, cclauses);
23392 : 20 : clauses = cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL];
23393 : : }
23394 : :
23395 : 1075 : block = c_begin_omp_parallel ();
23396 : 1075 : parser->omp_attrs_forbidden_p = true;
23397 : 1075 : c_parser_statement (parser, if_p);
23398 : 1075 : stmt = c_finish_omp_parallel (loc, clauses, block);
23399 : :
23400 : 1075 : return stmt;
23401 : : }
23402 : :
23403 : : /* OpenMP 2.5:
23404 : : # pragma omp single single-clause[optseq] new-line
23405 : : structured-block
23406 : :
23407 : : LOC is the location of the #pragma.
23408 : : */
23409 : :
23410 : : #define OMP_SINGLE_CLAUSE_MASK \
23411 : : ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
23412 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
23413 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYPRIVATE) \
23414 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23415 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
23416 : :
23417 : : static tree
23418 : 221 : c_parser_omp_single (location_t loc, c_parser *parser, bool *if_p)
23419 : : {
23420 : 221 : tree stmt = make_node (OMP_SINGLE);
23421 : 221 : SET_EXPR_LOCATION (stmt, loc);
23422 : 221 : TREE_TYPE (stmt) = void_type_node;
23423 : :
23424 : 442 : OMP_SINGLE_CLAUSES (stmt)
23425 : 221 : = c_parser_omp_all_clauses (parser, OMP_SINGLE_CLAUSE_MASK,
23426 : : "#pragma omp single");
23427 : 221 : OMP_SINGLE_BODY (stmt) = c_parser_omp_structured_block (parser, if_p);
23428 : :
23429 : 221 : return add_stmt (stmt);
23430 : : }
23431 : :
23432 : : /* OpenMP 5.1:
23433 : : # pragma omp scope scope-clause[optseq] new-line
23434 : : structured-block
23435 : :
23436 : : LOC is the location of the #pragma.
23437 : : */
23438 : :
23439 : : #define OMP_SCOPE_CLAUSE_MASK \
23440 : : ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
23441 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
23442 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
23443 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23444 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
23445 : :
23446 : : static tree
23447 : 61 : c_parser_omp_scope (location_t loc, c_parser *parser, bool *if_p)
23448 : : {
23449 : 61 : tree stmt = make_node (OMP_SCOPE);
23450 : 61 : SET_EXPR_LOCATION (stmt, loc);
23451 : 61 : TREE_TYPE (stmt) = void_type_node;
23452 : :
23453 : 122 : OMP_SCOPE_CLAUSES (stmt)
23454 : 61 : = c_parser_omp_all_clauses (parser, OMP_SCOPE_CLAUSE_MASK,
23455 : : "#pragma omp scope");
23456 : 61 : OMP_SCOPE_BODY (stmt) = c_parser_omp_structured_block (parser, if_p);
23457 : :
23458 : 61 : return add_stmt (stmt);
23459 : : }
23460 : :
23461 : : /* OpenMP 3.0:
23462 : : # pragma omp task task-clause[optseq] new-line
23463 : :
23464 : : LOC is the location of the #pragma.
23465 : : */
23466 : :
23467 : : #define OMP_TASK_CLAUSE_MASK \
23468 : : ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
23469 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
23470 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
23471 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
23472 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
23473 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
23474 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
23475 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
23476 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
23477 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
23478 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23479 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION) \
23480 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DETACH) \
23481 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_AFFINITY))
23482 : :
23483 : : static tree
23484 : 892 : c_parser_omp_task (location_t loc, c_parser *parser, bool *if_p)
23485 : : {
23486 : 892 : tree clauses, block;
23487 : :
23488 : 892 : clauses = c_parser_omp_all_clauses (parser, OMP_TASK_CLAUSE_MASK,
23489 : : "#pragma omp task");
23490 : :
23491 : 892 : block = c_begin_omp_task ();
23492 : 892 : parser->omp_attrs_forbidden_p = true;
23493 : 892 : c_parser_statement (parser, if_p);
23494 : 892 : return c_finish_omp_task (loc, clauses, block);
23495 : : }
23496 : :
23497 : : /* OpenMP 3.0:
23498 : : # pragma omp taskwait new-line
23499 : :
23500 : : OpenMP 5.0:
23501 : : # pragma omp taskwait taskwait-clause[optseq] new-line
23502 : : */
23503 : :
23504 : : #define OMP_TASKWAIT_CLAUSE_MASK \
23505 : : ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
23506 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
23507 : :
23508 : : static void
23509 : 91 : c_parser_omp_taskwait (c_parser *parser)
23510 : : {
23511 : 91 : location_t loc = c_parser_peek_token (parser)->location;
23512 : 91 : c_parser_consume_pragma (parser);
23513 : :
23514 : 91 : tree clauses
23515 : 91 : = c_parser_omp_all_clauses (parser, OMP_TASKWAIT_CLAUSE_MASK,
23516 : : "#pragma omp taskwait");
23517 : :
23518 : 91 : if (clauses)
23519 : : {
23520 : 20 : tree stmt = make_node (OMP_TASK);
23521 : 20 : TREE_TYPE (stmt) = void_node;
23522 : 20 : OMP_TASK_CLAUSES (stmt) = clauses;
23523 : 20 : OMP_TASK_BODY (stmt) = NULL_TREE;
23524 : 20 : SET_EXPR_LOCATION (stmt, loc);
23525 : 20 : add_stmt (stmt);
23526 : : }
23527 : : else
23528 : 71 : c_finish_omp_taskwait (loc);
23529 : 91 : }
23530 : :
23531 : : /* OpenMP 3.1:
23532 : : # pragma omp taskyield new-line
23533 : : */
23534 : :
23535 : : static void
23536 : 6 : c_parser_omp_taskyield (c_parser *parser)
23537 : : {
23538 : 6 : location_t loc = c_parser_peek_token (parser)->location;
23539 : 6 : c_parser_consume_pragma (parser);
23540 : 6 : c_parser_skip_to_pragma_eol (parser);
23541 : :
23542 : 6 : c_finish_omp_taskyield (loc);
23543 : 6 : }
23544 : :
23545 : : /* OpenMP 4.0:
23546 : : # pragma omp taskgroup new-line
23547 : :
23548 : : OpenMP 5.0:
23549 : : # pragma omp taskgroup taskgroup-clause[optseq] new-line
23550 : : */
23551 : :
23552 : : #define OMP_TASKGROUP_CLAUSE_MASK \
23553 : : ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23554 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASK_REDUCTION))
23555 : :
23556 : : static tree
23557 : 138 : c_parser_omp_taskgroup (location_t loc, c_parser *parser, bool *if_p)
23558 : : {
23559 : 138 : tree clauses = c_parser_omp_all_clauses (parser, OMP_TASKGROUP_CLAUSE_MASK,
23560 : : "#pragma omp taskgroup");
23561 : :
23562 : 138 : tree body = c_parser_omp_structured_block (parser, if_p);
23563 : 138 : return c_finish_omp_taskgroup (loc, body, clauses);
23564 : : }
23565 : :
23566 : : /* OpenMP 4.0:
23567 : : # pragma omp cancel cancel-clause[optseq] new-line
23568 : :
23569 : : LOC is the location of the #pragma.
23570 : : */
23571 : :
23572 : : #define OMP_CANCEL_CLAUSE_MASK \
23573 : : ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
23574 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
23575 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
23576 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP) \
23577 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF))
23578 : :
23579 : : static void
23580 : 213 : c_parser_omp_cancel (c_parser *parser)
23581 : : {
23582 : 213 : location_t loc = c_parser_peek_token (parser)->location;
23583 : :
23584 : 213 : c_parser_consume_pragma (parser);
23585 : 213 : tree clauses = c_parser_omp_all_clauses (parser, OMP_CANCEL_CLAUSE_MASK,
23586 : : "#pragma omp cancel");
23587 : :
23588 : 213 : c_finish_omp_cancel (loc, clauses);
23589 : 213 : }
23590 : :
23591 : : /* OpenMP 4.0:
23592 : : # pragma omp cancellation point cancelpt-clause[optseq] new-line
23593 : :
23594 : : LOC is the location of the #pragma.
23595 : : */
23596 : :
23597 : : #define OMP_CANCELLATION_POINT_CLAUSE_MASK \
23598 : : ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
23599 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
23600 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
23601 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP))
23602 : :
23603 : : static bool
23604 : 179 : c_parser_omp_cancellation_point (c_parser *parser, enum pragma_context context)
23605 : : {
23606 : 179 : location_t loc = c_parser_peek_token (parser)->location;
23607 : 179 : tree clauses;
23608 : 179 : bool point_seen = false;
23609 : :
23610 : 179 : c_parser_consume_pragma (parser);
23611 : 179 : if (c_parser_next_token_is (parser, CPP_NAME))
23612 : : {
23613 : 179 : const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
23614 : 179 : if (strcmp (p, "point") == 0)
23615 : : {
23616 : 177 : c_parser_consume_token (parser);
23617 : 177 : point_seen = true;
23618 : : }
23619 : : }
23620 : 177 : if (!point_seen)
23621 : : {
23622 : 2 : c_parser_error (parser, "expected %<point%>");
23623 : 2 : c_parser_skip_to_pragma_eol (parser);
23624 : 2 : return false;
23625 : : }
23626 : :
23627 : 177 : if (context != pragma_compound)
23628 : : {
23629 : 10 : if (context == pragma_stmt)
23630 : 9 : error_at (loc,
23631 : : "%<#pragma %s%> may only be used in compound statements",
23632 : : "omp cancellation point");
23633 : : else
23634 : 1 : c_parser_error (parser, "expected declaration specifiers");
23635 : 10 : c_parser_skip_to_pragma_eol (parser, false);
23636 : 10 : return true;
23637 : : }
23638 : :
23639 : 167 : clauses
23640 : 167 : = c_parser_omp_all_clauses (parser, OMP_CANCELLATION_POINT_CLAUSE_MASK,
23641 : : "#pragma omp cancellation point");
23642 : :
23643 : 167 : c_finish_omp_cancellation_point (loc, clauses);
23644 : 167 : return true;
23645 : : }
23646 : :
23647 : : /* OpenMP 4.0:
23648 : : #pragma omp distribute distribute-clause[optseq] new-line
23649 : : for-loop */
23650 : :
23651 : : #define OMP_DISTRIBUTE_CLAUSE_MASK \
23652 : : ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
23653 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
23654 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
23655 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)\
23656 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23657 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
23658 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
23659 : :
23660 : : static tree
23661 : 3404 : c_parser_omp_distribute (location_t loc, c_parser *parser,
23662 : : char *p_name, omp_clause_mask mask, tree *cclauses,
23663 : : bool *if_p)
23664 : : {
23665 : 3404 : tree clauses, block, ret;
23666 : :
23667 : 3404 : strcat (p_name, " distribute");
23668 : 3404 : mask |= OMP_DISTRIBUTE_CLAUSE_MASK;
23669 : :
23670 : 3404 : if (c_parser_next_token_is (parser, CPP_NAME))
23671 : : {
23672 : 3308 : const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
23673 : 3308 : bool simd = false;
23674 : 3308 : bool parallel = false;
23675 : :
23676 : 3308 : if (strcmp (p, "simd") == 0)
23677 : : simd = true;
23678 : : else
23679 : 2968 : parallel = strcmp (p, "parallel") == 0;
23680 : 3308 : if (parallel || simd)
23681 : : {
23682 : 3041 : tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
23683 : 3041 : if (cclauses == NULL)
23684 : 1142 : cclauses = cclauses_buf;
23685 : 3041 : c_parser_consume_token (parser);
23686 : 3041 : if (!flag_openmp) /* flag_openmp_simd */
23687 : : {
23688 : 15 : if (simd)
23689 : 6 : return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
23690 : 6 : if_p);
23691 : : else
23692 : 9 : return c_parser_omp_parallel (loc, parser, p_name, mask,
23693 : 9 : cclauses, if_p);
23694 : : }
23695 : 3026 : block = c_begin_compound_stmt (true);
23696 : 3026 : if (simd)
23697 : 334 : ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
23698 : : if_p);
23699 : : else
23700 : 2692 : ret = c_parser_omp_parallel (loc, parser, p_name, mask, cclauses,
23701 : : if_p);
23702 : 3026 : block = c_end_compound_stmt (loc, block, true);
23703 : 3026 : if (ret == NULL)
23704 : : return ret;
23705 : 3021 : ret = make_node (OMP_DISTRIBUTE);
23706 : 3021 : TREE_TYPE (ret) = void_type_node;
23707 : 3021 : OMP_FOR_BODY (ret) = block;
23708 : 3021 : OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE];
23709 : 3021 : SET_EXPR_LOCATION (ret, loc);
23710 : 3021 : add_stmt (ret);
23711 : 3021 : return ret;
23712 : : }
23713 : : }
23714 : 363 : if (!flag_openmp) /* flag_openmp_simd */
23715 : : {
23716 : 2 : c_parser_skip_to_pragma_eol (parser, false);
23717 : 2 : return NULL_TREE;
23718 : : }
23719 : :
23720 : 361 : clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
23721 : 361 : if (cclauses)
23722 : : {
23723 : 194 : omp_split_clauses (loc, OMP_DISTRIBUTE, mask, clauses, cclauses);
23724 : 194 : clauses = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE];
23725 : : }
23726 : :
23727 : 361 : block = c_begin_compound_stmt (true);
23728 : 361 : ret = c_parser_omp_for_loop (loc, parser, OMP_DISTRIBUTE, clauses, NULL,
23729 : : if_p);
23730 : 361 : block = c_end_compound_stmt (loc, block, true);
23731 : 361 : add_stmt (block);
23732 : :
23733 : 361 : return ret;
23734 : : }
23735 : :
23736 : : /* OpenMP 4.0:
23737 : : # pragma omp teams teams-clause[optseq] new-line
23738 : : structured-block */
23739 : :
23740 : : #define OMP_TEAMS_CLAUSE_MASK \
23741 : : ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
23742 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
23743 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
23744 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
23745 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS) \
23746 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \
23747 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23748 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT))
23749 : :
23750 : : static tree
23751 : 3633 : c_parser_omp_teams (location_t loc, c_parser *parser,
23752 : : char *p_name, omp_clause_mask mask, tree *cclauses,
23753 : : bool *if_p)
23754 : : {
23755 : 3633 : tree clauses, block, ret;
23756 : :
23757 : 3633 : strcat (p_name, " teams");
23758 : 3633 : mask |= OMP_TEAMS_CLAUSE_MASK;
23759 : :
23760 : 3633 : if (c_parser_next_token_is (parser, CPP_NAME))
23761 : : {
23762 : 2313 : const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
23763 : 2313 : if (strcmp (p, "distribute") == 0)
23764 : : {
23765 : 2095 : tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
23766 : 2095 : if (cclauses == NULL)
23767 : 1258 : cclauses = cclauses_buf;
23768 : :
23769 : 2095 : c_parser_consume_token (parser);
23770 : 2095 : if (!flag_openmp) /* flag_openmp_simd */
23771 : 12 : return c_parser_omp_distribute (loc, parser, p_name, mask,
23772 : 12 : cclauses, if_p);
23773 : 2083 : block = c_begin_omp_parallel ();
23774 : 2083 : ret = c_parser_omp_distribute (loc, parser, p_name, mask, cclauses,
23775 : : if_p);
23776 : 2083 : block = c_end_compound_stmt (loc, block, true);
23777 : 2083 : if (ret == NULL)
23778 : : return ret;
23779 : 2083 : clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
23780 : 2083 : ret = make_node (OMP_TEAMS);
23781 : 2083 : TREE_TYPE (ret) = void_type_node;
23782 : 2083 : OMP_TEAMS_CLAUSES (ret) = clauses;
23783 : 2083 : OMP_TEAMS_BODY (ret) = block;
23784 : 2083 : OMP_TEAMS_COMBINED (ret) = 1;
23785 : 2083 : SET_EXPR_LOCATION (ret, loc);
23786 : 2083 : return add_stmt (ret);
23787 : : }
23788 : 218 : else if (strcmp (p, "loop") == 0)
23789 : : {
23790 : 33 : tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
23791 : 33 : if (cclauses == NULL)
23792 : 16 : cclauses = cclauses_buf;
23793 : :
23794 : 33 : c_parser_consume_token (parser);
23795 : 33 : if (!flag_openmp) /* flag_openmp_simd */
23796 : 2 : return c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
23797 : 2 : if_p);
23798 : 31 : block = c_begin_omp_parallel ();
23799 : 31 : ret = c_parser_omp_loop (loc, parser, p_name, mask, cclauses, if_p);
23800 : 31 : block = c_end_compound_stmt (loc, block, true);
23801 : 31 : if (ret == NULL)
23802 : : return ret;
23803 : 31 : clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
23804 : 31 : ret = make_node (OMP_TEAMS);
23805 : 31 : TREE_TYPE (ret) = void_type_node;
23806 : 31 : OMP_TEAMS_CLAUSES (ret) = clauses;
23807 : 31 : OMP_TEAMS_BODY (ret) = block;
23808 : 31 : OMP_TEAMS_COMBINED (ret) = 1;
23809 : 31 : SET_EXPR_LOCATION (ret, loc);
23810 : 31 : return add_stmt (ret);
23811 : : }
23812 : : }
23813 : 1505 : if (!flag_openmp) /* flag_openmp_simd */
23814 : : {
23815 : 2 : c_parser_skip_to_pragma_eol (parser, false);
23816 : 2 : return NULL_TREE;
23817 : : }
23818 : :
23819 : 1503 : clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
23820 : 1503 : if (cclauses)
23821 : : {
23822 : 868 : omp_split_clauses (loc, OMP_TEAMS, mask, clauses, cclauses);
23823 : 868 : clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
23824 : : }
23825 : :
23826 : 1503 : tree stmt = make_node (OMP_TEAMS);
23827 : 1503 : TREE_TYPE (stmt) = void_type_node;
23828 : 1503 : OMP_TEAMS_CLAUSES (stmt) = clauses;
23829 : 1503 : block = c_begin_omp_parallel ();
23830 : 1503 : add_stmt (c_parser_omp_structured_block (parser, if_p));
23831 : 1503 : OMP_TEAMS_BODY (stmt) = c_end_compound_stmt (loc, block, true);
23832 : 1503 : SET_EXPR_LOCATION (stmt, loc);
23833 : :
23834 : 1503 : return add_stmt (stmt);
23835 : : }
23836 : :
23837 : : /* OpenMP 4.0:
23838 : : # pragma omp target data target-data-clause[optseq] new-line
23839 : : structured-block */
23840 : :
23841 : : #define OMP_TARGET_DATA_CLAUSE_MASK \
23842 : : ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
23843 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
23844 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
23845 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR) \
23846 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR))
23847 : :
23848 : : static tree
23849 : 149 : c_parser_omp_target_data (location_t loc, c_parser *parser, bool *if_p)
23850 : : {
23851 : 149 : if (flag_openmp)
23852 : 149 : omp_requires_mask
23853 : 149 : = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
23854 : :
23855 : 149 : tree clauses
23856 : 149 : = c_parser_omp_all_clauses (parser, OMP_TARGET_DATA_CLAUSE_MASK,
23857 : 149 : "#pragma omp target data");
23858 : 149 : c_omp_adjust_map_clauses (clauses, false);
23859 : 149 : int map_seen = 0;
23860 : 433 : for (tree *pc = &clauses; *pc;)
23861 : : {
23862 : 284 : if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
23863 : 207 : switch (OMP_CLAUSE_MAP_KIND (*pc))
23864 : : {
23865 : : case GOMP_MAP_TO:
23866 : : case GOMP_MAP_ALWAYS_TO:
23867 : : case GOMP_MAP_PRESENT_TO:
23868 : : case GOMP_MAP_ALWAYS_PRESENT_TO:
23869 : : case GOMP_MAP_FROM:
23870 : : case GOMP_MAP_ALWAYS_FROM:
23871 : : case GOMP_MAP_PRESENT_FROM:
23872 : : case GOMP_MAP_ALWAYS_PRESENT_FROM:
23873 : : case GOMP_MAP_TOFROM:
23874 : : case GOMP_MAP_ALWAYS_TOFROM:
23875 : : case GOMP_MAP_PRESENT_TOFROM:
23876 : : case GOMP_MAP_ALWAYS_PRESENT_TOFROM:
23877 : : case GOMP_MAP_ALLOC:
23878 : : case GOMP_MAP_PRESENT_ALLOC:
23879 : 284 : map_seen = 3;
23880 : : break;
23881 : : case GOMP_MAP_FIRSTPRIVATE_POINTER:
23882 : : case GOMP_MAP_ALWAYS_POINTER:
23883 : : case GOMP_MAP_ATTACH_DETACH:
23884 : : case GOMP_MAP_ATTACH:
23885 : : break;
23886 : 0 : default:
23887 : 0 : map_seen |= 1;
23888 : 0 : error_at (OMP_CLAUSE_LOCATION (*pc),
23889 : : "%<#pragma omp target data%> with map-type other "
23890 : : "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
23891 : : "on %<map%> clause");
23892 : 0 : *pc = OMP_CLAUSE_CHAIN (*pc);
23893 : 0 : continue;
23894 : : }
23895 : 77 : else if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_PTR
23896 : 77 : || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_ADDR)
23897 : : map_seen = 3;
23898 : 284 : pc = &OMP_CLAUSE_CHAIN (*pc);
23899 : : }
23900 : :
23901 : 149 : if (map_seen != 3)
23902 : : {
23903 : 3 : if (map_seen == 0)
23904 : 3 : error_at (loc,
23905 : : "%<#pragma omp target data%> must contain at least "
23906 : : "one %<map%>, %<use_device_ptr%> or %<use_device_addr%> "
23907 : : "clause");
23908 : 3 : return NULL_TREE;
23909 : : }
23910 : :
23911 : 146 : tree stmt = make_node (OMP_TARGET_DATA);
23912 : 146 : TREE_TYPE (stmt) = void_type_node;
23913 : 146 : OMP_TARGET_DATA_CLAUSES (stmt) = clauses;
23914 : 146 : keep_next_level ();
23915 : 146 : tree block = c_begin_compound_stmt (true);
23916 : 146 : add_stmt (c_parser_omp_structured_block (parser, if_p));
23917 : 146 : OMP_TARGET_DATA_BODY (stmt) = c_end_compound_stmt (loc, block, true);
23918 : :
23919 : 146 : SET_EXPR_LOCATION (stmt, loc);
23920 : 146 : return add_stmt (stmt);
23921 : : }
23922 : :
23923 : : /* OpenMP 4.0:
23924 : : # pragma omp target update target-update-clause[optseq] new-line */
23925 : :
23926 : : #define OMP_TARGET_UPDATE_CLAUSE_MASK \
23927 : : ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FROM) \
23928 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
23929 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
23930 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
23931 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
23932 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
23933 : :
23934 : : static bool
23935 : 2825 : c_parser_omp_target_update (location_t loc, c_parser *parser,
23936 : : enum pragma_context context)
23937 : : {
23938 : 2825 : if (context == pragma_stmt)
23939 : : {
23940 : 8 : error_at (loc, "%<#pragma %s%> may only be used in compound statements",
23941 : : "omp target update");
23942 : 8 : c_parser_skip_to_pragma_eol (parser, false);
23943 : 8 : return true;
23944 : : }
23945 : :
23946 : 2817 : tree clauses
23947 : 2817 : = c_parser_omp_all_clauses (parser, OMP_TARGET_UPDATE_CLAUSE_MASK,
23948 : : "#pragma omp target update");
23949 : 2817 : if (omp_find_clause (clauses, OMP_CLAUSE_TO) == NULL_TREE
23950 : 2817 : && omp_find_clause (clauses, OMP_CLAUSE_FROM) == NULL_TREE)
23951 : : {
23952 : 3 : error_at (loc,
23953 : : "%<#pragma omp target update%> must contain at least one "
23954 : : "%<from%> or %<to%> clauses");
23955 : 3 : return false;
23956 : : }
23957 : :
23958 : 2814 : if (flag_openmp)
23959 : 2814 : omp_requires_mask
23960 : 2814 : = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
23961 : :
23962 : 2814 : tree stmt = make_node (OMP_TARGET_UPDATE);
23963 : 2814 : TREE_TYPE (stmt) = void_type_node;
23964 : 2814 : OMP_TARGET_UPDATE_CLAUSES (stmt) = clauses;
23965 : 2814 : SET_EXPR_LOCATION (stmt, loc);
23966 : 2814 : add_stmt (stmt);
23967 : 2814 : return false;
23968 : : }
23969 : :
23970 : : /* OpenMP 4.5:
23971 : : # pragma omp target enter data target-data-clause[optseq] new-line */
23972 : :
23973 : : #define OMP_TARGET_ENTER_DATA_CLAUSE_MASK \
23974 : : ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
23975 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
23976 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
23977 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
23978 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
23979 : :
23980 : : static bool
23981 : 102 : c_parser_omp_target_enter_data (location_t loc, c_parser *parser,
23982 : : enum pragma_context context)
23983 : : {
23984 : 102 : bool data_seen = false;
23985 : 102 : if (c_parser_next_token_is (parser, CPP_NAME))
23986 : : {
23987 : 102 : const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
23988 : 102 : if (strcmp (p, "data") == 0)
23989 : : {
23990 : 102 : c_parser_consume_token (parser);
23991 : 102 : data_seen = true;
23992 : : }
23993 : : }
23994 : 102 : if (!data_seen)
23995 : : {
23996 : 0 : c_parser_error (parser, "expected %<data%>");
23997 : 0 : c_parser_skip_to_pragma_eol (parser);
23998 : 0 : return false;
23999 : : }
24000 : :
24001 : 102 : if (context == pragma_stmt)
24002 : : {
24003 : 8 : error_at (loc, "%<#pragma %s%> may only be used in compound statements",
24004 : : "omp target enter data");
24005 : 8 : c_parser_skip_to_pragma_eol (parser, false);
24006 : 8 : return true;
24007 : : }
24008 : :
24009 : 94 : if (flag_openmp)
24010 : 94 : omp_requires_mask
24011 : 94 : = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
24012 : :
24013 : 94 : tree clauses
24014 : 94 : = c_parser_omp_all_clauses (parser, OMP_TARGET_ENTER_DATA_CLAUSE_MASK,
24015 : 94 : "#pragma omp target enter data");
24016 : 94 : c_omp_adjust_map_clauses (clauses, false);
24017 : 94 : int map_seen = 0;
24018 : 322 : for (tree *pc = &clauses; *pc;)
24019 : : {
24020 : 228 : if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
24021 : 187 : switch (OMP_CLAUSE_MAP_KIND (*pc))
24022 : : {
24023 : : case GOMP_MAP_TO:
24024 : : case GOMP_MAP_ALWAYS_TO:
24025 : : case GOMP_MAP_PRESENT_TO:
24026 : : case GOMP_MAP_ALWAYS_PRESENT_TO:
24027 : : case GOMP_MAP_ALLOC:
24028 : : case GOMP_MAP_PRESENT_ALLOC:
24029 : 158 : map_seen = 3;
24030 : : break;
24031 : 10 : case GOMP_MAP_TOFROM:
24032 : 10 : OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_TO);
24033 : 10 : map_seen = 3;
24034 : 10 : break;
24035 : 3 : case GOMP_MAP_ALWAYS_TOFROM:
24036 : 3 : OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_ALWAYS_TO);
24037 : 3 : map_seen = 3;
24038 : 3 : break;
24039 : 2 : case GOMP_MAP_PRESENT_TOFROM:
24040 : 2 : OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_PRESENT_TO);
24041 : 2 : map_seen = 3;
24042 : 2 : break;
24043 : 2 : case GOMP_MAP_ALWAYS_PRESENT_TOFROM:
24044 : 2 : OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_ALWAYS_PRESENT_TO);
24045 : 2 : map_seen = 3;
24046 : 2 : break;
24047 : : case GOMP_MAP_FIRSTPRIVATE_POINTER:
24048 : : case GOMP_MAP_ALWAYS_POINTER:
24049 : : case GOMP_MAP_ATTACH_DETACH:
24050 : : case GOMP_MAP_ATTACH:
24051 : : break;
24052 : 2 : default:
24053 : 2 : map_seen |= 1;
24054 : 2 : error_at (OMP_CLAUSE_LOCATION (*pc),
24055 : : "%<#pragma omp target enter data%> with map-type other "
24056 : : "than %<to%>, %<tofrom%> or %<alloc%> on %<map%> clause");
24057 : 2 : *pc = OMP_CLAUSE_CHAIN (*pc);
24058 : 2 : continue;
24059 : : }
24060 : 226 : pc = &OMP_CLAUSE_CHAIN (*pc);
24061 : : }
24062 : :
24063 : 94 : if (map_seen != 3)
24064 : : {
24065 : 4 : if (map_seen == 0)
24066 : 2 : error_at (loc,
24067 : : "%<#pragma omp target enter data%> must contain at least "
24068 : : "one %<map%> clause");
24069 : 4 : return true;
24070 : : }
24071 : :
24072 : 90 : tree stmt = make_node (OMP_TARGET_ENTER_DATA);
24073 : 90 : TREE_TYPE (stmt) = void_type_node;
24074 : 90 : OMP_TARGET_ENTER_DATA_CLAUSES (stmt) = clauses;
24075 : 90 : SET_EXPR_LOCATION (stmt, loc);
24076 : 90 : add_stmt (stmt);
24077 : 90 : return true;
24078 : : }
24079 : :
24080 : : /* OpenMP 4.5:
24081 : : # pragma omp target exit data target-data-clause[optseq] new-line */
24082 : :
24083 : : #define OMP_TARGET_EXIT_DATA_CLAUSE_MASK \
24084 : : ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
24085 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
24086 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
24087 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
24088 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
24089 : :
24090 : : static bool
24091 : 96 : c_parser_omp_target_exit_data (location_t loc, c_parser *parser,
24092 : : enum pragma_context context)
24093 : : {
24094 : 96 : bool data_seen = false;
24095 : 96 : if (c_parser_next_token_is (parser, CPP_NAME))
24096 : : {
24097 : 96 : const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
24098 : 96 : if (strcmp (p, "data") == 0)
24099 : : {
24100 : 96 : c_parser_consume_token (parser);
24101 : 96 : data_seen = true;
24102 : : }
24103 : : }
24104 : 96 : if (!data_seen)
24105 : : {
24106 : 0 : c_parser_error (parser, "expected %<data%>");
24107 : 0 : c_parser_skip_to_pragma_eol (parser);
24108 : 0 : return false;
24109 : : }
24110 : :
24111 : 96 : if (context == pragma_stmt)
24112 : : {
24113 : 8 : error_at (loc, "%<#pragma %s%> may only be used in compound statements",
24114 : : "omp target exit data");
24115 : 8 : c_parser_skip_to_pragma_eol (parser, false);
24116 : 8 : return true;
24117 : : }
24118 : :
24119 : 88 : if (flag_openmp)
24120 : 88 : omp_requires_mask
24121 : 88 : = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
24122 : :
24123 : 88 : tree clauses
24124 : 88 : = c_parser_omp_all_clauses (parser, OMP_TARGET_EXIT_DATA_CLAUSE_MASK,
24125 : : "#pragma omp target exit data", false);
24126 : 88 : clauses = c_finish_omp_clauses (clauses, C_ORT_OMP_EXIT_DATA);
24127 : 88 : c_omp_adjust_map_clauses (clauses, false);
24128 : 88 : int map_seen = 0;
24129 : 291 : for (tree *pc = &clauses; *pc;)
24130 : : {
24131 : 203 : if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
24132 : 161 : switch (OMP_CLAUSE_MAP_KIND (*pc))
24133 : : {
24134 : : case GOMP_MAP_FROM:
24135 : : case GOMP_MAP_ALWAYS_FROM:
24136 : : case GOMP_MAP_PRESENT_FROM:
24137 : : case GOMP_MAP_ALWAYS_PRESENT_FROM:
24138 : : case GOMP_MAP_RELEASE:
24139 : : case GOMP_MAP_DELETE:
24140 : 135 : map_seen = 3;
24141 : : break;
24142 : 8 : case GOMP_MAP_TOFROM:
24143 : 8 : OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_FROM);
24144 : 8 : map_seen = 3;
24145 : 8 : break;
24146 : 1 : case GOMP_MAP_ALWAYS_TOFROM:
24147 : 1 : OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_ALWAYS_FROM);
24148 : 1 : map_seen = 3;
24149 : 1 : break;
24150 : 0 : case GOMP_MAP_PRESENT_TOFROM:
24151 : 0 : OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_PRESENT_FROM);
24152 : 0 : map_seen = 3;
24153 : 0 : break;
24154 : 0 : case GOMP_MAP_ALWAYS_PRESENT_TOFROM:
24155 : 0 : OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_ALWAYS_PRESENT_FROM);
24156 : 0 : map_seen = 3;
24157 : 0 : break;
24158 : : case GOMP_MAP_FIRSTPRIVATE_POINTER:
24159 : : case GOMP_MAP_ALWAYS_POINTER:
24160 : : case GOMP_MAP_ATTACH_DETACH:
24161 : : case GOMP_MAP_DETACH:
24162 : : break;
24163 : 2 : default:
24164 : 2 : map_seen |= 1;
24165 : 2 : error_at (OMP_CLAUSE_LOCATION (*pc),
24166 : : "%<#pragma omp target exit data%> with map-type other "
24167 : : "than %<from%>, %<tofrom%>, %<release%> or %<delete%> "
24168 : : "on %<map%> clause");
24169 : 2 : *pc = OMP_CLAUSE_CHAIN (*pc);
24170 : 2 : continue;
24171 : : }
24172 : 201 : pc = &OMP_CLAUSE_CHAIN (*pc);
24173 : : }
24174 : :
24175 : 88 : if (map_seen != 3)
24176 : : {
24177 : 2 : if (map_seen == 0)
24178 : 0 : error_at (loc,
24179 : : "%<#pragma omp target exit data%> must contain at least one "
24180 : : "%<map%> clause");
24181 : 2 : return true;
24182 : : }
24183 : :
24184 : 86 : tree stmt = make_node (OMP_TARGET_EXIT_DATA);
24185 : 86 : TREE_TYPE (stmt) = void_type_node;
24186 : 86 : OMP_TARGET_EXIT_DATA_CLAUSES (stmt) = clauses;
24187 : 86 : SET_EXPR_LOCATION (stmt, loc);
24188 : 86 : add_stmt (stmt);
24189 : 86 : return true;
24190 : : }
24191 : :
24192 : : /* OpenMP 4.0:
24193 : : # pragma omp target target-clause[optseq] new-line
24194 : : structured-block */
24195 : :
24196 : : #define OMP_TARGET_CLAUSE_MASK \
24197 : : ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
24198 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
24199 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
24200 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
24201 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
24202 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
24203 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
24204 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
24205 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULTMAP) \
24206 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION) \
24207 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \
24208 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR)\
24209 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR))
24210 : :
24211 : : static bool
24212 : 7139 : c_parser_omp_target (c_parser *parser, enum pragma_context context, bool *if_p)
24213 : : {
24214 : 7139 : location_t loc = c_parser_peek_token (parser)->location;
24215 : 7139 : c_parser_consume_pragma (parser);
24216 : 7139 : tree *pc = NULL, stmt, block;
24217 : :
24218 : 7139 : if (context != pragma_stmt && context != pragma_compound)
24219 : : {
24220 : 2 : c_parser_error (parser, "expected declaration specifiers");
24221 : 2 : c_parser_skip_to_pragma_eol (parser);
24222 : 2 : return false;
24223 : : }
24224 : :
24225 : 7137 : if (flag_openmp)
24226 : 7123 : omp_requires_mask
24227 : 7123 : = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
24228 : :
24229 : 7137 : if (c_parser_next_token_is (parser, CPP_NAME))
24230 : : {
24231 : 6237 : const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
24232 : 6237 : enum tree_code ccode = ERROR_MARK;
24233 : :
24234 : 6237 : if (strcmp (p, "teams") == 0)
24235 : : ccode = OMP_TEAMS;
24236 : 4514 : else if (strcmp (p, "parallel") == 0)
24237 : : ccode = OMP_PARALLEL;
24238 : 4054 : else if (strcmp (p, "simd") == 0)
24239 : : ccode = OMP_SIMD;
24240 : 3994 : if (ccode != ERROR_MARK)
24241 : : {
24242 : 2243 : tree cclauses[C_OMP_CLAUSE_SPLIT_COUNT];
24243 : 2243 : char p_name[sizeof ("#pragma omp target teams distribute "
24244 : : "parallel for simd")];
24245 : :
24246 : 2243 : c_parser_consume_token (parser);
24247 : 2243 : strcpy (p_name, "#pragma omp target");
24248 : 2243 : if (!flag_openmp) /* flag_openmp_simd */
24249 : : {
24250 : 13 : tree stmt;
24251 : 13 : switch (ccode)
24252 : : {
24253 : 8 : case OMP_TEAMS:
24254 : 8 : stmt = c_parser_omp_teams (loc, parser, p_name,
24255 : 8 : OMP_TARGET_CLAUSE_MASK,
24256 : : cclauses, if_p);
24257 : 8 : break;
24258 : 4 : case OMP_PARALLEL:
24259 : 4 : stmt = c_parser_omp_parallel (loc, parser, p_name,
24260 : 4 : OMP_TARGET_CLAUSE_MASK,
24261 : : cclauses, if_p);
24262 : 4 : break;
24263 : 1 : case OMP_SIMD:
24264 : 1 : stmt = c_parser_omp_simd (loc, parser, p_name,
24265 : 1 : OMP_TARGET_CLAUSE_MASK,
24266 : : cclauses, if_p);
24267 : 1 : break;
24268 : 0 : default:
24269 : 0 : gcc_unreachable ();
24270 : : }
24271 : 13 : return stmt != NULL_TREE;
24272 : : }
24273 : 2230 : keep_next_level ();
24274 : 2230 : tree block = c_begin_compound_stmt (true), ret;
24275 : 2230 : switch (ccode)
24276 : : {
24277 : 1715 : case OMP_TEAMS:
24278 : 1715 : ret = c_parser_omp_teams (loc, parser, p_name,
24279 : 1715 : OMP_TARGET_CLAUSE_MASK, cclauses,
24280 : : if_p);
24281 : 1715 : break;
24282 : 456 : case OMP_PARALLEL:
24283 : 456 : ret = c_parser_omp_parallel (loc, parser, p_name,
24284 : 456 : OMP_TARGET_CLAUSE_MASK, cclauses,
24285 : : if_p);
24286 : 456 : break;
24287 : 59 : case OMP_SIMD:
24288 : 59 : ret = c_parser_omp_simd (loc, parser, p_name,
24289 : 59 : OMP_TARGET_CLAUSE_MASK, cclauses,
24290 : : if_p);
24291 : 59 : break;
24292 : 0 : default:
24293 : 0 : gcc_unreachable ();
24294 : : }
24295 : 2230 : block = c_end_compound_stmt (loc, block, true);
24296 : 2230 : if (ret == NULL_TREE)
24297 : : return false;
24298 : 2230 : if (ccode == OMP_TEAMS)
24299 : : /* For combined target teams, ensure the num_teams and
24300 : : thread_limit clause expressions are evaluated on the host,
24301 : : before entering the target construct. */
24302 : 2194 : for (tree c = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
24303 : 2194 : c; c = OMP_CLAUSE_CHAIN (c))
24304 : 479 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS
24305 : 479 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
24306 : 202 : for (int i = 0;
24307 : 332 : i <= (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS); ++i)
24308 : 202 : if (OMP_CLAUSE_OPERAND (c, i)
24309 : 202 : && TREE_CODE (OMP_CLAUSE_OPERAND (c, i)) != INTEGER_CST)
24310 : : {
24311 : 129 : tree expr = OMP_CLAUSE_OPERAND (c, i);
24312 : 129 : tree tmp = create_tmp_var_raw (TREE_TYPE (expr));
24313 : 129 : expr = build4 (TARGET_EXPR, TREE_TYPE (expr), tmp,
24314 : : expr, NULL_TREE, NULL_TREE);
24315 : 129 : add_stmt (expr);
24316 : 129 : OMP_CLAUSE_OPERAND (c, i) = expr;
24317 : 129 : tree tc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
24318 : : OMP_CLAUSE_FIRSTPRIVATE);
24319 : 129 : OMP_CLAUSE_DECL (tc) = tmp;
24320 : 129 : OMP_CLAUSE_CHAIN (tc)
24321 : 129 : = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
24322 : 129 : cclauses[C_OMP_CLAUSE_SPLIT_TARGET] = tc;
24323 : : }
24324 : 2230 : tree stmt = make_node (OMP_TARGET);
24325 : 2230 : TREE_TYPE (stmt) = void_type_node;
24326 : 2230 : OMP_TARGET_CLAUSES (stmt) = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
24327 : 2230 : c_omp_adjust_map_clauses (OMP_TARGET_CLAUSES (stmt), true);
24328 : 2230 : OMP_TARGET_BODY (stmt) = block;
24329 : 2230 : OMP_TARGET_COMBINED (stmt) = 1;
24330 : 2230 : SET_EXPR_LOCATION (stmt, loc);
24331 : 2230 : add_stmt (stmt);
24332 : 2230 : pc = &OMP_TARGET_CLAUSES (stmt);
24333 : 2230 : goto check_clauses;
24334 : : }
24335 : 3994 : else if (!flag_openmp) /* flag_openmp_simd */
24336 : : {
24337 : 0 : c_parser_skip_to_pragma_eol (parser, false);
24338 : 0 : return false;
24339 : : }
24340 : 3994 : else if (strcmp (p, "data") == 0)
24341 : : {
24342 : 149 : c_parser_consume_token (parser);
24343 : 149 : c_parser_omp_target_data (loc, parser, if_p);
24344 : 149 : return true;
24345 : : }
24346 : 3845 : else if (strcmp (p, "enter") == 0)
24347 : : {
24348 : 102 : c_parser_consume_token (parser);
24349 : 102 : return c_parser_omp_target_enter_data (loc, parser, context);
24350 : : }
24351 : 3743 : else if (strcmp (p, "exit") == 0)
24352 : : {
24353 : 96 : c_parser_consume_token (parser);
24354 : 96 : return c_parser_omp_target_exit_data (loc, parser, context);
24355 : : }
24356 : 3647 : else if (strcmp (p, "update") == 0)
24357 : : {
24358 : 2825 : c_parser_consume_token (parser);
24359 : 2825 : return c_parser_omp_target_update (loc, parser, context);
24360 : : }
24361 : : }
24362 : 1722 : if (!flag_openmp) /* flag_openmp_simd */
24363 : : {
24364 : 1 : c_parser_skip_to_pragma_eol (parser, false);
24365 : 1 : return false;
24366 : : }
24367 : :
24368 : 1721 : stmt = make_node (OMP_TARGET);
24369 : 1721 : TREE_TYPE (stmt) = void_type_node;
24370 : :
24371 : 3442 : OMP_TARGET_CLAUSES (stmt)
24372 : 1721 : = c_parser_omp_all_clauses (parser, OMP_TARGET_CLAUSE_MASK,
24373 : : "#pragma omp target", false);
24374 : 3316 : for (tree c = OMP_TARGET_CLAUSES (stmt); c; c = OMP_CLAUSE_CHAIN (c))
24375 : 1595 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION)
24376 : : {
24377 : 50 : tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
24378 : 50 : OMP_CLAUSE_DECL (nc) = OMP_CLAUSE_DECL (c);
24379 : 50 : OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_ALWAYS_TOFROM);
24380 : 50 : OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (c);
24381 : 50 : OMP_CLAUSE_CHAIN (c) = nc;
24382 : : }
24383 : 3442 : OMP_TARGET_CLAUSES (stmt)
24384 : 1721 : = c_finish_omp_clauses (OMP_TARGET_CLAUSES (stmt), C_ORT_OMP_TARGET);
24385 : 1721 : c_omp_adjust_map_clauses (OMP_TARGET_CLAUSES (stmt), true);
24386 : :
24387 : 1721 : pc = &OMP_TARGET_CLAUSES (stmt);
24388 : 1721 : keep_next_level ();
24389 : 1721 : block = c_begin_compound_stmt (true);
24390 : 1721 : add_stmt (c_parser_omp_structured_block (parser, if_p));
24391 : 1721 : OMP_TARGET_BODY (stmt) = c_end_compound_stmt (loc, block, true);
24392 : :
24393 : 1721 : SET_EXPR_LOCATION (stmt, loc);
24394 : 1721 : add_stmt (stmt);
24395 : :
24396 : : check_clauses:
24397 : 7199 : while (*pc)
24398 : : {
24399 : 3248 : if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
24400 : 1727 : switch (OMP_CLAUSE_MAP_KIND (*pc))
24401 : : {
24402 : : case GOMP_MAP_TO:
24403 : : case GOMP_MAP_ALWAYS_TO:
24404 : : case GOMP_MAP_PRESENT_TO:
24405 : : case GOMP_MAP_ALWAYS_PRESENT_TO:
24406 : : case GOMP_MAP_FROM:
24407 : : case GOMP_MAP_ALWAYS_FROM:
24408 : : case GOMP_MAP_PRESENT_FROM:
24409 : : case GOMP_MAP_ALWAYS_PRESENT_FROM:
24410 : : case GOMP_MAP_TOFROM:
24411 : : case GOMP_MAP_ALWAYS_TOFROM:
24412 : : case GOMP_MAP_PRESENT_TOFROM:
24413 : : case GOMP_MAP_ALWAYS_PRESENT_TOFROM:
24414 : : case GOMP_MAP_ALLOC:
24415 : : case GOMP_MAP_PRESENT_ALLOC:
24416 : : case GOMP_MAP_FIRSTPRIVATE_POINTER:
24417 : : case GOMP_MAP_ALWAYS_POINTER:
24418 : : case GOMP_MAP_POINTER:
24419 : : case GOMP_MAP_ATTACH_DETACH:
24420 : : case GOMP_MAP_ATTACH:
24421 : : break;
24422 : 1 : default:
24423 : 1 : error_at (OMP_CLAUSE_LOCATION (*pc),
24424 : : "%<#pragma omp target%> with map-type other "
24425 : : "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
24426 : : "on %<map%> clause");
24427 : 1 : *pc = OMP_CLAUSE_CHAIN (*pc);
24428 : 1 : continue;
24429 : : }
24430 : 3247 : pc = &OMP_CLAUSE_CHAIN (*pc);
24431 : : }
24432 : 3951 : cfun->has_omp_target = true;
24433 : 3951 : return true;
24434 : : }
24435 : :
24436 : : /* OpenMP 4.0:
24437 : : # pragma omp declare simd declare-simd-clauses[optseq] new-line
24438 : :
24439 : : OpenMP 5.0:
24440 : : # pragma omp declare variant (identifier) match(context-selector) new-line
24441 : : */
24442 : :
24443 : : #define OMP_DECLARE_SIMD_CLAUSE_MASK \
24444 : : ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
24445 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
24446 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
24447 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM) \
24448 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INBRANCH) \
24449 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOTINBRANCH))
24450 : :
24451 : : static void
24452 : 544 : c_parser_omp_declare_simd (c_parser *parser, enum pragma_context context)
24453 : : {
24454 : 544 : c_token *token = c_parser_peek_token (parser);
24455 : 544 : gcc_assert (token->type == CPP_NAME);
24456 : 544 : tree kind = token->value;
24457 : 544 : gcc_assert (strcmp (IDENTIFIER_POINTER (kind), "simd") == 0
24458 : : || strcmp (IDENTIFIER_POINTER (kind), "variant") == 0);
24459 : :
24460 : 544 : auto_vec<c_token> clauses;
24461 : 7369 : while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
24462 : : {
24463 : 6825 : c_token *token = c_parser_peek_token (parser);
24464 : 6825 : if (token->type == CPP_EOF)
24465 : : {
24466 : 0 : c_parser_skip_to_pragma_eol (parser);
24467 : 0 : return;
24468 : : }
24469 : 6825 : clauses.safe_push (*token);
24470 : 6825 : c_parser_consume_token (parser);
24471 : : }
24472 : 544 : clauses.safe_push (*c_parser_peek_token (parser));
24473 : 544 : c_parser_skip_to_pragma_eol (parser);
24474 : :
24475 : 1191 : while (c_parser_next_token_is (parser, CPP_PRAGMA))
24476 : : {
24477 : 105 : if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_DECLARE
24478 : 103 : || c_parser_peek_2nd_token (parser)->type != CPP_NAME
24479 : 208 : || c_parser_peek_2nd_token (parser)->value != kind)
24480 : : {
24481 : 2 : error ("%<#pragma omp declare %s%> must be followed by "
24482 : : "function declaration or definition or another "
24483 : : "%<#pragma omp declare %s%>",
24484 : 2 : IDENTIFIER_POINTER (kind), IDENTIFIER_POINTER (kind));
24485 : 2 : return;
24486 : : }
24487 : 103 : c_parser_consume_pragma (parser);
24488 : 2068 : while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
24489 : : {
24490 : 1862 : c_token *token = c_parser_peek_token (parser);
24491 : 1862 : if (token->type == CPP_EOF)
24492 : : {
24493 : 0 : c_parser_skip_to_pragma_eol (parser);
24494 : 0 : return;
24495 : : }
24496 : 1862 : clauses.safe_push (*token);
24497 : 1862 : c_parser_consume_token (parser);
24498 : : }
24499 : 103 : clauses.safe_push (*c_parser_peek_token (parser));
24500 : 103 : c_parser_skip_to_pragma_eol (parser);
24501 : : }
24502 : :
24503 : : /* Make sure nothing tries to read past the end of the tokens. */
24504 : 542 : c_token eof_token;
24505 : 542 : memset (&eof_token, 0, sizeof (eof_token));
24506 : 542 : eof_token.type = CPP_EOF;
24507 : 542 : clauses.safe_push (eof_token);
24508 : 542 : clauses.safe_push (eof_token);
24509 : :
24510 : 542 : switch (context)
24511 : : {
24512 : 525 : case pragma_external:
24513 : 525 : if (c_parser_next_token_is (parser, CPP_KEYWORD)
24514 : 525 : && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
24515 : : {
24516 : 1 : int ext = disable_extension_diagnostics ();
24517 : 1 : do
24518 : 1 : c_parser_consume_token (parser);
24519 : 1 : while (c_parser_next_token_is (parser, CPP_KEYWORD)
24520 : 2 : && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
24521 : 1 : c_parser_declaration_or_fndef (parser, true, true, true, false, true,
24522 : : NULL, &clauses);
24523 : 1 : restore_extension_diagnostics (ext);
24524 : : }
24525 : : else
24526 : 524 : c_parser_declaration_or_fndef (parser, true, true, true, false, true,
24527 : : NULL, &clauses);
24528 : : break;
24529 : 6 : case pragma_struct:
24530 : 6 : case pragma_param:
24531 : 6 : case pragma_stmt:
24532 : 6 : error ("%<#pragma omp declare %s%> must be followed by "
24533 : : "function declaration or definition",
24534 : 6 : IDENTIFIER_POINTER (kind));
24535 : 6 : break;
24536 : 11 : case pragma_compound:
24537 : 11 : bool have_std_attrs;
24538 : 11 : tree std_attrs;
24539 : 11 : have_std_attrs = c_parser_nth_token_starts_std_attributes (parser, 1);
24540 : 11 : if (have_std_attrs)
24541 : 1 : std_attrs = c_parser_std_attribute_specifier_sequence (parser);
24542 : : else
24543 : : std_attrs = NULL_TREE;
24544 : 11 : if (c_parser_next_token_is (parser, CPP_KEYWORD)
24545 : 11 : && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
24546 : : {
24547 : 1 : int ext = disable_extension_diagnostics ();
24548 : 3 : do
24549 : 3 : c_parser_consume_token (parser);
24550 : 3 : while (c_parser_next_token_is (parser, CPP_KEYWORD)
24551 : 4 : && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
24552 : 1 : if (c_parser_next_tokens_start_declaration (parser)
24553 : 1 : || c_parser_nth_token_starts_std_attributes (parser, 1))
24554 : : {
24555 : 1 : c_parser_declaration_or_fndef (parser, true, true, true, true,
24556 : : true, NULL, &clauses,
24557 : : have_std_attrs, std_attrs);
24558 : 1 : restore_extension_diagnostics (ext);
24559 : 1 : break;
24560 : : }
24561 : 0 : restore_extension_diagnostics (ext);
24562 : : }
24563 : 10 : else if (c_parser_next_tokens_start_declaration (parser))
24564 : : {
24565 : 10 : c_parser_declaration_or_fndef (parser, true, true, true, true, true,
24566 : : NULL, &clauses, have_std_attrs,
24567 : : std_attrs);
24568 : 10 : break;
24569 : : }
24570 : 0 : error ("%<#pragma omp declare %s%> must be followed by "
24571 : : "function declaration or definition",
24572 : 0 : IDENTIFIER_POINTER (kind));
24573 : 0 : break;
24574 : 0 : default:
24575 : 0 : gcc_unreachable ();
24576 : : }
24577 : 544 : }
24578 : :
24579 : : /* OpenMP 5.0:
24580 : :
24581 : : trait-selector:
24582 : : trait-selector-name[([trait-score:]trait-property[,trait-property[,...]])]
24583 : :
24584 : : trait-score:
24585 : : score(score-expression)
24586 : :
24587 : : Note that this function returns a list of trait selectors for the
24588 : : trait-selector-set SET. */
24589 : :
24590 : : static tree
24591 : 415 : c_parser_omp_context_selector (c_parser *parser, enum omp_tss_code set,
24592 : : tree parms)
24593 : : {
24594 : 415 : tree ret = NULL_TREE;
24595 : 532 : do
24596 : : {
24597 : 532 : tree selector;
24598 : 532 : if (c_parser_next_token_is (parser, CPP_KEYWORD)
24599 : 1007 : || c_parser_next_token_is (parser, CPP_NAME))
24600 : 530 : selector = c_parser_peek_token (parser)->value;
24601 : : else
24602 : : {
24603 : 2 : c_parser_error (parser, "expected trait selector name");
24604 : 2 : return error_mark_node;
24605 : : }
24606 : 530 : enum omp_ts_code sel
24607 : 530 : = omp_lookup_ts_code (set, IDENTIFIER_POINTER (selector));
24608 : :
24609 : 530 : if (sel == OMP_TRAIT_INVALID)
24610 : : {
24611 : : /* Per the spec, "Implementations can ignore specified selectors
24612 : : that are not those described in this section"; however, we
24613 : : must record such selectors because they cause match failures. */
24614 : 36 : warning_at (c_parser_peek_token (parser)->location, OPT_Wopenmp,
24615 : : "unknown selector %qs for context selector set %qs",
24616 : 18 : IDENTIFIER_POINTER (selector), omp_tss_map[set]);
24617 : 18 : c_parser_consume_token (parser);
24618 : 18 : ret = make_trait_selector (sel, NULL_TREE, NULL_TREE, ret);
24619 : 18 : if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
24620 : 5 : c_parser_balanced_token_sequence (parser);
24621 : 18 : if (c_parser_next_token_is (parser, CPP_COMMA))
24622 : : {
24623 : 1 : c_parser_consume_token (parser);
24624 : 1 : continue;
24625 : : }
24626 : : else
24627 : : break;
24628 : : }
24629 : :
24630 : 512 : c_parser_consume_token (parser);
24631 : :
24632 : 512 : tree properties = NULL_TREE;
24633 : 512 : tree scoreval = NULL_TREE;
24634 : 512 : enum omp_tp_type property_kind = omp_ts_map[sel].tp_type;
24635 : 512 : bool allow_score = omp_ts_map[sel].allow_score;
24636 : 512 : tree t;
24637 : :
24638 : 512 : if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
24639 : : {
24640 : 305 : if (property_kind == OMP_TRAIT_PROPERTY_NONE)
24641 : : {
24642 : 12 : error_at (c_parser_peek_token (parser)->location,
24643 : : "selector %qs does not accept any properties",
24644 : 6 : IDENTIFIER_POINTER (selector));
24645 : 14 : return error_mark_node;
24646 : : }
24647 : :
24648 : 299 : matching_parens parens;
24649 : 299 : parens.require_open (parser);
24650 : :
24651 : 299 : c_token *token = c_parser_peek_token (parser);
24652 : 299 : if (c_parser_next_token_is (parser, CPP_NAME)
24653 : 225 : && strcmp (IDENTIFIER_POINTER (token->value), "score") == 0
24654 : 357 : && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN)
24655 : : {
24656 : 58 : c_parser_consume_token (parser);
24657 : :
24658 : 58 : matching_parens parens2;
24659 : 58 : parens2.require_open (parser);
24660 : 58 : tree score = c_parser_expr_no_commas (parser, NULL).value;
24661 : 58 : parens2.skip_until_found_close (parser);
24662 : 58 : c_parser_require (parser, CPP_COLON, "expected %<:%>");
24663 : 58 : if (!allow_score)
24664 : 4 : error_at (token->location,
24665 : : "%<score%> cannot be specified in traits "
24666 : : "in the %qs trait-selector-set",
24667 : : omp_tss_map[set]);
24668 : 54 : else if (score != error_mark_node)
24669 : : {
24670 : 54 : mark_exp_read (score);
24671 : 54 : score = c_fully_fold (score, false, NULL);
24672 : 108 : if (!INTEGRAL_TYPE_P (TREE_TYPE (score))
24673 : 107 : || TREE_CODE (score) != INTEGER_CST)
24674 : 1 : error_at (token->location, "%<score%> argument must "
24675 : : "be constant integer expression");
24676 : 53 : else if (tree_int_cst_sgn (score) < 0)
24677 : 1 : error_at (token->location, "%<score%> argument must "
24678 : : "be non-negative");
24679 : : else
24680 : : scoreval = score;
24681 : : }
24682 : 58 : token = c_parser_peek_token (parser);
24683 : : }
24684 : :
24685 : 299 : switch (property_kind)
24686 : : {
24687 : 25 : case OMP_TRAIT_PROPERTY_ID:
24688 : 25 : if (c_parser_next_token_is (parser, CPP_KEYWORD)
24689 : 50 : || c_parser_next_token_is (parser, CPP_NAME))
24690 : : {
24691 : 24 : tree prop = c_parser_peek_token (parser)->value;
24692 : 24 : c_parser_consume_token (parser);
24693 : 24 : properties = make_trait_property (prop, NULL_TREE,
24694 : : properties);
24695 : : }
24696 : : else
24697 : : {
24698 : 1 : c_parser_error (parser, "expected identifier");
24699 : 1 : return error_mark_node;
24700 : : }
24701 : 24 : break;
24702 : 255 : case OMP_TRAIT_PROPERTY_NAME_LIST:
24703 : 303 : do
24704 : : {
24705 : 255 : tree prop = OMP_TP_NAMELIST_NODE;
24706 : 255 : tree value = NULL_TREE;
24707 : 255 : if (c_parser_next_token_is (parser, CPP_KEYWORD)
24708 : 510 : || c_parser_next_token_is (parser, CPP_NAME))
24709 : : {
24710 : 192 : value = c_parser_peek_token (parser)->value;
24711 : 192 : c_parser_consume_token (parser);
24712 : : }
24713 : 63 : else if (c_parser_next_token_is (parser, CPP_STRING))
24714 : 58 : value = c_parser_string_literal (parser, false,
24715 : : false).value;
24716 : : else
24717 : : {
24718 : 5 : c_parser_error (parser, "expected identifier or "
24719 : : "string literal");
24720 : 5 : return error_mark_node;
24721 : : }
24722 : :
24723 : 250 : properties = make_trait_property (prop, value, properties);
24724 : :
24725 : 250 : if (c_parser_next_token_is (parser, CPP_COMMA))
24726 : 48 : c_parser_consume_token (parser);
24727 : : else
24728 : : break;
24729 : 48 : }
24730 : : while (1);
24731 : : break;
24732 : 44 : case OMP_TRAIT_PROPERTY_DEV_NUM_EXPR:
24733 : 44 : case OMP_TRAIT_PROPERTY_BOOL_EXPR:
24734 : 44 : t = c_parser_expr_no_commas (parser, NULL).value;
24735 : 44 : if (t != error_mark_node)
24736 : : {
24737 : 42 : mark_exp_read (t);
24738 : 42 : t = c_fully_fold (t, false, NULL);
24739 : : /* FIXME: this is bogus, both device_num and
24740 : : condition selectors allow arbitrary expressions. */
24741 : 84 : if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
24742 : 83 : || !tree_fits_shwi_p (t))
24743 : 1 : error_at (token->location, "property must be "
24744 : : "constant integer expression");
24745 : : else
24746 : 41 : properties = make_trait_property (NULL_TREE, t,
24747 : : properties);
24748 : : }
24749 : : else
24750 : 2 : return error_mark_node;
24751 : : break;
24752 : 23 : case OMP_TRAIT_PROPERTY_CLAUSE_LIST:
24753 : 23 : if (sel == OMP_TRAIT_CONSTRUCT_SIMD)
24754 : : {
24755 : 23 : if (parms == NULL_TREE)
24756 : : {
24757 : 0 : error_at (token->location, "properties for %<simd%> "
24758 : : "selector may not be specified in "
24759 : : "%<metadirective%>");
24760 : 0 : return error_mark_node;
24761 : : }
24762 : 23 : tree c;
24763 : 23 : c = c_parser_omp_all_clauses (parser,
24764 : 23 : OMP_DECLARE_SIMD_CLAUSE_MASK,
24765 : : "simd", true, 2);
24766 : 46 : c = c_omp_declare_simd_clauses_to_numbers (parms
24767 : 23 : == error_mark_node
24768 : : ? NULL_TREE : parms,
24769 : : c);
24770 : 23 : properties = c;
24771 : : }
24772 : 0 : else if (sel == OMP_TRAIT_IMPLEMENTATION_REQUIRES)
24773 : : {
24774 : : /* FIXME: The "requires" selector was added in OpenMP 5.1.
24775 : : Currently only the now-deprecated syntax
24776 : : from OpenMP 5.0 is supported. */
24777 : 0 : sorry_at (token->location,
24778 : : "%<requires%> selector is not supported yet");
24779 : 0 : return error_mark_node;
24780 : : }
24781 : : else
24782 : 0 : gcc_unreachable ();
24783 : 23 : break;
24784 : 0 : default:
24785 : 0 : gcc_unreachable ();
24786 : : }
24787 : :
24788 : 291 : parens.skip_until_found_close (parser);
24789 : 291 : properties = nreverse (properties);
24790 : : }
24791 : 207 : else if (property_kind != OMP_TRAIT_PROPERTY_NONE
24792 : 207 : && property_kind != OMP_TRAIT_PROPERTY_CLAUSE_LIST
24793 : 8 : && property_kind != OMP_TRAIT_PROPERTY_EXTENSION)
24794 : : {
24795 : 8 : c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>");
24796 : 8 : return error_mark_node;
24797 : : }
24798 : :
24799 : 490 : ret = make_trait_selector (sel, scoreval, properties, ret);
24800 : :
24801 : 490 : if (c_parser_next_token_is (parser, CPP_COMMA))
24802 : 116 : c_parser_consume_token (parser);
24803 : : else
24804 : : break;
24805 : : }
24806 : : while (1);
24807 : :
24808 : 391 : return nreverse (ret);
24809 : : }
24810 : :
24811 : : /* OpenMP 5.0:
24812 : :
24813 : : trait-set-selector[,trait-set-selector[,...]]
24814 : :
24815 : : trait-set-selector:
24816 : : trait-set-selector-name = { trait-selector[, trait-selector[, ...]] }
24817 : :
24818 : : trait-set-selector-name:
24819 : : constructor
24820 : : device
24821 : : implementation
24822 : : user */
24823 : :
24824 : : static tree
24825 : 348 : c_parser_omp_context_selector_specification (c_parser *parser, tree parms)
24826 : : {
24827 : 348 : tree ret = NULL_TREE;
24828 : 498 : do
24829 : : {
24830 : 423 : const char *setp = "";
24831 : 423 : if (c_parser_next_token_is (parser, CPP_NAME))
24832 : 421 : setp = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
24833 : 423 : enum omp_tss_code set = omp_lookup_tss_code (setp);
24834 : :
24835 : 423 : if (set == OMP_TRAIT_SET_INVALID)
24836 : : {
24837 : 5 : c_parser_error (parser, "expected context selector set name");
24838 : 8 : return error_mark_node;
24839 : : }
24840 : :
24841 : 418 : c_parser_consume_token (parser);
24842 : :
24843 : 418 : if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
24844 : 1 : return error_mark_node;
24845 : :
24846 : 417 : matching_braces braces;
24847 : 417 : if (!braces.require_open (parser))
24848 : 2 : return error_mark_node;
24849 : :
24850 : 415 : tree selectors = c_parser_omp_context_selector (parser, set, parms);
24851 : 415 : if (selectors == error_mark_node)
24852 : : ret = error_mark_node;
24853 : 391 : else if (ret != error_mark_node)
24854 : 391 : ret = make_trait_set_selector (set, selectors, ret);
24855 : :
24856 : 415 : braces.skip_until_found_close (parser);
24857 : :
24858 : 415 : if (c_parser_next_token_is (parser, CPP_COMMA))
24859 : 75 : c_parser_consume_token (parser);
24860 : : else
24861 : : break;
24862 : 75 : }
24863 : : while (1);
24864 : :
24865 : 340 : if (ret == error_mark_node)
24866 : : return ret;
24867 : 316 : return nreverse (ret);
24868 : : }
24869 : :
24870 : : /* Finalize #pragma omp declare variant after FNDECL has been parsed, and put
24871 : : that into "omp declare variant base" attribute. */
24872 : :
24873 : : static void
24874 : 357 : c_finish_omp_declare_variant (c_parser *parser, tree fndecl, tree parms)
24875 : : {
24876 : 357 : matching_parens parens;
24877 : 357 : if (!parens.require_open (parser))
24878 : : {
24879 : 3 : fail:
24880 : 41 : c_parser_skip_to_pragma_eol (parser, false);
24881 : 41 : return;
24882 : : }
24883 : :
24884 : 354 : if (c_parser_next_token_is_not (parser, CPP_NAME)
24885 : 354 : || c_parser_peek_token (parser)->id_kind != C_ID_ID)
24886 : : {
24887 : 3 : c_parser_error (parser, "expected identifier");
24888 : 3 : goto fail;
24889 : : }
24890 : :
24891 : 351 : c_token *token = c_parser_peek_token (parser);
24892 : 351 : tree variant = lookup_name (token->value);
24893 : :
24894 : 351 : if (variant == NULL_TREE)
24895 : : {
24896 : 1 : undeclared_variable (token->location, token->value);
24897 : 1 : variant = error_mark_node;
24898 : : }
24899 : :
24900 : 351 : c_parser_consume_token (parser);
24901 : :
24902 : 351 : parens.require_close (parser);
24903 : :
24904 : 351 : if (c_parser_next_token_is (parser, CPP_COMMA)
24905 : 351 : && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
24906 : 6 : c_parser_consume_token (parser);
24907 : :
24908 : 351 : const char *clause = "";
24909 : 351 : location_t match_loc = c_parser_peek_token (parser)->location;
24910 : 351 : if (c_parser_next_token_is (parser, CPP_NAME))
24911 : 350 : clause = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
24912 : 351 : if (strcmp (clause, "match"))
24913 : : {
24914 : 2 : c_parser_error (parser, "expected %<match%>");
24915 : 2 : goto fail;
24916 : : }
24917 : :
24918 : 349 : c_parser_consume_token (parser);
24919 : :
24920 : 349 : if (!parens.require_open (parser))
24921 : 1 : goto fail;
24922 : :
24923 : 348 : if (parms == NULL_TREE)
24924 : 276 : parms = error_mark_node;
24925 : :
24926 : 348 : tree ctx = c_parser_omp_context_selector_specification (parser, parms);
24927 : 348 : if (ctx == error_mark_node)
24928 : 32 : goto fail;
24929 : 316 : ctx = omp_check_context_selector (match_loc, ctx);
24930 : 316 : if (ctx != error_mark_node && variant != error_mark_node)
24931 : : {
24932 : 305 : if (TREE_CODE (variant) != FUNCTION_DECL)
24933 : : {
24934 : 1 : error_at (token->location, "variant %qD is not a function", variant);
24935 : 1 : variant = error_mark_node;
24936 : : }
24937 : 304 : else if (!omp_get_context_selector (ctx, OMP_TRAIT_SET_CONSTRUCT,
24938 : : OMP_TRAIT_CONSTRUCT_SIMD)
24939 : 304 : && !comptypes (TREE_TYPE (fndecl), TREE_TYPE (variant)))
24940 : : {
24941 : 1 : error_at (token->location, "variant %qD and base %qD have "
24942 : : "incompatible types", variant, fndecl);
24943 : 1 : variant = error_mark_node;
24944 : : }
24945 : 303 : else if (fndecl_built_in_p (variant)
24946 : 303 : && (strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
24947 : : "__builtin_", strlen ("__builtin_")) == 0
24948 : 0 : || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
24949 : : "__sync_", strlen ("__sync_")) == 0
24950 : 0 : || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
24951 : : "__atomic_", strlen ("__atomic_")) == 0))
24952 : : {
24953 : 1 : error_at (token->location, "variant %qD is a built-in", variant);
24954 : 1 : variant = error_mark_node;
24955 : : }
24956 : 305 : if (variant != error_mark_node)
24957 : : {
24958 : 302 : C_DECL_USED (variant) = 1;
24959 : 302 : tree construct
24960 : 302 : = omp_get_context_selector_list (ctx, OMP_TRAIT_SET_CONSTRUCT);
24961 : 302 : omp_mark_declare_variant (match_loc, variant, construct);
24962 : 302 : if (omp_context_selector_matches (ctx))
24963 : : {
24964 : 166 : tree attr
24965 : 166 : = tree_cons (get_identifier ("omp declare variant base"),
24966 : : build_tree_list (variant, ctx),
24967 : 166 : DECL_ATTRIBUTES (fndecl));
24968 : 166 : DECL_ATTRIBUTES (fndecl) = attr;
24969 : : }
24970 : : }
24971 : : }
24972 : :
24973 : 316 : parens.require_close (parser);
24974 : 316 : c_parser_skip_to_pragma_eol (parser);
24975 : : }
24976 : :
24977 : : /* Finalize #pragma omp declare simd or #pragma omp declare variant
24978 : : clauses after FNDECL has been parsed, and put that into "omp declare simd"
24979 : : or "omp declare variant base" attribute. */
24980 : :
24981 : : static void
24982 : 615 : c_finish_omp_declare_simd (c_parser *parser, tree fndecl, tree parms,
24983 : : vec<c_token> *pclauses)
24984 : : {
24985 : 615 : vec<c_token> &clauses = *pclauses;
24986 : :
24987 : : /* Normally first token is CPP_NAME "simd" or "variant". CPP_EOF there
24988 : : indicates error has been reported and CPP_PRAGMA that
24989 : : c_finish_omp_declare_simd has already processed the tokens. */
24990 : 1230 : if (clauses.exists () && clauses[0].type == CPP_EOF)
24991 : : return;
24992 : 611 : const char *kind = "simd";
24993 : 611 : if (clauses.exists ()
24994 : 1222 : && (clauses[0].type == CPP_NAME || clauses[0].type == CPP_PRAGMA))
24995 : 611 : kind = IDENTIFIER_POINTER (clauses[0].value);
24996 : 611 : gcc_assert (strcmp (kind, "simd") == 0 || strcmp (kind, "variant") == 0);
24997 : 611 : if (fndecl == NULL_TREE || TREE_CODE (fndecl) != FUNCTION_DECL)
24998 : : {
24999 : 15 : error ("%<#pragma omp declare %s%> not immediately followed by "
25000 : : "a function declaration or definition", kind);
25001 : 15 : clauses[0].type = CPP_EOF;
25002 : 15 : return;
25003 : : }
25004 : 1192 : if (clauses.exists () && clauses[0].type != CPP_NAME)
25005 : : {
25006 : 2 : error_at (DECL_SOURCE_LOCATION (fndecl),
25007 : : "%<#pragma omp declare %s%> not immediately followed by "
25008 : : "a single function declaration or definition", kind);
25009 : 2 : clauses[0].type = CPP_EOF;
25010 : 2 : return;
25011 : : }
25012 : :
25013 : 594 : if (parms == NULL_TREE)
25014 : 411 : parms = DECL_ARGUMENTS (fndecl);
25015 : :
25016 : 594 : unsigned int tokens_avail = parser->tokens_avail;
25017 : 594 : gcc_assert (parser->tokens == &parser->tokens_buf[0]);
25018 : :
25019 : 594 : parser->tokens = clauses.address ();
25020 : 594 : parser->tokens_avail = clauses.length ();
25021 : :
25022 : : /* c_parser_omp_declare_simd pushed 2 extra CPP_EOF tokens at the end. */
25023 : 1309 : while (parser->tokens_avail > 3)
25024 : : {
25025 : 715 : c_token *token = c_parser_peek_token (parser);
25026 : 715 : gcc_assert (token->type == CPP_NAME);
25027 : 715 : kind = IDENTIFIER_POINTER (token->value);
25028 : 715 : c_parser_consume_token (parser);
25029 : 715 : parser->in_pragma = true;
25030 : :
25031 : 715 : if (strcmp (kind, "simd") == 0)
25032 : : {
25033 : 358 : tree c;
25034 : 358 : c = c_parser_omp_all_clauses (parser, OMP_DECLARE_SIMD_CLAUSE_MASK,
25035 : : "#pragma omp declare simd");
25036 : 358 : c = c_omp_declare_simd_clauses_to_numbers (parms, c);
25037 : 358 : if (c != NULL_TREE)
25038 : 255 : c = tree_cons (NULL_TREE, c, NULL_TREE);
25039 : 358 : c = build_tree_list (get_identifier ("omp declare simd"), c);
25040 : 358 : TREE_CHAIN (c) = DECL_ATTRIBUTES (fndecl);
25041 : 358 : DECL_ATTRIBUTES (fndecl) = c;
25042 : : }
25043 : : else
25044 : : {
25045 : 357 : gcc_assert (strcmp (kind, "variant") == 0);
25046 : 357 : c_finish_omp_declare_variant (parser, fndecl, parms);
25047 : : }
25048 : : }
25049 : :
25050 : 594 : parser->tokens = &parser->tokens_buf[0];
25051 : 594 : parser->tokens_avail = tokens_avail;
25052 : 594 : if (clauses.exists ())
25053 : 594 : clauses[0].type = CPP_PRAGMA;
25054 : : }
25055 : :
25056 : : /* D should be C_TOKEN_VEC from omp::decl attribute. If it contains
25057 : : a threadprivate, groupprivate, allocate or declare target directive,
25058 : : return true and parse it for DECL. */
25059 : :
25060 : : bool
25061 : 36 : c_maybe_parse_omp_decl (tree decl, tree d)
25062 : : {
25063 : 36 : gcc_assert (TREE_CODE (d) == C_TOKEN_VEC);
25064 : 36 : vec<c_token, va_gc> *toks = C_TOKEN_VEC_TOKENS (d);
25065 : 36 : c_token *first = toks->address ();
25066 : 36 : c_token *last = first + toks->length ();
25067 : 36 : const char *directive[3] = {};
25068 : 105 : for (int j = 0; j < 3; j++)
25069 : : {
25070 : 93 : tree id = NULL_TREE;
25071 : 93 : if (first + j == last)
25072 : : break;
25073 : 74 : if (first[j].type == CPP_NAME)
25074 : 69 : id = first[j].value;
25075 : 5 : else if (first[j].type == CPP_KEYWORD)
25076 : 0 : id = ridpointers[(int) first[j].keyword];
25077 : : else
25078 : : break;
25079 : 69 : directive[j] = IDENTIFIER_POINTER (id);
25080 : : }
25081 : 36 : const c_omp_directive *dir = NULL;
25082 : 36 : if (directive[0])
25083 : 36 : dir = c_omp_categorize_directive (directive[0], directive[1],
25084 : : directive[2]);
25085 : 36 : if (dir == NULL)
25086 : : {
25087 : 0 : error_at (first->location,
25088 : : "unknown OpenMP directive name in "
25089 : : "%qs attribute argument", "omp::decl");
25090 : 0 : return false;
25091 : : }
25092 : 36 : if (dir->id != PRAGMA_OMP_THREADPRIVATE
25093 : : /* && dir->id != PRAGMA_OMP_GROUPPRIVATE */
25094 : 21 : && dir->id != PRAGMA_OMP_ALLOCATE
25095 : 21 : && (dir->id != PRAGMA_OMP_DECLARE
25096 : 21 : || strcmp (directive[1], "target") != 0))
25097 : : return false;
25098 : :
25099 : 36 : if (!flag_openmp && !dir->simd)
25100 : : return true;
25101 : :
25102 : 36 : c_parser *parser = the_parser;
25103 : 36 : unsigned int tokens_avail = parser->tokens_avail;
25104 : 36 : gcc_assert (parser->tokens == &parser->tokens_buf[0]);
25105 : 36 : toks = NULL;
25106 : 36 : vec_safe_reserve (toks, last - first + 2, true);
25107 : 36 : c_token tok = {};
25108 : 36 : tok.type = CPP_PRAGMA;
25109 : 36 : tok.keyword = RID_MAX;
25110 : 36 : tok.pragma_kind = pragma_kind (dir->id);
25111 : 36 : tok.location = first->location;
25112 : 36 : toks->quick_push (tok);
25113 : 152 : while (++first < last)
25114 : 80 : toks->quick_push (*first);
25115 : 36 : tok = {};
25116 : 36 : tok.type = CPP_PRAGMA_EOL;
25117 : 36 : tok.keyword = RID_MAX;
25118 : 36 : tok.location = last[-1].location;
25119 : 36 : toks->quick_push (tok);
25120 : 36 : tok = {};
25121 : 36 : tok.type = CPP_EOF;
25122 : 36 : tok.keyword = RID_MAX;
25123 : 36 : tok.location = last[-1].location;
25124 : 36 : tok.flags = tokens_avail;
25125 : 36 : toks->quick_push (tok);
25126 : 36 : parser->in_omp_decl_attribute = decl;
25127 : 36 : parser->tokens = toks->address ();
25128 : 36 : parser->tokens_avail = toks->length ();
25129 : 36 : parser->in_omp_attribute_pragma = toks;
25130 : 36 : c_parser_pragma (parser, pragma_external, NULL);
25131 : 36 : parser->in_omp_decl_attribute = NULL_TREE;
25132 : 36 : return true;
25133 : : }
25134 : :
25135 : : /* OpenMP 4.0:
25136 : : # pragma omp declare target new-line
25137 : : declarations and definitions
25138 : : # pragma omp end declare target new-line
25139 : :
25140 : : OpenMP 4.5:
25141 : : # pragma omp declare target ( extended-list ) new-line
25142 : :
25143 : : # pragma omp declare target declare-target-clauses[seq] new-line */
25144 : :
25145 : : #define OMP_DECLARE_TARGET_CLAUSE_MASK \
25146 : : ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
25147 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ENTER) \
25148 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK) \
25149 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE) \
25150 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INDIRECT))
25151 : :
25152 : : static void
25153 : 260 : c_parser_omp_declare_target (c_parser *parser)
25154 : : {
25155 : 260 : tree clauses = NULL_TREE;
25156 : 260 : int device_type = 0;
25157 : 260 : bool indirect = false;
25158 : 260 : bool only_device_type_or_indirect = true;
25159 : 260 : if (c_parser_next_token_is (parser, CPP_NAME)
25160 : 387 : || (c_parser_next_token_is (parser, CPP_COMMA)
25161 : 5 : && c_parser_peek_2nd_token (parser)->type == CPP_NAME))
25162 : 137 : clauses = c_parser_omp_all_clauses (parser, OMP_DECLARE_TARGET_CLAUSE_MASK,
25163 : : "#pragma omp declare target");
25164 : 123 : else if (parser->in_omp_decl_attribute
25165 : 240 : || c_parser_next_token_is (parser, CPP_OPEN_PAREN))
25166 : : {
25167 : 20 : clauses = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ENTER,
25168 : : clauses);
25169 : 20 : clauses = c_finish_omp_clauses (clauses, C_ORT_OMP);
25170 : 20 : c_parser_skip_to_pragma_eol (parser);
25171 : : }
25172 : : else
25173 : : {
25174 : 103 : bool attr_syntax = parser->in_omp_attribute_pragma != NULL;
25175 : 103 : c_parser_skip_to_pragma_eol (parser);
25176 : 103 : c_omp_declare_target_attr attr = { attr_syntax, -1, 0 };
25177 : 103 : vec_safe_push (current_omp_declare_target_attribute, attr);
25178 : 103 : return;
25179 : : }
25180 : 396 : for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
25181 : : {
25182 : 239 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
25183 : 27 : device_type |= OMP_CLAUSE_DEVICE_TYPE_KIND (c);
25184 : 239 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_INDIRECT)
25185 : 16 : indirect |= !integer_zerop (OMP_CLAUSE_INDIRECT_EXPR (c));
25186 : : }
25187 : 396 : for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
25188 : : {
25189 : 239 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE
25190 : 239 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_INDIRECT)
25191 : 239 : continue;
25192 : 196 : tree t = OMP_CLAUSE_DECL (c), id;
25193 : 196 : tree at1 = lookup_attribute ("omp declare target", DECL_ATTRIBUTES (t));
25194 : 196 : tree at2 = lookup_attribute ("omp declare target link",
25195 : 196 : DECL_ATTRIBUTES (t));
25196 : 196 : only_device_type_or_indirect = false;
25197 : 196 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINK)
25198 : : {
25199 : 29 : id = get_identifier ("omp declare target link");
25200 : 29 : std::swap (at1, at2);
25201 : : }
25202 : : else
25203 : 167 : id = get_identifier ("omp declare target");
25204 : 196 : if (at2)
25205 : : {
25206 : 6 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ENTER)
25207 : 3 : error_at (OMP_CLAUSE_LOCATION (c),
25208 : : "%qD specified both in declare target %<link%> and %qs"
25209 : 3 : " clauses", t, OMP_CLAUSE_ENTER_TO (c) ? "to" : "enter");
25210 : : else
25211 : 3 : error_at (OMP_CLAUSE_LOCATION (c),
25212 : : "%qD specified both in declare target %<link%> and "
25213 : : "%<to%> or %<enter%> clauses", t);
25214 : 6 : continue;
25215 : : }
25216 : 190 : if (!at1)
25217 : : {
25218 : 161 : DECL_ATTRIBUTES (t) = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
25219 : 161 : if (TREE_CODE (t) != FUNCTION_DECL && !is_global_var (t))
25220 : 1 : continue;
25221 : :
25222 : 160 : symtab_node *node = symtab_node::get (t);
25223 : 160 : if (node != NULL)
25224 : : {
25225 : 114 : node->offloadable = 1;
25226 : 114 : if (ENABLE_OFFLOADING)
25227 : : {
25228 : : g->have_offload = true;
25229 : : if (is_a <varpool_node *> (node))
25230 : : vec_safe_push (offload_vars, t);
25231 : : }
25232 : : }
25233 : : }
25234 : 189 : if (TREE_CODE (t) != FUNCTION_DECL)
25235 : 112 : continue;
25236 : 77 : if ((device_type & OMP_CLAUSE_DEVICE_TYPE_HOST) != 0)
25237 : : {
25238 : 13 : tree at3 = lookup_attribute ("omp declare target host",
25239 : 13 : DECL_ATTRIBUTES (t));
25240 : 13 : if (at3 == NULL_TREE)
25241 : : {
25242 : 11 : id = get_identifier ("omp declare target host");
25243 : 11 : DECL_ATTRIBUTES (t)
25244 : 22 : = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
25245 : : }
25246 : : }
25247 : 77 : if ((device_type & OMP_CLAUSE_DEVICE_TYPE_NOHOST) != 0)
25248 : : {
25249 : 13 : tree at3 = lookup_attribute ("omp declare target nohost",
25250 : 13 : DECL_ATTRIBUTES (t));
25251 : 13 : if (at3 == NULL_TREE)
25252 : : {
25253 : 11 : id = get_identifier ("omp declare target nohost");
25254 : 11 : DECL_ATTRIBUTES (t)
25255 : 22 : = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
25256 : : }
25257 : : }
25258 : 77 : if (indirect)
25259 : : {
25260 : 9 : tree at4 = lookup_attribute ("omp declare target indirect",
25261 : 9 : DECL_ATTRIBUTES (t));
25262 : 9 : if (at4 == NULL_TREE)
25263 : : {
25264 : 9 : id = get_identifier ("omp declare target indirect");
25265 : 9 : DECL_ATTRIBUTES (t)
25266 : 18 : = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
25267 : : }
25268 : : }
25269 : : }
25270 : 157 : if ((device_type || indirect) && only_device_type_or_indirect)
25271 : 3 : error_at (OMP_CLAUSE_LOCATION (clauses),
25272 : : "directive with only %<device_type%> or %<indirect%> clauses");
25273 : 157 : if (indirect && device_type && device_type != OMP_CLAUSE_DEVICE_TYPE_ANY)
25274 : 1 : error_at (OMP_CLAUSE_LOCATION (clauses),
25275 : : "%<device_type%> clause must specify 'any' when used with "
25276 : : "an %<indirect%> clause");
25277 : : }
25278 : :
25279 : : /* OpenMP 5.1
25280 : : #pragma omp begin assumes clauses[optseq] new-line
25281 : :
25282 : : #pragma omp begin declare target clauses[optseq] new-line */
25283 : :
25284 : : #define OMP_BEGIN_DECLARE_TARGET_CLAUSE_MASK \
25285 : : ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE) \
25286 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INDIRECT))
25287 : :
25288 : : static void
25289 : 88 : c_parser_omp_begin (c_parser *parser)
25290 : : {
25291 : 88 : const char *p = "";
25292 : 88 : c_parser_consume_pragma (parser);
25293 : 88 : if (c_parser_next_token_is (parser, CPP_NAME))
25294 : 88 : p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
25295 : 88 : if (strcmp (p, "declare") == 0)
25296 : : {
25297 : 43 : c_parser_consume_token (parser);
25298 : 43 : p = "";
25299 : 43 : if (c_parser_next_token_is (parser, CPP_NAME))
25300 : 43 : p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
25301 : 43 : if (strcmp (p, "target") == 0)
25302 : : {
25303 : 43 : c_parser_consume_token (parser);
25304 : 43 : bool attr_syntax = parser->in_omp_attribute_pragma != NULL;
25305 : 43 : tree clauses
25306 : 43 : = c_parser_omp_all_clauses (parser,
25307 : 43 : OMP_BEGIN_DECLARE_TARGET_CLAUSE_MASK,
25308 : : "#pragma omp begin declare target");
25309 : 43 : int device_type = 0;
25310 : 43 : int indirect = 0;
25311 : 67 : for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
25312 : : {
25313 : 24 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
25314 : 15 : device_type |= OMP_CLAUSE_DEVICE_TYPE_KIND (c);
25315 : 24 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_INDIRECT)
25316 : 9 : indirect |= !integer_zerop (OMP_CLAUSE_INDIRECT_EXPR (c));
25317 : : }
25318 : 43 : c_omp_declare_target_attr attr = { attr_syntax, device_type,
25319 : 43 : indirect };
25320 : 43 : vec_safe_push (current_omp_declare_target_attribute, attr);
25321 : : }
25322 : : else
25323 : : {
25324 : 0 : c_parser_error (parser, "expected %<target%>");
25325 : 0 : c_parser_skip_to_pragma_eol (parser);
25326 : : }
25327 : : }
25328 : 45 : else if (strcmp (p, "assumes") == 0)
25329 : : {
25330 : 45 : c_parser_consume_token (parser);
25331 : 45 : bool attr_syntax = parser->in_omp_attribute_pragma != NULL;
25332 : 45 : c_parser_omp_assumption_clauses (parser, false);
25333 : 45 : struct c_omp_begin_assumes_data a = { attr_syntax };
25334 : 45 : vec_safe_push (current_omp_begin_assumes, a);
25335 : : }
25336 : : else
25337 : : {
25338 : 0 : c_parser_error (parser, "expected %<declare target%> or %<assumes%>");
25339 : 0 : c_parser_skip_to_pragma_eol (parser);
25340 : : }
25341 : 88 : }
25342 : :
25343 : : /* OpenMP 4.0
25344 : : #pragma omp end declare target
25345 : :
25346 : : OpenMP 5.1
25347 : : #pragma omp end assumes */
25348 : :
25349 : : static void
25350 : 189 : c_parser_omp_end (c_parser *parser)
25351 : : {
25352 : 189 : location_t loc = c_parser_peek_token (parser)->location;
25353 : 189 : const char *p = "";
25354 : 189 : c_parser_consume_pragma (parser);
25355 : 189 : if (c_parser_next_token_is (parser, CPP_NAME))
25356 : 189 : p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
25357 : 189 : if (strcmp (p, "declare") == 0)
25358 : : {
25359 : 144 : c_parser_consume_token (parser);
25360 : 144 : if (c_parser_next_token_is (parser, CPP_NAME)
25361 : 144 : && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
25362 : : "target") == 0)
25363 : 144 : c_parser_consume_token (parser);
25364 : : else
25365 : : {
25366 : 0 : c_parser_error (parser, "expected %<target%>");
25367 : 0 : c_parser_skip_to_pragma_eol (parser);
25368 : 0 : return;
25369 : : }
25370 : 144 : bool attr_syntax = parser->in_omp_attribute_pragma != NULL;
25371 : 144 : c_parser_skip_to_pragma_eol (parser);
25372 : 144 : if (!vec_safe_length (current_omp_declare_target_attribute))
25373 : 2 : error_at (loc, "%<#pragma omp end declare target%> without "
25374 : : "corresponding %<#pragma omp declare target%> or "
25375 : : "%<#pragma omp begin declare target%>");
25376 : : else
25377 : : {
25378 : 142 : c_omp_declare_target_attr
25379 : 142 : a = current_omp_declare_target_attribute->pop ();
25380 : 142 : if (a.attr_syntax != attr_syntax)
25381 : : {
25382 : 16 : if (a.attr_syntax)
25383 : 12 : error_at (loc,
25384 : : "%qs in attribute syntax terminated "
25385 : : "with %qs in pragma syntax",
25386 : : a.device_type >= 0 ? "begin declare target"
25387 : : : "declare target",
25388 : : "end declare target");
25389 : : else
25390 : 12 : error_at (loc,
25391 : : "%qs in pragma syntax terminated "
25392 : : "with %qs in attribute syntax",
25393 : : a.device_type >= 0 ? "begin declare target"
25394 : : : "declare target",
25395 : : "end declare target");
25396 : : }
25397 : : }
25398 : : }
25399 : 45 : else if (strcmp (p, "assumes") == 0)
25400 : : {
25401 : 45 : c_parser_consume_token (parser);
25402 : 45 : bool attr_syntax = parser->in_omp_attribute_pragma != NULL;
25403 : 45 : c_parser_skip_to_pragma_eol (parser);
25404 : 45 : if (!vec_safe_length (current_omp_begin_assumes))
25405 : 1 : error_at (loc, "%qs without corresponding %qs",
25406 : : "#pragma omp end assumes", "#pragma omp begin assumes");
25407 : : else
25408 : : {
25409 : 44 : c_omp_begin_assumes_data
25410 : 44 : a = current_omp_begin_assumes->pop ();
25411 : 44 : if (a.attr_syntax != attr_syntax)
25412 : : {
25413 : 8 : if (a.attr_syntax)
25414 : 4 : error_at (loc,
25415 : : "%qs in attribute syntax terminated "
25416 : : "with %qs in pragma syntax",
25417 : : "begin assumes", "end assumes");
25418 : : else
25419 : 4 : error_at (loc,
25420 : : "%qs in pragma syntax terminated "
25421 : : "with %qs in attribute syntax",
25422 : : "begin assumes", "end assumes");
25423 : : }
25424 : : }
25425 : : }
25426 : : else
25427 : : {
25428 : 0 : c_parser_error (parser, "expected %<declare%> or %<assumes%>");
25429 : 0 : c_parser_skip_to_pragma_eol (parser);
25430 : : }
25431 : : }
25432 : :
25433 : : /* OpenMP 4.0
25434 : : #pragma omp declare reduction (reduction-id : typename-list : expression) \
25435 : : initializer-clause[opt] new-line
25436 : :
25437 : : initializer-clause:
25438 : : initializer (omp_priv = initializer)
25439 : : initializer (function-name (argument-list)) */
25440 : :
25441 : : static void
25442 : 164 : c_parser_omp_declare_reduction (c_parser *parser, enum pragma_context context)
25443 : : {
25444 : 164 : unsigned int tokens_avail = 0, i;
25445 : 164 : c_token *saved_tokens = NULL;
25446 : 164 : vec<tree> types = vNULL;
25447 : 164 : vec<c_token> clauses = vNULL;
25448 : 164 : enum tree_code reduc_code = ERROR_MARK;
25449 : 164 : tree reduc_id = NULL_TREE;
25450 : 164 : tree type;
25451 : 164 : location_t rloc = c_parser_peek_token (parser)->location;
25452 : :
25453 : 164 : if (context == pragma_struct || context == pragma_param)
25454 : : {
25455 : 2 : error ("%<#pragma omp declare reduction%> not at file or block scope");
25456 : 2 : goto fail;
25457 : : }
25458 : :
25459 : 162 : if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
25460 : 1 : goto fail;
25461 : :
25462 : 161 : switch (c_parser_peek_token (parser)->type)
25463 : : {
25464 : : case CPP_PLUS:
25465 : : reduc_code = PLUS_EXPR;
25466 : : break;
25467 : 14 : case CPP_MULT:
25468 : 14 : reduc_code = MULT_EXPR;
25469 : 14 : break;
25470 : 0 : case CPP_MINUS:
25471 : 0 : reduc_code = MINUS_EXPR;
25472 : 0 : break;
25473 : 4 : case CPP_AND:
25474 : 4 : reduc_code = BIT_AND_EXPR;
25475 : 4 : break;
25476 : 0 : case CPP_XOR:
25477 : 0 : reduc_code = BIT_XOR_EXPR;
25478 : 0 : break;
25479 : 10 : case CPP_OR:
25480 : 10 : reduc_code = BIT_IOR_EXPR;
25481 : 10 : break;
25482 : 0 : case CPP_AND_AND:
25483 : 0 : reduc_code = TRUTH_ANDIF_EXPR;
25484 : 0 : break;
25485 : 0 : case CPP_OR_OR:
25486 : 0 : reduc_code = TRUTH_ORIF_EXPR;
25487 : 0 : break;
25488 : 89 : case CPP_NAME:
25489 : 89 : const char *p;
25490 : 89 : p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
25491 : 89 : if (strcmp (p, "min") == 0)
25492 : : {
25493 : : reduc_code = MIN_EXPR;
25494 : : break;
25495 : : }
25496 : 83 : if (strcmp (p, "max") == 0)
25497 : : {
25498 : : reduc_code = MAX_EXPR;
25499 : : break;
25500 : : }
25501 : 83 : reduc_id = c_parser_peek_token (parser)->value;
25502 : 83 : break;
25503 : 0 : default:
25504 : 0 : c_parser_error (parser,
25505 : : "expected %<+%>, %<*%>, %<-%>, %<&%>, "
25506 : : "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
25507 : 0 : goto fail;
25508 : : }
25509 : :
25510 : 161 : tree orig_reduc_id, reduc_decl;
25511 : 161 : orig_reduc_id = reduc_id;
25512 : 161 : reduc_id = c_omp_reduction_id (reduc_code, reduc_id);
25513 : 161 : reduc_decl = c_omp_reduction_decl (reduc_id);
25514 : 161 : c_parser_consume_token (parser);
25515 : :
25516 : 161 : if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
25517 : 0 : goto fail;
25518 : :
25519 : 165 : while (true)
25520 : : {
25521 : 163 : location_t loc = c_parser_peek_token (parser)->location;
25522 : 163 : struct c_type_name *ctype = c_parser_type_name (parser);
25523 : 163 : if (ctype != NULL)
25524 : : {
25525 : 163 : type = groktypename (ctype, NULL, NULL);
25526 : 163 : if (type == error_mark_node)
25527 : : ;
25528 : 163 : else if ((INTEGRAL_TYPE_P (type)
25529 : 163 : || SCALAR_FLOAT_TYPE_P (type)
25530 : 98 : || TREE_CODE (type) == COMPLEX_TYPE)
25531 : 69 : && orig_reduc_id == NULL_TREE)
25532 : 8 : error_at (loc, "predeclared arithmetic type in "
25533 : : "%<#pragma omp declare reduction%>");
25534 : 155 : else if (TREE_CODE (type) == FUNCTION_TYPE
25535 : 150 : || TREE_CODE (type) == ARRAY_TYPE)
25536 : 8 : error_at (loc, "function or array type in "
25537 : : "%<#pragma omp declare reduction%>");
25538 : 147 : else if (TYPE_ATOMIC (type))
25539 : 1 : error_at (loc, "%<_Atomic%> qualified type in "
25540 : : "%<#pragma omp declare reduction%>");
25541 : 146 : else if (TYPE_QUALS_NO_ADDR_SPACE (type))
25542 : 8 : error_at (loc, "const, volatile or restrict qualified type in "
25543 : : "%<#pragma omp declare reduction%>");
25544 : : else
25545 : : {
25546 : 138 : tree t;
25547 : 200 : for (t = DECL_INITIAL (reduc_decl); t; t = TREE_CHAIN (t))
25548 : 66 : if (comptypes (TREE_PURPOSE (t), type))
25549 : : {
25550 : 4 : error_at (loc, "redeclaration of %qs "
25551 : : "%<#pragma omp declare reduction%> for "
25552 : : "type %qT",
25553 : 4 : IDENTIFIER_POINTER (reduc_id)
25554 : : + sizeof ("omp declare reduction ") - 1,
25555 : : type);
25556 : 4 : location_t ploc
25557 : 4 : = DECL_SOURCE_LOCATION (TREE_VEC_ELT (TREE_VALUE (t),
25558 : : 0));
25559 : 4 : error_at (ploc, "previous %<#pragma omp declare "
25560 : : "reduction%>");
25561 : 4 : break;
25562 : : }
25563 : 4 : if (t == NULL_TREE)
25564 : 134 : types.safe_push (type);
25565 : : }
25566 : 163 : if (c_parser_next_token_is (parser, CPP_COMMA))
25567 : 2 : c_parser_consume_token (parser);
25568 : : else
25569 : : break;
25570 : : }
25571 : : else
25572 : : break;
25573 : 2 : }
25574 : :
25575 : 161 : if (!c_parser_require (parser, CPP_COLON, "expected %<:%>")
25576 : 161 : || types.is_empty ())
25577 : : {
25578 : 34 : fail:
25579 : 34 : clauses.release ();
25580 : 34 : types.release ();
25581 : 460 : while (true)
25582 : : {
25583 : 247 : c_token *token = c_parser_peek_token (parser);
25584 : 247 : if (token->type == CPP_EOF || token->type == CPP_PRAGMA_EOL)
25585 : : break;
25586 : 213 : c_parser_consume_token (parser);
25587 : 213 : }
25588 : 34 : c_parser_skip_to_pragma_eol (parser);
25589 : 34 : return;
25590 : : }
25591 : :
25592 : 132 : if (types.length () > 1)
25593 : : {
25594 : 13 : while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
25595 : : {
25596 : 12 : c_token *token = c_parser_peek_token (parser);
25597 : 12 : if (token->type == CPP_EOF)
25598 : 0 : goto fail;
25599 : 12 : clauses.safe_push (*token);
25600 : 12 : c_parser_consume_token (parser);
25601 : : }
25602 : 1 : clauses.safe_push (*c_parser_peek_token (parser));
25603 : 1 : c_parser_skip_to_pragma_eol (parser);
25604 : :
25605 : : /* Make sure nothing tries to read past the end of the tokens. */
25606 : 1 : c_token eof_token;
25607 : 1 : memset (&eof_token, 0, sizeof (eof_token));
25608 : 1 : eof_token.type = CPP_EOF;
25609 : 1 : clauses.safe_push (eof_token);
25610 : 1 : clauses.safe_push (eof_token);
25611 : : }
25612 : :
25613 : 132 : int errs = errorcount;
25614 : 238 : FOR_EACH_VEC_ELT (types, i, type)
25615 : : {
25616 : 134 : saved_tokens = parser->tokens;
25617 : 134 : tokens_avail = parser->tokens_avail;
25618 : 134 : if (!clauses.is_empty ())
25619 : : {
25620 : 3 : parser->tokens = clauses.address ();
25621 : 3 : parser->tokens_avail = clauses.length ();
25622 : 3 : parser->in_pragma = true;
25623 : : }
25624 : :
25625 : 134 : bool nested = current_function_decl != NULL_TREE;
25626 : 134 : if (nested)
25627 : 27 : c_push_function_context ();
25628 : 134 : tree fndecl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
25629 : : reduc_id, default_function_type);
25630 : 134 : current_function_decl = fndecl;
25631 : 134 : allocate_struct_function (fndecl, true);
25632 : 134 : push_scope ();
25633 : 134 : tree stmt = push_stmt_list ();
25634 : : /* Intentionally BUILTINS_LOCATION, so that -Wshadow doesn't
25635 : : warn about these. */
25636 : 134 : tree omp_out = build_decl (BUILTINS_LOCATION, VAR_DECL,
25637 : : get_identifier ("omp_out"), type);
25638 : 134 : DECL_ARTIFICIAL (omp_out) = 1;
25639 : 134 : DECL_CONTEXT (omp_out) = fndecl;
25640 : 134 : pushdecl (omp_out);
25641 : 134 : tree omp_in = build_decl (BUILTINS_LOCATION, VAR_DECL,
25642 : : get_identifier ("omp_in"), type);
25643 : 134 : DECL_ARTIFICIAL (omp_in) = 1;
25644 : 134 : DECL_CONTEXT (omp_in) = fndecl;
25645 : 134 : pushdecl (omp_in);
25646 : 134 : struct c_expr combiner = c_parser_expression (parser);
25647 : 134 : struct c_expr initializer;
25648 : 134 : tree omp_priv = NULL_TREE, omp_orig = NULL_TREE;
25649 : 134 : bool bad = false;
25650 : 134 : initializer.set_error ();
25651 : 134 : if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
25652 : : bad = true;
25653 : 134 : else if (c_parser_next_token_is (parser, CPP_COMMA)
25654 : 134 : && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
25655 : 2 : c_parser_consume_token (parser);
25656 : 2 : if (!bad
25657 : 134 : && (c_parser_next_token_is (parser, CPP_NAME)
25658 : 77 : && strcmp (IDENTIFIER_POINTER
25659 : : (c_parser_peek_token (parser)->value),
25660 : : "initializer") == 0))
25661 : : {
25662 : 77 : c_parser_consume_token (parser);
25663 : 77 : pop_scope ();
25664 : 77 : push_scope ();
25665 : 77 : omp_priv = build_decl (BUILTINS_LOCATION, VAR_DECL,
25666 : : get_identifier ("omp_priv"), type);
25667 : 77 : DECL_ARTIFICIAL (omp_priv) = 1;
25668 : 77 : DECL_INITIAL (omp_priv) = error_mark_node;
25669 : 77 : DECL_CONTEXT (omp_priv) = fndecl;
25670 : 77 : pushdecl (omp_priv);
25671 : 77 : omp_orig = build_decl (BUILTINS_LOCATION, VAR_DECL,
25672 : : get_identifier ("omp_orig"), type);
25673 : 77 : DECL_ARTIFICIAL (omp_orig) = 1;
25674 : 77 : DECL_CONTEXT (omp_orig) = fndecl;
25675 : 77 : pushdecl (omp_orig);
25676 : 77 : if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
25677 : : bad = true;
25678 : 77 : else if (!c_parser_next_token_is (parser, CPP_NAME))
25679 : : {
25680 : 0 : c_parser_error (parser, "expected %<omp_priv%> or "
25681 : : "function-name");
25682 : 0 : bad = true;
25683 : : }
25684 : 77 : else if (strcmp (IDENTIFIER_POINTER
25685 : : (c_parser_peek_token (parser)->value),
25686 : : "omp_priv") != 0)
25687 : : {
25688 : 20 : if (c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN
25689 : 20 : || c_parser_peek_token (parser)->id_kind != C_ID_ID)
25690 : : {
25691 : 0 : c_parser_error (parser, "expected function-name %<(%>");
25692 : 0 : bad = true;
25693 : : }
25694 : : else
25695 : 20 : initializer = c_parser_postfix_expression (parser);
25696 : 20 : if (initializer.value
25697 : 20 : && TREE_CODE (initializer.value) == CALL_EXPR)
25698 : : {
25699 : : int j;
25700 : : tree c = initializer.value;
25701 : 21 : for (j = 0; j < call_expr_nargs (c); j++)
25702 : : {
25703 : 20 : tree a = CALL_EXPR_ARG (c, j);
25704 : 20 : STRIP_NOPS (a);
25705 : 20 : if (TREE_CODE (a) == ADDR_EXPR
25706 : 20 : && TREE_OPERAND (a, 0) == omp_priv)
25707 : : break;
25708 : : }
25709 : 20 : if (j == call_expr_nargs (c))
25710 : 1 : error ("one of the initializer call arguments should be "
25711 : : "%<&omp_priv%>");
25712 : : }
25713 : : }
25714 : : else
25715 : : {
25716 : 57 : c_parser_consume_token (parser);
25717 : 57 : if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
25718 : : bad = true;
25719 : : else
25720 : : {
25721 : 55 : tree st = push_stmt_list ();
25722 : 55 : location_t loc = c_parser_peek_token (parser)->location;
25723 : 55 : rich_location richloc (line_table, loc);
25724 : 55 : start_init (omp_priv, NULL_TREE, false, false, &richloc);
25725 : 55 : struct c_expr init = c_parser_initializer (parser, omp_priv);
25726 : 55 : finish_init ();
25727 : 55 : finish_decl (omp_priv, loc, init.value,
25728 : : init.original_type, NULL_TREE);
25729 : 55 : pop_stmt_list (st);
25730 : 55 : }
25731 : : }
25732 : 0 : if (!bad
25733 : 75 : && !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
25734 : : bad = true;
25735 : : }
25736 : :
25737 : 134 : if (!bad)
25738 : : {
25739 : 132 : c_parser_skip_to_pragma_eol (parser);
25740 : :
25741 : 189 : tree t = tree_cons (type, make_tree_vec (omp_priv ? 6 : 3),
25742 : 132 : DECL_INITIAL (reduc_decl));
25743 : 132 : DECL_INITIAL (reduc_decl) = t;
25744 : 132 : DECL_SOURCE_LOCATION (omp_out) = rloc;
25745 : 132 : TREE_VEC_ELT (TREE_VALUE (t), 0) = omp_out;
25746 : 132 : TREE_VEC_ELT (TREE_VALUE (t), 1) = omp_in;
25747 : 132 : TREE_VEC_ELT (TREE_VALUE (t), 2) = combiner.value;
25748 : 132 : walk_tree (&combiner.value, c_check_omp_declare_reduction_r,
25749 : : &TREE_VEC_ELT (TREE_VALUE (t), 0), NULL);
25750 : 132 : if (omp_priv)
25751 : : {
25752 : 75 : DECL_SOURCE_LOCATION (omp_priv) = rloc;
25753 : 75 : TREE_VEC_ELT (TREE_VALUE (t), 3) = omp_priv;
25754 : 75 : TREE_VEC_ELT (TREE_VALUE (t), 4) = omp_orig;
25755 : 75 : TREE_VEC_ELT (TREE_VALUE (t), 5) = initializer.value;
25756 : 75 : walk_tree (&initializer.value, c_check_omp_declare_reduction_r,
25757 : : &TREE_VEC_ELT (TREE_VALUE (t), 3), NULL);
25758 : 75 : walk_tree (&DECL_INITIAL (omp_priv),
25759 : : c_check_omp_declare_reduction_r,
25760 : : &TREE_VEC_ELT (TREE_VALUE (t), 3), NULL);
25761 : : }
25762 : : }
25763 : :
25764 : 134 : pop_stmt_list (stmt);
25765 : 134 : pop_scope ();
25766 : 134 : if (cfun->language != NULL)
25767 : : {
25768 : 0 : ggc_free (cfun->language);
25769 : 0 : cfun->language = NULL;
25770 : : }
25771 : 134 : set_cfun (NULL);
25772 : 134 : current_function_decl = NULL_TREE;
25773 : 134 : if (nested)
25774 : 27 : c_pop_function_context ();
25775 : :
25776 : 134 : if (!clauses.is_empty ())
25777 : : {
25778 : 3 : parser->tokens = saved_tokens;
25779 : 3 : parser->tokens_avail = tokens_avail;
25780 : : }
25781 : 134 : if (bad)
25782 : 2 : goto fail;
25783 : 132 : if (errs != errorcount)
25784 : : break;
25785 : : }
25786 : :
25787 : 130 : clauses.release ();
25788 : 130 : types.release ();
25789 : : }
25790 : :
25791 : :
25792 : : /* OpenMP 4.0
25793 : : #pragma omp declare simd declare-simd-clauses[optseq] new-line
25794 : : #pragma omp declare reduction (reduction-id : typename-list : expression) \
25795 : : initializer-clause[opt] new-line
25796 : : #pragma omp declare target new-line
25797 : :
25798 : : OpenMP 5.0
25799 : : #pragma omp declare variant (identifier) match (context-selector) */
25800 : :
25801 : : static bool
25802 : 968 : c_parser_omp_declare (c_parser *parser, enum pragma_context context)
25803 : : {
25804 : 968 : c_parser_consume_pragma (parser);
25805 : 968 : if (c_parser_next_token_is (parser, CPP_NAME))
25806 : : {
25807 : 968 : const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
25808 : 968 : if (strcmp (p, "simd") == 0)
25809 : : {
25810 : : /* c_parser_consume_token (parser); done in
25811 : : c_parser_omp_declare_simd. */
25812 : 263 : c_parser_omp_declare_simd (parser, context);
25813 : 263 : return true;
25814 : : }
25815 : 705 : if (strcmp (p, "reduction") == 0)
25816 : : {
25817 : 164 : c_parser_consume_token (parser);
25818 : 164 : c_parser_omp_declare_reduction (parser, context);
25819 : 164 : return false;
25820 : : }
25821 : 541 : if (!flag_openmp) /* flag_openmp_simd */
25822 : : {
25823 : 0 : c_parser_skip_to_pragma_eol (parser, false);
25824 : 0 : return false;
25825 : : }
25826 : 541 : if (strcmp (p, "target") == 0)
25827 : : {
25828 : 260 : c_parser_consume_token (parser);
25829 : 260 : c_parser_omp_declare_target (parser);
25830 : 260 : return false;
25831 : : }
25832 : 281 : if (strcmp (p, "variant") == 0)
25833 : : {
25834 : : /* c_parser_consume_token (parser); done in
25835 : : c_parser_omp_declare_simd. */
25836 : 281 : c_parser_omp_declare_simd (parser, context);
25837 : 281 : return true;
25838 : : }
25839 : : }
25840 : :
25841 : 0 : c_parser_error (parser, "expected %<simd%>, %<reduction%>, "
25842 : : "%<target%> or %<variant%>");
25843 : 0 : c_parser_skip_to_pragma_eol (parser);
25844 : 0 : return false;
25845 : : }
25846 : :
25847 : : /* OpenMP 5.0
25848 : : #pragma omp requires clauses[optseq] new-line */
25849 : :
25850 : : static void
25851 : 59 : c_parser_omp_requires (c_parser *parser)
25852 : : {
25853 : 59 : enum omp_requires new_req = (enum omp_requires) 0;
25854 : :
25855 : 59 : c_parser_consume_pragma (parser);
25856 : :
25857 : 59 : location_t loc = c_parser_peek_token (parser)->location;
25858 : 132 : while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
25859 : : {
25860 : 77 : if (c_parser_next_token_is (parser, CPP_COMMA)
25861 : 77 : && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
25862 : 14 : c_parser_consume_token (parser);
25863 : :
25864 : 77 : if (c_parser_next_token_is (parser, CPP_NAME))
25865 : : {
25866 : 76 : const char *p
25867 : 76 : = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
25868 : 76 : location_t cloc = c_parser_peek_token (parser)->location;
25869 : 76 : enum omp_requires this_req = (enum omp_requires) 0;
25870 : :
25871 : 76 : if (!strcmp (p, "unified_address"))
25872 : : this_req = OMP_REQUIRES_UNIFIED_ADDRESS;
25873 : 62 : else if (!strcmp (p, "unified_shared_memory"))
25874 : : this_req = OMP_REQUIRES_UNIFIED_SHARED_MEMORY;
25875 : 49 : else if (!strcmp (p, "dynamic_allocators"))
25876 : : this_req = OMP_REQUIRES_DYNAMIC_ALLOCATORS;
25877 : 38 : else if (!strcmp (p, "reverse_offload"))
25878 : : this_req = OMP_REQUIRES_REVERSE_OFFLOAD;
25879 : 21 : else if (!strcmp (p, "atomic_default_mem_order"))
25880 : : {
25881 : 20 : c_parser_consume_token (parser);
25882 : :
25883 : 20 : matching_parens parens;
25884 : 20 : if (parens.require_open (parser))
25885 : : {
25886 : 20 : if (c_parser_next_token_is (parser, CPP_NAME))
25887 : : {
25888 : 19 : tree v = c_parser_peek_token (parser)->value;
25889 : 19 : p = IDENTIFIER_POINTER (v);
25890 : :
25891 : 19 : if (!strcmp (p, "seq_cst"))
25892 : : this_req
25893 : : = (enum omp_requires) OMP_MEMORY_ORDER_SEQ_CST;
25894 : 10 : else if (!strcmp (p, "relaxed"))
25895 : : this_req
25896 : : = (enum omp_requires) OMP_MEMORY_ORDER_RELAXED;
25897 : 9 : else if (!strcmp (p, "release"))
25898 : : this_req
25899 : : = (enum omp_requires) OMP_MEMORY_ORDER_RELEASE;
25900 : 7 : else if (!strcmp (p, "acq_rel"))
25901 : : this_req
25902 : : = (enum omp_requires) OMP_MEMORY_ORDER_ACQ_REL;
25903 : 4 : else if (!strcmp (p, "acquire"))
25904 : : this_req
25905 : : = (enum omp_requires) OMP_MEMORY_ORDER_ACQUIRE;
25906 : : }
25907 : : if (this_req == 0)
25908 : : {
25909 : 2 : error_at (c_parser_peek_token (parser)->location,
25910 : : "expected %<acq_rel%>, %<acquire%>, "
25911 : : "%<relaxed%>, %<release%> or %<seq_cst%>");
25912 : 2 : switch (c_parser_peek_token (parser)->type)
25913 : : {
25914 : : case CPP_EOF:
25915 : : case CPP_PRAGMA_EOL:
25916 : : case CPP_CLOSE_PAREN:
25917 : : break;
25918 : 1 : default:
25919 : 1 : if (c_parser_peek_2nd_token (parser)->type
25920 : : == CPP_CLOSE_PAREN)
25921 : 1 : c_parser_consume_token (parser);
25922 : : break;
25923 : : }
25924 : : }
25925 : : else
25926 : 18 : c_parser_consume_token (parser);
25927 : :
25928 : 20 : parens.skip_until_found_close (parser);
25929 : 20 : if (this_req == 0)
25930 : : {
25931 : 2 : c_parser_skip_to_pragma_eol (parser, false);
25932 : 2 : return;
25933 : : }
25934 : : }
25935 : 18 : p = NULL;
25936 : : }
25937 : : else
25938 : : {
25939 : 1 : error_at (cloc, "expected %<unified_address%>, "
25940 : : "%<unified_shared_memory%>, "
25941 : : "%<dynamic_allocators%>, "
25942 : : "%<reverse_offload%> "
25943 : : "or %<atomic_default_mem_order%> clause");
25944 : 1 : c_parser_skip_to_pragma_eol (parser, false);
25945 : 1 : return;
25946 : : }
25947 : 18 : if (p)
25948 : 55 : c_parser_consume_token (parser);
25949 : 73 : if (this_req)
25950 : : {
25951 : 73 : if ((this_req & ~OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
25952 : : {
25953 : 55 : if ((this_req & new_req) != 0)
25954 : 4 : error_at (cloc, "too many %qs clauses", p);
25955 : 55 : if (this_req != OMP_REQUIRES_DYNAMIC_ALLOCATORS
25956 : 44 : && (omp_requires_mask & OMP_REQUIRES_TARGET_USED) != 0)
25957 : 3 : error_at (cloc, "%qs clause used lexically after first "
25958 : : "target construct or offloading API", p);
25959 : : }
25960 : 18 : else if ((new_req & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
25961 : : {
25962 : 1 : error_at (cloc, "too many %qs clauses",
25963 : : "atomic_default_mem_order");
25964 : 1 : this_req = (enum omp_requires) 0;
25965 : : }
25966 : 17 : else if ((omp_requires_mask
25967 : : & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
25968 : : {
25969 : 2 : error_at (cloc, "more than one %<atomic_default_mem_order%>"
25970 : : " clause in a single compilation unit");
25971 : 2 : this_req
25972 : 2 : = (enum omp_requires)
25973 : 2 : (omp_requires_mask
25974 : : & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER);
25975 : : }
25976 : 15 : else if ((omp_requires_mask
25977 : : & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED) != 0)
25978 : 1 : error_at (cloc, "%<atomic_default_mem_order%> clause used "
25979 : : "lexically after first %<atomic%> construct "
25980 : : "without memory order clause");
25981 : 73 : new_req = (enum omp_requires) (new_req | this_req);
25982 : 73 : omp_requires_mask
25983 : 73 : = (enum omp_requires) (omp_requires_mask | this_req);
25984 : 73 : continue;
25985 : : }
25986 : : }
25987 : : break;
25988 : : }
25989 : 56 : c_parser_skip_to_pragma_eol (parser);
25990 : :
25991 : 56 : if (new_req == 0)
25992 : 1 : error_at (loc, "%<pragma omp requires%> requires at least one clause");
25993 : : }
25994 : :
25995 : : /* Helper function for c_parser_omp_taskloop.
25996 : : Disallow zero sized or potentially zero sized task reductions. */
25997 : :
25998 : : static tree
25999 : 370 : c_finish_taskloop_clauses (tree clauses)
26000 : : {
26001 : 370 : tree *pc = &clauses;
26002 : 1974 : for (tree c = clauses; c; c = *pc)
26003 : : {
26004 : 1604 : bool remove = false;
26005 : 1604 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
26006 : : {
26007 : 142 : tree type = strip_array_types (TREE_TYPE (OMP_CLAUSE_DECL (c)));
26008 : 142 : if (integer_zerop (TYPE_SIZE_UNIT (type)))
26009 : : {
26010 : 2 : error_at (OMP_CLAUSE_LOCATION (c),
26011 : : "zero sized type %qT in %<reduction%> clause", type);
26012 : 2 : remove = true;
26013 : : }
26014 : 140 : else if (TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST)
26015 : : {
26016 : 0 : error_at (OMP_CLAUSE_LOCATION (c),
26017 : : "variable sized type %qT in %<reduction%> clause",
26018 : : type);
26019 : 0 : remove = true;
26020 : : }
26021 : : }
26022 : 2 : if (remove)
26023 : 2 : *pc = OMP_CLAUSE_CHAIN (c);
26024 : : else
26025 : 1602 : pc = &OMP_CLAUSE_CHAIN (c);
26026 : : }
26027 : 370 : return clauses;
26028 : : }
26029 : :
26030 : : /* OpenMP 4.5:
26031 : : #pragma omp taskloop taskloop-clause[optseq] new-line
26032 : : for-loop
26033 : :
26034 : : #pragma omp taskloop simd taskloop-simd-clause[optseq] new-line
26035 : : for-loop */
26036 : :
26037 : : #define OMP_TASKLOOP_CLAUSE_MASK \
26038 : : ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
26039 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
26040 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
26041 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
26042 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
26043 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_GRAINSIZE) \
26044 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TASKS) \
26045 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
26046 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
26047 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
26048 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
26049 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
26050 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP) \
26051 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
26052 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
26053 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
26054 : : | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION))
26055 : :
26056 : : static tree
26057 : 375 : c_parser_omp_taskloop (location_t loc, c_parser *parser,
26058 : : char *p_name, omp_clause_mask mask, tree *cclauses,
26059 : : bool *if_p)
26060 : : {
26061 : 375 : tree clauses, block, ret;
26062 : :
26063 : 375 : strcat (p_name, " taskloop");
26064 : 375 : mask |= OMP_TASKLOOP_CLAUSE_MASK;
26065 : : /* #pragma omp parallel master taskloop{, simd} disallow in_reduction
26066 : : clause. */
26067 : 375 : if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0)
26068 : 67 : mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION);
26069 : :
26070 : 375 : if (c_parser_next_token_is (parser, CPP_NAME))
26071 : : {
26072 : 304 : const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
26073 : :
26074 : 304 : if (strcmp (p, "simd") == 0)
26075 : : {
26076 : 164 : tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
26077 : 164 : if (cclauses == NULL)
26078 : 84 : cclauses = cclauses_buf;
26079 : 164 : c_parser_consume_token (parser);
26080 : 164 : if (!flag_openmp) /* flag_openmp_simd */
26081 : 3 : return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
26082 : 3 : if_p);
26083 : 161 : block = c_begin_compound_stmt (true);
26084 : 161 : ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses, if_p);
26085 : 161 : block = c_end_compound_stmt (loc, block, true);
26086 : 161 : if (ret == NULL)
26087 : : return ret;
26088 : 161 : ret = make_node (OMP_TASKLOOP);
26089 : 161 : TREE_TYPE (ret) = void_type_node;
26090 : 161 : OMP_FOR_BODY (ret) = block;
26091 : 161 : OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
26092 : 161 : OMP_FOR_CLAUSES (ret)
26093 : 161 : = c_finish_taskloop_clauses (OMP_FOR_CLAUSES (ret));
26094 : 161 : SET_EXPR_LOCATION (ret, loc);
26095 : 161 : add_stmt (ret);
26096 : 161 : return ret;
26097 : : }
26098 : : }
26099 : 211 : if (!flag_openmp) /* flag_openmp_simd */
26100 : : {
26101 : 2 : c_parser_skip_to_pragma_eol (parser, false);
26102 : 2 : return NULL_TREE;
26103 : : }
26104 : :
26105 : 209 : clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
26106 : 209 : if (cclauses)
26107 : : {
26108 : 52 : omp_split_clauses (loc, OMP_TASKLOOP, mask, clauses, cclauses);
26109 : 52 : clauses = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
26110 : : }
26111 : :
26112 : 209 : clauses = c_finish_taskloop_clauses (clauses);
26113 : 209 : block = c_begin_compound_stmt (true);
26114 : 209 : ret = c_parser_omp_for_loop (loc, parser, OMP_TASKLOOP, clauses, NULL, if_p);
26115 : 209 : block = c_end_compound_stmt (loc, block, true);
26116 : 209 : add_stmt (block);
26117 : :
26118 : 209 : return ret;
26119 : : }
26120 : :
26121 : : /* OpenMP 5.1
26122 : : #pragma omp nothing new-line */
26123 : :
26124 : : static void
26125 : 23 : c_parser_omp_nothing (c_parser *parser)
26126 : : {
26127 : 23 : c_parser_consume_pragma (parser);
26128 : 23 : c_parser_skip_to_pragma_eol (parser);
26129 : 23 : }
26130 : :
26131 : : /* OpenMP 5.1
26132 : : #pragma omp error clauses[optseq] new-line */
26133 : :
26134 : : static bool
26135 : 90 : c_parser_omp_error (c_parser *parser, enum pragma_context context)
26136 : : {
26137 : 90 : int at_compilation = -1;
26138 : 90 : int severity_fatal = -1;
26139 : 90 : tree message = NULL_TREE;
26140 : 90 : bool bad = false;
26141 : 90 : location_t loc = c_parser_peek_token (parser)->location;
26142 : :
26143 : 90 : c_parser_consume_pragma (parser);
26144 : :
26145 : 322 : while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
26146 : : {
26147 : 145 : if (c_parser_next_token_is (parser, CPP_COMMA)
26148 : 145 : && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
26149 : 21 : c_parser_consume_token (parser);
26150 : :
26151 : 145 : if (!c_parser_next_token_is (parser, CPP_NAME))
26152 : : break;
26153 : :
26154 : 144 : const char *p
26155 : 144 : = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
26156 : 144 : location_t cloc = c_parser_peek_token (parser)->location;
26157 : 144 : static const char *args[] = {
26158 : : "execution", "compilation", "warning", "fatal"
26159 : : };
26160 : 144 : int *v = NULL;
26161 : 144 : int idx = 0, n = -1;
26162 : 144 : tree m = NULL_TREE;
26163 : :
26164 : 144 : if (!strcmp (p, "at"))
26165 : : v = &at_compilation;
26166 : 94 : else if (!strcmp (p, "severity"))
26167 : : {
26168 : : v = &severity_fatal;
26169 : : idx += 2;
26170 : : }
26171 : 49 : else if (strcmp (p, "message"))
26172 : : {
26173 : 2 : error_at (cloc,
26174 : : "expected %<at%>, %<severity%> or %<message%> clause");
26175 : 2 : c_parser_skip_to_pragma_eol (parser, false);
26176 : 2 : return false;
26177 : : }
26178 : :
26179 : 142 : c_parser_consume_token (parser);
26180 : :
26181 : 142 : matching_parens parens;
26182 : 142 : if (parens.require_open (parser))
26183 : : {
26184 : 139 : if (v == NULL)
26185 : : {
26186 : 46 : location_t expr_loc = c_parser_peek_token (parser)->location;
26187 : 46 : c_expr expr = c_parser_expr_no_commas (parser, NULL);
26188 : 46 : expr = convert_lvalue_to_rvalue (expr_loc, expr, true, true);
26189 : 46 : m = convert (const_string_type_node, expr.value);
26190 : 46 : m = c_fully_fold (m, false, NULL);
26191 : : }
26192 : : else
26193 : : {
26194 : 93 : if (c_parser_next_token_is (parser, CPP_NAME))
26195 : : {
26196 : 89 : tree val = c_parser_peek_token (parser)->value;
26197 : 89 : const char *q = IDENTIFIER_POINTER (val);
26198 : :
26199 : 89 : if (!strcmp (q, args[idx]))
26200 : : n = 0;
26201 : 40 : else if (!strcmp (q, args[idx + 1]))
26202 : : n = 1;
26203 : : }
26204 : : if (n == -1)
26205 : : {
26206 : 6 : error_at (c_parser_peek_token (parser)->location,
26207 : 6 : "expected %qs or %qs", args[idx], args[idx + 1]);
26208 : 6 : bad = true;
26209 : 6 : switch (c_parser_peek_token (parser)->type)
26210 : : {
26211 : : case CPP_EOF:
26212 : : case CPP_PRAGMA_EOL:
26213 : : case CPP_CLOSE_PAREN:
26214 : : break;
26215 : 4 : default:
26216 : 4 : if (c_parser_peek_2nd_token (parser)->type
26217 : : == CPP_CLOSE_PAREN)
26218 : 2 : c_parser_consume_token (parser);
26219 : : break;
26220 : : }
26221 : : }
26222 : : else
26223 : 87 : c_parser_consume_token (parser);
26224 : : }
26225 : :
26226 : 139 : parens.skip_until_found_close (parser);
26227 : :
26228 : 139 : if (v == NULL)
26229 : : {
26230 : 46 : if (message)
26231 : : {
26232 : 1 : error_at (cloc, "too many %qs clauses", p);
26233 : 1 : bad = true;
26234 : : }
26235 : : else
26236 : : message = m;
26237 : : }
26238 : 93 : else if (n != -1)
26239 : : {
26240 : 87 : if (*v != -1)
26241 : : {
26242 : 2 : error_at (cloc, "too many %qs clauses", p);
26243 : 2 : bad = true;
26244 : : }
26245 : : else
26246 : 85 : *v = n;
26247 : : }
26248 : : }
26249 : : else
26250 : : bad = true;
26251 : : }
26252 : 88 : c_parser_skip_to_pragma_eol (parser);
26253 : 88 : if (bad)
26254 : : return true;
26255 : :
26256 : 76 : if (at_compilation == -1)
26257 : 33 : at_compilation = 1;
26258 : 76 : if (severity_fatal == -1)
26259 : 38 : severity_fatal = 1;
26260 : 76 : if (!at_compilation)
26261 : : {
26262 : 23 : if (context != pragma_compound)
26263 : : {
26264 : 7 : error_at (loc, "%<#pragma omp error%> with %<at(execution)%> clause "
26265 : : "may only be used in compound statements");
26266 : 7 : return true;
26267 : : }
26268 : 16 : tree fndecl
26269 : 24 : = builtin_decl_explicit (severity_fatal ? BUILT_IN_GOMP_ERROR
26270 : : : BUILT_IN_GOMP_WARNING);
26271 : 16 : if (!message)
26272 : 3 : message = build_zero_cst (const_string_type_node);
26273 : 16 : tree stmt = build_call_expr_loc (loc, fndecl, 2, message,
26274 : : build_all_ones_cst (size_type_node));
26275 : 16 : add_stmt (stmt);
26276 : 16 : return true;
26277 : : }
26278 : 53 : const char *msg = NULL;
26279 : 53 : if (message)
26280 : : {
26281 : 27 : msg = c_getstr (message);
26282 : 27 : if (msg == NULL)
26283 : 6 : msg = _("<message unknown at compile time>");
26284 : : }
26285 : 6 : if (msg)
26286 : 39 : emit_diagnostic (severity_fatal ? DK_ERROR : DK_WARNING, loc, 0,
26287 : : "%<pragma omp error%> encountered: %s", msg);
26288 : : else
26289 : 29 : emit_diagnostic (severity_fatal ? DK_ERROR : DK_WARNING, loc, 0,
26290 : : "%<pragma omp error%> encountered");
26291 : : return false;
26292 : : }
26293 : :
26294 : : /* Assumption clauses:
26295 : : OpenMP 5.1
26296 : : absent (directive-name-list)
26297 : : contains (directive-name-list)
26298 : : holds (expression)
26299 : : no_openmp
26300 : : no_openmp_routines
26301 : : no_parallelism */
26302 : :
26303 : : static void
26304 : 122 : c_parser_omp_assumption_clauses (c_parser *parser, bool is_assume)
26305 : : {
26306 : 122 : bool no_openmp = false;
26307 : 122 : bool no_openmp_routines = false;
26308 : 122 : bool no_parallelism = false;
26309 : 122 : bitmap_head absent_head, contains_head;
26310 : :
26311 : 122 : bitmap_obstack_initialize (NULL);
26312 : 122 : bitmap_initialize (&absent_head, &bitmap_default_obstack);
26313 : 122 : bitmap_initialize (&contains_head, &bitmap_default_obstack);
26314 : :
26315 : 122 : if (c_parser_next_token_is (parser, CPP_PRAGMA_EOL))
26316 : 3 : error_at (c_parser_peek_token (parser)->location,
26317 : : "expected at least one assumption clause");
26318 : :
26319 : 339 : while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
26320 : : {
26321 : 220 : if (c_parser_next_token_is (parser, CPP_COMMA)
26322 : 220 : && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
26323 : 53 : c_parser_consume_token (parser);
26324 : :
26325 : 220 : if (!c_parser_next_token_is (parser, CPP_NAME))
26326 : : break;
26327 : :
26328 : 220 : const char *p
26329 : 220 : = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
26330 : 220 : location_t cloc = c_parser_peek_token (parser)->location;
26331 : :
26332 : 220 : if (!strcmp (p, "no_openmp"))
26333 : : {
26334 : 16 : c_parser_consume_token (parser);
26335 : 16 : if (no_openmp)
26336 : 3 : error_at (cloc, "too many %qs clauses", "no_openmp");
26337 : : no_openmp = true;
26338 : : }
26339 : 204 : else if (!strcmp (p, "no_openmp_routines"))
26340 : : {
26341 : 16 : c_parser_consume_token (parser);
26342 : 16 : if (no_openmp_routines)
26343 : 3 : error_at (cloc, "too many %qs clauses", "no_openmp_routines");
26344 : : no_openmp_routines = true;
26345 : : }
26346 : 188 : else if (!strcmp (p, "no_parallelism"))
26347 : : {
26348 : 18 : c_parser_consume_token (parser);
26349 : 18 : if (no_parallelism)
26350 : 3 : error_at (cloc, "too many %qs clauses", "no_parallelism");
26351 : : no_parallelism = true;
26352 : : }
26353 : 170 : else if (!strcmp (p, "holds"))
26354 : : {
26355 : 18 : c_parser_consume_token (parser);
26356 : 18 : matching_parens parens;
26357 : 18 : if (parens.require_open (parser))
26358 : : {
26359 : 18 : location_t eloc = c_parser_peek_token (parser)->location;
26360 : 18 : c_expr expr = c_parser_expr_no_commas (parser, NULL);
26361 : 18 : tree t = convert_lvalue_to_rvalue (eloc, expr, true, true).value;
26362 : 18 : t = c_objc_common_truthvalue_conversion (eloc, t);
26363 : 18 : t = c_fully_fold (t, false, NULL);
26364 : 18 : if (is_assume && t != error_mark_node)
26365 : : {
26366 : 10 : tree fn = build_call_expr_internal_loc (eloc, IFN_ASSUME,
26367 : : void_type_node, 1,
26368 : : t);
26369 : 10 : add_stmt (fn);
26370 : : }
26371 : 18 : parens.skip_until_found_close (parser);
26372 : : }
26373 : : }
26374 : 152 : else if (!strcmp (p, "absent") || !strcmp (p, "contains"))
26375 : : {
26376 : 143 : c_parser_consume_token (parser);
26377 : 143 : matching_parens parens;
26378 : 143 : if (parens.require_open (parser))
26379 : : {
26380 : 601 : do
26381 : : {
26382 : 372 : const char *directive[3] = {};
26383 : 372 : int i;
26384 : 372 : location_t dloc = c_parser_peek_token (parser)->location;
26385 : 837 : for (i = 0; i < 3; i++)
26386 : : {
26387 : 804 : tree id;
26388 : 804 : if (c_parser_peek_nth_token (parser, i + 1)->type
26389 : : == CPP_NAME)
26390 : 453 : id = c_parser_peek_nth_token (parser, i + 1)->value;
26391 : 351 : else if (c_parser_peek_nth_token (parser, i + 1)->keyword
26392 : : != RID_MAX)
26393 : : {
26394 : 12 : enum rid rid
26395 : 12 : = c_parser_peek_nth_token (parser, i + 1)->keyword;
26396 : 12 : id = ridpointers[rid];
26397 : : }
26398 : : else
26399 : : break;
26400 : 465 : directive[i] = IDENTIFIER_POINTER (id);
26401 : : }
26402 : 372 : if (i == 0)
26403 : 0 : error_at (dloc, "expected directive name");
26404 : : else
26405 : : {
26406 : 372 : const struct c_omp_directive *dir
26407 : 372 : = c_omp_categorize_directive (directive[0],
26408 : : directive[1],
26409 : : directive[2]);
26410 : 372 : if (dir == NULL
26411 : 369 : || dir->kind == C_OMP_DIR_DECLARATIVE
26412 : 366 : || dir->kind == C_OMP_DIR_INFORMATIONAL
26413 : 354 : || dir->id == PRAGMA_OMP_END
26414 : 354 : || (!dir->second && directive[1])
26415 : 345 : || (!dir->third && directive[2]))
26416 : 27 : error_at (dloc, "unknown OpenMP directive name in "
26417 : : "%qs clause argument", p);
26418 : : else
26419 : : {
26420 : 345 : int id = dir - c_omp_directives;
26421 : 388 : if (bitmap_bit_p (p[0] == 'a' ? &contains_head
26422 : : : &absent_head, id))
26423 : 18 : error_at (dloc, "%<%s%s%s%s%s%> directive "
26424 : : "mentioned in both %<absent%> and "
26425 : : "%<contains%> clauses",
26426 : : directive[0],
26427 : : directive[1] ? " " : "",
26428 : : directive[1] ? directive[1] : "",
26429 : : directive[2] ? " " : "",
26430 : : directive[2] ? directive[2] : "");
26431 : 379 : else if (!bitmap_set_bit (p[0] == 'a'
26432 : : ? &absent_head
26433 : : : &contains_head, id))
26434 : 36 : error_at (dloc, "%<%s%s%s%s%s%> directive "
26435 : : "mentioned multiple times in %qs "
26436 : : "clauses",
26437 : : directive[0],
26438 : : directive[1] ? " " : "",
26439 : : directive[1] ? directive[1] : "",
26440 : : directive[2] ? " " : "",
26441 : : directive[2] ? directive[2] : "", p);
26442 : : }
26443 : 837 : for (; i; --i)
26444 : 465 : c_parser_consume_token (parser);
26445 : : }
26446 : 372 : if (c_parser_next_token_is (parser, CPP_COMMA))
26447 : 229 : c_parser_consume_token (parser);
26448 : : else
26449 : : break;
26450 : 229 : }
26451 : : while (1);
26452 : 143 : parens.skip_until_found_close (parser);
26453 : : }
26454 : 143 : }
26455 : 9 : else if (startswith (p, "ext_"))
26456 : : {
26457 : 6 : warning_at (cloc, OPT_Wopenmp, "unknown assumption clause %qs", p);
26458 : 6 : c_parser_consume_token (parser);
26459 : 6 : if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
26460 : : {
26461 : 3 : matching_parens parens;
26462 : 3 : parens.consume_open (parser);
26463 : 3 : c_parser_balanced_token_sequence (parser);
26464 : 3 : parens.require_close (parser);
26465 : : }
26466 : : }
26467 : : else
26468 : : {
26469 : 3 : c_parser_consume_token (parser);
26470 : 3 : error_at (cloc, "expected assumption clause");
26471 : 3 : break;
26472 : : }
26473 : : }
26474 : 122 : c_parser_skip_to_pragma_eol (parser);
26475 : 122 : }
26476 : :
26477 : : /* OpenMP 5.1
26478 : : #pragma omp assume clauses[optseq] new-line */
26479 : :
26480 : : static void
26481 : 40 : c_parser_omp_assume (c_parser *parser, bool *if_p)
26482 : : {
26483 : 40 : c_parser_omp_assumption_clauses (parser, true);
26484 : 40 : add_stmt (c_parser_omp_structured_block (parser, if_p));
26485 : 40 : }
26486 : :
26487 : : /* OpenMP 5.1
26488 : : #pragma omp assumes clauses[optseq] new-line */
26489 : :
26490 : : static void
26491 : 37 : c_parser_omp_assumes (c_parser *parser)
26492 : : {
26493 : 37 : c_parser_consume_pragma (parser);
26494 : 37 : c_parser_omp_assumption_clauses (parser, false);
26495 : 37 : }
26496 : :
26497 : : /* Main entry point to parsing most OpenMP pragmas. */
26498 : :
26499 : : static void
26500 : 16031 : c_parser_omp_construct (c_parser *parser, bool *if_p)
26501 : : {
26502 : 16031 : enum pragma_kind p_kind;
26503 : 16031 : location_t loc;
26504 : 16031 : tree stmt;
26505 : 16031 : char p_name[sizeof "#pragma omp teams distribute parallel for simd"];
26506 : 16031 : omp_clause_mask mask (0);
26507 : :
26508 : 16031 : loc = c_parser_peek_token (parser)->location;
26509 : 16031 : p_kind = c_parser_peek_token (parser)->pragma_kind;
26510 : 16031 : c_parser_consume_pragma (parser);
26511 : :
26512 : 16031 : switch (p_kind)
26513 : : {
26514 : 309 : case PRAGMA_OACC_ATOMIC:
26515 : 309 : c_parser_omp_atomic (loc, parser, true);
26516 : 2057 : return;
26517 : 137 : case PRAGMA_OACC_CACHE:
26518 : 137 : strcpy (p_name, "#pragma acc");
26519 : 137 : stmt = c_parser_oacc_cache (loc, parser);
26520 : 137 : break;
26521 : 465 : case PRAGMA_OACC_DATA:
26522 : 465 : stmt = c_parser_oacc_data (loc, parser, if_p);
26523 : 465 : break;
26524 : 23 : case PRAGMA_OACC_HOST_DATA:
26525 : 23 : stmt = c_parser_oacc_host_data (loc, parser, if_p);
26526 : 23 : break;
26527 : 1982 : case PRAGMA_OACC_KERNELS:
26528 : 1982 : case PRAGMA_OACC_PARALLEL:
26529 : 1982 : case PRAGMA_OACC_SERIAL:
26530 : 1982 : strcpy (p_name, "#pragma acc");
26531 : 1982 : stmt = c_parser_oacc_compute (loc, parser, p_kind, p_name, if_p);
26532 : 1982 : break;
26533 : 1525 : case PRAGMA_OACC_LOOP:
26534 : 1525 : strcpy (p_name, "#pragma acc");
26535 : 1525 : stmt = c_parser_oacc_loop (loc, parser, p_name, mask, NULL, if_p);
26536 : 1525 : break;
26537 : 80 : case PRAGMA_OACC_WAIT:
26538 : 80 : strcpy (p_name, "#pragma wait");
26539 : 80 : stmt = c_parser_oacc_wait (loc, parser, p_name);
26540 : 80 : break;
26541 : 1399 : case PRAGMA_OMP_ATOMIC:
26542 : 1399 : c_parser_omp_atomic (loc, parser, false);
26543 : 1399 : return;
26544 : 143 : case PRAGMA_OMP_CRITICAL:
26545 : 143 : stmt = c_parser_omp_critical (loc, parser, if_p);
26546 : 143 : break;
26547 : 1309 : case PRAGMA_OMP_DISTRIBUTE:
26548 : 1309 : strcpy (p_name, "#pragma omp");
26549 : 1309 : stmt = c_parser_omp_distribute (loc, parser, p_name, mask, NULL, if_p);
26550 : 1309 : break;
26551 : 1688 : case PRAGMA_OMP_FOR:
26552 : 1688 : strcpy (p_name, "#pragma omp");
26553 : 1688 : stmt = c_parser_omp_for (loc, parser, p_name, mask, NULL, if_p);
26554 : 1688 : break;
26555 : 157 : case PRAGMA_OMP_LOOP:
26556 : 157 : strcpy (p_name, "#pragma omp");
26557 : 157 : stmt = c_parser_omp_loop (loc, parser, p_name, mask, NULL, if_p);
26558 : 157 : break;
26559 : 56 : case PRAGMA_OMP_MASKED:
26560 : 56 : strcpy (p_name, "#pragma omp");
26561 : 56 : stmt = c_parser_omp_masked (loc, parser, p_name, mask, NULL, if_p);
26562 : 56 : break;
26563 : 141 : case PRAGMA_OMP_MASTER:
26564 : 141 : strcpy (p_name, "#pragma omp");
26565 : 141 : stmt = c_parser_omp_master (loc, parser, p_name, mask, NULL, if_p);
26566 : 141 : break;
26567 : 2299 : case PRAGMA_OMP_PARALLEL:
26568 : 2299 : strcpy (p_name, "#pragma omp");
26569 : 2299 : stmt = c_parser_omp_parallel (loc, parser, p_name, mask, NULL, if_p);
26570 : 2299 : break;
26571 : 61 : case PRAGMA_OMP_SCOPE:
26572 : 61 : stmt = c_parser_omp_scope (loc, parser, if_p);
26573 : 61 : break;
26574 : 105 : case PRAGMA_OMP_SECTIONS:
26575 : 105 : strcpy (p_name, "#pragma omp");
26576 : 105 : stmt = c_parser_omp_sections (loc, parser, p_name, mask, NULL);
26577 : 105 : break;
26578 : 710 : case PRAGMA_OMP_SIMD:
26579 : 710 : strcpy (p_name, "#pragma omp");
26580 : 710 : stmt = c_parser_omp_simd (loc, parser, p_name, mask, NULL, if_p);
26581 : 710 : break;
26582 : 221 : case PRAGMA_OMP_SINGLE:
26583 : 221 : stmt = c_parser_omp_single (loc, parser, if_p);
26584 : 221 : break;
26585 : 892 : case PRAGMA_OMP_TASK:
26586 : 892 : stmt = c_parser_omp_task (loc, parser, if_p);
26587 : 892 : break;
26588 : 138 : case PRAGMA_OMP_TASKGROUP:
26589 : 138 : stmt = c_parser_omp_taskgroup (loc, parser, if_p);
26590 : 138 : break;
26591 : 241 : case PRAGMA_OMP_TASKLOOP:
26592 : 241 : strcpy (p_name, "#pragma omp");
26593 : 241 : stmt = c_parser_omp_taskloop (loc, parser, p_name, mask, NULL, if_p);
26594 : 241 : break;
26595 : 1910 : case PRAGMA_OMP_TEAMS:
26596 : 1910 : strcpy (p_name, "#pragma omp");
26597 : 1910 : stmt = c_parser_omp_teams (loc, parser, p_name, mask, NULL, if_p);
26598 : 1910 : break;
26599 : 40 : case PRAGMA_OMP_ASSUME:
26600 : 40 : c_parser_omp_assume (parser, if_p);
26601 : 40 : return;
26602 : 0 : default:
26603 : 0 : gcc_unreachable ();
26604 : : }
26605 : :
26606 : 14283 : if (stmt && stmt != error_mark_node)
26607 : 14081 : gcc_assert (EXPR_LOCATION (stmt) != UNKNOWN_LOCATION);
26608 : : }
26609 : :
26610 : :
26611 : : /* OpenMP 2.5:
26612 : : # pragma omp threadprivate (variable-list) */
26613 : :
26614 : : static void
26615 : 77 : c_parser_omp_threadprivate (c_parser *parser)
26616 : : {
26617 : 77 : tree vars, t;
26618 : 77 : location_t loc;
26619 : :
26620 : 77 : c_parser_consume_pragma (parser);
26621 : 77 : loc = c_parser_peek_token (parser)->location;
26622 : 77 : vars = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
26623 : :
26624 : : /* Mark every variable in VARS to be assigned thread local storage. */
26625 : 164 : for (t = vars; t; t = TREE_CHAIN (t))
26626 : : {
26627 : 87 : tree v = TREE_PURPOSE (t);
26628 : :
26629 : : /* FIXME diagnostics: Ideally we should keep individual
26630 : : locations for all the variables in the var list to make the
26631 : : following errors more precise. Perhaps
26632 : : c_parser_omp_var_list_parens() should construct a list of
26633 : : locations to go along with the var list. */
26634 : :
26635 : : /* If V had already been marked threadprivate, it doesn't matter
26636 : : whether it had been used prior to this point. */
26637 : 87 : if (!VAR_P (v))
26638 : 1 : error_at (loc, "%qD is not a variable", v);
26639 : 86 : else if (TREE_USED (v) && !C_DECL_THREADPRIVATE_P (v))
26640 : 1 : error_at (loc, "%qE declared %<threadprivate%> after first use", v);
26641 : 85 : else if (! is_global_var (v))
26642 : 1 : error_at (loc, "automatic variable %qE cannot be %<threadprivate%>", v);
26643 : 84 : else if (TREE_TYPE (v) == error_mark_node)
26644 : : ;
26645 : 83 : else if (! COMPLETE_TYPE_P (TREE_TYPE (v)))
26646 : 1 : error_at (loc, "%<threadprivate%> %qE has incomplete type", v);
26647 : : else
26648 : : {
26649 : 82 : if (! DECL_THREAD_LOCAL_P (v))
26650 : : {
26651 : 82 : set_decl_tls_model (v, decl_default_tls_model (v));
26652 : : /* If rtl has been already set for this var, call
26653 : : make_decl_rtl once again, so that encode_section_info
26654 : : has a chance to look at the new decl flags. */
26655 : 82 : if (DECL_RTL_SET_P (v))
26656 : 0 : make_decl_rtl (v);
26657 : : }
26658 : 82 : C_DECL_THREADPRIVATE_P (v) = 1;
26659 : : }
26660 : : }
26661 : :
26662 : 77 : c_parser_skip_to_pragma_eol (parser);
26663 : 77 : }
26664 : :
26665 : : /* Parse a transaction attribute (GCC Extension).
26666 : :
26667 : : transaction-attribute:
26668 : : gnu-attributes
26669 : : attribute-specifier
26670 : : */
26671 : :
26672 : : static tree
26673 : 139 : c_parser_transaction_attributes (c_parser *parser)
26674 : : {
26675 : 139 : if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
26676 : 0 : return c_parser_gnu_attributes (parser);
26677 : :
26678 : 139 : if (!c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
26679 : : return NULL_TREE;
26680 : 20 : return c_parser_std_attribute_specifier (parser, true);
26681 : : }
26682 : :
26683 : : /* Parse a __transaction_atomic or __transaction_relaxed statement
26684 : : (GCC Extension).
26685 : :
26686 : : transaction-statement:
26687 : : __transaction_atomic transaction-attribute[opt] compound-statement
26688 : : __transaction_relaxed compound-statement
26689 : :
26690 : : Note that the only valid attribute is: "outer".
26691 : : */
26692 : :
26693 : : static tree
26694 : 137 : c_parser_transaction (c_parser *parser, enum rid keyword)
26695 : : {
26696 : 137 : unsigned int old_in = parser->in_transaction;
26697 : 137 : unsigned int this_in = 1, new_in;
26698 : 137 : location_t loc = c_parser_peek_token (parser)->location;
26699 : 137 : tree stmt, attrs;
26700 : :
26701 : 274 : gcc_assert ((keyword == RID_TRANSACTION_ATOMIC
26702 : : || keyword == RID_TRANSACTION_RELAXED)
26703 : : && c_parser_next_token_is_keyword (parser, keyword));
26704 : 137 : c_parser_consume_token (parser);
26705 : :
26706 : 137 : if (keyword == RID_TRANSACTION_RELAXED)
26707 : : this_in |= TM_STMT_ATTR_RELAXED;
26708 : : else
26709 : : {
26710 : 106 : attrs = c_parser_transaction_attributes (parser);
26711 : 106 : if (attrs)
26712 : 14 : this_in |= parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER);
26713 : : }
26714 : :
26715 : : /* Keep track if we're in the lexical scope of an outer transaction. */
26716 : 137 : new_in = this_in | (old_in & TM_STMT_ATTR_OUTER);
26717 : :
26718 : 137 : parser->in_transaction = new_in;
26719 : 137 : stmt = c_parser_compound_statement (parser);
26720 : 137 : parser->in_transaction = old_in;
26721 : :
26722 : 137 : if (flag_tm)
26723 : 135 : stmt = c_finish_transaction (loc, stmt, this_in);
26724 : : else
26725 : 2 : error_at (loc, (keyword == RID_TRANSACTION_ATOMIC ?
26726 : : "%<__transaction_atomic%> without transactional memory support enabled"
26727 : : : "%<__transaction_relaxed %> "
26728 : : "without transactional memory support enabled"));
26729 : :
26730 : 137 : return stmt;
26731 : : }
26732 : :
26733 : : /* Parse a __transaction_atomic or __transaction_relaxed expression
26734 : : (GCC Extension).
26735 : :
26736 : : transaction-expression:
26737 : : __transaction_atomic ( expression )
26738 : : __transaction_relaxed ( expression )
26739 : : */
26740 : :
26741 : : static struct c_expr
26742 : 7 : c_parser_transaction_expression (c_parser *parser, enum rid keyword)
26743 : : {
26744 : 7 : struct c_expr ret;
26745 : 7 : unsigned int old_in = parser->in_transaction;
26746 : 7 : unsigned int this_in = 1;
26747 : 7 : location_t loc = c_parser_peek_token (parser)->location;
26748 : 7 : tree attrs;
26749 : :
26750 : 14 : gcc_assert ((keyword == RID_TRANSACTION_ATOMIC
26751 : : || keyword == RID_TRANSACTION_RELAXED)
26752 : : && c_parser_next_token_is_keyword (parser, keyword));
26753 : 7 : c_parser_consume_token (parser);
26754 : :
26755 : 7 : if (keyword == RID_TRANSACTION_RELAXED)
26756 : : this_in |= TM_STMT_ATTR_RELAXED;
26757 : : else
26758 : : {
26759 : 5 : attrs = c_parser_transaction_attributes (parser);
26760 : 5 : if (attrs)
26761 : 0 : this_in |= parse_tm_stmt_attr (attrs, 0);
26762 : : }
26763 : :
26764 : 7 : parser->in_transaction = this_in;
26765 : 7 : matching_parens parens;
26766 : 7 : if (parens.require_open (parser))
26767 : : {
26768 : 7 : tree expr = c_parser_expression (parser).value;
26769 : 7 : ret.original_type = TREE_TYPE (expr);
26770 : 7 : ret.value = build1 (TRANSACTION_EXPR, ret.original_type, expr);
26771 : 7 : if (this_in & TM_STMT_ATTR_RELAXED)
26772 : 2 : TRANSACTION_EXPR_RELAXED (ret.value) = 1;
26773 : 7 : SET_EXPR_LOCATION (ret.value, loc);
26774 : 7 : ret.original_code = TRANSACTION_EXPR;
26775 : 7 : ret.m_decimal = 0;
26776 : 7 : if (!parens.require_close (parser))
26777 : : {
26778 : 0 : c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
26779 : 0 : goto error;
26780 : : }
26781 : : }
26782 : : else
26783 : : {
26784 : 0 : error:
26785 : 0 : ret.set_error ();
26786 : 0 : ret.original_code = ERROR_MARK;
26787 : 0 : ret.original_type = NULL;
26788 : : }
26789 : 7 : parser->in_transaction = old_in;
26790 : :
26791 : 7 : if (!flag_tm)
26792 : 6 : error_at (loc, (keyword == RID_TRANSACTION_ATOMIC ?
26793 : : "%<__transaction_atomic%> without transactional memory support enabled"
26794 : : : "%<__transaction_relaxed %> "
26795 : : "without transactional memory support enabled"));
26796 : :
26797 : 7 : set_c_expr_source_range (&ret, loc, loc);
26798 : :
26799 : 7 : return ret;
26800 : : }
26801 : :
26802 : : /* Parse a __transaction_cancel statement (GCC Extension).
26803 : :
26804 : : transaction-cancel-statement:
26805 : : __transaction_cancel transaction-attribute[opt] ;
26806 : :
26807 : : Note that the only valid attribute is "outer".
26808 : : */
26809 : :
26810 : : static tree
26811 : 28 : c_parser_transaction_cancel (c_parser *parser)
26812 : : {
26813 : 28 : location_t loc = c_parser_peek_token (parser)->location;
26814 : 28 : tree attrs;
26815 : 28 : bool is_outer = false;
26816 : :
26817 : 28 : gcc_assert (c_parser_next_token_is_keyword (parser, RID_TRANSACTION_CANCEL));
26818 : 28 : c_parser_consume_token (parser);
26819 : :
26820 : 28 : attrs = c_parser_transaction_attributes (parser);
26821 : 28 : if (attrs)
26822 : 5 : is_outer = (parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER) != 0);
26823 : :
26824 : 28 : if (!flag_tm)
26825 : : {
26826 : 2 : error_at (loc, "%<__transaction_cancel%> without "
26827 : : "transactional memory support enabled");
26828 : 2 : goto ret_error;
26829 : : }
26830 : 26 : else if (parser->in_transaction & TM_STMT_ATTR_RELAXED)
26831 : : {
26832 : 0 : error_at (loc, "%<__transaction_cancel%> within a "
26833 : : "%<__transaction_relaxed%>");
26834 : 0 : goto ret_error;
26835 : : }
26836 : 26 : else if (is_outer)
26837 : : {
26838 : 5 : if ((parser->in_transaction & TM_STMT_ATTR_OUTER) == 0
26839 : 5 : && !is_tm_may_cancel_outer (current_function_decl))
26840 : : {
26841 : 0 : error_at (loc, "outer %<__transaction_cancel%> not "
26842 : : "within outer %<__transaction_atomic%> or "
26843 : : "a %<transaction_may_cancel_outer%> function");
26844 : 0 : goto ret_error;
26845 : : }
26846 : : }
26847 : 21 : else if (parser->in_transaction == 0)
26848 : : {
26849 : 0 : error_at (loc, "%<__transaction_cancel%> not within "
26850 : : "%<__transaction_atomic%>");
26851 : 0 : goto ret_error;
26852 : : }
26853 : :
26854 : 26 : return add_stmt (build_tm_abort_call (loc, is_outer));
26855 : :
26856 : 2 : ret_error:
26857 : 2 : return build1 (NOP_EXPR, void_type_node, error_mark_node);
26858 : : }
26859 : :
26860 : : /* Parse a single source file. */
26861 : :
26862 : : void
26863 : 100203 : c_parse_file (void)
26864 : : {
26865 : : /* Use local storage to begin. If the first token is a pragma, parse it.
26866 : : If it is #pragma GCC pch_preprocess, then this will load a PCH file
26867 : : which will cause garbage collection. */
26868 : 100203 : c_parser tparser;
26869 : :
26870 : 100203 : memset (&tparser, 0, sizeof tparser);
26871 : 100203 : tparser.translate_strings_p = true;
26872 : 100203 : tparser.tokens = &tparser.tokens_buf[0];
26873 : 100203 : the_parser = &tparser;
26874 : :
26875 : 100203 : if (c_parser_peek_token (&tparser)->pragma_kind == PRAGMA_GCC_PCH_PREPROCESS)
26876 : 12 : c_parser_pragma_pch_preprocess (&tparser);
26877 : : else
26878 : 100133 : c_common_no_more_pch ();
26879 : :
26880 : 100145 : the_parser = ggc_alloc<c_parser> ();
26881 : 100145 : *the_parser = tparser;
26882 : 100145 : if (tparser.tokens == &tparser.tokens_buf[0])
26883 : 100145 : the_parser->tokens = &the_parser->tokens_buf[0];
26884 : :
26885 : : /* Initialize EH, if we've been told to do so. */
26886 : 100145 : if (flag_exceptions)
26887 : 494 : using_eh_for_cleanups ();
26888 : :
26889 : 100145 : c_parser_translation_unit (the_parser);
26890 : 100056 : the_parser = NULL;
26891 : 100056 : }
26892 : :
26893 : : void
26894 : 4557 : c_init_preprocess (void)
26895 : : {
26896 : : /* Create a parser for use by pragma_lex during preprocessing. */
26897 : 4557 : the_parser = ggc_alloc<c_parser> ();
26898 : 4557 : memset (the_parser, 0, sizeof (c_parser));
26899 : 4557 : the_parser->tokens = &the_parser->tokens_buf[0];
26900 : 4557 : }
26901 : :
26902 : : /* Parse the body of a function declaration marked with "__RTL".
26903 : :
26904 : : The RTL parser works on the level of characters read from a
26905 : : FILE *, whereas c_parser works at the level of tokens.
26906 : : Square this circle by consuming all of the tokens up to and
26907 : : including the closing brace, recording the start/end of the RTL
26908 : : fragment, and reopening the file and re-reading the relevant
26909 : : lines within the RTL parser.
26910 : :
26911 : : This requires the opening and closing braces of the C function
26912 : : to be on separate lines from the RTL they wrap.
26913 : :
26914 : : Take ownership of START_WITH_PASS, if non-NULL. */
26915 : :
26916 : : location_t
26917 : 18 : c_parser_parse_rtl_body (c_parser *parser, char *start_with_pass)
26918 : : {
26919 : 18 : if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
26920 : : {
26921 : 0 : free (start_with_pass);
26922 : 0 : return c_parser_peek_token (parser)->location;
26923 : : }
26924 : :
26925 : 18 : location_t start_loc = c_parser_peek_token (parser)->location;
26926 : :
26927 : : /* Consume all tokens, up to the closing brace, handling
26928 : : matching pairs of braces in the rtl dump. */
26929 : 18 : int num_open_braces = 1;
26930 : 22392 : while (1)
26931 : : {
26932 : 11205 : switch (c_parser_peek_token (parser)->type)
26933 : : {
26934 : 1 : case CPP_OPEN_BRACE:
26935 : 1 : num_open_braces++;
26936 : 1 : break;
26937 : 18 : case CPP_CLOSE_BRACE:
26938 : 18 : if (--num_open_braces == 0)
26939 : 17 : goto found_closing_brace;
26940 : : break;
26941 : 1 : case CPP_EOF:
26942 : 1 : error_at (start_loc, "no closing brace");
26943 : 1 : free (start_with_pass);
26944 : 1 : return c_parser_peek_token (parser)->location;
26945 : : default:
26946 : : break;
26947 : : }
26948 : 11187 : c_parser_consume_token (parser);
26949 : : }
26950 : :
26951 : 17 : found_closing_brace:
26952 : : /* At the closing brace; record its location. */
26953 : 17 : location_t end_loc = c_parser_peek_token (parser)->location;
26954 : :
26955 : : /* Consume the closing brace. */
26956 : 17 : c_parser_consume_token (parser);
26957 : :
26958 : : /* Invoke the RTL parser. */
26959 : 17 : if (!read_rtl_function_body_from_file_range (start_loc, end_loc))
26960 : : {
26961 : 0 : free (start_with_pass);
26962 : 0 : return end_loc;
26963 : : }
26964 : :
26965 : : /* Run the backend on the cfun created above, transferring ownership of
26966 : : START_WITH_PASS. */
26967 : 16 : run_rtl_passes (start_with_pass);
26968 : 16 : return end_loc;
26969 : : }
26970 : :
26971 : : #include "gt-c-c-parser.h"
|