OSDN Git Service

* cp-tree.h (dfs_mark_primary_bases_queue_p): New function.
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 2 Jan 2000 19:41:09 +0000 (19:41 +0000)
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 2 Jan 2000 19:41:09 +0000 (19:41 +0000)
(layout_basetypes): Remove.
* class.c (propagate_binfo_offsets): Moved here from tree.c.
Update to handle primary virtual bases.
(remove_base_fields): New function, split out from
layout_basetypes.
(dfs_mark_primary_bases_and_set_vbase_offsets): New function.
(layout_virtual_bases): New function, split out from
layout_basetypes.  Update to handle primary virtual bases.
(layout_basetypes): Moved here from tree.c.  Use
remove_base_fields and layout_virtual_bases.
* search.c (dfs_mark_primary_bases_queue_p): New function.
(mark_primary_bases): Use it.
* tree.c (CEIL): Remove.
(propagate_binfo_offsets): Remove.
(layout_basetypes): Remove.

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

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/search.c
gcc/cp/tree.c

index d1762d6..c023f90 100644 (file)
@@ -1,3 +1,22 @@
+2000-01-02  Mark Mitchell  <mark@codesourcery.com>
+
+       * cp-tree.h (dfs_mark_primary_bases_queue_p): New function.
+       (layout_basetypes): Remove.
+       * class.c (propagate_binfo_offsets): Moved here from tree.c.
+       Update to handle primary virtual bases.
+       (remove_base_fields): New function, split out from
+       layout_basetypes.
+       (dfs_mark_primary_bases_and_set_vbase_offsets): New function.
+       (layout_virtual_bases): New function, split out from
+       layout_basetypes.  Update to handle primary virtual bases.
+       (layout_basetypes): Moved here from tree.c.  Use
+       remove_base_fields and layout_virtual_bases.
+       * search.c (dfs_mark_primary_bases_queue_p): New function.
+       (mark_primary_bases): Use it.
+       * tree.c (CEIL): Remove.
+       (propagate_binfo_offsets): Remove.
+       (layout_basetypes): Remove.
+       
 2000-01-01  Mark Mitchell  <mark@codesourcery.com>
 
        * cp-tree.h (skip_rtti_stuff): Adjust prototype.
index fe5d296..7d22db8 100644 (file)
@@ -138,6 +138,11 @@ static void layout_class_type PROTO((tree, int *, int *, int *, tree *, tree *))
 static void fixup_pending_inline PROTO((struct pending_inline *));
 static void fixup_inline_methods PROTO((tree));
 static void set_primary_base PROTO((tree, int, int *));
+static void propagate_binfo_offsets PROTO((tree, tree));
+static int layout_basetypes PROTO((tree, int));
+static tree dfs_mark_primary_bases_and_set_vbase_offsets PROTO((tree, void *));
+static int layout_virtual_bases PROTO((tree, int));
+static void remove_base_fields PROTO((tree));
 
 /* Variables shared between class.c and call.c.  */
 
@@ -4143,6 +4148,320 @@ fixup_inline_methods (type)
   CLASSTYPE_INLINE_FRIENDS (type) = NULL_TREE;
 }
 
