OSDN Git Service

PR c++/10990
[pf3gnuchains/gcc-fork.git] / gcc / cp / class.c
index 5e8b9fa..b5eb245 100644 (file)
@@ -110,7 +110,7 @@ static void finish_struct_anon (tree);
 static tree get_vtable_name (tree);
 static tree get_basefndecls (tree, tree);
 static int build_primary_vtable (tree, tree);
-static int build_secondary_vtable (tree, tree);
+static int build_secondary_vtable (tree);
 static void finish_vtbls (tree);
 static void modify_vtable_entry (tree, tree, tree, tree, tree *);
 static tree delete_duplicate_fields_1 (tree, tree);
@@ -152,9 +152,8 @@ static void layout_class_type (tree, tree *);
 static void fixup_pending_inline (tree);
 static void fixup_inline_methods (tree);
 static void set_primary_base (tree, tree);
-static void propagate_binfo_offsets (tree, tree, tree);
+static void propagate_binfo_offsets (tree, tree);
 static void layout_virtual_bases (record_layout_info, splay_tree);
-static tree dfs_set_offset_for_unshared_vbases (tree, void *);
 static void build_vbase_offset_vtbl_entries (tree, vtbl_init_data *);
 static void add_vcall_offset_vtbl_entries_r (tree, vtbl_init_data *);
 static void add_vcall_offset_vtbl_entries_1 (tree, vtbl_init_data *);
@@ -162,10 +161,12 @@ static void build_vcall_offset_vtbl_entries (tree, vtbl_init_data *);
 static void add_vcall_offset (tree, tree, vtbl_init_data *);
 static void layout_vtable_decl (tree, int);
 static tree dfs_find_final_overrider (tree, void *);
+static tree dfs_find_final_overrider_post (tree, void *);
+static tree dfs_find_final_overrider_q (tree, int, void *);
 static tree find_final_overrider (tree, tree, tree);
 static int make_new_vtable (tree, tree);
 static int maybe_indent_hierarchy (FILE *, int, int);
-static void dump_class_hierarchy_r (FILE *, int, tree, tree, int);
+static tree dump_class_hierarchy_r (FILE *, int, tree, tree, int);
 static void dump_class_hierarchy (tree);
 static void dump_array (FILE *, tree);
 static void dump_vtable (tree, tree, tree);
@@ -176,18 +177,14 @@ static void initialize_array (tree, tree);
 static void layout_nonempty_base_or_field (record_layout_info,
                                                   tree, tree, splay_tree);
 static tree end_of_class (tree, int);
-static bool layout_empty_base (tree, tree, splay_tree, tree);
+static bool layout_empty_base (tree, tree, splay_tree);
 static void accumulate_vtbl_inits (tree, tree, tree, tree, tree);
 static tree dfs_accumulate_vtbl_inits (tree, tree, tree, tree,
                                               tree);
 static void build_rtti_vtbl_entries (tree, vtbl_init_data *);
 static void build_vcall_and_vbase_vtbl_entries (tree, 
                                                        vtbl_init_data *);
-static void force_canonical_binfo_r (tree, tree, tree, tree);
-static void force_canonical_binfo (tree, tree, tree, tree);
-static tree dfs_unshared_virtual_bases (tree, void *);
 static void mark_primary_bases (tree);
-static tree mark_primary_virtual_base (tree, tree);
 static void clone_constructors_and_destructors (tree);
 static tree build_clone (tree, tree);
 static void update_vtable_entry_for_fn (tree, tree, tree, tree *, unsigned);
@@ -197,10 +194,8 @@ static void build_vtt (tree);
 static tree binfo_ctor_vtable (tree);
 static tree *build_vtt_inits (tree, tree, tree *, tree *);
 static tree dfs_build_secondary_vptr_vtt_inits (tree, void *);
-static tree dfs_ctor_vtable_bases_queue_p (tree, void *data);
+static tree dfs_ctor_vtable_bases_queue_p (tree, int, void *data);
 static tree dfs_fixup_binfo_vtbls (tree, void *);
-static tree get_original_base (tree, tree);
-static tree dfs_get_primary_binfo (tree, void*);
 static int record_subobject_offset (tree, tree, splay_tree);
 static int check_subobject_offset (tree, tree, splay_tree);
 static int walk_subobject_offsets (tree, subobject_offset_fn,
@@ -212,7 +207,6 @@ static int splay_tree_compare_integer_csts (splay_tree_key k1,
 static void warn_about_ambiguous_bases (tree);
 static bool type_requires_array_cookie (tree);
 static bool contains_empty_class_p (tree);
-static tree dfs_base_derived_from (tree, void *);
 static bool base_derived_from (tree, tree);
 static int empty_base_at_nonzero_offset_p (tree, tree, splay_tree);
 static tree end_of_base (tree);
@@ -308,10 +302,25 @@ build_base_path (enum tree_code code,
       /* Going via virtual base V_BINFO.  We need the static offset
          from V_BINFO to BINFO, and the dynamic offset from D_BINFO to
          V_BINFO.  That offset is an entry in D_BINFO's vtable.  */
-      tree v_offset = build_vfield_ref (build_indirect_ref (expr, NULL),
-                                       TREE_TYPE (TREE_TYPE (expr)));
-      
-      v_binfo = binfo_for_vbase (BINFO_TYPE (v_binfo), BINFO_TYPE (d_binfo));
+      tree v_offset;
+
+      if (fixed_type_p < 0 && in_base_initializer)
+       {
+         /* In a base member initializer, we cannot rely on
+            the vtable being set up. We have to use the vtt_parm.  */
+         tree derived = BINFO_INHERITANCE_CHAIN (v_binfo);
+         
+         v_offset = build (PLUS_EXPR, TREE_TYPE (current_vtt_parm),
+                           current_vtt_parm, BINFO_VPTR_INDEX (derived));
+         
+         v_offset = build1 (INDIRECT_REF,
+                            TREE_TYPE (TYPE_VFIELD (BINFO_TYPE (derived))),
+                            v_offset);
+         
+       }
+      else
+       v_offset = build_vfield_ref (build_indirect_ref (expr, NULL),
+                                    TREE_TYPE (TREE_TYPE (expr)));
       
       v_offset = build (PLUS_EXPR, TREE_TYPE (v_offset),
                        v_offset,  BINFO_VPTR_FIELD (v_binfo));
@@ -443,10 +452,8 @@ build_vtbl_ref_1 (tree instance, tree idx)
     }
 
   if (!vtbl)
-    {
-      vtbl = build_vfield_ref (instance, basetype);
-    }
-
+    vtbl = build_vfield_ref (instance, basetype);
+  
   assemble_external (vtbl);
 
   aref = build_array_ref (vtbl, idx);
@@ -523,6 +530,12 @@ build_vtable (tree class_type, tree name, tree vtable_type)
   TREE_READONLY (decl) = 1;
   DECL_VIRTUAL_P (decl) = 1;
   DECL_ALIGN (decl) = TARGET_VTABLE_ENTRY_ALIGN;
+  DECL_VTABLE_OR_VTT_P (decl) = 1;
+
+  /* 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));
 
   import_export_vtable (decl, class_type, 0);
 
@@ -543,14 +556,9 @@ get_vtable_decl (tree type, int complete)
   if (CLASSTYPE_VTABLES (type))
     return CLASSTYPE_VTABLES (type);
   
-  decl = build_vtable (type, get_vtable_name (type), void_type_node);
+  decl = build_vtable (type, get_vtable_name (type), vtbl_type_node);
   CLASSTYPE_VTABLES (type) = decl;
 
-  /* 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));
-
   if (complete)
     {
       DECL_EXTERNAL (decl) = 1;
@@ -592,7 +600,7 @@ build_primary_vtable (tree binfo, tree type)
   
   if (binfo)
     {
-      if (BINFO_NEW_VTABLE_MARKED (binfo, type))
+      if (BINFO_NEW_VTABLE_MARKED (binfo))
        /* We have already created a vtable for this base, so there's
           no need to do it again.  */
        return 0;
@@ -604,8 +612,7 @@ build_primary_vtable (tree binfo, tree type)
     }
   else
     {
-      my_friendly_assert (TREE_CODE (TREE_TYPE (decl)) == VOID_TYPE,
-                          20000118);
+      my_friendly_assert (TREE_TYPE (decl) == vtbl_type_node, 20000118);
       virtuals = NULL_TREE;
     }
 
@@ -618,7 +625,7 @@ build_primary_vtable (tree binfo, tree type)
      on our first approximation.  */
   TYPE_BINFO_VTABLE (type) = decl;
   TYPE_BINFO_VIRTUALS (type) = virtuals;
-  SET_BINFO_NEW_VTABLE_MARKED (TYPE_BINFO (type), type);
+  SET_BINFO_NEW_VTABLE_MARKED (TYPE_BINFO (type));
   return 1;
 }
 
@@ -637,18 +644,16 @@ build_primary_vtable (tree binfo, tree type)
    can result.  */
 
 static int
