1 /* C++-specific tree lowering bits; see also c-gimplify.c and tree-gimple.c. 2 3 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 4 Free Software Foundation, Inc. 5 Contributed by Jason Merrill <jason@redhat.com> 6 7 This file is part of GCC. 8 9 GCC is free software; you can redistribute it and/or modify it under 10 the terms of the GNU General Public License as published by the Free 11 Software Foundation; either version 3, or (at your option) any later 12 version. 13 14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY 15 WARRANTY; without even the implied warranty of MERCHANTABILITY or 16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 17 for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with GCC; see the file COPYING3. If not see 21 <http://www.gnu.org/licenses/>. */ 22 23 #include "config.h" 24 #include "system.h" 25 #include "coretypes.h" 26 #include "tm.h" 27 #include "tree.h" 28 #include "cp-tree.h" 29 #include "c-family/c-common.h" 30 #include "tree-iterator.h" 31 #include "gimple.h" 32 #include "hashtab.h" 33 #include "pointer-set.h" 34 #include "flags.h" 35 #include "splay-tree.h" 36 37 /* Local declarations. */ 38 39 enum bc_t { bc_break = 0, bc_continue = 1 }; 40 41 /* Stack of labels which are targets for "break" or "continue", 42 linked through TREE_CHAIN. */ 43 static tree bc_label[2]; 44 45 /* Begin a scope which can be exited by a break or continue statement. BC 46 indicates which. 47 48 Just creates a label and pushes it into the current context. */ 49 50 static tree 51 begin_bc_block (enum bc_t bc) 52 { 53 tree label = create_artificial_label (input_location); 54 DECL_CHAIN (label) = bc_label[bc]; 55 bc_label[bc] = label; 56 return label; 57 } 58 59 /* Finish a scope which can be exited by a break or continue statement. 60 LABEL was returned from the most recent call to begin_bc_block. BODY is 61 an expression for the contents of the scope. 62 63 If we saw a break (or continue) in the scope, append a LABEL_EXPR to 64 body. Otherwise, just forget the label. */ 65 66 static gimple_seq 67 finish_bc_block (enum bc_t bc, tree label, gimple_seq body) 68 { 69 gcc_assert (label == bc_label[bc]); 70 71 if (TREE_USED (label)) 72 { 73 gimple_seq_add_stmt (&body, gimple_build_label (label)); 74 } 75 76 bc_label[bc] = DECL_CHAIN (label); 77 DECL_CHAIN (label) = NULL_TREE; 78 return body; 79 } 80 81 /* Get the LABEL_EXPR to represent a break or continue statement 82 in the current block scope. BC indicates which. */ 83 84 static tree 85 get_bc_label (enum bc_t bc) 86 { 87 tree label = bc_label[bc]; 88 89 /* Mark the label used for finish_bc_block. */ 90 TREE_USED (label) = 1; 91 return label; 92 } 93 94 /* Genericize a TRY_BLOCK. */ 95 96 static void 97 genericize_try_block (tree *stmt_p) 98 { 99 tree body = TRY_STMTS (*stmt_p); 100 tree cleanup = TRY_HANDLERS (*stmt_p); 101 102 *stmt_p = build2 (TRY_CATCH_EXPR, void_type_node, body, cleanup); 103 } 104 105 /* Genericize a HANDLER by converting to a CATCH_EXPR. */ 106 107 static void 108 genericize_catch_block (tree *stmt_p) 109 { 110 tree type = HANDLER_TYPE (*stmt_p); 111 tree body = HANDLER_BODY (*stmt_p); 112 113 /* FIXME should the caught type go in TREE_TYPE? */ 114 *stmt_p = build2 (CATCH_EXPR, void_type_node, type, body); 115 } 116 117 /* A terser interface for building a representation of an exception 118 specification. */ 119 120 static tree 121 build_gimple_eh_filter_tree (tree body, tree allowed, tree failure) 122 { 123 tree t; 124 125 /* FIXME should the allowed types go in TREE_TYPE? */ 126 t = build2 (EH_FILTER_EXPR, void_type_node, allowed, NULL_TREE); 127 append_to_statement_list (failure, &EH_FILTER_FAILURE (t)); 128 129 t = build2 (TRY_CATCH_EXPR, void_type_node, NULL_TREE, t); 130 append_to_statement_list (body, &TREE_OPERAND (t, 0)); 131 132 return t; 133 } 134 135 /* Genericize an EH_SPEC_BLOCK by converting it to a 136 TRY_CATCH_EXPR/EH_FILTER_EXPR pair. */ 137 138 static void 139 genericize_eh_spec_block (tree *stmt_p) 140 { 141 tree body = EH_SPEC_STMTS (*stmt_p); 142 tree allowed = EH_SPEC_RAISES (*stmt_p); 143 tree failure = build_call_n (call_unexpected_node, 1, build_exc_ptr ()); 144 145 *stmt_p = build_gimple_eh_filter_tree (body, allowed, failure); 146 TREE_NO_WARNING (*stmt_p) = true; 147 TREE_NO_WARNING (TREE_OPERAND (*stmt_p, 1)) = true; 148 } 149 150 /* Genericize an IF_STMT by turning it into a COND_EXPR. */ 151 152 static void 153 genericize_if_stmt (tree *stmt_p) 154 { 155 tree stmt, cond, then_, else_; 156 location_t locus = EXPR_LOCATION (*stmt_p); 157 158 stmt = *stmt_p; 159 cond = IF_COND (stmt); 160 then_ = THEN_CLAUSE (stmt); 161 else_ = ELSE_CLAUSE (stmt); 162 163 if (!then_) 164 then_ = build_empty_stmt (locus); 165 if (!else_) 166 else_ = build_empty_stmt (locus); 167 168 if (integer_nonzerop (cond) && !TREE_SIDE_EFFECTS (else_)) 169 stmt = then_; 170 else if (integer_zerop (cond) && !TREE_SIDE_EFFECTS (then_)) 171 stmt = else_; 172 else 173 stmt = build3 (COND_EXPR, void_type_node, cond, then_, else_); 174 if (CAN_HAVE_LOCATION_P (stmt) && !EXPR_HAS_LOCATION (stmt)) 175 SET_EXPR_LOCATION (stmt, locus); 176 *stmt_p = stmt; 177 } 178 179 /* Build a generic representation of one of the C loop forms. COND is the 180 loop condition or NULL_TREE. BODY is the (possibly compound) statement 181 controlled by the loop. INCR is the increment expression of a for-loop, 182 or NULL_TREE. COND_IS_FIRST indicates whether the condition is 183 evaluated before the loop body as in while and for loops, or after the 184 loop body as in do-while loops. */ 185 186 static gimple_seq 187 gimplify_cp_loop (tree cond, tree body, tree incr, bool cond_is_first) 188 { 189 gimple top, entry, stmt; 190 gimple_seq stmt_list, body_seq, incr_seq, exit_seq; 191 tree cont_block, break_block; 192 location_t stmt_locus; 193 194 stmt_locus = input_location; 195 stmt_list = NULL; 196 body_seq = NULL; 197 incr_seq = NULL; 198 exit_seq = NULL; 199 entry = NULL; 200 201 break_block = begin_bc_block (bc_break); 202 cont_block = begin_bc_block (bc_continue); 203 204 /* If condition is zero don't generate a loop construct. */ 205 if (cond && integer_zerop (cond)) 206 { 207 top = NULL; 208 if (cond_is_first) 209 { 210 stmt = gimple_build_goto (get_bc_label (bc_break)); 211 gimple_set_location (stmt, stmt_locus); 212 gimple_seq_add_stmt (&stmt_list, stmt); 213 } 214 } 215 else 216 { 217 /* If we use a LOOP_EXPR here, we have to feed the whole thing 218 back through the main gimplifier to lower it. Given that we 219 have to gimplify the loop body NOW so that we can resolve 220 break/continue stmts, seems easier to just expand to gotos. */ 221 top = gimple_build_label (create_artificial_label (stmt_locus)); 222 223 /* If we have an exit condition, then we build an IF with gotos either 224 out of the loop, or to the top of it. If there's no exit condition, 225 then we just build a jump back to the top. */ 226 if (cond && !integer_nonzerop (cond)) 227 { 228 if (cond != error_mark_node) 229 { 230 gimplify_expr (&cond, &exit_seq, NULL, is_gimple_val, fb_rvalue); 231 stmt = gimple_build_cond (NE_EXPR, cond, 232 build_int_cst (TREE_TYPE (cond), 0), 233 gimple_label_label (top), 234 get_bc_label (bc_break)); 235 gimple_seq_add_stmt (&exit_seq, stmt); 236 } 237 238 if (cond_is_first) 239 { 240 if (incr) 241 { 242 entry = gimple_build_label 243 (create_artificial_label (stmt_locus)); 244 stmt = gimple_build_goto (gimple_label_label (entry)); 245 } 246 else 247 stmt = gimple_build_goto (get_bc_label (bc_continue)); 248 gimple_set_location (stmt, stmt_locus); 249 gimple_seq_add_stmt (&stmt_list, stmt); 250 } 251 } 252 else 253 { 254 stmt = gimple_build_goto (gimple_label_label (top)); 255 gimple_seq_add_stmt (&exit_seq, stmt); 256 } 257 } 258 259 gimplify_stmt (&body, &body_seq); 260 gimplify_stmt (&incr, &incr_seq); 261 262 body_seq = finish_bc_block (bc_continue, cont_block, body_seq); 263 264 gimple_seq_add_stmt (&stmt_list, top); 265 gimple_seq_add_seq (&stmt_list, body_seq); 266 gimple_seq_add_seq (&stmt_list, incr_seq); 267 gimple_seq_add_stmt (&stmt_list, entry); 268 gimple_seq_add_seq (&stmt_list, exit_seq); 269 270 annotate_all_with_location (stmt_list, stmt_locus); 271 272 return finish_bc_block (bc_break, break_block, stmt_list); 273 } 274 275 /* Gimplify a FOR_STMT node. Move the stuff in the for-init-stmt into the 276 prequeue and hand off to gimplify_cp_loop. */ 277 278 static void 279 gimplify_for_stmt (tree *stmt_p, gimple_seq *pre_p) 280 { 281 tree stmt = *stmt_p; 282 283 if (FOR_INIT_STMT (stmt)) 284 gimplify_and_add (FOR_INIT_STMT (stmt), pre_p); 285 286 gimple_seq_add_seq (pre_p, 287 gimplify_cp_loop (FOR_COND (stmt), FOR_BODY (stmt), 288 FOR_EXPR (stmt), 1)); 289 *stmt_p = NULL_TREE; 290 } 291 292 /* Gimplify a WHILE_STMT node. */ 293 294 static void 295 gimplify_while_stmt (tree *stmt_p, gimple_seq *pre_p) 296 { 297 tree stmt = *stmt_p; 298 gimple_seq_add_seq (pre_p, 299 gimplify_cp_loop (WHILE_COND (stmt), WHILE_BODY (stmt), 300 NULL_TREE, 1)); 301 *stmt_p = NULL_TREE; 302 } 303 304 /* Gimplify a DO_STMT node. */ 305 306 static void 307 gimplify_do_stmt (tree *stmt_p, gimple_seq *pre_p) 308 { 309 tree stmt = *stmt_p; 310 gimple_seq_add_seq (pre_p, 311 gimplify_cp_loop (DO_COND (stmt), DO_BODY (stmt), 312 NULL_TREE, 0)); 313 *stmt_p = NULL_TREE; 314 } 315 316 /* Genericize a SWITCH_STMT by turning it into a SWITCH_EXPR. */ 317 318 static void 319 gimplify_switch_stmt (tree *stmt_p, gimple_seq *pre_p) 320 { 321 tree stmt = *stmt_p; 322 tree break_block, body, t; 323 location_t stmt_locus = input_location; 324 gimple_seq seq = NULL; 325 326 break_block = begin_bc_block (bc_break); 327 328 body = SWITCH_STMT_BODY (stmt); 329 if (!body) 330 body = build_empty_stmt (stmt_locus); 331 332 t = build3 (SWITCH_EXPR, SWITCH_STMT_TYPE (stmt), 333 SWITCH_STMT_COND (stmt), body, NULL_TREE); 334 SET_EXPR_LOCATION (t, stmt_locus); 335 gimplify_and_add (t, &seq); 336 337 seq = finish_bc_block (bc_break, break_block, seq); 338 gimple_seq_add_seq (pre_p, seq); 339 *stmt_p = NULL_TREE; 340 } 341 342 /* Hook into the middle of gimplifying an OMP_FOR node. This is required 343 in order to properly gimplify CONTINUE statements. Here we merely 344 manage the continue stack; the rest of the job is performed by the 345 regular gimplifier. */ 346 347 static enum gimplify_status 348 cp_gimplify_omp_for (tree *expr_p, gimple_seq *pre_p) 349 { 350 tree for_stmt = *expr_p; 351 tree cont_block; 352 gimple stmt; 353 gimple_seq seq = NULL; 354 355 /* Protect ourselves from recursion. */ 356 if (OMP_FOR_GIMPLIFYING_P (for_stmt)) 357 return GS_UNHANDLED; 358 OMP_FOR_GIMPLIFYING_P (for_stmt) = 1; 359 360 /* Note that while technically the continue label is enabled too soon 361 here, we should have already diagnosed invalid continues nested within 362 statement expressions within the INIT, COND, or INCR expressions. */ 363 cont_block = begin_bc_block (bc_continue); 364 365 gimplify_and_add (for_stmt, &seq); 366 stmt = gimple_seq_last_stmt (seq); 367 if (gimple_code (stmt) == GIMPLE_OMP_FOR) 368 gimple_omp_set_body (stmt, finish_bc_block (bc_continue, cont_block, 369 gimple_omp_body (stmt))); 370 else 371 seq = finish_bc_block (bc_continue, cont_block, seq); 372 gimple_seq_add_seq (pre_p, seq); 373 374 OMP_FOR_GIMPLIFYING_P (for_stmt) = 0; 375 376 return GS_ALL_DONE; 377 } 378 379 /* Gimplify an EXPR_STMT node. */ 380 381 static void 382 gimplify_expr_stmt (tree *stmt_p) 383 { 384 tree stmt = EXPR_STMT_EXPR (*stmt_p); 385 386 if (stmt == error_mark_node) 387 stmt = NULL; 388 389 /* Gimplification of a statement expression will nullify the 390 statement if all its side effects are moved to *PRE_P and *POST_P. 391 392 In this case we will not want to emit the gimplified statement. 393 However, we may still want to emit a warning, so we do that before 394 gimplification. */ 395 if (stmt && warn_unused_value) 396 { 397 if (!TREE_SIDE_EFFECTS (stmt)) 398 { 399 if (!IS_EMPTY_STMT (stmt) 400 && !VOID_TYPE_P (TREE_TYPE (stmt)) 401 && !TREE_NO_WARNING (stmt)) 402 warning (OPT_Wunused_value, "statement with no effect"); 403 } 404 else 405 warn_if_unused_value (stmt, input_location); 406 } 407 408 if (stmt == NULL_TREE) 409 stmt = alloc_stmt_list (); 410 411 *stmt_p = stmt; 412 } 413 414 /* Gimplify initialization from an AGGR_INIT_EXPR. */ 415 416 static void 417 cp_gimplify_init_expr (tree *expr_p) 418 { 419 tree from = TREE_OPERAND (*expr_p, 1); 420 tree to = TREE_OPERAND (*expr_p, 0); 421 tree t; 422 423 /* What about code that pulls out the temp and uses it elsewhere? I 424 think that such code never uses the TARGET_EXPR as an initializer. If 425 I'm wrong, we'll abort because the temp won't have any RTL. In that 426 case, I guess we'll need to replace references somehow. */ 427 if (TREE_CODE (from) == TARGET_EXPR) 428 from = TARGET_EXPR_INITIAL (from); 429 430 /* Look through any COMPOUND_EXPRs, since build_compound_expr pushes them 431 inside the TARGET_EXPR. */ 432 for (t = from; t; ) 433 { 434 tree sub = TREE_CODE (t) == COMPOUND_EXPR ? TREE_OPERAND (t, 0) : t; 435 436 /* If we are initializing from an AGGR_INIT_EXPR, drop the INIT_EXPR and 437 replace the slot operand with our target. 438 439 Should we add a target parm to gimplify_expr instead? No, as in this 440 case we want to replace the INIT_EXPR. */ 441 if (TREE_CODE (sub) == AGGR_INIT_EXPR 442 || TREE_CODE (sub) == VEC_INIT_EXPR) 443 { 444 if (TREE_CODE (sub) == AGGR_INIT_EXPR) 445 AGGR_INIT_EXPR_SLOT (sub) = to; 446 else 447 VEC_INIT_EXPR_SLOT (sub) = to; 448 *expr_p = from; 449 450 /* The initialization is now a side-effect, so the container can 451 become void. */ 452 if (from != sub) 453 TREE_TYPE (from) = void_type_node; 454 } 455 456 if (t == sub) 457 break; 458 else 459 t = TREE_OPERAND (t, 1); 460 } 461 462 } 463 464 /* Gimplify a MUST_NOT_THROW_EXPR. */ 465 466 static enum gimplify_status 467 gimplify_must_not_throw_expr (tree *expr_p, gimple_seq *pre_p) 468 { 469 tree stmt = *expr_p; 470 tree temp = voidify_wrapper_expr (stmt, NULL); 471 tree body = TREE_OPERAND (stmt, 0); 472 gimple_seq try_ = NULL; 473 gimple_seq catch_ = NULL; 474 gimple mnt; 475 476 gimplify_and_add (body, &try_); 477 mnt = gimple_build_eh_must_not_throw (terminate_node); 478 gimple_seq_add_stmt_without_update (&catch_, mnt); 479 mnt = gimple_build_try (try_, catch_, GIMPLE_TRY_CATCH); 480 481 gimple_seq_add_stmt_without_update (pre_p, mnt); 482 if (temp) 483 { 484 *expr_p = temp; 485 return GS_OK; 486 } 487 488 *expr_p = NULL; 489 return GS_ALL_DONE; 490 } 491 492 /* Do C++-specific gimplification. Args are as for gimplify_expr. */ 493 494 int 495 cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p) 496 { 497 int saved_stmts_are_full_exprs_p = 0; 498 enum tree_code code = TREE_CODE (*expr_p); 499 enum gimplify_status ret; 500 501 if (STATEMENT_CODE_P (code)) 502 { 503 saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p (); 504 current_stmt_tree ()->stmts_are_full_exprs_p 505 = STMT_IS_FULL_EXPR_P (*expr_p); 506 } 507 508 switch (code) 509 { 510 case PTRMEM_CST: 511 *expr_p = cplus_expand_constant (*expr_p); 512 ret = GS_OK; 513 break; 514 515 case AGGR_INIT_EXPR: 516 simplify_aggr_init_expr (expr_p); 517 ret = GS_OK; 518 break; 519 520 case VEC_INIT_EXPR: 521 { 522 location_t loc = input_location; 523 tree init = VEC_INIT_EXPR_INIT (*expr_p); 524 int from_array = (init && TREE_CODE (TREE_TYPE (init)) == ARRAY_TYPE); 525 gcc_assert (EXPR_HAS_LOCATION (*expr_p)); 526 input_location = EXPR_LOCATION (*expr_p); 527 *expr_p = build_vec_init (VEC_INIT_EXPR_SLOT (*expr_p), NULL_TREE, 528 init, VEC_INIT_EXPR_VALUE_INIT (*expr_p), 529 from_array, 530 tf_warning_or_error); 531 ret = GS_OK; 532 input_location = loc; 533 } 534 break; 535 536 case THROW_EXPR: 537 /* FIXME communicate throw type to back end, probably by moving 538 THROW_EXPR into ../tree.def. */ 539 *expr_p = TREE_OPERAND (*expr_p, 0); 540 ret = GS_OK; 541 break; 542 543 case MUST_NOT_THROW_EXPR: 544 ret = gimplify_must_not_throw_expr (expr_p, pre_p); 545 break; 546 547 /* We used to do this for MODIFY_EXPR as well, but that's unsafe; the 548 LHS of an assignment might also be involved in the RHS, as in bug 549 25979. */ 550 case INIT_EXPR: 551 cp_gimplify_init_expr (expr_p); 552 if (TREE_CODE (*expr_p) != INIT_EXPR) 553 return GS_OK; 554 /* Otherwise fall through. */ 555 case MODIFY_EXPR: 556 { 557 /* If the back end isn't clever enough to know that the lhs and rhs 558 types are the same, add an explicit conversion. */ 559 tree op0 = TREE_OPERAND (*expr_p, 0); 560 tree op1 = TREE_OPERAND (*expr_p, 1); 561 562 if (!error_operand_p (op0) 563 && !error_operand_p (op1) 564 && (TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (op0)) 565 || TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (op1))) 566 && !useless_type_conversion_p (TREE_TYPE (op1), TREE_TYPE (op0))) 567 TREE_OPERAND (*expr_p, 1) = build1 (VIEW_CONVERT_EXPR, 568 TREE_TYPE (op0), op1); 569 570 else if ((is_gimple_lvalue (op1) || INDIRECT_REF_P (op1) 571 || (TREE_CODE (op1) == CONSTRUCTOR 572 && CONSTRUCTOR_NELTS (op1) == 0 573 && !TREE_CLOBBER_P (op1)) 574 || (TREE_CODE (op1) == CALL_EXPR 575 && !CALL_EXPR_RETURN_SLOT_OPT (op1))) 576 && is_really_empty_class (TREE_TYPE (op0))) 577 { 578 /* Remove any copies of empty classes. We check that the RHS 579 has a simple form so that TARGET_EXPRs and non-empty 580 CONSTRUCTORs get reduced properly, and we leave the return 581 slot optimization alone because it isn't a copy (FIXME so it 582 shouldn't be represented as one). 583 584 Also drop volatile variables on the RHS to avoid infinite 585 recursion from gimplify_expr trying to load the value. */ 586 if (!TREE_SIDE_EFFECTS (op1) 587 || (DECL_P (op1) && TREE_THIS_VOLATILE (op1))) 588 *expr_p = op0; 589 else if (TREE_CODE (op1) == MEM_REF 590 && TREE_THIS_VOLATILE (op1)) 591 { 592 /* Similarly for volatile MEM_REFs on the RHS. */ 593 if (!TREE_SIDE_EFFECTS (TREE_OPERAND (op1, 0))) 594 *expr_p = op0; 595 else 596 *expr_p = build2 (COMPOUND_EXPR, TREE_TYPE (*expr_p), 597 TREE_OPERAND (op1, 0), op0); 598 } 599 else 600 *expr_p = build2 (COMPOUND_EXPR, TREE_TYPE (*expr_p), 601 op0, op1); 602 } 603 } 604 ret = GS_OK; 605 break; 606 607 case EMPTY_CLASS_EXPR: 608 /* We create an empty CONSTRUCTOR with RECORD_TYPE. */ 609 *expr_p = build_constructor (TREE_TYPE (*expr_p), NULL); 610 ret = GS_OK; 611 break; 612 613 case BASELINK: 614 *expr_p = BASELINK_FUNCTIONS (*expr_p); 615 ret = GS_OK; 616 break; 617 618 case TRY_BLOCK: 619 genericize_try_block (expr_p); 620 ret = GS_OK; 621 break; 622 623 case HANDLER: 624 genericize_catch_block (expr_p); 625 ret = GS_OK; 626 break; 627 628 case EH_SPEC_BLOCK: 629 genericize_eh_spec_block (expr_p); 630 ret = GS_OK; 631 break; 632 633 case USING_STMT: 634 gcc_unreachable (); 635 636 case FOR_STMT: 637 gimplify_for_stmt (expr_p, pre_p); 638 ret = GS_OK; 639 break; 640 641 case WHILE_STMT: 642 gimplify_while_stmt (expr_p, pre_p); 643 ret = GS_OK; 644 break; 645 646 case DO_STMT: 647 gimplify_do_stmt (expr_p, pre_p); 648 ret = GS_OK; 649 break; 650 651 case SWITCH_STMT: 652 gimplify_switch_stmt (expr_p, pre_p); 653 ret = GS_OK; 654 break; 655 656 case OMP_FOR: 657 ret = cp_gimplify_omp_for (expr_p, pre_p); 658 break; 659 660 case CONTINUE_STMT: 661 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_CONTINUE, NOT_TAKEN)); 662 gimple_seq_add_stmt (pre_p, gimple_build_goto (get_bc_label (bc_continue))); 663 *expr_p = NULL_TREE; 664 ret = GS_ALL_DONE; 665 break; 666 667 case BREAK_STMT: 668 gimple_seq_add_stmt (pre_p, gimple_build_goto (get_bc_label (bc_break))); 669 *expr_p = NULL_TREE; 670 ret = GS_ALL_DONE; 671 break; 672 673 case EXPR_STMT: 674 gimplify_expr_stmt (expr_p); 675 ret = GS_OK; 676 break; 677 678 case UNARY_PLUS_EXPR: 679 { 680 tree arg = TREE_OPERAND (*expr_p, 0); 681 tree type = TREE_TYPE (*expr_p); 682 *expr_p = (TREE_TYPE (arg) != type) ? fold_convert (type, arg) 683 : arg; 684 ret = GS_OK; 685 } 686 break; 687 688 default: 689 ret = (enum gimplify_status) c_gimplify_expr (expr_p, pre_p, post_p); 690 break; 691 } 692 693 /* Restore saved state. */ 694 if (STATEMENT_CODE_P (code)) 695 current_stmt_tree ()->stmts_are_full_exprs_p 696 = saved_stmts_are_full_exprs_p; 697 698 return ret; 699 } 700 701 static inline bool 702 is_invisiref_parm (const_tree t) 703 { 704 return ((TREE_CODE (t) == PARM_DECL || TREE_CODE (t) == RESULT_DECL) 705 && DECL_BY_REFERENCE (t)); 706 } 707 708 /* Return true if the uid in both int tree maps are equal. */ 709 710 int 711 cxx_int_tree_map_eq (const void *va, const void *vb) 712 { 713 const struct cxx_int_tree_map *a = (const struct cxx_int_tree_map *) va; 714 const struct cxx_int_tree_map *b = (const struct cxx_int_tree_map *) vb; 715 return (a->uid == b->uid); 716 } 717 718 /* Hash a UID in a cxx_int_tree_map. */ 719 720 unsigned int 721 cxx_int_tree_map_hash (const void *item) 722 { 723 return ((const struct cxx_int_tree_map *)item)->uid; 724 } 725 726 /* A stable comparison routine for use with splay trees and DECLs. */ 727 728 static int 729 splay_tree_compare_decl_uid (splay_tree_key xa, splay_tree_key xb) 730 { 731 tree a = (tree) xa; 732 tree b = (tree) xb; 733 734 return DECL_UID (a) - DECL_UID (b); 735 } 736 737 /* OpenMP context during genericization. */ 738 739 struct cp_genericize_omp_taskreg 740 { 741 bool is_parallel; 742 bool default_shared; 743 struct cp_genericize_omp_taskreg *outer; 744 splay_tree variables; 745 }; 746 747 /* Return true if genericization should try to determine if 748 DECL is firstprivate or shared within task regions. */ 749 750 static bool 751 omp_var_to_track (tree decl) 752 { 753 tree type = TREE_TYPE (decl); 754 if (is_invisiref_parm (decl)) 755 type = TREE_TYPE (type); 756 while (TREE_CODE (type) == ARRAY_TYPE) 757 type = TREE_TYPE (type); 758 if (type == error_mark_node || !CLASS_TYPE_P (type)) 759 return false; 760 if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL_P (decl)) 761 return false; 762 if (cxx_omp_predetermined_sharing (decl) != OMP_CLAUSE_DEFAULT_UNSPECIFIED) 763 return false; 764 return true; 765 } 766 767 /* Note DECL use in OpenMP region OMP_CTX during genericization. */ 768 769 static void 770 omp_cxx_notice_variable (struct cp_genericize_omp_taskreg *omp_ctx, tree decl) 771 { 772 splay_tree_node n = splay_tree_lookup (omp_ctx->variables, 773 (splay_tree_key) decl); 774 if (n == NULL) 775 { 776 int flags = OMP_CLAUSE_DEFAULT_SHARED; 777 if (omp_ctx->outer) 778 omp_cxx_notice_variable (omp_ctx->outer, decl); 779 if (!omp_ctx->default_shared) 780 { 781 struct cp_genericize_omp_taskreg *octx; 782 783 for (octx = omp_ctx->outer; octx; octx = octx->outer) 784 { 785 n = splay_tree_lookup (octx->variables, (splay_tree_key) decl); 786 if (n && n->value != OMP_CLAUSE_DEFAULT_SHARED) 787 { 788 flags = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE; 789 break; 790 } 791 if (octx->is_parallel) 792 break; 793 } 794 if (octx == NULL 795 && (TREE_CODE (decl) == PARM_DECL 796 || (!(TREE_STATIC (decl) || DECL_EXTERNAL (decl)) 797 && DECL_CONTEXT (decl) == current_function_decl))) 798 flags = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE; 799 if (flags == OMP_CLAUSE_DEFAULT_FIRSTPRIVATE) 800 { 801 /* DECL is implicitly determined firstprivate in 802 the current task construct. Ensure copy ctor and 803 dtor are instantiated, because during gimplification 804 it will be already too late. */ 805 tree type = TREE_TYPE (decl); 806 if (is_invisiref_parm (decl)) 807 type = TREE_TYPE (type); 808 while (TREE_CODE (type) == ARRAY_TYPE) 809 type = TREE_TYPE (type); 810 get_copy_ctor (type, tf_none); 811 get_dtor (type, tf_none); 812 } 813 } 814 splay_tree_insert (omp_ctx->variables, (splay_tree_key) decl, flags); 815 } 816 } 817 818 /* Genericization context. */ 819 820 struct cp_genericize_data 821 { 822 struct pointer_set_t *p_set; 823 VEC (tree, heap) *bind_expr_stack; 824 struct cp_genericize_omp_taskreg *omp_ctx; 825 }; 826 827 /* Perform any pre-gimplification lowering of C++ front end trees to 828 GENERIC. */ 829 830 static tree 831 cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data) 832 { 833 tree stmt = *stmt_p; 834 struct cp_genericize_data *wtd = (struct cp_genericize_data *) data; 835 struct pointer_set_t *p_set = wtd->p_set; 836 837 /* If in an OpenMP context, note var uses. */ 838 if (__builtin_expect (wtd->omp_ctx != NULL, 0) 839 && (TREE_CODE (stmt) == VAR_DECL 840 || TREE_CODE (stmt) == PARM_DECL 841 || TREE_CODE (stmt) == RESULT_DECL) 842 && omp_var_to_track (stmt)) 843 omp_cxx_notice_variable (wtd->omp_ctx, stmt); 844 845 if (is_invisiref_parm (stmt) 846 /* Don't dereference parms in a thunk, pass the references through. */ 847 && !(DECL_THUNK_P (current_function_decl) 848 && TREE_CODE (stmt) == PARM_DECL)) 849 { 850 *stmt_p = convert_from_reference (stmt); 851 *walk_subtrees = 0; 852 return NULL; 853 } 854 855 /* Map block scope extern declarations to visible declarations with the 856 same name and type in outer scopes if any. */ 857 if (cp_function_chain->extern_decl_map 858 && (TREE_CODE (stmt) == FUNCTION_DECL || TREE_CODE (stmt) == VAR_DECL) 859 && DECL_EXTERNAL (stmt)) 860 { 861 struct cxx_int_tree_map *h, in; 862 in.uid = DECL_UID (stmt); 863 h = (struct cxx_int_tree_map *) 864 htab_find_with_hash (cp_function_chain->extern_decl_map, 865 &in, in.uid); 866 if (h) 867 { 868 *stmt_p = h->to; 869 *walk_subtrees = 0; 870 return NULL; 871 } 872 } 873 874 /* Other than invisiref parms, don't walk the same tree twice. */ 875 if (pointer_set_contains (p_set, stmt)) 876 { 877 *walk_subtrees = 0; 878 return NULL_TREE; 879 } 880 881 if (TREE_CODE (stmt) == ADDR_EXPR 882 && is_invisiref_parm (TREE_OPERAND (stmt, 0))) 883 { 884 /* If in an OpenMP context, note var uses. */ 885 if (__builtin_expect (wtd->omp_ctx != NULL, 0) 886 && omp_var_to_track (TREE_OPERAND (stmt, 0))) 887 omp_cxx_notice_variable (wtd->omp_ctx, TREE_OPERAND (stmt, 0)); 888 *stmt_p = convert (TREE_TYPE (stmt), TREE_OPERAND (stmt, 0)); 889 *walk_subtrees = 0; 890 } 891 else if (TREE_CODE (stmt) == RETURN_EXPR 892 && TREE_OPERAND (stmt, 0) 893 && is_invisiref_parm (TREE_OPERAND (stmt, 0))) 894 /* Don't dereference an invisiref RESULT_DECL inside a RETURN_EXPR. */ 895 *walk_subtrees = 0; 896 else if (TREE_CODE (stmt) == OMP_CLAUSE) 897 switch (OMP_CLAUSE_CODE (stmt)) 898 { 899 case OMP_CLAUSE_LASTPRIVATE: 900 /* Don't dereference an invisiref in OpenMP clauses. */ 901 if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt))) 902 { 903 *walk_subtrees = 0; 904 if (OMP_CLAUSE_LASTPRIVATE_STMT (stmt)) 905 cp_walk_tree (&OMP_CLAUSE_LASTPRIVATE_STMT (stmt), 906 cp_genericize_r, data, NULL); 907 } 908 break; 909 case OMP_CLAUSE_PRIVATE: 910 /* Don't dereference an invisiref in OpenMP clauses. */ 911 if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt))) 912 *walk_subtrees = 0; 913 else if (wtd->omp_ctx != NULL) 914 { 915 /* Private clause doesn't cause any references to the 916 var in outer contexts, avoid calling 917 omp_cxx_notice_variable for it. */ 918 struct cp_genericize_omp_taskreg *old = wtd->omp_ctx; 919 wtd->omp_ctx = NULL; 920 cp_walk_tree (&OMP_CLAUSE_DECL (stmt), cp_genericize_r, 921 data, NULL); 922 wtd->omp_ctx = old; 923 *walk_subtrees = 0; 924 } 925 break; 926 case OMP_CLAUSE_SHARED: 927 case OMP_CLAUSE_FIRSTPRIVATE: 928 case OMP_CLAUSE_COPYIN: 929 case OMP_CLAUSE_COPYPRIVATE: 930 /* Don't dereference an invisiref in OpenMP clauses. */ 931 if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt))) 932 *walk_subtrees = 0; 933 break; 934 case OMP_CLAUSE_REDUCTION: 935 gcc_assert (!is_invisiref_parm (OMP_CLAUSE_DECL (stmt))); 936 break; 937 default: 938 break; 939 } 940 else if (IS_TYPE_OR_DECL_P (stmt)) 941 *walk_subtrees = 0; 942 943 /* Due to the way voidify_wrapper_expr is written, we don't get a chance 944 to lower this construct before scanning it, so we need to lower these 945 before doing anything else. */ 946 else if (TREE_CODE (stmt) == CLEANUP_STMT) 947 *stmt_p = build2 (CLEANUP_EH_ONLY (stmt) ? TRY_CATCH_EXPR 948 : TRY_FINALLY_EXPR, 949 void_type_node, 950 CLEANUP_BODY (stmt), 951 CLEANUP_EXPR (stmt)); 952 953 else if (TREE_CODE (stmt) == IF_STMT) 954 { 955 genericize_if_stmt (stmt_p); 956 /* *stmt_p has changed, tail recurse to handle it again. */ 957 return cp_genericize_r (stmt_p, walk_subtrees, data); 958 } 959 960 /* COND_EXPR might have incompatible types in branches if one or both 961 arms are bitfields. Fix it up now. */ 962 else if (TREE_CODE (stmt) == COND_EXPR) 963 { 964 tree type_left 965 = (TREE_OPERAND (stmt, 1) 966 ? is_bitfield_expr_with_lowered_type (TREE_OPERAND (stmt, 1)) 967 : NULL_TREE); 968 tree type_right 969 = (TREE_OPERAND (stmt, 2) 970 ? is_bitfield_expr_with_lowered_type (TREE_OPERAND (stmt, 2)) 971 : NULL_TREE); 972 if (type_left 973 && !useless_type_conversion_p (TREE_TYPE (stmt), 974 TREE_TYPE (TREE_OPERAND (stmt, 1)))) 975 { 976 TREE_OPERAND (stmt, 1) 977 = fold_convert (type_left, TREE_OPERAND (stmt, 1)); 978 gcc_assert (useless_type_conversion_p (TREE_TYPE (stmt), 979 type_left)); 980 } 981 if (type_right 982 && !useless_type_conversion_p (TREE_TYPE (stmt), 983 TREE_TYPE (TREE_OPERAND (stmt, 2)))) 984 { 985 TREE_OPERAND (stmt, 2) 986 = fold_convert (type_right, TREE_OPERAND (stmt, 2)); 987 gcc_assert (useless_type_conversion_p (TREE_TYPE (stmt), 988 type_right)); 989 } 990 } 991 992 else if (TREE_CODE (stmt) == BIND_EXPR) 993 { 994 if (__builtin_expect (wtd->omp_ctx != NULL, 0)) 995 { 996 tree decl; 997 for (decl = BIND_EXPR_VARS (stmt); decl; decl = DECL_CHAIN (decl)) 998 if (TREE_CODE (decl) == VAR_DECL 999 && !DECL_EXTERNAL (decl) 1000 && omp_var_to_track (decl)) 1001 { 1002 splay_tree_node n 1003 = splay_tree_lookup (wtd->omp_ctx->variables, 1004 (splay_tree_key) decl); 1005 if (n == NULL) 1006 splay_tree_insert (wtd->omp_ctx->variables, 1007 (splay_tree_key) decl, 1008 TREE_STATIC (decl) 1009 ? OMP_CLAUSE_DEFAULT_SHARED 1010 : OMP_CLAUSE_DEFAULT_PRIVATE); 1011 } 1012 } 1013 VEC_safe_push (tree, heap, wtd->bind_expr_stack, stmt); 1014 cp_walk_tree (&BIND_EXPR_BODY (stmt), 1015 cp_genericize_r, data, NULL); 1016 VEC_pop (tree, wtd->bind_expr_stack); 1017 } 1018 1019 else if (TREE_CODE (stmt) == USING_STMT) 1020 { 1021 tree block = NULL_TREE; 1022 1023 /* Get the innermost inclosing GIMPLE_BIND that has a non NULL 1024 BLOCK, and append an IMPORTED_DECL to its 1025 BLOCK_VARS chained list. */ 1026 if (wtd->bind_expr_stack) 1027 { 1028 int i; 1029 for (i = VEC_length (tree, wtd->bind_expr_stack) - 1; i >= 0; i--) 1030 if ((block = BIND_EXPR_BLOCK (VEC_index (tree, 1031 wtd->bind_expr_stack, i)))) 1032 break; 1033 } 1034 if (block) 1035 { 1036 tree using_directive; 1037 gcc_assert (TREE_OPERAND (stmt, 0)); 1038 1039 using_directive = make_node (IMPORTED_DECL); 1040 TREE_TYPE (using_directive) = void_type_node; 1041 1042 IMPORTED_DECL_ASSOCIATED_DECL (using_directive) 1043 = TREE_OPERAND (stmt, 0); 1044 DECL_CHAIN (using_directive) = BLOCK_VARS (block); 1045 BLOCK_VARS (block) = using_directive; 1046 } 1047 /* The USING_STMT won't appear in GENERIC. */ 1048 *stmt_p = build1 (NOP_EXPR, void_type_node, integer_zero_node); 1049 *walk_subtrees = 0; 1050 } 1051 1052 else if (TREE_CODE (stmt) == DECL_EXPR 1053 && TREE_CODE (DECL_EXPR_DECL (stmt)) == USING_DECL) 1054 { 1055 /* Using decls inside DECL_EXPRs are just dropped on the floor. */ 1056 *stmt_p = build1 (NOP_EXPR, void_type_node, integer_zero_node); 1057 *walk_subtrees = 0; 1058 } 1059 else if (TREE_CODE (stmt) == OMP_PARALLEL || TREE_CODE (stmt) == OMP_TASK) 1060 { 1061 struct cp_genericize_omp_taskreg omp_ctx; 1062 tree c, decl; 1063 splay_tree_node n; 1064 1065 *walk_subtrees = 0; 1066 cp_walk_tree (&OMP_CLAUSES (stmt), cp_genericize_r, data, NULL); 1067 omp_ctx.is_parallel = TREE_CODE (stmt) == OMP_PARALLEL; 1068 omp_ctx.default_shared = omp_ctx.is_parallel; 1069 omp_ctx.outer = wtd->omp_ctx; 1070 omp_ctx.variables = splay_tree_new (splay_tree_compare_decl_uid, 0, 0); 1071 wtd->omp_ctx = &omp_ctx; 1072 for (c = OMP_CLAUSES (stmt); c; c = OMP_CLAUSE_CHAIN (c)) 1073 switch (OMP_CLAUSE_CODE (c)) 1074 { 1075 case OMP_CLAUSE_SHARED: 1076 case OMP_CLAUSE_PRIVATE: 1077 case OMP_CLAUSE_FIRSTPRIVATE: 1078 case OMP_CLAUSE_LASTPRIVATE: 1079 decl = OMP_CLAUSE_DECL (c); 1080 if (decl == error_mark_node || !omp_var_to_track (decl)) 1081 break; 1082 n = splay_tree_lookup (omp_ctx.variables, (splay_tree_key) decl); 1083 if (n != NULL) 1084 break; 1085 splay_tree_insert (omp_ctx.variables, (splay_tree_key) decl, 1086 OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED 1087 ? OMP_CLAUSE_DEFAULT_SHARED 1088 : OMP_CLAUSE_DEFAULT_PRIVATE); 1089 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_PRIVATE 1090 && omp_ctx.outer) 1091 omp_cxx_notice_variable (omp_ctx.outer, decl); 1092 break; 1093 case OMP_CLAUSE_DEFAULT: 1094 if (OMP_CLAUSE_DEFAULT_KIND (c) == OMP_CLAUSE_DEFAULT_SHARED) 1095 omp_ctx.default_shared = true; 1096 default: 1097 break; 1098 } 1099 cp_walk_tree (&OMP_BODY (stmt), cp_genericize_r, data, NULL); 1100 wtd->omp_ctx = omp_ctx.outer; 1101 splay_tree_delete (omp_ctx.variables); 1102 } 1103 else if (TREE_CODE (stmt) == CONVERT_EXPR) 1104 gcc_assert (!CONVERT_EXPR_VBASE_PATH (stmt)); 1105 1106 pointer_set_insert (p_set, *stmt_p); 1107 1108 return NULL; 1109 } 1110 1111 void 1112 cp_genericize (tree fndecl) 1113 { 1114 tree t; 1115 struct cp_genericize_data wtd; 1116 1117 /* Fix up the types of parms passed by invisible reference. */ 1118 for (t = DECL_ARGUMENTS (fndecl); t; t = DECL_CHAIN (t)) 1119 if (TREE_ADDRESSABLE (TREE_TYPE (t))) 1120 { 1121 /* If a function's arguments are copied to create a thunk, 1122 then DECL_BY_REFERENCE will be set -- but the type of the 1123 argument will be a pointer type, so we will never get 1124 here. */ 1125 gcc_assert (!DECL_BY_REFERENCE (t)); 1126 gcc_assert (DECL_ARG_TYPE (t) != TREE_TYPE (t)); 1127 TREE_TYPE (t) = DECL_ARG_TYPE (t); 1128 DECL_BY_REFERENCE (t) = 1; 1129 TREE_ADDRESSABLE (t) = 0; 1130 relayout_decl (t); 1131 } 1132 1133 /* Do the same for the return value. */ 1134 if (TREE_ADDRESSABLE (TREE_TYPE (DECL_RESULT (fndecl)))) 1135 { 1136 t = DECL_RESULT (fndecl); 1137 TREE_TYPE (t) = build_reference_type (TREE_TYPE (t)); 1138 DECL_BY_REFERENCE (t) = 1; 1139 TREE_ADDRESSABLE (t) = 0; 1140 relayout_decl (t); 1141 if (DECL_NAME (t)) 1142 { 1143 /* Adjust DECL_VALUE_EXPR of the original var. */ 1144 tree outer = outer_curly_brace_block (current_function_decl); 1145 tree var; 1146 1147 if (outer) 1148 for (var = BLOCK_VARS (outer); var; var = DECL_CHAIN (var)) 1149 if (DECL_NAME (t) == DECL_NAME (var) 1150 && DECL_HAS_VALUE_EXPR_P (var) 1151 && DECL_VALUE_EXPR (var) == t) 1152 { 1153 tree val = convert_from_reference (t); 1154 SET_DECL_VALUE_EXPR (var, val); 1155 break; 1156 } 1157 } 1158 } 1159 1160 /* If we're a clone, the body is already GIMPLE. */ 1161 if (DECL_CLONED_FUNCTION_P (fndecl)) 1162 return; 1163 1164 /* We do want to see every occurrence of the parms, so we can't just use 1165 walk_tree's hash functionality. */ 1166 wtd.p_set = pointer_set_create (); 1167 wtd.bind_expr_stack = NULL; 1168 wtd.omp_ctx = NULL; 1169 cp_walk_tree (&DECL_SAVED_TREE (fndecl), cp_genericize_r, &wtd, NULL); 1170 pointer_set_destroy (wtd.p_set); 1171 VEC_free (tree, heap, wtd.bind_expr_stack); 1172 1173 /* Do everything else. */ 1174 c_genericize (fndecl); 1175 1176 gcc_assert (bc_label[bc_break] == NULL); 1177 gcc_assert (bc_label[bc_continue] == NULL); 1178 } 1179 1180 /* Build code to apply FN to each member of ARG1 and ARG2. FN may be 1181 NULL if there is in fact nothing to do. ARG2 may be null if FN 1182 actually only takes one argument. */ 1183 1184 static tree 1185 cxx_omp_clause_apply_fn (tree fn, tree arg1, tree arg2) 1186 { 1187 tree defparm, parm, t; 1188 int i = 0; 1189 int nargs; 1190 tree *argarray; 1191 1192 if (fn == NULL) 1193 return NULL; 1194 1195 nargs = list_length (DECL_ARGUMENTS (fn)); 1196 argarray = XALLOCAVEC (tree, nargs); 1197 1198 defparm = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn))); 1199 if (arg2) 1200 defparm = TREE_CHAIN (defparm); 1201 1202 if (TREE_CODE (TREE_TYPE (arg1)) == ARRAY_TYPE) 1203 { 1204 tree inner_type = TREE_TYPE (arg1); 1205 tree start1, end1, p1; 1206 tree start2 = NULL, p2 = NULL; 1207 tree ret = NULL, lab; 1208 1209 start1 = arg1; 1210 start2 = arg2; 1211 do 1212 { 1213 inner_type = TREE_TYPE (inner_type); 1214 start1 = build4 (ARRAY_REF, inner_type, start1, 1215 size_zero_node, NULL, NULL); 1216 if (arg2) 1217 start2 = build4 (ARRAY_REF, inner_type, start2, 1218 size_zero_node, NULL, NULL); 1219 } 1220 while (TREE_CODE (inner_type) == ARRAY_TYPE); 1221 start1 = build_fold_addr_expr_loc (input_location, start1); 1222 if (arg2) 1223 start2 = build_fold_addr_expr_loc (input_location, start2); 1224 1225 end1 = TYPE_SIZE_UNIT (TREE_TYPE (arg1)); 1226 end1 = fold_build_pointer_plus (start1, end1); 1227 1228 p1 = create_tmp_var (TREE_TYPE (start1), NULL); 1229 t = build2 (MODIFY_EXPR, TREE_TYPE (p1), p1, start1); 1230 append_to_statement_list (t, &ret); 1231 1232 if (arg2) 1233 { 1234 p2 = create_tmp_var (TREE_TYPE (start2), NULL); 1235 t = build2 (MODIFY_EXPR, TREE_TYPE (p2), p2, start2); 1236 append_to_statement_list (t, &ret); 1237 } 1238 1239 lab = create_artificial_label (input_location); 1240 t = build1 (LABEL_EXPR, void_type_node, lab); 1241 append_to_statement_list (t, &ret); 1242 1243 argarray[i++] = p1; 1244 if (arg2) 1245 argarray[i++] = p2; 1246 /* Handle default arguments. */ 1247 for (parm = defparm; parm && parm != void_list_node; 1248 parm = TREE_CHAIN (parm), i++) 1249 argarray[i] = convert_default_arg (TREE_VALUE (parm), 1250 TREE_PURPOSE (parm), fn, i); 1251 t = build_call_a (fn, i, argarray); 1252 t = fold_convert (void_type_node, t); 1253 t = fold_build_cleanup_point_expr (TREE_TYPE (t), t); 1254 append_to_statement_list (t, &ret); 1255 1256 t = fold_build_pointer_plus (p1, TYPE_SIZE_UNIT (inner_type)); 1257 t = build2 (MODIFY_EXPR, TREE_TYPE (p1), p1, t); 1258 append_to_statement_list (t, &ret); 1259 1260 if (arg2) 1261 { 1262 t = fold_build_pointer_plus (p2, TYPE_SIZE_UNIT (inner_type)); 1263 t = build2 (MODIFY_EXPR, TREE_TYPE (p2), p2, t); 1264 append_to_statement_list (t, &ret); 1265 } 1266 1267 t = build2 (NE_EXPR, boolean_type_node, p1, end1); 1268 t = build3 (COND_EXPR, void_type_node, t, build_and_jump (&lab), NULL); 1269 append_to_statement_list (t, &ret); 1270 1271 return ret; 1272 } 1273 else 1274 { 1275 argarray[i++] = build_fold_addr_expr_loc (input_location, arg1); 1276 if (arg2) 1277 argarray[i++] = build_fold_addr_expr_loc (input_location, arg2); 1278 /* Handle default arguments. */ 1279 for (parm = defparm; parm && parm != void_list_node; 1280 parm = TREE_CHAIN (parm), i++) 1281 argarray[i] = convert_default_arg (TREE_VALUE (parm), 1282 TREE_PURPOSE (parm), 1283 fn, i); 1284 t = build_call_a (fn, i, argarray); 1285 t = fold_convert (void_type_node, t); 1286 return fold_build_cleanup_point_expr (TREE_TYPE (t), t); 1287 } 1288 } 1289 1290 /* Return code to initialize DECL with its default constructor, or 1291 NULL if there's nothing to do. */ 1292 1293 tree 1294 cxx_omp_clause_default_ctor (tree clause, tree decl, 1295 tree outer ATTRIBUTE_UNUSED) 1296 { 1297 tree info = CP_OMP_CLAUSE_INFO (clause); 1298 tree ret = NULL; 1299 1300 if (info) 1301 ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 0), decl, NULL); 1302 1303 return ret; 1304 } 1305 1306 /* Return code to initialize DST with a copy constructor from SRC. */ 1307 1308 tree 1309 cxx_omp_clause_copy_ctor (tree clause, tree dst, tree src) 1310 { 1311 tree info = CP_OMP_CLAUSE_INFO (clause); 1312 tree ret = NULL; 1313 1314 if (info) 1315 ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 0), dst, src); 1316 if (ret == NULL) 1317 ret = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src); 1318 1319 return ret; 1320 } 1321 1322 /* Similarly, except use an assignment operator instead. */ 1323 1324 tree 1325 cxx_omp_clause_assign_op (tree clause, tree dst, tree src) 1326 { 1327 tree info = CP_OMP_CLAUSE_INFO (clause); 1328 tree ret = NULL; 1329 1330 if (info) 1331 ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 2), dst, src); 1332 if (ret == NULL) 1333 ret = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src); 1334 1335 return ret; 1336 } 1337 1338 /* Return code to destroy DECL. */ 1339 1340 tree 1341 cxx_omp_clause_dtor (tree clause, tree decl) 1342 { 1343 tree info = CP_OMP_CLAUSE_INFO (clause); 1344 tree ret = NULL; 1345 1346 if (info) 1347 ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 1), decl, NULL); 1348 1349 return ret; 1350 } 1351 1352 /* True if OpenMP should privatize what this DECL points to rather 1353 than the DECL itself. */ 1354 1355 bool 1356 cxx_omp_privatize_by_reference (const_tree decl) 1357 { 1358 return is_invisiref_parm (decl); 1359 } 1360 1361 /* Return true if DECL is const qualified var having no mutable member. */ 1362 bool 1363 cxx_omp_const_qual_no_mutable (tree decl) 1364 { 1365 tree type = TREE_TYPE (decl); 1366 if (TREE_CODE (type) == REFERENCE_TYPE) 1367 { 1368 if (!is_invisiref_parm (decl)) 1369 return false; 1370 type = TREE_TYPE (type); 1371 1372 if (TREE_CODE (decl) == RESULT_DECL && DECL_NAME (decl)) 1373 { 1374 /* NVR doesn't preserve const qualification of the 1375 variable's type. */ 1376 tree outer = outer_curly_brace_block (current_function_decl); 1377 tree var; 1378 1379 if (outer) 1380 for (var = BLOCK_VARS (outer); var; var = DECL_CHAIN (var)) 1381 if (DECL_NAME (decl) == DECL_NAME (var) 1382 && (TYPE_MAIN_VARIANT (type) 1383 == TYPE_MAIN_VARIANT (TREE_TYPE (var)))) 1384 { 1385 if (TYPE_READONLY (TREE_TYPE (var))) 1386 type = TREE_TYPE (var); 1387 break; 1388 } 1389 } 1390 } 1391 1392 if (type == error_mark_node) 1393 return false; 1394 1395 /* Variables with const-qualified type having no mutable member 1396 are predetermined shared. */ 1397 if (TYPE_READONLY (type) && !cp_has_mutable_p (type)) 1398 return true; 1399 1400 return false; 1401 } 1402 1403 /* True if OpenMP sharing attribute of DECL is predetermined. */ 1404 1405 enum omp_clause_default_kind 1406 cxx_omp_predetermined_sharing (tree decl) 1407 { 1408 /* Static data members are predetermined shared. */ 1409 if (TREE_STATIC (decl)) 1410 { 1411 tree ctx = CP_DECL_CONTEXT (decl); 1412 if (TYPE_P (ctx) && MAYBE_CLASS_TYPE_P (ctx)) 1413 return OMP_CLAUSE_DEFAULT_SHARED; 1414 } 1415 1416 /* Const qualified vars having no mutable member are predetermined 1417 shared. */ 1418 if (cxx_omp_const_qual_no_mutable (decl)) 1419 return OMP_CLAUSE_DEFAULT_SHARED; 1420 1421 return OMP_CLAUSE_DEFAULT_UNSPECIFIED; 1422 } 1423 1424 /* Finalize an implicitly determined clause. */ 1425 1426 void 1427 cxx_omp_finish_clause (tree c) 1428 { 1429 tree decl, inner_type; 1430 bool make_shared = false; 1431 1432 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_FIRSTPRIVATE) 1433 return; 1434 1435 decl = OMP_CLAUSE_DECL (c); 1436 decl = require_complete_type (decl); 1437 inner_type = TREE_TYPE (decl); 1438 if (decl == error_mark_node) 1439 make_shared = true; 1440 else if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE) 1441 { 1442 if (is_invisiref_parm (decl)) 1443 inner_type = TREE_TYPE (inner_type); 1444 else 1445 { 1446 error ("%qE implicitly determined as %<firstprivate%> has reference type", 1447 decl); 1448 make_shared = true; 1449 } 1450 } 1451 1452 /* We're interested in the base element, not arrays. */ 1453 while (TREE_CODE (inner_type) == ARRAY_TYPE) 1454 inner_type = TREE_TYPE (inner_type); 1455 1456 /* Check for special function availability by building a call to one. 1457 Save the results, because later we won't be in the right context 1458 for making these queries. */ 1459 if (!make_shared 1460 && CLASS_TYPE_P (inner_type) 1461 && cxx_omp_create_clause_info (c, inner_type, false, true, false)) 1462 make_shared = true; 1463 1464 if (make_shared) 1465 OMP_CLAUSE_CODE (c) = OMP_CLAUSE_SHARED; 1466 } 1467