+/* Add OFFSET to all base types of T.
+
+   OFFSET, which is a type offset, is number of bytes.
+
+   Note that we don't have to worry about having two paths to the
+   same base type, since this type owns its association list.  */
+
+static void
+propagate_binfo_offsets (binfo, offset)
+     tree binfo;
+     tree offset;
+{
+  tree binfos = BINFO_BASETYPES (binfo);
+  int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
+
+  if (flag_new_abi)
+    {
+      for (i = 0; i < n_baselinks; ++i)
+       {
+         tree base_binfo;
+
+         /* Figure out which base we're looking at.  */
+         base_binfo = TREE_VEC_ELT (binfos, i);
+
+         /* Skip non-primary virtual bases.  Their BINFO_OFFSET
+            doesn't matter since they are always reached by using
+            offsets looked up at run-time.  */
+         if (TREE_VIA_VIRTUAL (base_binfo) 
+             && i != CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo)))
+           continue;
+
+         /* Whatever offset this class used to have in its immediate
+            derived class, it is now at OFFSET more bytes in its
+            final derived class, since the immediate derived class is
+            already at the indicated OFFSET.  */
+         BINFO_OFFSET (base_binfo)
+           = size_binop (PLUS_EXPR, BINFO_OFFSET (base_binfo), offset);
+
+         propagate_binfo_offsets (base_binfo, offset);
+       }
+    }
+  else
+    {
+      /* This algorithm, used for the old ABI, is neither simple, nor
+        general.  For example, it mishandles the case of:
+       
+           struct A;
+          struct B : public A;
+          struct C : public B;
+          
+        if B is at offset zero in C, but A is not in offset zero in
+        B.  In that case, it sets the BINFO_OFFSET for A to zero.
+        (This sitution arises in the new ABI if B has virtual
+        functions, but A does not.)  Rather than change this
+        algorithm, and risking breaking the old ABI, it is preserved
+        here.  */
+      for (i = 0; i < n_baselinks; /* note increment is done in the
+                                     loop.  */)
+       {
+         tree base_binfo = TREE_VEC_ELT (binfos, i);
+
+         if (TREE_VIA_VIRTUAL (base_binfo))
+           i += 1;
+         else
+           {
+             int j;
+             tree delta = NULL_TREE;
+
+             for (j = i+1; j < n_baselinks; j++)
+               if (! TREE_VIA_VIRTUAL (TREE_VEC_ELT (binfos, j)))
+                 {
+                   /* The next basetype offset must take into account
+                      the space between the classes, not just the
+                      size of each class.  */
+                   delta = size_binop (MINUS_EXPR,
+                                       BINFO_OFFSET (TREE_VEC_ELT (binfos, 
+                                                                   j)),
+                                       BINFO_OFFSET (base_binfo));
+                   break;
+                 }
+
+             BINFO_OFFSET (base_binfo) = offset;
+
+             propagate_binfo_offsets (base_binfo, offset);
+
+             /* Go to our next class that counts for offset
+                 propagation.  */
+             i = j;
+             if (i < n_baselinks)
+               offset = size_binop (PLUS_EXPR, offset, delta);
+           }
+       }
+    }
+}
+
+/* Remove the FIELD_DECLs created for T's base classes in
+   build_base_fields.  Simultaneously, update BINFO_OFFSET for all the
+   bases, except for non-primary virtual baseclasses.  */
+
+static void
+remove_base_fields (t)
+     tree t;
+{
+  int i;
+  tree *field;
+
+  /* Now propagate offset information throughout the lattice.
+     Simultaneously, remove the temporary FIELD_DECLS we created in
+     build_base_fields to refer to base types.  */
+  field = &TYPE_FIELDS (t);
+  if (TYPE_VFIELD (t) == *field)
+    {
+      /* If this class did not have a primary base, we create a
+        virtual function table pointer.  It will be the first thing
+        in the class, under the new ABI.  Skip it; the base fields
+        will follow it.  */
+      my_friendly_assert (flag_new_abi 
+                         && !CLASSTYPE_HAS_PRIMARY_BASE_P (t),
+                         19991218);
+      field = &TREE_CHAIN (*field);
+    }
+    
+  for (i = 0; i < CLASSTYPE_N_BASECLASSES (t); i++)
+    {
+      register tree base_binfo = BINFO_BASETYPE (TYPE_BINFO (t), i);
+      register tree basetype = BINFO_TYPE (base_binfo);
+
+      /* We treat a primary virtual base class just like an ordinary
+        base class.  But, non-primary virtual bases are laid out
+        later.  */
+      if (TREE_VIA_VIRTUAL (base_binfo) && i != CLASSTYPE_VFIELD_PARENT (t))
+       continue;
+
+      my_friendly_assert (TREE_TYPE (*field) == basetype, 23897);
+
+      if (get_base_distance (basetype, t, 0, (tree*)0) == -2)
+       cp_warning ("direct base `%T' inaccessible in `%T' due to ambiguity",
+                   basetype, t);
+
+      BINFO_OFFSET (base_binfo)
+       = size_int (CEIL (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (*field)),
+                         BITS_PER_UNIT));
+      propagate_binfo_offsets (base_binfo, BINFO_OFFSET (base_binfo));
+
+      /* Remove this field.  */
+      *field = TREE_CHAIN (*field);
+    }
+}
+
+/* Called via dfs_walk from layout_virtual_bases.  */
+
+static tree
+dfs_mark_primary_bases_and_set_vbase_offsets (binfo, data)
+     tree binfo;
+     void *data;
+{
+  if (CLASSTYPE_HAS_PRIMARY_BASE_P (BINFO_TYPE (binfo)))
+    {
+      int i;
+      tree base_binfo;
+
+      i = CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo));
+      base_binfo = BINFO_BASETYPE (binfo, i);
+      
+      /* If this is a virtual base class, and we've just now
+        discovered it to be a primary base, then reuse this copy as
+        the virtual base class for the complete object. */
+      if (TREE_VIA_VIRTUAL (base_binfo)
+         && !BINFO_PRIMARY_MARKED_P (base_binfo))
+       {
+         tree vbase;
+
+         vbase = BINFO_FOR_VBASE (BINFO_TYPE (base_binfo), (tree) data);
+         BINFO_OFFSET (vbase) = BINFO_OFFSET (base_binfo);
+       }
+
+      SET_BINFO_PRIMARY_MARKED_P (BINFO_BASETYPE (binfo, i));
+    }
+
+  SET_BINFO_MARKED (binfo);
+
+  return NULL_TREE;
+}
+
+/* Set BINFO_OFFSET for all of the virtual bases for T.  Update
+   TYPE_ALIGN and TYPE_SIZE for T.  Return the maximum of MAX and the
+   largest CLASSTYPE_VSIZE for any of the virtual bases.  */
+
+static int
+layout_virtual_bases (t, max)
+     tree t;
+     int max;
+{
+  tree vbase;
+  int dsize;
+
+  /* Mark the primary base classes.  Only virtual bases that are not
+     also primary base classes need to be laid out (since otherwise we
+     can just reuse one of the places in the hierarchy where the
+     virtual base already occurs.)  */
+  dfs_walk (TYPE_BINFO (t), 
+           dfs_mark_primary_bases_and_set_vbase_offsets,
+           dfs_mark_primary_bases_queue_p, 
+           t);
+
+  /* DSIZE is the size of the class without the virtual bases.  */
+  dsize = TREE_INT_CST_LOW (TYPE_SIZE (t));
+  /* Make every class have alignment of at least one.  */
+  TYPE_ALIGN (t) = MAX (TYPE_ALIGN (t), BITS_PER_UNIT);
+
+  for (vbase = CLASSTYPE_VBASECLASSES (t); 
+       vbase; 
+       vbase = TREE_CHAIN (vbase))
+    if (!BINFO_PRIMARY_MARKED_P (vbase))
+      {
+       /* This virtual base is not a primary base of any class in the
+          hierarchy, so we have to add space for it.  */
+       tree basetype;
+       unsigned int desired_align;
+
+       basetype = BINFO_TYPE (vbase);
+       desired_align = TYPE_ALIGN (basetype);
+       TYPE_ALIGN (t) = MAX (TYPE_ALIGN (t), desired_align);
+
+       /* Add padding so that we can put the virtual base class at an
+          appropriately aligned offset.  */
+       dsize = CEIL (dsize, desired_align) * desired_align;
+       /* And compute the offset of the virtual base.  */
+       BINFO_OFFSET (vbase) = size_int (CEIL (dsize, BITS_PER_UNIT));
+       /* Every virtual baseclass takes a least a UNIT, so that we can
+          take it's address and get something different for each base.  */
+       dsize += MAX (BITS_PER_UNIT,
+                     TREE_INT_CST_LOW (CLASSTYPE_SIZE (basetype)));
+
+       /* Now that we've laid out this virtual base class, some of
+          the remaining virtual bases might have been implicitly laid
+          out as well -- they could be primary base classes of
+          classes in BASETYPE.  */
+       dfs_walk (vbase,
+                 dfs_mark_primary_bases_and_set_vbase_offsets,
+                 dfs_mark_primary_bases_queue_p, 
+                 t);
+
+       /* While we're here, see if this new virtual base class has
+          more virtual functions than we expected.  */
+       max = MAX (CLASSTYPE_VSIZE (basetype), max);
+      }
+
+  /* We're done with the various marks, now, so clear them.  */
+  unmark_primary_bases (t);
+  dfs_walk (TYPE_BINFO (t), dfs_unmark, markedp, 0);
+
+  /* Now, make sure that the total size of the type is a multiple of
+     its alignment.  */
+  dsize = CEIL (dsize, TYPE_ALIGN (t)) * TYPE_ALIGN (t);
+  TYPE_SIZE (t) = size_int (dsize);
+  TYPE_SIZE_UNIT (t) = size_binop (FLOOR_DIV_EXPR, TYPE_SIZE (t),
+                                  size_int (BITS_PER_UNIT));
+
+  return max;
+}
+
+/* Finish the work of layout_record, now taking virtual bases into account.
+   Also compute the actual offsets that our base classes will have.
+   This must be performed after the fields are laid out, since virtual
+   baseclasses must lay down at the end of the record.
+
+   Returns the maximum number of virtual functions any of the
+   baseclasses provide.  */
+
+static int
+layout_basetypes (rec, max)
+     tree rec;
+     int max;
+{
+  tree vbase_types;
+
+#ifdef STRUCTURE_SIZE_BOUNDARY
+  /* Packed structures don't need to have minimum size.  */
+  if (! TYPE_PACKED (rec))
+    TYPE_ALIGN (rec) = MAX (TYPE_ALIGN (rec), STRUCTURE_SIZE_BOUNDARY);
+#endif
+
+  /* Remove the FIELD_DECLs we created for baseclasses in
+     build_base_fields.  Simultaneously, update the BINFO_OFFSETs for
+     everything in the hierarcy except non-primary virtual bases.  */
+  remove_base_fields (rec);
+
+  /* Allocate the virtual base classes.  */
+  max = layout_virtual_bases (rec, max);
+
+  /* Get all the virtual base types that this type uses.  The
+     TREE_VALUE slot holds the virtual baseclass type.  Note that
+     get_vbase_types makes copies of the virtual base BINFOs, so that
+     the vbase_types are unshared.  */
+  for (vbase_types = CLASSTYPE_VBASECLASSES (rec); vbase_types;
+       vbase_types = TREE_CHAIN (vbase_types))
+    {
+      BINFO_INHERITANCE_CHAIN (vbase_types) = TYPE_BINFO (rec);
+      unshare_base_binfos (vbase_types);
+      propagate_binfo_offsets (vbase_types, BINFO_OFFSET (vbase_types));
+
+      if (extra_warnings)
+       {
+         tree basetype = BINFO_TYPE (vbase_types);
+         if (get_base_distance (basetype, rec, 0, (tree*)0) == -2)
+           cp_warning ("virtual base `%T' inaccessible in `%T' due to ambiguity",
+                       basetype, rec);
+       }
+    }
+
+  return max;
+}
+
 /* Calculate the TYPE_SIZE, TYPE_ALIGN, etc for T.  Calculate
    BINFO_OFFSETs for all of the base-classes.  Position the vtable
    pointer.  */
