/* Functions related to building classes and their related objects.
   Copyright (C) 1987, 92, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
   Contributed by Michael Tiemann (tiemann@cygnus.com)

This file is part of GNU CC.

GNU CC 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 2, or (at your option)
any later version.

GNU CC 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 GNU CC; see the file COPYING.  If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.  */


/* High-level class interface.  */

#include "config.h"
#include "system.h"
#include "tree.h"
#include "cp-tree.h"
#include "flags.h"
#include "rtl.h"
#include "output.h"
#include "toplev.h"

#include "obstack.h"
#define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free

extern struct obstack permanent_obstack;

/* This is how we tell when two virtual member functions are really the
   same.  */
#define SAME_FN(FN1DECL, FN2DECL) (DECL_ASSEMBLER_NAME (FN1DECL) == DECL_ASSEMBLER_NAME (FN2DECL))

extern void set_class_shadows PROTO ((tree));

/* Way of stacking class types.  */
static tree *current_class_base, *current_class_stack;
static int current_class_stacksize;
int current_class_depth;

struct class_level
{
  /* The previous class level.  */
  struct class_level *level_chain;

  /* The class instance variable, as a PARM_DECL.  */
  tree decl;
  /* The class instance variable, as an object.  */
  tree object;
  /* The virtual function table pointer
     for the class instance variable.  */
  tree vtable_decl;

  /* Name of the current class.  */
  tree name;
  /* Type of the current class.  */
  tree type;

  /* Flags for this class level.  */
  int this_is_variable;
  int memoized_lookups;
  int save_memoized;
  int unused;
};

/* The current_class_ptr is the pointer to the current class.
   current_class_ref is the actual current class.  */
tree current_class_ptr, current_class_ref;

/* The following two can be derived from the previous one */
tree current_class_name;	/* IDENTIFIER_NODE: name of current class */
tree current_class_type;	/* _TYPE: the type of the current class */
tree previous_class_type;	/* _TYPE: the previous type that was a class */
tree previous_class_values;		/* TREE_LIST: copy of the class_shadowed list
				   when leaving an outermost class scope.  */

struct base_info;

static tree get_vfield_name PROTO((tree));
static void finish_struct_anon PROTO((tree));
static tree build_vbase_pointer PROTO((tree, tree));
static int complete_type_p PROTO((tree));
static tree build_vtable_entry PROTO((tree, tree));
static tree get_vtable_name PROTO((tree));
static tree get_derived_offset PROTO((tree, tree));
static tree get_basefndecls PROTO((tree, tree));
static void set_rtti_entry PROTO((tree, tree, tree));
static tree build_vtable PROTO((tree, tree));
static void prepare_fresh_vtable PROTO((tree, tree));
static void fixup_vtable_deltas1 PROTO((tree, tree));
static void fixup_vtable_deltas PROTO((tree, int, tree));
static void grow_method PROTO((tree, tree *));
static void finish_vtbls PROTO((tree, int, tree));
static void modify_vtable_entry PROTO((tree, tree, tree));
static tree get_vtable_entry_n PROTO((tree, unsigned HOST_WIDE_INT));
static void add_virtual_function PROTO((tree *, tree *, int *, tree, tree));
static tree delete_duplicate_fields_1 PROTO((tree, tree));
static void delete_duplicate_fields PROTO((tree));
static void finish_struct_bits PROTO((tree, int));
static int alter_access PROTO((tree, tree, tree, tree));
static void handle_using_decl PROTO((tree, tree, tree, tree));
static int overrides PROTO((tree, tree));
static int strictly_overrides PROTO((tree, tree));
static void merge_overrides PROTO((tree, tree, int, tree));
static void override_one_vtable PROTO((tree, tree, tree));
static void mark_overriders PROTO((tree, tree));
static void check_for_override PROTO((tree, tree));
static tree maybe_fixup_vptrs PROTO((tree, tree, tree));
static tree get_class_offset_1 PROTO((tree, tree, tree, tree, tree));
static tree get_class_offset PROTO((tree, tree, tree, tree));
static void modify_one_vtable PROTO((tree, tree, tree, tree));
static void modify_all_vtables PROTO((tree, tree, tree));
static void modify_all_direct_vtables PROTO((tree, int, tree, tree,
					     tree));
static void modify_all_indirect_vtables PROTO((tree, int, int, tree,
					       tree, tree));
static void build_class_init_list PROTO((tree));
static int finish_base_struct PROTO((tree, struct base_info *));

/* Way of stacking language names.  */
tree *current_lang_base, *current_lang_stack;
int current_lang_stacksize;

/* Names of languages we recognize.  */
tree lang_name_c, lang_name_cplusplus, lang_name_java;
tree current_lang_name;

/* When layout out an aggregate type, the size of the
   basetypes (virtual and non-virtual) is passed to layout_record
   via this node.  */
static tree base_layout_decl;

/* Constants used for access control.  */
tree access_default_node; /* 0 */
tree access_public_node; /* 1 */
tree access_protected_node; /* 2 */
tree access_private_node; /* 3 */
tree access_default_virtual_node; /* 4 */
tree access_public_virtual_node; /* 5 */
tree access_protected_virtual_node; /* 6 */
tree access_private_virtual_node; /* 7 */

/* Variables shared between class.c and call.c.  */

#ifdef GATHER_STATISTICS
int n_vtables = 0;
int n_vtable_entries = 0;
int n_vtable_searches = 0;
int n_vtable_elems = 0;
int n_convert_harshness = 0;
int n_compute_conversion_costs = 0;
int n_build_method_call = 0;
int n_inner_fields_searched = 0;
#endif

/* Virtual baseclass things.  */

static tree
build_vbase_pointer (exp, type)
     tree exp, type;
{
  char *name;

  name = (char *) alloca (TYPE_NAME_LENGTH (type) + sizeof (VBASE_NAME) + 1);
  sprintf (name, VBASE_NAME_FORMAT, TYPE_NAME_STRING (type));
  return build_component_ref (exp, get_identifier (name), NULL_TREE, 0);
}

/* Is the type of the EXPR, the complete type of the object?
   If we are going to be wrong, we must be conservative, and return 0.  */

static int
complete_type_p (expr)
     tree expr;
{
  tree type = TYPE_MAIN_VARIANT (TREE_TYPE (expr));
  while (1)
    {
      switch (TREE_CODE (expr))
	{
	case SAVE_EXPR:
	case INDIRECT_REF:
	case ADDR_EXPR:
	case NOP_EXPR:
	case CONVERT_EXPR:
	  expr = TREE_OPERAND (expr, 0);
	  continue;

	case CALL_EXPR: 
	  if (! TREE_HAS_CONSTRUCTOR (expr))
	    break;
	  /* fall through...  */
	case VAR_DECL:
	case FIELD_DECL:
	  if (TREE_CODE (TREE_TYPE (expr)) == ARRAY_TYPE
	      && IS_AGGR_TYPE (TREE_TYPE (TREE_TYPE (expr)))
	      && TYPE_MAIN_VARIANT (TREE_TYPE (expr)) == type)
	    return 1;
	  /* fall through...  */
	case TARGET_EXPR:
	case PARM_DECL:
	  if (IS_AGGR_TYPE (TREE_TYPE (expr))
	      && TYPE_MAIN_VARIANT (TREE_TYPE (expr)) == type)
	    return 1;
	  /* fall through...  */
	case PLUS_EXPR:
	default:
	  break;
	}
      break;
    }
  return 0;
}

/* Build multi-level access to EXPR using hierarchy path PATH.
   CODE is PLUS_EXPR if we are going with the grain,
   and MINUS_EXPR if we are not (in which case, we cannot traverse
   virtual baseclass links).

   TYPE is the type we want this path to have on exit.

   ALIAS_THIS is non-zero if EXPR in an expression involving `this'.  */

tree
build_vbase_path (code, type, expr, path, alias_this)
     enum tree_code code;
     tree type, expr, path;
     int alias_this;
{
  register int changed = 0;
  tree last = NULL_TREE, last_virtual = NULL_TREE;
  int nonnull = 0;
  int fixed_type_p;
  tree null_expr = 0, nonnull_expr;
  tree basetype;
  tree offset = integer_zero_node;

  if (BINFO_INHERITANCE_CHAIN (path) == NULL_TREE)
    return build1 (NOP_EXPR, type, expr);

  if (nonnull == 0 && (alias_this && flag_this_is_variable <= 0))
    nonnull = 1;

#if 0
  /* We need additional logic to convert back to the unconverted type
     (the static type of the complete object), and then convert back
     to the type we want.  Until that is done, or until we can
     recognize when that is, we cannot do the short cut logic. (mrs) */
  fixed_type_p = resolves_to_fixed_type_p (expr, &nonnull);
#else
  /* Do this, until we can undo any previous conversions.  See net35.C
     for a testcase.  */
  fixed_type_p = complete_type_p (expr);
#endif

  if (!fixed_type_p && TREE_SIDE_EFFECTS (expr))
    expr = save_expr (expr);
  nonnull_expr = expr;

  if (BINFO_INHERITANCE_CHAIN (path))
    {
      tree reverse_path = NULL_TREE;

      push_expression_obstack ();
      while (path)
	{
	  tree r = copy_node (path);
	  BINFO_INHERITANCE_CHAIN (r) = reverse_path;
	  reverse_path = r;
	  path = BINFO_INHERITANCE_CHAIN (path);
	}
      path = reverse_path;
      pop_obstacks ();
    }

  basetype = BINFO_TYPE (path);

  while (path)
    {
      if (TREE_VIA_VIRTUAL (path))
	{
	  last_virtual = BINFO_TYPE (path);
	  if (code == PLUS_EXPR)
	    {
	      changed = ! fixed_type_p;

	      if (changed)
		{
		  tree ind;

		  /* We already check for ambiguous things in the caller, just
		     find a path.  */
		  if (last)
		    {
		      tree binfo = get_binfo (last, TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (nonnull_expr))), 0);
		      nonnull_expr = convert_pointer_to_real (binfo, nonnull_expr);
		    }
		  ind = build_indirect_ref (nonnull_expr, NULL_PTR);
		  nonnull_expr = build_vbase_pointer (ind, last_virtual);
		  if (nonnull == 0
		      && (TREE_CODE (type) == POINTER_TYPE
			  || !flag_assume_nonnull_objects)
		      && null_expr == NULL_TREE)
		    {
		      null_expr = build1 (NOP_EXPR, build_pointer_type (last_virtual), integer_zero_node);
		      expr = build (COND_EXPR, build_pointer_type (last_virtual),
				    build (EQ_EXPR, boolean_type_node, expr,
					   integer_zero_node),
				    null_expr, nonnull_expr);
		    }
		}
	      /* else we'll figure out the offset below.  */

	      /* Happens in the case of parse errors.  */
	      if (nonnull_expr == error_mark_node)
		return error_mark_node;
	    }
	  else
	    {
	      cp_error ("cannot cast up from virtual baseclass `%T'",
			  last_virtual);
	      return error_mark_node;
	    }
	}
      last = path;
      path = BINFO_INHERITANCE_CHAIN (path);
    }
  /* LAST is now the last basetype assoc on the path.  */

  /* A pointer to a virtual base member of a non-null object
     is non-null.  Therefore, we only need to test for zeroness once.
     Make EXPR the canonical expression to deal with here.  */
  if (null_expr)
    {
      TREE_OPERAND (expr, 2) = nonnull_expr;
      TREE_TYPE (expr) = TREE_TYPE (TREE_OPERAND (expr, 1))
	= TREE_TYPE (nonnull_expr);
    }
  else
    expr = nonnull_expr;

  /* If we go through any virtual base pointers, make sure that
     casts to BASETYPE from the last virtual base class use
     the right value for BASETYPE.  */
  if (changed)
    {
      tree intype = TREE_TYPE (TREE_TYPE (expr));
      if (TYPE_MAIN_VARIANT (intype) != BINFO_TYPE (last))
	{
	  tree binfo = get_binfo (last, TYPE_MAIN_VARIANT (intype), 0);
	  offset = BINFO_OFFSET (binfo);
	}
    }
  else
    {
      if (last_virtual)
	{
	  offset = BINFO_OFFSET (binfo_member (last_virtual,
					       CLASSTYPE_VBASECLASSES (basetype)));
	  offset = size_binop (PLUS_EXPR, offset, BINFO_OFFSET (last));
	}
      else
	offset = BINFO_OFFSET (last);
    }

  if (TREE_INT_CST_LOW (offset))
    {
      /* Bash types to make the backend happy.  */
      offset = cp_convert (type, offset);
#if 0
      /* This shouldn't be necessary.  (mrs) */
      expr = build1 (NOP_EXPR, type, expr);
#endif

      /* For multiple inheritance: if `this' can be set by any
	 function, then it could be 0 on entry to any function.
	 Preserve such zeroness here.  Otherwise, only in the
	 case of constructors need we worry, and in those cases,
	 it will be zero, or initialized to some valid value to
	 which we may add.  */
      if (nonnull == 0)
	{
	  if (null_expr)
	    TREE_TYPE (null_expr) = type;
	  else
	    null_expr = build1 (NOP_EXPR, type, integer_zero_node);
	  if (TREE_SIDE_EFFECTS (expr))
	    expr = save_expr (expr);

	  return build (COND_EXPR, type,
			build (EQ_EXPR, boolean_type_node, expr, integer_zero_node),
			null_expr,
			build (code, type, expr, offset));
	}
      else return build (code, type, expr, offset);
    }

  /* Cannot change the TREE_TYPE of a NOP_EXPR here, since it may
     be used multiple times in initialization of multiple inheritance.  */
  if (null_expr)
    {
      TREE_TYPE (expr) = type;
      return expr;
    }
  else
    return build1 (NOP_EXPR, type, expr);
}

/* Virtual function things.  */

/* Build an entry in the virtual function table.
   DELTA is the offset for the `this' pointer.
   PFN is an ADDR_EXPR containing a pointer to the virtual function.
   Note that the index (DELTA2) in the virtual function table
   is always 0.  */

static tree
build_vtable_entry (delta, pfn)
     tree delta, pfn;
{
  if (flag_vtable_thunks)
    {
      HOST_WIDE_INT idelta = TREE_INT_CST_LOW (delta);
      if (idelta && ! DECL_ABSTRACT_VIRTUAL_P (TREE_OPERAND (pfn, 0)))
	{
	  pfn = build1 (ADDR_EXPR, vtable_entry_type,
			make_thunk (pfn, idelta));
	  TREE_READONLY (pfn) = 1;
	  TREE_CONSTANT (pfn) = 1;
	}
#ifdef GATHER_STATISTICS
      n_vtable_entries += 1;
#endif
      return pfn;
    }
  else
    {
      extern int flag_huge_objects;
      tree elems = expr_tree_cons (NULL_TREE, delta,
			      expr_tree_cons (NULL_TREE, integer_zero_node,
					 build_expr_list (NULL_TREE, pfn)));
      tree entry = build (CONSTRUCTOR, vtable_entry_type, NULL_TREE, elems);

      /* DELTA used to be constructed by `size_int' and/or size_binop,
	 which caused overflow problems when it was negative.  That should
	 be fixed now.  */

      if (! int_fits_type_p (delta, delta_type_node))
	{
	  if (flag_huge_objects)
	    sorry ("object size exceeds built-in limit for virtual function table implementation");
	  else
	    sorry ("object size exceeds normal limit for virtual function table implementation, recompile all source and use -fhuge-objects");
	}
      
      TREE_CONSTANT (entry) = 1;
      TREE_STATIC (entry) = 1;
      TREE_READONLY (entry) = 1;

#ifdef GATHER_STATISTICS
      n_vtable_entries += 1;
#endif

      return entry;
    }
}

/* Given an object INSTANCE, return an expression which yields the
   virtual function 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 (instance, idx)
     tree instance, idx;
{
  tree vtbl, aref;
  tree basetype = TREE_TYPE (instance);

  if (TREE_CODE (basetype) == REFERENCE_TYPE)
    basetype = TREE_TYPE (basetype);

  if (instance == current_class_ref)
    vtbl = build_indirect_ref (build_vfield_ref (instance, basetype),
			       NULL_PTR);
  else
    {
      if (optimize)
	{
	  /* Try to figure out what a reference refers to, and
	     access its virtual function table directly.  */
	  tree ref = NULL_TREE;

	  if (TREE_CODE (instance) == INDIRECT_REF
	      && TREE_CODE (TREE_TYPE (TREE_OPERAND (instance, 0))) == REFERENCE_TYPE)
	    ref = TREE_OPERAND (instance, 0);
	  else if (TREE_CODE (TREE_TYPE (instance)) == REFERENCE_TYPE)
	    ref = instance;

	  if (ref && TREE_CODE (ref) == VAR_DECL
	      && DECL_INITIAL (ref))
	    {
	      tree init = DECL_INITIAL (ref);

	      while (TREE_CODE (init) == NOP_EXPR
		     || TREE_CODE (init) == NON_LVALUE_EXPR)
		init = TREE_OPERAND (init, 0);
	      if (TREE_CODE (init) == ADDR_EXPR)
		{
		  init = TREE_OPERAND (init, 0);
		  if (IS_AGGR_TYPE (TREE_TYPE (init))
		      && (TREE_CODE (init) == PARM_DECL
			  || TREE_CODE (init) == VAR_DECL))
		    instance = init;
		}
	    }
	}

      if (IS_AGGR_TYPE (TREE_TYPE (instance))
	  && (TREE_CODE (instance) == RESULT_DECL
	      || TREE_CODE (instance) == PARM_DECL
	      || TREE_CODE (instance) == VAR_DECL))
	vtbl = TYPE_BINFO_VTABLE (basetype);
      else
	vtbl = build_indirect_ref (build_vfield_ref (instance, basetype),
				   NULL_PTR);
    }
  assemble_external (vtbl);
  aref = build_array_ref (vtbl, idx);

  return aref;
}

/* Given an object INSTANCE, return an expression which yields the
   virtual function 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_vfn_ref (ptr_to_instptr, instance, idx)
     tree *ptr_to_instptr, instance;
     tree idx;
{
  tree aref = build_vtbl_ref (instance, idx);

  /* When using thunks, there is no extra delta, and we get the pfn
     directly.  */
  if (flag_vtable_thunks)
    return aref;

  if (ptr_to_instptr)
    {
      /* Save the intermediate result in a SAVE_EXPR so we don't have to
	 compute each component of the virtual function pointer twice.  */ 
      if (TREE_CODE (aref) == INDIRECT_REF)
	TREE_OPERAND (aref, 0) = save_expr (TREE_OPERAND (aref, 0));

      *ptr_to_instptr
	= build (PLUS_EXPR, TREE_TYPE (*ptr_to_instptr),
		 *ptr_to_instptr,
		 cp_convert (ptrdiff_type_node,
			     build_component_ref (aref, delta_identifier, NULL_TREE, 0)));
    }

  return build_component_ref (aref, pfn_identifier, NULL_TREE, 0);
}

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

static tree
get_vtable_name (type)
     tree type;
{
  tree type_id = build_typename_overload (type);
  char *buf = (char *) alloca (strlen (VTABLE_NAME_FORMAT)
			       + IDENTIFIER_LENGTH (type_id) + 2);
  char *ptr = IDENTIFIER_POINTER (type_id);
  int i;
  for (i = 0; ptr[i] == OPERATOR_TYPENAME_FORMAT[i]; i++) ;
#if 0
  /* We don't take off the numbers; prepare_fresh_vtable uses the
     DECL_ASSEMBLER_NAME for the type, which includes the number
     in `3foo'.  If we were to pull them off here, we'd end up with
     something like `_vt.foo.3bar', instead of a uniform definition.  */
  while (ptr[i] >= '0' && ptr[i] <= '9')
    i += 1;
#endif
  sprintf (buf, VTABLE_NAME_FORMAT, ptr+i);
  return get_identifier (buf);
}

/* Return the offset to the main vtable for a given base BINFO.  */

tree
get_vfield_offset (binfo)
     tree binfo;
{
  tree tmp
    = size_binop (FLOOR_DIV_EXPR,
		  DECL_FIELD_BITPOS (CLASSTYPE_VFIELD (BINFO_TYPE (binfo))),
		  size_int (BITS_PER_UNIT));
  tmp = convert (sizetype, tmp);
  return size_binop (PLUS_EXPR, tmp, BINFO_OFFSET (binfo));
}

/* Get the offset to the start of the original binfo that we derived
   this binfo from.  If we find TYPE first, return the offset only
   that far.  The shortened search is useful because the this pointer
   on method calling is expected to point to a DECL_CONTEXT (fndecl)
   object, and not a baseclass of it.  */

static tree
get_derived_offset (binfo, type)
     tree binfo, type;
{
  tree offset1 = get_vfield_offset (TYPE_BINFO (BINFO_TYPE (binfo)));
  tree offset2;
  int i;
  while (BINFO_BASETYPES (binfo)
	 && (i=CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo))) != -1)
    {
      tree binfos = BINFO_BASETYPES (binfo);
      if (BINFO_TYPE (binfo) == type)
	break;
      binfo = TREE_VEC_ELT (binfos, i);
    }
  offset2 = get_vfield_offset (TYPE_BINFO (BINFO_TYPE (binfo)));
  return size_binop (MINUS_EXPR, offset1, offset2);
}

/* Update the rtti info for this class.  */

static void
set_rtti_entry (virtuals, offset, type)
     tree virtuals, offset, type;
{
  tree vfn;

  if (flag_rtti)
    vfn = build1 (ADDR_EXPR, vfunc_ptr_type_node, get_tinfo_fn (type));
  else
    vfn = build1 (NOP_EXPR, vfunc_ptr_type_node, size_zero_node);
  TREE_CONSTANT (vfn) = 1;

  if (! flag_vtable_thunks)
    TREE_VALUE (virtuals) = build_vtable_entry (offset, vfn);
  else
    {
      tree voff = build1 (NOP_EXPR, vfunc_ptr_type_node, offset);
      TREE_CONSTANT (voff) = 1;

      TREE_VALUE (virtuals) = build_vtable_entry (integer_zero_node, voff);

      /* The second slot is for the tdesc pointer when thunks are used.  */
      TREE_VALUE (TREE_CHAIN (virtuals))
	= build_vtable_entry (integer_zero_node, vfn);
    }
}

/* Build a virtual function for type 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.  */

static tree
build_vtable (binfo, type)
     tree binfo, type;
{
  tree name = get_vtable_name (type);
  tree virtuals, decl;

  if (binfo)
    {
      tree offset;

      virtuals = copy_list (BINFO_VIRTUALS (binfo));
      decl = build_decl (VAR_DECL, name, TREE_TYPE (BINFO_VTABLE (binfo)));

      /* Now do rtti stuff.  */
      offset = get_derived_offset (TYPE_BINFO (type), NULL_TREE);
      offset = ssize_binop (MINUS_EXPR, integer_zero_node, offset);
      set_rtti_entry (virtuals, offset, type);
    }
  else
    {
      virtuals = NULL_TREE;
      decl = build_decl (VAR_DECL, name, void_type_node);
    }

#ifdef GATHER_STATISTICS
  n_vtables += 1;
  n_vtable_elems += list_length (virtuals);
#endif

  /* Set TREE_PUBLIC and TREE_EXTERN as appropriate.  */
  import_export_vtable (decl, type, at_eof);

  decl = pushdecl_top_level (decl);
  SET_IDENTIFIER_GLOBAL_VALUE (name, decl);
  /* Initialize the association list for this type, based
     on our first approximation.  */
  TYPE_BINFO_VTABLE (type) = decl;
  TYPE_BINFO_VIRTUALS (type) = virtuals;

  DECL_ARTIFICIAL (decl) = 1;
  TREE_STATIC (decl) = 1;
#ifndef WRITABLE_VTABLES
  /* Make them READONLY by default. (mrs) */
  TREE_READONLY (decl) = 1;
#endif
  /* At one time the vtable info was grabbed 2 words at a time.  This
     fails on sparc unless you have 8-byte alignment.  (tiemann) */
  DECL_ALIGN (decl) = MAX (TYPE_ALIGN (double_type_node),
			   DECL_ALIGN (decl));

  /* Why is this conditional? (mrs) */
  if (binfo && write_virtuals >= 0)
    DECL_VIRTUAL_P (decl) = 1;
  DECL_CONTEXT (decl) = type;

  binfo = TYPE_BINFO (type);
  SET_BINFO_NEW_VTABLE_MARKED (binfo);
  return decl;
}

extern tree signed_size_zero_node;

