comparison gcc/c/gimple-parser.c @ 111:04ced10e8804

gcc 7
author kono
date Fri, 27 Oct 2017 22:46:09 +0900
parents
children 84e7813d76e9
comparison
equal deleted inserted replaced
68:561a7518be6b 111:04ced10e8804
1 /* Parser for GIMPLE.
2 Copyright (C) 2016-2017 Free Software Foundation, Inc.
3
4 This file is part of GCC.
5
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
10
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 for more details.
15
16 You should have received a copy of the GNU General Public License
17 along 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. */
59 static bool c_parser_gimple_compound_statement (c_parser *, gimple_seq *);
60 static void c_parser_gimple_label (c_parser *, gimple_seq *);
61 static void c_parser_gimple_statement (c_parser *, gimple_seq *);
62 static struct c_expr c_parser_gimple_binary_expression (c_parser *);
63 static struct c_expr c_parser_gimple_unary_expression (c_parser *);
64 static struct c_expr c_parser_gimple_postfix_expression (c_parser *);
65 static struct c_expr c_parser_gimple_postfix_expression_after_primary (c_parser *,
66 location_t,
67 struct c_expr);
68 static void c_parser_gimple_declaration (c_parser *);
69 static void c_parser_gimple_goto_stmt (location_t, tree, gimple_seq *);
70 static void c_parser_gimple_if_stmt (c_parser *, gimple_seq *);
71 static void c_parser_gimple_switch_stmt (c_parser *, gimple_seq *);
72 static void c_parser_gimple_return_stmt (c_parser *, gimple_seq *);
73 static void c_finish_gimple_return (location_t, tree);
74 static tree c_parser_gimple_paren_condition (c_parser *);
75 static void c_parser_gimple_expr_list (c_parser *, vec<tree> *);
76
77
78 /* Parse the body of a function declaration marked with "__GIMPLE". */
79
80 void
81 c_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
136 static bool
137 c_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:
224 expr_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
261 static void
262 c_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 assign = gimple_build_assign (lhs.value, rhs.value);
423 gimple_seq_add_stmt (seq, assign);
424 gimple_set_location (assign, loc);
425 }
426 return;
427 }
428
429 /* Parse gimple binary expr.
430
431 gimple-binary-expression:
432 gimple-unary-expression * gimple-unary-expression
433 gimple-unary-expression / gimple-unary-expression
434 gimple-unary-expression % gimple-unary-expression
435 gimple-unary-expression + gimple-unary-expression
436 gimple-unary-expression - gimple-unary-expression
437 gimple-unary-expression << gimple-unary-expression
438 gimple-unary-expression >> gimple-unary-expression
439 gimple-unary-expression < gimple-unary-expression
440 gimple-unary-expression > gimple-unary-expression
441 gimple-unary-expression <= gimple-unary-expression
442 gimple-unary-expression >= gimple-unary-expression
443 gimple-unary-expression == gimple-unary-expression
444 gimple-unary-expression != gimple-unary-expression
445 gimple-unary-expression & gimple-unary-expression
446 gimple-unary-expression ^ gimple-unary-expression
447 gimple-unary-expression | gimple-unary-expression
448
449 */
450
451 static c_expr
452 c_parser_gimple_binary_expression (c_parser *parser)
453 {
454 /* Location of the binary operator. */
455 struct c_expr ret, lhs, rhs;
456 enum tree_code code = ERROR_MARK;
457 ret.set_error ();
458 lhs = c_parser_gimple_postfix_expression (parser);
459 if (c_parser_error (parser))
460 return ret;
461 tree ret_type = TREE_TYPE (lhs.value);
462 switch (c_parser_peek_token (parser)->type)
463 {
464 case CPP_MULT:
465 code = MULT_EXPR;
466 break;
467 case CPP_DIV:
468 code = TRUNC_DIV_EXPR;
469 break;
470 case CPP_MOD:
471 code = TRUNC_MOD_EXPR;
472 break;
473 case CPP_PLUS:
474 if (POINTER_TYPE_P (TREE_TYPE (lhs.value)))
475 code = POINTER_PLUS_EXPR;
476 else
477 code = PLUS_EXPR;
478 break;
479 case CPP_MINUS:
480 code = MINUS_EXPR;
481 break;
482 case CPP_LSHIFT:
483 code = LSHIFT_EXPR;
484 break;
485 case CPP_RSHIFT:
486 code = RSHIFT_EXPR;
487 break;
488 case CPP_LESS:
489 code = LT_EXPR;
490 ret_type = boolean_type_node;
491 break;
492 case CPP_GREATER:
493 code = GT_EXPR;
494 ret_type = boolean_type_node;
495 break;
496 case CPP_LESS_EQ:
497 code = LE_EXPR;
498 ret_type = boolean_type_node;
499 break;
500 case CPP_GREATER_EQ:
501 code = GE_EXPR;
502 ret_type = boolean_type_node;
503 break;
504 case CPP_EQ_EQ:
505 code = EQ_EXPR;
506 ret_type = boolean_type_node;
507 break;
508 case CPP_NOT_EQ:
509 code = NE_EXPR;
510 ret_type = boolean_type_node;
511 break;
512 case CPP_AND:
513 code = BIT_AND_EXPR;
514 break;
515 case CPP_XOR:
516 code = BIT_XOR_EXPR;
517 break;
518 case CPP_OR:
519 code = BIT_IOR_EXPR;
520 break;
521 case CPP_AND_AND:
522 c_parser_error (parser, "%<&&%> not valid in GIMPLE");
523 return ret;
524 case CPP_OR_OR:
525 c_parser_error (parser, "%<||%> not valid in GIMPLE");
526 return ret;
527 default:
528 /* Not a binary expression. */
529 return lhs;
530 }
531 location_t ret_loc = c_parser_peek_token (parser)->location;
532 c_parser_consume_token (parser);
533 rhs = c_parser_gimple_postfix_expression (parser);
534 if (lhs.value != error_mark_node && rhs.value != error_mark_node)
535 ret.value = build2_loc (ret_loc, code, ret_type, lhs.value, rhs.value);
536 return ret;
537 }
538
539 /* Parse gimple unary expression.
540
541 gimple-unary-expression:
542 gimple-postfix-expression
543 unary-operator gimple-postfix-expression
544
545 unary-operator: one of
546 & * + - ~ abs_expr
547 */
548
549 static c_expr
550 c_parser_gimple_unary_expression (c_parser *parser)
551 {
552 struct c_expr ret, op;
553 location_t op_loc = c_parser_peek_token (parser)->location;
554 location_t finish;
555 ret.set_error ();
556 switch (c_parser_peek_token (parser)->type)
557 {
558 case CPP_AND:
559 c_parser_consume_token (parser);
560 op = c_parser_gimple_postfix_expression (parser);
561 mark_exp_read (op.value);
562 return parser_build_unary_op (op_loc, ADDR_EXPR, op);
563 case CPP_MULT:
564 {
565 c_parser_consume_token (parser);
566 op = c_parser_gimple_postfix_expression (parser);
567 if (op.value == error_mark_node)
568 return ret;
569 if (! POINTER_TYPE_P (TREE_TYPE (op.value)))
570 {
571 error_at (op_loc, "expected pointer as argument of unary %<*%>");
572 return ret;
573 }
574 finish = op.get_finish ();
575 location_t combined_loc = make_location (op_loc, op_loc, finish);
576 ret.value = build_simple_mem_ref_loc (combined_loc, op.value);
577 TREE_SIDE_EFFECTS (ret.value)
578 = TREE_THIS_VOLATILE (ret.value)
579 = TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (op.value)));
580 ret.src_range.m_start = op_loc;
581 ret.src_range.m_finish = finish;
582 return ret;
583 }
584 case CPP_PLUS:
585 c_parser_consume_token (parser);
586 op = c_parser_gimple_postfix_expression (parser);
587 return parser_build_unary_op (op_loc, CONVERT_EXPR, op);
588 case CPP_MINUS:
589 c_parser_consume_token (parser);
590 op = c_parser_gimple_postfix_expression (parser);
591 return parser_build_unary_op (op_loc, NEGATE_EXPR, op);
592 case CPP_COMPL:
593 c_parser_consume_token (parser);
594 op = c_parser_gimple_postfix_expression (parser);
595 return parser_build_unary_op (op_loc, BIT_NOT_EXPR, op);
596 case CPP_NOT:
597 c_parser_error (parser, "%<!%> not valid in GIMPLE");
598 return ret;
599 case CPP_KEYWORD:
600 switch (c_parser_peek_token (parser)->keyword)
601 {
602 case RID_REALPART:
603 c_parser_consume_token (parser);
604 op = c_parser_gimple_postfix_expression (parser);
605 return parser_build_unary_op (op_loc, REALPART_EXPR, op);
606 case RID_IMAGPART:
607 c_parser_consume_token (parser);
608 op = c_parser_gimple_postfix_expression (parser);
609 return parser_build_unary_op (op_loc, IMAGPART_EXPR, op);
610 default:
611 return c_parser_gimple_postfix_expression (parser);
612 }
613 case CPP_NAME:
614 {
615 tree id = c_parser_peek_token (parser)->value;
616 if (strcmp (IDENTIFIER_POINTER (id), "__ABS") == 0)
617 {
618 c_parser_consume_token (parser);
619 op = c_parser_gimple_postfix_expression (parser);
620 return parser_build_unary_op (op_loc, ABS_EXPR, op);
621 }
622 else
623 return c_parser_gimple_postfix_expression (parser);
624 }
625 default:
626 return c_parser_gimple_postfix_expression (parser);
627 }
628 }
629
630 /* Decompose ID into base name (ID until ver_offset) and VERSION. Return
631 true if ID matches a SSA name. */
632
633 static bool
634 c_parser_parse_ssa_name_id (tree id, unsigned *version, unsigned *ver_offset)
635 {
636 const char *token = IDENTIFIER_POINTER (id);
637 const char *var_version = strrchr (token, '_');
638 if (! var_version)
639 return false;
640
641 *ver_offset = var_version - token;
642 for (const char *p = var_version + 1; *p; ++p)
643 if (! ISDIGIT (*p))
644 return false;
645 *version = atoi (var_version + 1);
646 return *version > 0;
647 }
648
649 /* Get at the actual SSA name ID with VERSION starting at VER_OFFSET.
650 TYPE is the type if the SSA name is being declared. */
651
652 static tree
653 c_parser_parse_ssa_name (c_parser *parser,
654 tree id, tree type, unsigned version,
655 unsigned ver_offset)
656 {
657 tree name = NULL_TREE;
658 const char *token = IDENTIFIER_POINTER (id);
659
660 if (ver_offset == 0)
661 {
662 /* Anonymous unnamed SSA name. */
663 if (version < num_ssa_names)
664 name = ssa_name (version);
665 if (! name)
666 {
667 if (! type)
668 {
669 c_parser_error (parser, "SSA name undeclared");
670 return error_mark_node;
671 }
672 name = make_ssa_name_fn (cfun, type, NULL, version);
673 }
674 }
675 else
676 {
677 if (version < num_ssa_names)
678 name = ssa_name (version);
679 if (! name)
680 {
681 /* Separate var name from version. */
682 char *var_name = XNEWVEC (char, ver_offset + 1);
683 memcpy (var_name, token, ver_offset);
684 var_name[ver_offset] = '\0';
685 /* lookup for parent decl. */
686 id = get_identifier (var_name);
687 tree parent = lookup_name (id);
688 XDELETEVEC (var_name);
689 if (! parent || parent == error_mark_node)
690 {
691 c_parser_error (parser, "base variable or SSA name undeclared");
692 return error_mark_node;
693 }
694 if (!(VAR_P (parent)
695 || TREE_CODE (parent) == PARM_DECL
696 || TREE_CODE (parent) == RESULT_DECL))
697 {
698 error ("invalid base %qE for SSA name", parent);
699 return error_mark_node;
700 }
701 if (VECTOR_TYPE_P (TREE_TYPE (parent))
702 || TREE_CODE (TREE_TYPE (parent)) == COMPLEX_TYPE)
703 DECL_GIMPLE_REG_P (parent) = 1;
704 name = make_ssa_name_fn (cfun, parent,
705 gimple_build_nop (), version);
706 }
707 }
708
709 return name;
710 }
711
712 /* Parse gimple postfix expression.
713
714 gimple-postfix-expression:
715 gimple-primary-expression
716 gimple-primary-xpression [ gimple-primary-expression ]
717 gimple-primary-expression ( gimple-argument-expression-list[opt] )
718 postfix-expression . identifier
719 postfix-expression -> identifier
720
721 gimple-argument-expression-list:
722 gimple-unary-expression
723 gimple-argument-expression-list , gimple-unary-expression
724
725 gimple-primary-expression:
726 identifier
727 constant
728 string-literal
729
730 */
731
732 static struct c_expr
733 c_parser_gimple_postfix_expression (c_parser *parser)
734 {
735 location_t loc = c_parser_peek_token (parser)->location;
736 source_range tok_range = c_parser_peek_token (parser)->get_range ();
737 struct c_expr expr;
738 expr.set_error ();
739 switch (c_parser_peek_token (parser)->type)
740 {
741 case CPP_NUMBER:
742 expr.value = c_parser_peek_token (parser)->value;
743 set_c_expr_source_range (&expr, tok_range);
744 loc = c_parser_peek_token (parser)->location;
745 c_parser_consume_token (parser);
746 break;
747 case CPP_CHAR:
748 case CPP_CHAR16:
749 case CPP_CHAR32:
750 case CPP_WCHAR:
751 expr.value = c_parser_peek_token (parser)->value;
752 set_c_expr_source_range (&expr, tok_range);
753 c_parser_consume_token (parser);
754 break;
755 case CPP_STRING:
756 case CPP_STRING16:
757 case CPP_STRING32:
758 case CPP_WSTRING:
759 case CPP_UTF8STRING:
760 expr.value = c_parser_peek_token (parser)->value;
761 set_c_expr_source_range (&expr, tok_range);
762 expr.original_code = STRING_CST;
763 c_parser_consume_token (parser);
764 break;
765 case CPP_NAME:
766 if (c_parser_peek_token (parser)->id_kind == C_ID_ID)
767 {
768 tree id = c_parser_peek_token (parser)->value;
769 if (strcmp (IDENTIFIER_POINTER (id), "__MEM") == 0)
770 {
771 /* __MEM '<' type-name [ ',' number ] '>'
772 '(' [ '(' type-name ')' ] unary-expression
773 [ '+' number ] ')' */
774 location_t loc = c_parser_peek_token (parser)->location;
775 c_parser_consume_token (parser);
776 struct c_type_name *type_name = NULL;
777 tree alignment = NULL_TREE;
778 if (c_parser_require (parser, CPP_LESS, "expected %<<%>"))
779 {
780 type_name = c_parser_type_name (parser);
781 /* Optional alignment. */
782 if (c_parser_next_token_is (parser, CPP_COMMA))
783 {
784 c_parser_consume_token (parser);
785 alignment
786 = c_parser_gimple_postfix_expression (parser).value;
787 }
788 c_parser_skip_until_found (parser,
789 CPP_GREATER, "expected %<>%>");
790 }
791 struct c_expr ptr;
792 ptr.value = error_mark_node;
793 tree alias_off = NULL_TREE;
794 if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
795 {
796 tree alias_type = NULL_TREE;
797 /* Optional alias-type cast. */
798 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
799 {
800 c_parser_consume_token (parser);
801 struct c_type_name *alias_type_name
802 = c_parser_type_name (parser);
803 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
804 "expected %<)%>");
805 if (alias_type_name)
806 {
807 tree tem;
808 alias_type = groktypename (alias_type_name,
809 &tem, NULL);
810 }
811 }
812 ptr = c_parser_gimple_unary_expression (parser);
813 if (ptr.value == error_mark_node
814 || ! POINTER_TYPE_P (TREE_TYPE (ptr.value)))
815 {
816 if (ptr.value != error_mark_node)
817 error_at (ptr.get_start (),
818 "invalid type of %<__MEM%> operand");
819 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
820 "expected %<)%>");
821 return expr;
822 }
823 if (! alias_type)
824 alias_type = TREE_TYPE (ptr.value);
825 /* Optional constant offset. */
826 if (c_parser_next_token_is (parser, CPP_PLUS))
827 {
828 c_parser_consume_token (parser);
829 alias_off
830 = c_parser_gimple_postfix_expression (parser).value;
831 alias_off = fold_convert (alias_type, alias_off);
832 }
833 if (! alias_off)
834 alias_off = build_int_cst (alias_type, 0);
835 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
836 "expected %<)%>");
837 }
838 if (! type_name || c_parser_error (parser))
839 {
840 c_parser_set_error (parser, false);
841 return expr;
842 }
843 tree tem = NULL_TREE;
844 tree type = groktypename (type_name, &tem, NULL);
845 if (alignment)
846 type = build_aligned_type (type, tree_to_uhwi (alignment));
847 expr.value = build2_loc (loc, MEM_REF,
848 type, ptr.value, alias_off);
849 break;
850 }
851 else if (strcmp (IDENTIFIER_POINTER (id), "_Literal") == 0)
852 {
853 /* _Literal '(' type-name ')' [ '-' ] constant */
854 c_parser_consume_token (parser);
855 tree type = NULL_TREE;
856 if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
857 {
858 struct c_type_name *type_name = c_parser_type_name (parser);
859 tree tem;
860 if (type_name)
861 type = groktypename (type_name, &tem, NULL);
862 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
863 "expected %<)%>");
864 }
865 bool neg_p;
866 if ((neg_p = c_parser_next_token_is (parser, CPP_MINUS)))
867 c_parser_consume_token (parser);
868 tree val = c_parser_gimple_postfix_expression (parser).value;
869 if (! type
870 || ! val
871 || val == error_mark_node
872 || ! CONSTANT_CLASS_P (val))
873 {
874 c_parser_error (parser, "invalid _Literal");
875 return expr;
876 }
877 if (neg_p)
878 {
879 val = const_unop (NEGATE_EXPR, TREE_TYPE (val), val);
880 if (! val)
881 {
882 c_parser_error (parser, "invalid _Literal");
883 return expr;
884 }
885 }
886 expr.value = fold_convert (type, val);
887 return expr;
888 }
889 else if (strcmp (IDENTIFIER_POINTER (id), "__FMA") == 0)
890 {
891 c_parser_consume_token (parser);
892 auto_vec<tree> args;
893
894 if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
895 {
896 c_parser_gimple_expr_list (parser, &args);
897 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
898 "expected %<)%>");
899 }
900 if (args.length () != 3)
901 {
902 error_at (loc, "invalid number of operands to __FMA");
903 expr.value = error_mark_node;
904 return expr;
905 }
906 expr.value = build3_loc (loc, FMA_EXPR, TREE_TYPE (args[0]),
907 args[0], args[1], args[2]);
908 return expr;
909 }
910
911 /* SSA name. */
912 unsigned version, ver_offset;
913 if (! lookup_name (id)
914 && c_parser_parse_ssa_name_id (id, &version, &ver_offset))
915 {
916 c_parser_consume_token (parser);
917 expr.value = c_parser_parse_ssa_name (parser, id, NULL_TREE,
918 version, ver_offset);
919 if (expr.value == error_mark_node)
920 return expr;
921 set_c_expr_source_range (&expr, tok_range);
922 /* For default definition SSA names. */
923 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
924 && c_parser_peek_2nd_token (parser)->type == CPP_NAME
925 && strcmp ("D",
926 IDENTIFIER_POINTER
927 (c_parser_peek_2nd_token (parser)->value)) == 0
928 && c_parser_peek_nth_token (parser, 3)->type == CPP_CLOSE_PAREN)
929 {
930 c_parser_consume_token (parser);
931 c_parser_consume_token (parser);
932 c_parser_consume_token (parser);
933 if (! SSA_NAME_IS_DEFAULT_DEF (expr.value))
934 {
935 if (!SSA_NAME_VAR (expr.value))
936 {
937 error_at (loc, "anonymous SSA name cannot have"
938 " default definition");
939 expr.value = error_mark_node;
940 return expr;
941 }
942 set_ssa_default_def (cfun, SSA_NAME_VAR (expr.value),
943 expr.value);
944 SSA_NAME_DEF_STMT (expr.value) = gimple_build_nop ();
945 }
946 }
947 }
948 else
949 {
950 c_parser_consume_token (parser);
951 expr.value
952 = build_external_ref (loc, id,
953 (c_parser_peek_token (parser)->type
954 == CPP_OPEN_PAREN), &expr.original_type);
955 set_c_expr_source_range (&expr, tok_range);
956 }
957 break;
958 }
959 else
960 {
961 c_parser_error (parser, "expected expression");
962 expr.set_error ();
963 break;
964 }
965 break;
966 default:
967 c_parser_error (parser, "expected expression");
968 expr.set_error ();
969 break;
970 }
971 return c_parser_gimple_postfix_expression_after_primary
972 (parser, EXPR_LOC_OR_LOC (expr.value, loc), expr);
973 }
974
975 /* Parse a gimple postfix expression after the initial primary or compound
976 literal. */
977
978 static struct c_expr
979 c_parser_gimple_postfix_expression_after_primary (c_parser *parser,
980 location_t expr_loc,
981 struct c_expr expr)
982 {
983 location_t start;
984 location_t finish;
985 tree ident;
986 location_t comp_loc;
987
988 while (true)
989 {
990 location_t op_loc = c_parser_peek_token (parser)->location;
991 switch (c_parser_peek_token (parser)->type)
992 {
993 case CPP_OPEN_SQUARE:
994 {
995 c_parser_consume_token (parser);
996 tree idx = c_parser_gimple_unary_expression (parser).value;
997
998 if (! c_parser_require (parser, CPP_CLOSE_SQUARE, "expected %<]%>"))
999 {
1000 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL);
1001 break;
1002 }
1003
1004 start = expr.get_start ();
1005 finish = c_parser_tokens_buf (parser, 0)->location;
1006 expr.value = build_array_ref (op_loc, expr.value, idx);
1007 set_c_expr_source_range (&expr, start, finish);
1008
1009 expr.original_code = ERROR_MARK;
1010 expr.original_type = NULL;
1011 break;
1012 }
1013 case CPP_OPEN_PAREN:
1014 {
1015 /* Function call. */
1016 c_parser_consume_token (parser);
1017 auto_vec<tree> exprlist;
1018 if (! c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
1019 c_parser_gimple_expr_list (parser, &exprlist);
1020 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
1021 "expected %<)%>");
1022 expr.value = build_call_array_loc
1023 (expr_loc, TREE_TYPE (TREE_TYPE (expr.value)),
1024 expr.value, exprlist.length (), exprlist.address ());
1025 expr.original_code = ERROR_MARK;
1026 expr.original_type = NULL;
1027 break;
1028 }
1029 case CPP_DOT:
1030 {
1031 /* Structure element reference. */
1032 c_parser_consume_token (parser);
1033 if (c_parser_next_token_is (parser, CPP_NAME))
1034 {
1035 c_token *comp_tok = c_parser_peek_token (parser);
1036 ident = comp_tok->value;
1037 comp_loc = comp_tok->location;
1038 }
1039 else
1040 {
1041 c_parser_error (parser, "expected identifier");
1042 expr.set_error ();
1043 expr.original_code = ERROR_MARK;
1044 expr.original_type = NULL;
1045 return expr;
1046 }
1047 start = expr.get_start ();
1048 finish = c_parser_peek_token (parser)->get_finish ();
1049 c_parser_consume_token (parser);
1050 expr.value = build_component_ref (op_loc, expr.value, ident,
1051 comp_loc);
1052 set_c_expr_source_range (&expr, start, finish);
1053 expr.original_code = ERROR_MARK;
1054 if (TREE_CODE (expr.value) != COMPONENT_REF)
1055 expr.original_type = NULL;
1056 else
1057 {
1058 /* Remember the original type of a bitfield. */
1059 tree field = TREE_OPERAND (expr.value, 1);
1060 if (TREE_CODE (field) != FIELD_DECL)
1061 expr.original_type = NULL;
1062 else
1063 expr.original_type = DECL_BIT_FIELD_TYPE (field);
1064 }
1065 break;
1066 }
1067 case CPP_DEREF:
1068 {
1069 /* Structure element reference. */
1070 c_parser_consume_token (parser);
1071 if (c_parser_next_token_is (parser, CPP_NAME))
1072 {
1073 c_token *comp_tok = c_parser_peek_token (parser);
1074 ident = comp_tok->value;
1075 comp_loc = comp_tok->location;
1076 }
1077 else
1078 {
1079 c_parser_error (parser, "expected identifier");
1080 expr.set_error ();
1081 expr.original_code = ERROR_MARK;
1082 expr.original_type = NULL;
1083 return expr;
1084 }
1085 start = expr.get_start ();
1086 finish = c_parser_peek_token (parser)->get_finish ();
1087 c_parser_consume_token (parser);
1088 expr.value = build_component_ref (op_loc,
1089 build_simple_mem_ref_loc
1090 (op_loc, expr.value),
1091 ident, comp_loc);
1092 set_c_expr_source_range (&expr, start, finish);
1093 expr.original_code = ERROR_MARK;
1094 if (TREE_CODE (expr.value) != COMPONENT_REF)
1095 expr.original_type = NULL;
1096 else
1097 {
1098 /* Remember the original type of a bitfield. */
1099 tree field = TREE_OPERAND (expr.value, 1);
1100 if (TREE_CODE (field) != FIELD_DECL)
1101 expr.original_type = NULL;
1102 else
1103 expr.original_type = DECL_BIT_FIELD_TYPE (field);
1104 }
1105 break;
1106 }
1107 default:
1108 return expr;
1109 }
1110 }
1111 }
1112
1113 /* Parse expression list.
1114
1115 gimple-expr-list:
1116 gimple-unary-expression
1117 gimple-expr-list , gimple-unary-expression
1118
1119 */
1120
1121 static void
1122 c_parser_gimple_expr_list (c_parser *parser, vec<tree> *ret)
1123 {
1124 struct c_expr expr;
1125
1126 expr = c_parser_gimple_unary_expression (parser);
1127 ret->safe_push (expr.value);
1128 while (c_parser_next_token_is (parser, CPP_COMMA))
1129 {
1130 c_parser_consume_token (parser);
1131 expr = c_parser_gimple_unary_expression (parser);
1132 ret->safe_push (expr.value);
1133 }
1134 }
1135
1136 /* Parse gimple label.
1137
1138 gimple-label:
1139 identifier :
1140 case constant-expression :
1141 default :
1142
1143 */
1144
1145 static void
1146 c_parser_gimple_label (c_parser *parser, gimple_seq *seq)
1147 {
1148 tree name = c_parser_peek_token (parser)->value;
1149 location_t loc1 = c_parser_peek_token (parser)->location;
1150 gcc_assert (c_parser_next_token_is (parser, CPP_NAME));
1151 c_parser_consume_token (parser);
1152 gcc_assert (c_parser_next_token_is (parser, CPP_COLON));
1153 c_parser_consume_token (parser);
1154 tree label = define_label (loc1, name);
1155 gimple_seq_add_stmt (seq, gimple_build_label (label));
1156 return;
1157 }
1158
1159 /* Parse gimple/RTL pass list.
1160
1161 gimple-or-rtl-pass-list:
1162 startwith("pass-name")
1163 */
1164
1165 char *
1166 c_parser_gimple_or_rtl_pass_list (c_parser *parser)
1167 {
1168 char *pass = NULL;
1169
1170 /* Accept __GIMPLE/__RTL. */
1171 if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
1172 return NULL;
1173 c_parser_consume_token (parser);
1174
1175 if (c_parser_next_token_is (parser, CPP_NAME))
1176 {
1177 const char *op = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
1178 c_parser_consume_token (parser);
1179 if (! strcmp (op, "startwith"))
1180 {
1181 if (! c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
1182 return NULL;
1183 if (c_parser_next_token_is_not (parser, CPP_STRING))
1184 {
1185 error_at (c_parser_peek_token (parser)->location,
1186 "expected pass name");
1187 return NULL;
1188 }
1189 pass = xstrdup (TREE_STRING_POINTER
1190 (c_parser_peek_token (parser)->value));
1191 c_parser_consume_token (parser);
1192 if (! c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
1193 return NULL;
1194 }
1195 else
1196 {
1197 error_at (c_parser_peek_token (parser)->location,
1198 "invalid operation");
1199 return NULL;
1200 }
1201 }
1202
1203 if (! c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
1204 return NULL;
1205
1206 return pass;
1207 }
1208
1209 /* Parse gimple local declaration.
1210
1211 declaration-specifiers:
1212 storage-class-specifier declaration-specifiers[opt]
1213 type-specifier declaration-specifiers[opt]
1214 type-qualifier declaration-specifiers[opt]
1215 function-specifier declaration-specifiers[opt]
1216 alignment-specifier declaration-specifiers[opt]
1217
1218 storage-class-specifier:
1219 typedef
1220 extern
1221 static
1222 auto
1223 register
1224
1225 type-specifier:
1226 void
1227 char
1228 short
1229 int
1230 long
1231 float
1232 double
1233 signed
1234 unsigned
1235 _Bool
1236 _Complex
1237
1238 type-qualifier:
1239 const
1240 restrict
1241 volatile
1242 address-space-qualifier
1243 _Atomic
1244
1245 */
1246
1247 static void
1248 c_parser_gimple_declaration (c_parser *parser)
1249 {
1250 struct c_declarator *declarator;
1251 struct c_declspecs *specs = build_null_declspecs ();
1252 c_parser_declspecs (parser, specs, true, true, true,
1253 true, true, cla_nonabstract_decl);
1254 finish_declspecs (specs);
1255
1256 /* Provide better error recovery. Note that a type name here is usually
1257 better diagnosed as a redeclaration. */
1258 if (c_parser_next_token_starts_declspecs (parser)
1259 && ! c_parser_next_token_is (parser, CPP_NAME))
1260 {
1261 c_parser_error (parser, "expected %<;%>");
1262 c_parser_set_error (parser, false);
1263 return;
1264 }
1265
1266 bool dummy = false;
1267 declarator = c_parser_declarator (parser,
1268 specs->typespec_kind != ctsk_none,
1269 C_DTR_NORMAL, &dummy);
1270
1271 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
1272 {
1273 /* Handle SSA name decls specially, they do not go into the identifier
1274 table but we simply build the SSA name for later lookup. */
1275 unsigned version, ver_offset;
1276 if (declarator->kind == cdk_id
1277 && is_gimple_reg_type (specs->type)
1278 && c_parser_parse_ssa_name_id (declarator->u.id,
1279 &version, &ver_offset)
1280 /* The following restricts it to unnamed anonymous SSA names
1281 which fails parsing of named ones in dumps (we could
1282 decide to not dump their name for -gimple). */
1283 && ver_offset == 0)
1284 c_parser_parse_ssa_name (parser, declarator->u.id, specs->type,
1285 version, ver_offset);
1286 else
1287 {
1288 tree postfix_attrs = NULL_TREE;
1289 tree all_prefix_attrs = specs->attrs;
1290 specs->attrs = NULL;
1291 tree decl = start_decl (declarator, specs, false,
1292 chainon (postfix_attrs, all_prefix_attrs));
1293 if (decl)
1294 finish_decl (decl, UNKNOWN_LOCATION, NULL_TREE, NULL_TREE,
1295 NULL_TREE);
1296 }
1297 }
1298 else
1299 {
1300 c_parser_error (parser, "expected %<;%>");
1301 return;
1302 }
1303 }
1304
1305 /* Parse gimple goto statement. */
1306
1307 static void
1308 c_parser_gimple_goto_stmt (location_t loc, tree label, gimple_seq *seq)
1309 {
1310 tree decl = lookup_label_for_goto (loc, label);
1311 gimple_seq_add_stmt (seq, gimple_build_goto (decl));
1312 return;
1313 }
1314
1315 /* Parse a parenthesized condition.
1316 gimple-condition:
1317 ( gimple-binary-expression ) */
1318
1319 static tree
1320 c_parser_gimple_paren_condition (c_parser *parser)
1321 {
1322 if (! c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
1323 return error_mark_node;
1324 tree cond = c_parser_gimple_binary_expression (parser).value;
1325 if (! c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
1326 return error_mark_node;
1327 return cond;
1328 }
1329
1330 /* Parse gimple if-else statement.
1331
1332 if-statement:
1333 if ( gimple-binary-expression ) gimple-goto-statement
1334 if ( gimple-binary-expression ) gimple-goto-statement \
1335 else gimple-goto-statement
1336 */
1337
1338 static void
1339 c_parser_gimple_if_stmt (c_parser *parser, gimple_seq *seq)
1340 {
1341 tree t_label, f_label, label;
1342 location_t loc;
1343 c_parser_consume_token (parser);
1344 tree cond = c_parser_gimple_paren_condition (parser);
1345
1346 if (c_parser_next_token_is_keyword (parser, RID_GOTO))
1347 {
1348 loc = c_parser_peek_token (parser)->location;
1349 c_parser_consume_token (parser);
1350 if (! c_parser_next_token_is (parser, CPP_NAME))
1351 {
1352 c_parser_error (parser, "expected label");
1353 return;
1354 }
1355 label = c_parser_peek_token (parser)->value;
1356 c_parser_consume_token (parser);
1357 t_label = lookup_label_for_goto (loc, label);
1358 if (! c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
1359 return;
1360 }
1361 else
1362 {
1363 c_parser_error (parser, "expected goto expression");
1364 return;
1365 }
1366
1367 if (c_parser_next_token_is_keyword (parser, RID_ELSE))
1368 c_parser_consume_token (parser);
1369 else
1370 {
1371 c_parser_error (parser, "expected else statement");
1372 return;
1373 }
1374
1375 if (c_parser_next_token_is_keyword (parser, RID_GOTO))
1376 {
1377 loc = c_parser_peek_token (parser)->location;
1378 c_parser_consume_token (parser);
1379 if (! c_parser_next_token_is (parser, CPP_NAME))
1380 {
1381 c_parser_error (parser, "expected label");
1382 return;
1383 }
1384 label = c_parser_peek_token (parser)->value;
1385 f_label = lookup_label_for_goto (loc, label);
1386 c_parser_consume_token (parser);
1387 if (! c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
1388 return;
1389 }
1390 else
1391 {
1392 c_parser_error (parser, "expected goto expression");
1393 return;
1394 }
1395
1396 if (cond != error_mark_node)
1397 gimple_seq_add_stmt (seq, gimple_build_cond_from_tree (cond, t_label,
1398 f_label));
1399 }
1400
1401 /* Parse gimple switch-statement.
1402
1403 gimple-switch-statement:
1404 switch (gimple-postfix-expression) gimple-case-statement
1405
1406 gimple-case-statement:
1407 gimple-case-statement
1408 gimple-label-statement : gimple-goto-statment
1409 */
1410
1411 static void
1412 c_parser_gimple_switch_stmt (c_parser *parser, gimple_seq *seq)
1413 {
1414 c_expr cond_expr;
1415 tree case_label, label;
1416 auto_vec<tree> labels;
1417 tree default_label = NULL_TREE;
1418 gimple_seq switch_body = NULL;
1419 c_parser_consume_token (parser);
1420
1421 if (! c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
1422 return;
1423 cond_expr = c_parser_gimple_postfix_expression (parser);
1424 if (! c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
1425 return;
1426
1427 if (! c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
1428 return;
1429
1430 while (c_parser_next_token_is_not (parser, CPP_CLOSE_BRACE))
1431 {
1432 if (c_parser_next_token_is (parser, CPP_EOF))
1433 {
1434 c_parser_error (parser, "expected statement");
1435 return;
1436 }
1437
1438 switch (c_parser_peek_token (parser)->keyword)
1439 {
1440 case RID_CASE:
1441 {
1442 c_expr exp1;
1443 location_t loc = c_parser_peek_token (parser)->location;
1444 c_parser_consume_token (parser);
1445
1446 if (c_parser_next_token_is (parser, CPP_NAME)
1447 || c_parser_peek_token (parser)->type == CPP_NUMBER)
1448 exp1 = c_parser_gimple_postfix_expression (parser);
1449 else
1450 {
1451 c_parser_error (parser, "expected expression");
1452 return;
1453 }
1454
1455 if (c_parser_next_token_is (parser, CPP_COLON))
1456 {
1457 c_parser_consume_token (parser);
1458 if (c_parser_next_token_is (parser, CPP_NAME))
1459 {
1460 label = c_parser_peek_token (parser)->value;
1461 c_parser_consume_token (parser);
1462 tree decl = lookup_label_for_goto (loc, label);
1463 case_label = build_case_label (exp1.value, NULL_TREE,
1464 decl);
1465 labels.safe_push (case_label);
1466 if (! c_parser_require (parser, CPP_SEMICOLON,
1467 "expected %<;%>"))
1468 return;
1469 }
1470 else if (! c_parser_require (parser, CPP_NAME,
1471 "expected label"))
1472 return;
1473 }
1474 else if (! c_parser_require (parser, CPP_SEMICOLON,
1475 "expected %<:%>"))
1476 return;
1477 break;
1478 }
1479 case RID_DEFAULT:
1480 {
1481 location_t loc = c_parser_peek_token (parser)->location;
1482 c_parser_consume_token (parser);
1483 if (c_parser_next_token_is (parser, CPP_COLON))
1484 {
1485 c_parser_consume_token (parser);
1486 if (c_parser_next_token_is (parser, CPP_NAME))
1487 {
1488 label = c_parser_peek_token (parser)->value;
1489 c_parser_consume_token (parser);
1490 tree decl = lookup_label_for_goto (loc, label);
1491 default_label = build_case_label (NULL_TREE, NULL_TREE,
1492 decl);
1493 if (! c_parser_require (parser, CPP_SEMICOLON,
1494 "expected %<;%>"))
1495 return;
1496 }
1497 else if (! c_parser_require (parser, CPP_NAME,
1498 "expected label"))
1499 return;
1500 }
1501 else if (! c_parser_require (parser, CPP_SEMICOLON,
1502 "expected %<:%>"))
1503 return;
1504 break;
1505 }
1506 case RID_GOTO:
1507 {
1508 location_t loc = c_parser_peek_token (parser)->location;
1509 c_parser_consume_token (parser);
1510 if (c_parser_next_token_is (parser, CPP_NAME))
1511 {
1512 c_parser_gimple_goto_stmt (loc,
1513 c_parser_peek_token
1514 (parser)->value,
1515 &switch_body);
1516 c_parser_consume_token (parser);
1517 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
1518 c_parser_consume_token (parser);
1519 else
1520 {
1521 c_parser_error (parser, "expected semicolon");
1522 return;
1523 }
1524 }
1525 else if (! c_parser_require (parser, CPP_NAME,
1526 "expected label"))
1527 return;
1528 break;
1529 }
1530 default:
1531 c_parser_error (parser, "expected case label or goto statement");
1532 return;
1533 }
1534
1535 }
1536 if (! c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>"))
1537 return;
1538
1539 if (cond_expr.value != error_mark_node)
1540 {
1541 gimple_seq_add_stmt (seq, gimple_build_switch (cond_expr.value,
1542 default_label, labels));
1543 gimple_seq_add_seq (seq, switch_body);
1544 }
1545 }
1546
1547 /* Parse gimple return statement. */
1548
1549 static void
1550 c_parser_gimple_return_stmt (c_parser *parser, gimple_seq *seq)
1551 {
1552 location_t loc = c_parser_peek_token (parser)->location;
1553 gimple *ret = NULL;
1554 c_parser_consume_token (parser);
1555 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
1556 {
1557 c_finish_gimple_return (loc, NULL_TREE);
1558 ret = gimple_build_return (NULL);
1559 gimple_seq_add_stmt (seq, ret);
1560 }
1561 else
1562 {
1563 location_t xloc = c_parser_peek_token (parser)->location;
1564 c_expr expr = c_parser_gimple_unary_expression (parser);
1565 if (expr.value != error_mark_node)
1566 {
1567 c_finish_gimple_return (xloc, expr.value);
1568 ret = gimple_build_return (expr.value);
1569 gimple_seq_add_stmt (seq, ret);
1570 }
1571 }
1572 }
1573
1574 /* Support function for c_parser_gimple_return_stmt. */
1575
1576 static void
1577 c_finish_gimple_return (location_t loc, tree retval)
1578 {
1579 tree valtype = TREE_TYPE (TREE_TYPE (current_function_decl));
1580
1581 /* Use the expansion point to handle cases such as returning NULL
1582 in a function returning void. */
1583 source_location xloc = expansion_point_location_if_in_system_header (loc);
1584
1585 if (TREE_THIS_VOLATILE (current_function_decl))
1586 warning_at (xloc, 0,
1587 "function declared %<noreturn%> has a %<return%> statement");
1588
1589 if (! retval)
1590 current_function_returns_null = 1;
1591 else if (valtype == 0 || TREE_CODE (valtype) == VOID_TYPE)
1592 {
1593 current_function_returns_null = 1;
1594 if (TREE_CODE (TREE_TYPE (retval)) != VOID_TYPE)
1595 {
1596 error_at
1597 (xloc, "%<return%> with a value, in function returning void");
1598 inform (DECL_SOURCE_LOCATION (current_function_decl),
1599 "declared here");
1600 }
1601 }
1602 else if (TREE_CODE (valtype) != TREE_CODE (TREE_TYPE (retval)))
1603 {
1604 error_at
1605 (xloc, "invalid conversion in return statement");
1606 inform (DECL_SOURCE_LOCATION (current_function_decl),
1607 "declared here");
1608 }
1609 return;
1610 }