* 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
+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.
* 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>
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;
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
-finish_base_struct (t, b, t_binfo)
+finish_base_struct (t, 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));
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). */
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;
/* 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));
/* 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;
}
}
- /* 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);
- 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);
}
}
{
- tree v = get_vbase_types (t_binfo);
+ tree v = get_vbase_types (t);
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",
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;
}
#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.
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;
{
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;
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;
+ empty = 0;
}
else
{
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;
/* 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;
}
}
- 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);
}
+ 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
TYPE_FIELDS (t) = fields;
- /* Pass layout information about base classes to layout_type, if any. */
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. */
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);
- 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. */
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;
- max_has_virtual = layout_vbasetypes (t, max_has_virtual);
vbases = CLASSTYPE_VBASECLASSES (t);
CLASSTYPE_N_VBASECLASSES (t) = list_length (vbases);
#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)
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));
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))
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;
#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;
}
}
-/* 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
-layout_vbasetypes (rec, max)
+layout_basetypes (rec, 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);
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));
}
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;
}
-/* 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
-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;
- 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++)
{
- int inc;
- unsigned int desired_align;
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
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));
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