cp-tree.h (lang_type): Add nearly_empty_p.
authorMark Mitchell <mark@codesourcery.com>
Wed, 29 Dec 1999 08:28:50 +0000 (08:28 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Wed, 29 Dec 1999 08:28:50 +0000 (08:28 +0000)
* cp-tree.h (lang_type): Add nearly_empty_p.  Adjust dummy.
(CLASSTYPE_NEARLY_EMPTY_P): New macro.
* class.c (check_bases): Update CLASSTYPE_NEARLY_EMPTY_P.
(check_field_decls): Likewise.
(check_bases_and_members): Likewise.

From-SVN: r31116

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

index 6e9e6fb..e6df5ba 100644 (file)
@@ -1,3 +1,11 @@
+1999-12-29  Mark Mitchell  <mark@codesourcery.com>
+
+       * cp-tree.h (lang_type): Add nearly_empty_p.  Adjust dummy.
+       (CLASSTYPE_NEARLY_EMPTY_P): New macro.
+       * class.c (check_bases): Update CLASSTYPE_NEARLY_EMPTY_P.
+       (check_field_decls): Likewise.
+       (check_bases_and_members): Likewise.
+
 1999-12-28  Mark Mitchell  <mark@codesourcery.com>
 
        * cp-tree.h (do_inline_function_hair): Remove.
index c381efb..88b566e 100644 (file)
@@ -1511,10 +1511,12 @@ check_bases (t, cant_have_default_ctor_p, cant_have_const_ctor_p,
 {
   int n_baseclasses;
   int i;
+  int seen_nearly_empty_base_p;
   tree binfos;
 
   binfos = TYPE_BINFO_BASETYPES (t);
   n_baseclasses = CLASSTYPE_N_BASECLASSES (t);
+  seen_nearly_empty_base_p = 0;
 
   /* An aggregate cannot have baseclasses.  */
   CLASSTYPE_NON_AGGREGATE (t) |= (n_baseclasses != 0);
@@ -1578,6 +1580,20 @@ check_bases (t, cant_have_default_ctor_p, cant_have_const_ctor_p,
            }
        }
 
+      /* If the base class is not empty or nearly empty, then this
+        class cannot be nearly empty.  */
+      if (!CLASSTYPE_NEARLY_EMPTY_P (basetype) && !is_empty_class (basetype))
+       CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
+      /* And if there is more than one nearly empty base, then the
+        derived class is not nearly empty either.  */
+      else if (CLASSTYPE_NEARLY_EMPTY_P (basetype) 
+              && seen_nearly_empty_base_p)
+       CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
+      /* If this is the first nearly empty base class, then remember
+        that we saw it.  */
+      else if (CLASSTYPE_NEARLY_EMPTY_P (basetype))
+       seen_nearly_empty_base_p = 1;
+
       /* A lot of properties from the bases also apply to the derived
         class.  */
       TYPE_NEEDS_CONSTRUCTING (t) |= TYPE_NEEDS_CONSTRUCTING (basetype);
@@ -3480,7 +3496,12 @@ check_field_decls (t, access_decls, empty_p,
               non-empty.  */
            ;
          else
-           *empty_p = 0;
+           {
+             /* The class is non-empty.  */
+             *empty_p = 0;
+             /* The class is not even nearly empty.  */
+             CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
+           }
        }
 
       if (TREE_CODE (x) == USING_DECL)
@@ -3986,6 +4007,10 @@ check_bases_and_members (t, empty_p)
   cant_have_const_ctor = 0;
   no_const_asn_ref = 0;
 
+  /* Assume that the class is nearly empty; we'll clear this flag if
+     it turns out not to be nearly empty.  */
+  CLASSTYPE_NEARLY_EMPTY_P (t) = 1;
+
   /* Check all the base-classes. */
   check_bases (t, &cant_have_default_ctor, &cant_have_const_ctor,
               &no_const_asn_ref);
@@ -3999,6 +4024,11 @@ check_bases_and_members (t, empty_p)
   /* Check all the method declarations.  */
   check_methods (t);
 
+  /* A nearly-empty class has to be polymorphic; a nearly empty class
+     contains a vptr.  */
+  if (!TYPE_POLYMORPHIC_P (t))
+    CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
+
   /* Do some bookkeeping that will guide the generation of implicitly
      declared member functions.  */
   TYPE_HAS_COMPLEX_INIT_REF (t)
index 0935f1e..d5be18c 100644 (file)
@@ -1218,6 +1218,7 @@ struct lang_type
 
   unsigned com_interface : 1;
   unsigned non_pod_class : 1;
+  unsigned nearly_empty_p : 1;
 
   /* When adding a flag here, consider whether or not it ought to
      apply to a template instance if it applies to the template.  If
@@ -1226,7 +1227,7 @@ struct lang_type
   /* There are six bits left to fill out a 32-bit word.  Keep track of
      this by updating the size of this bitfield whenever you add or
      remove a flag.  */
-  unsigned dummy : 6;
+  unsigned dummy : 5;
       
   int vsize;
   int vfield_parent;
@@ -1461,6 +1462,11 @@ struct lang_type
 /*  Nonzero means that this class type is a non-POD class.  */
 #define CLASSTYPE_NON_POD_P(NODE) (TYPE_LANG_SPECIFIC (NODE)->non_pod_class)
 
+/* Nonzero if this class is "nearly empty", i.e., contains only a
+   virtual function table pointer.  */
+#define CLASSTYPE_NEARLY_EMPTY_P(NODE) \
+  (TYPE_LANG_SPECIFIC (NODE)->nearly_empty_p)
+
 /* Nonzero means that this type is meant for communication via COM.  */
 #define CLASSTYPE_COM_INTERFACE(NODE) \
   (TYPE_LANG_SPECIFIC(NODE)->com_interface)