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