]> 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.
8d9254fc 2 Copyright (C) 1998-2020 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
AP
60
61 DECL_GIMPLE_REG_P (cloned_parm) = DECL_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;
726a989a 106 id.transform_lang_insert_block = NULL;
9ff420f1
PB
107
108 /* We're not inside any EH region. */
1d65f45c 109 id.eh_lp_nr = 0;
9ff420f1 110
a406865a
RG
111 stmts = DECL_SAVED_TREE (fn);
112 walk_tree (&stmts, copy_tree_body_r, &id, NULL);
e6ca6e2a
JM
113
114 /* Also remap the initializer of any static variables so that they (in
115 particular, any label addresses) correspond to the base variant rather
116 than the abstract one. */
117 if (DECL_NAME (clone) == base_dtor_identifier
118 || DECL_NAME (clone) == base_ctor_identifier)
119 {
c021f10b
NF
120 unsigned ix;
121 tree decl;
122
123 FOR_EACH_LOCAL_DECL (DECL_STRUCT_FUNCTION (fn), ix, decl)
124 walk_tree (&DECL_INITIAL (decl), copy_tree_body_r, &id, NULL);
e6ca6e2a
JM
125 }
126
a406865a 127 append_to_statement_list_force (stmts, &DECL_SAVED_TREE (clone));
9ff420f1
PB
128}
129
68e0e461
WG
130/* DELETE_DTOR is a delete destructor whose body will be built.
131 COMPLETE_DTOR is the corresponding complete destructor. */
132
133static void
134build_delete_destructor_body (tree delete_dtor, tree complete_dtor)
135{
68e0e461
WG
136 tree parm = DECL_ARGUMENTS (delete_dtor);
137 tree virtual_size = cxx_sizeof (current_class_type);
138
68e0e461 139 /* Call the delete function. */
ee392fc2
NS
140 tree call_delete = build_op_delete_call (DELETE_EXPR, current_class_ptr,
141 virtual_size,
142 /*global_p=*/false,
143 /*placement=*/NULL_TREE,
144 /*alloc_fn=*/NULL_TREE,
145 tf_warning_or_error);
146
a6bb6b07
JM
147 tree op = get_callee_fndecl (call_delete);
148 if (op && DECL_P (op) && destroying_delete_p (op))
149 {
150 /* The destroying delete will handle calling complete_dtor. */
151 add_stmt (call_delete);
152 }
153 else
154 {
155 /* Call the corresponding complete destructor. */
156 gcc_assert (complete_dtor);
157 tree call_dtor = build_cxx_call (complete_dtor, 1, &parm,
158 tf_warning_or_error);
159
160 /* Operator delete must be called, whether or not the dtor throws. */
161 add_stmt (build2 (TRY_FINALLY_EXPR, void_type_node,
162 call_dtor, call_delete));
163 }
68e0e461 164
a6bb6b07
JM
165 /* Return the address of the object.
166 ??? How is it useful to return an invalid address? */
68e0e461
WG
167 if (targetm.cxx.cdtor_returns_this ())
168 {
169 tree val = DECL_ARGUMENTS (delete_dtor);
170 val = build2 (MODIFY_EXPR, TREE_TYPE (val),
171 DECL_RESULT (delete_dtor), val);
172 add_stmt (build_stmt (0, RETURN_EXPR, val));
173 }
174}
175
24b3ff2c
JJ
176/* Return name of comdat group for complete and base ctor (or dtor)
177 that have the same body. If dtor is virtual, deleting dtor goes
178 into this comdat group as well. */
179
180static tree
181cdtor_comdat_group (tree complete, tree base)
182{
cbb4d6a4
JM
183 tree complete_name = DECL_ASSEMBLER_NAME (complete);
184 tree base_name = DECL_ASSEMBLER_NAME (base);
24b3ff2c
JJ
185 char *grp_name;
186 const char *p, *q;
187 bool diff_seen = false;
188 size_t idx;
24b3ff2c
JJ
189 gcc_assert (IDENTIFIER_LENGTH (complete_name)
190 == IDENTIFIER_LENGTH (base_name));
191 grp_name = XALLOCAVEC (char, IDENTIFIER_LENGTH (complete_name) + 1);
192 p = IDENTIFIER_POINTER (complete_name);
193 q = IDENTIFIER_POINTER (base_name);
194 for (idx = 0; idx < IDENTIFIER_LENGTH (complete_name); idx++)
195 if (p[idx] == q[idx])
196 grp_name[idx] = p[idx];
197 else
198 {
199 gcc_assert (!diff_seen
200 && idx > 0
31f7f784
JM
201 && (p[idx - 1] == 'C' || p[idx - 1] == 'D'
202 || p[idx - 1] == 'I')
24b3ff2c
JJ
203 && p[idx] == '1'
204 && q[idx] == '2');
205 grp_name[idx] = '5';
206 diff_seen = true;
207 }
208 grp_name[idx] = '\0';
cbb4d6a4 209 gcc_assert (diff_seen);
24b3ff2c
JJ
210 return get_identifier (grp_name);
211}
212
1f26ac87
JM
213/* Returns true iff we can make the base and complete [cd]tor aliases of
214 the same symbol rather than separate functions. */
db9b2174 215
1f26ac87
JM
216static bool
217can_alias_cdtor (tree fn)
db9b2174 218{
1f26ac87 219 /* If aliases aren't supported by the assembler, fail. */
a8b522b4
ML
220 if (!TARGET_SUPPORTS_ALIASES)
221 return false;
222
1f26ac87
JM
223 /* We can't use an alias if there are virtual bases. */
224 if (CLASSTYPE_VBASECLASSES (DECL_CONTEXT (fn)))
225 return false;
5f150326 226 gcc_assert (DECL_MAYBE_IN_CHARGE_CDTOR_P (fn));
1f26ac87
JM
227 /* Don't use aliases for weak/linkonce definitions unless we can put both
228 symbols in the same COMDAT group. */
229 return (DECL_INTERFACE_KNOWN (fn)
230 && (SUPPORTS_ONE_ONLY || !DECL_WEAK (fn))
231 && (!DECL_ONE_ONLY (fn)
232 || (HAVE_COMDAT_GROUP && DECL_WEAK (fn))));
233}
db9b2174 234
1f26ac87
JM
235/* FN is a [cd]tor, fns is a pointer to an array of length 3. Fill fns
236 with pointers to the base, complete, and deleting variants. */
db9b2174 237
1f26ac87
JM
238static void
239populate_clone_array (tree fn, tree *fns)
240{
241 tree clone;
5daf7c0a 242
b2583345
JJ
243 fns[0] = NULL_TREE;
244 fns[1] = NULL_TREE;
245 fns[2] = NULL_TREE;
246
09039e9c
JM
247 tree ctx = DECL_CONTEXT (fn);
248
68e0e461 249 FOR_EACH_CLONE (clone, fn)
b2583345
JJ
250 if (DECL_NAME (clone) == complete_dtor_identifier
251 || DECL_NAME (clone) == complete_ctor_identifier)
252 fns[1] = clone;
253 else if (DECL_NAME (clone) == base_dtor_identifier
254 || DECL_NAME (clone) == base_ctor_identifier)
09039e9c
JM
255 {
256 /* We don't need to define the base variants for a final class. */
257 if (!CLASSTYPE_FINAL (ctx))
258 fns[0] = clone;
259 }
b2583345
JJ
260 else if (DECL_NAME (clone) == deleting_dtor_identifier)
261 fns[2] = clone;
262 else
263 gcc_unreachable ();
1f26ac87
JM
264}
265
266/* FN is a constructor or destructor, and there are FUNCTION_DECLs
267 cloned from it nearby. Instead of cloning this body, leave it
268 alone and create tiny one-call bodies for the cloned
269 FUNCTION_DECLs. These clones are sibcall candidates, and their
270 resulting code will be very thunk-esque. */
271
272static bool
273maybe_thunk_body (tree fn, bool force)
274{
275 tree bind, block, call, clone, clone_result, fn_parm, fn_parm_typelist;
276 tree last_arg, modify, *args;
277 int parmno, vtt_parmno, max_parms;
278 tree fns[3];
279
280 if (!force && !flag_declone_ctor_dtor)
281 return 0;
282
283 /* If function accepts variable arguments, give up. */
284 last_arg = tree_last (TYPE_ARG_TYPES (TREE_TYPE (fn)));
285 if (last_arg != void_list_node)
286 return 0;
287
288 /* If we got this far, we've decided to turn the clones into thunks. */
289
290 /* We're going to generate code for fn, so it is no longer "abstract."
291 Also make the unified ctor/dtor private to either the translation unit
292 (for non-vague linkage ctors) or the COMDAT group (otherwise). */
293
294 populate_clone_array (fn, fns);
31f7f784 295
c94a3f9f
PC
296 /* Can happen during error recovery (c++/71464). */
297 if (!fns[0] || !fns[1])
298 return 0;
299
31f7f784 300 /* Don't use thunks if the base clone omits inherited parameters. */
c94a3f9f 301 if (ctor_omit_inherited_parms (fns[0]))
31f7f784
JM
302 return 0;
303
00de328a 304 DECL_ABSTRACT_P (fn) = false;
1f26ac87
JM
305 if (!DECL_WEAK (fn))
306 {
307 TREE_PUBLIC (fn) = false;
308 DECL_EXTERNAL (fn) = false;
309 DECL_INTERFACE_KNOWN (fn) = true;
310 }
311 else if (HAVE_COMDAT_GROUP)
312 {
ec5a0fe0
JJ
313 /* At eof, defer creation of mangling aliases temporarily. */
314 bool save_defer_mangling_aliases = defer_mangling_aliases;
315 defer_mangling_aliases = true;
1f26ac87 316 tree comdat_group = cdtor_comdat_group (fns[1], fns[0]);
ec5a0fe0 317 defer_mangling_aliases = save_defer_mangling_aliases;
d52f5295
ML
318 cgraph_node::get_create (fns[0])->set_comdat_group (comdat_group);
319 cgraph_node::get_create (fns[1])->add_to_same_comdat_group
320 (cgraph_node::get_create (fns[0]));
321 symtab_node::get (fn)->add_to_same_comdat_group
322 (symtab_node::get (fns[0]));
1f26ac87
JM
323 if (fns[2])
324 /* If *[CD][12]* dtors go into the *[CD]5* comdat group and dtor is
325 virtual, it goes into the same comdat group as well. */
d52f5295
ML
326 cgraph_node::get_create (fns[2])->add_to_same_comdat_group
327 (symtab_node::get (fns[0]));
ec5a0fe0
JJ
328 /* Emit them now that the thunks are same comdat group aliases. */
329 if (!save_defer_mangling_aliases)
330 generate_mangling_aliases ();
1f26ac87
JM
331 TREE_PUBLIC (fn) = false;
332 DECL_EXTERNAL (fn) = false;
333 DECL_INTERFACE_KNOWN (fn) = true;
334 /* function_and_variable_visibility doesn't want !PUBLIC decls to
335 have these flags set. */
336 DECL_WEAK (fn) = false;
337 DECL_COMDAT (fn) = false;
338 }
339
340 /* Find the vtt_parm, if present. */
341 for (vtt_parmno = -1, parmno = 0, fn_parm = DECL_ARGUMENTS (fn);
342 fn_parm;
343 ++parmno, fn_parm = TREE_CHAIN (fn_parm))
344 {
345 if (DECL_ARTIFICIAL (fn_parm)
346 && DECL_NAME (fn_parm) == vtt_parm_identifier)
347 {
348 /* Compensate for removed in_charge parameter. */
349 vtt_parmno = parmno;
350 break;
351 }
352 }
353
354 /* Allocate an argument buffer for build_cxx_call().
355 Make sure it is large enough for any of the clones. */
356 max_parms = 0;
357 FOR_EACH_CLONE (clone, fn)
358 {
359 int length = list_length (DECL_ARGUMENTS (fn));
360 if (length > max_parms)
361 max_parms = length;
362 }
e260b0a7 363 args = XALLOCAVEC (tree, max_parms);
1f26ac87 364
5aaa8fb4 365 /* We know that any clones immediately follow FN in TYPE_FIELDS. */
1f26ac87
JM
366 FOR_EACH_CLONE (clone, fn)
367 {
368 tree clone_parm;
369
370 /* If we've already generated a body for this clone, avoid
371 duplicating it. (Is it possible for a clone-list to grow after we
372 first see it?) */
373 if (DECL_SAVED_TREE (clone) || TREE_ASM_WRITTEN (clone))
374 continue;
375
376 /* Start processing the function. */
377 start_preparsed_function (clone, NULL_TREE, SF_PRE_PARSED);
378
379 if (clone == fns[2])
380 {
381 for (clone_parm = DECL_ARGUMENTS (clone); clone_parm;
382 clone_parm = TREE_CHAIN (clone_parm))
383 DECL_ABSTRACT_ORIGIN (clone_parm) = NULL_TREE;
384 /* Build the delete destructor by calling complete destructor and
385 delete function. */
386 build_delete_destructor_body (clone, fns[1]);
387 }
388 else
389 {
390 /* Walk parameter lists together, creating parameter list for
391 call to original function. */
392 for (parmno = 0,
393 fn_parm = DECL_ARGUMENTS (fn),
394 fn_parm_typelist = TYPE_ARG_TYPES (TREE_TYPE (fn)),
395 clone_parm = DECL_ARGUMENTS (clone);
396 fn_parm;
397 ++parmno,
398 fn_parm = TREE_CHAIN (fn_parm))
399 {
400 if (parmno == vtt_parmno && ! DECL_HAS_VTT_PARM_P (clone))
401 {
402 gcc_assert (fn_parm_typelist);
403 /* Clobber argument with formal parameter type. */
404 args[parmno]
405 = convert (TREE_VALUE (fn_parm_typelist),
406 null_pointer_node);
407 }
408 else if (parmno == 1 && DECL_HAS_IN_CHARGE_PARM_P (fn))
409 {
410 tree in_charge
411 = copy_node (in_charge_arg_for_name (DECL_NAME (clone)));
412 args[parmno] = in_charge;
413 }
414 /* Map other parameters to their equivalents in the cloned
415 function. */
416 else
417 {
418 gcc_assert (clone_parm);
419 DECL_ABSTRACT_ORIGIN (clone_parm) = NULL;
420 args[parmno] = clone_parm;
d397e394
JJ
421 /* Clear TREE_ADDRESSABLE on thunk arguments. */
422 TREE_ADDRESSABLE (clone_parm) = 0;
1f26ac87
JM
423 clone_parm = TREE_CHAIN (clone_parm);
424 }
425 if (fn_parm_typelist)
426 fn_parm_typelist = TREE_CHAIN (fn_parm_typelist);
427 }
428
429 /* We built this list backwards; fix now. */
430 mark_used (fn);
431 call = build_cxx_call (fn, parmno, args, tf_warning_or_error);
432 /* Arguments passed to the thunk by invisible reference should
433 be transmitted to the callee unchanged. Do not create a
434 temporary and invoke the copy constructor. The thunking
435 transformation must not introduce any constructor calls. */
436 CALL_FROM_THUNK_P (call) = 1;
437 block = make_node (BLOCK);
438 if (targetm.cxx.cdtor_returns_this ())
439 {
440 clone_result = DECL_RESULT (clone);
441 modify = build2 (MODIFY_EXPR, TREE_TYPE (clone_result),
442 clone_result, call);
8ae90330 443 modify = build1 (RETURN_EXPR, void_type_node, modify);
1f26ac87 444 add_stmt (modify);
1f26ac87
JM
445 }
446 else
447 {
448 add_stmt (call);
449 }
450 bind = c_build_bind_expr (DECL_SOURCE_LOCATION (clone),
451 block, cur_stmt_list);
452 DECL_SAVED_TREE (clone) = push_stmt_list ();
453 add_stmt (bind);
454 }
455
456 DECL_ABSTRACT_ORIGIN (clone) = NULL;
90e3c064 457 expand_or_defer_fn (finish_function (/*inline_p=*/false));
1f26ac87
JM
458 }
459 return 1;
460}
461
462/* FN is a function that has a complete body. Clone the body as
463 necessary. Returns nonzero if there's no longer any need to
464 process the main body. */
465
466bool
467maybe_clone_body (tree fn)
468{
469 tree comdat_group = NULL_TREE;
470 tree clone;
471 tree fns[3];
472 bool first = true;
473 int idx;
474 bool need_alias = false;
475
476 /* We only clone constructors and destructors. */
5f150326 477 if (!DECL_MAYBE_IN_CHARGE_CDTOR_P (fn))
1f26ac87
JM
478 return 0;
479
480 populate_clone_array (fn, fns);
68e0e461 481
e6ca6e2a
JM
482 /* Remember if we can't have multiple clones for some reason. We need to
483 check this before we remap local static initializers in clone_body. */
09039e9c 484 if (!tree_versionable_function_p (fn) && fns[0] && fns[1])
e6ca6e2a
JM
485 need_alias = true;
486
5aaa8fb4 487 /* We know that any clones immediately follow FN in the TYPE_FIELDS
db9b2174 488 list. */
f44b0c8e 489 push_to_top_level ();
b2583345 490 for (idx = 0; idx < 3; idx++)
db9b2174
MM
491 {
492 tree parm;
493 tree clone_parm;
db9b2174 494
b2583345
JJ
495 clone = fns[idx];
496 if (!clone)
497 continue;
498
db9b2174 499 /* Update CLONE's source position information to match FN's. */
f31686a3 500 DECL_SOURCE_LOCATION (clone) = DECL_SOURCE_LOCATION (fn);
79065db2 501 DECL_DECLARED_INLINE_P (clone) = DECL_DECLARED_INLINE_P (fn);
525c617d 502 DECL_DECLARED_CONSTEXPR_P (clone) = DECL_DECLARED_CONSTEXPR_P (fn);
3ec6bad3
MM
503 DECL_COMDAT (clone) = DECL_COMDAT (fn);
504 DECL_WEAK (clone) = DECL_WEAK (fn);
fc26fae3
RAE
505
506 /* We don't copy the comdat group from fn to clone because the assembler
507 name of fn was corrupted by write_mangled_name by adding *INTERNAL*
508 to it. By doing so, it also corrupted the comdat group. */
509 if (DECL_ONE_ONLY (fn))
d52f5295 510 cgraph_node::get_create (clone)->set_comdat_group (cxx_comdat_group (clone));
459c43ad
MM
511 DECL_USE_TEMPLATE (clone) = DECL_USE_TEMPLATE (fn);
512 DECL_EXTERNAL (clone) = DECL_EXTERNAL (fn);
513 DECL_INTERFACE_KNOWN (clone) = DECL_INTERFACE_KNOWN (fn);
514 DECL_NOT_REALLY_EXTERN (clone) = DECL_NOT_REALLY_EXTERN (fn);
b96ada87 515 TREE_PUBLIC (clone) = TREE_PUBLIC (fn);
968b41a1 516 DECL_VISIBILITY (clone) = DECL_VISIBILITY (fn);
d7afec4b 517 DECL_VISIBILITY_SPECIFIED (clone) = DECL_VISIBILITY_SPECIFIED (fn);
39e6670f 518 DECL_DLLIMPORT_P (clone) = DECL_DLLIMPORT_P (fn);
87e92864
AP
519 DECL_ATTRIBUTES (clone) = copy_list (DECL_ATTRIBUTES (fn));
520 DECL_DISREGARD_INLINE_LIMITS (clone) = DECL_DISREGARD_INLINE_LIMITS (fn);
24d047a3 521 set_decl_section_name (clone, DECL_SECTION_NAME (fn));
db9b2174 522
c6002625 523 /* Adjust the parameter names and locations. */
02a1a68c
NS
524 parm = DECL_ARGUMENTS (fn);
525 clone_parm = DECL_ARGUMENTS (clone);
4a90862e 526 /* Update the `this' parameter, which is always first. */
b8ad8c93 527 update_cloned_parm (parm, clone_parm, first);
910ad8de
NF
528 parm = DECL_CHAIN (parm);
529 clone_parm = DECL_CHAIN (clone_parm);
02a1a68c 530 if (DECL_HAS_IN_CHARGE_PARM_P (fn))
910ad8de 531 parm = DECL_CHAIN (parm);
02a1a68c 532 if (DECL_HAS_VTT_PARM_P (fn))
910ad8de 533 parm = DECL_CHAIN (parm);
02a1a68c 534 if (DECL_HAS_VTT_PARM_P (clone))
910ad8de 535 clone_parm = DECL_CHAIN (clone_parm);
31f7f784 536 for (; parm && clone_parm;
910ad8de 537 parm = DECL_CHAIN (parm), clone_parm = DECL_CHAIN (clone_parm))
85b22f78 538 /* Update this parameter. */
b8ad8c93 539 update_cloned_parm (parm, clone_parm, first);
1f26ac87
JM
540 }
541
542 bool can_alias = can_alias_cdtor (fn);
543
544 /* If we decide to turn clones into thunks, they will branch to fn.
545 Must have original function available to call. */
546 if (!can_alias && maybe_thunk_body (fn, need_alias))
547 {
548 pop_from_top_level ();
549 /* We still need to emit the original function. */
550 return 0;
551 }
552
553 /* Emit the DWARF1 abstract instance. */
554 (*debug_hooks->deferred_inline_function) (fn);
555
5aaa8fb4 556 /* We know that any clones immediately follow FN in the TYPE_FIELDS. */
1f26ac87
JM
557 for (idx = 0; idx < 3; idx++)
558 {
559 tree parm;
560 tree clone_parm;
561 int parmno;
b787e7a2 562 hash_map<tree, tree> *decl_map;
1f26ac87
JM
563 bool alias = false;
564
565 clone = fns[idx];
566 if (!clone)
567 continue;
02a1a68c 568
db9b2174 569 /* Start processing the function. */
058b15c1 570 start_preparsed_function (clone, NULL_TREE, SF_PRE_PARSED);
db9b2174 571
b2583345
JJ
572 /* Tell cgraph if both ctors or both dtors are known to have
573 the same body. */
1f26ac87 574 if (can_alias
b2583345
JJ
575 && fns[0]
576 && idx == 1
d52f5295
ML
577 && cgraph_node::get_create (fns[0])->create_same_body_alias
578 (clone, fns[0]))
6744a6ab
JH
579 {
580 alias = true;
24b3ff2c
JJ
581 if (DECL_ONE_ONLY (fns[0]))
582 {
583 /* For comdat base and complete cdtors put them
584 into the same, *[CD]5* comdat group instead of
585 *[CD][12]*. */
586 comdat_group = cdtor_comdat_group (fns[1], fns[0]);
d52f5295
ML
587 cgraph_node::get_create (fns[0])->set_comdat_group (comdat_group);
588 if (symtab_node::get (clone)->same_comdat_group)
589 symtab_node::get (clone)->remove_from_same_comdat_group ();
590 symtab_node::get (clone)->add_to_same_comdat_group
591 (symtab_node::get (fns[0]));
24b3ff2c 592 }
6744a6ab 593 }
b2583345 594
68e0e461
WG
595 /* Build the delete destructor by calling complete destructor
596 and delete function. */
b2583345 597 if (idx == 2)
2fda8e14
JM
598 {
599 build_delete_destructor_body (clone, fns[1]);
600 /* If *[CD][12]* dtors go into the *[CD]5* comdat group and dtor is
601 virtual, it goes into the same comdat group as well. */
602 if (comdat_group)
d52f5295
ML
603 cgraph_node::get_create (clone)->add_to_same_comdat_group
604 (symtab_node::get (fns[0]));
2fda8e14 605 }
b2583345
JJ
606 else if (alias)
607 /* No need to populate body. */ ;
68e0e461 608 else
b2583345 609 {
e6ca6e2a
JM
610 /* If we can't have multiple copies of FN (say, because there's a
611 static local initialized with the address of a label), we need
612 to use an alias for the complete variant. */
613 if (idx == 1 && need_alias)
614 {
615 if (DECL_STRUCT_FUNCTION (fn)->cannot_be_copied_set)
616 sorry (DECL_STRUCT_FUNCTION (fn)->cannot_be_copied_reason, fn);
617 else
618 sorry ("making multiple clones of %qD", fn);
619 }
620
68e0e461 621 /* Remap the parameters. */
b787e7a2 622 decl_map = new hash_map<tree, tree>;
68e0e461
WG
623 for (parmno = 0,
624 parm = DECL_ARGUMENTS (fn),
625 clone_parm = DECL_ARGUMENTS (clone);
626 parm;
627 ++parmno,
910ad8de 628 parm = DECL_CHAIN (parm))
68e0e461
WG
629 {
630 /* Map the in-charge parameter to an appropriate constant. */
631 if (DECL_HAS_IN_CHARGE_PARM_P (fn) && parmno == 1)
632 {
633 tree in_charge;
634 in_charge = in_charge_arg_for_name (DECL_NAME (clone));
b787e7a2 635 decl_map->put (parm, in_charge);
68e0e461
WG
636 }
637 else if (DECL_ARTIFICIAL (parm)
638 && DECL_NAME (parm) == vtt_parm_identifier)
639 {
640 /* For a subobject constructor or destructor, the next
641 argument is the VTT parameter. Remap the VTT_PARM
642 from the CLONE to this parameter. */
643 if (DECL_HAS_VTT_PARM_P (clone))
644 {
645 DECL_ABSTRACT_ORIGIN (clone_parm) = parm;
b787e7a2 646 decl_map->put (parm, clone_parm);
910ad8de 647 clone_parm = DECL_CHAIN (clone_parm);
68e0e461
WG
648 }
649 /* Otherwise, map the VTT parameter to `NULL'. */
650 else
b787e7a2
TS
651 {
652 tree t
653 = fold_convert (TREE_TYPE (parm), null_pointer_node);
654 decl_map->put (parm, t);
655 }
68e0e461
WG
656 }
657 /* Map other parameters to their equivalents in the cloned
658 function. */
659 else
660 {
77095a6a 661 tree replacement;
31f7f784 662 if (clone_parm)
77095a6a
JM
663 {
664 replacement = clone_parm;
665 clone_parm = DECL_CHAIN (clone_parm);
666 }
667 else
668 {
669 /* Inheriting ctors can omit parameters from the base
670 clone. Replace them with null lvalues. */
671 tree reftype = build_reference_type (TREE_TYPE (parm));
672 replacement = fold_convert (reftype, null_pointer_node);
673 replacement = convert_from_reference (replacement);
674 }
675 decl_map->put (parm, replacement);
68e0e461
WG
676 }
677 }
678
679 if (targetm.cxx.cdtor_returns_this ())
680 {
681 parm = DECL_RESULT (fn);
682 clone_parm = DECL_RESULT (clone);
b787e7a2 683 decl_map->put (parm, clone_parm);
68e0e461
WG
684 }
685
686 /* Clone the body. */
687 clone_body (clone, fn, decl_map);
688
689 /* Clean up. */
b787e7a2 690 delete decl_map;
68e0e461 691 }
db9b2174 692
b2dd096b
MM
693 /* The clone can throw iff the original function can throw. */
694 cp_function_chain->can_throw = !TREE_NOTHROW (fn);
695
db9b2174 696 /* Now, expand this function into RTL, if appropriate. */
90e3c064 697 finish_function (/*inline_p=*/false);
5daf7c0a 698 BLOCK_ABSTRACT_ORIGIN (DECL_INITIAL (clone)) = DECL_INITIAL (fn);
b2583345 699 if (alias)
249ccaff
JJ
700 {
701 if (expand_or_defer_fn_1 (clone))
702 emit_associated_thunks (clone);
ca30abcd
JM
703 /* We didn't generate a body, so remove the empty one. */
704 DECL_SAVED_TREE (clone) = NULL_TREE;
249ccaff 705 }
b2583345
JJ
706 else
707 expand_or_defer_fn (clone);
b8ad8c93 708 first = false;
db9b2174 709 }
f44b0c8e 710 pop_from_top_level ();
9c96f3f8 711
db9b2174
MM
712 /* We don't need to process the original function any further. */
713 return 1;
714}