index db9a5e4..a83dc15 100644 (file)
@@ -3909,6 +3909,7 @@ extern tree dfs_walk                            PROTO((tree,
                                                       void *));
 extern tree dfs_unmark                          PROTO((tree, void *));
 extern tree markedp                             PROTO((tree, void *));
+extern tree dfs_mark_primary_bases_queue_p      PROTO((tree, void *));
 extern void mark_primary_bases                  PROTO((tree));
 extern void unmark_primary_bases                PROTO((tree));
 
@@ -4028,7 +4029,6 @@ extern tree break_out_calls                       PROTO((tree));
 extern tree build_cplus_method_type            PROTO((tree, tree, tree));
 extern tree build_cplus_staticfn_type          PROTO((tree, tree, tree));
 extern tree build_cplus_array_type             PROTO((tree, tree));
-extern int layout_basetypes                    PROTO((tree, int));
 extern tree hash_tree_cons                     PROTO((tree, tree, tree));
 extern tree hash_tree_chain                    PROTO((tree, tree));
 extern tree hash_chainon                       PROTO((tree, tree));
index c22391d..079a653 100644 (file)
@@ -2104,7 +2104,7 @@ get_matching_virtual (binfo, fndecl, dtorp)
     }
 }
 
-/* Called via dfs_walk from mark_nonprimary_bases.  */
+/* Called via dfs_walk from mark_primary_bases.  */
 
 static tree
 dfs_mark_primary_bases (binfo, data)