-build_secondary_vtable (tree binfo, tree for_type)
+build_secondary_vtable (tree binfo)
 {
-  my_friendly_assert (binfo == CANONICAL_BINFO (binfo, for_type), 20010605);
-
-  if (BINFO_NEW_VTABLE_MARKED (binfo, for_type))
+  if (BINFO_NEW_VTABLE_MARKED (binfo))
     /* We already created a vtable for this base.  There's no need to
        do it again.  */
     return 0;
 
   /* Remember that we've created a vtable for this BINFO, so that we
      don't try to do so again.  */
-  SET_BINFO_NEW_VTABLE_MARKED (binfo, for_type);
+  SET_BINFO_NEW_VTABLE_MARKED (binfo);
   
   /* Make fresh virtual list, so we can smash it later.  */
   BINFO_VIRTUALS (binfo) = copy_virtuals (binfo);
@@ -678,7 +683,7 @@ make_new_vtable (tree t, tree binfo)
        we will fill in all the virtual functions that override the
        virtual functions in these base classes which are not defined
        by the current type.  */
-    return build_secondary_vtable (binfo, t);
+    return build_secondary_vtable (binfo);
 }
 
 /* Make *VIRTUALS, an entry on the BINFO_VIRTUALS list for BINFO
@@ -692,7 +697,7 @@ modify_vtable_entry (tree t,
                      tree binfo, 
                      tree fndecl, 
                      tree delta, 
-                     treevirtuals)
+                     tree *virtuals)
 {
   tree v;
 
@@ -1059,8 +1064,7 @@ alter_access (tree t, tree fdecl, tree access)
   if (!DECL_LANG_SPECIFIC (fdecl))
     retrofit_lang_decl (fdecl);
 
-  if (DECL_DISCRIMINATOR_P (fdecl))
-    abort ();
+  my_friendly_assert (!DECL_DISCRIMINATOR_P (fdecl), 20030624);
 
   elem = purpose_member (t, DECL_ACCESS (fdecl));
   if (elem)
@@ -1082,7 +1086,7 @@ alter_access (tree t, tree fdecl, tree access)
     }
   else
     {
-      enforce_access (t, fdecl);
+      perform_or_defer_access_check (TYPE_BINFO (t), fdecl);
       DECL_ACCESS (fdecl) = tree_cons (t, access, DECL_ACCESS (fdecl));
       return 1;
     }
@@ -1104,6 +1108,9 @@ handle_using_decl (tree using_decl, tree t)
   tree flist = NULL_TREE;
   tree old_value;
 
+  if (ctype == error_mark_node)
+    return;
+
   binfo = lookup_base (t, ctype, ba_any, NULL);
   if (! binfo)
     {
@@ -1296,170 +1303,6 @@ check_bases (tree t,
     }
 }
 
-/* Binfo FROM is within a virtual hierarchy which is being reseated to
-   TO. Move primary information from FROM to TO, and recursively traverse
-   into FROM's bases. The hierarchy is dominated by TYPE.  MAPPINGS is an
-   assoc list of binfos that have already been reseated.  */
-
-static void
-force_canonical_binfo_r (tree to, tree from, tree type, tree mappings)
-{
-  int i, n_baseclasses = BINFO_N_BASETYPES (from);
-
-  my_friendly_assert (to != from, 20010905);
-  BINFO_INDIRECT_PRIMARY_P (to)
-          = BINFO_INDIRECT_PRIMARY_P (from);
-  BINFO_INDIRECT_PRIMARY_P (from) = 0;
-  BINFO_UNSHARED_MARKED (to) = BINFO_UNSHARED_MARKED (from);
-  BINFO_UNSHARED_MARKED (from) = 0;
-  BINFO_LOST_PRIMARY_P (to) = BINFO_LOST_PRIMARY_P (from);
-  BINFO_LOST_PRIMARY_P (from) = 0;
-  if (BINFO_PRIMARY_P (from))
-    {
-      tree primary = BINFO_PRIMARY_BASE_OF (from);
-      tree assoc;
-      
-      /* We might have just moved the primary base too, see if it's on our
-         mappings.  */
-      assoc = purpose_member (primary, mappings);
-      if (assoc)
-        primary = TREE_VALUE (assoc);
-      BINFO_PRIMARY_BASE_OF (to) = primary;
-      BINFO_PRIMARY_BASE_OF (from) = NULL_TREE;
-    }
-  my_friendly_assert (same_type_p (BINFO_TYPE (to), BINFO_TYPE (from)),
-                     20010104);
-  mappings = tree_cons (from, to, mappings);
-
-  if (CLASSTYPE_HAS_PRIMARY_BASE_P (BINFO_TYPE (from))
-      && TREE_VIA_VIRTUAL (CLASSTYPE_PRIMARY_BINFO (BINFO_TYPE (from))))
-    {
-      tree from_primary = get_primary_binfo (from);
-      
-      if (BINFO_PRIMARY_BASE_OF (from_primary) == from)
-       force_canonical_binfo (get_primary_binfo (to), from_primary,
-                              type, mappings);
-    }
-  
-  for (i = 0; i != n_baseclasses; i++)
-    {
-      tree from_binfo = BINFO_BASETYPE (from, i);
-      tree to_binfo = BINFO_BASETYPE (to, i);
-
-      if (TREE_VIA_VIRTUAL (from_binfo))
-        {
-         if (BINFO_PRIMARY_P (from_binfo) &&
-             purpose_member (BINFO_PRIMARY_BASE_OF (from_binfo), mappings))
-           /* This base is a primary of some binfo we have already
-              reseated. We must reseat this one too.  */
-            force_canonical_binfo (to_binfo, from_binfo, type, mappings);
-        }
-      else
-        force_canonical_binfo_r (to_binfo, from_binfo, type, mappings);
-    }
-}
-
-/* FROM is the canonical binfo for a virtual base. It is being reseated to
-   make TO the canonical binfo, within the hierarchy dominated by TYPE.
-   MAPPINGS is an assoc list of binfos that have already been reseated.
-   Adjust any non-virtual bases within FROM, and also move any virtual bases
-   which are canonical.  This complication arises because selecting primary
-   bases walks in inheritance graph order, but we don't share binfos for
-   virtual bases, hence we can fill in the primaries for a virtual base,
-   and then discover that a later base requires the virtual as its
-   primary.  */
-
-static void
-force_canonical_binfo (tree to, tree from, tree type, tree mappings)
-{
-  tree assoc = purpose_member (BINFO_TYPE (to),
-                              CLASSTYPE_VBASECLASSES (type));
-  if (TREE_VALUE (assoc) != to)
-    {
-      TREE_VALUE (assoc) = to;
-      force_canonical_binfo_r (to, from, type, mappings);
-    }
-}
-
-/* Make BASE_BINFO the a primary virtual base within the hierarchy
-   dominated by TYPE. Returns BASE_BINFO, if it is not already one, NULL
-   otherwise (because something else has already made it primary).  */
-
-static tree
-mark_primary_virtual_base (tree base_binfo, tree type)
-{
-  tree shared_binfo = binfo_for_vbase (BINFO_TYPE (base_binfo), type);
-
-  if (BINFO_PRIMARY_P (shared_binfo))
-    {
-      /* It's already allocated in the hierarchy. BINFO won't have a
-         primary base in this hierarchy, even though the complete object
-         BINFO is for, would do.  */
-      return NULL_TREE;
-    }
-     
-  /* We need to make sure that the assoc list
-     CLASSTYPE_VBASECLASSES of TYPE, indicates this particular
-     primary BINFO for the virtual base, as this is the one
-     that'll really exist.  */
-  if (base_binfo != shared_binfo)
-    force_canonical_binfo (base_binfo, shared_binfo, type, NULL);
-
-  return base_binfo;
-}
-
-/* If BINFO is an unmarked virtual binfo for a class with a primary virtual
-   base, then BINFO has no primary base in this graph.  Called from
-   mark_primary_bases.  DATA is the most derived type.  */
-
-static tree
-dfs_unshared_virtual_bases (tree binfo, void* data)
-{
-  tree t = (tree) data;
-  
-  if (!BINFO_UNSHARED_MARKED (binfo)
-      && CLASSTYPE_HAS_PRIMARY_BASE_P (BINFO_TYPE (binfo)))
-    {
-      /* This morally virtual base has a primary base when it
-         is a complete object. We need to locate the shared instance
-         of this binfo in the type dominated by T. We duplicate the
-         primary base information from there to here.  */
-      tree vbase;
-      tree unshared_base;
-      
-      for (vbase = binfo; !TREE_VIA_VIRTUAL (vbase);
-          vbase = BINFO_INHERITANCE_CHAIN (vbase))
-       continue;
-      unshared_base = get_original_base (binfo,
-                                        binfo_for_vbase (BINFO_TYPE (vbase),
-                                                         t));
-      my_friendly_assert (unshared_base != binfo, 20010612);
-      BINFO_LOST_PRIMARY_P (binfo) = BINFO_LOST_PRIMARY_P (unshared_base);
-      if (!BINFO_LOST_PRIMARY_P (binfo))
-       BINFO_PRIMARY_BASE_OF (get_primary_binfo (binfo)) = binfo;
-    }
-  
-  if (binfo != TYPE_BINFO (t))
-    /* The vtable fields will have been copied when duplicating the
-       base binfos. That information is bogus, make sure we don't try
-       and use it.  */
-    BINFO_VTABLE (binfo) = NULL_TREE;
-
-  /* If this is a virtual primary base, make sure its offset matches
-     that which it is primary for.  */
-  if (BINFO_PRIMARY_P (binfo) && TREE_VIA_VIRTUAL (binfo) &&
-      binfo_for_vbase (BINFO_TYPE (binfo), t) == binfo)
-    {
-      tree delta = size_diffop (BINFO_OFFSET (BINFO_PRIMARY_BASE_OF (binfo)),
-                               BINFO_OFFSET (binfo));
-      if (!integer_zerop (delta))
-       propagate_binfo_offsets (binfo, delta, t);
-    }
-  
-  BINFO_UNSHARED_MARKED (binfo) = 0;
-  return NULL;
-}
-
 /* Set BINFO_PRIMARY_BASE_OF for all binfos in the hierarchy
    dominated by TYPE that are primary bases.  */
 
@@ -1471,33 +1314,29 @@ mark_primary_bases (tree type)
   /* Walk the bases in inheritance graph order.  */
   for (binfo = TYPE_BINFO (type); binfo; binfo = TREE_CHAIN (binfo))
     {
-      tree base_binfo;
-      
-      if (!CLASSTYPE_HAS_PRIMARY_BASE_P (BINFO_TYPE (binfo)))
-        /* Not a dynamic base.  */
-        continue;
+      tree base_binfo = get_primary_binfo (binfo);
 
-      base_binfo = get_primary_binfo (binfo);
-
-      if (TREE_VIA_VIRTUAL (base_binfo))
-        base_binfo = mark_primary_virtual_base (base_binfo, type);
-
-      if (base_binfo)
-        BINFO_PRIMARY_BASE_OF (base_binfo) = binfo;
-      else
+      if (!base_binfo)
+       /* Not a dynamic base.  */;
+      else if (BINFO_PRIMARY_P (base_binfo))
        BINFO_LOST_PRIMARY_P (binfo) = 1;
-      
-      BINFO_UNSHARED_MARKED (binfo) = 1;
+      else
+       {
+         BINFO_PRIMARY_BASE_OF (base_binfo) = binfo;
+         /* A virtual binfo might have been copied from within
+            another hierarchy. As we're about to use it as a primary
+            base, make sure the offsets match.  */
+         if (TREE_VIA_VIRTUAL (base_binfo))
+           {
+             tree delta = size_diffop (convert (ssizetype,
+                                                BINFO_OFFSET (binfo)),
+                                       convert (ssizetype,
+                                                BINFO_OFFSET (base_binfo)));
+         
+             propagate_binfo_offsets (base_binfo, delta);
+           }
+       }
     }
