/* Perform optimizations on tree structure.
   Copyright (C) 1998-2022 Free Software Foundation, Inc.
   Written by Mark Michell (mark@codesourcery.com).

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.

GCC is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "target.h"
#include "cp-tree.h"
#include "stringpool.h"
#include "cgraph.h"
#include "debug.h"
#include "tree-inline.h"
#include "tree-iterator.h"

/* Prototypes.  */

static void update_cloned_parm (tree, tree, bool);

/* CLONED_PARM is a copy of CLONE, generated for a cloned constructor
   or destructor.  Update it to ensure that the source-position for
   the cloned parameter matches that for the original, and that the
   debugging generation code will be able to find the original PARM.  */

static void
update_cloned_parm (tree parm, tree cloned_parm, bool first)
{
  DECL_ABSTRACT_ORIGIN (cloned_parm) = parm;

  /* We may have taken its address.  */
  TREE_ADDRESSABLE (cloned_parm) = TREE_ADDRESSABLE (parm);

  DECL_BY_REFERENCE (cloned_parm) = DECL_BY_REFERENCE (parm);

  /* The definition might have different constness.  */
  TREE_READONLY (cloned_parm) = TREE_READONLY (parm);

  TREE_USED (cloned_parm) = !first || TREE_USED (parm);

  /* The name may have changed from the declaration.  */
  DECL_NAME (cloned_parm) = DECL_NAME (parm);
  DECL_SOURCE_LOCATION (cloned_parm) = DECL_SOURCE_LOCATION (parm);
  TREE_TYPE (cloned_parm) = TREE_TYPE (parm);

  DECL_NOT_GIMPLE_REG_P (cloned_parm) = DECL_NOT_GIMPLE_REG_P (parm);
}

/* Like copy_decl_no_change, but handle DECL_OMP_PRIVATIZED_MEMBER
   properly.  */

static tree
cxx_copy_decl (tree decl, copy_body_data *id)
{
  tree copy = copy_decl_no_change (decl, id);
  if (VAR_P (decl)
      && DECL_HAS_VALUE_EXPR_P (decl)
      && DECL_ARTIFICIAL (decl)
      && DECL_LANG_SPECIFIC (decl)
      && DECL_OMP_PRIVATIZED_MEMBER (decl))
    {
      tree expr = DECL_VALUE_EXPR (copy);
      walk_tree (&expr, copy_tree_body_r, id, NULL);
      SET_DECL_VALUE_EXPR (copy, expr);
    }
  return copy;
}

/* FN is a function in High GIMPLE form that has a complete body and no
   CFG.  CLONE is a function whose body is to be set to a copy of FN,
   mapping argument declarations according to the ARG_MAP splay_tree.  */

static void
clone_body (tree clone, tree fn, void *arg_map)
{
  copy_body_data id;
  tree stmts;

  /* Clone the body, as if we were making an inline call.  But, remap
     the parameters in the callee to the parameters of caller.  */
  memset (&id, 0, sizeof (id));
  id.src_fn = fn;
  id.dst_fn = clone;
  id.src_cfun = DECL_STRUCT_FUNCTION (fn);
  id.decl_map = static_cast<hash_map<tree, tree> *> (arg_map);

  id.copy_decl = cxx_copy_decl;
  id.transform_call_graph_edges = CB_CGE_DUPLICATE;
  id.transform_new_cfg = true;
  id.transform_return_to_modify = false;

  /* We're not inside any EH region.  */
  id.eh_lp_nr = 0;

  stmts = DECL_SAVED_TREE (fn);
  walk_tree (&stmts, copy_tree_body_r, &id, NULL);

  /* Also remap the initializer of any static variables so that they (in
     particular, any label addresses) correspond to the base variant rather
     than the abstract one.  */
  if (DECL_NAME (clone) == base_dtor_identifier
      || DECL_NAME (clone) == base_ctor_identifier)
    {
      unsigned ix;
      tree decl;

      FOR_EACH_LOCAL_DECL (DECL_STRUCT_FUNCTION (fn), ix, decl)
        walk_tree (&DECL_INITIAL (decl), copy_tree_body_r, &id, NULL);
    }

  append_to_statement_list_force (stmts, &DECL_SAVED_TREE (clone));
}