/* Give TYPE 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 derived type which caused this table to
   be needed.

   BINFO is the type association which provided TYPE for FOR_TYPE.

   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 void
prepare_fresh_vtable (binfo, for_type)
     tree binfo, for_type;
{
  tree basetype;
  tree orig_decl = BINFO_VTABLE (binfo);
  tree name;
  tree new_decl;
  tree offset;
  tree path = binfo;
  char *buf, *buf2;
  char joiner = '_';
  int i;

#ifdef JOINER
  joiner = JOINER;
#endif

  basetype = TYPE_MAIN_VARIANT (BINFO_TYPE (binfo));

  buf2 = TYPE_ASSEMBLER_NAME_STRING (basetype);
  i = TYPE_ASSEMBLER_NAME_LENGTH (basetype) + 1;

  /* We know that the vtable that we are going to create doesn't exist
     yet in the global namespace, and when we finish, it will be
     pushed into the global namespace.  In complex MI hierarchies, we
     have to loop while the name we are thinking of adding is globally
     defined, adding more name components to the vtable name as we
     loop, until the name is unique.  This is because in complex MI
     cases, we might have the same base more than once.  This means
     that the order in which this function is called for vtables must
     remain the same, otherwise binary compatibility can be
     compromised.  */

  while (1)
    {
      char *buf1 = (char *) alloca (TYPE_ASSEMBLER_NAME_LENGTH (for_type)
				    + 1 + i);
      char *new_buf2;

      sprintf (buf1, "%s%c%s", TYPE_ASSEMBLER_NAME_STRING (for_type), joiner,
	       buf2);
      buf = (char *) alloca (strlen (VTABLE_NAME_FORMAT) + strlen (buf1) + 1);
      sprintf (buf, VTABLE_NAME_FORMAT, buf1);
      name = get_identifier (buf);

      /* If this name doesn't clash, then we can use it, otherwise
	 we add more to the name until it is unique.  */

      if (! IDENTIFIER_GLOBAL_VALUE (name))
	break;

      /* Set values for next loop through, if the name isn't unique.  */

      path = BINFO_INHERITANCE_CHAIN (path);

      /* We better not run out of stuff to make it unique.  */
      my_friendly_assert (path != NULL_TREE, 368);

      basetype = TYPE_MAIN_VARIANT (BINFO_TYPE (path));

      if (for_type == basetype)
	{
	  /* If we run out of basetypes in the path, we have already
	     found created a vtable with that name before, we now
	     resort to tacking on _%d to distinguish them.  */
	  int j = 2;
	  i = TYPE_ASSEMBLER_NAME_LENGTH (basetype) + 1 + i + 1 + 3;
	  buf1 = (char *) alloca (i);
	  do {
	    sprintf (buf1, "%s%c%s%c%d",
		     TYPE_ASSEMBLER_NAME_STRING (basetype), joiner,
		     buf2, joiner, j);
	    buf = (char *) alloca (strlen (VTABLE_NAME_FORMAT)
				   + strlen (buf1) + 1);
	    sprintf (buf, VTABLE_NAME_FORMAT, buf1);
	    name = get_identifier (buf);

	    /* If this name doesn't clash, then we can use it,
	       otherwise we add something different to the name until
	       it is unique.  */
	  } while (++j <= 999 && IDENTIFIER_GLOBAL_VALUE (name));

	  /* Hey, they really like MI don't they?  Increase the 3
             above to 6, and the 999 to 999999.  :-)  */
	  my_friendly_assert (j <= 999, 369);

	  break;
	}

      i = TYPE_ASSEMBLER_NAME_LENGTH (basetype) + 1 + i;
      new_buf2 = (char *) alloca (i);
      sprintf (new_buf2, "%s%c%s",
	       TYPE_ASSEMBLER_NAME_STRING (basetype), joiner, buf2);
      buf2 = new_buf2;
    }

  new_decl = build_decl (VAR_DECL, name, TREE_TYPE (orig_decl));
  /* Remember which class this vtable is really for.  */
  DECL_CONTEXT (new_decl) = for_type;

  DECL_ARTIFICIAL (new_decl) = 1;
  TREE_STATIC (new_decl) = 1;
  BINFO_VTABLE (binfo) = pushdecl_top_level (new_decl);
  DECL_VIRTUAL_P (new_decl) = 1;
#ifndef WRITABLE_VTABLES
  /* Make them READONLY by default. (mrs) */
  TREE_READONLY (new_decl) = 1;
#endif
  DECL_ALIGN (new_decl) = DECL_ALIGN (orig_decl);

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

  if (TREE_VIA_VIRTUAL (binfo))
    {
      tree binfo1 = binfo_member (BINFO_TYPE (binfo), 
				  CLASSTYPE_VBASECLASSES (for_type));

      /* XXX - This should never happen, if it does, the caller should
	 ensure that the binfo is from for_type's binfos, not from any
	 base type's.  We can remove all this code after a while.  */
      if (binfo1 != binfo)
	warning ("internal inconsistency: binfo offset error for rtti");

      offset = BINFO_OFFSET (binfo1);
    }
  else
    offset = BINFO_OFFSET (binfo);

  set_rtti_entry (BINFO_VIRTUALS (binfo),
		  ssize_binop (MINUS_EXPR, integer_zero_node, offset),
		  for_type);

#ifdef GATHER_STATISTICS
  n_vtables += 1;
  n_vtable_elems += list_length (BINFO_VIRTUALS (binfo));
#endif

  /* Set TREE_PUBLIC and TREE_EXTERN as appropriate.  */
  import_export_vtable (new_decl, for_type, at_eof);

  if (TREE_VIA_VIRTUAL (binfo))
    my_friendly_assert (binfo == binfo_member (BINFO_TYPE (binfo),
				   CLASSTYPE_VBASECLASSES (current_class_type)),
			170);
  SET_BINFO_NEW_VTABLE_MARKED (binfo);
}

#if 0
/* Access the virtual function table entry that logically
   contains BASE_FNDECL.  VIRTUALS is the virtual function table's
   initializer.  We can run off the end, when dealing with virtual
   destructors in MI situations, return NULL_TREE in that case.  */

static tree
get_vtable_entry (virtuals, base_fndecl)
     tree virtuals, base_fndecl;
{
  unsigned HOST_WIDE_INT n = (HOST_BITS_PER_WIDE_INT >= BITS_PER_WORD
	   ? (TREE_INT_CST_LOW (DECL_VINDEX (base_fndecl))
	      & (((unsigned HOST_WIDE_INT)1<<(BITS_PER_WORD-1))-1))
	   : TREE_INT_CST_LOW (DECL_VINDEX (base_fndecl)));

#ifdef GATHER_STATISTICS
  n_vtable_searches += n;
#endif

  while (n > 0 && virtuals)
    {
      --n;
      virtuals = TREE_CHAIN (virtuals);
    }
  return virtuals;
}
#endif

/* Put new entry ENTRY into virtual function table initializer
   VIRTUALS.

   Also update DECL_VINDEX (FNDECL).  */

static void
modify_vtable_entry (old_entry_in_list, new_entry, fndecl)
     tree old_entry_in_list, new_entry, fndecl;
{
  tree base_fndecl = TREE_OPERAND (FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (old_entry_in_list)), 0);

#ifdef NOTQUITE
  cp_warning ("replaced %D with %D", DECL_ASSEMBLER_NAME (base_fndecl),
	      DECL_ASSEMBLER_NAME (fndecl));
#endif
  TREE_VALUE (old_entry_in_list) = new_entry;

  /* Now assign virtual dispatch information, if unset.  */
  /* We can dispatch this, through any overridden base function.  */
  if (TREE_CODE (DECL_VINDEX (fndecl)) != INTEGER_CST)
    {
      DECL_VINDEX (fndecl) = DECL_VINDEX (base_fndecl);
      DECL_CONTEXT (fndecl) = DECL_CONTEXT (base_fndecl);
    }
}

/* Access the virtual function table entry N.  VIRTUALS is the virtual
   function table's initializer.  */

static tree
get_vtable_entry_n (virtuals, n)
     tree virtuals;
     unsigned HOST_WIDE_INT n;
{
  while (n > 0)
    {
      --n;
      virtuals = TREE_CHAIN (virtuals);
    }
  return virtuals;
}

/* Add a virtual function to all the appropriate vtables for the class
   T.  DECL_VINDEX(X) should be error_mark_node, if we want to
   allocate a new slot in our table.  If it is error_mark_node, we
   know that no other function from another vtable is overridden by X.
   HAS_VIRTUAL keeps track of how many virtuals there are in our main
   vtable for the type, and we build upon the PENDING_VIRTUALS list
   and return it.  */

static void
add_virtual_function (pv, phv, has_virtual, fndecl, t)
     tree *pv, *phv;
     int *has_virtual;
     tree fndecl;
     tree t; /* Structure type.  */
{
  tree pending_virtuals = *pv;
  tree pending_hard_virtuals = *phv;

  /* FUNCTION_TYPEs and OFFSET_TYPEs no longer freely
     convert to void *.  Make such a conversion here.  */
  tree vfn = build1 (ADDR_EXPR, vfunc_ptr_type_node, fndecl);
  TREE_CONSTANT (vfn) = 1;

#ifndef DUMB_USER
  if (current_class_type == 0)
    cp_warning ("internal problem, current_class_type is zero when adding `%D', please report",
		fndecl);
  if (current_class_type && t != current_class_type)
    cp_warning ("internal problem, current_class_type differs when adding `%D', please report",
		fndecl);
#endif

  /* If the virtual function is a redefinition of a prior one,
     figure out in which base class the new definition goes,
     and if necessary, make a fresh virtual function table
     to hold that entry.  */
  if (DECL_VINDEX (fndecl) == error_mark_node)
    {
      tree entry;

      /* We remember that this was the base sub-object for rtti.  */
      CLASSTYPE_RTTI (t) = t;

      /* If we are using thunks, use two slots at the front, one
	 for the offset pointer, one for the tdesc pointer.  */
      if (*has_virtual == 0 && flag_vtable_thunks)
	{
	  *has_virtual = 1;
	}

      /* Build a new INT_CST for this DECL_VINDEX.  */
      {
	static tree index_table[256];
	tree idx;
	/* We skip a slot for the offset/tdesc entry.  */
	int i = ++(*has_virtual);

	if (i >= 256 || index_table[i] == 0)
	  {
	    idx = build_int_2 (i, 0);
	    if (i < 256)
	      index_table[i] = idx;
	  }
	else
	  idx = index_table[i];

	/* Now assign virtual dispatch information.  */
	DECL_VINDEX (fndecl) = idx;
	DECL_CONTEXT (fndecl) = t;
      }
      entry = build_vtable_entry (integer_zero_node, vfn);
      pending_virtuals = tree_cons (DECL_VINDEX (fndecl), entry, pending_virtuals);
    }
  /* Might already be INTEGER_CST if declared twice in class.  We will
     give error later or we've already given it.  */
  else if (TREE_CODE (DECL_VINDEX (fndecl)) != INTEGER_CST)
    {
      /* Need an entry in some other virtual function table.
         Deal with this after we have laid out our virtual base classes.  */
      pending_hard_virtuals = temp_tree_cons (fndecl, vfn, pending_hard_virtuals);
    }
  *pv = pending_virtuals;
  *phv = pending_hard_virtuals;
}

/* Obstack on which to build the vector of class methods.  */
struct obstack class_obstack;
extern struct obstack *current_obstack;

/* Add method METHOD to class TYPE.  This is used when a method
   has been defined which did not initially appear in the class definition,
   and helps cut down on spurious error messages.

   FIELDS is the entry in the METHOD_VEC vector entry of the class type where
   the method should be added.  */

void
add_method (type, fields, method)
     tree type, *fields, method;
{
  push_obstacks (&permanent_obstack, &permanent_obstack);

  if (fields && *fields)
      *fields = build_overload (method, *fields);
  else if (CLASSTYPE_METHOD_VEC (type) == 0)
    {
      tree method_vec = make_node (TREE_VEC);
      if (TYPE_IDENTIFIER (type) == DECL_NAME (method))
	{
	  /* ??? Is it possible for there to have been enough room in the
	     current chunk for the tree_vec structure but not a tree_vec
	     plus a tree*?  Will this work in that case?  */
	  obstack_free (current_obstack, method_vec);
	  obstack_blank (current_obstack, sizeof (struct tree_vec) + sizeof (tree *));
	  if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (method)))
	    TREE_VEC_ELT (method_vec, 1) = method;
	  else
	    TREE_VEC_ELT (method_vec, 0) = method;
	  TREE_VEC_LENGTH (method_vec) = 2;
	}
      else
	{
	  /* ??? Is it possible for there to have been enough room in the
	     current chunk for the tree_vec structure but not a tree_vec
	     plus a tree*?  Will this work in that case?  */
	  obstack_free (current_obstack, method_vec);
	  obstack_blank (current_obstack, sizeof (struct tree_vec) + 2*sizeof (tree *));
	  TREE_VEC_ELT (method_vec, 2) = method;
	  TREE_VEC_LENGTH (method_vec) = 3;
	  obstack_finish (current_obstack);
	}
      CLASSTYPE_METHOD_VEC (type) = method_vec;
    }
  else
    {
      tree method_vec = CLASSTYPE_METHOD_VEC (type);
      int len = TREE_VEC_LENGTH (method_vec);

      /* Adding a new ctor or dtor.  This is easy because our
         METHOD_VEC always has a slot for such entries.  */
      if (TYPE_IDENTIFIER (type) == DECL_NAME (method))
	{
	  int idx = !!DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (method));
	  /* TREE_VEC_ELT (method_vec, idx) = method; */
	  if (method != TREE_VEC_ELT (method_vec, idx))
	    TREE_VEC_ELT (method_vec, idx) =
	      build_overload (method, TREE_VEC_ELT (method_vec, idx));
	}
      else
	{
	  /* This is trickier.  We try to extend the TREE_VEC in-place,
	     but if that does not work, we copy all its data to a new
	     TREE_VEC that's large enough.  */
	  struct obstack *ob = &class_obstack;
	  tree *end = (tree *)obstack_next_free (ob);

	  if (end != TREE_VEC_END (method_vec))
	    {
	      ob = current_obstack;
	      TREE_VEC_LENGTH (method_vec) += 1;
	      TREE_VEC_ELT (method_vec, len) = NULL_TREE;
	      method_vec = copy_node (method_vec);
	      TREE_VEC_LENGTH (method_vec) -= 1;
	    }
	  else
	    {
	      tree tmp_vec = (tree) obstack_base (ob);
	      if (obstack_room (ob) < sizeof (tree))
		{
		  obstack_blank (ob, sizeof (struct tree_common)
				 + tree_code_length[(int) TREE_VEC]
				   * sizeof (char *)
				 + len * sizeof (tree));
		  tmp_vec = (tree) obstack_base (ob);
		  bcopy ((char *) method_vec, (char *) tmp_vec,
			 (sizeof (struct tree_common)
			  + tree_code_length[(int) TREE_VEC] * sizeof (char *)
			  + (len-1) * sizeof (tree)));
		  method_vec = tmp_vec;
		}
	      else
		obstack_blank (ob, sizeof (tree));
	    }

	  obstack_finish (ob);
	  TREE_VEC_ELT (method_vec, len) = method;
	  TREE_VEC_LENGTH (method_vec) = len + 1;
	  CLASSTYPE_METHOD_VEC (type) = method_vec;

	  if (TYPE_BINFO_BASETYPES (type) && CLASSTYPE_BASELINK_VEC (type))
	    {
	      /* ??? May be better to know whether these can be extended?  */
	      tree baselink_vec = CLASSTYPE_BASELINK_VEC (type);

	      TREE_VEC_LENGTH (baselink_vec) += 1;
	      CLASSTYPE_BASELINK_VEC (type) = copy_node (baselink_vec);
	      TREE_VEC_LENGTH (baselink_vec) -= 1;

	      TREE_VEC_ELT (CLASSTYPE_BASELINK_VEC (type), len) = 0;
	    }
	}
    }
  DECL_CONTEXT (method) = type;
  DECL_CLASS_CONTEXT (method) = type;

  pop_obstacks ();
}

/* Subroutines of finish_struct.  */

/* Look through the list of fields for this struct, deleting
   duplicates as we go.  This must be recursive to handle
   anonymous unions.

   FIELD is the field which may not appear anywhere in FIELDS.
   FIELD_PTR, if non-null, is the starting point at which
   chained deletions may take place.
   The value returned is the first acceptable entry found
   in FIELDS.

   Note that anonymous fields which are not of UNION_TYPE are
   not duplicates, they are just anonymous fields.  This happens
   when we have unnamed bitfields, for example.  */

static tree
delete_duplicate_fields_1 (field, fields)
     tree field, fields;
{
  tree x;
  tree prev = 0;
  if (DECL_NAME (field) == 0)
    {
      if (TREE_CODE (TREE_TYPE (field)) != UNION_TYPE)
	return fields;

      for (x = TYPE_FIELDS (TREE_TYPE (field)); x; x = TREE_CHAIN (x))
	fields = delete_duplicate_fields_1 (x, fields);
      return fields;
    }
  else
    {
      for (x = fields; x; prev = x, x = TREE_CHAIN (x))
	{
	  if (DECL_NAME (x) == 0)
	    {
	      if (TREE_CODE (TREE_TYPE (x)) != UNION_TYPE)
		continue;
	      TYPE_FIELDS (TREE_TYPE (x))
		= delete_duplicate_fields_1 (field, TYPE_FIELDS (TREE_TYPE (x)));
	      if (TYPE_FIELDS (TREE_TYPE (x)) == 0)
		{
		  if (prev == 0)
		    fields = TREE_CHAIN (fields);
		  else
		    TREE_CHAIN (prev) = TREE_CHAIN (x);
		}
	    }
	  else
	    {
	      if (DECL_NAME (field) == DECL_NAME (x))
		{
		  if (TREE_CODE (field) == CONST_DECL
		      && TREE_CODE (x) == CONST_DECL)
		    cp_error_at ("duplicate enum value `%D'", x);
		  else if (TREE_CODE (field) == CONST_DECL
			   || TREE_CODE (x) == CONST_DECL)
		    cp_error_at ("duplicate field `%D' (as enum and non-enum)",
				x);
		  else if (DECL_DECLARES_TYPE_P (field)
			   && DECL_DECLARES_TYPE_P (x))
		    {
		      if (comptypes (TREE_TYPE (field), TREE_TYPE (x), 1))
			continue;
		      cp_error_at ("duplicate nested type `%D'", x);
		    }
		  else if (DECL_DECLARES_TYPE_P (field)
			   || DECL_DECLARES_TYPE_P (x))
		    {
		      /* Hide tag decls.  */
		      if ((TREE_CODE (field) == TYPE_DECL
			   && DECL_ARTIFICIAL (field))
			  || (TREE_CODE (x) == TYPE_DECL
			      && DECL_ARTIFICIAL (x)))
			continue;
		      cp_error_at ("duplicate field `%D' (as type and non-type)",
				   x);
		    }
		  else
		    cp_error_at ("duplicate member `%D'", x);
		  if (prev == 0)
		    fields = TREE_CHAIN (fields);
		  else
		    TREE_CHAIN (prev) = TREE_CHAIN (x);
		}
	    }
	}
    }
  return fields;
}

static void
delete_duplicate_fields (fields)
     tree fields;
{
  tree x;
  for (x = fields; x && TREE_CHAIN (x); x = TREE_CHAIN (x))
    TREE_CHAIN (x) = delete_duplicate_fields_1 (x, TREE_CHAIN (x));
}

/* Change the access of FDECL to ACCESS in T.  The access to FDECL is
   along the path given by BINFO.  Return 1 if change was legit,
   otherwise return 0.  */

static int
alter_access (t, binfo, fdecl, access)
     tree t;
     tree binfo;
     tree fdecl;
     tree access;
{
  tree elem = purpose_member (t, DECL_ACCESS (fdecl));
  if (elem)
    {
      if (TREE_VALUE (elem) != access)
	{
	  if (TREE_CODE (TREE_TYPE (fdecl)) == FUNCTION_DECL)
	    cp_error_at ("conflicting access specifications for method `%D', ignored", TREE_TYPE (fdecl));
	  else
	    error ("conflicting access specifications for field `%s', ignored",
		   IDENTIFIER_POINTER (DECL_NAME (fdecl)));
	}
      else
	{
	  /* They're changing the access to the same thing they changed
	     it to before.  That's OK.  */
	  ;
	}
    }
  else
    {
      enforce_access (binfo, fdecl);

      DECL_ACCESS (fdecl) = tree_cons (t, access, DECL_ACCESS (fdecl));
      return 1;
    }
  return 0;
}

/* Process the USING_DECL, which is a member of T.  The METHOD_VEC, if
   non-NULL, is the methods of T.  The FIELDS are the fields of T.
   Returns 1 if the USING_DECL was valid, 0 otherwise.  */

void
handle_using_decl (using_decl, t, method_vec, fields)
     tree using_decl;
     tree t;
     tree method_vec;
     tree fields;
{
  tree ctype = DECL_INITIAL (using_decl);
  tree name = DECL_NAME (using_decl);
  tree access
    = TREE_PRIVATE (using_decl) ? access_private_node
    : TREE_PROTECTED (using_decl) ? access_protected_node
    : access_public_node;
  tree fdecl, binfo;
  tree flist = NULL_TREE;
  tree tmp;
  int i;
  int n_methods;

  binfo = binfo_or_else (ctype, t);
  if (! binfo)
    return;
  
  if (name == constructor_name (ctype)
      || name == constructor_name_full (ctype))
    cp_error_at ("using-declaration for constructor", using_decl);
  
  fdecl = lookup_member (binfo, name, 0, 0);
  
  if (!fdecl)
    {
      cp_error_at ("no members matching `%D' in `%#T'", using_decl, ctype);
      return;
    }

  /* Functions are represented as TREE_LIST, with the purpose
     being the type and the value the functions. Other members
     come as themselves. */
  if (TREE_CODE (fdecl) == TREE_LIST)
    /* Ignore base type this came from. */
    fdecl = TREE_VALUE (fdecl);

  if (TREE_CODE (fdecl) == OVERLOAD)
    {
      /* We later iterate over all functions. */
      flist = fdecl;
      fdecl = OVL_FUNCTION (flist);
    }
  
  name = DECL_NAME (fdecl);
  n_methods = method_vec ? TREE_VEC_LENGTH (method_vec) : 0;
  for (i = 2; i < n_methods; i++)
    if (DECL_NAME (OVL_CURRENT (TREE_VEC_ELT (method_vec, i)))
	== name)
      {
	cp_error ("cannot adjust access to `%#D' in `%#T'", fdecl, t);
	cp_error_at ("  because of local method `%#D' with same name",
		     OVL_CURRENT (TREE_VEC_ELT (method_vec, i)));
	return;
      }

  if (! DECL_LANG_SPECIFIC (fdecl))
    /* We don't currently handle DECL_ACCESS for TYPE_DECLs; just return.  */
    return;
  
  for (tmp = fields; tmp; tmp = TREE_CHAIN (tmp))
    if (DECL_NAME (tmp) == name)
      {
	cp_error ("cannot adjust access to `%#D' in `%#T'", fdecl, t);
	cp_error_at ("  because of local field `%#D' with same name", tmp);
	return;
      }
  
  /* Make type T see field decl FDECL with access ACCESS.*/
  if (flist)
    {
      while (flist)
	{
	  if (alter_access (t, binfo, OVL_FUNCTION (flist), 
			    access) == 0)
	    return;
	  flist = OVL_CHAIN (flist);
	}
    }
  else
    alter_access (t, binfo, fdecl, access);
}

/* If FOR_TYPE needs to reinitialize virtual function table pointers
   for TYPE's sub-objects, add such reinitializations to BASE_INIT_LIST.
   Returns BASE_INIT_LIST appropriately modified.  */

static tree
maybe_fixup_vptrs (for_type, binfo, base_init_list)
     tree for_type, binfo, base_init_list;
{
  /* Now reinitialize any slots that don't fall under our virtual
     function table pointer.  */
  tree vfields = CLASSTYPE_VFIELDS (BINFO_TYPE (binfo));
  while (vfields)
    {
      tree basetype = VF_NORMAL_VALUE (vfields)
	? TYPE_MAIN_VARIANT (VF_NORMAL_VALUE (vfields))
	  : VF_BASETYPE_VALUE (vfields);

      tree base_binfo = get_binfo (basetype, for_type, 0);
      /* Punt until this is implemented.  */
      if (1 /* BINFO_MODIFIED (base_binfo) */)
	{
	  tree base_offset = get_vfield_offset (base_binfo);
	  if (! tree_int_cst_equal (base_offset, get_vfield_offset (TYPE_BINFO (for_type)))
	      && ! tree_int_cst_equal (base_offset, get_vfield_offset (binfo)))
	    base_init_list = tree_cons (error_mark_node, base_binfo,
					base_init_list);
	}
      vfields = TREE_CHAIN (vfields);
    }
  return base_init_list;
}

