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