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