/* If TYPE does not have a constructor, then the compiler must
   manually deal with all of the initialization this type requires.

   If a base initializer exists only to fill in the virtual function
   table pointer, then we mark that fact with the TREE_VIRTUAL bit.
   This way, we avoid multiple initializations of the same field by
   each virtual function table up the class hierarchy.

   Virtual base class pointers are not initialized here.  They are
   initialized only at the "top level" of object creation.  If we
   initialized them here, we would have to skip a lot of work.  */

static void
build_class_init_list (type)
     tree type;
{
  tree base_init_list = NULL_TREE;
  tree member_init_list = NULL_TREE;

  /* Since we build member_init_list and base_init_list using
     tree_cons, backwards fields the all through work.  */
  tree x;
  tree binfos = BINFO_BASETYPES (TYPE_BINFO (type));
  int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0;

  for (x = TYPE_FIELDS (type); x; x = TREE_CHAIN (x))
    {
      if (TREE_CODE (x) != FIELD_DECL)
	continue;

      if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (x))
	  || DECL_INITIAL (x) != NULL_TREE)
	member_init_list = tree_cons (x, type, member_init_list);
    }
  member_init_list = nreverse (member_init_list);

  /* We will end up doing this last.  Need special marker
     to avoid infinite regress.  */
  if (TYPE_VIRTUAL_P (type))
    {
      base_init_list = build_tree_list (error_mark_node, TYPE_BINFO (type));
      if (CLASSTYPE_NEEDS_VIRTUAL_REINIT (type) == 0)
	TREE_VALUE (base_init_list) = NULL_TREE;
      TREE_ADDRESSABLE (base_init_list) = 1;
    }

  /* Each base class which needs to have initialization
     of some kind gets to make such requests known here.  */
  for (i = n_baseclasses-1; i >= 0; i--)
    {
      tree base_binfo = TREE_VEC_ELT (binfos, i);
      tree blist;

      /* Don't initialize virtual baseclasses this way.  */
      if (TREE_VIA_VIRTUAL (base_binfo))
	continue;

      if (TYPE_HAS_CONSTRUCTOR (BINFO_TYPE (base_binfo)))
	{
	  /* ...and the last shall come first...  */
	  base_init_list = maybe_fixup_vptrs (type, base_binfo, base_init_list);
	  base_init_list = tree_cons (NULL_TREE, base_binfo, base_init_list);
	  continue;
	}

      if ((blist = CLASSTYPE_BASE_INIT_LIST (BINFO_TYPE (base_binfo))) == NULL_TREE)
	/* Nothing to initialize.  */
	continue;

      /* ...ditto...  */
      base_init_list = maybe_fixup_vptrs (type, base_binfo, base_init_list);

      /* This is normally true for single inheritance.
	 The win is we can shrink the chain of initializations
	 to be done by only converting to the actual type
	 we are interested in.  */
      if (TREE_VALUE (blist)
	  && TREE_CODE (TREE_VALUE (blist)) == TREE_VEC
	  && tree_int_cst_equal (BINFO_OFFSET (base_binfo),
				 BINFO_OFFSET (TREE_VALUE (blist))))
	{
	  if (base_init_list)
	    {
	      /* Does it do more than just fill in a
		 virtual function table pointer?  */
	      if (! TREE_ADDRESSABLE (blist))
		base_init_list = build_tree_list (blist, base_init_list);
	      /* Can we get by just with the virtual function table
		 pointer that it fills in?  */
	      else if (TREE_ADDRESSABLE (base_init_list)
		       && TREE_VALUE (base_init_list) == 0)
		base_init_list = blist;
	      /* Maybe, but it is not obvious as the previous case.  */
	      else if (! CLASSTYPE_NEEDS_VIRTUAL_REINIT (type))
		{
		  tree last = tree_last (base_init_list);
		  while (TREE_VALUE (last)
			 && TREE_CODE (TREE_VALUE (last)) == TREE_LIST)
		    last = tree_last (TREE_VALUE (last));
		  if (TREE_VALUE (last) == 0)
		    base_init_list = build_tree_list (blist, base_init_list);
		}
	    }
	  else
	    base_init_list = blist;
	}
      else
	{
	  /* The function expand_aggr_init knows how to do the
	     initialization of `basetype' without getting
	     an explicit `blist'.  */
	  if (base_init_list)
	    base_init_list = tree_cons (NULL_TREE, base_binfo, base_init_list);
	  else
	    base_init_list = CLASSTYPE_BINFO_AS_LIST (BINFO_TYPE (base_binfo));
	}
    }

  if (base_init_list)
    {
      if (member_init_list)
	CLASSTYPE_BASE_INIT_LIST (type) =
	  build_tree_list (base_init_list, member_init_list);
      else
	CLASSTYPE_BASE_INIT_LIST (type) = base_init_list;
    }
  else if (member_init_list)
    CLASSTYPE_BASE_INIT_LIST (type) = member_init_list;
}

struct base_info
{
  int has_virtual;
  int max_has_virtual;
  int n_ancestors;
  tree vfield;
  tree vfields;
  tree rtti;
  char cant_have_default_ctor;
  char cant_have_const_ctor;
  char no_const_asn_ref;
};

/* Record information about type T derived from its base classes.
   Store most of that information in T itself, and place the
   remaining information in the struct BASE_INFO.

   Propagate basetype offsets throughout the lattice.  Note that the
   lattice topped by T is really a pair: it's a DAG that gives the
   structure of the derivation hierarchy, and it's a list of the
   virtual baseclasses that appear anywhere in the DAG.  When a vbase
   type appears in the DAG, it's offset is 0, and it's children start
   their offsets from that point.  When a vbase type appears in the list,
   its offset is the offset it has in the hierarchy, and its children's
   offsets include that offset in theirs.

   Returns the index of the first base class to have virtual functions,
   or -1 if no such base class.  */

static int
finish_base_struct (t, b)
     tree t;
     struct base_info *b;
{
  tree binfos = TYPE_BINFO_BASETYPES (t);
  int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0;
  int first_vfn_base_index = -1;
  bzero ((char *) b, sizeof (struct base_info));

  for (i = 0; i < n_baseclasses; i++)
    {
      tree base_binfo = TREE_VEC_ELT (binfos, i);
      tree basetype = BINFO_TYPE (base_binfo);

      /* Effective C++ rule 14.  We only need to check TYPE_VIRTUAL_P
	 here because the case of virtual functions but non-virtual
	 dtor is handled in finish_struct_1.  */
      if (warn_ecpp && ! TYPE_VIRTUAL_P (basetype)
	  && TYPE_HAS_DESTRUCTOR (basetype))
	cp_warning ("base class `%#T' has a non-virtual destructor", basetype);

      /* If the type of basetype is incomplete, then
	 we already complained about that fact
	 (and we should have fixed it up as well).  */
      if (TYPE_SIZE (basetype) == 0)
	{
	  int j;
	  /* The base type is of incomplete type.  It is
	     probably best to pretend that it does not
	     exist.  */
	  if (i == n_baseclasses-1)
	    TREE_VEC_ELT (binfos, i) = NULL_TREE;
	  TREE_VEC_LENGTH (binfos) -= 1;
	  n_baseclasses -= 1;
	  for (j = i; j+1 < n_baseclasses; j++)
	    TREE_VEC_ELT (binfos, j) = TREE_VEC_ELT (binfos, j+1);
	}

      if (! TYPE_HAS_CONST_INIT_REF (basetype))
	b->cant_have_const_ctor = 1;

      if (TYPE_HAS_CONSTRUCTOR (basetype)
	  && ! TYPE_HAS_DEFAULT_CONSTRUCTOR (basetype))
	{
	  b->cant_have_default_ctor = 1;
	  if (! TYPE_HAS_CONSTRUCTOR (t))
	    {
	      cp_pedwarn ("base `%T' with only non-default constructor",
			  basetype);
	      cp_pedwarn ("in class without a constructor");
	    }
	}

      if (TYPE_HAS_ASSIGN_REF (basetype)
	  && !TYPE_HAS_CONST_ASSIGN_REF (basetype))
	b->no_const_asn_ref = 1;

      b->n_ancestors += CLASSTYPE_N_SUPERCLASSES (basetype);
      TYPE_NEEDS_CONSTRUCTING (t) |= TYPE_NEEDS_CONSTRUCTING (basetype);
      TYPE_NEEDS_DESTRUCTOR (t) |= TYPE_NEEDS_DESTRUCTOR (basetype);
      TYPE_HAS_COMPLEX_ASSIGN_REF (t) |= TYPE_HAS_COMPLEX_ASSIGN_REF (basetype);
      TYPE_HAS_COMPLEX_INIT_REF (t) |= TYPE_HAS_COMPLEX_INIT_REF (basetype);

      TYPE_OVERLOADS_CALL_EXPR (t) |= TYPE_OVERLOADS_CALL_EXPR (basetype);
      TYPE_OVERLOADS_ARRAY_REF (t) |= TYPE_OVERLOADS_ARRAY_REF (basetype);
      TYPE_OVERLOADS_ARROW (t) |= TYPE_OVERLOADS_ARROW (basetype);

      if (! TREE_VIA_VIRTUAL (base_binfo))
	CLASSTYPE_N_SUPERCLASSES (t) += 1;

      if (TYPE_VIRTUAL_P (basetype))
	{
	  /* Ensure that this is set from at least a virtual base
             class.  */
	  if (b->rtti == NULL_TREE)
	    b->rtti = CLASSTYPE_RTTI (basetype);

	  /* Don't borrow virtuals from virtual baseclasses.  */
	  if (TREE_VIA_VIRTUAL (base_binfo))
	    continue;

	  if (first_vfn_base_index < 0)
	    {
	      tree vfields;
	      first_vfn_base_index = i;

	      /* Update these two, now that we know what vtable we are
		 going to extend.  This is so that we can add virtual
		 functions, and override them properly.  */
	      TYPE_BINFO_VTABLE (t) = TYPE_BINFO_VTABLE (basetype);
	      TYPE_BINFO_VIRTUALS (t) = TYPE_BINFO_VIRTUALS (basetype);
	      b->has_virtual = CLASSTYPE_VSIZE (basetype);
	      b->vfield = CLASSTYPE_VFIELD (basetype);
	      b->vfields = copy_list (CLASSTYPE_VFIELDS (basetype));
	      vfields = b->vfields;
	      while (vfields)
		{
		  if (VF_BINFO_VALUE (vfields) == NULL_TREE
		      || ! TREE_VIA_VIRTUAL (VF_BINFO_VALUE (vfields)))
		    {
		      tree value = VF_BASETYPE_VALUE (vfields);
		      if (DECL_NAME (CLASSTYPE_VFIELD (value))
			  == DECL_NAME (CLASSTYPE_VFIELD (basetype)))
			VF_NORMAL_VALUE (b->vfields) = basetype;
		      else
			VF_NORMAL_VALUE (b->vfields) = VF_NORMAL_VALUE (vfields);
		    }
		  vfields = TREE_CHAIN (vfields);
		}
	      CLASSTYPE_VFIELD (t) = b->vfield;
	    }
	  else
	    {
	      /* Only add unique vfields, and flatten them out as we go.  */
	      tree vfields = CLASSTYPE_VFIELDS (basetype);
	      while (vfields)
		{
		  if (VF_BINFO_VALUE (vfields) == NULL_TREE
		      || ! TREE_VIA_VIRTUAL (VF_BINFO_VALUE (vfields)))
		    {
		      tree value = VF_BASETYPE_VALUE (vfields);
		      b->vfields = tree_cons (base_binfo, value, b->vfields);
		      if (DECL_NAME (CLASSTYPE_VFIELD (value))
			  == DECL_NAME (CLASSTYPE_VFIELD (basetype)))
			VF_NORMAL_VALUE (b->vfields) = basetype;
		      else
			VF_NORMAL_VALUE (b->vfields) = VF_NORMAL_VALUE (vfields);
		    }
		  vfields = TREE_CHAIN (vfields);
		}

	      if (b->has_virtual == 0)
		{
		  first_vfn_base_index = i;

		  /* Update these two, now that we know what vtable we are
		     going to extend.  This is so that we can add virtual
		     functions, and override them properly.  */
		  TYPE_BINFO_VTABLE (t) = TYPE_BINFO_VTABLE (basetype);
		  TYPE_BINFO_VIRTUALS (t) = TYPE_BINFO_VIRTUALS (basetype);
		  b->has_virtual = CLASSTYPE_VSIZE (basetype);
		  b->vfield = CLASSTYPE_VFIELD (basetype);
		  CLASSTYPE_VFIELD (t) = b->vfield;
		  /* When we install the first one, set the VF_NORMAL_VALUE
		     to be the current class, as this it is the most derived
		     class.  Hopefully, this is not set to something else
		     later.  (mrs) */
		  vfields = b->vfields;
		  while (vfields)
		    {
		      if (DECL_NAME (CLASSTYPE_VFIELD (t))
			  == DECL_NAME (CLASSTYPE_VFIELD (basetype)))
			{
			  VF_NORMAL_VALUE (vfields) = t;
			  /* There should only be one of them!  And it should
			     always be found, if we get into here.  (mrs)  */
			  break;
			}
		      vfields = TREE_CHAIN (vfields);
		    }
		}
	    }
	}
    }

  /* This comment said "Must come after offsets are fixed for all bases."
     Well, now this happens before the offsets are fixed, but it seems to
     work fine.  Guess we'll see...  */
  for (i = 0; i < n_baseclasses; i++)
    {
      tree base_binfo = TREE_VEC_ELT (binfos, i);
      tree basetype = BINFO_TYPE (base_binfo);

      if (get_base_distance (basetype, t, 0, (tree*)0) == -2)
	{
	  cp_warning ("direct base `%T' inaccessible in `%T' due to ambiguity",
		      basetype, t);
	}
    }
  {
    tree v = get_vbase_types (t);

    for (; v; v = TREE_CHAIN (v))
      {
	tree basetype = BINFO_TYPE (v);
	if (get_base_distance (basetype, t, 0, (tree*)0) == -2)
	  {
	    if (extra_warnings)
	      cp_warning ("virtual base `%T' inaccessible in `%T' due to ambiguity",
			  basetype, t);
	  }
      }
  }    

  {
    tree vfields;
    /* Find the base class with the largest number of virtual functions.  */
    for (vfields = b->vfields; vfields; vfields = TREE_CHAIN (vfields))
      {
	if (CLASSTYPE_VSIZE (VF_BASETYPE_VALUE (vfields)) > b->max_has_virtual)
	  b->max_has_virtual = CLASSTYPE_VSIZE (VF_BASETYPE_VALUE (vfields));
	if (VF_DERIVED_VALUE (vfields)
	    && CLASSTYPE_VSIZE (VF_DERIVED_VALUE (vfields)) > b->max_has_virtual)
	  b->max_has_virtual = CLASSTYPE_VSIZE (VF_DERIVED_VALUE (vfields));
      }
  }

  if (b->vfield == 0)
    /* If all virtual functions come only from virtual baseclasses.  */
    return -1;

  /* Update the rtti base if we have a non-virtual base class version
     of it.  */
  b->rtti = CLASSTYPE_RTTI (BINFO_TYPE (TREE_VEC_ELT (binfos, first_vfn_base_index)));

  return first_vfn_base_index;
}

/* Set memoizing fields and bits of T (and its variants) for later use.
   MAX_HAS_VIRTUAL is the largest size of any T's virtual function tables.  */

static void
finish_struct_bits (t, max_has_virtual)
     tree t;
     int max_has_virtual;
{
  int i, n_baseclasses = CLASSTYPE_N_BASECLASSES (t);

  /* Fix up variants (if any).  */
  tree variants = TYPE_NEXT_VARIANT (t);
  while (variants)
    {
      /* These fields are in the _TYPE part of the node, not in
	 the TYPE_LANG_SPECIFIC component, so they are not shared.  */
      TYPE_HAS_CONSTRUCTOR (variants) = TYPE_HAS_CONSTRUCTOR (t);
      TYPE_HAS_DESTRUCTOR (variants) = TYPE_HAS_DESTRUCTOR (t);
      TYPE_NEEDS_CONSTRUCTING (variants) = TYPE_NEEDS_CONSTRUCTING (t);
      TYPE_NEEDS_DESTRUCTOR (variants) = TYPE_NEEDS_DESTRUCTOR (t);

      TYPE_USES_COMPLEX_INHERITANCE (variants) = TYPE_USES_COMPLEX_INHERITANCE (t);
      TYPE_VIRTUAL_P (variants) = TYPE_VIRTUAL_P (t);
      TYPE_USES_VIRTUAL_BASECLASSES (variants) = TYPE_USES_VIRTUAL_BASECLASSES (t);
      /* Copy whatever these are holding today.  */
      TYPE_MIN_VALUE (variants) = TYPE_MIN_VALUE (t);
      TYPE_MAX_VALUE (variants) = TYPE_MAX_VALUE (t);
      TYPE_FIELDS (variants) = TYPE_FIELDS (t);
      TYPE_SIZE (variants) = TYPE_SIZE (t);
      variants = TYPE_NEXT_VARIANT (variants);
    }

  if (n_baseclasses && max_has_virtual)
    {
      /* Done by `finish_struct' for classes without baseclasses.  */
      int might_have_abstract_virtuals = CLASSTYPE_ABSTRACT_VIRTUALS (t) != 0;
      tree binfos = TYPE_BINFO_BASETYPES (t);
      for (i = n_baseclasses-1; i >= 0; i--)
	{
	  might_have_abstract_virtuals
	    |= (CLASSTYPE_ABSTRACT_VIRTUALS (BINFO_TYPE (TREE_VEC_ELT (binfos, i))) != 0);
	  if (might_have_abstract_virtuals)
	    break;
	}
      if (might_have_abstract_virtuals)
	{
	  /* We use error_mark_node from override_one_vtable to signal
	     an artificial abstract.  */
	  if (CLASSTYPE_ABSTRACT_VIRTUALS (t) == error_mark_node)
	    CLASSTYPE_ABSTRACT_VIRTUALS (t) = NULL_TREE;
	  CLASSTYPE_ABSTRACT_VIRTUALS (t) = get_abstract_virtuals (t);
	}
    }

  if (n_baseclasses)
    {
      /* Notice whether this class has type conversion functions defined.  */
      tree binfo = TYPE_BINFO (t);
      tree binfos = BINFO_BASETYPES (binfo);
      tree basetype;

      for (i = n_baseclasses-1; i >= 0; i--)
	{
	  basetype = BINFO_TYPE (TREE_VEC_ELT (binfos, i));

	  TYPE_HAS_CONVERSION (t) |= TYPE_HAS_CONVERSION (basetype);
	  if (CLASSTYPE_MAX_DEPTH (basetype) >= CLASSTYPE_MAX_DEPTH (t))
	    CLASSTYPE_MAX_DEPTH (t) = CLASSTYPE_MAX_DEPTH (basetype) + 1;
	}
    }

  /* If this type has a copy constructor, 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.

     Also do this if the class has BLKmode but can still be returned in
     registers, since function_cannot_inline_p won't let us inline
     functions returning such a type.  This affects the HP-PA.  */
  if (! TYPE_HAS_TRIVIAL_INIT_REF (t)
      || (TYPE_MODE (t) == BLKmode && ! aggregate_value_p (t)
	  && CLASSTYPE_NON_AGGREGATE (t)))
    {
      tree variants;
      DECL_MODE (TYPE_MAIN_DECL (t)) = BLKmode;
      for (variants = t; variants; variants = TYPE_NEXT_VARIANT (variants))
	{
	  TYPE_MODE (variants) = BLKmode;
	  TREE_ADDRESSABLE (variants) = 1;
	}
    }
}

/* Add FNDECL to the method_vec growing on the class_obstack.  Used by
   finish_struct_methods.  Note, FNDECL cannot be a constructor or
   destructor, those cases are handled by the caller.  */

static void
grow_method (fndecl, method_vec_ptr)
     tree fndecl;
     tree *method_vec_ptr;
{
  tree method_vec = (tree)obstack_base (&class_obstack);

  /* Start off past the constructors and destructor.  */
  tree *testp = &TREE_VEC_ELT (method_vec, 2);

  while (testp < (tree *) obstack_next_free (&class_obstack)
	 && (*testp == NULL_TREE || DECL_NAME (OVL_CURRENT (*testp)) != DECL_NAME (fndecl)))
    testp++;

  if (testp < (tree *) obstack_next_free (&class_obstack))
    *testp = build_overload (fndecl, *testp);
  else
    {
      obstack_ptr_grow (&class_obstack, fndecl);
      *method_vec_ptr = (tree)obstack_base (&class_obstack);
    }
}

/* Warn about duplicate methods in fn_fields.  Also compact method
   lists so that lookup can be made faster.

   Algorithm: Outer loop builds lists by method name.  Inner loop
   checks for redundant method names within a list.

   Data Structure: List of method lists.  The outer list is a
   TREE_LIST, whose TREE_PURPOSE field is the field name and the
   TREE_VALUE is the DECL_CHAIN of the FUNCTION_DECLs.  TREE_CHAIN
   links the entire list of methods for TYPE_METHODS.  Friends are
   chained in the same way as member functions (? TREE_CHAIN or
   DECL_CHAIN), but they live in the TREE_TYPE field of the outer
   list.  That allows them to be quickly deleted, and requires no
   extra storage.

   If there are any constructors/destructors, they are moved to the
   front of the list.  This makes pushclass more efficient.

   We also link each field which has shares a name with its baseclass
   to the head of the list of fields for that base class.  This allows
   us to reduce search time in places like `build_method_call' to
   consider only reasonably likely functions.  */

tree
finish_struct_methods (t, fn_fields, nonprivate_method)
     tree t;
     tree fn_fields;
     int nonprivate_method;
{
  tree method_vec;
  tree save_fn_fields = fn_fields;
  tree ctor_name = constructor_name (t);
  int i, n_baseclasses = CLASSTYPE_N_BASECLASSES (t);

  /* Now prepare to gather fn_fields into vector.  */
  struct obstack *ambient_obstack = current_obstack;
  current_obstack = &class_obstack;
  method_vec = make_tree_vec (2);
  current_obstack = ambient_obstack;

  /* Now make this a live vector.  */
  obstack_free (&class_obstack, method_vec);

  /* Save room for constructors and destructors.  */
  obstack_blank (&class_obstack, sizeof (struct tree_vec) + sizeof (struct tree *));

  /* First fill in entry 0 with the constructors, entry 1 with destructors,
     and the next few with type conversion operators (if any).  */

  for (; fn_fields; fn_fields = TREE_CHAIN (fn_fields))
    {
      tree fn_name = DECL_NAME (fn_fields);

      /* Clear out this flag.

	 @@ Doug may figure out how to break
	 @@ this with nested classes and friends.  */
      DECL_IN_AGGR_P (fn_fields) = 0;

      /* Note here that a copy ctor is private, so we don't dare generate
 	 a default copy constructor for a class that has a member
 	 of this type without making sure they have access to it.  */
      if (fn_name == ctor_name)
 	{
 	  tree parmtypes = FUNCTION_ARG_CHAIN (fn_fields);
 	  tree parmtype = parmtypes ? TREE_VALUE (parmtypes) : void_type_node;
	  
 	  if (TREE_CODE (parmtype) == REFERENCE_TYPE
 	      && TYPE_MAIN_VARIANT (TREE_TYPE (parmtype)) == t)
 	    {
 	      if (TREE_CHAIN (parmtypes) == NULL_TREE
 		  || TREE_CHAIN (parmtypes) == void_list_node
 		  || TREE_PURPOSE (TREE_CHAIN (parmtypes)))
 		{
 		  if (TREE_PROTECTED (fn_fields))
 		    TYPE_HAS_NONPUBLIC_CTOR (t) = 1;
 		  else if (TREE_PRIVATE (fn_fields))
 		    TYPE_HAS_NONPUBLIC_CTOR (t) = 2;
 		}
 	    }
	  if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (fn_fields)))
	    {	    
	      /* Destructors go in slot 1.  */
	      TREE_VEC_ELT (method_vec, 1) = 
		build_overload (fn_fields, TREE_VEC_ELT (method_vec, 1));
	    }
	  else
	    {
	      /* Constructors go in slot 0.  */
	      TREE_VEC_ELT (method_vec, 0) = 
		build_overload (fn_fields, TREE_VEC_ELT (method_vec, 0));
	    }
 	}
      else if (IDENTIFIER_TYPENAME_P (fn_name))
	grow_method (fn_fields, &method_vec);
    }

  fn_fields = save_fn_fields;
  for (; fn_fields; fn_fields = TREE_CHAIN (fn_fields))
    {
      tree fn_name = DECL_NAME (fn_fields);

      if (fn_name == ctor_name || IDENTIFIER_TYPENAME_P (fn_name))
	continue;

      if (fn_name == ansi_opname[(int) MODIFY_EXPR])
	{
	  tree parmtype = TREE_VALUE (FUNCTION_ARG_CHAIN (fn_fields));

	  if (copy_assignment_arg_p (parmtype, DECL_VIRTUAL_P (fn_fields)))
	    {
	      if (TREE_PROTECTED (fn_fields))
		TYPE_HAS_NONPUBLIC_ASSIGN_REF (t) = 1;
	      else if (TREE_PRIVATE (fn_fields))
		TYPE_HAS_NONPUBLIC_ASSIGN_REF (t) = 2;
	    }
	}

      grow_method (fn_fields, &method_vec);
    }

  TREE_VEC_LENGTH (method_vec) = (tree *)obstack_next_free (&class_obstack)
    - (&TREE_VEC_ELT (method_vec, 0));
  obstack_finish (&class_obstack);
  CLASSTYPE_METHOD_VEC (t) = method_vec;

  if (nonprivate_method == 0
      && CLASSTYPE_FRIEND_CLASSES (t) == NULL_TREE
      && DECL_FRIENDLIST (TYPE_MAIN_DECL (t)) == NULL_TREE)
    {
      tree binfos = BINFO_BASETYPES (TYPE_BINFO (t));
      for (i = 0; i < n_baseclasses; i++)
	if (TREE_VIA_PUBLIC (TREE_VEC_ELT (binfos, i))
	    || TREE_VIA_PROTECTED (TREE_VEC_ELT (binfos, i)))
	  {
	    nonprivate_method = 1;
	    break;
	  }
      if (nonprivate_method == 0 
	  && warn_ctor_dtor_privacy)
	cp_warning ("all member functions in class `%T' are private", t);
    }

  /* Warn if all destructors are private (in which case this class is
     effectively unusable.  */
  if (TYPE_HAS_DESTRUCTOR (t))
    {
      tree dtor = TREE_VEC_ELT (method_vec, 1);

      /* Wild parse errors can cause this to happen.  */
      if (dtor == NULL_TREE)
	TYPE_HAS_DESTRUCTOR (t) = 0;
      else if (TREE_PRIVATE (dtor)
	       && CLASSTYPE_FRIEND_CLASSES (t) == NULL_TREE
	       && DECL_FRIENDLIST (TYPE_MAIN_DECL (t)) == NULL_TREE
	       && warn_ctor_dtor_privacy)
	cp_warning ("`%#T' only defines a private destructor and has no friends",
		    t);
    }

  /* Now for each member function (except for constructors and
     destructors), compute where member functions of the same
     name reside in base classes.  */
  if (n_baseclasses != 0
      && TREE_VEC_LENGTH (method_vec) > 2)
    {
      int len = TREE_VEC_LENGTH (method_vec);
      tree baselink_vec = make_tree_vec (len);
      int any_links = 0;
      tree baselink_binfo = build_tree_list (NULL_TREE, TYPE_BINFO (t));

      for (i = 2; i < len; i++)
	{
	  TREE_VEC_ELT (baselink_vec, i)
	    = get_baselinks (baselink_binfo, t, 
			     DECL_NAME (OVL_CURRENT (TREE_VEC_ELT (method_vec, i))));
	  if (TREE_VEC_ELT (baselink_vec, i) != 0)
	    any_links = 1;
	}
      if (any_links != 0)
	CLASSTYPE_BASELINK_VEC (t) = baselink_vec;
      else
	obstack_free (current_obstack, baselink_vec);
    }

  return method_vec;
}

