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