/* Handle the hair of processing (but not expanding) inline functions.
   Also manage function and variable name overloading.
   Copyright (C) 1987-2013 Free Software Foundation, Inc.
   Contributed by Michael Tiemann (tiemann@cygnus.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/>.  */


/* Handle method declarations.  */
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
#include "cp-tree.h"
#include "flags.h"
#include "toplev.h"
#include "tm_p.h"
#include "target.h"
#include "common/common-target.h"
#include "diagnostic.h"
#include "cgraph.h"
#include "gimple.h"

/* Various flags to control the mangling process.  */

enum mangling_flags
{
  /* No flags.  */
  mf_none = 0,
  /* The thing we are presently mangling is part of a template type,
     rather than a fully instantiated type.  Therefore, we may see
     complex expressions where we would normally expect to see a
     simple integer constant.  */
  mf_maybe_uninstantiated = 1,
  /* When mangling a numeric value, use the form `_XX_' (instead of
     just `XX') if the value has more than one digit.  */
  mf_use_underscores_around_value = 2
};

typedef enum mangling_flags mangling_flags;

static void do_build_copy_assign (tree);
static void do_build_copy_constructor (tree);
static tree make_alias_for_thunk (tree);

/* Called once to initialize method.c.  */

void
init_method (void)
{
  init_mangle ();
}

/* Return a this or result adjusting thunk to FUNCTION.  THIS_ADJUSTING
   indicates whether it is a this or result adjusting thunk.
   FIXED_OFFSET and VIRTUAL_OFFSET indicate how to do the adjustment
   (see thunk_adjust).  VIRTUAL_OFFSET can be NULL, but FIXED_OFFSET
   never is.  VIRTUAL_OFFSET is the /index/ into the vtable for this
   adjusting thunks, we scale it to a byte offset. For covariant
   thunks VIRTUAL_OFFSET is the virtual binfo.  You must post process
   the returned thunk with finish_thunk.  */

tree
make_thunk (tree function, bool this_adjusting,
	    tree fixed_offset, tree virtual_offset)
{
  HOST_WIDE_INT d;
  tree thunk;

  gcc_assert (TREE_CODE (function) == FUNCTION_DECL);
  /* We can have this thunks to covariant thunks, but not vice versa.  */
  gcc_assert (!DECL_THIS_THUNK_P (function));
  gcc_assert (!DECL_RESULT_THUNK_P (function) || this_adjusting);

  /* Scale the VIRTUAL_OFFSET to be in terms of bytes.  */
  if (this_adjusting && virtual_offset)
    virtual_offset
      = size_binop (MULT_EXPR,
		    virtual_offset,
		    convert (ssizetype,
			     TYPE_SIZE_UNIT (vtable_entry_type)));

  d = tree_low_cst (fixed_offset, 0);

  /* See if we already have the thunk in question.  For this_adjusting
     thunks VIRTUAL_OFFSET will be an INTEGER_CST, for covariant thunks it
     will be a BINFO.  */
  for (thunk = DECL_THUNKS (function); thunk; thunk = DECL_CHAIN (thunk))
    if (DECL_THIS_THUNK_P (thunk) == this_adjusting
	&& THUNK_FIXED_OFFSET (thunk) == d
	&& !virtual_offset == !THUNK_VIRTUAL_OFFSET (thunk)
	&& (!virtual_offset
	    || (this_adjusting
		? tree_int_cst_equal (THUNK_VIRTUAL_OFFSET (thunk),
				      virtual_offset)
		: THUNK_VIRTUAL_OFFSET (thunk) == virtual_offset)))
      return thunk;

  /* All thunks must be created before FUNCTION is actually emitted;
     the ABI requires that all thunks be emitted together with the
     function to which they transfer control.  */
  gcc_assert (!TREE_ASM_WRITTEN (function));
  /* Likewise, we can only be adding thunks to a function declared in
     the class currently being laid out.  */
  gcc_assert (TYPE_SIZE (DECL_CONTEXT (function))
	      && TYPE_BEING_DEFINED (DECL_CONTEXT (function)));

  thunk = build_decl (DECL_SOURCE_LOCATION (function),
		      FUNCTION_DECL, NULL_TREE, TREE_TYPE (function));
  DECL_LANG_SPECIFIC (thunk) = DECL_LANG_SPECIFIC (function);
  cxx_dup_lang_specific_decl (thunk);
  DECL_VIRTUAL_P (thunk) = true;
  SET_DECL_THUNKS (thunk, NULL_TREE);

  DECL_CONTEXT (thunk) = DECL_CONTEXT (function);
  TREE_READONLY (thunk) = TREE_READONLY (function);
  TREE_THIS_VOLATILE (thunk) = TREE_THIS_VOLATILE (function);
  TREE_PUBLIC (thunk) = TREE_PUBLIC (function);
  SET_DECL_THUNK_P (thunk, this_adjusting);
  THUNK_TARGET (thunk) = function;
  THUNK_FIXED_OFFSET (thunk) = d;
  THUNK_VIRTUAL_OFFSET (thunk) = virtual_offset;
  THUNK_ALIAS (thunk) = NULL_TREE;

  DECL_INTERFACE_KNOWN (thunk) = 1;
  DECL_NOT_REALLY_EXTERN (thunk) = 1;
  DECL_COMDAT (thunk) = DECL_COMDAT (function);
  DECL_SAVED_FUNCTION_DATA (thunk) = NULL;
  /* The thunk itself is not a constructor or destructor, even if
     the thing it is thunking to is.  */
  DECL_DESTRUCTOR_P (thunk) = 0;
  DECL_CONSTRUCTOR_P (thunk) = 0;
  DECL_EXTERNAL (thunk) = 1;
  DECL_ARTIFICIAL (thunk) = 1;
  /* The THUNK is not a pending inline, even if the FUNCTION is.  */
  DECL_PENDING_INLINE_P (thunk) = 0;
  DECL_DECLARED_INLINE_P (thunk) = 0;
  /* Nor is it a template instantiation.  */
  DECL_USE_TEMPLATE (thunk) = 0;
  DECL_TEMPLATE_INFO (thunk) = NULL;

  /* Add it to the list of thunks associated with FUNCTION.  */
  DECL_CHAIN (thunk) = DECL_THUNKS (function);
  SET_DECL_THUNKS (function, thunk);

  return thunk;
}

/* Finish THUNK, a thunk decl.  */

void
finish_thunk (tree thunk)
{
  tree function, name;
  tree fixed_offset = ssize_int (THUNK_FIXED_OFFSET (thunk));
  tree virtual_offset = THUNK_VIRTUAL_OFFSET (thunk);

  gcc_assert (!DECL_NAME (thunk) && DECL_THUNK_P (thunk));
  if (virtual_offset && DECL_RESULT_THUNK_P (thunk))
    virtual_offset = BINFO_VPTR_FIELD (virtual_offset);
  function = THUNK_TARGET (thunk);
  name = mangle_thunk (function, DECL_THIS_THUNK_P (thunk),
		       fixed_offset, virtual_offset);

  /* We can end up with declarations of (logically) different
     covariant thunks, that do identical adjustments.  The two thunks
     will be adjusting between within different hierarchies, which
     happen to have the same layout.  We must nullify one of them to
     refer to the other.  */
  if (DECL_RESULT_THUNK_P (thunk))
    {
      tree cov_probe;

      for (cov_probe = DECL_THUNKS (function);
	   cov_probe; cov_probe = DECL_CHAIN (cov_probe))
	if (DECL_NAME (cov_probe) == name)
	  {
	    gcc_assert (!DECL_THUNKS (thunk));
	    THUNK_ALIAS (thunk) = (THUNK_ALIAS (cov_probe)
				   ? THUNK_ALIAS (cov_probe) : cov_probe);
	    break;
	  }
    }

  DECL_NAME (thunk) = name;
  SET_DECL_ASSEMBLER_NAME (thunk, name);
}

static GTY (()) int thunk_labelno;

/* Create a static alias to target.  */

