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>
|
||||
|
||||
* 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_decls PARAMS ((tree, tree *, int *, int *, int *,
|
||||
int *));
|
||||
static int avoid_overlap PARAMS ((tree, tree, int *));
|
||||
static tree build_base_field PARAMS ((tree, tree, int *, int *, unsigned int *));
|
||||
static tree build_base_fields PARAMS ((tree, int *));
|
||||
static tree build_vbase_pointer_fields PARAMS ((tree, int *));
|
||||
static void build_base_field PARAMS ((record_layout_info, tree, int *,
|
||||
unsigned int *, varray_type *));
|
||||
static varray_type build_base_fields PARAMS ((record_layout_info, 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,
|
||||
int *));
|
||||
static void check_methods PARAMS ((tree));
|
||||
static void remove_zero_width_bit_fields PARAMS ((tree));
|
||||
static void check_bases PARAMS ((tree, int *, int *, 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 fixup_pending_inline PARAMS ((struct pending_inline *));
|
||||
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 layout_basetypes 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_unshared_vbases 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));
|
||||
static tree build_vtable PARAMS ((tree, 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. */
|
||||
|
||||
@ -175,12 +176,13 @@ int n_inner_fields_searched = 0;
|
||||
FIELD_DECLS. */
|
||||
|
||||
static tree
|
||||
build_vbase_pointer_fields (rec, empty_p)
|
||||
tree rec;
|
||||
build_vbase_pointer_fields (rli, empty_p)
|
||||
record_layout_info rli;
|
||||
int *empty_p;
|
||||
{
|
||||
/* Chain to hold all the new FIELD_DECLs which point at virtual
|
||||
base classes. */
|
||||
tree rec = rli->t;
|
||||
tree vbase_decls = NULL_TREE;
|
||||
tree binfos = TYPE_BINFO_BASETYPES (rec);
|
||||
int n_baseclasses = CLASSTYPE_N_BASECLASSES (rec);
|
||||
@ -235,6 +237,7 @@ build_vbase_pointer_fields (rec, empty_p)
|
||||
empty_p);
|
||||
BINFO_VPTR_FIELD (base_binfo) = decl;
|
||||
TREE_CHAIN (decl) = vbase_decls;
|
||||
layout_field (rli, decl);
|
||||
vbase_decls = decl;
|
||||
*empty_p = 0;
|
||||
|
||||
@ -4091,46 +4094,155 @@ build_vtbl_or_vbase_field (name, assembler_name, type, class_type, fcontext,
|
||||
return field;
|
||||
}
|
||||
|
||||
/* If the empty base field in DECL overlaps with a base of the same type in
|
||||
NEWDECL, which is either another base field or the first data field of
|
||||
the class, pad the base just before NEWDECL and return 1. Otherwise,
|
||||
return 0. */
|
||||
/* Return the BINFO_OFFSET for BINFO as a native integer, not an
|
||||
INTEGER_CST. */
|
||||
|
||||
static int
|
||||
avoid_overlap (decl, newdecl, empty_p)
|
||||
tree decl, newdecl;
|
||||
int *empty_p;
|
||||
static unsigned HOST_WIDE_INT
|
||||
get_binfo_offset_as_int (binfo)
|
||||
tree binfo;
|
||||
{
|
||||
tree field;
|
||||
tree offset;
|
||||
|
||||
if (newdecl == NULL_TREE
|
||||
|| ! types_overlap_p (TREE_TYPE (decl), TREE_TYPE (newdecl)))
|
||||
return 0;
|
||||
offset = BINFO_OFFSET (binfo);
|
||||
my_friendly_assert (TREE_CODE (offset) == INTEGER_CST, 20000313);
|
||||
my_friendly_assert (TREE_INT_CST_HIGH (offset) == 0, 20000313);
|
||||
|
||||
for (field = decl; TREE_CHAIN (field) && TREE_CHAIN (field) != newdecl;
|
||||
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;
|
||||
return (unsigned HOST_WIDE_INT) TREE_INT_CST_LOW (offset);
|
||||
}
|
||||
|
||||
/* Build a FIELD_DECL for the base given by BINFO in T. If the new
|
||||
object is non-empty, clear *EMPTY_P. Otherwise, set *SAW_EMPTY_P.
|
||||
*BASE_ALIGN is a running maximum of the alignments of any base
|
||||
class. */
|
||||
/* Record the type of BINFO in the slot in DATA (which is really a
|
||||
`varray_type *') corresponding to the BINFO_OFFSET. */
|
||||
|
||||
static tree
|
||||
build_base_field (t, binfo, empty_p, saw_empty_p, base_align)
|
||||
tree t;
|
||||
dfs_record_base_offsets (binfo, data)
|
||||
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;
|
||||
int *empty_p;
|
||||
int *saw_empty_p;
|
||||
unsigned int *base_align;
|
||||
varray_type *v;
|
||||
{
|
||||
tree basetype = BINFO_TYPE (binfo);
|
||||
tree decl;
|
||||
@ -4138,25 +4250,15 @@ build_base_field (t, binfo, empty_p, saw_empty_p, base_align)
|
||||
if (TYPE_SIZE (basetype) == 0)
|
||||
/* This error is now reported in xref_tag, thus giving better
|
||||
location information. */
|
||||
return NULL_TREE;
|
||||
return;
|
||||
|
||||
decl = build_lang_decl (FIELD_DECL, NULL_TREE, basetype);
|
||||
DECL_ARTIFICIAL (decl) = 1;
|
||||
DECL_FIELD_CONTEXT (decl) = t;
|
||||
DECL_FIELD_CONTEXT (decl) = rli->t;
|
||||
DECL_SIZE (decl) = CLASSTYPE_SIZE (basetype);
|
||||
DECL_SIZE_UNIT (decl) = CLASSTYPE_SIZE_UNIT (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)
|
||||
{
|
||||
/* 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));
|
||||
}
|
||||
|
||||
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
|
||||
of REC. These fields are later removed by layout_basetypes. */
|
||||
/* Layout all of the non-virtual base classes. Returns a map from
|
||||
offsets to types present at those offsets. */
|
||||
|
||||
static tree
|
||||
build_base_fields (rec, empty_p)
|
||||
tree rec;
|
||||
static varray_type
|
||||
build_base_fields (rli, empty_p)
|
||||
record_layout_info rli;
|
||||
int *empty_p;
|
||||
{
|
||||
/* Chain to hold all the new FIELD_DECLs which stand in for base class
|
||||
subobjects. */
|
||||
tree base_decls = NULL_TREE;
|
||||
tree rec = rli->t;
|
||||
int n_baseclasses = CLASSTYPE_N_BASECLASSES (rec);
|
||||
tree decl, nextdecl;
|
||||
int i, saw_empty = 0;
|
||||
int i;
|
||||
varray_type v;
|
||||
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
|
||||
first. */
|
||||
if (flag_new_abi && CLASSTYPE_HAS_PRIMARY_BASE_P (rec))
|
||||
{
|
||||
tree primary_base;
|
||||
|
||||
primary_base = CLASSTYPE_PRIMARY_BINFO (rec);
|
||||
base_decls = chainon (build_base_field (rec,
|
||||
primary_base,
|
||||
empty_p,
|
||||
&saw_empty,
|
||||
&base_align),
|
||||
base_decls);
|
||||
}
|
||||
build_base_field (rli, CLASSTYPE_PRIMARY_BINFO (rec),
|
||||
empty_p, &base_align, &v);
|
||||
|
||||
/* Now allocate the rest of the bases. */
|
||||
for (i = 0; i < n_baseclasses; ++i)
|
||||
@ -4227,44 +4374,10 @@ build_base_fields (rec, empty_p)
|
||||
&& !BINFO_PRIMARY_MARKED_P (base_binfo))
|
||||
continue;
|
||||
|
||||
base_decls = chainon (build_base_field (rec, base_binfo,
|
||||
empty_p,
|
||||
&saw_empty,
|
||||
&base_align),
|
||||
base_decls);
|
||||
build_base_field (rli, base_binfo, empty_p, &base_align, &v);
|
||||
}
|
||||
|
||||
/* Reverse the list of fields so we allocate the bases in the proper
|
||||
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;
|
||||
return v;
|
||||
}
|
||||
|
||||
/* 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
|
||||
accordingly, and, if necessary, add the TYPE_VFIELD to the
|
||||
TYPE_FIELDS list. */
|
||||
accordingly. If a new vfield was created (because T doesn't have a
|
||||
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,
|
||||
new_virtuals_p, overridden_virtuals_p)
|
||||
tree t;
|
||||
@ -4496,29 +4611,17 @@ create_vtable_ptr (t, empty_p, has_virtual_p,
|
||||
t,
|
||||
empty_p);
|
||||
|
||||
/* Add the new field to the list of fields in this class. */
|
||||
if (!flag_new_abi)
|
||||
/* In the old ABI, the vtable pointer goes at the end of the
|
||||
class. */
|
||||
TYPE_FIELDS (t) = chainon (TYPE_FIELDS (t), TYPE_VFIELD (t));
|
||||
else
|
||||
{
|
||||
/* 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;
|
||||
}
|
||||
if (flag_new_abi && CLASSTYPE_N_BASECLASSES (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. */
|
||||
TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (t) = 1;
|
||||
|
||||
/* We can't yet add this new field to the list of all virtual
|
||||
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 TYPE_VFIELD (t);
|
||||
}
|
||||
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
/* Fixup the inline function given by INFO now that the class is
|
||||
@ -4613,85 +4716,6 @@ propagate_binfo_offsets (binfo, offset)
|
||||
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. */
|
||||
|
||||
static tree
|
||||
@ -4819,17 +4843,15 @@ layout_basetypes (rec)
|
||||
{
|
||||
tree vbase_types;
|
||||
|
||||
if (CLASSTYPE_N_BASECLASSES (rec) == 0)
|
||||
return;
|
||||
|
||||
#ifdef STRUCTURE_SIZE_BOUNDARY
|
||||
/* Packed structures don't need to have minimum size. */
|
||||
if (! TYPE_PACKED (rec))
|
||||
TYPE_ALIGN (rec) = MAX (TYPE_ALIGN (rec), STRUCTURE_SIZE_BOUNDARY);
|
||||
#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. */
|
||||
layout_virtual_bases (rec);
|
||||
|
||||
@ -4861,64 +4883,117 @@ layout_class_type (t, empty_p, has_virtual_p,
|
||||
tree *new_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
|
||||
of our base classes. */
|
||||
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. */
|
||||
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));
|
||||
/* Build FIELD_DECLs for all of the non-virtual base-types. */
|
||||
TYPE_FIELDS (t) = chainon (build_base_fields (t, 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);
|
||||
v = build_base_fields (rli, empty_p);
|
||||
|
||||
/* CLASSTYPE_INLINE_FRIENDS is really TYPE_NONCOPIED_PARTS. Thus,
|
||||
we have to save this before we start modifying
|
||||
TYPE_NONCOPIED_PARTS. */
|
||||
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
|
||||
have non-zero size. The field that we add here is fake, in the
|
||||
sense that, for example, we don't want people to be able to
|
||||
initialize it later. So, we add it just long enough to let the
|
||||
back-end lay out the type, and then remove it. In the new ABI,
|
||||
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. */
|
||||
have non-zero size. In the new ABI, the class may be empty even
|
||||
if it has basetypes. Therefore, we add the fake field after all
|
||||
the other fields; if there are already FIELD_DECLs on the list,
|
||||
their offsets will not be disturbed. */
|
||||
if (*empty_p)
|
||||
{
|
||||
tree padding;
|
||||
|
||||
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)
|
||||
= tree_cons (NULL_TREE, padding, TYPE_NONCOPIED_PARTS (t));
|
||||
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
|
||||
have only included non-virtual base-classes; we will lay out the
|
||||
virtual base classes later. So, the TYPE_SIZE/TYPE_ALIGN after
|
||||
this call are not necessarily correct; they are just the size and
|
||||
alignment when no virtual base clases are used. */
|
||||
layout_type (t);
|
||||
|
||||
/* 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);
|
||||
}
|
||||
finish_record_layout (rli);
|
||||
|
||||
/* Delete all zero-width bit-fields from the list of fields. Now
|
||||
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
|
||||
around. We must get these done before we try to lay out the
|
||||
virtual function table. */
|
||||
if (CLASSTYPE_N_BASECLASSES (t))
|
||||
/* layout_basetypes will remove the base subobject fields. */
|
||||
layout_basetypes (t);
|
||||
virtual function table. As a side-effect, this will remove the
|
||||
base subobject fields. */
|
||||
layout_basetypes (t);
|
||||
}
|
||||
|
||||
/* Create a RECORD_TYPE or UNION_TYPE node for a C struct or union declaration
|
||||
|
Loading…
Reference in New Issue
Block a user