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