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