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