]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/cp/optimize.c
Update copyright years.
[thirdparty/gcc.git] / gcc / cp / optimize.c
CommitLineData
46e8c075 1/* Perform optimizations on tree structure.
7adcbafe 2 Copyright (C) 1998-2022 Free Software Foundation, Inc.
46e8c075
MM
3 Written by Mark Michell (mark@codesourcery.com).
4
f5adbb8d 5This file is part of GCC.
46e8c075 6
f5adbb8d 7GCC is free software; you can redistribute it and/or modify it
06ceef4e 8under the terms of the GNU General Public License as published by
e77f031d 9the Free Software Foundation; either version 3, or (at your option)
06ceef4e
RK
10any later version.
11
f5adbb8d 12GCC is distributed in the hope that it will be useful, but
06ceef4e
RK
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.
9c96f3f8 16
06ceef4e 17You should have received a copy of the GNU General Public License
e77f031d
NC
18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
46e8c075
MM
20
21#include "config.h"
22#include "system.h"
4977bab6 23#include "coretypes.h"
2adfab87 24#include "target.h"
46e8c075 25#include "cp-tree.h"
2adfab87
AM
26#include "stringpool.h"
27#include "cgraph.h"
2b85879e 28#include "debug.h"
25af8512 29#include "tree-inline.h"
a406865a 30#include "tree-iterator.h"
46e8c075 31
46e8c075
MM
32/* Prototypes. */
33
b8ad8c93 34static void update_cloned_parm (tree, tree, bool);
95fabfd3 35
d60e5448
MM
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
41static void
b8ad8c93 42update_cloned_parm (tree parm, tree cloned_parm, bool first)
d60e5448
MM
43{
44 DECL_ABSTRACT_ORIGIN (cloned_parm) = parm;
d30a825a 45
c6002625 46 /* We may have taken its address. */
d30a825a
NS
47 TREE_ADDRESSABLE (cloned_parm) = TREE_ADDRESSABLE (parm);
48
77b46042
TV
49 DECL_BY_REFERENCE (cloned_parm) = DECL_BY_REFERENCE (parm);
50
c6002625 51 /* The definition might have different constness. */
d30a825a 52 TREE_READONLY (cloned_parm) = TREE_READONLY (parm);
c8094d83 53
b8ad8c93 54 TREE_USED (cloned_parm) = !first || TREE_USED (parm);
c8094d83 55
c6002625 56 /* The name may have changed from the declaration. */
d60e5448 57 DECL_NAME (cloned_parm) = DECL_NAME (parm);
f31686a3 58 DECL_SOURCE_LOCATION (cloned_parm) = DECL_SOURCE_LOCATION (parm);
e777303f 59 TREE_TYPE (cloned_parm) = TREE_TYPE (parm);
b3c4918f 60
eb72dc66 61 DECL_NOT_GIMPLE_REG_P (cloned_parm) = DECL_NOT_GIMPLE_REG_P (parm);
d60e5448
MM
62}
63
44f4e418
JJ
64/* Like copy_decl_no_change, but handle DECL_OMP_PRIVATIZED_MEMBER
65 properly. */
66
67static tree
68cxx_copy_decl (tree decl, copy_body_data *id)
69{
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))
76 {
77 tree expr = DECL_VALUE_EXPR (copy);
78 walk_tree (&expr, copy_tree_body_r, id, NULL);
79 SET_DECL_VALUE_EXPR (copy, expr);
80 }
81 return copy;
82}
726a989a
RB
83
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. */
9ff420f1
PB
87
88static void
89clone_body (tree clone, tree fn, void *arg_map)
90{
91 copy_body_data id;
a406865a 92 tree stmts;
9ff420f1 93
726a989a
RB
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. */
9ff420f1
PB
96 memset (&id, 0, sizeof (id));
97 id.src_fn = fn;
98 id.dst_fn = clone;
99 id.src_cfun = DECL_STRUCT_FUNCTION (fn);
b787e7a2 100 id.decl_map = static_cast<hash_map<tree, tree> *> (arg_map);
9ff420f1 101
44f4e418 102 id.copy_decl = cxx_copy_decl;
9ff420f1
PB
103 id.transform_call_graph_edges = CB_CGE_DUPLICATE;
104 id.transform_new_cfg = true;
105 id.transform_return_to_modify = false;
9ff420f1
PB
106
107 /* We're not inside any EH region. */
1d65f45c 108 id.eh_lp_nr = 0;
9ff420f1 109
a406865a
RG
110 stmts = DECL_SAVED_TREE (fn);
111 walk_tree (&stmts, copy_tree_body_r, &id, NULL);
e6ca6e2a
JM
112
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)
118 {
c021f10b
NF
119 unsigned ix;
120 tree decl;
121
122 FOR_EACH_LOCAL_DECL (DECL_STRUCT_FUNCTION (fn), ix, decl)
123 walk_tree (&DECL_INITIAL (decl), copy_tree_body_r, &id, NULL);
e6ca6e2a
JM
124 }
125
a406865a 126 append_to_statement_list_force (stmts, &DECL_SAVED_TREE (clone));
9ff420f1
PB
127}
128
68e0e461
WG
129/* DELETE_DTOR is a delete destructor whose body will be built.
130 COMPLETE_DTOR is the corresponding complete destructor. */
131
132static void
133build_delete_destructor_body (tree delete_dtor, tree complete_dtor)
134{
68e0e461
WG
135 tree parm = DECL_ARGUMENTS (delete_dtor);
136 tree virtual_size = cxx_sizeof (current_class_type);
137
68e0e461 138 /* Call the delete function. */
ee392fc2
NS
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);
145
a6bb6b07
JM
146 tree op = get_callee_fndecl (call_delete);
147 if (op && DECL_P (op) && destroying_delete_p (op))
148 {
149 /* The destroying delete will handle calling complete_dtor. */
150 add_stmt (call_delete);
151 }
152 else
153 {
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);
158
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));
162 }
68e0e461 163
a6bb6b07
JM
164 /* Return the address of the object.
165 ??? How is it useful to return an invalid address? */
68e0e461
WG
166 if (targetm.cxx.cdtor_returns_this ())
167 {
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));
172 }
173}
174
24b3ff2c
JJ
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. */
178
179static tree
180cdtor_comdat_group (tree complete, tree base)
181{
cbb4d6a4
JM
182 tree complete_name = DECL_ASSEMBLER_NAME (complete);
183 tree base_name = DECL_ASSEMBLER_NAME (base);
24b3ff2c
JJ
184 char *grp_name;
185 const char *p, *q;
186 bool diff_seen = false;
187 size_t idx;
24b3ff2c
JJ
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
197 {
198 gcc_assert (!diff_seen
199 && idx > 0
31f7f784
JM
200 && (p[idx - 1] == 'C' || p[idx - 1] == 'D'
201 || p[idx - 1] == 'I')
24b3ff2c
JJ
202 && p[idx] == '1'
203 && q[idx] == '2');
204 grp_name[idx] = '5';
205 diff_seen = true;
206 }
207 grp_name[idx] = '\0';
cbb4d6a4 208 gcc_assert (diff_seen);
24b3ff2c
JJ
209 return get_identifier (grp_name);
210}
211
1f26ac87
JM
212/* Returns true iff we can make the base and complete [cd]tor aliases of
213 the same symbol rather than separate functions. */
db9b2174 214
1f26ac87
JM
215static bool
216can_alias_cdtor (tree fn)
db9b2174 217{
1f26ac87 218 /* If aliases aren't supported by the assembler, fail. */
a8b522b4
ML
219 if (!TARGET_SUPPORTS_ALIASES)
220 return false;
221
1f26ac87
JM
222 /* We can't use an alias if there are virtual bases. */
223 if (CLASSTYPE_VBASECLASSES (DECL_CONTEXT (fn)))
224 return false;
5f150326 225 gcc_assert (DECL_MAYBE_IN_CHARGE_CDTOR_P (fn));
1f26ac87
JM
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))));
232}
db9b2174 233
1f26ac87
JM
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. */
db9b2174 236
1f26ac87
JM
237static void
238populate_clone_array (tree fn, tree *fns)
239{
240 tree clone;
5daf7c0a 241
b2583345
JJ
242 fns[0] = NULL_TREE;
243 fns[1] = NULL_TREE;
244 fns[2] = NULL_TREE;
245
68e0e461 246 FOR_EACH_CLONE (clone, fn)
b2583345
JJ
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)
6b958ee0 252 fns[0] = clone;
b2583345
JJ
253 else if (DECL_NAME (clone) == deleting_dtor_identifier)
254 fns[2] = clone;
255 else
256 gcc_unreachable ();
1f26ac87
JM
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);
31f7f784 288
c94a3f9f
PC
289 /* Can happen during error recovery (c++/71464). */
290 if (!fns[0] || !fns[1])
291 return 0;
292
31f7f784 293 /* Don't use thunks if the base clone omits inherited parameters. */
c94a3f9f 294 if (ctor_omit_inherited_parms (fns[0]))
31f7f784
JM
295 return 0;
296
00de328a 297 DECL_ABSTRACT_P (fn) = false;
1f26ac87
JM
298 if (!DECL_WEAK (fn))
299 {
300 TREE_PUBLIC (fn) = false;
301 DECL_EXTERNAL (fn) = false;
302 DECL_INTERFACE_KNOWN (fn) = true;
303 }
304 else if (HAVE_COMDAT_GROUP)
305 {
ec5a0fe0
JJ
306 /* At eof, defer creation of mangling aliases temporarily. */
307 bool save_defer_mangling_aliases = defer_mangling_aliases;
308 defer_mangling_aliases = true;
1f26ac87 309 tree comdat_group = cdtor_comdat_group (fns[1], fns[0]);
ec5a0fe0 310 defer_mangling_aliases = save_defer_mangling_aliases;
d52f5295
ML
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]));
1f26ac87
JM
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. */
d52f5295
ML
319 cgraph_node::get_create (fns[2])->add_to_same_comdat_group
320 (symtab_node::get (fns[0]));
ec5a0fe0
JJ
321 /* Emit them now that the thunks are same comdat group aliases. */
322 if (!save_defer_mangling_aliases)
323 generate_mangling_aliases ();
1f26ac87
JM
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;
331 }
332
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))
337 {
338 if (DECL_ARTIFICIAL (fn_parm)
339 && DECL_NAME (fn_parm) == vtt_parm_identifier)
340 {
341 /* Compensate for removed in_charge parameter. */
342 vtt_parmno = parmno;
343 break;
344 }
345 }
346
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)
351 {
352 int length = list_length (DECL_ARGUMENTS (fn));
353 if (length > max_parms)
354 max_parms = length;
355 }
e260b0a7 356 args = XALLOCAVEC (tree, max_parms);
1f26ac87 357
5aaa8fb4 358 /* We know that any clones immediately follow FN in TYPE_FIELDS. */
1f26ac87
JM
359 FOR_EACH_CLONE (clone, fn)
360 {
361 tree clone_parm;
362
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;
368
369 /* Start processing the function. */
370 start_preparsed_function (clone, NULL_TREE, SF_PRE_PARSED);
371
372 if (clone == fns[2])
373 {
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]);
380 }
381 else
382 {
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))
392 {
393 if (parmno == vtt_parmno && ! DECL_HAS_VTT_PARM_P (clone))
394 {
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);
400 }
401 else if (parmno == 1 && DECL_HAS_IN_CHARGE_PARM_P (fn))
402 {
403 tree in_charge
404 = copy_node (in_charge_arg_for_name (DECL_NAME (clone)));
405 args[parmno] = in_charge;
406 }
407 /* Map other parameters to their equivalents in the cloned
408 function. */
409 else
410 {
411 gcc_assert (clone_parm);
412 DECL_ABSTRACT_ORIGIN (clone_parm) = NULL;
413 args[parmno] = clone_parm;
d397e394
JJ
414 /* Clear TREE_ADDRESSABLE on thunk arguments. */
415 TREE_ADDRESSABLE (clone_parm) = 0;
1f26ac87
JM
416 clone_parm = TREE_CHAIN (clone_parm);
417 }
418 if (fn_parm_typelist)
419 fn_parm_typelist = TREE_CHAIN (fn_parm_typelist);
420 }
421
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 ())
432 {
433 clone_result = DECL_RESULT (clone);
434 modify = build2 (MODIFY_EXPR, TREE_TYPE (clone_result),
435 clone_result, call);
8ae90330 436 modify = build1 (RETURN_EXPR, void_type_node, modify);
1f26ac87 437 add_stmt (modify);
1f26ac87
JM
438 }
439 else
440 {
441 add_stmt (call);
442 }
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);
447 }
448
449 DECL_ABSTRACT_ORIGIN (clone) = NULL;
90e3c064 450 expand_or_defer_fn (finish_function (/*inline_p=*/false));
1f26ac87
JM
451 }
452 return 1;
453}
454
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. */
458
459bool
460maybe_clone_body (tree fn)
461{
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;
468
469 /* We only clone constructors and destructors. */
5f150326 470 if (!DECL_MAYBE_IN_CHARGE_CDTOR_P (fn))
1f26ac87
JM
471 return 0;
472
473 populate_clone_array (fn, fns);
68e0e461 474
e6ca6e2a
JM
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. */
6b958ee0 477 if (!tree_versionable_function_p (fn))
e6ca6e2a
JM
478 need_alias = true;
479
5aaa8fb4 480 /* We know that any clones immediately follow FN in the TYPE_FIELDS
db9b2174 481 list. */
f44b0c8e 482 push_to_top_level ();
b2583345 483 for (idx = 0; idx < 3; idx++)
db9b2174
MM
484 {
485 tree parm;
486 tree clone_parm;
db9b2174 487
b2583345
JJ
488 clone = fns[idx];
489 if (!clone)
490 continue;
491
db9b2174 492 /* Update CLONE's source position information to match FN's. */
f31686a3 493 DECL_SOURCE_LOCATION (clone) = DECL_SOURCE_LOCATION (fn);
79065db2 494 DECL_DECLARED_INLINE_P (clone) = DECL_DECLARED_INLINE_P (fn);
525c617d 495 DECL_DECLARED_CONSTEXPR_P (clone) = DECL_DECLARED_CONSTEXPR_P (fn);
3ec6bad3
MM
496 DECL_COMDAT (clone) = DECL_COMDAT (fn);
497 DECL_WEAK (clone) = DECL_WEAK (fn);
fc26fae3
RAE
498
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))
d52f5295 503 cgraph_node::get_create (clone)->set_comdat_group (cxx_comdat_group (clone));
459c43ad
MM
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);
b96ada87 508 TREE_PUBLIC (clone) = TREE_PUBLIC (fn);
968b41a1 509 DECL_VISIBILITY (clone) = DECL_VISIBILITY (fn);
d7afec4b 510 DECL_VISIBILITY_SPECIFIED (clone) = DECL_VISIBILITY_SPECIFIED (fn);
39e6670f 511 DECL_DLLIMPORT_P (clone) = DECL_DLLIMPORT_P (fn);
87e92864
AP
512 DECL_ATTRIBUTES (clone) = copy_list (DECL_ATTRIBUTES (fn));
513 DECL_DISREGARD_INLINE_LIMITS (clone) = DECL_DISREGARD_INLINE_LIMITS (fn);
8b9a92f7 514 set_decl_section_name (clone, fn);
db9b2174 515
c6002625 516 /* Adjust the parameter names and locations. */
02a1a68c
NS
517 parm = DECL_ARGUMENTS (fn);
518 clone_parm = DECL_ARGUMENTS (clone);
4a90862e 519 /* Update the `this' parameter, which is always first. */
b8ad8c93 520 update_cloned_parm (parm, clone_parm, first);
910ad8de
NF
521 parm = DECL_CHAIN (parm);
522 clone_parm = DECL_CHAIN (clone_parm);
02a1a68c 523 if (DECL_HAS_IN_CHARGE_PARM_P (fn))
910ad8de 524 parm = DECL_CHAIN (parm);
02a1a68c 525 if (DECL_HAS_VTT_PARM_P (fn))
910ad8de 526 parm = DECL_CHAIN (parm);
02a1a68c 527 if (DECL_HAS_VTT_PARM_P (clone))
910ad8de 528 clone_parm = DECL_CHAIN (clone_parm);
31f7f784 529 for (; parm && clone_parm;
910ad8de 530 parm = DECL_CHAIN (parm), clone_parm = DECL_CHAIN (clone_parm))
85b22f78 531 /* Update this parameter. */
b8ad8c93 532 update_cloned_parm (parm, clone_parm, first);
1f26ac87
JM
533 }
534
535 bool can_alias = can_alias_cdtor (fn);
536
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))
540 {
541 pop_from_top_level ();
542 /* We still need to emit the original function. */
543 return 0;
544 }
545
546 /* Emit the DWARF1 abstract instance. */
547 (*debug_hooks->deferred_inline_function) (fn);
548
5aaa8fb4 549 /* We know that any clones immediately follow FN in the TYPE_FIELDS. */
1f26ac87
JM
550 for (idx = 0; idx < 3; idx++)
551 {
552 tree parm;
553 tree clone_parm;
554 int parmno;
b787e7a2 555 hash_map<tree, tree> *decl_map;
1f26ac87
JM
556 bool alias = false;
557
558 clone = fns[idx];
559 if (!clone)
560 continue;
02a1a68c 561
db9b2174 562 /* Start processing the function. */
058b15c1 563 start_preparsed_function (clone, NULL_TREE, SF_PRE_PARSED);
db9b2174 564
b2583345
JJ
565 /* Tell cgraph if both ctors or both dtors are known to have
566 the same body. */
1f26ac87 567 if (can_alias
b2583345
JJ
568 && fns[0]
569 && idx == 1
d52f5295
ML
570 && cgraph_node::get_create (fns[0])->create_same_body_alias
571 (clone, fns[0]))
6744a6ab
JH
572 {
573 alias = true;
24b3ff2c
JJ
574 if (DECL_ONE_ONLY (fns[0]))
575 {
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]);
d52f5295
ML
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]));
24b3ff2c 585 }
6744a6ab 586 }
b2583345 587
68e0e461
WG
588 /* Build the delete destructor by calling complete destructor
589 and delete function. */
b2583345 590 if (idx == 2)
2fda8e14
JM
591 {
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)
d52f5295
ML
596 cgraph_node::get_create (clone)->add_to_same_comdat_group
597 (symtab_node::get (fns[0]));
2fda8e14 598 }
b2583345
JJ
599 else if (alias)
600 /* No need to populate body. */ ;
68e0e461 601 else
b2583345 602 {
e6ca6e2a
JM
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)
607 {
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);
612 }
613
68e0e461 614 /* Remap the parameters. */
b787e7a2 615 decl_map = new hash_map<tree, tree>;
68e0e461
WG
616 for (parmno = 0,
617 parm = DECL_ARGUMENTS (fn),
618 clone_parm = DECL_ARGUMENTS (clone);
619 parm;
620 ++parmno,
910ad8de 621 parm = DECL_CHAIN (parm))
68e0e461
WG
622 {
623 /* Map the in-charge parameter to an appropriate constant. */
624 if (DECL_HAS_IN_CHARGE_PARM_P (fn) && parmno == 1)
625 {
626 tree in_charge;
627 in_charge = in_charge_arg_for_name (DECL_NAME (clone));
b787e7a2 628 decl_map->put (parm, in_charge);
68e0e461
WG
629 }
630 else if (DECL_ARTIFICIAL (parm)
631 && DECL_NAME (parm) == vtt_parm_identifier)
632 {
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))
637 {
638 DECL_ABSTRACT_ORIGIN (clone_parm) = parm;
b787e7a2 639 decl_map->put (parm, clone_parm);
910ad8de 640 clone_parm = DECL_CHAIN (clone_parm);
68e0e461
WG
641 }
642 /* Otherwise, map the VTT parameter to `NULL'. */
643 else
b787e7a2
TS
644 {
645 tree t
646 = fold_convert (TREE_TYPE (parm), null_pointer_node);
647 decl_map->put (parm, t);
648 }
68e0e461
WG
649 }
650 /* Map other parameters to their equivalents in the cloned
651 function. */
652 else
653 {
77095a6a 654 tree replacement;
31f7f784 655 if (clone_parm)
77095a6a
JM
656 {
657 replacement = clone_parm;
658 clone_parm = DECL_CHAIN (clone_parm);
659 }
660 else
661 {
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);
667 }
668 decl_map->put (parm, replacement);
68e0e461
WG
669 }
670 }
671
672 if (targetm.cxx.cdtor_returns_this ())
673 {
674 parm = DECL_RESULT (fn);
675 clone_parm = DECL_RESULT (clone);
b787e7a2 676 decl_map->put (parm, clone_parm);
68e0e461
WG
677 }
678
679 /* Clone the body. */
680 clone_body (clone, fn, decl_map);
681
682 /* Clean up. */
b787e7a2 683 delete decl_map;
68e0e461 684 }
db9b2174 685
b2dd096b
MM
686 /* The clone can throw iff the original function can throw. */
687 cp_function_chain->can_throw = !TREE_NOTHROW (fn);
688
db9b2174 689 /* Now, expand this function into RTL, if appropriate. */
90e3c064 690 finish_function (/*inline_p=*/false);
5daf7c0a 691 BLOCK_ABSTRACT_ORIGIN (DECL_INITIAL (clone)) = DECL_INITIAL (fn);
b2583345 692 if (alias)
249ccaff
JJ
693 {
694 if (expand_or_defer_fn_1 (clone))
695 emit_associated_thunks (clone);
ca30abcd
JM
696 /* We didn't generate a body, so remove the empty one. */
697 DECL_SAVED_TREE (clone) = NULL_TREE;
249ccaff 698 }
b2583345
JJ
699 else
700 expand_or_defer_fn (clone);
b8ad8c93 701 first = false;
db9b2174 702 }
f44b0c8e 703 pop_from_top_level ();
9c96f3f8 704
db9b2174
MM
705 /* We don't need to process the original function any further. */
706 return 1;
707}