1/* Parser for GIMPLE.
2 Copyright (C) 2016-2017 Free Software Foundation, Inc.
3
4This file is part of GCC.
5
6GCC is free software; you can redistribute it and/or modify it under
7the terms of the GNU General Public License as published by the Free
8Software Foundation; either version 3, or (at your option) any later
9version.
10
11GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12WARRANTY; without even the implied warranty of MERCHANTABILITY or
13FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14for more details.
15
16You should have received a copy of the GNU General Public License
17along with GCC; see the file COPYING3. If not see
18<http://www.gnu.org/licenses/>. */
19
20#include "config.h"
21#include "system.h"
22#include "coretypes.h"
23#include "target.h"
24#include "function.h"
25#include "c-tree.h"
26#include "timevar.h"
27#include "stringpool.h"
28#include "cgraph.h"
29#include "attribs.h"
30#include "stor-layout.h"
31#include "varasm.h"
32#include "trans-mem.h"
33#include "c-family/c-pragma.h"
34#include "c-lang.h"
35#include "c-family/c-objc.h"
36#include "plugin.h"
37#include "builtins.h"
38#include "gomp-constants.h"
39#include "c-family/c-indentation.h"
40#include "gimple-expr.h"
41#include "context.h"
42#include "gcc-rich-location.h"
43#include "c-parser.h"
44#include "tree-vrp.h"
45#include "tree-pass.h"
46#include "tree-pretty-print.h"
47#include "tree.h"
48#include "basic-block.h"
49#include "gimple.h"
50#include "gimple-pretty-print.h"
51#include "tree-ssa.h"
52#include "pass_manager.h"
53#include "tree-ssanames.h"
54#include "gimple-ssa.h"
55#include "tree-dfa.h"
56
57
58/* Gimple parsing functions. */
59static bool c_parser_gimple_compound_statement (c_parser *, gimple_seq *);
60static void c_parser_gimple_label (c_parser *, gimple_seq *);
61static void c_parser_gimple_statement (c_parser *, gimple_seq *);
62static struct c_expr c_parser_gimple_binary_expression (c_parser *);
63static struct c_expr c_parser_gimple_unary_expression (c_parser *);
64static struct c_expr c_parser_gimple_postfix_expression (c_parser *);
65static struct c_expr c_parser_gimple_postfix_expression_after_primary (c_parser *,
66 location_t,
67 struct c_expr);
68static void c_parser_gimple_declaration (c_parser *);
69static void c_parser_gimple_goto_stmt (location_t, tree, gimple_seq *);
70static void c_parser_gimple_if_stmt (c_parser *, gimple_seq *);
71static void c_parser_gimple_switch_stmt (c_parser *, gimple_seq *);
72static void c_parser_gimple_return_stmt (c_parser *, gimple_seq *);
73static void c_finish_gimple_return (location_t, tree);
74static tree c_parser_gimple_paren_condition (c_parser *);
75static void c_parser_gimple_expr_list (c_parser *, vec<tree> *);
76
77
78/* Parse the body of a function declaration marked with "__GIMPLE". */
79
80void
81c_parser_parse_gimple_body (c_parser *parser)
82{
83 gimple_seq seq = NULL;
84 gimple_seq body = NULL;
85 tree stmt = push_stmt_list ();
86 push_scope ();
87 location_t loc1 = c_parser_peek_token (parser)->location;
88
89 init_tree_ssa (cfun);
90
91 if (! c_parser_gimple_compound_statement (parser, &seq))
92 {
93 gimple *ret = gimple_build_return (NULL);
94 gimple_seq_add_stmt (&seq, ret);
95 }
96
97 tree block = pop_scope ();
98 stmt = pop_stmt_list (stmt);
99 stmt = c_build_bind_expr (loc1, block, stmt);
100
101 block = DECL_INITIAL (current_function_decl);
102 BLOCK_SUBBLOCKS (block) = NULL_TREE;
103 BLOCK_CHAIN (block) = NULL_TREE;
104 TREE_ASM_WRITTEN (block) = 1;
105
106 gbind *bind_stmt = gimple_build_bind (BIND_EXPR_VARS (stmt), NULL,
107 BIND_EXPR_BLOCK (stmt));
108 gimple_bind_set_body (bind_stmt, seq);
109 gimple_seq_add_stmt (&body, bind_stmt);
110 gimple_set_body (current_function_decl, body);
111
112 /* While we have SSA names in the IL we do not have a CFG built yet
113 and PHIs are represented using a PHI internal function. We do
114 have lowered control flow and exception handling (well, we do not
115 have parser support for EH yet). But as we still have BINDs
116 we have to go through lowering again. */
117 cfun->curr_properties = PROP_gimple_any;
118
119 dump_function (TDI_gimple, current_function_decl);
120}
121
122/* Parse a compound statement in gimple function body.
123
124 gimple-statement:
125 gimple-statement
126 gimple-declaration-statement
127 gimple-if-statement
128 gimple-switch-statement
129 gimple-labeled-statement
130 gimple-expression-statement
131 gimple-goto-statement
132 gimple-phi-statement
133 gimple-return-statement
134*/
135
136static bool
137c_parser_gimple_compound_statement (c_parser *parser, gimple_seq *seq)
138{
139 bool return_p = false;
140
141 if (! c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
142 return false;
143
144 /* A compund statement starts with optional declarations. */
145 while (c_parser_next_tokens_start_declaration (parser))
146 {
147 c_parser_gimple_declaration (parser);
148 if (! c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
149 return false;
150 }
151
152 while (c_parser_next_token_is_not (parser, CPP_CLOSE_BRACE))
153 {
154 if (c_parser_error (parser))
155 {
156 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
157 return return_p;
158 }
159 else if (c_parser_next_token_is (parser, CPP_EOF))
160 {
161 c_parser_error (parser, "expected declaration or statement");
162 return return_p;
163 }
164
165 switch (c_parser_peek_token (parser)->type)
166 {
167 case CPP_KEYWORD:
168 switch (c_parser_peek_token (parser)->keyword)
169 {
170 case RID_IF:
171 c_parser_gimple_if_stmt (parser, seq);
172 break;
173 case RID_SWITCH:
174 c_parser_gimple_switch_stmt (parser, seq);
175 break;
176 case RID_GOTO:
177 {
178 location_t loc = c_parser_peek_token (parser)->location;
179 c_parser_consume_token (parser);
180 if (c_parser_next_token_is (parser, CPP_NAME))
181 {
182 c_parser_gimple_goto_stmt (loc,
183 c_parser_peek_token
184 (parser)->value,
185 seq);
186 c_parser_consume_token (parser);
187 if (! c_parser_require (parser, CPP_SEMICOLON,
188 "expected %<;%>"))
189 return return_p;
190 }
191 }
192 break;
193 case RID_RETURN:
194 return_p = true;
195 c_parser_gimple_return_stmt (parser, seq);
196 if (! c_parser_require (parser, CPP_SEMICOLON,
197 "expected %<;%>"))
198 return return_p;
199 break;
200 default:
201 goto expr_stmt;
202 }
203 break;
204 case CPP_NAME:
205 if (c_parser_peek_2nd_token (parser)->type == CPP_COLON)
206 {
207 c_parser_gimple_label (parser, seq);
208 break;
209 }
210 goto expr_stmt;
211
212 case CPP_SEMICOLON:
213 {
214 /* Empty stmt. */
215 location_t loc = c_parser_peek_token (parser)->location;
216 c_parser_consume_token (parser);
217 gimple *nop = gimple_build_nop ();
218 gimple_set_location (nop, loc);
219 gimple_seq_add_stmt (seq, nop);
220 break;
221 }
222
223 default:
224expr_stmt:
225 c_parser_gimple_statement (parser, seq);
226 if (! c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
227 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
228 }
229 }
230 c_parser_consume_token (parser);
231 return return_p;
232}
233
234/* Parse a gimple statement.
235
236 gimple-statement:
237 gimple-call-expression
238 gimple-assign-statement
239 gimple-phi-statement
240
241 gimple-assign-statement:
242 gimple-unary-expression = gimple-assign-rhs
243
244 gimple-assign-rhs:
245 gimple-cast-expression
246 gimple-unary-expression
247 gimple-binary-expression
248 gimple-call-expression
249
250 gimple-phi-statement:
251 identifier = __PHI ( label : gimple_primary-expression, ... )
252
253 gimple-call-expr:
254 gimple-primary-expression ( argument-list )
255
256 gimple-cast-expression:
257 ( type-name ) gimple-primary-expression
258
259*/
260
261static void
262c_parser_gimple_statement (c_parser *parser, gimple_seq *seq)
263{
264 struct c_expr lhs, rhs;
265 gimple *assign = NULL;
266 location_t loc;
267 tree arg = NULL_TREE;
268 auto_vec<tree> vargs;
269
270 lhs = c_parser_gimple_unary_expression (parser);
271 loc = EXPR_LOCATION (lhs.value);
272 rhs.set_error ();
273
274 /* GIMPLE call statement without LHS. */
275 if (c_parser_next_token_is (parser, CPP_SEMICOLON)
276 && TREE_CODE (lhs.value) == CALL_EXPR)
277 {
278 gimple *call;
279 call = gimple_build_call_from_tree (lhs.value, NULL);
280 gimple_seq_add_stmt (seq, call);
281 gimple_set_location (call, loc);
282 return;
283 }
284
285 /* All following cases are statements with LHS. */
286 if (! c_parser_require (parser, CPP_EQ, "expected %<=%>"))
287 return;
288
289 /* Cast expression. */
290 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
291 && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
292 {
293 c_parser_consume_token (parser);
294 struct c_type_name *type_name = c_parser_type_name (parser);
295 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
296 if (type_name == NULL)
297 return;
298 /* ??? The actual type used in the cast expression is ignored as
299 in GIMPLE it is encoded by the type of the LHS. */
300 rhs = c_parser_gimple_postfix_expression (parser);
301 if (lhs.value != error_mark_node
302 && rhs.value != error_mark_node)
303 {
304 enum tree_code code = NOP_EXPR;
305 if (VECTOR_TYPE_P (TREE_TYPE (lhs.value)))
306 {
307 code = VIEW_CONVERT_EXPR;
308 rhs.value = build1 (VIEW_CONVERT_EXPR,
309 TREE_TYPE (lhs.value), rhs.value);
310 }
311 else if (FLOAT_TYPE_P (TREE_TYPE (lhs.value))
312 && ! FLOAT_TYPE_P (TREE_TYPE (rhs.value)))
313 code = FLOAT_EXPR;
314 else if (! FLOAT_TYPE_P (TREE_TYPE (lhs.value))
315 && FLOAT_TYPE_P (TREE_TYPE (rhs.value)))
316 code = FIX_TRUNC_EXPR;
317 assign = gimple_build_assign (lhs.value, code, rhs.value);
318 gimple_seq_add_stmt (seq, assign);
319 gimple_set_location (assign, loc);
320 return;
321 }
322 }
323
324 /* Unary expression. */
325 switch (c_parser_peek_token (parser)->type)
326 {
327 case CPP_NAME:
328 {
329 tree id = c_parser_peek_token (parser)->value;
330 if (strcmp (IDENTIFIER_POINTER (id), "__ABS") == 0)
331 goto build_unary_expr;
332 break;
333 }
334 case CPP_KEYWORD:
335 if (c_parser_peek_token (parser)->keyword != RID_REALPART
336 && c_parser_peek_token (parser)->keyword != RID_IMAGPART)
337 break;
338 /* Fallthru. */
339 case CPP_AND:
340 case CPP_PLUS:
341 case CPP_MINUS:
342 case CPP_COMPL:
343 case CPP_NOT:
344 case CPP_MULT: /* pointer deref */
345 build_unary_expr:
346 rhs = c_parser_gimple_unary_expression (parser);
347 if (rhs.value != error_mark_node)
348 {
349 assign = gimple_build_assign (lhs.value, rhs.value);
350 gimple_set_location (assign, loc);
351 gimple_seq_add_stmt (seq, assign);
352 }
353 return;
354
355 default:;
356 }
357
358 /* GIMPLE PHI statement. */
359 if (c_parser_next_token_is_keyword (parser, RID_PHI))
360 {
361 c_parser_consume_token (parser);
362
363 if (! c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
364 return;
365
366 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
367 c_parser_consume_token (parser);
368
369 while (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN))
370 {
371 if (c_parser_next_token_is (parser, CPP_NAME)
372 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
373 {
374 arg = lookup_label_for_goto (loc,
375 c_parser_peek_token (parser)->value);
376 c_parser_consume_token (parser);
377
378 if (c_parser_next_token_is (parser, CPP_COLON))
379 c_parser_consume_token (parser);
380 vargs.safe_push (arg);
381 }
382 else if (c_parser_next_token_is (parser, CPP_COMMA))
383 c_parser_consume_token (parser);
384 else
385 {
386 arg = c_parser_gimple_unary_expression (parser).value;
387 vargs.safe_push (arg);
388 }
389 }
390
391 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
392 "expected %<)%>");
393
394 /* Build internal function for PHI. */
395 gcall *call_stmt = gimple_build_call_internal_vec (IFN_PHI, vargs);
396 gimple_call_set_lhs (call_stmt, lhs.value);
397 gimple_set_location (call_stmt, UNKNOWN_LOCATION);
398 gimple_seq_add_stmt (seq, call_stmt);
399 return;
400 }
401
402 /* GIMPLE call with lhs. */
403 if (c_parser_next_token_is (parser, CPP_NAME)
404 && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN
405 && lookup_name (c_parser_peek_token (parser)->value))
406 {
407 rhs = c_parser_gimple_unary_expression (parser);
408 if (rhs.value != error_mark_node)
409 {
410 gimple *call = gimple_build_call_from_tree (rhs.value, NULL);
411 gimple_call_set_lhs (call, lhs.value);
412 gimple_seq_add_stmt (seq, call);
413 gimple_set_location (call, loc);
414 }
415 return;
416 }
417
418 rhs = c_parser_gimple_binary_expression (parser);
419 if (lhs.value != error_mark_node
420 && rhs.value != error_mark_node)
421 {
422 /* If we parsed a comparison and the next token is a '?' then
423 parse a conditional expression. */
424 if (COMPARISON_CLASS_P (rhs.value)
425 && c_parser_next_token_is (parser, CPP_QUERY))
426 {
427 struct c_expr trueval, falseval;
428 c_parser_consume_token (parser);
429 trueval = c_parser_gimple_postfix_expression (parser);
430 falseval.set_error ();
431 if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
432 falseval = c_parser_gimple_postfix_expression (parser);
433 if (trueval.value == error_mark_node
434 || falseval.value == error_mark_node)
435 return;
436 rhs.value = build3_loc (loc, COND_EXPR, TREE_TYPE (trueval.value),
437 rhs.value, trueval.value, falseval.value);
438 }
439 assign = gimple_build_assign (lhs.value, rhs.value);
440 gimple_seq_add_stmt (seq, assign);
441 gimple_set_location (assign, loc);
442 }
443 return;
444}
445
446/* Parse gimple binary expr.
447
448 gimple-binary-expression:
449 gimple-unary-expression * gimple-unary-expression
450 gimple-unary-expression / gimple-unary-expression
451 gimple-unary-expression % gimple-unary-expression
452 gimple-unary-expression + gimple-unary-expression
453 gimple-unary-expression - gimple-unary-expression
454 gimple-unary-expression << gimple-unary-expression
455 gimple-unary-expression >> gimple-unary-expression
456 gimple-unary-expression < gimple-unary-expression
457 gimple-unary-expression > gimple-unary-expression
458 gimple-unary-expression <= gimple-unary-expression
459 gimple-unary-expression >= gimple-unary-expression
460 gimple-unary-expression == gimple-unary-expression
461 gimple-unary-expression != gimple-unary-expression
462 gimple-unary-expression & gimple-unary-expression
463 gimple-unary-expression ^ gimple-unary-expression
464 gimple-unary-expression | gimple-unary-expression
465
466*/
467
468static c_expr
469c_parser_gimple_binary_expression (c_parser *parser)
470{
471 /* Location of the binary operator. */
472 struct c_expr ret, lhs, rhs;
473 enum tree_code code = ERROR_MARK;
474 ret.set_error ();
475 lhs = c_parser_gimple_postfix_expression (parser);
476 if (c_parser_error (parser))
477 return ret;
478 tree ret_type = TREE_TYPE (lhs.value);
479 switch (c_parser_peek_token (parser)->type)
480 {
481 case CPP_MULT:
482 code = MULT_EXPR;
483 break;
484 case CPP_DIV:
485 code = TRUNC_DIV_EXPR;
486 break;
487 case CPP_MOD:
488 code = TRUNC_MOD_EXPR;
489 break;
490 case CPP_PLUS:
491 if (POINTER_TYPE_P (TREE_TYPE (lhs.value)))
492 code = POINTER_PLUS_EXPR;
493 else
494 code = PLUS_EXPR;
495 break;
496 case CPP_MINUS:
497 code = MINUS_EXPR;
498 break;
499 case CPP_LSHIFT:
500 code = LSHIFT_EXPR;
501 break;
502 case CPP_RSHIFT:
503 code = RSHIFT_EXPR;
504 break;
505 case CPP_LESS:
506 code = LT_EXPR;
507 ret_type = boolean_type_node;
508 break;
509 case CPP_GREATER:
510 code = GT_EXPR;
511 ret_type = boolean_type_node;
512 break;
513 case CPP_LESS_EQ:
514 code = LE_EXPR;
515 ret_type = boolean_type_node;
516 break;
517 case CPP_GREATER_EQ:
518 code = GE_EXPR;
519 ret_type = boolean_type_node;
520 break;
521 case CPP_EQ_EQ:
522 code = EQ_EXPR;
523 ret_type = boolean_type_node;
524 break;
525 case CPP_NOT_EQ:
526 code = NE_EXPR;
527 ret_type = boolean_type_node;
528 break;
529 case CPP_AND:
530 code = BIT_AND_EXPR;
531 break;
532 case CPP_XOR:
533 code = BIT_XOR_EXPR;
534 break;
535 case CPP_OR:
536 code = BIT_IOR_EXPR;
537 break;
538 case CPP_AND_AND:
539 c_parser_error (parser, "%<&&%> not valid in GIMPLE");
540 return ret;
541 case CPP_OR_OR:
542 c_parser_error (parser, "%<||%> not valid in GIMPLE");
543 return ret;
544 default:
545 /* Not a binary expression. */
546 return lhs;
547 }
548 location_t ret_loc = c_parser_peek_token (parser)->location;
549 c_parser_consume_token (parser);
550 rhs = c_parser_gimple_postfix_expression (parser);
551 if (lhs.value != error_mark_node && rhs.value != error_mark_node)
552 ret.value = build2_loc (ret_loc, code, ret_type, lhs.value, rhs.value);
553 return ret;
554}
555
556/* Parse gimple unary expression.
557
558 gimple-unary-expression:
559 gimple-postfix-expression
560 unary-operator gimple-postfix-expression
561
562 unary-operator: one of
563 & * + - ~ abs_expr
564*/
565
566static c_expr
567c_parser_gimple_unary_expression (c_parser *parser)
568{
569 struct c_expr ret, op;
570 location_t op_loc = c_parser_peek_token (parser)->location;
571 location_t finish;
572 ret.set_error ();
573 switch (c_parser_peek_token (parser)->type)
574 {
575 case CPP_AND:
576 c_parser_consume_token (parser);
577 op = c_parser_gimple_postfix_expression (parser);
578 mark_exp_read (op.value);
579 return parser_build_unary_op (op_loc, ADDR_EXPR, op);
580 case CPP_MULT:
581 {
582 c_parser_consume_token (parser);
583 op = c_parser_gimple_postfix_expression (parser);
584 if (op.value == error_mark_node)
585 return ret;
586 if (! POINTER_TYPE_P (TREE_TYPE (op.value)))
587 {
588 error_at (op_loc, "expected pointer as argument of unary %<*%>");
589 return ret;
590 }
591 finish = op.get_finish ();
592 location_t combined_loc = make_location (op_loc, op_loc, finish);
593 ret.value = build_simple_mem_ref_loc (combined_loc, op.value);
594 TREE_SIDE_EFFECTS (ret.value)
595 = TREE_THIS_VOLATILE (ret.value)
596 = TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (op.value)));
597 ret.src_range.m_start = op_loc;
598 ret.src_range.m_finish = finish;
599 return ret;
600 }
601 case CPP_PLUS:
602 c_parser_consume_token (parser);
603 op = c_parser_gimple_postfix_expression (parser);
604 return parser_build_unary_op (op_loc, CONVERT_EXPR, op);
605 case CPP_MINUS:
606 c_parser_consume_token (parser);
607 op = c_parser_gimple_postfix_expression (parser);
608 return parser_build_unary_op (op_loc, NEGATE_EXPR, op);
609 case CPP_COMPL:
610 c_parser_consume_token (parser);
611 op = c_parser_gimple_postfix_expression (parser);
612 return parser_build_unary_op (op_loc, BIT_NOT_EXPR, op);
613 case CPP_NOT:
614 c_parser_error (parser, "%<!%> not valid in GIMPLE");
615 return ret;
616 case CPP_KEYWORD:
617 switch (c_parser_peek_token (parser)->keyword)
618 {
619 case RID_REALPART:
620 c_parser_consume_token (parser);
621 op = c_parser_gimple_postfix_expression (parser);
622 return parser_build_unary_op (op_loc, REALPART_EXPR, op);
623 case RID_IMAGPART:
624 c_parser_consume_token (parser);
625 op = c_parser_gimple_postfix_expression (parser);
626 return parser_build_unary_op (op_loc, IMAGPART_EXPR, op);
627 default:
628 return c_parser_gimple_postfix_expression (parser);
629 }
630 case CPP_NAME:
631 {
632 tree id = c_parser_peek_token (parser)->value;
633 if (strcmp (IDENTIFIER_POINTER (id), "__ABS") == 0)
634 {
635 c_parser_consume_token (parser);
636 op = c_parser_gimple_postfix_expression (parser);
637 return parser_build_unary_op (op_loc, ABS_EXPR, op);
638 }
639 else
640 return c_parser_gimple_postfix_expression (parser);
641 }
642 default:
643 return c_parser_gimple_postfix_expression (parser);
644 }
645}
646
647/* Decompose ID into base name (ID until ver_offset) and VERSION. Return
648 true if ID matches a SSA name. */
649
650static bool
651c_parser_parse_ssa_name_id (tree id, unsigned *version, unsigned *ver_offset)
652{
653 const char *token = IDENTIFIER_POINTER (id);
654 const char *var_version = strrchr (token, '_');
655 if (! var_version)
656 return false;
657
658 *ver_offset = var_version - token;
659 for (const char *p = var_version + 1; *p; ++p)
660 if (! ISDIGIT (*p))
661 return false;
662 *version = atoi (var_version + 1);
663 return *version > 0;
664}
665
666/* Get at the actual SSA name ID with VERSION starting at VER_OFFSET.
667 TYPE is the type if the SSA name is being declared. */
668
669static tree
670c_parser_parse_ssa_name (c_parser *parser,
671 tree id, tree type, unsigned version,
672 unsigned ver_offset)
673{
674 tree name = NULL_TREE;
675 const char *token = IDENTIFIER_POINTER (id);
676
677 if (ver_offset == 0)
678 {
679 /* Anonymous unnamed SSA name. */
680 if (version < num_ssa_names)
681 name = ssa_name (version);
682 if (! name)
683 {
684 if (! type)
685 {
686 c_parser_error (parser, "SSA name undeclared");
687 return error_mark_node;
688 }
689 name = make_ssa_name_fn (cfun, type, NULL, version);
690 }
691 }
692 else
693 {
694 if (version < num_ssa_names)
695 name = ssa_name (version);
696 if (! name)
697 {
698 /* Separate var name from version. */
699 char *var_name = XNEWVEC (char, ver_offset + 1);
700 memcpy (var_name, token, ver_offset);
701 var_name[ver_offset] = '\0';
702 /* lookup for parent decl. */
703 id = get_identifier (var_name);
704 tree parent = lookup_name (id);
705 XDELETEVEC (var_name);
706 if (! parent || parent == error_mark_node)
707 {
708 c_parser_error (parser, "base variable or SSA name undeclared");
709 return error_mark_node;
710 }
711 if (!(VAR_P (parent)
712 || TREE_CODE (parent) == PARM_DECL
713 || TREE_CODE (parent) == RESULT_DECL))
714 {
715 error ("invalid base %qE for SSA name", parent);
716 return error_mark_node;
717 }
718 if (VECTOR_TYPE_P (TREE_TYPE (parent))
719 || TREE_CODE (TREE_TYPE (parent)) == COMPLEX_TYPE)
720 DECL_GIMPLE_REG_P (parent) = 1;
721 name = make_ssa_name_fn (cfun, parent,
722 gimple_build_nop (), version);
723 }
724 }
725
726 return name;
727}
728
729/* Parse gimple postfix expression.
730
731 gimple-postfix-expression:
732 gimple-primary-expression
733 gimple-primary-xpression [ gimple-primary-expression ]
734 gimple-primary-expression ( gimple-argument-expression-list[opt] )
735 postfix-expression . identifier
736 postfix-expression -> identifier
737
738 gimple-argument-expression-list:
739 gimple-unary-expression
740 gimple-argument-expression-list , gimple-unary-expression
741
742 gimple-primary-expression:
743 identifier
744 constant
745 string-literal
746
747*/
748
749static struct c_expr
750c_parser_gimple_postfix_expression (c_parser *parser)
751{
752 location_t loc = c_parser_peek_token (parser)->location;
753 source_range tok_range = c_parser_peek_token (parser)->get_range ();
754 struct c_expr expr;
755 expr.set_error ();
756 switch (c_parser_peek_token (parser)->type)
757 {
758 case CPP_NUMBER:
759 expr.value = c_parser_peek_token (parser)->value;
760 set_c_expr_source_range (&expr, tok_range);
761 loc = c_parser_peek_token (parser)->location;
762 c_parser_consume_token (parser);
763 break;
764 case CPP_CHAR:
765 case CPP_CHAR16:
766 case CPP_CHAR32:
767 case CPP_WCHAR:
768 expr.value = c_parser_peek_token (parser)->value;
769 set_c_expr_source_range (&expr, tok_range);
770 c_parser_consume_token (parser);
771 break;
772 case CPP_STRING:
773 case CPP_STRING16:
774 case CPP_STRING32:
775 case CPP_WSTRING:
776 case CPP_UTF8STRING:
777 expr.value = c_parser_peek_token (parser)->value;
778 set_c_expr_source_range (&expr, tok_range);
779 expr.original_code = STRING_CST;
780 c_parser_consume_token (parser);
781 break;
782 case CPP_NAME:
783 if (c_parser_peek_token (parser)->id_kind == C_ID_ID)
784 {
785 tree id = c_parser_peek_token (parser)->value;
786 if (strcmp (IDENTIFIER_POINTER (id), "__MEM") == 0)
787 {
788 /* __MEM '<' type-name [ ',' number ] '>'
789 '(' [ '(' type-name ')' ] unary-expression
790 [ '+' number ] ')' */
791 location_t loc = c_parser_peek_token (parser)->location;
792 c_parser_consume_token (parser);
793 struct c_type_name *type_name = NULL;
794 tree alignment = NULL_TREE;
795 if (c_parser_require (parser, CPP_LESS, "expected %<<%>"))
796 {
797 type_name = c_parser_type_name (parser);
798 /* Optional alignment. */
799 if (c_parser_next_token_is (parser, CPP_COMMA))
800 {
801 c_parser_consume_token (parser);
802 alignment
803 = c_parser_gimple_postfix_expression (parser).value;
804 }
805 c_parser_skip_until_found (parser,
806 CPP_GREATER, "expected %<>%>");
807 }
808 struct c_expr ptr;
809 ptr.value = error_mark_node;
810 tree alias_off = NULL_TREE;
811 if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
812 {
813 tree alias_type = NULL_TREE;
814 /* Optional alias-type cast. */
815 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
816 {
817 c_parser_consume_token (parser);
818 struct c_type_name *alias_type_name
819 = c_parser_type_name (parser);
820 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
821 "expected %<)%>");
822 if (alias_type_name)
823 {
824 tree tem;
825 alias_type = groktypename (alias_type_name,
826 &tem, NULL);
827 }
828 }
829 ptr = c_parser_gimple_unary_expression (parser);
830 if (ptr.value == error_mark_node
831 || ! POINTER_TYPE_P (TREE_TYPE (ptr.value)))
832 {
833 if (ptr.value != error_mark_node)
834 error_at (ptr.get_start (),
835 "invalid type of %<__MEM%> operand");
836 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
837 "expected %<)%>");
838 return expr;
839 }
840 if (! alias_type)
841 alias_type = TREE_TYPE (ptr.value);
842 /* Optional constant offset. */
843 if (c_parser_next_token_is (parser, CPP_PLUS))
844 {
845 c_parser_consume_token (parser);
846 alias_off
847 = c_parser_gimple_postfix_expression (parser).value;
848 alias_off = fold_convert (alias_type, alias_off);
849 }
850 if (! alias_off)
851 alias_off = build_int_cst (alias_type, 0);
852 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
853 "expected %<)%>");
854 }
855 if (! type_name || c_parser_error (parser))
856 {
857 c_parser_set_error (parser, false);
858 return expr;
859 }
860 tree tem = NULL_TREE;
861 tree type = groktypename (type_name, &tem, NULL);
862 if (alignment)
863 type = build_aligned_type (type, tree_to_uhwi (alignment));
864 expr.value = build2_loc (loc, MEM_REF,
865 type, ptr.value, alias_off);
866 break;
867 }
868 else if (strcmp (IDENTIFIER_POINTER (id), "_Literal") == 0)
869 {
870 /* _Literal '(' type-name ')' [ '-' ] constant */
871 c_parser_consume_token (parser);
872 tree type = NULL_TREE;
873 if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
874 {
875 struct c_type_name *type_name = c_parser_type_name (parser);
876 tree tem;
877 if (type_name)
878 type = groktypename (type_name, &tem, NULL);
879 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
880 "expected %<)%>");
881 }
882 bool neg_p;
883 if ((neg_p = c_parser_next_token_is (parser, CPP_MINUS)))
884 c_parser_consume_token (parser);
885 tree val = c_parser_gimple_postfix_expression (parser).value;
886 if (! type
887 || ! val
888 || val == error_mark_node
889 || ! CONSTANT_CLASS_P (val))
890 {
891 c_parser_error (parser, "invalid _Literal");
892 return expr;
893 }
894 if (neg_p)
895 {
896 val = const_unop (NEGATE_EXPR, TREE_TYPE (val), val);
897 if (! val)
898 {
899 c_parser_error (parser, "invalid _Literal");
900 return expr;
901 }
902 }
903 expr.value = fold_convert (type, val);
904 return expr;
905 }
906 else if (strcmp (IDENTIFIER_POINTER (id), "__FMA") == 0)
907 {
908 c_parser_consume_token (parser);
909 auto_vec<tree> args;
910
911 if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
912 {
913 c_parser_gimple_expr_list (parser, &args);
914 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
915 "expected %<)%>");
916 }
917 if (args.length () != 3)
918 {
919 error_at (loc, "invalid number of operands to __FMA");
920 expr.value = error_mark_node;
921 return expr;
922 }
923 expr.value = build3_loc (loc, FMA_EXPR, TREE_TYPE (args[0]),
924 args[0], args[1], args[2]);
925 return expr;
926 }
927
928 /* SSA name. */
929 unsigned version, ver_offset;
930 if (! lookup_name (id)
931 && c_parser_parse_ssa_name_id (id, &version, &ver_offset))
932 {
933 c_parser_consume_token (parser);
934 expr.value = c_parser_parse_ssa_name (parser, id, NULL_TREE,
935 version, ver_offset);
936 if (expr.value == error_mark_node)
937 return expr;
938 set_c_expr_source_range (&expr, tok_range);
939 /* For default definition SSA names. */
940 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
941 && c_parser_peek_2nd_token (parser)->type == CPP_NAME
942 && strcmp ("D",
943 IDENTIFIER_POINTER
944 (c_parser_peek_2nd_token (parser)->value)) == 0
945 && c_parser_peek_nth_token (parser, 3)->type == CPP_CLOSE_PAREN)
946 {
947 c_parser_consume_token (parser);
948 c_parser_consume_token (parser);
949 c_parser_consume_token (parser);
950 if (! SSA_NAME_IS_DEFAULT_DEF (expr.value))
951 {
952 if (!SSA_NAME_VAR (expr.value))
953 {
954 error_at (loc, "anonymous SSA name cannot have"
955 " default definition");
956 expr.value = error_mark_node;
957 return expr;
958 }
959 set_ssa_default_def (cfun, SSA_NAME_VAR (expr.value),
960 expr.value);
961 SSA_NAME_DEF_STMT (expr.value) = gimple_build_nop ();
962 }
963 }
964 }
965 else
966 {
967 c_parser_consume_token (parser);
968 expr.value
969 = build_external_ref (loc, id,
970 (c_parser_peek_token (parser)->type
971 == CPP_OPEN_PAREN), &expr.original_type);
972 set_c_expr_source_range (&expr, tok_range);
973 }
974 break;
975 }
976 else
977 {
978 c_parser_error (parser, "expected expression");
979 expr.set_error ();
980 break;
981 }
982 break;
983 default:
984 c_parser_error (parser, "expected expression");
985 expr.set_error ();
986 break;
987 }
988 return c_parser_gimple_postfix_expression_after_primary
989 (parser, EXPR_LOC_OR_LOC (expr.value, loc), expr);
990}
991
992/* Parse a gimple postfix expression after the initial primary or compound
993 literal. */
994
995static struct c_expr
996c_parser_gimple_postfix_expression_after_primary (c_parser *parser,
997 location_t expr_loc,
998 struct c_expr expr)
999{
1000 location_t start;
1001 location_t finish;
1002 tree ident;
1003 location_t comp_loc;
1004
1005 while (true)
1006 {
1007 location_t op_loc = c_parser_peek_token (parser)->location;
1008 switch (c_parser_peek_token (parser)->type)
1009 {
1010 case CPP_OPEN_SQUARE:
1011 {
1012 c_parser_consume_token (parser);
1013 tree idx = c_parser_gimple_unary_expression (parser).value;
1014
1015 if (! c_parser_require (parser, CPP_CLOSE_SQUARE, "expected %<]%>"))
1016 {
1017 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL);
1018 break;
1019 }
1020
1021 start = expr.get_start ();
1022 finish = c_parser_tokens_buf (parser, 0)->location;
1023 expr.value = build_array_ref (op_loc, expr.value, idx);
1024 set_c_expr_source_range (&expr, start, finish);
1025
1026 expr.original_code = ERROR_MARK;
1027 expr.original_type = NULL;
1028 break;
1029 }
1030 case CPP_OPEN_PAREN:
1031 {
1032 /* Function call. */
1033 c_parser_consume_token (parser);
1034 auto_vec<tree> exprlist;
1035 if (! c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
1036 c_parser_gimple_expr_list (parser, &exprlist);
1037 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
1038 "expected %<)%>");
1039 expr.value = build_call_array_loc
1040 (expr_loc, TREE_TYPE (TREE_TYPE (expr.value)),
1041 expr.value, exprlist.length (), exprlist.address ());
1042 expr.original_code = ERROR_MARK;
1043 expr.original_type = NULL;
1044 break;
1045 }
1046 case CPP_DOT:
1047 {
1048 /* Structure element reference. */
1049 c_parser_consume_token (parser);
1050 if (c_parser_next_token_is (parser, CPP_NAME))
1051 {
1052 c_token *comp_tok = c_parser_peek_token (parser);
1053 ident = comp_tok->value;
1054 comp_loc = comp_tok->location;
1055 }
1056 else
1057 {
1058 c_parser_error (parser, "expected identifier");
1059 expr.set_error ();
1060 expr.original_code = ERROR_MARK;
1061 expr.original_type = NULL;
1062 return expr;
1063 }
1064 start = expr.get_start ();
1065 finish = c_parser_peek_token (parser)->get_finish ();
1066 c_parser_consume_token (parser);
1067 expr.value = build_component_ref (op_loc, expr.value, ident,
1068 comp_loc);
1069 set_c_expr_source_range (&expr, start, finish);
1070 expr.original_code = ERROR_MARK;
1071 if (TREE_CODE (expr.value) != COMPONENT_REF)
1072 expr.original_type = NULL;
1073 else
1074 {
1075 /* Remember the original type of a bitfield. */
1076 tree field = TREE_OPERAND (expr.value, 1);
1077 if (TREE_CODE (field) != FIELD_DECL)
1078 expr.original_type = NULL;
1079 else
1080 expr.original_type = DECL_BIT_FIELD_TYPE (field);
1081 }
1082 break;
1083 }
1084 case CPP_DEREF:
1085 {
1086 /* Structure element reference. */
1087 c_parser_consume_token (parser);
1088 if (c_parser_next_token_is (parser, CPP_NAME))
1089 {
1090 c_token *comp_tok = c_parser_peek_token (parser);
1091 ident = comp_tok->value;
1092 comp_loc = comp_tok->location;
1093 }
1094 else
1095 {
1096 c_parser_error (parser, "expected identifier");
1097 expr.set_error ();
1098 expr.original_code = ERROR_MARK;
1099 expr.original_type = NULL;
1100 return expr;
1101 }
1102 start = expr.get_start ();
1103 finish = c_parser_peek_token (parser)->get_finish ();
1104 c_parser_consume_token (parser);
1105 expr.value = build_component_ref (op_loc,
1106 build_simple_mem_ref_loc
1107 (op_loc, expr.value),
1108 ident, comp_loc);
1109 set_c_expr_source_range (&expr, start, finish);
1110 expr.original_code = ERROR_MARK;
1111 if (TREE_CODE (expr.value) != COMPONENT_REF)
1112 expr.original_type = NULL;
1113 else
1114 {
1115 /* Remember the original type of a bitfield. */
1116 tree field = TREE_OPERAND (expr.value, 1);
1117 if (TREE_CODE (field) != FIELD_DECL)
1118 expr.original_type = NULL;
1119 else
1120 expr.original_type = DECL_BIT_FIELD_TYPE (field);
1121 }
1122 break;
1123 }
1124 default:
1125 return expr;
1126 }
1127 }
1128}
1129
1130/* Parse expression list.
1131
1132 gimple-expr-list:
1133 gimple-unary-expression
1134 gimple-expr-list , gimple-unary-expression
1135
1136 */
1137
1138static void
1139c_parser_gimple_expr_list (c_parser *parser, vec<tree> *ret)
1140{
1141 struct c_expr expr;
1142
1143 expr = c_parser_gimple_unary_expression (parser);
1144 ret->safe_push (expr.value);
1145 while (c_parser_next_token_is (parser, CPP_COMMA))
1146 {
1147 c_parser_consume_token (parser);
1148 expr = c_parser_gimple_unary_expression (parser);
1149 ret->safe_push (expr.value);
1150 }
1151}
1152
1153/* Parse gimple label.
1154
1155 gimple-label:
1156 identifier :
1157 case constant-expression :
1158 default :
1159
1160*/
1161
1162static void
1163c_parser_gimple_label (c_parser *parser, gimple_seq *seq)
1164{
1165 tree name = c_parser_peek_token (parser)->value;
1166 location_t loc1 = c_parser_peek_token (parser)->location;
1167 gcc_assert (c_parser_next_token_is (parser, CPP_NAME));
1168 c_parser_consume_token (parser);
1169 gcc_assert (c_parser_next_token_is (parser, CPP_COLON));
1170 c_parser_consume_token (parser);
1171 tree label = define_label (loc1, name);
1172 gimple_seq_add_stmt (seq, gimple_build_label (label));
1173 return;
1174}
1175
1176/* Parse gimple/RTL pass list.
1177
1178 gimple-or-rtl-pass-list:
1179 startwith("pass-name")
1180 */
1181
1182char *
1183c_parser_gimple_or_rtl_pass_list (c_parser *parser)
1184{
1185 char *pass = NULL;
1186
1187 /* Accept __GIMPLE/__RTL. */
1188 if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
1189 return NULL;
1190 c_parser_consume_token (parser);
1191
1192 if (c_parser_next_token_is (parser, CPP_NAME))
1193 {
1194 const char *op = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
1195 c_parser_consume_token (parser);
1196 if (! strcmp (op, "startwith"))
1197 {
1198 if (! c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
1199 return NULL;
1200 if (c_parser_next_token_is_not (parser, CPP_STRING))
1201 {
1202 error_at (c_parser_peek_token (parser)->location,
1203 "expected pass name");
1204 return NULL;
1205 }
1206 pass = xstrdup (TREE_STRING_POINTER
1207 (c_parser_peek_token (parser)->value));
1208 c_parser_consume_token (parser);
1209 if (! c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
1210 return NULL;
1211 }
1212 else
1213 {
1214 error_at (c_parser_peek_token (parser)->location,
1215 "invalid operation");
1216 return NULL;
1217 }
1218 }
1219
1220 if (! c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
1221 return NULL;
1222
1223 return pass;
1224}
1225
1226/* Parse gimple local declaration.
1227
1228 declaration-specifiers:
1229 storage-class-specifier declaration-specifiers[opt]
1230 type-specifier declaration-specifiers[opt]
1231 type-qualifier declaration-specifiers[opt]
1232 function-specifier declaration-specifiers[opt]
1233 alignment-specifier declaration-specifiers[opt]
1234
1235 storage-class-specifier:
1236 typedef
1237 extern
1238 static
1239 auto
1240 register
1241
1242 type-specifier:
1243 void
1244 char
1245 short
1246 int
1247 long
1248 float
1249 double
1250 signed
1251 unsigned
1252 _Bool
1253 _Complex
1254
1255 type-qualifier:
1256 const
1257 restrict
1258 volatile
1259 address-space-qualifier
1260 _Atomic
1261
1262 */
1263
1264static void
1265c_parser_gimple_declaration (c_parser *parser)
1266{
1267 struct c_declarator *declarator;
1268 struct c_declspecs *specs = build_null_declspecs ();
1269 c_parser_declspecs (parser, specs, true, true, true,
1270 true, true, cla_nonabstract_decl);
1271 finish_declspecs (specs);
1272
1273 /* Provide better error recovery. Note that a type name here is usually
1274 better diagnosed as a redeclaration. */
1275 if (c_parser_next_token_starts_declspecs (parser)
1276 && ! c_parser_next_token_is (parser, CPP_NAME))
1277 {
1278 c_parser_error (parser, "expected %<;%>");
1279 c_parser_set_error (parser, false);
1280 return;
1281 }
1282
1283 bool dummy = false;
1284 declarator = c_parser_declarator (parser,
1285 specs->typespec_kind != ctsk_none,
1286 C_DTR_NORMAL, &dummy);
1287
1288 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
1289 {
1290 /* Handle SSA name decls specially, they do not go into the identifier
1291 table but we simply build the SSA name for later lookup. */
1292 unsigned version, ver_offset;
1293 if (declarator->kind == cdk_id
1294 && is_gimple_reg_type (specs->type)
1295 && c_parser_parse_ssa_name_id (declarator->u.id,
1296 &version, &ver_offset)
1297 /* The following restricts it to unnamed anonymous SSA names
1298 which fails parsing of named ones in dumps (we could
1299 decide to not dump their name for -gimple). */
1300 && ver_offset == 0)
1301 c_parser_parse_ssa_name (parser, declarator->u.id, specs->type,
1302 version, ver_offset);
1303 else
1304 {
1305 tree postfix_attrs = NULL_TREE;
1306 tree all_prefix_attrs = specs->attrs;
1307 specs->attrs = NULL;
1308 tree decl = start_decl (declarator, specs, false,
1309 chainon (postfix_attrs, all_prefix_attrs));
1310 if (decl)
1311 finish_decl (decl, UNKNOWN_LOCATION, NULL_TREE, NULL_TREE,
1312 NULL_TREE);
1313 }
1314 }
1315 else
1316 {
1317 c_parser_error (parser, "expected %<;%>");
1318 return;
1319 }
1320}
1321
1322/* Parse gimple goto statement. */
1323
1324static void
1325c_parser_gimple_goto_stmt (location_t loc, tree label, gimple_seq *seq)
1326{
1327 tree decl = lookup_label_for_goto (loc, label);
1328 gimple_seq_add_stmt (seq, gimple_build_goto (decl));
1329 return;
1330}
1331
1332/* Parse a parenthesized condition.
1333 gimple-condition:
1334 ( gimple-binary-expression ) */
1335
1336static tree
1337c_parser_gimple_paren_condition (c_parser *parser)
1338{
1339 if (! c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
1340 return error_mark_node;
1341 tree cond = c_parser_gimple_binary_expression (parser).value;
1342 if (! c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
1343 return error_mark_node;
1344 return cond;
1345}
1346
1347/* Parse gimple if-else statement.
1348
1349 if-statement:
1350 if ( gimple-binary-expression ) gimple-goto-statement
1351 if ( gimple-binary-expression ) gimple-goto-statement \
1352 else gimple-goto-statement
1353 */
1354
1355static void
1356c_parser_gimple_if_stmt (c_parser *parser, gimple_seq *seq)
1357{
1358 tree t_label, f_label, label;
1359 location_t loc;
1360 c_parser_consume_token (parser);
1361 tree cond = c_parser_gimple_paren_condition (parser);
1362
1363 if (c_parser_next_token_is_keyword (parser, RID_GOTO))
1364 {
1365 loc = c_parser_peek_token (parser)->location;
1366 c_parser_consume_token (parser);
1367 if (! c_parser_next_token_is (parser, CPP_NAME))
1368 {
1369 c_parser_error (parser, "expected label");
1370 return;
1371 }
1372 label = c_parser_peek_token (parser)->value;
1373 c_parser_consume_token (parser);
1374 t_label = lookup_label_for_goto (loc, label);
1375 if (! c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
1376 return;
1377 }
1378 else
1379 {
1380 c_parser_error (parser, "expected goto expression");
1381 return;
1382 }
1383
1384 if (c_parser_next_token_is_keyword (parser, RID_ELSE))
1385 c_parser_consume_token (parser);
1386 else
1387 {
1388 c_parser_error (parser, "expected else statement");
1389 return;
1390 }
1391
1392 if (c_parser_next_token_is_keyword (parser, RID_GOTO))
1393 {
1394 loc = c_parser_peek_token (parser)->location;
1395 c_parser_consume_token (parser);
1396 if (! c_parser_next_token_is (parser, CPP_NAME))
1397 {
1398 c_parser_error (parser, "expected label");
1399 return;
1400 }
1401 label = c_parser_peek_token (parser)->value;
1402 f_label = lookup_label_for_goto (loc, label);
1403 c_parser_consume_token (parser);
1404 if (! c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
1405 return;
1406 }
1407 else
1408 {
1409 c_parser_error (parser, "expected goto expression");
1410 return;
1411 }
1412
1413 if (cond != error_mark_node)
1414 gimple_seq_add_stmt (seq, gimple_build_cond_from_tree (cond, t_label,
1415 f_label));
1416}
1417
1418/* Parse gimple switch-statement.
1419
1420 gimple-switch-statement:
1421 switch (gimple-postfix-expression) gimple-case-statement
1422
1423 gimple-case-statement:
1424 gimple-case-statement
1425 gimple-label-statement : gimple-goto-statment
1426*/
1427
1428static void
1429c_parser_gimple_switch_stmt (c_parser *parser, gimple_seq *seq)
1430{
1431 c_expr cond_expr;
1432 tree case_label, label;
1433 auto_vec<tree> labels;
1434 tree default_label = NULL_TREE;
1435 gimple_seq switch_body = NULL;
1436 c_parser_consume_token (parser);
1437
1438 if (! c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
1439 return;
1440 cond_expr = c_parser_gimple_postfix_expression (parser);
1441 if (! c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
1442 return;
1443
1444 if (! c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
1445 return;
1446
1447 while (c_parser_next_token_is_not (parser, CPP_CLOSE_BRACE))
1448 {
1449 if (c_parser_next_token_is (parser, CPP_EOF))
1450 {
1451 c_parser_error (parser, "expected statement");
1452 return;
1453 }
1454
1455 switch (c_parser_peek_token (parser)->keyword)
1456 {
1457 case RID_CASE:
1458 {
1459 c_expr exp1;
1460 location_t loc = c_parser_peek_token (parser)->location;
1461 c_parser_consume_token (parser);
1462
1463 if (c_parser_next_token_is (parser, CPP_NAME)
1464 || c_parser_peek_token (parser)->type == CPP_NUMBER)
1465 exp1 = c_parser_gimple_postfix_expression (parser);
1466 else
1467 {
1468 c_parser_error (parser, "expected expression");
1469 return;
1470 }
1471
1472 if (c_parser_next_token_is (parser, CPP_COLON))
1473 {
1474 c_parser_consume_token (parser);
1475 if (c_parser_next_token_is (parser, CPP_NAME))
1476 {
1477 label = c_parser_peek_token (parser)->value;
1478 c_parser_consume_token (parser);
1479 tree decl = lookup_label_for_goto (loc, label);
1480 case_label = build_case_label (exp1.value, NULL_TREE,
1481 decl);
1482 labels.safe_push (case_label);
1483 if (! c_parser_require (parser, CPP_SEMICOLON,
1484 "expected %<;%>"))
1485 return;
1486 }
1487 else if (! c_parser_require (parser, CPP_NAME,
1488 "expected label"))
1489 return;
1490 }
1491 else if (! c_parser_require (parser, CPP_SEMICOLON,
1492 "expected %<:%>"))
1493 return;
1494 break;
1495 }
1496 case RID_DEFAULT:
1497 {
1498 location_t loc = c_parser_peek_token (parser)->location;
1499 c_parser_consume_token (parser);
1500 if (c_parser_next_token_is (parser, CPP_COLON))
1501 {
1502 c_parser_consume_token (parser);
1503 if (c_parser_next_token_is (parser, CPP_NAME))
1504 {
1505 label = c_parser_peek_token (parser)->value;
1506 c_parser_consume_token (parser);
1507 tree decl = lookup_label_for_goto (loc, label);
1508 default_label = build_case_label (NULL_TREE, NULL_TREE,
1509 decl);
1510 if (! c_parser_require (parser, CPP_SEMICOLON,
1511 "expected %<;%>"))
1512 return;
1513 }
1514 else if (! c_parser_require (parser, CPP_NAME,
1515 "expected label"))
1516 return;
1517 }
1518 else if (! c_parser_require (parser, CPP_SEMICOLON,
1519 "expected %<:%>"))
1520 return;
1521 break;
1522 }
1523 case RID_GOTO:
1524 {
1525 location_t loc = c_parser_peek_token (parser)->location;
1526 c_parser_consume_token (parser);
1527 if (c_parser_next_token_is (parser, CPP_NAME))
1528 {
1529 c_parser_gimple_goto_stmt (loc,
1530 c_parser_peek_token
1531 (parser)->value,
1532 &switch_body);
1533 c_parser_consume_token (parser);
1534 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
1535 c_parser_consume_token (parser);
1536 else
1537 {
1538 c_parser_error (parser, "expected semicolon");
1539 return;
1540 }
1541 }
1542 else if (! c_parser_require (parser, CPP_NAME,
1543 "expected label"))
1544 return;
1545 break;
1546 }
1547 default:
1548 c_parser_error (parser, "expected case label or goto statement");
1549 return;
1550 }
1551
1552 }
1553 if (! c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>"))
1554 return;
1555
1556 if (cond_expr.value != error_mark_node)
1557 {
1558 gimple_seq_add_stmt (seq, gimple_build_switch (cond_expr.value,
1559 default_label, labels));
1560 gimple_seq_add_seq (seq, switch_body);
1561 }
1562}
1563
1564/* Parse gimple return statement. */
1565
1566static void
1567c_parser_gimple_return_stmt (c_parser *parser, gimple_seq *seq)
1568{
1569 location_t loc = c_parser_peek_token (parser)->location;
1570 gimple *ret = NULL;
1571 c_parser_consume_token (parser);
1572 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
1573 {
1574 c_finish_gimple_return (loc, NULL_TREE);
1575 ret = gimple_build_return (NULL);
1576 gimple_seq_add_stmt (seq, ret);
1577 }
1578 else
1579 {
1580 location_t xloc = c_parser_peek_token (parser)->location;
1581 c_expr expr = c_parser_gimple_unary_expression (parser);
1582 if (expr.value != error_mark_node)
1583 {
1584 c_finish_gimple_return (xloc, expr.value);
1585 ret = gimple_build_return (expr.value);
1586 gimple_seq_add_stmt (seq, ret);
1587 }
1588 }
1589}
1590
1591/* Support function for c_parser_gimple_return_stmt. */
1592
1593static void
1594c_finish_gimple_return (location_t loc, tree retval)
1595{
1596 tree valtype = TREE_TYPE (TREE_TYPE (current_function_decl));
1597
1598 /* Use the expansion point to handle cases such as returning NULL
1599 in a function returning void. */
1600 source_location xloc = expansion_point_location_if_in_system_header (loc);
1601
1602 if (TREE_THIS_VOLATILE (current_function_decl))
1603 warning_at (xloc, 0,
1604 "function declared %<noreturn%> has a %<return%> statement");
1605
1606 if (! retval)
1607 current_function_returns_null = 1;
1608 else if (valtype == 0 || TREE_CODE (valtype) == VOID_TYPE)
1609 {
1610 current_function_returns_null = 1;
1611 if (TREE_CODE (TREE_TYPE (retval)) != VOID_TYPE)
1612 {
1613 error_at
1614 (xloc, "%<return%> with a value, in function returning void");
1615 inform (DECL_SOURCE_LOCATION (current_function_decl),
1616 "declared here");
1617 }
1618 }
1619 else if (TREE_CODE (valtype) != TREE_CODE (TREE_TYPE (retval)))
1620 {
1621 error_at
1622 (xloc, "invalid conversion in return statement");
1623 inform (DECL_SOURCE_LOCATION (current_function_decl),
1624 "declared here");
1625 }
1626 return;
1627}
1628