/* Emit error when a duplicate definition of a type is seen.  Patch up.  */

void
duplicate_tag_error (t)
     tree t;
{
  cp_error ("redefinition of `%#T'", t);
  cp_error_at ("previous definition here", t);

  /* Pretend we haven't defined this type.  */

  /* All of the component_decl's were TREE_CHAINed together in the parser.
     finish_struct_methods walks these chains and assembles all methods with
     the same base name into DECL_CHAINs. Now we don't need the parser chains
     anymore, so we unravel them.  */

  /* This used to be in finish_struct, but it turns out that the
     TREE_CHAIN is used by dbxout_type_methods and perhaps some other
     things...  */
  if (CLASSTYPE_METHOD_VEC (t)) 
    {
      tree method_vec = CLASSTYPE_METHOD_VEC (t);
      int i, len  = TREE_VEC_LENGTH (method_vec);
      for (i = 0; i < len; i++)
	{
	  tree unchain = TREE_VEC_ELT (method_vec, i);
	  while (unchain != NULL_TREE) 
	    {
	      TREE_CHAIN (OVL_CURRENT (unchain)) = NULL_TREE;
	      unchain = OVL_NEXT (unchain);
	    }
	}
    }

  if (TYPE_LANG_SPECIFIC (t))
    {
      tree as_list = CLASSTYPE_AS_LIST (t);
      tree binfo = TYPE_BINFO (t);
      tree binfo_as_list = CLASSTYPE_BINFO_AS_LIST (t);
      int interface_only = CLASSTYPE_INTERFACE_ONLY (t);
      int interface_unknown = CLASSTYPE_INTERFACE_UNKNOWN (t);

      bzero ((char *) TYPE_LANG_SPECIFIC (t), sizeof (struct lang_type));
      BINFO_BASETYPES(binfo) = NULL_TREE;

      CLASSTYPE_AS_LIST (t) = as_list;
      TYPE_BINFO (t) = binfo;
      CLASSTYPE_BINFO_AS_LIST (t) = binfo_as_list;
      CLASSTYPE_INTERFACE_ONLY (t) = interface_only;
      SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, interface_unknown);
      TYPE_REDEFINED (t) = 1;
    }
  TYPE_SIZE (t) = NULL_TREE;
  TYPE_MODE (t) = VOIDmode;
  TYPE_FIELDS (t) = NULL_TREE;
  TYPE_METHODS (t) = NULL_TREE;
  TYPE_VFIELD (t) = NULL_TREE;
  TYPE_CONTEXT (t) = NULL_TREE;
}

/* finish up all new vtables.  */

static void
finish_vtbls (binfo, do_self, t)
     tree binfo;
     int do_self;
     tree t;
{
  tree binfos = BINFO_BASETYPES (binfo);
  int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;

  /* Should we use something besides CLASSTYPE_VFIELDS? */
  if (do_self && CLASSTYPE_VFIELDS (BINFO_TYPE (binfo)))
    {
      if (BINFO_NEW_VTABLE_MARKED (binfo))
	{
	  tree decl, context;

	  decl = BINFO_VTABLE (binfo);
	  context = DECL_CONTEXT (decl);
	  DECL_CONTEXT (decl) = 0;
	  if (write_virtuals >= 0
	      && DECL_INITIAL (decl) != BINFO_VIRTUALS (binfo))
	    DECL_INITIAL (decl) = build_nt (CONSTRUCTOR, NULL_TREE,
					    BINFO_VIRTUALS (binfo));
	  cp_finish_decl (decl, DECL_INITIAL (decl), NULL_TREE, 0, 0);
	  DECL_CONTEXT (decl) = context;
	}
      CLEAR_BINFO_NEW_VTABLE_MARKED (binfo);
    }

  for (i = 0; i < n_baselinks; i++)
    {
      tree base_binfo = TREE_VEC_ELT (binfos, i);
      int is_not_base_vtable
	= i != CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo));
      if (TREE_VIA_VIRTUAL (base_binfo))
	{
	  base_binfo = binfo_member (BINFO_TYPE (base_binfo), CLASSTYPE_VBASECLASSES (t));
	}
      finish_vtbls (base_binfo, is_not_base_vtable, t);
    }
}

/* True if we should override the given BASE_FNDECL with the given
   FNDECL.  */

static int
overrides (fndecl, base_fndecl)
     tree fndecl, base_fndecl;
{
  /* Destructors have special names.  */
  if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (base_fndecl))
      && DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (fndecl)))
    return 1;
  if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (base_fndecl))
      || DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (fndecl)))
    return 0;
  if (DECL_NAME (fndecl) == DECL_NAME (base_fndecl))
    {
      tree types, base_types;
#if 0
      retypes = TREE_TYPE (TREE_TYPE (fndecl));
      base_retypes = TREE_TYPE (TREE_TYPE (base_fndecl));
#endif
      types = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
      base_types = TYPE_ARG_TYPES (TREE_TYPE (base_fndecl));
      if ((TYPE_READONLY (TREE_TYPE (TREE_VALUE (base_types)))
	   == TYPE_READONLY (TREE_TYPE (TREE_VALUE (types))))
	  && compparms (TREE_CHAIN (base_types), TREE_CHAIN (types), 3))
	return 1;
    }
  return 0;
}

static tree
get_class_offset_1 (parent, binfo, context, t, fndecl)
     tree parent, binfo, context, t, fndecl;
{
  tree binfos = BINFO_BASETYPES (binfo);
  int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
  tree rval = NULL_TREE;

  if (binfo == parent)
    return error_mark_node;

  for (i = 0; i < n_baselinks; i++)
    {
      tree base_binfo = TREE_VEC_ELT (binfos, i);
      tree nrval;

      if (TREE_VIA_VIRTUAL (base_binfo))
	base_binfo = binfo_member (BINFO_TYPE (base_binfo),
				   CLASSTYPE_VBASECLASSES (t));
      nrval = get_class_offset_1 (parent, base_binfo, context, t, fndecl);
      /* See if we have a new value */
      if (nrval && (nrval != error_mark_node || rval==0))
	{
	  /* Only compare if we have two offsets */
	  if (rval && rval != error_mark_node
	      && ! tree_int_cst_equal (nrval, rval))
	    {
	      /* Only give error if the two offsets are different */
	      error ("every virtual function must have a unique final overrider");
	      cp_error ("  found two (or more) `%T' class subobjects in `%T'", context, t);
	      cp_error ("  with virtual `%D' from virtual base class", fndecl);
	      return rval;
	    }
	  rval = nrval;
	}
	
      if (rval && BINFO_TYPE (binfo) == context)
	{
	  my_friendly_assert (rval == error_mark_node
			      || tree_int_cst_equal (rval, BINFO_OFFSET (binfo)), 999);
	  rval = BINFO_OFFSET (binfo);
	}
    }
  return rval;
}

/* Get the offset to the CONTEXT subobject that is related to the
   given BINFO.  */

static tree
get_class_offset (context, t, binfo, fndecl)
     tree context, t, binfo, fndecl;
{
  tree first_binfo = binfo;
  tree offset;
  int i;

  if (context == t)
    return integer_zero_node;

  if (BINFO_TYPE (binfo) == context)
    return BINFO_OFFSET (binfo);

  /* Check less derived binfos first.  */
  while (BINFO_BASETYPES (binfo)
	 && (i=CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo))) != -1)
    {
      tree binfos = BINFO_BASETYPES (binfo);
      binfo = TREE_VEC_ELT (binfos, i);
      if (BINFO_TYPE (binfo) == context)
	return BINFO_OFFSET (binfo);
    }

  /* Ok, not found in the less derived binfos, now check the more
     derived binfos.  */
  offset = get_class_offset_1 (first_binfo, TYPE_BINFO (t), context, t, fndecl);
  if (offset==0 || TREE_CODE (offset) != INTEGER_CST)
    my_friendly_abort (999);	/* we have to find it.  */
  return offset;
}

/* Skip RTTI information at the front of the virtual list.  */

unsigned HOST_WIDE_INT
skip_rtti_stuff (virtuals)
     tree *virtuals;
{
  int n;

  n = 0;
  if (*virtuals)
    {
      /* We always reserve a slot for the offset/tdesc entry.  */
      ++n;
      *virtuals = TREE_CHAIN (*virtuals);
    }
  if (flag_vtable_thunks && *virtuals)
    {
      /* The second slot is reserved for the tdesc pointer when thunks
         are used.  */
      ++n;
      *virtuals = TREE_CHAIN (*virtuals);
    }
  return n;
}

static void
modify_one_vtable (binfo, t, fndecl, pfn)
     tree binfo, t, fndecl, pfn;
{
  tree virtuals = BINFO_VIRTUALS (binfo);
  unsigned HOST_WIDE_INT n;
  
  /* update rtti entry */
  if (flag_rtti)
    {
      if (binfo == TYPE_BINFO (t))
	{
	  if (! BINFO_NEW_VTABLE_MARKED (binfo))
	    build_vtable (TYPE_BINFO (DECL_CONTEXT (CLASSTYPE_VFIELD (t))), t);
	}
      else
	{
	  if (! BINFO_NEW_VTABLE_MARKED (binfo))
	    prepare_fresh_vtable (binfo, t);
	}
    }
  if (fndecl == NULL_TREE)
    return;

  n = skip_rtti_stuff (&virtuals);

  while (virtuals)
    {
      tree current_fndecl = TREE_VALUE (virtuals);
      current_fndecl = FNADDR_FROM_VTABLE_ENTRY (current_fndecl);
      current_fndecl = TREE_OPERAND (current_fndecl, 0);
      if (current_fndecl && overrides (fndecl, current_fndecl))
	{
	  tree base_offset, offset;
	  tree context = DECL_CLASS_CONTEXT (fndecl);
	  tree vfield = CLASSTYPE_VFIELD (t);
	  tree this_offset;

	  offset = get_class_offset (context, t, binfo, fndecl);

	  /* Find the right offset for the this pointer based on the
	     base class we just found.  We have to take into
	     consideration the virtual base class pointers that we
	     stick in before the virtual function table pointer.

	     Also, we want just the delta between the most base class
	     that we derived this vfield from and us.  */
	  base_offset = size_binop (PLUS_EXPR,
				    get_derived_offset (binfo, DECL_CONTEXT (current_fndecl)),
				    BINFO_OFFSET (binfo));
	  this_offset = ssize_binop (MINUS_EXPR, offset, base_offset);

	  /* Make sure we can modify the derived association with immunity.  */
	  if (TREE_USED (binfo))
	    my_friendly_assert (0, 999);

	  if (binfo == TYPE_BINFO (t))
	    {
	      /* In this case, it is *type*'s vtable we are modifying.
		 We start with the approximation that it's vtable is that
		 of the immediate base class.  */
	      if (! BINFO_NEW_VTABLE_MARKED (binfo))
		build_vtable (TYPE_BINFO (DECL_CONTEXT (vfield)), 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.  */
	      if (! BINFO_NEW_VTABLE_MARKED (binfo))
		prepare_fresh_vtable (binfo, t);
	    }

#ifdef NOTQUITE
	  cp_warning ("in %D", DECL_NAME (BINFO_VTABLE (binfo)));
#endif
	  modify_vtable_entry (get_vtable_entry_n (BINFO_VIRTUALS (binfo), n),
			       build_vtable_entry (this_offset, pfn),
			       fndecl);
	}
      ++n;
      virtuals = TREE_CHAIN (virtuals);
    }
}

/* These are the ones that are not through virtual base classes.  */

static void
modify_all_direct_vtables (binfo, do_self, t, fndecl, pfn)
     tree binfo;
     int do_self;
     tree t, fndecl, pfn;
{
  tree binfos = BINFO_BASETYPES (binfo);
  int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;

  /* Should we use something besides CLASSTYPE_VFIELDS? */
  if (do_self && CLASSTYPE_VFIELDS (BINFO_TYPE (binfo)))
    {
      modify_one_vtable (binfo, t, fndecl, pfn);
    }

  for (i = 0; i < n_baselinks; i++)
    {
      tree base_binfo = TREE_VEC_ELT (binfos, i);
      int is_not_base_vtable
	= i != CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo));
      if (! TREE_VIA_VIRTUAL (base_binfo))
	modify_all_direct_vtables (base_binfo, is_not_base_vtable, t, fndecl, pfn);
    }
}

/* Fixup all the delta entries in this one vtable that need updating.  */

static void
fixup_vtable_deltas1 (binfo, t)
     tree binfo, t;
{
  tree virtuals = BINFO_VIRTUALS (binfo);
  unsigned HOST_WIDE_INT n;
  
  n = skip_rtti_stuff (&virtuals);

  while (virtuals)
    {
      tree fndecl = TREE_VALUE (virtuals);
      tree pfn = FNADDR_FROM_VTABLE_ENTRY (fndecl);
      tree delta = DELTA_FROM_VTABLE_ENTRY (fndecl);
      fndecl = TREE_OPERAND (pfn, 0);
      if (fndecl)
	{
	  tree base_offset, offset;
	  tree context = DECL_CLASS_CONTEXT (fndecl);
	  tree vfield = CLASSTYPE_VFIELD (t);
	  tree this_offset;

	  offset = get_class_offset (context, t, binfo, fndecl);

	  /* Find the right offset for the this pointer based on the
	     base class we just found.  We have to take into
	     consideration the virtual base class pointers that we
	     stick in before the virtual function table pointer.

	     Also, we want just the delta between the most base class
	     that we derived this vfield from and us.  */
	  base_offset = size_binop (PLUS_EXPR,
				    get_derived_offset (binfo,
							DECL_CONTEXT (fndecl)),
				    BINFO_OFFSET (binfo));
	  this_offset = ssize_binop (MINUS_EXPR, offset, base_offset);

	  if (! tree_int_cst_equal (this_offset, delta))
	    {
	      /* Make sure we can modify the derived association with immunity.  */
	      if (TREE_USED (binfo))
		my_friendly_assert (0, 999);

	      if (binfo == TYPE_BINFO (t))
		{
		  /* In this case, it is *type*'s vtable we are modifying.
		     We start with the approximation that it's vtable is that
		     of the immediate base class.  */
		  if (! BINFO_NEW_VTABLE_MARKED (binfo))
		    build_vtable (TYPE_BINFO (DECL_CONTEXT (vfield)), 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.  */
		  if (! BINFO_NEW_VTABLE_MARKED (binfo))
		    prepare_fresh_vtable (binfo, t);
		}

	      modify_vtable_entry (get_vtable_entry_n (BINFO_VIRTUALS (binfo), n),
				   build_vtable_entry (this_offset, pfn),
				   fndecl);
	    }
	}
      ++n;
      virtuals = TREE_CHAIN (virtuals);
    }
}

/* Fixup all the delta entries in all the direct vtables that need updating.
   This happens when we have non-overridden virtual functions from a
   virtual base class, that are at a different offset, in the new
   hierarchy, because the layout of the virtual bases has changed.  */

static void
fixup_vtable_deltas (binfo, init_self, t)
     tree binfo;
     int init_self;
     tree t;
{
  tree binfos = BINFO_BASETYPES (binfo);
  int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;

  for (i = 0; i < n_baselinks; i++)
    {
      tree base_binfo = TREE_VEC_ELT (binfos, i);
      int is_not_base_vtable
	= i != CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo));
      if (! TREE_VIA_VIRTUAL (base_binfo))
	fixup_vtable_deltas (base_binfo, is_not_base_vtable, t);
    }
  /* Should we use something besides CLASSTYPE_VFIELDS? */
  if (init_self && CLASSTYPE_VFIELDS (BINFO_TYPE (binfo)))
    {
      fixup_vtable_deltas1 (binfo, t);
    }
}

/* These are the ones that are through virtual base classes.  */

static void
modify_all_indirect_vtables (binfo, do_self, via_virtual, t, fndecl, pfn)
     tree binfo;
     int do_self, via_virtual;
     tree t, fndecl, pfn;
{
  tree binfos = BINFO_BASETYPES (binfo);
  int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;

  /* Should we use something besides CLASSTYPE_VFIELDS? */
  if (do_self && via_virtual && CLASSTYPE_VFIELDS (BINFO_TYPE (binfo)))
    {
      modify_one_vtable (binfo, t, fndecl, pfn);
    }

  for (i = 0; i < n_baselinks; i++)
    {
      tree base_binfo = TREE_VEC_ELT (binfos, i);
      int is_not_base_vtable
	= i != CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo));
      if (TREE_VIA_VIRTUAL (base_binfo))
	{
	  via_virtual = 1;
	  base_binfo = binfo_member (BINFO_TYPE (base_binfo), CLASSTYPE_VBASECLASSES (t));
	}
      modify_all_indirect_vtables (base_binfo, is_not_base_vtable, via_virtual, t, fndecl, pfn);
    }
}

static void
modify_all_vtables (t, fndecl, vfn)
     tree t, fndecl, vfn;
{
  /* Do these first, so that we will make use of any non-virtual class's
     vtable, over a virtual classes vtable.  */
  modify_all_direct_vtables (TYPE_BINFO (t), 1, t, fndecl, vfn);
  if (TYPE_USES_VIRTUAL_BASECLASSES (t))
    modify_all_indirect_vtables (TYPE_BINFO (t), 1, 0, t, fndecl, vfn);
}

/* Here, we already know that they match in every respect.
   All we have to check is where they had their declarations.  */

static int 
strictly_overrides (fndecl1, fndecl2)
     tree fndecl1, fndecl2;
{
  int distance = get_base_distance (DECL_CLASS_CONTEXT (fndecl2),
				    DECL_CLASS_CONTEXT (fndecl1),
				    0, (tree *)0);
  if (distance == -2 || distance > 0)
    return 1;
  return 0;
}

/* Merge overrides for one vtable.
   If we want to merge in same function, we are fine.
   else
     if one has a DECL_CLASS_CONTEXT that is a parent of the
       other, than choose the more derived one
     else
       potentially ill-formed (see 10.3 [class.virtual])
       we have to check later to see if there was an
       override in this class.  If there was ok, if not
       then it is ill-formed.  (mrs)

   We take special care to reuse a vtable, if we can.  */

static void
override_one_vtable (binfo, old, t)
     tree binfo, old, t;
{
  tree virtuals = BINFO_VIRTUALS (binfo);
  tree old_virtuals = BINFO_VIRTUALS (old);
  enum { REUSE_NEW, REUSE_OLD, UNDECIDED, NEITHER } choose = UNDECIDED;

  /* If we have already committed to modifying it, then don't try and
     reuse another vtable.  */
  if (BINFO_NEW_VTABLE_MARKED (binfo))
    choose = NEITHER;

  skip_rtti_stuff (&virtuals);
  skip_rtti_stuff (&old_virtuals);

  while (virtuals)
    {
      tree fndecl = TREE_VALUE (virtuals);
      tree old_fndecl = TREE_VALUE (old_virtuals);
      fndecl = FNADDR_FROM_VTABLE_ENTRY (fndecl);
      old_fndecl = FNADDR_FROM_VTABLE_ENTRY (old_fndecl);
      fndecl = TREE_OPERAND (fndecl, 0);
      old_fndecl = TREE_OPERAND (old_fndecl, 0);
      /* First check to see if they are the same.  */
      if (DECL_ASSEMBLER_NAME (fndecl) == DECL_ASSEMBLER_NAME (old_fndecl))
	{
	  /* No need to do anything.  */
	}
      else if (strictly_overrides (fndecl, old_fndecl))
	{
	  if (choose == UNDECIDED)
	    choose = REUSE_NEW;
	  else if (choose == REUSE_OLD)
	    {
	      choose = NEITHER;
	      if (! BINFO_NEW_VTABLE_MARKED (binfo))
		{
		  prepare_fresh_vtable (binfo, t);
		  override_one_vtable (binfo, old, t);
		  return;
		}
	    }
	}
      else if (strictly_overrides (old_fndecl, fndecl))
	{
	  if (choose == UNDECIDED)
	    choose = REUSE_OLD;
	  else if (choose == REUSE_NEW)
	    {
	      choose = NEITHER;
	      if (! BINFO_NEW_VTABLE_MARKED (binfo))
		{
		  prepare_fresh_vtable (binfo, t);
		  override_one_vtable (binfo, old, t);
		  return;
		}
	      TREE_VALUE (virtuals) = TREE_VALUE (old_virtuals);
	    }
	  else if (choose == NEITHER)
	    {
	      TREE_VALUE (virtuals) = TREE_VALUE (old_virtuals);
	    }  
	}
      else
	{
	  choose = NEITHER;
	  if (! BINFO_NEW_VTABLE_MARKED (binfo))
	    {
	      prepare_fresh_vtable (binfo, t);
	      override_one_vtable (binfo, old, t);
	      return;
	    }
	  {
	    /* This MUST be overridden, or the class is ill-formed.  */
	    /* For now, we just make it abstract.  */
	    tree fndecl = TREE_OPERAND (FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (virtuals)), 0);
	    tree vfn;

	    fndecl = copy_node (fndecl);
	    copy_lang_decl (fndecl);
	    DECL_ABSTRACT_VIRTUAL_P (fndecl) = 1;
	    DECL_NEEDS_FINAL_OVERRIDER_P (fndecl) = 1;
	    /* Make sure we search for it later.  */
	    if (! CLASSTYPE_ABSTRACT_VIRTUALS (t))
	      CLASSTYPE_ABSTRACT_VIRTUALS (t) = error_mark_node;

	    vfn = build1 (ADDR_EXPR, vfunc_ptr_type_node, fndecl);
	    TREE_CONSTANT (vfn) = 1;
	    
	    /* We can use integer_zero_node, as we will core dump
	       if this is used anyway.  */
	    TREE_VALUE (virtuals) = build_vtable_entry (integer_zero_node, vfn);
	  }
	}
      virtuals = TREE_CHAIN (virtuals);
      old_virtuals = TREE_CHAIN (old_virtuals);
    }

  /* Let's reuse the old vtable.  */
  if (choose == REUSE_OLD)
    {
      BINFO_VTABLE (binfo) = BINFO_VTABLE (old);
      BINFO_VIRTUALS (binfo) = BINFO_VIRTUALS (old);
    }
}

