]> 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.
 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.
 
        * 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>
 
        
 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 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;
 
 /* 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,
    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
 
 static int
-finish_base_struct (t, b, t_binfo)
+finish_base_struct (t, b)
      tree t;
      struct base_info *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));
   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);
 
       tree base_binfo = TREE_VEC_ELT (binfos, i);
       tree basetype = BINFO_TYPE (base_binfo);
 
+      /* Effective C++ rule 14.  We only need to check TYPE_VIRTUAL_P
+        here because the case of virtual functions but non-virtual
+        dtor is handled in finish_struct_1.  */
+      if (warn_ecpp && ! TYPE_VIRTUAL_P (basetype)
+         && TYPE_HAS_DESTRUCTOR (basetype))
+       cp_warning ("base class `%#T' has a non-virtual destructor", basetype);
+
       /* If the type of basetype is incomplete, then
         we already complained about that fact
         (and we should have fixed it up as well).  */
       /* If 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);
 
       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;
 
       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.  */
              /* 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));
              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.  */
                  /* 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;
                  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);
 
   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);
        }
     }
   {
        {
          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);
 
     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",
          {
            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;
   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;
   tree access_decls = NULL_TREE;
   int aggregate = 1;
   int empty = 1;
@@ -3125,13 +3100,6 @@ finish_struct_1 (t, warn_anon)
     }
 #endif
 
     }
 #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.
   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).  */
 
      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;
 
   else
     n_baseclasses = 0;
 
@@ -3150,13 +3118,7 @@ finish_struct_1 (t, warn_anon)
     {
       struct base_info base_info;
 
     {
       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;
       /* 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;
       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;
       aggregate = 0;
+      empty = 0;
     }
   else
     {
     }
   else
     {
@@ -3179,7 +3141,6 @@ finish_struct_1 (t, warn_anon)
       vfield = NULL_TREE;
       vfields = NULL_TREE;
       CLASSTYPE_RTTI (t) = NULL_TREE;
       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;
       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.  */
   /* 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;
 
   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);
 
     {
       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
   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;
 
 
   TYPE_FIELDS (t) = fields;
 
-  /* Pass layout information about base classes to layout_type, if any.  */
   if (n_baseclasses)
   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.  */
   else if (empty)
     {
       /* C++: do not let empty structures exist.  */
@@ -3914,16 +3864,13 @@ finish_struct_1 (t, warn_anon)
 
   layout_type (t);
 
 
   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);
 
      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.  */
   /* 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);
 
      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;
 
   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);
 
       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
 #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)
 
 #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 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));
 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 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))
 
 
 #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.  */
 
    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;
 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
 #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;
 
          /* 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
    baseclasses provide.  */
 
 int
-layout_vbasetypes (rec, max)
+layout_basetypes (rec, max)
      tree rec;
      int 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);
   /* 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.  */
       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));
        }
 
          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);
 
   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;
 }
 
     }
 
   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
 
 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;
 {
   /* 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++)
     {
 
   /* 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);
       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
 
       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,
              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));
                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.  */
 
        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
   return vbase_decls;
 }
 \f
This page took 0.106812 seconds and 5 git commands to generate.