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