/* Merge in overrides for virtual bases.
   BINFO is the hierarchy we want to modify, and OLD has the potential
   overrides.  */

static void
merge_overrides (binfo, old, do_self, t)
     tree binfo, old;
     int do_self;
     tree t;
{
  tree binfos = BINFO_BASETYPES (binfo);
  tree old_binfos = BINFO_BASETYPES (old);
  int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;

  /* Should we use something besides CLASSTYPE_VFIELDS? */
  if (do_self && CLASSTYPE_VFIELDS (BINFO_TYPE (binfo)))
    {
      override_one_vtable (binfo, old, t);
    }

  for (i = 0; i < n_baselinks; i++)
    {
      tree base_binfo = TREE_VEC_ELT (binfos, i);
      tree old_base_binfo = TREE_VEC_ELT (old_binfos, i);
      int is_not_base_vtable
	= i != CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo));
      if (! TREE_VIA_VIRTUAL (base_binfo))
	merge_overrides (base_binfo, old_base_binfo, is_not_base_vtable, t);
    }
}

/* Get the base virtual function declarations in T that are either
   overridden or hidden by FNDECL as a list.  We set TREE_PURPOSE with
   the overrider/hider.  */

static tree
get_basefndecls (fndecl, t)
     tree fndecl, t;
{
  tree methods = TYPE_METHODS (t);
  tree base_fndecls = NULL_TREE;
  tree binfos = BINFO_BASETYPES (TYPE_BINFO (t));
  int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0;

  while (methods)
    {
      if (TREE_CODE (methods) == FUNCTION_DECL
	  && DECL_VINDEX (methods) != NULL_TREE
	  && DECL_NAME (fndecl) == DECL_NAME (methods))
	base_fndecls = temp_tree_cons (fndecl, methods, base_fndecls);

      methods = TREE_CHAIN (methods);
    }

  if (base_fndecls)
    return base_fndecls;

  for (i = 0; i < n_baseclasses; i++)
    {
      tree base_binfo = TREE_VEC_ELT (binfos, i);
      tree basetype = BINFO_TYPE (base_binfo);

      base_fndecls = chainon (get_basefndecls (fndecl, basetype),
			      base_fndecls);
    }

  return base_fndecls;
}

/* Mark the functions that have been hidden with their overriders.
   Since we start out with all functions already marked with a hider,
   no need to mark functions that are just hidden.  */

static void
mark_overriders (fndecl, base_fndecls)
     tree fndecl, base_fndecls;
{
  while (base_fndecls)
    {
      if (overrides (TREE_VALUE (base_fndecls), fndecl))
	TREE_PURPOSE (base_fndecls) = fndecl;

      base_fndecls = TREE_CHAIN (base_fndecls);
    }
}

/* If this declaration supersedes the declaration of
   a method declared virtual in the base class, then
   mark this field as being virtual as well.  */

static void
check_for_override (decl, ctype)
     tree decl, ctype;
{
  tree binfos = BINFO_BASETYPES (TYPE_BINFO (ctype));
  int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
  int virtualp = DECL_VIRTUAL_P (decl);

  for (i = 0; i < n_baselinks; i++)
    {
      tree base_binfo = TREE_VEC_ELT (binfos, i);
      if (TYPE_VIRTUAL_P (BINFO_TYPE (base_binfo))
	  || flag_all_virtual == 1)
	{
	  tree tmp = get_matching_virtual
	    (base_binfo, decl,
	     DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (decl)));
	  if (tmp)
	    {
	      /* If this function overrides some virtual in some base
		 class, then the function itself is also necessarily
		 virtual, even if the user didn't explicitly say so.  */
	      DECL_VIRTUAL_P (decl) = 1;

	      /* The TMP we really want is the one from the deepest
		 baseclass on this path, taking care not to
		 duplicate if we have already found it (via another
		 path to its virtual baseclass.  */
	      if (TREE_CODE (TREE_TYPE (decl)) == FUNCTION_TYPE)
		{
		  cp_error_at ("method `%D' may not be declared static",
			       decl);
		  cp_error_at ("(since `%D' declared virtual in base class.)",
			       tmp);
		  break;
		}
	      virtualp = 1;

#if 0 /* The signature of an overriding function is not changed.  */
	      {
		/* The argument types may have changed...  */
		tree type = TREE_TYPE (decl);
		tree argtypes = TYPE_ARG_TYPES (type);
		tree base_variant = TREE_TYPE (TREE_VALUE (argtypes));
		tree raises = TYPE_RAISES_EXCEPTIONS (type);

		argtypes = commonparms (TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (tmp))),
					TREE_CHAIN (argtypes));
		/* But the return type has not.  */
		type = build_cplus_method_type (base_variant, TREE_TYPE (type), argtypes);
		if (raises)
		  type = build_exception_variant (type, raises);
		TREE_TYPE (decl) = type;
	      }
#endif
	      DECL_VINDEX (decl)
		= tree_cons (NULL_TREE, tmp, DECL_VINDEX (decl));
	      break;
	    }
	}
    }
  if (virtualp)
    {
      if (DECL_VINDEX (decl) == NULL_TREE)
	DECL_VINDEX (decl) = error_mark_node;
      IDENTIFIER_VIRTUAL_P (DECL_NAME (decl)) = 1;
    }
}

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

void
warn_hidden (t)
     tree t;
{
  tree method_vec = CLASSTYPE_METHOD_VEC (t);
  int n_methods = method_vec ? TREE_VEC_LENGTH (method_vec) : 0;
  int i;

  /* We go through each separately named virtual function.  */
  for (i = 2; i < n_methods; ++i)
    {
      tree fns = TREE_VEC_ELT (method_vec, i);
      tree fndecl;

      tree base_fndecls = NULL_TREE;
      tree binfos = BINFO_BASETYPES (TYPE_BINFO (t));
      int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0;

      fndecl = OVL_CURRENT (fns);
      if (DECL_VINDEX (fndecl) == NULL_TREE)
	continue;

      /* First we get a list of all possible functions that might be
	 hidden from each base class.  */
      for (i = 0; i < n_baseclasses; i++)
	{
	  tree base_binfo = TREE_VEC_ELT (binfos, i);
	  tree basetype = BINFO_TYPE (base_binfo);

	  base_fndecls = chainon (get_basefndecls (fndecl, basetype),
				  base_fndecls);
	}

      fns = OVL_NEXT (fns);
      if (fns)
	fndecl = OVL_CURRENT (fns);
      else
	fndecl = NULL_TREE;

      /* ...then mark up all the base functions with overriders, preferring
	 overriders to hiders.  */
      if (base_fndecls)
	while (fndecl)
	  {
	    mark_overriders (fndecl, base_fndecls);
	    
	    fns = OVL_NEXT (fns);
	    if (fns)
	      fndecl = OVL_CURRENT (fns);
	    else
	      fndecl = NULL_TREE;
	  }

      /* Now give a warning for all base functions without overriders,
	 as they are hidden.  */
      while (base_fndecls)
	{
	  if (! overrides (TREE_VALUE (base_fndecls),
			   TREE_PURPOSE (base_fndecls)))
	    {
	      /* Here we know it is a hider, and no overrider exists.  */
	      cp_warning_at ("`%D' was hidden", TREE_VALUE (base_fndecls));
	      cp_warning_at ("  by `%D'", TREE_PURPOSE (base_fndecls));
	    }

	  base_fndecls = TREE_CHAIN (base_fndecls);
	}
    }
}

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

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

      if (DECL_NAME (field) == NULL_TREE
	  && TREE_CODE (TREE_TYPE (field)) == UNION_TYPE)
	{
	  tree* uelt = &TYPE_FIELDS (TREE_TYPE (field));
	  for (; *uelt; uelt = &TREE_CHAIN (*uelt))
	    {
	      if (TREE_CODE (*uelt) != FIELD_DECL)
		continue;

	      if (TREE_PRIVATE (*uelt))
		cp_pedwarn_at ("private member `%#D' in anonymous union",
			       *uelt);
	      else if (TREE_PROTECTED (*uelt))
		cp_pedwarn_at ("protected member `%#D' in anonymous union",
			       *uelt);

	      TREE_PRIVATE (*uelt) = TREE_PRIVATE (field);
	      TREE_PROTECTED (*uelt) = TREE_PROTECTED (field);
	    }
	}
    }
}

extern int interface_only, interface_unknown;

/* Create a RECORD_TYPE or UNION_TYPE node for a C struct or union declaration
   (or C++ class declaration).

   For C++, we must handle the building of derived classes.
   Also, C++ allows static class members.  The way that this is
   handled is to keep the field name where it is (as the DECL_NAME
   of the field), and place the overloaded decl in the DECL_FIELD_BITPOS
   of the field.  layout_record and layout_union will know about this.

   More C++ hair: inline functions have text in their
   DECL_PENDING_INLINE_INFO nodes which must somehow be parsed into
   meaningful tree structure.  After the struct has been laid out, set
   things up so that this can happen.

   And still more: virtual functions.  In the case of single inheritance,
   when a new virtual function is seen which redefines a virtual function
   from the base class, the new virtual function is placed into
   the virtual function table at exactly the same address that
   it had in the base class.  When this is extended to multiple
   inheritance, the same thing happens, except that multiple virtual
   function tables must be maintained.  The first virtual function
   table is treated in exactly the same way as in the case of single
   inheritance.  Additional virtual function tables have different
   DELTAs, which tell how to adjust `this' to point to the right thing.

   LIST_OF_FIELDLISTS is just that.  The elements of the list are
   TREE_LIST elements, whose TREE_PURPOSE field tells what access
   the list has, and the TREE_VALUE slot gives the actual fields.

   ATTRIBUTES is the set of decl attributes to be applied, if any.

   If flag_all_virtual == 1, then we lay all functions into
   the virtual function table, as though they were declared
   virtual.  Constructors do not lay down in the virtual function table.

   If flag_all_virtual == 2, then we lay all functions into
   the virtual function table, such that virtual functions
   occupy a space by themselves, and then all functions
   of the class occupy a space by themselves.  This is illustrated
   in the following diagram:

   class A; class B : A;

	Class A's vtbl:			Class B's vtbl:
    --------------------------------------------------------------------
   | A's virtual functions|		| B's virtual functions		|
   |			  |		| (may inherit some from A).	|
    --------------------------------------------------------------------
   | All of A's functions |		| All of A's functions		|
   | (such as a->A::f).	  |		| (such as b->A::f)		|
    --------------------------------------------------------------------
					| B's new virtual functions	|
					| (not defined in A.)		|
					 -------------------------------
					| All of B's functions		|
					| (such as b->B::f)		|
					 -------------------------------

   this allows the program to make references to any function, virtual
   or otherwise in a type-consistent manner.  */

tree
finish_struct_1 (t, warn_anon)
     tree t;
     int warn_anon;
{
  int old;
  tree name = TYPE_IDENTIFIER (t);
  enum tree_code code = TREE_CODE (t);
  tree fields = TYPE_FIELDS (t);
  tree fn_fields = TYPE_METHODS (t);
  tree x, last_x, method_vec;
  int all_virtual;
  int has_virtual;
  int max_has_virtual;
  tree pending_virtuals = NULL_TREE;
  tree pending_hard_virtuals = NULL_TREE;
  tree abstract_virtuals = NULL_TREE;
  tree vfield;
  tree vfields;
  int cant_have_default_ctor;
  int cant_have_const_ctor;
  int no_const_asn_ref;

  /* The index of the first base class which has virtual
     functions.  Only applied to non-virtual baseclasses.  */
  int first_vfn_base_index;

  int n_baseclasses;
  int any_default_members = 0;
  int const_sans_init = 0;
  int ref_sans_init = 0;
  int nonprivate_method = 0;
  tree access_decls = NULL_TREE;
  int aggregate = 1;
  int empty = 1;
  int has_pointers = 0;

  if (warn_anon && code != UNION_TYPE && ANON_AGGRNAME_P (TYPE_IDENTIFIER (t)))
    pedwarn ("anonymous class type not used to declare any objects");

  if (TYPE_SIZE (t))
    {
      if (IS_AGGR_TYPE (t))
	cp_error ("redefinition of `%#T'", t);
      else
	my_friendly_abort (172);
      popclass (0);
      return t;
    }

  GNU_xref_decl (current_function_decl, t);

  /* If this type was previously laid out as a forward reference,
     make sure we lay it out again.  */

  TYPE_SIZE (t) = NULL_TREE;
  CLASSTYPE_GOT_SEMICOLON (t) = 0;

#if 0
  /* This is in general too late to do this.  I moved the main case up to
     left_curly, what else needs to move?  */
  if (! IS_SIGNATURE (t))
    {
      my_friendly_assert (CLASSTYPE_INTERFACE_ONLY (t) == interface_only, 999);
      my_friendly_assert (CLASSTYPE_INTERFACE_KNOWN (t) == ! interface_unknown, 999);
    }
#endif

  old = suspend_momentary ();

  /* Install struct as DECL_FIELD_CONTEXT of each field decl.
     Also process specified field sizes.
     Set DECL_FIELD_SIZE to the specified size, or 0 if none specified.
     The specified size is found in the DECL_INITIAL.
     Store 0 there, except for ": 0" fields (so we can find them
     and delete them, below).  */

  if (TYPE_BINFO_BASETYPES (t))
    n_baseclasses = TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES (t));
  else
    n_baseclasses = 0;

  if (n_baseclasses > 0)
    {
      struct base_info base_info;

      first_vfn_base_index = finish_base_struct (t, &base_info);
      /* Remember where we got our vfield from.  */
      CLASSTYPE_VFIELD_PARENT (t) = first_vfn_base_index;
      has_virtual = base_info.has_virtual;
      max_has_virtual = base_info.max_has_virtual;
      CLASSTYPE_N_SUPERCLASSES (t) += base_info.n_ancestors;
      vfield = base_info.vfield;
      vfields = base_info.vfields;
      CLASSTYPE_RTTI (t) = base_info.rtti;
      cant_have_default_ctor = base_info.cant_have_default_ctor;
      cant_have_const_ctor = base_info.cant_have_const_ctor;
      no_const_asn_ref = base_info.no_const_asn_ref;
      aggregate = 0;
    }
  else
    {
      first_vfn_base_index = -1;
      has_virtual = 0;
      max_has_virtual = has_virtual;
      vfield = NULL_TREE;
      vfields = NULL_TREE;
      CLASSTYPE_RTTI (t) = NULL_TREE;
      cant_have_default_ctor = 0;
      cant_have_const_ctor = 0;
      no_const_asn_ref = 0;
    }

#if 0
  /* Both of these should be done before now.  */
  if (write_virtuals == 3 && CLASSTYPE_INTERFACE_KNOWN (t)
      && ! IS_SIGNATURE (t))
    {
      my_friendly_assert (CLASSTYPE_INTERFACE_ONLY (t) == interface_only, 999);
      my_friendly_assert (CLASSTYPE_VTABLE_NEEDS_WRITING (t) == ! interface_only, 999);
    }
