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