-  /* There could remain unshared morally virtual bases which were not
-     visited in the inheritance graph walk. These bases will have lost
-     their virtual primary base (should they have one). We must now
-     find them. Also we must fix up the BINFO_OFFSETs of primary
-     virtual bases. We could not do that as we went along, as they
-     were originally copied from the bases we inherited from by
-     unshare_base_binfos. That may have decided differently about
-     where a virtual primary base went.  */
-  dfs_walk (TYPE_BINFO (type), dfs_unshared_virtual_bases, NULL, type);
 }
 
 /* Make the BINFO the primary base of T.  */
@@ -1802,10 +1641,10 @@ maybe_warn_about_overly_private_class (tree t)
         issues error messages specifically referring to
         constructors/destructors.)  */
       int i;
-      tree binfos = BINFO_BASETYPES (TYPE_BINFO (t));
-      for (i = 0; i < CLASSTYPE_N_BASECLASSES (t); i++)
-       if (TREE_VIA_PUBLIC (TREE_VEC_ELT (binfos, i))
-           || TREE_VIA_PROTECTED (TREE_VEC_ELT (binfos, i)))
+      tree binfo = TYPE_BINFO (t);
+      
+      for (i = 0; i < BINFO_N_BASETYPES (binfo); i++)
+       if (BINFO_BASEACCESS (binfo, i) != access_private_node)
          {
            has_nonprivate_method = 1;
            break;
@@ -2088,78 +1927,6 @@ finish_struct_methods (tree t)
           method_name_cmp);
 }
 
-/* Emit error when a duplicate definition of a type is seen.  Patch up.  */
-
-void
-duplicate_tag_error (tree t)
-{
-  error ("redefinition of `%#T'", t);
-  cp_error_at ("previous definition of `%#T'", 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 binfo = TYPE_BINFO (t);
-      int interface_only = CLASSTYPE_INTERFACE_ONLY (t);
-      int interface_unknown = CLASSTYPE_INTERFACE_UNKNOWN (t);
-      tree template_info = CLASSTYPE_TEMPLATE_INFO (t);
-      int use_template = CLASSTYPE_USE_TEMPLATE (t);
-
-      memset ((char *) TYPE_LANG_SPECIFIC (t), 0, sizeof (struct lang_type));
-      BINFO_BASETYPES(binfo) = NULL_TREE;
-
-      TYPE_LANG_SPECIFIC (t)->u.h.is_lang_type_class = 1;
-      TYPE_BINFO (t) = binfo;
-      CLASSTYPE_INTERFACE_ONLY (t) = interface_only;
-      SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, interface_unknown);
-      TYPE_REDEFINED (t) = 1;
-      CLASSTYPE_TEMPLATE_INFO (t) = template_info;
-      CLASSTYPE_USE_TEMPLATE (t) = use_template;
-      CLASSTYPE_DECL_LIST (t) = NULL_TREE;
-    }
-  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;
-  
-  /* Clear TYPE_LANG_FLAGS -- those in TYPE_LANG_SPECIFIC are cleared above.  */
-  TYPE_LANG_FLAG_0 (t) = 0;
-  TYPE_LANG_FLAG_1 (t) = 0;
-  TYPE_LANG_FLAG_2 (t) = 0;
-  TYPE_LANG_FLAG_3 (t) = 0;
-  TYPE_LANG_FLAG_4 (t) = 0;
-  TYPE_LANG_FLAG_5 (t) = 0;
-  TYPE_LANG_FLAG_6 (t) = 0;
-  /* But not this one.  */
-  SET_IS_AGGR_TYPE (t, 1);
-}
-
 /* Make BINFO's vtable have N entries, including RTTI entries,
    vbase and vcall offsets, etc.  Set its type and call the backend
    to lay it out.  */
@@ -2181,11 +1948,6 @@ layout_vtable_decl (tree binfo, int n)
       TREE_TYPE (vtable) = atype;
       DECL_SIZE (vtable) = DECL_SIZE_UNIT (vtable) = NULL_TREE;
       layout_decl (vtable, 0);
-
-      /* At one time the vtable info was grabbed 2 words at a time.  This
-        fails on SPARC unless you have 8-byte alignment.  */
-      DECL_ALIGN (vtable) = MAX (TYPE_ALIGN (double_type_node),
-                                DECL_ALIGN (vtable));
     }
 }
 
@@ -2220,27 +1982,27 @@ same_signature_p (tree fndecl, tree base_fndecl)
   return 0;
 }
 
-/* Called from base_derived_from via dfs_walk.  */
-
-static tree
-dfs_base_derived_from (tree binfo, void *data)
-{
-  tree base = (tree) data;
-
-  if (same_type_p (TREE_TYPE (base), TREE_TYPE (binfo))
-      && tree_int_cst_equal (BINFO_OFFSET (base), BINFO_OFFSET (binfo)))
-    return error_mark_node;
-
-  return NULL_TREE;
-}
-
 /* Returns TRUE if DERIVED is a binfo containing the binfo BASE as a
    subobject.  */
  
 static bool
 base_derived_from (tree derived, tree base)
 {
-  return dfs_walk (derived, dfs_base_derived_from, NULL, base) != NULL_TREE;
+  tree probe;
+
+  for (probe = base; probe; probe = BINFO_INHERITANCE_CHAIN (probe))
+    {
+      if (probe == derived)
+       return true;
+      else if (TREE_VIA_VIRTUAL (probe))
+       /* If we meet a virtual base, we can't follow the inheritance
+          any more.  See if the complete type of DERIVED contains
+          such a virtual base.  */
+       return purpose_member (BINFO_TYPE (probe),
+                              CLASSTYPE_VBASECLASSES (BINFO_TYPE (derived)))
+         != NULL_TREE;
+    }
+  return false;
 }
 
 typedef struct find_final_overrider_data_s {
@@ -2252,6 +2014,8 @@ typedef struct find_final_overrider_data_s {
   tree most_derived_type;
   /* The candidate overriders.  */
   tree candidates;
+  /* Binfos which inherited virtually on the currrent path.  */
+  tree vpath;
 } find_final_overrider_data;
 
 /* Called from find_final_overrider via dfs_walk.  */
@@ -2261,61 +2025,82 @@ dfs_find_final_overrider (tree binfo, void* data)
 {
   find_final_overrider_data *ffod = (find_final_overrider_data *) data;
 
-  if (same_type_p (BINFO_TYPE (binfo), 
-                  BINFO_TYPE (ffod->declaring_base))
-      && tree_int_cst_equal (BINFO_OFFSET (binfo),
-                            BINFO_OFFSET (ffod->declaring_base)))
-    {
-      tree path;
-      tree method;
-
-      /* We haven't found an overrider yet.  */
-      method = NULL_TREE;
-      /* We've found a path to the declaring base.  Walk down the path
-        looking for an overrider for FN.  */
-      path = reverse_path (binfo);
-      while (!same_type_p (BINFO_TYPE (TREE_VALUE (path)),
-                          ffod->most_derived_type))
-       path = TREE_CHAIN (path);
-      while (path)
+  if (binfo == ffod->declaring_base)
+    {
+      /* We've found a path to the declaring base.  Walk the path from
+        derived to base, looking for an overrider for FN.  */
+      tree path, probe, vpath;
+
+      /* Build the path, using the inheritance chain and record of
+        virtual inheritance.  */
+      for (path = NULL_TREE, probe = binfo, vpath = ffod->vpath;;)
+       {
+         path = tree_cons (NULL_TREE, probe, path);
+         if (same_type_p (BINFO_TYPE (probe), ffod->most_derived_type))
+           break;
+         if (TREE_VIA_VIRTUAL (probe))
+           {
+             probe = TREE_VALUE (vpath);
+             vpath = TREE_CHAIN (vpath);
+           }
+         else
+           probe = BINFO_INHERITANCE_CHAIN (probe);
+       }
+      /* Now walk path, looking for overrides.  */
+      for (; path; path = TREE_CHAIN (path))
        {
-         method = look_for_overrides_here (BINFO_TYPE (TREE_VALUE (path)),
-                                           ffod->fn);
+         tree method = look_for_overrides_here
+           (BINFO_TYPE (TREE_VALUE (path)), ffod->fn);
+         
          if (method)
            {
+             tree *candidate = &ffod->candidates;
              path = TREE_VALUE (path);
+
+             /* Remove any candidates overridden by this new function.  */
+             while (*candidate)
+               {
+                 /* If *CANDIDATE overrides METHOD, then METHOD
+                    cannot override anything else on the list.  */
+                 if (base_derived_from (TREE_VALUE (*candidate), path))
+                   return NULL_TREE;
+                 /* If METHOD overrides *CANDIDATE, remove *CANDIDATE.  */
+                 if (base_derived_from (path, TREE_VALUE (*candidate)))
+                   *candidate = TREE_CHAIN (*candidate);
+                 else
+                   candidate = &TREE_CHAIN (*candidate);
+               }
+             
+             /* Add the new function.  */
+             ffod->candidates = tree_cons (method, path, ffod->candidates);
              break;
            }
-
-         path = TREE_CHAIN (path);
        }
+    }
 
-      /* If we found an overrider, record the overriding function, and
-        the base from which it came.  */
-      if (path)
-       {
-         tree *candidate;
+  return NULL_TREE;
+}
 
-         /* Remove any candidates overridden by this new function.  */
-         candidate = &ffod->candidates;
-         while (*candidate)
-           {
-             /* If *CANDIDATE overrides METHOD, then METHOD
-                cannot override anything else on the list.  */
-             if (base_derived_from (TREE_VALUE (*candidate), path))
-                 return NULL_TREE;
-             /* If METHOD overrides *CANDIDATE, remove *CANDIDATE.  */
-             if (base_derived_from (path, TREE_VALUE (*candidate)))
-               *candidate = TREE_CHAIN (*candidate);
-             else
-               candidate = &TREE_CHAIN (*candidate);
-           }
+static tree
+dfs_find_final_overrider_q (tree derived, int ix, void *data)
+{
+  tree binfo = BINFO_BASETYPE (derived, ix);
+  find_final_overrider_data *ffod = (find_final_overrider_data *) data;
 
-         /* Add the new function.  */
-         ffod->candidates = tree_cons (method, path, ffod->candidates);
-       }
-    }
+  if (TREE_VIA_VIRTUAL (binfo))
+    ffod->vpath = tree_cons (NULL_TREE, derived, ffod->vpath);
+  
+  return binfo;
+}
 
+static tree
+dfs_find_final_overrider_post (tree binfo, void *data)
+{
+  find_final_overrider_data *ffod = (find_final_overrider_data *) data;
+
+  if (TREE_VIA_VIRTUAL (binfo) && TREE_CHAIN (ffod->vpath))
+    ffod->vpath = TREE_CHAIN (ffod->vpath);
+  
   return NULL_TREE;
 }
 
@@ -2354,11 +2139,13 @@ find_final_overrider (tree derived, tree binfo, tree fn)
   ffod.declaring_base = binfo;
   ffod.most_derived_type = BINFO_TYPE (derived);
   ffod.candidates = NULL_TREE;
+  ffod.vpath = NULL_TREE;
 
-  dfs_walk (derived,
-           dfs_find_final_overrider,
-           NULL,
-           &ffod);
+  dfs_walk_real (derived,
+                dfs_find_final_overrider,
+                dfs_find_final_overrider_post,
+                dfs_find_final_overrider_q,
+                &ffod);
 
   /* If there was no winner, issue an error message.  */
   if (!ffod.candidates || TREE_CHAIN (ffod.candidates))
@@ -2448,9 +2235,6 @@ update_vtable_entry_for_fn (tree t, tree binfo, tree fn, tree* virtuals,
        {
          fixed_offset = ssize_int (THUNK_FIXED_OFFSET (fn));
          virtual_offset = THUNK_VIRTUAL_OFFSET (fn);
-         if (virtual_offset)
-           virtual_offset = binfo_for_vbase (BINFO_TYPE (virtual_offset),
-                                             TREE_TYPE (over_return));
        }
       else
        fixed_offset = virtual_offset = NULL_TREE;
@@ -2477,11 +2261,10 @@ update_vtable_entry_for_fn (tree t, tree binfo, tree fn, tree* virtuals,
                     base and adjust the fixed offset to be from there.  */
                  while (!TREE_VIA_VIRTUAL (thunk_binfo))
                    thunk_binfo = BINFO_INHERITANCE_CHAIN (thunk_binfo);
-             
-                 virtual_offset = binfo_for_vbase (BINFO_TYPE (thunk_binfo),
-                                                   TREE_TYPE (over_return));
+
+                 virtual_offset = thunk_binfo;
                  offset = size_binop (MINUS_EXPR, offset,
-                                       BINFO_OFFSET (virtual_offset));
+                                      BINFO_OFFSET (virtual_offset));
                }
              if (fixed_offset)
                /* There was an existing fixed offset, this must be
@@ -2520,8 +2303,11 @@ update_vtable_entry_for_fn (tree t, tree binfo, tree fn, tree* virtuals,
       /* If we find a virtual base, and we haven't yet found the
         overrider, then there is a virtual base between the
         declaring base (first_defn) and the final overrider.  */
-      if (!virtual_base && TREE_VIA_VIRTUAL (b))
-       virtual_base = b;
+      if (TREE_VIA_VIRTUAL (b))
+       {
+         virtual_base = b;
+         break;
+       }
     }
 
   if (overrider_fn != overrider_target && !virtual_base)
