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