@@ -2124,6 +2124,31 @@ dfs_mark_primary_bases (binfo, data)
   return NULL_TREE;
 }
 
+/* Called via dfs_walk from mark_primary_bases.  */
+
+tree
+dfs_mark_primary_bases_queue_p (binfo, data)
+     tree binfo;
+     void *data ATTRIBUTE_UNUSED;
+{
+  /* Don't walk into virtual baseclasses that are not primary 
+     bases.  */
+  if (TREE_VIA_VIRTUAL (binfo))
+    {
+      tree derived_class;
+      tree primary_base;
+      
+      derived_class = BINFO_TYPE (BINFO_INHERITANCE_CHAIN (binfo));
+      primary_base = CLASSTYPE_PRIMARY_BINFO (derived_class);
+      if (!primary_base || !same_type_p (BINFO_TYPE (primary_base),
+                                        BINFO_TYPE (binfo)))
+       return NULL_TREE;
+    }
+
+  /* But do walk into everything else.  */
+  return binfo;
+}
+
 /* Set BINFO_PRIMARY_MARKED_P for all binfos in the hierarchy
    dominated by TYPE that are primary bases.  (In addition,
    BINFO_MARKED is set for all classes in the hierarchy; callers
@@ -2135,7 +2160,7 @@ mark_primary_bases (type)
 {
   dfs_walk (TYPE_BINFO (type), 
            dfs_mark_primary_bases,
-           unmarkedp,
+           dfs_mark_primary_bases_queue_p,
            NULL);
 }
 
index f5e2474..a951b5f 100644 (file)
@@ -37,7 +37,6 @@ static tree build_cplus_array_type_1 PROTO((tree, tree));
 static void list_hash_add PROTO((int, tree));
 static int list_hash PROTO((tree, tree, tree));
 static tree list_hash_lookup PROTO((int, tree, tree, tree));
-static void propagate_binfo_offsets PROTO((tree, tree));
 static cp_lvalue_kind lvalue_p_1 PROTO((tree, int));
 static tree no_linkage_helper PROTO((tree *, int *, void *));
 static tree build_srcloc PROTO((char *, int));
@@ -48,8 +47,6 @@ static tree cp_unsave_r PROTO ((tree *, int *, void *));
 static void cp_unsave PROTO((tree *));
 static tree build_target_expr PROTO((tree, tree));
 
-#define CEIL(x,y) (((x) + (y) - 1) / (y))
-
 /* If REF is an lvalue, returns the kind of lvalue that REF is.
    Otherwise, returns clk_none.  If TREAT_CLASS_RVALUES_AS_LVALUES is
    non-zero, rvalues of class type are considered lvalues.  */
