Line data Source code
1 : /* Parser for GIMPLE.
2 : Copyright (C) 2016-2026 Free Software Foundation, Inc.
3 :
4 : This file is part of GCC.
5 :
6 : GCC is free software; you can redistribute it and/or modify it under
7 : the terms of the GNU General Public License as published by the Free
8 : Software Foundation; either version 3, or (at your option) any later
9 : version.
10 :
11 : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 : WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 : for more details.
15 :
16 : You should have received a copy of the GNU General Public License
17 : along with GCC; see the file COPYING3. If not see
18 : <http://www.gnu.org/licenses/>. */
19 :
20 : #include "config.h"
21 : #include "system.h"
22 : #include "coretypes.h"
23 : #include "target.h"
24 : #include "function.h"
25 : #include "c-tree.h"
26 : #include "timevar.h"
27 : #include "stringpool.h"
28 : #include "cgraph.h"
29 : #include "attribs.h"
30 : #include "stor-layout.h"
31 : #include "varasm.h"
32 : #include "trans-mem.h"
33 : #include "c-family/c-pragma.h"
34 : #include "c-lang.h"
35 : #include "c-family/c-objc.h"
36 : #include "plugin.h"
37 : #include "builtins.h"
38 : #include "gomp-constants.h"
39 : #include "c-family/c-indentation.h"
40 : #include "gimple-expr.h"
41 : #include "context.h"
42 : #include "gcc-rich-location.h"
43 : #include "c-parser.h"
44 : #include "tree-vrp.h"
45 : #include "tree-pass.h"
46 : #include "tree-pretty-print.h"
47 : #include "tree.h"
48 : #include "basic-block.h"
49 : #include "gimple.h"
50 : #include "gimple-pretty-print.h"
51 : #include "tree-ssa.h"
52 : #include "pass_manager.h"
53 : #include "tree-ssanames.h"
54 : #include "gimple-ssa.h"
55 : #include "tree-dfa.h"
56 : #include "internal-fn.h"
57 : #include "cfg.h"
58 : #include "cfghooks.h"
59 : #include "bitmap.h"
60 : #include "cfganal.h"
61 : #include "tree-cfg.h"
62 : #include "gimple-iterator.h"
63 : #include "cfgloop.h"
64 : #include "tree-phinodes.h"
65 : #include "tree-into-ssa.h"
66 :
67 :
68 : /* GIMPLE parser state. */
69 :
70 1014 : class gimple_parser
71 : {
72 : public:
73 507 : gimple_parser (c_parser *p) : parser (p), edges(), current_bb(NULL) {}
74 : /* c_parser is not visible here, use composition and fake inheritance
75 : via a conversion operator. */
76 245997 : operator c_parser *() { return parser; }
77 : c_parser *parser;
78 :
79 : /* CFG build state. */
80 1448 : class gimple_parser_edge
81 : {
82 : public:
83 : int src;
84 : int dest;
85 : int flags;
86 : profile_probability probability;
87 : };
88 : auto_vec<gimple_parser_edge> edges;
89 : basic_block current_bb;
90 :
91 : void push_edge (int, int, int, profile_probability);
92 : };
93 :
94 : void
95 1448 : gimple_parser::push_edge (int src, int dest, int flags,
96 : profile_probability prob)
97 : {
98 1448 : gimple_parser_edge e;
99 1448 : e.src = src;
100 1448 : e.dest = dest;
101 1448 : e.flags = flags;
102 1448 : e.probability = prob;
103 1448 : edges.safe_push (e);
104 1448 : }
105 :
106 :
107 : /* Gimple parsing functions. */
108 : static bool c_parser_gimple_compound_statement (gimple_parser &, gimple_seq *);
109 : static void c_parser_gimple_label (gimple_parser &, gimple_seq *);
110 : static void c_parser_gimple_statement (gimple_parser &, gimple_seq *);
111 : static struct c_expr c_parser_gimple_binary_expression (gimple_parser &, tree);
112 : static struct c_expr c_parser_gimple_unary_expression (gimple_parser &);
113 : static struct c_expr c_parser_gimple_postfix_expression (gimple_parser &);
114 : static struct c_expr c_parser_gimple_postfix_expression_after_primary
115 : (gimple_parser &, location_t, struct c_expr);
116 : static void c_parser_gimple_declaration (gimple_parser &);
117 : static void c_parser_gimple_goto_stmt (gimple_parser &, location_t,
118 : tree, gimple_seq *);
119 : static void c_parser_gimple_try_stmt (gimple_parser &, gimple_seq *);
120 : static void c_parser_gimple_if_stmt (gimple_parser &, gimple_seq *);
121 : static void c_parser_gimple_switch_stmt (gimple_parser &, gimple_seq *);
122 : static void c_parser_gimple_return_stmt (gimple_parser &, gimple_seq *);
123 : static void c_finish_gimple_return (location_t, tree);
124 : static tree c_parser_gimple_paren_condition (gimple_parser &);
125 : static void c_parser_gimple_expr_list (gimple_parser &, vec<tree> *);
126 :
127 :
128 : /* Much like parser_build_unary_op, but avoid applying default conversions. */
129 :
130 : static c_expr
131 57 : gimple_parser_build_unary_op (location_t loc,
132 : enum tree_code code, struct c_expr arg)
133 : {
134 57 : struct c_expr result;
135 :
136 57 : result.original_code = code;
137 57 : result.original_type = NULL;
138 57 : result.m_decimal = 0;
139 :
140 57 : if (reject_gcc_builtin (arg.value))
141 : {
142 0 : result.value = error_mark_node;
143 : }
144 : else
145 : {
146 57 : result.value = build_unary_op (loc, code, arg.value, true);
147 :
148 57 : if (TREE_OVERFLOW_P (result.value) && !TREE_OVERFLOW_P (arg.value))
149 0 : overflow_warning (loc, result.value, arg.value);
150 : }
151 :
152 : /* We are typically called when parsing a prefix token at LOC acting on
153 : ARG. Reflect this by updating the source range of the result to
154 : start at LOC and end at the end of ARG. */
155 57 : set_c_expr_source_range (&result,
156 : loc, arg.get_finish ());
157 :
158 57 : return result;
159 : }
160 :
161 : /* See if VAL is an identifier matching __BB<num> and return <num>
162 : in *INDEX. */
163 :
164 : static bool
165 1587 : c_parser_gimple_parse_bb_spec (tree val, int *index)
166 : {
167 1587 : if (!startswith (IDENTIFIER_POINTER (val), "__BB"))
168 : return false;
169 :
170 1587 : const char *bb = IDENTIFIER_POINTER (val) + 4;
171 1587 : if (! ISDIGIT (*bb))
172 : return false;
173 :
174 1587 : char *pend;
175 1587 : errno = 0;
176 1587 : const unsigned long number = strtoul (bb, &pend, 10);
177 1587 : if (errno == ERANGE
178 1587 : || *pend != '\0'
179 1587 : || number > INT_MAX)
180 : return false;
181 :
182 1587 : *index = number;
183 1587 : return true;
184 : }
185 :
186 : /* See if VAL is an identifier matching __BB<num> and return <num>
187 : in *INDEX. Return true if so and parse also FREQUENCY of
188 : the edge. */
189 :
190 :
191 : static bool
192 946 : c_parser_gimple_parse_bb_spec_edge_probability (tree val,
193 : gimple_parser &parser,
194 : int *index,
195 : profile_probability
196 : *probability)
197 : {
198 946 : bool return_p = c_parser_gimple_parse_bb_spec (val, index);
199 946 : if (return_p)
200 : {
201 946 : *probability = profile_probability::uninitialized ();
202 : /* Parse frequency if provided. */
203 946 : if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
204 : {
205 384 : tree f;
206 384 : c_parser_consume_token (parser);
207 384 : if (!c_parser_next_token_is (parser, CPP_NAME))
208 : {
209 0 : c_parser_error (parser, "expected frequency quality");
210 0 : return false;
211 : }
212 :
213 384 : profile_quality quality;
214 384 : const char *v
215 384 : = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
216 384 : if (!parse_profile_quality (v, &quality))
217 : {
218 0 : c_parser_error (parser, "unknown profile quality");
219 0 : return false;
220 : }
221 :
222 384 : c_parser_consume_token (parser);
223 384 : if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
224 : return false;
225 :
226 384 : if (!c_parser_next_token_is (parser, CPP_NUMBER)
227 384 : || (TREE_CODE (f = c_parser_peek_token (parser)->value)
228 : != INTEGER_CST))
229 : {
230 0 : c_parser_error (parser, "expected frequency value");
231 0 : return false;
232 : }
233 :
234 384 : unsigned int value = TREE_INT_CST_LOW (f);
235 384 : *probability = profile_probability (value, quality);
236 :
237 384 : c_parser_consume_token (parser);
238 384 : if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
239 : return false;
240 :
241 384 : if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
242 : return false;
243 : }
244 :
245 946 : return true;
246 : }
247 :
248 : return false;
249 :
250 : }
251 :
252 : /* Parse the body of a function declaration marked with "__GIMPLE". */
253 :
254 : void
255 507 : c_parser_parse_gimple_body (c_parser *cparser, char *gimple_pass,
256 : enum c_declspec_il cdil,
257 : profile_count entry_bb_count)
258 : {
259 507 : gimple_parser parser (cparser);
260 507 : gimple_seq seq = NULL;
261 507 : gimple_seq body = NULL;
262 507 : tree stmt = push_stmt_list ();
263 507 : push_scope ();
264 507 : location_t loc1 = c_parser_peek_token (parser)->location;
265 :
266 507 : cfun->pass_startwith = gimple_pass;
267 507 : init_tree_ssa (cfun);
268 :
269 507 : if (cdil == cdil_gimple)
270 : /* While we have SSA names in the IL we do not have a CFG built yet
271 : and PHIs are represented using a PHI internal function. We do
272 : have lowered control flow and exception handling (well, we do not
273 : have parser support for EH yet). But as we still have BINDs
274 : we have to go through lowering again. */
275 255 : cfun->curr_properties = PROP_gimple_any;
276 : else
277 : {
278 : /* We have at least cdil_gimple_cfg. */
279 252 : gimple_register_cfg_hooks ();
280 252 : init_empty_tree_cfg ();
281 252 : parser.current_bb = ENTRY_BLOCK_PTR_FOR_FN (cfun);
282 : /* Initialize the bare loop structure - we are going to only
283 : mark headers and leave the rest to fixup. */
284 252 : set_loops_for_fn (cfun, ggc_cleared_alloc<struct loops> ());
285 252 : init_loops_structure (cfun, loops_for_fn (cfun), 1);
286 252 : loops_state_set (cfun, LOOPS_NEED_FIXUP|LOOPS_MAY_HAVE_MULTIPLE_LATCHES);
287 252 : cfun->curr_properties
288 252 : |= PROP_gimple_lcf | PROP_gimple_leh | PROP_cfg | PROP_loops;
289 252 : if (cdil == cdil_gimple_ssa)
290 : {
291 252 : init_ssa_operands (cfun);
292 252 : cfun->curr_properties |= PROP_ssa;
293 : }
294 : }
295 :
296 507 : if (! c_parser_gimple_compound_statement (parser, &seq)
297 507 : && cdil == cdil_gimple)
298 : {
299 38 : gimple *ret = gimple_build_return (NULL);
300 38 : gimple_seq_add_stmt_without_update (&seq, ret);
301 : }
302 :
303 507 : tree block = pop_scope ();
304 507 : stmt = pop_stmt_list (stmt);
305 507 : stmt = c_build_bind_expr (loc1, block, stmt);
306 :
307 507 : block = DECL_INITIAL (current_function_decl);
308 507 : BLOCK_SUBBLOCKS (block) = NULL_TREE;
309 507 : BLOCK_CHAIN (block) = NULL_TREE;
310 507 : TREE_ASM_WRITTEN (block) = 1;
311 :
312 507 : if (cdil == cdil_gimple)
313 : {
314 510 : gbind *bind_stmt = gimple_build_bind (BIND_EXPR_VARS (stmt), NULL,
315 255 : BIND_EXPR_BLOCK (stmt));
316 255 : gimple_bind_set_body (bind_stmt, seq);
317 255 : gimple_seq_add_stmt_without_update (&body, bind_stmt);
318 255 : gimple_set_body (current_function_decl, body);
319 : }
320 : else
321 : {
322 : /* Control-flow and binds are lowered, record local decls. */
323 621 : for (tree var = BIND_EXPR_VARS (stmt); var; var = DECL_CHAIN (var))
324 369 : if (VAR_P (var)
325 369 : && !DECL_EXTERNAL (var))
326 : {
327 357 : add_local_decl (cfun, var);
328 : /* When the middle-end re-gimplifies any expression we might
329 : run into the assertion that we've seen the decl in a BIND. */
330 357 : if (!TREE_STATIC (var))
331 357 : DECL_SEEN_IN_BIND_EXPR_P (var) = 1;
332 : }
333 : /* We have a CFG. Build the edges. */
334 1700 : for (unsigned i = 0; i < parser.edges.length (); ++i)
335 : {
336 2896 : edge e = make_edge (BASIC_BLOCK_FOR_FN (cfun, parser.edges[i].src),
337 1448 : BASIC_BLOCK_FOR_FN (cfun, parser.edges[i].dest),
338 1448 : parser.edges[i].flags);
339 1448 : e->probability = parser.edges[i].probability;
340 : }
341 : /* Add edges for case labels. */
342 252 : basic_block bb;
343 1183 : FOR_EACH_BB_FN (bb, cfun)
344 931 : if (EDGE_COUNT (bb->succs) == 0)
345 : {
346 957 : if (gswitch *sw = safe_dyn_cast <gswitch *> (*gsi_last_bb (bb)))
347 17 : for (unsigned i = 0; i < gimple_switch_num_labels (sw); ++i)
348 : {
349 13 : basic_block label_bb = gimple_switch_label_bb (cfun, sw, i);
350 13 : make_edge (bb, label_bb, 0);
351 : }
352 : }
353 : /* Need those for loop fixup. */
354 252 : calculate_dominance_info (CDI_DOMINATORS);
355 : /* With SSA lower PHIs parsed as internal function calls and
356 : update stmts. */
357 252 : if (cdil == cdil_gimple_ssa)
358 : {
359 : /* Create PHI nodes, they are parsed into __PHI internal calls
360 : and update SSA operands. */
361 1183 : FOR_EACH_BB_FN (bb, cfun)
362 : {
363 931 : gimple_stmt_iterator gsi;
364 2196 : for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
365 : {
366 1028 : gimple *stmt = gsi_stmt (gsi);
367 1028 : if (!gimple_call_internal_p (stmt, IFN_PHI))
368 : break;
369 :
370 334 : gphi *phi = create_phi_node (gimple_call_lhs (stmt), bb);
371 975 : for (unsigned i = 0; i < gimple_call_num_args (stmt); i += 2)
372 : {
373 641 : int srcidx = TREE_INT_CST_LOW (gimple_call_arg (stmt, i));
374 641 : edge e = find_edge (BASIC_BLOCK_FOR_FN (cfun, srcidx), bb);
375 641 : if (!e)
376 0 : c_parser_error (parser, "edge not found");
377 : else
378 641 : add_phi_arg (phi, gimple_call_arg (stmt, i + 1), e,
379 : UNKNOWN_LOCATION);
380 : }
381 334 : gsi_remove (&gsi, true);
382 : }
383 3369 : for (; !gsi_end_p (gsi); gsi_next (&gsi))
384 2438 : update_stmt (gsi_stmt (gsi));
385 : }
386 : /* Fill SSA name gaps, putting them on the freelist and diagnose
387 : SSA names without definition. */
388 7016 : for (unsigned i = 1; i < num_ssa_names; ++i)
389 6764 : if (!ssa_name (i))
390 : {
391 4602 : tree name = make_ssa_name_fn (cfun, integer_type_node, NULL, i);
392 4602 : release_ssa_name_fn (cfun, name);
393 : }
394 2162 : else if (!SSA_NAME_DEF_STMT (ssa_name (i)))
395 1 : error ("SSA name %qE with version %d has no definition",
396 : ssa_name (i), i);
397 : /* No explicit virtual operands (yet). */
398 252 : bitmap_obstack_initialize (NULL);
399 252 : update_ssa (TODO_update_ssa_only_virtuals);
400 252 : bitmap_obstack_release (NULL);
401 : /* ??? By flushing the freelist after virtual operand SSA rewrite
402 : we keep the gaps available for re-use like needed for the
403 : PR89595 testcase but then usually virtual operands would have
404 : taken most of them. The fix is obviously to make virtual
405 : operands explicit in the SSA IL. */
406 252 : flush_ssaname_freelist ();
407 : }
408 252 : fix_loop_structure (NULL);
409 : }
410 :
411 507 : if (cfun->curr_properties & PROP_cfg)
412 : {
413 252 : ENTRY_BLOCK_PTR_FOR_FN (cfun)->count = entry_bb_count;
414 252 : gcov_type t = param_gimple_fe_computed_hot_bb_threshold;
415 252 : set_hot_bb_threshold (t);
416 252 : update_max_bb_count ();
417 252 : cgraph_node::get_create (cfun->decl);
418 252 : cgraph_edge::rebuild_edges ();
419 : }
420 :
421 : /* Perform IL validation and if any error is found abort compilation
422 : of this function by zapping its body. */
423 507 : if ((cfun->curr_properties & PROP_cfg)
424 507 : && verify_gimple_in_cfg (cfun, false, false))
425 0 : init_empty_tree_cfg ();
426 507 : else if (!(cfun->curr_properties & PROP_cfg)
427 507 : && verify_gimple_in_seq (gimple_body (current_function_decl), false))
428 1 : gimple_set_body (current_function_decl, NULL);
429 :
430 507 : dump_function (TDI_gimple, current_function_decl);
431 507 : }
432 :
433 : /* Parse a compound statement in gimple function body.
434 :
435 : gimple-statement:
436 : gimple-statement
437 : gimple-declaration-statement
438 : gimple-if-statement
439 : gimple-switch-statement
440 : gimple-labeled-statement
441 : gimple-expression-statement
442 : gimple-goto-statement
443 : gimple-phi-statement
444 : gimple-return-statement
445 : */
446 :
447 : static bool
448 517 : c_parser_gimple_compound_statement (gimple_parser &parser, gimple_seq *seq)
449 : {
450 517 : bool return_p = false;
451 :
452 517 : if (! c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
453 : return false;
454 :
455 : /* A compund statement starts with optional declarations. */
456 2639 : while (c_parser_next_tokens_start_declaration (parser))
457 : {
458 2122 : c_parser_gimple_declaration (parser);
459 2122 : if (! c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
460 : return false;
461 : }
462 :
463 5692 : while (c_parser_next_token_is_not (parser, CPP_CLOSE_BRACE))
464 : {
465 5179 : if (c_parser_error (parser))
466 : {
467 4 : c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
468 4 : return return_p;
469 : }
470 5175 : else if (c_parser_next_token_is (parser, CPP_EOF))
471 : {
472 0 : c_parser_error (parser, "expected declaration or statement");
473 0 : return return_p;
474 : }
475 :
476 5175 : switch (c_parser_peek_token (parser)->type)
477 : {
478 1165 : case CPP_KEYWORD:
479 1165 : switch (c_parser_peek_token (parser)->keyword)
480 : {
481 0 : case RID_AT_TRY:
482 0 : c_parser_gimple_try_stmt (parser, seq);
483 0 : break;
484 299 : case RID_IF:
485 299 : c_parser_gimple_if_stmt (parser, seq);
486 299 : break;
487 5 : case RID_SWITCH:
488 5 : c_parser_gimple_switch_stmt (parser, seq);
489 5 : break;
490 394 : case RID_GOTO:
491 394 : {
492 394 : location_t loc = c_parser_peek_token (parser)->location;
493 394 : c_parser_consume_token (parser);
494 394 : if (c_parser_next_token_is (parser, CPP_NAME))
495 : {
496 394 : tree label = c_parser_peek_token (parser)->value;
497 394 : c_parser_consume_token (parser);
498 394 : c_parser_gimple_goto_stmt (parser, loc, label, seq);
499 394 : if (! c_parser_require (parser, CPP_SEMICOLON,
500 : "expected %<;%>"))
501 : return return_p;
502 : }
503 : }
504 : break;
505 467 : case RID_RETURN:
506 467 : return_p = true;
507 467 : c_parser_gimple_return_stmt (parser, seq);
508 467 : if (! c_parser_require (parser, CPP_SEMICOLON,
509 : "expected %<;%>"))
510 : return return_p;
511 467 : if (cfun->curr_properties & PROP_cfg)
512 250 : parser.push_edge (parser.current_bb->index, EXIT_BLOCK, 0,
513 : profile_probability::uninitialized ());
514 : break;
515 0 : default:
516 0 : goto expr_stmt;
517 : }
518 : break;
519 4000 : case CPP_NAME:
520 4000 : if (c_parser_peek_2nd_token (parser)->type == CPP_COLON)
521 : {
522 71 : c_parser_gimple_label (parser, seq);
523 71 : break;
524 : }
525 3929 : if (c_parser_next_token_is (parser, CPP_NAME)
526 3929 : && c_parser_peek_token (parser)->id_kind == C_ID_ID
527 7858 : && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
528 : "try") == 0)
529 : {
530 4 : c_parser_gimple_try_stmt (parser, seq);
531 4 : break;
532 : }
533 : /* Basic block specification.
534 : __BB (index, ...) */
535 3925 : if ((cfun->curr_properties & PROP_cfg)
536 3925 : && !strcmp (IDENTIFIER_POINTER
537 : (c_parser_peek_token (parser)->value), "__BB"))
538 : {
539 931 : c_parser_consume_token (parser);
540 931 : if (! c_parser_require (parser, CPP_OPEN_PAREN,
541 : "expected %<(%>"))
542 517 : return return_p;
543 931 : if (c_parser_next_token_is_not (parser, CPP_NUMBER))
544 : {
545 0 : c_parser_error (parser, "expected block index");
546 0 : return return_p;
547 : }
548 931 : tree tnum = c_parser_peek_token (parser)->value;
549 931 : if (TREE_CODE (tnum) != INTEGER_CST)
550 : {
551 0 : c_parser_error (parser, "expected block index");
552 0 : return return_p;
553 : }
554 931 : int index = TREE_INT_CST_LOW (tnum);
555 931 : if (index < NUM_FIXED_BLOCKS
556 931 : || (index < last_basic_block_for_fn (cfun)
557 209 : && BASIC_BLOCK_FOR_FN (cfun, index) != NULL))
558 : {
559 0 : c_parser_error (parser, "invalid block index");
560 0 : return return_p;
561 : }
562 931 : int is_loop_header_of = -1;
563 931 : profile_count bb_count = profile_count::uninitialized ();
564 931 : c_parser_consume_token (parser);
565 2327 : while (c_parser_next_token_is (parser, CPP_COMMA))
566 : {
567 465 : c_parser_consume_token (parser);
568 465 : if (! c_parser_next_token_is (parser, CPP_NAME))
569 : {
570 0 : c_parser_error (parser, "expected block specifier");
571 0 : return return_p;
572 : }
573 : /* loop_header (NUM) */
574 465 : if (!strcmp (IDENTIFIER_POINTER
575 : (c_parser_peek_token (parser)->value),
576 : "loop_header"))
577 : {
578 94 : c_parser_consume_token (parser);
579 94 : if (! c_parser_require (parser, CPP_OPEN_PAREN,
580 : "expected %<(%>"))
581 : return return_p;
582 94 : tree loop_num;
583 94 : if (! c_parser_next_token_is (parser, CPP_NUMBER)
584 94 : || TREE_CODE (loop_num
585 : = c_parser_peek_token (parser)->value)
586 : != INTEGER_CST)
587 : {
588 0 : c_parser_error (parser, "expected loop number");
589 0 : return return_p;
590 : }
591 94 : c_parser_consume_token (parser);
592 94 : is_loop_header_of = TREE_INT_CST_LOW (loop_num);
593 94 : if (! c_parser_require (parser, CPP_CLOSE_PAREN,
594 : "expected %<)%>"))
595 : return return_p;
596 : }
597 : /* Parse profile: quality(value) */
598 : else
599 : {
600 371 : tree q;
601 371 : profile_quality quality;
602 371 : tree v = c_parser_peek_token (parser)->value;
603 371 : if (!parse_profile_quality (IDENTIFIER_POINTER (v),
604 : &quality))
605 : {
606 0 : c_parser_error (parser, "unknown block specifier");
607 0 : return false;
608 : }
609 :
610 371 : c_parser_consume_token (parser);
611 371 : if (!c_parser_require (parser, CPP_OPEN_PAREN,
612 : "expected %<(%>"))
613 : return false;
614 :
615 371 : if (!c_parser_next_token_is (parser, CPP_NUMBER)
616 371 : || (TREE_CODE (q = c_parser_peek_token (parser)->value)
617 : != INTEGER_CST))
618 : {
619 0 : c_parser_error (parser, "expected count value");
620 0 : return false;
621 : }
622 :
623 371 : bb_count
624 371 : = profile_count::from_gcov_type (TREE_INT_CST_LOW (q),
625 : quality);
626 371 : c_parser_consume_token (parser);
627 371 : if (! c_parser_require (parser, CPP_CLOSE_PAREN,
628 : "expected %<)%>"))
629 : return return_p;
630 : }
631 : }
632 931 : if (! c_parser_require (parser, CPP_CLOSE_PAREN,
633 : "expected %<)%>")
634 931 : || ! c_parser_require (parser, CPP_COLON,
635 : "expected %<:%>"))
636 0 : return return_p;
637 :
638 : /* Put stmts parsed in the current block. */
639 931 : if (!gimple_seq_empty_p (*seq))
640 : {
641 451 : if (!parser.current_bb)
642 0 : c_parser_error (parser, "stmts without block");
643 : else
644 : {
645 451 : gimple_stmt_iterator gsi
646 451 : = gsi_start_bb (parser.current_bb);
647 451 : gsi_insert_seq_after_without_update (&gsi, *seq,
648 : GSI_CONTINUE_LINKING);
649 : }
650 451 : *seq = NULL;
651 : }
652 :
653 : /* Build an empty block with specified index, linking them
654 : in source order. */
655 931 : basic_block bb = alloc_block ();
656 931 : bb->index = index;
657 931 : link_block (bb, (parser.current_bb ? parser.current_bb
658 0 : : ENTRY_BLOCK_PTR_FOR_FN (cfun)));
659 931 : if (basic_block_info_for_fn (cfun)->length () <= (size_t)index)
660 1 : vec_safe_grow_cleared (basic_block_info_for_fn (cfun),
661 1 : index + 1, true);
662 931 : SET_BASIC_BLOCK_FOR_FN (cfun, index, bb);
663 931 : if (last_basic_block_for_fn (cfun) <= index)
664 722 : last_basic_block_for_fn (cfun) = index + 1;
665 931 : n_basic_blocks_for_fn (cfun)++;
666 931 : if (parser.current_bb->index == ENTRY_BLOCK)
667 252 : parser.push_edge (ENTRY_BLOCK, bb->index, EDGE_FALLTHRU,
668 : profile_probability::always ());
669 :
670 : /* We leave the proper setting to fixup. */
671 931 : class loop *loop_father = loops_for_fn (cfun)->tree_root;
672 : /* If the new block is a loop header, allocate a loop
673 : struct. Fixup will take care of proper placement within
674 : the loop tree. */
675 931 : if (is_loop_header_of != -1)
676 : {
677 94 : if (number_of_loops (cfun) > (unsigned)is_loop_header_of
678 94 : && get_loop (cfun, is_loop_header_of) != NULL)
679 : {
680 0 : c_parser_error (parser, "duplicate loop header");
681 : }
682 : else
683 : {
684 94 : class loop *loop = alloc_loop ();
685 94 : loop->num = is_loop_header_of;
686 94 : loop->header = bb;
687 188 : if (number_of_loops (cfun) <= (unsigned)is_loop_header_of)
688 92 : vec_safe_grow_cleared (loops_for_fn (cfun)->larray,
689 92 : is_loop_header_of + 1, true);
690 94 : (*loops_for_fn (cfun)->larray)[is_loop_header_of] = loop;
691 94 : flow_loop_tree_node_add (loops_for_fn (cfun)->tree_root,
692 : loop);
693 : }
694 94 : loop_father = get_loop (cfun, is_loop_header_of);
695 : }
696 931 : bb->loop_father = loop_father;
697 931 : bb->count = bb_count;
698 :
699 : /* Stmts now go to the new block. */
700 931 : parser.current_bb = bb;
701 931 : break;
702 : }
703 2994 : goto expr_stmt;
704 :
705 5 : case CPP_SEMICOLON:
706 5 : {
707 : /* Empty stmt. */
708 5 : location_t loc = c_parser_peek_token (parser)->location;
709 5 : c_parser_consume_token (parser);
710 5 : gimple *nop = gimple_build_nop ();
711 5 : gimple_set_location (nop, loc);
712 5 : gimple_seq_add_stmt_without_update (seq, nop);
713 5 : break;
714 : }
715 :
716 1 : case CPP_CLOSE_PAREN:
717 1 : case CPP_CLOSE_SQUARE:
718 : /* Avoid infinite loop in error recovery:
719 : c_parser_skip_until_found stops at a closing nesting
720 : delimiter without consuming it, but here we need to consume
721 : it to proceed further. */
722 1 : c_parser_error (parser, "expected statement");
723 1 : c_parser_consume_token (parser);
724 1 : break;
725 :
726 2998 : default:
727 2998 : expr_stmt:
728 2998 : c_parser_gimple_statement (parser, seq);
729 2998 : if (! c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
730 3 : c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
731 : }
732 : }
733 513 : c_parser_consume_token (parser);
734 :
735 : /* Put stmts parsed in the current block. */
736 513 : if ((cfun->curr_properties & PROP_cfg)
737 513 : && !gimple_seq_empty_p (*seq))
738 : {
739 251 : if (!parser.current_bb)
740 0 : c_parser_error (parser, "stmts without block");
741 : else
742 : {
743 251 : gimple_stmt_iterator gsi = gsi_start_bb (parser.current_bb);
744 251 : gsi_insert_seq_after_without_update (&gsi, *seq,
745 : GSI_CONTINUE_LINKING);
746 : }
747 251 : *seq = NULL;
748 : }
749 :
750 : return return_p;
751 : }
752 :
753 : /* Parse a gimple statement.
754 :
755 : gimple-statement:
756 : gimple-call-expression
757 : gimple-assign-statement
758 : gimple-phi-statement
759 :
760 : gimple-assign-statement:
761 : gimple-unary-expression = gimple-assign-rhs
762 :
763 : gimple-assign-rhs:
764 : gimple-cast-expression
765 : gimple-unary-expression
766 : gimple-binary-expression
767 : gimple-call-expression
768 :
769 : gimple-phi-statement:
770 : identifier = __PHI ( label : gimple_primary-expression, ... )
771 :
772 : gimple-call-expr:
773 : gimple-primary-expression ( argument-list )
774 :
775 : gimple-cast-expression:
776 : ( type-name ) gimple-primary-expression
777 :
778 : */
779 :
780 : static void
781 2998 : c_parser_gimple_statement (gimple_parser &parser, gimple_seq *seq)
782 : {
783 2998 : struct c_expr lhs, rhs;
784 2998 : gimple *assign = NULL;
785 2998 : location_t loc;
786 2998 : tree arg = NULL_TREE;
787 2998 : auto_vec<tree> vargs;
788 :
789 2998 : lhs = c_parser_gimple_unary_expression (parser);
790 2998 : loc = EXPR_LOCATION (lhs.value);
791 2998 : rhs.set_error ();
792 :
793 : /* GIMPLE call statement without LHS. */
794 2998 : if (c_parser_next_token_is (parser, CPP_SEMICOLON)
795 2998 : && TREE_CODE (lhs.value) == CALL_EXPR)
796 : {
797 103 : gimple *call;
798 103 : call = gimple_build_call_from_tree (lhs.value, NULL);
799 103 : gimple_seq_add_stmt_without_update (seq, call);
800 103 : gimple_set_location (call, loc);
801 103 : return;
802 : }
803 :
804 : /* All following cases are statements with LHS. */
805 2895 : if (! c_parser_require (parser, CPP_EQ, "expected %<=%>"))
806 : return;
807 :
808 : /* Cast expression. */
809 2894 : if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
810 2894 : && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
811 : {
812 149 : c_parser_consume_token (parser);
813 149 : struct c_type_name *type_name = c_parser_type_name (parser);
814 149 : c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
815 149 : if (type_name == NULL)
816 : return;
817 : /* ??? The actual type used in the cast expression is ignored as
818 : in GIMPLE it is encoded by the type of the LHS. */
819 149 : rhs = c_parser_gimple_postfix_expression (parser);
820 149 : if (lhs.value != error_mark_node
821 149 : && rhs.value != error_mark_node)
822 : {
823 149 : enum tree_code code = NOP_EXPR;
824 298 : if (FLOAT_TYPE_P (TREE_TYPE (lhs.value))
825 149 : && ! FLOAT_TYPE_P (TREE_TYPE (rhs.value)))
826 : code = FLOAT_EXPR;
827 298 : else if (! FLOAT_TYPE_P (TREE_TYPE (lhs.value))
828 298 : && FLOAT_TYPE_P (TREE_TYPE (rhs.value)))
829 : code = FIX_TRUNC_EXPR;
830 149 : assign = gimple_build_assign (lhs.value, code, rhs.value);
831 149 : gimple_seq_add_stmt_without_update (seq, assign);
832 149 : gimple_set_location (assign, loc);
833 149 : return;
834 : }
835 : }
836 :
837 : /* Unary expression. */
838 2745 : switch (c_parser_peek_token (parser)->type)
839 : {
840 2167 : case CPP_NAME:
841 2167 : {
842 2167 : tree id = c_parser_peek_token (parser)->value;
843 2167 : if (strcmp (IDENTIFIER_POINTER (id), "__ABS") == 0
844 2164 : || strcmp (IDENTIFIER_POINTER (id), "__ABSU") == 0
845 2157 : || strcmp (IDENTIFIER_POINTER (id), "__MIN") == 0
846 2141 : || strcmp (IDENTIFIER_POINTER (id), "__MAX") == 0
847 2140 : || strcmp (IDENTIFIER_POINTER (id), "__BIT_INSERT") == 0
848 4303 : || strcmp (IDENTIFIER_POINTER (id), "__VEC_PERM") == 0)
849 48 : goto build_unary_expr;
850 : break;
851 : }
852 340 : case CPP_KEYWORD:
853 340 : if (c_parser_peek_token (parser)->keyword != RID_REALPART
854 340 : && c_parser_peek_token (parser)->keyword != RID_IMAGPART)
855 : break;
856 : /* Fallthru. */
857 69 : case CPP_AND:
858 69 : case CPP_PLUS:
859 69 : case CPP_MINUS:
860 69 : case CPP_COMPL:
861 69 : case CPP_NOT:
862 69 : case CPP_MULT: /* pointer deref */
863 69 : build_unary_expr:
864 69 : rhs = c_parser_gimple_unary_expression (parser);
865 69 : if (rhs.value != error_mark_node)
866 : {
867 68 : assign = gimple_build_assign (lhs.value, rhs.value);
868 68 : gimple_set_location (assign, loc);
869 68 : gimple_seq_add_stmt_without_update (seq, assign);
870 : }
871 : return;
872 :
873 2676 : default:;
874 : }
875 :
876 : /* GIMPLE PHI statement. */
877 2676 : if (c_parser_next_token_is_keyword (parser, RID_PHI))
878 : {
879 334 : c_parser_consume_token (parser);
880 :
881 334 : if (! c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
882 : return;
883 :
884 334 : if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
885 0 : c_parser_consume_token (parser);
886 :
887 1923 : while (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN))
888 : {
889 1589 : if (c_parser_next_token_is (parser, CPP_NAME)
890 1589 : && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
891 : {
892 641 : arg = c_parser_peek_token (parser)->value;
893 641 : c_parser_consume_token (parser);
894 641 : if (c_parser_next_token_is (parser, CPP_COLON))
895 641 : c_parser_consume_token (parser);
896 641 : int src_index = -1;
897 641 : if (!c_parser_gimple_parse_bb_spec (arg, &src_index))
898 0 : c_parser_error (parser, "invalid source block specification");
899 641 : vargs.safe_push (size_int (src_index));
900 : }
901 948 : else if (c_parser_next_token_is (parser, CPP_COMMA))
902 307 : c_parser_consume_token (parser);
903 : else
904 : {
905 641 : arg = c_parser_gimple_unary_expression (parser).value;
906 641 : vargs.safe_push (arg);
907 : }
908 : }
909 :
910 334 : c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
911 : "expected %<)%>");
912 :
913 : /* Build internal function for PHI. */
914 334 : gcall *call_stmt = gimple_build_call_internal_vec (IFN_PHI, vargs);
915 334 : gimple_call_set_lhs (call_stmt, lhs.value);
916 334 : gimple_set_location (call_stmt, UNKNOWN_LOCATION);
917 334 : gimple_seq_add_stmt_without_update (seq, call_stmt);
918 334 : return;
919 : }
920 :
921 : /* GIMPLE call with lhs. */
922 2342 : if (c_parser_next_token_is (parser, CPP_DOT)
923 2342 : || (c_parser_next_token_is (parser, CPP_NAME)
924 2119 : && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN
925 353 : && lookup_name (c_parser_peek_token (parser)->value)))
926 : {
927 24 : rhs = c_parser_gimple_unary_expression (parser);
928 24 : if (rhs.value != error_mark_node)
929 : {
930 24 : gimple *call = gimple_build_call_from_tree (rhs.value, NULL);
931 24 : gimple_call_set_lhs (call, lhs.value);
932 24 : gimple_seq_add_stmt_without_update (seq, call);
933 48 : gimple_set_location (call, loc);
934 : }
935 24 : return;
936 : }
937 :
938 2318 : rhs = c_parser_gimple_binary_expression (parser, TREE_TYPE (lhs.value));
939 2318 : if (lhs.value != error_mark_node
940 2312 : && rhs.value != error_mark_node)
941 : {
942 : /* If we parsed an identifier and the next token is a '?' then parse
943 : a conditional expression. */
944 2309 : if (SSA_VAR_P (rhs.value) && c_parser_next_token_is (parser, CPP_QUERY))
945 : {
946 246 : struct c_expr trueval, falseval;
947 246 : c_parser_consume_token (parser);
948 246 : trueval = c_parser_gimple_postfix_expression (parser);
949 246 : falseval.set_error ();
950 246 : if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
951 246 : falseval = c_parser_gimple_postfix_expression (parser);
952 246 : if (trueval.value == error_mark_node
953 246 : || falseval.value == error_mark_node)
954 0 : return;
955 246 : rhs.value = build3_loc (loc,
956 246 : VECTOR_TYPE_P (TREE_TYPE (rhs.value))
957 : ? VEC_COND_EXPR : COND_EXPR,
958 246 : TREE_TYPE (trueval.value),
959 : rhs.value, trueval.value, falseval.value);
960 : }
961 2309 : if (get_gimple_rhs_class (TREE_CODE (rhs.value)) == GIMPLE_INVALID_RHS)
962 : {
963 0 : c_parser_error (parser, "unexpected RHS for assignment");
964 0 : return;
965 : }
966 2309 : assign = gimple_build_assign (lhs.value, rhs.value);
967 2309 : gimple_seq_add_stmt_without_update (seq, assign);
968 2309 : gimple_set_location (assign, loc);
969 : }
970 : return;
971 2998 : }
972 :
973 : /* A mapping between an identifier to a tree code for binary operations. */
974 : static const std::pair<const char *, tree_code> gimple_binary_identifier_code[] =
975 : {
976 : {"__MULT_HIGHPART", MULT_HIGHPART_EXPR},
977 : {"__UNLT", UNLT_EXPR},
978 : {"__UNLE", UNLE_EXPR},
979 : {"__UNGT", UNGT_EXPR},
980 : {"__UNGE", UNGE_EXPR},
981 : {"__UNEQ", UNEQ_EXPR},
982 : {"__UNORDERED", UNORDERED_EXPR},
983 : {"__ORDERED", ORDERED_EXPR},
984 : {"__LTGT", LTGT_EXPR},
985 : {"__FLOOR_DIV", FLOOR_DIV_EXPR},
986 : {"__ROUND_DIV", ROUND_DIV_EXPR},
987 : {"__EXACT_DIV", EXACT_DIV_EXPR},
988 : {"__CEIL_DIV", CEIL_DIV_EXPR},
989 : {"__FLOOR_MOD", FLOOR_MOD_EXPR},
990 : {"__ROUND_MOD", ROUND_MOD_EXPR},
991 : {"__CEIL_MOD", CEIL_MOD_EXPR},
992 : {"__ROTATE_LEFT", LROTATE_EXPR},
993 : {"__ROTATE_RIGHT", RROTATE_EXPR},
994 : };
995 :
996 : /* Parse gimple binary expr.
997 :
998 : gimple-binary-expression:
999 : gimple-unary-expression * gimple-unary-expression
1000 : gimple-unary-expression __MULT_HIGHPART gimple-unary-expression
1001 : gimple-unary-expression / gimple-unary-expression
1002 : gimple-unary-expression % gimple-unary-expression
1003 : gimple-unary-expression + gimple-unary-expression
1004 : gimple-unary-expression - gimple-unary-expression
1005 : gimple-unary-expression << gimple-unary-expression
1006 : gimple-unary-expression >> gimple-unary-expression
1007 : gimple-unary-expression < gimple-unary-expression
1008 : gimple-unary-expression > gimple-unary-expression
1009 : gimple-unary-expression <= gimple-unary-expression
1010 : gimple-unary-expression >= gimple-unary-expression
1011 : gimple-unary-expression == gimple-unary-expression
1012 : gimple-unary-expression != gimple-unary-expression
1013 : gimple-unary-expression & gimple-unary-expression
1014 : gimple-unary-expression ^ gimple-unary-expression
1015 : gimple-unary-expression | gimple-unary-expression
1016 :
1017 : */
1018 :
1019 : static c_expr
1020 2617 : c_parser_gimple_binary_expression (gimple_parser &parser, tree ret_type)
1021 : {
1022 : /* Location of the binary operator. */
1023 2617 : struct c_expr ret, lhs, rhs;
1024 2617 : enum tree_code code = ERROR_MARK;
1025 2617 : ret.set_error ();
1026 2617 : lhs = c_parser_gimple_postfix_expression (parser);
1027 2617 : if (c_parser_error (parser))
1028 5 : return ret;
1029 2612 : switch (c_parser_peek_token (parser)->type)
1030 : {
1031 : case CPP_MULT:
1032 : code = MULT_EXPR;
1033 : break;
1034 11 : case CPP_DIV:
1035 11 : code = TRUNC_DIV_EXPR;
1036 11 : break;
1037 10 : case CPP_MOD:
1038 10 : code = TRUNC_MOD_EXPR;
1039 10 : break;
1040 410 : case CPP_PLUS:
1041 410 : if (POINTER_TYPE_P (TREE_TYPE (lhs.value)))
1042 : code = POINTER_PLUS_EXPR;
1043 : else
1044 : code = PLUS_EXPR;
1045 : break;
1046 103 : case CPP_MINUS:
1047 103 : if (POINTER_TYPE_P (TREE_TYPE (lhs.value)))
1048 : code = POINTER_DIFF_EXPR;
1049 : else
1050 : code = MINUS_EXPR;
1051 : break;
1052 13 : case CPP_LSHIFT:
1053 13 : code = LSHIFT_EXPR;
1054 13 : break;
1055 10 : case CPP_RSHIFT:
1056 10 : code = RSHIFT_EXPR;
1057 10 : break;
1058 24 : case CPP_LESS:
1059 24 : code = LT_EXPR;
1060 24 : break;
1061 216 : case CPP_GREATER:
1062 216 : code = GT_EXPR;
1063 216 : break;
1064 17 : case CPP_LESS_EQ:
1065 17 : code = LE_EXPR;
1066 17 : break;
1067 10 : case CPP_GREATER_EQ:
1068 10 : code = GE_EXPR;
1069 10 : break;
1070 53 : case CPP_EQ_EQ:
1071 53 : code = EQ_EXPR;
1072 53 : break;
1073 223 : case CPP_NOT_EQ:
1074 223 : code = NE_EXPR;
1075 223 : break;
1076 26 : case CPP_AND:
1077 26 : code = BIT_AND_EXPR;
1078 26 : break;
1079 14 : case CPP_XOR:
1080 14 : code = BIT_XOR_EXPR;
1081 14 : break;
1082 17 : case CPP_OR:
1083 17 : code = BIT_IOR_EXPR;
1084 17 : break;
1085 0 : case CPP_AND_AND:
1086 0 : c_parser_error (parser, "%<&&%> not valid in GIMPLE");
1087 0 : return ret;
1088 0 : case CPP_OR_OR:
1089 0 : c_parser_error (parser, "%<||%> not valid in GIMPLE");
1090 0 : return ret;
1091 113 : case CPP_NAME:
1092 113 : {
1093 113 : tree id = c_parser_peek_token (parser)->value;
1094 1360 : for (auto &p : gimple_binary_identifier_code)
1095 : {
1096 1360 : if (strcmp (IDENTIFIER_POINTER (id), p.first) == 0)
1097 : {
1098 113 : code = p.second;
1099 113 : break;
1100 : }
1101 : }
1102 113 : if (code != ERROR_MARK)
1103 : break;
1104 : }
1105 : /* Fallthru. */
1106 1147 : default:
1107 : /* Not a binary expression. */
1108 1147 : return lhs;
1109 : }
1110 1465 : location_t ret_loc = c_parser_peek_token (parser)->location;
1111 1465 : c_parser_consume_token (parser);
1112 1465 : rhs = c_parser_gimple_postfix_expression (parser);
1113 1465 : if (lhs.value != error_mark_node && rhs.value != error_mark_node)
1114 1464 : ret.value = build2_loc (ret_loc, code, ret_type, lhs.value, rhs.value);
1115 1465 : return ret;
1116 : }
1117 :
1118 : /* Parse a gimple parentized binary expression. */
1119 :
1120 : static c_expr
1121 17 : c_parser_gimple_parentized_binary_expression (gimple_parser &parser,
1122 : location_t op_loc,
1123 : tree_code code)
1124 : {
1125 17 : struct c_expr ret;
1126 17 : ret.set_error ();
1127 :
1128 17 : c_parser_consume_token (parser);
1129 17 : if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
1130 : return ret;
1131 17 : c_expr op1 = c_parser_gimple_postfix_expression (parser);
1132 17 : if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
1133 : return ret;
1134 17 : c_expr op2 = c_parser_gimple_postfix_expression (parser);
1135 17 : if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
1136 : return ret;
1137 :
1138 17 : if (op1.value != error_mark_node && op2.value != error_mark_node)
1139 17 : ret.value = build2_loc (op_loc,
1140 17 : code, TREE_TYPE (op1.value), op1.value, op2.value);
1141 : return ret;
1142 : }
1143 :
1144 : /* Parse a gimple parentized binary expression. */
1145 :
1146 : static c_expr
1147 17 : c_parser_gimple_parentized_ternary_expression (gimple_parser &parser,
1148 : location_t op_loc,
1149 : tree_code code)
1150 : {
1151 17 : struct c_expr ret;
1152 17 : ret.set_error ();
1153 :
1154 17 : c_parser_consume_token (parser);
1155 17 : if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
1156 : return ret;
1157 17 : c_expr op1 = c_parser_gimple_postfix_expression (parser);
1158 17 : if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
1159 : return ret;
1160 17 : c_expr op2 = c_parser_gimple_postfix_expression (parser);
1161 17 : if (!c_parser_require (parser, CPP_COMMA, "expected %<)%>"))
1162 : return ret;
1163 17 : c_expr op3 = c_parser_gimple_postfix_expression (parser);
1164 17 : if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
1165 : return ret;
1166 :
1167 17 : if (op1.value != error_mark_node
1168 17 : && op2.value != error_mark_node
1169 17 : && op3.value != error_mark_node)
1170 17 : ret.value = build3_loc (op_loc,
1171 17 : code, TREE_TYPE (op1.value),
1172 : op1.value, op2.value, op3.value);
1173 : return ret;
1174 : }
1175 :
1176 : /* Parse gimple unary expression.
1177 :
1178 : gimple-unary-expression:
1179 : gimple-postfix-expression
1180 : unary-operator gimple-postfix-expression
1181 :
1182 : unary-operator: one of
1183 : & * + - ~ abs_expr
1184 : */
1185 :
1186 : static c_expr
1187 4662 : c_parser_gimple_unary_expression (gimple_parser &parser)
1188 : {
1189 4662 : struct c_expr ret, op;
1190 4662 : location_t op_loc = c_parser_peek_token (parser)->location;
1191 4662 : location_t finish;
1192 4662 : ret.set_error ();
1193 4662 : switch (c_parser_peek_token (parser)->type)
1194 : {
1195 32 : case CPP_AND:
1196 32 : c_parser_consume_token (parser);
1197 32 : op = c_parser_gimple_postfix_expression (parser);
1198 32 : mark_exp_read (op.value);
1199 32 : return gimple_parser_build_unary_op (op_loc, ADDR_EXPR, op);
1200 8 : case CPP_MULT:
1201 8 : {
1202 8 : c_parser_consume_token (parser);
1203 8 : op = c_parser_gimple_postfix_expression (parser);
1204 8 : if (op.value == error_mark_node)
1205 1 : return ret;
1206 7 : if (! POINTER_TYPE_P (TREE_TYPE (op.value)))
1207 : {
1208 1 : error_at (op_loc, "expected pointer as argument of unary %<*%>");
1209 1 : return ret;
1210 : }
1211 6 : finish = op.get_finish ();
1212 6 : location_t combined_loc = make_location (op_loc, op_loc, finish);
1213 6 : ret.value = build_simple_mem_ref_loc (combined_loc, op.value);
1214 12 : TREE_SIDE_EFFECTS (ret.value)
1215 6 : = TREE_THIS_VOLATILE (ret.value)
1216 6 : = TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (op.value)));
1217 6 : ret.src_range.m_start = op_loc;
1218 6 : ret.src_range.m_finish = finish;
1219 6 : return ret;
1220 : }
1221 0 : case CPP_PLUS:
1222 0 : c_parser_consume_token (parser);
1223 0 : op = c_parser_gimple_postfix_expression (parser);
1224 0 : return gimple_parser_build_unary_op (op_loc, CONVERT_EXPR, op);
1225 6 : case CPP_MINUS:
1226 6 : c_parser_consume_token (parser);
1227 6 : op = c_parser_gimple_postfix_expression (parser);
1228 6 : return gimple_parser_build_unary_op (op_loc, NEGATE_EXPR, op);
1229 3 : case CPP_COMPL:
1230 3 : c_parser_consume_token (parser);
1231 3 : op = c_parser_gimple_postfix_expression (parser);
1232 3 : return gimple_parser_build_unary_op (op_loc, BIT_NOT_EXPR, op);
1233 0 : case CPP_NOT:
1234 0 : c_parser_error (parser, "%<!%> not valid in GIMPLE");
1235 0 : return ret;
1236 6 : case CPP_KEYWORD:
1237 6 : switch (c_parser_peek_token (parser)->keyword)
1238 : {
1239 4 : case RID_REALPART:
1240 4 : c_parser_consume_token (parser);
1241 4 : op = c_parser_gimple_postfix_expression (parser);
1242 4 : return gimple_parser_build_unary_op (op_loc, REALPART_EXPR, op);
1243 2 : case RID_IMAGPART:
1244 2 : c_parser_consume_token (parser);
1245 2 : op = c_parser_gimple_postfix_expression (parser);
1246 2 : return gimple_parser_build_unary_op (op_loc, IMAGPART_EXPR, op);
1247 0 : default:
1248 0 : return c_parser_gimple_postfix_expression (parser);
1249 : }
1250 4143 : case CPP_NAME:
1251 4143 : {
1252 4143 : tree id = c_parser_peek_token (parser)->value;
1253 4143 : if (strcmp (IDENTIFIER_POINTER (id), "__ABS") == 0)
1254 : {
1255 3 : c_parser_consume_token (parser);
1256 3 : op = c_parser_gimple_postfix_expression (parser);
1257 3 : return gimple_parser_build_unary_op (op_loc, ABS_EXPR, op);
1258 : }
1259 4140 : else if (strcmp (IDENTIFIER_POINTER (id), "__ABSU") == 0)
1260 : {
1261 7 : c_parser_consume_token (parser);
1262 7 : op = c_parser_gimple_postfix_expression (parser);
1263 7 : return gimple_parser_build_unary_op (op_loc, ABSU_EXPR, op);
1264 : }
1265 4133 : else if (strcmp (IDENTIFIER_POINTER (id), "__MIN") == 0)
1266 16 : return c_parser_gimple_parentized_binary_expression (parser,
1267 : op_loc,
1268 16 : MIN_EXPR);
1269 4117 : else if (strcmp (IDENTIFIER_POINTER (id), "__MAX") == 0)
1270 1 : return c_parser_gimple_parentized_binary_expression (parser,
1271 : op_loc,
1272 1 : MAX_EXPR);
1273 4116 : else if (strcmp (IDENTIFIER_POINTER (id), "__VEC_PERM") == 0)
1274 17 : return c_parser_gimple_parentized_ternary_expression
1275 17 : (parser, op_loc, VEC_PERM_EXPR);
1276 4099 : else if (strcmp (IDENTIFIER_POINTER (id), "__BIT_INSERT") == 0)
1277 : {
1278 : /* __BIT_INSERT '(' postfix-expression, postfix-expression,
1279 : integer ')' */
1280 4 : location_t loc = c_parser_peek_token (parser)->location;
1281 4 : c_parser_consume_token (parser);
1282 4 : if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
1283 : {
1284 4 : c_expr op0 = c_parser_gimple_postfix_expression (parser);
1285 4 : c_parser_skip_until_found (parser, CPP_COMMA,
1286 : "expected %<,%>");
1287 4 : c_expr op1 = c_parser_gimple_postfix_expression (parser);
1288 4 : c_parser_skip_until_found (parser, CPP_COMMA,
1289 : "expected %<,%>");
1290 4 : c_expr op2 = c_parser_gimple_postfix_expression (parser);
1291 4 : if (TREE_CODE (op2.value) != INTEGER_CST
1292 4 : || !int_fits_type_p (op2.value, bitsizetype))
1293 0 : c_parser_error (parser, "expected constant offset");
1294 4 : c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
1295 : "expected %<)%>");
1296 4 : if (op0.value != error_mark_node
1297 4 : && op1.value != error_mark_node
1298 4 : && TREE_CODE (op2.value) == INTEGER_CST)
1299 8 : ret.value = build3_loc (loc, BIT_INSERT_EXPR,
1300 4 : TREE_TYPE (op0.value),
1301 : op0.value, op1.value,
1302 : fold_convert (bitsizetype,
1303 : op2.value));
1304 : }
1305 4 : return ret;
1306 : }
1307 : else
1308 4095 : return c_parser_gimple_postfix_expression (parser);
1309 : }
1310 464 : default:
1311 464 : return c_parser_gimple_postfix_expression (parser);
1312 : }
1313 : }
1314 :
1315 : /* Decompose ID into base name (ID until ver_offset) and VERSION. Return
1316 : true if ID matches a SSA name. */
1317 :
1318 : static bool
1319 6877 : c_parser_parse_ssa_name_id (tree id, unsigned *version, unsigned *ver_offset)
1320 : {
1321 6877 : const char *token = IDENTIFIER_POINTER (id);
1322 6877 : const char *var_version = strrchr (token, '_');
1323 6877 : if (! var_version)
1324 : return false;
1325 :
1326 6154 : *ver_offset = var_version - token;
1327 15227 : for (const char *p = var_version + 1; *p; ++p)
1328 9081 : if (! ISDIGIT (*p))
1329 : return false;
1330 6146 : *version = atoi (var_version + 1);
1331 6146 : return *version > 0;
1332 : }
1333 :
1334 : /* Get at the actual SSA name ID with VERSION starting at VER_OFFSET.
1335 : TYPE is the type if the SSA name is being declared. */
1336 :
1337 : static tree
1338 6055 : c_parser_parse_ssa_name (gimple_parser &parser,
1339 : tree id, tree type, unsigned version,
1340 : unsigned ver_offset)
1341 : {
1342 6055 : tree name = NULL_TREE;
1343 6055 : const char *token = IDENTIFIER_POINTER (id);
1344 :
1345 6055 : if (ver_offset == 0)
1346 : {
1347 : /* Anonymous unnamed SSA name. */
1348 4006 : if (version < num_ssa_names)
1349 2850 : name = ssa_name (version);
1350 2850 : if (! name)
1351 : {
1352 1258 : if (! type)
1353 : {
1354 0 : c_parser_error (parser, "SSA name undeclared");
1355 0 : return error_mark_node;
1356 : }
1357 1258 : name = make_ssa_name_fn (cfun, type, NULL, version);
1358 : }
1359 : }
1360 : else
1361 : {
1362 2049 : if (version < num_ssa_names)
1363 1733 : name = ssa_name (version);
1364 1733 : if (! name)
1365 : {
1366 : /* Separate var name from version. */
1367 992 : char *var_name = XNEWVEC (char, ver_offset + 1);
1368 992 : memcpy (var_name, token, ver_offset);
1369 992 : var_name[ver_offset] = '\0';
1370 : /* lookup for parent decl. */
1371 992 : id = get_identifier (var_name);
1372 992 : tree parent = lookup_name (id);
1373 992 : XDELETEVEC (var_name);
1374 992 : if (! parent || parent == error_mark_node)
1375 : {
1376 1 : c_parser_error (parser, "base variable or SSA name undeclared");
1377 1 : return error_mark_node;
1378 : }
1379 991 : if (!(VAR_P (parent)
1380 : || TREE_CODE (parent) == PARM_DECL
1381 : || TREE_CODE (parent) == RESULT_DECL))
1382 : {
1383 1 : error ("invalid base %qE for SSA name", parent);
1384 1 : return error_mark_node;
1385 : }
1386 990 : name = make_ssa_name_fn (cfun, parent,
1387 : gimple_build_nop (), version);
1388 : }
1389 : }
1390 :
1391 : return name;
1392 : }
1393 :
1394 : /* Parse a gimple call to an internal function.
1395 :
1396 : gimple-call-internal:
1397 : . identifier ( gimple-argument-expression-list[opt] ) */
1398 :
1399 : static struct c_expr
1400 5 : c_parser_gimple_call_internal (gimple_parser &parser)
1401 : {
1402 5 : struct c_expr expr;
1403 5 : expr.set_error ();
1404 :
1405 5 : gcc_assert (c_parser_next_token_is (parser, CPP_DOT));
1406 5 : c_parser_consume_token (parser);
1407 5 : location_t loc = c_parser_peek_token (parser)->location;
1408 5 : if (!c_parser_next_token_is (parser, CPP_NAME)
1409 5 : || c_parser_peek_token (parser)->id_kind != C_ID_ID)
1410 : {
1411 0 : c_parser_error (parser, "expecting internal function name");
1412 0 : return expr;
1413 : }
1414 5 : tree id = c_parser_peek_token (parser)->value;
1415 5 : internal_fn ifn = lookup_internal_fn (IDENTIFIER_POINTER (id));
1416 5 : c_parser_consume_token (parser);
1417 5 : if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
1418 : {
1419 5 : auto_vec<tree> exprlist;
1420 5 : if (!c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
1421 5 : c_parser_gimple_expr_list (parser, &exprlist);
1422 5 : c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
1423 5 : if (ifn == IFN_LAST)
1424 0 : error_at (loc, "unknown internal function %qE", id);
1425 : else
1426 : {
1427 5 : expr.value = build_call_expr_internal_loc_array
1428 5 : (loc, ifn, void_type_node, exprlist.length (),
1429 5 : exprlist.address ());
1430 5 : expr.original_code = ERROR_MARK;
1431 5 : expr.original_type = NULL;
1432 5 : expr.m_decimal = 0;
1433 : }
1434 5 : }
1435 : return expr;
1436 : }
1437 :
1438 : /* Parse '<' type [',' alignment] '>' and return a type on success
1439 : and NULL_TREE on error. */
1440 :
1441 : static tree
1442 345 : c_parser_gimple_typespec (gimple_parser &parser)
1443 : {
1444 345 : struct c_type_name *type_name = NULL;
1445 345 : tree alignment = NULL_TREE;
1446 345 : if (c_parser_require (parser, CPP_LESS, "expected %<<%>"))
1447 : {
1448 344 : type_name = c_parser_type_name (parser);
1449 : /* Optional alignment. */
1450 344 : if (c_parser_next_token_is (parser, CPP_COMMA))
1451 : {
1452 14 : c_parser_consume_token (parser);
1453 14 : alignment
1454 14 : = c_parser_gimple_postfix_expression (parser).value;
1455 : }
1456 344 : c_parser_skip_until_found (parser,
1457 : CPP_GREATER, "expected %<>%>");
1458 : }
1459 344 : if (!type_name)
1460 1 : return NULL_TREE;
1461 344 : tree tem;
1462 344 : tree type = groktypename (type_name, &tem, NULL);
1463 344 : if (alignment)
1464 14 : type = build_aligned_type (type, tree_to_uhwi (alignment));
1465 : return type;
1466 : }
1467 :
1468 : /* Parse gimple postfix expression.
1469 :
1470 : gimple-postfix-expression:
1471 : gimple-primary-expression
1472 : gimple-primary-expression [ gimple-primary-expression ]
1473 : gimple-primary-expression ( gimple-argument-expression-list[opt] )
1474 : gimple-postfix-expression . identifier
1475 : gimple-postfix-expression -> identifier
1476 :
1477 : gimple-argument-expression-list:
1478 : gimple-unary-expression
1479 : gimple-argument-expression-list , gimple-unary-expression
1480 :
1481 : gimple-primary-expression:
1482 : identifier
1483 : constant
1484 : string-literal
1485 : constructor
1486 : gimple-call-internal
1487 :
1488 : */
1489 :
1490 : static struct c_expr
1491 10235 : c_parser_gimple_postfix_expression (gimple_parser &parser)
1492 : {
1493 10235 : location_t loc = c_parser_peek_token (parser)->location;
1494 10235 : source_range tok_range = c_parser_peek_token (parser)->get_range ();
1495 10235 : struct c_expr expr;
1496 10235 : expr.set_error ();
1497 10235 : switch (c_parser_peek_token (parser)->type)
1498 : {
1499 2425 : case CPP_NUMBER:
1500 2425 : expr.value = c_parser_peek_token (parser)->value;
1501 2425 : set_c_expr_source_range (&expr, tok_range);
1502 2425 : loc = c_parser_peek_token (parser)->location;
1503 2425 : c_parser_consume_token (parser);
1504 2425 : break;
1505 0 : case CPP_CHAR:
1506 0 : case CPP_CHAR16:
1507 0 : case CPP_CHAR32:
1508 0 : case CPP_UTF8CHAR:
1509 0 : case CPP_WCHAR:
1510 0 : expr.value = c_parser_peek_token (parser)->value;
1511 0 : set_c_expr_source_range (&expr, tok_range);
1512 0 : c_parser_consume_token (parser);
1513 0 : break;
1514 6 : case CPP_STRING:
1515 6 : case CPP_STRING16:
1516 6 : case CPP_STRING32:
1517 6 : case CPP_WSTRING:
1518 6 : case CPP_UTF8STRING:
1519 6 : expr = c_parser_string_literal (parser, false, true);
1520 6 : break;
1521 5 : case CPP_DOT:
1522 5 : expr = c_parser_gimple_call_internal (parser);
1523 5 : break;
1524 7796 : case CPP_NAME:
1525 7796 : if (c_parser_peek_token (parser)->id_kind == C_ID_ID)
1526 : {
1527 7796 : tree id = c_parser_peek_token (parser)->value;
1528 7796 : if (strcmp (IDENTIFIER_POINTER (id), "__MEM") == 0)
1529 : {
1530 : /* __MEM '<' type-name [ ',' number ] '>'
1531 : '(' [ '(' type-name ')' ] unary-expression
1532 : [ '+' number ]
1533 : [ ',' number ':' number ] ')' */
1534 300 : location_t loc = c_parser_peek_token (parser)->location;
1535 300 : c_parser_consume_token (parser);
1536 300 : tree type = c_parser_gimple_typespec (parser);
1537 300 : struct c_expr ptr, alias_off, step, index, index2;
1538 300 : ptr.value = error_mark_node;
1539 300 : alias_off.value = NULL_TREE;
1540 300 : step.value = NULL_TREE;
1541 300 : index.value = NULL_TREE;
1542 300 : index2.value = NULL_TREE;
1543 300 : unsigned short clique = 0;
1544 300 : unsigned short base = 0;
1545 300 : if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
1546 : {
1547 300 : tree alias_type = NULL_TREE;
1548 : /* Optional alias-type cast. */
1549 300 : if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
1550 : {
1551 53 : c_parser_consume_token (parser);
1552 53 : struct c_type_name *alias_type_name
1553 53 : = c_parser_type_name (parser);
1554 53 : c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
1555 : "expected %<)%>");
1556 53 : if (alias_type_name)
1557 : {
1558 53 : tree tem;
1559 53 : alias_type = groktypename (alias_type_name,
1560 : &tem, NULL);
1561 : }
1562 : }
1563 300 : ptr = c_parser_gimple_unary_expression (parser);
1564 300 : if (ptr.value == error_mark_node
1565 300 : || ! POINTER_TYPE_P (TREE_TYPE (ptr.value)))
1566 : {
1567 1 : if (ptr.value != error_mark_node)
1568 0 : error_at (ptr.get_start (),
1569 : "invalid type of %<__MEM%> operand");
1570 1 : c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
1571 : "expected %<)%>");
1572 1 : return expr;
1573 : }
1574 299 : if (! alias_type)
1575 246 : alias_type = TREE_TYPE (ptr.value);
1576 : /* Optional constant offset. */
1577 299 : if (c_parser_next_token_is (parser, CPP_PLUS))
1578 : {
1579 64 : c_parser_consume_token (parser);
1580 64 : alias_off = c_parser_gimple_postfix_expression (parser);
1581 : }
1582 299 : if (c_parser_next_token_is (parser, CPP_MULT))
1583 : {
1584 1 : std::swap (index, alias_off);
1585 1 : c_parser_consume_token (parser);
1586 1 : step = c_parser_gimple_postfix_expression (parser);
1587 : }
1588 298 : else if (c_parser_next_token_is (parser, CPP_PLUS))
1589 : {
1590 3 : c_parser_consume_token (parser);
1591 3 : index = c_parser_gimple_postfix_expression (parser);
1592 3 : if (c_parser_next_token_is (parser, CPP_MULT))
1593 : {
1594 2 : c_parser_consume_token (parser);
1595 2 : step = c_parser_gimple_postfix_expression (parser);
1596 : }
1597 : else
1598 1 : std::swap (index, index2);
1599 : }
1600 295 : else if (alias_off.value
1601 60 : && TREE_CODE (alias_off.value) != INTEGER_CST)
1602 1 : std::swap (alias_off, index2);
1603 299 : if (c_parser_next_token_is (parser, CPP_PLUS))
1604 : {
1605 1 : c_parser_consume_token (parser);
1606 1 : index2 = c_parser_gimple_postfix_expression (parser);
1607 : }
1608 299 : if (alias_off.value)
1609 : {
1610 62 : if (TREE_CODE (alias_off.value) != INTEGER_CST)
1611 0 : error_at (alias_off.get_start (),
1612 : "expected constant offset for %<__MEM%> "
1613 : "operand");
1614 62 : alias_off.value = fold_convert (alias_type,
1615 : alias_off.value);
1616 : }
1617 : else
1618 237 : alias_off.value = build_int_cst (alias_type, 0);
1619 299 : if (step.value)
1620 : {
1621 3 : if (TREE_CODE (step.value) != INTEGER_CST)
1622 0 : error_at (step.get_start (),
1623 : "expected constant step for %<__MEM%> "
1624 : "operand");
1625 : }
1626 299 : if (c_parser_next_token_is (parser, CPP_COMMA))
1627 : {
1628 3 : struct c_expr cl, ba;
1629 3 : c_parser_consume_token (parser);
1630 3 : cl = c_parser_gimple_postfix_expression (parser);
1631 3 : if (c_parser_require (parser,
1632 : CPP_COLON, "expected %<:%>"))
1633 : {
1634 3 : ba = c_parser_gimple_postfix_expression (parser);
1635 3 : if (!tree_fits_uhwi_p (cl.value)
1636 3 : || !tree_fits_uhwi_p (ba.value)
1637 3 : || compare_tree_int (cl.value,
1638 3 : (clique = tree_to_uhwi
1639 3 : (cl.value)))
1640 6 : || compare_tree_int (ba.value,
1641 3 : (base = tree_to_uhwi
1642 3 : (ba.value))))
1643 0 : error_at (cl.get_start (),
1644 : "invalid clique/base pair");
1645 : }
1646 : }
1647 299 : c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
1648 : "expected %<)%>");
1649 : }
1650 299 : if (! type || c_parser_error (parser))
1651 : {
1652 0 : c_parser_set_error (parser, false);
1653 0 : return expr;
1654 : }
1655 299 : if (index.value || step.value || index2.value)
1656 5 : expr.value = build5_loc (loc, TARGET_MEM_REF,
1657 : type, ptr.value, alias_off.value,
1658 : index.value, step.value, index2.value);
1659 : else
1660 294 : expr.value = build2_loc (loc, MEM_REF,
1661 : type, ptr.value, alias_off.value);
1662 299 : if (clique != 0)
1663 : {
1664 3 : cfun->last_clique = MAX (cfun->last_clique, clique);
1665 3 : MR_DEPENDENCE_CLIQUE (expr.value) = clique;
1666 3 : MR_DEPENDENCE_BASE (expr.value) = base;
1667 : }
1668 299 : break;
1669 : }
1670 7496 : else if (strcmp (IDENTIFIER_POINTER (id), "__VIEW_CONVERT") == 0)
1671 : {
1672 : /* __VIEW_CONVERT '<' type-name [ ',' number ] '>'
1673 : '(' postfix-expression ')' */
1674 10 : location_t loc = c_parser_peek_token (parser)->location;
1675 10 : c_parser_consume_token (parser);
1676 10 : tree type = c_parser_gimple_typespec (parser);
1677 10 : if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
1678 : {
1679 10 : c_expr op = c_parser_gimple_postfix_expression (parser);
1680 10 : c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
1681 : "expected %<)%>");
1682 10 : if (type && op.value != error_mark_node)
1683 10 : expr.value = build1_loc (loc, VIEW_CONVERT_EXPR,
1684 : type, op.value);
1685 : }
1686 : break;
1687 : }
1688 7486 : else if (strcmp (IDENTIFIER_POINTER (id), "__BIT_FIELD_REF") == 0)
1689 : {
1690 : /* __BIT_FIELD_REF '<' type-name [ ',' number ] '>'
1691 : '(' postfix-expression, integer, integer ')' */
1692 35 : location_t loc = c_parser_peek_token (parser)->location;
1693 35 : c_parser_consume_token (parser);
1694 35 : tree type = c_parser_gimple_typespec (parser);
1695 35 : if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
1696 : {
1697 35 : c_expr op0 = c_parser_gimple_postfix_expression (parser);
1698 35 : c_parser_skip_until_found (parser, CPP_COMMA,
1699 : "expected %<,%>");
1700 35 : c_expr op1 = c_parser_gimple_postfix_expression (parser);
1701 35 : if (TREE_CODE (op1.value) != INTEGER_CST
1702 35 : || !int_fits_type_p (op1.value, bitsizetype))
1703 0 : c_parser_error (parser, "expected constant size");
1704 35 : c_parser_skip_until_found (parser, CPP_COMMA,
1705 : "expected %<,%>");
1706 35 : c_expr op2 = c_parser_gimple_postfix_expression (parser);
1707 35 : if (TREE_CODE (op2.value) != INTEGER_CST
1708 35 : || !int_fits_type_p (op2.value, bitsizetype))
1709 0 : c_parser_error (parser, "expected constant offset");
1710 35 : c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
1711 : "expected %<)%>");
1712 35 : if (type
1713 35 : && op0.value != error_mark_node
1714 35 : && TREE_CODE (op1.value) == INTEGER_CST
1715 35 : && TREE_CODE (op2.value) == INTEGER_CST)
1716 35 : expr.value = build3_loc (loc, BIT_FIELD_REF, type,
1717 : op0.value,
1718 : fold_convert (bitsizetype,
1719 : op1.value),
1720 : fold_convert (bitsizetype,
1721 : op2.value));
1722 : }
1723 : break;
1724 : }
1725 7451 : else if (strcmp (IDENTIFIER_POINTER (id), "_Literal") == 0)
1726 : {
1727 : /* _Literal '(' type-name ')' ( [ '-' ] constant | constructor ) */
1728 423 : c_parser_consume_token (parser);
1729 423 : tree type = NULL_TREE;
1730 423 : if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
1731 : {
1732 423 : struct c_type_name *type_name = c_parser_type_name (parser);
1733 423 : tree tem;
1734 423 : if (type_name)
1735 423 : type = groktypename (type_name, &tem, NULL);
1736 423 : c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
1737 : "expected %<)%>");
1738 : }
1739 423 : if (! type)
1740 : {
1741 0 : c_parser_error (parser, "invalid _Literal");
1742 0 : return expr;
1743 : }
1744 423 : if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
1745 : {
1746 82 : c_parser_consume_token (parser);
1747 82 : if (!AGGREGATE_TYPE_P (type)
1748 82 : && !VECTOR_TYPE_P (type))
1749 : {
1750 0 : c_parser_error (parser, "invalid type for _Literal with "
1751 : "constructor");
1752 0 : c_parser_skip_until_found (parser, CPP_CLOSE_BRACE,
1753 : "expected %<}%>");
1754 0 : return expr;
1755 : }
1756 82 : vec<constructor_elt, va_gc> *v = NULL;
1757 82 : bool constant_p = true;
1758 82 : if (VECTOR_TYPE_P (type)
1759 82 : && !c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
1760 : {
1761 59 : vec_alloc (v, TYPE_VECTOR_SUBPARTS (type).to_constant ());
1762 397 : do
1763 : {
1764 228 : tree val
1765 228 : = c_parser_gimple_postfix_expression (parser).value;
1766 228 : if (! val
1767 228 : || val == error_mark_node
1768 228 : || (! CONSTANT_CLASS_P (val)
1769 : && ! SSA_VAR_P (val)))
1770 : {
1771 0 : c_parser_error (parser, "invalid _Literal");
1772 0 : return expr;
1773 : }
1774 228 : CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, val);
1775 228 : if (! CONSTANT_CLASS_P (val))
1776 83 : constant_p = false;
1777 228 : if (c_parser_next_token_is (parser, CPP_COMMA))
1778 169 : c_parser_consume_token (parser);
1779 : else
1780 : break;
1781 169 : }
1782 : while (1);
1783 : }
1784 82 : if (c_parser_require (parser, CPP_CLOSE_BRACE,
1785 : "expected %<}%>"))
1786 : {
1787 82 : if (v && constant_p)
1788 32 : expr.value = build_vector_from_ctor (type, v);
1789 : else
1790 50 : expr.value = build_constructor (type, v);
1791 : }
1792 : else
1793 : {
1794 0 : c_parser_skip_until_found (parser, CPP_CLOSE_BRACE,
1795 : "expected %<}%>");
1796 0 : return expr;
1797 : }
1798 : }
1799 : else
1800 : {
1801 341 : bool neg_p, addr_p;
1802 341 : if ((neg_p = c_parser_next_token_is (parser, CPP_MINUS)))
1803 22 : c_parser_consume_token (parser);
1804 341 : if ((addr_p = c_parser_next_token_is (parser, CPP_AND)))
1805 87 : c_parser_consume_token (parser);
1806 341 : tree val = c_parser_gimple_postfix_expression (parser).value;
1807 341 : if (! val
1808 341 : || val == error_mark_node
1809 341 : || (!CONSTANT_CLASS_P (val) && !addr_p))
1810 : {
1811 0 : c_parser_error (parser, "invalid _Literal");
1812 0 : return expr;
1813 : }
1814 256 : if (addr_p)
1815 : {
1816 87 : val = build1 (ADDR_EXPR, type, val);
1817 87 : if (!is_gimple_invariant_address (val))
1818 : {
1819 0 : c_parser_error (parser, "invalid _Literal");
1820 0 : return expr;
1821 : }
1822 : }
1823 341 : if (neg_p)
1824 : {
1825 22 : val = const_unop (NEGATE_EXPR, TREE_TYPE (val), val);
1826 22 : if (! val)
1827 : {
1828 0 : c_parser_error (parser, "invalid _Literal");
1829 0 : return expr;
1830 : }
1831 : }
1832 341 : expr.value = fold_convert (type, val);
1833 : }
1834 423 : return expr;
1835 : }
1836 :
1837 : /* SSA name. */
1838 7028 : unsigned version, ver_offset;
1839 7028 : if (! lookup_name (id)
1840 7028 : && c_parser_parse_ssa_name_id (id, &version, &ver_offset))
1841 : {
1842 4797 : c_parser_consume_token (parser);
1843 4797 : expr.value = c_parser_parse_ssa_name (parser, id, NULL_TREE,
1844 : version, ver_offset);
1845 4797 : if (expr.value == error_mark_node)
1846 2 : return expr;
1847 4795 : set_c_expr_source_range (&expr, tok_range);
1848 : /* For default definition SSA names. */
1849 4795 : if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
1850 500 : && c_parser_peek_2nd_token (parser)->type == CPP_NAME
1851 499 : && strcmp ("D",
1852 499 : IDENTIFIER_POINTER
1853 : (c_parser_peek_2nd_token (parser)->value)) == 0
1854 5294 : && c_parser_peek_nth_token (parser, 3)->type == CPP_CLOSE_PAREN)
1855 : {
1856 499 : c_parser_consume_token (parser);
1857 499 : c_parser_consume_token (parser);
1858 499 : c_parser_consume_token (parser);
1859 499 : if (! SSA_NAME_IS_DEFAULT_DEF (expr.value))
1860 : {
1861 313 : if (!SSA_NAME_VAR (expr.value))
1862 : {
1863 1 : error_at (loc, "anonymous SSA name cannot have"
1864 : " default definition");
1865 1 : expr.value = error_mark_node;
1866 1 : return expr;
1867 : }
1868 312 : set_ssa_default_def (cfun, SSA_NAME_VAR (expr.value),
1869 : expr.value);
1870 312 : SSA_NAME_DEF_STMT (expr.value) = gimple_build_nop ();
1871 : }
1872 : }
1873 : }
1874 : else
1875 : {
1876 2231 : c_parser_consume_token (parser);
1877 2231 : expr.value
1878 4462 : = build_external_ref (loc, id,
1879 2231 : (c_parser_peek_token (parser)->type
1880 : == CPP_OPEN_PAREN), &expr.original_type);
1881 2231 : set_c_expr_source_range (&expr, tok_range);
1882 : }
1883 : break;
1884 : }
1885 : /* Fallthru. */
1886 3 : default:
1887 3 : c_parser_error (parser, "expected expression");
1888 3 : expr.set_error ();
1889 3 : break;
1890 : }
1891 9808 : if (expr.value == error_mark_node)
1892 9 : return expr;
1893 9799 : return c_parser_gimple_postfix_expression_after_primary
1894 19249 : (parser, EXPR_LOC_OR_LOC (expr.value, loc), expr);
1895 : }
1896 :
1897 : /* Parse a gimple postfix expression after the initial primary or compound
1898 : literal. */
1899 :
1900 : static struct c_expr
1901 9799 : c_parser_gimple_postfix_expression_after_primary (gimple_parser &parser,
1902 : location_t expr_loc,
1903 : struct c_expr expr)
1904 : {
1905 10186 : location_t start;
1906 10186 : location_t finish;
1907 10186 : tree ident;
1908 10186 : location_t comp_loc;
1909 :
1910 10186 : while (true)
1911 : {
1912 10186 : location_t op_loc = c_parser_peek_token (parser)->location;
1913 10186 : switch (c_parser_peek_token (parser)->type)
1914 : {
1915 234 : case CPP_OPEN_SQUARE:
1916 234 : {
1917 234 : c_parser_consume_token (parser);
1918 234 : tree idx = c_parser_gimple_unary_expression (parser).value;
1919 :
1920 234 : if (! c_parser_require (parser, CPP_CLOSE_SQUARE, "expected %<]%>"))
1921 : {
1922 0 : c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL);
1923 0 : break;
1924 : }
1925 :
1926 234 : start = expr.get_start ();
1927 234 : finish = c_parser_tokens_buf (parser, 0)->location;
1928 234 : expr.value = build_array_ref (op_loc, expr.value, idx);
1929 234 : set_c_expr_source_range (&expr, start, finish);
1930 234 : expr.m_decimal = 0;
1931 :
1932 234 : expr.original_code = ERROR_MARK;
1933 234 : expr.original_type = NULL;
1934 234 : break;
1935 : }
1936 125 : case CPP_OPEN_PAREN:
1937 125 : {
1938 : /* Function call. */
1939 125 : c_parser_consume_token (parser);
1940 125 : auto_vec<tree> exprlist;
1941 125 : if (! c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
1942 26 : c_parser_gimple_expr_list (parser, &exprlist);
1943 125 : c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
1944 : "expected %<)%>");
1945 125 : if (!FUNC_OR_METHOD_TYPE_P (TREE_TYPE (expr.value)))
1946 : {
1947 1 : c_parser_error (parser, "invalid call to non-function");
1948 1 : expr.set_error ();
1949 1 : break;
1950 : }
1951 124 : expr.value = build_call_array_loc
1952 124 : (expr_loc, TREE_TYPE (TREE_TYPE (expr.value)),
1953 150 : expr.value, exprlist.length (), exprlist.address ());
1954 124 : expr.m_decimal = 0;
1955 124 : expr.original_code = ERROR_MARK;
1956 124 : expr.original_type = NULL;
1957 124 : break;
1958 125 : }
1959 20 : case CPP_DOT:
1960 20 : {
1961 : /* Structure element reference. */
1962 20 : c_parser_consume_token (parser);
1963 20 : if (c_parser_next_token_is (parser, CPP_NAME))
1964 : {
1965 20 : c_token *comp_tok = c_parser_peek_token (parser);
1966 20 : ident = comp_tok->value;
1967 20 : comp_loc = comp_tok->location;
1968 : }
1969 : else
1970 : {
1971 0 : c_parser_error (parser, "expected identifier");
1972 0 : expr.set_error ();
1973 0 : expr.original_code = ERROR_MARK;
1974 0 : expr.original_type = NULL;
1975 0 : return expr;
1976 : }
1977 20 : start = expr.get_start ();
1978 20 : finish = c_parser_peek_token (parser)->get_finish ();
1979 20 : c_parser_consume_token (parser);
1980 20 : expr.value = build_component_ref (op_loc, expr.value, ident,
1981 : comp_loc, UNKNOWN_LOCATION);
1982 20 : set_c_expr_source_range (&expr, start, finish);
1983 20 : expr.m_decimal = 0;
1984 20 : expr.original_code = ERROR_MARK;
1985 20 : if (TREE_CODE (expr.value) != COMPONENT_REF)
1986 0 : expr.original_type = NULL;
1987 : else
1988 : {
1989 : /* Remember the original type of a bitfield. */
1990 20 : tree field = TREE_OPERAND (expr.value, 1);
1991 20 : if (TREE_CODE (field) != FIELD_DECL)
1992 0 : expr.original_type = NULL;
1993 : else
1994 20 : expr.original_type = DECL_BIT_FIELD_TYPE (field);
1995 : }
1996 : break;
1997 : }
1998 9 : case CPP_DEREF:
1999 9 : {
2000 : /* Structure element reference. */
2001 9 : if (!POINTER_TYPE_P (TREE_TYPE (expr.value)))
2002 : {
2003 1 : c_parser_error (parser, "dereference of non-pointer");
2004 1 : expr.set_error ();
2005 1 : expr.original_code = ERROR_MARK;
2006 1 : expr.original_type = NULL;
2007 1 : return expr;
2008 : }
2009 8 : c_parser_consume_token (parser);
2010 8 : if (c_parser_next_token_is (parser, CPP_NAME))
2011 : {
2012 8 : c_token *comp_tok = c_parser_peek_token (parser);
2013 8 : ident = comp_tok->value;
2014 8 : comp_loc = comp_tok->location;
2015 : }
2016 : else
2017 : {
2018 0 : c_parser_error (parser, "expected identifier");
2019 0 : expr.set_error ();
2020 0 : expr.original_code = ERROR_MARK;
2021 0 : expr.original_type = NULL;
2022 0 : return expr;
2023 : }
2024 8 : start = expr.get_start ();
2025 8 : finish = c_parser_peek_token (parser)->get_finish ();
2026 8 : c_parser_consume_token (parser);
2027 8 : expr.value = build_component_ref (op_loc,
2028 : build_simple_mem_ref_loc
2029 : (op_loc, expr.value),
2030 : ident, comp_loc,
2031 : expr.get_location ());
2032 8 : set_c_expr_source_range (&expr, start, finish);
2033 8 : expr.m_decimal = 0;
2034 8 : expr.original_code = ERROR_MARK;
2035 8 : if (TREE_CODE (expr.value) != COMPONENT_REF)
2036 0 : expr.original_type = NULL;
2037 : else
2038 : {
2039 : /* Remember the original type of a bitfield. */
2040 8 : tree field = TREE_OPERAND (expr.value, 1);
2041 8 : if (TREE_CODE (field) != FIELD_DECL)
2042 0 : expr.original_type = NULL;
2043 : else
2044 8 : expr.original_type = DECL_BIT_FIELD_TYPE (field);
2045 : }
2046 : break;
2047 : }
2048 9798 : default:
2049 9798 : return expr;
2050 : }
2051 : }
2052 : }
2053 :
2054 : /* Parse expression list.
2055 :
2056 : gimple-expr-list:
2057 : gimple-unary-expression
2058 : gimple-expr-list , gimple-unary-expression
2059 :
2060 : */
2061 :
2062 : static void
2063 31 : c_parser_gimple_expr_list (gimple_parser &parser, vec<tree> *ret)
2064 : {
2065 31 : struct c_expr expr;
2066 :
2067 31 : expr = c_parser_gimple_unary_expression (parser);
2068 31 : ret->safe_push (expr.value);
2069 83 : while (c_parser_next_token_is (parser, CPP_COMMA))
2070 : {
2071 21 : c_parser_consume_token (parser);
2072 21 : expr = c_parser_gimple_unary_expression (parser);
2073 21 : ret->safe_push (expr.value);
2074 : }
2075 31 : }
2076 :
2077 : /* Parse gimple label.
2078 :
2079 : gimple-label:
2080 : identifier :
2081 : case constant-expression :
2082 : default :
2083 :
2084 : */
2085 :
2086 : static void
2087 71 : c_parser_gimple_label (gimple_parser &parser, gimple_seq *seq)
2088 : {
2089 71 : tree name = c_parser_peek_token (parser)->value;
2090 71 : location_t loc1 = c_parser_peek_token (parser)->location;
2091 71 : gcc_assert (c_parser_next_token_is (parser, CPP_NAME));
2092 71 : c_parser_consume_token (parser);
2093 71 : gcc_assert (c_parser_next_token_is (parser, CPP_COLON));
2094 71 : c_parser_consume_token (parser);
2095 71 : tree label = define_label (loc1, name);
2096 71 : if (label)
2097 70 : gimple_seq_add_stmt_without_update (seq, gimple_build_label (label));
2098 71 : return;
2099 : }
2100 :
2101 : /* Parse gimple/RTL pass list.
2102 :
2103 : gimple-or-rtl-pass-list:
2104 : startwith("pass-name")[,{cfg,ssa}]
2105 : */
2106 :
2107 : void
2108 533 : c_parser_gimple_or_rtl_pass_list (c_parser *parser, c_declspecs *specs)
2109 : {
2110 533 : char *pass = NULL;
2111 :
2112 : /* Accept __GIMPLE/__RTL. */
2113 533 : if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
2114 : return;
2115 357 : c_parser_consume_token (parser);
2116 :
2117 357 : specs->entry_bb_count = profile_count::uninitialized ();
2118 852 : while (c_parser_next_token_is (parser, CPP_NAME))
2119 : {
2120 495 : profile_quality quality;
2121 495 : const char *op = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
2122 495 : c_parser_consume_token (parser);
2123 495 : if (! strcmp (op, "startwith"))
2124 : {
2125 158 : if (! c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
2126 0 : return;
2127 158 : if (c_parser_next_token_is_not (parser, CPP_STRING))
2128 : {
2129 0 : error_at (c_parser_peek_token (parser)->location,
2130 : "expected pass name");
2131 0 : return;
2132 : }
2133 158 : pass = xstrdup (TREE_STRING_POINTER
2134 : (c_parser_string_literal (parser, false,
2135 : false).value));
2136 158 : if (! c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<(%>"))
2137 : return;
2138 : }
2139 337 : else if (parse_profile_quality (op, &quality))
2140 : {
2141 85 : tree q;
2142 85 : if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
2143 : return;
2144 :
2145 85 : if (!c_parser_next_token_is (parser, CPP_NUMBER)
2146 85 : || (TREE_CODE (q = c_parser_peek_token (parser)->value)
2147 : != INTEGER_CST))
2148 : {
2149 0 : c_parser_error (parser, "expected count value");
2150 0 : return;
2151 : }
2152 :
2153 85 : specs->entry_bb_count
2154 85 : = profile_count::from_gcov_type (TREE_INT_CST_LOW (q), quality);
2155 85 : c_parser_consume_token (parser);
2156 85 : if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
2157 : return;
2158 : }
2159 252 : else if (specs->declspec_il != cdil_gimple)
2160 : /* Allow only one IL specifier and none on RTL. */
2161 : ;
2162 252 : else if (! strcmp (op, "cfg"))
2163 0 : specs->declspec_il = cdil_gimple_cfg;
2164 252 : else if (! strcmp (op, "ssa"))
2165 252 : specs->declspec_il = cdil_gimple_ssa;
2166 : else
2167 : {
2168 0 : error_at (c_parser_peek_token (parser)->location,
2169 : "invalid operation");
2170 0 : return;
2171 : }
2172 495 : if (c_parser_next_token_is (parser, CPP_COMMA))
2173 216 : c_parser_consume_token (parser);
2174 : }
2175 :
2176 357 : if (! c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
2177 : return;
2178 :
2179 357 : specs->gimple_or_rtl_pass = pass;
2180 : }
2181 :
2182 : /* Parse gimple local declaration.
2183 :
2184 : declaration-specifiers:
2185 : storage-class-specifier declaration-specifiers[opt]
2186 : type-specifier declaration-specifiers[opt]
2187 : type-qualifier declaration-specifiers[opt]
2188 : function-specifier declaration-specifiers[opt]
2189 : alignment-specifier declaration-specifiers[opt]
2190 :
2191 : storage-class-specifier:
2192 : typedef
2193 : extern
2194 : static
2195 : auto
2196 : register
2197 :
2198 : type-specifier:
2199 : void
2200 : char
2201 : short
2202 : int
2203 : long
2204 : float
2205 : double
2206 : signed
2207 : unsigned
2208 : _Bool
2209 : _Complex
2210 :
2211 : type-qualifier:
2212 : const
2213 : restrict
2214 : volatile
2215 : address-space-qualifier
2216 : _Atomic
2217 :
2218 : */
2219 :
2220 : static void
2221 2122 : c_parser_gimple_declaration (gimple_parser &parser)
2222 : {
2223 2122 : struct c_declarator *declarator;
2224 2122 : struct c_declspecs *specs = build_null_declspecs ();
2225 2122 : c_parser_declspecs (parser, specs, true, true, true,
2226 : true, true, true, true, cla_nonabstract_decl);
2227 2122 : finish_declspecs (specs);
2228 :
2229 : /* Provide better error recovery. Note that a type name here is usually
2230 : better diagnosed as a redeclaration. */
2231 2122 : if (c_parser_next_token_starts_declspecs (parser)
2232 2122 : && ! c_parser_next_token_is (parser, CPP_NAME))
2233 : {
2234 0 : c_parser_error (parser, "expected %<;%>");
2235 0 : c_parser_set_error (parser, false);
2236 0 : return;
2237 : }
2238 :
2239 2122 : bool dummy = false;
2240 4244 : declarator = c_parser_declarator (parser,
2241 2122 : specs->typespec_kind != ctsk_none,
2242 : C_DTR_NORMAL, &dummy);
2243 :
2244 2122 : if (!c_parser_next_token_is (parser, CPP_SEMICOLON))
2245 : {
2246 0 : c_parser_error (parser, "expected %<;%>");
2247 0 : return;
2248 : }
2249 2122 : if (declarator)
2250 : {
2251 : /* Handle SSA name decls specially, they do not go into the identifier
2252 : table but we simply build the SSA name for later lookup. */
2253 : unsigned version, ver_offset;
2254 : /* Handle SSA pointer declarations in a very simplistic ways, we
2255 : probably would like to call grokdeclarator in a special mode to
2256 : just build the type of the decl - start_decl already pushes
2257 : the identifier to the bindings for lookup, something we do not
2258 : want. */
2259 : struct c_declarator *id_declarator = declarator;
2260 2291 : while (id_declarator->kind == cdk_pointer)
2261 170 : id_declarator = id_declarator->declarator;
2262 2121 : if (id_declarator->kind == cdk_id
2263 2085 : && (declarator->kind == cdk_pointer
2264 1915 : || is_gimple_reg_type (specs->type))
2265 2077 : && c_parser_parse_ssa_name_id (id_declarator->u.id.id,
2266 : &version, &ver_offset)
2267 : /* The following restricts it to unnamed anonymous SSA names
2268 : which fails parsing of named ones in dumps (we could
2269 : decide to not dump their name for -gimple). */
2270 3428 : && ver_offset == 0)
2271 : {
2272 1258 : struct c_declarator *p = declarator;
2273 1258 : tree type = specs->type;
2274 1375 : while (p->kind == cdk_pointer)
2275 : {
2276 117 : type = build_pointer_type (type);
2277 117 : p = p->declarator;
2278 : }
2279 1258 : c_parser_parse_ssa_name (parser, id_declarator->u.id.id, type,
2280 : version, ver_offset);
2281 : }
2282 : else
2283 : {
2284 863 : tree postfix_attrs = NULL_TREE;
2285 863 : tree all_prefix_attrs = specs->attrs;
2286 863 : specs->attrs = NULL;
2287 863 : tree decl = start_decl (declarator, specs, false,
2288 : chainon (postfix_attrs, all_prefix_attrs));
2289 863 : if (decl)
2290 863 : finish_decl (decl, UNKNOWN_LOCATION, NULL_TREE, NULL_TREE,
2291 : NULL_TREE);
2292 : }
2293 : }
2294 : }
2295 :
2296 : /* Parse gimple goto statement. */
2297 :
2298 : static void
2299 394 : c_parser_gimple_goto_stmt (gimple_parser &parser,
2300 : location_t loc, tree label, gimple_seq *seq)
2301 : {
2302 394 : if (cfun->curr_properties & PROP_cfg)
2303 : {
2304 390 : int dest_index;
2305 390 : profile_probability prob;
2306 390 : if (c_parser_gimple_parse_bb_spec_edge_probability (label, parser,
2307 : &dest_index, &prob))
2308 : {
2309 390 : parser.push_edge (parser.current_bb->index, dest_index,
2310 : EDGE_FALLTHRU, prob);
2311 390 : return;
2312 : }
2313 : }
2314 4 : tree decl = lookup_label_for_goto (loc, label);
2315 4 : gimple_seq_add_stmt_without_update (seq, gimple_build_goto (decl));
2316 : }
2317 :
2318 : /* Parse a parenthesized condition.
2319 : gimple-condition:
2320 : ( gimple-binary-expression ) */
2321 :
2322 : static tree
2323 299 : c_parser_gimple_paren_condition (gimple_parser &parser)
2324 : {
2325 299 : if (! c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
2326 0 : return error_mark_node;
2327 299 : tree cond
2328 299 : = c_parser_gimple_binary_expression (parser, boolean_type_node).value;
2329 299 : if (cond != error_mark_node
2330 298 : && ! COMPARISON_CLASS_P (cond)
2331 6 : && ! CONSTANT_CLASS_P (cond)
2332 : && ! SSA_VAR_P (cond))
2333 : {
2334 1 : c_parser_error (parser, "comparison required");
2335 1 : cond = error_mark_node;
2336 : }
2337 299 : if (! c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
2338 0 : return error_mark_node;
2339 : return cond;
2340 : }
2341 :
2342 : /* Parse gimple try statement.
2343 :
2344 : try-statement:
2345 : try { ... } finally { ... }
2346 : try { ... } finally { ... } else { ... }
2347 :
2348 : This could support try/catch as well, but it's not implemented yet.
2349 : */
2350 :
2351 : static void
2352 4 : c_parser_gimple_try_stmt (gimple_parser &parser, gimple_seq *seq)
2353 : {
2354 4 : gimple_seq tryseq = NULL;
2355 4 : c_parser_consume_token (parser);
2356 4 : c_parser_gimple_compound_statement (parser, &tryseq);
2357 :
2358 4 : if ((c_parser_next_token_is (parser, CPP_KEYWORD)
2359 0 : && c_parser_peek_token (parser)->keyword == RID_AT_FINALLY)
2360 4 : || (c_parser_next_token_is (parser, CPP_NAME)
2361 4 : && c_parser_peek_token (parser)->id_kind == C_ID_ID
2362 4 : && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
2363 : "finally") == 0))
2364 : {
2365 4 : gimple_seq finseq = NULL;
2366 4 : c_parser_consume_token (parser);
2367 4 : c_parser_gimple_compound_statement (parser, &finseq);
2368 :
2369 4 : if (c_parser_next_token_is (parser, CPP_KEYWORD)
2370 4 : && c_parser_peek_token (parser)->keyword == RID_ELSE)
2371 : {
2372 2 : gimple_seq elsseq = NULL;
2373 2 : c_parser_consume_token (parser);
2374 2 : c_parser_gimple_compound_statement (parser, &elsseq);
2375 :
2376 2 : geh_else *stmt = gimple_build_eh_else (finseq, elsseq);
2377 2 : finseq = NULL;
2378 2 : gimple_seq_add_stmt_without_update (&finseq, stmt);
2379 : }
2380 :
2381 4 : gtry *stmt = gimple_build_try (tryseq, finseq, GIMPLE_TRY_FINALLY);
2382 4 : gimple_seq_add_stmt_without_update (seq, stmt);
2383 : }
2384 0 : else if (c_parser_next_token_is (parser, CPP_KEYWORD)
2385 0 : && c_parser_peek_token (parser)->keyword == RID_AT_CATCH)
2386 0 : c_parser_error (parser, "%<catch%> is not supported");
2387 : else
2388 0 : c_parser_error (parser, "expected %<finally%> or %<catch%>");
2389 4 : }
2390 :
2391 : /* Parse gimple if-else statement.
2392 :
2393 : if-statement:
2394 : if ( gimple-binary-expression ) gimple-goto-statement
2395 : if ( gimple-binary-expression ) gimple-goto-statement \
2396 : else gimple-goto-statement
2397 : */
2398 :
2399 : static void
2400 299 : c_parser_gimple_if_stmt (gimple_parser &parser, gimple_seq *seq)
2401 : {
2402 299 : tree t_label = NULL_TREE, f_label = NULL_TREE, label;
2403 299 : location_t loc;
2404 299 : c_parser_consume_token (parser);
2405 299 : tree cond = c_parser_gimple_paren_condition (parser);
2406 :
2407 299 : if (c_parser_next_token_is_keyword (parser, RID_GOTO))
2408 : {
2409 299 : loc = c_parser_peek_token (parser)->location;
2410 299 : c_parser_consume_token (parser);
2411 299 : if (! c_parser_next_token_is (parser, CPP_NAME))
2412 : {
2413 1 : c_parser_error (parser, "expected label");
2414 2 : return;
2415 : }
2416 298 : label = c_parser_peek_token (parser)->value;
2417 298 : c_parser_consume_token (parser);
2418 298 : int dest_index;
2419 298 : profile_probability prob;
2420 298 : if ((cfun->curr_properties & PROP_cfg)
2421 298 : && c_parser_gimple_parse_bb_spec_edge_probability (label, parser,
2422 : &dest_index, &prob))
2423 278 : parser.push_edge (parser.current_bb->index, dest_index,
2424 : EDGE_TRUE_VALUE, prob);
2425 : else
2426 20 : t_label = lookup_label_for_goto (loc, label);
2427 298 : if (! c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
2428 : return;
2429 : }
2430 : else
2431 : {
2432 0 : c_parser_error (parser, "expected goto expression");
2433 0 : return;
2434 : }
2435 :
2436 298 : if (c_parser_next_token_is_keyword (parser, RID_ELSE))
2437 298 : c_parser_consume_token (parser);
2438 : else
2439 : {
2440 0 : c_parser_error (parser, "expected else statement");
2441 0 : return;
2442 : }
2443 :
2444 298 : if (c_parser_next_token_is_keyword (parser, RID_GOTO))
2445 : {
2446 298 : loc = c_parser_peek_token (parser)->location;
2447 298 : c_parser_consume_token (parser);
2448 298 : if (! c_parser_next_token_is (parser, CPP_NAME))
2449 : {
2450 2 : c_parser_error (parser, "expected label");
2451 4 : return;
2452 : }
2453 296 : label = c_parser_peek_token (parser)->value;
2454 296 : c_parser_consume_token (parser);
2455 296 : int dest_index;
2456 296 : profile_probability prob;
2457 296 : if ((cfun->curr_properties & PROP_cfg)
2458 296 : && c_parser_gimple_parse_bb_spec_edge_probability (label, parser,
2459 : &dest_index, &prob))
2460 278 : parser.push_edge (parser.current_bb->index, dest_index,
2461 : EDGE_FALSE_VALUE, prob);
2462 : else
2463 18 : f_label = lookup_label_for_goto (loc, label);
2464 296 : if (! c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
2465 : return;
2466 : }
2467 : else
2468 : {
2469 0 : c_parser_error (parser, "expected goto expression");
2470 0 : return;
2471 : }
2472 :
2473 296 : if (cond != error_mark_node)
2474 294 : gimple_seq_add_stmt_without_update (seq, gimple_build_cond_from_tree (cond, t_label,
2475 : f_label));
2476 : }
2477 :
2478 : /* Parse gimple switch-statement.
2479 :
2480 : gimple-switch-statement:
2481 : switch (gimple-postfix-expression) gimple-case-statement
2482 :
2483 : gimple-case-statement:
2484 : gimple-case-statement
2485 : gimple-label-statement : gimple-goto-statement
2486 : */
2487 :
2488 : static void
2489 5 : c_parser_gimple_switch_stmt (gimple_parser &parser, gimple_seq *seq)
2490 : {
2491 5 : c_expr cond_expr;
2492 5 : tree case_label, label;
2493 5 : auto_vec<tree> labels;
2494 5 : tree default_label = NULL_TREE;
2495 5 : c_parser_consume_token (parser);
2496 :
2497 5 : if (! c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
2498 : return;
2499 5 : cond_expr = c_parser_gimple_postfix_expression (parser);
2500 5 : if (! c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
2501 : return;
2502 :
2503 5 : if (! c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
2504 : return;
2505 :
2506 21 : while (c_parser_next_token_is_not (parser, CPP_CLOSE_BRACE))
2507 : {
2508 16 : if (c_parser_next_token_is (parser, CPP_EOF))
2509 : {
2510 0 : c_parser_error (parser, "expected statement");
2511 0 : return;
2512 : }
2513 :
2514 16 : switch (c_parser_peek_token (parser)->keyword)
2515 : {
2516 11 : case RID_CASE:
2517 11 : {
2518 11 : c_expr exp1;
2519 11 : location_t loc = c_parser_peek_token (parser)->location;
2520 11 : c_parser_consume_token (parser);
2521 :
2522 11 : if (c_parser_next_token_is (parser, CPP_NAME)
2523 11 : || c_parser_peek_token (parser)->type == CPP_NUMBER)
2524 11 : exp1 = c_parser_gimple_postfix_expression (parser);
2525 : else
2526 : {
2527 0 : c_parser_error (parser, "expected expression");
2528 0 : return;
2529 : }
2530 :
2531 11 : if (c_parser_next_token_is (parser, CPP_COLON))
2532 : {
2533 11 : c_parser_consume_token (parser);
2534 11 : if (c_parser_next_token_is (parser, CPP_NAME))
2535 : {
2536 11 : label = c_parser_peek_token (parser)->value;
2537 11 : c_parser_consume_token (parser);
2538 11 : tree decl = lookup_label_for_goto (loc, label);
2539 11 : case_label = build_case_label (exp1.value, NULL_TREE,
2540 : decl);
2541 11 : labels.safe_push (case_label);
2542 11 : if (! c_parser_require (parser, CPP_SEMICOLON,
2543 : "expected %<;%>"))
2544 : return;
2545 : }
2546 0 : else if (! c_parser_require (parser, CPP_NAME,
2547 : "expected label"))
2548 : return;
2549 : }
2550 0 : else if (! c_parser_require (parser, CPP_SEMICOLON,
2551 : "expected %<:%>"))
2552 : return;
2553 11 : break;
2554 : }
2555 5 : case RID_DEFAULT:
2556 5 : {
2557 5 : location_t loc = c_parser_peek_token (parser)->location;
2558 5 : c_parser_consume_token (parser);
2559 5 : if (c_parser_next_token_is (parser, CPP_COLON))
2560 : {
2561 5 : c_parser_consume_token (parser);
2562 5 : if (c_parser_next_token_is (parser, CPP_NAME))
2563 : {
2564 5 : label = c_parser_peek_token (parser)->value;
2565 5 : c_parser_consume_token (parser);
2566 5 : tree decl = lookup_label_for_goto (loc, label);
2567 5 : default_label = build_case_label (NULL_TREE, NULL_TREE,
2568 : decl);
2569 5 : if (! c_parser_require (parser, CPP_SEMICOLON,
2570 : "expected %<;%>"))
2571 : return;
2572 : }
2573 0 : else if (! c_parser_require (parser, CPP_NAME,
2574 : "expected label"))
2575 : return;
2576 : }
2577 0 : else if (! c_parser_require (parser, CPP_SEMICOLON,
2578 : "expected %<:%>"))
2579 : return;
2580 : break;
2581 : }
2582 0 : default:
2583 0 : c_parser_error (parser, "expected case label");
2584 0 : return;
2585 : }
2586 :
2587 : }
2588 5 : if (! c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>"))
2589 : return;
2590 :
2591 5 : if (cond_expr.value != error_mark_node)
2592 : {
2593 4 : gswitch *s = gimple_build_switch (cond_expr.value, default_label, labels);
2594 4 : gimple_seq_add_stmt_without_update (seq, s);
2595 : }
2596 5 : }
2597 :
2598 : /* Parse gimple return statement. */
2599 :
2600 : static void
2601 467 : c_parser_gimple_return_stmt (gimple_parser &parser, gimple_seq *seq)
2602 : {
2603 467 : location_t loc = c_parser_peek_token (parser)->location;
2604 467 : gimple *ret = NULL;
2605 467 : c_parser_consume_token (parser);
2606 467 : if (c_parser_next_token_is (parser, CPP_SEMICOLON))
2607 : {
2608 123 : c_finish_gimple_return (loc, NULL_TREE);
2609 123 : ret = gimple_build_return (NULL);
2610 123 : gimple_seq_add_stmt_without_update (seq, ret);
2611 : }
2612 : else
2613 : {
2614 344 : location_t xloc = c_parser_peek_token (parser)->location;
2615 344 : c_expr expr = c_parser_gimple_unary_expression (parser);
2616 344 : if (expr.value != error_mark_node)
2617 : {
2618 342 : c_finish_gimple_return (xloc, expr.value);
2619 342 : ret = gimple_build_return (expr.value);
2620 342 : gimple_seq_add_stmt_without_update (seq, ret);
2621 : }
2622 : }
2623 467 : }
2624 :
2625 : /* Support function for c_parser_gimple_return_stmt. */
2626 :
2627 : static void
2628 465 : c_finish_gimple_return (location_t loc, tree retval)
2629 : {
2630 465 : tree valtype = TREE_TYPE (TREE_TYPE (current_function_decl));
2631 :
2632 : /* Use the expansion point to handle cases such as returning NULL
2633 : in a function returning void. */
2634 465 : location_t xloc = expansion_point_location_if_in_system_header (loc);
2635 :
2636 465 : if (TREE_THIS_VOLATILE (current_function_decl))
2637 0 : warning_at (xloc, 0,
2638 : "function declared %<noreturn%> has a %<return%> statement");
2639 :
2640 465 : if (! retval)
2641 123 : current_function_returns_null = 1;
2642 342 : else if (valtype == 0 || VOID_TYPE_P (valtype))
2643 : {
2644 0 : current_function_returns_null = 1;
2645 0 : if (TREE_CODE (TREE_TYPE (retval)) != VOID_TYPE)
2646 : {
2647 0 : error_at
2648 0 : (xloc, "%<return%> with a value, in function returning void");
2649 0 : inform (DECL_SOURCE_LOCATION (current_function_decl),
2650 : "declared here");
2651 : }
2652 : }
2653 342 : else if (TREE_CODE (valtype) != TREE_CODE (TREE_TYPE (retval)))
2654 : {
2655 0 : error_at
2656 0 : (xloc, "invalid conversion in return statement");
2657 0 : inform (DECL_SOURCE_LOCATION (current_function_decl),
2658 : "declared here");
2659 : }
2660 465 : return;
2661 : }
|