OSDN Git Service

Use vector API for vbase list.
authornathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 28 Jun 2004 10:34:42 +0000 (10:34 +0000)
committernathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 28 Jun 2004 10:34:42 +0000 (10:34 +0000)
* cp-tree.h: Include vec.h
(DEF_VEC_P (tree)): New type.
(struct lang_type_class): Change vbase's member type.
(binfo_for_vbase): Declare.
* class.c (determine_primary_base, base_derived_from,
update_vtable_entry_for_fn, walk_subobject_offsets, end_of_class,
warn_about_ambiguous_bases, dfs_accumulate_vtbl_inits,
build_vtbl_initializer): Adjust.
* decl.c (xref_basetypes): Adjust, accumulate upper bound of
vbases.
* init.c (sort_mem_initializers, expand_member_init,
push_base_cleanups): Adjust.
* method.c (do_build_copy_constructor): Adjust.
* search.c (get_pure_virtuals, copied_binfo, original_binfo): Adjust.
(binfo_for_vbase): New.
* tree.c (copy_base_binfos): Adjust.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@83770 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/init.c
gcc/cp/method.c
gcc/cp/search.c
gcc/cp/tree.c

index 756bc91..14527ca 100644 (file)
@@ -1,3 +1,23 @@
+2004-06-28  Nathan Sidwell  <nathan@codesourcery.com>
+
+       Use vector API for vbase list.
+       * cp-tree.h: Include vec.h
+       (DEF_VEC_P (tree)): New type.
+       (struct lang_type_class): Change vbase's member type.
+       (binfo_for_vbase): Declare.
+       * class.c (determine_primary_base, base_derived_from,
+       update_vtable_entry_for_fn, walk_subobject_offsets, end_of_class,
+       warn_about_ambiguous_bases, dfs_accumulate_vtbl_inits,
+       build_vtbl_initializer): Adjust.
+       * decl.c (xref_basetypes): Adjust, accumulate upper bound of
+       vbases.
+       * init.c (sort_mem_initializers, expand_member_init,
+       push_base_cleanups): Adjust.
+       * method.c (do_build_copy_constructor): Adjust.
+       * search.c (get_pure_virtuals, copied_binfo, original_binfo): Adjust.
+       (binfo_for_vbase): New.
+       * tree.c (copy_base_binfos): Adjust.
+
 2004-06-28  Mark Mitchell  <mark@codesourcery.com>
 
        * parser.c (cp_parser_set_decl_spec_type): Fix thinko.
