mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-02-13 01:09:44 +08:00
cp-tree.h: Tweak documentation.
* cp-tree.h: Tweak documentation. * class.c (build_vbase_pointer_fields): Layout the fields, too. (avoid_overlap): Remove. (get_binfo_offset_as_int): New function. (dfs_serach_base_offsets): Likewise. (layout_nonempty_base_or_field): Likewise. (build_base_field): Layout fields here. Avoid placing two objects of the same type at the same address, under the new ABI. (build_base_fields): Adjust accordingly. (create_vtable_ptr): Return the new field, but don't attach it to TYPE_FIELDS. (remove_base_field): Remove. (remove_base_fields): Remove. (layout_basetypes): Adjust accordingly. (layout_class_type): Call layout_field for each field, rather than just making a wholesale call to layout_type. From-SVN: r32549
This commit is contained in:
parent
cc9d4a85d7
commit
5c24fba69a
@ -1,3 +1,22 @@
|
|||||||
|
2000-03-14 Mark Mitchell <mark@codesourcery.com>
|
||||||
|
|
||||||
|
* cp-tree.h: Tweak documentation.
|
||||||
|
* class.c (build_vbase_pointer_fields): Layout the fields, too.
|
||||||
|
(avoid_overlap): Remove.
|
||||||
|
(get_binfo_offset_as_int): New function.
|
||||||
|
(dfs_serach_base_offsets): Likewise.
|
||||||
|
(layout_nonempty_base_or_field): Likewise.
|
||||||
|
(build_base_field): Layout fields here. Avoid placing two objects
|
||||||
|
of the same type at the same address, under the new ABI.
|
||||||
|
(build_base_fields): Adjust accordingly.
|
||||||
|
(create_vtable_ptr): Return the new field, but don't attach it to
|
||||||
|
TYPE_FIELDS.
|
||||||
|
(remove_base_field): Remove.
|
||||||
|
(remove_base_fields): Remove.
|
||||||
|
(layout_basetypes): Adjust accordingly.
|
||||||
|
(layout_class_type): Call layout_field for each field, rather than
|
||||||
|
just making a wholesale call to layout_type.
|
||||||
|
|
||||||
2000-03-14 Jeff Sturm <jsturm@sigma6.com>
|
2000-03-14 Jeff Sturm <jsturm@sigma6.com>
|
||||||
|
|
||||||
* except.c (expand_throw): Fix typo in _Jv_Sjlj_Throw.
|
* except.c (expand_throw): Fix typo in _Jv_Sjlj_Throw.
|
||||||
|
570
gcc/cp/class.c
570
gcc/cp/class.c
@ -116,17 +116,17 @@ static void check_bitfield_decl PARAMS ((tree));
|
|||||||
static void check_field_decl PARAMS ((tree, tree, int *, int *, int *, int *));
|
static void check_field_decl PARAMS ((tree, tree, int *, int *, int *, int *));
|
||||||
static void check_field_decls PARAMS ((tree, tree *, int *, int *, int *,
|
static void check_field_decls PARAMS ((tree, tree *, int *, int *, int *,
|
||||||
int *));
|
int *));
|
||||||
static int avoid_overlap PARAMS ((tree, tree, int *));
|
static void build_base_field PARAMS ((record_layout_info, tree, int *,
|
||||||
static tree build_base_field PARAMS ((tree, tree, int *, int *, unsigned int *));
|
unsigned int *, varray_type *));
|
||||||
static tree build_base_fields PARAMS ((tree, int *));
|
static varray_type build_base_fields PARAMS ((record_layout_info, int *));
|
||||||
static tree build_vbase_pointer_fields PARAMS ((tree, int *));
|
static tree build_vbase_pointer_fields PARAMS ((record_layout_info, int *));
|
||||||
static tree build_vtbl_or_vbase_field PARAMS ((tree, tree, tree, tree, tree,
|
static tree build_vtbl_or_vbase_field PARAMS ((tree, tree, tree, tree, tree,
|
||||||
int *));
|
int *));
|
||||||
static void check_methods PARAMS ((tree));
|
static void check_methods PARAMS ((tree));
|
||||||
static void remove_zero_width_bit_fields PARAMS ((tree));
|
static void remove_zero_width_bit_fields PARAMS ((tree));
|
||||||
static void check_bases PARAMS ((tree, int *, int *, int *));
|
static void check_bases PARAMS ((tree, int *, int *, int *));
|
||||||
static void check_bases_and_members PARAMS ((tree, int *));
|
static void check_bases_and_members PARAMS ((tree, int *));
|
||||||
static void create_vtable_ptr PARAMS ((tree, int *, int *, tree *, tree *));
|
static tree create_vtable_ptr PARAMS ((tree, int *, int *, tree *, tree *));
|
||||||
static void layout_class_type PARAMS ((tree, int *, int *, tree *, tree *));
|
static void layout_class_type PARAMS ((tree, int *, int *, tree *, tree *));
|
||||||
static void fixup_pending_inline PARAMS ((struct pending_inline *));
|
static void fixup_pending_inline PARAMS ((struct pending_inline *));
|
||||||
static void fixup_inline_methods PARAMS ((tree));
|
static void fixup_inline_methods PARAMS ((tree));
|
||||||
@ -135,8 +135,6 @@ static tree dfs_propagate_binfo_offsets PARAMS ((tree, void *));
|
|||||||
static void propagate_binfo_offsets PARAMS ((tree, tree));
|
static void propagate_binfo_offsets PARAMS ((tree, tree));
|
||||||
static void layout_basetypes PARAMS ((tree));
|
static void layout_basetypes PARAMS ((tree));
|
||||||
static void layout_virtual_bases PARAMS ((tree));
|
static void layout_virtual_bases PARAMS ((tree));
|
||||||
static void remove_base_field PARAMS ((tree, tree, tree *));
|
|
||||||
static void remove_base_fields PARAMS ((tree));
|
|
||||||
static tree dfs_set_offset_for_shared_vbases PARAMS ((tree, void *));
|
static tree dfs_set_offset_for_shared_vbases PARAMS ((tree, void *));
|
||||||
static tree dfs_set_offset_for_unshared_vbases PARAMS ((tree, void *));
|
static tree dfs_set_offset_for_unshared_vbases PARAMS ((tree, void *));
|
||||||
static tree dfs_build_vbase_offset_vtbl_entries PARAMS ((tree, void *));
|
static tree dfs_build_vbase_offset_vtbl_entries PARAMS ((tree, void *));
|
||||||
@ -155,6 +153,9 @@ static int make_new_vtable PARAMS ((tree, tree));
|
|||||||
extern void dump_class_hierarchy PARAMS ((tree, int));
|
extern void dump_class_hierarchy PARAMS ((tree, int));
|
||||||
static tree build_vtable PARAMS ((tree, tree, tree));
|
static tree build_vtable PARAMS ((tree, tree, tree));
|
||||||
static void initialize_vtable PARAMS ((tree, tree));
|
static void initialize_vtable PARAMS ((tree, tree));
|
||||||
|
static void layout_nonempty_base_or_field PARAMS ((record_layout_info,
|
||||||
|
tree, tree,
|
||||||
|
varray_type));
|
||||||
|
|
||||||
/* Variables shared between class.c and call.c. */
|
/* Variables shared between class.c and call.c. */
|
||||||
|
|
||||||
@ -175,12 +176,13 @@ int n_inner_fields_searched = 0;
|
|||||||
FIELD_DECLS. */
|
FIELD_DECLS. */
|
||||||
|
|
||||||
static tree
|
static tree
|
||||||
build_vbase_pointer_fields (rec, empty_p)
|
build_vbase_pointer_fields (rli, empty_p)
|
||||||
tree rec;
|
record_layout_info rli;
|
||||||
int *empty_p;
|
int *empty_p;
|
||||||
{
|
{
|
||||||
/* Chain to hold all the new FIELD_DECLs which point at virtual
|
/* Chain to hold all the new FIELD_DECLs which point at virtual
|
||||||
base classes. */
|
base classes. */
|
||||||
|
tree rec = rli->t;
|
||||||
tree vbase_decls = NULL_TREE;
|
tree vbase_decls = NULL_TREE;
|
||||||
tree binfos = TYPE_BINFO_BASETYPES (rec);
|
tree binfos = TYPE_BINFO_BASETYPES (rec);
|
||||||
int n_baseclasses = CLASSTYPE_N_BASECLASSES (rec);
|
int n_baseclasses = CLASSTYPE_N_BASECLASSES (rec);
|
||||||
@ -235,6 +237,7 @@ build_vbase_pointer_fields (rec, empty_p)
|
|||||||
empty_p);
|
empty_p);
|
||||||
BINFO_VPTR_FIELD (base_binfo) = decl;
|
BINFO_VPTR_FIELD (base_binfo) = decl;
|
||||||
TREE_CHAIN (decl) = vbase_decls;
|
TREE_CHAIN (decl) = vbase_decls;
|
||||||
|
layout_field (rli, decl);
|
||||||
vbase_decls = decl;
|
vbase_decls = decl;
|
||||||
*empty_p = 0;
|
*empty_p = 0;
|
||||||
|
|
||||||
@ -4091,46 +4094,155 @@ build_vtbl_or_vbase_field (name, assembler_name, type, class_type, fcontext,
|
|||||||
return field;
|
return field;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the empty base field in DECL overlaps with a base of the same type in
|
/* Return the BINFO_OFFSET for BINFO as a native integer, not an
|
||||||
NEWDECL, which is either another base field or the first data field of
|
INTEGER_CST. */
|
||||||
the class, pad the base just before NEWDECL and return 1. Otherwise,
|
|
||||||
return 0. */
|
|
||||||
|
|
||||||
static int
|
static unsigned HOST_WIDE_INT
|
||||||
avoid_overlap (decl, newdecl, empty_p)
|
get_binfo_offset_as_int (binfo)
|
||||||
tree decl, newdecl;
|
tree binfo;
|
||||||
int *empty_p;
|
|
||||||
{
|
{
|
||||||
tree field;
|
tree offset;
|
||||||
|
|
||||||
if (newdecl == NULL_TREE
|
offset = BINFO_OFFSET (binfo);
|
||||||
|| ! types_overlap_p (TREE_TYPE (decl), TREE_TYPE (newdecl)))
|
my_friendly_assert (TREE_CODE (offset) == INTEGER_CST, 20000313);
|
||||||
return 0;
|
my_friendly_assert (TREE_INT_CST_HIGH (offset) == 0, 20000313);
|
||||||
|
|
||||||
for (field = decl; TREE_CHAIN (field) && TREE_CHAIN (field) != newdecl;
|
return (unsigned HOST_WIDE_INT) TREE_INT_CST_LOW (offset);
|
||||||
field = TREE_CHAIN (field))
|
|
||||||
;
|
|
||||||
|
|
||||||
DECL_SIZE (field) = bitsize_int (1);
|
|
||||||
DECL_SIZE_UNIT (field) = 0;
|
|
||||||
/* The containing class cannot be empty; this field takes up space. */
|
|
||||||
*empty_p = 0;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Build a FIELD_DECL for the base given by BINFO in T. If the new
|
/* Record the type of BINFO in the slot in DATA (which is really a
|
||||||
object is non-empty, clear *EMPTY_P. Otherwise, set *SAW_EMPTY_P.
|
`varray_type *') corresponding to the BINFO_OFFSET. */
|
||||||
*BASE_ALIGN is a running maximum of the alignments of any base
|
|
||||||
class. */
|
|
||||||
|
|
||||||
static tree
|
static tree
|
||||||
build_base_field (t, binfo, empty_p, saw_empty_p, base_align)
|
dfs_record_base_offsets (binfo, data)
|
||||||
tree t;
|
tree binfo;
|
||||||
|
void *data;
|
||||||
|
{
|
||||||
|
varray_type *v;
|
||||||
|
unsigned HOST_WIDE_INT offset = get_binfo_offset_as_int (binfo);
|
||||||
|
|
||||||
|
v = (varray_type *) data;
|
||||||
|
while (VARRAY_SIZE (*v) <= offset)
|
||||||
|
VARRAY_GROW (*v, 2 * VARRAY_SIZE (*v));
|
||||||
|
VARRAY_TREE (*v, offset) = tree_cons (NULL_TREE,
|
||||||
|
BINFO_TYPE (binfo),
|
||||||
|
VARRAY_TREE (*v, offset));
|
||||||
|
|
||||||
|
return NULL_TREE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns non-NULL if there is already an entry in DATA (which is
|
||||||
|
really a `varray_type') indicating that an object with the same
|
||||||
|
type of BINFO is already at the BINFO_OFFSET for BINFO. */
|
||||||
|
|
||||||
|
static tree
|
||||||
|
dfs_search_base_offsets (binfo, data)
|
||||||
|
tree binfo;
|
||||||
|
void *data;
|
||||||
|
{
|
||||||
|
if (is_empty_class (BINFO_TYPE (binfo)))
|
||||||
|
{
|
||||||
|
varray_type v = (varray_type) data;
|
||||||
|
unsigned HOST_WIDE_INT offset;
|
||||||
|
tree t;
|
||||||
|
|
||||||
|
/* Find the offset for this BINFO. */
|
||||||
|
offset = get_binfo_offset_as_int (binfo);
|
||||||
|
/* If we haven't yet encountered any objects at offsets that
|
||||||
|
big, then there's no conflict. */
|
||||||
|
if (VARRAY_SIZE (v) <= offset)
|
||||||
|
return NULL_TREE;
|
||||||
|
/* Otherwise, go through the objects already allocated at this
|
||||||
|
offset. */
|
||||||
|
for (t = VARRAY_TREE (v, offset); t; t = TREE_CHAIN (t))
|
||||||
|
if (same_type_p (TREE_VALUE (t), BINFO_TYPE (binfo)))
|
||||||
|
return binfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL_TREE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* DECL is a FIELD_DECL corresponding either to a base subobject of a
|
||||||
|
non-static data member of the type indicated by RLI. BINFO is the
|
||||||
|
binfo corresponding to the base subobject, or, if this is a
|
||||||
|
non-static data-member, a dummy BINFO for the type of the data
|
||||||
|
member. V maps offsets to types already located at those offsets.
|
||||||
|
This function determines the position of the DECL. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
layout_nonempty_base_or_field (rli, decl, binfo, v)
|
||||||
|
record_layout_info rli;
|
||||||
|
tree decl;
|
||||||
|
tree binfo;
|
||||||
|
varray_type v;
|
||||||
|
{
|
||||||
|
/* Try to place the field. It may take more than one try if we have
|
||||||
|
a hard time placing the field without putting two objects of the
|
||||||
|
same type at the same address. */
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
tree offset;
|
||||||
|
|
||||||
|
/* Layout this field. */
|
||||||
|
layout_field (rli, decl);
|
||||||
|
|
||||||
|
/* Now that we know where it wil be placed, update its
|
||||||
|
BINFO_OFFSET. */
|
||||||
|
offset = size_int (CEIL (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (decl)),
|
||||||
|
BITS_PER_UNIT));
|
||||||
|
propagate_binfo_offsets (binfo, offset);
|
||||||
|
|
||||||
|
/* We have to check to see whether or not there is already
|
||||||
|
something of the same type at the offset we're about to use.
|
||||||
|
For example:
|
||||||
|
|
||||||
|
struct S {};
|
||||||
|
struct T : public S { int i; };
|
||||||
|
struct U : public S, public T {};
|
||||||
|
|
||||||
|
Here, we put S at offset zero in U. Then, we can't put T at
|
||||||
|
offset zero -- its S component would be at the same address
|
||||||
|
as the S we already allocated. So, we have to skip ahead.
|
||||||
|
Since all data members, including those whose type is an
|
||||||
|
empty class, have non-zero size, any overlap can happen only
|
||||||
|
with a direct or indirect base-class -- it can't happen with
|
||||||
|
a data member. */
|
||||||
|
if (flag_new_abi && dfs_walk (binfo,
|
||||||
|
dfs_search_base_offsets,
|
||||||
|
dfs_skip_vbases,
|
||||||
|
v))
|
||||||
|
{
|
||||||
|
/* Undo the propogate_binfo_offsets call. */
|
||||||
|
offset = convert (sizetype,
|
||||||
|
size_diffop (size_zero_node, offset));
|
||||||
|
propagate_binfo_offsets (binfo, offset);
|
||||||
|
|
||||||
|
/* Strip off the size allocated to this field. That puts us
|
||||||
|
at the first place we could have put the field with
|
||||||
|
proper alignment. */
|
||||||
|
rli->const_size -= TREE_INT_CST_LOW (DECL_SIZE (decl));
|
||||||
|
/* Bump up by th alignment required for the type, without
|
||||||
|
virtual base classes. */
|
||||||
|
rli->const_size += CLASSTYPE_ALIGN (BINFO_TYPE (binfo));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
/* There was no conflict. We're done laying out this field. */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Build a FIELD_DECL for the base given by BINFO in the class
|
||||||
|
*indicated by RLI. If the new object is non-empty, clear *EMPTY_P.
|
||||||
|
*BASE_ALIGN is a running maximum of the alignments of any base
|
||||||
|
*class. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
build_base_field (rli, binfo, empty_p, base_align, v)
|
||||||
|
record_layout_info rli;
|
||||||
tree binfo;
|
tree binfo;
|
||||||
int *empty_p;
|
int *empty_p;
|
||||||
int *saw_empty_p;
|
|
||||||
unsigned int *base_align;
|
unsigned int *base_align;
|
||||||
|
varray_type *v;
|
||||||
{
|
{
|
||||||
tree basetype = BINFO_TYPE (binfo);
|
tree basetype = BINFO_TYPE (binfo);
|
||||||
tree decl;
|
tree decl;
|
||||||
@ -4138,25 +4250,15 @@ build_base_field (t, binfo, empty_p, saw_empty_p, base_align)
|
|||||||
if (TYPE_SIZE (basetype) == 0)
|
if (TYPE_SIZE (basetype) == 0)
|
||||||
/* This error is now reported in xref_tag, thus giving better
|
/* This error is now reported in xref_tag, thus giving better
|
||||||
location information. */
|
location information. */
|
||||||
return NULL_TREE;
|
return;
|
||||||
|
|
||||||
decl = build_lang_decl (FIELD_DECL, NULL_TREE, basetype);
|
decl = build_lang_decl (FIELD_DECL, NULL_TREE, basetype);
|
||||||
DECL_ARTIFICIAL (decl) = 1;
|
DECL_ARTIFICIAL (decl) = 1;
|
||||||
DECL_FIELD_CONTEXT (decl) = t;
|
DECL_FIELD_CONTEXT (decl) = rli->t;
|
||||||
DECL_SIZE (decl) = CLASSTYPE_SIZE (basetype);
|
DECL_SIZE (decl) = CLASSTYPE_SIZE (basetype);
|
||||||
DECL_SIZE_UNIT (decl) = CLASSTYPE_SIZE_UNIT (basetype);
|
DECL_SIZE_UNIT (decl) = CLASSTYPE_SIZE_UNIT (basetype);
|
||||||
DECL_ALIGN (decl) = CLASSTYPE_ALIGN (basetype);
|
DECL_ALIGN (decl) = CLASSTYPE_ALIGN (basetype);
|
||||||
|
|
||||||
if (flag_new_abi && integer_zerop (DECL_SIZE (decl)))
|
|
||||||
{
|
|
||||||
*saw_empty_p = 1;
|
|
||||||
return decl;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The containing class is non-empty because it has a non-empty base
|
|
||||||
class. */
|
|
||||||
*empty_p = 0;
|
|
||||||
|
|
||||||
if (! flag_new_abi)
|
if (! flag_new_abi)
|
||||||
{
|
{
|
||||||
/* Brain damage for backwards compatibility. For no good
|
/* Brain damage for backwards compatibility. For no good
|
||||||
@ -4174,39 +4276,84 @@ build_base_field (t, binfo, empty_p, saw_empty_p, base_align)
|
|||||||
(int) *base_align / BITS_PER_UNIT));
|
(int) *base_align / BITS_PER_UNIT));
|
||||||
}
|
}
|
||||||
|
|
||||||
return decl;
|
if (!integer_zerop (DECL_SIZE (decl)))
|
||||||
|
{
|
||||||
|
/* The containing class is non-empty because it has a non-empty
|
||||||
|
base class. */
|
||||||
|
*empty_p = 0;
|
||||||
|
|
||||||
|
/* Try to place the field. It may take more than one try if we
|
||||||
|
have a hard time placing the field without putting two
|
||||||
|
objects of the same type at the same address. */
|
||||||
|
layout_nonempty_base_or_field (rli, decl, binfo, *v);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* This code assumes that zero-sized classes have one-byte
|
||||||
|
alignment. There might someday be a system where that's not
|
||||||
|
true. */
|
||||||
|
my_friendly_assert (DECL_ALIGN (basetype) == BITS_PER_UNIT,
|
||||||
|
20000314);
|
||||||
|
|
||||||
|
/* This is an empty base class. We first try to put it at
|
||||||
|
offset zero. */
|
||||||
|
if (dfs_walk (binfo, dfs_search_base_offsets, dfs_skip_vbases, *v))
|
||||||
|
{
|
||||||
|
/* That didn't work. Now, we move forward from the next
|
||||||
|
available spot in the class. */
|
||||||
|
propagate_binfo_offsets (binfo, size_int (rli->const_size));
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
if (!dfs_walk (binfo, dfs_search_base_offsets,
|
||||||
|
dfs_skip_vbases, *v))
|
||||||
|
/* We finally found a spot where there's no overlap. */
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* There's overlap here, too. Bump along to the next
|
||||||
|
spot. */
|
||||||
|
propagate_binfo_offsets (binfo, size_one_node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check for inaccessible base classes. If the same base class
|
||||||
|
appears more than once in the hierarchy, but isn't virtual, then
|
||||||
|
it's ambiguous. */
|
||||||
|
if (get_base_distance (basetype, rli->t, 0, NULL) == -2)
|
||||||
|
cp_warning ("direct base `%T' inaccessible in `%T' due to ambiguity",
|
||||||
|
basetype, rli->t);
|
||||||
|
|
||||||
|
/* Record the offsets of BINFO and its base subobjects. */
|
||||||
|
dfs_walk (binfo,
|
||||||
|
dfs_record_base_offsets,
|
||||||
|
dfs_skip_vbases,
|
||||||
|
v);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Returns a list of fields to stand in for the base class subobjects
|
/* Layout all of the non-virtual base classes. Returns a map from
|
||||||
of REC. These fields are later removed by layout_basetypes. */
|
offsets to types present at those offsets. */
|
||||||
|
|
||||||
static tree
|
static varray_type
|
||||||
build_base_fields (rec, empty_p)
|
build_base_fields (rli, empty_p)
|
||||||
tree rec;
|
record_layout_info rli;
|
||||||
int *empty_p;
|
int *empty_p;
|
||||||
{
|
{
|
||||||
/* Chain to hold all the new FIELD_DECLs which stand in for base class
|
/* Chain to hold all the new FIELD_DECLs which stand in for base class
|
||||||
subobjects. */
|
subobjects. */
|
||||||
tree base_decls = NULL_TREE;
|
tree rec = rli->t;
|
||||||
int n_baseclasses = CLASSTYPE_N_BASECLASSES (rec);
|
int n_baseclasses = CLASSTYPE_N_BASECLASSES (rec);
|
||||||
tree decl, nextdecl;
|
int i;
|
||||||
int i, saw_empty = 0;
|
varray_type v;
|
||||||
unsigned int base_align = 0;
|
unsigned int base_align = 0;
|
||||||
|
|
||||||
|
/* Create the table mapping offsets to empty base classes. */
|
||||||
|
VARRAY_TREE_INIT (v, 32, "v");
|
||||||
|
|
||||||
/* Under the new ABI, the primary base class is always allocated
|
/* Under the new ABI, the primary base class is always allocated
|
||||||
first. */
|
first. */
|
||||||
if (flag_new_abi && CLASSTYPE_HAS_PRIMARY_BASE_P (rec))
|
if (flag_new_abi && CLASSTYPE_HAS_PRIMARY_BASE_P (rec))
|
||||||
{
|
build_base_field (rli, CLASSTYPE_PRIMARY_BINFO (rec),
|
||||||
tree primary_base;
|
empty_p, &base_align, &v);
|
||||||
|
|
||||||
primary_base = CLASSTYPE_PRIMARY_BINFO (rec);
|
|
||||||
base_decls = chainon (build_base_field (rec,
|
|
||||||
primary_base,
|
|
||||||
empty_p,
|
|
||||||
&saw_empty,
|
|
||||||
&base_align),
|
|
||||||
base_decls);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now allocate the rest of the bases. */
|
/* Now allocate the rest of the bases. */
|
||||||
for (i = 0; i < n_baseclasses; ++i)
|
for (i = 0; i < n_baseclasses; ++i)
|
||||||
@ -4227,44 +4374,10 @@ build_base_fields (rec, empty_p)
|
|||||||
&& !BINFO_PRIMARY_MARKED_P (base_binfo))
|
&& !BINFO_PRIMARY_MARKED_P (base_binfo))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
base_decls = chainon (build_base_field (rec, base_binfo,
|
build_base_field (rli, base_binfo, empty_p, &base_align, &v);
|
||||||
empty_p,
|
|
||||||
&saw_empty,
|
|
||||||
&base_align),
|
|
||||||
base_decls);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reverse the list of fields so we allocate the bases in the proper
|
return v;
|
||||||
order. */
|
|
||||||
base_decls = nreverse (base_decls);
|
|
||||||
|
|
||||||
/* In the presence of empty base classes, we run the risk of allocating
|
|
||||||
two objects of the same class on top of one another. Avoid that. */
|
|
||||||
if (flag_new_abi && saw_empty)
|
|
||||||
for (decl = base_decls; decl; decl = TREE_CHAIN (decl))
|
|
||||||
{
|
|
||||||
if (integer_zerop (DECL_SIZE (decl)))
|
|
||||||
{
|
|
||||||
/* First step through the following bases until we find
|
|
||||||
an overlap or a non-empty base. */
|
|
||||||
for (nextdecl = TREE_CHAIN (decl); nextdecl;
|
|
||||||
nextdecl = TREE_CHAIN (nextdecl))
|
|
||||||
if (avoid_overlap (decl, nextdecl, empty_p)
|
|
||||||
|| ! integer_zerop (DECL_SIZE (nextdecl)))
|
|
||||||
goto nextbase;
|
|
||||||
|
|
||||||
/* If we're still looking, also check against the first
|
|
||||||
field. */
|
|
||||||
for (nextdecl = TYPE_FIELDS (rec);
|
|
||||||
nextdecl && TREE_CODE (nextdecl) != FIELD_DECL;
|
|
||||||
nextdecl = TREE_CHAIN (nextdecl))
|
|
||||||
/* keep looking */;
|
|
||||||
avoid_overlap (decl, nextdecl, empty_p);
|
|
||||||
}
|
|
||||||
nextbase:;
|
|
||||||
}
|
|
||||||
|
|
||||||
return base_decls;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Go through the TYPE_METHODS of T issuing any appropriate
|
/* Go through the TYPE_METHODS of T issuing any appropriate
|
||||||
@ -4438,10 +4551,12 @@ check_bases_and_members (t, empty_p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* If T needs a pointer to its virtual function table, set TYPE_VFIELD
|
/* If T needs a pointer to its virtual function table, set TYPE_VFIELD
|
||||||
accordingly, and, if necessary, add the TYPE_VFIELD to the
|
accordingly. If a new vfield was created (because T doesn't have a
|
||||||
TYPE_FIELDS list. */
|
primary base class), then the newly created field is returned. It
|
||||||
|
is not added to the TYPE_FIELDS list; it is the callers
|
||||||
|
responsibility to do that. */
|
||||||
|
|
||||||
static void
|
static tree
|
||||||
create_vtable_ptr (t, empty_p, has_virtual_p,
|
create_vtable_ptr (t, empty_p, has_virtual_p,
|
||||||
new_virtuals_p, overridden_virtuals_p)
|
new_virtuals_p, overridden_virtuals_p)
|
||||||
tree t;
|
tree t;
|
||||||
@ -4496,29 +4611,17 @@ create_vtable_ptr (t, empty_p, has_virtual_p,
|
|||||||
t,
|
t,
|
||||||
empty_p);
|
empty_p);
|
||||||
|
|
||||||
/* Add the new field to the list of fields in this class. */
|
if (flag_new_abi && CLASSTYPE_N_BASECLASSES (t))
|
||||||
if (!flag_new_abi)
|
/* If there were any baseclasses, they can't possibly be at
|
||||||
/* In the old ABI, the vtable pointer goes at the end of the
|
offset zero any more, because that's where the vtable
|
||||||
class. */
|
pointer is. So, converting to a base class is going to
|
||||||
TYPE_FIELDS (t) = chainon (TYPE_FIELDS (t), TYPE_VFIELD (t));
|
take work. */
|
||||||
else
|
TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (t) = 1;
|
||||||
{
|
|
||||||
/* But in the new ABI, the vtable pointer is the first thing
|
|
||||||
in the class. */
|
|
||||||
TYPE_FIELDS (t) = chainon (TYPE_VFIELD (t), TYPE_FIELDS (t));
|
|
||||||
/* If there were any baseclasses, they can't possibly be at
|
|
||||||
offset zero any more, because that's where the vtable
|
|
||||||
pointer is. So, converting to a base class is going to
|
|
||||||
take work. */
|
|
||||||
if (CLASSTYPE_N_BASECLASSES (t))
|
|
||||||
TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (t) = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We can't yet add this new field to the list of all virtual
|
return TYPE_VFIELD (t);
|
||||||
function table pointers in this class. The
|
|
||||||
modify_all_vtables function depends on this not being done.
|
|
||||||
So, it is done later, in finish_struct_1. */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return NULL_TREE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fixup the inline function given by INFO now that the class is
|
/* Fixup the inline function given by INFO now that the class is
|
||||||
@ -4613,85 +4716,6 @@ propagate_binfo_offsets (binfo, offset)
|
|||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remove *FIELD (which corresponds to the base given by BINFO) from
|
|
||||||
the field list for T. */
|
|
||||||
|
|
||||||
static void
|
|
||||||
remove_base_field (t, binfo, field)
|
|
||||||
tree t;
|
|
||||||
tree binfo;
|
|
||||||
tree *field;
|
|
||||||
{
|
|
||||||
tree basetype = BINFO_TYPE (binfo);
|
|
||||||
tree offset;
|
|
||||||
|
|
||||||
my_friendly_assert (TREE_TYPE (*field) == basetype, 23897);
|
|
||||||
|
|
||||||
if (get_base_distance (basetype, t, 0, (tree*)0) == -2)
|
|
||||||
cp_warning ("direct base `%T' inaccessible in `%T' due to ambiguity",
|
|
||||||
basetype, t);
|
|
||||||
|
|
||||||
offset
|
|
||||||
= size_int (CEIL (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (*field)),
|
|
||||||
BITS_PER_UNIT));
|
|
||||||
propagate_binfo_offsets (binfo, offset);
|
|
||||||
|
|
||||||
/* Remove this field. */
|
|
||||||
*field = TREE_CHAIN (*field);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Remove the FIELD_DECLs created for T's base classes in
|
|
||||||
build_base_fields. Simultaneously, update BINFO_OFFSET for all the
|
|
||||||
bases, except for non-primary virtual baseclasses. */
|
|
||||||
|
|
||||||
static void
|
|
||||||
remove_base_fields (t)
|
|
||||||
tree t;
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
tree *field;
|
|
||||||
|
|
||||||
/* Now propagate offset information throughout the lattice.
|
|
||||||
Simultaneously, remove the temporary FIELD_DECLS we created in
|
|
||||||
build_base_fields to refer to base types. */
|
|
||||||
field = &TYPE_FIELDS (t);
|
|
||||||
if (TYPE_VFIELD (t) == *field)
|
|
||||||
{
|
|
||||||
/* If this class did not have a primary base, we create a
|
|
||||||
virtual function table pointer. It will be the first thing
|
|
||||||
in the class, under the new ABI. Skip it; the base fields
|
|
||||||
will follow it. */
|
|
||||||
my_friendly_assert (flag_new_abi
|
|
||||||
&& !CLASSTYPE_HAS_PRIMARY_BASE_P (t),
|
|
||||||
19991218);
|
|
||||||
field = &TREE_CHAIN (*field);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Under the new ABI, the primary base is always allocated first. */
|
|
||||||
if (flag_new_abi && CLASSTYPE_HAS_PRIMARY_BASE_P (t))
|
|
||||||
remove_base_field (t, CLASSTYPE_PRIMARY_BINFO (t), field);
|
|
||||||
|
|
||||||
/* Now remove the rest of the bases. */
|
|
||||||
for (i = 0; i < CLASSTYPE_N_BASECLASSES (t); i++)
|
|
||||||
{
|
|
||||||
tree binfo;
|
|
||||||
|
|
||||||
/* Under the new ABI, we've already removed the primary base
|
|
||||||
above. */
|
|
||||||
if (flag_new_abi && i == CLASSTYPE_VFIELD_PARENT (t))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
binfo = BINFO_BASETYPE (TYPE_BINFO (t), i);
|
|
||||||
|
|
||||||
/* We treat a primary virtual base class just like an ordinary base
|
|
||||||
class. But, non-primary virtual bases are laid out later. */
|
|
||||||
if (TREE_VIA_VIRTUAL (binfo) && !BINFO_PRIMARY_MARKED_P (binfo))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
remove_base_field (t, binfo, field);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Called via dfs_walk from layout_virtual bases. */
|
/* Called via dfs_walk from layout_virtual bases. */
|
||||||
|
|
||||||
static tree
|
static tree
|
||||||
@ -4819,17 +4843,15 @@ layout_basetypes (rec)
|
|||||||
{
|
{
|
||||||
tree vbase_types;
|
tree vbase_types;
|
||||||
|
|
||||||
|
if (CLASSTYPE_N_BASECLASSES (rec) == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
#ifdef STRUCTURE_SIZE_BOUNDARY
|
#ifdef STRUCTURE_SIZE_BOUNDARY
|
||||||
/* Packed structures don't need to have minimum size. */
|
/* Packed structures don't need to have minimum size. */
|
||||||
if (! TYPE_PACKED (rec))
|
if (! TYPE_PACKED (rec))
|
||||||
TYPE_ALIGN (rec) = MAX (TYPE_ALIGN (rec), STRUCTURE_SIZE_BOUNDARY);
|
TYPE_ALIGN (rec) = MAX (TYPE_ALIGN (rec), STRUCTURE_SIZE_BOUNDARY);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Remove the FIELD_DECLs we created for baseclasses in
|
|
||||||
build_base_fields. Simultaneously, update the BINFO_OFFSETs for
|
|
||||||
everything in the hierarcy except non-primary virtual bases. */
|
|
||||||
remove_base_fields (rec);
|
|
||||||
|
|
||||||
/* Allocate the virtual base classes. */
|
/* Allocate the virtual base classes. */
|
||||||
layout_virtual_bases (rec);
|
layout_virtual_bases (rec);
|
||||||
|
|
||||||
@ -4861,64 +4883,117 @@ layout_class_type (t, empty_p, has_virtual_p,
|
|||||||
tree *new_virtuals_p;
|
tree *new_virtuals_p;
|
||||||
tree *overridden_virtuals_p;
|
tree *overridden_virtuals_p;
|
||||||
{
|
{
|
||||||
tree padding = NULL_TREE;
|
tree non_static_data_members;
|
||||||
|
tree field;
|
||||||
|
tree vptr;
|
||||||
|
record_layout_info rli;
|
||||||
|
varray_type v;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Keep track of the first non-static data member. */
|
||||||
|
non_static_data_members = TYPE_FIELDS (t);
|
||||||
|
|
||||||
|
/* Initialize the layout information. */
|
||||||
|
rli = new_record_layout_info (t);
|
||||||
|
|
||||||
/* If possible, we reuse the virtual function table pointer from one
|
/* If possible, we reuse the virtual function table pointer from one
|
||||||
of our base classes. */
|
of our base classes. */
|
||||||
determine_primary_base (t, has_virtual_p);
|
determine_primary_base (t, has_virtual_p);
|
||||||
|
|
||||||
|
/* Create a pointer to our virtual function table. */
|
||||||
|
vptr = create_vtable_ptr (t, empty_p, has_virtual_p,
|
||||||
|
new_virtuals_p, overridden_virtuals_p);
|
||||||
|
|
||||||
|
/* Under the new ABI, the vptr is always the first thing in the
|
||||||
|
class. */
|
||||||
|
if (flag_new_abi && vptr)
|
||||||
|
{
|
||||||
|
TYPE_FIELDS (t) = chainon (vptr, TYPE_FIELDS (t));
|
||||||
|
layout_field (rli, vptr);
|
||||||
|
}
|
||||||
|
|
||||||
/* Add pointers to all of our virtual base-classes. */
|
/* Add pointers to all of our virtual base-classes. */
|
||||||
TYPE_FIELDS (t) = chainon (build_vbase_pointer_fields (t, empty_p),
|
TYPE_FIELDS (t) = chainon (build_vbase_pointer_fields (rli, empty_p),
|
||||||
TYPE_FIELDS (t));
|
TYPE_FIELDS (t));
|
||||||
/* Build FIELD_DECLs for all of the non-virtual base-types. */
|
/* Build FIELD_DECLs for all of the non-virtual base-types. */
|
||||||
TYPE_FIELDS (t) = chainon (build_base_fields (t, empty_p),
|
v = build_base_fields (rli, empty_p);
|
||||||
TYPE_FIELDS (t));
|
|
||||||
|
|
||||||
/* Create a pointer to our virtual function table. */
|
|
||||||
create_vtable_ptr (t, empty_p, has_virtual_p,
|
|
||||||
new_virtuals_p, overridden_virtuals_p);
|
|
||||||
|
|
||||||
/* CLASSTYPE_INLINE_FRIENDS is really TYPE_NONCOPIED_PARTS. Thus,
|
/* CLASSTYPE_INLINE_FRIENDS is really TYPE_NONCOPIED_PARTS. Thus,
|
||||||
we have to save this before we start modifying
|
we have to save this before we start modifying
|
||||||
TYPE_NONCOPIED_PARTS. */
|
TYPE_NONCOPIED_PARTS. */
|
||||||
fixup_inline_methods (t);
|
fixup_inline_methods (t);
|
||||||
|
|
||||||
|
/* Layout the non-static data members. */
|
||||||
|
for (field = non_static_data_members;
|
||||||
|
field;
|
||||||
|
field = TREE_CHAIN (field))
|
||||||
|
{
|
||||||
|
tree binfo;
|
||||||
|
|
||||||
|
/* We still pass things that aren't non-static data members to
|
||||||
|
the back-end, in case it wants to do something with them. */
|
||||||
|
if (TREE_CODE (field) != FIELD_DECL)
|
||||||
|
{
|
||||||
|
layout_field (rli, field);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create a dummy BINFO corresponding to this field. */
|
||||||
|
binfo = make_binfo (size_zero_node, TREE_TYPE (field),
|
||||||
|
NULL_TREE, NULL_TREE);
|
||||||
|
unshare_base_binfos (binfo);
|
||||||
|
layout_nonempty_base_or_field (rli, field, binfo, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clean up. */
|
||||||
|
VARRAY_FREE (v);
|
||||||
|
|
||||||
|
/* It might be the case that we grew the class to allocate a
|
||||||
|
zero-sized base class. That won't be reflected in RLI, yet,
|
||||||
|
because we are willing to overlay multiple bases at the same
|
||||||
|
offset. However, now we need to make sure that RLI is big enough
|
||||||
|
to reflect the entire class. */
|
||||||
|
for (i = 0; i < CLASSTYPE_N_BASECLASSES (t); ++i)
|
||||||
|
{
|
||||||
|
tree base_binfo;
|
||||||
|
unsigned HOST_WIDE_INT offset;
|
||||||
|
|
||||||
|
base_binfo = BINFO_BASETYPE (TYPE_BINFO (t), i);
|
||||||
|
offset = get_binfo_offset_as_int (base_binfo);
|
||||||
|
if (offset * BITS_PER_UNIT > rli->const_size)
|
||||||
|
rli->const_size = (offset + 1) * BITS_PER_UNIT;
|
||||||
|
}
|
||||||
|
|
||||||
/* We make all structures have at least one element, so that they
|
/* We make all structures have at least one element, so that they
|
||||||
have non-zero size. The field that we add here is fake, in the
|
have non-zero size. In the new ABI, the class may be empty even
|
||||||
sense that, for example, we don't want people to be able to
|
if it has basetypes. Therefore, we add the fake field after all
|
||||||
initialize it later. So, we add it just long enough to let the
|
the other fields; if there are already FIELD_DECLs on the list,
|
||||||
back-end lay out the type, and then remove it. In the new ABI,
|
their offsets will not be disturbed. */
|
||||||
the class may be empty even if it has basetypes. Therefore, we
|
|
||||||
add the fake field at the end of the fields list; if there are
|
|
||||||
already FIELD_DECLs on the list, their offsets will not be
|
|
||||||
disturbed. */
|
|
||||||
if (*empty_p)
|
if (*empty_p)
|
||||||
{
|
{
|
||||||
|
tree padding;
|
||||||
|
|
||||||
padding = build_lang_decl (FIELD_DECL, NULL_TREE, char_type_node);
|
padding = build_lang_decl (FIELD_DECL, NULL_TREE, char_type_node);
|
||||||
TYPE_FIELDS (t) = chainon (TYPE_FIELDS (t), padding);
|
layout_field (rli, padding);
|
||||||
TYPE_NONCOPIED_PARTS (t)
|
TYPE_NONCOPIED_PARTS (t)
|
||||||
= tree_cons (NULL_TREE, padding, TYPE_NONCOPIED_PARTS (t));
|
= tree_cons (NULL_TREE, padding, TYPE_NONCOPIED_PARTS (t));
|
||||||
TREE_STATIC (TYPE_NONCOPIED_PARTS (t)) = 1;
|
TREE_STATIC (TYPE_NONCOPIED_PARTS (t)) = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Under the old ABI, the vptr comes at the very end of the
|
||||||
|
class. */
|
||||||
|
if (!flag_new_abi && vptr)
|
||||||
|
{
|
||||||
|
layout_field (rli, vptr);
|
||||||
|
TYPE_FIELDS (t) = chainon (TYPE_FIELDS (t), vptr);
|
||||||
|
}
|
||||||
|
|
||||||
/* Let the back-end lay out the type. Note that at this point we
|
/* Let the back-end lay out the type. Note that at this point we
|
||||||
have only included non-virtual base-classes; we will lay out the
|
have only included non-virtual base-classes; we will lay out the
|
||||||
virtual base classes later. So, the TYPE_SIZE/TYPE_ALIGN after
|
virtual base classes later. So, the TYPE_SIZE/TYPE_ALIGN after
|
||||||
this call are not necessarily correct; they are just the size and
|
this call are not necessarily correct; they are just the size and
|
||||||
alignment when no virtual base clases are used. */
|
alignment when no virtual base clases are used. */
|
||||||
layout_type (t);
|
finish_record_layout (rli);
|
||||||
|
|
||||||
/* If we added an extra field to make this class non-empty, remove
|
|
||||||
it now. */
|
|
||||||
if (*empty_p)
|
|
||||||
{
|
|
||||||
tree *declp;
|
|
||||||
|
|
||||||
declp = &TYPE_FIELDS (t);
|
|
||||||
while (*declp != padding)
|
|
||||||
declp = &TREE_CHAIN (*declp);
|
|
||||||
*declp = TREE_CHAIN (*declp);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Delete all zero-width bit-fields from the list of fields. Now
|
/* Delete all zero-width bit-fields from the list of fields. Now
|
||||||
that the type is laid out they are no longer important. */
|
that the type is laid out they are no longer important. */
|
||||||
@ -4952,10 +5027,9 @@ layout_class_type (t, empty_p, has_virtual_p,
|
|||||||
|
|
||||||
/* Now fix up any virtual base class types that we left lying
|
/* Now fix up any virtual base class types that we left lying
|
||||||
around. We must get these done before we try to lay out the
|
around. We must get these done before we try to lay out the
|
||||||
virtual function table. */
|
virtual function table. As a side-effect, this will remove the
|
||||||
if (CLASSTYPE_N_BASECLASSES (t))
|
base subobject fields. */
|
||||||
/* layout_basetypes will remove the base subobject fields. */
|
layout_basetypes (t);
|
||||||
layout_basetypes (t);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create a RECORD_TYPE or UNION_TYPE node for a C struct or union declaration
|
/* Create a RECORD_TYPE or UNION_TYPE node for a C struct or union declaration
|
||||||
|
Loading…
Reference in New Issue
Block a user