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