#endif

  /* The three of these are approximations which may later be
     modified.  Needed at this point to make add_virtual_function
     and modify_vtable_entries work.  */
  CLASSTYPE_VFIELDS (t) = vfields;
  CLASSTYPE_VFIELD (t) = vfield;

  if (IS_SIGNATURE (t))
    all_virtual = 0;
  else if (flag_all_virtual == 1)
    all_virtual = 1;
  else
    all_virtual = 0;

  for (x = TYPE_METHODS (t); x; x = TREE_CHAIN (x))
    {
      GNU_xref_member (current_class_name, x);

      nonprivate_method |= ! TREE_PRIVATE (x);

      /* If this was an evil function, don't keep it in class.  */
      if (IDENTIFIER_ERROR_LOCUS (DECL_ASSEMBLER_NAME (x)))
	continue;

      DECL_CLASS_CONTEXT (x) = t;

      /* Do both of these, even though they're in the same union;
	 if the insn `r' member and the size `i' member are
	 different sizes, as on the alpha, the larger of the two
	 will end up with garbage in it.  */
      DECL_SAVED_INSNS (x) = NULL_RTX;
      DECL_FIELD_SIZE (x) = 0;

      check_for_override (x, t);
      if (DECL_ABSTRACT_VIRTUAL_P (x) && ! DECL_VINDEX (x))
	cp_error_at ("initializer specified for non-virtual method `%D'", x);

      /* The name of the field is the original field name
	 Save this in auxiliary field for later overloading.  */
      if (DECL_VINDEX (x)
	  || (all_virtual == 1 && ! DECL_CONSTRUCTOR_P (x)))
	{
	  add_virtual_function (&pending_virtuals, &pending_hard_virtuals,
				&has_virtual, x, t);
	  if (DECL_ABSTRACT_VIRTUAL_P (x))
	    abstract_virtuals = tree_cons (NULL_TREE, x, abstract_virtuals);
#if 0
	  /* XXX Why did I comment this out?  (jason) */
	  else
	    TREE_USED (x) = 1;
#endif
	}
    }

  if (n_baseclasses)
    fields = chainon (build_vbase_pointer_fields (t), fields);

  last_x = NULL_TREE;
  for (x = fields; x; x = TREE_CHAIN (x))
    {
      GNU_xref_member (current_class_name, x);

      if (TREE_CODE (x) == FIELD_DECL)
	{
	  DECL_PACKED (x) |= TYPE_PACKED (t);
	  empty = 0;
	}

      if (TREE_CODE (x) == USING_DECL)
	{
	  /* Save access declarations for later.  */
	  if (last_x)
	    TREE_CHAIN (last_x) = TREE_CHAIN (x);
	  else
	    fields = TREE_CHAIN (x);
	  
	  access_decls = scratch_tree_cons (NULL_TREE, x, access_decls);
	  continue;
	}

      last_x = x;

      if (TREE_CODE (x) == TYPE_DECL
	  || TREE_CODE (x) == TEMPLATE_DECL)
	continue;

      /* If we've gotten this far, it's a data member, possibly static,
	 or an enumerator.  */

      DECL_FIELD_CONTEXT (x) = t;

      /* ``A local class cannot have static data members.'' ARM 9.4 */
      if (current_function_decl && TREE_STATIC (x))
	cp_error_at ("field `%D' in local class cannot be static", x);

      /* Perform error checking that did not get done in
	 grokdeclarator.  */
      if (TREE_CODE (TREE_TYPE (x)) == FUNCTION_TYPE)
	{
	  cp_error_at ("field `%D' invalidly declared function type",
		       x);
	  TREE_TYPE (x) = build_pointer_type (TREE_TYPE (x));
	}
      else if (TREE_CODE (TREE_TYPE (x)) == METHOD_TYPE)
	{
	  cp_error_at ("field `%D' invalidly declared method type", x);
	  TREE_TYPE (x) = build_pointer_type (TREE_TYPE (x));
	}
      else if (TREE_CODE (TREE_TYPE (x)) == OFFSET_TYPE)
	{
	  cp_error_at ("field `%D' invalidly declared offset type", x);
	  TREE_TYPE (x) = build_pointer_type (TREE_TYPE (x));
	}

#if 0
      if (DECL_NAME (x) == constructor_name (t))
	cant_have_default_ctor = 1;
#endif

      if (TREE_TYPE (x) == error_mark_node)
	continue;
	  
      DECL_SAVED_INSNS (x) = NULL_RTX;
      DECL_FIELD_SIZE (x) = 0;

      /* When this goes into scope, it will be a non-local reference.  */
      DECL_NONLOCAL (x) = 1;

      if (TREE_CODE (x) == CONST_DECL)
	continue;

      if (TREE_CODE (x) == VAR_DECL)
	{
	  if (TREE_CODE (t) == UNION_TYPE)
	    /* Unions cannot have static members.  */
	    cp_error_at ("field `%D' declared static in union", x);
	      
	  continue;
	}

      /* Now it can only be a FIELD_DECL.  */

      if (TREE_PRIVATE (x) || TREE_PROTECTED (x))
	aggregate = 0;

      /* If this is of reference type, check if it needs an init.
	 Also do a little ANSI jig if necessary.  */
      if (TREE_CODE (TREE_TYPE (x)) == REFERENCE_TYPE)
 	{
	  if (DECL_INITIAL (x) == NULL_TREE)
	    ref_sans_init = 1;

	  /* ARM $12.6.2: [A member initializer list] (or, for an
	     aggregate, initialization by a brace-enclosed list) is the
	     only way to initialize nonstatic const and reference
	     members.  */
	  cant_have_default_ctor = 1;
	  TYPE_HAS_COMPLEX_ASSIGN_REF (t) = 1;

	  if (! TYPE_HAS_CONSTRUCTOR (t) && extra_warnings)
	    {
	      if (DECL_NAME (x))
		cp_warning_at ("non-static reference `%#D' in class without a constructor", x);
	      else
		cp_warning_at ("non-static reference in class without a constructor", x);
	    }
	}

      if (TREE_CODE (TREE_TYPE (x)) == POINTER_TYPE)
	has_pointers = 1;

      /* If any field is const, the structure type is pseudo-const.  */
      if (TREE_READONLY (x))
	{
	  C_TYPE_FIELDS_READONLY (t) = 1;
	  if (DECL_INITIAL (x) == NULL_TREE)
	    const_sans_init = 1;

	  /* ARM $12.6.2: [A member initializer list] (or, for an
	     aggregate, initialization by a brace-enclosed list) is the
	     only way to initialize nonstatic const and reference
	     members.  */
	  cant_have_default_ctor = 1;
	  TYPE_HAS_COMPLEX_ASSIGN_REF (t) = 1;

	  if (! TYPE_HAS_CONSTRUCTOR (t) && !IS_SIGNATURE (t)
	      && extra_warnings)
	    {
	      if (DECL_NAME (x))
		cp_warning_at ("non-static const member `%#D' in class without a constructor", x);
	      else
		cp_warning_at ("non-static const member in class without a constructor", x);
	    }
	}
      else
	{
	  /* A field that is pseudo-const makes the structure
	     likewise.  */
	  tree t1 = TREE_TYPE (x);
	  while (TREE_CODE (t1) == ARRAY_TYPE)
	    t1 = TREE_TYPE (t1);
	  if (IS_AGGR_TYPE (t1))
	    {
	      if (C_TYPE_FIELDS_READONLY (t1))
		C_TYPE_FIELDS_READONLY (t) = 1;
	      if (CLASSTYPE_READONLY_FIELDS_NEED_INIT (t1))
		const_sans_init = 1;
	    }
	}

      /* We set DECL_BIT_FIELD tentatively in grokbitfield.
	 If the type and width are valid, we'll keep it set.
	 Otherwise, the flag is cleared.  */
      if (DECL_BIT_FIELD (x))
	{
	  DECL_BIT_FIELD (x) = 0;
	  /* Invalid bit-field size done by grokfield.  */
	  /* Detect invalid bit-field type.  */
	  if (DECL_INITIAL (x)
	      && ! INTEGRAL_TYPE_P (TREE_TYPE (x)))
	    {
	      cp_error_at ("bit-field `%#D' with non-integral type", x);
	      DECL_INITIAL (x) = NULL;
	    }

	  /* Detect and ignore out of range field width.  */
	  if (DECL_INITIAL (x))
	    {
	      tree w = DECL_INITIAL (x);
	      register int width = 0;

	      /* Avoid the non_lvalue wrapper added by fold for PLUS_EXPRs.  */
	      STRIP_NOPS (w);

	      /* detect invalid field size.  */
	      if (TREE_CODE (w) == CONST_DECL)
		w = DECL_INITIAL (w);
	      else if (TREE_READONLY_DECL_P (w))
		w = decl_constant_value (w);

	      if (TREE_CODE (w) != INTEGER_CST)
		{
		  cp_error_at ("bit-field `%D' width not an integer constant",
			       x);
		  DECL_INITIAL (x) = NULL_TREE;
		}
	      else if (width = TREE_INT_CST_LOW (w),
		       width < 0)
		{
		  DECL_INITIAL (x) = NULL;
		  cp_error_at ("negative width in bit-field `%D'", x);
		}
	      else if (width == 0 && DECL_NAME (x) != 0)
		{
		  DECL_INITIAL (x) = NULL;
		  cp_error_at ("zero width for bit-field `%D'", x);
		}
	      else if (width
		       > TYPE_PRECISION (long_long_unsigned_type_node))
		{
		  /* The backend will dump if you try to use something
		     too big; avoid that.  */
		  DECL_INITIAL (x) = NULL;
		  sorry ("bit-fields larger than %d bits",
			 TYPE_PRECISION (long_long_unsigned_type_node));
		  cp_error_at ("  in declaration of `%D'", x);
		}
	      else if (width > TYPE_PRECISION (TREE_TYPE (x))
		       && TREE_CODE (TREE_TYPE (x)) != ENUMERAL_TYPE
		       && TREE_CODE (TREE_TYPE (x)) != BOOLEAN_TYPE)
		{
		  cp_warning_at ("width of `%D' exceeds its type", x);
		}
	      else if (TREE_CODE (TREE_TYPE (x)) == ENUMERAL_TYPE
		       && ((min_precision (TYPE_MIN_VALUE (TREE_TYPE (x)),
					   TREE_UNSIGNED (TREE_TYPE (x))) > width)
			   || (min_precision (TYPE_MAX_VALUE (TREE_TYPE (x)),
					      TREE_UNSIGNED (TREE_TYPE (x))) > width)))
		{
		  cp_warning_at ("`%D' is too small to hold all values of `%#T'",
				 x, TREE_TYPE (x));
		}

	      if (DECL_INITIAL (x) == NULL_TREE)
		;
	      else if (width == 0)
		{
#ifdef EMPTY_FIELD_BOUNDARY
		  DECL_ALIGN (x) = MAX (DECL_ALIGN (x), EMPTY_FIELD_BOUNDARY);
#endif
#ifdef PCC_BITFIELD_TYPE_MATTERS
		  DECL_ALIGN (x) = MAX (DECL_ALIGN (x),
					TYPE_ALIGN (TREE_TYPE (x)));
#endif
		}
	      else
		{
		  DECL_INITIAL (x) = NULL_TREE;
		  DECL_FIELD_SIZE (x) = width;
		  DECL_BIT_FIELD (x) = 1;
		}
	    }
	  else
	    /* Non-bit-fields are aligned for their type.  */
	    DECL_ALIGN (x) = MAX (DECL_ALIGN (x), TYPE_ALIGN (TREE_TYPE (x)));
	}
      else
	{
	  tree type = TREE_TYPE (x);

	  while (TREE_CODE (type) == ARRAY_TYPE)
	    type = TREE_TYPE (type);

	  if (TYPE_LANG_SPECIFIC (type) && ! ANON_UNION_P (x)
	      && ! TYPE_PTRMEMFUNC_P (type))
	    {
	      /* Never let anything with uninheritable virtuals
		 make it through without complaint.  */
	      if (CLASSTYPE_ABSTRACT_VIRTUALS (type))
		abstract_virtuals_error (x, type);
		      
	      /* Don't let signatures make it through either.  */
	      if (IS_SIGNATURE (type))
		signature_error (x, type);
		      
	      if (code == UNION_TYPE)
		{
		  char *fie = NULL;
		  if (TYPE_NEEDS_CONSTRUCTING (type))
		    fie = "constructor";
		  else if (TYPE_NEEDS_DESTRUCTOR (type))
		    fie = "destructor";
		  else if (TYPE_HAS_REAL_ASSIGNMENT (type))
		    fie = "assignment operator";
		  if (fie)
		    cp_error_at ("member `%#D' with %s not allowed in union", x,
				 fie);
		}
	      else
		{
		  TYPE_NEEDS_CONSTRUCTING (t) |= TYPE_NEEDS_CONSTRUCTING (type);
		  TYPE_NEEDS_DESTRUCTOR (t) |= TYPE_NEEDS_DESTRUCTOR (type);
		  TYPE_HAS_COMPLEX_ASSIGN_REF (t) |= TYPE_HAS_COMPLEX_ASSIGN_REF (type);
		  TYPE_HAS_COMPLEX_INIT_REF (t) |= TYPE_HAS_COMPLEX_INIT_REF (type);
		}

	      if (!TYPE_HAS_CONST_INIT_REF (type))
		cant_have_const_ctor = 1;

	      if (!TYPE_HAS_CONST_ASSIGN_REF (type))
		no_const_asn_ref = 1;

	      if (TYPE_HAS_CONSTRUCTOR (type)
		  && ! TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
		{
		  cant_have_default_ctor = 1;
#if 0
		  /* This is wrong for aggregates.  */
		  if (! TYPE_HAS_CONSTRUCTOR (t))
		    {
		      if (DECL_NAME (x))
			cp_pedwarn_at ("member `%#D' with only non-default constructor", x);
		      else
			cp_pedwarn_at ("member with only non-default constructor", x);
		      cp_pedwarn_at ("in class without a constructor",
				     x);
		    }
#endif
		}
	    }
	  if (DECL_INITIAL (x) != NULL_TREE)
	    {
	      /* `build_class_init_list' does not recognize
		 non-FIELD_DECLs.  */
	      if (code == UNION_TYPE && any_default_members != 0)
		cp_error_at ("multiple fields in union `%T' initialized");
	      any_default_members = 1;
	    }
	}
    }

  /* If this type has any constant members which did not come
     with their own initialization, mark that fact here.  It is
     not an error here, since such types can be saved either by their
     constructors, or by fortuitous initialization.  */
  CLASSTYPE_READONLY_FIELDS_NEED_INIT (t) = const_sans_init;
  CLASSTYPE_REF_FIELDS_NEED_INIT (t) = ref_sans_init;
  CLASSTYPE_ABSTRACT_VIRTUALS (t) = abstract_virtuals;

  /* Synthesize any needed methods.  Note that methods will be synthesized
     for anonymous unions; grok_x_components undoes that.  */

  if (! fn_fields)
    nonprivate_method = 1;

  if (TYPE_NEEDS_DESTRUCTOR (t) && !TYPE_HAS_DESTRUCTOR (t)
      && !IS_SIGNATURE (t))
    {
      /* Here we must cons up a destructor on the fly.  */
      tree dtor = cons_up_default_function (t, name, 0);
      check_for_override (dtor, t);

      /* If we couldn't make it work, then pretend we didn't need it.  */
      if (dtor == void_type_node)
	TYPE_NEEDS_DESTRUCTOR (t) = 0;
      else
	{
	  /* Link dtor onto end of fn_fields.  */

	  TREE_CHAIN (dtor) = fn_fields;
	  fn_fields = dtor;

	  if (DECL_VINDEX (dtor))
	    add_virtual_function (&pending_virtuals, &pending_hard_virtuals,
				  &has_virtual, dtor, t);
	  nonprivate_method = 1;
	}
    }

  /* Effective C++ rule 11.  */
  if (has_pointers && warn_ecpp && TYPE_HAS_CONSTRUCTOR (t)
      && ! (TYPE_HAS_INIT_REF (t) && TYPE_HAS_ASSIGN_REF (t)))
    {
      cp_warning ("`%#T' has pointer data members", t);
      
      if (! TYPE_HAS_INIT_REF (t))
	{
	  cp_warning ("  but does not override `%T(const %T&)'", t, t);
	  if (! TYPE_HAS_ASSIGN_REF (t))
	    cp_warning ("  or `operator=(const %T&)'", t);
	}
      else if (! TYPE_HAS_ASSIGN_REF (t))
	cp_warning ("  but does not override `operator=(const %T&)'", t);
    }

  TYPE_NEEDS_DESTRUCTOR (t) |= TYPE_HAS_DESTRUCTOR (t);

  TYPE_HAS_COMPLEX_INIT_REF (t)
    |= (TYPE_HAS_INIT_REF (t) || TYPE_USES_VIRTUAL_BASECLASSES (t)
	|| has_virtual || any_default_members);
  TYPE_NEEDS_CONSTRUCTING (t)
    |= (TYPE_HAS_CONSTRUCTOR (t) || TYPE_USES_VIRTUAL_BASECLASSES (t)
	|| has_virtual || any_default_members);
  if (! IS_SIGNATURE (t))
    CLASSTYPE_NON_AGGREGATE (t)
      = ! aggregate || has_virtual || TYPE_HAS_CONSTRUCTOR (t);

  /* ARM $12.1: A default constructor will be generated for a class X
     only if no constructor has been declared for class X.  So we
     check TYPE_HAS_CONSTRUCTOR also, to make sure we don't generate
     one if they declared a constructor in this class.  */
  if (! TYPE_HAS_CONSTRUCTOR (t) && ! cant_have_default_ctor
      && ! IS_SIGNATURE (t))
    {
      tree default_fn = cons_up_default_function (t, name, 2);
      TREE_CHAIN (default_fn) = fn_fields;
      fn_fields = default_fn;
    }

  /* Create default copy constructor, if needed.  */
  if (! TYPE_HAS_INIT_REF (t) && ! IS_SIGNATURE (t) && ! TYPE_FOR_JAVA (t))
    {
      /* ARM 12.18: You get either X(X&) or X(const X&), but
	 not both.  --Chip  */
      tree default_fn = cons_up_default_function (t, name,
						  3 + cant_have_const_ctor);
      TREE_CHAIN (default_fn) = fn_fields;
      fn_fields = default_fn;
    }

  TYPE_HAS_REAL_ASSIGNMENT (t) |= TYPE_HAS_ASSIGNMENT (t);
  TYPE_HAS_REAL_ASSIGN_REF (t) |= TYPE_HAS_ASSIGN_REF (t);
  TYPE_HAS_COMPLEX_ASSIGN_REF (t)
    |= TYPE_HAS_ASSIGN_REF (t) || TYPE_USES_VIRTUAL_BASECLASSES (t);

  if (! TYPE_HAS_ASSIGN_REF (t) && ! IS_SIGNATURE (t) && ! TYPE_FOR_JAVA (t))
    {
      tree default_fn = cons_up_default_function (t, name,
						  5 + no_const_asn_ref);
      TREE_CHAIN (default_fn) = fn_fields;
      fn_fields = default_fn;
    }

  if (fn_fields)
    {
      TYPE_METHODS (t) = fn_fields;
      method_vec = finish_struct_methods (t, fn_fields, nonprivate_method);

      if (TYPE_HAS_CONSTRUCTOR (t)
	  && CLASSTYPE_FRIEND_CLASSES (t) == NULL_TREE
	  && DECL_FRIENDLIST (TYPE_MAIN_DECL (t)) == NULL_TREE)
	{
	  int nonprivate_ctor = 0;
	  tree ctor;

	  for (ctor = TREE_VEC_ELT (method_vec, 0);
	       ctor;
	       ctor = OVL_NEXT (ctor))
	    if (! TREE_PRIVATE (OVL_CURRENT (ctor)))
	      {
		nonprivate_ctor = 1;
		break;
	      }

	  if (nonprivate_ctor == 0 && warn_ctor_dtor_privacy)
	    cp_warning ("`%#T' only defines private constructors and has no friends",
			t);
	}
    }
  else
    {
      method_vec = 0;

      /* Just in case these got accidentally
	 filled in by syntax errors.  */
      TYPE_HAS_CONSTRUCTOR (t) = 0;
      TYPE_HAS_DESTRUCTOR (t) = 0;
    }

  for (access_decls = nreverse (access_decls); access_decls;
       access_decls = TREE_CHAIN (access_decls))
    handle_using_decl (TREE_VALUE (access_decls), t, method_vec, fields); 

  if (vfield == NULL_TREE && has_virtual)
    {
      /* We build this decl with ptr_type_node, and
	 change the type when we know what it should be.  */
      vfield = build_lang_field_decl (FIELD_DECL, get_vfield_name (t),
				      ptr_type_node);
      /* If you change any of the below, take a look at all the
	 other VFIELD_BASEs and VTABLE_BASEs in the code, and change
	 them too.  */
      DECL_ASSEMBLER_NAME (vfield) = get_identifier (VFIELD_BASE);
      CLASSTYPE_VFIELD (t) = vfield;
      DECL_VIRTUAL_P (vfield) = 1;
      DECL_ARTIFICIAL (vfield) = 1;
      DECL_FIELD_CONTEXT (vfield) = t;
      DECL_CLASS_CONTEXT (vfield) = t;
      DECL_FCONTEXT (vfield) = t;
      DECL_SAVED_INSNS (vfield) = NULL_RTX;
      DECL_FIELD_SIZE (vfield) = 0;
      DECL_ALIGN (vfield) = TYPE_ALIGN (ptr_type_node);
#if 0
      /* This is more efficient, but breaks binary compatibility, turn
	 it on sometime when we don't care.  If we turn it on, we also
	 have to enable the code in dfs_init_vbase_pointers.  */
      /* vfield is always first entry in structure.  */
      TREE_CHAIN (vfield) = fields;
      fields = vfield;
#else
      if (last_x)
	{
	  my_friendly_assert (TREE_CHAIN (last_x) == NULL_TREE, 175);
	  TREE_CHAIN (last_x) = vfield;
	  last_x = vfield;
	}
      else
	fields = vfield;
#endif
      empty = 0;
      vfields = chainon (vfields, CLASSTYPE_AS_LIST (t));
    }

  /* Now DECL_INITIAL is null on all members except for zero-width bit-fields.
     And they have already done their work.

     C++: maybe we will support default field initialization some day...  */

  /* Delete all zero-width bit-fields from the front of the fieldlist */
  while (fields && DECL_BIT_FIELD (fields)
	 && DECL_INITIAL (fields))
    fields = TREE_CHAIN (fields);
  /* Delete all such fields from the rest of the fields.  */
  for (x = fields; x;)
    {
      if (TREE_CHAIN (x) && DECL_BIT_FIELD (TREE_CHAIN (x))
	  && DECL_INITIAL (TREE_CHAIN (x)))
	TREE_CHAIN (x) = TREE_CHAIN (TREE_CHAIN (x));
      else
	x = TREE_CHAIN (x);
    }
  /* Delete all duplicate fields from the fields */
  delete_duplicate_fields (fields);

  /* Catch function/field name conflict.  We don't need to do this for a
     signature, since it can only contain the fields constructed in
     append_signature_fields.  */
  if (! IS_SIGNATURE (t))
    {
      int n_methods = method_vec ? TREE_VEC_LENGTH (method_vec) : 0;
      for (x = fields; x; x = TREE_CHAIN (x))
	{
	  tree name = DECL_NAME (x);
	  int i = 2;

	  if (TREE_CODE (x) == TYPE_DECL && DECL_ARTIFICIAL (x))
	    continue;

	  for (; i < n_methods; ++i)
	    if (DECL_NAME (OVL_CURRENT (TREE_VEC_ELT (method_vec, i)))
		== name)
	      {
		cp_error_at ("data member `%#D' conflicts with", x);
		cp_error_at ("function member `%#D'",
			     OVL_CURRENT (TREE_VEC_ELT (method_vec, i)));
		break;
	      }
	}
    }

  /* Now we have the final fieldlist for the data fields.  Record it,
     then lay out the structure or union (including the fields).  */

  TYPE_FIELDS (t) = fields;

  if (n_baseclasses)
    {
      last_x = build_base_fields (t);

      /* If all our bases are empty, we can be empty too.  */
      for (x = last_x; empty && x; x = TREE_CHAIN (x))
	if (DECL_SIZE (x) != integer_zero_node)
	  empty = 0;
    }
  if (empty)
    {
      /* C++: do not let empty structures exist.  */
      tree decl = build_lang_field_decl
	(FIELD_DECL, NULL_TREE, char_type_node);
      TREE_CHAIN (decl) = fields;
      TYPE_FIELDS (t) = decl;
    }
  if (n_baseclasses)
    TYPE_FIELDS (t) = chainon (last_x, TYPE_FIELDS (t));

  layout_type (t);

  /* Remember the size and alignment of the class before adding
     the virtual bases.  */
  if (empty && flag_new_abi)
    CLASSTYPE_SIZE (t) = integer_zero_node;
  else if (flag_new_abi && TYPE_HAS_COMPLEX_INIT_REF (t)
	   && TYPE_HAS_COMPLEX_ASSIGN_REF (t))
    CLASSTYPE_SIZE (t) = TYPE_BINFO_SIZE (t);
  else
    CLASSTYPE_SIZE (t) = TYPE_SIZE (t);
  CLASSTYPE_ALIGN (t) = TYPE_ALIGN (t);

  finish_struct_anon (t);

  /* 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.  */
  pending_hard_virtuals = nreverse (pending_hard_virtuals);

  if (n_baseclasses)
    /* layout_basetypes will remove the base subobject fields.  */
    max_has_virtual = layout_basetypes (t, max_has_virtual);
  else if (empty)
    TYPE_FIELDS (t) = fields;

  if (TYPE_USES_VIRTUAL_BASECLASSES (t))
    {
      tree vbases;

      vbases = CLASSTYPE_VBASECLASSES (t);
      CLASSTYPE_N_VBASECLASSES (t) = list_length (vbases);

      {
	/* Now fixup overrides of all functions in vtables from all
	   direct or indirect virtual base classes.  */
	tree binfos = BINFO_BASETYPES (TYPE_BINFO (t));
	int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0;

	for (i = 0; i < n_baseclasses; i++)
	  {
	    tree base_binfo = TREE_VEC_ELT (binfos, i);
	    tree basetype = BINFO_TYPE (base_binfo);
	    tree vbases;

	    vbases = CLASSTYPE_VBASECLASSES (basetype);
	    while (vbases)
	      {
		merge_overrides (binfo_member (BINFO_TYPE (vbases),
					       CLASSTYPE_VBASECLASSES (t)),
				 vbases, 1, t);
		vbases = TREE_CHAIN (vbases);
	      }
	  }
	}
    }

  /* Set up the DECL_FIELD_BITPOS of the vfield if we need to, as we
     might need to know it for setting up the offsets in the vtable
     (or in thunks) below.  */
  if (vfield != NULL_TREE
      && DECL_FIELD_CONTEXT (vfield) != t)
    {
      tree binfo = get_binfo (DECL_FIELD_CONTEXT (vfield), t, 0);
      tree offset = BINFO_OFFSET (binfo);

      vfield = copy_node (vfield);
      copy_lang_decl (vfield);

      if (! integer_zerop (offset))
	offset = size_binop (MULT_EXPR, offset, size_int (BITS_PER_UNIT));
      DECL_FIELD_CONTEXT (vfield) = t;
      DECL_CLASS_CONTEXT (vfield) = t;
      DECL_FIELD_BITPOS (vfield)
	= size_binop (PLUS_EXPR, offset, DECL_FIELD_BITPOS (vfield));
      CLASSTYPE_VFIELD (t) = vfield;
    }
    
#ifdef NOTQUITE
  cp_warning ("Doing hard virtuals for %T...", t);
#endif

  if (has_virtual > max_has_virtual)
    max_has_virtual = has_virtual;
  if (max_has_virtual > 0)
    TYPE_VIRTUAL_P (t) = 1;

  /* Do this here before we start messing with vtables so that we are ready
     for import_export_vtable.  */
  if (at_eof)
    import_export_class (t);

  if (flag_rtti && TYPE_VIRTUAL_P (t) && !pending_hard_virtuals)
    modify_all_vtables (t, NULL_TREE, NULL_TREE);

  while (pending_hard_virtuals)
    {
      modify_all_vtables (t,
			  TREE_PURPOSE (pending_hard_virtuals),
			  TREE_VALUE (pending_hard_virtuals));
      pending_hard_virtuals = TREE_CHAIN (pending_hard_virtuals);
    }
  
  if (TYPE_USES_VIRTUAL_BASECLASSES (t))
    {
      tree vbases;
      /* Now fixup any virtual function entries from virtual bases
	 that have different deltas.  This has to come after we do the
	 pending hard virtuals, as we might have a function that comes
	 from multiple virtual base instances that is only overridden
	 by a hard virtual above.  */
      vbases = CLASSTYPE_VBASECLASSES (t);
      while (vbases)
	{
	  /* We might be able to shorten the amount of work we do by
	     only doing this for vtables that come from virtual bases
	     that have differing offsets, but don't want to miss any
	     entries.  */
	  fixup_vtable_deltas (vbases, 1, t);
	  vbases = TREE_CHAIN (vbases);
	}
    }

  /* Under our model of GC, every C++ class gets its own virtual
     function table, at least virtually.  */
  if (pending_virtuals)
    {
      pending_virtuals = nreverse (pending_virtuals);
      /* We must enter these virtuals into the table.  */
      if (first_vfn_base_index < 0)
	{
	  /* The second slot is for the tdesc pointer when thunks are used.  */
	  if (flag_vtable_thunks)
	    pending_virtuals = tree_cons (NULL_TREE, NULL_TREE, pending_virtuals);

	  /* The first slot is for the rtti offset.  */
	  pending_virtuals = tree_cons (NULL_TREE, NULL_TREE, pending_virtuals);

	  set_rtti_entry (pending_virtuals,
			  convert (ssizetype, integer_zero_node), t);
	  build_vtable (NULL_TREE, t);
	}
      else
	{
	  /* Here we know enough to change the type of our virtual
	     function table, but we will wait until later this function.  */

	  if (! BINFO_NEW_VTABLE_MARKED (TYPE_BINFO (t)))
	    build_vtable (TREE_VEC_ELT (TYPE_BINFO_BASETYPES (t), first_vfn_base_index), t);
	}

      /* If this type has basetypes with constructors, then those
	 constructors might clobber the virtual function table.  But
	 they don't if the derived class shares the exact vtable of the base
	 class.  */

      CLASSTYPE_NEEDS_VIRTUAL_REINIT (t) = 1;
    }
  else if (first_vfn_base_index >= 0)
    {
      tree binfo = TREE_VEC_ELT (TYPE_BINFO_BASETYPES (t), first_vfn_base_index);
      /* This class contributes nothing new to the virtual function
	 table.  However, it may have declared functions which
	 went into the virtual function table "inherited" from the
	 base class.  If so, we grab a copy of those updated functions,
	 and pretend they are ours.  */

      /* See if we should steal the virtual info from base class.  */
      if (TYPE_BINFO_VTABLE (t) == NULL_TREE)
	TYPE_BINFO_VTABLE (t) = BINFO_VTABLE (binfo);
      if (TYPE_BINFO_VIRTUALS (t) == NULL_TREE)
	TYPE_BINFO_VIRTUALS (t) = BINFO_VIRTUALS (binfo);
      if (TYPE_BINFO_VTABLE (t) != BINFO_VTABLE (binfo))
	CLASSTYPE_NEEDS_VIRTUAL_REINIT (t) = 1;
    }

  if (max_has_virtual || first_vfn_base_index >= 0)
    {
      CLASSTYPE_VSIZE (t) = has_virtual;
      if (first_vfn_base_index >= 0)
	{
	  if (pending_virtuals)
	    TYPE_BINFO_VIRTUALS (t) = chainon (TYPE_BINFO_VIRTUALS (t),
						pending_virtuals);
	}
      else if (has_virtual)
	{
	  TYPE_BINFO_VIRTUALS (t) = pending_virtuals;
	  if (write_virtuals >= 0)
	    DECL_VIRTUAL_P (TYPE_BINFO_VTABLE (t)) = 1;
	}
    }

  /* Now lay out the virtual function table.  */
  if (has_virtual)
    {
      tree atype, itype;

      if (TREE_TYPE (vfield) == ptr_type_node)
	{
	  /* We must create a pointer to this table because
	     the one inherited from base class does not exist.
	     We will fill in the type when we know what it
	     should really be.  Use `size_int' so values are memoized
	     in common cases.  */
	  itype = build_index_type (size_int (has_virtual));
	  atype = build_array_type (vtable_entry_type, itype);
	  layout_type (atype);
	  TREE_TYPE (vfield) = build_pointer_type (atype);
	}
      else
	{
	  atype = TREE_TYPE (TREE_TYPE (vfield));

	  if (has_virtual != TREE_INT_CST_LOW (TYPE_MAX_VALUE (TYPE_DOMAIN (atype))))
	    {
	      /* We must extend (or create) the boundaries on this array,
		 because we picked up virtual functions from multiple
		 base classes.  */
	      itype = build_index_type (size_int (has_virtual));
	      atype = build_array_type (vtable_entry_type, itype);
	      layout_type (atype);
	      vfield = copy_node (vfield);
	      TREE_TYPE (vfield) = build_pointer_type (atype);
	    }
	}

      CLASSTYPE_VFIELD (t) = vfield;
      if (TREE_TYPE (TYPE_BINFO_VTABLE (t)) != atype)
	{
	  TREE_TYPE (TYPE_BINFO_VTABLE (t)) = atype;
	  DECL_SIZE (TYPE_BINFO_VTABLE (t)) = 0;
	  layout_decl (TYPE_BINFO_VTABLE (t), 0);
	  /* At one time the vtable info was grabbed 2 words at a time.  This
	     fails on sparc unless you have 8-byte alignment.  (tiemann) */
	  DECL_ALIGN (TYPE_BINFO_VTABLE (t))
	    = MAX (TYPE_ALIGN (double_type_node),
		   DECL_ALIGN (TYPE_BINFO_VTABLE (t)));
	}
    }
  else if (first_vfn_base_index >= 0)
    CLASSTYPE_VFIELD (t) = vfield;
  CLASSTYPE_VFIELDS (t) = vfields;

  finish_struct_bits (t, max_has_virtual);

  /* Complete the rtl for any static member objects of the type we're
     working on.  */
  for (x = fields; x; x = TREE_CHAIN (x))
    {
      if (TREE_CODE (x) == VAR_DECL && TREE_STATIC (x)
	  && TREE_TYPE (x) == t)
	{
	  DECL_MODE (x) = TYPE_MODE (t);
	  make_decl_rtl (x, NULL, 0);
	}
    }

  if (TYPE_HAS_CONSTRUCTOR (t))
    {
      tree vfields = CLASSTYPE_VFIELDS (t);

      while (vfields)
	{
	  /* Mark the fact that constructor for T
	     could affect anybody inheriting from T
	     who wants to initialize vtables for VFIELDS's type.  */
	  if (VF_DERIVED_VALUE (vfields))
	    TREE_ADDRESSABLE (vfields) = 1;
	  vfields = TREE_CHAIN (vfields);
	}
      if (any_default_members != 0)
	build_class_init_list (t);
    }
  else if (TYPE_NEEDS_CONSTRUCTING (t))
    build_class_init_list (t);

  /* Write out inline function definitions.  */
  do_inline_function_hair (t, CLASSTYPE_INLINE_FRIENDS (t));
  CLASSTYPE_INLINE_FRIENDS (t) = 0;

  if (CLASSTYPE_VSIZE (t) != 0)
    {
#if 0
      /* This is now done above.  */
      if (DECL_FIELD_CONTEXT (vfield) != t)
	{
	  tree binfo = get_binfo (DECL_FIELD_CONTEXT (vfield), t, 0);
	  tree offset = BINFO_OFFSET (binfo);

	  vfield = copy_node (vfield);
	  copy_lang_decl (vfield);

	  if (! integer_zerop (offset))
	    offset = size_binop (MULT_EXPR, offset, size_int (BITS_PER_UNIT));
	  DECL_FIELD_CONTEXT (vfield) = t;
	  DECL_CLASS_CONTEXT (vfield) = t;
	  DECL_FIELD_BITPOS (vfield)
	    = size_binop (PLUS_EXPR, offset, DECL_FIELD_BITPOS (vfield));
	  CLASSTYPE_VFIELD (t) = vfield;
	}
#endif

      /* In addition to this one, all the other vfields should be listed.  */
      /* Before that can be done, we have to have FIELD_DECLs for them, and
	 a place to find them.  */
      TYPE_NONCOPIED_PARTS (t) = build_tree_list (default_conversion (TYPE_BINFO_VTABLE (t)), vfield);

      if (warn_nonvdtor && TYPE_HAS_DESTRUCTOR (t)
	  && DECL_VINDEX (TREE_VEC_ELT (method_vec, 1)) == NULL_TREE)
	cp_warning ("`%#T' has virtual functions but non-virtual destructor",
		    t);
    }

  /* Make the rtl for any new vtables we have created, and unmark
     the base types we marked.  */
  finish_vtbls (TYPE_BINFO (t), 1, t);
  hack_incomplete_structures (t);

#if 0
  if (TYPE_NAME (t) && TYPE_IDENTIFIER (t))
    undo_template_name_overload (TYPE_IDENTIFIER (t), 1);
#endif

  resume_momentary (old);

  if (warn_overloaded_virtual)
    warn_hidden (t);

#if 0
  /* This has to be done after we have sorted out what to do with
     the enclosing type.  */
  if (write_symbols != DWARF_DEBUG)
    {
      /* Be smarter about nested classes here.  If a type is nested,
	 only output it if we would output the enclosing type.  */
      if (DECL_CLASS_SCOPE_P (TYPE_MAIN_DECL (t)))
	DECL_IGNORED_P (TYPE_MAIN_DECL (t)) = TREE_ASM_WRITTEN (TYPE_MAIN_DECL (t));
    }
#endif

  if (write_symbols != DWARF_DEBUG && write_symbols != DWARF2_DEBUG)
    {
      /* If the type has methods, we want to think about cutting down
	 the amount of symbol table stuff we output.  The value stored in
	 the TYPE_DECL's DECL_IGNORED_P slot is a first approximation.
	 For example, if a member function is seen and we decide to
	 write out that member function, then we can change the value
	 of the DECL_IGNORED_P slot, and the type will be output when
	 that member function's debug info is written out.

	 We can't do this with DWARF, which does not support name
	 references between translation units.  */
      if (CLASSTYPE_METHOD_VEC (t))
	{
	  extern tree pending_vtables;

	  /* Don't output full info about any type
	     which does not have its implementation defined here.  */
	  if (TYPE_VIRTUAL_P (t) && write_virtuals == 2)
	    TYPE_DECL_SUPPRESS_DEBUG (TYPE_MAIN_DECL (t))
	      = (value_member (TYPE_IDENTIFIER (t), pending_vtables) == 0);
	  else if (CLASSTYPE_INTERFACE_ONLY (t))
	    TYPE_DECL_SUPPRESS_DEBUG (TYPE_MAIN_DECL (t)) = 1;
#if 0
	  /* XXX do something about this.  */
	  else if (CLASSTYPE_INTERFACE_UNKNOWN (t))
	    /* Only a first approximation!  */
	    TYPE_DECL_SUPPRESS_DEBUG (TYPE_MAIN_DECL (t)) = 1;
#endif
	}
      else if (CLASSTYPE_INTERFACE_ONLY (t))
	TYPE_DECL_SUPPRESS_DEBUG (TYPE_MAIN_DECL (t)) = 1;
    }

  /* Finish debugging output for this type.  */
  rest_of_type_compilation (t, toplevel_bindings_p ());

  return t;
}

