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