tree
make_alias_for (tree target, tree newid)
{
  tree alias = build_decl (DECL_SOURCE_LOCATION (target),
			   TREE_CODE (target), newid, TREE_TYPE (target));
  DECL_LANG_SPECIFIC (alias) = DECL_LANG_SPECIFIC (target);
  cxx_dup_lang_specific_decl (alias);
  DECL_CONTEXT (alias) = NULL;
  TREE_READONLY (alias) = TREE_READONLY (target);
  TREE_THIS_VOLATILE (alias) = TREE_THIS_VOLATILE (target);
  TREE_PUBLIC (alias) = 0;
  DECL_INTERFACE_KNOWN (alias) = 1;
  if (DECL_LANG_SPECIFIC (alias))
    {
      DECL_NOT_REALLY_EXTERN (alias) = 1;
      DECL_USE_TEMPLATE (alias) = 0;
      DECL_TEMPLATE_INFO (alias) = NULL;
    }
  DECL_EXTERNAL (alias) = 0;
  DECL_ARTIFICIAL (alias) = 1;
  DECL_TEMPLATE_INSTANTIATED (alias) = 0;
  if (TREE_CODE (alias) == FUNCTION_DECL)
    {
      DECL_SAVED_FUNCTION_DATA (alias) = NULL;
      DECL_DESTRUCTOR_P (alias) = 0;
      DECL_CONSTRUCTOR_P (alias) = 0;
      DECL_PENDING_INLINE_P (alias) = 0;
      DECL_DECLARED_INLINE_P (alias) = 0;
      DECL_INITIAL (alias) = error_mark_node;
      DECL_ARGUMENTS (alias) = copy_list (DECL_ARGUMENTS (target));
    }
  else
    TREE_STATIC (alias) = 1;
  TREE_ADDRESSABLE (alias) = 1;
  TREE_USED (alias) = 1;
  SET_DECL_ASSEMBLER_NAME (alias, DECL_NAME (alias));
  return alias;
}

static tree
make_alias_for_thunk (tree function)
{
  tree alias;
  char buf[256];

  targetm.asm_out.generate_internal_label (buf, "LTHUNK", thunk_labelno);
  thunk_labelno++;

  alias = make_alias_for (function, get_identifier (buf));

  if (!flag_syntax_only)
    {
      struct cgraph_node *funcn, *aliasn;
      funcn = cgraph_get_node (function);
      gcc_checking_assert (funcn);
      aliasn = cgraph_same_body_alias (funcn, alias, function);
      DECL_ASSEMBLER_NAME (function);
      gcc_assert (aliasn != NULL);
    }

  return alias;
}

/* Emit the definition of a C++ multiple inheritance or covariant
   return vtable thunk.  If EMIT_P is nonzero, the thunk is emitted
   immediately.  */

void
use_thunk (tree thunk_fndecl, bool emit_p)
{
  tree a, t, function, alias;
  tree virtual_offset;
  HOST_WIDE_INT fixed_offset, virtual_value;
  bool this_adjusting = DECL_THIS_THUNK_P (thunk_fndecl);
  struct cgraph_node *funcn, *thunk_node;

  /* We should have called finish_thunk to give it a name.  */
  gcc_assert (DECL_NAME (thunk_fndecl));

  /* We should never be using an alias, always refer to the
     aliased thunk.  */
  gcc_assert (!THUNK_ALIAS (thunk_fndecl));

  if (TREE_ASM_WRITTEN (thunk_fndecl))
    return;

  function = THUNK_TARGET (thunk_fndecl);
  if (DECL_RESULT (thunk_fndecl))
    /* We already turned this thunk into an ordinary function.
       There's no need to process this thunk again.  */
    return;

  if (DECL_THUNK_P (function))
    /* The target is itself a thunk, process it now.  */
    use_thunk (function, emit_p);

  /* Thunks are always addressable; they only appear in vtables.  */
  TREE_ADDRESSABLE (thunk_fndecl) = 1;

  /* Figure out what function is being thunked to.  It's referenced in
     this translation unit.  */
  TREE_ADDRESSABLE (function) = 1;
  mark_used (function);
  if (!emit_p)
    return;

  if (TARGET_USE_LOCAL_THUNK_ALIAS_P (function))
   alias = make_alias_for_thunk (function);
  else
   alias = function;

  fixed_offset = THUNK_FIXED_OFFSET (thunk_fndecl);
  virtual_offset = THUNK_VIRTUAL_OFFSET (thunk_fndecl);

  if (virtual_offset)
    {
      if (!this_adjusting)
	virtual_offset = BINFO_VPTR_FIELD (virtual_offset);
      virtual_value = tree_low_cst (virtual_offset, /*pos=*/0);
      gcc_assert (virtual_value);
    }
  else
    virtual_value = 0;

  /* And, if we need to emit the thunk, it's used.  */
  mark_used (thunk_fndecl);
  /* This thunk is actually defined.  */
  DECL_EXTERNAL (thunk_fndecl) = 0;
  /* The linkage of the function may have changed.  FIXME in linkage
     rewrite.  */
  gcc_assert (DECL_INTERFACE_KNOWN (function));
  TREE_PUBLIC (thunk_fndecl) = TREE_PUBLIC (function);
  DECL_VISIBILITY (thunk_fndecl) = DECL_VISIBILITY (function);
  DECL_VISIBILITY_SPECIFIED (thunk_fndecl)
    = DECL_VISIBILITY_SPECIFIED (function);
  DECL_COMDAT (thunk_fndecl) = DECL_COMDAT (function);
  DECL_WEAK (thunk_fndecl) = DECL_WEAK (function);

  if (flag_syntax_only)
    {
      TREE_ASM_WRITTEN (thunk_fndecl) = 1;
      return;
    }

  push_to_top_level ();

  if (TARGET_USE_LOCAL_THUNK_ALIAS_P (function)
      && targetm_common.have_named_sections)
    {
      resolve_unique_section (function, 0, flag_function_sections);

      if (DECL_SECTION_NAME (function) != NULL && DECL_ONE_ONLY (function))
	{
	  resolve_unique_section (thunk_fndecl, 0, flag_function_sections);

	  /* Output the thunk into the same section as function.  */
	  DECL_SECTION_NAME (thunk_fndecl) = DECL_SECTION_NAME (function);
	}
    }

  /* Set up cloned argument trees for the thunk.  */
  t = NULL_TREE;
  for (a = DECL_ARGUMENTS (function); a; a = DECL_CHAIN (a))
    {
      tree x = copy_node (a);
      DECL_CHAIN (x) = t;
      DECL_CONTEXT (x) = thunk_fndecl;
      SET_DECL_RTL (x, NULL);
      DECL_HAS_VALUE_EXPR_P (x) = 0;
      TREE_ADDRESSABLE (x) = 0;
      t = x;
    }
  a = nreverse (t);
  DECL_ARGUMENTS (thunk_fndecl) = a;
  TREE_ASM_WRITTEN (thunk_fndecl) = 1;
  funcn = cgraph_get_node (function);
  gcc_checking_assert (funcn);
  thunk_node = cgraph_add_thunk (funcn, thunk_fndecl, function,
				 this_adjusting, fixed_offset, virtual_value,
				 virtual_offset, alias);
  if (DECL_ONE_ONLY (function))
    symtab_add_to_same_comdat_group ((symtab_node) thunk_node,
				     (symtab_node) funcn);

  if (!this_adjusting
      || !targetm.asm_out.can_output_mi_thunk (thunk_fndecl, fixed_offset,
					       virtual_value, alias))
    {
      /* If this is a covariant thunk, or we don't have the necessary
	 code for efficient thunks, generate a thunk function that
	 just makes a call to the real function.  Unfortunately, this
	 doesn't work for varargs.  */

      if (varargs_function_p (function))
	error ("generic thunk code fails for method %q#D which uses %<...%>",
	       function);
    }

  pop_from_top_level ();
}

/* Code for synthesizing methods which have default semantics defined.  */

/* True iff CTYPE has a trivial SFK.  */

static bool
type_has_trivial_fn (tree ctype, special_function_kind sfk)
{
  switch (sfk)
    {
    case sfk_constructor:
      return !TYPE_HAS_COMPLEX_DFLT (ctype);
    case sfk_copy_constructor:
      return !TYPE_HAS_COMPLEX_COPY_CTOR (ctype);
    case sfk_move_constructor:
      return !TYPE_HAS_COMPLEX_MOVE_CTOR (ctype);
    case sfk_copy_assignment:
      return !TYPE_HAS_COMPLEX_COPY_ASSIGN (ctype);
    case sfk_move_assignment:
      return !TYPE_HAS_COMPLEX_MOVE_ASSIGN (ctype);
    case sfk_destructor:
      return !TYPE_HAS_NONTRIVIAL_DESTRUCTOR (ctype);
    case sfk_inheriting_constructor:
      return false;
    default:
      gcc_unreachable ();
    }
}

/* Note that CTYPE has a non-trivial SFK even though we previously thought
   it was trivial.  */

static void
type_set_nontrivial_flag (tree ctype, special_function_kind sfk)
{
  switch (sfk)
    {
    case sfk_constructor:
      TYPE_HAS_COMPLEX_DFLT (ctype) = true;
      return;
    case sfk_copy_constructor:
      TYPE_HAS_COMPLEX_COPY_CTOR (ctype) = true;
      return;
    case sfk_move_constructor:
      TYPE_HAS_COMPLEX_MOVE_CTOR (ctype) = true;
      return;
    case sfk_copy_assignment:
      TYPE_HAS_COMPLEX_COPY_ASSIGN (ctype) = true;
      return;
    case sfk_move_assignment:
      TYPE_HAS_COMPLEX_MOVE_ASSIGN (ctype) = true;
      return;
    case sfk_destructor:
      TYPE_HAS_NONTRIVIAL_DESTRUCTOR (ctype) = true;
      return;
    case sfk_inheriting_constructor:
    default:
      gcc_unreachable ();
    }
}