tree
finish_struct (t, list_of_fieldlists, attributes, warn_anon)
     tree t, list_of_fieldlists, attributes;
     int warn_anon;
{
  tree fields = NULL_TREE;
  tree *tail = &TYPE_METHODS (t);
  tree specializations = NULL_TREE;
  tree *specialization_tail = &specializations;
  tree name = TYPE_NAME (t);
  tree x, last_x = NULL_TREE;
  tree access;
  tree dummy = NULL_TREE;
  tree next_x = NULL_TREE;

  if (TREE_CODE (name) == TYPE_DECL)
    {
      extern int lineno;
	  
      DECL_SOURCE_FILE (name) = input_filename;
      /* For TYPE_DECL that are not typedefs (those marked with a line
	 number of zero, we don't want to mark them as real typedefs.
	 If this fails one needs to make sure real typedefs have a
	 previous line number, even if it is wrong, that way the below
	 will fill in the right line number.  (mrs) */
      if (DECL_SOURCE_LINE (name))
	DECL_SOURCE_LINE (name) = lineno;
      CLASSTYPE_SOURCE_LINE (t) = lineno;
      name = DECL_NAME (name);
    }

  /* Append the fields we need for constructing signature tables.  */
  if (IS_SIGNATURE (t))
    append_signature_fields (list_of_fieldlists);

  /* Move our self-reference declaration to the end of the field list so
     any real field with the same name takes precedence.  */
  if (list_of_fieldlists
      && TREE_VALUE (list_of_fieldlists)
      && DECL_ARTIFICIAL (TREE_VALUE (list_of_fieldlists)))
    {
      dummy = TREE_VALUE (list_of_fieldlists);
      list_of_fieldlists = TREE_CHAIN (list_of_fieldlists);
    }

  if (last_x && list_of_fieldlists)
    TREE_CHAIN (last_x) = TREE_VALUE (list_of_fieldlists);

  while (list_of_fieldlists)
    {
      access = TREE_PURPOSE (list_of_fieldlists);

      /* For signatures, we made all methods `public' in the parser and
	 reported an error if a access specifier was used.  */
      if (access == access_default_node)
	{
	  if (CLASSTYPE_DECLARED_CLASS (t) == 0)
	    access = access_public_node;
	  else
	    access = access_private_node;
	}

      for (x = TREE_VALUE (list_of_fieldlists); x; x = next_x)
	{
	  next_x = TREE_CHAIN (x);

	  TREE_PRIVATE (x) = access == access_private_node;
	  TREE_PROTECTED (x) = access == access_protected_node;

	  if (TREE_CODE (x) == TEMPLATE_DECL)
	    {
	      TREE_PRIVATE (DECL_RESULT (x)) = TREE_PRIVATE (x);
	      TREE_PROTECTED (DECL_RESULT (x)) = TREE_PROTECTED (x);
	    }

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

             Enums, types and static vars have already been checked.  */
	  if (TREE_CODE (x) != TYPE_DECL && TREE_CODE (x) != USING_DECL
	      && ! (TREE_CODE (x) == TEMPLATE_DECL
		    && TREE_CODE (DECL_RESULT (x)) == TYPE_DECL)
	      && TREE_CODE (x) != CONST_DECL && TREE_CODE (x) != VAR_DECL)
	    {
	      tree name = DECL_NAME (x);
	      tree icv;

	      /* Don't get confused by access decls.  */
	      if (name && TREE_CODE (name) == IDENTIFIER_NODE)
		icv = IDENTIFIER_CLASS_VALUE (name);
	      else
		icv = NULL_TREE;

	      if (icv
		  && flag_optional_diags
		  /* Don't complain about constructors.  */
		  && name != constructor_name (current_class_type)
		  /* Or inherited names.  */
		  && id_in_current_class (name)
		  /* Or shadowed tags.  */
		  && !(TREE_CODE (icv) == TYPE_DECL
		       && DECL_CONTEXT (icv) == t))
		{
		  cp_pedwarn_at ("declaration of identifier `%D' as `%+#D'",
				 name, x);
		  cp_pedwarn_at ("conflicts with other use in class as `%#D'",
				 icv);
		}
	    }

	  if (TREE_CODE (x) == FUNCTION_DECL 
	      || DECL_FUNCTION_TEMPLATE_P (x))
	    {
	      DECL_CLASS_CONTEXT (x) = t;

	      if (last_x)
		TREE_CHAIN (last_x) = next_x;

	      if (DECL_TEMPLATE_SPECIALIZATION (x))
		/* We don't enter the specialization into the class
		   method vector since specializations don't affect
		   overloading.  Instead we keep track of the
		   specializations, and process them after the method
		   vector is complete.  */
		{
		  *specialization_tail = x;
		  specialization_tail = &TREE_CHAIN (x);
		  TREE_CHAIN (x) = NULL_TREE;
		  continue;
		}

	      /* Link x onto end of TYPE_METHODS.  */
	      *tail = x;
	      tail = &TREE_CHAIN (x);
	      continue;
	    }

	  if (TREE_CODE (x) != TYPE_DECL)
	    DECL_FIELD_CONTEXT (x) = t;

	  if (! fields)
	    fields = x;
	  last_x = x;
	}
      list_of_fieldlists = TREE_CHAIN (list_of_fieldlists);
      /* link the tail while we have it! */
      if (last_x)
	{
	  TREE_CHAIN (last_x) = NULL_TREE;

	  if (list_of_fieldlists
	      && TREE_VALUE (list_of_fieldlists)
	      && TREE_CODE (TREE_VALUE (list_of_fieldlists)) != FUNCTION_DECL)
	    TREE_CHAIN (last_x) = TREE_VALUE (list_of_fieldlists);
	}
    }

  /* Now add the tags, if any, to the list of TYPE_DECLs
     defined for this type.  */
  if (CLASSTYPE_TAGS (t) || dummy)
    {
      /* The list of tags was built up in pushtag in reverse order; we need
	 to fix that so that enumerators will be processed in forward order
	 in template instantiation.  */
      CLASSTYPE_TAGS (t) = x = nreverse (CLASSTYPE_TAGS (t));
      while (x)
	{
	  tree tag_type = TREE_VALUE (x);
	  tree tag = TYPE_MAIN_DECL (TREE_VALUE (x));

	  if (IS_AGGR_TYPE_CODE (TREE_CODE (tag_type))
	      && CLASSTYPE_IS_TEMPLATE (tag_type))
	    tag = CLASSTYPE_TI_TEMPLATE (tag_type);

	  TREE_NONLOCAL_FLAG (tag_type) = 0;
	  x = TREE_CHAIN (x);
	  last_x = chainon (last_x, tag);
	}
      if (dummy)
	last_x = chainon (last_x, dummy);
      if (fields == NULL_TREE)
	fields = last_x;
      CLASSTYPE_LOCAL_TYPEDECLS (t) = 1;
    }

  *tail = NULL_TREE;
  TYPE_FIELDS (t) = fields;

  cplus_decl_attributes (t, attributes, NULL_TREE);

  if (processing_template_decl)
    {
      tree d = getdecls ();
      for (; d; d = TREE_CHAIN (d))
	{
	  /* If this is the decl for the class or one of the template
             parms, we've seen all the injected decls.  */
	  if ((TREE_CODE (d) == TYPE_DECL
	       && (TREE_TYPE (d) == t
		   || TREE_CODE (TREE_TYPE (d)) == TEMPLATE_TYPE_PARM
		   || TREE_CODE (TREE_TYPE (d)) == TEMPLATE_TEMPLATE_PARM))
	      || TREE_CODE (d) == CONST_DECL)
	    break;
	  /* Don't inject cache decls.  */
	  else if (IDENTIFIER_TEMPLATE (DECL_NAME (d)))
	    continue;
	  DECL_TEMPLATE_INJECT (CLASSTYPE_TI_TEMPLATE (t))
	    = tree_cons (NULL_TREE, d,
			 DECL_TEMPLATE_INJECT (CLASSTYPE_TI_TEMPLATE (t)));
	}
      CLASSTYPE_METHOD_VEC (t)
	= finish_struct_methods (t, TYPE_METHODS (t), 1);
      TYPE_SIZE (t) = integer_zero_node;
    }      
  else
    t = finish_struct_1 (t, warn_anon);

  TYPE_BEING_DEFINED (t) = 0;

  /* Now, figure out which member templates we're specializing.  */
  for (x = specializations; x != NULL_TREE; x = TREE_CHAIN (x))
    {
      tree spec_args;
      tree fn;
      int pending_specialization;

      if (uses_template_parms (t))
	/* If t is a template class, and x is a specialization, then x
	   is itself really a template.  Due to the vagaries of the
	   parser, however, we will have a handle to a function
	   declaration, rather than the template declaration, at this
	   point.  */
	{
	  my_friendly_assert (DECL_TEMPLATE_INFO (x) != NULL_TREE, 0);
	  my_friendly_assert (DECL_TI_TEMPLATE (x) != NULL_TREE, 0);
	  fn = DECL_TI_TEMPLATE (x);
	}
      else
	fn = x;

      /* We want the specialization arguments, which will be the
	 innermost ones.  */
      if (DECL_TI_ARGS (fn) && TREE_CODE (DECL_TI_ARGS (fn)) == TREE_VEC)
	spec_args 
	  = TREE_VEC_ELT (DECL_TI_ARGS (fn), 0);
      else
	spec_args = DECL_TI_ARGS (fn);
      
      pending_specialization 
	= TI_PENDING_SPECIALIZATION_FLAG (DECL_TEMPLATE_INFO (fn));
      check_explicit_specialization 
	(lookup_template_function (DECL_NAME (fn), spec_args),
	 fn, 0, 1 | (8 * pending_specialization));
      TI_PENDING_SPECIALIZATION_FLAG (DECL_TEMPLATE_INFO (fn)) = 0;

      /* Now, the assembler name will be correct for fn, so we
	 make its RTL.  */
      DECL_RTL (fn) = 0;
      make_decl_rtl (fn, NULL_PTR, 1);

      if (x != fn)
	{
	  DECL_RTL (x) = 0;
	  make_decl_rtl (x, NULL_PTR, 1);
	}
    }

  if (current_class_type)
    popclass (0);
  else
    error ("trying to finish struct, but kicked out due to previous parse errors.");

  return t;
}

/* Return non-zero if the effective type of INSTANCE is static.
   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.  */

int
resolves_to_fixed_type_p (instance, nonnull)
     tree instance;
     int *nonnull;
{
  switch (TREE_CODE (instance))
    {
    case INDIRECT_REF:
      /* Check that we are not going through a cast of some sort.  */
      if (TREE_TYPE (instance)
	  == TREE_TYPE (TREE_TYPE (TREE_OPERAND (instance, 0))))
	instance = TREE_OPERAND (instance, 0);
      /* fall through...  */
    case CALL_EXPR:
      /* This is a call to a constructor, hence it's never zero.  */
      if (TREE_HAS_CONSTRUCTOR (instance))
	{
	  if (nonnull)
	    *nonnull = 1;
	  return 1;
	}
      return 0;

    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 1;
	}
      return resolves_to_fixed_type_p (TREE_OPERAND (instance, 0), nonnull);

    case RTL_EXPR:
      return 0;

    case PLUS_EXPR:
    case MINUS_EXPR:
      if (TREE_CODE (TREE_OPERAND (instance, 1)) == INTEGER_CST)
	/* Propagate nonnull.  */
	resolves_to_fixed_type_p (TREE_OPERAND (instance, 0), nonnull);
      if (TREE_CODE (TREE_OPERAND (instance, 0)) == ADDR_EXPR)
	return resolves_to_fixed_type_p (TREE_OPERAND (instance, 0), nonnull);
      return 0;

    case NOP_EXPR:
    case CONVERT_EXPR:
      return resolves_to_fixed_type_p (TREE_OPERAND (instance, 0), nonnull);

    case ADDR_EXPR:
      if (nonnull)
	*nonnull = 1;
      return resolves_to_fixed_type_p (TREE_OPERAND (instance, 0), nonnull);

    case COMPONENT_REF:
      return resolves_to_fixed_type_p (TREE_OPERAND (instance, 1), nonnull);

    case VAR_DECL:
    case FIELD_DECL:
      if (TREE_CODE (TREE_TYPE (instance)) == ARRAY_TYPE
	  && IS_AGGR_TYPE (TREE_TYPE (TREE_TYPE (instance))))
	{
	  if (nonnull)
	    *nonnull = 1;
	  return 1;
	}
      /* fall through...  */
    case TARGET_EXPR:
    case PARM_DECL:
      if (IS_AGGR_TYPE (TREE_TYPE (instance)))
	{
	  if (nonnull)
	    *nonnull = 1;
	  return 1;
	}
      else if (nonnull)
	{
	  if (instance == current_class_ptr
	      && flag_this_is_variable <= 0)
	    {
	      /* Some people still use `this = 0' inside destructors.  */
	      *nonnull = ! DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (current_function_decl));
	      /* In a constructor, we know our type.  */
	      if (flag_this_is_variable < 0)
		return 1;
	    }
	  else if (TREE_CODE (TREE_TYPE (instance)) == REFERENCE_TYPE)
	    /* Reference variables should be references to objects.  */
	    *nonnull = 1;
	}
      return 0;

    default:
      return 0;
    }
}

void
init_class_processing ()
{
  current_class_depth = 0;
  current_class_stacksize = 10;
  current_class_base = (tree *)xmalloc(current_class_stacksize * sizeof (tree));
  current_class_stack = current_class_base;

  current_lang_stacksize = 10;
  current_lang_base = (tree *)xmalloc(current_lang_stacksize * sizeof (tree));
  current_lang_stack = current_lang_base;

  access_default_node = build_int_2 (0, 0);
  access_public_node = build_int_2 (1, 0);
  access_protected_node = build_int_2 (2, 0);
  access_private_node = build_int_2 (3, 0);
  access_default_virtual_node = build_int_2 (4, 0);
  access_public_virtual_node = build_int_2 (5, 0);
  access_protected_virtual_node = build_int_2 (6, 0);
  access_private_virtual_node = build_int_2 (7, 0);

  /* Keep these values lying around.  */
  base_layout_decl = build_lang_field_decl (FIELD_DECL, NULL_TREE, error_mark_node);
  TREE_TYPE (base_layout_decl) = make_node (RECORD_TYPE);

  gcc_obstack_init (&class_obstack);
}

/* Set current scope to NAME. CODE tells us if this is a
   STRUCT, UNION, or ENUM environment.

   NAME may end up being NULL_TREE if this is an anonymous or
   late-bound struct (as in "struct { ... } foo;")  */

/* Set global variables CURRENT_CLASS_NAME and CURRENT_CLASS_TYPE to
   appropriate values, found by looking up the type definition of
   NAME (as a CODE).

   If MODIFY is 1, we set IDENTIFIER_CLASS_VALUE's of names
   which can be seen locally to the class.  They are shadowed by
   any subsequent local declaration (including parameter names).

   If MODIFY is 2, we set IDENTIFIER_CLASS_VALUE's of names
   which have static meaning (i.e., static members, static
   member functions, enum declarations, etc).

   If MODIFY is 3, we set IDENTIFIER_CLASS_VALUE of names
   which can be seen locally to the class (as in 1), but
   know that we are doing this for declaration purposes
   (i.e. friend foo::bar (int)).

   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.  The first pass performs a pre-order search,
   marking types after the type has had its fields installed in
   the appropriate IDENTIFIER_CLASS_VALUE slot.  The second pass merely
   unmarks the marked types.  If a field or member function name
   appears in an ambiguous way, the IDENTIFIER_CLASS_VALUE of
   that name becomes `error_mark_node'.  */

void
pushclass (type, modify)
     tree type;
     int modify;
{
  type = TYPE_MAIN_VARIANT (type);
  push_memoized_context (type, modify);

  current_class_depth++;
  *current_class_stack++ = current_class_name;
  *current_class_stack++ = current_class_type;
  if (current_class_stack >= current_class_base + current_class_stacksize)
    {
      current_class_base
	= (tree *)xrealloc (current_class_base,
			    sizeof (tree) * (current_class_stacksize + 10));
      current_class_stack = current_class_base + current_class_stacksize;
      current_class_stacksize += 10;
    }

  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;

  if (previous_class_type != NULL_TREE
      && (type != previous_class_type || TYPE_SIZE (previous_class_type) == NULL_TREE)
      && current_class_depth == 1)
    {
      /* Forcibly remove any old class remnants.  */
      popclass (-1);
      previous_class_type = NULL_TREE;
    }

  pushlevel_class ();

#if 0
  if (CLASSTYPE_TEMPLATE_INFO (type))
    overload_template_name (type);
#endif

  if (modify)
    {
      tree tags;
      tree this_fndecl = current_function_decl;

      if (current_function_decl
	  && DECL_CONTEXT (current_function_decl)
	  && TREE_CODE (DECL_CONTEXT (current_function_decl)) == FUNCTION_DECL)
	current_function_decl = DECL_CONTEXT (current_function_decl);
      else
	current_function_decl = NULL_TREE;

      if (type != previous_class_type || current_class_depth > 1)
	{
#ifdef MI_MATRIX
	  build_mi_matrix (type);
	  push_class_decls (type);
	  free_mi_matrix ();
#else
	  push_class_decls (type);
#endif
	}
      else
	{
	  tree item;

	  /* Hooray, we successfully cached; let's just install the
	     cached class_shadowed list, and walk through it to get the
	     IDENTIFIER_TYPE_VALUEs correct.  */
	  set_class_shadows (previous_class_values);
	  for (item = previous_class_values; item; item = TREE_CHAIN (item))
	    {
	      tree id = TREE_PURPOSE (item);
	      tree decl = IDENTIFIER_CLASS_VALUE (id);

	      if (TREE_CODE (decl) == TYPE_DECL)
		set_identifier_type_value (id, TREE_TYPE (decl));
	    }
	  unuse_fields (type);
	}

      for (tags = CLASSTYPE_TAGS (type); tags; tags = TREE_CHAIN (tags))
	{
	  tree tag_type = TREE_VALUE (tags);

	  TREE_NONLOCAL_FLAG (tag_type) = 1;
	  if (! TREE_PURPOSE (tags))
	    continue;
	  if (! (IS_AGGR_TYPE_CODE (TREE_CODE (tag_type))
		 && CLASSTYPE_IS_TEMPLATE (tag_type)))
	    pushtag (TREE_PURPOSE (tags), tag_type, 0);
	  else
	    pushdecl_class_level (CLASSTYPE_TI_TEMPLATE (tag_type));
	}

      current_function_decl = this_fndecl;
    }
}
 
/* Get out of the current class scope. If we were in a class scope
   previously, that is the one popped to.  The flag MODIFY tells whether
   the current scope declarations needs to be modified as a result of
   popping to the previous scope.  0 is used for class definitions.  */