/* DELETE_DTOR is a delete destructor whose body will be built.
   COMPLETE_DTOR is the corresponding complete destructor.  */

static void
build_delete_destructor_body (tree delete_dtor, tree complete_dtor)
{
  tree parm = DECL_ARGUMENTS (delete_dtor);
  tree virtual_size = cxx_sizeof (current_class_type);

  /* Call the delete function.  */
  tree call_delete = build_op_delete_call (DELETE_EXPR, current_class_ptr,
					   virtual_size,
					   /*global_p=*/false,
					   /*placement=*/NULL_TREE,
					   /*alloc_fn=*/NULL_TREE,
					   tf_warning_or_error);

  tree op = get_callee_fndecl (call_delete);
  if (op && DECL_P (op) && destroying_delete_p (op))
    {
      /* The destroying delete will handle calling complete_dtor.  */
      add_stmt (call_delete);
    }
  else
    {
      /* Call the corresponding complete destructor.  */
      gcc_assert (complete_dtor);
      tree call_dtor = build_cxx_call (complete_dtor, 1, &parm,
				       tf_warning_or_error);

      /* Operator delete must be called, whether or not the dtor throws.  */
      add_stmt (build2 (TRY_FINALLY_EXPR, void_type_node,
			call_dtor, call_delete));
    }

  /* Return the address of the object.
     ??? How is it useful to return an invalid address?  */
  if (targetm.cxx.cdtor_returns_this ())
    {
      tree val = DECL_ARGUMENTS (delete_dtor);
      suppress_warning (val, OPT_Wuse_after_free);
      val = build2 (MODIFY_EXPR, TREE_TYPE (val),
                    DECL_RESULT (delete_dtor), val);
      add_stmt (build_stmt (0, RETURN_EXPR, val));
    }
}

/* Return name of comdat group for complete and base ctor (or dtor)
   that have the same body.  If dtor is virtual, deleting dtor goes
   into this comdat group as well.  */

static tree
cdtor_comdat_group (tree complete, tree base)
{
  tree complete_name = DECL_ASSEMBLER_NAME (complete);
  tree base_name = DECL_ASSEMBLER_NAME (base);
  char *grp_name;
  const char *p, *q;
  bool diff_seen = false;
  size_t idx;
  gcc_assert (IDENTIFIER_LENGTH (complete_name)
	      == IDENTIFIER_LENGTH (base_name));
  grp_name = XALLOCAVEC (char, IDENTIFIER_LENGTH (complete_name) + 1);
  p = IDENTIFIER_POINTER (complete_name);
  q = IDENTIFIER_POINTER (base_name);
  for (idx = 0; idx < IDENTIFIER_LENGTH (complete_name); idx++)
    if (p[idx] == q[idx])
      grp_name[idx] = p[idx];
    else
      {
	gcc_assert (!diff_seen
		    && idx > 0
		    && (p[idx - 1] == 'C' || p[idx - 1] == 'D'
			|| p[idx - 1] == 'I')
		    && p[idx] == '1'
		    && q[idx] == '2');
	grp_name[idx] = '5';
	diff_seen = true;
      }
  grp_name[idx] = '\0';
  gcc_assert (diff_seen);
  return get_identifier (grp_name);
}

/* Returns true iff we can make the base and complete [cd]tor aliases of
   the same symbol rather than separate functions.  */

