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

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