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