/* True iff FN is a trivial defaulted member function ([cd]tor, op=).  */

bool
trivial_fn_p (tree fn)
{
  if (!DECL_DEFAULTED_FN (fn))
    return false;

  /* If fn is a clone, get the primary variant.  */
  fn = DECL_ORIGIN (fn);
  return type_has_trivial_fn (DECL_CONTEXT (fn), special_function_p (fn));
}

/* Subroutine of do_build_copy_constructor: Add a mem-initializer for BINFO
   given the parameter or parameters PARM, possibly inherited constructor
   base INH, or move flag MOVE_P.  */

static tree
add_one_base_init (tree binfo, tree parm, bool move_p, tree inh,
		   tree member_init_list)
{
  tree init;
  if (inh)
    {
      /* An inheriting constructor only has a mem-initializer for
	 the base it inherits from.  */
      if (BINFO_TYPE (binfo) != inh)
	return member_init_list;

      tree *p = &init;
      init = NULL_TREE;
      for (; parm; parm = DECL_CHAIN (parm))
	{
	  tree exp = convert_from_reference (parm);
	  if (TREE_CODE (TREE_TYPE (parm)) != REFERENCE_TYPE
	      || TYPE_REF_IS_RVALUE (TREE_TYPE (parm)))
	    exp = move (exp);
	  *p = build_tree_list (NULL_TREE, exp);
	  p = &TREE_CHAIN (*p);
	}
    }
  else
    {
      init = build_base_path (PLUS_EXPR, parm, binfo, 1,
			      tf_warning_or_error);
      if (move_p)
	init = move (init);
      init = build_tree_list (NULL_TREE, init);
    }
  return tree_cons (binfo, init, member_init_list);
}

/* Generate code for default X(X&) or X(X&&) constructor or an inheriting
   constructor.  */

