+2002-10-21 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/8218
+ * cp-tree.h (lang_type_class): Add contains_empty_class_p.
+ (CLASSTYPE_CONTAINS_EMPTY_CLASS_P): New macro.
+ * class.c (check_bases): Update CLASSTYPE_CONTAINS_EMPTY_CLASS_P.
+ (check_field_decls): Likewise.
+ (layout_class_type): Likewise.
+ (finish_struct_1): Initialize it.
+ (walk_subobject_offsets): Use it to prune searches.
+
2002-10-18 Zack Weinberg <zack@codesourcery.com>
* decl.c (start_decl): Point users of the old initialized-
TYPE_OVERLOADS_ARRAY_REF (t) |= TYPE_OVERLOADS_ARRAY_REF (basetype);
TYPE_OVERLOADS_ARROW (t) |= TYPE_OVERLOADS_ARROW (basetype);
TYPE_POLYMORPHIC_P (t) |= TYPE_POLYMORPHIC_P (basetype);
+ CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t)
+ |= CLASSTYPE_CONTAINS_EMPTY_CLASS_P (basetype);
}
}
;
else
{
+ tree element_type;
+
/* The class is non-empty. */
*empty_p = 0;
/* The class is not even nearly empty. */
CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
+ /* If one of the data members contains an empty class,
+ so does T. */
+ element_type = strip_array_types (type);
+ if (CLASS_TYPE_P (element_type)
+ && CLASSTYPE_CONTAINS_EMPTY_CLASS_P (element_type))
+ CLASSTYPE_CONTAINS_EMPTY_CLASS_P (element_type) = 1;
}
}
tree field;
int i;
+ /* Avoid recursing into objects that are not interesting. */
+ if (!CLASSTYPE_CONTAINS_EMPTY_CLASS_P (type))
+ return 0;
+
/* Record the location of TYPE. */
r = (*f) (type, offset, offsets);
if (r)
}
else if (TREE_CODE (type) == ARRAY_TYPE)
{
+ tree element_type = strip_array_types (type);
tree domain = TYPE_DOMAIN (type);
tree index;
+ /* Avoid recursing into objects that are not interesting. */
+ if (!CLASS_TYPE_P (element_type)
+ || !CLASSTYPE_CONTAINS_EMPTY_CLASS_P (element_type))
+ return 0;
+
/* Step through each of the elements in the array. */
for (index = size_zero_node;
INT_CST_LT (index, TYPE_MAX_VALUE (domain));
/* 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;
+ CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t) = 0;
/* Check all the base-classes. */
check_bases (t, &cant_have_default_ctor, &cant_have_const_ctor,
CLASSTYPE_ALIGN (t) = TYPE_ALIGN (t);
CLASSTYPE_USER_ALIGN (t) = TYPE_USER_ALIGN (t);
+ /* Every empty class contains an empty class. */
+ if (*empty_p)
+ CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t) = 1;
+
/* 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. */
unsigned java_interface : 1;
unsigned non_zero_init : 1;
+ unsigned contains_empty_class_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
/* There are some 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 : 7;
+ unsigned dummy : 6;
int vsize;
#define CLASSTYPE_NEARLY_EMPTY_P(NODE) \
(TYPE_LANG_SPECIFIC (NODE)->nearly_empty_p)
+/* Nonzero if this class contains an empty subobject. */
+#define CLASSTYPE_CONTAINS_EMPTY_CLASS_P(NODE) \
+ (TYPE_LANG_SPECIFIC (NODE)->contains_empty_class_p)
+
/* A list of class types of which this type is a friend. The
TREE_VALUE is normally a TYPE, but will be a TEMPLATE_DECL in the
case of a template friend. */