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

source code of gcc/c/gimple-parser.cc