This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

C++ PATCH to keep track of nearly empty base classes



The IA64 ABI has a notion of "nearly empty" classes.  This patch keeps
track of the appropriate information for use in the class layout
algorithm.

--
Mark Mitchell                   mark@codesourcery.com
CodeSourcery, LLC               http://www.codesourcery.com

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.

Index: cp-tree.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/cp-tree.h,v
retrieving revision 1.370
diff -c -p -r1.370 cp-tree.h
*** cp-tree.h	1999/12/29 07:31:51	1.370
--- cp-tree.h	1999/12/29 08:27:01
*************** struct lang_type
*** 1218,1223 ****
--- 1218,1224 ----
  
    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
*************** struct lang_type
*** 1226,1232 ****
    /* 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;
        
    int vsize;
    int vfield_parent;
--- 1227,1233 ----
    /* 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 : 5;
        
    int vsize;
    int vfield_parent;
*************** struct lang_type
*** 1460,1465 ****
--- 1461,1471 ----
  
  /*  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) \
Index: class.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/class.c,v
retrieving revision 1.211
diff -c -p -r1.211 class.c
*** class.c	1999/12/29 07:31:51	1.211
--- class.c	1999/12/29 08:26:58
*************** check_bases (t, cant_have_default_ctor_p
*** 1511,1520 ****
--- 1511,1522 ----
  {
    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);
*************** check_bases (t, cant_have_default_ctor_p
*** 1578,1583 ****
--- 1580,1599 ----
  	    }
  	}
  
+       /* 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);
*************** check_field_decls (t, access_decls, empt
*** 3480,3486 ****
  	       non-empty.  */
  	    ;
  	  else
! 	    *empty_p = 0;
  	}
  
        if (TREE_CODE (x) == USING_DECL)
--- 3496,3507 ----
  	       non-empty.  */
  	    ;
  	  else
! 	    {
! 	      /* 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)
*************** check_bases_and_members (t, empty_p)
*** 3986,3991 ****
--- 4007,4016 ----
    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);
*************** check_bases_and_members (t, empty_p)
*** 3998,4003 ****
--- 4023,4033 ----
  
    /* 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.  */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]