This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH to keep track of nearly empty base classes
- To: gcc-patches at gcc dot gnu dot org
- Subject: C++ PATCH to keep track of nearly empty base classes
- From: Mark Mitchell <mark at codesourcery dot com>
- Date: Wed, 29 Dec 1999 00:27:20 -0800
- Organization: CodeSourcery, LLC
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. */