static void
do_build_copy_constructor (tree fndecl)
{
  tree parm = FUNCTION_FIRST_USER_PARM (fndecl);
  bool move_p = DECL_MOVE_CONSTRUCTOR_P (fndecl);
  bool trivial = trivial_fn_p (fndecl);
  tree inh = DECL_INHERITED_CTOR_BASE (fndecl);

  if (!inh)
    parm = convert_from_reference (parm);

  if (trivial
      && is_empty_class (current_class_type))
    /* Don't copy the padding byte; it might not have been allocated
       if *this is a base subobject.  */;
  else if (trivial)
    {
      tree t = build2 (INIT_EXPR, void_type_node, current_class_ref, parm);
      finish_expr_stmt (t);
    }
  else
    {
      tree fields = TYPE_FIELDS (current_class_type);
      tree member_init_list = NULL_TREE;
      int cvquals = cp_type_quals (TREE_TYPE (parm));
      int i;
      tree binfo, base_binfo;
      tree init;
      vec<tree, va_gc> *vbases;

      /* Initialize all the base-classes with the parameter converted
	 to their type so that we get their copy constructor and not
	 another constructor that takes current_class_type.  We must
	 deal with the binfo's directly as a direct base might be
	 inaccessible due to ambiguity.  */
      for (vbases = CLASSTYPE_VBASECLASSES (current_class_type), i = 0;
	   vec_safe_iterate (vbases, i, &binfo); i++)
	{
	  member_init_list = add_one_base_init (binfo, parm, move_p, inh,
						member_init_list);
	}

      for (binfo = TYPE_BINFO (current_class_type), i = 0;
	   BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
	{
	  if (BINFO_VIRTUAL_P (base_binfo))
	    continue;
	  member_init_list = add_one_base_init (base_binfo, parm, move_p,
						inh, member_init_list);
	}

      for (; fields; fields = DECL_CHAIN (fields))
	{
	  tree field = fields;
	  tree expr_type;

	  if (TREE_CODE (field) != FIELD_DECL)
	    continue;
	  if (inh)
	    continue;

	  expr_type = TREE_TYPE (field);
	  if (DECL_NAME (field))
	    {
	      if (VFIELD_NAME_P (DECL_NAME (field)))
		continue;
	    }
	  else if (ANON_AGGR_TYPE_P (expr_type) && TYPE_FIELDS (expr_type))
	    /* Just use the field; anonymous types can't have
	       nontrivial copy ctors or assignment ops or this
	       function would be deleted.  */;
	  else
	    continue;

	  /* Compute the type of "init->field".  If the copy-constructor
	     parameter is, for example, "const S&", and the type of
	     the field is "T", then the type will usually be "const
	     T".  (There are no cv-qualified variants of reference
	     types.)  */
	  if (TREE_CODE (expr_type) != REFERENCE_TYPE)
	    {
	      int quals = cvquals;

	      if (DECL_MUTABLE_P (field))
		quals &= ~TYPE_QUAL_CONST;
	      quals |= cp_type_quals (expr_type);
	      expr_type = cp_build_qualified_type (expr_type, quals);
	    }

	  init = build3 (COMPONENT_REF, expr_type, parm, field, NULL_TREE);
	  if (move_p && TREE_CODE (expr_type) != REFERENCE_TYPE
	      /* 'move' breaks bit-fields, and has no effect for scalars.  */
	      && !scalarish_type_p (expr_type))
	    init = move (init);
	  init = build_tree_list (NULL_TREE, init);

	  member_init_list = tree_cons (field, init, member_init_list);
	}
      finish_mem_initializers (member_init_list);
    }
}

static void
do_build_copy_assign (tree fndecl)
{
  tree parm = DECL_CHAIN (DECL_ARGUMENTS (fndecl));
  tree compound_stmt;
  bool move_p = move_fn_p (fndecl);
  bool trivial = trivial_fn_p (fndecl);
  int flags = LOOKUP_NORMAL | LOOKUP_NONVIRTUAL | LOOKUP_DEFAULTED;

  compound_stmt = begin_compound_stmt (0);
  parm = convert_from_reference (parm);

  if (trivial
      && is_empty_class (current_class_type))
    /* Don't copy the padding byte; it might not have been allocated
       if *this is a base subobject.  */;
  else if (trivial)
    {
      tree t = build2 (MODIFY_EXPR, void_type_node, current_class_ref, parm);
      finish_expr_stmt (t);
    }
  else
    {
      tree fields;
      int cvquals = cp_type_quals (TREE_TYPE (parm));
      int i;
      tree binfo, base_binfo;

      /* Assign to each of the direct base classes.  */
      for (binfo = TYPE_BINFO (current_class_type), i = 0;
	   BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
	{
	  tree converted_parm;
	  vec<tree, va_gc> *parmvec;

	  /* We must convert PARM directly to the base class
	     explicitly since the base class may be ambiguous.  */
	  converted_parm = build_base_path (PLUS_EXPR, parm, base_binfo, 1,
					    tf_warning_or_error);
	  if (move_p)
	    converted_parm = move (converted_parm);
	  /* Call the base class assignment operator.  */
	  parmvec = make_tree_vector_single (converted_parm);
	  finish_expr_stmt
	    (build_special_member_call (current_class_ref,
					ansi_assopname (NOP_EXPR),
					&parmvec,
					base_binfo,
					flags,
                                        tf_warning_or_error));
	  release_tree_vector (parmvec);
	}

      /* Assign to each of the non-static data members.  */
      for (fields = TYPE_FIELDS (current_class_type);
	   fields;
	   fields = DECL_CHAIN (fields))
	{
	  tree comp = current_class_ref;
	  tree init = parm;
	  tree field = fields;
	  tree expr_type;
	  int quals;

	  if (TREE_CODE (field) != FIELD_DECL || DECL_ARTIFICIAL (field))
	    continue;

	  expr_type = TREE_TYPE (field);

	  if (CP_TYPE_CONST_P (expr_type))
	    {
	      error ("non-static const member %q#D, can%'t use default "
		     "assignment operator", field);
	      continue;
	    }
	  else if (TREE_CODE (expr_type) == REFERENCE_TYPE)
	    {
	      error ("non-static reference member %q#D, can%'t use "
		     "default assignment operator", field);
	      continue;
	    }

	  if (DECL_NAME (field))
	    {
	      if (VFIELD_NAME_P (DECL_NAME (field)))
		continue;
	    }
	  else if (ANON_AGGR_TYPE_P (expr_type)
		   && TYPE_FIELDS (expr_type) != NULL_TREE)
	    /* Just use the field; anonymous types can't have
	       nontrivial copy ctors or assignment ops or this
	       function would be deleted.  */;
	  else
	    continue;

	  comp = build3 (COMPONENT_REF, expr_type, comp, field, NULL_TREE);

	  /* Compute the type of init->field  */
	  quals = cvquals;
	  if (DECL_MUTABLE_P (field))
	    quals &= ~TYPE_QUAL_CONST;
	  expr_type = cp_build_qualified_type (expr_type, quals);

	  init = build3 (COMPONENT_REF, expr_type, init, field, NULL_TREE);
	  if (move_p && TREE_CODE (expr_type) != REFERENCE_TYPE
	      /* 'move' breaks bit-fields, and has no effect for scalars.  */
	      && !scalarish_type_p (expr_type))
	    init = move (init);

	  if (DECL_NAME (field))
	    init = cp_build_modify_expr (comp, NOP_EXPR, init, 
					 tf_warning_or_error);
	  else
	    init = build2 (MODIFY_EXPR, TREE_TYPE (comp), comp, init);
	  finish_expr_stmt (init);
	}
    }
  finish_return_stmt (current_class_ref);
  finish_compound_stmt (compound_stmt);
}

/* Synthesize FNDECL, a non-static member function.   */

void
synthesize_method (tree fndecl)
{
  bool nested = (current_function_decl != NULL_TREE);
  tree context = decl_function_context (fndecl);
  bool need_body = true;
  tree stmt;
  location_t save_input_location = input_location;
  int error_count = errorcount;
  int warning_count = warningcount;

  /* Reset the source location, we might have been previously
     deferred, and thus have saved where we were first needed.  */
  DECL_SOURCE_LOCATION (fndecl)
    = DECL_SOURCE_LOCATION (TYPE_NAME (DECL_CONTEXT (fndecl)));

  /* If we've been asked to synthesize a clone, just synthesize the
     cloned function instead.  Doing so will automatically fill in the
     body for the clone.  */
  if (DECL_CLONED_FUNCTION_P (fndecl))
    fndecl = DECL_CLONED_FUNCTION (fndecl);

  /* We may be in the middle of deferred access check.  Disable
     it now.  */
  push_deferring_access_checks (dk_no_deferred);

  if (! context)
    push_to_top_level ();
  else if (nested)
    push_function_context ();

  input_location = DECL_SOURCE_LOCATION (fndecl);

  start_preparsed_function (fndecl, NULL_TREE, SF_DEFAULT | SF_PRE_PARSED);
  stmt = begin_function_body ();

  if (DECL_OVERLOADED_OPERATOR_P (fndecl) == NOP_EXPR)
    {
      do_build_copy_assign (fndecl);
      need_body = false;
    }
  else if (DECL_CONSTRUCTOR_P (fndecl))
    {
      tree arg_chain = FUNCTION_FIRST_USER_PARMTYPE (fndecl);
      if (arg_chain != void_list_node)
	do_build_copy_constructor (fndecl);
      else
	finish_mem_initializers (NULL_TREE);
    }

  /* If we haven't yet generated the body of the function, just
     generate an empty compound statement.  */
  if (need_body)
    {
      tree compound_stmt;
      compound_stmt = begin_compound_stmt (BCS_FN_BODY);
      finish_compound_stmt (compound_stmt);
    }

  finish_function_body (stmt);
  expand_or_defer_fn (finish_function (0));

  input_location = save_input_location;

  if (! context)
    pop_from_top_level ();
  else if (nested)
    pop_function_context ();

  pop_deferring_access_checks ();

  if (error_count != errorcount || warning_count != warningcount)
    inform (input_location, "synthesized method %qD first required here ",
	    fndecl);
}

/* Build a reference to type TYPE with cv-quals QUALS, which is an
   rvalue if RVALUE is true.  */

static tree
build_stub_type (tree type, int quals, bool rvalue)
{
  tree argtype = cp_build_qualified_type (type, quals);
  return cp_build_reference_type (argtype, rvalue);
}

/* Build a dummy glvalue from dereferencing a dummy reference of type
   REFTYPE.  */

static tree
build_stub_object (tree reftype)
{
  tree stub = build1 (NOP_EXPR, reftype, integer_one_node);
  return convert_from_reference (stub);
}

/* Determine which function will be called when looking up NAME in TYPE,
   called with a single ARGTYPE argument, or no argument if ARGTYPE is
   null.  FLAGS and COMPLAIN are as for build_new_method_call.

   Returns a FUNCTION_DECL if all is well.
   Returns NULL_TREE if overload resolution failed.
   Returns error_mark_node if the chosen function cannot be called.  */

static tree
locate_fn_flags (tree type, tree name, tree argtype, int flags,
		 tsubst_flags_t complain)
{
  tree ob, fn, fns, binfo, rval;
  vec<tree, va_gc> *args;

  if (TYPE_P (type))
    binfo = TYPE_BINFO (type);
  else
    {
      binfo = type;
      type = BINFO_TYPE (binfo);
    }

  ob = build_stub_object (cp_build_reference_type (type, false));
  args = make_tree_vector ();
  if (argtype)
    {
      if (TREE_CODE (argtype) == TREE_LIST)
	{
	  for (tree elt = argtype; elt != void_list_node;
	       elt = TREE_CHAIN (elt))
	    {
	      tree type = TREE_VALUE (elt);
	      if (TREE_CODE (type) != REFERENCE_TYPE)
		type = cp_build_reference_type (type, /*rval*/true);
	      tree arg = build_stub_object (type);
	      vec_safe_push (args, arg);
	    }
	}
      else
	{
	  tree arg = build_stub_object (argtype);
	  args->quick_push (arg);
	}
    }

  fns = lookup_fnfields (binfo, name, 0);
  rval = build_new_method_call (ob, fns, &args, binfo, flags, &fn, complain);

  release_tree_vector (args);
  if (fn && rval == error_mark_node)
    return rval;
  else
    return fn;
}

/* Locate the dtor of TYPE.  */

tree
get_dtor (tree type, tsubst_flags_t complain)
{
  tree fn = locate_fn_flags (type, complete_dtor_identifier, NULL_TREE,
			     LOOKUP_NORMAL, complain);
  if (fn == error_mark_node)
    return NULL_TREE;
  return fn;
}

/* Locate the default ctor of TYPE.  */

tree
locate_ctor (tree type)
{
  tree fn;

  push_deferring_access_checks (dk_no_check);
  fn = locate_fn_flags (type, complete_ctor_identifier, NULL_TREE,
			LOOKUP_SPECULATIVE, tf_none);
  pop_deferring_access_checks ();
  if (fn == error_mark_node)
    return NULL_TREE;
  return fn;
}

/* Likewise, but give any appropriate errors.  */

tree
get_default_ctor (tree type)
{
  tree fn = locate_fn_flags (type, complete_ctor_identifier, NULL_TREE,
			     LOOKUP_NORMAL, tf_warning_or_error);
  if (fn == error_mark_node)
    return NULL_TREE;
  return fn;
}

/* Locate the copy ctor of TYPE.  */

tree
get_copy_ctor (tree type, tsubst_flags_t complain)
{
  int quals = (TYPE_HAS_CONST_COPY_CTOR (type)
	       ? TYPE_QUAL_CONST : TYPE_UNQUALIFIED);
  tree argtype = build_stub_type (type, quals, false);
  tree fn = locate_fn_flags (type, complete_ctor_identifier, argtype,
			     LOOKUP_NORMAL, complain);
  if (fn == error_mark_node)
    return NULL_TREE;
  return fn;
}

/* Locate the copy assignment operator of TYPE.  */

tree
get_copy_assign (tree type)
{
  int quals = (TYPE_HAS_CONST_COPY_ASSIGN (type)
	       ? TYPE_QUAL_CONST : TYPE_UNQUALIFIED);
  tree argtype = build_stub_type (type, quals, false);
  tree fn = locate_fn_flags (type, ansi_assopname (NOP_EXPR), argtype,
			     LOOKUP_NORMAL, tf_warning_or_error);
  if (fn == error_mark_node)
    return NULL_TREE;
  return fn;
}

/* Subroutine of synthesized_method_walk.  Update SPEC_P, TRIVIAL_P and
   DELETED_P or give an error message MSG with argument ARG.  */

static void
process_subob_fn (tree fn, tree *spec_p, bool *trivial_p,
		  bool *deleted_p, bool *constexpr_p,
		  bool diag, tree arg)
{
  if (!fn || fn == error_mark_node)
    goto bad;

  if (spec_p)
    {
      tree raises = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn));
      *spec_p = merge_exception_specifiers (*spec_p, raises, fn);
    }

  if (!trivial_fn_p (fn))
    {
      if (trivial_p)
	*trivial_p = false;
      if (TREE_CODE (arg) == FIELD_DECL
	  && TREE_CODE (DECL_CONTEXT (arg)) == UNION_TYPE)
	{
	  if (deleted_p)
	    *deleted_p = true;
	  if (diag)
	    error ("union member %q+D with non-trivial %qD", arg, fn);
	}
    }

  if (constexpr_p && !DECL_DECLARED_CONSTEXPR_P (fn))
    {
      *constexpr_p = false;
      if (diag)
	{
	  inform (0, "defaulted constructor calls non-constexpr "
		  "%q+D", fn);
	  explain_invalid_constexpr_fn (fn);
	}
    }

  return;

 bad:
  if (deleted_p)
    *deleted_p = true;
}