@@ -656,100 +653,6 @@ canonical_type_variant (t)
   return cp_build_qualified_type (TYPE_MAIN_VARIANT (t), CP_TYPE_QUALS (t));
 }
 \f
-/* Add OFFSET to all base types of T.
-
-   OFFSET, which is a type offset, is number of bytes.
-
-   Note that we don't have to worry about having two paths to the
-   same base type, since this type owns its association list.  */
-
-static void
-propagate_binfo_offsets (binfo, offset)
-     tree binfo;
-     tree offset;
-{
-  tree binfos = BINFO_BASETYPES (binfo);
-  int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
-
-  if (flag_new_abi)
-    {
-      for (i = 0; i < n_baselinks; ++i)
-       {
-         tree base_binfo;
-
-         /* Figure out which base we're looking at.  */
-         base_binfo = TREE_VEC_ELT (binfos, i);
-
-         /* Skip virtual bases.  Their BINFO_OFFSET doesn't matter
-            since they are always reached by using offsets looked up
-            at run-time.  */
-         if (TREE_VIA_VIRTUAL (base_binfo))
-           continue;
-
-         /* Whatever offset this class used to have in its immediate
-            derived class, it is now at OFFSET more bytes in its
-            final derived class, since the immediate derived class is
-            already at the indicated OFFSET.  */
-         BINFO_OFFSET (base_binfo)
-           = size_binop (PLUS_EXPR, BINFO_OFFSET (base_binfo), offset);
-
-         propagate_binfo_offsets (base_binfo, offset);
-       }
-    }
-  else
-    {
-      /* This algorithm, used for the old ABI, is neither simple, nor
-        general.  For example, it mishandles the case of:
-       
-           struct A;
-          struct B : public A;
-          struct C : public B;
-          
-        if B is at offset zero in C, but A is not in offset zero in
-        B.  In that case, it sets the BINFO_OFFSET for A to zero.
-        (This sitution arises in the new ABI if B has virtual
-        functions, but A does not.)  Rather than change this
-        algorithm, and risking breaking the old ABI, it is preserved
-        here.  */
-      for (i = 0; i < n_baselinks; /* note increment is done in the
-                                     loop.  */)
-       {
-         tree base_binfo = TREE_VEC_ELT (binfos, i);
-
-         if (TREE_VIA_VIRTUAL (base_binfo))
-           i += 1;
-         else
-           {
-             int j;
-             tree delta = NULL_TREE;
-
-             for (j = i+1; j < n_baselinks; j++)
-               if (! TREE_VIA_VIRTUAL (TREE_VEC_ELT (binfos, j)))
-                 {
-                   /* The next basetype offset must take into account
-                      the space between the classes, not just the
-                      size of each class.  */
-                   delta = size_binop (MINUS_EXPR,
-                                       BINFO_OFFSET (TREE_VEC_ELT (binfos, 
-                                                                   j)),
-                                       BINFO_OFFSET (base_binfo));
-                   break;
-                 }
-
-             BINFO_OFFSET (base_binfo) = offset;
-
-             propagate_binfo_offsets (base_binfo, offset);
-
-             /* Go to our next class that counts for offset
-                 propagation.  */
-             i = j;
-             if (i < n_baselinks)
-               offset = size_binop (PLUS_EXPR, offset, delta);
-           }
-       }
-    }
-}
-
 /* Makes new binfos for the indirect bases under BINFO, and updates
    BINFO_OFFSET for them and their bases.  */
 
