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