/* Subroutine of synthesized_method_walk to allow recursion into anonymous
   aggregates.  */

static void
walk_field_subobs (tree fields, tree fnname, special_function_kind sfk,
		   int quals, bool copy_arg_p, bool move_p,
		   bool assign_p, tree *spec_p, bool *trivial_p,
		   bool *deleted_p, bool *constexpr_p,
		   bool diag, int flags, tsubst_flags_t complain)
{
  tree field;
  for (field = fields; field; field = DECL_CHAIN (field))
    {
      tree mem_type, argtype, rval;

      if (TREE_CODE (field) != FIELD_DECL
	  || DECL_ARTIFICIAL (field))
	continue;

      mem_type = strip_array_types (TREE_TYPE (field));
      if (assign_p)
	{
	  bool bad = true;
	  if (CP_TYPE_CONST_P (mem_type) && !CLASS_TYPE_P (mem_type))
	    {
	      if (diag)
		error ("non-static const member %q#D, can%'t use default "
		       "assignment operator", field);
	    }
	  else if (TREE_CODE (mem_type) == REFERENCE_TYPE)
	    {
	      if (diag)
		error ("non-static reference member %q#D, can%'t use "
		       "default assignment operator", field);
	    }
	  else
	    bad = false;

	  if (bad && deleted_p)
	    *deleted_p = true;
	}
      else if (sfk == sfk_constructor)
	{
	  bool bad;

	  if (DECL_INITIAL (field))
	    {
	      if (diag && DECL_INITIAL (field) == error_mark_node)
		inform (0, "initializer for %q+#D is invalid", field);
	      if (trivial_p)
		*trivial_p = false;
#if 0
	      /* Core 1351: If the field has an NSDMI that could throw, the
		 default constructor is noexcept(false).  FIXME this is
		 broken by deferred parsing and 1360 saying we can't lazily
		 declare a non-trivial default constructor.  Also this
		 needs to do deferred instantiation.  Disable until the
		 conflict between 1351 and 1360 is resolved.  */
	      if (spec_p && !expr_noexcept_p (DECL_INITIAL (field), complain))
		*spec_p = noexcept_false_spec;
#endif

	      /* Don't do the normal processing.  */
	      continue;
	    }

	  bad = false;
	  if (CP_TYPE_CONST_P (mem_type)
	      && default_init_uninitialized_part (mem_type))
	    {
	      if (diag)
		error ("uninitialized non-static const member %q#D",
		       field);
	      bad = true;
	    }
	  else if (TREE_CODE (mem_type) == REFERENCE_TYPE)
	    {
	      if (diag)
		error ("uninitialized non-static reference member %q#D",
		       field);
	      bad = true;
	    }

	  if (bad && deleted_p)
	    *deleted_p = true;

	  /* For an implicitly-defined default constructor to be constexpr,
	     every member must have a user-provided default constructor or
	     an explicit initializer.  */
	  if (constexpr_p && !CLASS_TYPE_P (mem_type)
	      && TREE_CODE (DECL_CONTEXT (field)) != UNION_TYPE)
	    {
	      *constexpr_p = false;
	      if (diag)
		inform (0, "defaulted default constructor does not "
			"initialize %q+#D", field);
	    }
	}

      if (!CLASS_TYPE_P (mem_type))
	continue;

      if (ANON_AGGR_TYPE_P (mem_type))
	{
	  walk_field_subobs (TYPE_FIELDS (mem_type), fnname, sfk, quals,
			     copy_arg_p, move_p, assign_p, spec_p, trivial_p,
			     deleted_p, constexpr_p,
			     diag, flags, complain);
	  continue;
	}

      if (copy_arg_p)
	{
	  int mem_quals = cp_type_quals (mem_type) | quals;
	  if (DECL_MUTABLE_P (field))
	    mem_quals &= ~TYPE_QUAL_CONST;
	  argtype = build_stub_type (mem_type, mem_quals, move_p);
	}
      else
	argtype = NULL_TREE;

      rval = locate_fn_flags (mem_type, fnname, argtype, flags, complain);

      process_subob_fn (rval, spec_p, trivial_p, deleted_p,
			constexpr_p, diag, field);
    }
}

/* The caller wants to generate an implicit declaration of SFK for CTYPE
   which is const if relevant and CONST_P is set.  If spec_p, trivial_p and
   deleted_p are non-null, set their referent appropriately.  If diag is
   true, we're either being called from maybe_explain_implicit_delete to
   give errors, or if constexpr_p is non-null, from
   explain_invalid_constexpr_fn.  */