@@ -782,154 +685,6 @@ unshare_base_binfos (binfo)
     }
 }
 
-/* Finish the work of layout_record, now taking virtual bases into account.
-   Also compute the actual offsets that our base classes will have.
-   This must be performed after the fields are laid out, since virtual
-   baseclasses must lay down at the end of the record.
-
-   Returns the maximum number of virtual functions any of the
-   baseclasses provide.  */
-
-int
-layout_basetypes (rec, max)
-     tree rec;
-     int max;
-{
-  tree binfos = TYPE_BINFO_BASETYPES (rec);
-  int i, n_baseclasses = CLASSTYPE_N_BASECLASSES (rec);
-  tree vbase_types;
-  tree *field;
-
-  unsigned int record_align = MAX (BITS_PER_UNIT, TYPE_ALIGN (rec));
-  unsigned int desired_align;
-
-  /* Record size so far is CONST_SIZE bits, where CONST_SIZE is an integer.  */
-  register unsigned int const_size = 0;
-  unsigned int nonvirtual_const_size;
-
-#ifdef STRUCTURE_SIZE_BOUNDARY
-  /* Packed structures don't need to have minimum size.  */
-  if (! TYPE_PACKED (rec))
-    record_align = MAX (record_align, STRUCTURE_SIZE_BOUNDARY);
-#endif
-
-  /* Get all the virtual base types that this type uses.  The
-     TREE_VALUE slot holds the virtual baseclass type.  Note that
-     get_vbase_types makes copies of the virtual base BINFOs, so that
-     the vbase_types are unshared.  */
-  vbase_types = CLASSTYPE_VBASECLASSES (rec);
-
-  my_friendly_assert (TREE_CODE (TYPE_SIZE (rec)) == INTEGER_CST, 19970302);
-  const_size = TREE_INT_CST_LOW (TYPE_SIZE (rec));
-
-  nonvirtual_const_size = const_size;
-
-  while (vbase_types)
-    {
-      tree basetype = BINFO_TYPE (vbase_types);
-      tree offset;
-
-      desired_align = TYPE_ALIGN (basetype);
-      record_align = MAX (record_align, desired_align);
-
-      if (const_size == 0)
-       offset = integer_zero_node;
-      else
-       {
-         /* Give each virtual base type the alignment it wants.  */
-         const_size = CEIL (const_size, desired_align) * desired_align;
-         offset = size_int (CEIL (const_size, BITS_PER_UNIT));
-       }
-
-      if (CLASSTYPE_VSIZE (basetype) > max)
-       max = CLASSTYPE_VSIZE (basetype);
-      BINFO_OFFSET (vbase_types) = offset;
-
-      /* Every virtual baseclass takes a least a UNIT, so that we can
-        take it's address and get something different for each base.  */
-      const_size += MAX (BITS_PER_UNIT,
-                        TREE_INT_CST_LOW (CLASSTYPE_SIZE (basetype)));
-
-      vbase_types = TREE_CHAIN (vbase_types);
-    }
-
-  if (const_size)
-    {
-      /* Because a virtual base might take a single byte above,
-        we have to re-adjust the total size to make sure it is
-        a multiple of the alignment.  */
-      /* Give the whole object the alignment it wants.  */
-      const_size = CEIL (const_size, record_align) * record_align;
-    }
-
-  /* Set the alignment in the complete type.  We don't set CLASSTYPE_ALIGN
-   here, as that is for this class, without any virtual base classes.  */
-  TYPE_ALIGN (rec) = record_align;
-  if (const_size != nonvirtual_const_size)
-    {
-      TYPE_SIZE (rec) = size_int (const_size);
-      TYPE_SIZE_UNIT (rec) = size_binop (FLOOR_DIV_EXPR, TYPE_SIZE (rec),
-                                         size_int (BITS_PER_UNIT));
-    }
-
-  /* Now propagate offset information throughout the lattice.
-     Simultaneously, remove the temporary FIELD_DECLS we created in
-     build_base_fields to refer to base types.  */
-  field = &TYPE_FIELDS (rec);
-  if (TYPE_VFIELD (rec) == *field)
-    {
-      /* If this class did not have a primary base, we create a
-        virtual function table pointer.  It will be the first thing
-        in the class, under the new ABI.  Skip it; the base fields
-        will follow it.  */
-      my_friendly_assert (flag_new_abi 
-                         && !CLASSTYPE_HAS_PRIMARY_BASE_P (rec),
-                         19991218);
-      field = &TREE_CHAIN (*field);
-    }
-    
-  for (i = 0; i < n_baseclasses; i++)
-    {
-      register tree base_binfo = TREE_VEC_ELT (binfos, i);
-      register tree basetype = BINFO_TYPE (base_binfo);
-
-      if (TREE_VIA_VIRTUAL (base_binfo))
-       continue;
-
-      my_friendly_assert (TREE_TYPE (*field) == basetype, 23897);
-
-      if (get_base_distance (basetype, rec, 0, (tree*)0) == -2)
-       cp_warning ("direct base `%T' inaccessible in `%T' due to ambiguity",
-                   basetype, rec);
-
-      BINFO_OFFSET (base_binfo)
-       = size_int (CEIL (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (*field)),
-                         BITS_PER_UNIT));
-      propagate_binfo_offsets (base_binfo, BINFO_OFFSET (base_binfo));
-
-      /* Remove this field.  */
-      *field = TREE_CHAIN (*field);
-    }
-
-  for (vbase_types = CLASSTYPE_VBASECLASSES (rec); vbase_types;
-       vbase_types = TREE_CHAIN (vbase_types))
-    {
-      BINFO_INHERITANCE_CHAIN (vbase_types) = TYPE_BINFO (rec);
-      unshare_base_binfos (vbase_types);
-      propagate_binfo_offsets (vbase_types, BINFO_OFFSET (vbase_types));
-
-      if (extra_warnings)
-       {
-         tree basetype = BINFO_TYPE (vbase_types);
-         if (get_base_distance (basetype, rec, 0, (tree*)0) == -2)
-           cp_warning ("virtual base `%T' inaccessible in `%T' due to ambiguity",
-                       basetype, rec);
-       }
-    }
-
-  return max;
-}
-
 \f
 /* Hashing of lists so that we don't make duplicates.
    The entry point is `list_hash_canon'.  */