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