static bool
can_alias_cdtor (tree fn)
{
  /* If aliases aren't supported by the assembler, fail.  */
  if (!TARGET_SUPPORTS_ALIASES)
    return false;

  /* We can't use an alias if there are virtual bases.  */
  if (CLASSTYPE_VBASECLASSES (DECL_CONTEXT (fn)))
    return false;
  gcc_assert (DECL_MAYBE_IN_CHARGE_CDTOR_P (fn));
  /* Don't use aliases for weak/linkonce definitions unless we can put both
     symbols in the same COMDAT group.  */
  return (DECL_INTERFACE_KNOWN (fn)
	  && (SUPPORTS_ONE_ONLY || !DECL_WEAK (fn))
	  && (!DECL_ONE_ONLY (fn)
	      || (HAVE_COMDAT_GROUP && DECL_WEAK (fn))));
}

/* FN is a [cd]tor, fns is a pointer to an array of length 3.  Fill fns
   with pointers to the base, complete, and deleting variants.  */

static void
populate_clone_array (tree fn, tree *fns)
{
  tree clone;

  fns[0] = NULL_TREE;
  fns[1] = NULL_TREE;
  fns[2] = NULL_TREE;

  FOR_EACH_CLONE (clone, fn)
    if (DECL_NAME (clone) == complete_dtor_identifier
	|| DECL_NAME (clone) == complete_ctor_identifier)
      fns[1] = clone;
    else if (DECL_NAME (clone) == base_dtor_identifier
	     || DECL_NAME (clone) == base_ctor_identifier)
      fns[0] = clone;
    else if (DECL_NAME (clone) == deleting_dtor_identifier)
      fns[2] = clone;
    else
      gcc_unreachable ();
}

/* FN is a constructor or destructor, and there are FUNCTION_DECLs
   cloned from it nearby.  Instead of cloning this body, leave it
   alone and create tiny one-call bodies for the cloned
   FUNCTION_DECLs.  These clones are sibcall candidates, and their
   resulting code will be very thunk-esque.  */

