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