/* Functions related to building -*- C++ -*- classes and their related objects.
   Copyright (C) 1987-2021 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/>.  */


/* High-level class interface.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "target.h"
#include "cp-tree.h"
#include "stringpool.h"
#include "cgraph.h"
#include "stor-layout.h"
#include "attribs.h"
#include "flags.h"
#include "toplev.h"
#include "convert.h"
#include "dumpfile.h"
#include "gimplify.h"
#include "intl.h"
#include "asan.h"

/* Id for dumping the class hierarchy.  */
int class_dump_id;
 
/* The number of nested classes being processed.  If we are not in the
   scope of any class, this is zero.  */

int current_class_depth;

/* In order to deal with nested classes, we keep a stack of classes.
   The topmost entry is the innermost class, and is the entry at index
   CURRENT_CLASS_DEPTH  */

typedef struct class_stack_node {
  /* The name of the class.  */
  tree name;

  /* The _TYPE node for the class.  */
  tree type;

  /* The access specifier pending for new declarations in the scope of
     this class.  */
  tree access;

  /* If were defining TYPE, the names used in this class.  */
  splay_tree names_used;

  /* Nonzero if this class is no longer open, because of a call to
     push_to_top_level.  */
  size_t hidden;
}* class_stack_node_t;

struct vtbl_init_data
{
  /* The base for which we're building initializers.  */
  tree binfo;
  /* The type of the most-derived type.  */
  tree derived;
  /* The binfo for the dynamic type. This will be TYPE_BINFO (derived),
     unless ctor_vtbl_p is true.  */
  tree rtti_binfo;
  /* The negative-index vtable initializers built up so far.  These
     are in order from least negative index to most negative index.  */
  vec<constructor_elt, va_gc> *inits;
  /* The binfo for the virtual base for which we're building
     vcall offset initializers.  */
  tree vbase;
  /* The functions in vbase for which we have already provided vcall
     offsets.  */
  vec<tree, va_gc> *fns;
  /* The vtable index of the next vcall or vbase offset.  */
  tree index;
  /* Nonzero if we are building the initializer for the primary
     vtable.  */
  int primary_vtbl_p;
  /* Nonzero if we are building the initializer for a construction
     vtable.  */
  int ctor_vtbl_p;
  /* True when adding vcall offset entries to the vtable.  False when
     merely computing the indices.  */
  bool generate_vcall_entries;
};

/* The type of a function passed to walk_subobject_offsets.  */
typedef int (*subobject_offset_fn) (tree, tree, splay_tree);

/* The stack itself.  This is a dynamically resized array.  The
   number of elements allocated is CURRENT_CLASS_STACK_SIZE.  */
static int current_class_stack_size;
static class_stack_node_t current_class_stack;

/* The size of the largest empty class seen in this translation unit.  */
static GTY (()) tree sizeof_biggest_empty_class;

static tree get_vfield_name (tree);
static void finish_struct_anon (tree);
static tree get_vtable_name (tree);
static void get_basefndecls (tree, tree, vec<tree> *);
static int build_primary_vtable (tree, tree);
static int build_secondary_vtable (tree);
static void finish_vtbls (tree);
static void modify_vtable_entry (tree, tree, tree, tree, tree *);
static void finish_struct_bits (tree);
static int alter_access (tree, tree, tree);
static void handle_using_decl (tree, tree);
static tree dfs_modify_vtables (tree, void *);
static tree modify_all_vtables (tree, tree);
static void determine_primary_bases (tree);
static void maybe_warn_about_overly_private_class (tree);
static void add_implicitly_declared_members (tree, tree*, int, int);
static tree fixed_type_or_null (tree, int *, int *);
static tree build_simple_base_path (tree expr, tree binfo);
static void build_vtbl_initializer (tree, tree, tree, tree, int *,
				    vec<constructor_elt, va_gc> **);
static bool check_bitfield_decl (tree);
static bool check_field_decl (tree, tree, int *, int *);
static void check_field_decls (tree, tree *, int *, int *);
static void build_base_fields (record_layout_info, splay_tree, tree *);
static void check_methods (tree);
static void remove_zero_width_bit_fields (tree);
static bool accessible_nvdtor_p (tree);

/* Used by find_flexarrays and related functions.  */
struct flexmems_t;
static void diagnose_flexarrays (tree, const flexmems_t *);
static void find_flexarrays (tree, flexmems_t *, bool = false,
			     tree = NULL_TREE, tree = NULL_TREE);
static void check_flexarrays (tree, flexmems_t * = NULL, bool = false);
static void check_bases (tree, int *, int *);
static void check_bases_and_members (tree);
static tree create_vtable_ptr (tree, tree *);
static void include_empty_classes (record_layout_info);
static void layout_class_type (tree, tree *);
static void propagate_binfo_offsets (tree, tree);
static void layout_virtual_bases (record_layout_info, splay_tree);
static void build_vbase_offset_vtbl_entries (tree, vtbl_init_data *);
static void add_vcall_offset_vtbl_entries_r (tree, vtbl_init_data *);
static void add_vcall_offset_vtbl_entries_1 (tree, vtbl_init_data *);
static void build_vcall_offset_vtbl_entries (tree, vtbl_init_data *);
static void add_vcall_offset (tree, tree, vtbl_init_data *);
static void layout_vtable_decl (tree, int);
static tree dfs_find_final_overrider_pre (tree, void *);
static tree dfs_find_final_overrider_post (tree, void *);
static tree find_final_overrider (tree, tree, tree);
static int make_new_vtable (tree, tree);
static tree get_primary_binfo (tree);
static int maybe_indent_hierarchy (FILE *, int, int);
static tree dump_class_hierarchy_r (FILE *, dump_flags_t, tree, tree, int);
static void dump_class_hierarchy (tree);
static void dump_class_hierarchy_1 (FILE *, dump_flags_t, tree);
static void dump_array (FILE *, tree);
static void dump_vtable (tree, tree, tree);
static void dump_vtt (tree, tree);
static void dump_thunk (FILE *, int, tree);
static tree build_vtable (tree, tree, tree);
static void initialize_vtable (tree, vec<constructor_elt, va_gc> *);
static void layout_nonempty_base_or_field (record_layout_info,
					   tree, tree, splay_tree);
static void accumulate_vtbl_inits (tree, tree, tree, tree, tree,
				   vec<constructor_elt, va_gc> **);
static void dfs_accumulate_vtbl_inits (tree, tree, tree, tree, tree,
				       vec<constructor_elt, va_gc> **);
static void build_rtti_vtbl_entries (tree, vtbl_init_data *);
static void build_vcall_and_vbase_vtbl_entries (tree, vtbl_init_data *);
static void clone_constructors_and_destructors (tree);
static void update_vtable_entry_for_fn (tree, tree, tree, tree *, unsigned);
static void build_ctor_vtbl_group (tree, tree);
static void build_vtt (tree);
static tree binfo_ctor_vtable (tree);
static void build_vtt_inits (tree, tree, vec<constructor_elt, va_gc> **,
			     tree *);
static tree dfs_build_secondary_vptr_vtt_inits (tree, void *);
static tree dfs_fixup_binfo_vtbls (tree, void *);
static int record_subobject_offset (tree, tree, splay_tree);
static int check_subobject_offset (tree, tree, splay_tree);
static int walk_subobject_offsets (tree, subobject_offset_fn,
				   tree, splay_tree, tree, int);
static int layout_conflict_p (tree, tree, splay_tree, int);
static int splay_tree_compare_integer_csts (splay_tree_key k1,
					    splay_tree_key k2);
static void maybe_warn_about_inaccessible_bases (tree);
static bool type_requires_array_cookie (tree);
static bool base_derived_from (tree, tree);
static int empty_base_at_nonzero_offset_p (tree, tree, splay_tree);
static tree end_of_base (tree);
static tree get_vcall_index (tree, tree);
static bool type_maybe_constexpr_default_constructor (tree);
static bool type_maybe_constexpr_destructor (tree);
static bool field_poverlapping_p (tree);

/* Set CURRENT_ACCESS_SPECIFIER based on the protection of DECL.  */

void
set_current_access_from_decl (tree decl)
{
  if (TREE_PRIVATE (decl))
    current_access_specifier = access_private_node;
  else if (TREE_PROTECTED (decl))
    current_access_specifier = access_protected_node;
  else
    current_access_specifier = access_public_node;
}

/* Return a COND_EXPR that executes TRUE_STMT if this execution of the
   'structor is in charge of 'structing virtual bases, or FALSE_STMT
   otherwise.  */

tree
build_if_in_charge (tree true_stmt, tree false_stmt)
{
  gcc_assert (DECL_HAS_IN_CHARGE_PARM_P (current_function_decl));
  tree cmp = build2 (NE_EXPR, boolean_type_node,
		     current_in_charge_parm, integer_zero_node);
  tree type = unlowered_expr_type (true_stmt);
  if (VOID_TYPE_P (type))
    type = unlowered_expr_type (false_stmt);
  tree cond = build3 (COND_EXPR, type,
		      cmp, true_stmt, false_stmt);
  return cond;
}

/* Convert to or from a base subobject.  EXPR is an expression of type
   `A' or `A*', an expression of type `B' or `B*' is returned.  To
   convert A to a base B, CODE is PLUS_EXPR and BINFO is the binfo for
   the B base instance within A.  To convert base A to derived B, CODE
   is MINUS_EXPR and BINFO is the binfo for the A instance within B.
   In this latter case, A must not be a morally virtual base of B.
   NONNULL is true if EXPR is known to be non-NULL (this is only
   needed when EXPR is of pointer type).  CV qualifiers are preserved
   from EXPR.  */

tree
build_base_path (enum tree_code code,
		 tree expr,
		 tree binfo,
		 int nonnull,
		 tsubst_flags_t complain)
{
  tree v_binfo = NULL_TREE;
  tree d_binfo = NULL_TREE;
  tree probe;
  tree offset;
  tree target_type;
  tree null_test = NULL;
  tree ptr_target_type;
  int fixed_type_p;
  int want_pointer = TYPE_PTR_P (TREE_TYPE (expr));
  bool has_empty = false;
  bool virtual_access;
  bool rvalue = false;

  if (expr == error_mark_node || binfo == error_mark_node || !binfo)
    return error_mark_node;

  for (probe = binfo; probe; probe = BINFO_INHERITANCE_CHAIN (probe))
    {
      d_binfo = probe;
      if (is_empty_class (BINFO_TYPE (probe)))
	has_empty = true;
      if (!v_binfo && BINFO_VIRTUAL_P (probe))
	v_binfo = probe;
    }

  probe = TYPE_MAIN_VARIANT (TREE_TYPE (expr));
  if (want_pointer)
    probe = TYPE_MAIN_VARIANT (TREE_TYPE (probe));
  if (dependent_type_p (probe))
    if (tree open = currently_open_class (probe))
      probe = open;

  if (code == PLUS_EXPR
      && !SAME_BINFO_TYPE_P (BINFO_TYPE (d_binfo), probe))
    {
      /* This can happen when adjust_result_of_qualified_name_lookup can't
	 find a unique base binfo in a call to a member function.  We
	 couldn't give the diagnostic then since we might have been calling
	 a static member function, so we do it now.  In other cases, eg.
	 during error recovery (c++/71979), we may not have a base at all.  */
      if (complain & tf_error)
	{
	  tree base = lookup_base (probe, BINFO_TYPE (d_binfo),
				   ba_unique, NULL, complain);
	  gcc_assert (base == error_mark_node || !base);
	}
      return error_mark_node;
    }

  gcc_assert ((code == MINUS_EXPR
	       && SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), probe))
	      || code == PLUS_EXPR);

  if (binfo == d_binfo)
    /* Nothing to do.  */
    return expr;

  if (code == MINUS_EXPR && v_binfo)
    {
      if (complain & tf_error)
	{
	  if (SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), BINFO_TYPE (v_binfo)))
	    {
	      if (want_pointer)
		error ("cannot convert from pointer to base class %qT to "
		       "pointer to derived class %qT because the base is "
		       "virtual", BINFO_TYPE (binfo), BINFO_TYPE (d_binfo));
	      else
		error ("cannot convert from base class %qT to derived "
		       "class %qT because the base is virtual",
		       BINFO_TYPE (binfo), BINFO_TYPE (d_binfo));
	    }	      
	  else
	    {
	      if (want_pointer)
		error ("cannot convert from pointer to base class %qT to "
		       "pointer to derived class %qT via virtual base %qT",
		       BINFO_TYPE (binfo), BINFO_TYPE (d_binfo),
		       BINFO_TYPE (v_binfo));
	      else
		error ("cannot convert from base class %qT to derived "
		       "class %qT via virtual base %qT", BINFO_TYPE (binfo),
		       BINFO_TYPE (d_binfo), BINFO_TYPE (v_binfo));
	    }
	}
      return error_mark_node;
    }

  bool uneval = (cp_unevaluated_operand != 0
		 || processing_template_decl
		 || in_template_function ());

  /* For a non-pointer simple base reference, express it as a COMPONENT_REF
     without taking its address (and so causing lambda capture, 91933).  */
  if (code == PLUS_EXPR && !v_binfo && !want_pointer && !has_empty && !uneval)
    return build_simple_base_path (expr, binfo);

  if (!want_pointer)
    {
      rvalue = !lvalue_p (expr);
      /* This must happen before the call to save_expr.  */
      expr = cp_build_addr_expr (expr, complain);
    }
  else
    expr = mark_rvalue_use (expr);

  offset = BINFO_OFFSET (binfo);
  fixed_type_p = resolves_to_fixed_type_p (expr, &nonnull);
  target_type = code == PLUS_EXPR ? BINFO_TYPE (binfo) : BINFO_TYPE (d_binfo);
  /* TARGET_TYPE has been extracted from BINFO, and, is therefore always
     cv-unqualified.  Extract the cv-qualifiers from EXPR so that the
     expression returned matches the input.  */
  target_type = cp_build_qualified_type
    (target_type, cp_type_quals (TREE_TYPE (TREE_TYPE (expr))));
  ptr_target_type = build_pointer_type (target_type);

  /* Do we need to look in the vtable for the real offset?  */
  virtual_access = (v_binfo && fixed_type_p <= 0);

  /* Don't bother with the calculations inside sizeof; they'll ICE if the
     source type is incomplete and the pointer value doesn't matter.  In a
     template (even in instantiate_non_dependent_expr), we don't have vtables
     set up properly yet, and the value doesn't matter there either; we're
     just interested in the result of overload resolution.  */
  if (uneval)
    {
      expr = build_nop (ptr_target_type, expr);
      goto indout;
    }

  if (!COMPLETE_TYPE_P (probe))
    {
      if (complain & tf_error)
	error ("cannot convert from %qT to base class %qT because %qT is "
	       "incomplete", BINFO_TYPE (d_binfo), BINFO_TYPE (binfo),
	       BINFO_TYPE (d_binfo));
      return error_mark_node;
    }

  /* If we're in an NSDMI, we don't have the full constructor context yet
     that we need for converting to a virtual base, so just build a stub
     CONVERT_EXPR and expand it later in bot_replace.  */
  if (virtual_access && fixed_type_p < 0
      && current_scope () != current_function_decl)
    {
      expr = build1 (CONVERT_EXPR, ptr_target_type, expr);
      CONVERT_EXPR_VBASE_PATH (expr) = true;
      goto indout;
    }

  /* Do we need to check for a null pointer?  */
  if (want_pointer && !nonnull)
    {
      /* If we know the conversion will not actually change the value
	 of EXPR, then we can avoid testing the expression for NULL.
	 We have to avoid generating a COMPONENT_REF for a base class
	 field, because other parts of the compiler know that such
	 expressions are always non-NULL.  */
      if (!virtual_access && integer_zerop (offset))
	return build_nop (ptr_target_type, expr);
      null_test = error_mark_node;
    }

  /* Protect against multiple evaluation if necessary.  */
  if (TREE_SIDE_EFFECTS (expr) && (null_test || virtual_access))
    expr = save_expr (expr);

  /* Store EXPR and build the real null test just before returning.  */
  if (null_test)
    null_test = expr;

  /* If this is a simple base reference, express it as a COMPONENT_REF.  */
  if (code == PLUS_EXPR && !virtual_access
      /* We don't build base fields for empty bases, and they aren't very
	 interesting to the optimizers anyway.  */
      && !has_empty)
    {
      expr = cp_build_fold_indirect_ref (expr);
      expr = build_simple_base_path (expr, binfo);
      if (rvalue && lvalue_p (expr))
	expr = move (expr);
      if (want_pointer)
	expr = build_address (expr);
      target_type = TREE_TYPE (expr);
      goto out;
    }

  if (virtual_access)
    {
      /* Going via virtual base V_BINFO.  We need the static offset
	 from V_BINFO to BINFO, and the dynamic offset from D_BINFO to
	 V_BINFO.  That offset is an entry in D_BINFO's vtable.  */
      tree v_offset;

      if (fixed_type_p < 0 && in_base_initializer)
	{
	  /* In a base member initializer, we cannot rely on the
	     vtable being set up.  We have to indirect via the
	     vtt_parm.  */
	  tree t;

	  t = TREE_TYPE (TYPE_VFIELD (current_class_type));
	  t = build_pointer_type (t);
	  v_offset = fold_convert (t, current_vtt_parm);
	  v_offset = cp_build_fold_indirect_ref (v_offset);
	}
      else
	{
	  tree t = expr;
	  if (sanitize_flags_p (SANITIZE_VPTR)
	      && fixed_type_p == 0)
	    {
	      t = cp_ubsan_maybe_instrument_cast_to_vbase (input_location,
							   probe, expr);
	      if (t == NULL_TREE)
		t = expr;
	    }
	  v_offset = build_vfield_ref (cp_build_fold_indirect_ref (t),
	  TREE_TYPE (TREE_TYPE (expr)));
	}

      if (v_offset == error_mark_node)
	return error_mark_node;

      v_offset = fold_build_pointer_plus (v_offset, BINFO_VPTR_FIELD (v_binfo));
      v_offset = build1 (NOP_EXPR,
			 build_pointer_type (ptrdiff_type_node),
			 v_offset);
      v_offset = cp_build_fold_indirect_ref (v_offset);
      TREE_CONSTANT (v_offset) = 1;

      offset = convert_to_integer (ptrdiff_type_node,
				   size_diffop_loc (input_location, offset,
						BINFO_OFFSET (v_binfo)));

      if (!integer_zerop (offset))
	v_offset = build2 (code, ptrdiff_type_node, v_offset, offset);

      if (fixed_type_p < 0)
	/* Negative fixed_type_p means this is a constructor or destructor;
	   virtual base layout is fixed in in-charge [cd]tors, but not in
	   base [cd]tors.  */
	offset = build_if_in_charge
	  (convert_to_integer (ptrdiff_type_node, BINFO_OFFSET (binfo)),
	   v_offset);
      else
	offset = v_offset;
    }

  if (want_pointer)
    target_type = ptr_target_type;

  if (!integer_zerop (offset))
    {
      offset = fold_convert (sizetype, offset);
      if (code == MINUS_EXPR)
	offset = fold_build1_loc (input_location, NEGATE_EXPR, sizetype, offset);
      expr = fold_build_pointer_plus (expr, offset);
    }
  else
    null_test = NULL;

  expr = build1 (NOP_EXPR, ptr_target_type, expr);

 indout:
  if (!want_pointer)
    {
      expr = cp_build_fold_indirect_ref (expr);
      if (rvalue)
	expr = move (expr);
    }

 out:
  if (null_test)
    /* Wrap EXPR in a null test.  */
    expr = build_if_nonnull (null_test, expr, complain);

  return expr;
}

/* Subroutine of build_base_path; EXPR and BINFO are as in that function.
   Perform a derived-to-base conversion by recursively building up a
   sequence of COMPONENT_REFs to the appropriate base fields.  */

static tree
build_simple_base_path (tree expr, tree binfo)
{
  tree type = BINFO_TYPE (binfo);
  tree d_binfo = BINFO_INHERITANCE_CHAIN (binfo);
  tree field;

  if (d_binfo == NULL_TREE)
    {
      tree temp;

      gcc_assert (TYPE_MAIN_VARIANT (TREE_TYPE (expr)) == type);

      /* Transform `(a, b).x' into `(*(a, &b)).x', `(a ? b : c).x'
	 into `(*(a ?  &b : &c)).x', and so on.  A COND_EXPR is only
	 an lvalue in the front end; only _DECLs and _REFs are lvalues
	 in the back end.  */
      temp = unary_complex_lvalue (ADDR_EXPR, expr);
      if (temp)
	expr = cp_build_fold_indirect_ref (temp);

      return expr;
    }

  /* Recurse.  */
  expr = build_simple_base_path (expr, d_binfo);

  for (field = TYPE_FIELDS (BINFO_TYPE (d_binfo));
       field; field = DECL_CHAIN (field))
    /* Is this the base field created by build_base_field?  */
    if (TREE_CODE (field) == FIELD_DECL
	&& DECL_FIELD_IS_BASE (field)
	&& TREE_TYPE (field) == type
	/* If we're looking for a field in the most-derived class,
	   also check the field offset; we can have two base fields
	   of the same type if one is an indirect virtual base and one
	   is a direct non-virtual base.  */
	&& (BINFO_INHERITANCE_CHAIN (d_binfo)
	    || tree_int_cst_equal (byte_position (field),
				   BINFO_OFFSET (binfo))))
      {
	/* We don't use build_class_member_access_expr here, as that
	   has unnecessary checks, and more importantly results in
	   recursive calls to dfs_walk_once.  */
	int type_quals = cp_type_quals (TREE_TYPE (expr));

	expr = build3 (COMPONENT_REF,
		       cp_build_qualified_type (type, type_quals),
		       expr, field, NULL_TREE);
	/* Mark the expression const or volatile, as appropriate.
	   Even though we've dealt with the type above, we still have
	   to mark the expression itself.  */
	if (type_quals & TYPE_QUAL_CONST)
	  TREE_READONLY (expr) = 1;
	if (type_quals & TYPE_QUAL_VOLATILE)
	  TREE_THIS_VOLATILE (expr) = 1;

	return expr;
      }

  /* Didn't find the base field?!?  */
  gcc_unreachable ();
}

/* Convert OBJECT to the base TYPE.  OBJECT is an expression whose
   type is a class type or a pointer to a class type.  In the former
   case, TYPE is also a class type; in the latter it is another
   pointer type.  If CHECK_ACCESS is true, an error message is emitted
   if TYPE is inaccessible.  If OBJECT has pointer type, the value is
   assumed to be non-NULL.  */

tree
convert_to_base (tree object, tree type, bool check_access, bool nonnull,
		 tsubst_flags_t complain)
{
  tree binfo;
  tree object_type;

  if (TYPE_PTR_P (TREE_TYPE (object)))
    {
      object_type = TREE_TYPE (TREE_TYPE (object));
      type = TREE_TYPE (type);
    }
  else
    object_type = TREE_TYPE (object);

  binfo = lookup_base (object_type, type, check_access ? ba_check : ba_unique,
		       NULL, complain);
  if (!binfo || binfo == error_mark_node)
    return error_mark_node;

  return build_base_path (PLUS_EXPR, object, binfo, nonnull, complain);
}

/* EXPR is an expression with unqualified class type.  BASE is a base
   binfo of that class type.  Returns EXPR, converted to the BASE
   type.  This function assumes that EXPR is the most derived class;
   therefore virtual bases can be found at their static offsets.  */

tree
convert_to_base_statically (tree expr, tree base)
{
  tree expr_type;

  expr_type = TREE_TYPE (expr);
  if (!SAME_BINFO_TYPE_P (BINFO_TYPE (base), expr_type))
    {
      /* If this is a non-empty base, use a COMPONENT_REF.  */
      if (!is_empty_class (BINFO_TYPE (base)))
	return build_simple_base_path (expr, base);

      /* We use fold_build2 and fold_convert below to simplify the trees
	 provided to the optimizers.  It is not safe to call these functions
	 when processing a template because they do not handle C++-specific
	 trees.  */
      gcc_assert (!processing_template_decl);
      expr = cp_build_addr_expr (expr, tf_warning_or_error);
      if (!integer_zerop (BINFO_OFFSET (base)))
        expr = fold_build_pointer_plus_loc (input_location,
					    expr, BINFO_OFFSET (base));
      expr = fold_convert (build_pointer_type (BINFO_TYPE (base)), expr);
      expr = build_fold_indirect_ref_loc (input_location, expr);
    }

  return expr;
}

/* True IFF EXPR is a reference to an empty base class "subobject", as built in
   convert_to_base_statically.  We look for the result of the fold_convert
   call, a NOP_EXPR from one pointer type to another, where the target is an
   empty base of the original type.  */

bool
is_empty_base_ref (tree expr)
{
  if (TREE_CODE (expr) == INDIRECT_REF)
    expr = TREE_OPERAND (expr, 0);
  if (TREE_CODE (expr) != NOP_EXPR)
    return false;
  tree type = TREE_TYPE (expr);
  if (!POINTER_TYPE_P (type))
    return false;
  type = TREE_TYPE (type);
  if (!is_empty_class (type))
    return false;
  STRIP_NOPS (expr);
  tree fromtype = TREE_TYPE (expr);
  if (!POINTER_TYPE_P (fromtype))
    return false;
  fromtype = TREE_TYPE (fromtype);
  return (CLASS_TYPE_P (fromtype)
	  && !same_type_ignoring_top_level_qualifiers_p (fromtype, type)
	  && DERIVED_FROM_P (type, fromtype));
}

tree
build_vfield_ref (tree datum, tree type)
{
  tree vfield, vcontext;

  if (datum == error_mark_node
      /* Can happen in case of duplicate base types (c++/59082).  */
      || !TYPE_VFIELD (type))
    return error_mark_node;

  /* First, convert to the requested type.  */
  if (!same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (datum), type))
    datum = convert_to_base (datum, type, /*check_access=*/false,
			     /*nonnull=*/true, tf_warning_or_error);

  /* Second, the requested type may not be the owner of its own vptr.
     If not, convert to the base class that owns it.  We cannot use
     convert_to_base here, because VCONTEXT may appear more than once
     in the inheritance hierarchy of TYPE, and thus direct conversion
     between the types may be ambiguous.  Following the path back up
     one step at a time via primary bases avoids the problem.  */
  vfield = TYPE_VFIELD (type);
  vcontext = DECL_CONTEXT (vfield);
  while (!same_type_ignoring_top_level_qualifiers_p (vcontext, type))
    {
      datum = build_simple_base_path (datum, CLASSTYPE_PRIMARY_BINFO (type));
      type = TREE_TYPE (datum);
    }

  return build3 (COMPONENT_REF, TREE_TYPE (vfield), datum, vfield, NULL_TREE);
}

/* Given an object INSTANCE, return an expression which yields the
   vtable element corresponding to INDEX.  There are many special
   cases for INSTANCE which we take care of here, mainly to avoid
   creating extra tree nodes when we don't have to.  */

tree
build_vtbl_ref (tree instance, tree idx)
{
  tree aref;
  tree vtbl = NULL_TREE;

  /* Try to figure out what a reference refers to, and
     access its virtual function table directly.  */

  int cdtorp = 0;
  tree fixed_type = fixed_type_or_null (instance, NULL, &cdtorp);

  tree basetype = non_reference (TREE_TYPE (instance));

  if (fixed_type && !cdtorp)
    {
      tree binfo = lookup_base (fixed_type, basetype,
				ba_unique, NULL, tf_none);
      if (binfo && binfo != error_mark_node)
	vtbl = unshare_expr (BINFO_VTABLE (binfo));
    }

  if (!vtbl)
    vtbl = build_vfield_ref (instance, basetype);

  aref = build_array_ref (input_location, vtbl, idx);
  TREE_CONSTANT (aref) |= TREE_CONSTANT (vtbl) && TREE_CONSTANT (idx);

  return aref;
}

/* Given a stable object pointer INSTANCE_PTR, return an expression which
   yields a function pointer corresponding to vtable element INDEX.  */

tree
build_vfn_ref (tree instance_ptr, tree idx)
{
  tree aref;

  aref = build_vtbl_ref (cp_build_fold_indirect_ref (instance_ptr), idx);

  /* When using function descriptors, the address of the
     vtable entry is treated as a function pointer.  */
  if (TARGET_VTABLE_USES_DESCRIPTORS)
    aref = build1 (NOP_EXPR, TREE_TYPE (aref),
		   cp_build_addr_expr (aref, tf_warning_or_error));

  /* Remember this as a method reference, for later devirtualization.  */
  aref = build3 (OBJ_TYPE_REF, TREE_TYPE (aref), aref, instance_ptr, idx);

  return aref;
}

/* Return the name of the virtual function table (as an IDENTIFIER_NODE)
   for the given TYPE.  */

static tree
get_vtable_name (tree type)
{
  return mangle_vtbl_for_type (type);
}

/* DECL is an entity associated with TYPE, like a virtual table or an
   implicitly generated constructor.  Determine whether or not DECL
   should have external or internal linkage at the object file
   level.  This routine does not deal with COMDAT linkage and other
   similar complexities; it simply sets TREE_PUBLIC if it possible for
   entities in other translation units to contain copies of DECL, in
   the abstract.  */

void
set_linkage_according_to_type (tree /*type*/, tree decl)
{
  TREE_PUBLIC (decl) = 1;
  determine_visibility (decl);
}

/* Create a VAR_DECL for a primary or secondary vtable for CLASS_TYPE.
   (For a secondary vtable for B-in-D, CLASS_TYPE should be D, not B.)
   Use NAME for the name of the vtable, and VTABLE_TYPE for its type.  */

static tree
build_vtable (tree class_type, tree name, tree vtable_type)
{
  tree decl;

  decl = build_lang_decl (VAR_DECL, name, vtable_type);
  /* vtable names are already mangled; give them their DECL_ASSEMBLER_NAME
     now to avoid confusion in mangle_decl.  */
  SET_DECL_ASSEMBLER_NAME (decl, name);
  DECL_CONTEXT (decl) = class_type;
  DECL_ARTIFICIAL (decl) = 1;
  TREE_STATIC (decl) = 1;
  TREE_READONLY (decl) = 1;
  DECL_VIRTUAL_P (decl) = 1;
  SET_DECL_ALIGN (decl, TARGET_VTABLE_ENTRY_ALIGN);
  DECL_USER_ALIGN (decl) = true;
  DECL_VTABLE_OR_VTT_P (decl) = 1;
  set_linkage_according_to_type (class_type, decl);
  /* The vtable has not been defined -- yet.  */
  DECL_EXTERNAL (decl) = 1;
  DECL_NOT_REALLY_EXTERN (decl) = 1;

  /* Mark the VAR_DECL node representing the vtable itself as a
     "gratuitous" one, thereby forcing dwarfout.c to ignore it.  It
     is rather important that such things be ignored because any
     effort to actually generate DWARF for them will run into
     trouble when/if we encounter code like:

     #pragma interface
     struct S { virtual void member (); };

     because the artificial declaration of the vtable itself (as
     manufactured by the g++ front end) will say that the vtable is
     a static member of `S' but only *after* the debug output for
     the definition of `S' has already been output.  This causes
     grief because the DWARF entry for the definition of the vtable
     will try to refer back to an earlier *declaration* of the
     vtable as a static member of `S' and there won't be one.  We
     might be able to arrange to have the "vtable static member"
     attached to the member list for `S' before the debug info for
     `S' get written (which would solve the problem) but that would
     require more intrusive changes to the g++ front end.  */
  DECL_IGNORED_P (decl) = 1;

  return decl;
}

/* Get the VAR_DECL of the vtable for TYPE. TYPE need not be polymorphic,
   or even complete.  If this does not exist, create it.  If COMPLETE is
   nonzero, then complete the definition of it -- that will render it
   impossible to actually build the vtable, but is useful to get at those
   which are known to exist in the runtime.  */

tree
get_vtable_decl (tree type, int complete)
{
  tree decl;

  if (CLASSTYPE_VTABLES (type))
    return CLASSTYPE_VTABLES (type);

  decl = build_vtable (type, get_vtable_name (type), vtbl_type_node);
  CLASSTYPE_VTABLES (type) = decl;

  if (complete)
    {
      DECL_EXTERNAL (decl) = 1;
      cp_finish_decl (decl, NULL_TREE, false, NULL_TREE, 0);
    }

  return decl;
}

/* Build the primary virtual function table for TYPE.  If BINFO is
   non-NULL, build the vtable starting with the initial approximation
   that it is the same as the one which is the head of the association
   list.  Returns a nonzero value if a new vtable is actually
   created.  */

static int
build_primary_vtable (tree binfo, tree type)
{
  tree decl;
  tree virtuals;

  decl = get_vtable_decl (type, /*complete=*/0);

  if (binfo)
    {
      if (BINFO_NEW_VTABLE_MARKED (binfo))
	/* We have already created a vtable for this base, so there's
	   no need to do it again.  */
	return 0;

      virtuals = copy_list (BINFO_VIRTUALS (binfo));
      TREE_TYPE (decl) = TREE_TYPE (get_vtbl_decl_for_binfo (binfo));
      DECL_SIZE (decl) = TYPE_SIZE (TREE_TYPE (decl));
      DECL_SIZE_UNIT (decl) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
    }
  else
    {
      gcc_assert (TREE_TYPE (decl) == vtbl_type_node);
      virtuals = NULL_TREE;
    }

  /* Initialize the association list for this type, based
     on our first approximation.  */
  BINFO_VTABLE (TYPE_BINFO (type)) = decl;
  BINFO_VIRTUALS (TYPE_BINFO (type)) = virtuals;
  SET_BINFO_NEW_VTABLE_MARKED (TYPE_BINFO (type));
  return 1;
}

/* Give BINFO a new virtual function table which is initialized
   with a skeleton-copy of its original initialization.  The only
   entry that changes is the `delta' entry, so we can really
   share a lot of structure.

   FOR_TYPE is the most derived type which caused this table to
   be needed.

   Returns nonzero if we haven't met BINFO before.

   The order in which vtables are built (by calling this function) for
   an object must remain the same, otherwise a binary incompatibility
   can result.  */

static int
build_secondary_vtable (tree binfo)
{
  if (BINFO_NEW_VTABLE_MARKED (binfo))
    /* We already created a vtable for this base.  There's no need to
       do it again.  */
    return 0;

  /* Remember that we've created a vtable for this BINFO, so that we
     don't try to do so again.  */
  SET_BINFO_NEW_VTABLE_MARKED (binfo);

  /* Make fresh virtual list, so we can smash it later.  */
  BINFO_VIRTUALS (binfo) = copy_list (BINFO_VIRTUALS (binfo));

  /* Secondary vtables are laid out as part of the same structure as
     the primary vtable.  */
  BINFO_VTABLE (binfo) = NULL_TREE;
  return 1;
}

/* Create a new vtable for BINFO which is the hierarchy dominated by
   T. Return nonzero if we actually created a new vtable.  */

static int
make_new_vtable (tree t, tree binfo)
{
  if (binfo == TYPE_BINFO (t))
    /* In this case, it is *type*'s vtable we are modifying.  We start
       with the approximation that its vtable is that of the
       immediate base class.  */
    return build_primary_vtable (binfo, t);
  else
    /* This is our very own copy of `basetype' to play with.  Later,
       we will fill in all the virtual functions that override the
       virtual functions in these base classes which are not defined
       by the current type.  */
    return build_secondary_vtable (binfo);
}

/* Make *VIRTUALS, an entry on the BINFO_VIRTUALS list for BINFO
   (which is in the hierarchy dominated by T) list FNDECL as its
   BV_FN.  DELTA is the required constant adjustment from the `this'
   pointer where the vtable entry appears to the `this' required when
   the function is actually called.  */

static void
modify_vtable_entry (tree t,
		     tree binfo,
		     tree fndecl,
		     tree delta,
		     tree *virtuals)
{
  tree v;

  v = *virtuals;

  if (fndecl != BV_FN (v)
      || !tree_int_cst_equal (delta, BV_DELTA (v)))
    {
      /* We need a new vtable for BINFO.  */
      if (make_new_vtable (t, binfo))
	{
	  /* If we really did make a new vtable, we also made a copy
	     of the BINFO_VIRTUALS list.  Now, we have to find the
	     corresponding entry in that list.  */
	  *virtuals = BINFO_VIRTUALS (binfo);
	  while (BV_FN (*virtuals) != BV_FN (v))
	    *virtuals = TREE_CHAIN (*virtuals);
	  v = *virtuals;
	}

      BV_DELTA (v) = delta;
      BV_VCALL_INDEX (v) = NULL_TREE;
      BV_FN (v) = fndecl;
    }
}


/* Add method METHOD to class TYPE.  If VIA_USING indicates whether
   METHOD is being injected via a using_decl.  Returns true if the
   method could be added to the method vec.  */

bool
add_method (tree type, tree method, bool via_using)
{
  if (method == error_mark_node)
    return false;

  gcc_assert (!DECL_EXTERN_C_P (method));

  tree *slot = find_member_slot (type, DECL_NAME (method));
  tree current_fns = slot ? *slot : NULL_TREE;

  /* See below.  */
  int losem = -1;

  /* Check to see if we've already got this method.  */
  for (ovl_iterator iter (current_fns); iter; ++iter)
    {
      tree fn = *iter;

      if (TREE_CODE (fn) != TREE_CODE (method))
	continue;

      /* Two using-declarations can coexist, we'll complain about ambiguity in
	 overload resolution.  */
      if (via_using && iter.using_p ()
	  /* Except handle inherited constructors specially.  */
	  && ! DECL_CONSTRUCTOR_P (fn))
	continue;

      /* [over.load] Member function declarations with the
	 same name and the same parameter types cannot be
	 overloaded if any of them is a static member
	 function declaration.

	 [over.load] Member function declarations with the same name and
	 the same parameter-type-list as well as member function template
	 declarations with the same name, the same parameter-type-list, and
	 the same template parameter lists cannot be overloaded if any of
	 them, but not all, have a ref-qualifier.

	 [namespace.udecl] When a using-declaration brings names
	 from a base class into a derived class scope, member
	 functions in the derived class override and/or hide member
	 functions with the same name and parameter types in a base
	 class (rather than conflicting).  */
      tree fn_type = TREE_TYPE (fn);
      tree method_type = TREE_TYPE (method);

      /* Compare the quals on the 'this' parm.  Don't compare
	 the whole types, as used functions are treated as
	 coming from the using class in overload resolution.  */
      if (! DECL_STATIC_FUNCTION_P (fn)
	  && ! DECL_STATIC_FUNCTION_P (method)
	  /* Either both or neither need to be ref-qualified for
	     differing quals to allow overloading.  */
	  && (FUNCTION_REF_QUALIFIED (fn_type)
	      == FUNCTION_REF_QUALIFIED (method_type))
	  && (type_memfn_quals (fn_type) != type_memfn_quals (method_type)
	      || type_memfn_rqual (fn_type) != type_memfn_rqual (method_type)))
	  continue;

      tree real_fn = fn;
      tree real_method = method;

      /* Templates and conversion ops must match return types.  */
      if ((DECL_CONV_FN_P (fn) || TREE_CODE (fn) == TEMPLATE_DECL)
	  && !same_type_p (TREE_TYPE (fn_type), TREE_TYPE (method_type)))
	continue;
      
      /* For templates, the template parameters must be identical.  */
      if (TREE_CODE (fn) == TEMPLATE_DECL)
	{
	  if (!comp_template_parms (DECL_TEMPLATE_PARMS (fn),
				    DECL_TEMPLATE_PARMS (method)))
	    continue;

	  real_fn = DECL_TEMPLATE_RESULT (fn);
	  real_method = DECL_TEMPLATE_RESULT (method);
	}

      tree parms1 = TYPE_ARG_TYPES (fn_type);
      tree parms2 = TYPE_ARG_TYPES (method_type);
      if (! DECL_STATIC_FUNCTION_P (real_fn))
	parms1 = TREE_CHAIN (parms1);
      if (! DECL_STATIC_FUNCTION_P (real_method))
	parms2 = TREE_CHAIN (parms2);

      /* Bring back parameters omitted from an inherited ctor.  The
	 method and the function can have different omittedness.  */
      if (ctor_omit_inherited_parms (real_fn))
	parms1 = FUNCTION_FIRST_USER_PARMTYPE (DECL_CLONED_FUNCTION (real_fn));
      if (ctor_omit_inherited_parms (real_method))
	parms2 = (FUNCTION_FIRST_USER_PARMTYPE
		  (DECL_CLONED_FUNCTION (real_method)));

      if (!compparms (parms1, parms2))
	continue;

      if (!equivalently_constrained (fn, method))
	{
	  if (processing_template_decl)
	    /* We can't check satisfaction in dependent context, wait until
	       the class is instantiated.  */
	    continue;

	  special_function_kind sfk = special_memfn_p (method);

	  if (sfk == sfk_none
	      || DECL_INHERITED_CTOR (fn)
	      || TREE_CODE (fn) == TEMPLATE_DECL)
	    /* Member function templates and non-special member functions
	       coexist if they are not equivalently constrained.  A member
	       function is not hidden by an inherited constructor.  */
	    continue;

	  /* P0848: For special member functions, deleted, unsatisfied, or
	     less constrained overloads are ineligible.  We implement this
	     by removing them from CLASSTYPE_MEMBER_VEC.  Destructors don't
	     use the notion of eligibility, and the selected destructor can
	     be deleted, but removing unsatisfied or less constrained
	     overloads has the same effect as overload resolution.  */
	  bool dtor = (sfk == sfk_destructor);
	  if (losem == -1)
	    losem = ((!dtor && DECL_DELETED_FN (method))
		     || !constraints_satisfied_p (method));
	  bool losef = ((!dtor && DECL_DELETED_FN (fn))
			|| !constraints_satisfied_p (fn));
	  int win;
	  if (losem || losef)
	    win = losem - losef;
	  else
	    win = more_constrained (fn, method);
	  if (win > 0)
	    /* Leave FN in the method vec, discard METHOD.  */
	    return false;
	  else if (win < 0)
	    {
	      /* Remove FN, add METHOD.  */
	      current_fns = iter.remove_node (current_fns);
	      continue;
	    }
	  else
	    /* Let them coexist for now.  */
	    continue;
	}

      /* If these are versions of the same function, process and
	 move on.  */
      if (TREE_CODE (fn) == FUNCTION_DECL
	  && maybe_version_functions (method, fn, true))
	continue;

      if (DECL_INHERITED_CTOR (method))
	{
	  if (!DECL_INHERITED_CTOR (fn))
	    /* Defer to the other function.  */
	    return false;
	    
	  tree basem = DECL_INHERITED_CTOR_BASE (method);
	  tree basef = DECL_INHERITED_CTOR_BASE (fn);
	  if (flag_new_inheriting_ctors)
	    {
	      if (basem == basef)
		{
		  /* Inheriting the same constructor along different
		     paths, combine them.  */
		  SET_DECL_INHERITED_CTOR
		    (fn, ovl_make (DECL_INHERITED_CTOR (method),
				   DECL_INHERITED_CTOR (fn)));
		  /* And discard the new one.  */
		  return false;
		}
	      else
		/* Inherited ctors can coexist until overload
		   resolution.  */
		continue;
	    }

	  error_at (DECL_SOURCE_LOCATION (method),
		    "%q#D conflicts with version inherited from %qT",
		    method, basef);
	  inform (DECL_SOURCE_LOCATION (fn),
		  "version inherited from %qT declared here",
		  basef);
	  return false;
	}

      if (via_using)
	/* Defer to the local function.  */
	return false;
      else if (flag_new_inheriting_ctors
	       && DECL_INHERITED_CTOR (fn))
	{
	  /* Remove the inherited constructor.  */
	  current_fns = iter.remove_node (current_fns);
	  continue;
	}
      else
	{
	  error_at (DECL_SOURCE_LOCATION (method),
		    "%q#D cannot be overloaded with %q#D", method, fn);
	  inform (DECL_SOURCE_LOCATION (fn),
		  "previous declaration %q#D", fn);
	  return false;
	}
    }

  current_fns = ovl_insert (method, current_fns, via_using);

  if (!COMPLETE_TYPE_P (type) && !DECL_CONV_FN_P (method)
      && !push_class_level_binding (DECL_NAME (method), current_fns))
    return false;

  if (!slot)
    slot = add_member_slot (type, DECL_NAME (method));

  /* Maintain TYPE_HAS_USER_CONSTRUCTOR, etc.  */
  grok_special_member_properties (method);

  *slot = current_fns;

  return true;
}

/* Subroutines of finish_struct.  */

/* Change the access of FDECL to ACCESS in T.  Return 1 if change was
   legit, otherwise return 0.  */

static int
alter_access (tree t, tree fdecl, tree access)
{
  tree elem;

  retrofit_lang_decl (fdecl);

  gcc_assert (!DECL_DISCRIMINATOR_P (fdecl));

  elem = purpose_member (t, DECL_ACCESS (fdecl));
  if (elem)
    {
      if (TREE_VALUE (elem) != access)
	{
	  if (TREE_CODE (TREE_TYPE (fdecl)) == FUNCTION_DECL)
	    error ("conflicting access specifications for method"
		   " %q+D, ignored", TREE_TYPE (fdecl));
	  else
	    error ("conflicting access specifications for field %qE, ignored",
		   DECL_NAME (fdecl));
	}
      else
	{
	  /* They're changing the access to the same thing they changed
	     it to before.  That's OK.  */
	  ;
	}
    }
  else
    {
      perform_or_defer_access_check (TYPE_BINFO (t), fdecl, fdecl,
				     tf_warning_or_error);
      DECL_ACCESS (fdecl) = tree_cons (t, access, DECL_ACCESS (fdecl));
      return 1;
    }
  return 0;
}

/* Return the access node for DECL's access in its enclosing class.  */

tree
declared_access (tree decl)
{
  return (TREE_PRIVATE (decl) ? access_private_node
	  : TREE_PROTECTED (decl) ? access_protected_node
	  : access_public_node);
}

/* Process the USING_DECL, which is a member of T.  */

static void
handle_using_decl (tree using_decl, tree t)
{
  tree decl = USING_DECL_DECLS (using_decl);
  tree name = DECL_NAME (using_decl);
  tree access = declared_access (using_decl);
  tree flist = NULL_TREE;
  tree old_value;

  gcc_assert (!processing_template_decl && decl);

  old_value = lookup_member (t, name, /*protect=*/0, /*want_type=*/false,
			     tf_warning_or_error);
  if (old_value)
    {
      old_value = OVL_FIRST (old_value);

      if (DECL_P (old_value) && DECL_CONTEXT (old_value) == t)
	/* OK */;
      else
	old_value = NULL_TREE;
    }

  cp_emit_debug_info_for_using (decl, t);

  if (is_overloaded_fn (decl))
    flist = decl;

  if (! old_value)
    ;
  else if (is_overloaded_fn (old_value))
    {
      if (flist)
	/* It's OK to use functions from a base when there are functions with
	   the same name already present in the current class.  */;
      else
	{
	  error_at (DECL_SOURCE_LOCATION (using_decl), "%qD invalid in %q#T "
		    "because of local method %q#D with same name",
		    using_decl, t, old_value);
	  inform (DECL_SOURCE_LOCATION (old_value),
		  "local method %q#D declared here", old_value);
	  return;
	}
    }
  else if (!DECL_ARTIFICIAL (old_value))
    {
      error_at (DECL_SOURCE_LOCATION (using_decl), "%qD invalid in %q#T "
		"because of local member %q#D with same name",
		using_decl, t, old_value);
      inform (DECL_SOURCE_LOCATION (old_value),
	      "local member %q#D declared here", old_value);
      return;
    }

  iloc_sentinel ils (DECL_SOURCE_LOCATION (using_decl));

  /* Make type T see field decl FDECL with access ACCESS.  */
  if (flist)
    for (tree f : ovl_range (flist))
      {
	add_method (t, f, true);
	alter_access (t, f, access);
      }
  else if (USING_DECL_UNRELATED_P (using_decl))
    {
      /* C++20 using enum can import non-inherited enumerators into class
	 scope.  We implement that by making a copy of the CONST_DECL for which
	 CONST_DECL_USING_P is true.  */
      gcc_assert (TREE_CODE (decl) == CONST_DECL);

      auto cas = make_temp_override (current_access_specifier);
      set_current_access_from_decl (using_decl);
      tree copy = copy_decl (decl);
      DECL_CONTEXT (copy) = t;
      DECL_ARTIFICIAL (copy) = true;
      /* We emitted debug info for the USING_DECL above; make sure we don't
	 also emit anything for this clone.  */
      DECL_IGNORED_P (copy) = true;
      DECL_SOURCE_LOCATION (copy) = DECL_SOURCE_LOCATION (using_decl);
      finish_member_declaration (copy);
      DECL_ABSTRACT_ORIGIN (copy) = decl;
    }
  else
    alter_access (t, decl, access);
}

/* Data structure for find_abi_tags_r, below.  */

struct abi_tag_data
{
  tree t;		// The type that we're checking for missing tags.
  tree subob;		// The subobject of T that we're getting tags from.
  tree tags; // error_mark_node for diagnostics, or a list of missing tags.
};

/* Subroutine of find_abi_tags_r. Handle a single TAG found on the class TP
   in the context of P.  TAG can be either an identifier (the DECL_NAME of
   a tag NAMESPACE_DECL) or a STRING_CST (a tag attribute).  */

static void
check_tag (tree tag, tree id, tree *tp, abi_tag_data *p)
{
  if (!IDENTIFIER_MARKED (id))
    {
      if (p->tags != error_mark_node)
	{
	  /* We're collecting tags from template arguments or from
	     the type of a variable or function return type.  */
	  p->tags = tree_cons (NULL_TREE, tag, p->tags);

	  /* Don't inherit this tag multiple times.  */
	  IDENTIFIER_MARKED (id) = true;

	  if (TYPE_P (p->t))
	    {
	      /* Tags inherited from type template arguments are only used
		 to avoid warnings.  */
	      ABI_TAG_IMPLICIT (p->tags) = true;
	      return;
	    }
	  /* For functions and variables we want to warn, too.  */
	}

      /* Otherwise we're diagnosing missing tags.  */
      if (TREE_CODE (p->t) == FUNCTION_DECL)
	{
	  auto_diagnostic_group d;
	  if (warning (OPT_Wabi_tag, "%qD inherits the %E ABI tag "
		       "that %qT (used in its return type) has",
		       p->t, tag, *tp))
	    inform (location_of (*tp), "%qT declared here", *tp);
	}
      else if (VAR_P (p->t))
	{
	  auto_diagnostic_group d;
	  if (warning (OPT_Wabi_tag, "%qD inherits the %E ABI tag "
		       "that %qT (used in its type) has", p->t, tag, *tp))
	    inform (location_of (*tp), "%qT declared here", *tp);
	}
      else if (TYPE_P (p->subob))
	{
	  auto_diagnostic_group d;
	  if (warning (OPT_Wabi_tag, "%qT does not have the %E ABI tag "
		       "that base %qT has", p->t, tag, p->subob))
	    inform (location_of (p->subob), "%qT declared here",
		    p->subob);
	}
      else
	{
	  auto_diagnostic_group d;
	  if (warning (OPT_Wabi_tag, "%qT does not have the %E ABI tag "
		       "that %qT (used in the type of %qD) has",
		       p->t, tag, *tp, p->subob))
	    {
	      inform (location_of (p->subob), "%qD declared here",
		      p->subob);
	      inform (location_of (*tp), "%qT declared here", *tp);
	    }
	}
    }
}

/* Find all the ABI tags in the attribute list ATTR and either call
   check_tag (if TP is non-null) or set IDENTIFIER_MARKED to val.  */

static void
mark_or_check_attr_tags (tree attr, tree *tp, abi_tag_data *p, bool val)
{
  if (!attr)
    return;
  for (; (attr = lookup_attribute ("abi_tag", attr));
       attr = TREE_CHAIN (attr))
    for (tree list = TREE_VALUE (attr); list;
	 list = TREE_CHAIN (list))
      {
	tree tag = TREE_VALUE (list);
	tree id = get_identifier (TREE_STRING_POINTER (tag));
	if (tp)
	  check_tag (tag, id, tp, p);
	else
	  IDENTIFIER_MARKED (id) = val;
      }
}

/* Find all the ABI tags on T and its enclosing scopes and either call
   check_tag (if TP is non-null) or set IDENTIFIER_MARKED to val.  */

static void
mark_or_check_tags (tree t, tree *tp, abi_tag_data *p, bool val)
{
  while (t != global_namespace)
    {
      tree attr;
      if (TYPE_P (t))
	{
	  attr = TYPE_ATTRIBUTES (t);
	  t = CP_TYPE_CONTEXT (t);
	}
      else
	{
	  attr = DECL_ATTRIBUTES (t);
	  t = CP_DECL_CONTEXT (t);
	}
      mark_or_check_attr_tags (attr, tp, p, val);
    }
}

/* walk_tree callback for check_abi_tags: if the type at *TP involves any
   types with ABI tags, add the corresponding identifiers to the VEC in
   *DATA and set IDENTIFIER_MARKED.  */

static tree
find_abi_tags_r (tree *tp, int *walk_subtrees, void *data)
{
  if (TYPE_P (*tp) && *walk_subtrees == 1 && flag_abi_version != 14)
    /* Tell cp_walk_subtrees to look though typedefs. [PR98481] */
    *walk_subtrees = 2;

  if (!OVERLOAD_TYPE_P (*tp))
    return NULL_TREE;

  /* walk_tree shouldn't be walking into any subtrees of a RECORD_TYPE
     anyway, but let's make sure of it.  */
  *walk_subtrees = false;

  abi_tag_data *p = static_cast<struct abi_tag_data*>(data);

  mark_or_check_tags (*tp, tp, p, false);

  return NULL_TREE;
}

/* walk_tree callback for mark_abi_tags: if *TP is a class, set
   IDENTIFIER_MARKED on its ABI tags.  */

static tree
mark_abi_tags_r (tree *tp, int *walk_subtrees, void *data)
{
  if (TYPE_P (*tp) && *walk_subtrees == 1 && flag_abi_version != 14)
    /* Tell cp_walk_subtrees to look though typedefs.  */
    *walk_subtrees = 2;

  if (!OVERLOAD_TYPE_P (*tp))
    return NULL_TREE;

  /* walk_tree shouldn't be walking into any subtrees of a RECORD_TYPE
     anyway, but let's make sure of it.  */
  *walk_subtrees = false;

  bool *valp = static_cast<bool*>(data);

  mark_or_check_tags (*tp, NULL, NULL, *valp);

  return NULL_TREE;
}

/* Set IDENTIFIER_MARKED on all the ABI tags on T and its enclosing
   scopes.  */

static void
mark_abi_tags (tree t, bool val)
{
  mark_or_check_tags (t, NULL, NULL, val);
  if (DECL_P (t))
    {
      if (DECL_LANG_SPECIFIC (t) && DECL_USE_TEMPLATE (t)
	  && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (t)))
	{
	  /* Template arguments are part of the signature.  */
	  tree level = INNERMOST_TEMPLATE_ARGS (DECL_TI_ARGS (t));
	  for (int j = 0; j < TREE_VEC_LENGTH (level); ++j)
	    {
	      tree arg = TREE_VEC_ELT (level, j);
	      cp_walk_tree_without_duplicates (&arg, mark_abi_tags_r, &val);
	    }
	}
      if (TREE_CODE (t) == FUNCTION_DECL)
	/* A function's parameter types are part of the signature, so
	   we don't need to inherit any tags that are also in them.  */
	for (tree arg = FUNCTION_FIRST_USER_PARMTYPE (t); arg;
	     arg = TREE_CHAIN (arg))
	  cp_walk_tree_without_duplicates (&TREE_VALUE (arg),
					   mark_abi_tags_r, &val);
    }
}

/* Check that T has all the ABI tags that subobject SUBOB has, or
   warn if not.  If T is a (variable or function) declaration, also
   return any missing tags, and add them to T if JUST_CHECKING is false.  */

static tree
check_abi_tags (tree t, tree subob, bool just_checking = false)
{
  bool inherit = DECL_P (t);

  if (!inherit && !warn_abi_tag)
    return NULL_TREE;

  tree decl = TYPE_P (t) ? TYPE_NAME (t) : t;
  if (!TREE_PUBLIC (decl))
    /* No need to worry about things local to this TU.  */
    return NULL_TREE;

  mark_abi_tags (t, true);

  tree subtype = TYPE_P (subob) ? subob : TREE_TYPE (subob);
  struct abi_tag_data data = { t, subob, error_mark_node };
  if (inherit)
    data.tags = NULL_TREE;

  cp_walk_tree_without_duplicates (&subtype, find_abi_tags_r, &data);

  if (!(inherit && data.tags))
    /* We don't need to do anything with data.tags.  */;
  else if (just_checking)
    for (tree t = data.tags; t; t = TREE_CHAIN (t))
      {
	tree id = get_identifier (TREE_STRING_POINTER (TREE_VALUE (t)));
	IDENTIFIER_MARKED (id) = false;
      }
  else
    {
      tree attr = lookup_attribute ("abi_tag", DECL_ATTRIBUTES (t));
      if (attr)
	TREE_VALUE (attr) = chainon (data.tags, TREE_VALUE (attr));
      else
	DECL_ATTRIBUTES (t)
	  = tree_cons (abi_tag_identifier, data.tags, DECL_ATTRIBUTES (t));
    }

  mark_abi_tags (t, false);

  return data.tags;
}

/* Check that DECL has all the ABI tags that are used in parts of its type
   that are not reflected in its mangled name.  */

void
check_abi_tags (tree decl)
{
  if (VAR_P (decl))
    check_abi_tags (decl, TREE_TYPE (decl));
  else if (TREE_CODE (decl) == FUNCTION_DECL
	   && !DECL_CONV_FN_P (decl)
	   && !mangle_return_type_p (decl))
    check_abi_tags (decl, TREE_TYPE (TREE_TYPE (decl)));
}

/* Return any ABI tags that are used in parts of the type of DECL
   that are not reflected in its mangled name.  This function is only
   used in backward-compatible mangling for ABI <11.  */

tree
missing_abi_tags (tree decl)
{
  if (VAR_P (decl))
    return check_abi_tags (decl, TREE_TYPE (decl), true);
  else if (TREE_CODE (decl) == FUNCTION_DECL
	   /* Don't check DECL_CONV_FN_P here like we do in check_abi_tags, so
	      that we can use this function for setting need_abi_warning
	      regardless of the current flag_abi_version.  */
	   && !mangle_return_type_p (decl))
    return check_abi_tags (decl, TREE_TYPE (TREE_TYPE (decl)), true);
  else
    return NULL_TREE;
}

void
inherit_targ_abi_tags (tree t)
{
  if (!CLASS_TYPE_P (t)
      || CLASSTYPE_TEMPLATE_INFO (t) == NULL_TREE)
    return;

  mark_abi_tags (t, true);

  tree args = CLASSTYPE_TI_ARGS (t);
  struct abi_tag_data data = { t, NULL_TREE, NULL_TREE };
  for (int i = 0; i < TMPL_ARGS_DEPTH (args); ++i)
    {
      tree level = TMPL_ARGS_LEVEL (args, i+1);
      for (int j = 0; j < TREE_VEC_LENGTH (level); ++j)
	{
	  tree arg = TREE_VEC_ELT (level, j);
	  data.subob = arg;
	  cp_walk_tree_without_duplicates (&arg, find_abi_tags_r, &data);
	}
    }

  // If we found some tags on our template arguments, add them to our
  // abi_tag attribute.
  if (data.tags)
    {
      tree attr = lookup_attribute ("abi_tag", TYPE_ATTRIBUTES (t));
      if (attr)
	TREE_VALUE (attr) = chainon (data.tags, TREE_VALUE (attr));
      else
	TYPE_ATTRIBUTES (t)
	  = tree_cons (abi_tag_identifier, data.tags, TYPE_ATTRIBUTES (t));
    }

  mark_abi_tags (t, false);
}

/* Return true, iff class T has a non-virtual destructor that is
   accessible from outside the class heirarchy (i.e. is public, or
   there's a suitable friend.  */

static bool
accessible_nvdtor_p (tree t)
{
  tree dtor = CLASSTYPE_DESTRUCTOR (t);

  /* An implicitly declared destructor is always public.  And,
     if it were virtual, we would have created it by now.  */
  if (!dtor)
    return true;

  if (DECL_VINDEX (dtor))
    return false; /* Virtual */
  
  if (!TREE_PRIVATE (dtor) && !TREE_PROTECTED (dtor))
    return true;  /* Public */

  if (CLASSTYPE_FRIEND_CLASSES (t)
      || DECL_FRIENDLIST (TYPE_MAIN_DECL (t)))
    return true;   /* Has friends */

  return false;
}

/* Run through the base classes of T, updating CANT_HAVE_CONST_CTOR_P,
   and NO_CONST_ASN_REF_P.  Also set flag bits in T based on
   properties of the bases.  */

static void
check_bases (tree t,
	     int* cant_have_const_ctor_p,
	     int* no_const_asn_ref_p)
{
  int i;
  bool seen_non_virtual_nearly_empty_base_p = 0;
  int seen_tm_mask = 0;
  tree base_binfo;
  tree binfo;
  tree field = NULL_TREE;

  if (!CLASSTYPE_NON_STD_LAYOUT (t))
    for (field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field))
      if (TREE_CODE (field) == FIELD_DECL)
	break;

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

      gcc_assert (COMPLETE_TYPE_P (basetype));

      if (CLASSTYPE_FINAL (basetype))
        error ("cannot derive from %<final%> base %qT in derived type %qT",
               basetype, t);

      /* If any base class is non-literal, so is the derived class.  */
      if (!CLASSTYPE_LITERAL_P (basetype))
        CLASSTYPE_LITERAL_P (t) = false;

      /* If the base class doesn't have copy constructors or
	 assignment operators that take const references, then the
	 derived class cannot have such a member automatically
	 generated.  */
      if (TYPE_HAS_COPY_CTOR (basetype)
	  && ! TYPE_HAS_CONST_COPY_CTOR (basetype))
	*cant_have_const_ctor_p = 1;
      if (TYPE_HAS_COPY_ASSIGN (basetype)
	  && !TYPE_HAS_CONST_COPY_ASSIGN (basetype))
	*no_const_asn_ref_p = 1;

      if (BINFO_VIRTUAL_P (base_binfo))
	/* A virtual base does not effect nearly emptiness.  */
	;
      else if (CLASSTYPE_NEARLY_EMPTY_P (basetype))
	{
	  if (seen_non_virtual_nearly_empty_base_p)
	    /* And if there is more than one nearly empty base, then the
	       derived class is not nearly empty either.  */
	    CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
	  else
	    /* Remember we've seen one.  */
	    seen_non_virtual_nearly_empty_base_p = 1;
	}
      else if (!is_empty_class (basetype))
	/* If the base class is not empty or nearly empty, then this
	   class cannot be nearly empty.  */
	CLASSTYPE_NEARLY_EMPTY_P (t) = 0;

      /* A lot of properties from the bases also apply to the derived
	 class.  */
      TYPE_NEEDS_CONSTRUCTING (t) |= TYPE_NEEDS_CONSTRUCTING (basetype);
      TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t)
	|= TYPE_HAS_NONTRIVIAL_DESTRUCTOR (basetype);
      TYPE_HAS_COMPLEX_COPY_ASSIGN (t)
	|= (TYPE_HAS_COMPLEX_COPY_ASSIGN (basetype)
	    || !TYPE_HAS_COPY_ASSIGN (basetype));
      TYPE_HAS_COMPLEX_COPY_CTOR (t) |= (TYPE_HAS_COMPLEX_COPY_CTOR (basetype)
					 || !TYPE_HAS_COPY_CTOR (basetype));
      TYPE_HAS_COMPLEX_MOVE_ASSIGN (t)
	|= TYPE_HAS_COMPLEX_MOVE_ASSIGN (basetype);
      TYPE_HAS_COMPLEX_MOVE_CTOR (t) |= TYPE_HAS_COMPLEX_MOVE_CTOR (basetype);
      TYPE_POLYMORPHIC_P (t) |= TYPE_POLYMORPHIC_P (basetype);
      CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t)
	|= CLASSTYPE_CONTAINS_EMPTY_CLASS_P (basetype);
      TYPE_HAS_COMPLEX_DFLT (t) |= (!TYPE_HAS_DEFAULT_CONSTRUCTOR (basetype)
				    || TYPE_HAS_COMPLEX_DFLT (basetype));
      SET_CLASSTYPE_READONLY_FIELDS_NEED_INIT
	(t, CLASSTYPE_READONLY_FIELDS_NEED_INIT (t)
	 | CLASSTYPE_READONLY_FIELDS_NEED_INIT (basetype));
      SET_CLASSTYPE_REF_FIELDS_NEED_INIT
	(t, CLASSTYPE_REF_FIELDS_NEED_INIT (t)
	 | CLASSTYPE_REF_FIELDS_NEED_INIT (basetype));
      if (TYPE_HAS_MUTABLE_P (basetype))
	CLASSTYPE_HAS_MUTABLE (t) = 1;

      /*  A standard-layout class is a class that:
	  ...
	  * has no non-standard-layout base classes,  */
      CLASSTYPE_NON_STD_LAYOUT (t) |= CLASSTYPE_NON_STD_LAYOUT (basetype);
      if (!CLASSTYPE_NON_STD_LAYOUT (t))
	{
	  tree basefield;
	  /* ...has no base classes of the same type as the first non-static
	     data member...  */
	  if (field && DECL_CONTEXT (field) == t
	      && (same_type_ignoring_top_level_qualifiers_p
		  (TREE_TYPE (field), basetype)))
	    CLASSTYPE_NON_STD_LAYOUT (t) = 1;
	  /* DR 1813:
	     ...has at most one base class subobject of any given type...  */
	  else if (CLASSTYPE_REPEATED_BASE_P (t))
	    CLASSTYPE_NON_STD_LAYOUT (t) = 1;
	  else
	    /* ...has all non-static data members and bit-fields in the class
	       and its base classes first declared in the same class.  */
	    for (basefield = TYPE_FIELDS (basetype); basefield;
		 basefield = DECL_CHAIN (basefield))
	      if (TREE_CODE (basefield) == FIELD_DECL
		  && !(DECL_FIELD_IS_BASE (basefield)
		       && is_empty_field (basefield)))
		{
		  if (field)
		    CLASSTYPE_NON_STD_LAYOUT (t) = 1;
		  else
		    field = basefield;
		  break;
		}
	}

      /* Don't bother collecting tm attributes if transactional memory
	 support is not enabled.  */
      if (flag_tm)
	{
	  tree tm_attr = find_tm_attribute (TYPE_ATTRIBUTES (basetype));
	  if (tm_attr)
	    seen_tm_mask |= tm_attr_to_mask (tm_attr);
	}

      check_abi_tags (t, basetype);
    }

  /* If one of the base classes had TM attributes, and the current class
     doesn't define its own, then the current class inherits one.  */
  if (seen_tm_mask && !find_tm_attribute (TYPE_ATTRIBUTES (t)))
    {
      tree tm_attr = tm_mask_to_attr (least_bit_hwi (seen_tm_mask));
      TYPE_ATTRIBUTES (t) = tree_cons (tm_attr, NULL, TYPE_ATTRIBUTES (t));
    }
}

/* Determine all the primary bases within T.  Sets BINFO_PRIMARY_BASE_P for
   those that are primaries.  Sets BINFO_LOST_PRIMARY_P for those
   that have had a nearly-empty virtual primary base stolen by some
   other base in the hierarchy.  Determines CLASSTYPE_PRIMARY_BASE for
   T.  */

static void
determine_primary_bases (tree t)
{
  unsigned i;
  tree primary = NULL_TREE;
  tree type_binfo = TYPE_BINFO (t);
  tree base_binfo;

  /* Determine the primary bases of our bases.  */
  for (base_binfo = TREE_CHAIN (type_binfo); base_binfo;
       base_binfo = TREE_CHAIN (base_binfo))
    {
      tree primary = CLASSTYPE_PRIMARY_BINFO (BINFO_TYPE (base_binfo));

      /* See if we're the non-virtual primary of our inheritance
	 chain.  */
      if (!BINFO_VIRTUAL_P (base_binfo))
	{
	  tree parent = BINFO_INHERITANCE_CHAIN (base_binfo);
	  tree parent_primary = CLASSTYPE_PRIMARY_BINFO (BINFO_TYPE (parent));

	  if (parent_primary
	      && SAME_BINFO_TYPE_P (BINFO_TYPE (base_binfo),
				    BINFO_TYPE (parent_primary)))
	    /* We are the primary binfo.  */
	    BINFO_PRIMARY_P (base_binfo) = 1;
	}
      /* Determine if we have a virtual primary base, and mark it so.
       */
      if (primary && BINFO_VIRTUAL_P (primary))
	{
	  tree this_primary = copied_binfo (primary, base_binfo);

	  if (BINFO_PRIMARY_P (this_primary))
	    /* Someone already claimed this base.  */
	    BINFO_LOST_PRIMARY_P (base_binfo) = 1;
	  else
	    {
	      tree delta;

	      BINFO_PRIMARY_P (this_primary) = 1;
	      BINFO_INHERITANCE_CHAIN (this_primary) = base_binfo;

	      /* A virtual binfo might have been copied from within
		 another hierarchy. As we're about to use it as a
		 primary base, make sure the offsets match.  */
	      delta = size_diffop_loc (input_location,
				   fold_convert (ssizetype,
					    BINFO_OFFSET (base_binfo)),
				   fold_convert (ssizetype,
					    BINFO_OFFSET (this_primary)));

	      propagate_binfo_offsets (this_primary, delta);
	    }
	}
    }

  /* First look for a dynamic direct non-virtual base.  */
  for (i = 0; BINFO_BASE_ITERATE (type_binfo, i, base_binfo); i++)
    {
      tree basetype = BINFO_TYPE (base_binfo);

      if (TYPE_CONTAINS_VPTR_P (basetype) && !BINFO_VIRTUAL_P (base_binfo))
	{
	  primary = base_binfo;
	  goto found;
	}
    }

  /* A "nearly-empty" virtual base class can be the primary base
     class, if no non-virtual polymorphic base can be found.  Look for
     a nearly-empty virtual dynamic base that is not already a primary
     base of something in the hierarchy.  If there is no such base,
     just pick the first nearly-empty virtual base.  */

  for (base_binfo = TREE_CHAIN (type_binfo); base_binfo;
       base_binfo = TREE_CHAIN (base_binfo))
    if (BINFO_VIRTUAL_P (base_binfo)
	&& CLASSTYPE_NEARLY_EMPTY_P (BINFO_TYPE (base_binfo)))
      {
	if (!BINFO_PRIMARY_P (base_binfo))
	  {
	    /* Found one that is not primary.  */
	    primary = base_binfo;
	    goto found;
	  }
	else if (!primary)
	  /* Remember the first candidate.  */
	  primary = base_binfo;
      }

 found:
  /* If we've got a primary base, use it.  */
  if (primary)
    {
      tree basetype = BINFO_TYPE (primary);

      CLASSTYPE_PRIMARY_BINFO (t) = primary;
      if (BINFO_PRIMARY_P (primary))
	/* We are stealing a primary base.  */
	BINFO_LOST_PRIMARY_P (BINFO_INHERITANCE_CHAIN (primary)) = 1;
      BINFO_PRIMARY_P (primary) = 1;
      if (BINFO_VIRTUAL_P (primary))
	{
	  tree delta;

	  BINFO_INHERITANCE_CHAIN (primary) = type_binfo;
	  /* A virtual binfo might have been copied from within
	     another hierarchy. As we're about to use it as a primary
	     base, make sure the offsets match.  */
	  delta = size_diffop_loc (input_location, ssize_int (0),
			       fold_convert (ssizetype, BINFO_OFFSET (primary)));

	  propagate_binfo_offsets (primary, delta);
	}

      primary = TYPE_BINFO (basetype);

      TYPE_VFIELD (t) = TYPE_VFIELD (basetype);
      BINFO_VTABLE (type_binfo) = BINFO_VTABLE (primary);
      BINFO_VIRTUALS (type_binfo) = BINFO_VIRTUALS (primary);
    }
}

/* Update the variant types of T.  */

void
fixup_type_variants (tree type)
{
  if (!type)
    return;

  for (tree variant = TYPE_NEXT_VARIANT (type);
       variant;
       variant = TYPE_NEXT_VARIANT (variant))
    {
      /* These fields are in the _TYPE part of the node, not in
	 the TYPE_LANG_SPECIFIC component, so they are not shared.  */
      TYPE_HAS_USER_CONSTRUCTOR (variant) = TYPE_HAS_USER_CONSTRUCTOR (type);
      TYPE_NEEDS_CONSTRUCTING (variant) = TYPE_NEEDS_CONSTRUCTING (type);
      TYPE_HAS_NONTRIVIAL_DESTRUCTOR (variant)
	= TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type);

      TYPE_POLYMORPHIC_P (variant) = TYPE_POLYMORPHIC_P (type);
      CLASSTYPE_FINAL (variant) = CLASSTYPE_FINAL (type);

      TYPE_BINFO (variant) = TYPE_BINFO (type);

      /* Copy whatever these are holding today.  */
      TYPE_VFIELD (variant) = TYPE_VFIELD (type);
      TYPE_FIELDS (variant) = TYPE_FIELDS (type);

      TYPE_SIZE (variant) = TYPE_SIZE (type);
      TYPE_SIZE_UNIT (variant) = TYPE_SIZE_UNIT (type);

      if (!TYPE_USER_ALIGN (variant)
	  || TYPE_NAME (variant) == TYPE_NAME (type)
	  || TYPE_ALIGN_RAW (variant) < TYPE_ALIGN_RAW (type))
	{
	  TYPE_ALIGN_RAW (variant) =  TYPE_ALIGN_RAW (type);
	  TYPE_USER_ALIGN (variant) = TYPE_USER_ALIGN (type);
	}

      TYPE_PRECISION (variant) = TYPE_PRECISION (type);
      TYPE_MODE_RAW (variant) = TYPE_MODE_RAW (type);
      TYPE_EMPTY_P (variant) = TYPE_EMPTY_P (type);
    }
}

/* KLASS is a class that we're applying may_alias to after the body is
   parsed.  Fixup any POINTER_TO and REFERENCE_TO types.  The
   canonical type(s) will be implicitly updated.  */

static void
fixup_may_alias (tree klass)
{
  tree t, v;

  for (t = TYPE_POINTER_TO (klass); t; t = TYPE_NEXT_PTR_TO (t))
    for (v = TYPE_MAIN_VARIANT (t); v; v = TYPE_NEXT_VARIANT (v))
      TYPE_REF_CAN_ALIAS_ALL (v) = true;
  for (t = TYPE_REFERENCE_TO (klass); t; t = TYPE_NEXT_REF_TO (t))
    for (v = TYPE_MAIN_VARIANT (t); v; v = TYPE_NEXT_VARIANT (v))
      TYPE_REF_CAN_ALIAS_ALL (v) = true;
}

/* Early variant fixups: we apply attributes at the beginning of the class
   definition, and we need to fix up any variants that have already been
   made via elaborated-type-specifier so that check_qualified_type works.  */

void
fixup_attribute_variants (tree t)
{
  tree variants;

  if (!t)
    return;

  tree attrs = TYPE_ATTRIBUTES (t);
  unsigned align = TYPE_ALIGN (t);
  bool user_align = TYPE_USER_ALIGN (t);
  bool may_alias = lookup_attribute ("may_alias", attrs);
  bool packed = TYPE_PACKED (t);

  if (may_alias)
    fixup_may_alias (t);

  for (variants = TYPE_NEXT_VARIANT (t);
       variants;
       variants = TYPE_NEXT_VARIANT (variants))
    {
      /* These are the two fields that check_qualified_type looks at and
	 are affected by attributes.  */
      TYPE_ATTRIBUTES (variants) = attrs;
      unsigned valign = align;
      if (TYPE_USER_ALIGN (variants))
	valign = MAX (valign, TYPE_ALIGN (variants));
      else
	TYPE_USER_ALIGN (variants) = user_align;
      SET_TYPE_ALIGN (variants, valign);
      TYPE_PACKED (variants) = packed;
      if (may_alias)
	fixup_may_alias (variants);
    }
}

/* Set memoizing fields and bits of T (and its variants) for later
   use.  */

static void
finish_struct_bits (tree t)
{
  /* Fix up variants (if any).  */
  fixup_type_variants (t);

  if (BINFO_N_BASE_BINFOS (TYPE_BINFO (t)) && TYPE_POLYMORPHIC_P (t))
    /* For a class w/o baseclasses, 'finish_struct' has set
       CLASSTYPE_PURE_VIRTUALS correctly (by definition).
       Similarly for a class whose base classes do not have vtables.
       When neither of these is true, we might have removed abstract
       virtuals (by providing a definition), added some (by declaring
       new ones), or redeclared ones from a base class.  We need to
       recalculate what's really an abstract virtual at this point (by
       looking in the vtables).  */
    get_pure_virtuals (t);

  /* If this type has a copy constructor or a destructor, force its
     mode to be BLKmode, and force its TREE_ADDRESSABLE bit to be
     nonzero.  This will cause it to be passed by invisible reference
     and prevent it from being returned in a register.  */
  if (type_has_nontrivial_copy_init (t)
      || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t))
    {
      tree variants;
      SET_DECL_MODE (TYPE_MAIN_DECL (t), BLKmode);
      for (variants = t; variants; variants = TYPE_NEXT_VARIANT (variants))
	{
	  SET_TYPE_MODE (variants, BLKmode);
	  TREE_ADDRESSABLE (variants) = 1;
	}
    }
}

/* Issue warnings about T having private constructors, but no friends,
   and so forth.

   HAS_NONPRIVATE_METHOD is nonzero if T has any non-private methods or
   static members.  HAS_NONPRIVATE_STATIC_FN is nonzero if T has any
   non-private static member functions.  */

static void
maybe_warn_about_overly_private_class (tree t)
{
  int has_member_fn = 0;
  int has_nonprivate_method = 0;
  bool nonprivate_ctor = false;

  if (!warn_ctor_dtor_privacy
      /* If the class has friends, those entities might create and
	 access instances, so we should not warn.  */
      || (CLASSTYPE_FRIEND_CLASSES (t)
	  || DECL_FRIENDLIST (TYPE_MAIN_DECL (t)))
      /* We will have warned when the template was declared; there's
	 no need to warn on every instantiation.  */
      || CLASSTYPE_TEMPLATE_INSTANTIATION (t))
    /* There's no reason to even consider warning about this
       class.  */
    return;

  /* We only issue one warning, if more than one applies, because
     otherwise, on code like:

     class A {
       // Oops - forgot `public:'
       A();
       A(const A&);
       ~A();
     };

     we warn several times about essentially the same problem.  */

  /* Check to see if all (non-constructor, non-destructor) member
     functions are private.  (Since there are no friends or
     non-private statics, we can't ever call any of the private member
     functions.)  */
  for (tree fn = TYPE_FIELDS (t); fn; fn = DECL_CHAIN (fn))
    if (TREE_CODE (fn) == USING_DECL
	&& DECL_NAME (fn) == ctor_identifier
	&& !TREE_PRIVATE (fn))
      nonprivate_ctor = true;
    else if (!DECL_DECLARES_FUNCTION_P (fn))
      /* Not a function.  */;
    else if (DECL_ARTIFICIAL (fn))
      /* We're not interested in compiler-generated methods; they don't
	 provide any way to call private members.  */;
    else if (!TREE_PRIVATE (fn))
      {
	if (DECL_STATIC_FUNCTION_P (fn))
	  /* A non-private static member function is just like a
	     friend; it can create and invoke private member
	     functions, and be accessed without a class
	     instance.  */
	  return;

	has_nonprivate_method = 1;
	/* Keep searching for a static member function.  */
      }
    else if (!DECL_CONSTRUCTOR_P (fn) && !DECL_DESTRUCTOR_P (fn))
      has_member_fn = 1;

  if (!has_nonprivate_method && has_member_fn)
    {
      /* There are no non-private methods, and there's at least one
	 private member function that isn't a constructor or
	 destructor.  (If all the private members are
	 constructors/destructors we want to use the code below that
	 issues error messages specifically referring to
	 constructors/destructors.)  */
      unsigned i;
      tree binfo = TYPE_BINFO (t);

      for (i = 0; i != BINFO_N_BASE_BINFOS (binfo); i++)
	if (BINFO_BASE_ACCESS (binfo, i) != access_private_node)
	  {
	    has_nonprivate_method = 1;
	    break;
	  }
      if (!has_nonprivate_method)
	{
	  warning (OPT_Wctor_dtor_privacy,
		   "all member functions in class %qT are private", t);
	  return;
	}
    }

  /* Even if some of the member functions are non-private, the class
     won't be useful for much if all the constructors or destructors
     are private: such an object can never be created or destroyed.  */
  if (tree dtor = CLASSTYPE_DESTRUCTOR (t))
    if (TREE_PRIVATE (dtor))
      {
	warning (OPT_Wctor_dtor_privacy,
		 "%q#T only defines a private destructor and has no friends",
		 t);
	return;
      }

  /* Warn about classes that have private constructors and no friends.  */
  if (TYPE_HAS_USER_CONSTRUCTOR (t)
      /* Implicitly generated constructors are always public.  */
      && !CLASSTYPE_LAZY_DEFAULT_CTOR (t))
    {
      tree copy_or_move = NULL_TREE;

      /* If a non-template class does not define a copy
	 constructor, one is defined for it, enabling it to avoid
	 this warning.  For a template class, this does not
	 happen, and so we would normally get a warning on:

	   template <class T> class C { private: C(); };

	 To avoid this asymmetry, we check TYPE_HAS_COPY_CTOR.  All
	 complete non-template or fully instantiated classes have this
	 flag set.  */
      if (!TYPE_HAS_COPY_CTOR (t))
	nonprivate_ctor = true;
      else
	for (tree fn : ovl_range (CLASSTYPE_CONSTRUCTORS (t)))
	  if (TREE_PRIVATE (fn))
	    continue;
	  else if (copy_fn_p (fn) || move_fn_p (fn))
	    /* Ideally, we wouldn't count any constructor that takes
	       an argument of the class type as a parameter, because
	       such things cannot be used to construct an instance of
	       the class unless you already have one.  */
	    copy_or_move = fn;
	  else
	    {
	      nonprivate_ctor = true;
	      break;
	    }

      if (!nonprivate_ctor)
	{
	  bool w = warning (OPT_Wctor_dtor_privacy,
			    "%q#T only defines private constructors and has "
			    "no friends", t);
	  if (w && copy_or_move)
	    inform (DECL_SOURCE_LOCATION (copy_or_move),
		    "%q#D is public, but requires an existing %q#T object",
		    copy_or_move, t);
	  return;
	}
    }
}

/* Make BINFO's vtable have N entries, including RTTI entries,
   vbase and vcall offsets, etc.  Set its type and call the back end
   to lay it out.  */

static void
layout_vtable_decl (tree binfo, int n)
{
  tree atype;
  tree vtable;

  atype = build_array_of_n_type (vtable_entry_type, n);
  layout_type (atype);

  /* We may have to grow the vtable.  */
  vtable = get_vtbl_decl_for_binfo (binfo);
  if (!same_type_p (TREE_TYPE (vtable), atype))
    {
      TREE_TYPE (vtable) = atype;
      DECL_SIZE (vtable) = DECL_SIZE_UNIT (vtable) = NULL_TREE;
      layout_decl (vtable, 0);
    }
}

/* True iff FNDECL and BASE_FNDECL (both non-static member functions)
   have the same signature.  */

int
same_signature_p (const_tree fndecl, const_tree base_fndecl)
{
  /* One destructor overrides another if they are the same kind of
     destructor.  */
  if (DECL_DESTRUCTOR_P (base_fndecl) && DECL_DESTRUCTOR_P (fndecl)
      && special_function_p (base_fndecl) == special_function_p (fndecl))
    return 1;
  /* But a non-destructor never overrides a destructor, nor vice
     versa, nor do different kinds of destructors override
     one-another.  For example, a complete object destructor does not
     override a deleting destructor.  */
  if (DECL_DESTRUCTOR_P (base_fndecl) || DECL_DESTRUCTOR_P (fndecl))
    return 0;

  if (DECL_NAME (fndecl) == DECL_NAME (base_fndecl)
      || (DECL_CONV_FN_P (fndecl)
	  && DECL_CONV_FN_P (base_fndecl)
	  && same_type_p (DECL_CONV_FN_TYPE (fndecl),
			  DECL_CONV_FN_TYPE (base_fndecl))))
    {
      tree fntype = TREE_TYPE (fndecl);
      tree base_fntype = TREE_TYPE (base_fndecl);
      if (type_memfn_quals (fntype) == type_memfn_quals (base_fntype)
	  && type_memfn_rqual (fntype) == type_memfn_rqual (base_fntype)
	  && compparms (FUNCTION_FIRST_USER_PARMTYPE (fndecl),
			FUNCTION_FIRST_USER_PARMTYPE (base_fndecl)))
	return 1;
    }
  return 0;
}

/* Returns TRUE if DERIVED is a binfo containing the binfo BASE as a
   subobject.  */

static bool
base_derived_from (tree derived, tree base)
{
  tree probe;

  for (probe = base; probe; probe = BINFO_INHERITANCE_CHAIN (probe))
    {
      if (probe == derived)
	return true;
      else if (BINFO_VIRTUAL_P (probe))
	/* If we meet a virtual base, we can't follow the inheritance
	   any more.  See if the complete type of DERIVED contains
	   such a virtual base.  */
	return (binfo_for_vbase (BINFO_TYPE (probe), BINFO_TYPE (derived))
		!= NULL_TREE);
    }
  return false;
}

struct find_final_overrider_data {
  /* The function for which we are trying to find a final overrider.  */
  tree fn;
  /* The base class in which the function was declared.  */
  tree declaring_base;
  /* The candidate overriders.  */
  tree candidates;
  /* Path to most derived.  */
  auto_vec<tree> path;
};

/* Add the overrider along the current path to FFOD->CANDIDATES.
   Returns true if an overrider was found; false otherwise.  */

static bool
dfs_find_final_overrider_1 (tree binfo,
			    find_final_overrider_data *ffod,
			    unsigned depth)
{
  tree method;

  /* If BINFO is not the most derived type, try a more derived class.
     A definition there will overrider a definition here.  */
  if (depth)
    {
      depth--;
      if (dfs_find_final_overrider_1
	  (ffod->path[depth], ffod, depth))
	return true;
    }

  method = look_for_overrides_here (BINFO_TYPE (binfo), ffod->fn);
  if (method)
    {
      tree *candidate = &ffod->candidates;

      /* Remove any candidates overridden by this new function.  */
      while (*candidate)
	{
	  /* If *CANDIDATE overrides METHOD, then METHOD
	     cannot override anything else on the list.  */
	  if (base_derived_from (TREE_VALUE (*candidate), binfo))
	    return true;
	  /* If METHOD overrides *CANDIDATE, remove *CANDIDATE.  */
	  if (base_derived_from (binfo, TREE_VALUE (*candidate)))
	    *candidate = TREE_CHAIN (*candidate);
	  else
	    candidate = &TREE_CHAIN (*candidate);
	}

      /* Add the new function.  */
      ffod->candidates = tree_cons (method, binfo, ffod->candidates);
      return true;
    }

  return false;
}

/* Called from find_final_overrider via dfs_walk.  */

static tree
dfs_find_final_overrider_pre (tree binfo, void *data)
{
  find_final_overrider_data *ffod = (find_final_overrider_data *) data;

  if (binfo == ffod->declaring_base)
    dfs_find_final_overrider_1 (binfo, ffod, ffod->path.length ());
  ffod->path.safe_push (binfo);

  return NULL_TREE;
}

static tree
dfs_find_final_overrider_post (tree /*binfo*/, void *data)
{
  find_final_overrider_data *ffod = (find_final_overrider_data *) data;
  ffod->path.pop ();

  return NULL_TREE;
}

/* Returns a TREE_LIST whose TREE_PURPOSE is the final overrider for
   FN and whose TREE_VALUE is the binfo for the base where the
   overriding occurs.  BINFO (in the hierarchy dominated by the binfo
   DERIVED) is the base object in which FN is declared.  */

static tree
find_final_overrider (tree derived, tree binfo, tree fn)
{
  find_final_overrider_data ffod;

  /* Getting this right is a little tricky.  This is valid:

       struct S { virtual void f (); };
       struct T { virtual void f (); };
       struct U : public S, public T { };

     even though calling `f' in `U' is ambiguous.  But,

       struct R { virtual void f(); };
       struct S : virtual public R { virtual void f (); };
       struct T : virtual public R { virtual void f (); };
       struct U : public S, public T { };

     is not -- there's no way to decide whether to put `S::f' or
     `T::f' in the vtable for `R'.

     The solution is to look at all paths to BINFO.  If we find
     different overriders along any two, then there is a problem.  */
  if (DECL_THUNK_P (fn))
    fn = THUNK_TARGET (fn);

  /* Determine the depth of the hierarchy.  */
  ffod.fn = fn;
  ffod.declaring_base = binfo;
  ffod.candidates = NULL_TREE;
  ffod.path.create (30);

  dfs_walk_all (derived, dfs_find_final_overrider_pre,
		dfs_find_final_overrider_post, &ffod);

  /* If there was no winner, issue an error message.  */
  if (!ffod.candidates || TREE_CHAIN (ffod.candidates))
    return error_mark_node;

  return ffod.candidates;
}

/* Return the index of the vcall offset for FN when TYPE is used as a
   virtual base.  */

static tree
get_vcall_index (tree fn, tree type)
{
  vec<tree_pair_s, va_gc> *indices = CLASSTYPE_VCALL_INDICES (type);
  tree_pair_p p;
  unsigned ix;

  FOR_EACH_VEC_SAFE_ELT (indices, ix, p)
    if ((DECL_DESTRUCTOR_P (fn) && DECL_DESTRUCTOR_P (p->purpose))
	|| same_signature_p (fn, p->purpose))
      return p->value;

  /* There should always be an appropriate index.  */
  gcc_unreachable ();
}

/* Given a DECL_VINDEX of a virtual function found in BINFO, return the final
   overrider at that index in the vtable.  This should only be used when we
   know that BINFO is correct for the dynamic type of the object.  */

tree
lookup_vfn_in_binfo (tree idx, tree binfo)
{
  int ix = tree_to_shwi (idx);
  if (TARGET_VTABLE_USES_DESCRIPTORS)
    ix /= MAX (TARGET_VTABLE_USES_DESCRIPTORS, 1);
  while (BINFO_PRIMARY_P (binfo))
    /* BINFO_VIRTUALS in a primary base isn't accurate, find the derived
       class that actually owns the vtable.  */
    binfo = BINFO_INHERITANCE_CHAIN (binfo);
  tree virtuals = BINFO_VIRTUALS (binfo);
  return TREE_VALUE (chain_index (ix, virtuals));
}

/* Update an entry in the vtable for BINFO, which is in the hierarchy
   dominated by T.  FN is the old function; VIRTUALS points to the
   corresponding position in the new BINFO_VIRTUALS list.  IX is the index
   of that entry in the list.  */

static void
update_vtable_entry_for_fn (tree t, tree binfo, tree fn, tree* virtuals,
			    unsigned ix)
{
  tree b;
  tree overrider;
  tree delta;
  tree virtual_base;
  tree first_defn;
  tree overrider_fn, overrider_target;
  tree target_fn = DECL_THUNK_P (fn) ? THUNK_TARGET (fn) : fn;
  tree over_return, base_return;
  bool lost = false;

  /* Find the nearest primary base (possibly binfo itself) which defines
     this function; this is the class the caller will convert to when
     calling FN through BINFO.  */
  for (b = binfo; ; b = get_primary_binfo (b))
    {
      gcc_assert (b);
      if (look_for_overrides_here (BINFO_TYPE (b), target_fn))
	break;

      /* The nearest definition is from a lost primary.  */
      if (BINFO_LOST_PRIMARY_P (b))
	lost = true;
    }
  first_defn = b;

  /* Find the final overrider.  */
  overrider = find_final_overrider (TYPE_BINFO (t), b, target_fn);
  if (overrider == error_mark_node)
    {
      error ("no unique final overrider for %qD in %qT", target_fn, t);
      return;
    }
  overrider_target = overrider_fn = TREE_PURPOSE (overrider);

  /* Check for adjusting covariant return types.  */
  over_return = TREE_TYPE (TREE_TYPE (overrider_target));
  base_return = TREE_TYPE (TREE_TYPE (target_fn));

  if (INDIRECT_TYPE_P (over_return)
      && TREE_CODE (over_return) == TREE_CODE (base_return)
      && CLASS_TYPE_P (TREE_TYPE (over_return))
      && CLASS_TYPE_P (TREE_TYPE (base_return))
      /* If the overrider is invalid, don't even try.  */
      && !DECL_INVALID_OVERRIDER_P (overrider_target))
    {
      /* If FN is a covariant thunk, we must figure out the adjustment
	 to the final base FN was converting to. As OVERRIDER_TARGET might
	 also be converting to the return type of FN, we have to
	 combine the two conversions here.  */
      tree fixed_offset, virtual_offset;

      over_return = TREE_TYPE (over_return);
      base_return = TREE_TYPE (base_return);

      if (DECL_THUNK_P (fn))
	{
	  gcc_assert (DECL_RESULT_THUNK_P (fn));
	  fixed_offset = ssize_int (THUNK_FIXED_OFFSET (fn));
	  virtual_offset = THUNK_VIRTUAL_OFFSET (fn);
	}
      else
	fixed_offset = virtual_offset = NULL_TREE;

      if (virtual_offset)
	/* Find the equivalent binfo within the return type of the
	   overriding function. We will want the vbase offset from
	   there.  */
	virtual_offset = binfo_for_vbase (BINFO_TYPE (virtual_offset),
					  over_return);
      else if (!same_type_ignoring_top_level_qualifiers_p
	       (over_return, base_return))
	{
	  /* There was no existing virtual thunk (which takes
	     precedence).  So find the binfo of the base function's
	     return type within the overriding function's return type.
	     Fortunately we know the covariancy is valid (it
	     has already been checked), so we can just iterate along
	     the binfos, which have been chained in inheritance graph
	     order.  Of course it is lame that we have to repeat the
	     search here anyway -- we should really be caching pieces
	     of the vtable and avoiding this repeated work.  */
	  tree thunk_binfo = NULL_TREE;
	  tree base_binfo = TYPE_BINFO (base_return);

	  /* Find the base binfo within the overriding function's
	     return type.  We will always find a thunk_binfo, except
	     when the covariancy is invalid (which we will have
	     already diagnosed).  */
	  if (base_binfo)
	    for (thunk_binfo = TYPE_BINFO (over_return); thunk_binfo;
		 thunk_binfo = TREE_CHAIN (thunk_binfo))
	      if (SAME_BINFO_TYPE_P (BINFO_TYPE (thunk_binfo),
				     BINFO_TYPE (base_binfo)))
		break;
	  gcc_assert (thunk_binfo || errorcount);

	  /* See if virtual inheritance is involved.  */
	  for (virtual_offset = thunk_binfo;
	       virtual_offset;
	       virtual_offset = BINFO_INHERITANCE_CHAIN (virtual_offset))
	    if (BINFO_VIRTUAL_P (virtual_offset))
	      break;

	  if (virtual_offset
	      || (thunk_binfo && !BINFO_OFFSET_ZEROP (thunk_binfo)))
	    {
	      tree offset = fold_convert (ssizetype, BINFO_OFFSET (thunk_binfo));

	      if (virtual_offset)
		{
		  /* We convert via virtual base.  Adjust the fixed
		     offset to be from there.  */
		  offset = 
		    size_diffop (offset,
				 fold_convert (ssizetype,
					  BINFO_OFFSET (virtual_offset)));
		}
	      if (fixed_offset)
		/* There was an existing fixed offset, this must be
		   from the base just converted to, and the base the
		   FN was thunking to.  */
		fixed_offset = size_binop (PLUS_EXPR, fixed_offset, offset);
	      else
		fixed_offset = offset;
	    }
	}

      if (fixed_offset || virtual_offset)
	/* Replace the overriding function with a covariant thunk.  We
	   will emit the overriding function in its own slot as
	   well.  */
	overrider_fn = make_thunk (overrider_target, /*this_adjusting=*/0,
				   fixed_offset, virtual_offset);
    }
  else
    gcc_assert (DECL_INVALID_OVERRIDER_P (overrider_target) ||
		!DECL_THUNK_P (fn));

  /* If we need a covariant thunk, then we may need to adjust first_defn.
     The ABI specifies that the thunks emitted with a function are
     determined by which bases the function overrides, so we need to be
     sure that we're using a thunk for some overridden base; even if we
     know that the necessary this adjustment is zero, there may not be an
     appropriate zero-this-adjustment thunk for us to use since thunks for
     overriding virtual bases always use the vcall offset.

     Furthermore, just choosing any base that overrides this function isn't
     quite right, as this slot won't be used for calls through a type that
     puts a covariant thunk here.  Calling the function through such a type
     will use a different slot, and that slot is the one that determines
     the thunk emitted for that base.

     So, keep looking until we find the base that we're really overriding
     in this slot: the nearest primary base that doesn't use a covariant
     thunk in this slot.  */
  if (overrider_target != overrider_fn)
    {
      if (BINFO_TYPE (b) == DECL_CONTEXT (overrider_target))
	/* We already know that the overrider needs a covariant thunk.  */
	b = get_primary_binfo (b);
      for (; ; b = get_primary_binfo (b))
	{
	  tree main_binfo = TYPE_BINFO (BINFO_TYPE (b));
	  tree bv = chain_index (ix, BINFO_VIRTUALS (main_binfo));
	  if (!DECL_THUNK_P (TREE_VALUE (bv)))
	    break;
	  if (BINFO_LOST_PRIMARY_P (b))
	    lost = true;
	}
      first_defn = b;
    }

  /* Assume that we will produce a thunk that convert all the way to
     the final overrider, and not to an intermediate virtual base.  */
  virtual_base = NULL_TREE;

  /* See if we can convert to an intermediate virtual base first, and then
     use the vcall offset located there to finish the conversion.  */
  for (; b; b = BINFO_INHERITANCE_CHAIN (b))
    {
      /* If we find the final overrider, then we can stop
	 walking.  */
      if (SAME_BINFO_TYPE_P (BINFO_TYPE (b),
			     BINFO_TYPE (TREE_VALUE (overrider))))
	break;

      /* If we find a virtual base, and we haven't yet found the
	 overrider, then there is a virtual base between the
	 declaring base (first_defn) and the final overrider.  */
      if (BINFO_VIRTUAL_P (b))
	{
	  virtual_base = b;
	  break;
	}
    }

  /* Compute the constant adjustment to the `this' pointer.  The
     `this' pointer, when this function is called, will point at BINFO
     (or one of its primary bases, which are at the same offset).  */
  if (virtual_base)
    /* The `this' pointer needs to be adjusted from the declaration to
       the nearest virtual base.  */
    delta = size_diffop_loc (input_location,
			 fold_convert (ssizetype, BINFO_OFFSET (virtual_base)),
			 fold_convert (ssizetype, BINFO_OFFSET (first_defn)));
  else if (lost)
    /* If the nearest definition is in a lost primary, we don't need an
       entry in our vtable.  Except possibly in a constructor vtable,
       if we happen to get our primary back.  In that case, the offset
       will be zero, as it will be a primary base.  */
    delta = size_zero_node;
  else
    /* The `this' pointer needs to be adjusted from pointing to
       BINFO to pointing at the base where the final overrider
       appears.  */
    delta = size_diffop_loc (input_location,
			 fold_convert (ssizetype,
				  BINFO_OFFSET (TREE_VALUE (overrider))),
			 fold_convert (ssizetype, BINFO_OFFSET (binfo)));

  modify_vtable_entry (t, binfo, overrider_fn, delta, virtuals);

  if (virtual_base)
    BV_VCALL_INDEX (*virtuals)
      = get_vcall_index (overrider_target, BINFO_TYPE (virtual_base));
  else
    BV_VCALL_INDEX (*virtuals) = NULL_TREE;

  BV_LOST_PRIMARY (*virtuals) = lost;
}

/* Called from modify_all_vtables via dfs_walk.  */

static tree
dfs_modify_vtables (tree binfo, void* data)
{
  tree t = (tree) data;
  tree virtuals;
  tree old_virtuals;
  unsigned ix;

  if (!TYPE_CONTAINS_VPTR_P (BINFO_TYPE (binfo)))
    /* A base without a vtable needs no modification, and its bases
       are uninteresting.  */
    return dfs_skip_bases;

  if (SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), t)
      && !CLASSTYPE_HAS_PRIMARY_BASE_P (t))
    /* Don't do the primary vtable, if it's new.  */
    return NULL_TREE;

  if (BINFO_PRIMARY_P (binfo) && !BINFO_VIRTUAL_P (binfo))
    /* There's no need to modify the vtable for a non-virtual primary
       base; we're not going to use that vtable anyhow.  We do still
       need to do this for virtual primary bases, as they could become
       non-primary in a construction vtable.  */
    return NULL_TREE;

  make_new_vtable (t, binfo);

  /* Now, go through each of the virtual functions in the virtual
     function table for BINFO.  Find the final overrider, and update
     the BINFO_VIRTUALS list appropriately.  */
  for (ix = 0, virtuals = BINFO_VIRTUALS (binfo),
	 old_virtuals = BINFO_VIRTUALS (TYPE_BINFO (BINFO_TYPE (binfo)));
       virtuals;
       ix++, virtuals = TREE_CHAIN (virtuals),
	 old_virtuals = TREE_CHAIN (old_virtuals))
    update_vtable_entry_for_fn (t,
				binfo,
				BV_FN (old_virtuals),
				&virtuals, ix);

  return NULL_TREE;
}

/* Update all of the primary and secondary vtables for T.  Create new
   vtables as required, and initialize their RTTI information.  Each
   of the functions in VIRTUALS is declared in T and may override a
   virtual function from a base class; find and modify the appropriate
   entries to point to the overriding functions.  Returns a list, in
   declaration order, of the virtual functions that are declared in T,
   but do not appear in the primary base class vtable, and which
   should therefore be appended to the end of the vtable for T.  */

static tree
modify_all_vtables (tree t, tree virtuals)
{
  tree binfo = TYPE_BINFO (t);
  tree *fnsp;

  /* Mangle the vtable name before entering dfs_walk (c++/51884).  */
  if (TYPE_CONTAINS_VPTR_P (t))
    get_vtable_decl (t, false);

  /* Update all of the vtables.  */
  dfs_walk_once (binfo, dfs_modify_vtables, NULL, t);

  /* Add virtual functions not already in our primary vtable. These
     will be both those introduced by this class, and those overridden
     from secondary bases.  It does not include virtuals merely
     inherited from secondary bases.  */
  for (fnsp = &virtuals; *fnsp; )
    {
      tree fn = TREE_VALUE (*fnsp);

      if (!value_member (fn, BINFO_VIRTUALS (binfo))
	  || DECL_VINDEX (fn) == error_mark_node)
	{
	  /* We don't need to adjust the `this' pointer when
	     calling this function.  */
	  BV_DELTA (*fnsp) = integer_zero_node;
	  BV_VCALL_INDEX (*fnsp) = NULL_TREE;

	  /* This is a function not already in our vtable.  Keep it.  */
	  fnsp = &TREE_CHAIN (*fnsp);
	}
      else
	/* We've already got an entry for this function.  Skip it.  */
	*fnsp = TREE_CHAIN (*fnsp);
    }

  return virtuals;
}

/* Get the base virtual function declarations in T that have the
   indicated NAME.  */

static void
get_basefndecls (tree name, tree t, vec<tree> *base_fndecls)
{
  bool found_decls = false;

  /* Find virtual functions in T with the indicated NAME.  */
  for (tree method : ovl_range (get_class_binding (t, name)))
    {
      if (TREE_CODE (method) == FUNCTION_DECL && DECL_VINDEX (method))
	{
	  base_fndecls->safe_push (method);
	  found_decls = true;
	}
    }

  if (found_decls)
    return;

  int n_baseclasses = BINFO_N_BASE_BINFOS (TYPE_BINFO (t));
  for (int i = 0; i < n_baseclasses; i++)
    {
      tree basetype = BINFO_TYPE (BINFO_BASE_BINFO (TYPE_BINFO (t), i));
      get_basefndecls (name, basetype, base_fndecls);
    }
}

/* If this method overrides a virtual method from a base, then mark
   this member function as being virtual as well.  Do 'final' and
   'override' checks too.  */

void
check_for_override (tree decl, tree ctype)
{
  if (TREE_CODE (decl) == TEMPLATE_DECL)
    /* In [temp.mem] we have:

	 A specialization of a member function template does not
	 override a virtual function from a base class.  */
    return;

  /* IDENTIFIER_VIRTUAL_P indicates whether the name has ever been
     used for a vfunc.  That avoids the expensive look_for_overrides
     call that when we know there's nothing to find.  As conversion
     operators for the same type can have distinct identifiers, we
     cannot optimize those in that way.  */
  if ((IDENTIFIER_VIRTUAL_P (DECL_NAME (decl))
       || DECL_CONV_FN_P (decl))
      && look_for_overrides (ctype, decl)
      /* Check staticness after we've checked if we 'override'.  */
      && !DECL_STATIC_FUNCTION_P (decl))
    {
      /* Set DECL_VINDEX to a value that is neither an INTEGER_CST nor
	 the error_mark_node so that we know it is an overriding
	 function.  */
      DECL_VINDEX (decl) = decl;

      if (warn_override
	  && !DECL_OVERRIDE_P (decl)
	  && !DECL_FINAL_P (decl)
	  && !DECL_DESTRUCTOR_P (decl))
	warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wsuggest_override,
		    "%qD can be marked override", decl);
    }
  else if (DECL_OVERRIDE_P (decl))
    error ("%q+#D marked %<override%>, but does not override", decl);

  if (DECL_VIRTUAL_P (decl))
    {
      /* Remember this identifier is virtual name.  */
      IDENTIFIER_VIRTUAL_P (DECL_NAME (decl)) = true;

      if (!DECL_VINDEX (decl))
	/* It's a new vfunc.  */
	DECL_VINDEX (decl) = error_mark_node;

      if (DECL_DESTRUCTOR_P (decl))
	TYPE_HAS_NONTRIVIAL_DESTRUCTOR (ctype) = true;
    }
  else if (DECL_FINAL_P (decl))
    error ("%q+#D marked %<final%>, but is not virtual", decl);
}

/* Warn about hidden virtual functions that are not overridden in t.
   We know that constructors and destructors don't apply.  */

static void
warn_hidden (tree t)
{
  if (vec<tree, va_gc> *member_vec = CLASSTYPE_MEMBER_VEC (t))
    for (unsigned ix = member_vec->length (); ix--;)
      {
	tree fns = (*member_vec)[ix];

	if (!OVL_P (fns))
	  continue;

	tree name = OVL_NAME (fns);
	auto_vec<tree, 20> base_fndecls;
	tree base_binfo;
	tree binfo;
	unsigned j;

	/* Iterate through all of the base classes looking for possibly
	   hidden functions.  */
	for (binfo = TYPE_BINFO (t), j = 0;
	     BINFO_BASE_ITERATE (binfo, j, base_binfo); j++)
	  {
	    tree basetype = BINFO_TYPE (base_binfo);
	    get_basefndecls (name, basetype, &base_fndecls);
	  }

	/* If there are no functions to hide, continue.  */
	if (base_fndecls.is_empty ())
	  continue;

	/* Remove any overridden functions.  */
	for (tree fndecl : ovl_range (fns))
	  {
	    if (TREE_CODE (fndecl) == FUNCTION_DECL
		&& DECL_VINDEX (fndecl))
	      {
		/* If the method from the base class has the same
		   signature as the method from the derived class, it
		   has been overridden.  */
		for (size_t k = 0; k < base_fndecls.length (); k++)
		  if (base_fndecls[k]
		      && same_signature_p (fndecl, base_fndecls[k]))
		    base_fndecls[k] = NULL_TREE;
	      }
	  }

	/* Now give a warning for all base functions without overriders,
	   as they are hidden.  */
	tree base_fndecl;
	FOR_EACH_VEC_ELT (base_fndecls, j, base_fndecl)
	  if (base_fndecl)
	    {
	      auto_diagnostic_group d;
	      /* Here we know it is a hider, and no overrider exists.  */
	      if (warning_at (location_of (base_fndecl),
			      OPT_Woverloaded_virtual,
			      "%qD was hidden", base_fndecl))
		inform (location_of (fns), "  by %qD", fns);
	    }
      }
}

/* Recursive helper for finish_struct_anon.  */

static void
finish_struct_anon_r (tree field)
{
  for (tree elt = TYPE_FIELDS (TREE_TYPE (field)); elt; elt = DECL_CHAIN (elt))
    {
      /* We're generally only interested in entities the user
	 declared, but we also find nested classes by noticing
	 the TYPE_DECL that we create implicitly.  You're
	 allowed to put one anonymous union inside another,
	 though, so we explicitly tolerate that.  We use
	 TYPE_UNNAMED_P rather than ANON_AGGR_TYPE_P so that
	 we also allow unnamed types used for defining fields.  */
      if (DECL_ARTIFICIAL (elt)
	  && (!DECL_IMPLICIT_TYPEDEF_P (elt)
	      || TYPE_UNNAMED_P (TREE_TYPE (elt))))
	continue;

      TREE_PRIVATE (elt) = TREE_PRIVATE (field);
      TREE_PROTECTED (elt) = TREE_PROTECTED (field);

      /* Recurse into the anonymous aggregates to correctly handle
	 access control (c++/24926):

	 class A {
	   union {
	     union {
	       int i;
	     };
	   };
	 };

	 int j=A().i;  */
      if (DECL_NAME (elt) == NULL_TREE
	  && ANON_AGGR_TYPE_P (TREE_TYPE (elt)))
	finish_struct_anon_r (elt);
    }
}

/* Check for things that are invalid.  There are probably plenty of other
   things we should check for also.  */

static void
finish_struct_anon (tree t)
{
  for (tree field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field))
    {
      if (TREE_STATIC (field))
	continue;
      if (TREE_CODE (field) != FIELD_DECL)
	continue;

      if (DECL_NAME (field) == NULL_TREE
	  && ANON_AGGR_TYPE_P (TREE_TYPE (field)))
	finish_struct_anon_r (field);
    }
}

/* Add T to CLASSTYPE_DECL_LIST of current_class_type which
   will be used later during class template instantiation.
   When FRIEND_P is zero, T can be a static member data (VAR_DECL),
   a non-static member data (FIELD_DECL), a member function
   (FUNCTION_DECL), a nested type (RECORD_TYPE, ENUM_TYPE),
   a typedef (TYPE_DECL) or a member class template (TEMPLATE_DECL)
   When FRIEND_P is nonzero, T is either a friend class
   (RECORD_TYPE, TEMPLATE_DECL) or a friend function
   (FUNCTION_DECL, TEMPLATE_DECL).  */

void
maybe_add_class_template_decl_list (tree type, tree t, int friend_p)
{
  if (CLASSTYPE_TEMPLATE_INFO (type)
      && TREE_CODE (t) != CONST_DECL)
    {
      tree purpose = friend_p ? NULL_TREE : type;

      CLASSTYPE_DECL_LIST (type)
	= tree_cons (purpose, t, CLASSTYPE_DECL_LIST (type));
    }
}

/* This function is called from declare_virt_assop_and_dtor via
   dfs_walk_all.

   DATA is a type that direcly or indirectly inherits the base
   represented by BINFO.  If BINFO contains a virtual assignment [copy
   assignment or move assigment] operator or a virtual constructor,
   declare that function in DATA if it hasn't been already declared.  */

static tree
dfs_declare_virt_assop_and_dtor (tree binfo, void *data)
{
  tree bv, fn, t = (tree)data;
  tree opname = assign_op_identifier;

  gcc_assert (t && CLASS_TYPE_P (t));
  gcc_assert (binfo && TREE_CODE (binfo) == TREE_BINFO);

  if (!TYPE_CONTAINS_VPTR_P (BINFO_TYPE (binfo)))
    /* A base without a vtable needs no modification, and its bases
       are uninteresting.  */
    return dfs_skip_bases;

  if (BINFO_PRIMARY_P (binfo))
    /* If this is a primary base, then we have already looked at the
       virtual functions of its vtable.  */
    return NULL_TREE;

  for (bv = BINFO_VIRTUALS (binfo); bv; bv = TREE_CHAIN (bv))
    {
      fn = BV_FN (bv);

      if (DECL_NAME (fn) == opname)
	{
	  if (CLASSTYPE_LAZY_COPY_ASSIGN (t))
	    lazily_declare_fn (sfk_copy_assignment, t);
	  if (CLASSTYPE_LAZY_MOVE_ASSIGN (t))
	    lazily_declare_fn (sfk_move_assignment, t);
	}
      else if (DECL_DESTRUCTOR_P (fn)
	       && CLASSTYPE_LAZY_DESTRUCTOR (t))
	lazily_declare_fn (sfk_destructor, t);
    }

  return NULL_TREE;
}

/* If the class type T has a direct or indirect base that contains a
   virtual assignment operator or a virtual destructor, declare that
   function in T if it hasn't been already declared.  */

static void
declare_virt_assop_and_dtor (tree t)
{
  if (!(TYPE_POLYMORPHIC_P (t)
	&& (CLASSTYPE_LAZY_COPY_ASSIGN (t)
	    || CLASSTYPE_LAZY_MOVE_ASSIGN (t)
	    || CLASSTYPE_LAZY_DESTRUCTOR (t))))
    return;

  dfs_walk_all (TYPE_BINFO (t),
		dfs_declare_virt_assop_and_dtor,
		NULL, t);
}

/* Declare the inheriting constructor for class T inherited from base
   constructor CTOR with the parameter array PARMS of size NPARMS.  */

static void
one_inheriting_sig (tree t, tree ctor, tree *parms, int nparms)
{
  gcc_assert (TYPE_MAIN_VARIANT (t) == t);

  /* We don't declare an inheriting ctor that would be a default,
     copy or move ctor for derived or base.  */
  if (nparms == 0)
    return;
  if (nparms == 1
      && TYPE_REF_P (parms[0]))
    {
      tree parm = TYPE_MAIN_VARIANT (TREE_TYPE (parms[0]));
      if (parm == t || parm == DECL_CONTEXT (ctor))
	return;
    }

  tree parmlist = void_list_node;
  for (int i = nparms - 1; i >= 0; i--)
    parmlist = tree_cons (NULL_TREE, parms[i], parmlist);
  tree fn = implicitly_declare_fn (sfk_inheriting_constructor,
				   t, false, ctor, parmlist);

  if (add_method (t, fn, false))
    {
      DECL_CHAIN (fn) = TYPE_FIELDS (t);
      TYPE_FIELDS (t) = fn;
    }
}

/* Declare all the inheriting constructors for class T inherited from base
   constructor CTOR.  */

static void
one_inherited_ctor (tree ctor, tree t, tree using_decl)
{
  tree parms = FUNCTION_FIRST_USER_PARMTYPE (ctor);

  if (flag_new_inheriting_ctors)
    {
      ctor = implicitly_declare_fn (sfk_inheriting_constructor,
				    t, /*const*/false, ctor, parms);
      add_method (t, ctor, using_decl != NULL_TREE);
      return;
    }

  tree *new_parms = XALLOCAVEC (tree, list_length (parms));
  int i = 0;
  for (; parms && parms != void_list_node; parms = TREE_CHAIN (parms))
    {
      if (TREE_PURPOSE (parms))
	one_inheriting_sig (t, ctor, new_parms, i);
      new_parms[i++] = TREE_VALUE (parms);
    }
  one_inheriting_sig (t, ctor, new_parms, i);
  if (parms == NULL_TREE)
    {
      auto_diagnostic_group d;
      if (warning (OPT_Winherited_variadic_ctor,
		   "the ellipsis in %qD is not inherited", ctor))
	inform (DECL_SOURCE_LOCATION (ctor), "%qD declared here", ctor);
    }
}

/* Create default constructors, assignment operators, and so forth for
   the type indicated by T, if they are needed.  CANT_HAVE_CONST_CTOR,
   and CANT_HAVE_CONST_ASSIGNMENT are nonzero if, for whatever reason,
   the class cannot have a default constructor, copy constructor
   taking a const reference argument, or an assignment operator taking
   a const reference, respectively.  */

static void
add_implicitly_declared_members (tree t, tree* access_decls,
				 int cant_have_const_cctor,
				 int cant_have_const_assignment)
{
  /* Destructor.  */
  if (!CLASSTYPE_DESTRUCTOR (t))
    /* In general, we create destructors lazily.  */
    CLASSTYPE_LAZY_DESTRUCTOR (t) = 1;

  bool move_ok = false;
  if (cxx_dialect >= cxx11 && CLASSTYPE_LAZY_DESTRUCTOR (t)
      && !TYPE_HAS_COPY_CTOR (t) && !TYPE_HAS_COPY_ASSIGN (t)
      && !classtype_has_move_assign_or_move_ctor_p (t, false))
    move_ok = true;

  /* [class.ctor]

     If there is no user-declared constructor for a class, a default
     constructor is implicitly declared.  */
  if (! TYPE_HAS_USER_CONSTRUCTOR (t))
    {
      TYPE_HAS_DEFAULT_CONSTRUCTOR (t) = 1;
      CLASSTYPE_LAZY_DEFAULT_CTOR (t) = 1;
      if (cxx_dialect >= cxx11)
	TYPE_HAS_CONSTEXPR_CTOR (t)
	  /* Don't force the declaration to get a hard answer; if the
	     definition would have made the class non-literal, it will still be
	     non-literal because of the base or member in question, and that
	     gives a better diagnostic.  */
	  = type_maybe_constexpr_default_constructor (t);
    }

  /* [class.ctor]

     If a class definition does not explicitly declare a copy
     constructor, one is declared implicitly.  */
  if (! TYPE_HAS_COPY_CTOR (t))
    {
      TYPE_HAS_COPY_CTOR (t) = 1;
      TYPE_HAS_CONST_COPY_CTOR (t) = !cant_have_const_cctor;
      CLASSTYPE_LAZY_COPY_CTOR (t) = 1;
      if (move_ok)
	CLASSTYPE_LAZY_MOVE_CTOR (t) = 1;
    }

  /* If there is no assignment operator, one will be created if and
     when it is needed.  For now, just record whether or not the type
     of the parameter to the assignment operator will be a const or
     non-const reference.  */
  if (!TYPE_HAS_COPY_ASSIGN (t))
    {
      TYPE_HAS_COPY_ASSIGN (t) = 1;
      TYPE_HAS_CONST_COPY_ASSIGN (t) = !cant_have_const_assignment;
      CLASSTYPE_LAZY_COPY_ASSIGN (t) = 1;
      if (move_ok && !LAMBDA_TYPE_P (t))
	CLASSTYPE_LAZY_MOVE_ASSIGN (t) = 1;
    }

  /* We can't be lazy about declaring functions that might override
     a virtual function from a base class.  */
  declare_virt_assop_and_dtor (t);

  /* If the class definition does not explicitly declare an == operator
     function, but declares a defaulted three-way comparison operator function,
     an == operator function is declared implicitly.  */
  if (!classtype_has_op (t, EQ_EXPR))
    if (tree space = classtype_has_defaulted_op (t, SPACESHIP_EXPR))
      {
	tree eq = implicitly_declare_fn (sfk_comparison, t, false, space,
					 NULL_TREE);
	bool is_friend = DECL_CONTEXT (space) != t;
	if (is_friend)
	  do_friend (NULL_TREE, DECL_NAME (eq), eq,
		     NO_SPECIAL, true);
	else
	  {
	    add_method (t, eq, false);
	    DECL_CHAIN (eq) = TYPE_FIELDS (t);
	    TYPE_FIELDS (t) = eq;
	  }
	maybe_add_class_template_decl_list (t, eq, is_friend);
      }

  while (*access_decls)
    {
      tree using_decl = TREE_VALUE (*access_decls);
      tree decl = USING_DECL_DECLS (using_decl);
      if (DECL_NAME (using_decl) == ctor_identifier)
	{
	  /* declare, then remove the decl */
	  tree ctor_list = decl;
	  location_t loc = input_location;
	  input_location = DECL_SOURCE_LOCATION (using_decl);
	  for (tree fn : ovl_range (ctor_list))
	    one_inherited_ctor (fn, t, using_decl);
	  *access_decls = TREE_CHAIN (*access_decls);
	  input_location = loc;
	}
      else
	access_decls = &TREE_CHAIN (*access_decls);
    }
}

/* Cache of enum_min_precision values.  */
static GTY((deletable)) hash_map<tree, int> *enum_to_min_precision;

/* Return the minimum precision of a bit-field needed to store all
   enumerators of ENUMERAL_TYPE TYPE.  */

static int
enum_min_precision (tree type)
{
  type = TYPE_MAIN_VARIANT (type);
  /* For unscoped enums without fixed underlying type and without mode
     attribute we can just use precision of the underlying type.  */
  if (UNSCOPED_ENUM_P (type)
      && !ENUM_FIXED_UNDERLYING_TYPE_P (type)
      && !lookup_attribute ("mode", TYPE_ATTRIBUTES (type)))
    return TYPE_PRECISION (ENUM_UNDERLYING_TYPE (type));

  if (enum_to_min_precision == NULL)
    enum_to_min_precision = hash_map<tree, int>::create_ggc (37);

  bool existed;
  int &prec = enum_to_min_precision->get_or_insert (type, &existed);
  if (existed)
    return prec;

  tree minnode, maxnode;
  if (TYPE_VALUES (type))
    {
      minnode = maxnode = NULL_TREE;
      for (tree values = TYPE_VALUES (type);
	   values; values = TREE_CHAIN (values))
	{
	  tree decl = TREE_VALUE (values);
	  tree value = DECL_INITIAL (decl);
	  if (value == error_mark_node)
	    value = integer_zero_node;
	  if (!minnode)
	    minnode = maxnode = value;
	  else if (tree_int_cst_lt (maxnode, value))
	    maxnode = value;
	  else if (tree_int_cst_lt (value, minnode))
	    minnode = value;
	}
    }
  else
    minnode = maxnode = integer_zero_node;

  signop sgn = tree_int_cst_sgn (minnode) >= 0 ? UNSIGNED : SIGNED;
  int lowprec = tree_int_cst_min_precision (minnode, sgn);
  int highprec = tree_int_cst_min_precision (maxnode, sgn);
  prec = MAX (lowprec, highprec);
  return prec;
}

/* FIELD is a bit-field.  We are finishing the processing for its
   enclosing type.  Issue any appropriate messages and set appropriate
   flags.  Returns false if an error has been diagnosed.  */

static bool
check_bitfield_decl (tree field)
{
  tree type = TREE_TYPE (field);
  tree w;

  /* Extract the declared width of the bitfield, which has been
     temporarily stashed in DECL_BIT_FIELD_REPRESENTATIVE by grokbitfield.  */
  w = DECL_BIT_FIELD_REPRESENTATIVE (field);
  gcc_assert (w != NULL_TREE);
  /* Remove the bit-field width indicator so that the rest of the
     compiler does not treat that value as a qualifier.  */
  DECL_BIT_FIELD_REPRESENTATIVE (field) = NULL_TREE;

  /* Detect invalid bit-field type.  */
  if (!INTEGRAL_OR_ENUMERATION_TYPE_P (type))
    {
      error_at (DECL_SOURCE_LOCATION (field),
		"bit-field %q#D with non-integral type %qT", field, type);
      w = error_mark_node;
    }
  else
    {
      location_t loc = input_location;
      /* Avoid the non_lvalue wrapper added by fold for PLUS_EXPRs.  */
      STRIP_NOPS (w);

      /* detect invalid field size.  */
      input_location = DECL_SOURCE_LOCATION (field);
      w = cxx_constant_value (w);
      input_location = loc;

      if (TREE_CODE (w) != INTEGER_CST)
	{
	  error ("bit-field %q+D width not an integer constant", field);
	  w = error_mark_node;
	}
      else if (tree_int_cst_sgn (w) < 0)
	{
	  error ("negative width in bit-field %q+D", field);
	  w = error_mark_node;
	}
      else if (integer_zerop (w) && DECL_NAME (field) != 0)
	{
	  error ("zero width for bit-field %q+D", field);
	  w = error_mark_node;
	}
      else if ((TREE_CODE (type) != ENUMERAL_TYPE
		&& TREE_CODE (type) != BOOLEAN_TYPE
		&& compare_tree_int (w, TYPE_PRECISION (type)) > 0)
	       || ((TREE_CODE (type) == ENUMERAL_TYPE
		    || TREE_CODE (type) == BOOLEAN_TYPE)
		   && tree_int_cst_lt (TYPE_SIZE (type), w)))
	warning_at (DECL_SOURCE_LOCATION (field), 0,
		    "width of %qD exceeds its type", field);
      else if (TREE_CODE (type) == ENUMERAL_TYPE)
	{
	  int prec = enum_min_precision (type);
	  if (compare_tree_int (w, prec) < 0)
	    warning_at (DECL_SOURCE_LOCATION (field), 0,
			"%qD is too small to hold all values of %q#T",
			field, type);
	}
    }

  if (w != error_mark_node)
    {
      DECL_SIZE (field) = fold_convert (bitsizetype, w);
      DECL_BIT_FIELD (field) = 1;
      return true;
    }
  else
    {
      /* Non-bit-fields are aligned for their type.  */
      DECL_BIT_FIELD (field) = 0;
      CLEAR_DECL_C_BIT_FIELD (field);
      return false;
    }
}

/* FIELD is a non bit-field.  We are finishing the processing for its
   enclosing type T.  Issue any appropriate messages and set appropriate
   flags.  */

static bool
check_field_decl (tree field,
		  tree t,
		  int* cant_have_const_ctor,
		  int* no_const_asn_ref)
{
  tree type = strip_array_types (TREE_TYPE (field));
  bool any_default_members = false;

  /* In C++98 an anonymous union cannot contain any fields which would change
     the settings of CANT_HAVE_CONST_CTOR and friends.  */
  if (ANON_UNION_TYPE_P (type) && cxx_dialect < cxx11)
    ;
  /* And, we don't set TYPE_HAS_CONST_COPY_CTOR, etc., for anonymous
     structs.  So, we recurse through their fields here.  */
  else if (ANON_AGGR_TYPE_P (type))
    {
      for (tree fields = TYPE_FIELDS (type); fields;
	   fields = DECL_CHAIN (fields))
	if (TREE_CODE (fields) == FIELD_DECL)
	  any_default_members |= check_field_decl (fields, t,
						   cant_have_const_ctor,
						   no_const_asn_ref);
    }
  /* Check members with class type for constructors, destructors,
     etc.  */
  else if (CLASS_TYPE_P (type))
    {
      /* Never let anything with uninheritable virtuals
	 make it through without complaint.  */
      abstract_virtuals_error (field, type);

      if (TREE_CODE (t) == UNION_TYPE && cxx_dialect < cxx11)
	{
	  static bool warned;
	  int oldcount = errorcount;
	  if (TYPE_NEEDS_CONSTRUCTING (type))
	    error ("member %q+#D with constructor not allowed in union",
		   field);
	  if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
	    error ("member %q+#D with destructor not allowed in union", field);
	  if (TYPE_HAS_COMPLEX_COPY_ASSIGN (type))
	    error ("member %q+#D with copy assignment operator not allowed in union",
		   field);
	  if (!warned && errorcount > oldcount)
	    {
	      inform (DECL_SOURCE_LOCATION (field), "unrestricted unions "
		      "only available with %<-std=c++11%> or %<-std=gnu++11%>");
	      warned = true;
	    }
	}
      else
	{
	  TYPE_NEEDS_CONSTRUCTING (t) |= TYPE_NEEDS_CONSTRUCTING (type);
	  TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t)
	    |= TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type);
	  TYPE_HAS_COMPLEX_COPY_ASSIGN (t)
	    |= (TYPE_HAS_COMPLEX_COPY_ASSIGN (type)
		|| !TYPE_HAS_COPY_ASSIGN (type));
	  TYPE_HAS_COMPLEX_COPY_CTOR (t) |= (TYPE_HAS_COMPLEX_COPY_CTOR (type)
					     || !TYPE_HAS_COPY_CTOR (type));
	  TYPE_HAS_COMPLEX_MOVE_ASSIGN (t) |= TYPE_HAS_COMPLEX_MOVE_ASSIGN (type);
	  TYPE_HAS_COMPLEX_MOVE_CTOR (t) |= TYPE_HAS_COMPLEX_MOVE_CTOR (type);
	  TYPE_HAS_COMPLEX_DFLT (t) |= (!TYPE_HAS_DEFAULT_CONSTRUCTOR (type)
					|| TYPE_HAS_COMPLEX_DFLT (type));
	}

      if (TYPE_HAS_COPY_CTOR (type)
	  && !TYPE_HAS_CONST_COPY_CTOR (type))
	*cant_have_const_ctor = 1;

      if (TYPE_HAS_COPY_ASSIGN (type)
	  && !TYPE_HAS_CONST_COPY_ASSIGN (type))
	*no_const_asn_ref = 1;
    }

  check_abi_tags (t, field);

  if (DECL_INITIAL (field) != NULL_TREE)
    /* `build_class_init_list' does not recognize
       non-FIELD_DECLs.  */
    any_default_members = true;

  return any_default_members;
}

/* Check the data members (both static and non-static), class-scoped
   typedefs, etc., appearing in the declaration of T.  Issue
   appropriate diagnostics.  Sets ACCESS_DECLS to a list (in
   declaration order) of access declarations; each TREE_VALUE in this
   list is a USING_DECL.

   In addition, set the following flags:

     EMPTY_P
       The class is empty, i.e., contains no non-static data members.

     CANT_HAVE_CONST_CTOR_P
       This class cannot have an implicitly generated copy constructor
       taking a const reference.

     CANT_HAVE_CONST_ASN_REF
       This class cannot have an implicitly generated assignment
       operator taking a const reference.

   All of these flags should be initialized before calling this
   function.   */

static void
check_field_decls (tree t, tree *access_decls,
		   int *cant_have_const_ctor_p,
		   int *no_const_asn_ref_p)
{
  int cant_pack = 0;

  /* Assume there are no access declarations.  */
  *access_decls = NULL_TREE;
  /* Effective C has things to say about classes with pointer members.  */
  tree pointer_member = NULL_TREE;
  /* Default initialized members affect the whole class.  */
  tree default_init_member = NULL_TREE;
  /* Lack of any non-static data member of non-volatile literal
     type affects a union.  */
  bool found_nv_literal_p = false;
  /* Standard layout requires all FIELDS have same access.  */
  int field_access = -1;

  for (tree field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field))
    {
      tree type = TREE_TYPE (field);

      switch (TREE_CODE (field))
	{
	default:
	  gcc_unreachable ();

	case USING_DECL:
	  /* Save the access declarations for our caller.  */
	  *access_decls = tree_cons (NULL_TREE, field, *access_decls);
	  break;

	case TYPE_DECL:
	case TEMPLATE_DECL:
	  break;

	case FUNCTION_DECL:
	  /* FIXME: We should fold in the checking from check_methods.  */
	  break;

	case CONST_DECL:
	  DECL_NONLOCAL (field) = 1;
	  break;
	  
	case VAR_DECL:
	  if (TREE_CODE (t) == UNION_TYPE
	      && cxx_dialect < cxx11)
	    {
	      /* [class.union]

		 (C++98) If a union contains a static data member,
		 ... the program is ill-formed.  */
	      if (cxx_dialect < cxx11)
		error ("in C++98 %q+D may not be static because it is "
		       "a member of a union", field);
	    }
	  goto data_member;
	  
	case FIELD_DECL:
	  if (TREE_CODE (t) == UNION_TYPE)
	    {
	      /* [class.union]

		 If a union contains ... or a [non-static data] member
		 of reference type, the program is ill-formed.  */
	      if (TYPE_REF_P (type))
		error ("non-static data member %q+D in a union may not "
		       "have reference type %qT", field, type);
	    }

	data_member:
	  /* Common VAR_DECL & FIELD_DECL processing.  */
	  DECL_CONTEXT (field) = t;
	  DECL_NONLOCAL (field) = 1;

	  /* Template instantiation can cause this.  Perhaps this
	     should be a specific instantiation check?  */
	  if (TREE_CODE (type) == FUNCTION_TYPE)
	    {
	      error ("data member %q+D invalidly declared function type", field);
	      type = build_pointer_type (type);
	      TREE_TYPE (field) = type;
	    }
	  else if (TREE_CODE (type) == METHOD_TYPE)
	    {
	      error ("data member %q+D invalidly declared method type", field);
	      type = build_pointer_type (type);
	      TREE_TYPE (field) = type;
	    }

	  break;
	}

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

      if (type == error_mark_node)
	continue;

      /* If it is not a union and at least one non-static data member is
	 non-literal, the whole class becomes non-literal.  Per Core/1453,
	 volatile non-static data members and base classes are also not allowed.
	 If it is a union, we might set CLASSTYPE_LITERAL_P after we've seen all
	 members.
	 Note: if the type is incomplete we will complain later on.  */
      if (COMPLETE_TYPE_P (type))
	{
	  if (!literal_type_p (type) || CP_TYPE_VOLATILE_P (type))
	    CLASSTYPE_LITERAL_P (t) = false;
	  else
	    found_nv_literal_p = true;
	}

      int this_field_access = (TREE_PROTECTED (field) ? 1
			       : TREE_PRIVATE (field) ? 2 : 0);
      if (field_access != this_field_access)
	{
	  /* A standard-layout class is a class that:

	     ... has the same access control (Clause 11) for all
	     non-static data members, */
	  if (field_access < 0)
	    field_access = this_field_access;
	  else
	    CLASSTYPE_NON_STD_LAYOUT (t) = 1;

	  /* Aggregates must be public.  */
	  if (this_field_access)
	    CLASSTYPE_NON_AGGREGATE (t) = 1;
	}

      /* If this is of reference type, check if it needs an init.  */
      if (TYPE_REF_P (type))
	{
	  CLASSTYPE_NON_LAYOUT_POD_P (t) = 1;
	  CLASSTYPE_NON_STD_LAYOUT (t) = 1;
	  if (DECL_INITIAL (field) == NULL_TREE)
	    SET_CLASSTYPE_REF_FIELDS_NEED_INIT (t, 1);
	  if (cxx_dialect < cxx11)
	    {
	      /* ARM $12.6.2: [A member initializer list] (or, for an
		 aggregate, initialization by a brace-enclosed list) is the
		 only way to initialize non-static const and reference
		 members.  */
	      TYPE_HAS_COMPLEX_COPY_ASSIGN (t) = 1;
	      TYPE_HAS_COMPLEX_MOVE_ASSIGN (t) = 1;
	    }
	}

      type = strip_array_types (type);

      if (TYPE_PACKED (t))
	{
	  if (!layout_pod_type_p (type) && !TYPE_PACKED (type))
	    {
	      warning_at (DECL_SOURCE_LOCATION (field), 0,
			  "ignoring packed attribute because of"
			  " unpacked non-POD field %q#D", field);
	      cant_pack = 1;
	    }
	  else if (DECL_C_BIT_FIELD (field)
		   || TYPE_ALIGN (TREE_TYPE (field)) > BITS_PER_UNIT)
	    DECL_PACKED (field) = 1;
	}

      if (DECL_C_BIT_FIELD (field)
	  && integer_zerop (DECL_BIT_FIELD_REPRESENTATIVE (field)))
	/* We don't treat zero-width bitfields as making a class
	   non-empty.  */
	;
      else if (field_poverlapping_p (field)
	       && is_empty_class (TREE_TYPE (field)))
	/* Empty data members also don't make a class non-empty.  */
	CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t) = 1;
      else
	{
	  /* The class is non-empty.  */
	  CLASSTYPE_EMPTY_P (t) = 0;
	  /* The class is not even nearly empty.  */
	  CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
	  /* If one of the data members contains an empty class, so
	     does T.  */
	  if (CLASS_TYPE_P (type)
	      && CLASSTYPE_CONTAINS_EMPTY_CLASS_P (type))
	    CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t) = 1;
	}

      /* This is used by -Weffc++ (see below). Warn only for pointers
	 to members which might hold dynamic memory. So do not warn
	 for pointers to functions or pointers to members.  */
      if (TYPE_PTR_P (type)
	  && !TYPE_PTRFN_P (type))
	pointer_member = field;

      if (CLASS_TYPE_P (type))
	{
	  if (CLASSTYPE_REF_FIELDS_NEED_INIT (type))
	    SET_CLASSTYPE_REF_FIELDS_NEED_INIT (t, 1);
	  if (CLASSTYPE_READONLY_FIELDS_NEED_INIT (type))
	    SET_CLASSTYPE_READONLY_FIELDS_NEED_INIT (t, 1);
	}

      if (DECL_MUTABLE_P (field) || TYPE_HAS_MUTABLE_P (type))
	CLASSTYPE_HAS_MUTABLE (t) = 1;

      if (DECL_MUTABLE_P (field))
	{
	  if (TYPE_REF_P (type))
	    error ("member %q+D cannot be declared as a %<mutable%> "
		   "reference", field);
	  else if (CP_TYPE_CONST_P (type))
	    error ("member %q+D cannot be declared both %<const%> "
		   "and %<mutable%>", field);
	}

      if (! layout_pod_type_p (type))
	/* DR 148 now allows pointers to members (which are POD themselves),
	   to be allowed in POD structs.  */
	CLASSTYPE_NON_LAYOUT_POD_P (t) = 1;

      if (field_poverlapping_p (field))
	/* A potentially-overlapping non-static data member makes the class
	   non-layout-POD.  */
	CLASSTYPE_NON_LAYOUT_POD_P (t) = 1;

      if (!std_layout_type_p (type))
	CLASSTYPE_NON_STD_LAYOUT (t) = 1;

      if (! zero_init_p (type))
	CLASSTYPE_NON_ZERO_INIT_P (t) = 1;

      /* We set DECL_C_BIT_FIELD in grokbitfield.
	 If the type and width are valid, we'll also set DECL_BIT_FIELD.  */
      if (DECL_C_BIT_FIELD (field))
	check_bitfield_decl (field);

      if (check_field_decl (field, t,
			    cant_have_const_ctor_p, no_const_asn_ref_p))
	{
	  if (default_init_member
	      && TREE_CODE (t) == UNION_TYPE)
	    {
	      error ("multiple fields in union %qT initialized", t);
	      inform (DECL_SOURCE_LOCATION (default_init_member),
		      "initialized member %q+D declared here",
		      default_init_member);
	    }
	  default_init_member = field;
	}

      /* Now that we've removed bit-field widths from DECL_INITIAL,
	 anything left in DECL_INITIAL is an NSDMI that makes the class
	 non-aggregate in C++11.  */
      if (DECL_INITIAL (field) && cxx_dialect < cxx14)
	CLASSTYPE_NON_AGGREGATE (t) = true;

      if (CP_TYPE_CONST_P (type))
	{
	  /* If any field is const, the structure type is pseudo-const.  */
	  C_TYPE_FIELDS_READONLY (t) = 1;
	  if (DECL_INITIAL (field) == NULL_TREE)
	    SET_CLASSTYPE_READONLY_FIELDS_NEED_INIT (t, 1);
	  if (cxx_dialect < cxx11)
	    {
	      /* ARM $12.6.2: [A member initializer list] (or, for an
		 aggregate, initialization by a brace-enclosed list) is the
		 only way to initialize non-static const and reference
		 members.  */
	      TYPE_HAS_COMPLEX_COPY_ASSIGN (t) = 1;
	      TYPE_HAS_COMPLEX_MOVE_ASSIGN (t) = 1;
	    }
	}
      /* A field that is pseudo-const makes the structure likewise.  */
      else if (CLASS_TYPE_P (type))
	{
	  C_TYPE_FIELDS_READONLY (t) |= C_TYPE_FIELDS_READONLY (type);
	  SET_CLASSTYPE_READONLY_FIELDS_NEED_INIT (t,
	    CLASSTYPE_READONLY_FIELDS_NEED_INIT (t)
	    | CLASSTYPE_READONLY_FIELDS_NEED_INIT (type));
	}

      /* Core issue 80: A non-static data member is required to have a
	 different name from the class iff the class has a
	 user-declared constructor.  */
      if (constructor_name_p (DECL_NAME (field), t)
	  && TYPE_HAS_USER_CONSTRUCTOR (t))
	permerror (DECL_SOURCE_LOCATION (field),
		   "field %q#D with same name as class", field);
    }

  /* Per CWG 2096, a type is a literal type if it is a union, and at least
     one of its non-static data members is of non-volatile literal type.  */
  if (TREE_CODE (t) == UNION_TYPE && found_nv_literal_p)
    CLASSTYPE_LITERAL_P (t) = true;

  /* Effective C++ rule 11: if a class has dynamic memory held by pointers,
     it should also define a copy constructor and an assignment operator to
     implement the correct copy semantic (deep vs shallow, etc.). As it is
     not feasible to check whether the constructors do allocate dynamic memory
     and store it within members, we approximate the warning like this:

     -- Warn only if there are members which are pointers
     -- Warn only if there is a non-trivial constructor (otherwise,
	there cannot be memory allocated).
     -- Warn only if there is a non-trivial destructor. We assume that the
	user at least implemented the cleanup correctly, and a destructor
	is needed to free dynamic memory.

     This seems enough for practical purposes.  */
  if (warn_ecpp
      && pointer_member
      && TYPE_HAS_USER_CONSTRUCTOR (t)
      && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t)
      && !(TYPE_HAS_COPY_CTOR (t) && TYPE_HAS_COPY_ASSIGN (t)))
    {
      if (warning (OPT_Weffc__, "%q#T has pointer data members", t))
	{
	  if (! TYPE_HAS_COPY_CTOR (t))
	    {
	      warning (OPT_Weffc__,
		       "  but does not declare %<%T(const %T&)%>", t, t);
	      if (!TYPE_HAS_COPY_ASSIGN (t))
		warning (OPT_Weffc__, "  or %<operator=(const %T&)%>", t);
	    }
	  else if (! TYPE_HAS_COPY_ASSIGN (t))
	    warning (OPT_Weffc__,
		     "  but does not declare %<operator=(const %T&)%>", t);
	  inform (DECL_SOURCE_LOCATION (pointer_member),
		  "pointer member %q+D declared here", pointer_member);
	}
    }

  /* Non-static data member initializers make the default constructor
     non-trivial.  */
  if (default_init_member)
    {
      TYPE_NEEDS_CONSTRUCTING (t) = true;
      TYPE_HAS_COMPLEX_DFLT (t) = true;
    }

  /* If any of the fields couldn't be packed, unset TYPE_PACKED.  */
  if (cant_pack)
    TYPE_PACKED (t) = 0;

  /* Check anonymous struct/anonymous union fields.  */
  finish_struct_anon (t);

  /* We've built up the list of access declarations in reverse order.
     Fix that now.  */
  *access_decls = nreverse (*access_decls);
}

/* If TYPE is an empty class type, records its OFFSET in the table of
   OFFSETS.  */

static int
record_subobject_offset (tree type, tree offset, splay_tree offsets)
{
  splay_tree_node n;

  if (!is_empty_class (type))
    return 0;

  /* Record the location of this empty object in OFFSETS.  */
  n = splay_tree_lookup (offsets, (splay_tree_key) offset);
  if (!n)
    n = splay_tree_insert (offsets,
			   (splay_tree_key) offset,
			   (splay_tree_value) NULL_TREE);
  n->value = ((splay_tree_value)
	      tree_cons (NULL_TREE,
			 type,
			 (tree) n->value));

  return 0;
}

/* Returns nonzero if TYPE is an empty class type and there is
   already an entry in OFFSETS for the same TYPE as the same OFFSET.  */

static int
check_subobject_offset (tree type, tree offset, splay_tree offsets)
{
  splay_tree_node n;
  tree t;

  if (!is_empty_class (type))
    return 0;

  /* Record the location of this empty object in OFFSETS.  */
  n = splay_tree_lookup (offsets, (splay_tree_key) offset);
  if (!n)
    return 0;

  for (t = (tree) n->value; t; t = TREE_CHAIN (t))
    if (same_type_p (TREE_VALUE (t), type))
      return 1;

  return 0;
}

/* Walk through all the subobjects of TYPE (located at OFFSET).  Call
   F for every subobject, passing it the type, offset, and table of
   OFFSETS.  If VBASES_P is one, then virtual non-primary bases should
   be traversed.

   If MAX_OFFSET is non-NULL, then subobjects with an offset greater
   than MAX_OFFSET will not be walked.

   If F returns a nonzero value, the traversal ceases, and that value
   is returned.  Otherwise, returns zero.  */

static int
walk_subobject_offsets (tree type,
			subobject_offset_fn f,
			tree offset,
			splay_tree offsets,
			tree max_offset,
			int vbases_p)
{
  int r = 0;
  tree type_binfo = NULL_TREE;

  /* If this OFFSET is bigger than the MAX_OFFSET, then we should
     stop.  */
  if (max_offset && tree_int_cst_lt (max_offset, offset))
    return 0;

  if (type == error_mark_node)
    return 0;

  if (!TYPE_P (type))
    {
      type_binfo = type;
      type = BINFO_TYPE (type);
    }

  if (CLASS_TYPE_P (type))
    {
      tree field;
      tree binfo;
      int i;

      /* Avoid recursing into objects that are not interesting.  */
      if (!CLASSTYPE_CONTAINS_EMPTY_CLASS_P (type))
	return 0;

      /* Record the location of TYPE.  */
      r = (*f) (type, offset, offsets);
      if (r)
	return r;

      /* Iterate through the direct base classes of TYPE.  */
      if (!type_binfo)
	type_binfo = TYPE_BINFO (type);
      for (i = 0; BINFO_BASE_ITERATE (type_binfo, i, binfo); i++)
	{
	  tree binfo_offset;

	  if (BINFO_VIRTUAL_P (binfo))
	    continue;

	  tree orig_binfo;
	  /* We cannot rely on BINFO_OFFSET being set for the base
	     class yet, but the offsets for direct non-virtual
	     bases can be calculated by going back to the TYPE.  */
	  orig_binfo = BINFO_BASE_BINFO (TYPE_BINFO (type), i);
	  binfo_offset = size_binop (PLUS_EXPR,
				     offset,
				     BINFO_OFFSET (orig_binfo));

	  r = walk_subobject_offsets (binfo,
				      f,
				      binfo_offset,
				      offsets,
				      max_offset,
				      /*vbases_p=*/0);
	  if (r)
	    return r;
	}

      if (CLASSTYPE_VBASECLASSES (type))
	{
	  unsigned ix;
	  vec<tree, va_gc> *vbases;

	  /* Iterate through the virtual base classes of TYPE.  In G++
	     3.2, we included virtual bases in the direct base class
	     loop above, which results in incorrect results; the
	     correct offsets for virtual bases are only known when
	     working with the most derived type.  */
	  if (vbases_p)
	    for (vbases = CLASSTYPE_VBASECLASSES (type), ix = 0;
		 vec_safe_iterate (vbases, ix, &binfo); ix++)
	      {
		r = walk_subobject_offsets (binfo,
					    f,
					    size_binop (PLUS_EXPR,
							offset,
							BINFO_OFFSET (binfo)),
					    offsets,
					    max_offset,
					    /*vbases_p=*/0);
		if (r)
		  return r;
	      }
	  else
	    {
	      /* We still have to walk the primary base, if it is
		 virtual.  (If it is non-virtual, then it was walked
		 above.)  */
	      tree vbase = get_primary_binfo (type_binfo);

	      if (vbase && BINFO_VIRTUAL_P (vbase)
		  && BINFO_PRIMARY_P (vbase)
		  && BINFO_INHERITANCE_CHAIN (vbase) == type_binfo)
		{
		  r = (walk_subobject_offsets
		       (vbase, f, offset,
			offsets, max_offset, /*vbases_p=*/0));
		  if (r)
		    return r;
		}
	    }
	}

      /* Iterate through the fields of TYPE.  */
      for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
	if (TREE_CODE (field) == FIELD_DECL
	    && TREE_TYPE (field) != error_mark_node
	    && !DECL_ARTIFICIAL (field))
	  {
	    tree field_offset;

	    field_offset = byte_position (field);

	    r = walk_subobject_offsets (TREE_TYPE (field),
					f,
					size_binop (PLUS_EXPR,
						    offset,
						    field_offset),
					offsets,
					max_offset,
					/*vbases_p=*/1);
	    if (r)
	      return r;
	  }
    }
  else if (TREE_CODE (type) == ARRAY_TYPE)
    {
      tree element_type = strip_array_types (type);
      tree domain = TYPE_DOMAIN (type);
      tree index;

      /* Avoid recursing into objects that are not interesting.  */
      if (!CLASS_TYPE_P (element_type)
	  || !CLASSTYPE_CONTAINS_EMPTY_CLASS_P (element_type)
	  || !domain
	  || integer_minus_onep (TYPE_MAX_VALUE (domain)))
	return 0;

      /* Step through each of the elements in the array.  */
      for (index = size_zero_node;
	   !tree_int_cst_lt (TYPE_MAX_VALUE (domain), index);
	   index = size_binop (PLUS_EXPR, index, size_one_node))
	{
	  r = walk_subobject_offsets (TREE_TYPE (type),
				      f,
				      offset,
				      offsets,
				      max_offset,
				      /*vbases_p=*/1);
	  if (r)
	    return r;
	  offset = size_binop (PLUS_EXPR, offset,
			       TYPE_SIZE_UNIT (TREE_TYPE (type)));
	  /* If this new OFFSET is bigger than the MAX_OFFSET, then
	     there's no point in iterating through the remaining
	     elements of the array.  */
	  if (max_offset && tree_int_cst_lt (max_offset, offset))
	    break;
	}
    }

  return 0;
}

/* Return true iff FIELD_DECL DECL is potentially overlapping.  */

static bool
field_poverlapping_p (tree decl)
{
  /* Base fields are actually potentially overlapping, but C++ bases go through
     a different code path based on binfos, and ObjC++ base fields are laid out
     in objc-act, so we don't want layout_class_type to mess with them.  */
  if (DECL_FIELD_IS_BASE (decl))
    {
      gcc_checking_assert (c_dialect_objc ());
      return false;
    }

  return lookup_attribute ("no_unique_address",
			   DECL_ATTRIBUTES (decl));
}

/* Return true iff DECL is an empty field, either for an empty base or a
   [[no_unique_address]] data member.  */

bool
is_empty_field (tree decl)
{
  if (!decl || TREE_CODE (decl) != FIELD_DECL)
    return false;

  bool r = (is_empty_class (TREE_TYPE (decl))
	    && (DECL_FIELD_IS_BASE (decl)
		|| field_poverlapping_p (decl)));

  /* Empty fields should have size zero.  */
  gcc_checking_assert (!r || integer_zerop (DECL_SIZE (decl)));

  return r;
}

/* Record all of the empty subobjects of DECL_OR_BINFO.  */

static void
record_subobject_offsets (tree decl_or_binfo,
			  splay_tree offsets)
{
  tree type, offset;
  bool overlapping, vbases_p;

  if (DECL_P (decl_or_binfo))
    {
      tree decl = decl_or_binfo;
      type = TREE_TYPE (decl);
      offset = byte_position (decl);
      overlapping = field_poverlapping_p (decl);
      vbases_p = true;
    }
  else
    {
      type = BINFO_TYPE (decl_or_binfo);
      offset = BINFO_OFFSET (decl_or_binfo);
      overlapping = true;
      vbases_p = false;
    }

  tree max_offset;
  /* If recording subobjects for a non-static data member or a
     non-empty base class, we do not need to record offsets beyond
     the size of the biggest empty class.  Additional data members
     will go at the end of the class.  Additional base classes will go
     either at offset zero (if empty, in which case they cannot
     overlap with offsets past the size of the biggest empty class) or
     at the end of the class.

     However, if we are placing an empty base class, then we must record
     all offsets, as either the empty class is at offset zero (where
     other empty classes might later be placed) or at the end of the
     class (where other objects might then be placed, so other empty
     subobjects might later overlap).  */
  if (!overlapping
      || !is_empty_class (type))
    max_offset = sizeof_biggest_empty_class;
  else
    max_offset = NULL_TREE;
  walk_subobject_offsets (type, record_subobject_offset, offset,
			  offsets, max_offset, vbases_p);
}

/* Returns nonzero if any of the empty subobjects of TYPE (located at
   OFFSET) conflict with entries in OFFSETS.  If VBASES_P is nonzero,
   virtual bases of TYPE are examined.  */

static int
layout_conflict_p (tree type,
		   tree offset,
		   splay_tree offsets,
		   int vbases_p)
{
  splay_tree_node max_node;

  /* Get the node in OFFSETS that indicates the maximum offset where
     an empty subobject is located.  */
  max_node = splay_tree_max (offsets);
  /* If there aren't any empty subobjects, then there's no point in
     performing this check.  */
  if (!max_node)
    return 0;

  return walk_subobject_offsets (type, check_subobject_offset, offset,
				 offsets, (tree) (max_node->key),
				 vbases_p);
}

/* DECL is a FIELD_DECL corresponding either to a base subobject of a
   non-static data member of the type indicated by RLI.  BINFO is the
   binfo corresponding to the base subobject, OFFSETS maps offsets to
   types already located at those offsets.  This function determines
   the position of the DECL.  */

static void
layout_nonempty_base_or_field (record_layout_info rli,
			       tree decl,
			       tree binfo,
			       splay_tree offsets)
{
  tree offset = NULL_TREE;
  bool field_p;
  tree type;

  if (binfo)
    {
      /* For the purposes of determining layout conflicts, we want to
	 use the class type of BINFO; TREE_TYPE (DECL) will be the
	 CLASSTYPE_AS_BASE version, which does not contain entries for
	 zero-sized bases.  */
      type = TREE_TYPE (binfo);
      field_p = false;
    }
  else
    {
      type = TREE_TYPE (decl);
      field_p = true;
    }

  /* Try to place the field.  It may take more than one try if we have
     a hard time placing the field without putting two objects of the
     same type at the same address.  */
  while (1)
    {
      struct record_layout_info_s old_rli = *rli;

      /* Place this field.  */
      place_field (rli, decl);
      offset = byte_position (decl);

      /* We have to check to see whether or not there is already
	 something of the same type at the offset we're about to use.
	 For example, consider:

	   struct S {};
	   struct T : public S { int i; };
	   struct U : public S, public T {};

	 Here, we put S at offset zero in U.  Then, we can't put T at
	 offset zero -- its S component would be at the same address
	 as the S we already allocated.  So, we have to skip ahead.
	 Since all data members, including those whose type is an
	 empty class, have nonzero size, any overlap can happen only
	 with a direct or indirect base-class -- it can't happen with
	 a data member.  */
      /* In a union, overlap is permitted; all members are placed at
	 offset zero.  */
      if (TREE_CODE (rli->t) == UNION_TYPE)
	break;
      if (layout_conflict_p (field_p ? type : binfo, offset,
			     offsets, field_p))
	{
	  /* Strip off the size allocated to this field.  That puts us
	     at the first place we could have put the field with
	     proper alignment.  */
	  *rli = old_rli;

	  /* Bump up by the alignment required for the type.  */
	  rli->bitpos
	    = size_binop (PLUS_EXPR, rli->bitpos,
			  bitsize_int (binfo
				       ? CLASSTYPE_ALIGN (type)
				       : TYPE_ALIGN (type)));
	  normalize_rli (rli);
	}
      else if (TREE_CODE (type) == NULLPTR_TYPE
	       && warn_abi && abi_version_crosses (9))
	{
	  /* Before ABI v9, we were giving nullptr_t alignment of 1; if
	     the offset wasn't aligned like a pointer when we started to
	     layout this field, that affects its position.  */
	  tree pos = rli_size_unit_so_far (&old_rli);
	  if (int_cst_value (pos) % TYPE_ALIGN_UNIT (ptr_type_node) != 0)
	    {
	      if (abi_version_at_least (9))
		warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wabi,
			    "alignment of %qD increased in %<-fabi-version=9%> "
			    "(GCC 5.2)", decl);
	      else
		warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wabi, "alignment "
			    "of %qD will increase in %<-fabi-version=9%>",
			    decl);
	    }
	  break;
	}
      else
	/* There was no conflict.  We're done laying out this field.  */
	break;
    }

  /* Now that we know where it will be placed, update its
     BINFO_OFFSET.  */
  if (binfo && CLASS_TYPE_P (BINFO_TYPE (binfo)))
    /* Indirect virtual bases may have a nonzero BINFO_OFFSET at
       this point because their BINFO_OFFSET is copied from another
       hierarchy.  Therefore, we may not need to add the entire
       OFFSET.  */
    propagate_binfo_offsets (binfo,
			     size_diffop_loc (input_location,
					  fold_convert (ssizetype, offset),
					  fold_convert (ssizetype,
						   BINFO_OFFSET (binfo))));
}

/* Returns true if TYPE is empty and OFFSET is nonzero.  */

static int
empty_base_at_nonzero_offset_p (tree type,
				tree offset,
				splay_tree /*offsets*/)
{
  return is_empty_class (type) && !integer_zerop (offset);
}

/* Layout the empty base BINFO.  EOC indicates the byte currently just
   past the end of the class, and should be correctly aligned for a
   class of the type indicated by BINFO; OFFSETS gives the offsets of
   the empty bases allocated so far. T is the most derived
   type.  Return nonzero iff we added it at the end.  */

static bool
layout_empty_base_or_field (record_layout_info rli, tree binfo_or_decl,
			    splay_tree offsets)
{
  tree alignment;
  bool atend = false;
  tree binfo = NULL_TREE;
  tree decl = NULL_TREE;
  tree type;
  if (TREE_CODE (binfo_or_decl) == TREE_BINFO)
    {
      binfo = binfo_or_decl;
      type = BINFO_TYPE (binfo);
    }
  else
    {
      decl = binfo_or_decl;
      type = TREE_TYPE (decl);
    }

  /* On some platforms (ARM), even empty classes will not be
     byte-aligned.  */
  tree eoc = round_up_loc (input_location,
			   rli_size_unit_so_far (rli),
			   CLASSTYPE_ALIGN_UNIT (type));

  /* This routine should only be used for empty classes.  */
  gcc_assert (is_empty_class (type));

  if (decl && DECL_USER_ALIGN (decl))
    alignment = size_int (DECL_ALIGN_UNIT (decl));
  else
    alignment = size_int (CLASSTYPE_ALIGN_UNIT (type));

  /* This is an empty base class.  We first try to put it at offset
     zero.  */
  tree offset = size_zero_node;
  if (TREE_CODE (rli->t) != UNION_TYPE
      && layout_conflict_p (type,
			    offset,
			    offsets,
			    /*vbases_p=*/0))
    {
      /* That didn't work.  Now, we move forward from the next
	 available spot in the class.  */
      atend = true;
      offset = eoc;
      while (1)
	{
	  if (!layout_conflict_p (type,
				  offset,
				  offsets,
				  /*vbases_p=*/0))
	    /* We finally found a spot where there's no overlap.  */
	    break;

	  /* There's overlap here, too.  Bump along to the next spot.  */
	  offset = size_binop (PLUS_EXPR, offset, alignment);
	}
    }

  if (decl && DECL_USER_ALIGN (decl))
    {
      rli->record_align = MAX (rli->record_align, DECL_ALIGN (decl));
      if (warn_packed)
	rli->unpacked_align = MAX (rli->unpacked_align, DECL_ALIGN (decl));
      TYPE_USER_ALIGN (rli->t) = 1;
    }
  else if (CLASSTYPE_USER_ALIGN (type))
    {
      rli->record_align = MAX (rli->record_align, CLASSTYPE_ALIGN (type));
      if (warn_packed)
	rli->unpacked_align = MAX (rli->unpacked_align, CLASSTYPE_ALIGN (type));
      TYPE_USER_ALIGN (rli->t) = 1;
    }

  if (binfo)
    /* Adjust BINFO_OFFSET (binfo) to be exactly OFFSET.  */
    propagate_binfo_offsets (binfo,
			     size_diffop (offset, BINFO_OFFSET (binfo)));
  else
    {
      DECL_FIELD_OFFSET (decl) = offset;
      DECL_FIELD_BIT_OFFSET (decl) = bitsize_zero_node;
      SET_DECL_OFFSET_ALIGN (decl, BITS_PER_UNIT);
    }

  return atend;
}

/* Build the FIELD_DECL for BASETYPE as a base of T, add it to the chain of
   fields at NEXT_FIELD, and return it.  */

static tree
build_base_field_1 (tree t, tree binfo, tree access, tree *&next_field)
{
  /* Create the FIELD_DECL.  */
  tree basetype = BINFO_TYPE (binfo);
  tree as_base = CLASSTYPE_AS_BASE (basetype);
  gcc_assert (as_base);
  tree decl = build_decl (input_location, FIELD_DECL, NULL_TREE, as_base);

  DECL_ARTIFICIAL (decl) = 1;
  DECL_IGNORED_P (decl) = 1;
  DECL_FIELD_CONTEXT (decl) = t;
  if (is_empty_class (basetype))
    /* CLASSTYPE_SIZE is one byte, but the field needs to have size zero.  */
    DECL_SIZE (decl) = DECL_SIZE_UNIT (decl) = size_zero_node;
  else
    {
      DECL_SIZE (decl) = CLASSTYPE_SIZE (basetype);
      DECL_SIZE_UNIT (decl) = CLASSTYPE_SIZE_UNIT (basetype);
    }
  SET_DECL_ALIGN (decl, CLASSTYPE_ALIGN (basetype));
  DECL_USER_ALIGN (decl) = CLASSTYPE_USER_ALIGN (basetype);
  SET_DECL_MODE (decl, TYPE_MODE (basetype));
  DECL_FIELD_IS_BASE (decl) = 1;

  if (access == access_private_node)
    TREE_PRIVATE (decl) = true;
  else if (access == access_protected_node)
    TREE_PROTECTED (decl) = true;

  /* Add the new FIELD_DECL to the list of fields for T.  */
  DECL_CHAIN (decl) = *next_field;
  *next_field = decl;
  next_field = &DECL_CHAIN (decl);

  return decl;
}

/* Layout the base given by BINFO in the class indicated by RLI.
   *BASE_ALIGN is a running maximum of the alignments of
   any base class.  OFFSETS gives the location of empty base
   subobjects.  T is the most derived type.  Return nonzero if the new
   object cannot be nearly-empty.  A new FIELD_DECL is inserted at
   *NEXT_FIELD, unless BINFO is for an empty base class.

   Returns the location at which the next field should be inserted.  */

static tree *
build_base_field (record_layout_info rli, tree binfo, tree access,
		  splay_tree offsets, tree *next_field)
{
  tree t = rli->t;
  tree basetype = BINFO_TYPE (binfo);

  if (!COMPLETE_TYPE_P (basetype))
    /* This error is now reported in xref_tag, thus giving better
       location information.  */
    return next_field;

  /* Place the base class.  */
  if (!is_empty_class (basetype))
    {
      tree decl;

      /* The containing class is non-empty because it has a non-empty
	 base class.  */
      CLASSTYPE_EMPTY_P (t) = 0;

      /* Create the FIELD_DECL.  */
      decl = build_base_field_1 (t, binfo, access, next_field);

      /* Try to place the field.  It may take more than one try if we
	 have a hard time placing the field without putting two
	 objects of the same type at the same address.  */
      layout_nonempty_base_or_field (rli, decl, binfo, offsets);
    }
  else
    {
      bool atend = layout_empty_base_or_field (rli, binfo, offsets);
      /* A nearly-empty class "has no proper base class that is empty,
	 not morally virtual, and at an offset other than zero."  */
      if (!BINFO_VIRTUAL_P (binfo) && CLASSTYPE_NEARLY_EMPTY_P (t))
	{
	  if (atend)
	    CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
	  /* The check above (used in G++ 3.2) is insufficient because
	     an empty class placed at offset zero might itself have an
	     empty base at a nonzero offset.  */
	  else if (walk_subobject_offsets (basetype,
					   empty_base_at_nonzero_offset_p,
					   size_zero_node,
					   /*offsets=*/NULL,
					   /*max_offset=*/NULL_TREE,
					   /*vbases_p=*/true))
	    CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
	}

      /* We used to not create a FIELD_DECL for empty base classes because of
	 back end issues with overlapping FIELD_DECLs, but that doesn't seem to
	 be a problem anymore.  We need them to handle initialization of C++17
	 aggregate bases.  */
      if (cxx_dialect >= cxx17 && !BINFO_VIRTUAL_P (binfo))
	{
	  tree decl = build_base_field_1 (t, binfo, access, next_field);
	  DECL_FIELD_OFFSET (decl) = BINFO_OFFSET (binfo);
	  DECL_FIELD_BIT_OFFSET (decl) = bitsize_zero_node;
	  SET_DECL_OFFSET_ALIGN (decl, BITS_PER_UNIT);
	  DECL_FIELD_ABI_IGNORED (decl) = 1;
	}

      /* An empty virtual base causes a class to be non-empty
	 -- but in that case we do not need to clear CLASSTYPE_EMPTY_P
	 here because that was already done when the virtual table
	 pointer was created.  */
    }

  /* Record the offsets of BINFO and its base subobjects.  */
  record_subobject_offsets (binfo, offsets);

  return next_field;
}

/* Layout all of the non-virtual base classes.  Record empty
   subobjects in OFFSETS.  T is the most derived type.  Return nonzero
   if the type cannot be nearly empty.  The fields created
   corresponding to the base classes will be inserted at
   *NEXT_FIELD.  */

static void
build_base_fields (record_layout_info rli,
		   splay_tree offsets, tree *next_field)
{
  /* Chain to hold all the new FIELD_DECLs which stand in for base class
     subobjects.  */
  tree t = rli->t;
  tree binfo = TYPE_BINFO (t);
  int n_baseclasses = BINFO_N_BASE_BINFOS (binfo);

  /* The primary base class is always allocated first.  */
  const tree primary_binfo = CLASSTYPE_PRIMARY_BINFO (t);
  if (primary_binfo)
    {
      /* We need to walk BINFO_BASE_BINFO to find the access of the primary
	 base, if it is direct.  Indirect base fields are private.  */
      tree primary_access = access_private_node;
      for (int i = 0; i < n_baseclasses; ++i)
	{
	  tree base_binfo = BINFO_BASE_BINFO (binfo, i);
	  if (base_binfo == primary_binfo)
	    {
	      primary_access = BINFO_BASE_ACCESS (binfo, i);
	      break;
	    }
	}
      next_field = build_base_field (rli, primary_binfo,
				     primary_access,
				     offsets, next_field);
    }

  /* Now allocate the rest of the bases.  */
  for (int i = 0; i < n_baseclasses; ++i)
    {
      tree base_binfo = BINFO_BASE_BINFO (binfo, i);

      /* The primary base was already allocated above, so we don't
	 need to allocate it again here.  */
      if (base_binfo == primary_binfo)
       continue;

      /* Virtual bases are added at the end (a primary virtual base
	 will have already been added).  */
      if (BINFO_VIRTUAL_P (base_binfo))
	continue;

      next_field = build_base_field (rli, base_binfo,
				     BINFO_BASE_ACCESS (binfo, i),
				     offsets, next_field);
    }
}

/* Go through the TYPE_FIELDS of T issuing any appropriate
   diagnostics, figuring out which methods override which other
   methods, and so forth.  */

static void
check_methods (tree t)
{
  for (tree x = TYPE_FIELDS (t); x; x = DECL_CHAIN (x))
    if (DECL_DECLARES_FUNCTION_P (x))
      {
	check_for_override (x, t);

	if (DECL_PURE_VIRTUAL_P (x)
	    && (TREE_CODE (x) != FUNCTION_DECL || ! DECL_VINDEX (x)))
	  error ("initializer specified for non-virtual method %q+D", x);
	/* The name of the field is the original field name
	   Save this in auxiliary field for later overloading.  */
	if (TREE_CODE (x) == FUNCTION_DECL && DECL_VINDEX (x))
	  {
	    TYPE_POLYMORPHIC_P (t) = 1;
	    if (DECL_PURE_VIRTUAL_P (x))
	      vec_safe_push (CLASSTYPE_PURE_VIRTUALS (t), x);
	  }

	if (!DECL_VIRTUAL_P (x)
	    && lookup_attribute ("transaction_safe_dynamic",
				 DECL_ATTRIBUTES (x)))
	  error_at (DECL_SOURCE_LOCATION (x),
		    "%<transaction_safe_dynamic%> may only be specified for "
		    "a virtual function");
      }

  /* Check whether the eligible special member functions (P0848) are
     user-provided.  add_method arranged that the CLASSTYPE_MEMBER_VEC only
     has the eligible ones; TYPE_FIELDS also contains ineligible overloads,
     which is why this needs to be separate from the loop above.  */

  if (tree dtor = CLASSTYPE_DESTRUCTOR (t))
    {
      if (TREE_CODE (dtor) == OVERLOAD)
	{
	  /* P0848: At the end of the definition of a class, overload
	     resolution is performed among the prospective destructors declared
	     in that class with an empty argument list to select the destructor
	     for the class, also known as the selected destructor. The program
	     is ill-formed if overload resolution fails. */
	  auto_diagnostic_group d;
	  error_at (location_of (t), "destructor for %qT is ambiguous", t);
	  print_candidates (dtor);
	}
      else if (user_provided_p (dtor))
	TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) = true;
    }

  for (tree fn : ovl_range (CLASSTYPE_CONSTRUCTORS (t)))
    {
      if (!user_provided_p (fn))
	/* Might be trivial.  */;
      else if (copy_fn_p (fn))
	TYPE_HAS_COMPLEX_COPY_CTOR (t) = true;
      else if (move_fn_p (fn))
	TYPE_HAS_COMPLEX_MOVE_CTOR (t) = true;
    }

  for (tree fn : ovl_range (get_class_binding_direct (t, assign_op_identifier)))
    {
      if (!user_provided_p (fn))
	/* Might be trivial.  */;
      else if (copy_fn_p (fn))
	TYPE_HAS_COMPLEX_COPY_ASSIGN (t) = true;
      else if (move_fn_p (fn))
	TYPE_HAS_COMPLEX_MOVE_ASSIGN (t) = true;
    }
}

/* FN is constructor, destructor or operator function.  Clone the
   declaration to create a NAME'd variant.  NEED_VTT_PARM_P and
   OMIT_INHERITED_PARMS_P are relevant if it's a cdtor.  */

static tree
copy_fndecl_with_name (tree fn, tree name, tree_code code,
		       bool need_vtt_parm_p, bool omit_inherited_parms_p)
{
  /* Copy the function.  */
  tree clone = copy_decl (fn);
  /* Reset the function name.  */
  DECL_NAME (clone) = name;

  if (flag_concepts)
    /* Clone constraints.  */
    if (tree ci = get_constraints (fn))
      set_constraints (clone, copy_node (ci));

  SET_DECL_ASSEMBLER_NAME (clone, NULL_TREE);
  /* There's no pending inline data for this function.  */
  DECL_PENDING_INLINE_INFO (clone) = NULL;
  DECL_PENDING_INLINE_P (clone) = 0;

  if (name == base_dtor_identifier)
    {
      /* The base-class destructor is not virtual.  */
      DECL_VIRTUAL_P (clone) = 0;
      DECL_VINDEX (clone) = NULL_TREE;
    }
  else if (code != ERROR_MARK)
    {
      /* Set the operator code.  */
      const ovl_op_info_t *ovl_op = OVL_OP_INFO (false, code);
      DECL_OVERLOADED_OPERATOR_CODE_RAW (clone) = ovl_op->ovl_op_code;

      /* The operator could be virtual.  */
      if (DECL_VIRTUAL_P (clone))
	IDENTIFIER_VIRTUAL_P (name) = true;
   }

  if (omit_inherited_parms_p)
    gcc_assert (DECL_HAS_IN_CHARGE_PARM_P (clone));

  /* If there was an in-charge parameter, drop it from the function
     type.  */
  if (DECL_HAS_IN_CHARGE_PARM_P (clone))
    {
      tree basetype = TYPE_METHOD_BASETYPE (TREE_TYPE (clone));
      tree parmtypes = TYPE_ARG_TYPES (TREE_TYPE (clone));
      /* Skip the `this' parameter.  */
      parmtypes = TREE_CHAIN (parmtypes);
      /* Skip the in-charge parameter.  */
      parmtypes = TREE_CHAIN (parmtypes);
      /* And the VTT parm, in a complete [cd]tor.  */
      if (DECL_HAS_VTT_PARM_P (fn) && !need_vtt_parm_p)
	parmtypes = TREE_CHAIN (parmtypes);
      if (omit_inherited_parms_p)
	{
	  /* If we're omitting inherited parms, that just leaves the VTT.  */
	  gcc_assert (need_vtt_parm_p);
	  parmtypes = tree_cons (NULL_TREE, vtt_parm_type, void_list_node);
	}
      TREE_TYPE (clone)
	= build_method_type_directly (basetype,
				      TREE_TYPE (TREE_TYPE (clone)),
				      parmtypes);
      TREE_TYPE (clone)
	= cp_build_type_attribute_variant (TREE_TYPE (clone),
					   TYPE_ATTRIBUTES (TREE_TYPE (fn)));
      TREE_TYPE (clone)
	= cxx_copy_lang_qualifiers (TREE_TYPE (clone), TREE_TYPE (fn));
    }

  /* Copy the function parameters.  */
  DECL_ARGUMENTS (clone) = copy_list (DECL_ARGUMENTS (clone));

  /* Remove the in-charge parameter.  */
  if (DECL_HAS_IN_CHARGE_PARM_P (clone))
    {
      DECL_CHAIN (DECL_ARGUMENTS (clone))
	= DECL_CHAIN (DECL_CHAIN (DECL_ARGUMENTS (clone)));
      DECL_HAS_IN_CHARGE_PARM_P (clone) = 0;
    }

  /* And the VTT parm, in a complete [cd]tor.  */
  if (DECL_HAS_VTT_PARM_P (fn))
    {
      if (need_vtt_parm_p)
	DECL_HAS_VTT_PARM_P (clone) = 1;
      else
	{
	  DECL_CHAIN (DECL_ARGUMENTS (clone))
	    = DECL_CHAIN (DECL_CHAIN (DECL_ARGUMENTS (clone)));
	  DECL_HAS_VTT_PARM_P (clone) = 0;
	}
    }

  /* A base constructor inheriting from a virtual base doesn't get the
     arguments.  */
  if (omit_inherited_parms_p)
    DECL_CHAIN (DECL_CHAIN (DECL_ARGUMENTS (clone))) = NULL_TREE;

  for (tree parms = DECL_ARGUMENTS (clone); parms; parms = DECL_CHAIN (parms))
    {
      DECL_CONTEXT (parms) = clone;
      cxx_dup_lang_specific_decl (parms);
    }

  /* Create the RTL for this function.  */
  SET_DECL_RTL (clone, NULL);

  /* Regardless of the current scope, this is a member function, so
     not at namespace scope.  */
  rest_of_decl_compilation (clone, /*top_level=*/0, at_eof);

  return clone;
}

/* FN is an operator function, create a variant for CODE.  */

tree
copy_operator_fn (tree fn, tree_code code)
{
  return copy_fndecl_with_name (fn, ovl_op_identifier (code),
				code, false, false);
}

/* FN is a constructor or destructor.  Clone the declaration to create
   a specialized in-charge or not-in-charge version, as indicated by
   NAME.  */

static tree
build_clone (tree fn, tree name, bool need_vtt_parm_p,
	     bool omit_inherited_parms_p)
{
  tree clone;

  /* If this is a template, do the rest on the DECL_TEMPLATE_RESULT.  */
  if (TREE_CODE (fn) == TEMPLATE_DECL)
    {
      clone = copy_decl (fn);
      DECL_NAME (clone) = name;

      tree result = build_clone (DECL_TEMPLATE_RESULT (clone), name,
				 need_vtt_parm_p, omit_inherited_parms_p);
      DECL_TEMPLATE_RESULT (clone) = result;

      DECL_TEMPLATE_INFO (result) = copy_node (DECL_TEMPLATE_INFO (result));
      DECL_TI_TEMPLATE (result) = clone;

      TREE_TYPE (clone) = TREE_TYPE (result);
    }
  else
    {
      clone = copy_fndecl_with_name (fn, name, ERROR_MARK,
				     need_vtt_parm_p, omit_inherited_parms_p);
      DECL_CLONED_FUNCTION (clone) = fn;
    }

  /* Remember where this function came from.  */
  DECL_ABSTRACT_ORIGIN (clone) = fn;

  /* Make it easy to find the CLONE given the FN.  Note the
     template_result of a template will be chained this way too.  */
  DECL_CHAIN (clone) = DECL_CHAIN (fn);
  DECL_CHAIN (fn) = clone;

  return clone;
}

/* Build the clones of FN, return the number of clones built.  These
   will be inserted onto DECL_CHAIN of FN.  */

void
build_cdtor_clones (tree fn, bool needs_vtt_p, bool base_omits_inherited_p,
		    bool update_methods)
{
  unsigned count = 0;

  if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn))
    {
      /* For each constructor, we need two variants: an in-charge version
	 and a not-in-charge version.  */
      build_clone (fn, complete_ctor_identifier, false, false);
      build_clone (fn, base_ctor_identifier, needs_vtt_p,
		   base_omits_inherited_p);
      count += 2;
    }
  else
    {
      gcc_assert (DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn));

      /* For each destructor, we need three variants: an in-charge
	 version, a not-in-charge version, and an in-charge deleting
	 version.  We clone the deleting version first because that
	 means it will go second on the TYPE_FIELDS list -- and that
	 corresponds to the correct layout order in the virtual
	 function table.

	 For a non-virtual destructor, we do not build a deleting
	 destructor.  */
      if (DECL_VIRTUAL_P (fn))
	{
	  build_clone (fn, deleting_dtor_identifier, false, false);
	  count++;
	}
      build_clone (fn, complete_dtor_identifier, false, false);
      build_clone (fn, base_dtor_identifier, needs_vtt_p, false);
      count += 2;
    }

  /* The original is now an abstract function that is never
     emitted.  */
  DECL_ABSTRACT_P (fn) = true;

  if (update_methods)
    for (tree clone = fn; count--;)
      {
	clone = DECL_CHAIN (clone);
	add_method (DECL_CONTEXT (clone), clone, false);
      }
}

/* Produce declarations for all appropriate clones of FN.  If
   UPDATE_METHODS is true, the clones are added to the
   CLASSTYPE_MEMBER_VEC.  */

void
clone_cdtor (tree fn, bool update_methods)
{
  /* Avoid inappropriate cloning.  */
  if (DECL_CHAIN (fn)
      && DECL_CLONED_FUNCTION_P (DECL_CHAIN (fn)))
    return;

  /* Base cdtors need a vtt parm if there are virtual bases.  */
  bool vtt = CLASSTYPE_VBASECLASSES (DECL_CONTEXT (fn));

  /* Base ctor omits inherited parms it needs a vttparm and inherited
     from a virtual nase ctor.  */
  bool base_omits_inherited = (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn)
			       && base_ctor_omit_inherited_parms (fn));

  build_cdtor_clones (fn, vtt, base_omits_inherited, update_methods);
}

/* DECL is an in charge constructor, which is being defined. This will
   have had an in class declaration, from whence clones were
   declared. An out-of-class definition can specify additional default
   arguments. As it is the clones that are involved in overload
   resolution, we must propagate the information from the DECL to its
   clones.  */

void
adjust_clone_args (tree decl)
{
  tree clone;

  for (clone = DECL_CHAIN (decl); clone && DECL_CLONED_FUNCTION_P (clone);
       clone = DECL_CHAIN (clone))
    {
      tree orig_clone_parms = TYPE_ARG_TYPES (TREE_TYPE (clone));
      tree orig_decl_parms = TYPE_ARG_TYPES (TREE_TYPE (decl));
      tree decl_parms, clone_parms;

      /* Skip the 'this' parameter.  */
      orig_clone_parms = TREE_CHAIN (orig_clone_parms);
      orig_decl_parms = TREE_CHAIN (orig_decl_parms);

      if (DECL_HAS_IN_CHARGE_PARM_P (decl))
	orig_decl_parms = TREE_CHAIN (orig_decl_parms);
      if (DECL_HAS_VTT_PARM_P (decl))
	orig_decl_parms = TREE_CHAIN (orig_decl_parms);

      clone_parms = orig_clone_parms;
      if (DECL_HAS_VTT_PARM_P (clone))
	clone_parms = TREE_CHAIN (clone_parms);

      for (decl_parms = orig_decl_parms; decl_parms;
	   decl_parms = TREE_CHAIN (decl_parms),
	     clone_parms = TREE_CHAIN (clone_parms))
	{
	  if (clone_parms == void_list_node)
	    {
	      gcc_assert (decl_parms == clone_parms
			  || ctor_omit_inherited_parms (clone));
	      break;
	    }

	  gcc_checking_assert (same_type_p (TREE_VALUE (decl_parms),
					    TREE_VALUE (clone_parms)));

	  if (TREE_PURPOSE (decl_parms) && !TREE_PURPOSE (clone_parms))
	    {
	      /* A default parameter has been added. Adjust the
		 clone's parameters.  */
	      clone_parms = orig_decl_parms;

	      if (DECL_HAS_VTT_PARM_P (clone))
		{
		  clone_parms = tree_cons (TREE_PURPOSE (orig_clone_parms),
					   TREE_VALUE (orig_clone_parms),
					   clone_parms);
		  TREE_TYPE (clone_parms) = TREE_TYPE (orig_clone_parms);
		}

	      tree basetype = TYPE_METHOD_BASETYPE (TREE_TYPE (clone));
	      tree type
		= build_method_type_directly (basetype,
					      TREE_TYPE (TREE_TYPE (clone)),
					      clone_parms);
	      if (tree attrs = TYPE_ATTRIBUTES (TREE_TYPE (clone)))
		type = cp_build_type_attribute_variant (type, attrs);
	      type = cxx_copy_lang_qualifiers (type, TREE_TYPE (clone));
	      TREE_TYPE (clone) = type;

	      clone_parms = NULL_TREE;
	      break;
	    }
	}
      gcc_assert (!clone_parms || clone_parms == void_list_node);
    }
}

/* For each of the constructors and destructors in T, create an
   in-charge and not-in-charge variant.  */

static void
clone_constructors_and_destructors (tree t)
{
  /* We do not need to propagate the usingness to the clone, at this
     point that is not needed.  */
  for (tree fn : ovl_range (CLASSTYPE_CONSTRUCTORS (t)))
    clone_cdtor (fn, /*update_methods=*/true);

  if (tree dtor = CLASSTYPE_DESTRUCTOR (t))
    clone_cdtor (dtor, /*update_methods=*/true);
}

/* Deduce noexcept for a destructor DTOR.  */

void
deduce_noexcept_on_destructor (tree dtor)
{
  if (!TYPE_RAISES_EXCEPTIONS (TREE_TYPE (dtor)))
    TREE_TYPE (dtor) = build_exception_variant (TREE_TYPE (dtor),
						noexcept_deferred_spec);
}

/* Subroutine of set_one_vmethod_tm_attributes.  Search base classes
   of TYPE for virtual functions which FNDECL overrides.  Return a
   mask of the tm attributes found therein.  */

static int
look_for_tm_attr_overrides (tree type, tree fndecl)
{
  tree binfo = TYPE_BINFO (type);
  tree base_binfo;
  int ix, found = 0;

  for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ++ix)
    {
      tree o, basetype = BINFO_TYPE (base_binfo);

      if (!TYPE_POLYMORPHIC_P (basetype))
	continue;

      o = look_for_overrides_here (basetype, fndecl);
      if (o)
	{
	  if (lookup_attribute ("transaction_safe_dynamic",
				DECL_ATTRIBUTES (o)))
	    /* transaction_safe_dynamic is not inherited.  */;
	  else
	    found |= tm_attr_to_mask (find_tm_attribute
				      (TYPE_ATTRIBUTES (TREE_TYPE (o))));
	}
      else
	found |= look_for_tm_attr_overrides (basetype, fndecl);
    }

  return found;
}

/* Subroutine of set_method_tm_attributes.  Handle the checks and
   inheritance for one virtual method FNDECL.  */

static void
set_one_vmethod_tm_attributes (tree type, tree fndecl)
{
  tree tm_attr;
  int found, have;

  found = look_for_tm_attr_overrides (type, fndecl);

  /* If FNDECL doesn't actually override anything (i.e. T is the
     class that first declares FNDECL virtual), then we're done.  */
  if (found == 0)
    return;

  tm_attr = find_tm_attribute (TYPE_ATTRIBUTES (TREE_TYPE (fndecl)));
  have = tm_attr_to_mask (tm_attr);

  /* Intel STM Language Extension 3.0, Section 4.2 table 4:
     tm_pure must match exactly, otherwise no weakening of
     tm_safe > tm_callable > nothing.  */
  /* ??? The tm_pure attribute didn't make the transition to the
     multivendor language spec.  */
  if (have == TM_ATTR_PURE)
    {
      if (found != TM_ATTR_PURE)
	{
	  found &= -found;
	  goto err_override;
	}
    }
  /* If the overridden function is tm_pure, then FNDECL must be.  */
  else if (found == TM_ATTR_PURE && tm_attr)
    goto err_override;
  /* Look for base class combinations that cannot be satisfied.  */
  else if (found != TM_ATTR_PURE && (found & TM_ATTR_PURE))
    {
      found &= ~TM_ATTR_PURE;
      found &= -found;
      error_at (DECL_SOURCE_LOCATION (fndecl),
		"method overrides both %<transaction_pure%> and %qE methods",
		tm_mask_to_attr (found));
    }
  /* If FNDECL did not declare an attribute, then inherit the most
     restrictive one.  */
  else if (tm_attr == NULL)
    {
      apply_tm_attr (fndecl, tm_mask_to_attr (least_bit_hwi (found)));
    }
  /* Otherwise validate that we're not weaker than a function
     that is being overridden.  */
  else
    {
      found &= -found;
      if (found <= TM_ATTR_CALLABLE && have > found)
	goto err_override;
    }
  return;

 err_override:
  error_at (DECL_SOURCE_LOCATION (fndecl),
	    "method declared %qE overriding %qE method",
	    tm_attr, tm_mask_to_attr (found));
}

/* For each of the methods in T, propagate a class-level tm attribute.  */

static void
set_method_tm_attributes (tree t)
{
  tree class_tm_attr, fndecl;

  /* Don't bother collecting tm attributes if transactional memory
     support is not enabled.  */
  if (!flag_tm)
    return;

  /* Process virtual methods first, as they inherit directly from the
     base virtual function and also require validation of new attributes.  */
  if (TYPE_CONTAINS_VPTR_P (t))
    {
      tree vchain;
      for (vchain = BINFO_VIRTUALS (TYPE_BINFO (t)); vchain;
	   vchain = TREE_CHAIN (vchain))
	{
	  fndecl = BV_FN (vchain);
	  if (DECL_THUNK_P (fndecl))
	    fndecl = THUNK_TARGET (fndecl);
	  set_one_vmethod_tm_attributes (t, fndecl);
	}
    }

  /* If the class doesn't have an attribute, nothing more to do.  */
  class_tm_attr = find_tm_attribute (TYPE_ATTRIBUTES (t));
  if (class_tm_attr == NULL)
    return;

  /* Any method that does not yet have a tm attribute inherits
     the one from the class.  */
  for (fndecl = TYPE_FIELDS (t); fndecl; fndecl = DECL_CHAIN (fndecl))
    if (DECL_DECLARES_FUNCTION_P (fndecl)
	&& !find_tm_attribute (TYPE_ATTRIBUTES (TREE_TYPE (fndecl))))
      apply_tm_attr (fndecl, class_tm_attr);
}

/* Returns true if FN is a default constructor.  */

bool
default_ctor_p (const_tree fn)
{
  return (DECL_CONSTRUCTOR_P (fn)
	  && sufficient_parms_p (FUNCTION_FIRST_USER_PARMTYPE (fn)));
}

/* Returns true iff class T has a user-provided constructor that can be called
   with more than zero arguments.  */

bool
type_has_user_nondefault_constructor (tree t)
{
  if (!TYPE_HAS_USER_CONSTRUCTOR (t))
    return false;

  for (tree fn : ovl_range (CLASSTYPE_CONSTRUCTORS (t)))
    {
      if (user_provided_p (fn)
	  && (TREE_CODE (fn) == TEMPLATE_DECL
	      || (skip_artificial_parms_for (fn, DECL_ARGUMENTS (fn))
		  != NULL_TREE)))
	return true;
    }

  return false;
}

/* Returns the defaulted constructor if T has one. Otherwise, returns
   NULL_TREE.  */

tree
in_class_defaulted_default_constructor (tree t)
{
  if (!TYPE_HAS_USER_CONSTRUCTOR (t))
    return NULL_TREE;

  for (ovl_iterator iter (CLASSTYPE_CONSTRUCTORS (t)); iter; ++iter)
    {
      tree fn = *iter;

      if (DECL_DEFAULTED_IN_CLASS_P (fn)
	  && default_ctor_p (fn))
	return fn;
    }

  return NULL_TREE;
}

/* Returns true iff FN is a user-provided function, i.e. user-declared
   and not defaulted at its first declaration.  */

bool
user_provided_p (tree fn)
{
  fn = STRIP_TEMPLATE (fn);
  return (!DECL_ARTIFICIAL (fn)
	  && !(DECL_INITIALIZED_IN_CLASS_P (fn)
	       && (DECL_DEFAULTED_FN (fn) || DECL_DELETED_FN (fn))));
}

/* Returns true iff class T has a user-provided constructor.  */

bool
type_has_user_provided_constructor (tree t)
{
  if (!CLASS_TYPE_P (t))
    return false;

  if (!TYPE_HAS_USER_CONSTRUCTOR (t))
    return false;

  for (ovl_iterator iter (CLASSTYPE_CONSTRUCTORS (t)); iter; ++iter)
    if (user_provided_p (*iter))
      return true;

  return false;
}

/* Returns true iff class T has a user-provided or explicit constructor.  */

bool
type_has_user_provided_or_explicit_constructor (tree t)
{
  if (!CLASS_TYPE_P (t))
    return false;

  if (!TYPE_HAS_USER_CONSTRUCTOR (t))
    return false;

  for (ovl_iterator iter (CLASSTYPE_CONSTRUCTORS (t)); iter; ++iter)
    {
      tree fn = *iter;
      if (user_provided_p (fn) || DECL_NONCONVERTING_P (fn))
	return true;
    }

  return false;
}

/* Returns true iff class T has a non-user-provided (i.e. implicitly
   declared or explicitly defaulted in the class body) default
   constructor.  */

bool
type_has_non_user_provided_default_constructor (tree t)
{
  if (!TYPE_HAS_DEFAULT_CONSTRUCTOR (t))
    return false;
  if (CLASSTYPE_LAZY_DEFAULT_CTOR (t))
    return true;

  for (ovl_iterator iter (CLASSTYPE_CONSTRUCTORS (t)); iter; ++iter)
    {
      tree fn = *iter;
      if (TREE_CODE (fn) == FUNCTION_DECL
	  && default_ctor_p (fn)
	  && !user_provided_p (fn))
	return true;
    }

  return false;
}

/* TYPE is being used as a virtual base, and has a non-trivial move
   assignment.  Return true if this is due to there being a user-provided
   move assignment in TYPE or one of its subobjects; if there isn't, then
   multiple move assignment can't cause any harm.  */

bool
vbase_has_user_provided_move_assign (tree type)
{
  /* Does the type itself have a user-provided move assignment operator?  */
  if (!CLASSTYPE_LAZY_MOVE_ASSIGN (type))
    for (ovl_iterator iter (get_class_binding_direct
			    (type, assign_op_identifier));
	 iter; ++iter)
      if (user_provided_p (*iter) && move_fn_p (*iter))
	return true;

  /* Do any of its bases?  */
  tree binfo = TYPE_BINFO (type);
  tree base_binfo;
  for (int i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
    if (vbase_has_user_provided_move_assign (BINFO_TYPE (base_binfo)))
      return true;

  /* Or non-static data members?  */
  for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
    {
      if (TREE_CODE (field) == FIELD_DECL
	  && CLASS_TYPE_P (TREE_TYPE (field))
	  && vbase_has_user_provided_move_assign (TREE_TYPE (field)))
	return true;
    }

  /* Seems not.  */
  return false;
}

/* If default-initialization leaves part of TYPE uninitialized, returns
   a DECL for the field or TYPE itself (DR 253).  */

tree
default_init_uninitialized_part (tree type)
{
  tree t, r, binfo;
  int i;

  type = strip_array_types (type);
  if (!CLASS_TYPE_P (type))
    return type;
  if (!type_has_non_user_provided_default_constructor (type))
    return NULL_TREE;
  for (binfo = TYPE_BINFO (type), i = 0;
       BINFO_BASE_ITERATE (binfo, i, t); ++i)
    {
      r = default_init_uninitialized_part (BINFO_TYPE (t));
      if (r)
	return r;
    }
  for (t = TYPE_FIELDS (type); t; t = DECL_CHAIN (t))
    if (TREE_CODE (t) == FIELD_DECL
	&& !DECL_ARTIFICIAL (t)
	&& !DECL_INITIAL (t))
      {
	r = default_init_uninitialized_part (TREE_TYPE (t));
	if (r)
	  return DECL_P (r) ? r : t;
      }

  return NULL_TREE;
}

/* Returns true iff for class T, a trivial synthesized default constructor
   would be constexpr.  */

bool
trivial_default_constructor_is_constexpr (tree t)
{
  /* A defaulted trivial default constructor is constexpr
     if there is nothing to initialize.  */
  gcc_assert (!TYPE_HAS_COMPLEX_DFLT (t));
  /* A class with a vptr doesn't have a trivial default ctor.
     In C++20, a class can have transient uninitialized members, e.g.:

       struct S { int i; constexpr S() = default; };

     should work.  */
  return (cxx_dialect >= cxx20
	  || is_really_empty_class (t, /*ignore_vptr*/true));
}

/* Returns true iff class T has a constexpr default constructor.  */

bool
type_has_constexpr_default_constructor (tree t)
{
  tree fns;

  if (!CLASS_TYPE_P (t))
    {
      /* The caller should have stripped an enclosing array.  */
      gcc_assert (TREE_CODE (t) != ARRAY_TYPE);
      return false;
    }
  if (CLASSTYPE_LAZY_DEFAULT_CTOR (t))
    {
      if (!TYPE_HAS_COMPLEX_DFLT (t))
	return trivial_default_constructor_is_constexpr (t);
      /* Non-trivial, we need to check subobject constructors.  */
      lazily_declare_fn (sfk_constructor, t);
    }
  fns = locate_ctor (t);
  return (fns && DECL_DECLARED_CONSTEXPR_P (fns));
}

/* Returns true iff class T has a constexpr default constructor or has an
   implicitly declared default constructor that we can't tell if it's constexpr
   without forcing a lazy declaration (which might cause undesired
   instantiations).  */

static bool
type_maybe_constexpr_default_constructor (tree t)
{
  if (CLASS_TYPE_P (t) && CLASSTYPE_LAZY_DEFAULT_CTOR (t)
      && TYPE_HAS_COMPLEX_DFLT (t))
    /* Assume it's constexpr.  */
    return true;
  return type_has_constexpr_default_constructor (t);
}

/* Returns true iff class T has a constexpr destructor.  */

bool
type_has_constexpr_destructor (tree t)
{
  tree fns;

  if (CLASSTYPE_LAZY_DESTRUCTOR (t))
    /* Non-trivial, we need to check subobject destructors.  */
    lazily_declare_fn (sfk_destructor, t);
  fns = CLASSTYPE_DESTRUCTOR (t);
  return (fns && DECL_DECLARED_CONSTEXPR_P (fns));
}

/* Returns true iff class T has a constexpr destructor or has an
   implicitly declared destructor that we can't tell if it's constexpr
   without forcing a lazy declaration (which might cause undesired
   instantiations).  */

static bool
type_maybe_constexpr_destructor (tree t)
{
  if (CLASS_TYPE_P (t) && CLASSTYPE_LAZY_DESTRUCTOR (t))
    /* Assume it's constexpr.  */
    return true;
  return type_has_constexpr_destructor (t);
}

/* Returns true iff class TYPE has a virtual destructor.  */

bool
type_has_virtual_destructor (tree type)
{
  tree dtor;

  if (!CLASS_TYPE_P (type))
    return false;

  gcc_assert (COMPLETE_TYPE_P (type));
  dtor = CLASSTYPE_DESTRUCTOR (type);
  return (dtor && DECL_VIRTUAL_P (dtor));
}

/* Returns true iff T, a class, has a move-assignment or
   move-constructor.  Does not lazily declare either.
   If USER_P is false, any move function will do.  If it is true, the
   move function must be user-declared.

   Note that user-declared here is different from "user-provided",
   which doesn't include functions that are defaulted in the
   class.  */

bool
classtype_has_move_assign_or_move_ctor_p (tree t, bool user_p)
{
  gcc_assert (user_p
	      || (!CLASSTYPE_LAZY_MOVE_CTOR (t)
		  && !CLASSTYPE_LAZY_MOVE_ASSIGN (t)));

  if (!CLASSTYPE_LAZY_MOVE_CTOR (t))
    for (ovl_iterator iter (CLASSTYPE_CONSTRUCTORS (t)); iter; ++iter)
      if ((!user_p || !DECL_ARTIFICIAL (*iter)) && move_fn_p (*iter))
	return true;

  if (!CLASSTYPE_LAZY_MOVE_ASSIGN (t))
    for (ovl_iterator iter (get_class_binding_direct
			    (t, assign_op_identifier));
	 iter; ++iter)
      if ((!user_p || !DECL_ARTIFICIAL (*iter))
	  && DECL_CONTEXT (*iter) == t
	  && move_fn_p (*iter))
	return true;
  
  return false;
}

/* True iff T has a move constructor that is not deleted.  */

bool
classtype_has_non_deleted_move_ctor (tree t)
{
  if (CLASSTYPE_LAZY_MOVE_CTOR (t))
    lazily_declare_fn (sfk_move_constructor, t);
  for (ovl_iterator iter (CLASSTYPE_CONSTRUCTORS (t)); iter; ++iter)
    if (move_fn_p (*iter) && !DECL_DELETED_FN (*iter))
      return true;
  return false;
}

/* If T, a class, has a user-provided copy constructor, copy assignment
   operator, or destructor, returns that function.  Otherwise, null.  */

tree
classtype_has_depr_implicit_copy (tree t)
{
  if (!CLASSTYPE_LAZY_COPY_CTOR (t))
    for (ovl_iterator iter (CLASSTYPE_CONSTRUCTORS (t)); iter; ++iter)
      {
	tree fn = *iter;
	if (user_provided_p (fn) && copy_fn_p (fn))
	  return fn;
      }

  if (!CLASSTYPE_LAZY_COPY_ASSIGN (t))
    for (ovl_iterator iter (get_class_binding_direct
			    (t, assign_op_identifier));
	 iter; ++iter)
      {
	tree fn = *iter;
	if (DECL_CONTEXT (fn) == t
	    && user_provided_p (fn) && copy_fn_p (fn))
	  return fn;
      }

  if (!CLASSTYPE_LAZY_DESTRUCTOR (t))
    {
      tree fn = CLASSTYPE_DESTRUCTOR (t);
      if (user_provided_p (fn))
	return fn;
    }

  return NULL_TREE;
}

/* True iff T has a member or friend declaration of operator OP.  */

bool
classtype_has_op (tree t, tree_code op)
{
  tree name = ovl_op_identifier (op);
  if (get_class_binding (t, name))
    return true;
  for (tree f = DECL_FRIENDLIST (TYPE_MAIN_DECL (t)); f; f = TREE_CHAIN (f))
    if (FRIEND_NAME (f) == name)
      return true;
  return false;
}


/* If T has a defaulted member or friend declaration of OP, return it.  */

tree
classtype_has_defaulted_op (tree t, tree_code op)
{
  tree name = ovl_op_identifier (op);
  for (ovl_iterator oi (get_class_binding (t, name)); oi; ++oi)
    {
      tree fn = *oi;
      if (DECL_DEFAULTED_FN (fn))
	return fn;
    }
  for (tree f = DECL_FRIENDLIST (TYPE_MAIN_DECL (t)); f; f = TREE_CHAIN (f))
    if (FRIEND_NAME (f) == name)
      for (tree l = FRIEND_DECLS (f); l; l = TREE_CHAIN (l))
	{
	  tree fn = TREE_VALUE (l);
	  if (DECL_DEFAULTED_FN (fn))
	    return fn;
	}
  return NULL_TREE;
}

/* Nonzero if we need to build up a constructor call when initializing an
   object of this class, either because it has a user-declared constructor
   or because it doesn't have a default constructor (so we need to give an
   error if no initializer is provided).  Use TYPE_NEEDS_CONSTRUCTING when
   what you care about is whether or not an object can be produced by a
   constructor (e.g. so we don't set TREE_READONLY on const variables of
   such type); use this function when what you care about is whether or not
   to try to call a constructor to create an object.  The latter case is
   the former plus some cases of constructors that cannot be called.  */

bool
type_build_ctor_call (tree t)
{
  tree inner;
  if (TYPE_NEEDS_CONSTRUCTING (t))
    return true;
  inner = strip_array_types (t);
  if (!CLASS_TYPE_P (inner) || ANON_AGGR_TYPE_P (inner))
    return false;
  if (!TYPE_HAS_DEFAULT_CONSTRUCTOR (inner))
    return true;
  if (cxx_dialect < cxx11)
    return false;
  /* A user-declared constructor might be private, and a constructor might
     be trivial but deleted.  */
  for (ovl_iterator iter (get_class_binding (inner, complete_ctor_identifier));
       iter; ++iter)
    {
      tree fn = *iter;
      if (!DECL_ARTIFICIAL (fn)
	  || TREE_DEPRECATED (fn)
	  || DECL_DELETED_FN (fn))
	return true;
    }
  return false;
}

/* Like type_build_ctor_call, but for destructors.  */

bool
type_build_dtor_call (tree t)
{
  tree inner;
  if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t))
    return true;
  inner = strip_array_types (t);
  if (!CLASS_TYPE_P (inner) || ANON_AGGR_TYPE_P (inner)
      || !COMPLETE_TYPE_P (inner))
    return false;
  if (cxx_dialect < cxx11)
    return false;
  /* A user-declared destructor might be private, and a destructor might
     be trivial but deleted.  */
  for (ovl_iterator iter (get_class_binding (inner, complete_dtor_identifier));
       iter; ++iter)
    {
      tree fn = *iter;
      if (!DECL_ARTIFICIAL (fn)
	  || TREE_DEPRECATED (fn)
	  || DECL_DELETED_FN (fn))
	return true;
    }
  return false;
}

/* Remove all zero-width bit-fields from T.  */

static void
remove_zero_width_bit_fields (tree t)
{
  tree *fieldsp;

  fieldsp = &TYPE_FIELDS (t);
  while (*fieldsp)
    {
      if (TREE_CODE (*fieldsp) == FIELD_DECL
	  && DECL_C_BIT_FIELD (*fieldsp)
	  /* We should not be confused by the fact that grokbitfield
	     temporarily sets the width of the bit field into
	     DECL_BIT_FIELD_REPRESENTATIVE (*fieldsp).
	     check_bitfield_decl eventually sets DECL_SIZE (*fieldsp)
	     to that width.  */
	  && (DECL_SIZE (*fieldsp) == NULL_TREE
	      || integer_zerop (DECL_SIZE (*fieldsp))))
	*fieldsp = DECL_CHAIN (*fieldsp);
      else
	fieldsp = &DECL_CHAIN (*fieldsp);
    }
}

/* Returns TRUE iff we need a cookie when dynamically allocating an
   array whose elements have the indicated class TYPE.  */

static bool
type_requires_array_cookie (tree type)
{
  tree fns;
  bool has_two_argument_delete_p = false;

  gcc_assert (CLASS_TYPE_P (type));

  /* If there's a non-trivial destructor, we need a cookie.  In order
     to iterate through the array calling the destructor for each
     element, we'll have to know how many elements there are.  */
  if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
    return true;

  /* If the usual deallocation function is a two-argument whose second
     argument is of type `size_t', then we have to pass the size of
     the array to the deallocation function, so we will need to store
     a cookie.  */
  fns = lookup_fnfields (TYPE_BINFO (type),
			 ovl_op_identifier (false, VEC_DELETE_EXPR),
			 /*protect=*/0, tf_warning_or_error);
  /* If there are no `operator []' members, or the lookup is
     ambiguous, then we don't need a cookie.  */
  if (!fns || fns == error_mark_node)
    return false;
  /* Loop through all of the functions.  */
  for (lkp_iterator iter (BASELINK_FUNCTIONS (fns)); iter; ++iter)
    {
      tree fn = *iter;

      /* See if this function is a one-argument delete function.  If
	 it is, then it will be the usual deallocation function.  */
      tree second_parm = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn)));
      if (second_parm == void_list_node)
	return false;
      /* Do not consider this function if its second argument is an
	 ellipsis.  */
      if (!second_parm)
	continue;
      /* Otherwise, if we have a two-argument function and the second
	 argument is `size_t', it will be the usual deallocation
	 function -- unless there is one-argument function, too.  */
      if (TREE_CHAIN (second_parm) == void_list_node
	  && same_type_p (TREE_VALUE (second_parm), size_type_node))
	has_two_argument_delete_p = true;
    }

  return has_two_argument_delete_p;
}

/* Finish computing the `literal type' property of class type T.

   At this point, we have already processed base classes and
   non-static data members.  We need to check whether the copy
   constructor is trivial, the destructor is trivial, and there
   is a trivial default constructor or at least one constexpr
   constructor other than the copy constructor.  */

static void
finalize_literal_type_property (tree t)
{
  tree fn;

  if (cxx_dialect < cxx11)
    CLASSTYPE_LITERAL_P (t) = false;
  else if (CLASSTYPE_LITERAL_P (t)
	   && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t)
	   && (cxx_dialect < cxx20 || !type_maybe_constexpr_destructor (t)))
    CLASSTYPE_LITERAL_P (t) = false;
  else if (CLASSTYPE_LITERAL_P (t) && LAMBDA_TYPE_P (t))
    CLASSTYPE_LITERAL_P (t) = (cxx_dialect >= cxx17);
  else if (CLASSTYPE_LITERAL_P (t) && !TYPE_HAS_TRIVIAL_DFLT (t)
	   && CLASSTYPE_NON_AGGREGATE (t)
	   && !TYPE_HAS_CONSTEXPR_CTOR (t))
    CLASSTYPE_LITERAL_P (t) = false;

  /* C++14 DR 1684 removed this restriction.  */
  if (cxx_dialect < cxx14
      && !CLASSTYPE_LITERAL_P (t) && !LAMBDA_TYPE_P (t))
    for (fn = TYPE_FIELDS (t); fn; fn = DECL_CHAIN (fn))
      if (TREE_CODE (fn) == FUNCTION_DECL
	  && DECL_DECLARED_CONSTEXPR_P (fn)
	  && DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)
	  && !DECL_CONSTRUCTOR_P (fn))
	{
	  DECL_DECLARED_CONSTEXPR_P (fn) = false;
	  if (!DECL_GENERATED_P (fn))
	    {
	      auto_diagnostic_group d;
	      if (pedwarn (DECL_SOURCE_LOCATION (fn), OPT_Wpedantic,
			     "enclosing class of %<constexpr%> non-static "
			     "member function %q+#D is not a literal type", fn))
		explain_non_literal_class (t);
	    }
	}
}

/* T is a non-literal type used in a context which requires a constant
   expression.  Explain why it isn't literal.  */

void
explain_non_literal_class (tree t)
{
  static hash_set<tree> *diagnosed;

  if (!CLASS_TYPE_P (t))
    return;
  t = TYPE_MAIN_VARIANT (t);

  if (diagnosed == NULL)
    diagnosed = new hash_set<tree>;
  if (diagnosed->add (t))
    /* Already explained.  */
    return;

  auto_diagnostic_group d;
  inform (UNKNOWN_LOCATION, "%q+T is not literal because:", t);
  if (cxx_dialect < cxx17 && LAMBDA_TYPE_P (t))
    inform (UNKNOWN_LOCATION,
	    "  %qT is a closure type, which is only literal in "
	    "C++17 and later", t);
  else if (cxx_dialect < cxx20 && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t))
    inform (UNKNOWN_LOCATION, "  %q+T has a non-trivial destructor", t);
  else if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t)
	   && !type_maybe_constexpr_destructor (t))
    inform (UNKNOWN_LOCATION, "  %q+T does not have %<constexpr%> destructor",
	    t);
  else if (CLASSTYPE_NON_AGGREGATE (t)
	   && !TYPE_HAS_TRIVIAL_DFLT (t)
	   && !LAMBDA_TYPE_P (t)
	   && !TYPE_HAS_CONSTEXPR_CTOR (t))
    {
      inform (UNKNOWN_LOCATION,
	      "  %q+T is not an aggregate, does not have a trivial "
	      "default constructor, and has no %<constexpr%> constructor that "
	      "is not a copy or move constructor", t);
      if (type_has_non_user_provided_default_constructor (t))
	/* Note that we can't simply call locate_ctor because when the
	   constructor is deleted it just returns NULL_TREE.  */
	for (ovl_iterator iter (CLASSTYPE_CONSTRUCTORS (t)); iter; ++iter)
	  {
	    tree fn = *iter;
	    tree parms = TYPE_ARG_TYPES (TREE_TYPE (fn));

	    parms = skip_artificial_parms_for (fn, parms);

	    if (sufficient_parms_p (parms))
	      {
		if (DECL_DELETED_FN (fn))
		  maybe_explain_implicit_delete (fn);
		else
		  explain_invalid_constexpr_fn (fn);
		break;
	      }
	}
    }
  else
    {
      tree binfo, base_binfo, field; int i;
      for (binfo = TYPE_BINFO (t), i = 0;
	   BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
	{
	  tree basetype = TREE_TYPE (base_binfo);
	  if (!CLASSTYPE_LITERAL_P (basetype))
	    {
	      inform (UNKNOWN_LOCATION,
		      "  base class %qT of %q+T is non-literal",
		      basetype, t);
	      explain_non_literal_class (basetype);
	      return;
	    }
	}
      for (field = TYPE_FIELDS (t); field; field = TREE_CHAIN (field))
	{
	  tree ftype;
	  if (TREE_CODE (field) != FIELD_DECL)
	    continue;
	  ftype = TREE_TYPE (field);
	  if (!literal_type_p (ftype))
	    {
	      inform (DECL_SOURCE_LOCATION (field),
		      "  non-static data member %qD has non-literal type",
		      field);
	      if (CLASS_TYPE_P (ftype))
		explain_non_literal_class (ftype);
	    }
	  if (CP_TYPE_VOLATILE_P (ftype))
	    inform (DECL_SOURCE_LOCATION (field),
		    "  non-static data member %qD has volatile type", field);
	}
    }
}

/* Check the validity of the bases and members declared in T.  Add any
   implicitly-generated functions (like copy-constructors and
   assignment operators).  Compute various flag bits (like
   CLASSTYPE_NON_LAYOUT_POD_T) for T.  This routine works purely at the C++
   level: i.e., independently of the ABI in use.  */

static void
check_bases_and_members (tree t)
{
  /* Nonzero if the implicitly generated copy constructor should take
     a non-const reference argument.  */
  int cant_have_const_ctor;
  /* Nonzero if the implicitly generated assignment operator
     should take a non-const reference argument.  */
  int no_const_asn_ref;
  tree access_decls;
  bool saved_complex_asn_ref;
  bool saved_nontrivial_dtor;
  tree fn;

  /* By default, we use const reference arguments and generate default
     constructors.  */
  cant_have_const_ctor = 0;
  no_const_asn_ref = 0;

  /* Check all the base-classes and set FMEM members to point to arrays
     of potential interest.  */
  check_bases (t, &cant_have_const_ctor, &no_const_asn_ref);

  /* Deduce noexcept on destructor.  This needs to happen after we've set
     triviality flags appropriately for our bases.  */
  if (cxx_dialect >= cxx11)
    if (tree dtor = CLASSTYPE_DESTRUCTOR (t))
      deduce_noexcept_on_destructor (dtor);

  /* Check all the method declarations.  */
  check_methods (t);

  /* Save the initial values of these flags which only indicate whether
     or not the class has user-provided functions.  As we analyze the
     bases and members we can set these flags for other reasons.  */
  saved_complex_asn_ref = TYPE_HAS_COMPLEX_COPY_ASSIGN (t);
  saved_nontrivial_dtor = TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t);

  /* Check all the data member declarations.  We cannot call
     check_field_decls until we have called check_bases check_methods,
     as check_field_decls depends on TYPE_HAS_NONTRIVIAL_DESTRUCTOR
     being set appropriately.  */
  check_field_decls (t, &access_decls,
		     &cant_have_const_ctor,
		     &no_const_asn_ref);

  /* A nearly-empty class has to be vptr-containing; a nearly empty
     class contains just a vptr.  */
  if (!TYPE_CONTAINS_VPTR_P (t))
    CLASSTYPE_NEARLY_EMPTY_P (t) = 0;

  /* Do some bookkeeping that will guide the generation of implicitly
     declared member functions.  */
  TYPE_HAS_COMPLEX_COPY_CTOR (t) |= TYPE_CONTAINS_VPTR_P (t);
  TYPE_HAS_COMPLEX_MOVE_CTOR (t) |= TYPE_CONTAINS_VPTR_P (t);
  /* We need to call a constructor for this class if it has a
     user-provided constructor, or if the default constructor is going
     to initialize the vptr.  (This is not an if-and-only-if;
     TYPE_NEEDS_CONSTRUCTING is set elsewhere if bases or members
     themselves need constructing.)  */
  TYPE_NEEDS_CONSTRUCTING (t)
    |= (type_has_user_provided_constructor (t) || TYPE_CONTAINS_VPTR_P (t));
  /* [dcl.init.aggr]

     An aggregate is an array or a class with no user-provided
     constructors ... and no virtual functions.  

     Again, other conditions for being an aggregate are checked
     elsewhere.  */
  CLASSTYPE_NON_AGGREGATE (t)
    |= ((cxx_dialect < cxx20
	 ? type_has_user_provided_or_explicit_constructor (t)
	 : TYPE_HAS_USER_CONSTRUCTOR (t))
	|| TYPE_POLYMORPHIC_P (t));
  /* This is the C++98/03 definition of POD; it changed in C++0x, but we
     retain the old definition internally for ABI reasons.  */
  CLASSTYPE_NON_LAYOUT_POD_P (t)
    |= (CLASSTYPE_NON_AGGREGATE (t)
	|| saved_nontrivial_dtor || saved_complex_asn_ref);
  CLASSTYPE_NON_STD_LAYOUT (t) |= TYPE_CONTAINS_VPTR_P (t);
  TYPE_HAS_COMPLEX_COPY_ASSIGN (t) |= TYPE_CONTAINS_VPTR_P (t);
  TYPE_HAS_COMPLEX_MOVE_ASSIGN (t) |= TYPE_CONTAINS_VPTR_P (t);
  TYPE_HAS_COMPLEX_DFLT (t) |= TYPE_CONTAINS_VPTR_P (t);

  /* If the only explicitly declared default constructor is user-provided,
     set TYPE_HAS_COMPLEX_DFLT.  */
  if (!TYPE_HAS_COMPLEX_DFLT (t)
      && TYPE_HAS_DEFAULT_CONSTRUCTOR (t)
      && !type_has_non_user_provided_default_constructor (t))
    TYPE_HAS_COMPLEX_DFLT (t) = true;

  /* Warn if a public base of a polymorphic type has an accessible
     non-virtual destructor.  It is only now that we know the class is
     polymorphic.  Although a polymorphic base will have a already
     been diagnosed during its definition, we warn on use too.  */
  if (TYPE_POLYMORPHIC_P (t) && warn_nonvdtor)
    {
      tree binfo = TYPE_BINFO (t);
      vec<tree, va_gc> *accesses = BINFO_BASE_ACCESSES (binfo);
      tree base_binfo;
      unsigned i;
      
      for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
	{
	  tree basetype = TREE_TYPE (base_binfo);

	  if ((*accesses)[i] == access_public_node
	      && (TYPE_POLYMORPHIC_P (basetype) || warn_ecpp)
	      && accessible_nvdtor_p (basetype))
	    warning (OPT_Wnon_virtual_dtor,
		     "base class %q#T has accessible non-virtual destructor",
		     basetype);
	}
    }
  
  /* If the class has no user-declared constructor, but does have
     non-static const or reference data members that can never be
     initialized, issue a warning.  */
  if (warn_uninitialized
      /* Classes with user-declared constructors are presumed to
	 initialize these members.  */
      && !TYPE_HAS_USER_CONSTRUCTOR (t)
      /* Aggregates can be initialized with brace-enclosed
	 initializers.  */
      && CLASSTYPE_NON_AGGREGATE (t))
    {
      tree field;

      for (field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field))
	{
	  tree type;

	  if (TREE_CODE (field) != FIELD_DECL
	      || DECL_INITIAL (field) != NULL_TREE)
	    continue;

	  type = TREE_TYPE (field);
	  if (TYPE_REF_P (type))
	    warning_at (DECL_SOURCE_LOCATION (field),
			OPT_Wuninitialized, "non-static reference %q#D "
			"in class without a constructor", field);
	  else if (CP_TYPE_CONST_P (type)
		   && (!CLASS_TYPE_P (type)
		       || !TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
	    warning_at (DECL_SOURCE_LOCATION (field),
			OPT_Wuninitialized, "non-static const member %q#D "
			"in class without a constructor", field);
	}
    }

  /* Synthesize any needed methods.  */
  add_implicitly_declared_members (t, &access_decls,
				   cant_have_const_ctor,
				   no_const_asn_ref);

  /* Check defaulted declarations here so we have cant_have_const_ctor
     and don't need to worry about clones.  */
  for (fn = TYPE_FIELDS (t); fn; fn = DECL_CHAIN (fn))
    if (DECL_DECLARES_FUNCTION_P (fn)
	&& !DECL_ARTIFICIAL (fn)
	&& DECL_DEFAULTED_IN_CLASS_P (fn))
      {
	int copy = copy_fn_p (fn);
	if (copy > 0)
	  {
	    bool imp_const_p
	      = (DECL_CONSTRUCTOR_P (fn) ? !cant_have_const_ctor
		 : !no_const_asn_ref);
	    bool fn_const_p = (copy == 2);

	    if (fn_const_p && !imp_const_p)
	      /* If the function is defaulted outside the class, we just
		 give the synthesis error.  Core Issue #1331 says this is
		 no longer ill-formed, it is defined as deleted instead.  */
	      DECL_DELETED_FN (fn) = true;
	  }
	defaulted_late_check (fn);
      }

  if (LAMBDA_TYPE_P (t))
    /* "This class type is not an aggregate."  */
    CLASSTYPE_NON_AGGREGATE (t) = 1;

  /* Compute the 'literal type' property before we
     do anything with non-static member functions.  */
  finalize_literal_type_property (t);

  /* Create the in-charge and not-in-charge variants of constructors
     and destructors.  */
  clone_constructors_and_destructors (t);

  /* Process the using-declarations.  */
  for (; access_decls; access_decls = TREE_CHAIN (access_decls))
    handle_using_decl (TREE_VALUE (access_decls), t);

  /* Figure out whether or not we will need a cookie when dynamically
     allocating an array of this type.  */
  LANG_TYPE_CLASS_CHECK (t)->vec_new_uses_cookie
    = type_requires_array_cookie (t);
}

/* If T needs a pointer to its virtual function table, set TYPE_VFIELD
   accordingly.  If a new vfield was created (because T doesn't have a
   primary base class), then the newly created field is returned.  It
   is not added to the TYPE_FIELDS list; it is the caller's
   responsibility to do that.  Accumulate declared virtual functions
   on VIRTUALS_P.  */

static tree
create_vtable_ptr (tree t, tree* virtuals_p)
{
  tree fn;

  /* Collect the virtual functions declared in T.  */
  for (fn = TYPE_FIELDS (t); fn; fn = DECL_CHAIN (fn))
    if (TREE_CODE (fn) == FUNCTION_DECL
	&& DECL_VINDEX (fn) && !DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn)
	&& TREE_CODE (DECL_VINDEX (fn)) != INTEGER_CST)
      {
	tree new_virtual = make_node (TREE_LIST);

	BV_FN (new_virtual) = fn;
	BV_DELTA (new_virtual) = integer_zero_node;
	BV_VCALL_INDEX (new_virtual) = NULL_TREE;

	TREE_CHAIN (new_virtual) = *virtuals_p;
	*virtuals_p = new_virtual;
      }

  /* If we couldn't find an appropriate base class, create a new field
     here.  Even if there weren't any new virtual functions, we might need a
     new virtual function table if we're supposed to include vptrs in
     all classes that need them.  */
  if (!TYPE_VFIELD (t) && (*virtuals_p || TYPE_CONTAINS_VPTR_P (t)))
    {
      /* We build this decl with vtbl_ptr_type_node, which is a
	 `vtable_entry_type*'.  It might seem more precise to use
	 `vtable_entry_type (*)[N]' where N is the number of virtual
	 functions.  However, that would require the vtable pointer in
	 base classes to have a different type than the vtable pointer
	 in derived classes.  We could make that happen, but that
	 still wouldn't solve all the problems.  In particular, the
	 type-based alias analysis code would decide that assignments
	 to the base class vtable pointer can't alias assignments to
	 the derived class vtable pointer, since they have different
	 types.  Thus, in a derived class destructor, where the base
	 class constructor was inlined, we could generate bad code for
	 setting up the vtable pointer.

	 Therefore, we use one type for all vtable pointers.  We still
	 use a type-correct type; it's just doesn't indicate the array
	 bounds.  That's better than using `void*' or some such; it's
	 cleaner, and it let's the alias analysis code know that these
	 stores cannot alias stores to void*!  */
      tree field;

      field = build_decl (input_location, 
			  FIELD_DECL, get_vfield_name (t), vtbl_ptr_type_node);
      DECL_VIRTUAL_P (field) = 1;
      DECL_ARTIFICIAL (field) = 1;
      DECL_FIELD_CONTEXT (field) = t;
      DECL_FCONTEXT (field) = t;
      if (TYPE_PACKED (t))
	DECL_PACKED (field) = 1;

      TYPE_VFIELD (t) = field;

      /* This class is non-empty.  */
      CLASSTYPE_EMPTY_P (t) = 0;

      return field;
    }

  return NULL_TREE;
}

/* Add OFFSET to all base types of BINFO which is a base in the
   hierarchy dominated by T.

   OFFSET, which is a type offset, is number of bytes.  */

static void
propagate_binfo_offsets (tree binfo, tree offset)
{
  int i;
  tree primary_binfo;
  tree base_binfo;

  /* Update BINFO's offset.  */
  BINFO_OFFSET (binfo)
    = fold_convert (sizetype,
	       size_binop (PLUS_EXPR,
			   fold_convert (ssizetype, BINFO_OFFSET (binfo)),
			   offset));

  /* Find the primary base class.  */
  primary_binfo = get_primary_binfo (binfo);

  if (primary_binfo && BINFO_INHERITANCE_CHAIN (primary_binfo) == binfo)
    propagate_binfo_offsets (primary_binfo, offset);

  /* Scan all of the bases, pushing the BINFO_OFFSET adjust
     downwards.  */
  for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
    {
      /* Don't do the primary base twice.  */
      if (base_binfo == primary_binfo)
	continue;

      if (BINFO_VIRTUAL_P (base_binfo))
	continue;

      propagate_binfo_offsets (base_binfo, offset);
    }
}

/* Set BINFO_OFFSET for all of the virtual bases for RLI->T.  Update
   TYPE_ALIGN and TYPE_SIZE for T.  OFFSETS gives the location of
   empty subobjects of T.  */

static void
layout_virtual_bases (record_layout_info rli, splay_tree offsets)
{
  tree vbase;
  tree t = rli->t;
  tree *next_field;

  if (BINFO_N_BASE_BINFOS (TYPE_BINFO (t)) == 0)
    return;

  /* Find the last field.  The artificial fields created for virtual
     bases will go after the last extant field to date.  */
  next_field = &TYPE_FIELDS (t);
  while (*next_field)
    next_field = &DECL_CHAIN (*next_field);

  /* Go through the virtual bases, allocating space for each virtual
     base that is not already a primary base class.  These are
     allocated in inheritance graph order.  */
  for (vbase = TYPE_BINFO (t); vbase; vbase = TREE_CHAIN (vbase))
    {
      if (!BINFO_VIRTUAL_P (vbase))
	continue;

      if (!BINFO_PRIMARY_P (vbase))
	{
	  /* This virtual base is not a primary base of any class in the
	     hierarchy, so we have to add space for it.  */
	  next_field = build_base_field (rli, vbase,
					 access_private_node,
					 offsets, next_field);
	}
    }
}

/* Returns the offset of the byte just past the end of the base class
   BINFO.  */

static tree
end_of_base (tree binfo)
{
  tree size;

  if (!CLASSTYPE_AS_BASE (BINFO_TYPE (binfo)))
    size = TYPE_SIZE_UNIT (char_type_node);
  else if (is_empty_class (BINFO_TYPE (binfo)))
    /* An empty class has zero CLASSTYPE_SIZE_UNIT, but we need to
       allocate some space for it. It cannot have virtual bases, so
       TYPE_SIZE_UNIT is fine.  */
    size = TYPE_SIZE_UNIT (BINFO_TYPE (binfo));
  else
    size = CLASSTYPE_SIZE_UNIT (BINFO_TYPE (binfo));

  return size_binop (PLUS_EXPR, BINFO_OFFSET (binfo), size);
}

/* Returns the offset of the byte just past the end of the base class or empty
   data member with the highest offset in T.  If INCLUDE_VIRTUALS_P is zero,
   then only non-virtual bases are included.  */

static tree
end_of_class (tree t, bool include_virtuals_p)
{
  tree result = size_zero_node;
  vec<tree, va_gc> *vbases;
  tree binfo;
  tree base_binfo;
  tree offset;
  int i;

  for (binfo = TYPE_BINFO (t), i = 0;
       BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
    {
      if (!include_virtuals_p
	  && BINFO_VIRTUAL_P (base_binfo)
	  && (!BINFO_PRIMARY_P (base_binfo)
	      || BINFO_INHERITANCE_CHAIN (base_binfo) != TYPE_BINFO (t)))
	continue;

      offset = end_of_base (base_binfo);
      if (tree_int_cst_lt (result, offset))
	result = offset;
    }

  /* Also consider empty data members.  */
  for (tree field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field))
    if (TREE_CODE (field) == FIELD_DECL
	&& !DECL_ARTIFICIAL (field)
	&& field_poverlapping_p (field)
	&& is_empty_class (TREE_TYPE (field)))
      {
	/* Update sizeof(C) to max (sizeof(C), offset(D)+sizeof(D)) */
	offset = size_binop (PLUS_EXPR, DECL_FIELD_OFFSET (field),
			     TYPE_SIZE_UNIT (TREE_TYPE (field)));
	if (tree_int_cst_lt (result, offset))
	  result = offset;
      }

  if (include_virtuals_p)
    for (vbases = CLASSTYPE_VBASECLASSES (t), i = 0;
	 vec_safe_iterate (vbases, i, &base_binfo); i++)
      {
	offset = end_of_base (base_binfo);
	if (tree_int_cst_lt (result, offset))
	  result = offset;
      }

  return result;
}

/* Warn about bases of T that are inaccessible because they are
   ambiguous.  For example:

     struct S {};
     struct T : public S {};
     struct U : public S, public T {};

   Here, `(S*) new U' is not allowed because there are two `S'
   subobjects of U.  */

static void
maybe_warn_about_inaccessible_bases (tree t)
{
  int i;
  vec<tree, va_gc> *vbases;
  tree basetype;
  tree binfo;
  tree base_binfo;

  /* If not checking for warning then return early.  */
  if (!warn_inaccessible_base)
    return;

  /* If there are no repeated bases, nothing can be ambiguous.  */
  if (!CLASSTYPE_REPEATED_BASE_P (t))
    return;

  /* Check direct bases.  */
  for (binfo = TYPE_BINFO (t), i = 0;
       BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
    {
      basetype = BINFO_TYPE (base_binfo);

      if (!uniquely_derived_from_p (basetype, t))
	warning (OPT_Winaccessible_base, "direct base %qT inaccessible "
		 "in %qT due to ambiguity", basetype, t);
    }

  /* Check for ambiguous virtual bases.  */
  if (extra_warnings)
    for (vbases = CLASSTYPE_VBASECLASSES (t), i = 0;
	 vec_safe_iterate (vbases, i, &binfo); i++)
      {
	basetype = BINFO_TYPE (binfo);

	if (!uniquely_derived_from_p (basetype, t))
	  warning (OPT_Winaccessible_base, "virtual base %qT inaccessible in "
		   "%qT due to ambiguity", basetype, t);
      }
}

/* Compare two INTEGER_CSTs K1 and K2.  */

static int
splay_tree_compare_integer_csts (splay_tree_key k1, splay_tree_key k2)
{
  return tree_int_cst_compare ((tree) k1, (tree) k2);
}

/* Increase the size indicated in RLI to account for empty classes
   that are "off the end" of the class.  */

static void
include_empty_classes (record_layout_info rli)
{
  tree eoc;
  tree rli_size;

  /* It might be the case that we grew the class to allocate a
     zero-sized base class.  That won't be reflected in RLI, yet,
     because we are willing to overlay multiple bases at the same
     offset.  However, now we need to make sure that RLI is big enough
     to reflect the entire class.  */
  eoc = end_of_class (rli->t, CLASSTYPE_AS_BASE (rli->t) != NULL_TREE);
  rli_size = rli_size_unit_so_far (rli);
  if (TREE_CODE (rli_size) == INTEGER_CST
      && tree_int_cst_lt (rli_size, eoc))
    {
      /* The size should have been rounded to a whole byte.  */
      gcc_assert (tree_int_cst_equal
		  (rli->bitpos, round_down (rli->bitpos, BITS_PER_UNIT)));
      rli->bitpos
	= size_binop (PLUS_EXPR,
		      rli->bitpos,
		      size_binop (MULT_EXPR,
				  fold_convert (bitsizetype,
					   size_binop (MINUS_EXPR,
						       eoc, rli_size)),
				  bitsize_int (BITS_PER_UNIT)));
      normalize_rli (rli);
    }
}

/* Calculate the TYPE_SIZE, TYPE_ALIGN, etc for T.  Calculate
   BINFO_OFFSETs for all of the base-classes.  Position the vtable
   pointer.  Accumulate declared virtual functions on VIRTUALS_P.  */

static void
layout_class_type (tree t, tree *virtuals_p)
{
  tree non_static_data_members;
  tree field;
  tree vptr;
  record_layout_info rli;
  /* Maps offsets (represented as INTEGER_CSTs) to a TREE_LIST of
     types that appear at that offset.  */
  splay_tree empty_base_offsets;
  /* True if the last field laid out was a bit-field.  */
  bool last_field_was_bitfield = false;
  /* The location at which the next field should be inserted.  */
  tree *next_field;

  /* Keep track of the first non-static data member.  */
  non_static_data_members = TYPE_FIELDS (t);

  /* Start laying out the record.  */
  rli = start_record_layout (t);

  /* Mark all the primary bases in the hierarchy.  */
  determine_primary_bases (t);

  /* Create a pointer to our virtual function table.  */
  vptr = create_vtable_ptr (t, virtuals_p);

  /* The vptr is always the first thing in the class.  */
  if (vptr)
    {
      DECL_CHAIN (vptr) = TYPE_FIELDS (t);
      TYPE_FIELDS (t) = vptr;
      next_field = &DECL_CHAIN (vptr);
      place_field (rli, vptr);
    }
  else
    next_field = &TYPE_FIELDS (t);

  /* Build FIELD_DECLs for all of the non-virtual base-types.  */
  empty_base_offsets = splay_tree_new (splay_tree_compare_integer_csts,
				       NULL, NULL);
  build_base_fields (rli, empty_base_offsets, next_field);

  /* Layout the non-static data members.  */
  for (field = non_static_data_members; field; field = DECL_CHAIN (field))
    {
      tree type;
      tree padding;

      /* We still pass things that aren't non-static data members to
	 the back end, in case it wants to do something with them.  */
      if (TREE_CODE (field) != FIELD_DECL)
	{
	  place_field (rli, field);
	  /* If the static data member has incomplete type, keep track
	     of it so that it can be completed later.  (The handling
	     of pending statics in finish_record_layout is
	     insufficient; consider:

	       struct S1;
	       struct S2 { static S1 s1; };

	     At this point, finish_record_layout will be called, but
	     S1 is still incomplete.)  */
	  if (VAR_P (field))
	    {
	      maybe_register_incomplete_var (field);
	      /* The visibility of static data members is determined
		 at their point of declaration, not their point of
		 definition.  */
	      determine_visibility (field);
	    }
	  continue;
	}

      type = TREE_TYPE (field);
      if (type == error_mark_node)
	continue;

      padding = NULL_TREE;

      bool might_overlap = field_poverlapping_p (field);

      if (might_overlap && CLASS_TYPE_P (type)
	  && (CLASSTYPE_NON_LAYOUT_POD_P (type) || CLASSTYPE_EMPTY_P (type)))
	{
	  /* if D is a potentially-overlapping data member, update sizeof(C) to
	     max (sizeof(C), offset(D)+max (nvsize(D), dsize(D))).  */
	  tree nvsize = CLASSTYPE_SIZE_UNIT (type);
	  /* end_of_class doesn't always give dsize, but it does in the case of
	     a class with virtual bases, which is when dsize > nvsize.  */
	  tree dsize = end_of_class (type, /*vbases*/true);
	  if (CLASSTYPE_EMPTY_P (type))
	    DECL_SIZE (field) = DECL_SIZE_UNIT (field) = size_zero_node;
	  else if (tree_int_cst_le (dsize, nvsize))
	    {
	      DECL_SIZE_UNIT (field) = nvsize;
	      DECL_SIZE (field) = CLASSTYPE_SIZE (type);
	    }
	  else
	    {
	      DECL_SIZE_UNIT (field) = dsize;
	      DECL_SIZE (field) = bit_from_pos (dsize, bitsize_zero_node);
	    }
	}

      /* If this field is a bit-field whose width is greater than its
	 type, then there are some special rules for allocating
	 it.  */
      if (DECL_C_BIT_FIELD (field)
	  && tree_int_cst_lt (TYPE_SIZE (type), DECL_SIZE (field)))
	{
	  bool was_unnamed_p = false;
	  /* We must allocate the bits as if suitably aligned for the
	     longest integer type that fits in this many bits.  Then,
	     we are supposed to use the left over bits as additional
	     padding.  */

	  /* Do not pick a type bigger than MAX_FIXED_MODE_SIZE.  */
	  tree limit = size_int (MAX_FIXED_MODE_SIZE);
	  if (tree_int_cst_lt (DECL_SIZE (field), limit))
	    limit = DECL_SIZE (field);

	  tree integer_type = integer_types[itk_char];
	  for (unsigned itk = itk_char; itk != itk_none; itk++)
	    if (tree next = integer_types[itk])
	      {
		if (tree_int_cst_lt (limit, TYPE_SIZE (next)))
		  /* Too big, so our current guess is what we want.  */
		  break;
		/* Not bigger than limit, ok  */
		integer_type = next;
	      }

	  /* Figure out how much additional padding is required.  */
	  if (TREE_CODE (t) == UNION_TYPE)
	    /* In a union, the padding field must have the full width
	       of the bit-field; all fields start at offset zero.  */
	    padding = DECL_SIZE (field);
	  else
	    padding = size_binop (MINUS_EXPR, DECL_SIZE (field),
				  TYPE_SIZE (integer_type));

 	  if (integer_zerop (padding))
	    padding = NULL_TREE;

	  /* An unnamed bitfield does not normally affect the
	     alignment of the containing class on a target where
	     PCC_BITFIELD_TYPE_MATTERS.  But, the C++ ABI does not
	     make any exceptions for unnamed bitfields when the
	     bitfields are longer than their types.  Therefore, we
	     temporarily give the field a name.  */
	  if (PCC_BITFIELD_TYPE_MATTERS && !DECL_NAME (field))
	    {
	      was_unnamed_p = true;
	      DECL_NAME (field) = make_anon_name ();
	    }

	  DECL_SIZE (field) = TYPE_SIZE (integer_type);
	  SET_DECL_ALIGN (field, TYPE_ALIGN (integer_type));
	  DECL_USER_ALIGN (field) = TYPE_USER_ALIGN (integer_type);
	  layout_nonempty_base_or_field (rli, field, NULL_TREE,
					 empty_base_offsets);
	  if (was_unnamed_p)
	    DECL_NAME (field) = NULL_TREE;
	  /* Now that layout has been performed, set the size of the
	     field to the size of its declared type; the rest of the
	     field is effectively invisible.  */
	  DECL_SIZE (field) = TYPE_SIZE (type);
	  /* We must also reset the DECL_MODE of the field.  */
	  SET_DECL_MODE (field, TYPE_MODE (type));
	}
      else if (might_overlap && is_empty_class (type))
	{
	  DECL_FIELD_ABI_IGNORED (field) = 1;
	  layout_empty_base_or_field (rli, field, empty_base_offsets);
	}
      else
	layout_nonempty_base_or_field (rli, field, NULL_TREE,
				       empty_base_offsets);

      /* Remember the location of any empty classes in FIELD.  */
      record_subobject_offsets (field, empty_base_offsets);

      /* If a bit-field does not immediately follow another bit-field,
	 and yet it starts in the middle of a byte, we have failed to
	 comply with the ABI.  */
      if (warn_abi
	  && DECL_C_BIT_FIELD (field)
	  /* The TREE_NO_WARNING flag gets set by Objective-C when
	     laying out an Objective-C class.  The ObjC ABI differs
	     from the C++ ABI, and so we do not want a warning
	     here.  */
	  && !warning_suppressed_p (field, OPT_Wabi)
	  && !last_field_was_bitfield
	  && !integer_zerop (size_binop (TRUNC_MOD_EXPR,
					 DECL_FIELD_BIT_OFFSET (field),
					 bitsize_unit_node)))
	warning_at (DECL_SOURCE_LOCATION (field), OPT_Wabi,
		    "offset of %qD is not ABI-compliant and may "
		    "change in a future version of GCC", field);

      /* The middle end uses the type of expressions to determine the
	 possible range of expression values.  In order to optimize
	 "x.i > 7" to "false" for a 2-bit bitfield "i", the middle end
	 must be made aware of the width of "i", via its type.

	 Because C++ does not have integer types of arbitrary width,
	 we must (for the purposes of the front end) convert from the
	 type assigned here to the declared type of the bitfield
	 whenever a bitfield expression is used as an rvalue.
	 Similarly, when assigning a value to a bitfield, the value
	 must be converted to the type given the bitfield here.  */
      if (DECL_C_BIT_FIELD (field))
	{
	  unsigned HOST_WIDE_INT width;
	  tree ftype = TREE_TYPE (field);
	  width = tree_to_uhwi (DECL_SIZE (field));
	  if (width != TYPE_PRECISION (ftype))
	    {
	      TREE_TYPE (field)
		= c_build_bitfield_integer_type (width,
						 TYPE_UNSIGNED (ftype));
	      TREE_TYPE (field)
		= cp_build_qualified_type (TREE_TYPE (field),
					   cp_type_quals (ftype));
	    }
	}

      /* If we needed additional padding after this field, add it
	 now.  */
      if (padding)
	{
	  tree padding_field;

	  padding_field = build_decl (input_location,
				      FIELD_DECL,
				      NULL_TREE,
				      char_type_node);
	  DECL_BIT_FIELD (padding_field) = 1;
	  DECL_SIZE (padding_field) = padding;
	  DECL_CONTEXT (padding_field) = t;
	  DECL_ARTIFICIAL (padding_field) = 1;
	  DECL_IGNORED_P (padding_field) = 1;
	  DECL_PADDING_P (padding_field) = 1;
	  layout_nonempty_base_or_field (rli, padding_field,
					 NULL_TREE,
					 empty_base_offsets);
	}

      last_field_was_bitfield = DECL_C_BIT_FIELD (field);
    }

  if (!integer_zerop (rli->bitpos))
    {
      /* Make sure that we are on a byte boundary so that the size of
	 the class without virtual bases will always be a round number
	 of bytes.  */
      rli->bitpos = round_up_loc (input_location, rli->bitpos, BITS_PER_UNIT);
      normalize_rli (rli);
    }

  /* Delete all zero-width bit-fields from the list of fields.  Now
     that the type is laid out they are no longer important.  */
  remove_zero_width_bit_fields (t);

  if (CLASSTYPE_NON_LAYOUT_POD_P (t) || CLASSTYPE_EMPTY_P (t))
    {
      /* T needs a different layout as a base (eliding virtual bases
	 or whatever).  Create that version.  */
      tree base_t = make_node (TREE_CODE (t));
      tree base_d = create_implicit_typedef (as_base_identifier, base_t);

      TYPE_CONTEXT (base_t) = t;
      DECL_CONTEXT (base_d) = t;

      set_instantiating_module (base_d);

      /* If the ABI version is not at least two, and the last
	 field was a bit-field, RLI may not be on a byte
	 boundary.  In particular, rli_size_unit_so_far might
	 indicate the last complete byte, while rli_size_so_far
	 indicates the total number of bits used.  Therefore,
	 rli_size_so_far, rather than rli_size_unit_so_far, is
	 used to compute TYPE_SIZE_UNIT.  */

      /* Set the size and alignment for the new type.  */
      tree eoc = end_of_class (t, /*include_virtuals_p=*/0);
      TYPE_SIZE_UNIT (base_t)
	= size_binop (MAX_EXPR,
		      fold_convert (sizetype,
			       size_binop (CEIL_DIV_EXPR,
					   rli_size_so_far (rli),
					   bitsize_int (BITS_PER_UNIT))),
		      eoc);
      TYPE_SIZE (base_t)
	= size_binop (MAX_EXPR,
		      rli_size_so_far (rli),
		      size_binop (MULT_EXPR,
				  fold_convert (bitsizetype, eoc),
				  bitsize_int (BITS_PER_UNIT)));
      SET_TYPE_ALIGN (base_t, rli->record_align);
      TYPE_USER_ALIGN (base_t) = TYPE_USER_ALIGN (t);
      TYPE_TYPELESS_STORAGE (base_t) = TYPE_TYPELESS_STORAGE (t);
      TYPE_CXX_ODR_P (base_t) = TYPE_CXX_ODR_P (t);

      /* Copy the non-static data members of T. This will include its
	 direct non-virtual bases & vtable.  */
      next_field = &TYPE_FIELDS (base_t);
      for (field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field))
	if (TREE_CODE (field) == FIELD_DECL)
	  {
	    *next_field = copy_node (field);
	    /* Zap any NSDMI, it's not needed and might be a deferred
	       parse.  */
	    DECL_INITIAL (*next_field) = NULL_TREE;
	    DECL_CONTEXT (*next_field) = base_t;
	    next_field = &DECL_CHAIN (*next_field);
	  }
      *next_field = NULL_TREE;

      /* We use the base type for trivial assignments, and hence it
	 needs a mode.  */
      compute_record_mode (base_t);

      /* Record the base version of the type.  */
      CLASSTYPE_AS_BASE (t) = base_t;
    }
  else
    CLASSTYPE_AS_BASE (t) = t;

  /* Every empty class contains an empty class.  */
  if (CLASSTYPE_EMPTY_P (t))
    CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t) = 1;

  /* Set the TYPE_DECL for this type to contain the right
     value for DECL_OFFSET, so that we can use it as part
     of a COMPONENT_REF for multiple inheritance.  */
  layout_decl (TYPE_MAIN_DECL (t), 0);

  /* Now fix up any virtual base class types that we left lying
     around.  We must get these done before we try to lay out the
     virtual function table.  As a side-effect, this will remove the
     base subobject fields.  */
  layout_virtual_bases (rli, empty_base_offsets);

  /* Make sure that empty classes are reflected in RLI at this
     point.  */
  include_empty_classes (rli);

  /* Make sure not to create any structures with zero size.  */
  if (integer_zerop (rli_size_unit_so_far (rli)) && CLASSTYPE_EMPTY_P (t))
    place_field (rli,
		 build_decl (input_location,
			     FIELD_DECL, NULL_TREE, char_type_node));

  /* If this is a non-POD, declaring it packed makes a difference to how it
     can be used as a field; don't let finalize_record_size undo it.  */
  if (TYPE_PACKED (t) && !layout_pod_type_p (t))
    rli->packed_maybe_necessary = true;

  /* Let the back end lay out the type.  */
  finish_record_layout (rli, /*free_p=*/true);

  /* If we didn't end up needing an as-base type, don't use it.  */
  if (CLASSTYPE_AS_BASE (t) != t
      /* If T's CLASSTYPE_AS_BASE is TYPE_USER_ALIGN, but T is not,
	 replacing the as-base type would change CLASSTYPE_USER_ALIGN,
	 causing us to lose the user-specified alignment as in PR94050.  */
      && TYPE_USER_ALIGN (t) == TYPE_USER_ALIGN (CLASSTYPE_AS_BASE (t))
      && tree_int_cst_equal (TYPE_SIZE (t),
			     TYPE_SIZE (CLASSTYPE_AS_BASE (t))))
    CLASSTYPE_AS_BASE (t) = t;

  if (TYPE_SIZE_UNIT (t)
      && TREE_CODE (TYPE_SIZE_UNIT (t)) == INTEGER_CST
      && !TREE_OVERFLOW (TYPE_SIZE_UNIT (t))
      && !valid_constant_size_p (TYPE_SIZE_UNIT (t)))
    error ("size of type %qT is too large (%qE bytes)", t, TYPE_SIZE_UNIT (t));

  /* Warn about bases that can't be talked about due to ambiguity.  */
  maybe_warn_about_inaccessible_bases (t);

  /* Now that we're done with layout, give the base fields the real types.  */
  for (field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field))
    if (DECL_ARTIFICIAL (field) && IS_FAKE_BASE_TYPE (TREE_TYPE (field)))
      TREE_TYPE (field) = TYPE_CONTEXT (TREE_TYPE (field));

  /* Clean up.  */
  splay_tree_delete (empty_base_offsets);

  if (CLASSTYPE_EMPTY_P (t)
      && tree_int_cst_lt (sizeof_biggest_empty_class,
			  TYPE_SIZE_UNIT (t)))
    sizeof_biggest_empty_class = TYPE_SIZE_UNIT (t);
}

/* Determine the "key method" for the class type indicated by TYPE,
   and set CLASSTYPE_KEY_METHOD accordingly.  */

void
determine_key_method (tree type)
{
  tree method;

  if (processing_template_decl
      || CLASSTYPE_TEMPLATE_INSTANTIATION (type)
      || CLASSTYPE_INTERFACE_KNOWN (type))
    return;

  /* The key method is the first non-pure virtual function that is not
     inline at the point of class definition.  On some targets the
     key function may not be inline; those targets should not call
     this function until the end of the translation unit.  */
  for (method = TYPE_FIELDS (type); method; method = DECL_CHAIN (method))
    if (TREE_CODE (method) == FUNCTION_DECL
	&& DECL_VINDEX (method) != NULL_TREE
	&& ! DECL_DECLARED_INLINE_P (method)
	&& ! DECL_PURE_VIRTUAL_P (method))
      {
	CLASSTYPE_KEY_METHOD (type) = method;
	break;
      }

  return;
}

/* Helper of find_flexarrays.  Return true when FLD refers to a non-static
   class data member of non-zero size, otherwise false.  */

static inline bool
field_nonempty_p (const_tree fld)
{
  if (TREE_CODE (fld) == ERROR_MARK)
    return false;

  tree type = TREE_TYPE (fld);
  if (TREE_CODE (fld) == FIELD_DECL
      && TREE_CODE (type) != ERROR_MARK
      && (DECL_NAME (fld) || RECORD_OR_UNION_TYPE_P (type)))
    {
      return TYPE_SIZE (type)
	&& (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST
	    || !tree_int_cst_equal (size_zero_node, TYPE_SIZE (type)));
    }

  return false;
}

/* Used by find_flexarrays and related functions.  */

struct flexmems_t
{
  /* The first flexible array member or non-zero array member found
     in the order of layout.  */
  tree array;
  /* First non-static non-empty data member in the class or its bases.  */
  tree first;
  /* The first non-static non-empty data member following either
     the flexible array member, if found, or the zero-length array member
     otherwise.  AFTER[1] refers to the first such data member of a union
     of which the struct containing the flexible array member or zero-length
     array is a member, or NULL when no such union exists.  This element is
     only used during searching, not for diagnosing problems.  AFTER[0]
     refers to the first such data member that is not a member of such
     a union.  */
  tree after[2];

  /* Refers to a struct (not union) in which the struct of which the flexible
     array is member is defined.  Used to diagnose strictly (according to C)
     invalid uses of the latter structs.  */
  tree enclosing;
};

/* Find either the first flexible array member or the first zero-length
   array, in that order of preference, among members of class T (but not
   its base classes), and set members of FMEM accordingly.
   BASE_P is true if T is a base class of another class.
   PUN is set to the outermost union in which the flexible array member
   (or zero-length array) is defined if one such union exists, otherwise
   to NULL.
   Similarly, PSTR is set to a data member of the outermost struct of
   which the flexible array is a member if one such struct exists,
   otherwise to NULL.  */

static void
find_flexarrays (tree t, flexmems_t *fmem, bool base_p,
		 tree pun /* = NULL_TREE */,
		 tree pstr /* = NULL_TREE */)
{
  /* Set the "pointer" to the outermost enclosing union if not set
     yet and maintain it for the remainder of the recursion.   */
  if (!pun && TREE_CODE (t) == UNION_TYPE)
    pun = t;

  for (tree fld = TYPE_FIELDS (t); fld; fld = DECL_CHAIN (fld))
    {
      if (fld == error_mark_node)
	return;

      /* Is FLD a typedef for an anonymous struct?  */

      /* FIXME: Note that typedefs (as well as arrays) need to be fully
	 handled elsewhere so that errors like the following are detected
	 as well:
	   typedef struct { int i, a[], j; } S;   // bug c++/72753
	   S s [2];                               // bug c++/68489
      */
      if (TREE_CODE (fld) == TYPE_DECL
	  && DECL_IMPLICIT_TYPEDEF_P (fld)
	  && CLASS_TYPE_P (TREE_TYPE (fld))
	  && IDENTIFIER_ANON_P (DECL_NAME (fld)))
	{
	  /* Check the nested unnamed type referenced via a typedef
	     independently of FMEM (since it's not a data member of
	     the enclosing class).  */
	  check_flexarrays (TREE_TYPE (fld));
	  continue;
	}

      /* Skip anything that's GCC-generated or not a (non-static) data
	 member.  */
      if (DECL_ARTIFICIAL (fld) || TREE_CODE (fld) != FIELD_DECL)
	continue;

      /* Type of the member.  */
      tree fldtype = TREE_TYPE (fld);
      if (fldtype == error_mark_node)
	return;

      /* Determine the type of the array element or object referenced
	 by the member so that it can be checked for flexible array
	 members if it hasn't been yet.  */
      tree eltype = fldtype;
      while (TREE_CODE (eltype) == ARRAY_TYPE
	     || INDIRECT_TYPE_P (eltype))
	eltype = TREE_TYPE (eltype);

      if (RECORD_OR_UNION_TYPE_P (eltype))
	{
	  if (fmem->array && !fmem->after[bool (pun)])
	    {
	      /* Once the member after the flexible array has been found
		 we're done.  */
	      fmem->after[bool (pun)] = fld;
	      break;
	    }

	  if (eltype == fldtype || TYPE_UNNAMED_P (eltype))
	    {
	      /* Descend into the non-static member struct or union and try
		 to find a flexible array member or zero-length array among
		 its members.  This is only necessary for anonymous types
		 and types in whose context the current type T has not been
		 defined (the latter must not be checked again because they
		 are already in the process of being checked by one of the
		 recursive calls).  */

	      tree first = fmem->first;
	      tree array = fmem->array;

	      /* If this member isn't anonymous and a prior non-flexible array
		 member has been seen in one of the enclosing structs, clear
		 the FIRST member since it doesn't contribute to the flexible
		 array struct's members.  */
	      if (first && !array && !ANON_AGGR_TYPE_P (eltype))
		fmem->first = NULL_TREE;

	      find_flexarrays (eltype, fmem, false, pun,
			       !pstr && TREE_CODE (t) == RECORD_TYPE ? fld : pstr);

	      if (fmem->array != array)
		continue;

	      if (first && !array && !ANON_AGGR_TYPE_P (eltype))
		{
		  /* Restore the FIRST member reset above if no flexible
		     array member has been found in this member's struct.  */
		  fmem->first = first;
		}

	      /* If the member struct contains the first flexible array
		 member, or if this member is a base class, continue to
		 the next member and avoid setting the FMEM->NEXT pointer
		 to point to it.  */
	      if (base_p)
		continue;
	    }
	}

      if (field_nonempty_p (fld))
	{
	  /* Remember the first non-static data member.  */
	  if (!fmem->first)
	    fmem->first = fld;

	  /* Remember the first non-static data member after the flexible
	     array member, if one has been found, or the zero-length array
	     if it has been found.  */
	  if (fmem->array && !fmem->after[bool (pun)])
	    fmem->after[bool (pun)] = fld;
	}

      /* Skip non-arrays.  */
      if (TREE_CODE (fldtype) != ARRAY_TYPE)
	continue;

      /* Determine the upper bound of the array if it has one.  */
      if (TYPE_DOMAIN (fldtype))
	{
	  if (fmem->array)
	    {
	      /* Make a record of the zero-length array if either one
		 such field or a flexible array member has been seen to
		 handle the pathological and unlikely case of multiple
		 such members.  */
	      if (!fmem->after[bool (pun)])
		fmem->after[bool (pun)] = fld;
	    }
	  else if (integer_all_onesp (TYPE_MAX_VALUE (TYPE_DOMAIN (fldtype))))
	    {
	      /* Remember the first zero-length array unless a flexible array
		 member has already been seen.  */
	      fmem->array = fld;
	      fmem->enclosing = pstr;
	    }
	}
      else
	{
	  /* Flexible array members have no upper bound.  */
	  if (fmem->array)
	    {
	      if (TYPE_DOMAIN (TREE_TYPE (fmem->array)))
		{
		  /* Replace the zero-length array if it's been stored and
		     reset the after pointer.  */
		  fmem->after[bool (pun)] = NULL_TREE;
		  fmem->array = fld;
		  fmem->enclosing = pstr;
		}
	      else if (!fmem->after[bool (pun)])
		/* Make a record of another flexible array member.  */
		fmem->after[bool (pun)] = fld;
	    }
	  else
	    {
	      fmem->array = fld;
	      fmem->enclosing = pstr;
	    }
	}
    }
}

/* Diagnose a strictly (by the C standard) invalid use of a struct with
   a flexible array member (or the zero-length array extension).  */

static void
diagnose_invalid_flexarray (const flexmems_t *fmem)
{
  if (fmem->array && fmem->enclosing)
    {
      auto_diagnostic_group d;
      if (pedwarn (location_of (fmem->enclosing), OPT_Wpedantic,
		     TYPE_DOMAIN (TREE_TYPE (fmem->array))
		     ? G_("invalid use of %q#T with a zero-size array "
			  "in %q#D")
		     : G_("invalid use of %q#T with a flexible array member "
			  "in %q#T"),
		     DECL_CONTEXT (fmem->array),
		     DECL_CONTEXT (fmem->enclosing)))
	inform (DECL_SOURCE_LOCATION (fmem->array),
		  "array member %q#D declared here", fmem->array);
    }
}

/* Issue diagnostics for invalid flexible array members or zero-length
   arrays that are not the last elements of the containing class or its
   base classes or that are its sole members.  */

static void
diagnose_flexarrays (tree t, const flexmems_t *fmem)
{
  if (!fmem->array)
    return;

  if (fmem->first && !fmem->after[0])
    {
      diagnose_invalid_flexarray (fmem);
      return;
    }

  /* Has a diagnostic been issued?  */
  bool diagd = false;

  const char *msg = 0;

  if (TYPE_DOMAIN (TREE_TYPE (fmem->array)))
    {
      if (fmem->after[0])
	msg = G_("zero-size array member %qD not at end of %q#T");
      else if (!fmem->first)
	msg = G_("zero-size array member %qD in an otherwise empty %q#T");

      if (msg)
	{
	  location_t loc = DECL_SOURCE_LOCATION (fmem->array);

	  auto_diagnostic_group d;
	  if (pedwarn (loc, OPT_Wpedantic, msg, fmem->array, t))
	    {
	      inform (location_of (t), "in the definition of %q#T", t);
	      diagd = true;
	    }
	}
    }
  else
    {
      if (fmem->after[0])
	msg = G_("flexible array member %qD not at end of %q#T");
      else if (!fmem->first)
	msg = G_("flexible array member %qD in an otherwise empty %q#T");

      if (msg)
	{
	  location_t loc = DECL_SOURCE_LOCATION (fmem->array);
	  diagd = true;

	  auto_diagnostic_group d;
	  error_at (loc, msg, fmem->array, t);

	  /* In the unlikely event that the member following the flexible
	     array member is declared in a different class, or the member
	     overlaps another member of a common union, point to it.
	     Otherwise it should be obvious.  */
	  if (fmem->after[0]
	      && ((DECL_CONTEXT (fmem->after[0])
		   != DECL_CONTEXT (fmem->array))))
	    {
	      inform (DECL_SOURCE_LOCATION (fmem->after[0]),
		      "next member %q#D declared here",
		      fmem->after[0]);
	      inform (location_of (t), "in the definition of %q#T", t);
	    }
	}
    }

  if (!diagd && fmem->array && fmem->enclosing)
    diagnose_invalid_flexarray (fmem);
}


/* Recursively check to make sure that any flexible array or zero-length
   array members of class T or its bases are valid (i.e., not the sole
   non-static data member of T and, if one exists, that it is the last
   non-static data member of T and its base classes.  FMEM is expected
   to be initially null and is used internally by recursive calls to
   the function.  Issue the appropriate diagnostics for the array member
   that fails the checks.  */

static void
check_flexarrays (tree t, flexmems_t *fmem /* = NULL */,
		  bool base_p /* = false */)
{
  /* Initialize the result of a search for flexible array and zero-length
     array members.  Avoid doing any work if the most interesting FMEM data
     have already been populated.  */
  flexmems_t flexmems = flexmems_t ();
  if (!fmem)
    fmem = &flexmems;
  else if (fmem->array && fmem->first && fmem->after[0])
    return;

  tree fam = fmem->array;

  /* Recursively check the primary base class first.  */
  if (CLASSTYPE_HAS_PRIMARY_BASE_P (t))
    {
      tree basetype = BINFO_TYPE (CLASSTYPE_PRIMARY_BINFO (t));
      check_flexarrays (basetype, fmem, true);
    }

  /* Recursively check the base classes.  */
  int nbases = TYPE_BINFO (t) ? BINFO_N_BASE_BINFOS (TYPE_BINFO (t)) : 0;
  for (int i = 0; i < nbases; ++i)
    {
      tree base_binfo = BINFO_BASE_BINFO (TYPE_BINFO (t), i);

      /* The primary base class was already checked above.  */
      if (base_binfo == CLASSTYPE_PRIMARY_BINFO (t))
	continue;

      /* Virtual base classes are at the end.  */
      if (BINFO_VIRTUAL_P (base_binfo))
	continue;

      /* Check the base class.  */
      check_flexarrays (BINFO_TYPE (base_binfo), fmem, /*base_p=*/true);
    }

  if (fmem == &flexmems)
    {
      /* Check virtual base classes only once per derived class.
	 I.e., this check is not performed recursively for base
	 classes.  */
      int i;
      tree base_binfo;
      vec<tree, va_gc> *vbases;
      for (vbases = CLASSTYPE_VBASECLASSES (t), i = 0;
	   vec_safe_iterate (vbases, i, &base_binfo); i++)
	{
	  /* Check the virtual base class.  */
	  tree basetype = TREE_TYPE (base_binfo);

	  check_flexarrays (basetype, fmem, /*base_p=*/true);
	}
    }

  /* Is the type unnamed (and therefore a member of it potentially
     an anonymous struct or union)?  */
  bool maybe_anon_p = TYPE_UNNAMED_P (t);
  if (tree ctx = maybe_anon_p ? TYPE_CONTEXT (t) : NULL_TREE)
    maybe_anon_p = RECORD_OR_UNION_TYPE_P (ctx);

  /* Search the members of the current (possibly derived) class, skipping
     unnamed structs and unions since those could be anonymous.  */
  if (fmem != &flexmems || !maybe_anon_p)
    find_flexarrays (t, fmem, base_p || fam != fmem->array);

  if (fmem == &flexmems && !maybe_anon_p)
    {
      /* Issue diagnostics for invalid flexible and zero-length array
	 members found in base classes or among the members of the current
	 class.  Ignore anonymous structs and unions whose members are
	 considered to be members of the enclosing class and thus will
	 be diagnosed when checking it.  */
      diagnose_flexarrays (t, fmem);
    }
}

/* Perform processing required when the definition of T (a class type)
   is complete.  Diagnose invalid definitions of flexible array members
   and zero-size arrays.  */

void
finish_struct_1 (tree t)
{
  tree x;
  /* A TREE_LIST.  The TREE_VALUE of each node is a FUNCTION_DECL.  */
  tree virtuals = NULL_TREE;

  if (COMPLETE_TYPE_P (t))
    {
      gcc_assert (MAYBE_CLASS_TYPE_P (t));
      error ("redefinition of %q#T", t);
      popclass ();
      return;
    }

  /* If this type was previously laid out as a forward reference,
     make sure we lay it out again.  */
  TYPE_SIZE (t) = NULL_TREE;
  CLASSTYPE_PRIMARY_BINFO (t) = NULL_TREE;

  /* Make assumptions about the class; we'll reset the flags if
     necessary.  */
  CLASSTYPE_EMPTY_P (t) = 1;
  CLASSTYPE_NEARLY_EMPTY_P (t) = 1;
  CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t) = 0;
  CLASSTYPE_LITERAL_P (t) = true;

  /* Do end-of-class semantic processing: checking the validity of the
     bases and members and add implicitly generated methods.  */
  check_bases_and_members (t);

  /* Find the key method.  */
  if (TYPE_CONTAINS_VPTR_P (t))
    {
      /* The Itanium C++ ABI permits the key method to be chosen when
	 the class is defined -- even though the key method so
	 selected may later turn out to be an inline function.  On
	 some systems (such as ARM Symbian OS) the key method cannot
	 be determined until the end of the translation unit.  On such
	 systems, we leave CLASSTYPE_KEY_METHOD set to NULL, which
	 will cause the class to be added to KEYED_CLASSES.  Then, in
	 finish_file we will determine the key method.  */
      if (targetm.cxx.key_method_may_be_inline ())
	determine_key_method (t);

      /* If a polymorphic class has no key method, we may emit the vtable
	 in every translation unit where the class definition appears.  If
	 we're devirtualizing, we can look into the vtable even if we
	 aren't emitting it.  */
      if (!CLASSTYPE_KEY_METHOD (t))
	vec_safe_push (keyed_classes, t);
    }

  /* Layout the class itself.  */
  layout_class_type (t, &virtuals);
  /* COMPLETE_TYPE_P is now true.  */

  set_class_bindings (t);

  /* With the layout complete, check for flexible array members and
     zero-length arrays that might overlap other members in the final
     layout.  */
  check_flexarrays (t);

  virtuals = modify_all_vtables (t, nreverse (virtuals));

  /* If necessary, create the primary vtable for this class.  */
  if (virtuals || TYPE_CONTAINS_VPTR_P (t))
    {
      /* We must enter these virtuals into the table.  */
      if (!CLASSTYPE_HAS_PRIMARY_BASE_P (t))
	build_primary_vtable (NULL_TREE, t);
      else if (! BINFO_NEW_VTABLE_MARKED (TYPE_BINFO (t)))
	/* Here we know enough to change the type of our virtual
	   function table, but we will wait until later this function.  */
	build_primary_vtable (CLASSTYPE_PRIMARY_BINFO (t), t);

      /* If we're warning about ABI tags, check the types of the new
	 virtual functions.  */
      if (warn_abi_tag)
	for (tree v = virtuals; v; v = TREE_CHAIN (v))
	  check_abi_tags (t, TREE_VALUE (v));
    }

  if (TYPE_CONTAINS_VPTR_P (t))
    {
      int vindex;
      tree fn;

      if (BINFO_VTABLE (TYPE_BINFO (t)))
	gcc_assert (DECL_VIRTUAL_P (BINFO_VTABLE (TYPE_BINFO (t))));
      if (!CLASSTYPE_HAS_PRIMARY_BASE_P (t))
	gcc_assert (BINFO_VIRTUALS (TYPE_BINFO (t)) == NULL_TREE);

      /* Add entries for virtual functions introduced by this class.  */
      BINFO_VIRTUALS (TYPE_BINFO (t))
	= chainon (BINFO_VIRTUALS (TYPE_BINFO (t)), virtuals);

      /* Set DECL_VINDEX for all functions declared in this class.  */
      for (vindex = 0, fn = BINFO_VIRTUALS (TYPE_BINFO (t));
	   fn;
	   fn = TREE_CHAIN (fn),
	     vindex += (TARGET_VTABLE_USES_DESCRIPTORS
			? TARGET_VTABLE_USES_DESCRIPTORS : 1))
	{
	  tree fndecl = BV_FN (fn);

	  if (DECL_THUNK_P (fndecl))
	    /* A thunk. We should never be calling this entry directly
	       from this vtable -- we'd use the entry for the non
	       thunk base function.  */
	    DECL_VINDEX (fndecl) = NULL_TREE;
	  else if (TREE_CODE (DECL_VINDEX (fndecl)) != INTEGER_CST)
	    DECL_VINDEX (fndecl) = build_int_cst (NULL_TREE, vindex);
	}
    }

  finish_struct_bits (t);

  set_method_tm_attributes (t);
  if (flag_openmp || flag_openmp_simd)
    finish_omp_declare_simd_methods (t);

  /* Clear DECL_IN_AGGR_P for all member functions.  Complete the rtl
     for any static member objects of the type we're working on.  */
  for (x = TYPE_FIELDS (t); x; x = DECL_CHAIN (x))
    if (DECL_DECLARES_FUNCTION_P (x))
      DECL_IN_AGGR_P (x) = false;
    else if (VAR_P (x) && TREE_STATIC (x)
	     && TREE_TYPE (x) != error_mark_node
	     && same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (x)), t))
      SET_DECL_MODE (x, TYPE_MODE (t));

  /* Complain if one of the field types requires lower visibility.  */
  constrain_class_visibility (t);

  /* Make the rtl for any new vtables we have created, and unmark
     the base types we marked.  */
  finish_vtbls (t);

  /* Build the VTT for T.  */
  build_vtt (t);

  if (warn_nonvdtor
      && TYPE_POLYMORPHIC_P (t) && accessible_nvdtor_p (t)
      && !CLASSTYPE_FINAL (t))
    warning (OPT_Wnon_virtual_dtor,
	     "%q#T has virtual functions and accessible"
	     " non-virtual destructor", t);

  complete_vars (t);

  if (warn_overloaded_virtual)
    warn_hidden (t);

  /* Class layout, assignment of virtual table slots, etc., is now
     complete.  Give the back end a chance to tweak the visibility of
     the class or perform any other required target modifications.  */
  targetm.cxx.adjust_class_at_definition (t);

  maybe_suppress_debug_info (t);

  if (flag_vtable_verify)
    vtv_save_class_info (t);

  dump_class_hierarchy (t);

  /* Finish debugging output for this type.  */
  rest_of_type_compilation (t, ! LOCAL_CLASS_P (t));

  if (TYPE_TRANSPARENT_AGGR (t))
    {
      tree field = first_field (t);
      if (field == NULL_TREE || error_operand_p (field))
	{
	  error ("type transparent %q#T does not have any fields", t);
	  TYPE_TRANSPARENT_AGGR (t) = 0;
	}
      else if (DECL_ARTIFICIAL (field))
	{
	  if (DECL_FIELD_IS_BASE (field))
	    error ("type transparent class %qT has base classes", t);
	  else
	    {
	      gcc_checking_assert (DECL_VIRTUAL_P (field));
	      error ("type transparent class %qT has virtual functions", t);
	    }
	  TYPE_TRANSPARENT_AGGR (t) = 0;
	}
      else if (TYPE_MODE (t) != DECL_MODE (field))
	{
	  error ("type transparent %q#T cannot be made transparent because "
		 "the type of the first field has a different ABI from the "
		 "class overall", t);
	  TYPE_TRANSPARENT_AGGR (t) = 0;
	}
    }
}

/* When T was built up, the member declarations were added in reverse
   order.  Rearrange them to declaration order.  */

void
unreverse_member_declarations (tree t)
{
  tree next;
  tree prev;
  tree x;

  /* The following lists are all in reverse order.  Put them in
     declaration order now.  */
  CLASSTYPE_DECL_LIST (t) = nreverse (CLASSTYPE_DECL_LIST (t));

  /* For the TYPE_FIELDS, only the non TYPE_DECLs are in reverse
     order, so we can't just use nreverse.  Due to stat_hack
     chicanery in finish_member_declaration.  */
  prev = NULL_TREE;
  for (x = TYPE_FIELDS (t);
       x && TREE_CODE (x) != TYPE_DECL;
       x = next)
    {
      next = DECL_CHAIN (x);
      DECL_CHAIN (x) = prev;
      prev = x;
    }

  if (prev)
    {
      DECL_CHAIN (TYPE_FIELDS (t)) = x;
      TYPE_FIELDS (t) = prev;
    }
}

tree
finish_struct (tree t, tree attributes)
{
  location_t saved_loc = input_location;

  /* Now that we've got all the field declarations, reverse everything
     as necessary.  */
  unreverse_member_declarations (t);

  cplus_decl_attributes (&t, attributes, (int) ATTR_FLAG_TYPE_IN_PLACE);
  fixup_attribute_variants (t);

  /* Nadger the current location so that diagnostics point to the start of
     the struct, not the end.  */
  input_location = DECL_SOURCE_LOCATION (TYPE_NAME (t));

  if (processing_template_decl)
    {
      tree x;

      /* We need to add the target functions of USING_DECLS, so that
	 they can be found when the using declaration is not
	 instantiated yet.  */
      for (x = TYPE_FIELDS (t); x; x = DECL_CHAIN (x))
	if (TREE_CODE (x) == USING_DECL)
	  {
	    tree fn = strip_using_decl (x);
  	    if (OVL_P (fn))
	      for (lkp_iterator iter (fn); iter; ++iter)
		add_method (t, *iter, true);
	  }
	else if (DECL_DECLARES_FUNCTION_P (x))
	  {
	    DECL_IN_AGGR_P (x) = false;
	    if (DECL_VIRTUAL_P (x))
	      CLASSTYPE_NON_AGGREGATE (t) = true;
	  }
	else if (TREE_CODE (x) == FIELD_DECL)
	  {
	    if (TREE_PROTECTED (x) || TREE_PRIVATE (x))
	      CLASSTYPE_NON_AGGREGATE (t) = true;
	  }

      /* Also add a USING_DECL for operator=.  We know there'll be (at
	 least) one, but we don't know the signature(s).  We want name
	 lookup not to fail or recurse into bases.  This isn't added
	 to the template decl list so we drop this at instantiation
	 time.  */
      tree ass_op = build_lang_decl (USING_DECL, assign_op_identifier,
				     NULL_TREE);
      DECL_CONTEXT (ass_op) = t;
      USING_DECL_SCOPE (ass_op) = t;
      DECL_DEPENDENT_P (ass_op) = true;
      DECL_ARTIFICIAL (ass_op) = true;
      DECL_CHAIN (ass_op) = TYPE_FIELDS (t);
      TYPE_FIELDS (t) = ass_op;

      TYPE_SIZE (t) = bitsize_zero_node;
      TYPE_SIZE_UNIT (t) = size_zero_node;
      /* COMPLETE_TYPE_P is now true.  */

      set_class_bindings (t);

      /* We need to emit an error message if this type was used as a parameter
	 and it is an abstract type, even if it is a template. We construct
	 a simple CLASSTYPE_PURE_VIRTUALS list without taking bases into
	 account and we call complete_vars with this type, which will check
	 the PARM_DECLS. Note that while the type is being defined,
	 CLASSTYPE_PURE_VIRTUALS contains the list of the inline friends
	 (see CLASSTYPE_INLINE_FRIENDS) so we need to clear it.  */
      CLASSTYPE_PURE_VIRTUALS (t) = NULL;
      for (x = TYPE_FIELDS (t); x; x = DECL_CHAIN (x))
	if (TREE_CODE (x) == FUNCTION_DECL && DECL_PURE_VIRTUAL_P (x))
	  vec_safe_push (CLASSTYPE_PURE_VIRTUALS (t), x);
      complete_vars (t);

      /* Remember current #pragma pack value.  */
      TYPE_PRECISION (t) = maximum_field_alignment;

      if (cxx_dialect < cxx20)
	{
	  if (!CLASSTYPE_NON_AGGREGATE (t)
	      && type_has_user_provided_or_explicit_constructor (t))
	    CLASSTYPE_NON_AGGREGATE (t) = 1;
	}
      else if (TYPE_HAS_USER_CONSTRUCTOR (t))
	CLASSTYPE_NON_AGGREGATE (t) = 1;

      /* Fix up any variants we've already built.  */
      fixup_type_variants (t);
    }
  else
    finish_struct_1 (t);
  /* COMPLETE_TYPE_P is now true.  */

  maybe_warn_about_overly_private_class (t);
  
  if (is_std_init_list (t))
    {
      /* People keep complaining that the compiler crashes on an invalid
	 definition of initializer_list, so I guess we should explicitly
	 reject it.  What the compiler internals care about is that it's a
	 template and has a pointer field followed by size_type field.  */
      bool ok = false;
      if (processing_template_decl)
	{
	  tree f = next_initializable_field (TYPE_FIELDS (t));
	  if (f && TYPE_PTR_P (TREE_TYPE (f)))
	    {
	      f = next_initializable_field (DECL_CHAIN (f));
	      if (f && same_type_p (TREE_TYPE (f), size_type_node))
		ok = true;
	    }
	}
      if (!ok)
	fatal_error (input_location, "definition of %qD does not match "
		     "%<#include <initializer_list>%>", TYPE_NAME (t));
    }

  input_location = saved_loc;

  TYPE_BEING_DEFINED (t) = 0;

  if (current_class_type)
    popclass ();
  else
    error ("trying to finish struct, but kicked out due to previous parse errors");

  if (flag_openmp)
    for (tree decl = TYPE_FIELDS (t); decl; decl = DECL_CHAIN (decl))
      if (TREE_CODE (decl) == FUNCTION_DECL
	  && DECL_NONSTATIC_MEMBER_FUNCTION_P (decl))
	if (tree attr = lookup_attribute ("omp declare variant base",
					  DECL_ATTRIBUTES (decl)))
	  omp_declare_variant_finalize (decl, attr);

  if (processing_template_decl && at_function_scope_p ()
      /* Lambdas are defined by the LAMBDA_EXPR.  */
      && !LAMBDA_TYPE_P (t))
    add_stmt (build_min (TAG_DEFN, t));

  return t;
}

/* Hash table to avoid endless recursion when handling references.  */
static hash_table<nofree_ptr_hash<tree_node> > *fixed_type_or_null_ref_ht;

/* Return the dynamic type of INSTANCE, if known.
   Used to determine whether the virtual function table is needed
   or not.

   *NONNULL is set iff INSTANCE can be known to be nonnull, regardless
   of our knowledge of its type.  *NONNULL should be initialized
   before this function is called.  */

static tree
fixed_type_or_null (tree instance, int *nonnull, int *cdtorp)
{
#define RECUR(T) fixed_type_or_null((T), nonnull, cdtorp)

  switch (TREE_CODE (instance))
    {
    case INDIRECT_REF:
      if (INDIRECT_TYPE_P (TREE_TYPE (instance)))
	return NULL_TREE;
      else
	return RECUR (TREE_OPERAND (instance, 0));

    case CALL_EXPR:
      /* This is a call to a constructor, hence it's never zero.  */
      if (CALL_EXPR_FN (instance)
	  && TREE_HAS_CONSTRUCTOR (instance))
	{
	  if (nonnull)
	    *nonnull = 1;
	  return TREE_TYPE (instance);
	}
      return NULL_TREE;

    case SAVE_EXPR:
      /* This is a call to a constructor, hence it's never zero.  */
      if (TREE_HAS_CONSTRUCTOR (instance))
	{
	  if (nonnull)
	    *nonnull = 1;
	  return TREE_TYPE (instance);
	}
      return RECUR (TREE_OPERAND (instance, 0));

    case POINTER_PLUS_EXPR:
    case PLUS_EXPR:
    case MINUS_EXPR:
      if (TREE_CODE (TREE_OPERAND (instance, 0)) == ADDR_EXPR)
	return RECUR (TREE_OPERAND (instance, 0));
      if (TREE_CODE (TREE_OPERAND (instance, 1)) == INTEGER_CST)
	/* Propagate nonnull.  */
	return RECUR (TREE_OPERAND (instance, 0));

      return NULL_TREE;

    CASE_CONVERT:
      return RECUR (TREE_OPERAND (instance, 0));

    case ADDR_EXPR:
      instance = TREE_OPERAND (instance, 0);
      if (nonnull)
	{
	  /* Just because we see an ADDR_EXPR doesn't mean we're dealing
	     with a real object -- given &p->f, p can still be null.  */
	  tree t = get_base_address (instance);
	  /* ??? Probably should check DECL_WEAK here.  */
	  if (t && DECL_P (t))
	    *nonnull = 1;
	}
      return RECUR (instance);

    case COMPONENT_REF:
      /* If this component is really a base class reference, then the field
	 itself isn't definitive.  */
      if (DECL_FIELD_IS_BASE (TREE_OPERAND (instance, 1)))
	return RECUR (TREE_OPERAND (instance, 0));
      return RECUR (TREE_OPERAND (instance, 1));

    case VAR_DECL:
    case FIELD_DECL:
      if (TREE_CODE (TREE_TYPE (instance)) == ARRAY_TYPE
	  && MAYBE_CLASS_TYPE_P (TREE_TYPE (TREE_TYPE (instance))))
	{
	  if (nonnull)
	    *nonnull = 1;
	  return TREE_TYPE (TREE_TYPE (instance));
	}
      /* fall through.  */
    case TARGET_EXPR:
    case PARM_DECL:
    case RESULT_DECL:
      if (MAYBE_CLASS_TYPE_P (TREE_TYPE (instance)))
	{
	  if (nonnull)
	    *nonnull = 1;
	  return TREE_TYPE (instance);
	}
      else if (instance == current_class_ptr)
	{
	  if (nonnull)
	    *nonnull = 1;

	  /* if we're in a ctor or dtor, we know our type.  If
	     current_class_ptr is set but we aren't in a function, we're in
	     an NSDMI (and therefore a constructor).  */
	  if (current_scope () != current_function_decl
	      || (DECL_LANG_SPECIFIC (current_function_decl)
		  && (DECL_CONSTRUCTOR_P (current_function_decl)
		      || DECL_DESTRUCTOR_P (current_function_decl))))
	    {
	      if (cdtorp)
		*cdtorp = 1;
	      return TREE_TYPE (TREE_TYPE (instance));
	    }
	}
      else if (TYPE_REF_P (TREE_TYPE (instance)))
	{
	  /* We only need one hash table because it is always left empty.  */
	  if (!fixed_type_or_null_ref_ht)
	    fixed_type_or_null_ref_ht
	      = new hash_table<nofree_ptr_hash<tree_node> > (37);

	  /* Reference variables should be references to objects.  */
	  if (nonnull)
	    *nonnull = 1;

	  /* Enter the INSTANCE in a table to prevent recursion; a
	     variable's initializer may refer to the variable
	     itself.  */
	  if (VAR_P (instance)
	      && DECL_INITIAL (instance)
	      && !type_dependent_expression_p_push (DECL_INITIAL (instance))
	      && !fixed_type_or_null_ref_ht->find (instance))
	    {
	      tree type;
	      tree_node **slot;

	      slot = fixed_type_or_null_ref_ht->find_slot (instance, INSERT);
	      *slot = instance;
	      type = RECUR (DECL_INITIAL (instance));
	      fixed_type_or_null_ref_ht->remove_elt (instance);

	      return type;
	    }
	}
      return NULL_TREE;

    case VIEW_CONVERT_EXPR:
      if (location_wrapper_p (instance))
	return RECUR (TREE_OPERAND (instance, 0));
      else
	/* TODO: Recursion may be correct for some non-location-wrapper
	   uses of VIEW_CONVERT_EXPR.  */
	return NULL_TREE;

    default:
      return NULL_TREE;
    }
#undef RECUR
}

/* Return nonzero if the dynamic type of INSTANCE is known, and
   equivalent to the static type.  We also handle the case where
   INSTANCE is really a pointer. Return negative if this is a
   ctor/dtor. There the dynamic type is known, but this might not be
   the most derived base of the original object, and hence virtual
   bases may not be laid out according to this type.

   Used to determine whether the virtual function table is needed
   or not.

   *NONNULL is set iff INSTANCE can be known to be nonnull, regardless
   of our knowledge of its type.  *NONNULL should be initialized
   before this function is called.  */

int
resolves_to_fixed_type_p (tree instance, int* nonnull)
{
  tree t = TREE_TYPE (instance);
  int cdtorp = 0;
  tree fixed;

  /* processing_template_decl can be false in a template if we're in
     instantiate_non_dependent_expr, but we still want to suppress
     this check.  */
  if (in_template_function ())
    {
      /* In a template we only care about the type of the result.  */
      if (nonnull)
	*nonnull = true;
      return true;
    }

  fixed = fixed_type_or_null (instance, nonnull, &cdtorp);
  if (INDIRECT_TYPE_P (t))
    t = TREE_TYPE (t);
  if (CLASS_TYPE_P (t) && CLASSTYPE_FINAL (t))
    return 1;
  if (fixed == NULL_TREE)
    return 0;
  if (!same_type_ignoring_top_level_qualifiers_p (t, fixed))
    return 0;
  return cdtorp ? -1 : 1;
}


void
init_class_processing (void)
{
  current_class_depth = 0;
  current_class_stack_size = 10;
  current_class_stack
    = XNEWVEC (struct class_stack_node, current_class_stack_size);
  sizeof_biggest_empty_class = size_zero_node;

  ridpointers[(int) RID_PUBLIC] = access_public_node;
  ridpointers[(int) RID_PRIVATE] = access_private_node;
  ridpointers[(int) RID_PROTECTED] = access_protected_node;
}

/* Restore the cached PREVIOUS_CLASS_LEVEL.  */

static void
restore_class_cache (void)
{
  tree type;

  /* We are re-entering the same class we just left, so we don't
     have to search the whole inheritance matrix to find all the
     decls to bind again.  Instead, we install the cached
     class_shadowed list and walk through it binding names.  */
  push_binding_level (previous_class_level);
  class_binding_level = previous_class_level;
  /* Restore IDENTIFIER_TYPE_VALUE.  */
  for (type = class_binding_level->type_shadowed;
       type;
       type = TREE_CHAIN (type))
    SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (type), TREE_TYPE (type));
}

/* Set global variables CURRENT_CLASS_NAME and CURRENT_CLASS_TYPE as
   appropriate for TYPE.

   So that we may avoid calls to lookup_name, we cache the _TYPE
   nodes of local TYPE_DECLs in the TREE_TYPE field of the name.

   For multiple inheritance, we perform a two-pass depth-first search
   of the type lattice.  */

void
pushclass (tree type)
{
  class_stack_node_t csn;

  type = TYPE_MAIN_VARIANT (type);

  /* Make sure there is enough room for the new entry on the stack.  */
  if (current_class_depth + 1 >= current_class_stack_size)
    {
      current_class_stack_size *= 2;
      current_class_stack
	= XRESIZEVEC (struct class_stack_node, current_class_stack,
		      current_class_stack_size);
    }

  /* Insert a new entry on the class stack.  */
  csn = current_class_stack + current_class_depth;
  csn->name = current_class_name;
  csn->type = current_class_type;
  csn->access = current_access_specifier;
  csn->names_used = 0;
  csn->hidden = 0;
  current_class_depth++;

  /* Now set up the new type.  */
  current_class_name = TYPE_NAME (type);
  if (TREE_CODE (current_class_name) == TYPE_DECL)
    current_class_name = DECL_NAME (current_class_name);
  current_class_type = type;

  /* By default, things in classes are private, while things in
     structures or unions are public.  */
  current_access_specifier = (CLASSTYPE_DECLARED_CLASS (type)
			      ? access_private_node
			      : access_public_node);

  if (previous_class_level
      && type != previous_class_level->this_entity
      && current_class_depth == 1)
    {
      /* Forcibly remove any old class remnants.  */
      invalidate_class_lookup_cache ();
    }

  if (!previous_class_level
      || type != previous_class_level->this_entity
      || current_class_depth > 1)
    pushlevel_class ();
  else
    restore_class_cache ();
}

/* Get out of the current class scope. If we were in a class scope
   previously, that is the one popped to.  */

void
popclass (void)
{
  poplevel_class ();

  current_class_depth--;
  current_class_name = current_class_stack[current_class_depth].name;
  current_class_type = current_class_stack[current_class_depth].type;
  current_access_specifier = current_class_stack[current_class_depth].access;
  if (current_class_stack[current_class_depth].names_used)
    splay_tree_delete (current_class_stack[current_class_depth].names_used);
}

/* Mark the top of the class stack as hidden.  */

void
push_class_stack (void)
{
  if (current_class_depth)
    ++current_class_stack[current_class_depth - 1].hidden;
}

/* Mark the top of the class stack as un-hidden.  */

void
pop_class_stack (void)
{
  if (current_class_depth)
    --current_class_stack[current_class_depth - 1].hidden;
}

/* If the class type currently being defined is either T or
   a nested type of T, returns the type from the current_class_stack,
   which might be equivalent to but not equal to T in case of
   constrained partial specializations.  */

tree
currently_open_class (tree t)
{
  int i;

  if (!CLASS_TYPE_P (t))
    return NULL_TREE;

  t = TYPE_MAIN_VARIANT (t);

  /* We start looking from 1 because entry 0 is from global scope,
     and has no type.  */
  for (i = current_class_depth; i > 0; --i)
    {
      tree c;
      if (i == current_class_depth)
	c = current_class_type;
      else
	{
	  if (current_class_stack[i].hidden)
	    break;
	  c = current_class_stack[i].type;
	}
      if (!c)
	continue;
      if (same_type_p (c, t))
	return c;
    }
  return NULL_TREE;
}

/* If either current_class_type or one of its enclosing classes are derived
   from T, return the appropriate type.  Used to determine how we found
   something via unqualified lookup.  */

tree
currently_open_derived_class (tree t)
{
  int i;

  /* The bases of a dependent type are unknown.  */
  if (dependent_type_p (t))
    return NULL_TREE;

  if (!current_class_type)
    return NULL_TREE;

  if (DERIVED_FROM_P (t, current_class_type))
    return current_class_type;

  for (i = current_class_depth - 1; i > 0; --i)
    {
      if (current_class_stack[i].hidden)
	break;
      if (DERIVED_FROM_P (t, current_class_stack[i].type))
	return current_class_stack[i].type;
    }

  return NULL_TREE;
}

/* Return the outermost enclosing class type that is still open, or
   NULL_TREE.  */

tree
outermost_open_class (void)
{
  if (!current_class_type)
    return NULL_TREE;
  tree r = NULL_TREE;
  if (TYPE_BEING_DEFINED (current_class_type))
    r = current_class_type;
  for (int i = current_class_depth - 1; i > 0; --i)
    {
      if (current_class_stack[i].hidden)
	break;
      tree t = current_class_stack[i].type;
      if (!TYPE_BEING_DEFINED (t))
	break;
      r = t;
    }
  return r;
}

/* Returns the innermost class type which is not a lambda closure type.  */

tree
current_nonlambda_class_type (void)
{
  tree type = current_class_type;
  while (type && LAMBDA_TYPE_P (type))
    type = decl_type_context (TYPE_NAME (type));
  return type;
}

/* When entering a class scope, all enclosing class scopes' names with
   static meaning (static variables, static functions, types and
   enumerators) have to be visible.  This recursive function calls
   pushclass for all enclosing class contexts until global or a local
   scope is reached.  TYPE is the enclosed class.  */

void
push_nested_class (tree type)
{
  /* A namespace might be passed in error cases, like A::B:C.  */
  if (type == NULL_TREE
      || !CLASS_TYPE_P (type))
    return;

  push_nested_class (DECL_CONTEXT (TYPE_MAIN_DECL (type)));

  pushclass (type);
}

/* Undoes a push_nested_class call.  */

void
pop_nested_class (void)
{
  tree context = DECL_CONTEXT (TYPE_MAIN_DECL (current_class_type));

  popclass ();
  if (context && CLASS_TYPE_P (context))
    pop_nested_class ();
}

/* Returns the number of extern "LANG" blocks we are nested within.  */

int
current_lang_depth (void)
{
  return vec_safe_length (current_lang_base);
}

/* Set global variables CURRENT_LANG_NAME to appropriate value
   so that behavior of name-mangling machinery is correct.  */

void
push_lang_context (tree name)
{
  vec_safe_push (current_lang_base, current_lang_name);

  if (name == lang_name_cplusplus)
    current_lang_name = name;
  else if (name == lang_name_c)
    current_lang_name = name;
  else
    error ("language string %<\"%E\"%> not recognized", name);
}

/* Get out of the current language scope.  */

void
pop_lang_context (void)
{
  current_lang_name = current_lang_base->pop ();
}

/* Type instantiation routines.  */

/* Given an OVERLOAD and a TARGET_TYPE, return the function that
   matches the TARGET_TYPE.  If there is no satisfactory match, return
   error_mark_node, and issue an error & warning messages under
   control of FLAGS.  Permit pointers to member function if FLAGS
   permits.  If TEMPLATE_ONLY, the name of the overloaded function was
   a template-id, and EXPLICIT_TARGS are the explicitly provided
   template arguments.  

   If OVERLOAD is for one or more member functions, then ACCESS_PATH
   is the base path used to reference those member functions.  If
   the address is resolved to a member function, access checks will be
   performed and errors issued if appropriate.  */

static tree
resolve_address_of_overloaded_function (tree target_type,
					tree overload,
					tsubst_flags_t complain,
					bool template_only,
					tree explicit_targs,
					tree access_path)
{
  /* Here's what the standard says:

       [over.over]

       If the name is a function template, template argument deduction
       is done, and if the argument deduction succeeds, the deduced
       arguments are used to generate a single template function, which
       is added to the set of overloaded functions considered.

       Non-member functions and static member functions match targets of
       type "pointer-to-function" or "reference-to-function."  Nonstatic
       member functions match targets of type "pointer-to-member
       function;" the function type of the pointer to member is used to
       select the member function from the set of overloaded member
       functions.  If a non-static member function is selected, the
       reference to the overloaded function name is required to have the
       form of a pointer to member as described in 5.3.1.

       If more than one function is selected, any template functions in
       the set are eliminated if the set also contains a non-template
       function, and any given template function is eliminated if the
       set contains a second template function that is more specialized
       than the first according to the partial ordering rules 14.5.5.2.
       After such eliminations, if any, there shall remain exactly one
       selected function.  */

  int is_ptrmem = 0;
  /* We store the matches in a TREE_LIST rooted here.  The functions
     are the TREE_PURPOSE, not the TREE_VALUE, in this list, for easy
     interoperability with most_specialized_instantiation.  */
  tree matches = NULL_TREE;
  tree fn;
  tree target_fn_type;

  /* By the time we get here, we should be seeing only real
     pointer-to-member types, not the internal POINTER_TYPE to
     METHOD_TYPE representation.  */
  gcc_assert (!TYPE_PTR_P (target_type)
	      || TREE_CODE (TREE_TYPE (target_type)) != METHOD_TYPE);

  gcc_assert (is_overloaded_fn (overload));

  /* Check that the TARGET_TYPE is reasonable.  */
  if (TYPE_PTRFN_P (target_type)
      || TYPE_REFFN_P (target_type))
    /* This is OK.  */;
  else if (TYPE_PTRMEMFUNC_P (target_type))
    /* This is OK, too.  */
    is_ptrmem = 1;
  else if (TREE_CODE (target_type) == FUNCTION_TYPE)
    /* This is OK, too.  This comes from a conversion to reference
       type.  */
    target_type = build_reference_type (target_type);
  else
    {
      if (complain & tf_error)
	error ("cannot resolve overloaded function %qD based on"
	       " conversion to type %qT",
	       OVL_NAME (overload), target_type);
      return error_mark_node;
    }

  /* Non-member functions and static member functions match targets of type
     "pointer-to-function" or "reference-to-function."  Nonstatic member
     functions match targets of type "pointer-to-member-function;" the
     function type of the pointer to member is used to select the member
     function from the set of overloaded member functions.

     So figure out the FUNCTION_TYPE that we want to match against.  */
  target_fn_type = static_fn_type (target_type);

  /* If we can find a non-template function that matches, we can just
     use it.  There's no point in generating template instantiations
     if we're just going to throw them out anyhow.  But, of course, we
     can only do this when we don't *need* a template function.  */
  if (!template_only)
    for (lkp_iterator iter (overload); iter; ++iter)
      {
	tree fn = *iter;

	if (TREE_CODE (fn) == TEMPLATE_DECL)
	  /* We're not looking for templates just yet.  */
	  continue;

	if ((TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE) != is_ptrmem)
	  /* We're looking for a non-static member, and this isn't
	     one, or vice versa.  */
	  continue;

	/* Constraints must be satisfied. This is done before
	   return type deduction since that instantiates the
	   function. */
	if (!constraints_satisfied_p (fn))
	  continue;

	if (undeduced_auto_decl (fn))
	  {
	    /* Force instantiation to do return type deduction.  */
	    maybe_instantiate_decl (fn);
	    require_deduced_type (fn);
	  }

	/* In C++17 we need the noexcept-qualifier to compare types.  */
	if (flag_noexcept_type
	    && !maybe_instantiate_noexcept (fn, complain))
	  continue;

	/* See if there's a match.  */
	tree fntype = static_fn_type (fn);
	if (same_type_p (target_fn_type, fntype)
	    || fnptr_conv_p (target_fn_type, fntype))
	  matches = tree_cons (fn, NULL_TREE, matches);
      }

  /* Now, if we've already got a match (or matches), there's no need
     to proceed to the template functions.  But, if we don't have a
     match we need to look at them, too.  */
  if (!matches)
    {
      tree target_arg_types;
      tree target_ret_type;
      tree *args;
      unsigned int nargs, ia;
      tree arg;

      target_arg_types = TYPE_ARG_TYPES (target_fn_type);
      target_ret_type = TREE_TYPE (target_fn_type);

      nargs = list_length (target_arg_types);
      args = XALLOCAVEC (tree, nargs);
      for (arg = target_arg_types, ia = 0;
	   arg != NULL_TREE && arg != void_list_node;
	   arg = TREE_CHAIN (arg), ++ia)
	args[ia] = TREE_VALUE (arg);
      nargs = ia;

      for (lkp_iterator iter (overload); iter; ++iter)
	{
	  tree fn = *iter;
	  tree instantiation;
	  tree targs;

	  if (TREE_CODE (fn) != TEMPLATE_DECL)
	    /* We're only looking for templates.  */
	    continue;

	  if ((TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE)
	      != is_ptrmem)
	    /* We're not looking for a non-static member, and this is
	       one, or vice versa.  */
	    continue;

	  tree ret = target_ret_type;

	  /* If the template has a deduced return type, don't expose it to
	     template argument deduction.  */
	  if (undeduced_auto_decl (fn))
	    ret = NULL_TREE;

	  /* Try to do argument deduction.  */
	  targs = make_tree_vec (DECL_NTPARMS (fn));
	  instantiation = fn_type_unification (fn, explicit_targs, targs, args,
					       nargs, ret,
					      DEDUCE_EXACT, LOOKUP_NORMAL,
					       NULL, false, false);
	  if (instantiation == error_mark_node)
	    /* Instantiation failed.  */
	    continue;

	  /* Constraints must be satisfied. This is done before
	     return type deduction since that instantiates the
	     function. */
	  if (flag_concepts && !constraints_satisfied_p (instantiation))
	    continue;

	  /* And now force instantiation to do return type deduction.  */
	  if (undeduced_auto_decl (instantiation))
	    {
	      ++function_depth;
	      instantiate_decl (instantiation, /*defer*/false, /*class*/false);
	      --function_depth;

	      require_deduced_type (instantiation);
	    }

	  /* In C++17 we need the noexcept-qualifier to compare types.  */
	  if (flag_noexcept_type)
	    maybe_instantiate_noexcept (instantiation, complain);

	  /* See if there's a match.  */
	  tree fntype = static_fn_type (instantiation);
	  if (same_type_p (target_fn_type, fntype)
	      || fnptr_conv_p (target_fn_type, fntype))
	    matches = tree_cons (instantiation, fn, matches);
	}

      /* Now, remove all but the most specialized of the matches.  */
      if (matches)
	{
	  tree match = most_specialized_instantiation (matches);

	  if (match != error_mark_node)
	    matches = tree_cons (TREE_PURPOSE (match),
				 NULL_TREE,
				 NULL_TREE);
	}
    }

  /* Now we should have exactly one function in MATCHES.  */
  if (matches == NULL_TREE)
    {
      /* There were *no* matches.  */
      if (complain & tf_error)
	{
	  error ("no matches converting function %qD to type %q#T",
		 OVL_NAME (overload), target_type);

	  print_candidates (overload);
	}
      return error_mark_node;
    }
  else if (TREE_CHAIN (matches))
    {
      /* There were too many matches.  First check if they're all
	 the same function.  */
      tree match = NULL_TREE;

      fn = TREE_PURPOSE (matches);

      /* For multi-versioned functions, more than one match is just fine and
	 decls_match will return false as they are different.  */
      for (match = TREE_CHAIN (matches); match; match = TREE_CHAIN (match))
	if (!decls_match (fn, TREE_PURPOSE (match))
	    && !targetm.target_option.function_versions
	       (fn, TREE_PURPOSE (match)))
          break;

      if (match)
	{
	  if (complain & tf_error)
	    {
	      error ("converting overloaded function %qD to type %q#T is ambiguous",
		     OVL_NAME (overload), target_type);

	      /* Since print_candidates expects the functions in the
		 TREE_VALUE slot, we flip them here.  */
	      for (match = matches; match; match = TREE_CHAIN (match))
		TREE_VALUE (match) = TREE_PURPOSE (match);

	      print_candidates (matches);
	    }

	  return error_mark_node;
	}
    }

  /* Good, exactly one match.  Now, convert it to the correct type.  */
  fn = TREE_PURPOSE (matches);

  if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)
      && !(complain & tf_ptrmem_ok) && !flag_ms_extensions)
    {
      static int explained;

      if (!(complain & tf_error))
	return error_mark_node;

      auto_diagnostic_group d;
      if (permerror (input_location, "assuming pointer to member %qD", fn)
	  && !explained)
	{
	  inform (input_location, "(a pointer to member can only be "
		  "formed with %<&%E%>)", fn);
	  explained = 1;
	}
    }

  /* If a pointer to a function that is multi-versioned is requested, the
     pointer to the dispatcher function is returned instead.  This works
     well because indirectly calling the function will dispatch the right
     function version at run-time.  */
  if (DECL_FUNCTION_VERSIONED (fn))
    {
      fn = get_function_version_dispatcher (fn);
      if (fn == NULL)
	return error_mark_node;
      /* Mark all the versions corresponding to the dispatcher as used.  */
      if (!(complain & tf_conv))
	mark_versions_used (fn);
    }

  /* If we're doing overload resolution purely for the purpose of
     determining conversion sequences, we should not consider the
     function used.  If this conversion sequence is selected, the
     function will be marked as used at this point.  */
  if (!(complain & tf_conv))
    {
      /* Make =delete work with SFINAE.  */
      if (DECL_DELETED_FN (fn) && !(complain & tf_error))
	return error_mark_node;
      if (!mark_used (fn, complain) && !(complain & tf_error))
	return error_mark_node;
    }

  /* We could not check access to member functions when this
     expression was originally created since we did not know at that
     time to which function the expression referred.  */
  if (DECL_FUNCTION_MEMBER_P (fn))
    {
      gcc_assert (access_path);
      perform_or_defer_access_check (access_path, fn, fn, complain);
    }

  if (TYPE_PTRFN_P (target_type) || TYPE_PTRMEMFUNC_P (target_type))
    return cp_build_addr_expr (fn, complain);
  else
    {
      /* The target must be a REFERENCE_TYPE.  Above, cp_build_unary_op
	 will mark the function as addressed, but here we must do it
	 explicitly.  */
      cxx_mark_addressable (fn);

      return fn;
    }
}

/* This function will instantiate the type of the expression given in
   RHS to match the type of LHSTYPE.  If errors exist, then return
   error_mark_node. COMPLAIN is a bit mask.  If TF_ERROR is set, then
   we complain on errors.  If we are not complaining, never modify rhs,
   as overload resolution wants to try many possible instantiations, in
   the hope that at least one will work.

   For non-recursive calls, LHSTYPE should be a function, pointer to
   function, or a pointer to member function.  */

tree
instantiate_type (tree lhstype, tree rhs, tsubst_flags_t complain)
{
  tsubst_flags_t complain_in = complain;
  tree access_path = NULL_TREE;

  complain &= ~tf_ptrmem_ok;

  if (lhstype == unknown_type_node)
    {
      if (complain & tf_error)
	error ("not enough type information");
      return error_mark_node;
    }

  if (TREE_TYPE (rhs) != NULL_TREE && ! (type_unknown_p (rhs)))
    {
      tree fntype = non_reference (lhstype);
      if (same_type_p (fntype, TREE_TYPE (rhs)))
	return rhs;
      if (fnptr_conv_p (fntype, TREE_TYPE (rhs)))
	return rhs;
      if (flag_ms_extensions
	  && TYPE_PTRMEMFUNC_P (fntype)
	  && !TYPE_PTRMEMFUNC_P (TREE_TYPE (rhs)))
	/* Microsoft allows `A::f' to be resolved to a
	   pointer-to-member.  */
	;
      else
	{
	  if (complain & tf_error)
	    error ("cannot convert %qE from type %qT to type %qT",
		   rhs, TREE_TYPE (rhs), fntype);
	  return error_mark_node;
	}
    }

  /* If we instantiate a template, and it is a A ?: C expression
     with omitted B, look through the SAVE_EXPR.  */
  if (TREE_CODE (rhs) == SAVE_EXPR)
    rhs = TREE_OPERAND (rhs, 0);

  if (BASELINK_P (rhs))
    {
      access_path = BASELINK_ACCESS_BINFO (rhs);
      rhs = BASELINK_FUNCTIONS (rhs);
    }

  /* If we are in a template, and have a NON_DEPENDENT_EXPR, we cannot
     deduce any type information.  */
  if (TREE_CODE (rhs) == NON_DEPENDENT_EXPR)
    {
      if (complain & tf_error)
	error ("not enough type information");
      return error_mark_node;
    }

  /* There are only a few kinds of expressions that may have a type
     dependent on overload resolution.  */
  gcc_assert (TREE_CODE (rhs) == ADDR_EXPR
	      || TREE_CODE (rhs) == COMPONENT_REF
	      || is_overloaded_fn (rhs)
	      || (flag_ms_extensions && TREE_CODE (rhs) == FUNCTION_DECL));

  /* This should really only be used when attempting to distinguish
     what sort of a pointer to function we have.  For now, any
     arithmetic operation which is not supported on pointers
     is rejected as an error.  */

  switch (TREE_CODE (rhs))
    {
    case COMPONENT_REF:
      {
	tree member = TREE_OPERAND (rhs, 1);

	member = instantiate_type (lhstype, member, complain);
	if (member != error_mark_node
	    && TREE_SIDE_EFFECTS (TREE_OPERAND (rhs, 0)))
	  /* Do not lose object's side effects.  */
	  return build2 (COMPOUND_EXPR, TREE_TYPE (member),
			 TREE_OPERAND (rhs, 0), member);
	return member;
      }

    case OFFSET_REF:
      rhs = TREE_OPERAND (rhs, 1);
      if (BASELINK_P (rhs))
	return instantiate_type (lhstype, rhs, complain_in);

      /* This can happen if we are forming a pointer-to-member for a
	 member template.  */
      gcc_assert (TREE_CODE (rhs) == TEMPLATE_ID_EXPR);

      /* Fall through.  */

    case TEMPLATE_ID_EXPR:
      {
	tree fns = TREE_OPERAND (rhs, 0);
	tree args = TREE_OPERAND (rhs, 1);

	return
	  resolve_address_of_overloaded_function (lhstype, fns, complain_in,
						  /*template_only=*/true,
						  args, access_path);
      }

    case OVERLOAD:
    case FUNCTION_DECL:
      return
	resolve_address_of_overloaded_function (lhstype, rhs, complain_in,
						/*template_only=*/false,
						/*explicit_targs=*/NULL_TREE,
						access_path);

    case ADDR_EXPR:
    {
      if (PTRMEM_OK_P (rhs))
	complain |= tf_ptrmem_ok;

      return instantiate_type (lhstype, TREE_OPERAND (rhs, 0), complain);
    }

    case ERROR_MARK:
      return error_mark_node;

    default:
      gcc_unreachable ();
    }
  return error_mark_node;
}

/* Return the name of the virtual function pointer field
   (as an IDENTIFIER_NODE) for the given TYPE.  Note that
   this may have to look back through base types to find the
   ultimate field name.  (For single inheritance, these could
   all be the same name.  Who knows for multiple inheritance).  */

static tree
get_vfield_name (tree type)
{
  tree binfo, base_binfo;

  for (binfo = TYPE_BINFO (type);
       BINFO_N_BASE_BINFOS (binfo);
       binfo = base_binfo)
    {
      base_binfo = BINFO_BASE_BINFO (binfo, 0);

      if (BINFO_VIRTUAL_P (base_binfo)
	  || !TYPE_CONTAINS_VPTR_P (BINFO_TYPE (base_binfo)))
	break;
    }

  type = BINFO_TYPE (binfo);
  tree ctor_name = constructor_name (type);
  char *buf = (char *) alloca (sizeof (VFIELD_NAME_FORMAT)
			       + IDENTIFIER_LENGTH (ctor_name) + 2);
  sprintf (buf, VFIELD_NAME_FORMAT, IDENTIFIER_POINTER (ctor_name));
  return get_identifier (buf);
}

/* Build a dummy reference to ourselves so Derived::Base (and A::A) works,
   according to [class]:
					  The class-name is also inserted
   into  the scope of the class itself.  For purposes of access checking,
   the inserted class name is treated as if it were a public member name.  */

void
build_self_reference (void)
{
  tree name = DECL_NAME (TYPE_NAME (current_class_type));
  tree decl = build_lang_decl (TYPE_DECL, name, current_class_type);

  DECL_NONLOCAL (decl) = 1;
  DECL_CONTEXT (decl) = current_class_type;
  DECL_ARTIFICIAL (decl) = 1;
  SET_DECL_SELF_REFERENCE_P (decl);
  set_underlying_type (decl);
  set_instantiating_module (decl);  

  if (processing_template_decl)
    decl = push_template_decl (decl);

  tree saved_cas = current_access_specifier;
  current_access_specifier = access_public_node;
  finish_member_declaration (decl);
  current_access_specifier = saved_cas;
}

/* Returns 1 if TYPE contains only padding bytes.  */

int
is_empty_class (tree type)
{
  if (type == error_mark_node)
    return 0;

  if (! CLASS_TYPE_P (type))
    return 0;

  return CLASSTYPE_EMPTY_P (type);
}

/* Returns true if TYPE contains no actual data, just various
   possible combinations of empty classes.  If IGNORE_VPTR is true,
   a vptr doesn't prevent the class from being considered empty.  Typically
   we want to ignore the vptr on assignment, and not on initialization.  */

bool
is_really_empty_class (tree type, bool ignore_vptr)
{
  if (CLASS_TYPE_P (type))
    {
      tree field;
      tree binfo;
      tree base_binfo;
      int i;

      /* CLASSTYPE_EMPTY_P isn't set properly until the class is actually laid
	 out, but we'd like to be able to check this before then.  */
      if (COMPLETE_TYPE_P (type) && is_empty_class (type))
	return true;

      if (!ignore_vptr && TYPE_CONTAINS_VPTR_P (type))
	return false;

      for (binfo = TYPE_BINFO (type), i = 0;
	   BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
	if (!is_really_empty_class (BINFO_TYPE (base_binfo), ignore_vptr))
	  return false;
      for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
	if (TREE_CODE (field) == FIELD_DECL
	    && !DECL_ARTIFICIAL (field)
	    /* An unnamed bit-field is not a data member.  */
	    && !DECL_UNNAMED_BIT_FIELD (field)
	    && !is_really_empty_class (TREE_TYPE (field), ignore_vptr))
	  return false;
      return true;
    }
  else if (TREE_CODE (type) == ARRAY_TYPE)
    return (integer_zerop (array_type_nelts_top (type))
	    || is_really_empty_class (TREE_TYPE (type), ignore_vptr));
  return false;
}

/* Note that NAME was looked up while the current class was being
   defined and that the result of that lookup was DECL.  */

void
maybe_note_name_used_in_class (tree name, tree decl)
{
  splay_tree names_used;

  /* If we're not defining a class, there's nothing to do.  */
  if (!(innermost_scope_kind() == sk_class
	&& TYPE_BEING_DEFINED (current_class_type)
	&& !LAMBDA_TYPE_P (current_class_type)))
    return;

  /* If there's already a binding for this NAME, then we don't have
     anything to worry about.  */
  if (lookup_member (current_class_type, name,
		     /*protect=*/0, /*want_type=*/false, tf_warning_or_error))
    return;

  if (!current_class_stack[current_class_depth - 1].names_used)
    current_class_stack[current_class_depth - 1].names_used
      = splay_tree_new (splay_tree_compare_pointers, 0, 0);
  names_used = current_class_stack[current_class_depth - 1].names_used;

  splay_tree_insert (names_used,
		     (splay_tree_key) name,
		     (splay_tree_value) decl);
}

/* Note that NAME was declared (as DECL) in the current class.  Check
   to see that the declaration is valid.  */

void
note_name_declared_in_class (tree name, tree decl)
{
  splay_tree names_used;
  splay_tree_node n;

  /* Look to see if we ever used this name.  */
  names_used
    = current_class_stack[current_class_depth - 1].names_used;
  if (!names_used)
    return;
  /* The C language allows members to be declared with a type of the same
     name, and the C++ standard says this diagnostic is not required.  So
     allow it in extern "C" blocks unless predantic is specified.
     Allow it in all cases if -ms-extensions is specified.  */
  if ((!pedantic && current_lang_name == lang_name_c)
      || flag_ms_extensions)
    return;
  n = splay_tree_lookup (names_used, (splay_tree_key) name);
  if (n)
    {
      /* [basic.scope.class]

	 A name N used in a class S shall refer to the same declaration
	 in its context and when re-evaluated in the completed scope of
	 S.  */
      if (permerror (location_of (decl),
		     "declaration of %q#D changes meaning of %qD",
		     decl, OVL_NAME (decl)))
	inform (location_of ((tree) n->value),
		"%qD declared here as %q#D",
		OVL_NAME (decl), (tree) n->value);
    }
}

/* Returns the VAR_DECL for the complete vtable associated with BINFO.
   Secondary vtables are merged with primary vtables; this function
   will return the VAR_DECL for the primary vtable.  */

tree
get_vtbl_decl_for_binfo (tree binfo)
{
  tree decl;

  decl = BINFO_VTABLE (binfo);
  if (decl && TREE_CODE (decl) == POINTER_PLUS_EXPR)
    {
      gcc_assert (TREE_CODE (TREE_OPERAND (decl, 0)) == ADDR_EXPR);
      decl = TREE_OPERAND (TREE_OPERAND (decl, 0), 0);
    }
  if (decl)
    gcc_assert (VAR_P (decl));
  return decl;
}


/* Returns the binfo for the primary base of BINFO.  If the resulting
   BINFO is a virtual base, and it is inherited elsewhere in the
   hierarchy, then the returned binfo might not be the primary base of
   BINFO in the complete object.  Check BINFO_PRIMARY_P or
   BINFO_LOST_PRIMARY_P to be sure.  */

static tree
get_primary_binfo (tree binfo)
{
  tree primary_base;

  primary_base = CLASSTYPE_PRIMARY_BINFO (BINFO_TYPE (binfo));
  if (!primary_base)
    return NULL_TREE;

  return copied_binfo (primary_base, binfo);
}

/* As above, but iterate until we reach the binfo that actually provides the
   vptr for BINFO.  */

static tree
most_primary_binfo (tree binfo)
{
  tree b = binfo;
  while (CLASSTYPE_HAS_PRIMARY_BASE_P (BINFO_TYPE (b))
	 && !BINFO_LOST_PRIMARY_P (b))
    {
      tree primary_base = get_primary_binfo (b);
      gcc_assert (BINFO_PRIMARY_P (primary_base)
		  && BINFO_INHERITANCE_CHAIN (primary_base) == b);
      b = primary_base;
    }
  return b;
}

/* Returns true if BINFO gets its vptr from a virtual base of the most derived
   type.  Note that the virtual inheritance might be above or below BINFO in
   the hierarchy.  */

bool
vptr_via_virtual_p (tree binfo)
{
  if (TYPE_P (binfo))
    binfo = TYPE_BINFO (binfo);
  tree primary = most_primary_binfo (binfo);
  /* Don't limit binfo_via_virtual, we want to return true when BINFO itself is
     a morally virtual base.  */
  tree virt = binfo_via_virtual (primary, NULL_TREE);
  return virt != NULL_TREE;
}

/* If INDENTED_P is zero, indent to INDENT. Return nonzero.  */

static int
maybe_indent_hierarchy (FILE * stream, int indent, int indented_p)
{
  if (!indented_p)
    fprintf (stream, "%*s", indent, "");
  return 1;
}

/* Dump the offsets of all the bases rooted at BINFO to STREAM.
   INDENT should be zero when called from the top level; it is
   incremented recursively.  IGO indicates the next expected BINFO in
   inheritance graph ordering.  */

static tree
dump_class_hierarchy_r (FILE *stream,
			dump_flags_t flags,
			tree binfo,
			tree igo,
			int indent)
{
  int indented = 0;
  tree base_binfo;
  int i;

  fprintf (stream, "%s (0x" HOST_WIDE_INT_PRINT_HEX ") ",
	   type_as_string (BINFO_TYPE (binfo), TFF_PLAIN_IDENTIFIER),
	   (HOST_WIDE_INT) (uintptr_t) binfo);
  if (binfo != igo)
    {
      fprintf (stream, "alternative-path\n");
      return igo;
    }
  igo = TREE_CHAIN (binfo);

  fprintf (stream, HOST_WIDE_INT_PRINT_DEC,
	   tree_to_shwi (BINFO_OFFSET (binfo)));
  if (is_empty_class (BINFO_TYPE (binfo)))
    fprintf (stream, " empty");
  else if (CLASSTYPE_NEARLY_EMPTY_P (BINFO_TYPE (binfo)))
    fprintf (stream, " nearly-empty");
  if (BINFO_VIRTUAL_P (binfo))
    fprintf (stream, " virtual");
  fprintf (stream, "\n");

  if (BINFO_PRIMARY_P (binfo))
    {
      indented = maybe_indent_hierarchy (stream, indent + 3, indented);
      fprintf (stream, " primary-for %s (0x" HOST_WIDE_INT_PRINT_HEX ")",
	       type_as_string (BINFO_TYPE (BINFO_INHERITANCE_CHAIN (binfo)),
			       TFF_PLAIN_IDENTIFIER),
	       (HOST_WIDE_INT) (uintptr_t) BINFO_INHERITANCE_CHAIN (binfo));
    }
  if (BINFO_LOST_PRIMARY_P (binfo))
    {
      indented = maybe_indent_hierarchy (stream, indent + 3, indented);
      fprintf (stream, " lost-primary");
    }
  if (indented)
    fprintf (stream, "\n");

  if (!(flags & TDF_SLIM))
    {
      int indented = 0;

      if (BINFO_SUBVTT_INDEX (binfo))
	{
	  indented = maybe_indent_hierarchy (stream, indent + 3, indented);
	  fprintf (stream, " subvttidx=%s",
		   expr_as_string (BINFO_SUBVTT_INDEX (binfo),
				   TFF_PLAIN_IDENTIFIER));
	}
      if (BINFO_VPTR_INDEX (binfo))
	{
	  indented = maybe_indent_hierarchy (stream, indent + 3, indented);
	  fprintf (stream, " vptridx=%s",
		   expr_as_string (BINFO_VPTR_INDEX (binfo),
				   TFF_PLAIN_IDENTIFIER));
	}
      if (BINFO_VPTR_FIELD (binfo))
	{
	  indented = maybe_indent_hierarchy (stream, indent + 3, indented);
	  fprintf (stream, " vbaseoffset=%s",
		   expr_as_string (BINFO_VPTR_FIELD (binfo),
				   TFF_PLAIN_IDENTIFIER));
	}
      if (BINFO_VTABLE (binfo))
	{
	  indented = maybe_indent_hierarchy (stream, indent + 3, indented);
	  fprintf (stream, " vptr=%s",
		   expr_as_string (BINFO_VTABLE (binfo),
				   TFF_PLAIN_IDENTIFIER));
	}

      if (indented)
	fprintf (stream, "\n");
    }

  for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
    igo = dump_class_hierarchy_r (stream, flags, base_binfo, igo, indent + 2);

  return igo;
}

/* Dump the BINFO hierarchy for T.  */

static void
dump_class_hierarchy_1 (FILE *stream, dump_flags_t flags, tree t)
{
  fprintf (stream, "Class %s\n", type_as_string (t, TFF_PLAIN_IDENTIFIER));
  fprintf (stream, "   size=%lu align=%lu\n",
	   (unsigned long)(tree_to_shwi (TYPE_SIZE (t)) / BITS_PER_UNIT),
	   (unsigned long)(TYPE_ALIGN (t) / BITS_PER_UNIT));
  if (tree as_base = CLASSTYPE_AS_BASE (t))
    fprintf (stream, "   base size=%lu base align=%lu\n",
	     (unsigned long)(tree_to_shwi (TYPE_SIZE (as_base))
			     / BITS_PER_UNIT),
	     (unsigned long)(TYPE_ALIGN (as_base) / BITS_PER_UNIT));
  dump_class_hierarchy_r (stream, flags, TYPE_BINFO (t), TYPE_BINFO (t), 0);
  fprintf (stream, "\n");
}

/* Debug interface to hierarchy dumping.  */

void
debug_class (tree t)
{
  dump_class_hierarchy_1 (stderr, TDF_SLIM, t);
}

static void
dump_class_hierarchy (tree t)
{
  dump_flags_t flags;
  if (FILE *stream = dump_begin (class_dump_id, &flags))
    {
      dump_class_hierarchy_1 (stream, flags, t);
      dump_end (class_dump_id, stream);
    }
}

static void
dump_array (FILE * stream, tree decl)
{
  tree value;
  unsigned HOST_WIDE_INT ix;
  HOST_WIDE_INT elt;
  tree size = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (decl)));

  elt = (tree_to_shwi (TYPE_SIZE (TREE_TYPE (TREE_TYPE (decl))))
	 / BITS_PER_UNIT);
  fprintf (stream, "%s:", decl_as_string (decl, TFF_PLAIN_IDENTIFIER));
  fprintf (stream, " %s entries",
	   expr_as_string (size_binop (PLUS_EXPR, size, size_one_node),
			   TFF_PLAIN_IDENTIFIER));
  fprintf (stream, "\n");

  FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (DECL_INITIAL (decl)),
			      ix, value)
    fprintf (stream, "%-4ld  %s\n", (long)(ix * elt),
	     expr_as_string (value, TFF_PLAIN_IDENTIFIER));
}

static void
dump_vtable (tree t, tree binfo, tree vtable)
{
  dump_flags_t flags;
  FILE *stream = dump_begin (class_dump_id, &flags);

  if (!stream)
    return;

  if (!(flags & TDF_SLIM))
    {
      int ctor_vtbl_p = TYPE_BINFO (t) != binfo;

      fprintf (stream, "%s for %s",
	       ctor_vtbl_p ? "Construction vtable" : "Vtable",
	       type_as_string (BINFO_TYPE (binfo), TFF_PLAIN_IDENTIFIER));
      if (ctor_vtbl_p)
	{
	  if (!BINFO_VIRTUAL_P (binfo))
	    fprintf (stream, " (0x" HOST_WIDE_INT_PRINT_HEX " instance)",
		     (HOST_WIDE_INT) (uintptr_t) binfo);
	  fprintf (stream, " in %s", type_as_string (t, TFF_PLAIN_IDENTIFIER));
	}
      fprintf (stream, "\n");
      dump_array (stream, vtable);
      fprintf (stream, "\n");
    }

  dump_end (class_dump_id, stream);
}

static void
dump_vtt (tree t, tree vtt)
{
  dump_flags_t flags;
  FILE *stream = dump_begin (class_dump_id, &flags);

  if (!stream)
    return;

  if (!(flags & TDF_SLIM))
    {
      fprintf (stream, "VTT for %s\n",
	       type_as_string (t, TFF_PLAIN_IDENTIFIER));
      dump_array (stream, vtt);
      fprintf (stream, "\n");
    }

  dump_end (class_dump_id, stream);
}

/* Dump a function or thunk and its thunkees.  */

static void
dump_thunk (FILE *stream, int indent, tree thunk)
{
  static const char spaces[] = "        ";
  tree name = DECL_NAME (thunk);
  tree thunks;

  fprintf (stream, "%.*s%p %s %s", indent, spaces,
	   (void *)thunk,
	   !DECL_THUNK_P (thunk) ? "function"
	   : DECL_THIS_THUNK_P (thunk) ? "this-thunk" : "covariant-thunk",
	   name ? IDENTIFIER_POINTER (name) : "<unset>");
  if (DECL_THUNK_P (thunk))
    {
      HOST_WIDE_INT fixed_adjust = THUNK_FIXED_OFFSET (thunk);
      tree virtual_adjust = THUNK_VIRTUAL_OFFSET (thunk);

      fprintf (stream, " fixed=" HOST_WIDE_INT_PRINT_DEC, fixed_adjust);
      if (!virtual_adjust)
	/*NOP*/;
      else if (DECL_THIS_THUNK_P (thunk))
	fprintf (stream, " vcall="  HOST_WIDE_INT_PRINT_DEC,
		 tree_to_shwi (virtual_adjust));
      else
	fprintf (stream, " vbase=" HOST_WIDE_INT_PRINT_DEC "(%s)",
		 tree_to_shwi (BINFO_VPTR_FIELD (virtual_adjust)),
		 type_as_string (BINFO_TYPE (virtual_adjust), TFF_SCOPE));
      if (THUNK_ALIAS (thunk))
	fprintf (stream, " alias to %p", (void *)THUNK_ALIAS (thunk));
    }
  fprintf (stream, "\n");
  for (thunks = DECL_THUNKS (thunk); thunks; thunks = TREE_CHAIN (thunks))
    dump_thunk (stream, indent + 2, thunks);
}

/* Dump the thunks for FN.  */

void
debug_thunks (tree fn)
{
  dump_thunk (stderr, 0, fn);
}

/* Virtual function table initialization.  */

/* Create all the necessary vtables for T and its base classes.  */

static void
finish_vtbls (tree t)
{
  tree vbase;
  vec<constructor_elt, va_gc> *v = NULL;
  tree vtable = BINFO_VTABLE (TYPE_BINFO (t));

  /* We lay out the primary and secondary vtables in one contiguous
     vtable.  The primary vtable is first, followed by the non-virtual
     secondary vtables in inheritance graph order.  */
  accumulate_vtbl_inits (TYPE_BINFO (t), TYPE_BINFO (t), TYPE_BINFO (t),
			 vtable, t, &v);

  /* Then come the virtual bases, also in inheritance graph order.  */
  for (vbase = TYPE_BINFO (t); vbase; vbase = TREE_CHAIN (vbase))
    {
      if (!BINFO_VIRTUAL_P (vbase))
	continue;
      accumulate_vtbl_inits (vbase, vbase, TYPE_BINFO (t), vtable, t, &v);
    }

  if (BINFO_VTABLE (TYPE_BINFO (t)))
    initialize_vtable (TYPE_BINFO (t), v);
}

/* Initialize the vtable for BINFO with the INITS.  */

static void
initialize_vtable (tree binfo, vec<constructor_elt, va_gc> *inits)
{
  tree decl;

  layout_vtable_decl (binfo, vec_safe_length (inits));
  decl = get_vtbl_decl_for_binfo (binfo);
  initialize_artificial_var (decl, inits);
  dump_vtable (BINFO_TYPE (binfo), binfo, decl);
}

/* Build the VTT (virtual table table) for T.
   A class requires a VTT if it has virtual bases.

   This holds
   1 - primary virtual pointer for complete object T
   2 - secondary VTTs for each direct non-virtual base of T which requires a
       VTT
   3 - secondary virtual pointers for each direct or indirect base of T which
       has virtual bases or is reachable via a virtual path from T.
   4 - secondary VTTs for each direct or indirect virtual base of T.

   Secondary VTTs look like complete object VTTs without part 4.  */

static void
build_vtt (tree t)
{
  tree type;
  tree vtt;
  tree index;
  vec<constructor_elt, va_gc> *inits;

  /* Build up the initializers for the VTT.  */
  inits = NULL;
  index = size_zero_node;
  build_vtt_inits (TYPE_BINFO (t), t, &inits, &index);

  /* If we didn't need a VTT, we're done.  */
  if (!inits)
    return;

  /* Figure out the type of the VTT.  */
  type = build_array_of_n_type (const_ptr_type_node,
                                inits->length ());

  /* Now, build the VTT object itself.  */
  vtt = build_vtable (t, mangle_vtt_for_type (t), type);
  initialize_artificial_var (vtt, inits);
  /* Add the VTT to the vtables list.  */
  DECL_CHAIN (vtt) = DECL_CHAIN (CLASSTYPE_VTABLES (t));
  DECL_CHAIN (CLASSTYPE_VTABLES (t)) = vtt;

  dump_vtt (t, vtt);
}

/* When building a secondary VTT, BINFO_VTABLE is set to a TREE_LIST with
   PURPOSE the RTTI_BINFO, VALUE the real vtable pointer for this binfo,
   and CHAIN the vtable pointer for this binfo after construction is
   complete.  VALUE can also be another BINFO, in which case we recurse.  */

static tree
binfo_ctor_vtable (tree binfo)
{
  tree vt;

  while (1)
    {
      vt = BINFO_VTABLE (binfo);
      if (TREE_CODE (vt) == TREE_LIST)
	vt = TREE_VALUE (vt);
      if (TREE_CODE (vt) == TREE_BINFO)
	binfo = vt;
      else
	break;
    }

  return vt;
}

/* Data for secondary VTT initialization.  */
struct secondary_vptr_vtt_init_data
{
  /* Is this the primary VTT? */
  bool top_level_p;

  /* Current index into the VTT.  */
  tree index;

  /* Vector of initializers built up.  */
  vec<constructor_elt, va_gc> *inits;

  /* The type being constructed by this secondary VTT.  */
  tree type_being_constructed;
};

/* Recursively build the VTT-initializer for BINFO (which is in the
   hierarchy dominated by T).  INITS points to the end of the initializer
   list to date.  INDEX is the VTT index where the next element will be
   replaced.  Iff BINFO is the binfo for T, this is the top level VTT (i.e.
   not a subvtt for some base of T).  When that is so, we emit the sub-VTTs
   for virtual bases of T. When it is not so, we build the constructor
   vtables for the BINFO-in-T variant.  */

static void
build_vtt_inits (tree binfo, tree t, vec<constructor_elt, va_gc> **inits,
		 tree *index)
{
  int i;
  tree b;
  tree init;
  secondary_vptr_vtt_init_data data;
  int top_level_p = SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), t);

  /* We only need VTTs for subobjects with virtual bases.  */
  if (!CLASSTYPE_VBASECLASSES (BINFO_TYPE (binfo)))
    return;

  /* We need to use a construction vtable if this is not the primary
     VTT.  */
  if (!top_level_p)
    {
      build_ctor_vtbl_group (binfo, t);

      /* Record the offset in the VTT where this sub-VTT can be found.  */
      BINFO_SUBVTT_INDEX (binfo) = *index;
    }

  /* Add the address of the primary vtable for the complete object.  */
  init = binfo_ctor_vtable (binfo);
  CONSTRUCTOR_APPEND_ELT (*inits, NULL_TREE, init);
  if (top_level_p)
    {
      gcc_assert (!BINFO_VPTR_INDEX (binfo));
      BINFO_VPTR_INDEX (binfo) = *index;
    }
  *index = size_binop (PLUS_EXPR, *index, TYPE_SIZE_UNIT (ptr_type_node));

  /* Recursively add the secondary VTTs for non-virtual bases.  */
  for (i = 0; BINFO_BASE_ITERATE (binfo, i, b); ++i)
    if (!BINFO_VIRTUAL_P (b))
      build_vtt_inits (b, t, inits, index);

  /* Add secondary virtual pointers for all subobjects of BINFO with
     either virtual bases or reachable along a virtual path, except
     subobjects that are non-virtual primary bases.  */
  data.top_level_p = top_level_p;
  data.index = *index;
  data.inits = *inits;
  data.type_being_constructed = BINFO_TYPE (binfo);

  dfs_walk_once (binfo, dfs_build_secondary_vptr_vtt_inits, NULL, &data);

  *index = data.index;

  /* data.inits might have grown as we added secondary virtual pointers.
     Make sure our caller knows about the new vector.  */
  *inits = data.inits;

  if (top_level_p)
    /* Add the secondary VTTs for virtual bases in inheritance graph
       order.  */
    for (b = TYPE_BINFO (BINFO_TYPE (binfo)); b; b = TREE_CHAIN (b))
      {
	if (!BINFO_VIRTUAL_P (b))
	  continue;

	build_vtt_inits (b, t, inits, index);
      }
  else
    /* Remove the ctor vtables we created.  */
    dfs_walk_all (binfo, dfs_fixup_binfo_vtbls, NULL, binfo);
}

/* Called from build_vtt_inits via dfs_walk.  BINFO is the binfo for the base
   in most derived. DATA is a SECONDARY_VPTR_VTT_INIT_DATA structure.  */

static tree
dfs_build_secondary_vptr_vtt_inits (tree binfo, void *data_)
{
  secondary_vptr_vtt_init_data *data = (secondary_vptr_vtt_init_data *)data_;

  /* We don't care about bases that don't have vtables.  */
  if (!TYPE_VFIELD (BINFO_TYPE (binfo)))
    return dfs_skip_bases;

  /* We're only interested in proper subobjects of the type being
     constructed.  */
  if (SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), data->type_being_constructed))
    return NULL_TREE;

  /* We're only interested in bases with virtual bases or reachable
     via a virtual path from the type being constructed.  */
  if (!(CLASSTYPE_VBASECLASSES (BINFO_TYPE (binfo))
	|| binfo_via_virtual (binfo, data->type_being_constructed)))
    return dfs_skip_bases;

  /* We're not interested in non-virtual primary bases.  */
  if (!BINFO_VIRTUAL_P (binfo) && BINFO_PRIMARY_P (binfo))
    return NULL_TREE;

  /* Record the index where this secondary vptr can be found.  */
  if (data->top_level_p)
    {
      gcc_assert (!BINFO_VPTR_INDEX (binfo));
      BINFO_VPTR_INDEX (binfo) = data->index;

      if (BINFO_VIRTUAL_P (binfo))
	{
	  /* It's a primary virtual base, and this is not a
	     construction vtable.  Find the base this is primary of in
	     the inheritance graph, and use that base's vtable
	     now.  */
	  while (BINFO_PRIMARY_P (binfo))
	    binfo = BINFO_INHERITANCE_CHAIN (binfo);
	}
    }

  /* Add the initializer for the secondary vptr itself.  */
  CONSTRUCTOR_APPEND_ELT (data->inits, NULL_TREE, binfo_ctor_vtable (binfo));

  /* Advance the vtt index.  */
  data->index = size_binop (PLUS_EXPR, data->index,
			    TYPE_SIZE_UNIT (ptr_type_node));

  return NULL_TREE;
}

/* Called from build_vtt_inits via dfs_walk. After building
   constructor vtables and generating the sub-vtt from them, we need
   to restore the BINFO_VTABLES that were scribbled on.  DATA is the
   binfo of the base whose sub vtt was generated.  */

static tree
dfs_fixup_binfo_vtbls (tree binfo, void* data)
{
  tree vtable = BINFO_VTABLE (binfo);

  if (!TYPE_CONTAINS_VPTR_P (BINFO_TYPE (binfo)))
    /* If this class has no vtable, none of its bases do.  */
    return dfs_skip_bases;

  if (!vtable)
    /* This might be a primary base, so have no vtable in this
       hierarchy.  */
    return NULL_TREE;

  /* If we scribbled the construction vtable vptr into BINFO, clear it
     out now.  */
  if (TREE_CODE (vtable) == TREE_LIST
      && (TREE_PURPOSE (vtable) == (tree) data))
    BINFO_VTABLE (binfo) = TREE_CHAIN (vtable);

  return NULL_TREE;
}

/* Build the construction vtable group for BINFO which is in the
   hierarchy dominated by T.  */

static void
build_ctor_vtbl_group (tree binfo, tree t)
{
  tree type;
  tree vtbl;
  tree id;
  tree vbase;
  vec<constructor_elt, va_gc> *v;

  /* See if we've already created this construction vtable group.  */
  id = mangle_ctor_vtbl_for_type (t, binfo);
  if (get_global_binding (id))
    return;

  gcc_assert (!SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), t));
  /* Build a version of VTBL (with the wrong type) for use in
     constructing the addresses of secondary vtables in the
     construction vtable group.  */
  vtbl = build_vtable (t, id, ptr_type_node);

  /* Don't export construction vtables from shared libraries.  Even on
     targets that don't support hidden visibility, this tells
     can_refer_decl_in_current_unit_p not to assume that it's safe to
     access from a different compilation unit (bz 54314).  */
  DECL_VISIBILITY (vtbl) = VISIBILITY_HIDDEN;
  DECL_VISIBILITY_SPECIFIED (vtbl) = true;

  v = NULL;
  accumulate_vtbl_inits (binfo, TYPE_BINFO (TREE_TYPE (binfo)),
			 binfo, vtbl, t, &v);

  /* Add the vtables for each of our virtual bases using the vbase in T
     binfo.  */
  for (vbase = TYPE_BINFO (BINFO_TYPE (binfo));
       vbase;
       vbase = TREE_CHAIN (vbase))
    {
      tree b;

      if (!BINFO_VIRTUAL_P (vbase))
	continue;
      b = copied_binfo (vbase, binfo);

      accumulate_vtbl_inits (b, vbase, binfo, vtbl, t, &v);
    }

  /* Figure out the type of the construction vtable.  */
  type = build_array_of_n_type (vtable_entry_type, v->length ());
  layout_type (type);
  TREE_TYPE (vtbl) = type;
  DECL_SIZE (vtbl) = DECL_SIZE_UNIT (vtbl) = NULL_TREE;
  layout_decl (vtbl, 0);

  /* Initialize the construction vtable.  */
  CLASSTYPE_VTABLES (t) = chainon (CLASSTYPE_VTABLES (t), vtbl);
  initialize_artificial_var (vtbl, v);
  dump_vtable (t, binfo, vtbl);
}

/* Add the vtbl initializers for BINFO (and its bases other than
   non-virtual primaries) to the list of INITS.  BINFO is in the
   hierarchy dominated by T.  RTTI_BINFO is the binfo within T of
   the constructor the vtbl inits should be accumulated for. (If this
   is the complete object vtbl then RTTI_BINFO will be TYPE_BINFO (T).)
   ORIG_BINFO is the binfo for this object within BINFO_TYPE (RTTI_BINFO).
   BINFO is the active base equivalent of ORIG_BINFO in the inheritance
   graph of T. Both BINFO and ORIG_BINFO will have the same BINFO_TYPE,
   but are not necessarily the same in terms of layout.  */

static void
accumulate_vtbl_inits (tree binfo,
		       tree orig_binfo,
		       tree rtti_binfo,
		       tree vtbl,
		       tree t,
		       vec<constructor_elt, va_gc> **inits)
{
  int i;
  tree base_binfo;
  int ctor_vtbl_p = !SAME_BINFO_TYPE_P (BINFO_TYPE (rtti_binfo), t);

  gcc_assert (SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), BINFO_TYPE (orig_binfo)));

  /* If it doesn't have a vptr, we don't do anything.  */
  if (!TYPE_CONTAINS_VPTR_P (BINFO_TYPE (binfo)))
    return;

  /* If we're building a construction vtable, we're not interested in
     subobjects that don't require construction vtables.  */
  if (ctor_vtbl_p
      && !CLASSTYPE_VBASECLASSES (BINFO_TYPE (binfo))
      && !binfo_via_virtual (orig_binfo, BINFO_TYPE (rtti_binfo)))
    return;

  /* Build the initializers for the BINFO-in-T vtable.  */
  dfs_accumulate_vtbl_inits (binfo, orig_binfo, rtti_binfo, vtbl, t, inits);

  /* Walk the BINFO and its bases.  We walk in preorder so that as we
     initialize each vtable we can figure out at what offset the
     secondary vtable lies from the primary vtable.  We can't use
     dfs_walk here because we need to iterate through bases of BINFO
     and RTTI_BINFO simultaneously.  */
  for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
    {
      /* Skip virtual bases.  */
      if (BINFO_VIRTUAL_P (base_binfo))
	continue;
      accumulate_vtbl_inits (base_binfo,
			     BINFO_BASE_BINFO (orig_binfo, i),
			     rtti_binfo, vtbl, t,
			     inits);
    }
}

/* Called from accumulate_vtbl_inits.  Adds the initializers for the
   BINFO vtable to L.  */

static void
dfs_accumulate_vtbl_inits (tree binfo,
			   tree orig_binfo,
			   tree rtti_binfo,
			   tree orig_vtbl,
			   tree t,
			   vec<constructor_elt, va_gc> **l)
{
  tree vtbl = NULL_TREE;
  int ctor_vtbl_p = !SAME_BINFO_TYPE_P (BINFO_TYPE (rtti_binfo), t);
  int n_inits;

  if (ctor_vtbl_p
      && BINFO_VIRTUAL_P (orig_binfo) && BINFO_PRIMARY_P (orig_binfo))
    {
      /* In the hierarchy of BINFO_TYPE (RTTI_BINFO), this is a
	 primary virtual base.  If it is not the same primary in
	 the hierarchy of T, we'll need to generate a ctor vtable
	 for it, to place at its location in T.  If it is the same
	 primary, we still need a VTT entry for the vtable, but it
	 should point to the ctor vtable for the base it is a
	 primary for within the sub-hierarchy of RTTI_BINFO.

	 There are three possible cases:

	 1) We are in the same place.
	 2) We are a primary base within a lost primary virtual base of
	 RTTI_BINFO.
	 3) We are primary to something not a base of RTTI_BINFO.  */

      tree b;
      tree last = NULL_TREE;

      /* First, look through the bases we are primary to for RTTI_BINFO
	 or a virtual base.  */
      b = binfo;
      while (BINFO_PRIMARY_P (b))
	{
	  b = BINFO_INHERITANCE_CHAIN (b);
	  last = b;
	  if (BINFO_VIRTUAL_P (b) || b == rtti_binfo)
	    goto found;
	}
      /* If we run out of primary links, keep looking down our
	 inheritance chain; we might be an indirect primary.  */
      for (b = last; b; b = BINFO_INHERITANCE_CHAIN (b))
	if (BINFO_VIRTUAL_P (b) || b == rtti_binfo)
	  break;
    found:

      /* If we found RTTI_BINFO, this is case 1.  If we found a virtual
	 base B and it is a base of RTTI_BINFO, this is case 2.  In
	 either case, we share our vtable with LAST, i.e. the
	 derived-most base within B of which we are a primary.  */
      if (b == rtti_binfo
	  || (b && binfo_for_vbase (BINFO_TYPE (b), BINFO_TYPE (rtti_binfo))))
	/* Just set our BINFO_VTABLE to point to LAST, as we may not have
	   set LAST's BINFO_VTABLE yet.  We'll extract the actual vptr in
	   binfo_ctor_vtable after everything's been set up.  */
	vtbl = last;

      /* Otherwise, this is case 3 and we get our own.  */
    }
  else if (!BINFO_NEW_VTABLE_MARKED (orig_binfo))
    return;

  n_inits = vec_safe_length (*l);

  if (!vtbl)
    {
      tree index;
      int non_fn_entries;

      /* Add the initializer for this vtable.  */
      build_vtbl_initializer (binfo, orig_binfo, t, rtti_binfo,
                              &non_fn_entries, l);

      /* Figure out the position to which the VPTR should point.  */
      vtbl = build1 (ADDR_EXPR, vtbl_ptr_type_node, orig_vtbl);
      index = size_binop (MULT_EXPR,
			  TYPE_SIZE_UNIT (vtable_entry_type),
			  size_int (non_fn_entries + n_inits));
      vtbl = fold_build_pointer_plus (vtbl, index);
    }

  if (ctor_vtbl_p)
    /* For a construction vtable, we can't overwrite BINFO_VTABLE.
       So, we make a TREE_LIST.  Later, dfs_fixup_binfo_vtbls will
       straighten this out.  */
    BINFO_VTABLE (binfo) = tree_cons (rtti_binfo, vtbl, BINFO_VTABLE (binfo));
  else if (BINFO_PRIMARY_P (binfo) && BINFO_VIRTUAL_P (binfo))
    /* Throw away any unneeded intializers.  */
    (*l)->truncate (n_inits);
  else
     /* For an ordinary vtable, set BINFO_VTABLE.  */
    BINFO_VTABLE (binfo) = vtbl;
}

static GTY(()) tree abort_fndecl_addr;
static GTY(()) tree dvirt_fn;

/* Construct the initializer for BINFO's virtual function table.  BINFO
   is part of the hierarchy dominated by T.  If we're building a
   construction vtable, the ORIG_BINFO is the binfo we should use to
   find the actual function pointers to put in the vtable - but they
   can be overridden on the path to most-derived in the graph that
   ORIG_BINFO belongs.  Otherwise,
   ORIG_BINFO should be the same as BINFO.  The RTTI_BINFO is the
   BINFO that should be indicated by the RTTI information in the
   vtable; it will be a base class of T, rather than T itself, if we
   are building a construction vtable.

   The value returned is a TREE_LIST suitable for wrapping in a
   CONSTRUCTOR to use as the DECL_INITIAL for a vtable.  If
   NON_FN_ENTRIES_P is not NULL, *NON_FN_ENTRIES_P is set to the
   number of non-function entries in the vtable.

   It might seem that this function should never be called with a
   BINFO for which BINFO_PRIMARY_P holds, the vtable for such a
   base is always subsumed by a derived class vtable.  However, when
   we are building construction vtables, we do build vtables for
   primary bases; we need these while the primary base is being
   constructed.  */

static void
build_vtbl_initializer (tree binfo,
			tree orig_binfo,
			tree t,
			tree rtti_binfo,
			int* non_fn_entries_p,
			vec<constructor_elt, va_gc> **inits)
{
  tree v;
  vtbl_init_data vid;
  unsigned ix, jx;
  tree vbinfo;
  vec<tree, va_gc> *vbases;
  constructor_elt *e;

  /* Initialize VID.  */
  memset (&vid, 0, sizeof (vid));
  vid.binfo = binfo;
  vid.derived = t;
  vid.rtti_binfo = rtti_binfo;
  vid.primary_vtbl_p = SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), t);
  vid.ctor_vtbl_p = !SAME_BINFO_TYPE_P (BINFO_TYPE (rtti_binfo), t);
  vid.generate_vcall_entries = true;
  /* The first vbase or vcall offset is at index -3 in the vtable.  */
  vid.index = ssize_int(-3 * TARGET_VTABLE_DATA_ENTRY_DISTANCE);

  /* Add entries to the vtable for RTTI.  */
  build_rtti_vtbl_entries (binfo, &vid);

  /* Create an array for keeping track of the functions we've
     processed.  When we see multiple functions with the same
     signature, we share the vcall offsets.  */
  vec_alloc (vid.fns, 32);
  /* Add the vcall and vbase offset entries.  */
  build_vcall_and_vbase_vtbl_entries (binfo, &vid);

  /* Clear BINFO_VTABLE_PATH_MARKED; it's set by
     build_vbase_offset_vtbl_entries.  */
  for (vbases = CLASSTYPE_VBASECLASSES (t), ix = 0;
       vec_safe_iterate (vbases, ix, &vbinfo); ix++)
    BINFO_VTABLE_PATH_MARKED (vbinfo) = 0;

  /* If the target requires padding between data entries, add that now.  */
  if (TARGET_VTABLE_DATA_ENTRY_DISTANCE > 1)
    {
      int n_entries = vec_safe_length (vid.inits);

      vec_safe_grow (vid.inits, TARGET_VTABLE_DATA_ENTRY_DISTANCE * n_entries,
		     true);

      /* Move data entries into their new positions and add padding
	 after the new positions.  Iterate backwards so we don't
	 overwrite entries that we would need to process later.  */
      for (ix = n_entries - 1;
	   vid.inits->iterate (ix, &e);
	   ix--)
	{
	  int j;
	  int new_position = (TARGET_VTABLE_DATA_ENTRY_DISTANCE * ix
			      + (TARGET_VTABLE_DATA_ENTRY_DISTANCE - 1));

	  (*vid.inits)[new_position] = *e;

	  for (j = 1; j < TARGET_VTABLE_DATA_ENTRY_DISTANCE; ++j)
	    {
	      constructor_elt *f = &(*vid.inits)[new_position - j];
	      f->index = NULL_TREE;
	      f->value = build1 (NOP_EXPR, vtable_entry_type,
				 null_pointer_node);
	    }
	}
    }

  if (non_fn_entries_p)
    *non_fn_entries_p = vec_safe_length (vid.inits);

  /* The initializers for virtual functions were built up in reverse
     order.  Straighten them out and add them to the running list in one
     step.  */
  jx = vec_safe_length (*inits);
  vec_safe_grow (*inits, jx + vid.inits->length (), true);

  for (ix = vid.inits->length () - 1;
       vid.inits->iterate (ix, &e);
       ix--, jx++)
    (**inits)[jx] = *e;

  /* Go through all the ordinary virtual functions, building up
     initializers.  */
  for (v = BINFO_VIRTUALS (orig_binfo); v; v = TREE_CHAIN (v))
    {
      tree delta;
      tree vcall_index;
      tree fn, fn_original;
      tree init = NULL_TREE;

      fn = BV_FN (v);
      fn_original = fn;
      if (DECL_THUNK_P (fn))
	{
	  if (!DECL_NAME (fn))
	    finish_thunk (fn);
	  if (THUNK_ALIAS (fn))
	    {
	      fn = THUNK_ALIAS (fn);
	      BV_FN (v) = fn;
	    }
	  fn_original = THUNK_TARGET (fn);
	}

      /* If the only definition of this function signature along our
	 primary base chain is from a lost primary, this vtable slot will
	 never be used, so just zero it out.  This is important to avoid
	 requiring extra thunks which cannot be generated with the function.

	 We first check this in update_vtable_entry_for_fn, so we handle
	 restored primary bases properly; we also need to do it here so we
	 zero out unused slots in ctor vtables, rather than filling them
	 with erroneous values (though harmless, apart from relocation
	 costs).  */
      if (BV_LOST_PRIMARY (v))
	init = size_zero_node;

      if (! init)
	{
	  /* Pull the offset for `this', and the function to call, out of
	     the list.  */
	  delta = BV_DELTA (v);
	  vcall_index = BV_VCALL_INDEX (v);

	  gcc_assert (TREE_CODE (delta) == INTEGER_CST);
	  gcc_assert (TREE_CODE (fn) == FUNCTION_DECL);

	  /* You can't call an abstract virtual function; it's abstract.
	     So, we replace these functions with __pure_virtual.  */
	  if (DECL_PURE_VIRTUAL_P (fn_original))
	    {
	      fn = abort_fndecl;
	      if (!TARGET_VTABLE_USES_DESCRIPTORS)
		{
		  if (abort_fndecl_addr == NULL)
		    abort_fndecl_addr
		      = fold_convert (vfunc_ptr_type_node,
				      build_fold_addr_expr (fn));
		  init = abort_fndecl_addr;
		}
	    }
	  /* Likewise for deleted virtuals.  */
	  else if (DECL_DELETED_FN (fn_original))
	    {
	      if (!dvirt_fn)
		{
		  tree name = get_identifier ("__cxa_deleted_virtual");
		  dvirt_fn = get_global_binding (name);
		  if (!dvirt_fn)
		    dvirt_fn = push_library_fn
		      (name,
		       build_function_type_list (void_type_node, NULL_TREE),
		       NULL_TREE, ECF_NORETURN | ECF_COLD);
		}
	      fn = dvirt_fn;
	      if (!TARGET_VTABLE_USES_DESCRIPTORS)
		init = fold_convert (vfunc_ptr_type_node,
				     build_fold_addr_expr (fn));
	    }
	  else
	    {
	      if (!integer_zerop (delta) || vcall_index)
		{
		  fn = make_thunk (fn, /*this_adjusting=*/1,
				   delta, vcall_index);
		  if (!DECL_NAME (fn))
		    finish_thunk (fn);
		}
	      /* Take the address of the function, considering it to be of an
		 appropriate generic type.  */
	      if (!TARGET_VTABLE_USES_DESCRIPTORS)
		init = fold_convert (vfunc_ptr_type_node,
				     build_fold_addr_expr (fn));
	      /* Don't refer to a virtual destructor from a constructor
		 vtable or a vtable for an abstract class, since destroying
		 an object under construction is undefined behavior and we
		 don't want it to be considered a candidate for speculative
		 devirtualization.  But do create the thunk for ABI
		 compliance.  */
	      if (DECL_DESTRUCTOR_P (fn_original)
		  && (CLASSTYPE_PURE_VIRTUALS (DECL_CONTEXT (fn_original))
		      || orig_binfo != binfo))
		init = size_zero_node;
	    }
	}

      /* And add it to the chain of initializers.  */
      if (TARGET_VTABLE_USES_DESCRIPTORS)
	{
	  int i;
	  if (init == size_zero_node)
	    for (i = 0; i < TARGET_VTABLE_USES_DESCRIPTORS; ++i)
	      CONSTRUCTOR_APPEND_ELT (*inits, size_int (jx++), init);
	  else
	    for (i = 0; i < TARGET_VTABLE_USES_DESCRIPTORS; ++i)
	      {
		tree fdesc = build2 (FDESC_EXPR, vfunc_ptr_type_node,
				     fn, build_int_cst (NULL_TREE, i));
		TREE_CONSTANT (fdesc) = 1;

		CONSTRUCTOR_APPEND_ELT (*inits, size_int (jx++), fdesc);
	      }
	}
      else
	CONSTRUCTOR_APPEND_ELT (*inits, size_int (jx++), init);
    }
}

/* Adds to vid->inits the initializers for the vbase and vcall
   offsets in BINFO, which is in the hierarchy dominated by T.  */

static void
build_vcall_and_vbase_vtbl_entries (tree binfo, vtbl_init_data* vid)
{
  tree b;

  /* If this is a derived class, we must first create entries
     corresponding to the primary base class.  */
  b = get_primary_binfo (binfo);
  if (b)
    build_vcall_and_vbase_vtbl_entries (b, vid);

  /* Add the vbase entries for this base.  */
  build_vbase_offset_vtbl_entries (binfo, vid);
  /* Add the vcall entries for this base.  */
  build_vcall_offset_vtbl_entries (binfo, vid);
}

/* Returns the initializers for the vbase offset entries in the vtable
   for BINFO (which is part of the class hierarchy dominated by T), in
   reverse order.  VBASE_OFFSET_INDEX gives the vtable index
   where the next vbase offset will go.  */

static void
build_vbase_offset_vtbl_entries (tree binfo, vtbl_init_data* vid)
{
  tree vbase;
  tree t;
  tree non_primary_binfo;

  /* If there are no virtual baseclasses, then there is nothing to
     do.  */
  if (!CLASSTYPE_VBASECLASSES (BINFO_TYPE (binfo)))
    return;

  t = vid->derived;

  /* We might be a primary base class.  Go up the inheritance hierarchy
     until we find the most derived class of which we are a primary base:
     it is the offset of that which we need to use.  */
  non_primary_binfo = binfo;
  while (BINFO_INHERITANCE_CHAIN (non_primary_binfo))
    {
      tree b;

      /* If we have reached a virtual base, then it must be a primary
	 base (possibly multi-level) of vid->binfo, or we wouldn't
	 have called build_vcall_and_vbase_vtbl_entries for it.  But it
	 might be a lost primary, so just skip down to vid->binfo.  */
      if (BINFO_VIRTUAL_P (non_primary_binfo))
	{
	  non_primary_binfo = vid->binfo;
	  break;
	}

      b = BINFO_INHERITANCE_CHAIN (non_primary_binfo);
      if (get_primary_binfo (b) != non_primary_binfo)
	break;
      non_primary_binfo = b;
    }

  /* Go through the virtual bases, adding the offsets.  */
  for (vbase = TYPE_BINFO (BINFO_TYPE (binfo));
       vbase;
       vbase = TREE_CHAIN (vbase))
    {
      tree b;
      tree delta;

      if (!BINFO_VIRTUAL_P (vbase))
	continue;

      /* Find the instance of this virtual base in the complete
	 object.  */
      b = copied_binfo (vbase, binfo);

      /* If we've already got an offset for this virtual base, we
	 don't need another one.  */
      if (BINFO_VTABLE_PATH_MARKED (b))
	continue;
      BINFO_VTABLE_PATH_MARKED (b) = 1;

      /* Figure out where we can find this vbase offset.  */
      delta = size_binop (MULT_EXPR,
			  vid->index,
			  fold_convert (ssizetype,
				   TYPE_SIZE_UNIT (vtable_entry_type)));
      if (vid->primary_vtbl_p)
	BINFO_VPTR_FIELD (b) = delta;

      if (binfo != TYPE_BINFO (t))
	/* The vbase offset had better be the same.  */
	gcc_assert (tree_int_cst_equal (delta, BINFO_VPTR_FIELD (vbase)));

      /* The next vbase will come at a more negative offset.  */
      vid->index = size_binop (MINUS_EXPR, vid->index,
			       ssize_int (TARGET_VTABLE_DATA_ENTRY_DISTANCE));

      /* The initializer is the delta from BINFO to this virtual base.
	 The vbase offsets go in reverse inheritance-graph order, and
	 we are walking in inheritance graph order so these end up in
	 the right order.  */
      delta = size_diffop_loc (input_location,
			   BINFO_OFFSET (b), BINFO_OFFSET (non_primary_binfo));

      CONSTRUCTOR_APPEND_ELT (vid->inits, NULL_TREE,
			      fold_build1_loc (input_location, NOP_EXPR,
					       vtable_entry_type, delta));
    }
}

/* Adds the initializers for the vcall offset entries in the vtable
   for BINFO (which is part of the class hierarchy dominated by VID->DERIVED)
   to VID->INITS.  */

static void
build_vcall_offset_vtbl_entries (tree binfo, vtbl_init_data* vid)
{
  /* We only need these entries if this base is a virtual base.  We
     compute the indices -- but do not add to the vtable -- when
     building the main vtable for a class.  */
  if (binfo == TYPE_BINFO (vid->derived)
      || (BINFO_VIRTUAL_P (binfo) 
	  /* If BINFO is RTTI_BINFO, then (since BINFO does not
	     correspond to VID->DERIVED), we are building a primary
	     construction virtual table.  Since this is a primary
	     virtual table, we do not need the vcall offsets for
	     BINFO.  */
	  && binfo != vid->rtti_binfo))
    {
      /* We need a vcall offset for each of the virtual functions in this
	 vtable.  For example:

	   class A { virtual void f (); };
	   class B1 : virtual public A { virtual void f (); };
	   class B2 : virtual public A { virtual void f (); };
	   class C: public B1, public B2 { virtual void f (); };

	 A C object has a primary base of B1, which has a primary base of A.  A
	 C also has a secondary base of B2, which no longer has a primary base
	 of A.  So the B2-in-C construction vtable needs a secondary vtable for
	 A, which will adjust the A* to a B2* to call f.  We have no way of
	 knowing what (or even whether) this offset will be when we define B2,
	 so we store this "vcall offset" in the A sub-vtable and look it up in
	 a "virtual thunk" for B2::f.

	 We need entries for all the functions in our primary vtable and
	 in our non-virtual bases' secondary vtables.  */
      vid->vbase = binfo;
      /* If we are just computing the vcall indices -- but do not need
	 the actual entries -- not that.  */
      if (!BINFO_VIRTUAL_P (binfo))
	vid->generate_vcall_entries = false;
      /* Now, walk through the non-virtual bases, adding vcall offsets.  */
      add_vcall_offset_vtbl_entries_r (binfo, vid);
    }
}

/* Build vcall offsets, starting with those for BINFO.  */

static void
add_vcall_offset_vtbl_entries_r (tree binfo, vtbl_init_data* vid)
{
  int i;
  tree primary_binfo;
  tree base_binfo;

  /* Don't walk into virtual bases -- except, of course, for the
     virtual base for which we are building vcall offsets.  Any
     primary virtual base will have already had its offsets generated
     through the recursion in build_vcall_and_vbase_vtbl_entries.  */
  if (BINFO_VIRTUAL_P (binfo) && vid->vbase != binfo)
    return;

  /* If BINFO has a primary base, process it first.  */
  primary_binfo = get_primary_binfo (binfo);
  if (primary_binfo)
    add_vcall_offset_vtbl_entries_r (primary_binfo, vid);

  /* Add BINFO itself to the list.  */
  add_vcall_offset_vtbl_entries_1 (binfo, vid);

  /* Scan the non-primary bases of BINFO.  */
  for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
    if (base_binfo != primary_binfo)
      add_vcall_offset_vtbl_entries_r (base_binfo, vid);
}

/* Called from build_vcall_offset_vtbl_entries_r.  */

static void
add_vcall_offset_vtbl_entries_1 (tree binfo, vtbl_init_data* vid)
{
  /* Make entries for the rest of the virtuals.  */
  tree orig_fn;

  /* The ABI requires that the methods be processed in declaration
     order.  */
  for (orig_fn = TYPE_FIELDS (BINFO_TYPE (binfo));
       orig_fn;
       orig_fn = DECL_CHAIN (orig_fn))
    if (TREE_CODE (orig_fn) == FUNCTION_DECL && DECL_VINDEX (orig_fn))
      add_vcall_offset (orig_fn, binfo, vid);
}

/* Add a vcall offset entry for ORIG_FN to the vtable.  */

static void
add_vcall_offset (tree orig_fn, tree binfo, vtbl_init_data *vid)
{
  size_t i;
  tree vcall_offset;
  tree derived_entry;

  /* If there is already an entry for a function with the same
     signature as FN, then we do not need a second vcall offset.
     Check the list of functions already present in the derived
     class vtable.  */
  FOR_EACH_VEC_SAFE_ELT (vid->fns, i, derived_entry)
    {
      if (same_signature_p (derived_entry, orig_fn)
	  /* We only use one vcall offset for virtual destructors,
	     even though there are two virtual table entries.  */
	  || (DECL_DESTRUCTOR_P (derived_entry)
	      && DECL_DESTRUCTOR_P (orig_fn)))
	return;
    }

  /* If we are building these vcall offsets as part of building
     the vtable for the most derived class, remember the vcall
     offset.  */
  if (vid->binfo == TYPE_BINFO (vid->derived))
    {
      tree_pair_s elt = {orig_fn, vid->index};
      vec_safe_push (CLASSTYPE_VCALL_INDICES (vid->derived), elt);
    }

  /* The next vcall offset will be found at a more negative
     offset.  */
  vid->index = size_binop (MINUS_EXPR, vid->index,
			   ssize_int (TARGET_VTABLE_DATA_ENTRY_DISTANCE));

  /* Keep track of this function.  */
  vec_safe_push (vid->fns, orig_fn);

  if (vid->generate_vcall_entries)
    {
      tree base;
      tree fn;

      /* Find the overriding function.  */
      fn = find_final_overrider (vid->rtti_binfo, binfo, orig_fn);
      if (fn == error_mark_node)
	vcall_offset = build_zero_cst (vtable_entry_type);
      else
	{
	  base = TREE_VALUE (fn);

	  /* The vbase we're working on is a primary base of
	     vid->binfo.  But it might be a lost primary, so its
	     BINFO_OFFSET might be wrong, so we just use the
	     BINFO_OFFSET from vid->binfo.  */
	  vcall_offset = size_diffop_loc (input_location,
				      BINFO_OFFSET (base),
				      BINFO_OFFSET (vid->binfo));
	  vcall_offset = fold_build1_loc (input_location,
				      NOP_EXPR, vtable_entry_type,
				      vcall_offset);
	}
      /* Add the initializer to the vtable.  */
      CONSTRUCTOR_APPEND_ELT (vid->inits, NULL_TREE, vcall_offset);
    }
}

/* Return vtbl initializers for the RTTI entries corresponding to the
   BINFO's vtable.  The RTTI entries should indicate the object given
   by VID->rtti_binfo.  */

static void
build_rtti_vtbl_entries (tree binfo, vtbl_init_data* vid)
{
  tree b;
  tree t;
  tree offset;
  tree decl;
  tree init;

  t = BINFO_TYPE (vid->rtti_binfo);

  /* To find the complete object, we will first convert to our most
     primary base, and then add the offset in the vtbl to that value.  */
  b = most_primary_binfo (binfo);
  offset = size_diffop_loc (input_location,
			BINFO_OFFSET (vid->rtti_binfo), BINFO_OFFSET (b));

  /* The second entry is the address of the typeinfo object.  */
  if (flag_rtti)
    decl = build_address (get_tinfo_decl (t));
  else
    decl = integer_zero_node;

  /* Convert the declaration to a type that can be stored in the
     vtable.  */
  init = build_nop (vfunc_ptr_type_node, decl);
  CONSTRUCTOR_APPEND_ELT (vid->inits, NULL_TREE, init);

  /* Add the offset-to-top entry.  It comes earlier in the vtable than
     the typeinfo entry.  Convert the offset to look like a
     function pointer, so that we can put it in the vtable.  */
  init = build_nop (vfunc_ptr_type_node, offset);
  CONSTRUCTOR_APPEND_ELT (vid->inits, NULL_TREE, init);
}

/* TRUE iff TYPE is uniquely derived from PARENT.  Ignores
   accessibility.  */

bool
uniquely_derived_from_p (tree parent, tree type)
{
  tree base = lookup_base (type, parent, ba_unique, NULL, tf_none);
  return base && base != error_mark_node;
}

/* TRUE iff TYPE is publicly & uniquely derived from PARENT.  */

bool
publicly_uniquely_derived_p (tree parent, tree type)
{
  tree base = lookup_base (type, parent, ba_ignore_scope | ba_check,
			   NULL, tf_none);
  return base && base != error_mark_node;
}

/* CTX1 and CTX2 are declaration contexts.  Return the innermost common
   class between them, if any.  */

tree
common_enclosing_class (tree ctx1, tree ctx2)
{
  if (!TYPE_P (ctx1) || !TYPE_P (ctx2))
    return NULL_TREE;
  gcc_assert (ctx1 == TYPE_MAIN_VARIANT (ctx1)
	      && ctx2 == TYPE_MAIN_VARIANT (ctx2));
  if (ctx1 == ctx2)
    return ctx1;
  for (tree t = ctx1; TYPE_P (t); t = TYPE_CONTEXT (t))
    TYPE_MARKED_P (t) = true;
  tree found = NULL_TREE;
  for (tree t = ctx2; TYPE_P (t); t = TYPE_CONTEXT (t))
    if (TYPE_MARKED_P (t))
      {
	found = t;
	break;
      }
  for (tree t = ctx1; TYPE_P (t); t = TYPE_CONTEXT (t))
    TYPE_MARKED_P (t) = false;
  return found;
}

#include "gt-cp-class.h"
