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