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