1 /* Parser for GIMPLE.
2    Copyright (C) 2016-2018 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       /* 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 
468 static c_expr
469 c_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 
566 static c_expr
567 c_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 
650 static bool
651 c_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 
669 static tree
670 c_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 
749 static struct c_expr
750 c_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 
995 static struct c_expr
996 c_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 
1138 static void
1139 c_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 
1162 static void
1163 c_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 
1182 char *
1183 c_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 
1264 static void
1265 c_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 
1324 static void
1325 c_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 
1336 static tree
1337 c_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 
1355 static void
1356 c_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 
1428 static void
1429 c_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 
1566 static void
1567 c_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 
1593 static void
1594 c_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