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
update_cloned_parm(tree parm,tree cloned_parm,bool first)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
clone_body(tree clone,tree fn,void * arg_map)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
build_delete_destructor_body(tree delete_dtor,tree complete_dtor)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
cdtor_comdat_group(tree complete,tree base)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
can_alias_cdtor(tree fn)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
populate_clone_array(tree fn,tree * fns)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
maybe_thunk_body(tree fn,bool force)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       DECL_COMDAT_GROUP (fns[0]) = 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
maybe_clone_body(tree fn)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 	DECL_COMDAT_GROUP (clone) = 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 	      DECL_COMDAT_GROUP (fns[0]) = 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 }
662