Fix typo in t-dimode
[official-gcc.git] / gcc / cp / optimize.c
blobe6fd27f1092e43b19cb248aed1693d16612dd208
1 /* Perform optimizations on tree structure.
2 Copyright (C) 1998-2021 Free Software Foundation, Inc.
3 Written by Mark Michell (mark@codesourcery.com).
5 This file is part of GCC.
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.
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.
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/>. */
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"
32 /* Prototypes. */
34 static void update_cloned_parm (tree, tree, bool);
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. */
41 static void
42 update_cloned_parm (tree parm, tree cloned_parm, bool first)
44 DECL_ABSTRACT_ORIGIN (cloned_parm) = parm;
46 /* We may have taken its address. */
47 TREE_ADDRESSABLE (cloned_parm) = TREE_ADDRESSABLE (parm);
49 DECL_BY_REFERENCE (cloned_parm) = DECL_BY_REFERENCE (parm);
51 /* The definition might have different constness. */
52 TREE_READONLY (cloned_parm) = TREE_READONLY (parm);
54 TREE_USED (cloned_parm) = !first || TREE_USED (parm);
56 /* The name may have changed from the declaration. */
57 DECL_NAME (cloned_parm) = DECL_NAME (parm);
58 DECL_SOURCE_LOCATION (cloned_parm) = DECL_SOURCE_LOCATION (parm);
59 TREE_TYPE (cloned_parm) = TREE_TYPE (parm);
61 DECL_NOT_GIMPLE_REG_P (cloned_parm) = DECL_NOT_GIMPLE_REG_P (parm);
64 /* Like copy_decl_no_change, but handle DECL_OMP_PRIVATIZED_MEMBER
65 properly. */
67 static tree
68 cxx_copy_decl (tree decl, copy_body_data *id)
70 tree copy = copy_decl_no_change (decl, id);
71 if (VAR_P (decl)
72 && DECL_HAS_VALUE_EXPR_P (decl)
73 && DECL_ARTIFICIAL (decl)
74 && DECL_LANG_SPECIFIC (decl)
75 && DECL_OMP_PRIVATIZED_MEMBER (decl))
77 tree expr = DECL_VALUE_EXPR (copy);
78 walk_tree (&expr, copy_tree_body_r, id, NULL);
79 SET_DECL_VALUE_EXPR (copy, expr);
81 return copy;
84 /* FN is a function in High GIMPLE form that has a complete body and no
85 CFG. CLONE is a function whose body is to be set to a copy of FN,
86 mapping argument declarations according to the ARG_MAP splay_tree. */
88 static void
89 clone_body (tree clone, tree fn, void *arg_map)
91 copy_body_data id;
92 tree stmts;
94 /* Clone the body, as if we were making an inline call. But, remap
95 the parameters in the callee to the parameters of caller. */
96 memset (&id, 0, sizeof (id));
97 id.src_fn = fn;
98 id.dst_fn = clone;
99 id.src_cfun = DECL_STRUCT_FUNCTION (fn);
100 id.decl_map = static_cast<hash_map<tree, tree> *> (arg_map);
102 id.copy_decl = cxx_copy_decl;
103 id.transform_call_graph_edges = CB_CGE_DUPLICATE;
104 id.transform_new_cfg = true;
105 id.transform_return_to_modify = false;
107 /* We're not inside any EH region. */
108 id.eh_lp_nr = 0;
110 stmts = DECL_SAVED_TREE (fn);
111 walk_tree (&stmts, copy_tree_body_r, &id, NULL);
113 /* Also remap the initializer of any static variables so that they (in
114 particular, any label addresses) correspond to the base variant rather
115 than the abstract one. */
116 if (DECL_NAME (clone) == base_dtor_identifier
117 || DECL_NAME (clone) == base_ctor_identifier)
119 unsigned ix;
120 tree decl;
122 FOR_EACH_LOCAL_DECL (DECL_STRUCT_FUNCTION (fn), ix, decl)
123 walk_tree (&DECL_INITIAL (decl), copy_tree_body_r, &id, NULL);
126 append_to_statement_list_force (stmts, &DECL_SAVED_TREE (clone));
129 /* DELETE_DTOR is a delete destructor whose body will be built.
130 COMPLETE_DTOR is the corresponding complete destructor. */
132 static void
133 build_delete_destructor_body (tree delete_dtor, tree complete_dtor)
135 tree parm = DECL_ARGUMENTS (delete_dtor);
136 tree virtual_size = cxx_sizeof (current_class_type);
138 /* Call the delete function. */
139 tree call_delete = build_op_delete_call (DELETE_EXPR, current_class_ptr,
140 virtual_size,
141 /*global_p=*/false,
142 /*placement=*/NULL_TREE,
143 /*alloc_fn=*/NULL_TREE,
144 tf_warning_or_error);
146 tree op = get_callee_fndecl (call_delete);
147 if (op && DECL_P (op) && destroying_delete_p (op))
149 /* The destroying delete will handle calling complete_dtor. */
150 add_stmt (call_delete);
152 else
154 /* Call the corresponding complete destructor. */
155 gcc_assert (complete_dtor);
156 tree call_dtor = build_cxx_call (complete_dtor, 1, &parm,
157 tf_warning_or_error);
159 /* Operator delete must be called, whether or not the dtor throws. */
160 add_stmt (build2 (TRY_FINALLY_EXPR, void_type_node,
161 call_dtor, call_delete));
164 /* Return the address of the object.
165 ??? How is it useful to return an invalid address? */
166 if (targetm.cxx.cdtor_returns_this ())
168 tree val = DECL_ARGUMENTS (delete_dtor);
169 val = build2 (MODIFY_EXPR, TREE_TYPE (val),
170 DECL_RESULT (delete_dtor), val);
171 add_stmt (build_stmt (0, RETURN_EXPR, val));
175 /* Return name of comdat group for complete and base ctor (or dtor)
176 that have the same body. If dtor is virtual, deleting dtor goes
177 into this comdat group as well. */
179 static tree
180 cdtor_comdat_group (tree complete, tree base)
182 tree complete_name = DECL_ASSEMBLER_NAME (complete);
183 tree base_name = DECL_ASSEMBLER_NAME (base);
184 char *grp_name;
185 const char *p, *q;
186 bool diff_seen = false;
187 size_t idx;
188 gcc_assert (IDENTIFIER_LENGTH (complete_name)
189 == IDENTIFIER_LENGTH (base_name));
190 grp_name = XALLOCAVEC (char, IDENTIFIER_LENGTH (complete_name) + 1);
191 p = IDENTIFIER_POINTER (complete_name);
192 q = IDENTIFIER_POINTER (base_name);
193 for (idx = 0; idx < IDENTIFIER_LENGTH (complete_name); idx++)
194 if (p[idx] == q[idx])
195 grp_name[idx] = p[idx];
196 else
198 gcc_assert (!diff_seen
199 && idx > 0
200 && (p[idx - 1] == 'C' || p[idx - 1] == 'D'
201 || p[idx - 1] == 'I')
202 && p[idx] == '1'
203 && q[idx] == '2');
204 grp_name[idx] = '5';
205 diff_seen = true;
207 grp_name[idx] = '\0';
208 gcc_assert (diff_seen);
209 return get_identifier (grp_name);
212 /* Returns true iff we can make the base and complete [cd]tor aliases of
213 the same symbol rather than separate functions. */
215 static bool
216 can_alias_cdtor (tree fn)
218 /* If aliases aren't supported by the assembler, fail. */
219 if (!TARGET_SUPPORTS_ALIASES)
220 return false;
222 /* We can't use an alias if there are virtual bases. */
223 if (CLASSTYPE_VBASECLASSES (DECL_CONTEXT (fn)))
224 return false;
225 gcc_assert (DECL_MAYBE_IN_CHARGE_CDTOR_P (fn));
226 /* Don't use aliases for weak/linkonce definitions unless we can put both
227 symbols in the same COMDAT group. */
228 return (DECL_INTERFACE_KNOWN (fn)
229 && (SUPPORTS_ONE_ONLY || !DECL_WEAK (fn))
230 && (!DECL_ONE_ONLY (fn)
231 || (HAVE_COMDAT_GROUP && DECL_WEAK (fn))));
234 /* FN is a [cd]tor, fns is a pointer to an array of length 3. Fill fns
235 with pointers to the base, complete, and deleting variants. */
237 static void
238 populate_clone_array (tree fn, tree *fns)
240 tree clone;
242 fns[0] = NULL_TREE;
243 fns[1] = NULL_TREE;
244 fns[2] = NULL_TREE;
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 ();
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. */
265 static bool
266 maybe_thunk_body (tree fn, bool force)
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];
273 if (!force && !flag_declone_ctor_dtor)
274 return 0;
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;
281 /* If we got this far, we've decided to turn the clones into thunks. */
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). */
287 populate_clone_array (fn, fns);
289 /* Can happen during error recovery (c++/71464). */
290 if (!fns[0] || !fns[1])
291 return 0;
293 /* Don't use thunks if the base clone omits inherited parameters. */
294 if (ctor_omit_inherited_parms (fns[0]))
295 return 0;
297 DECL_ABSTRACT_P (fn) = false;
298 if (!DECL_WEAK (fn))
300 TREE_PUBLIC (fn) = false;
301 DECL_EXTERNAL (fn) = false;
302 DECL_INTERFACE_KNOWN (fn) = true;
304 else if (HAVE_COMDAT_GROUP)
306 /* At eof, defer creation of mangling aliases temporarily. */
307 bool save_defer_mangling_aliases = defer_mangling_aliases;
308 defer_mangling_aliases = true;
309 tree comdat_group = cdtor_comdat_group (fns[1], fns[0]);
310 defer_mangling_aliases = save_defer_mangling_aliases;
311 cgraph_node::get_create (fns[0])->set_comdat_group (comdat_group);
312 cgraph_node::get_create (fns[1])->add_to_same_comdat_group
313 (cgraph_node::get_create (fns[0]));
314 symtab_node::get (fn)->add_to_same_comdat_group
315 (symtab_node::get (fns[0]));
316 if (fns[2])
317 /* If *[CD][12]* dtors go into the *[CD]5* comdat group and dtor is
318 virtual, it goes into the same comdat group as well. */
319 cgraph_node::get_create (fns[2])->add_to_same_comdat_group
320 (symtab_node::get (fns[0]));
321 /* Emit them now that the thunks are same comdat group aliases. */
322 if (!save_defer_mangling_aliases)
323 generate_mangling_aliases ();
324 TREE_PUBLIC (fn) = false;
325 DECL_EXTERNAL (fn) = false;
326 DECL_INTERFACE_KNOWN (fn) = true;
327 /* function_and_variable_visibility doesn't want !PUBLIC decls to
328 have these flags set. */
329 DECL_WEAK (fn) = false;
330 DECL_COMDAT (fn) = false;
333 /* Find the vtt_parm, if present. */
334 for (vtt_parmno = -1, parmno = 0, fn_parm = DECL_ARGUMENTS (fn);
335 fn_parm;
336 ++parmno, fn_parm = TREE_CHAIN (fn_parm))
338 if (DECL_ARTIFICIAL (fn_parm)
339 && DECL_NAME (fn_parm) == vtt_parm_identifier)
341 /* Compensate for removed in_charge parameter. */
342 vtt_parmno = parmno;
343 break;
347 /* Allocate an argument buffer for build_cxx_call().
348 Make sure it is large enough for any of the clones. */
349 max_parms = 0;
350 FOR_EACH_CLONE (clone, fn)
352 int length = list_length (DECL_ARGUMENTS (fn));
353 if (length > max_parms)
354 max_parms = length;
356 args = XALLOCAVEC (tree, max_parms);
358 /* We know that any clones immediately follow FN in TYPE_FIELDS. */
359 FOR_EACH_CLONE (clone, fn)
361 tree clone_parm;
363 /* If we've already generated a body for this clone, avoid
364 duplicating it. (Is it possible for a clone-list to grow after we
365 first see it?) */
366 if (DECL_SAVED_TREE (clone) || TREE_ASM_WRITTEN (clone))
367 continue;
369 /* Start processing the function. */
370 start_preparsed_function (clone, NULL_TREE, SF_PRE_PARSED);
372 if (clone == fns[2])
374 for (clone_parm = DECL_ARGUMENTS (clone); clone_parm;
375 clone_parm = TREE_CHAIN (clone_parm))
376 DECL_ABSTRACT_ORIGIN (clone_parm) = NULL_TREE;
377 /* Build the delete destructor by calling complete destructor and
378 delete function. */
379 build_delete_destructor_body (clone, fns[1]);
381 else
383 /* Walk parameter lists together, creating parameter list for
384 call to original function. */
385 for (parmno = 0,
386 fn_parm = DECL_ARGUMENTS (fn),
387 fn_parm_typelist = TYPE_ARG_TYPES (TREE_TYPE (fn)),
388 clone_parm = DECL_ARGUMENTS (clone);
389 fn_parm;
390 ++parmno,
391 fn_parm = TREE_CHAIN (fn_parm))
393 if (parmno == vtt_parmno && ! DECL_HAS_VTT_PARM_P (clone))
395 gcc_assert (fn_parm_typelist);
396 /* Clobber argument with formal parameter type. */
397 args[parmno]
398 = convert (TREE_VALUE (fn_parm_typelist),
399 null_pointer_node);
401 else if (parmno == 1 && DECL_HAS_IN_CHARGE_PARM_P (fn))
403 tree in_charge
404 = copy_node (in_charge_arg_for_name (DECL_NAME (clone)));
405 args[parmno] = in_charge;
407 /* Map other parameters to their equivalents in the cloned
408 function. */
409 else
411 gcc_assert (clone_parm);
412 DECL_ABSTRACT_ORIGIN (clone_parm) = NULL;
413 args[parmno] = clone_parm;
414 /* Clear TREE_ADDRESSABLE on thunk arguments. */
415 TREE_ADDRESSABLE (clone_parm) = 0;
416 clone_parm = TREE_CHAIN (clone_parm);
418 if (fn_parm_typelist)
419 fn_parm_typelist = TREE_CHAIN (fn_parm_typelist);
422 /* We built this list backwards; fix now. */
423 mark_used (fn);
424 call = build_cxx_call (fn, parmno, args, tf_warning_or_error);
425 /* Arguments passed to the thunk by invisible reference should
426 be transmitted to the callee unchanged. Do not create a
427 temporary and invoke the copy constructor. The thunking
428 transformation must not introduce any constructor calls. */
429 CALL_FROM_THUNK_P (call) = 1;
430 block = make_node (BLOCK);
431 if (targetm.cxx.cdtor_returns_this ())
433 clone_result = DECL_RESULT (clone);
434 modify = build2 (MODIFY_EXPR, TREE_TYPE (clone_result),
435 clone_result, call);
436 modify = build1 (RETURN_EXPR, void_type_node, modify);
437 add_stmt (modify);
439 else
441 add_stmt (call);
443 bind = c_build_bind_expr (DECL_SOURCE_LOCATION (clone),
444 block, cur_stmt_list);
445 DECL_SAVED_TREE (clone) = push_stmt_list ();
446 add_stmt (bind);
449 DECL_ABSTRACT_ORIGIN (clone) = NULL;
450 expand_or_defer_fn (finish_function (/*inline_p=*/false));
452 return 1;
455 /* FN is a function that has a complete body. Clone the body as
456 necessary. Returns nonzero if there's no longer any need to
457 process the main body. */
459 bool
460 maybe_clone_body (tree fn)
462 tree comdat_group = NULL_TREE;
463 tree clone;
464 tree fns[3];
465 bool first = true;
466 int idx;
467 bool need_alias = false;
469 /* We only clone constructors and destructors. */
470 if (!DECL_MAYBE_IN_CHARGE_CDTOR_P (fn))
471 return 0;
473 populate_clone_array (fn, fns);
475 /* Remember if we can't have multiple clones for some reason. We need to
476 check this before we remap local static initializers in clone_body. */
477 if (!tree_versionable_function_p (fn))
478 need_alias = true;
480 /* We know that any clones immediately follow FN in the TYPE_FIELDS
481 list. */
482 push_to_top_level ();
483 for (idx = 0; idx < 3; idx++)
485 tree parm;
486 tree clone_parm;
488 clone = fns[idx];
489 if (!clone)
490 continue;
492 /* Update CLONE's source position information to match FN's. */
493 DECL_SOURCE_LOCATION (clone) = DECL_SOURCE_LOCATION (fn);
494 DECL_DECLARED_INLINE_P (clone) = DECL_DECLARED_INLINE_P (fn);
495 DECL_DECLARED_CONSTEXPR_P (clone) = DECL_DECLARED_CONSTEXPR_P (fn);
496 DECL_COMDAT (clone) = DECL_COMDAT (fn);
497 DECL_WEAK (clone) = DECL_WEAK (fn);
499 /* We don't copy the comdat group from fn to clone because the assembler
500 name of fn was corrupted by write_mangled_name by adding *INTERNAL*
501 to it. By doing so, it also corrupted the comdat group. */
502 if (DECL_ONE_ONLY (fn))
503 cgraph_node::get_create (clone)->set_comdat_group (cxx_comdat_group (clone));
504 DECL_USE_TEMPLATE (clone) = DECL_USE_TEMPLATE (fn);
505 DECL_EXTERNAL (clone) = DECL_EXTERNAL (fn);
506 DECL_INTERFACE_KNOWN (clone) = DECL_INTERFACE_KNOWN (fn);
507 DECL_NOT_REALLY_EXTERN (clone) = DECL_NOT_REALLY_EXTERN (fn);
508 TREE_PUBLIC (clone) = TREE_PUBLIC (fn);
509 DECL_VISIBILITY (clone) = DECL_VISIBILITY (fn);
510 DECL_VISIBILITY_SPECIFIED (clone) = DECL_VISIBILITY_SPECIFIED (fn);
511 DECL_DLLIMPORT_P (clone) = DECL_DLLIMPORT_P (fn);
512 DECL_ATTRIBUTES (clone) = copy_list (DECL_ATTRIBUTES (fn));
513 DECL_DISREGARD_INLINE_LIMITS (clone) = DECL_DISREGARD_INLINE_LIMITS (fn);
514 set_decl_section_name (clone, fn);
516 /* Adjust the parameter names and locations. */
517 parm = DECL_ARGUMENTS (fn);
518 clone_parm = DECL_ARGUMENTS (clone);
519 /* Update the `this' parameter, which is always first. */
520 update_cloned_parm (parm, clone_parm, first);
521 parm = DECL_CHAIN (parm);
522 clone_parm = DECL_CHAIN (clone_parm);
523 if (DECL_HAS_IN_CHARGE_PARM_P (fn))
524 parm = DECL_CHAIN (parm);
525 if (DECL_HAS_VTT_PARM_P (fn))
526 parm = DECL_CHAIN (parm);
527 if (DECL_HAS_VTT_PARM_P (clone))
528 clone_parm = DECL_CHAIN (clone_parm);
529 for (; parm && clone_parm;
530 parm = DECL_CHAIN (parm), clone_parm = DECL_CHAIN (clone_parm))
531 /* Update this parameter. */
532 update_cloned_parm (parm, clone_parm, first);
535 bool can_alias = can_alias_cdtor (fn);
537 /* If we decide to turn clones into thunks, they will branch to fn.
538 Must have original function available to call. */
539 if (!can_alias && maybe_thunk_body (fn, need_alias))
541 pop_from_top_level ();
542 /* We still need to emit the original function. */
543 return 0;
546 /* Emit the DWARF1 abstract instance. */
547 (*debug_hooks->deferred_inline_function) (fn);
549 /* We know that any clones immediately follow FN in the TYPE_FIELDS. */
550 for (idx = 0; idx < 3; idx++)
552 tree parm;
553 tree clone_parm;
554 int parmno;
555 hash_map<tree, tree> *decl_map;
556 bool alias = false;
558 clone = fns[idx];
559 if (!clone)
560 continue;
562 /* Start processing the function. */
563 start_preparsed_function (clone, NULL_TREE, SF_PRE_PARSED);
565 /* Tell cgraph if both ctors or both dtors are known to have
566 the same body. */
567 if (can_alias
568 && fns[0]
569 && idx == 1
570 && cgraph_node::get_create (fns[0])->create_same_body_alias
571 (clone, fns[0]))
573 alias = true;
574 if (DECL_ONE_ONLY (fns[0]))
576 /* For comdat base and complete cdtors put them
577 into the same, *[CD]5* comdat group instead of
578 *[CD][12]*. */
579 comdat_group = cdtor_comdat_group (fns[1], fns[0]);
580 cgraph_node::get_create (fns[0])->set_comdat_group (comdat_group);
581 if (symtab_node::get (clone)->same_comdat_group)
582 symtab_node::get (clone)->remove_from_same_comdat_group ();
583 symtab_node::get (clone)->add_to_same_comdat_group
584 (symtab_node::get (fns[0]));
588 /* Build the delete destructor by calling complete destructor
589 and delete function. */
590 if (idx == 2)
592 build_delete_destructor_body (clone, fns[1]);
593 /* If *[CD][12]* dtors go into the *[CD]5* comdat group and dtor is
594 virtual, it goes into the same comdat group as well. */
595 if (comdat_group)
596 cgraph_node::get_create (clone)->add_to_same_comdat_group
597 (symtab_node::get (fns[0]));
599 else if (alias)
600 /* No need to populate body. */ ;
601 else
603 /* If we can't have multiple copies of FN (say, because there's a
604 static local initialized with the address of a label), we need
605 to use an alias for the complete variant. */
606 if (idx == 1 && need_alias)
608 if (DECL_STRUCT_FUNCTION (fn)->cannot_be_copied_set)
609 sorry (DECL_STRUCT_FUNCTION (fn)->cannot_be_copied_reason, fn);
610 else
611 sorry ("making multiple clones of %qD", fn);
614 /* Remap the parameters. */
615 decl_map = new hash_map<tree, tree>;
616 for (parmno = 0,
617 parm = DECL_ARGUMENTS (fn),
618 clone_parm = DECL_ARGUMENTS (clone);
619 parm;
620 ++parmno,
621 parm = DECL_CHAIN (parm))
623 /* Map the in-charge parameter to an appropriate constant. */
624 if (DECL_HAS_IN_CHARGE_PARM_P (fn) && parmno == 1)
626 tree in_charge;
627 in_charge = in_charge_arg_for_name (DECL_NAME (clone));
628 decl_map->put (parm, in_charge);
630 else if (DECL_ARTIFICIAL (parm)
631 && DECL_NAME (parm) == vtt_parm_identifier)
633 /* For a subobject constructor or destructor, the next
634 argument is the VTT parameter. Remap the VTT_PARM
635 from the CLONE to this parameter. */
636 if (DECL_HAS_VTT_PARM_P (clone))
638 DECL_ABSTRACT_ORIGIN (clone_parm) = parm;
639 decl_map->put (parm, clone_parm);
640 clone_parm = DECL_CHAIN (clone_parm);
642 /* Otherwise, map the VTT parameter to `NULL'. */
643 else
645 tree t
646 = fold_convert (TREE_TYPE (parm), null_pointer_node);
647 decl_map->put (parm, t);
650 /* Map other parameters to their equivalents in the cloned
651 function. */
652 else
654 tree replacement;
655 if (clone_parm)
657 replacement = clone_parm;
658 clone_parm = DECL_CHAIN (clone_parm);
660 else
662 /* Inheriting ctors can omit parameters from the base
663 clone. Replace them with null lvalues. */
664 tree reftype = build_reference_type (TREE_TYPE (parm));
665 replacement = fold_convert (reftype, null_pointer_node);
666 replacement = convert_from_reference (replacement);
668 decl_map->put (parm, replacement);
672 if (targetm.cxx.cdtor_returns_this ())
674 parm = DECL_RESULT (fn);
675 clone_parm = DECL_RESULT (clone);
676 decl_map->put (parm, clone_parm);
679 /* Clone the body. */
680 clone_body (clone, fn, decl_map);
682 /* Clean up. */
683 delete decl_map;
686 /* The clone can throw iff the original function can throw. */
687 cp_function_chain->can_throw = !TREE_NOTHROW (fn);
689 /* Now, expand this function into RTL, if appropriate. */
690 finish_function (/*inline_p=*/false);
691 BLOCK_ABSTRACT_ORIGIN (DECL_INITIAL (clone)) = DECL_INITIAL (fn);
692 if (alias)
694 if (expand_or_defer_fn_1 (clone))
695 emit_associated_thunks (clone);
696 /* We didn't generate a body, so remove the empty one. */
697 DECL_SAVED_TREE (clone) = NULL_TREE;
699 else
700 expand_or_defer_fn (clone);
701 first = false;
703 pop_from_top_level ();
705 /* We don't need to process the original function any further. */
706 return 1;