@@ -2619,7 +2405,7 @@ dfs_modify_vtables (tree binfo, void* data)
                                    &virtuals, ix);
     }
 
-  SET_BINFO_MARKED (binfo);
+  BINFO_MARKED (binfo) = 1;
 
   return NULL_TREE;
 }
@@ -2640,11 +2426,8 @@ modify_all_vtables (tree t, tree virtuals)
   tree *fnsp;
 
   /* Update all of the vtables.  */
-  dfs_walk (binfo, 
-           dfs_modify_vtables, 
-           dfs_unmarked_real_bases_queue_p,
-           t);
-  dfs_walk (binfo, dfs_unmark, dfs_marked_real_bases_queue_p, t);
+  dfs_walk (binfo, dfs_modify_vtables, unmarkedp, t);
+  dfs_walk (binfo, dfs_unmark, markedp, t);
 
   /* Add virtual functions not already in our primary vtable. These
      will be both those introduced by this class, and those overridden
@@ -2684,11 +2467,19 @@ get_basefndecls (tree name, tree t)
   int n_baseclasses = CLASSTYPE_N_BASECLASSES (t);
   int i;
 
-  for (methods = TYPE_METHODS (t); methods; methods = TREE_CHAIN (methods))
-    if (TREE_CODE (methods) == FUNCTION_DECL
-       && DECL_VINDEX (methods) != NULL_TREE
-       && DECL_NAME (methods) == name)
-      base_fndecls = tree_cons (NULL_TREE, methods, base_fndecls);
+  /* Find virtual functions in T with the indicated NAME.  */
+  i = lookup_fnfields_1 (t, name);
+  if (i != -1)
+    for (methods = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (t), i);
+        methods;
+        methods = OVL_NEXT (methods))
+      {
+       tree method = OVL_CURRENT (methods);
+
+       if (TREE_CODE (method) == FUNCTION_DECL
+           && DECL_VINDEX (method))
+         base_fndecls = tree_cons (NULL_TREE, method, base_fndecls);
+      }
 
   if (base_fndecls)
     return base_fndecls;
@@ -3087,31 +2878,12 @@ check_bitfield_decl (tree field)
     {
       DECL_SIZE (field) = convert (bitsizetype, w);
       DECL_BIT_FIELD (field) = 1;
-
-      if (integer_zerop (w)
-         && ! (* targetm.ms_bitfield_layout_p) (DECL_FIELD_CONTEXT (field)))
-       {
-#ifdef EMPTY_FIELD_BOUNDARY
-         DECL_ALIGN (field) = MAX (DECL_ALIGN (field), 
-                                   EMPTY_FIELD_BOUNDARY);
-#endif
-#ifdef PCC_BITFIELD_TYPE_MATTERS
-         if (PCC_BITFIELD_TYPE_MATTERS)
-           {
-             DECL_ALIGN (field) = MAX (DECL_ALIGN (field), 
-                                       TYPE_ALIGN (type));
-             DECL_USER_ALIGN (field) |= TYPE_USER_ALIGN (type);
-           }
-#endif
-       }
     }
   else
     {
       /* Non-bit-fields are aligned for their type.  */
       DECL_BIT_FIELD (field) = 0;
       CLEAR_DECL_C_BIT_FIELD (field);
-      DECL_ALIGN (field) = MAX (DECL_ALIGN (field), TYPE_ALIGN (type));
-      DECL_USER_ALIGN (field) |= TYPE_USER_ALIGN (type);
     }
 }
 
@@ -3192,15 +2964,6 @@ check_field_decl (tree field,
        cp_error_at ("multiple fields in union `%T' initialized");
       *any_default_members = 1;
     }
-
-  /* Non-bit-fields are aligned for their type, except packed fields
-     which require only BITS_PER_UNIT alignment.  */
-  DECL_ALIGN (field) = MAX (DECL_ALIGN (field), 
-                           (DECL_PACKED (field) 
-                            ? BITS_PER_UNIT
-                            : TYPE_ALIGN (TREE_TYPE (field))));
-  if (! DECL_PACKED (field))
-    DECL_USER_ALIGN (field) |= TYPE_USER_ALIGN (TREE_TYPE (field));
 }
 
 /* Check the data members (both static and non-static), class-scoped
@@ -3639,22 +3402,14 @@ walk_subobject_offsets (tree type,
                 virtual.  (If it is non-virtual, then it was walked
                 above.)  */
              vbase = get_primary_binfo (type_binfo);
-             if (vbase && TREE_VIA_VIRTUAL (vbase))
+             if (vbase && TREE_VIA_VIRTUAL (vbase)
+                 && BINFO_PRIMARY_BASE_OF (vbase) == type_binfo)
                {
-                 tree derived = type_binfo;
-                 while (BINFO_INHERITANCE_CHAIN (derived))
-                   derived = BINFO_INHERITANCE_CHAIN (derived);
-                 derived = TREE_TYPE (derived);
-                 vbase = binfo_for_vbase (TREE_TYPE (vbase), derived);
-
-                 if (BINFO_PRIMARY_BASE_OF (vbase) == type_binfo)
-                   {
-                     r = (walk_subobject_offsets 
-                          (vbase, f, offset,
-                           offsets, max_offset, /*vbases_p=*/0));
-                     if (r)
-                       return r;
-                   }
+                 r = (walk_subobject_offsets 
+                      (vbase, f, offset,
+                       offsets, max_offset, /*vbases_p=*/0));
+                 if (r)
+                   return r;
                }
            }
        }
@@ -3774,7 +3529,6 @@ layout_nonempty_base_or_field (record_layout_info rli,
                               tree binfo, 
                               splay_tree offsets)
 {
-  tree t = rli->t;
   tree offset = NULL_TREE;
   bool field_p;
   tree type;
@@ -3855,8 +3609,7 @@ layout_nonempty_base_or_field (record_layout_info rli,
     propagate_binfo_offsets (binfo, 
                             size_diffop (convert (ssizetype, offset),
                                          convert (ssizetype, 
-                                                  BINFO_OFFSET (binfo))),
-                            t);
+                                                  BINFO_OFFSET (binfo))));
 }
 
 /* Returns true if TYPE is empty and OFFSET is nonzero.  */
