/* 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 (ovl_iterator iter (flist); iter; ++iter)
      {
	add_method (t, *iter, true);
	alter_access (t, *iter, 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 (ovl_iterator iter (CLASSTYPE_CONSTRUCTORS (t));
	     !nonprivate_ctor && iter; ++iter)
	  if (TREE_PRIVATE (*iter))
	    continue;
	  else if (copy_fn_p (*iter) || move_fn_p (*iter))
	    /* 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 = *iter;
	  else
	    nonprivate_ctor = true;

      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.  */
  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);

  ffod.path.release ();

  /* 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 (ovl_iterator iter (get_class_binding (t, name)); iter; ++iter)
    {
      tree method = *iter;

      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 (ovl_iterator iter (fns); iter; ++iter)
	  {
	    tree fndecl = *iter;
	    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, bool complain)
{
  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;

      if (complain
	  && (TREE_CODE (elt) != FIELD_DECL
	      || (TREE_PRIVATE (elt) || TREE_PROTECTED (elt))))
	{
	  /* We already complained about static data members in
	     finish_static_data_member_decl.  */
	  if (!VAR_P (elt))
	    {
	      auto_diagnostic_group d;
	      if (permerror (DECL_SOURCE_LOCATION (elt),
			     TREE_CODE (TREE_TYPE (field)) == UNION_TYPE
			     ? "%q#D invalid; an anonymous union may "
			     "only have public non-static data members"
			     : "%q#D invalid; an anonymous struct may "
			     "only have public non-static data members", elt))
		{
		  static bool hint;
		  if (flag_permissive && !hint)
		    {
		      hint = true;
		      inform (DECL_SOURCE_LOCATION (elt),
			      "this flexibility is deprecated and will be "
			      "removed");
		    }
		}
	    }
	}

      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, /*complain=*/false);
    }
}

/* 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, /*complain=*/true);
    }
}

/* 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,
		     NULL_TREE, 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 (ovl_iterator iter (ctor_list); iter; ++iter)
	    one_inherited_ctor (*iter, 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 (ovl_iterator i (CLASSTYPE_CONSTRUCTORS (t)); i; ++i)
    {
      tree fn = *i;
      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 (ovl_iterator i (get_class_binding_direct (t, assign_op_identifier));
       i; ++i)
    {
      tree fn = *i;
      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 (ovl_iterator iter (CLASSTYPE_CONSTRUCTORS (t)); iter; ++iter)
    clone_cdtor (*iter, /*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 (ovl_iterator iter (CLASSTYPE_CONSTRUCTORS (t)); iter; ++iter)
    {
      tree fn = *iter;
      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;
}

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

bool
classtype_has_non_deleted_copy_ctor (tree t)
{
  if (CLASSTYPE_LAZY_COPY_CTOR (t))
    lazily_declare_fn (sfk_copy_constructor, t);
  for (ovl_iterator iter (CLASSTYPE_CONSTRUCTORS (t)); iter; ++iter)
    if (copy_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 (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.  */
	  && !TREE_NO_WARNING (field)
	  && !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"