static void
synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p,
			 tree *spec_p, bool *trivial_p, bool *deleted_p,
			 bool *constexpr_p, bool diag,
			 tree inherited_base, tree inherited_parms)
{
  tree binfo, base_binfo, scope, fnname, rval, argtype;
  bool move_p, copy_arg_p, assign_p, expected_trivial, check_vdtor;
  vec<tree, va_gc> *vbases;
  int i, quals, flags;
  tsubst_flags_t complain;
  bool ctor_p;

  if (spec_p)
    *spec_p = (cxx_dialect >= cxx0x ? noexcept_true_spec : empty_except_spec);

  if (deleted_p)
    {
      /* "The closure type associated with a lambda-expression has a deleted
	 default constructor and a deleted copy assignment operator."
         This is diagnosed in maybe_explain_implicit_delete.  */
      if (LAMBDA_TYPE_P (ctype)
	  && (sfk == sfk_constructor
	      || sfk == sfk_copy_assignment))
	{
	  *deleted_p = true;
	  return;
	}

      *deleted_p = false;
    }

  ctor_p = false;
  assign_p = false;
  check_vdtor = false;
  switch (sfk)
    {
    case sfk_move_assignment:
    case sfk_copy_assignment:
      assign_p = true;
      fnname = ansi_assopname (NOP_EXPR);
      break;

    case sfk_destructor:
      check_vdtor = true;
      /* The synthesized method will call base dtors, but check complete
	 here to avoid having to deal with VTT.  */
      fnname = complete_dtor_identifier;
      break;

    case sfk_constructor:
    case sfk_move_constructor:
    case sfk_copy_constructor:
    case sfk_inheriting_constructor:
      ctor_p = true;
      fnname = complete_ctor_identifier;
      break;

    default:
      gcc_unreachable ();
    }

  gcc_assert ((sfk == sfk_inheriting_constructor)
	      == (inherited_base != NULL_TREE));

  /* If that user-written default constructor would satisfy the
     requirements of a constexpr constructor (7.1.5), the
     implicitly-defined default constructor is constexpr.  */
  if (constexpr_p)
    *constexpr_p = ctor_p;

  move_p = false;
  switch (sfk)
    {
    case sfk_constructor:
    case sfk_destructor:
    case sfk_inheriting_constructor:
      copy_arg_p = false;
      break;

    case sfk_move_constructor:
    case sfk_move_assignment:
      move_p = true;
    case sfk_copy_constructor:
    case sfk_copy_assignment:
      copy_arg_p = true;
      break;

    default:
      gcc_unreachable ();
    }

  expected_trivial = type_has_trivial_fn (ctype, sfk);
  if (trivial_p)
    *trivial_p = expected_trivial;

  /* The TYPE_HAS_COMPLEX_* flags tell us about constraints from base
     class versions and other properties of the type.  But a subobject
     class can be trivially copyable and yet have overload resolution
     choose a template constructor for initialization, depending on
     rvalueness and cv-quals.  So we can't exit early for copy/move
     methods in C++0x.  The same considerations apply in C++98/03, but
     there the definition of triviality does not consider overload
     resolution, so a constructor can be trivial even if it would otherwise
     call a non-trivial constructor.  */
  if (expected_trivial
      && (!copy_arg_p || cxx_dialect < cxx0x))
    {
      if (constexpr_p && sfk == sfk_constructor)
	{
	  bool cx = trivial_default_constructor_is_constexpr (ctype);
	  *constexpr_p = cx;
	  if (diag && !cx && TREE_CODE (ctype) == UNION_TYPE)
	    /* A trivial constructor doesn't have any NSDMI.  */
	    inform (input_location, "defaulted default constructor does "
		    "not initialize any non-static data member");
	}
      if (!diag)
	return;
    }

  ++cp_unevaluated_operand;
  ++c_inhibit_evaluation_warnings;
  push_deferring_access_checks (dk_no_deferred);

  scope = push_scope (ctype);

  flags = LOOKUP_NORMAL|LOOKUP_SPECULATIVE;
  if (!inherited_base)
    flags |= LOOKUP_DEFAULTED;

  complain = diag ? tf_warning_or_error : tf_none;

  if (const_p)
    quals = TYPE_QUAL_CONST;
  else
    quals = TYPE_UNQUALIFIED;
  argtype = NULL_TREE;

  for (binfo = TYPE_BINFO (ctype), i = 0;
       BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
    {
      tree basetype = BINFO_TYPE (base_binfo);

      if (!assign_p && BINFO_VIRTUAL_P (base_binfo))
	/* We'll handle virtual bases below.  */
	continue;

      if (copy_arg_p)
	argtype = build_stub_type (basetype, quals, move_p);
      else if (basetype == inherited_base)
	argtype = inherited_parms;
      rval = locate_fn_flags (base_binfo, fnname, argtype, flags, complain);
      if (inherited_base)
	argtype = NULL_TREE;

      process_subob_fn (rval, spec_p, trivial_p, deleted_p,
			constexpr_p, diag, basetype);
      if (ctor_p && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (basetype))
	{
	  /* In a constructor we also need to check the subobject
	     destructors for cleanup of partially constructed objects.  */
	  rval = locate_fn_flags (base_binfo, complete_dtor_identifier,
				  NULL_TREE, flags, complain);
	  /* Note that we don't pass down trivial_p; the subobject
	     destructors don't affect triviality of the constructor.  Nor
	     do they affect constexpr-ness (a constant expression doesn't
	     throw) or exception-specification (a throw from one of the
	     dtors would be a double-fault).  */
	  process_subob_fn (rval, NULL, NULL,
			    deleted_p, NULL, false,
			    basetype);
	}

      if (check_vdtor && type_has_virtual_destructor (basetype))
	{
	  rval = locate_fn_flags (ctype, ansi_opname (DELETE_EXPR),
				  ptr_type_node, flags, complain);
	  /* Unlike for base ctor/op=/dtor, for operator delete it's fine
	     to have a null rval (no class-specific op delete).  */
	  if (rval && rval == error_mark_node && deleted_p)
	    *deleted_p = true;
	  check_vdtor = false;
	}

      if (diag && assign_p && move_p
	  && BINFO_VIRTUAL_P (base_binfo)
	  && rval && TREE_CODE (rval) == FUNCTION_DECL
	  && move_fn_p (rval) && !trivial_fn_p (rval)
	  && vbase_has_user_provided_move_assign (basetype))
	warning (OPT_Wvirtual_move_assign,
		 "defaulted move assignment for %qT calls a non-trivial "
		 "move assignment operator for virtual base %qT",
		 ctype, basetype);
    }

  vbases = CLASSTYPE_VBASECLASSES (ctype);
  if (vbases == NULL)
    /* No virtual bases to worry about.  */;
  else if (!assign_p)
    {
      if (constexpr_p)
	*constexpr_p = false;
      FOR_EACH_VEC_ELT (*vbases, i, base_binfo)
	{
	  tree basetype = BINFO_TYPE (base_binfo);
	  if (copy_arg_p)
	    argtype = build_stub_type (basetype, quals, move_p);
	  rval = locate_fn_flags (base_binfo, fnname, argtype, flags, complain);

	  process_subob_fn (rval, spec_p, trivial_p, deleted_p,
			    constexpr_p, diag, basetype);
	  if (ctor_p && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (basetype))
	    {
	      rval = locate_fn_flags (base_binfo, complete_dtor_identifier,
				      NULL_TREE, flags, complain);
	      process_subob_fn (rval, NULL, NULL,
				deleted_p, NULL, false,
				basetype);
	    }
	}
    }

  /* Now handle the non-static data members.  */
  walk_field_subobs (TYPE_FIELDS (ctype), fnname, sfk, quals,
		     copy_arg_p, move_p, assign_p, spec_p, trivial_p,
		     deleted_p, constexpr_p,
		     diag, flags, complain);
  if (ctor_p)
    walk_field_subobs (TYPE_FIELDS (ctype), complete_dtor_identifier,
		       sfk_destructor, TYPE_UNQUALIFIED, false,
		       false, false, NULL, NULL,
		       deleted_p, NULL,
		       false, flags, complain);

  pop_scope (scope);

  pop_deferring_access_checks ();
  --cp_unevaluated_operand;
  --c_inhibit_evaluation_warnings;
}

/* DECL is a deleted function.  If it's implicitly deleted, explain why and
   return true; else return false.  */

bool
maybe_explain_implicit_delete (tree decl)
{
  /* If decl is a clone, get the primary variant.  */
  decl = DECL_ORIGIN (decl);
  gcc_assert (DECL_DELETED_FN (decl));
  if (DECL_DEFAULTED_FN (decl))
    {
      /* Not marked GTY; it doesn't need to be GC'd or written to PCH.  */
      static struct pointer_set_t *explained;

      special_function_kind sfk;
      location_t loc;
      bool informed;
      tree ctype;

      if (!explained)
	explained = pointer_set_create ();
      if (pointer_set_insert (explained, decl))
	return true;

      sfk = special_function_p (decl);
      ctype = DECL_CONTEXT (decl);
      loc = input_location;
      input_location = DECL_SOURCE_LOCATION (decl);

      informed = false;
      if (LAMBDA_TYPE_P (ctype))
	{
	  informed = true;
	  if (sfk == sfk_constructor)
	    inform (DECL_SOURCE_LOCATION (decl),
		    "a lambda closure type has a deleted default constructor");
	  else if (sfk == sfk_copy_assignment)
	    inform (DECL_SOURCE_LOCATION (decl),
		    "a lambda closure type has a deleted copy assignment operator");
	  else
	    informed = false;
	}
      else if (DECL_ARTIFICIAL (decl)
	       && (sfk == sfk_copy_assignment
		   || sfk == sfk_copy_constructor)
	       && (type_has_user_declared_move_constructor (ctype)
		   || type_has_user_declared_move_assign (ctype)))
	{
	  inform (0, "%q+#D is implicitly declared as deleted because %qT "
		 "declares a move constructor or move assignment operator",
		 decl, ctype);
	  informed = true;
	}
      if (!informed)
	{
	  tree parms = FUNCTION_FIRST_USER_PARMTYPE (decl);
	  tree parm_type = TREE_VALUE (parms);
	  bool const_p = CP_TYPE_CONST_P (non_reference (parm_type));
	  tree scope = push_scope (ctype);
	  inform (0, "%q+#D is implicitly deleted because the default "
		 "definition would be ill-formed:", decl);
	  pop_scope (scope);
	  synthesized_method_walk (ctype, sfk, const_p,
				   NULL, NULL, NULL, NULL, true,
				   DECL_INHERITED_CTOR_BASE (decl), parms);
	}

      input_location = loc;
      return true;
    }
  return false;
}

/* DECL is a defaulted function which was declared constexpr.  Explain why
   it can't be constexpr.  */

void
explain_implicit_non_constexpr (tree decl)
{
  tree parm_type = TREE_VALUE (FUNCTION_FIRST_USER_PARMTYPE (decl));
  bool const_p = CP_TYPE_CONST_P (non_reference (parm_type));
  bool dummy;
  synthesized_method_walk (DECL_CLASS_CONTEXT (decl),
			   special_function_p (decl), const_p,
			   NULL, NULL, NULL, &dummy, true,
			   NULL_TREE, NULL_TREE);
}

/* DECL is an instantiation of an inheriting constructor template.  Deduce
   the correct exception-specification and deletedness for this particular
   specialization.  */

void
deduce_inheriting_ctor (tree decl)
{
  gcc_assert (DECL_INHERITED_CTOR_BASE (decl));
  tree spec;
  bool trivial, constexpr_, deleted;
  synthesized_method_walk (DECL_CONTEXT (decl), sfk_inheriting_constructor,
			   false, &spec, &trivial, &deleted, &constexpr_,
			   /*diag*/false,
			   DECL_INHERITED_CTOR_BASE (decl),
			   FUNCTION_FIRST_USER_PARMTYPE (decl));
  DECL_DELETED_FN (decl) = deleted;
  TREE_TYPE (decl) = build_exception_variant (TREE_TYPE (decl), spec);
}

/* Implicitly declare the special function indicated by KIND, as a
   member of TYPE.  For copy constructors and assignment operators,
   CONST_P indicates whether these functions should take a const
   reference argument or a non-const reference.  Returns the
   FUNCTION_DECL for the implicitly declared function.  */

tree
implicitly_declare_fn (special_function_kind kind, tree type,
		       bool const_p, tree inherited_ctor,
		       tree inherited_parms)
{
  tree fn;
  tree parameter_types = void_list_node;
  tree return_type;
  tree fn_type;
  tree raises = empty_except_spec;
  tree rhs_parm_type = NULL_TREE;
  tree this_parm;
  tree name;
  HOST_WIDE_INT saved_processing_template_decl;
  bool deleted_p;
  bool constexpr_p;

  /* Because we create declarations for implicitly declared functions
     lazily, we may be creating the declaration for a member of TYPE
     while in some completely different context.  However, TYPE will
     never be a dependent class (because we never want to do lookups
     for implicitly defined functions in a dependent class).
     Furthermore, we must set PROCESSING_TEMPLATE_DECL to zero here
     because we only create clones for constructors and destructors
     when not in a template.  */
  gcc_assert (!dependent_type_p (type));
  saved_processing_template_decl = processing_template_decl;
  processing_template_decl = 0;

  type = TYPE_MAIN_VARIANT (type);

  if (targetm.cxx.cdtor_returns_this () && !TYPE_FOR_JAVA (type))
    {
      if (kind == sfk_destructor)
	/* See comment in check_special_function_return_type.  */
	return_type = build_pointer_type (void_type_node);
      else
	return_type = build_pointer_type (type);
    }
  else
    return_type = void_type_node;

  switch (kind)
    {
    case sfk_destructor:
      /* Destructor.  */
      name = constructor_name (type);
      break;

    case sfk_constructor:
      /* Default constructor.  */
      name = constructor_name (type);
      break;

    case sfk_copy_constructor:
    case sfk_copy_assignment:
    case sfk_move_constructor:
    case sfk_move_assignment:
    case sfk_inheriting_constructor:
    {
      bool move_p;
      if (kind == sfk_copy_assignment
	  || kind == sfk_move_assignment)
	{
	  return_type = build_reference_type (type);
	  name = ansi_assopname (NOP_EXPR);
	}
      else
	name = constructor_name (type);

      if (kind == sfk_inheriting_constructor)
	parameter_types = inherited_parms;
      else
	{
	  if (const_p)
	    rhs_parm_type = cp_build_qualified_type (type, TYPE_QUAL_CONST);
	  else
	    rhs_parm_type = type;
	  move_p = (kind == sfk_move_assignment
		    || kind == sfk_move_constructor);
	  rhs_parm_type = cp_build_reference_type (rhs_parm_type, move_p);

	  parameter_types = tree_cons (NULL_TREE, rhs_parm_type, parameter_types);
	}
      break;
    }
    default:
      gcc_unreachable ();
    }

  tree inherited_base = (inherited_ctor
			 ? DECL_CONTEXT (inherited_ctor)
			 : NULL_TREE);
  bool trivial_p = false;

  if (inherited_ctor && TREE_CODE (inherited_ctor) == TEMPLATE_DECL)
    {
      /* For an inheriting constructor template, just copy these flags from
	 the inherited constructor template for now.  */
      raises = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (inherited_ctor));
      deleted_p = DECL_DELETED_FN (DECL_TEMPLATE_RESULT (inherited_ctor));
      constexpr_p
	= DECL_DECLARED_CONSTEXPR_P (DECL_TEMPLATE_RESULT (inherited_ctor));
    }
  else
    synthesized_method_walk (type, kind, const_p, &raises, &trivial_p,
			     &deleted_p, &constexpr_p, false,
			     inherited_base, inherited_parms);
  /* Don't bother marking a deleted constructor as constexpr.  */
  if (deleted_p)
    constexpr_p = false;
  /* A trivial copy/move constructor is also a constexpr constructor.  */
  else if (trivial_p && cxx_dialect >= cxx0x
	   && (kind == sfk_copy_constructor
	       || kind == sfk_move_constructor))
    gcc_assert (constexpr_p);

  if (!trivial_p && type_has_trivial_fn (type, kind))
    type_set_nontrivial_flag (type, kind);

  /* Create the function.  */
  fn_type = build_method_type_directly (type, return_type, parameter_types);
  if (raises)
    fn_type = build_exception_variant (fn_type, raises);
  fn = build_lang_decl (FUNCTION_DECL, name, fn_type);
  if (kind != sfk_inheriting_constructor)
    DECL_SOURCE_LOCATION (fn) = DECL_SOURCE_LOCATION (TYPE_NAME (type));
  if (kind == sfk_constructor || kind == sfk_copy_constructor
      || kind == sfk_move_constructor || kind == sfk_inheriting_constructor)
    DECL_CONSTRUCTOR_P (fn) = 1;
  else if (kind == sfk_destructor)
    DECL_DESTRUCTOR_P (fn) = 1;
  else
    {
      DECL_ASSIGNMENT_OPERATOR_P (fn) = 1;
      SET_OVERLOADED_OPERATOR_CODE (fn, NOP_EXPR);
    }
  
  /* If pointers to member functions use the least significant bit to
     indicate whether a function is virtual, ensure a pointer
     to this function will have that bit clear.  */
  if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_pfn
      && DECL_ALIGN (fn) < 2 * BITS_PER_UNIT)
    DECL_ALIGN (fn) = 2 * BITS_PER_UNIT;

  /* Create the explicit arguments.  */
  if (rhs_parm_type)
    {
      /* Note that this parameter is *not* marked DECL_ARTIFICIAL; we
	 want its type to be included in the mangled function
	 name.  */
      tree decl = cp_build_parm_decl (NULL_TREE, rhs_parm_type);
      TREE_READONLY (decl) = 1;
      retrofit_lang_decl (decl);
      DECL_PARM_INDEX (decl) = DECL_PARM_LEVEL (decl) = 1;
      DECL_ARGUMENTS (fn) = decl;
    }
  else if (kind == sfk_inheriting_constructor)
    {
      tree *p = &DECL_ARGUMENTS (fn);
      int index = 1;
      for (tree parm = inherited_parms; parm != void_list_node;
	   parm = TREE_CHAIN (parm))
	{
	  *p = cp_build_parm_decl (NULL_TREE, TREE_VALUE (parm));
	  retrofit_lang_decl (*p);
	  DECL_PARM_LEVEL (*p) = 1;
	  DECL_PARM_INDEX (*p) = index++;
	  DECL_CONTEXT (*p) = fn;
	  p = &DECL_CHAIN (*p);
	}
      SET_DECL_INHERITED_CTOR_BASE (fn, inherited_base);
      DECL_NONCONVERTING_P (fn) = DECL_NONCONVERTING_P (inherited_ctor);
      /* A constructor so declared has the same access as the corresponding
	 constructor in X.  */
      TREE_PRIVATE (fn) = TREE_PRIVATE (inherited_ctor);
      TREE_PROTECTED (fn) = TREE_PROTECTED (inherited_ctor);
      /* Copy constexpr from the inherited constructor even if the
	 inheriting constructor doesn't satisfy the requirements.  */
      constexpr_p
	= DECL_DECLARED_CONSTEXPR_P (STRIP_TEMPLATE (inherited_ctor));
    }
  /* Add the "this" parameter.  */
  this_parm = build_this_parm (fn_type, TYPE_UNQUALIFIED);
  DECL_CHAIN (this_parm) = DECL_ARGUMENTS (fn);
  DECL_ARGUMENTS (fn) = this_parm;

  grokclassfn (type, fn, kind == sfk_destructor ? DTOR_FLAG : NO_SPECIAL);
  set_linkage_according_to_type (type, fn);
  rest_of_decl_compilation (fn, toplevel_bindings_p (), at_eof);
  DECL_IN_AGGR_P (fn) = 1;
  DECL_ARTIFICIAL (fn) = 1;
  DECL_DEFAULTED_FN (fn) = 1;
  if (cxx_dialect >= cxx0x)
    {
      DECL_DELETED_FN (fn) = deleted_p;
      DECL_DECLARED_CONSTEXPR_P (fn) = constexpr_p;
    }
  DECL_EXTERNAL (fn) = true;
  DECL_NOT_REALLY_EXTERN (fn) = 1;
  DECL_DECLARED_INLINE_P (fn) = 1;
  gcc_assert (!TREE_USED (fn));

  /* Restore PROCESSING_TEMPLATE_DECL.  */
  processing_template_decl = saved_processing_template_decl;

  if (inherited_ctor && TREE_CODE (inherited_ctor) == TEMPLATE_DECL)
    fn = add_inherited_template_parms (fn, inherited_ctor);

  /* Warn about calling a non-trivial move assignment in a virtual base.  */
  if (kind == sfk_move_assignment && !deleted_p && !trivial_p
      && CLASSTYPE_VBASECLASSES (type))
    {
      location_t loc = input_location;
      input_location = DECL_SOURCE_LOCATION (fn);
      synthesized_method_walk (type, kind, const_p,
			       NULL, NULL, NULL, NULL, true,
			       NULL_TREE, NULL_TREE);
      input_location = loc;
    }

  return fn;
}