static bool
maybe_thunk_body (tree fn, bool force)
{
  tree bind, block, call, clone, clone_result, fn_parm, fn_parm_typelist;
  tree last_arg, modify, *args;
  int parmno, vtt_parmno, max_parms;
  tree fns[3];

  if (!force && !flag_declone_ctor_dtor)
    return 0;

  /* If function accepts variable arguments, give up.  */
  last_arg = tree_last (TYPE_ARG_TYPES (TREE_TYPE (fn)));
  if (last_arg != void_list_node)
    return 0;

  /* If we got this far, we've decided to turn the clones into thunks.  */

  /* We're going to generate code for fn, so it is no longer "abstract."
     Also make the unified ctor/dtor private to either the translation unit
     (for non-vague linkage ctors) or the COMDAT group (otherwise).  */

  populate_clone_array (fn, fns);

  /* Can happen during error recovery (c++/71464).  */
  if (!fns[0] || !fns[1])
    return 0;

  /* Don't use thunks if the base clone omits inherited parameters.  */
  if (ctor_omit_inherited_parms (fns[0]))
    return 0;

  DECL_ABSTRACT_P (fn) = false;
  if (!DECL_WEAK (fn))
    {
      TREE_PUBLIC (fn) = false;
      DECL_EXTERNAL (fn) = false;
      DECL_INTERFACE_KNOWN (fn) = true;
    }
  else if (HAVE_COMDAT_GROUP)
    {
      /* At eof, defer creation of mangling aliases temporarily.  */
      bool save_defer_mangling_aliases = defer_mangling_aliases;
      defer_mangling_aliases = true;
      tree comdat_group = cdtor_comdat_group (fns[1], fns[0]);
      defer_mangling_aliases = save_defer_mangling_aliases;
      cgraph_node::get_create (fns[0])->set_comdat_group (comdat_group);
      cgraph_node::get_create (fns[1])->add_to_same_comdat_group
	(cgraph_node::get_create (fns[0]));
      symtab_node::get (fn)->add_to_same_comdat_group
	(symtab_node::get (fns[0]));
      if (fns[2])
	/* If *[CD][12]* dtors go into the *[CD]5* comdat group and dtor is
	   virtual, it goes into the same comdat group as well.  */
	cgraph_node::get_create (fns[2])->add_to_same_comdat_group
	  (symtab_node::get (fns[0]));
      /* Emit them now that the thunks are same comdat group aliases.  */
      if (!save_defer_mangling_aliases)
	generate_mangling_aliases ();
      TREE_PUBLIC (fn) = false;
      DECL_EXTERNAL (fn) = false;
      DECL_INTERFACE_KNOWN (fn) = true;
      /* function_and_variable_visibility doesn't want !PUBLIC decls to
	 have these flags set.  */
      DECL_WEAK (fn) = false;
      DECL_COMDAT (fn) = false;
    }

  /* Find the vtt_parm, if present.  */
  for (vtt_parmno = -1, parmno = 0, fn_parm = DECL_ARGUMENTS (fn);
       fn_parm;
       ++parmno, fn_parm = TREE_CHAIN (fn_parm))
    {
      if (DECL_ARTIFICIAL (fn_parm)
	  && DECL_NAME (fn_parm) == vtt_parm_identifier)
	{
	  /* Compensate for removed in_charge parameter.  */
	  vtt_parmno = parmno;
	  break;
	}
    }

  /* Allocate an argument buffer for build_cxx_call().
     Make sure it is large enough for any of the clones.  */
  max_parms = 0;
  FOR_EACH_CLONE (clone, fn)
    {
      int length = list_length (DECL_ARGUMENTS (fn));
      if (length > max_parms)
        max_parms = length;
    }
  args = XALLOCAVEC (tree, max_parms);

  /* We know that any clones immediately follow FN in TYPE_FIELDS.  */
  FOR_EACH_CLONE (clone, fn)
    {
      tree clone_parm;

      /* If we've already generated a body for this clone, avoid
	 duplicating it.  (Is it possible for a clone-list to grow after we
	 first see it?)  */
      if (DECL_SAVED_TREE (clone) || TREE_ASM_WRITTEN (clone))
	continue;

      /* Start processing the function.  */
      start_preparsed_function (clone, NULL_TREE, SF_PRE_PARSED);

      if (clone == fns[2])
	{
	  for (clone_parm = DECL_ARGUMENTS (clone); clone_parm;
	       clone_parm = TREE_CHAIN (clone_parm))
	    DECL_ABSTRACT_ORIGIN (clone_parm) = NULL_TREE;
	  /* Build the delete destructor by calling complete destructor and
	     delete function.  */
	  build_delete_destructor_body (clone, fns[1]);
	}
      else
	{
	  /* Walk parameter lists together, creating parameter list for
	     call to original function.  */
	  for (parmno = 0,
		 fn_parm = DECL_ARGUMENTS (fn),
		 fn_parm_typelist = TYPE_ARG_TYPES (TREE_TYPE (fn)),
		 clone_parm = DECL_ARGUMENTS (clone);
	       fn_parm;
	       ++parmno,
		 fn_parm = TREE_CHAIN (fn_parm))
	    {
	      if (parmno == vtt_parmno && ! DECL_HAS_VTT_PARM_P (clone))
		{
		  gcc_assert (fn_parm_typelist);
		  /* Clobber argument with formal parameter type.  */
		  args[parmno]
		    = convert (TREE_VALUE (fn_parm_typelist),
			       null_pointer_node);
		}
	      else if (parmno == 1 && DECL_HAS_IN_CHARGE_PARM_P (fn))
		{
		  tree in_charge
		    = copy_node (in_charge_arg_for_name (DECL_NAME (clone)));
		  args[parmno] = in_charge;
		}
	      /* Map other parameters to their equivalents in the cloned
		 function.  */
	      else
		{
		  gcc_assert (clone_parm);
		  DECL_ABSTRACT_ORIGIN (clone_parm) = NULL;
		  args[parmno] = clone_parm;
		  /* Clear TREE_ADDRESSABLE on thunk arguments.  */
		  TREE_ADDRESSABLE (clone_parm) = 0;
		  clone_parm = TREE_CHAIN (clone_parm);
		}
	      if (fn_parm_typelist)
		fn_parm_typelist = TREE_CHAIN (fn_parm_typelist);
	    }

	  /* We built this list backwards; fix now.  */
	  mark_used (fn);
	  call = build_cxx_call (fn, parmno, args, tf_warning_or_error);
	  /* Arguments passed to the thunk by invisible reference should
	     be transmitted to the callee unchanged.  Do not create a
	     temporary and invoke the copy constructor.  The thunking
	     transformation must not introduce any constructor calls.  */
	  CALL_FROM_THUNK_P (call) = 1;
	  block = make_node (BLOCK);
	  if (targetm.cxx.cdtor_returns_this ())
	    {
	      clone_result = DECL_RESULT (clone);
	      modify = build2 (MODIFY_EXPR, TREE_TYPE (clone_result),
			       clone_result, call);
	      modify = build1 (RETURN_EXPR, void_type_node, modify);
	      add_stmt (modify);
	    }
	  else
	    {
	      add_stmt (call);
	    }
	  bind = c_build_bind_expr (DECL_SOURCE_LOCATION (clone),
				    block, cur_stmt_list);
	  DECL_SAVED_TREE (clone) = push_stmt_list ();
	  add_stmt (bind);
	}

      DECL_ABSTRACT_ORIGIN (clone) = NULL;
      expand_or_defer_fn (finish_function (/*inline_p=*/false));
    }
  return 1;
}

