tree-core.h (tree_decl_with_vis): Replace comdat_group by symtab_node pointer.
[gcc.git] / gcc / cp / optimize.c
1 /* Perform optimizations on tree structure.
2 Copyright (C) 1998-2014 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 "tm.h"
25 #include "tree.h"
26 #include "stringpool.h"
27 #include "cp-tree.h"
28 #include "input.h"
29 #include "params.h"
30 #include "hashtab.h"
31 #include "target.h"
32 #include "debug.h"
33 #include "tree-inline.h"
34 #include "flags.h"
35 #include "langhooks.h"
36 #include "diagnostic-core.h"
37 #include "dumpfile.h"
38 #include "pointer-set.h"
39 #include "tree-iterator.h"
40 #include "cgraph.h"
41
42 /* Prototypes. */
43
44 static void update_cloned_parm (tree, tree, bool);
45
46 /* CLONED_PARM is a copy of CLONE, generated for a cloned constructor
47 or destructor. Update it to ensure that the source-position for
48 the cloned parameter matches that for the original, and that the
49 debugging generation code will be able to find the original PARM. */
50
51 static void
52 update_cloned_parm (tree parm, tree cloned_parm, bool first)
53 {
54 DECL_ABSTRACT_ORIGIN (cloned_parm) = parm;
55
56 /* We may have taken its address. */
57 TREE_ADDRESSABLE (cloned_parm) = TREE_ADDRESSABLE (parm);
58
59 /* The definition might have different constness. */
60 TREE_READONLY (cloned_parm) = TREE_READONLY (parm);
61
62 TREE_USED (cloned_parm) = !first || TREE_USED (parm);
63
64 /* The name may have changed from the declaration. */
65 DECL_NAME (cloned_parm) = DECL_NAME (parm);
66 DECL_SOURCE_LOCATION (cloned_parm) = DECL_SOURCE_LOCATION (parm);
67 TREE_TYPE (cloned_parm) = TREE_TYPE (parm);
68
69 DECL_GIMPLE_REG_P (cloned_parm) = DECL_GIMPLE_REG_P (parm);
70 }
71
72
73 /* FN is a function in High GIMPLE form that has a complete body and no
74 CFG. CLONE is a function whose body is to be set to a copy of FN,
75 mapping argument declarations according to the ARG_MAP splay_tree. */
76
77 static void
78 clone_body (tree clone, tree fn, void *arg_map)
79 {
80 copy_body_data id;
81 tree stmts;
82
83 /* Clone the body, as if we were making an inline call. But, remap
84 the parameters in the callee to the parameters of caller. */
85 memset (&id, 0, sizeof (id));
86 id.src_fn = fn;
87 id.dst_fn = clone;
88 id.src_cfun = DECL_STRUCT_FUNCTION (fn);
89 id.decl_map = (struct pointer_map_t *) arg_map;
90
91 id.copy_decl = copy_decl_no_change;
92 id.transform_call_graph_edges = CB_CGE_DUPLICATE;
93 id.transform_new_cfg = true;
94 id.transform_return_to_modify = false;
95 id.transform_lang_insert_block = NULL;
96
97 /* We're not inside any EH region. */
98 id.eh_lp_nr = 0;
99
100 stmts = DECL_SAVED_TREE (fn);
101 walk_tree (&stmts, copy_tree_body_r, &id, NULL);
102
103 /* Also remap the initializer of any static variables so that they (in
104 particular, any label addresses) correspond to the base variant rather
105 than the abstract one. */
106 if (DECL_NAME (clone) == base_dtor_identifier
107 || DECL_NAME (clone) == base_ctor_identifier)
108 {
109 unsigned ix;
110 tree decl;
111
112 FOR_EACH_LOCAL_DECL (DECL_STRUCT_FUNCTION (fn), ix, decl)
113 walk_tree (&DECL_INITIAL (decl), copy_tree_body_r, &id, NULL);
114 }
115
116 append_to_statement_list_force (stmts, &DECL_SAVED_TREE (clone));
117 }
118
119 /* DELETE_DTOR is a delete destructor whose body will be built.
120 COMPLETE_DTOR is the corresponding complete destructor. */
121
122 static void
123 build_delete_destructor_body (tree delete_dtor, tree complete_dtor)
124 {
125 tree call_dtor, call_delete;
126 tree parm = DECL_ARGUMENTS (delete_dtor);
127 tree virtual_size = cxx_sizeof (current_class_type);
128
129 /* Call the corresponding complete destructor. */
130 gcc_assert (complete_dtor);
131 call_dtor = build_cxx_call (complete_dtor, 1, &parm,
132 tf_warning_or_error);
133 add_stmt (call_dtor);
134
135 add_stmt (build_stmt (0, LABEL_EXPR, cdtor_label));
136
137 /* Call the delete function. */
138 call_delete = build_op_delete_call (DELETE_EXPR, current_class_ptr,
139 virtual_size,
140 /*global_p=*/false,
141 /*placement=*/NULL_TREE,
142 /*alloc_fn=*/NULL_TREE,
143 tf_warning_or_error);
144 add_stmt (call_delete);
145
146 /* Return the address of the object. */
147 if (targetm.cxx.cdtor_returns_this ())
148 {
149 tree val = DECL_ARGUMENTS (delete_dtor);
150 val = build2 (MODIFY_EXPR, TREE_TYPE (val),
151 DECL_RESULT (delete_dtor), val);
152 add_stmt (build_stmt (0, RETURN_EXPR, val));
153 }
154 }
155
156 /* Return name of comdat group for complete and base ctor (or dtor)
157 that have the same body. If dtor is virtual, deleting dtor goes
158 into this comdat group as well. */
159
160 static tree
161 cdtor_comdat_group (tree complete, tree base)
162 {
163 tree complete_name = DECL_COMDAT_GROUP (complete);
164 tree base_name = DECL_COMDAT_GROUP (base);
165 char *grp_name;
166 const char *p, *q;
167 bool diff_seen = false;
168 size_t idx;
169 if (complete_name == NULL)
170 complete_name = cxx_comdat_group (complete);
171 if (base_name == NULL)
172 base_name = cxx_comdat_group (base);
173 gcc_assert (IDENTIFIER_LENGTH (complete_name)
174 == IDENTIFIER_LENGTH (base_name));
175 grp_name = XALLOCAVEC (char, IDENTIFIER_LENGTH (complete_name) + 1);
176 p = IDENTIFIER_POINTER (complete_name);
177 q = IDENTIFIER_POINTER (base_name);
178 for (idx = 0; idx < IDENTIFIER_LENGTH (complete_name); idx++)
179 if (p[idx] == q[idx])
180 grp_name[idx] = p[idx];
181 else
182 {
183 gcc_assert (!diff_seen
184 && idx > 0
185 && (p[idx - 1] == 'C' || p[idx - 1] == 'D')
186 && p[idx] == '1'
187 && q[idx] == '2');
188 grp_name[idx] = '5';
189 diff_seen = true;
190 }
191 grp_name[idx] = '\0';
192 gcc_assert (diff_seen);
193 return get_identifier (grp_name);
194 }
195
196 /* Returns true iff we can make the base and complete [cd]tor aliases of
197 the same symbol rather than separate functions. */
198
199 static bool
200 can_alias_cdtor (tree fn)
201 {
202 #ifndef ASM_OUTPUT_DEF
203 /* If aliases aren't supported by the assembler, fail. */
204 return false;
205 #endif
206 /* We can't use an alias if there are virtual bases. */
207 if (CLASSTYPE_VBASECLASSES (DECL_CONTEXT (fn)))
208 return false;
209 /* ??? Why not use aliases with -frepo? */
210 if (flag_use_repository)
211 return false;
212 gcc_assert (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn)
213 || DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn));
214 /* Don't use aliases for weak/linkonce definitions unless we can put both
215 symbols in the same COMDAT group. */
216 return (DECL_INTERFACE_KNOWN (fn)
217 && (SUPPORTS_ONE_ONLY || !DECL_WEAK (fn))
218 && (!DECL_ONE_ONLY (fn)
219 || (HAVE_COMDAT_GROUP && DECL_WEAK (fn))));
220 }
221
222 /* FN is a [cd]tor, fns is a pointer to an array of length 3. Fill fns
223 with pointers to the base, complete, and deleting variants. */
224
225 static void
226 populate_clone_array (tree fn, tree *fns)
227 {
228 tree clone;
229
230 fns[0] = NULL_TREE;
231 fns[1] = NULL_TREE;
232 fns[2] = NULL_TREE;
233
234 /* Look for the complete destructor which may be used to build the
235 delete destructor. */
236 FOR_EACH_CLONE (clone, fn)
237 if (DECL_NAME (clone) == complete_dtor_identifier
238 || DECL_NAME (clone) == complete_ctor_identifier)
239 fns[1] = clone;
240 else if (DECL_NAME (clone) == base_dtor_identifier
241 || DECL_NAME (clone) == base_ctor_identifier)
242 fns[0] = clone;
243 else if (DECL_NAME (clone) == deleting_dtor_identifier)
244 fns[2] = clone;
245 else
246 gcc_unreachable ();
247 }
248
249 /* FN is a constructor or destructor, and there are FUNCTION_DECLs
250 cloned from it nearby. Instead of cloning this body, leave it
251 alone and create tiny one-call bodies for the cloned
252 FUNCTION_DECLs. These clones are sibcall candidates, and their
253 resulting code will be very thunk-esque. */
254
255 static bool
256 maybe_thunk_body (tree fn, bool force)
257 {
258 tree bind, block, call, clone, clone_result, fn_parm, fn_parm_typelist;
259 tree last_arg, modify, *args;
260 int parmno, vtt_parmno, max_parms;
261 tree fns[3];
262
263 if (!force && !flag_declone_ctor_dtor)
264 return 0;
265
266 /* If function accepts variable arguments, give up. */
267 last_arg = tree_last (TYPE_ARG_TYPES (TREE_TYPE (fn)));
268 if (last_arg != void_list_node)
269 return 0;
270
271 /* If we got this far, we've decided to turn the clones into thunks. */
272
273 /* We're going to generate code for fn, so it is no longer "abstract."
274 Also make the unified ctor/dtor private to either the translation unit
275 (for non-vague linkage ctors) or the COMDAT group (otherwise). */
276
277 populate_clone_array (fn, fns);
278 DECL_ABSTRACT (fn) = false;
279 if (!DECL_WEAK (fn))
280 {
281 TREE_PUBLIC (fn) = false;
282 DECL_EXTERNAL (fn) = false;
283 DECL_INTERFACE_KNOWN (fn) = true;
284 }
285 else if (HAVE_COMDAT_GROUP)
286 {
287 tree comdat_group = cdtor_comdat_group (fns[1], fns[0]);
288 cgraph_get_create_node (fns[0])->set_comdat_group (comdat_group);
289 symtab_add_to_same_comdat_group (cgraph_get_create_node (fns[1]),
290 cgraph_get_create_node (fns[0]));
291 symtab_add_to_same_comdat_group (symtab_get_node (fn),
292 symtab_get_node (fns[0]));
293 if (fns[2])
294 /* If *[CD][12]* dtors go into the *[CD]5* comdat group and dtor is
295 virtual, it goes into the same comdat group as well. */
296 symtab_add_to_same_comdat_group (cgraph_get_create_node (fns[2]),
297 symtab_get_node (fns[0]));
298 TREE_PUBLIC (fn) = false;
299 DECL_EXTERNAL (fn) = false;
300 DECL_INTERFACE_KNOWN (fn) = true;
301 /* function_and_variable_visibility doesn't want !PUBLIC decls to
302 have these flags set. */
303 DECL_WEAK (fn) = false;
304 DECL_COMDAT (fn) = false;
305 }
306
307 /* Find the vtt_parm, if present. */
308 for (vtt_parmno = -1, parmno = 0, fn_parm = DECL_ARGUMENTS (fn);
309 fn_parm;
310 ++parmno, fn_parm = TREE_CHAIN (fn_parm))
311 {
312 if (DECL_ARTIFICIAL (fn_parm)
313 && DECL_NAME (fn_parm) == vtt_parm_identifier)
314 {
315 /* Compensate for removed in_charge parameter. */
316 vtt_parmno = parmno;
317 break;
318 }
319 }
320
321 /* Allocate an argument buffer for build_cxx_call().
322 Make sure it is large enough for any of the clones. */
323 max_parms = 0;
324 FOR_EACH_CLONE (clone, fn)
325 {
326 int length = list_length (DECL_ARGUMENTS (fn));
327 if (length > max_parms)
328 max_parms = length;
329 }
330 args = (tree *) alloca (max_parms * sizeof (tree));
331
332 /* We know that any clones immediately follow FN in TYPE_METHODS. */
333 FOR_EACH_CLONE (clone, fn)
334 {
335 tree clone_parm;
336
337 /* If we've already generated a body for this clone, avoid
338 duplicating it. (Is it possible for a clone-list to grow after we
339 first see it?) */
340 if (DECL_SAVED_TREE (clone) || TREE_ASM_WRITTEN (clone))
341 continue;
342
343 /* Start processing the function. */
344 start_preparsed_function (clone, NULL_TREE, SF_PRE_PARSED);
345
346 if (clone == fns[2])
347 {
348 for (clone_parm = DECL_ARGUMENTS (clone); clone_parm;
349 clone_parm = TREE_CHAIN (clone_parm))
350 DECL_ABSTRACT_ORIGIN (clone_parm) = NULL_TREE;
351 /* Build the delete destructor by calling complete destructor and
352 delete function. */
353 build_delete_destructor_body (clone, fns[1]);
354 }
355 else
356 {
357 /* Walk parameter lists together, creating parameter list for
358 call to original function. */
359 for (parmno = 0,
360 fn_parm = DECL_ARGUMENTS (fn),
361 fn_parm_typelist = TYPE_ARG_TYPES (TREE_TYPE (fn)),
362 clone_parm = DECL_ARGUMENTS (clone);
363 fn_parm;
364 ++parmno,
365 fn_parm = TREE_CHAIN (fn_parm))
366 {
367 if (parmno == vtt_parmno && ! DECL_HAS_VTT_PARM_P (clone))
368 {
369 gcc_assert (fn_parm_typelist);
370 /* Clobber argument with formal parameter type. */
371 args[parmno]
372 = convert (TREE_VALUE (fn_parm_typelist),
373 null_pointer_node);
374 }
375 else if (parmno == 1 && DECL_HAS_IN_CHARGE_PARM_P (fn))
376 {
377 tree in_charge
378 = copy_node (in_charge_arg_for_name (DECL_NAME (clone)));
379 args[parmno] = in_charge;
380 }
381 /* Map other parameters to their equivalents in the cloned
382 function. */
383 else
384 {
385 gcc_assert (clone_parm);
386 DECL_ABSTRACT_ORIGIN (clone_parm) = NULL;
387 args[parmno] = clone_parm;
388 clone_parm = TREE_CHAIN (clone_parm);
389 }
390 if (fn_parm_typelist)
391 fn_parm_typelist = TREE_CHAIN (fn_parm_typelist);
392 }
393
394 /* We built this list backwards; fix now. */
395 mark_used (fn);
396 call = build_cxx_call (fn, parmno, args, tf_warning_or_error);
397 /* Arguments passed to the thunk by invisible reference should
398 be transmitted to the callee unchanged. Do not create a
399 temporary and invoke the copy constructor. The thunking
400 transformation must not introduce any constructor calls. */
401 CALL_FROM_THUNK_P (call) = 1;
402 block = make_node (BLOCK);
403 if (targetm.cxx.cdtor_returns_this ())
404 {
405 clone_result = DECL_RESULT (clone);
406 modify = build2 (MODIFY_EXPR, TREE_TYPE (clone_result),
407 clone_result, call);
408 modify = build1 (RETURN_EXPR, void_type_node, modify);
409 add_stmt (modify);
410 }
411 else
412 {
413 add_stmt (call);
414 }
415 bind = c_build_bind_expr (DECL_SOURCE_LOCATION (clone),
416 block, cur_stmt_list);
417 DECL_SAVED_TREE (clone) = push_stmt_list ();
418 add_stmt (bind);
419 }
420
421 DECL_ABSTRACT_ORIGIN (clone) = NULL;
422 expand_or_defer_fn (finish_function (0));
423 }
424 return 1;
425 }
426
427 /* FN is a function that has a complete body. Clone the body as
428 necessary. Returns nonzero if there's no longer any need to
429 process the main body. */
430
431 bool
432 maybe_clone_body (tree fn)
433 {
434 tree comdat_group = NULL_TREE;
435 tree clone;
436 tree fns[3];
437 bool first = true;
438 int idx;
439 bool need_alias = false;
440
441 /* We only clone constructors and destructors. */
442 if (!DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn)
443 && !DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn))
444 return 0;
445
446 populate_clone_array (fn, fns);
447
448 /* Remember if we can't have multiple clones for some reason. We need to
449 check this before we remap local static initializers in clone_body. */
450 if (!tree_versionable_function_p (fn))
451 need_alias = true;
452
453 /* We know that any clones immediately follow FN in the TYPE_METHODS
454 list. */
455 push_to_top_level ();
456 for (idx = 0; idx < 3; idx++)
457 {
458 tree parm;
459 tree clone_parm;
460
461 clone = fns[idx];
462 if (!clone)
463 continue;
464
465 /* Update CLONE's source position information to match FN's. */
466 DECL_SOURCE_LOCATION (clone) = DECL_SOURCE_LOCATION (fn);
467 DECL_DECLARED_INLINE_P (clone) = DECL_DECLARED_INLINE_P (fn);
468 DECL_DECLARED_CONSTEXPR_P (clone) = DECL_DECLARED_CONSTEXPR_P (fn);
469 DECL_COMDAT (clone) = DECL_COMDAT (fn);
470 DECL_WEAK (clone) = DECL_WEAK (fn);
471
472 /* We don't copy the comdat group from fn to clone because the assembler
473 name of fn was corrupted by write_mangled_name by adding *INTERNAL*
474 to it. By doing so, it also corrupted the comdat group. */
475 if (DECL_ONE_ONLY (fn))
476 cgraph_get_create_node (clone)->set_comdat_group (cxx_comdat_group (clone));
477 DECL_SECTION_NAME (clone) = DECL_SECTION_NAME (fn);
478 DECL_USE_TEMPLATE (clone) = DECL_USE_TEMPLATE (fn);
479 DECL_EXTERNAL (clone) = DECL_EXTERNAL (fn);
480 DECL_INTERFACE_KNOWN (clone) = DECL_INTERFACE_KNOWN (fn);
481 DECL_NOT_REALLY_EXTERN (clone) = DECL_NOT_REALLY_EXTERN (fn);
482 TREE_PUBLIC (clone) = TREE_PUBLIC (fn);
483 DECL_VISIBILITY (clone) = DECL_VISIBILITY (fn);
484 DECL_VISIBILITY_SPECIFIED (clone) = DECL_VISIBILITY_SPECIFIED (fn);
485 DECL_DLLIMPORT_P (clone) = DECL_DLLIMPORT_P (fn);
486 DECL_ATTRIBUTES (clone) = copy_list (DECL_ATTRIBUTES (fn));
487 DECL_DISREGARD_INLINE_LIMITS (clone) = DECL_DISREGARD_INLINE_LIMITS (fn);
488
489 /* Adjust the parameter names and locations. */
490 parm = DECL_ARGUMENTS (fn);
491 clone_parm = DECL_ARGUMENTS (clone);
492 /* Update the `this' parameter, which is always first. */
493 update_cloned_parm (parm, clone_parm, first);
494 parm = DECL_CHAIN (parm);
495 clone_parm = DECL_CHAIN (clone_parm);
496 if (DECL_HAS_IN_CHARGE_PARM_P (fn))
497 parm = DECL_CHAIN (parm);
498 if (DECL_HAS_VTT_PARM_P (fn))
499 parm = DECL_CHAIN (parm);
500 if (DECL_HAS_VTT_PARM_P (clone))
501 clone_parm = DECL_CHAIN (clone_parm);
502 for (; parm;
503 parm = DECL_CHAIN (parm), clone_parm = DECL_CHAIN (clone_parm))
504 /* Update this parameter. */
505 update_cloned_parm (parm, clone_parm, first);
506 }
507
508 bool can_alias = can_alias_cdtor (fn);
509
510 /* If we decide to turn clones into thunks, they will branch to fn.
511 Must have original function available to call. */
512 if (!can_alias && maybe_thunk_body (fn, need_alias))
513 {
514 pop_from_top_level ();
515 /* We still need to emit the original function. */
516 return 0;
517 }
518
519 /* Emit the DWARF1 abstract instance. */
520 (*debug_hooks->deferred_inline_function) (fn);
521
522 /* We know that any clones immediately follow FN in the TYPE_METHODS list. */
523 for (idx = 0; idx < 3; idx++)
524 {
525 tree parm;
526 tree clone_parm;
527 int parmno;
528 struct pointer_map_t *decl_map;
529 bool alias = false;
530
531 clone = fns[idx];
532 if (!clone)
533 continue;
534
535 /* Start processing the function. */
536 start_preparsed_function (clone, NULL_TREE, SF_PRE_PARSED);
537
538 /* Tell cgraph if both ctors or both dtors are known to have
539 the same body. */
540 if (can_alias
541 && fns[0]
542 && idx == 1
543 && cgraph_same_body_alias (cgraph_get_create_node (fns[0]),
544 clone, fns[0]))
545 {
546 alias = true;
547 if (DECL_ONE_ONLY (fns[0]))
548 {
549 /* For comdat base and complete cdtors put them
550 into the same, *[CD]5* comdat group instead of
551 *[CD][12]*. */
552 comdat_group = cdtor_comdat_group (fns[1], fns[0]);
553 cgraph_get_create_node (fns[0])->set_comdat_group (comdat_group);
554 symtab_add_to_same_comdat_group (symtab_get_node (clone),
555 symtab_get_node (fns[0]));
556 }
557 }
558
559 /* Build the delete destructor by calling complete destructor
560 and delete function. */
561 if (idx == 2)
562 {
563 build_delete_destructor_body (clone, fns[1]);
564 /* If *[CD][12]* dtors go into the *[CD]5* comdat group and dtor is
565 virtual, it goes into the same comdat group as well. */
566 if (comdat_group)
567 symtab_add_to_same_comdat_group
568 (cgraph_get_create_node (clone),
569 symtab_get_node (fns[0]));
570 }
571 else if (alias)
572 /* No need to populate body. */ ;
573 else
574 {
575 /* If we can't have multiple copies of FN (say, because there's a
576 static local initialized with the address of a label), we need
577 to use an alias for the complete variant. */
578 if (idx == 1 && need_alias)
579 {
580 if (DECL_STRUCT_FUNCTION (fn)->cannot_be_copied_set)
581 sorry (DECL_STRUCT_FUNCTION (fn)->cannot_be_copied_reason, fn);
582 else
583 sorry ("making multiple clones of %qD", fn);
584 }
585
586 /* Remap the parameters. */
587 decl_map = pointer_map_create ();
588 for (parmno = 0,
589 parm = DECL_ARGUMENTS (fn),
590 clone_parm = DECL_ARGUMENTS (clone);
591 parm;
592 ++parmno,
593 parm = DECL_CHAIN (parm))
594 {
595 /* Map the in-charge parameter to an appropriate constant. */
596 if (DECL_HAS_IN_CHARGE_PARM_P (fn) && parmno == 1)
597 {
598 tree in_charge;
599 in_charge = in_charge_arg_for_name (DECL_NAME (clone));
600 *pointer_map_insert (decl_map, parm) = in_charge;
601 }
602 else if (DECL_ARTIFICIAL (parm)
603 && DECL_NAME (parm) == vtt_parm_identifier)
604 {
605 /* For a subobject constructor or destructor, the next
606 argument is the VTT parameter. Remap the VTT_PARM
607 from the CLONE to this parameter. */
608 if (DECL_HAS_VTT_PARM_P (clone))
609 {
610 DECL_ABSTRACT_ORIGIN (clone_parm) = parm;
611 *pointer_map_insert (decl_map, parm) = clone_parm;
612 clone_parm = DECL_CHAIN (clone_parm);
613 }
614 /* Otherwise, map the VTT parameter to `NULL'. */
615 else
616 *pointer_map_insert (decl_map, parm)
617 = fold_convert (TREE_TYPE (parm), null_pointer_node);
618 }
619 /* Map other parameters to their equivalents in the cloned
620 function. */
621 else
622 {
623 *pointer_map_insert (decl_map, parm) = clone_parm;
624 clone_parm = DECL_CHAIN (clone_parm);
625 }
626 }
627
628 if (targetm.cxx.cdtor_returns_this ())
629 {
630 parm = DECL_RESULT (fn);
631 clone_parm = DECL_RESULT (clone);
632 *pointer_map_insert (decl_map, parm) = clone_parm;
633 }
634
635 /* Clone the body. */
636 clone_body (clone, fn, decl_map);
637
638 /* Clean up. */
639 pointer_map_destroy (decl_map);
640 }
641
642 /* The clone can throw iff the original function can throw. */
643 cp_function_chain->can_throw = !TREE_NOTHROW (fn);
644
645 /* Now, expand this function into RTL, if appropriate. */
646 finish_function (0);
647 BLOCK_ABSTRACT_ORIGIN (DECL_INITIAL (clone)) = DECL_INITIAL (fn);
648 if (alias)
649 {
650 if (expand_or_defer_fn_1 (clone))
651 emit_associated_thunks (clone);
652 }
653 else
654 expand_or_defer_fn (clone);
655 first = false;
656 }
657 pop_from_top_level ();
658
659 /* We don't need to process the original function any further. */
660 return 1;
661 }