void
popclass (modify)
     int modify;
{
  if (modify < 0)
    {
      /* Back this old class out completely.  */
      tree tags = CLASSTYPE_TAGS (previous_class_type);
      tree t;

      /* This code can be seen as a cache miss.  When we've cached a
	 class' scope's bindings and we can't use them, we need to reset
	 them.  This is it!  */
      for (t = previous_class_values; t; t = TREE_CHAIN (t))
	IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (t)) = NULL_TREE;
      while (tags)
	{
	  TREE_NONLOCAL_FLAG (TREE_VALUE (tags)) = 0;
	  tags = TREE_CHAIN (tags);
	}
      goto ret;
    }

  if (modify)
    {
      /* Just remove from this class what didn't make
	 it into IDENTIFIER_CLASS_VALUE.  */
      tree tags = CLASSTYPE_TAGS (current_class_type);

      while (tags)
	{
	  TREE_NONLOCAL_FLAG (TREE_VALUE (tags)) = 0;
	  tags = TREE_CHAIN (tags);
	}
    }

  /* Force clearing of IDENTIFIER_CLASS_VALUEs after a class definition,
     since not all class decls make it there currently.  */
  poplevel_class (! modify);

  /* Since poplevel_class does the popping of class decls nowadays,
     this really only frees the obstack used for these decls.
     That's why it had to be moved down here.  */
  if (modify)
    pop_class_decls ();

  current_class_depth--;
  current_class_type = *--current_class_stack;
  current_class_name = *--current_class_stack;

  pop_memoized_context (modify);

 ret:
  ;
}

/* Returns 1 if current_class_type is either T or a nested type of T.  */

int
currently_open_class (t)
     tree t;
{
  int i;
  if (t == current_class_type)
    return 1;
  for (i = 0; i < current_class_depth; ++i)
    if (current_class_stack [-i*2 - 1] == t)
      return 1;
  return 0;
}

/* 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 and MODIFY is equivalent with the pushclass
   formal of the same name.  */

void
push_nested_class (type, modify)
     tree type;
     int modify;
{
  tree context;

  my_friendly_assert (!type || TREE_CODE (type) != NAMESPACE_DECL, 980711);

  if (type == NULL_TREE || type == error_mark_node || ! IS_AGGR_TYPE (type)
      || TREE_CODE (type) == TEMPLATE_TYPE_PARM
      || TREE_CODE (type) == TEMPLATE_TEMPLATE_PARM)
    return;
  
  context = DECL_CONTEXT (TYPE_MAIN_DECL (type));

  if (context && TREE_CODE (context) == RECORD_TYPE)
    push_nested_class (context, 2);
  pushclass (type, modify);
}

/* Undoes a push_nested_class call.  MODIFY is passed on to popclass.  */

void
pop_nested_class (modify)
     int modify;
{
  tree context = DECL_CONTEXT (TYPE_MAIN_DECL (current_class_type));

  popclass (modify);
  if (context && TREE_CODE (context) == RECORD_TYPE)
    pop_nested_class (modify);
}

/* Set global variables CURRENT_LANG_NAME to appropriate value
   so that behavior of name-mangling machinery is correct.  */

void
push_lang_context (name)
     tree name;
{
  *current_lang_stack++ = current_lang_name;
  if (current_lang_stack >= current_lang_base + current_lang_stacksize)
    {
      current_lang_base
	= (tree *)xrealloc (current_lang_base,
			    sizeof (tree) * (current_lang_stacksize + 10));
      current_lang_stack = current_lang_base + current_lang_stacksize;
      current_lang_stacksize += 10;
    }

  if (name == lang_name_cplusplus || name == lang_name_java)
    {
      strict_prototype = strict_prototypes_lang_cplusplus;
      current_lang_name = name;
    }
  else if (name == lang_name_c)
    {
      strict_prototype = strict_prototypes_lang_c;
      current_lang_name = name;
    }
  else
    error ("language string `\"%s\"' not recognized", IDENTIFIER_POINTER (name));
}
  
/* Get out of the current language scope.  */

void
pop_lang_context ()
{
  current_lang_name = *--current_lang_stack;
  if (current_lang_name == lang_name_cplusplus
      || current_lang_name == lang_name_java)
    strict_prototype = strict_prototypes_lang_cplusplus;
  else if (current_lang_name == lang_name_c)
    strict_prototype = strict_prototypes_lang_c;
}

/* Type instantiation routines.  */

static tree
validate_lhs (lhstype, complain)
     tree lhstype;
     int complain;
{
  if (TYPE_PTRMEMFUNC_P (lhstype))
    lhstype = TYPE_PTRMEMFUNC_FN_TYPE (lhstype);

  if (TREE_CODE (lhstype) == POINTER_TYPE)
    {
      if (TREE_CODE (TREE_TYPE (lhstype)) == FUNCTION_TYPE
	  || TREE_CODE (TREE_TYPE (lhstype)) == METHOD_TYPE)
	lhstype = TREE_TYPE (lhstype);
      else
	{
	  if (complain)
	    error ("invalid type combination for overload");
	  return error_mark_node;
	}
    }
  return lhstype;
}

/* 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.  If only complain is COMPLAIN is set.  If we are
   not complaining, never modify rhs, as overload resolution wants to
   try many possible instantiations, in hopes that at least one will
   work.

   This function is used in build_modify_expr, convert_arguments,
   build_c_cast, and compute_conversion_costs.  */

tree
instantiate_type (lhstype, rhs, complain)
     tree lhstype, rhs;
     int complain;
{
  tree explicit_targs = NULL_TREE;
  int template_only = 0;

  if (TREE_CODE (lhstype) == UNKNOWN_TYPE)
    {
      if (complain)
	error ("not enough type information");
      return error_mark_node;
    }

  if (TREE_TYPE (rhs) != NULL_TREE && ! (type_unknown_p (rhs)))
    {
      if (comptypes (lhstype, TREE_TYPE (rhs), 1))
	return rhs;
      if (complain)
	cp_error ("argument of type `%T' does not match `%T'",
		  TREE_TYPE (rhs), lhstype);
      return error_mark_node;
    }

  /* We don't overwrite rhs if it is an overloaded function.
     Copying it would destroy the tree link.  */
  if (TREE_CODE (rhs) != OVERLOAD)
    rhs = copy_node (rhs);

  /* 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 TYPE_EXPR:
    case CONVERT_EXPR:
    case SAVE_EXPR:
    case CONSTRUCTOR:
    case BUFFER_REF:
      my_friendly_abort (177);
      return error_mark_node;

    case INDIRECT_REF:
    case ARRAY_REF:
      {
	tree new_rhs;

	new_rhs = instantiate_type (build_pointer_type (lhstype),
				    TREE_OPERAND (rhs, 0), complain);
	if (new_rhs == error_mark_node)
	  return error_mark_node;

	TREE_TYPE (rhs) = lhstype;
	TREE_OPERAND (rhs, 0) = new_rhs;
	return rhs;
      }

    case NOP_EXPR:
      rhs = copy_node (TREE_OPERAND (rhs, 0));
      TREE_TYPE (rhs) = unknown_type_node;
      return instantiate_type (lhstype, rhs, complain);

    case COMPONENT_REF:
      {
	tree field = TREE_OPERAND (rhs, 1);
	if (TREE_CODE (field) == TREE_LIST)
	  {
	    tree function = instantiate_type (lhstype, field, complain);
	    if (function == error_mark_node)
	      return error_mark_node;
	    my_friendly_assert (TREE_CODE (function) == FUNCTION_DECL, 185);
	    if (DECL_VINDEX (function))
	      {
		tree base = TREE_OPERAND (rhs, 0);
		tree base_ptr = build_unary_op (ADDR_EXPR, base, 0);
		if (base_ptr == error_mark_node)
		  return error_mark_node;
		base_ptr = convert_pointer_to (DECL_CONTEXT (function), base_ptr);
		if (base_ptr == error_mark_node)
		  return error_mark_node;
		return build_vfn_ref (&base_ptr, base, DECL_VINDEX (function));
	      }
	    mark_used (function);
	    return function;
	  }

	/* I could not trigger this code. MvL */
	my_friendly_abort (980326);
#if 0
	my_friendly_assert (TREE_CODE (field) == FIELD_DECL, 178);
	my_friendly_assert (!(TREE_CODE (TREE_TYPE (field)) == FUNCTION_TYPE
			      || TREE_CODE (TREE_TYPE (field)) == METHOD_TYPE),
			    179);

	TREE_TYPE (rhs) = lhstype;
	/* First look for an exact match  */

	while (field && TREE_TYPE (field) != lhstype)
	  field = DECL_CHAIN (field);
	if (field)
	  {
	    TREE_OPERAND (rhs, 1) = field;
	    mark_used (field);
	    return rhs;
	  }

	/* No exact match found, look for a compatible function.  */
	field = TREE_OPERAND (rhs, 1);
	while (field && ! comptypes (lhstype, TREE_TYPE (field), 0))
	  field = DECL_CHAIN (field);
	if (field)
	  {
	    TREE_OPERAND (rhs, 1) = field;
	    field = DECL_CHAIN (field);
	    while (field && ! comptypes (lhstype, TREE_TYPE (field), 0))
	      field = DECL_CHAIN (field);
	    if (field)
	      {
		if (complain)
		  error ("ambiguous overload for COMPONENT_REF requested");
		return error_mark_node;
	      }
	  }
	else
	  {
	    if (complain)
	      error ("no appropriate overload exists for COMPONENT_REF");
	    return error_mark_node;
	  }
#endif
	return rhs;
      }

    case OFFSET_REF:
      /* This can happen if we are forming a pointer-to-member for a
	 member template.  */
      rhs = TREE_OPERAND (rhs, 1);
      my_friendly_assert (TREE_CODE (rhs) == TEMPLATE_ID_EXPR, 0);
	
      /* Fall through.  */

    case TEMPLATE_ID_EXPR:
      {
	explicit_targs = TREE_OPERAND (rhs, 1);
	template_only = 1;
	rhs = TREE_OPERAND (rhs, 0);
      }
      /* fall through */
      my_friendly_assert (TREE_CODE (rhs) == OVERLOAD, 980401);

    case OVERLOAD:
      {
	tree elem, elems;

	/* Check that the LHSTYPE and the RHS are reasonable.  */
	lhstype = validate_lhs (lhstype, complain);
	if (lhstype == error_mark_node)
	  return lhstype;

	if (TREE_CODE (lhstype) != FUNCTION_TYPE
	    && TREE_CODE (lhstype) != METHOD_TYPE)
	  {
	    if (complain)
	      cp_error("cannot resolve overloaded function `%D' " 
		       "based on non-function type", 
		       DECL_NAME (OVL_FUNCTION (rhs)));
	    return error_mark_node;
	  }
	
	/* Look for an exact match, by searching through the
	   overloaded functions.  */
	if (template_only)
	  /* If we're processing a template-id, only a template
	     function can match, so we don't look through the
	     overloaded functions.  */
	  ;
	else for (elems = rhs; elems; elems = OVL_CHAIN (elems))
	  {
	    elem = OVL_FUNCTION (elems);
	    if (comptypes (lhstype, TREE_TYPE (elem), 1))
	      {
		mark_used (elem);
		return elem;
	      }
	  }

	/* No overloaded function was an exact match.  See if we can
	   instantiate some template to match.  */
	{
	  tree save_elem = 0;
	  elems = rhs;
	  if (TREE_CODE (elems) == TREE_LIST)
	    elems = TREE_VALUE (rhs);
	  for (; elems; elems = OVL_NEXT (elems))
	    if (TREE_CODE (elem = OVL_CURRENT (elems)) == TEMPLATE_DECL)
	      {
		int n = DECL_NTPARMS (elem);
		tree t = make_scratch_vec (n);
		int i;
		i = type_unification
		  (DECL_INNERMOST_TEMPLATE_PARMS (elem), t,
		   TYPE_ARG_TYPES (TREE_TYPE (elem)),
		   TYPE_ARG_TYPES (lhstype), explicit_targs, DEDUCE_EXACT, 1);
		if (i == 0)
		  {
		    if (save_elem)
		      {
			cp_error ("ambiguous template instantiation converting to `%#T'", lhstype);
			return error_mark_node;
		      }
		    save_elem = instantiate_template (elem, t);
		    /* Check the return type.  */
		    if (! comptypes (TREE_TYPE (lhstype),
				     TREE_TYPE (TREE_TYPE (save_elem)), 1))
		      save_elem = 0;
		  }
	      }
	  if (save_elem)
	    {
	      mark_used (save_elem);
	      return save_elem;
	    }
	}

	/* There's no exact match, and no templates can be
	   instantiated to match.  The last thing we try is to see if
	   some ordinary overloaded function is close enough.  If
	   we're only looking for template functions, we don't do
	   this.  */
	if (!template_only)
	  {
	    for (elems = rhs; elems; elems = OVL_NEXT (elems))
	      {
		elem = OVL_CURRENT (elems);
		if (comp_target_types (lhstype, TREE_TYPE (elem), 1) > 0)
		  break;
	      }
	    if (elems)
	      {
		tree save_elem = elem;
		for (elems = OVL_CHAIN (elems); elems; 
		     elems = OVL_CHAIN (elems))
		  {
		    elem = OVL_FUNCTION (elems);
		    if (comp_target_types (lhstype, TREE_TYPE (elem), 0) > 0)
		      break;
		  }
		if (elems)
		  {
		    if (complain)
		      {
			cp_error 
			  ("cannot resolve overload to target type `%#T'",
			   lhstype);
			cp_error_at ("  ambiguity between `%#D'", save_elem); 
			cp_error_at ("  and `%#D', at least", elem);
		      }
		    return error_mark_node;
		  }
		mark_used (save_elem);
		return save_elem;
	      }
	  }

	/* We failed to find a match.  */
	if (complain)
	  {
	    cp_error ("cannot resolve overload to target type `%#T'", lhstype);
	    cp_error 
	      ("  because no suitable overload of function `%D' exists",
	       DECL_NAME (OVL_FUNCTION (rhs)));
	  }
	return error_mark_node;
      }

    case TREE_LIST:
      {
	tree elem, baselink, name = NULL_TREE;

	if (TREE_PURPOSE (rhs) == error_mark_node)
	  {
	    /* Make sure we don't drop the non-local flag, as the old code
	       would rely on it. */
	    int nl = TREE_NONLOCAL_FLAG (rhs);
	    /* We don't need the type of this node. */
	    rhs = TREE_VALUE (rhs);
	    my_friendly_assert (TREE_NONLOCAL_FLAG (rhs) == nl, 980331);
	  }

	/* Now we should have a baselink. */
	my_friendly_assert (TREE_CODE (TREE_PURPOSE (rhs)) == TREE_VEC,
			    980331);
	/* First look for an exact match.  Search member functions.
	   May have to undo what `default_conversion' might do to
	   lhstype.  */

	lhstype = validate_lhs (lhstype, complain);
	if (lhstype == error_mark_node)
	  return lhstype;

	my_friendly_assert (TREE_CHAIN (rhs) == NULL_TREE, 181);
	my_friendly_assert (TREE_CODE (TREE_VALUE (rhs)) == FUNCTION_DECL
			    || TREE_CODE (TREE_VALUE (rhs)) == OVERLOAD,
			    182);

	for (baselink = rhs; baselink;
	     baselink = next_baselink (baselink))
	  {
	    elem = TREE_VALUE (baselink);
	    while (elem)
	      if (comptypes (lhstype, TREE_TYPE (OVL_CURRENT (elem)), 1))
		{
		  mark_used (OVL_CURRENT (elem));
		  return OVL_CURRENT (elem);
		}
	      else
		elem = OVL_NEXT (elem);
	  }

	/* No exact match found, look for a compatible method.  */
	for (baselink = rhs; baselink;
	     baselink = next_baselink (baselink))
	  {
	    elem = TREE_VALUE (baselink);
	    for (; elem; elem = OVL_NEXT (elem))
	      if (comp_target_types (lhstype, 
				     TREE_TYPE (OVL_CURRENT (elem)), 1) > 0)
		break;
	    if (elem)
	      {
		tree save_elem = OVL_CURRENT (elem);
		for (elem = OVL_NEXT (elem); elem; elem = OVL_NEXT (elem))
		  if (comp_target_types (lhstype, 
					 TREE_TYPE (OVL_CURRENT (elem)), 0) > 0)
		    break;
		if (elem)
		  {
		    if (complain)
		      error ("ambiguous overload for overloaded method requested");
		    return error_mark_node;
		  }
		mark_used (save_elem);
		return save_elem;
	      }
	    name = rhs;
	    while (TREE_CODE (name) == TREE_LIST)
	      name = TREE_VALUE (name);
	    name = DECL_NAME (OVL_CURRENT (name));
#if 0
	    if (TREE_CODE (lhstype) == FUNCTION_TYPE && globals < 0)
	      {
		/* Try to instantiate from non-member functions.  */
		rhs = lookup_name_nonclass (name);
		if (rhs && TREE_CODE (rhs) == TREE_LIST)
		  {
		    /* This code seems to be missing a `return'.  */
		    my_friendly_abort (4);
		    instantiate_type (lhstype, rhs, complain);
		  }
	      }
#endif
	  }
	if (complain)
	  cp_error ("no compatible member functions named `%D'", name);
	return error_mark_node;
      }

    case CALL_EXPR:
      /* This is too hard for now.  */
      my_friendly_abort (183);
      return error_mark_node;

    case PLUS_EXPR:
    case MINUS_EXPR:
    case COMPOUND_EXPR:
      TREE_OPERAND (rhs, 0)
	= instantiate_type (lhstype, TREE_OPERAND (rhs, 0), complain);
      if (TREE_OPERAND (rhs, 0) == error_mark_node)
	return error_mark_node;
      TREE_OPERAND (rhs, 1)
	= instantiate_type (lhstype, TREE_OPERAND (rhs, 1), complain);
      if (TREE_OPERAND (rhs, 1) == error_mark_node)
	return error_mark_node;

      TREE_TYPE (rhs) = lhstype;
      return rhs;

    case MULT_EXPR:
    case TRUNC_DIV_EXPR:
    case FLOOR_DIV_EXPR:
    case CEIL_DIV_EXPR:
    case ROUND_DIV_EXPR:
    case RDIV_EXPR:
    case TRUNC_MOD_EXPR:
    case FLOOR_MOD_EXPR:
    case CEIL_MOD_EXPR:
    case ROUND_MOD_EXPR:
    case FIX_ROUND_EXPR:
    case FIX_FLOOR_EXPR:
    case FIX_CEIL_EXPR:
    case FIX_TRUNC_EXPR:
    case FLOAT_EXPR:
    case NEGATE_EXPR:
    case ABS_EXPR:
    case MAX_EXPR:
    case MIN_EXPR:
    case FFS_EXPR:

    case BIT_AND_EXPR:
    case BIT_IOR_EXPR:
    case BIT_XOR_EXPR:
    case LSHIFT_EXPR:
    case RSHIFT_EXPR:
    case LROTATE_EXPR:
    case RROTATE_EXPR:

    case PREINCREMENT_EXPR:
    case PREDECREMENT_EXPR:
    case POSTINCREMENT_EXPR:
    case POSTDECREMENT_EXPR:
      if (complain)
	error ("invalid operation on uninstantiated type");
      return error_mark_node;

    case TRUTH_AND_EXPR:
    case TRUTH_OR_EXPR:
    case TRUTH_XOR_EXPR:
    case LT_EXPR:
    case LE_EXPR:
    case GT_EXPR:
    case GE_EXPR:
    case EQ_EXPR:
    case NE_EXPR:
    case TRUTH_ANDIF_EXPR:
    case TRUTH_ORIF_EXPR:
    case TRUTH_NOT_EXPR:
      if (complain)
	error ("not enough type information");
      return error_mark_node;

    case COND_EXPR:
      if (type_unknown_p (TREE_OPERAND (rhs, 0)))
	{
	  if (complain)
	    error ("not enough type information");
	  return error_mark_node;
	}
      TREE_OPERAND (rhs, 1)
	= instantiate_type (lhstype, TREE_OPERAND (rhs, 1), complain);
      if (TREE_OPERAND (rhs, 1) == error_mark_node)
	return error_mark_node;
      TREE_OPERAND (rhs, 2)
	= instantiate_type (lhstype, TREE_OPERAND (rhs, 2), complain);
      if (TREE_OPERAND (rhs, 2) == error_mark_node)
	return error_mark_node;

      TREE_TYPE (rhs) = lhstype;
      return rhs;

    case MODIFY_EXPR:
      TREE_OPERAND (rhs, 1)
	= instantiate_type (lhstype, TREE_OPERAND (rhs, 1), complain);
      if (TREE_OPERAND (rhs, 1) == error_mark_node)
	return error_mark_node;

      TREE_TYPE (rhs) = lhstype;
      return rhs;
      
    case ADDR_EXPR:
      if (TYPE_PTRMEMFUNC_P (lhstype))
	lhstype = TYPE_PTRMEMFUNC_FN_TYPE (lhstype);
      else if (TREE_CODE (lhstype) != POINTER_TYPE)
	{
	  if (complain)
	    error ("type for resolving address of overloaded function must be pointer type");
	  return error_mark_node;
	}
      {
	tree fn = instantiate_type (TREE_TYPE (lhstype), TREE_OPERAND (rhs, 0), complain);
	if (fn == error_mark_node)
	  return error_mark_node;
	mark_addressable (fn);
	TREE_TYPE (rhs) = lhstype;
	TREE_OPERAND (rhs, 0) = fn;
	TREE_CONSTANT (rhs) = staticp (fn);
	if (TREE_CODE (lhstype) == POINTER_TYPE
	    && TREE_CODE (TREE_TYPE (lhstype)) == METHOD_TYPE)
	  {
	    build_ptrmemfunc_type (lhstype);
	    rhs = build_ptrmemfunc (lhstype, rhs, 0);
	  }
      }
      return rhs;

    case ENTRY_VALUE_EXPR:
      my_friendly_abort (184);
      return error_mark_node;

    case ERROR_MARK:
      return error_mark_node;

    default:
      my_friendly_abort (185);
      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 (type)
     tree type;
{
  tree binfo = TYPE_BINFO (type);
  char *buf;

  while (BINFO_BASETYPES (binfo)
	 && TYPE_VIRTUAL_P (BINFO_TYPE (BINFO_BASETYPE (binfo, 0)))
	 && ! TREE_VIA_VIRTUAL (BINFO_BASETYPE (binfo, 0)))
    binfo = BINFO_BASETYPE (binfo, 0);

  type = BINFO_TYPE (binfo);
  buf = (char *) alloca (sizeof (VFIELD_NAME_FORMAT)
			 + TYPE_NAME_LENGTH (type) + 2);
  sprintf (buf, VFIELD_NAME_FORMAT, TYPE_NAME_STRING (type));
  return get_identifier (buf);
}

void
print_class_statistics ()
{
#ifdef GATHER_STATISTICS
  fprintf (stderr, "convert_harshness = %d\n", n_convert_harshness);
  fprintf (stderr, "compute_conversion_costs = %d\n", n_compute_conversion_costs);
  fprintf (stderr, "build_method_call = %d (inner = %d)\n",
	   n_build_method_call, n_inner_fields_searched);
  if (n_vtables)
    {
      fprintf (stderr, "vtables = %d; vtable searches = %d\n",
	       n_vtables, n_vtable_searches);
      fprintf (stderr, "vtable entries = %d; vtable elems = %d\n",
	       n_vtable_entries, n_vtable_elems);
    }
#endif
}

/* Push an obstack which is sufficiently long-lived to hold such class
   decls that may be cached in the previous_class_values list.  For now, let's
   use the permanent obstack, later we may create a dedicated obstack just
   for this purpose.  The effect is undone by pop_obstacks.  */

void
maybe_push_cache_obstack ()
{
  push_obstacks_nochange ();
  if (current_class_depth == 1)
    current_obstack = &permanent_obstack;
}

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

tree
build_self_reference ()
{
  tree name = constructor_name (current_class_type);
  tree value = build_lang_decl (TYPE_DECL, name, current_class_type);
  DECL_NONLOCAL (value) = 1;
  DECL_CONTEXT (value) = current_class_type;
  DECL_CLASS_CONTEXT (value) = current_class_type;
  CLASSTYPE_LOCAL_TYPEDECLS (current_class_type) = 1;
  DECL_ARTIFICIAL (value) = 1;

  pushdecl_class_level (value);
  return value;
}

/* Returns 1 if TYPE contains only padding bytes.  */

int
is_empty_class (type)
     tree type;
{
  tree t;

  if (type == error_mark_node)
    return 0;

  if (! IS_AGGR_TYPE (type))
    return 0;

  if (flag_new_abi)
    return CLASSTYPE_SIZE (type) == integer_zero_node;

  if (TYPE_BINFO_BASETYPES (type))
    return 0;
  t = TYPE_FIELDS (type);
  while (t && TREE_CODE (t) != FIELD_DECL)
    t = TREE_CHAIN (t);
  return (t == NULL_TREE);
}
