]> gcc.gnu.org Git - gcc.git/commitdiff
Re-implement allocation of base class subobjects.
authorJason Merrill <jason@gcc.gnu.org>
Fri, 3 Apr 1998 03:41:20 +0000 (22:41 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Fri, 3 Apr 1998 03:41:20 +0000 (22:41 -0500)
* tree.c (unshare_base_binfos): New fn.
(layout_basetypes): Use it.  Now handles offsets of both virtual and
non-virtual bases, after layout_type.
(layout_vbasetypes): Remove.
(build_base_fields): Generate FIELD_DECLs for each non-virtual base.
(build_vbase_pointer_fields): Split out from old layout_basetypes.
* class.c (finish_base_struct): Lose offset handling code.
Move nonvdtor warning here.  Don't mess with t_binfo anymore.
(finish_struct_1): Don't mess with t_binfo anymore.  Use fns above.
* cp-tree.h: Adjust.

From-SVN: r18973

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

index 3de389d3c4e6173c734b0961eaa797eae5d0a57c..76101855e08e2c0a7e1c9203b722bc0d47e31138 100644 (file)
@@ -1,3 +1,17 @@
+Fri Apr  3 02:22:59 1998  Jason Merrill  <jason@yorick.cygnus.com>
+
+       Re-implement allocation of base class subobjects.
+       * tree.c (unshare_base_binfos): New fn.
+       (layout_basetypes): Use it.  Now handles offsets of both virtual and
+       non-virtual bases, after layout_type.
+       (layout_vbasetypes): Remove.
+       (build_base_fields): Generate FIELD_DECLs for each non-virtual base.
+       (build_vbase_pointer_fields): Split out from old layout_basetypes.
+       * class.c (finish_base_struct): Lose offset handling code.
+       Move nonvdtor warning here.  Don't mess with t_binfo anymore.
+       (finish_struct_1): Don't mess with t_binfo anymore.  Use fns above.
+       * cp-tree.h: Adjust.
+
 Thu Apr  2 14:25:13 1998  Jason Merrill  <jason@yorick.cygnus.com>
 
        * cp-tree.h: Lose CLASSTYPE_VBASE_SIZE, some unused stuff.
@@ -12,7 +26,7 @@ Wed Apr  1 18:22:25 1998  Jeffrey A Law  (law@cygnus.com)
 
        * class.c, Make sure system.h is included just after config.h.
        Delete lingering stdio and errno references too.
-       * decl.c, errfn.c, parse.y, ptree.c search.c, xrefc.: Likewwise.
+       * decl.c, errfn.c, parse.y, ptree.c search.c, xref.c: Likewise.
        
 Wed Apr  1 15:38:36 1998  Jason Merrill  <jason@yorick.cygnus.com>
 
index 3559c04221ebed07f0f2ee0bdb2fa1cc20116e08..c39caac5b119db1e21d689e1f6c716f2aa157bc3 100644 (file)
@@ -124,7 +124,7 @@ static void modify_all_direct_vtables PROTO((tree, int, tree, tree,
 static void modify_all_indirect_vtables PROTO((tree, int, int, tree,
                                               tree, tree));
 static void build_class_init_list PROTO((tree));
-static int finish_base_struct PROTO((tree, struct base_info *, tree));
+static int finish_base_struct PROTO((tree, struct base_info *));
 
 /* Way of stacking language names.  */
 tree *current_lang_base, *current_lang_stack;
@@ -1526,17 +1526,14 @@ struct base_info
    offsets include that offset in theirs.
 
    Returns the index of the first base class to have virtual functions,
-   or -1 if no such base class.
-
-   Note that at this point TYPE_BINFO (t) != t_binfo.  */
+   or -1 if no such base class.  */
 
 static int
-finish_base_struct (t, b, t_binfo)
+finish_base_struct (t, b)
      tree t;
      struct base_info *b;
-     tree t_binfo;
 {
-  tree binfos = BINFO_BASETYPES (t_binfo);
+  tree binfos = TYPE_BINFO_BASETYPES (t);
   int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0;
   int first_vfn_base_index = -1;
   bzero ((char *) b, sizeof (struct base_info));
@@ -1546,6 +1543,13 @@ finish_base_struct (t, b, t_binfo)
       tree base_binfo = TREE_VEC_ELT (binfos, i);
       tree basetype = BINFO_TYPE (base_binfo);
 
+      /* Effective C++ rule 14.  We only need to check TYPE_VIRTUAL_P
+        here because the case of virtual functions but non-virtual
+        dtor is handled in finish_struct_1.  */
+      if (warn_ecpp && ! TYPE_VIRTUAL_P (basetype)
+         && TYPE_HAS_DESTRUCTOR (basetype))
+       cp_warning ("base class `%#T' has a non-virtual destructor", basetype);
+
       /* If the type of basetype is incomplete, then
         we already complained about that fact
         (and we should have fixed it up as well).  */
@@ -1592,36 +1596,6 @@ finish_base_struct (t, b, t_binfo)
       TYPE_OVERLOADS_ARRAY_REF (t) |= TYPE_OVERLOADS_ARRAY_REF (basetype);
       TYPE_OVERLOADS_ARROW (t) |= TYPE_OVERLOADS_ARROW (basetype);
 
-      if (! TREE_VIA_VIRTUAL (base_binfo)
-         && BINFO_BASETYPES (base_binfo))
-       {
-         tree base_binfos = BINFO_BASETYPES (base_binfo);
-         tree chain = NULL_TREE;
-         int j;
-
-         /* Now unshare the structure beneath BASE_BINFO.  */
-         for (j = TREE_VEC_LENGTH (base_binfos)-1;
-              j >= 0; j--)
-           {
-             tree base_base_binfo = TREE_VEC_ELT (base_binfos, j);
-             if (! TREE_VIA_VIRTUAL (base_base_binfo))
-               TREE_VEC_ELT (base_binfos, j)
-                 = make_binfo (BINFO_OFFSET (base_base_binfo),
-                               base_base_binfo,
-                               BINFO_VTABLE (base_base_binfo),
-                               BINFO_VIRTUALS (base_base_binfo),
-                               chain);
-             chain = TREE_VEC_ELT (base_binfos, j);
-             TREE_VIA_PUBLIC (chain) = TREE_VIA_PUBLIC (base_base_binfo);
-             TREE_VIA_PROTECTED (chain) = TREE_VIA_PROTECTED (base_base_binfo);
-             BINFO_INHERITANCE_CHAIN (chain) = base_binfo;
-           }
-
-         /* Completely unshare potentially shared data, and
-            update what is ours.  */
-         propagate_binfo_offsets (base_binfo, BINFO_OFFSET (base_binfo));
-       }
-
       if (! TREE_VIA_VIRTUAL (base_binfo))
        CLASSTYPE_N_SUPERCLASSES (t) += 1;
 
@@ -1644,8 +1618,8 @@ finish_base_struct (t, b, t_binfo)
              /* Update these two, now that we know what vtable we are
                 going to extend.  This is so that we can add virtual
                 functions, and override them properly.  */
-             BINFO_VTABLE (t_binfo) = TYPE_BINFO_VTABLE (basetype);
-             BINFO_VIRTUALS (t_binfo) = TYPE_BINFO_VIRTUALS (basetype);
+             TYPE_BINFO_VTABLE (t) = TYPE_BINFO_VTABLE (basetype);
+             TYPE_BINFO_VIRTUALS (t) = TYPE_BINFO_VIRTUALS (basetype);
              b->has_virtual = CLASSTYPE_VSIZE (basetype);
              b->vfield = CLASSTYPE_VFIELD (basetype);
              b->vfields = copy_list (CLASSTYPE_VFIELDS (basetype));
@@ -1693,8 +1667,8 @@ finish_base_struct (t, b, t_binfo)
                  /* Update these two, now that we know what vtable we are
                     going to extend.  This is so that we can add virtual
                     functions, and override them properly.  */
-                 BINFO_VTABLE (t_binfo) = TYPE_BINFO_VTABLE (basetype);
-                 BINFO_VIRTUALS (t_binfo) = TYPE_BINFO_VIRTUALS (basetype);
+                 TYPE_BINFO_VTABLE (t) = TYPE_BINFO_VTABLE (basetype);
+                 TYPE_BINFO_VIRTUALS (t) = TYPE_BINFO_VIRTUALS (basetype);
                  b->has_virtual = CLASSTYPE_VSIZE (basetype);
                  b->vfield = CLASSTYPE_VFIELD (basetype);
                  CLASSTYPE_VFIELD (t) = b->vfield;
@@ -1720,25 +1694,27 @@ finish_base_struct (t, b, t_binfo)
        }
     }
 
-  /* Must come after offsets are fixed for all bases.  */
+  /* This comment said "Must come after offsets are fixed for all bases."
+     Well, now this happens before the offsets are fixed, but it seems to
+     work fine.  Guess we'll see...  */
   for (i = 0; i < n_baseclasses; i++)
     {
       tree base_binfo = TREE_VEC_ELT (binfos, i);
       tree basetype = BINFO_TYPE (base_binfo);
 
-      if (get_base_distance (basetype, t_binfo, 0, (tree*)0) == -2)
+      if (get_base_distance (basetype, t, 0, (tree*)0) == -2)
        {
          cp_warning ("direct base `%T' inaccessible in `%T' due to ambiguity",
                      basetype, t);
        }
     }
   {
-    tree v = get_vbase_types (t_binfo);
+    tree v = get_vbase_types (t);
 
     for (; v; v = TREE_CHAIN (v))
       {
        tree basetype = BINFO_TYPE (v);
-       if (get_base_distance (basetype, t_binfo, 0, (tree*)0) == -2)
+       if (get_base_distance (basetype, t, 0, (tree*)0) == -2)
          {
            if (extra_warnings)
              cp_warning ("virtual base `%T' inaccessible in `%T' due to ambiguity",
@@ -3088,7 +3064,6 @@ finish_struct_1 (t, warn_anon)
   int const_sans_init = 0;
   int ref_sans_init = 0;
   int nonprivate_method = 0;
-  tree t_binfo = TYPE_BINFO (t);
   tree access_decls = NULL_TREE;
   int aggregate = 1;
   int empty = 1;
@@ -3125,13 +3100,6 @@ finish_struct_1 (t, warn_anon)
     }
 #endif
 
-#if 0
-  if (flag_rtti)
-    build_t_desc (t, 0);
-#endif
-
-  TYPE_BINFO (t) = NULL_TREE;
-
   old = suspend_momentary ();
 
   /* Install struct as DECL_FIELD_CONTEXT of each field decl.
@@ -3141,8 +3109,8 @@ finish_struct_1 (t, warn_anon)
      Store 0 there, except for ": 0" fields (so we can find them
      and delete them, below).  */
 
-  if (t_binfo && BINFO_BASETYPES (t_binfo))
-    n_baseclasses = TREE_VEC_LENGTH (BINFO_BASETYPES (t_binfo));
+  if (TYPE_BINFO_BASETYPES (t))
+    n_baseclasses = TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES (t));
   else
     n_baseclasses = 0;
 
@@ -3150,13 +3118,7 @@ finish_struct_1 (t, warn_anon)
     {
       struct base_info base_info;
 
-      /* If using multiple inheritance, this may cause variants of our
-        basetypes to be used (instead of their canonical forms).  */
-      tree vf = layout_basetypes (t, BINFO_BASETYPES (t_binfo));
-      last_x = tree_last (vf);
-      fields = chainon (vf, fields);
-
-      first_vfn_base_index = finish_base_struct (t, &base_info, t_binfo);
+      first_vfn_base_index = finish_base_struct (t, &base_info);
       /* Remember where we got our vfield from.  */
       CLASSTYPE_VFIELD_PARENT (t) = first_vfn_base_index;
       has_virtual = base_info.has_virtual;
@@ -3168,8 +3130,8 @@ finish_struct_1 (t, warn_anon)
       cant_have_default_ctor = base_info.cant_have_default_ctor;
       cant_have_const_ctor = base_info.cant_have_const_ctor;
       no_const_asn_ref = base_info.no_const_asn_ref;
-      n_baseclasses = TREE_VEC_LENGTH (BINFO_BASETYPES (t_binfo));
       aggregate = 0;
+      empty = 0;
     }
   else
     {
@@ -3179,7 +3141,6 @@ finish_struct_1 (t, warn_anon)
       vfield = NULL_TREE;
       vfields = NULL_TREE;
       CLASSTYPE_RTTI (t) = NULL_TREE;
-      last_x = NULL_TREE;
       cant_have_default_ctor = 0;
       cant_have_const_ctor = 0;
       no_const_asn_ref = 0;
@@ -3198,8 +3159,6 @@ finish_struct_1 (t, warn_anon)
   /* The three of these are approximations which may later be
      modified.  Needed at this point to make add_virtual_function
      and modify_vtable_entries work.  */
-  TREE_CHAIN (t_binfo) = TYPE_BINFO (t);
-  TYPE_BINFO (t) = t_binfo;
   CLASSTYPE_VFIELDS (t) = vfields;
   CLASSTYPE_VFIELD (t) = vfield;
 
@@ -3250,7 +3209,8 @@ finish_struct_1 (t, warn_anon)
        }
     }
 
-  for (x = TYPE_FIELDS (t); x; x = TREE_CHAIN (x))
+  last_x = NULL_TREE;
+  for (x = fields; x; x = TREE_CHAIN (x))
     {
       GNU_xref_member (current_class_name, x);
 
@@ -3797,6 +3757,9 @@ finish_struct_1 (t, warn_anon)
     
   }
 
+  if (n_baseclasses)
+    fields = chainon (build_vbase_pointer_fields (t), fields);
+
   if (vfield == NULL_TREE && has_virtual)
     {
       /* We build this decl with ptr_type_node, and
@@ -3888,21 +3851,8 @@ finish_struct_1 (t, warn_anon)
 
   TYPE_FIELDS (t) = fields;
 
-  /* Pass layout information about base classes to layout_type, if any.  */
   if (n_baseclasses)
-    {
-      tree pseudo_basetype = TREE_TYPE (base_layout_decl);
-
-      TREE_CHAIN (base_layout_decl) = TYPE_FIELDS (t);
-      TYPE_FIELDS (t) = base_layout_decl;
-
-      TYPE_SIZE (pseudo_basetype) = CLASSTYPE_SIZE (t);
-      TYPE_MODE (pseudo_basetype) = TYPE_MODE (t);
-      TYPE_ALIGN (pseudo_basetype) = CLASSTYPE_ALIGN (t);
-      DECL_ALIGN (base_layout_decl) = TYPE_ALIGN (pseudo_basetype);
-      /* Don't re-use old size.  */
-      DECL_SIZE (base_layout_decl) = NULL_TREE;
-    }
+    TYPE_FIELDS (t) = chainon (build_base_fields (t), fields);
   else if (empty)
     {
       /* C++: do not let empty structures exist.  */
@@ -3914,16 +3864,13 @@ finish_struct_1 (t, warn_anon)
 
   layout_type (t);
 
-  /* Remember the size, mode and alignment of the class before adding
+  /* Remember the size and alignment of the class before adding
      the virtual bases.  */
   CLASSTYPE_SIZE (t) = TYPE_SIZE (t);
   CLASSTYPE_ALIGN (t) = TYPE_ALIGN (t);
 
   finish_struct_anon (t);
 
-  if (n_baseclasses || empty)
-    TYPE_FIELDS (t) = TREE_CHAIN (TYPE_FIELDS (t));
-
   /* Set the TYPE_DECL for this type to contain the right
      value for DECL_OFFSET, so that we can use it as part
      of a COMPONENT_REF for multiple inheritance.  */
@@ -3935,11 +3882,16 @@ finish_struct_1 (t, warn_anon)
      virtual function table.  */
   pending_hard_virtuals = nreverse (pending_hard_virtuals);
 
+  if (n_baseclasses)
+    /* layout_basetypes will remove the base subobject fields.  */
+    max_has_virtual = layout_basetypes (t, max_has_virtual);
+  else if (empty)
+    TYPE_FIELDS (t) = fields;
+
   if (TYPE_USES_VIRTUAL_BASECLASSES (t))
     {
       tree vbases;
 
-      max_has_virtual = layout_vbasetypes (t, max_has_virtual);
       vbases = CLASSTYPE_VBASECLASSES (t);
       CLASSTYPE_N_VBASECLASSES (t) = list_length (vbases);
 
index 25749d3625f19368d1fc0c1cd7724139f3d00b96..c62fe082a97b9f657d6c95108d2b555d066d3b8f 100644 (file)
@@ -728,13 +728,7 @@ struct lang_type
 #define CLASSTYPE_MTABLE_ENTRY(NODE) (TYPE_LANG_SPECIFIC(NODE)->memoized_table_entry)
 
 /* These are the size, mode and alignment of the type without its
-   virtual base classes, for when we use this type as a base itself.
-
-   CLASSTYPE_SIZE is also used during finish_struct_1 to remember the total
-   size of the baseclasses defined for the type.  We do this because it is
-   desirable to layout such information before beginning to process the
-   class itself, and we don't want to compute it second time when actually
-   laying out the type for real.  */
+   virtual base classes, for when we use this type as a base itself.  */
 #define CLASSTYPE_SIZE(NODE) (TYPE_LANG_SPECIFIC(NODE)->size)
 #define CLASSTYPE_ALIGN(NODE) (TYPE_LANG_SPECIFIC(NODE)->align)
 
@@ -2591,9 +2585,9 @@ 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 void propagate_binfo_offsets            PROTO((tree, tree));
-extern int layout_vbasetypes                   PROTO((tree, int));
-extern tree layout_basetypes                   PROTO((tree, tree));
+extern int layout_basetypes                    PROTO((tree, int));
+extern tree build_vbase_pointer_fields         PROTO((tree));
+extern tree build_base_fields                  PROTO((tree));
 extern tree hash_tree_cons                     PROTO((int, int, int, tree, tree, tree));
 extern tree hash_tree_chain                    PROTO((tree, tree));
 extern tree hash_chainon                       PROTO((tree, tree));
index 2f6dbe623bcbe76216901c5691b560d7b2fb71af..8f4d02d70ffa8cd1a3e6d4fdd3a107d41db70801 100644 (file)
@@ -42,6 +42,8 @@ static void list_hash_add PROTO((int, tree));
 static int list_hash PROTO((tree, tree, tree));
 static tree list_hash_lookup PROTO((int, int, int, int, tree, tree,
                                    tree));
+static void propagate_binfo_offsets PROTO((tree, tree));
+static void unshare_base_binfos PROTO((tree));
 
 #define CEIL(x,y) (((x) + (y) - 1) / (y))
 
@@ -548,7 +550,7 @@ cp_build_type_variant (type, constp, volatilep)
    Note that we don't have to worry about having two paths to the
    same base type, since this type owns its association list.  */
 
-void
+static void
 propagate_binfo_offsets (binfo, offset)
      tree binfo;
      tree offset;
@@ -588,31 +590,8 @@ propagate_binfo_offsets (binfo, offset)
 #else
          BINFO_OFFSET (base_binfo) = offset;
 #endif
-         if (base_binfos)
-           {
-             int k;
-             tree chain = NULL_TREE;
-
-             /* Now unshare the structure beneath BASE_BINFO.  */
-             for (k = TREE_VEC_LENGTH (base_binfos)-1;
-                  k >= 0; k--)
-               {
-                 tree base_base_binfo = TREE_VEC_ELT (base_binfos, k);
-                 if (! TREE_VIA_VIRTUAL (base_base_binfo))
-                   TREE_VEC_ELT (base_binfos, k)
-                     = make_binfo (BINFO_OFFSET (base_base_binfo),
-                                   base_base_binfo,
-                                   BINFO_VTABLE (base_base_binfo),
-                                   BINFO_VIRTUALS (base_base_binfo),
-                                   chain);
-                 chain = TREE_VEC_ELT (base_binfos, k);
-                 TREE_VIA_PUBLIC (chain) = TREE_VIA_PUBLIC (base_base_binfo);
-                 TREE_VIA_PROTECTED (chain) = TREE_VIA_PROTECTED (base_base_binfo);
-                 BINFO_INHERITANCE_CHAIN (chain) = base_binfo;
-               }
-             /* Now propagate the offset to the base types.  */
-             propagate_binfo_offsets (base_binfo, offset);
-           }
+
+         unshare_base_binfos (base_binfo);
 
          /* Go to our next class that counts for offset propagation.  */
          i = j;
@@ -622,19 +601,59 @@ propagate_binfo_offsets (binfo, offset)
     }
 }
 
-/* Compute the actual offsets that our virtual base classes
-   will have *for this type*.  This must be performed after
-   the fields are laid out, since virtual baseclasses must
-   lay down at the end of the record.
+/* Makes new binfos for the indirect bases under BASE_BINFO, and updates
+   BINFO_OFFSET for them and their bases.  */
 
-   Returns the maximum number of virtual functions any of the virtual
+static void
+unshare_base_binfos (base_binfo)
+     tree base_binfo;
+{
+  if (BINFO_BASETYPES (base_binfo))
+    {
+      tree base_binfos = BINFO_BASETYPES (base_binfo);
+      tree chain = NULL_TREE;
+      int j;
+
+      /* Now unshare the structure beneath BASE_BINFO.  */
+      for (j = TREE_VEC_LENGTH (base_binfos)-1;
+          j >= 0; j--)
+       {
+         tree base_base_binfo = TREE_VEC_ELT (base_binfos, j);
+         if (! TREE_VIA_VIRTUAL (base_base_binfo))
+           TREE_VEC_ELT (base_binfos, j)
+             = make_binfo (BINFO_OFFSET (base_base_binfo),
+                           base_base_binfo,
+                           BINFO_VTABLE (base_base_binfo),
+                           BINFO_VIRTUALS (base_base_binfo),
+                           chain);
+         chain = TREE_VEC_ELT (base_binfos, j);
+         TREE_VIA_PUBLIC (chain) = TREE_VIA_PUBLIC (base_base_binfo);
+         TREE_VIA_PROTECTED (chain) = TREE_VIA_PROTECTED (base_base_binfo);
+         BINFO_INHERITANCE_CHAIN (chain) = base_binfo;
+       }
+
+      /* Completely unshare potentially shared data, and
+        update what is ours.  */
+      propagate_binfo_offsets (base_binfo, BINFO_OFFSET (base_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_vbasetypes (rec, max)
+layout_basetypes (rec, max)
      tree rec;
      int max;
 {
+  tree binfos = TYPE_BINFO_BASETYPES (rec);
+  int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0;
+
   /* Get all the virtual base types that this type uses.
      The TREE_VALUE slot holds the virtual baseclass type.  */
   tree vbase_types = get_vbase_types (rec);
@@ -672,8 +691,7 @@ layout_vbasetypes (rec, max)
       else
        {
          /* Give each virtual base type the alignment it wants.  */
-         const_size = CEIL (const_size, TYPE_ALIGN (basetype))
-           * TYPE_ALIGN (basetype);
+         const_size = CEIL (const_size, desired_align) * desired_align;
          offset = size_int (CEIL (const_size, BITS_PER_UNIT));
        }
 
@@ -704,85 +722,106 @@ layout_vbasetypes (rec, max)
   if (const_size != nonvirtual_const_size)
     TYPE_SIZE (rec) = size_int (const_size);
 
-  /* Now propagate offset information throughout the lattice
-     under the vbase type.  */
-  for (vbase_types = CLASSTYPE_VBASECLASSES (rec); vbase_types;
-       vbase_types = TREE_CHAIN (vbase_types))
+  /* Now propagate offset information throughout the lattice.  */
+  for (i = 0; i < n_baseclasses; i++)
     {
-      tree base_binfos = BINFO_BASETYPES (vbase_types);
-
-      BINFO_INHERITANCE_CHAIN (vbase_types) = TYPE_BINFO (rec);
+      register tree base_binfo = TREE_VEC_ELT (binfos, i);
+      register tree basetype = BINFO_TYPE (base_binfo);
+      tree field = TYPE_FIELDS (rec);
 
-      if (base_binfos)
-       {
-         tree chain = NULL_TREE;
-         int j;
-         /* Now unshare the structure beneath BASE_BINFO.  */
+      if (TREE_VIA_VIRTUAL (base_binfo))
+       continue;
 
-         for (j = TREE_VEC_LENGTH (base_binfos)-1;
-              j >= 0; j--)
-           {
-             tree base_base_binfo = TREE_VEC_ELT (base_binfos, j);
-             if (! TREE_VIA_VIRTUAL (base_base_binfo))
-               TREE_VEC_ELT (base_binfos, j)
-                 = make_binfo (BINFO_OFFSET (base_base_binfo),
-                               base_base_binfo,
-                               BINFO_VTABLE (base_base_binfo),
-                               BINFO_VIRTUALS (base_base_binfo),
-                               chain);
-             chain = TREE_VEC_ELT (base_binfos, j);
-             TREE_VIA_PUBLIC (chain) = TREE_VIA_PUBLIC (base_base_binfo);
-             TREE_VIA_PROTECTED (chain) = TREE_VIA_PROTECTED (base_base_binfo);
-             BINFO_INHERITANCE_CHAIN (chain) = vbase_types;
-           }
+      my_friendly_assert (TREE_TYPE (field) == basetype, 23897);
+      BINFO_OFFSET (base_binfo)
+       = size_int (CEIL (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field)),
+                         BITS_PER_UNIT));
+      unshare_base_binfos (base_binfo);
+      TYPE_FIELDS (rec) = TREE_CHAIN (field);
+    }
 
-         propagate_binfo_offsets (vbase_types, BINFO_OFFSET (vbase_types));
-       }
+  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);
     }
 
   return max;
 }
 
-/* Lay out the base types of a record type, REC.
-   Tentatively set the size and alignment of REC
-   according to the base types alone.
+/* Returns a list of fields to stand in for the base class subobjects
+   of REC.  These fields are later removed by layout_basetypes.  */
+
+tree
+build_base_fields (rec)
+     tree rec;
+{
+  /* Chain to hold all the new FIELD_DECLs which stand in for base class
+     subobjects.  */
+  tree base_decls = NULL_TREE;
+  tree binfos = TYPE_BINFO_BASETYPES (rec);
+  int n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0;
+  tree decl;
+  int i;
+  unsigned int base_align = 0;
+
+  for (i = 0; i < n_baseclasses; ++i)
+    {
+      register tree base_binfo = TREE_VEC_ELT (binfos, i);
+      register tree basetype = BINFO_TYPE (base_binfo);
 
-   Offsets for immediate nonvirtual baseclasses are also computed here.
+      if (TYPE_SIZE (basetype) == 0)
+       /* This error is now reported in xref_tag, thus giving better
+          location information.  */
+       continue;
 
-   TYPE_BINFO (REC) should be NULL_TREE on entry, and this routine
-   creates a list of base_binfos in TYPE_BINFO (REC) from BINFOS.
+      if (TREE_VIA_VIRTUAL (base_binfo))
+       continue;
 
-   Returns list of virtual base class pointers in a FIELD_DECL chain.  */
+      decl = build_lang_field_decl (FIELD_DECL, NULL_TREE, basetype);
+      DECL_ARTIFICIAL (decl) = 1;
+      DECL_FIELD_CONTEXT (decl) = DECL_CLASS_CONTEXT (decl) = rec;
+      DECL_SIZE (decl) = CLASSTYPE_SIZE (basetype);
+      DECL_ALIGN (decl) = CLASSTYPE_ALIGN (basetype);
+      TREE_CHAIN (decl) = base_decls;
+      base_decls = decl;
+
+      /* Brain damage for backwards compatibility.  For no good reason, the
+        old layout_basetypes made every base at least as large as the
+        alignment for the bases up to that point, gratuitously wasting
+        space.  So we do the same thing here.  */
+      base_align = MAX (base_align, DECL_ALIGN (decl));
+      DECL_SIZE (decl) = size_int (MAX (TREE_INT_CST_LOW (DECL_SIZE (decl)),
+                                       base_align));
+    }
+
+  /* Reverse the list of fields so we allocate the bases in the proper
+     order.  */
+  return nreverse (base_decls);
+}
+
+/* Returns list of virtual base class pointers in a FIELD_DECL chain.  */
 
 tree
-layout_basetypes (rec, binfos)
-     tree rec, binfos;
+build_vbase_pointer_fields (rec)
+     tree rec;
 {
   /* Chain to hold all the new FIELD_DECLs which point at virtual
      base classes.  */
   tree vbase_decls = NULL_TREE;
-  unsigned record_align = MAX (BITS_PER_UNIT, TYPE_ALIGN (rec));
-
-  /* Record size so far is CONST_SIZE bits, where CONST_SIZE is an integer.  */
-  register unsigned const_size = 0;
-  int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0;
-
-#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
+  tree binfos = TYPE_BINFO_BASETYPES (rec);
+  int n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0;
+  tree decl;
+  int i;
 
   /* Handle basetypes almost like fields, but record their
      offsets differently.  */
 
   for (i = 0; i < n_baseclasses; i++)
     {
-      int inc;
-      unsigned int desired_align;
       register tree base_binfo = TREE_VEC_ELT (binfos, i);
       register tree basetype = BINFO_TYPE (base_binfo);
-      tree decl, offset;
 
       if (TYPE_SIZE (basetype) == 0)
        /* This error is now reported in xref_tag, thus giving better
@@ -811,7 +850,9 @@ layout_basetypes (rec, binfos)
              tree other_base_binfo = TREE_VEC_ELT (binfos, j);
              if (! TREE_VIA_VIRTUAL (other_base_binfo)
                  && binfo_member (basetype,
-                                  CLASSTYPE_VBASECLASSES (BINFO_TYPE (other_base_binfo))))
+                                  CLASSTYPE_VBASECLASSES (BINFO_TYPE
+                                                          (other_base_binfo))
+                                  ))
                goto got_it;
            }
          sprintf (name, VBASE_NAME_FORMAT, TYPE_NAME_STRING (basetype));
@@ -835,51 +876,10 @@ layout_basetypes (rec, binfos)
 
        got_it:
          /* The space this decl occupies has already been accounted for.  */
-         continue;
-       }
-
-      /* Effective C++ rule 14.  We only need to check TYPE_VIRTUAL_P
-        here because the case of virtual functions but non-virtual
-        dtor is handled in finish_struct_1.  */
-      if (warn_ecpp && ! TYPE_VIRTUAL_P (basetype)
-         && TYPE_HAS_DESTRUCTOR (basetype))
-       cp_warning ("base class `%#T' has a non-virtual destructor", basetype);
-
-      if (const_size == 0)
-       offset = integer_zero_node;
-      else
-       {
-         /* Give each base type the alignment it wants.  */
-         const_size = CEIL (const_size, TYPE_ALIGN (basetype))
-           * TYPE_ALIGN (basetype);
-         offset = size_int ((const_size + BITS_PER_UNIT - 1) / BITS_PER_UNIT);
+         ;
        }
-      BINFO_OFFSET (base_binfo) = offset;
-      if (CLASSTYPE_VSIZE (basetype))
-       {
-         BINFO_VTABLE (base_binfo) = TYPE_BINFO_VTABLE (basetype);
-         BINFO_VIRTUALS (base_binfo) = TYPE_BINFO_VIRTUALS (basetype);
-       }
-      TREE_CHAIN (base_binfo) = TYPE_BINFO (rec);
-      TYPE_BINFO (rec) = base_binfo;
-
-      /* Add only the amount of storage not present in
-        the virtual baseclasses.  */
-      inc = MAX (record_align, TREE_INT_CST_LOW (CLASSTYPE_SIZE (basetype)));
-
-      /* Record must have at least as much alignment as any field.  */
-      desired_align = TYPE_ALIGN (basetype);
-      record_align = MAX (record_align, desired_align);
-
-      const_size += inc;
     }
 
-  if (const_size)
-    CLASSTYPE_SIZE (rec) = size_int (const_size);
-  else
-    CLASSTYPE_SIZE (rec) = integer_zero_node;
-  CLASSTYPE_ALIGN (rec) = record_align;
-
   return vbase_decls;
 }
 \f
This page took 0.104791 seconds and 5 git commands to generate.