@@ -3876,7 +3629,7 @@ empty_base_at_nonzero_offset_p (tree type,
    type.  Return nonzero iff we added it at the end.  */
 
 static bool
-layout_empty_base (tree binfo, tree eoc, splay_tree offsets, tree t)
+layout_empty_base (tree binfo, tree eoc, splay_tree offsets)
 {
   tree alignment;
   tree basetype = BINFO_TYPE (binfo);
@@ -3903,7 +3656,7 @@ layout_empty_base (tree binfo, tree eoc, splay_tree offsets, tree t)
       /* That didn't work.  Now, we move forward from the next
         available spot in the class.  */
       atend = true;
-      propagate_binfo_offsets (binfo, convert (ssizetype, eoc), t);
+      propagate_binfo_offsets (binfo, convert (ssizetype, eoc));
       while (1) 
        {
          if (!layout_conflict_p (binfo,
@@ -3914,7 +3667,7 @@ layout_empty_base (tree binfo, tree eoc, splay_tree offsets, tree t)
            break;
 
          /* There's overlap here, too.  Bump along to the next spot.  */
-         propagate_binfo_offsets (binfo, alignment, t);
+         propagate_binfo_offsets (binfo, alignment);
        }
     }
   return atend;
@@ -3978,7 +3731,7 @@ build_base_field (record_layout_info rli, tree binfo,
         byte-aligned.  */
       eoc = round_up (rli_size_unit_so_far (rli),
                      CLASSTYPE_ALIGN_UNIT (basetype));
-      atend = layout_empty_base (binfo, eoc, offsets, t);
+      atend = layout_empty_base (binfo, eoc, offsets);
       /* A nearly-empty class "has no proper base class that is empty,
         not morally virtual, and at an offset other than zero."  */
       if (!TREE_VIA_VIRTUAL (binfo) && CLASSTYPE_NEARLY_EMPTY_P (t))
@@ -4057,11 +3810,9 @@ build_base_fields (record_layout_info rli,
       if (base_binfo == CLASSTYPE_PRIMARY_BINFO (t))
        continue;
 
-      /* A primary virtual base class is allocated just like any other
-        base class, but a non-primary virtual base is allocated
-        later, in layout_virtual_bases.  */
-      if (TREE_VIA_VIRTUAL (base_binfo) 
-         && !BINFO_PRIMARY_P (base_binfo))
+      /* Virtual bases are added at the end (a primary virtual base
+        will have already been added).  */
+      if (TREE_VIA_VIRTUAL (base_binfo))
        continue;
 
       next_field = build_base_field (rli, base_binfo,
@@ -4584,8 +4335,6 @@ create_vtable_ptr (tree t, tree* virtuals_p)
       DECL_ARTIFICIAL (field) = 1;
       DECL_FIELD_CONTEXT (field) = t;
       DECL_FCONTEXT (field) = t;
-      DECL_ALIGN (field) = TYPE_ALIGN (vtbl_ptr_type_node);
-      DECL_USER_ALIGN (field) = TYPE_USER_ALIGN (vtbl_ptr_type_node);
       
       TYPE_VFIELD (t) = field;
       
@@ -4658,7 +4407,7 @@ fixup_inline_methods (tree type)
    OFFSET, which is a type offset, is number of bytes.  */
 
 static void
-propagate_binfo_offsets (tree binfo, tree offset, tree t)
+propagate_binfo_offsets (tree binfo, tree offset)
 {
   int i;
   tree primary_binfo;
@@ -4699,37 +4448,11 @@ propagate_binfo_offsets (tree binfo, tree offset, tree t)
 
       /* Skip virtual bases that aren't our canonical primary base.  */
       if (TREE_VIA_VIRTUAL (base_binfo)
-         && (BINFO_PRIMARY_BASE_OF (base_binfo) != binfo
-             || base_binfo != binfo_for_vbase (BINFO_TYPE (base_binfo), t)))
+         && BINFO_PRIMARY_BASE_OF (base_binfo) != binfo)
        continue;
 
-      propagate_binfo_offsets (base_binfo, offset, t);
-    }
-}
-
-/* Called via dfs_walk from layout_virtual bases.  */
-
-static tree
-dfs_set_offset_for_unshared_vbases (tree binfo, void* data)
-{
-  /* If this is a virtual base, make sure it has the same offset as
-     the shared copy.  If it's a primary base, then we know it's
-     correct.  */
-  if (TREE_VIA_VIRTUAL (binfo))
-    {
-      tree t = (tree) data;
-      tree vbase;
-      tree offset;
-      
-      vbase = binfo_for_vbase (BINFO_TYPE (binfo), t);
-      if (vbase != binfo)
-       {
-         offset = size_diffop (BINFO_OFFSET (vbase), BINFO_OFFSET (binfo));
-         propagate_binfo_offsets (binfo, offset, t);
-       }
+      propagate_binfo_offsets (base_binfo, offset);
     }
-
-  return NULL_TREE;
 }
 
 /* Set BINFO_OFFSET for all of the virtual bases for RLI->T.  Update
@@ -4739,7 +4462,7 @@ dfs_set_offset_for_unshared_vbases (tree binfo, void* data)
 static void
 layout_virtual_bases (record_layout_info rli, splay_tree offsets)
 {
-  tree vbases;
+  tree vbase;
   tree t = rli->t;
   bool first_vbase = true;
   tree *next_field;
@@ -4771,17 +4494,11 @@ layout_virtual_bases (record_layout_info rli, splay_tree offsets)
   /* Go through the virtual bases, allocating space for each virtual
      base that is not already a primary base class.  These are
      allocated in inheritance graph order.  */
-  for (vbases = TYPE_BINFO (t);
-       vbases; 
-       vbases = TREE_CHAIN (vbases))
+  for (vbase = TYPE_BINFO (t); vbase; vbase = TREE_CHAIN (vbase))
     {
-      tree vbase;
-
-      if (!TREE_VIA_VIRTUAL (vbases))
+      if (!TREE_VIA_VIRTUAL (vbase))
        continue;
 
-      vbase = binfo_for_vbase (BINFO_TYPE (vbases), t);
-
       if (!BINFO_PRIMARY_P (vbase))
        {
          tree basetype = TREE_TYPE (vbase);
@@ -4812,13 +4529,6 @@ layout_virtual_bases (record_layout_info rli, splay_tree offsets)
          first_vbase = false;
        }
     }
-
-  /* Now, go through the TYPE_BINFO hierarchy, setting the
-     BINFO_OFFSETs correctly for all non-primary copies of the virtual
-     bases and their direct and indirect bases.  The ambiguity checks
-     in lookup_base depend on the BINFO_OFFSETs being set
-     correctly.  */
-  dfs_walk (TYPE_BINFO (t), dfs_set_offset_for_unshared_vbases, NULL, t);
 }
 
 /* Returns the offset of the byte just past the end of the base class
@@ -4858,7 +4568,7 @@ end_of_class (tree t, int include_virtuals_p)
 
       if (!include_virtuals_p
          && TREE_VIA_VIRTUAL (binfo) 
-         && !BINFO_PRIMARY_P (binfo))
+         && BINFO_PRIMARY_BASE_OF (binfo) != TYPE_BINFO (t))
        continue;
 
       offset = end_of_base (binfo);
@@ -5017,7 +4727,6 @@ layout_class_type (tree t, tree *virtuals_p)
     {
       tree type;
       tree padding;
-      bool was_unnamed_p = false;
 
       /* We still pass things that aren't non-static data members to
         the back-end, in case it wants to do something with them.  */
@@ -5040,6 +4749,8 @@ layout_class_type (tree t, tree *virtuals_p)
        }
 
       type = TREE_TYPE (field);
+      
+      padding = NULL_TREE;
 
       /* If this field is a bit-field whose width is greater than its
         type, then there are some special rules for allocating
@@ -5049,6 +4760,7 @@ layout_class_type (tree t, tree *virtuals_p)
        {
          integer_type_kind itk;
          tree integer_type;
+         bool was_unnamed_p = false;
          /* We must allocate the bits as if suitably aligned for the
             longest integer type that fits in this many bits.  type
             of the field.  Then, we are supposed to use the left over
@@ -5063,19 +4775,26 @@ layout_class_type (tree t, tree *virtuals_p)
             type that fits.  */
          integer_type = integer_types[itk - 1];
 
-         if (abi_version_at_least (2) && TREE_CODE (t) == UNION_TYPE)
-           /* In a union, the padding field must have the full width
-              of the bit-field; all fields start at offset zero.  */
-           padding = DECL_SIZE (field);
-         else
+         /* Figure out how much additional padding is required.  GCC
+            3.2 always created a padding field, even if it had zero
+            width.  */
+         if (!abi_version_at_least (2)
+             || INT_CST_LT (TYPE_SIZE (integer_type), DECL_SIZE (field)))
            {
-             if (warn_abi && TREE_CODE (t) == UNION_TYPE)
-               warning ("size assigned to `%T' may not be "
-                        "ABI-compliant and may change in a future "
-                        "version of GCC", 
-                        t);
-             padding = size_binop (MINUS_EXPR, DECL_SIZE (field),
-                                   TYPE_SIZE (integer_type));
+             if (abi_version_at_least (2) && TREE_CODE (t) == UNION_TYPE)
+               /* In a union, the padding field must have the full width
+                  of the bit-field; all fields start at offset zero.  */
+               padding = DECL_SIZE (field);
+             else
+               {
+                 if (warn_abi && TREE_CODE (t) == UNION_TYPE)
+                   warning ("size assigned to `%T' may not be "
+                            "ABI-compliant and may change in a future "
+                            "version of GCC", 
+                            t);
+                 padding = size_binop (MINUS_EXPR, DECL_SIZE (field),
+                                       TYPE_SIZE (integer_type));
+               }
            }
 #ifdef PCC_BITFIELD_TYPE_MATTERS
          /* An unnamed bitfield does not normally affect the
@@ -5093,16 +4812,18 @@ layout_class_type (tree t, tree *virtuals_p)
          DECL_SIZE (field) = TYPE_SIZE (integer_type);
          DECL_ALIGN (field) = TYPE_ALIGN (integer_type);
          DECL_USER_ALIGN (field) = TYPE_USER_ALIGN (integer_type);
+         layout_nonempty_base_or_field (rli, field, NULL_TREE,
+                                        empty_base_offsets);
+         if (was_unnamed_p)
+           DECL_NAME (field) = NULL_TREE;
+         /* Now that layout has been performed, set the size of the
+            field to the size of its declared type; the rest of the
+            field is effectively invisible.  */
+         DECL_SIZE (field) = TYPE_SIZE (type);
        }
       else
-       padding = NULL_TREE;
-
-      layout_nonempty_base_or_field (rli, field, NULL_TREE,
-                                    empty_base_offsets);
-      /* If the bit-field had no name originally, remove the name
-        now.  */
-      if (was_unnamed_p)
-       DECL_NAME (field) = NULL_TREE;
+       layout_nonempty_base_or_field (rli, field, NULL_TREE,
+                                      empty_base_offsets);
 
       /* Remember the location of any empty classes in FIELD.  */
       if (abi_version_at_least (2))
@@ -5145,8 +4866,7 @@ layout_class_type (tree t, tree *virtuals_p)
                                      char_type_node); 
          DECL_BIT_FIELD (padding_field) = 1;
          DECL_SIZE (padding_field) = padding;