/* Gives any errors about defaulted functions which need to be deferred
   until the containing class is complete.  */

void
defaulted_late_check (tree fn)
{
  /* Complain about invalid signature for defaulted fn.  */
  tree ctx = DECL_CONTEXT (fn);
  special_function_kind kind = special_function_p (fn);
  bool fn_const_p = (copy_fn_p (fn) == 2);
  tree implicit_fn = implicitly_declare_fn (kind, ctx, fn_const_p,
					    NULL, NULL);

  if (!same_type_p (TREE_TYPE (TREE_TYPE (fn)),
		    TREE_TYPE (TREE_TYPE (implicit_fn)))
      || !compparms (TYPE_ARG_TYPES (TREE_TYPE (fn)),
		     TYPE_ARG_TYPES (TREE_TYPE (implicit_fn))))
    {
      error ("defaulted declaration %q+D", fn);
      error_at (DECL_SOURCE_LOCATION (fn),
		"does not match expected signature %qD", implicit_fn);
    }

  /* 8.4.2/2: If it is explicitly defaulted on its first declaration, it is
     implicitly considered to have the same exception-specification as if
     it had been implicitly declared.  */
  if (DECL_DEFAULTED_IN_CLASS_P (fn))
    {
      tree eh_spec = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (implicit_fn));
      if (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn)))
	{
	  maybe_instantiate_noexcept (fn);
	  if (!comp_except_specs (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn)),
				  eh_spec, ce_normal))
	    error ("function %q+D defaulted on its first declaration "
		   "with an exception-specification that differs from "
		   "the implicit declaration %q#D", fn, implicit_fn);
	}
      TREE_TYPE (fn) = build_exception_variant (TREE_TYPE (fn), eh_spec);
      if (DECL_DECLARED_CONSTEXPR_P (implicit_fn))
	{
	  /* Hmm...should we do this for out-of-class too? Should it be OK to
	     add constexpr later like inline, rather than requiring
	     declarations to match?  */
	  DECL_DECLARED_CONSTEXPR_P (fn) = true;
	  if (kind == sfk_constructor)
	    TYPE_HAS_CONSTEXPR_CTOR (ctx) = true;
	}
    }

  if (!DECL_DECLARED_CONSTEXPR_P (implicit_fn)
      && DECL_DECLARED_CONSTEXPR_P (fn))
    {
      if (!CLASSTYPE_TEMPLATE_INSTANTIATION (ctx))
	{
	  error ("explicitly defaulted function %q+D cannot be declared "
		 "as constexpr because the implicit declaration is not "
		 "constexpr:", fn);
	  explain_implicit_non_constexpr (fn);
	}
      DECL_DECLARED_CONSTEXPR_P (fn) = false;
    }

  if (DECL_DELETED_FN (implicit_fn))
    DECL_DELETED_FN (fn) = 1;
}