index c2d6541..8f188c4 100644 (file)
@@ -1344,9 +1344,9 @@ set_primary_base (tree t, tree binfo)
 static void
 determine_primary_base (tree t)
 {
-  int i, n_baseclasses = CLASSTYPE_N_BASECLASSES (t);
-  tree vbases;
+  unsigned i, n_baseclasses = CLASSTYPE_N_BASECLASSES (t);
   tree type_binfo;
+  tree vbase_binfo;
 
   /* If there are no baseclasses, there is certainly no primary base.  */
   if (n_baseclasses == 0)
@@ -1394,29 +1394,26 @@ determine_primary_base (tree t)
 
   /* Find the indirect primary bases - those virtual bases which are primary
      bases of something else in this hierarchy.  */
-  for (vbases = CLASSTYPE_VBASECLASSES (t);
-       vbases;
-       vbases = TREE_CHAIN (vbases)) 
+  for (i = 0; (vbase_binfo = VEC_iterate
+              (tree, CLASSTYPE_VBASECLASSES (t), i)); i++)
     {
-      tree vbase_binfo = TREE_VALUE (vbases);
+      unsigned j;
 
-      /* See if this virtual base is an indirect primary base.  To be so,
-         it must be a primary base within the hierarchy of one of our
-         direct bases.  */
-      for (i = 0; i < n_baseclasses; ++i
+      /* See if this virtual base is an indirect primary base.  To be
+         so, it must be a primary base within the hierarchy of one of
+         our direct bases.  */
+      for (j = 0; j != n_baseclasses; ++j
        {
-         tree basetype = TYPE_BINFO_BASETYPE (t, i);
-         tree v;
-
-         for (v = CLASSTYPE_VBASECLASSES (basetype); 
-              v; 
-              v = TREE_CHAIN (v))
+         unsigned k;
+         tree base_vbase_binfo;
+         tree basetype = TYPE_BINFO_BASETYPE (t, j);
+         
+         for (k = 0; (base_vbase_binfo = VEC_iterate
+                      (tree, CLASSTYPE_VBASECLASSES (basetype), k)); k++)
            {
-             tree base_vbase = TREE_VALUE (v);
-             
-             if (BINFO_PRIMARY_P (base_vbase)
-                 && same_type_p (BINFO_TYPE (base_vbase),
-                                 BINFO_TYPE (vbase_binfo)))
+             if (BINFO_PRIMARY_P (base_vbase_binfo)
+                 && same_type_p (BINFO_TYPE (base_vbase_binfo),
+                                 BINFO_TYPE (vbase_binfo)))
                {
                  BINFO_INDIRECT_PRIMARY_P (vbase_binfo) = 1;
                  break;
@@ -1923,9 +1920,8 @@ base_derived_from (tree derived, tree base)
        /* 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 (binfo_for_vbase (BINFO_TYPE (probe), BINFO_TYPE (derived))
+               != NULL_TREE);
     }
   return false;
 }
@@ -2169,10 +2165,8 @@ update_vtable_entry_for_fn (tree t, tree binfo, tree fn, tree* virtuals,
        /* Find the equivalent binfo within the return type of the
           overriding function. We will want the vbase offset from
           there.  */
-       virtual_offset =
-         TREE_VALUE (purpose_member
-                     (BINFO_TYPE (virtual_offset),
-                      CLASSTYPE_VBASECLASSES (TREE_TYPE (over_return))));
+       virtual_offset = binfo_for_vbase (BINFO_TYPE (virtual_offset),
+                                         TREE_TYPE (over_return));
       else if (!same_type_p (TREE_TYPE (over_return),
                             TREE_TYPE (base_return)))
        {
@@ -3314,9 +3308,9 @@ walk_subobject_offsets (tree type,
            return r;
        }
 
-      if (abi_version_at_least (2))
+      if (abi_version_at_least (2) && CLASSTYPE_VBASECLASSES (type))
        {
-         tree vbase;
+         unsigned ix;
 
          /* Iterate through the virtual base classes of TYPE.  In G++
             3.2, we included virtual bases in the direct base class
@@ -3324,11 +3318,9 @@ walk_subobject_offsets (tree type,
             correct offsets for virtual bases are only known when
             working with the most derived type.  */
          if (vbases_p)
-           for (vbase = CLASSTYPE_VBASECLASSES (type);
-                vbase;
-                vbase = TREE_CHAIN (vbase))
+           for (ix = 0; (binfo = VEC_iterate
+                         (tree, CLASSTYPE_VBASECLASSES (type), ix)); ix++)
              {
-               binfo = TREE_VALUE (vbase);
                r = walk_subobject_offsets (binfo,
                                            f,
                                            size_binop (PLUS_EXPR,
@@ -3345,7 +3337,8 @@ walk_subobject_offsets (tree type,
              /* We still have to walk the primary base, if it is
                 virtual.  (If it is non-virtual, then it was walked
                 above.)  */
-             vbase = get_primary_binfo (type_binfo);
+             tree vbase = get_primary_binfo (type_binfo);
+             
              if (vbase && TREE_VIA_VIRTUAL (vbase)
                  && BINFO_PRIMARY_BASE_OF (vbase) == type_binfo)
                {
@@ -4525,11 +4518,10 @@ end_of_class (tree t, int include_virtuals_p)
 
   /* G++ 3.2 did not check indirect virtual bases.  */
   if (abi_version_at_least (2) && include_virtuals_p)
-    for (binfo = CLASSTYPE_VBASECLASSES (t); 
-        binfo; 
-        binfo = TREE_CHAIN (binfo))
+    for (i = 0; (binfo = VEC_iterate
+                (tree, CLASSTYPE_VBASECLASSES (t), i)); i++)
       {
-       offset = end_of_base (TREE_VALUE (binfo));
+       offset = end_of_base (binfo);
        if (INT_CST_LT_UNSIGNED (result, offset))
          result = offset;
       }
@@ -4551,8 +4543,8 @@ static void
 warn_about_ambiguous_bases (tree t)
 {
   int i;
-  tree vbases;
   tree basetype;
+  tree binfo;
 
   /* Check direct bases.  */
   for (i = 0; i < CLASSTYPE_N_BASECLASSES (t); ++i)
@@ -4566,11 +4558,10 @@ warn_about_ambiguous_bases (tree t)
 
   /* Check for ambiguous virtual bases.  */
   if (extra_warnings)
-    for (vbases = CLASSTYPE_VBASECLASSES (t); 
-        vbases; 
-        vbases = TREE_CHAIN (vbases))
+    for (i = 0; (binfo = VEC_iterate
+                (tree, CLASSTYPE_VBASECLASSES (t), i)); i++)
       {
-       basetype = BINFO_TYPE (TREE_VALUE (vbases));
+       basetype = BINFO_TYPE (binfo);
        
        if (!lookup_base (t, basetype, ba_ignore | ba_quiet, NULL))
          warning ("virtual base `%T' inaccessible in `%T' due to ambiguity",
@@ -7272,8 +7263,7 @@ 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 && purpose_member (BINFO_TYPE (b),
-                                  CLASSTYPE_VBASECLASSES (BINFO_TYPE (rtti_binfo)))))
+         || (b && binfo_for_vbase (BINFO_TYPE (b), BINFO_TYPE (rtti_binfo))))
        /* Just set our BINFO_VTABLE to point to LAST, as we may not have
           set LAST's BINFO_VTABLE yet.  We'll extract the actual vptr in
           binfo_ctor_vtable after everything's been set up.  */
@@ -7351,8 +7341,9 @@ build_vtbl_initializer (tree binfo,
 {
   tree v, b;
   tree vfun_inits;
-  tree vbase;
   vtbl_init_data vid;
+  unsigned ix;
+  tree vbinfo;
 
   /* Initialize VID.  */
   memset (&vid, 0, sizeof (vid));
@@ -7375,12 +7366,12 @@ build_vtbl_initializer (tree binfo,
   VARRAY_TREE_INIT (vid.fns, 32, "fns");
   /* Add the vcall and vbase offset entries.  */
   build_vcall_and_vbase_vtbl_entries (binfo, &vid);
+  
   /* Clear BINFO_VTABLE_PATH_MARKED; it's set by
      build_vbase_offset_vtbl_entries.  */
-  for (vbase = CLASSTYPE_VBASECLASSES (t); 
-       vbase; 
-       vbase = TREE_CHAIN (vbase))
-    BINFO_VTABLE_PATH_MARKED (TREE_VALUE (vbase)) = 0;
+  for (ix = 0; (vbinfo = VEC_iterate
+               (tree, CLASSTYPE_VBASECLASSES (t), ix)); ix++)
+    BINFO_VTABLE_PATH_MARKED (vbinfo) = 0;
 
   /* If the target requires padding between data entries, add that now.  */
   if (TARGET_VTABLE_DATA_ENTRY_DISTANCE > 1)
index 54bb0e3..c2a943e 100644 (file)
@@ -27,8 +27,8 @@ Boston, MA 02111-1307, USA.  */
 #include "function.h"
 #include "hashtab.h"
 #include "splay-tree.h"
+#include "vec.h"
 #include "varray.h"
-
 #include "c-common.h"
 #include "name-lookup.h"
 
@@ -1017,6 +1017,8 @@ struct lang_type_header GTY(())
   BOOL_BITFIELD has_const_assign_ref : 1;
 };
 
+DEF_VEC_P (tree);
+
 /* This structure provides additional information above and beyond
    what is provide in the ordinary tree_type.  In the past, we used it
    for the types of class types, template parameters types, typename
@@ -1087,7 +1089,7 @@ struct lang_type_class GTY(())
   tree vcall_indices;
   tree vtables;
   tree typeinfo_var;
-  tree vbases;
+  VEC (tree) *vbases;
   binding_table nested_udts;
   tree as_base;
   tree pure_virtuals;
@@ -1305,7 +1307,7 @@ struct lang_type GTY(())
 #define CLASSTYPE_PRIMARY_BINFO(NODE) \
   (LANG_TYPE_CLASS_CHECK (NODE)->primary_base)
 
-/* A chain of BINFOs for the direct and indirect virtual base classes
+/* A vector of BINFOs for the direct and indirect virtual base classes
    that this type uses in a post-order depth-first left-to-right
    order.  (In other words, these bases appear in the order that they
    should be initialized.)  */
@@ -4121,6 +4123,7 @@ extern tree context_for_name_lookup               (tree);
 extern tree lookup_conversions                 (tree);
 extern tree binfo_for_vtable                   (tree);
 extern tree binfo_from_vbase                   (tree);
+extern tree binfo_for_vbase                    (tree, tree);
 extern tree look_for_overrides_here            (tree, tree);
 extern int check_final_overrider               (tree, tree);
 extern tree dfs_walk                            (tree,
index 838f22b..11616c0 100644 (file)
@@ -9044,7 +9044,7 @@ xref_basetypes (tree ref, tree base_list)
   /* In the declaration `A : X, Y, ... Z' we mark all the types
      (A, X, Y, ..., Z) so we can check for duplicates.  */
   tree *basep;
-
+  unsigned max_vbases = 0;
   int i;
   enum tag_types tag_code;
 
@@ -9093,6 +9093,8 @@ xref_basetypes (tree ref, tree base_list)
          tree basetype = TREE_VALUE (base_list);
          tree base_binfo;
          
+         if (via_virtual)
+           max_vbases++;
          if (access == access_default_node)
            /* The base of a derived struct is public by default.  */
            access = (tag_code == class_type
@@ -9169,6 +9171,8 @@ xref_basetypes (tree ref, tree base_list)
                 base as well.  */
              TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (ref)
                |= TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (basetype);
+             max_vbases += VEC_length
+               (tree, CLASSTYPE_VBASECLASSES (basetype));
            }
          i++;
        }
@@ -9176,6 +9180,8 @@ xref_basetypes (tree ref, tree base_list)
        TREE_VEC_LENGTH (accesses) = TREE_VEC_LENGTH (binfos) = i;
       else
        BINFO_BASEACCESSES (binfo) = BINFO_BASETYPES (binfo) = NULL_TREE;
+      if (max_vbases)
+       CLASSTYPE_VBASECLASSES (ref) = VEC_alloc (tree, max_vbases);
       
       if (i > 1)
        {
@@ -9189,7 +9195,6 @@ xref_basetypes (tree ref, tree base_list)
   /* Copy the base binfos, collect the virtual bases and set the
      inheritance order chain.  */
   copy_base_binfos (TYPE_BINFO (ref), ref, NULL_TREE);
-  CLASSTYPE_VBASECLASSES (ref) = nreverse (CLASSTYPE_VBASECLASSES (ref));
 
   if (TYPE_FOR_JAVA (ref))
     {
index 425a853..c96e14d 100644 (file)
@@ -468,9 +468,12 @@ sort_mem_initializers (tree t, tree mem_inits)
      TREE_VALUE will be the constructor arguments, or NULL if no
      explicit initialization was provided.  */
   sorted_inits = NULL_TREE;
+  
   /* Process the virtual bases.  */
-  for (base = CLASSTYPE_VBASECLASSES (t); base; base = TREE_CHAIN (base))
-    sorted_inits = tree_cons (TREE_VALUE (base), NULL_TREE, sorted_inits);
+  for (i = 0; (base = VEC_iterate
+              (tree, CLASSTYPE_VBASECLASSES (t), i)); i++)
+    sorted_inits = tree_cons (base, NULL_TREE, sorted_inits);
+  
   /* Process the direct bases.  */
   for (i = 0; i < CLASSTYPE_N_BASECLASSES (t); ++i)
     {
@@ -988,13 +991,7 @@ expand_member_init (tree name)
       /* Look for a virtual base -- unless the direct base is itself
         virtual.  */
       if (!direct_binfo || !TREE_VIA_VIRTUAL (direct_binfo))
-       {
-         virtual_binfo 
-           = purpose_member (basetype,
-                             CLASSTYPE_VBASECLASSES (current_class_type));
-         if (virtual_binfo)
-           virtual_binfo = TREE_VALUE (virtual_binfo);
-       }
+       virtual_binfo = binfo_for_vbase (basetype, current_class_type);
 
       /* [class.base.init]
         
@@ -2874,27 +2871,23 @@ push_base_cleanups (void)
   /* Run destructors for all virtual baseclasses.  */
   if (TYPE_USES_VIRTUAL_BASECLASSES (current_class_type))
     {
-      tree vbases;
       tree cond = (condition_conversion
                   (build (BIT_AND_EXPR, integer_type_node,
                           current_in_charge_parm,
                           integer_two_node)));
 
-      vbases = CLASSTYPE_VBASECLASSES (current_class_type);
-      /* The CLASSTYPE_VBASECLASSES list is in initialization
+      /* The CLASSTYPE_VBASECLASSES vector is in initialization
         order, which is also the right order for pushing cleanups.  */
-      for (; vbases;
-          vbases = TREE_CHAIN (vbases))
+      for (i = 0; (binfos = VEC_iterate
+                  (tree, CLASSTYPE_VBASECLASSES (current_class_type), i));
+          i++)
        {
-         tree vbase = TREE_VALUE (vbases);
-         tree base_type = BINFO_TYPE (vbase);
-
-         if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (base_type))
+         if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (BINFO_TYPE (binfos)))
            {
              expr = build_special_member_call (current_class_ref, 
                                                base_dtor_identifier,
                                                NULL_TREE,
-                                               vbase,
+                                               binfos,
                                                (LOOKUP_NORMAL 
                                                 | LOOKUP_NONVIRTUAL));
              expr = build (COND_EXPR, void_type_node, cond,
@@ -2948,17 +2941,19 @@ push_base_cleanups (void)
 tree
 build_vbase_delete (tree type, tree decl)
 {
-  tree vbases = CLASSTYPE_VBASECLASSES (type);
+  unsigned ix;
+  tree binfo;
   tree result;
   tree addr = build_unary_op (ADDR_EXPR, decl, 0);
 
   my_friendly_assert (addr != error_mark_node, 222);
 
-  for (result = convert_to_void (integer_zero_node, NULL);
-       vbases; vbases = TREE_CHAIN (vbases))
+  result = convert_to_void (integer_zero_node, NULL);
+  for (ix = 0; (binfo = VEC_iterate
+               (tree, CLASSTYPE_VBASECLASSES (type), ix)); ix++)
     {
       tree base_addr = convert_force
-       (build_pointer_type (BINFO_TYPE (TREE_VALUE (vbases))), addr, 0);
+       (build_pointer_type (BINFO_TYPE (binfo)), addr, 0);
       tree base_delete = build_delete
        (TREE_TYPE (base_addr), base_addr, sfk_base_destructor,
         LOOKUP_NORMAL|LOOKUP_DESTRUCTOR, 0);
index adda8da..774f8c0 100644 (file)
@@ -523,17 +523,17 @@ do_build_copy_constructor (tree fndecl)
       tree member_init_list = NULL_TREE;
       int cvquals = cp_type_quals (TREE_TYPE (parm));
       int i;
+      tree binfo;
 
       /* Initialize all the base-classes with the parameter converted
         to their type so that we get their copy constructor and not
         another constructor that takes current_class_type.  We must
         deal with the binfo's directly as a direct base might be
         inaccessible due to ambiguity.  */
-      for (t = CLASSTYPE_VBASECLASSES (current_class_type); t;
-          t = TREE_CHAIN (t))
+      for (i = 0; (binfo = VEC_iterate
+                  (tree, CLASSTYPE_VBASECLASSES (current_class_type), i));
+          i++)
        {
-         tree binfo = TREE_VALUE (t);
-         
          member_init_list 
            = tree_cons (binfo,
                         build_tree_list (NULL_TREE,
index ca86b13..4bf87a3 100644 (file)
@@ -1921,7 +1921,8 @@ dfs_get_pure_virtuals (tree binfo, void *data)
 void
 get_pure_virtuals (tree type)
 {
-  tree vbases;
+  unsigned ix;
+  tree binfo;
 
   /* Clear the CLASSTYPE_PURE_VIRTUALS list; whatever is already there
      is going to be overridden.  */
@@ -1938,14 +1939,12 @@ get_pure_virtuals (tree type)
   /* Put the pure virtuals in dfs order.  */
   CLASSTYPE_PURE_VIRTUALS (type) = nreverse (CLASSTYPE_PURE_VIRTUALS (type));
 
-  for (vbases = CLASSTYPE_VBASECLASSES (type); 
-       vbases; 
-       vbases = TREE_CHAIN (vbases))
+  for (ix = 0; (binfo = VEC_iterate
+               (tree, CLASSTYPE_VBASECLASSES (type), ix)); ix++)
     {
       tree virtuals;
-
-      for (virtuals = BINFO_VIRTUALS (TREE_VALUE (vbases));
-          virtuals;
+      
+      for (virtuals = BINFO_VIRTUALS (binfo); virtuals;
           virtuals = TREE_CHAIN (virtuals))
        {
          tree base_fndecl = BV_FN (virtuals);
@@ -2532,10 +2531,8 @@ copied_binfo (tree binfo, tree here)
       for (t = here; BINFO_INHERITANCE_CHAIN (t);
           t = BINFO_INHERITANCE_CHAIN (t))
        continue;
-      
-      result = purpose_member (BINFO_TYPE (binfo),
-                              CLASSTYPE_VBASECLASSES (BINFO_TYPE (t)));
-      result = TREE_VALUE (result);
+
+      result = binfo_for_vbase (BINFO_TYPE (binfo), BINFO_TYPE (t));
     }
   else if (BINFO_INHERITANCE_CHAIN (binfo))
     {
@@ -2566,6 +2563,19 @@ copied_binfo (tree binfo, tree here)
   return result;
 }
 
+tree
+binfo_for_vbase (tree base, tree t)
+{
+  unsigned ix;
+  tree binfo;
+  
+  for (ix = 0; (binfo = VEC_iterate
+               (tree, CLASSTYPE_VBASECLASSES (t), ix)); ix++)
+    if (BINFO_TYPE (binfo) == base)
+      return binfo;
+  return NULL;
+}
+
 /* BINFO is some base binfo of HERE, within some other
    hierarchy. Return the equivalent binfo, but in the hierarchy
    dominated by HERE.  This is the inverse of copied_binfo.  If BINFO
@@ -2579,12 +2589,9 @@ original_binfo (tree binfo, tree here)
   if (BINFO_TYPE (binfo) == BINFO_TYPE (here))
     result = here;
   else if (TREE_VIA_VIRTUAL (binfo))
-    {
-      result = purpose_member (BINFO_TYPE (binfo),
-                              CLASSTYPE_VBASECLASSES (BINFO_TYPE (here)));
-      if (result)
-       result = TREE_VALUE (result);
-    }
+    result = (CLASSTYPE_VBASECLASSES (BINFO_TYPE (here))
+             ? binfo_for_vbase (BINFO_TYPE (binfo), BINFO_TYPE (here))
+             : NULL_TREE);
   else if (BINFO_INHERITANCE_CHAIN (binfo))
     {
       tree base_binfos;
index 4ae0779..8ef808c 100644 (file)
@@ -571,8 +571,8 @@ canonical_type_variant (tree t)
    derived TYPE. PREV is the previous binfo, whose TREE_CHAIN we make
    point to this binfo. We return the last BINFO created.
 
-   The CLASSTYPE_VBASECLASSES list of T is constructed in reverse
-   order (pre-order, depth-first, right-to-left). You must nreverse it.
+   The CLASSTYPE_VBASECLASSES vector of T is constructed in the correct
+   order.
 
    The BINFO_INHERITANCE of a virtual base class points to the binfo
    og the most derived type.
@@ -613,12 +613,7 @@ copy_base_binfos (tree binfo, tree t, tree prev)
          BINFO_DEPENDENT_BASE_P (new_binfo) = 1;
        }
       else if (TREE_VIA_VIRTUAL (base_binfo))
-       {
-         new_binfo = purpose_member (BINFO_TYPE (base_binfo),
-                                     CLASSTYPE_VBASECLASSES (t));
-         if (new_binfo)
-           new_binfo = TREE_VALUE (new_binfo);
-       }
+       new_binfo = binfo_for_vbase (BINFO_TYPE (base_binfo), t);
       
       if (!new_binfo)
        {
@@ -628,9 +623,7 @@ copy_base_binfos (tree binfo, tree t, tree prev)
          prev = copy_base_binfos (new_binfo, t, prev);
          if (TREE_VIA_VIRTUAL (base_binfo))
            {
-             CLASSTYPE_VBASECLASSES (t)
-               = tree_cons (BINFO_TYPE (new_binfo), new_binfo,
-                            CLASSTYPE_VBASECLASSES (t));
+             VEC_quick_push (tree, CLASSTYPE_VBASECLASSES (t), new_binfo);
              TREE_VIA_VIRTUAL (new_binfo) = 1;
              BINFO_INHERITANCE_CHAIN (new_binfo) = TYPE_BINFO (t);
            }