-         DECL_ALIGN (padding_field) = 1;
-         DECL_USER_ALIGN (padding_field) = 0;
+         DECL_CONTEXT (padding_field) = t;
          layout_nonempty_base_or_field (rli, padding_field,
                                         NULL_TREE, 
                                         empty_base_offsets);
@@ -5194,16 +4914,28 @@ layout_class_type (tree t, tree *virtuals_p)
        }
       else
        {
+         tree eoc;
+
+         /* If the ABI version is not at least two, and the last
+            field was a bit-field, RLI may not be on a byte
+            boundary.  In particular, rli_size_unit_so_far might
+            indicate the last complete byte, while rli_size_so_far
+            indicates the total number of bits used.  Therefore,
+            rli_size_so_far, rather than rli_size_unit_so_far, is
+            used to compute TYPE_SIZE_UNIT.  */
+         eoc = end_of_class (t, /*include_virtuals_p=*/0);
          TYPE_SIZE_UNIT (base_t) 
            = size_binop (MAX_EXPR,
-                         rli_size_unit_so_far (rli),
-                         end_of_class (t, /*include_virtuals_p=*/0));
+                         convert (sizetype,
+                                  size_binop (CEIL_DIV_EXPR,
+                                              rli_size_so_far (rli),
+                                              bitsize_int (BITS_PER_UNIT))),
+                         eoc);
          TYPE_SIZE (base_t) 
            = size_binop (MAX_EXPR,
                          rli_size_so_far (rli),
                          size_binop (MULT_EXPR,
-                                     convert (bitsizetype,
-                                              TYPE_SIZE_UNIT (base_t)),
+                                     convert (bitsizetype, eoc),
                                      bitsize_int (BITS_PER_UNIT)));
        }
       TYPE_ALIGN (base_t) = rli->record_align;
@@ -5330,7 +5062,7 @@ finish_struct_1 (tree t)
   check_bases_and_members (t);
 
   /* Find the key method */
-    if (TYPE_CONTAINS_VPTR_P (t))
+  if (TYPE_CONTAINS_VPTR_P (t))
     {
       CLASSTYPE_KEY_METHOD (t) = key_method (t);
 
@@ -5379,7 +5111,7 @@ finish_struct_1 (tree t)
       /* We must enter these virtuals into the table.  */
       if (!CLASSTYPE_HAS_PRIMARY_BASE_P (t))
        build_primary_vtable (NULL_TREE, t);
-      else if (! BINFO_NEW_VTABLE_MARKED (TYPE_BINFO (t), t))
+      else if (! BINFO_NEW_VTABLE_MARKED (TYPE_BINFO (t)))
        /* Here we know enough to change the type of our virtual
           function table, but we will wait until later this function.  */
        build_primary_vtable (CLASSTYPE_PRIMARY_BINFO (t), t);
@@ -5497,7 +5229,6 @@ unreverse_member_declarations (tree t)
   /* The following lists are all in reverse order.  Put them in
      declaration order now.  */
   TYPE_METHODS (t) = nreverse (TYPE_METHODS (t));
-  CLASSTYPE_TAGS (t) = nreverse (CLASSTYPE_TAGS (t));
   CLASSTYPE_DECL_LIST (t) = nreverse (CLASSTYPE_DECL_LIST (t));
 
   /* Actually, for the TYPE_FIELDS, only the non TYPE_DECLs are in
@@ -5522,8 +5253,7 @@ unreverse_member_declarations (tree t)
 tree
 finish_struct (tree t, tree attributes)
 {
-  const char *saved_filename = input_filename;
-  int saved_lineno = lineno;
+  location_t saved_loc = input_location;
 
   /* Now that we've got all the field declarations, reverse everything
      as necessary.  */
@@ -5533,8 +5263,7 @@ finish_struct (tree t, tree attributes)
 
   /* Nadger the current location so that diagnostics point to the start of
      the struct, not the end.  */
-  input_filename = DECL_SOURCE_FILE (TYPE_NAME (t));
-  lineno = DECL_SOURCE_LINE (TYPE_NAME (t));
+  input_location = DECL_SOURCE_LOCATION (TYPE_NAME (t));
 
   if (processing_template_decl)
     {
@@ -5544,8 +5273,7 @@ finish_struct (tree t, tree attributes)
   else
     finish_struct_1 (t);
 
-  input_filename = saved_filename;
-  lineno = saved_lineno;
+  input_location = saved_loc;
 
   TYPE_BEING_DEFINED (t) = 0;
 
@@ -5663,11 +5391,21 @@ fixed_type_or_null (tree instance, int* nonnull, int* cdtorp)
           /* Reference variables should be references to objects.  */
           if (nonnull)
            *nonnull = 1;
-
-         if (TREE_CODE (instance) == VAR_DECL
-             && DECL_INITIAL (instance))
-           return fixed_type_or_null (DECL_INITIAL (instance),
-                                      nonnull, cdtorp);
+         
+         /* DECL_VAR_MARKED_P is used to prevent recursion; a
+            variable's initializer may refer to the variable
+            itself.  */
+         if (TREE_CODE (instance) == VAR_DECL 
+             && DECL_INITIAL (instance)
+             && !DECL_VAR_MARKED_P (instance))
+           {
+             tree type;
+             DECL_VAR_MARKED_P (instance) = 1;
+             type = fixed_type_or_null (DECL_INITIAL (instance),
+                                        nonnull, cdtorp);
+             DECL_VAR_MARKED_P (instance) = 0;
+             return type;
+           }
        }
       return NULL_TREE;
 
@@ -5717,15 +5455,6 @@ init_class_processing (void)
                                    * sizeof (struct class_stack_node));
   VARRAY_TREE_INIT (local_classes, 8, "local_classes");
 
-  access_default_node = build_int_2 (0, 0);
-  access_public_node = build_int_2 (ak_public, 0);
-  access_protected_node = build_int_2 (ak_protected, 0);
-  access_private_node = build_int_2 (ak_private, 0);
-  access_default_virtual_node = build_int_2 (4, 0);
-  access_public_virtual_node = build_int_2 (4 | ak_public, 0);
-  access_protected_virtual_node = build_int_2 (4 | ak_protected, 0);
-  access_private_virtual_node = build_int_2 (4 | ak_private, 0);
-
   ridpointers[(int) RID_PUBLIC] = access_public_node;
   ridpointers[(int) RID_PRIVATE] = access_private_node;
   ridpointers[(int) RID_PROTECTED] = access_protected_node;
@@ -5834,7 +5563,7 @@ pushclass (tree type, bool modify)
          unuse_fields (type);
        }
 
-      storetags (CLASSTYPE_TAGS (type));
+      cxx_remember_type_decls (CLASSTYPE_NESTED_UTDS (type));
     }
 }
 
@@ -6172,7 +5901,8 @@ cannot resolve overloaded function `%D' based on conversion to type `%T'",
            continue;
 
          /* Instantiate the template.  */
-         instantiation = instantiate_template (fn, targs);
+         instantiation = instantiate_template (fn, targs,
+                                               complain ? tf_error : tf_none);
          if (instantiation == error_mark_node)
            /* Instantiation failed.  */
            continue;
