1/* Perform optimizations on tree structure. 2 Copyright (C) 1998-2015 Free Software Foundation, Inc. 3 Written by Mark Michell (mark@codesourcery.com). 4 5This file is part of GCC. 6 7GCC is free software; you can redistribute it and/or modify it 8under the terms of the GNU General Public License as published by 9the Free Software Foundation; either version 3, or (at your option) 10any later version. 11 12GCC is distributed in the hope that it will be useful, but 13WITHOUT ANY WARRANTY; without even the implied warranty of 14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15General Public License for more details. 16 17You should have received a copy of the GNU General Public License 18along with GCC; see the file COPYING3. If not see 19<http://www.gnu.org/licenses/>. */ 20 21#include "config.h" 22#include "system.h" 23#include "coretypes.h" 24#include "tm.h" 25#include "hash-set.h" 26#include "machmode.h" 27#include "vec.h" 28#include "double-int.h" 29#include "input.h" 30#include "alias.h" 31#include "symtab.h" 32#include "wide-int.h" 33#include "inchash.h" 34#include "tree.h" 35#include "stringpool.h" 36#include "cp-tree.h" 37#include "input.h" 38#include "params.h" 39#include "hashtab.h" 40#include "target.h" 41#include "debug.h" 42#include "tree-inline.h" 43#include "flags.h" 44#include "langhooks.h" 45#include "diagnostic-core.h" 46#include "dumpfile.h" 47#include "tree-iterator.h" 48#include "hash-map.h" 49#include "is-a.h" 50#include "plugin-api.h" 51#include "hard-reg-set.h" 52#include "function.h" 53#include "ipa-ref.h" 54#include "cgraph.h" 55 56/* Prototypes. */ 57 58static void update_cloned_parm (tree, tree, bool); 59 60/* CLONED_PARM is a copy of CLONE, generated for a cloned constructor 61 or destructor. Update it to ensure that the source-position for 62 the cloned parameter matches that for the original, and that the 63 debugging generation code will be able to find the original PARM. */ 64 65static void 66update_cloned_parm (tree parm, tree cloned_parm, bool first) 67{ 68 DECL_ABSTRACT_ORIGIN (cloned_parm) = parm; 69 70 /* We may have taken its address. */ 71 TREE_ADDRESSABLE (cloned_parm) = TREE_ADDRESSABLE (parm); 72 73 /* The definition might have different constness. */ 74 TREE_READONLY (cloned_parm) = TREE_READONLY (parm); 75 76 TREE_USED (cloned_parm) = !first || TREE_USED (parm); 77 78 /* The name may have changed from the declaration. */ 79 DECL_NAME (cloned_parm) = DECL_NAME (parm); 80 DECL_SOURCE_LOCATION (cloned_parm) = DECL_SOURCE_LOCATION (parm); 81 TREE_TYPE (cloned_parm) = TREE_TYPE (parm); 82 83 DECL_GIMPLE_REG_P (cloned_parm) = DECL_GIMPLE_REG_P (parm); 84} 85 86 87/* FN is a function in High GIMPLE form that has a complete body and no 88 CFG. CLONE is a function whose body is to be set to a copy of FN, 89 mapping argument declarations according to the ARG_MAP splay_tree. */ 90 91static void 92clone_body (tree clone, tree fn, void *arg_map) 93{ 94 copy_body_data id; 95 tree stmts; 96 97 /* Clone the body, as if we were making an inline call. But, remap 98 the parameters in the callee to the parameters of caller. */ 99 memset (&id, 0, sizeof (id)); 100 id.src_fn = fn; 101 id.dst_fn = clone; 102 id.src_cfun = DECL_STRUCT_FUNCTION (fn); 103 id.decl_map = static_cast<hash_map<tree, tree> *> (arg_map); 104 105 id.copy_decl = copy_decl_no_change; 106 id.transform_call_graph_edges = CB_CGE_DUPLICATE; 107 id.transform_new_cfg = true; 108 id.transform_return_to_modify = false; 109 id.transform_lang_insert_block = NULL; 110 111 /* We're not inside any EH region. */ 112 id.eh_lp_nr = 0; 113 114 stmts = DECL_SAVED_TREE (fn); 115 walk_tree (&stmts, copy_tree_body_r, &id, NULL); 116 117 /* Also remap the initializer of any static variables so that they (in 118 particular, any label addresses) correspond to the base variant rather 119 than the abstract one. */ 120 if (DECL_NAME (clone) == base_dtor_identifier 121 || DECL_NAME (clone) == base_ctor_identifier) 122 { 123 unsigned ix; 124 tree decl; 125 126 FOR_EACH_LOCAL_DECL (DECL_STRUCT_FUNCTION (fn), ix, decl) 127 walk_tree (&DECL_INITIAL (decl), copy_tree_body_r, &id, NULL); 128 } 129 130 append_to_statement_list_force (stmts, &DECL_SAVED_TREE (clone)); 131} 132 133/* DELETE_DTOR is a delete destructor whose body will be built. 134 COMPLETE_DTOR is the corresponding complete destructor. */ 135 136static void 137build_delete_destructor_body (tree delete_dtor, tree complete_dtor) 138{ 139 tree call_dtor, call_delete; 140 tree parm = DECL_ARGUMENTS (delete_dtor); 141 tree virtual_size = cxx_sizeof (current_class_type); 142 143 /* Call the corresponding complete destructor. */ 144 gcc_assert (complete_dtor); 145 call_dtor = build_cxx_call (complete_dtor, 1, &parm, 146 tf_warning_or_error); 147 add_stmt (call_dtor); 148 149 add_stmt (build_stmt (0, LABEL_EXPR, cdtor_label)); 150 151 /* Call the delete function. */ 152 call_delete = build_op_delete_call (DELETE_EXPR, current_class_ptr, 153 virtual_size, 154 /*global_p=*/false, 155 /*placement=*/NULL_TREE, 156 /*alloc_fn=*/NULL_TREE, 157 tf_warning_or_error); 158 add_stmt (call_delete); 159 160 /* Return the address of the object. */ 161 if (targetm.cxx.cdtor_returns_this ()) 162 { 163 tree val = DECL_ARGUMENTS (delete_dtor); 164 val = build2 (MODIFY_EXPR, TREE_TYPE (val), 165 DECL_RESULT (delete_dtor), val); 166 add_stmt (build_stmt (0, RETURN_EXPR, val)); 167 } 168} 169 170/* Return name of comdat group for complete and base ctor (or dtor) 171 that have the same body. If dtor is virtual, deleting dtor goes 172 into this comdat group as well. */ 173 174static tree 175cdtor_comdat_group (tree complete, tree base) 176{ 177 tree complete_name = DECL_ASSEMBLER_NAME (complete); 178 tree base_name = DECL_ASSEMBLER_NAME (base); 179 char *grp_name; 180 const char *p, *q; 181 bool diff_seen = false; 182 size_t idx; 183 gcc_assert (IDENTIFIER_LENGTH (complete_name) 184 == IDENTIFIER_LENGTH (base_name)); 185 grp_name = XALLOCAVEC (char, IDENTIFIER_LENGTH (complete_name) + 1); 186 p = IDENTIFIER_POINTER (complete_name); 187 q = IDENTIFIER_POINTER (base_name); 188 for (idx = 0; idx < IDENTIFIER_LENGTH (complete_name); idx++) 189 if (p[idx] == q[idx]) 190 grp_name[idx] = p[idx]; 191 else 192 { 193 gcc_assert (!diff_seen 194 && idx > 0 195 && (p[idx - 1] == 'C' || p[idx - 1] == 'D') 196 && p[idx] == '1' 197 && q[idx] == '2'); 198 grp_name[idx] = '5'; 199 diff_seen = true; 200 } 201 grp_name[idx] = '\0'; 202 gcc_assert (diff_seen); 203 return get_identifier (grp_name); 204} 205 206/* Returns true iff we can make the base and complete [cd]tor aliases of 207 the same symbol rather than separate functions. */ 208 209static bool 210can_alias_cdtor (tree fn) 211{ 212#ifndef ASM_OUTPUT_DEF 213 /* If aliases aren't supported by the assembler, fail. */ 214 return false; 215#endif 216 /* We can't use an alias if there are virtual bases. */ 217 if (CLASSTYPE_VBASECLASSES (DECL_CONTEXT (fn))) 218 return false; 219 /* ??? Why not use aliases with -frepo? */ 220 if (flag_use_repository) 221 return false; 222 gcc_assert (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn) 223 || DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn)); 224 /* Don't use aliases for weak/linkonce definitions unless we can put both 225 symbols in the same COMDAT group. */ 226 return (DECL_INTERFACE_KNOWN (fn) 227 && (SUPPORTS_ONE_ONLY || !DECL_WEAK (fn)) 228 && (!DECL_ONE_ONLY (fn) 229 || (HAVE_COMDAT_GROUP && DECL_WEAK (fn)))); 230} 231 232/* FN is a [cd]tor, fns is a pointer to an array of length 3. Fill fns 233 with pointers to the base, complete, and deleting variants. */ 234 235static void 236populate_clone_array (tree fn, tree *fns) 237{ 238 tree clone; 239 240 fns[0] = NULL_TREE; 241 fns[1] = NULL_TREE; 242 fns[2] = NULL_TREE; 243 244 /* Look for the complete destructor which may be used to build the 245 delete destructor. */ 246 FOR_EACH_CLONE (clone, fn) 247 if (DECL_NAME (clone) == complete_dtor_identifier 248 || DECL_NAME (clone) == complete_ctor_identifier) 249 fns[1] = clone; 250 else if (DECL_NAME (clone) == base_dtor_identifier 251 || DECL_NAME (clone) == base_ctor_identifier) 252 fns[0] = clone; 253 else if (DECL_NAME (clone) == deleting_dtor_identifier) 254 fns[2] = clone; 255 else 256 gcc_unreachable (); 257} 258 259/* FN is a constructor or destructor, and there are FUNCTION_DECLs 260 cloned from it nearby. Instead of cloning this body, leave it 261 alone and create tiny one-call bodies for the cloned 262 FUNCTION_DECLs. These clones are sibcall candidates, and their 263 resulting code will be very thunk-esque. */ 264 265static bool 266maybe_thunk_body (tree fn, bool force) 267{ 268 tree bind, block, call, clone, clone_result, fn_parm, fn_parm_typelist; 269 tree last_arg, modify, *args; 270 int parmno, vtt_parmno, max_parms; 271 tree fns[3]; 272 273 if (!force && !flag_declone_ctor_dtor) 274 return 0; 275 276 /* If function accepts variable arguments, give up. */ 277 last_arg = tree_last (TYPE_ARG_TYPES (TREE_TYPE (fn))); 278 if (last_arg != void_list_node) 279 return 0; 280 281 /* If we got this far, we've decided to turn the clones into thunks. */ 282 283 /* We're going to generate code for fn, so it is no longer "abstract." 284 Also make the unified ctor/dtor private to either the translation unit 285 (for non-vague linkage ctors) or the COMDAT group (otherwise). */ 286 287 populate_clone_array (fn, fns); 288 DECL_ABSTRACT_P (fn) = false; 289 if (!DECL_WEAK (fn)) 290 { 291 TREE_PUBLIC (fn) = false; 292 DECL_EXTERNAL (fn) = false; 293 DECL_INTERFACE_KNOWN (fn) = true; 294 } 295 else if (HAVE_COMDAT_GROUP) 296 { 297 /* At eof, defer creation of mangling aliases temporarily. */ 298 bool save_defer_mangling_aliases = defer_mangling_aliases; 299 defer_mangling_aliases = true; 300 tree comdat_group = cdtor_comdat_group (fns[1], fns[0]); 301 defer_mangling_aliases = save_defer_mangling_aliases; 302 cgraph_node::get_create (fns[0])->set_comdat_group (comdat_group); 303 cgraph_node::get_create (fns[1])->add_to_same_comdat_group 304 (cgraph_node::get_create (fns[0])); 305 symtab_node::get (fn)->add_to_same_comdat_group 306 (symtab_node::get (fns[0])); 307 if (fns[2]) 308 /* If *[CD][12]* dtors go into the *[CD]5* comdat group and dtor is 309 virtual, it goes into the same comdat group as well. */ 310 cgraph_node::get_create (fns[2])->add_to_same_comdat_group 311 (symtab_node::get (fns[0])); 312 /* Emit them now that the thunks are same comdat group aliases. */ 313 if (!save_defer_mangling_aliases) 314 generate_mangling_aliases (); 315 TREE_PUBLIC (fn) = false; 316 DECL_EXTERNAL (fn) = false; 317 DECL_INTERFACE_KNOWN (fn) = true; 318 /* function_and_variable_visibility doesn't want !PUBLIC decls to 319 have these flags set. */ 320 DECL_WEAK (fn) = false; 321 DECL_COMDAT (fn) = false; 322 } 323 324 /* Find the vtt_parm, if present. */ 325 for (vtt_parmno = -1, parmno = 0, fn_parm = DECL_ARGUMENTS (fn); 326 fn_parm; 327 ++parmno, fn_parm = TREE_CHAIN (fn_parm)) 328 { 329 if (DECL_ARTIFICIAL (fn_parm) 330 && DECL_NAME (fn_parm) == vtt_parm_identifier) 331 { 332 /* Compensate for removed in_charge parameter. */ 333 vtt_parmno = parmno; 334 break; 335 } 336 } 337 338 /* Allocate an argument buffer for build_cxx_call(). 339 Make sure it is large enough for any of the clones. */ 340 max_parms = 0; 341 FOR_EACH_CLONE (clone, fn) 342 { 343 int length = list_length (DECL_ARGUMENTS (fn)); 344 if (length > max_parms) 345 max_parms = length; 346 } 347 args = (tree *) alloca (max_parms * sizeof (tree)); 348 349 /* We know that any clones immediately follow FN in TYPE_METHODS. */ 350 FOR_EACH_CLONE (clone, fn) 351 { 352 tree clone_parm; 353 354 /* If we've already generated a body for this clone, avoid 355 duplicating it. (Is it possible for a clone-list to grow after we 356 first see it?) */ 357 if (DECL_SAVED_TREE (clone) || TREE_ASM_WRITTEN (clone)) 358 continue; 359 360 /* Start processing the function. */ 361 start_preparsed_function (clone, NULL_TREE, SF_PRE_PARSED); 362 363 if (clone == fns[2]) 364 { 365 for (clone_parm = DECL_ARGUMENTS (clone); clone_parm; 366 clone_parm = TREE_CHAIN (clone_parm)) 367 DECL_ABSTRACT_ORIGIN (clone_parm) = NULL_TREE; 368 /* Build the delete destructor by calling complete destructor and 369 delete function. */ 370 build_delete_destructor_body (clone, fns[1]); 371 } 372 else 373 { 374 /* Walk parameter lists together, creating parameter list for 375 call to original function. */ 376 for (parmno = 0, 377 fn_parm = DECL_ARGUMENTS (fn), 378 fn_parm_typelist = TYPE_ARG_TYPES (TREE_TYPE (fn)), 379 clone_parm = DECL_ARGUMENTS (clone); 380 fn_parm; 381 ++parmno, 382 fn_parm = TREE_CHAIN (fn_parm)) 383 { 384 if (parmno == vtt_parmno && ! DECL_HAS_VTT_PARM_P (clone)) 385 { 386 gcc_assert (fn_parm_typelist); 387 /* Clobber argument with formal parameter type. */ 388 args[parmno] 389 = convert (TREE_VALUE (fn_parm_typelist), 390 null_pointer_node); 391 } 392 else if (parmno == 1 && DECL_HAS_IN_CHARGE_PARM_P (fn)) 393 { 394 tree in_charge 395 = copy_node (in_charge_arg_for_name (DECL_NAME (clone))); 396 args[parmno] = in_charge; 397 } 398 /* Map other parameters to their equivalents in the cloned 399 function. */ 400 else 401 { 402 gcc_assert (clone_parm); 403 DECL_ABSTRACT_ORIGIN (clone_parm) = NULL; 404 args[parmno] = clone_parm; 405 clone_parm = TREE_CHAIN (clone_parm); 406 } 407 if (fn_parm_typelist) 408 fn_parm_typelist = TREE_CHAIN (fn_parm_typelist); 409 } 410 411 /* We built this list backwards; fix now. */ 412 mark_used (fn); 413 call = build_cxx_call (fn, parmno, args, tf_warning_or_error); 414 /* Arguments passed to the thunk by invisible reference should 415 be transmitted to the callee unchanged. Do not create a 416 temporary and invoke the copy constructor. The thunking 417 transformation must not introduce any constructor calls. */ 418 CALL_FROM_THUNK_P (call) = 1; 419 block = make_node (BLOCK); 420 if (targetm.cxx.cdtor_returns_this ()) 421 { 422 clone_result = DECL_RESULT (clone); 423 modify = build2 (MODIFY_EXPR, TREE_TYPE (clone_result), 424 clone_result, call); 425 modify = build1 (RETURN_EXPR, void_type_node, modify); 426 add_stmt (modify); 427 } 428 else 429 { 430 add_stmt (call); 431 } 432 bind = c_build_bind_expr (DECL_SOURCE_LOCATION (clone), 433 block, cur_stmt_list); 434 DECL_SAVED_TREE (clone) = push_stmt_list (); 435 add_stmt (bind); 436 } 437 438 DECL_ABSTRACT_ORIGIN (clone) = NULL; 439 expand_or_defer_fn (finish_function (0)); 440 } 441 return 1; 442} 443 444/* FN is a function that has a complete body. Clone the body as 445 necessary. Returns nonzero if there's no longer any need to 446 process the main body. */ 447 448bool 449maybe_clone_body (tree fn) 450{ 451 tree comdat_group = NULL_TREE; 452 tree clone; 453 tree fns[3]; 454 bool first = true; 455 int idx; 456 bool need_alias = false; 457 458 /* We only clone constructors and destructors. */ 459 if (!DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn) 460 && !DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn)) 461 return 0; 462 463 populate_clone_array (fn, fns); 464 465 /* Remember if we can't have multiple clones for some reason. We need to 466 check this before we remap local static initializers in clone_body. */ 467 if (!tree_versionable_function_p (fn)) 468 need_alias = true; 469 470 /* We know that any clones immediately follow FN in the TYPE_METHODS 471 list. */ 472 push_to_top_level (); 473 for (idx = 0; idx < 3; idx++) 474 { 475 tree parm; 476 tree clone_parm; 477 478 clone = fns[idx]; 479 if (!clone) 480 continue; 481 482 /* Update CLONE's source position information to match FN's. */ 483 DECL_SOURCE_LOCATION (clone) = DECL_SOURCE_LOCATION (fn); 484 DECL_DECLARED_INLINE_P (clone) = DECL_DECLARED_INLINE_P (fn); 485 DECL_DECLARED_CONSTEXPR_P (clone) = DECL_DECLARED_CONSTEXPR_P (fn); 486 DECL_COMDAT (clone) = DECL_COMDAT (fn); 487 DECL_WEAK (clone) = DECL_WEAK (fn); 488 489 /* We don't copy the comdat group from fn to clone because the assembler 490 name of fn was corrupted by write_mangled_name by adding *INTERNAL* 491 to it. By doing so, it also corrupted the comdat group. */ 492 if (DECL_ONE_ONLY (fn)) 493 cgraph_node::get_create (clone)->set_comdat_group (cxx_comdat_group (clone)); 494 DECL_USE_TEMPLATE (clone) = DECL_USE_TEMPLATE (fn); 495 DECL_EXTERNAL (clone) = DECL_EXTERNAL (fn); 496 DECL_INTERFACE_KNOWN (clone) = DECL_INTERFACE_KNOWN (fn); 497 DECL_NOT_REALLY_EXTERN (clone) = DECL_NOT_REALLY_EXTERN (fn); 498 TREE_PUBLIC (clone) = TREE_PUBLIC (fn); 499 DECL_VISIBILITY (clone) = DECL_VISIBILITY (fn); 500 DECL_VISIBILITY_SPECIFIED (clone) = DECL_VISIBILITY_SPECIFIED (fn); 501 DECL_DLLIMPORT_P (clone) = DECL_DLLIMPORT_P (fn); 502 DECL_ATTRIBUTES (clone) = copy_list (DECL_ATTRIBUTES (fn)); 503 DECL_DISREGARD_INLINE_LIMITS (clone) = DECL_DISREGARD_INLINE_LIMITS (fn); 504 set_decl_section_name (clone, DECL_SECTION_NAME (fn)); 505 506 /* Adjust the parameter names and locations. */ 507 parm = DECL_ARGUMENTS (fn); 508 clone_parm = DECL_ARGUMENTS (clone); 509 /* Update the `this' parameter, which is always first. */ 510 update_cloned_parm (parm, clone_parm, first); 511 parm = DECL_CHAIN (parm); 512 clone_parm = DECL_CHAIN (clone_parm); 513 if (DECL_HAS_IN_CHARGE_PARM_P (fn)) 514 parm = DECL_CHAIN (parm); 515 if (DECL_HAS_VTT_PARM_P (fn)) 516 parm = DECL_CHAIN (parm); 517 if (DECL_HAS_VTT_PARM_P (clone)) 518 clone_parm = DECL_CHAIN (clone_parm); 519 for (; parm; 520 parm = DECL_CHAIN (parm), clone_parm = DECL_CHAIN (clone_parm)) 521 /* Update this parameter. */ 522 update_cloned_parm (parm, clone_parm, first); 523 } 524 525 bool can_alias = can_alias_cdtor (fn); 526 527 /* If we decide to turn clones into thunks, they will branch to fn. 528 Must have original function available to call. */ 529 if (!can_alias && maybe_thunk_body (fn, need_alias)) 530 { 531 pop_from_top_level (); 532 /* We still need to emit the original function. */ 533 return 0; 534 } 535 536 /* Emit the DWARF1 abstract instance. */ 537 (*debug_hooks->deferred_inline_function) (fn); 538 539 /* We know that any clones immediately follow FN in the TYPE_METHODS list. */ 540 for (idx = 0; idx < 3; idx++) 541 { 542 tree parm; 543 tree clone_parm; 544 int parmno; 545 hash_map<tree, tree> *decl_map; 546 bool alias = false; 547 548 clone = fns[idx]; 549 if (!clone) 550 continue; 551 552 /* Start processing the function. */ 553 start_preparsed_function (clone, NULL_TREE, SF_PRE_PARSED); 554 555 /* Tell cgraph if both ctors or both dtors are known to have 556 the same body. */ 557 if (can_alias 558 && fns[0] 559 && idx == 1 560 && cgraph_node::get_create (fns[0])->create_same_body_alias 561 (clone, fns[0])) 562 { 563 alias = true; 564 if (DECL_ONE_ONLY (fns[0])) 565 { 566 /* For comdat base and complete cdtors put them 567 into the same, *[CD]5* comdat group instead of 568 *[CD][12]*. */ 569 comdat_group = cdtor_comdat_group (fns[1], fns[0]); 570 cgraph_node::get_create (fns[0])->set_comdat_group (comdat_group); 571 if (symtab_node::get (clone)->same_comdat_group) 572 symtab_node::get (clone)->remove_from_same_comdat_group (); 573 symtab_node::get (clone)->add_to_same_comdat_group 574 (symtab_node::get (fns[0])); 575 } 576 } 577 578 /* Build the delete destructor by calling complete destructor 579 and delete function. */ 580 if (idx == 2) 581 { 582 build_delete_destructor_body (clone, fns[1]); 583 /* If *[CD][12]* dtors go into the *[CD]5* comdat group and dtor is 584 virtual, it goes into the same comdat group as well. */ 585 if (comdat_group) 586 cgraph_node::get_create (clone)->add_to_same_comdat_group 587 (symtab_node::get (fns[0])); 588 } 589 else if (alias) 590 /* No need to populate body. */ ; 591 else 592 { 593 /* If we can't have multiple copies of FN (say, because there's a 594 static local initialized with the address of a label), we need 595 to use an alias for the complete variant. */ 596 if (idx == 1 && need_alias) 597 { 598 if (DECL_STRUCT_FUNCTION (fn)->cannot_be_copied_set) 599 sorry (DECL_STRUCT_FUNCTION (fn)->cannot_be_copied_reason, fn); 600 else 601 sorry ("making multiple clones of %qD", fn); 602 } 603 604 /* Remap the parameters. */ 605 decl_map = new hash_map<tree, tree>; 606 for (parmno = 0, 607 parm = DECL_ARGUMENTS (fn), 608 clone_parm = DECL_ARGUMENTS (clone); 609 parm; 610 ++parmno, 611 parm = DECL_CHAIN (parm)) 612 { 613 /* Map the in-charge parameter to an appropriate constant. */ 614 if (DECL_HAS_IN_CHARGE_PARM_P (fn) && parmno == 1) 615 { 616 tree in_charge; 617 in_charge = in_charge_arg_for_name (DECL_NAME (clone)); 618 decl_map->put (parm, in_charge); 619 } 620 else if (DECL_ARTIFICIAL (parm) 621 && DECL_NAME (parm) == vtt_parm_identifier) 622 { 623 /* For a subobject constructor or destructor, the next 624 argument is the VTT parameter. Remap the VTT_PARM 625 from the CLONE to this parameter. */ 626 if (DECL_HAS_VTT_PARM_P (clone)) 627 { 628 DECL_ABSTRACT_ORIGIN (clone_parm) = parm; 629 decl_map->put (parm, clone_parm); 630 clone_parm = DECL_CHAIN (clone_parm); 631 } 632 /* Otherwise, map the VTT parameter to `NULL'. */ 633 else 634 { 635 tree t 636 = fold_convert (TREE_TYPE (parm), null_pointer_node); 637 decl_map->put (parm, t); 638 } 639 } 640 /* Map other parameters to their equivalents in the cloned 641 function. */ 642 else 643 { 644 decl_map->put (parm, clone_parm); 645 clone_parm = DECL_CHAIN (clone_parm); 646 } 647 } 648 649 if (targetm.cxx.cdtor_returns_this ()) 650 { 651 parm = DECL_RESULT (fn); 652 clone_parm = DECL_RESULT (clone); 653 decl_map->put (parm, clone_parm); 654 } 655 656 /* Clone the body. */ 657 clone_body (clone, fn, decl_map); 658 659 /* Clean up. */ 660 delete decl_map; 661 } 662 663 /* The clone can throw iff the original function can throw. */ 664 cp_function_chain->can_throw = !TREE_NOTHROW (fn); 665 666 /* Now, expand this function into RTL, if appropriate. */ 667 finish_function (0); 668 BLOCK_ABSTRACT_ORIGIN (DECL_INITIAL (clone)) = DECL_INITIAL (fn); 669 if (alias) 670 { 671 if (expand_or_defer_fn_1 (clone)) 672 emit_associated_thunks (clone); 673 /* We didn't generate a body, so remove the empty one. */ 674 DECL_SAVED_TREE (clone) = NULL_TREE; 675 } 676 else 677 expand_or_defer_fn (clone); 678 first = false; 679 } 680 pop_from_top_level (); 681 682 /* We don't need to process the original function any further. */ 683 return 1; 684} 685