/* Returns true iff FN can be explicitly defaulted, and gives any
   errors if defaulting FN is ill-formed.  */

bool
defaultable_fn_check (tree fn)
{
  special_function_kind kind = sfk_none;

  if (template_parm_scope_p ())
    {
      error ("a template cannot be defaulted");
      return false;
    }

  if (DECL_CONSTRUCTOR_P (fn))
    {
      if (FUNCTION_FIRST_USER_PARMTYPE (fn) == void_list_node)
	kind = sfk_constructor;
      else if (copy_fn_p (fn) > 0
	       && (TREE_CHAIN (FUNCTION_FIRST_USER_PARMTYPE (fn))
		   == void_list_node))
	kind = sfk_copy_constructor;
      else if (move_fn_p (fn))
	kind = sfk_move_constructor;
    }
  else if (DECL_DESTRUCTOR_P (fn))
    kind = sfk_destructor;
  else if (DECL_ASSIGNMENT_OPERATOR_P (fn)
	   && DECL_OVERLOADED_OPERATOR_P (fn) == NOP_EXPR)
    {
      if (copy_fn_p (fn))
	kind = sfk_copy_assignment;
      else if (move_fn_p (fn))
	kind = sfk_move_assignment;
    }

  if (kind == sfk_none)
    {
      error ("%qD cannot be defaulted", fn);
      return false;
    }
  else
    {
      tree t = FUNCTION_FIRST_USER_PARMTYPE (fn);
      for (; t && t != void_list_node; t = TREE_CHAIN (t))
	if (TREE_PURPOSE (t))
	  {
	    error ("defaulted function %q+D with default argument", fn);
	    break;
	  }
      if (TYPE_BEING_DEFINED (DECL_CONTEXT (fn)))
	/* Defer checking.  */;
      else if (!processing_template_decl)
	defaulted_late_check (fn);

      return true;
    }
}

/* Add an implicit declaration to TYPE for the kind of function
   indicated by SFK.  Return the FUNCTION_DECL for the new implicit
   declaration.  */

tree
lazily_declare_fn (special_function_kind sfk, tree type)
{
  tree fn;
  /* Whether or not the argument has a const reference type.  */
  bool const_p = false;

  switch (sfk)
    {
    case sfk_constructor:
      CLASSTYPE_LAZY_DEFAULT_CTOR (type) = 0;
      break;
    case sfk_copy_constructor:
      const_p = TYPE_HAS_CONST_COPY_CTOR (type);
      CLASSTYPE_LAZY_COPY_CTOR (type) = 0;
      break;
    case sfk_move_constructor:
      CLASSTYPE_LAZY_MOVE_CTOR (type) = 0;
      break;
    case sfk_copy_assignment:
      const_p = TYPE_HAS_CONST_COPY_ASSIGN (type);
      CLASSTYPE_LAZY_COPY_ASSIGN (type) = 0;
      break;
    case sfk_move_assignment:
      CLASSTYPE_LAZY_MOVE_ASSIGN (type) = 0;
      break;
    case sfk_destructor:
      CLASSTYPE_LAZY_DESTRUCTOR (type) = 0;
      break;
    default:
      gcc_unreachable ();
    }

  /* Declare the function.  */
  fn = implicitly_declare_fn (sfk, type, const_p, NULL, NULL);

  /* [class.copy]/8 If the class definition declares a move constructor or
     move assignment operator, the implicitly declared copy constructor is
     defined as deleted.... */
  if ((sfk == sfk_copy_assignment
       || sfk == sfk_copy_constructor)
      && (type_has_user_declared_move_constructor (type)
	  || type_has_user_declared_move_assign (type)))
    DECL_DELETED_FN (fn) = true;

  /* A destructor may be virtual.  */
  if (sfk == sfk_destructor
      || sfk == sfk_move_assignment
      || sfk == sfk_copy_assignment)
    check_for_override (fn, type);
  /* Add it to CLASSTYPE_METHOD_VEC.  */
  add_method (type, fn, NULL_TREE);
  /* Add it to TYPE_METHODS.  */
  if (sfk == sfk_destructor
      && DECL_VIRTUAL_P (fn)
      && abi_version_at_least (2))
    /* The ABI requires that a virtual destructor go at the end of the
       vtable.  */
    TYPE_METHODS (type) = chainon (TYPE_METHODS (type), fn);
  else
    {
      /* G++ 3.2 put the implicit destructor at the *beginning* of the
	 TYPE_METHODS list, which cause the destructor to be emitted
	 in an incorrect location in the vtable.  */
      if (warn_abi && sfk == sfk_destructor && DECL_VIRTUAL_P (fn))
	warning (OPT_Wabi, "vtable layout for class %qT may not be ABI-compliant"
		 "and may change in a future version of GCC due to "
		 "implicit virtual destructor",
		 type);
      DECL_CHAIN (fn) = TYPE_METHODS (type);
      TYPE_METHODS (type) = fn;
    }
  maybe_add_class_template_decl_list (type, fn, /*friend_p=*/0);
  if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn)
      || DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn))
    /* Create appropriate clones.  */
    clone_function_decl (fn, /*update_method_vec=*/true);

  return fn;
}

/* Given a FUNCTION_DECL FN and a chain LIST, skip as many elements of LIST
   as there are artificial parms in FN.  */

tree
skip_artificial_parms_for (const_tree fn, tree list)
{
  if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn))
    list = TREE_CHAIN (list);
  else
    return list;

  if (DECL_HAS_IN_CHARGE_PARM_P (fn))
    list = TREE_CHAIN (list);
  if (DECL_HAS_VTT_PARM_P (fn))
    list = TREE_CHAIN (list);
  return list;
}

/* Given a FUNCTION_DECL FN and a chain LIST, return the number of
   artificial parms in FN.  */

int
num_artificial_parms_for (const_tree fn)
{
  int count = 0;

  if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn))
    count++;
  else
    return 0;

  if (DECL_HAS_IN_CHARGE_PARM_P (fn))
    count++;
  if (DECL_HAS_VTT_PARM_P (fn))
    count++;
  return count;
}


#include "gt-cp-method.h"