@@ -6289,8 +6019,6 @@ tree
 instantiate_type (tree lhstype, tree rhs, tsubst_flags_t flags)
 {
   int complain = (flags & tf_error);
-  int strict = (flags & tf_no_attributes)
-               ? COMPARE_NO_ATTRIBUTES : COMPARE_STRICT;
   int allow_ptrmem = flags & tf_ptrmem_ok;
   
   flags &= ~tf_ptrmem_ok;
@@ -6304,7 +6032,7 @@ instantiate_type (tree lhstype, tree rhs, tsubst_flags_t flags)
 
   if (TREE_TYPE (rhs) != NULL_TREE && ! (type_unknown_p (rhs)))
     {
-      if (comptypes (lhstype, TREE_TYPE (rhs), strict))
+      if (same_type_p (lhstype, TREE_TYPE (rhs)))
        return rhs;
       if (flag_ms_extensions 
          && TYPE_PTRMEMFUNC_P (lhstype)
@@ -6766,102 +6494,24 @@ get_vtbl_decl_for_binfo (tree binfo)
   return decl;
 }
 
-/* Called from get_primary_binfo via dfs_walk.  DATA is a TREE_LIST
-   who's TREE_PURPOSE is the TYPE of the required primary base and
-   who's TREE_VALUE is a list of candidate binfos that we fill in.  */
-
-static tree
-dfs_get_primary_binfo (tree binfo, void* data)
-{
-  tree cons = (tree) data;
-  tree primary_base = TREE_PURPOSE (cons);
 
-  if (TREE_VIA_VIRTUAL (binfo) 
-      && same_type_p (BINFO_TYPE (binfo), primary_base))
-    /* This is the right type of binfo, but it might be an unshared
-       instance, and the shared instance is later in the dfs walk.  We
-       must keep looking.  */
-    TREE_VALUE (cons) = tree_cons (NULL, binfo, TREE_VALUE (cons));
-  
-  return NULL_TREE;
-}
-
-/* Returns the unshared binfo for the primary base of BINFO.  Note
-   that in a complex hierarchy the resulting BINFO may not actually
-   *be* primary.  In particular if the resulting BINFO is a virtual
-   base, and it occurs elsewhere in the hierarchy, then this
-   occurrence may not actually be a primary base in the complete
-   object.  Check BINFO_PRIMARY_P to be sure.  */
+/* Returns the binfo for the primary base of BINFO.  If the resulting
+   BINFO is a virtual base, and it is inherited elsewhere in the
+   hierarchy, then the returned binfo might not be the primary base of
+   BINFO in the complete object.  Check BINFO_PRIMARY_P or
+   BINFO_LOST_PRIMARY_P to be sure.  */
 
 tree
 get_primary_binfo (tree binfo)
 {
   tree primary_base;
-  tree result = NULL_TREE;
-  tree virtuals;
+  tree result;
   
   primary_base = CLASSTYPE_PRIMARY_BINFO (BINFO_TYPE (binfo));
   if (!primary_base)
     return NULL_TREE;
 
-  /* A non-virtual primary base is always a direct base, and easy to
-     find.  */
-  if (!TREE_VIA_VIRTUAL (primary_base))
-    {
-      int i;
-
-      /* Scan the direct basetypes until we find a base with the same
-        type as the primary base.  */
-      for (i = 0; i < BINFO_N_BASETYPES (binfo); ++i)
-       {
-         tree base_binfo = BINFO_BASETYPE (binfo, i);
-         
-         if (same_type_p (BINFO_TYPE (base_binfo),
-                          BINFO_TYPE (primary_base)))
-           return base_binfo;
-       }
-
-      /* We should always find the primary base.  */
-      abort ();
-    }
-
-  /* For a primary virtual base, we have to scan the entire hierarchy
-     rooted at BINFO; the virtual base could be an indirect virtual
-     base.  There could be more than one instance of the primary base
-     in the hierarchy, and if one is the canonical binfo we want that
-     one.  If it exists, it should be the first one we find, but as a
-     consistency check we find them all and make sure.  */
-  virtuals = build_tree_list (BINFO_TYPE (primary_base), NULL_TREE);
-  dfs_walk (binfo, dfs_get_primary_binfo, NULL, virtuals);
-  virtuals = TREE_VALUE (virtuals);
-  
-  /* We must have found at least one instance.  */
-  my_friendly_assert (virtuals, 20010612);
-
-  if (TREE_CHAIN (virtuals))
-    {
-      /* We found more than one instance of the base.  If one is the
-        canonical one, choose that one.  */
-      tree complete_binfo;
-      tree canonical;
-      
-      for (complete_binfo = binfo;
-          BINFO_INHERITANCE_CHAIN (complete_binfo);
-          complete_binfo = BINFO_INHERITANCE_CHAIN (complete_binfo))
-       continue;
-      canonical = binfo_for_vbase (BINFO_TYPE (primary_base),
-                                  BINFO_TYPE (complete_binfo));
-      
-      for (; virtuals; virtuals = TREE_CHAIN (virtuals))
-       {
-         result = TREE_VALUE (virtuals);
-
-         if (canonical == result)
-           break;
-       }
-    }
-  else
-    result = TREE_VALUE (virtuals);
+  result = copied_binfo (primary_base, binfo);
   return result;
 }
 
@@ -6875,24 +6525,32 @@ maybe_indent_hierarchy (FILE * stream, int indent, int indented_p)
   return 1;
 }
 
-/* Dump the offsets of all the bases rooted at BINFO (in the hierarchy
-   dominated by T) to stderr.  INDENT should be zero when called from
-   the top level; it is incremented recursively.  */
+/* Dump the offsets of all the bases rooted at BINFO to STREAM.
+   INDENT should be zero when called from the top level; it is
+   incremented recursively.  IGO indicates the next expected BINFO in
+   inheritance graph ordering. */
 
-static void
-dump_class_hierarchy_r (FILE * stream,
+static tree
+dump_class_hierarchy_r (FILE *stream,
                         int flags,
-                        tree t,
                         tree binfo,
+                        tree igo,
                         int indent)
 {
-  int i;
   int indented = 0;
+  tree base_binfos;
   
   indented = maybe_indent_hierarchy (stream, indent, 0);
   fprintf (stream, "%s (0x%lx) ",
           type_as_string (binfo, TFF_PLAIN_IDENTIFIER),
           (unsigned long) binfo);
+  if (binfo != igo)
+    {
+      fprintf (stream, "alternative-path\n");
+      return igo;
+    }
+  igo = TREE_CHAIN (binfo);
+  
   fprintf (stream, HOST_WIDE_INT_PRINT_DEC,
           tree_low_cst (BINFO_OFFSET (binfo), 0));
   if (is_empty_class (BINFO_TYPE (binfo)))
@@ -6900,15 +6558,7 @@ dump_class_hierarchy_r (FILE * stream,
   else if (CLASSTYPE_NEARLY_EMPTY_P (BINFO_TYPE (binfo)))
     fprintf (stream, " nearly-empty");
   if (TREE_VIA_VIRTUAL (binfo))
-    {
-      tree canonical = binfo_for_vbase (BINFO_TYPE (binfo), t);
-
-      fprintf (stream, " virtual");
-      if (canonical == binfo)
-        fprintf (stream, " canonical");
-      else
-        fprintf (stream, " non-canonical");
-    }
+    fprintf (stream, " virtual");
   fprintf (stream, "\n");
 
   indented = 0;
@@ -6965,11 +6615,22 @@ dump_class_hierarchy_r (FILE * stream,
        fprintf (stream, "\n");
     }
   
+  base_binfos = BINFO_BASETYPES (binfo);
+  if (base_binfos)
+    {
+      int ix, n;
 
-  for (i = 0; i < BINFO_N_BASETYPES (binfo); ++i)
-    dump_class_hierarchy_r (stream, flags,
-                           t, BINFO_BASETYPE (binfo, i),
-                           indent + 2);
+      n = TREE_VEC_LENGTH (base_binfos);
+      for (ix = 0; ix != n; ix++)
+       {
+         tree base_binfo = TREE_VEC_ELT (base_binfos, ix);
+
+         igo = dump_class_hierarchy_r (stream, flags, base_binfo,
+                                       igo, indent + 2);
+       }
+    }
+  
+  return igo;
 }
 
 /* Dump the BINFO hierarchy for T.  */
@@ -6987,7 +6648,12 @@ dump_class_hierarchy (tree t)
   fprintf (stream, "   size=%lu align=%lu\n",
           (unsigned long)(tree_low_cst (TYPE_SIZE (t), 0) / BITS_PER_UNIT),
           (unsigned long)(TYPE_ALIGN (t) / BITS_PER_UNIT));
-  dump_class_hierarchy_r (stream, flags, t, TYPE_BINFO (t), 0);
+  fprintf (stream, "   base size=%lu base align=%lu\n",
+          (unsigned long)(tree_low_cst (TYPE_SIZE (CLASSTYPE_AS_BASE (t)), 0)
+                          / BITS_PER_UNIT),
+          (unsigned long)(TYPE_ALIGN (CLASSTYPE_AS_BASE (t))
+                          / BITS_PER_UNIT));
+  dump_class_hierarchy_r (stream, flags, TYPE_BINFO (t), TYPE_BINFO (t), 0);
   fprintf (stream, "\n");
   dump_end (TDI_class, stream);
 }
@@ -7008,7 +6674,7 @@ dump_array (FILE * stream, tree decl)
                           TFF_PLAIN_IDENTIFIER));
   fprintf (stream, "\n");
 