/* FN is a function that has a complete body.  Clone the body as
   necessary.  Returns nonzero if there's no longer any need to
   process the main body.  */

bool
maybe_clone_body (tree fn)
{
  tree comdat_group = NULL_TREE;
  tree clone;
  tree fns[3];
  bool first = true;
  int idx;
  bool need_alias = false;

  /* We only clone constructors and destructors.  */
  if (!DECL_MAYBE_IN_CHARGE_CDTOR_P (fn))
    return 0;

  populate_clone_array (fn, fns);

  /* Remember if we can't have multiple clones for some reason.  We need to
     check this before we remap local static initializers in clone_body.  */
  if (!tree_versionable_function_p (fn))
    need_alias = true;

  /* We know that any clones immediately follow FN in the TYPE_FIELDS
     list.  */
  push_to_top_level ();
  for (idx = 0; idx < 3; idx++)
    {
      tree parm;
      tree clone_parm;

      clone = fns[idx];
      if (!clone)
	continue;      

      /* Update CLONE's source position information to match FN's.  */
      DECL_SOURCE_LOCATION (clone) = DECL_SOURCE_LOCATION (fn);
      DECL_DECLARED_INLINE_P (clone) = DECL_DECLARED_INLINE_P (fn);
      DECL_DECLARED_CONSTEXPR_P (clone) = DECL_DECLARED_CONSTEXPR_P (fn);
      DECL_COMDAT (clone) = DECL_COMDAT (fn);
      DECL_WEAK (clone) = DECL_WEAK (fn);

      /* We don't copy the comdat group from fn to clone because the assembler
	 name of fn was corrupted by write_mangled_name by adding *INTERNAL*
	 to it. By doing so, it also corrupted the comdat group. */
      if (DECL_ONE_ONLY (fn))
	cgraph_node::get_create (clone)->set_comdat_group (cxx_comdat_group (clone));
      DECL_USE_TEMPLATE (clone) = DECL_USE_TEMPLATE (fn);
      DECL_EXTERNAL (clone) = DECL_EXTERNAL (fn);
      DECL_INTERFACE_KNOWN (clone) = DECL_INTERFACE_KNOWN (fn);
      DECL_NOT_REALLY_EXTERN (clone) = DECL_NOT_REALLY_EXTERN (fn);
      TREE_PUBLIC (clone) = TREE_PUBLIC (fn);
      DECL_VISIBILITY (clone) = DECL_VISIBILITY (fn);
      DECL_VISIBILITY_SPECIFIED (clone) = DECL_VISIBILITY_SPECIFIED (fn);
      DECL_DLLIMPORT_P (clone) = DECL_DLLIMPORT_P (fn);
      DECL_ATTRIBUTES (clone) = copy_list (DECL_ATTRIBUTES (fn));
      DECL_DISREGARD_INLINE_LIMITS (clone) = DECL_DISREGARD_INLINE_LIMITS (fn);
      set_decl_section_name (clone, fn);

      /* Adjust the parameter names and locations.  */
      parm = DECL_ARGUMENTS (fn);
      clone_parm = DECL_ARGUMENTS (clone);
      /* Update the `this' parameter, which is always first.  */
      update_cloned_parm (parm, clone_parm, first);
      parm = DECL_CHAIN (parm);
      clone_parm = DECL_CHAIN (clone_parm);
      if (DECL_HAS_IN_CHARGE_PARM_P (fn))
	parm = DECL_CHAIN (parm);
      if (DECL_HAS_VTT_PARM_P (fn))
	parm = DECL_CHAIN (parm);
      if (DECL_HAS_VTT_PARM_P (clone))
	clone_parm = DECL_CHAIN (clone_parm);
      for (; parm && clone_parm;
	   parm = DECL_CHAIN (parm), clone_parm = DECL_CHAIN (clone_parm))
	/* Update this parameter.  */
	update_cloned_parm (parm, clone_parm, first);
    }

  bool can_alias = can_alias_cdtor (fn);

  /* If we decide to turn clones into thunks, they will branch to fn.
     Must have original function available to call.  */
  if (!can_alias && maybe_thunk_body (fn, need_alias))
    {
      pop_from_top_level ();
      /* We still need to emit the original function.  */
      return 0;
    }

  /* Emit the DWARF1 abstract instance.  */
  (*debug_hooks->deferred_inline_function) (fn);

  /* We know that any clones immediately follow FN in the TYPE_FIELDS. */
  for (idx = 0; idx < 3; idx++)
    {
      tree parm;
      tree clone_parm;
      int parmno;
      hash_map<tree, tree> *decl_map;
      bool alias = false;

      clone = fns[idx];
      if (!clone)
	continue;

      /* Start processing the function.  */
      start_preparsed_function (clone, NULL_TREE, SF_PRE_PARSED);

      /* Tell cgraph if both ctors or both dtors are known to have
	 the same body.  */
      if (can_alias
	  && fns[0]
	  && idx == 1
	  && cgraph_node::get_create (fns[0])->create_same_body_alias
	       (clone, fns[0]))
	{
	  alias = true;
	  if (DECL_ONE_ONLY (fns[0]))
	    {
	      /* For comdat base and complete cdtors put them
		 into the same, *[CD]5* comdat group instead of
		 *[CD][12]*.  */
	      comdat_group = cdtor_comdat_group (fns[1], fns[0]);
	      cgraph_node::get_create (fns[0])->set_comdat_group (comdat_group);
	      if (symtab_node::get (clone)->same_comdat_group)
		symtab_node::get (clone)->remove_from_same_comdat_group ();
	      symtab_node::get (clone)->add_to_same_comdat_group
		(symtab_node::get (fns[0]));
	    }
	}

      /* Build the delete destructor by calling complete destructor
         and delete function.  */
      if (idx == 2)
	{
	  build_delete_destructor_body (clone, fns[1]);
	  /* If *[CD][12]* dtors go into the *[CD]5* comdat group and dtor is
	     virtual, it goes into the same comdat group as well.  */
	  if (comdat_group)
	    cgraph_node::get_create (clone)->add_to_same_comdat_group
	      (symtab_node::get (fns[0]));
	}
      else if (alias)
	/* No need to populate body.  */ ;
      else
	{
	  /* If we can't have multiple copies of FN (say, because there's a
	     static local initialized with the address of a label), we need
	     to use an alias for the complete variant.  */
	  if (idx == 1 && need_alias)
	    {
	      if (DECL_STRUCT_FUNCTION (fn)->cannot_be_copied_set)
		sorry (DECL_STRUCT_FUNCTION (fn)->cannot_be_copied_reason, fn);
	      else
		sorry ("making multiple clones of %qD", fn);
	    }

          /* Remap the parameters.  */
          decl_map = new hash_map<tree, tree>;
          for (parmno = 0,
                parm = DECL_ARGUMENTS (fn),
                clone_parm = DECL_ARGUMENTS (clone);
              parm;
              ++parmno,
                parm = DECL_CHAIN (parm))
            {
              /* Map the in-charge parameter to an appropriate constant.  */
              if (DECL_HAS_IN_CHARGE_PARM_P (fn) && parmno == 1)
                {
                  tree in_charge;
                  in_charge = in_charge_arg_for_name (DECL_NAME (clone));
                  decl_map->put (parm, in_charge);
                }
              else if (DECL_ARTIFICIAL (parm)
                       && DECL_NAME (parm) == vtt_parm_identifier)
                {
                  /* For a subobject constructor or destructor, the next
                     argument is the VTT parameter.  Remap the VTT_PARM
                     from the CLONE to this parameter.  */
                  if (DECL_HAS_VTT_PARM_P (clone))
                    {
                      DECL_ABSTRACT_ORIGIN (clone_parm) = parm;
                      decl_map->put (parm, clone_parm);
                      clone_parm = DECL_CHAIN (clone_parm);
                    }
                  /* Otherwise, map the VTT parameter to `NULL'.  */
                  else
		    {
		      tree t
			= fold_convert (TREE_TYPE (parm), null_pointer_node);
		      decl_map->put (parm, t);
		    }
                }
              /* Map other parameters to their equivalents in the cloned
                 function.  */
              else
                {
		  tree replacement;
		  if (clone_parm)
		    {
		      replacement = clone_parm;
		      clone_parm = DECL_CHAIN (clone_parm);
		    }
		  else
		    {
		      /* Inheriting ctors can omit parameters from the base
			 clone.  Replace them with null lvalues.  */
		      tree reftype = build_reference_type (TREE_TYPE (parm));
		      replacement = fold_convert (reftype, null_pointer_node);
		      replacement = convert_from_reference (replacement);
		    }
                  decl_map->put (parm, replacement);
                }
            }

          if (targetm.cxx.cdtor_returns_this ())
            {
              parm = DECL_RESULT (fn);
              clone_parm = DECL_RESULT (clone);
              decl_map->put (parm, clone_parm);
            }

          /* Clone the body.  */
          clone_body (clone, fn, decl_map);

          /* Clean up.  */
          delete decl_map;
        }

      /* The clone can throw iff the original function can throw.  */
      cp_function_chain->can_throw = !TREE_NOTHROW (fn);

      /* Now, expand this function into RTL, if appropriate.  */
      finish_function (/*inline_p=*/false);
      BLOCK_ABSTRACT_ORIGIN (DECL_INITIAL (clone)) = DECL_INITIAL (fn);
      if (alias)
	{
	  if (expand_or_defer_fn_1 (clone))
	    emit_associated_thunks (clone);
	  /* We didn't generate a body, so remove the empty one.  */
	  DECL_SAVED_TREE (clone) = NULL_TREE;
	}
      else
	expand_or_defer_fn (clone);
      first = false;
    }
  pop_from_top_level ();

  /* We don't need to process the original function any further.  */
  return 1;
}
