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