-  for (ix = 0, inits = TREE_OPERAND (DECL_INITIAL (decl), 1);
+  for (ix = 0, inits = CONSTRUCTOR_ELTS (DECL_INITIAL (decl));
        inits; ix++, inits = TREE_CHAIN (inits))
     fprintf (stream, "%-4ld  %s\n", (long)(ix * elt),
             expr_as_string (TREE_VALUE (inits), TFF_PLAIN_IDENTIFIER));
@@ -7073,7 +6739,6 @@ finish_vtbls (tree t)
 {
   tree list;
   tree vbase;
-  int i;
 
   /* We lay out the primary and secondary vtables in one contiguous
      vtable.  The primary vtable is first, followed by the non-virtual
@@ -7085,29 +6750,9 @@ finish_vtbls (tree t)
   /* Then come the virtual bases, also in inheritance graph order.  */
   for (vbase = TYPE_BINFO (t); vbase; vbase = TREE_CHAIN (vbase))
     {
-      tree real_base;
-         
       if (!TREE_VIA_VIRTUAL (vbase))
        continue;
-          
-      /* Although we walk in inheritance order, that might not get the
-         canonical base.  */
-      real_base = binfo_for_vbase (BINFO_TYPE (vbase), t);
-          
-      accumulate_vtbl_inits (real_base, real_base,
-                            TYPE_BINFO (t), t, list);
-    }
-
-  /* Fill in BINFO_VPTR_FIELD in the immediate binfos for our virtual
-     base classes, for the benefit of the debugging backends.  */
-  for (i = 0; i < BINFO_N_BASETYPES (TYPE_BINFO (t)); ++i)
-    {
-      tree base = BINFO_BASETYPE (TYPE_BINFO (t), i);
-      if (TREE_VIA_VIRTUAL (base))
-       {
-         vbase = binfo_for_vbase (BINFO_TYPE (base), t);
-         BINFO_VPTR_FIELD (base) = BINFO_VPTR_FIELD (vbase);
-       }
+      accumulate_vtbl_inits (vbase, vbase, TYPE_BINFO (t), t, list);
     }
 
   if (TYPE_BINFO_VTABLE (t))
@@ -7137,7 +6782,7 @@ initialize_array (tree decl, tree inits)
 
   context = DECL_CONTEXT (decl);
   DECL_CONTEXT (decl) = NULL_TREE;
-  DECL_INITIAL (decl) = build_nt (CONSTRUCTOR, NULL_TREE, inits);
+  DECL_INITIAL (decl) = build_constructor (NULL_TREE, inits);
   TREE_HAS_CONSTRUCTOR (DECL_INITIAL (decl)) = 1;
   cp_finish_decl (decl, DECL_INITIAL (decl), NULL_TREE, 0);
   DECL_CONTEXT (decl) = context;
@@ -7187,31 +6832,6 @@ build_vtt (tree t)
   dump_vtt (t, vtt);
 }
 
-/* The type corresponding to BASE_BINFO is a base of the type of BINFO, but
-   from within some hierarchy which is inherited from the type of BINFO.
-   Return BASE_BINFO's equivalent binfo from the hierarchy dominated by
-   BINFO.  */
-
-static tree
-get_original_base (tree base_binfo, tree binfo)
-{
-  tree derived;
-  int ix;
-  
-  if (same_type_p (BINFO_TYPE (base_binfo), BINFO_TYPE (binfo)))
-    return binfo;
-  if (TREE_VIA_VIRTUAL (base_binfo))
-    return binfo_for_vbase (BINFO_TYPE (base_binfo), BINFO_TYPE (binfo));
-  derived = get_original_base (BINFO_INHERITANCE_CHAIN (base_binfo), binfo);
-  
-  for (ix = 0; ix != BINFO_N_BASETYPES (derived); ix++)
-    if (same_type_p (BINFO_TYPE (base_binfo),
-                     BINFO_TYPE (BINFO_BASETYPE (derived, ix))))
-      return BINFO_BASETYPE (derived, ix);
-  abort ();
-  return NULL;
-}
-
 /* When building a secondary VTT, BINFO_VTABLE is set to a TREE_LIST with
    PURPOSE the RTTI_BINFO, VALUE the real vtable pointer for this binfo,
    and CHAIN the vtable pointer for this binfo after construction is
@@ -7321,13 +6941,10 @@ build_vtt_inits (tree binfo, tree t, tree* inits, tree* index)
   if (top_level_p)
     for (b = TYPE_BINFO (BINFO_TYPE (binfo)); b; b = TREE_CHAIN (b))
       {
-       tree vbase;
-       
        if (!TREE_VIA_VIRTUAL (b))
          continue;
        
-       vbase = binfo_for_vbase (BINFO_TYPE (b), t);
-       inits = build_vtt_inits (vbase, t, inits, index);
+       inits = build_vtt_inits (b, t, inits, index);
       }
 
   if (!top_level_p)
@@ -7364,7 +6981,7 @@ dfs_build_secondary_vptr_vtt_inits (tree binfo, void* data)
   t = TREE_CHAIN (l);
   top_level_p = VTT_TOP_LEVEL_P (l);
   
-  SET_BINFO_MARKED (binfo);
+  BINFO_MARKED (binfo) = 1;
 
   /* We don't care about bases that don't have vtables.  */
   if (!TYPE_VFIELD (BINFO_TYPE (binfo)))
@@ -7415,12 +7032,11 @@ dfs_build_secondary_vptr_vtt_inits (tree binfo, void* data)
    hierarchy.  */
 
 static tree
-dfs_ctor_vtable_bases_queue_p (tree binfo, void* data)
+dfs_ctor_vtable_bases_queue_p (tree derived, int ix,
+                              void* data)
 {
-  if (TREE_VIA_VIRTUAL (binfo))
-     /* Get the shared version.  */
-    binfo = binfo_for_vbase (BINFO_TYPE (binfo), TREE_PURPOSE ((tree) data));
-
+  tree binfo = BINFO_BASETYPE (derived, ix);
+  
   if (!BINFO_MARKED (binfo) == VTT_MARKED_BINFO_P ((tree) data))
     return NULL_TREE;
   return binfo;
@@ -7434,7 +7050,7 @@ dfs_ctor_vtable_bases_queue_p (tree binfo, void* data)
 static tree
 dfs_fixup_binfo_vtbls (tree binfo, void* data)
 {
-  CLEAR_BINFO_MARKED (binfo);
+  BINFO_MARKED (binfo) = 0;
 
   /* We don't care about bases that don't have vtables.  */
   if (!TYPE_VFIELD (BINFO_TYPE (binfo)))
@@ -7485,14 +7101,12 @@ build_ctor_vtbl_group (tree binfo, tree t)
        vbase = TREE_CHAIN (vbase))
     {
       tree b;
-      tree orig_base;
 
       if (!TREE_VIA_VIRTUAL (vbase))
        continue;
-      b = binfo_for_vbase (BINFO_TYPE (vbase), t);
-      orig_base = binfo_for_vbase (BINFO_TYPE (vbase), BINFO_TYPE (binfo));
+      b = copied_binfo (vbase, binfo);
       
-      accumulate_vtbl_inits (b, orig_base, binfo, t, list);
+      accumulate_vtbl_inits (b, vbase, binfo, t, list);
     }
   inits = TREE_VALUE (list);
 
@@ -7622,8 +7236,8 @@ dfs_accumulate_vtbl_inits (tree binfo,
         either case, we share our vtable with LAST, i.e. the
         derived-most base within B of which we are a primary.  */
       if (b == rtti_binfo
-         || (b && binfo_for_vbase (BINFO_TYPE (b),
-                                   BINFO_TYPE (rtti_binfo))))
+         || (b && purpose_member (BINFO_TYPE (b),
+                                  CLASSTYPE_VBASECLASSES (BINFO_TYPE (rtti_binfo)))))
        /* Just set our BINFO_VTABLE to point to LAST, as we may not have
           set LAST's BINFO_VTABLE yet.  We'll extract the actual vptr in
           binfo_ctor_vtable after everything's been set up.  */
@@ -7631,7 +7245,7 @@ dfs_accumulate_vtbl_inits (tree binfo,
 
       /* Otherwise, this is case 3 and we get our own.  */
     }
-  else if (!BINFO_NEW_VTABLE_MARKED (orig_binfo, BINFO_TYPE (rtti_binfo)))
+  else if (!BINFO_NEW_VTABLE_MARKED (orig_binfo))
     return inits;
 
   if (!vtbl)
@@ -7734,7 +7348,7 @@ build_vtbl_initializer (tree binfo,
   for (vbase = CLASSTYPE_VBASECLASSES (t); 
        vbase; 
        vbase = TREE_CHAIN (vbase))
-    CLEAR_BINFO_VTABLE_PATH_MARKED (TREE_VALUE (vbase));
+    BINFO_VTABLE_PATH_MARKED (TREE_VALUE (vbase)) = 0;
 
   /* If the target requires padding between data entries, add that now.  */
   if (TARGET_VTABLE_DATA_ENTRY_DISTANCE > 1)
@@ -7938,13 +7552,13 @@ build_vbase_offset_vtbl_entries (tree binfo, vtbl_init_data* vid)
 
       /* Find the instance of this virtual base in the complete
         object.  */
-      b = binfo_for_vbase (BINFO_TYPE (vbase), t);
+      b = copied_binfo (vbase, binfo);
 
       /* If we've already got an offset for this virtual base, we
         don't need another one.  */
       if (BINFO_VTABLE_PATH_MARKED (b))
        continue;
-      SET_BINFO_VTABLE_PATH_MARKED (b);
+      BINFO_VTABLE_PATH_MARKED (b) = 1;
 
       /* Figure out where we can find this vbase offset.  */
       delta = size_binop (MULT_EXPR, 
@@ -7956,16 +7570,10 @@ build_vbase_offset_vtbl_entries (tree binfo, vtbl_init_data* vid)
 
       if (binfo != TYPE_BINFO (t))
        {
-         tree orig_vbase;
-
-         /* Find the instance of this virtual base in the type of BINFO.  */
-         orig_vbase = binfo_for_vbase (BINFO_TYPE (vbase),
-                                       BINFO_TYPE (binfo));
-
          /* The vbase offset had better be the same.  */
-         if (!tree_int_cst_equal (delta,
-                                  BINFO_VPTR_FIELD (orig_vbase)))
-           abort ();
+         my_friendly_assert (tree_int_cst_equal (delta,
+                                                 BINFO_VPTR_FIELD (vbase)),
+                             20030202);
        }
 
       /* The next vbase will come at a more negative offset.  */
@@ -8119,8 +7727,8 @@ add_vcall_offset_vtbl_entries_1 (tree binfo, vtbl_init_data* vid)
       if (vid->ctor_vtbl_p)
        /* For a ctor vtable we need the equivalent binfo within the hierarchy
           where rtti_binfo is the most derived type.  */
-       non_primary_binfo = get_original_base
-          (non_primary_binfo, TYPE_BINFO (BINFO_TYPE (vid->rtti_binfo)));
+       non_primary_binfo
+         = original_binfo (non_primary_binfo, vid->rtti_binfo);
       
       for (base_virtuals = BINFO_VIRTUALS (binfo),
             derived_virtuals = BINFO_VIRTUALS (non_primary_binfo),
@@ -8250,22 +7858,20 @@ build_rtti_vtbl_entries (tree binfo, vtbl_init_data* vid)
 
   /* The second entry is the address of the typeinfo object.  */
   if (flag_rtti)
-    decl = build_unary_op (ADDR_EXPR, get_tinfo_decl (t), 0);
+    decl = build_address (get_tinfo_decl (t));
   else
     decl = integer_zero_node;
   
   /* Convert the declaration to a type that can be stored in the
      vtable.  */
-  init = build1 (NOP_EXPR, vfunc_ptr_type_node, decl);
-  TREE_CONSTANT (init) = 1;
+  init = build_nop (vfunc_ptr_type_node, decl);
   *vid->last_init = build_tree_list (NULL_TREE, init);
   vid->last_init = &TREE_CHAIN (*vid->last_init);
 
   /* Add the offset-to-top entry.  It comes earlier in the vtable that
      the the typeinfo entry.  Convert the offset to look like a
      function pointer, so that we can put it in the vtable.  */
-  init = build1 (NOP_EXPR, vfunc_ptr_type_node, offset);
-  TREE_CONSTANT (init) = 1;
+  init = build_nop (vfunc_ptr_type_node, offset);
   *vid->last_init = build_tree_list (NULL_TREE, init);
   vid->last_init = &TREE_CHAIN (*vid->last_init);
 }