class.c (struct vtbl_init_data_s): Remove last_init field.
* class.c (struct vtbl_init_data_s): Remove last_init field. (struct secondary_vptr_vtt_init_data_s): Change type of inits field to a VEC. (finish_vtbls): Use a VEC rather than a TREE_LIST for the accumulated initializers. (build_vtt): Likewise. (initialize_vtable): Take a VEC instead of a tree. (build_vtt_inits): Change return type to void. Take a VEC ** instead of a tree *; accumulate results into said VEC. (build_ctor_vtbl_group): Use a VEC rather than a TREE_LIST for the accumulated initializers. Pass the vtable to accumulate_vtbl_inits. (accumulate_vtbl_inits): Add extra vtable tree parameter; take a VEC instead of a tree. (dfs_accumulate_vtbl_inits): Likewise. Change return type to void. (build_vtbl_initializer): Add VEC parameter; accumulate initializers into it. (dfs_build_secondary_vptr_vtt_inits): Use CONSTRUCTOR_APPEND_ELT rather than tree_cons. (build_vbase_offset_vtbl_entries): Likewise. (add_vcall_offset): Likewise. (build_rtti_vtbl_entries): Likewise. * cp-tree.h (initialize_artificial_var): Take a VEC instead of a tree. * decl.c (initialize_artificial_var): Use build_constructor instead of build_constructor_from_list. From-SVN: r160233
This commit is contained in:
parent
8eee0b8f76
commit
9d6a019c9c
|
@ -1,3 +1,30 @@
|
|||
2010-06-03 Nathan Froyd <froydnj@codesourcery.com>
|
||||
|
||||
* class.c (struct vtbl_init_data_s): Remove last_init field.
|
||||
(struct secondary_vptr_vtt_init_data_s): Change type of inits field
|
||||
to a VEC.
|
||||
(finish_vtbls): Use a VEC rather than a TREE_LIST for the accumulated
|
||||
initializers.
|
||||
(build_vtt): Likewise.
|
||||
(initialize_vtable): Take a VEC instead of a tree.
|
||||
(build_vtt_inits): Change return type to void. Take a VEC **
|
||||
instead of a tree *; accumulate results into said VEC.
|
||||
(build_ctor_vtbl_group): Use a VEC rather than a TREE_LIST for the
|
||||
accumulated initializers. Pass the vtable to accumulate_vtbl_inits.
|
||||
(accumulate_vtbl_inits): Add extra vtable tree parameter; take a VEC
|
||||
instead of a tree.
|
||||
(dfs_accumulate_vtbl_inits): Likewise. Change return type to void.
|
||||
(build_vtbl_initializer): Add VEC parameter; accumulate initializers
|
||||
into it.
|
||||
(dfs_build_secondary_vptr_vtt_inits): Use CONSTRUCTOR_APPEND_ELT
|
||||
rather than tree_cons.
|
||||
(build_vbase_offset_vtbl_entries): Likewise.
|
||||
(add_vcall_offset): Likewise.
|
||||
(build_rtti_vtbl_entries): Likewise.
|
||||
* cp-tree.h (initialize_artificial_var): Take a VEC instead of a tree.
|
||||
* decl.c (initialize_artificial_var): Use build_constructor instead
|
||||
of build_constructor_from_list.
|
||||
|
||||
2010-06-03 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR c++/44294
|
||||
|
|
224
gcc/cp/class.c
224
gcc/cp/class.c
|
@ -77,9 +77,7 @@ typedef struct vtbl_init_data_s
|
|||
tree rtti_binfo;
|
||||
/* The negative-index vtable initializers built up so far. These
|
||||
are in order from least negative index to most negative index. */
|
||||
tree inits;
|
||||
/* The last (i.e., most negative) entry in INITS. */
|
||||
tree* last_init;
|
||||
VEC(constructor_elt,gc) *inits;
|
||||
/* The binfo for the virtual base for which we're building
|
||||
vcall offset initializers. */
|
||||
tree vbase;
|
||||
|
@ -136,7 +134,8 @@ static void add_implicitly_declared_members (tree, int, int);
|
|||
static tree fixed_type_or_null (tree, int *, int *);
|
||||
static tree build_simple_base_path (tree expr, tree binfo);
|
||||
static tree build_vtbl_ref_1 (tree, tree);
|
||||
static tree build_vtbl_initializer (tree, tree, tree, tree, int *);
|
||||
static void build_vtbl_initializer (tree, tree, tree, tree, int *,
|
||||
VEC(constructor_elt,gc) **);
|
||||
static int count_fields (tree);
|
||||
static int add_fields_to_record_type (tree, struct sorted_fields_type*, int);
|
||||
static bool check_bitfield_decl (tree);
|
||||
|
@ -173,14 +172,15 @@ static void dump_vtable (tree, tree, tree);
|
|||
static void dump_vtt (tree, tree);
|
||||
static void dump_thunk (FILE *, int, tree);
|
||||
static tree build_vtable (tree, tree, tree);
|
||||
static void initialize_vtable (tree, tree);
|
||||
static void initialize_vtable (tree, VEC(constructor_elt,gc) *);
|
||||
static void layout_nonempty_base_or_field (record_layout_info,
|
||||
tree, tree, splay_tree);
|
||||
static tree end_of_class (tree, int);
|
||||
static bool layout_empty_base (record_layout_info, tree, tree, splay_tree);
|
||||
static void accumulate_vtbl_inits (tree, tree, tree, tree, tree);
|
||||
static tree dfs_accumulate_vtbl_inits (tree, tree, tree, tree,
|
||||
tree);
|
||||
static void accumulate_vtbl_inits (tree, tree, tree, tree, tree,
|
||||
VEC(constructor_elt,gc) **);
|
||||
static void dfs_accumulate_vtbl_inits (tree, tree, tree, tree, tree,
|
||||
VEC(constructor_elt,gc) **);
|
||||
static void build_rtti_vtbl_entries (tree, vtbl_init_data *);
|
||||
static void build_vcall_and_vbase_vtbl_entries (tree, vtbl_init_data *);
|
||||
static void clone_constructors_and_destructors (tree);
|
||||
|
@ -189,7 +189,7 @@ static void update_vtable_entry_for_fn (tree, tree, tree, tree *, unsigned);
|
|||
static void build_ctor_vtbl_group (tree, tree);
|
||||
static void build_vtt (tree);
|
||||
static tree binfo_ctor_vtable (tree);
|
||||
static tree *build_vtt_inits (tree, tree, tree *, tree *);
|
||||
static void build_vtt_inits (tree, tree, VEC(constructor_elt,gc) **, tree *);
|
||||
static tree dfs_build_secondary_vptr_vtt_inits (tree, void *);
|
||||
static tree dfs_fixup_binfo_vtbls (tree, void *);
|
||||
static int record_subobject_offset (tree, tree, splay_tree);
|
||||
|
@ -7042,36 +7042,36 @@ debug_thunks (tree fn)
|
|||
static void
|
||||
finish_vtbls (tree t)
|
||||
{
|
||||
tree list;
|
||||
tree vbase;
|
||||
VEC(constructor_elt,gc) *v = NULL;
|
||||
tree vtable = BINFO_VTABLE (TYPE_BINFO (t));
|
||||
|
||||
/* We lay out the primary and secondary vtables in one contiguous
|
||||
vtable. The primary vtable is first, followed by the non-virtual
|
||||
secondary vtables in inheritance graph order. */
|
||||
list = build_tree_list (BINFO_VTABLE (TYPE_BINFO (t)), NULL_TREE);
|
||||
accumulate_vtbl_inits (TYPE_BINFO (t), TYPE_BINFO (t),
|
||||
TYPE_BINFO (t), t, list);
|
||||
accumulate_vtbl_inits (TYPE_BINFO (t), TYPE_BINFO (t), TYPE_BINFO (t),
|
||||
vtable, t, &v);
|
||||
|
||||
/* Then come the virtual bases, also in inheritance graph order. */
|
||||
for (vbase = TYPE_BINFO (t); vbase; vbase = TREE_CHAIN (vbase))
|
||||
{
|
||||
if (!BINFO_VIRTUAL_P (vbase))
|
||||
continue;
|
||||
accumulate_vtbl_inits (vbase, vbase, TYPE_BINFO (t), t, list);
|
||||
accumulate_vtbl_inits (vbase, vbase, TYPE_BINFO (t), vtable, t, &v);
|
||||
}
|
||||
|
||||
if (BINFO_VTABLE (TYPE_BINFO (t)))
|
||||
initialize_vtable (TYPE_BINFO (t), TREE_VALUE (list));
|
||||
initialize_vtable (TYPE_BINFO (t), v);
|
||||
}
|
||||
|
||||
/* Initialize the vtable for BINFO with the INITS. */
|
||||
|
||||
static void
|
||||
initialize_vtable (tree binfo, tree inits)
|
||||
initialize_vtable (tree binfo, VEC(constructor_elt,gc) *inits)
|
||||
{
|
||||
tree decl;
|
||||
|
||||
layout_vtable_decl (binfo, list_length (inits));
|
||||
layout_vtable_decl (binfo, VEC_length (constructor_elt, inits));
|
||||
decl = get_vtbl_decl_for_binfo (binfo);
|
||||
initialize_artificial_var (decl, inits);
|
||||
dump_vtable (BINFO_TYPE (binfo), binfo, decl);
|
||||
|
@ -7093,13 +7093,13 @@ initialize_vtable (tree binfo, tree inits)
|
|||
static void
|
||||
build_vtt (tree t)
|
||||
{
|
||||
tree inits;
|
||||
tree type;
|
||||
tree vtt;
|
||||
tree index;
|
||||
VEC(constructor_elt,gc) *inits;
|
||||
|
||||
/* Build up the initializers for the VTT. */
|
||||
inits = NULL_TREE;
|
||||
inits = NULL;
|
||||
index = size_zero_node;
|
||||
build_vtt_inits (TYPE_BINFO (t), t, &inits, &index);
|
||||
|
||||
|
@ -7108,7 +7108,7 @@ build_vtt (tree t)
|
|||
return;
|
||||
|
||||
/* Figure out the type of the VTT. */
|
||||
type = build_index_type (size_int (list_length (inits) - 1));
|
||||
type = build_index_type (size_int (VEC_length (constructor_elt, inits) - 1));
|
||||
type = build_cplus_array_type (const_ptr_type_node, type);
|
||||
|
||||
/* Now, build the VTT object itself. */
|
||||
|
@ -7154,8 +7154,8 @@ typedef struct secondary_vptr_vtt_init_data_s
|
|||
/* Current index into the VTT. */
|
||||
tree index;
|
||||
|
||||
/* TREE_LIST of initializers built up. */
|
||||
tree inits;
|
||||
/* Vector of initializers built up. */
|
||||
VEC(constructor_elt,gc) *inits;
|
||||
|
||||
/* The type being constructed by this secondary VTT. */
|
||||
tree type_being_constructed;
|
||||
|
@ -7169,19 +7169,18 @@ typedef struct secondary_vptr_vtt_init_data_s
|
|||
for virtual bases of T. When it is not so, we build the constructor
|
||||
vtables for the BINFO-in-T variant. */
|
||||
|
||||
static tree *
|
||||
build_vtt_inits (tree binfo, tree t, tree *inits, tree *index)
|
||||
static void
|
||||
build_vtt_inits (tree binfo, tree t, VEC(constructor_elt,gc) **inits, tree *index)
|
||||
{
|
||||
int i;
|
||||
tree b;
|
||||
tree init;
|
||||
tree secondary_vptrs;
|
||||
secondary_vptr_vtt_init_data data;
|
||||
int top_level_p = SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), t);
|
||||
|
||||
/* We only need VTTs for subobjects with virtual bases. */
|
||||
if (!CLASSTYPE_VBASECLASSES (BINFO_TYPE (binfo)))
|
||||
return inits;
|
||||
return;
|
||||
|
||||
/* We need to use a construction vtable if this is not the primary
|
||||
VTT. */
|
||||
|
@ -7195,8 +7194,7 @@ build_vtt_inits (tree binfo, tree t, tree *inits, tree *index)
|
|||
|
||||
/* Add the address of the primary vtable for the complete object. */
|
||||
init = binfo_ctor_vtable (binfo);
|
||||
*inits = build_tree_list (NULL_TREE, init);
|
||||
inits = &TREE_CHAIN (*inits);
|
||||
CONSTRUCTOR_APPEND_ELT (*inits, NULL_TREE, init);
|
||||
if (top_level_p)
|
||||
{
|
||||
gcc_assert (!BINFO_VPTR_INDEX (binfo));
|
||||
|
@ -7207,30 +7205,23 @@ build_vtt_inits (tree binfo, tree t, tree *inits, tree *index)
|
|||
/* Recursively add the secondary VTTs for non-virtual bases. */
|
||||
for (i = 0; BINFO_BASE_ITERATE (binfo, i, b); ++i)
|
||||
if (!BINFO_VIRTUAL_P (b))
|
||||
inits = build_vtt_inits (b, t, inits, index);
|
||||
build_vtt_inits (b, t, inits, index);
|
||||
|
||||
/* Add secondary virtual pointers for all subobjects of BINFO with
|
||||
either virtual bases or reachable along a virtual path, except
|
||||
subobjects that are non-virtual primary bases. */
|
||||
data.top_level_p = top_level_p;
|
||||
data.index = *index;
|
||||
data.inits = NULL;
|
||||
data.inits = *inits;
|
||||
data.type_being_constructed = BINFO_TYPE (binfo);
|
||||
|
||||
dfs_walk_once (binfo, dfs_build_secondary_vptr_vtt_inits, NULL, &data);
|
||||
|
||||
*index = data.index;
|
||||
|
||||
/* The secondary vptrs come back in reverse order. After we reverse
|
||||
them, and add the INITS, the last init will be the first element
|
||||
of the chain. */
|
||||
secondary_vptrs = data.inits;
|
||||
if (secondary_vptrs)
|
||||
{
|
||||
*inits = nreverse (secondary_vptrs);
|
||||
inits = &TREE_CHAIN (secondary_vptrs);
|
||||
gcc_assert (*inits == NULL_TREE);
|
||||
}
|
||||
/* data.inits might have grown as we added secondary virtual pointers.
|
||||
Make sure our caller knows about the new vector. */
|
||||
*inits = data.inits;
|
||||
|
||||
if (top_level_p)
|
||||
/* Add the secondary VTTs for virtual bases in inheritance graph
|
||||
|
@ -7240,13 +7231,11 @@ build_vtt_inits (tree binfo, tree t, tree *inits, tree *index)
|
|||
if (!BINFO_VIRTUAL_P (b))
|
||||
continue;
|
||||
|
||||
inits = build_vtt_inits (b, t, inits, index);
|
||||
build_vtt_inits (b, t, inits, index);
|
||||
}
|
||||
else
|
||||
/* Remove the ctor vtables we created. */
|
||||
dfs_walk_all (binfo, dfs_fixup_binfo_vtbls, NULL, binfo);
|
||||
|
||||
return inits;
|
||||
}
|
||||
|
||||
/* Called from build_vtt_inits via dfs_walk. BINFO is the binfo for the base
|
||||
|
@ -7294,7 +7283,7 @@ dfs_build_secondary_vptr_vtt_inits (tree binfo, void *data_)
|
|||
}
|
||||
|
||||
/* Add the initializer for the secondary vptr itself. */
|
||||
data->inits = tree_cons (NULL_TREE, binfo_ctor_vtable (binfo), data->inits);
|
||||
CONSTRUCTOR_APPEND_ELT (data->inits, NULL_TREE, binfo_ctor_vtable (binfo));
|
||||
|
||||
/* Advance the vtt index. */
|
||||
data->index = size_binop (PLUS_EXPR, data->index,
|
||||
|
@ -7337,12 +7326,11 @@ dfs_fixup_binfo_vtbls (tree binfo, void* data)
|
|||
static void
|
||||
build_ctor_vtbl_group (tree binfo, tree t)
|
||||
{
|
||||
tree list;
|
||||
tree type;
|
||||
tree vtbl;
|
||||
tree inits;
|
||||
tree id;
|
||||
tree vbase;
|
||||
VEC(constructor_elt,gc) *v;
|
||||
|
||||
/* See if we've already created this construction vtable group. */
|
||||
id = mangle_ctor_vtbl_for_type (t, binfo);
|
||||
|
@ -7355,9 +7343,10 @@ build_ctor_vtbl_group (tree binfo, tree t)
|
|||
construction vtable group. */
|
||||
vtbl = build_vtable (t, id, ptr_type_node);
|
||||
DECL_CONSTRUCTION_VTABLE_P (vtbl) = 1;
|
||||
list = build_tree_list (vtbl, NULL_TREE);
|
||||
|
||||
v = NULL;
|
||||
accumulate_vtbl_inits (binfo, TYPE_BINFO (TREE_TYPE (binfo)),
|
||||
binfo, t, list);
|
||||
binfo, vtbl, t, &v);
|
||||
|
||||
/* Add the vtables for each of our virtual bases using the vbase in T
|
||||
binfo. */
|
||||
|
@ -7371,12 +7360,11 @@ build_ctor_vtbl_group (tree binfo, tree t)
|
|||
continue;
|
||||
b = copied_binfo (vbase, binfo);
|
||||
|
||||
accumulate_vtbl_inits (b, vbase, binfo, t, list);
|
||||
accumulate_vtbl_inits (b, vbase, binfo, vtbl, t, &v);
|
||||
}
|
||||
inits = TREE_VALUE (list);
|
||||
|
||||
/* Figure out the type of the construction vtable. */
|
||||
type = build_index_type (size_int (list_length (inits) - 1));
|
||||
type = build_index_type (size_int (VEC_length (constructor_elt, v) - 1));
|
||||
type = build_cplus_array_type (vtable_entry_type, type);
|
||||
layout_type (type);
|
||||
TREE_TYPE (vtbl) = type;
|
||||
|
@ -7385,7 +7373,7 @@ build_ctor_vtbl_group (tree binfo, tree t)
|
|||
|
||||
/* Initialize the construction vtable. */
|
||||
CLASSTYPE_VTABLES (t) = chainon (CLASSTYPE_VTABLES (t), vtbl);
|
||||
initialize_artificial_var (vtbl, inits);
|
||||
initialize_artificial_var (vtbl, v);
|
||||
dump_vtable (t, binfo, vtbl);
|
||||
}
|
||||
|
||||
|
@ -7403,8 +7391,9 @@ static void
|
|||
accumulate_vtbl_inits (tree binfo,
|
||||
tree orig_binfo,
|
||||
tree rtti_binfo,
|
||||
tree vtbl,
|
||||
tree t,
|
||||
tree inits)
|
||||
VEC(constructor_elt,gc) **inits)
|
||||
{
|
||||
int i;
|
||||
tree base_binfo;
|
||||
|
@ -7424,10 +7413,7 @@ accumulate_vtbl_inits (tree binfo,
|
|||
return;
|
||||
|
||||
/* Build the initializers for the BINFO-in-T vtable. */
|
||||
TREE_VALUE (inits)
|
||||
= chainon (TREE_VALUE (inits),
|
||||
dfs_accumulate_vtbl_inits (binfo, orig_binfo,
|
||||
rtti_binfo, t, inits));
|
||||
dfs_accumulate_vtbl_inits (binfo, orig_binfo, rtti_binfo, vtbl, t, inits);
|
||||
|
||||
/* Walk the BINFO and its bases. We walk in preorder so that as we
|
||||
initialize each vtable we can figure out at what offset the
|
||||
|
@ -7441,24 +7427,25 @@ accumulate_vtbl_inits (tree binfo,
|
|||
continue;
|
||||
accumulate_vtbl_inits (base_binfo,
|
||||
BINFO_BASE_BINFO (orig_binfo, i),
|
||||
rtti_binfo, t,
|
||||
rtti_binfo, vtbl, t,
|
||||
inits);
|
||||
}
|
||||
}
|
||||
|
||||
/* Called from accumulate_vtbl_inits. Returns the initializers for
|
||||
the BINFO vtable. */
|
||||
/* Called from accumulate_vtbl_inits. Adds the initializers for the
|
||||
BINFO vtable to L. */
|
||||
|
||||
static tree
|
||||
static void
|
||||
dfs_accumulate_vtbl_inits (tree binfo,
|
||||
tree orig_binfo,
|
||||
tree rtti_binfo,
|
||||
tree orig_vtbl,
|
||||
tree t,
|
||||
tree l)
|
||||
VEC(constructor_elt,gc) **l)
|
||||
{
|
||||
tree inits = NULL_TREE;
|
||||
tree vtbl = NULL_TREE;
|
||||
int ctor_vtbl_p = !SAME_BINFO_TYPE_P (BINFO_TYPE (rtti_binfo), t);
|
||||
int n_inits;
|
||||
|
||||
if (ctor_vtbl_p
|
||||
&& BINFO_VIRTUAL_P (orig_binfo) && BINFO_PRIMARY_P (orig_binfo))
|
||||
|
@ -7512,23 +7499,24 @@ dfs_accumulate_vtbl_inits (tree binfo,
|
|||
/* Otherwise, this is case 3 and we get our own. */
|
||||
}
|
||||
else if (!BINFO_NEW_VTABLE_MARKED (orig_binfo))
|
||||
return inits;
|
||||
return;
|
||||
|
||||
n_inits = VEC_length (constructor_elt, *l);
|
||||
|
||||
if (!vtbl)
|
||||
{
|
||||
tree index;
|
||||
int non_fn_entries;
|
||||
|
||||
/* Compute the initializer for this vtable. */
|
||||
inits = build_vtbl_initializer (binfo, orig_binfo, t, rtti_binfo,
|
||||
&non_fn_entries);
|
||||
/* Add the initializer for this vtable. */
|
||||
build_vtbl_initializer (binfo, orig_binfo, t, rtti_binfo,
|
||||
&non_fn_entries, l);
|
||||
|
||||
/* Figure out the position to which the VPTR should point. */
|
||||
vtbl = TREE_PURPOSE (l);
|
||||
vtbl = build1 (ADDR_EXPR, vtbl_ptr_type_node, vtbl);
|
||||
vtbl = build1 (ADDR_EXPR, vtbl_ptr_type_node, orig_vtbl);
|
||||
index = size_binop (PLUS_EXPR,
|
||||
size_int (non_fn_entries),
|
||||
size_int (list_length (TREE_VALUE (l))));
|
||||
size_int (n_inits));
|
||||
index = size_binop (MULT_EXPR,
|
||||
TYPE_SIZE_UNIT (vtable_entry_type),
|
||||
index);
|
||||
|
@ -7541,12 +7529,11 @@ dfs_accumulate_vtbl_inits (tree binfo,
|
|||
straighten this out. */
|
||||
BINFO_VTABLE (binfo) = tree_cons (rtti_binfo, vtbl, BINFO_VTABLE (binfo));
|
||||
else if (BINFO_PRIMARY_P (binfo) && BINFO_VIRTUAL_P (binfo))
|
||||
inits = NULL_TREE;
|
||||
/* Throw away any unneeded intializers. */
|
||||
VEC_truncate (constructor_elt, *l, n_inits);
|
||||
else
|
||||
/* For an ordinary vtable, set BINFO_VTABLE. */
|
||||
BINFO_VTABLE (binfo) = vtbl;
|
||||
|
||||
return inits;
|
||||
}
|
||||
|
||||
static GTY(()) tree abort_fndecl_addr;
|
||||
|
@ -7574,26 +7561,26 @@ static GTY(()) tree abort_fndecl_addr;
|
|||
primary bases; we need these while the primary base is being
|
||||
constructed. */
|
||||
|
||||
static tree
|
||||
static void
|
||||
build_vtbl_initializer (tree binfo,
|
||||
tree orig_binfo,
|
||||
tree t,
|
||||
tree rtti_binfo,
|
||||
int* non_fn_entries_p)
|
||||
int* non_fn_entries_p,
|
||||
VEC(constructor_elt,gc) **inits)
|
||||
{
|
||||
tree v, b;
|
||||
tree vfun_inits;
|
||||
vtbl_init_data vid;
|
||||
unsigned ix;
|
||||
unsigned ix, jx;
|
||||
tree vbinfo;
|
||||
VEC(tree,gc) *vbases;
|
||||
constructor_elt *e;
|
||||
|
||||
/* Initialize VID. */
|
||||
memset (&vid, 0, sizeof (vid));
|
||||
vid.binfo = binfo;
|
||||
vid.derived = t;
|
||||
vid.rtti_binfo = rtti_binfo;
|
||||
vid.last_init = &vid.inits;
|
||||
vid.primary_vtbl_p = SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), t);
|
||||
vid.ctor_vtbl_p = !SAME_BINFO_TYPE_P (BINFO_TYPE (rtti_binfo), t);
|
||||
vid.generate_vcall_entries = true;
|
||||
|
@ -7619,28 +7606,51 @@ build_vtbl_initializer (tree binfo,
|
|||
/* If the target requires padding between data entries, add that now. */
|
||||
if (TARGET_VTABLE_DATA_ENTRY_DISTANCE > 1)
|
||||
{
|
||||
tree cur, *prev;
|
||||
int n_entries = VEC_length (constructor_elt, vid.inits);
|
||||
|
||||
for (prev = &vid.inits; (cur = *prev); prev = &TREE_CHAIN (cur))
|
||||
VEC_safe_grow (constructor_elt, gc, vid.inits,
|
||||
TARGET_VTABLE_DATA_ENTRY_DISTANCE * n_entries);
|
||||
|
||||
/* Move data entries into their new positions and add padding
|
||||
after the new positions. Iterate backwards so we don't
|
||||
overwrite entries that we would need to process later. */
|
||||
for (ix = n_entries - 1;
|
||||
VEC_iterate (constructor_elt, vid.inits, ix, e);
|
||||
ix--)
|
||||
{
|
||||
tree add = cur;
|
||||
int i;
|
||||
int j;
|
||||
int new_position = TARGET_VTABLE_DATA_ENTRY_DISTANCE * ix;
|
||||
|
||||
for (i = 1; i < TARGET_VTABLE_DATA_ENTRY_DISTANCE; ++i)
|
||||
add = tree_cons (NULL_TREE,
|
||||
build1 (NOP_EXPR, vtable_entry_type,
|
||||
null_pointer_node),
|
||||
add);
|
||||
*prev = add;
|
||||
VEC_replace (constructor_elt, vid.inits, new_position, e);
|
||||
|
||||
for (j = 1; j < TARGET_VTABLE_DATA_ENTRY_DISTANCE; ++j)
|
||||
{
|
||||
constructor_elt *f = VEC_index (constructor_elt, *inits,
|
||||
new_position + j);
|
||||
f->index = NULL_TREE;
|
||||
f->value = build1 (NOP_EXPR, vtable_entry_type,
|
||||
null_pointer_node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (non_fn_entries_p)
|
||||
*non_fn_entries_p = list_length (vid.inits);
|
||||
*non_fn_entries_p = VEC_length (constructor_elt, vid.inits);
|
||||
|
||||
/* The initializers for virtual functions were built up in reverse
|
||||
order. Straighten them out and add them to the running list in one
|
||||
step. */
|
||||
jx = VEC_length (constructor_elt, *inits);
|
||||
VEC_safe_grow (constructor_elt, gc, *inits,
|
||||
(jx + VEC_length (constructor_elt, vid.inits)));
|
||||
|
||||
for (ix = VEC_length (constructor_elt, vid.inits) - 1;
|
||||
VEC_iterate (constructor_elt, vid.inits, ix, e);
|
||||
ix--, jx++)
|
||||
VEC_replace (constructor_elt, *inits, jx, e);
|
||||
|
||||
/* Go through all the ordinary virtual functions, building up
|
||||
initializers. */
|
||||
vfun_inits = NULL_TREE;
|
||||
for (v = BINFO_VIRTUALS (orig_binfo); v; v = TREE_CHAIN (v))
|
||||
{
|
||||
tree delta;
|
||||
|
@ -7726,7 +7736,7 @@ build_vtbl_initializer (tree binfo,
|
|||
int i;
|
||||
if (init == size_zero_node)
|
||||
for (i = 0; i < TARGET_VTABLE_USES_DESCRIPTORS; ++i)
|
||||
vfun_inits = tree_cons (NULL_TREE, init, vfun_inits);
|
||||
CONSTRUCTOR_APPEND_ELT (*inits, NULL_TREE, init);
|
||||
else
|
||||
for (i = 0; i < TARGET_VTABLE_USES_DESCRIPTORS; ++i)
|
||||
{
|
||||
|
@ -7735,22 +7745,12 @@ build_vtbl_initializer (tree binfo,
|
|||
build_int_cst (NULL_TREE, i));
|
||||
TREE_CONSTANT (fdesc) = 1;
|
||||
|
||||
vfun_inits = tree_cons (NULL_TREE, fdesc, vfun_inits);
|
||||
CONSTRUCTOR_APPEND_ELT (*inits, NULL_TREE, fdesc);
|
||||
}
|
||||
}
|
||||
else
|
||||
vfun_inits = tree_cons (NULL_TREE, init, vfun_inits);
|
||||
CONSTRUCTOR_APPEND_ELT (*inits, NULL_TREE, init);
|
||||
}
|
||||
|
||||
/* The initializers for virtual functions were built up in reverse
|
||||
order; straighten them out now. */
|
||||
vfun_inits = nreverse (vfun_inits);
|
||||
|
||||
/* The negative offset initializers are also in reverse order. */
|
||||
vid.inits = nreverse (vid.inits);
|
||||
|
||||
/* Chain the two together. */
|
||||
return chainon (vid.inits, vfun_inits);
|
||||
}
|
||||
|
||||
/* Adds to vid->inits the initializers for the vbase and vcall
|
||||
|
@ -7860,12 +7860,9 @@ build_vbase_offset_vtbl_entries (tree binfo, vtbl_init_data* vid)
|
|||
delta = size_diffop_loc (input_location,
|
||||
BINFO_OFFSET (b), BINFO_OFFSET (non_primary_binfo));
|
||||
|
||||
*vid->last_init
|
||||
= build_tree_list (NULL_TREE,
|
||||
fold_build1_loc (input_location, NOP_EXPR,
|
||||
vtable_entry_type,
|
||||
delta));
|
||||
vid->last_init = &TREE_CHAIN (*vid->last_init);
|
||||
CONSTRUCTOR_APPEND_ELT (vid->inits, NULL_TREE,
|
||||
fold_build1_loc (input_location, NOP_EXPR,
|
||||
vtable_entry_type, delta));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8100,8 +8097,7 @@ add_vcall_offset (tree orig_fn, tree binfo, vtbl_init_data *vid)
|
|||
vcall_offset);
|
||||
}
|
||||
/* Add the initializer to the vtable. */
|
||||
*vid->last_init = build_tree_list (NULL_TREE, vcall_offset);
|
||||
vid->last_init = &TREE_CHAIN (*vid->last_init);
|
||||
CONSTRUCTOR_APPEND_ELT (vid->inits, NULL_TREE, vcall_offset);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8145,15 +8141,13 @@ build_rtti_vtbl_entries (tree binfo, vtbl_init_data* vid)
|
|||
/* Convert the declaration to a type that can be stored in the
|
||||
vtable. */
|
||||
init = build_nop (vfunc_ptr_type_node, decl);
|
||||
*vid->last_init = build_tree_list (NULL_TREE, init);
|
||||
vid->last_init = &TREE_CHAIN (*vid->last_init);
|
||||
CONSTRUCTOR_APPEND_ELT (vid->inits, NULL_TREE, init);
|
||||
|
||||
/* Add the offset-to-top entry. It comes earlier in the vtable than
|
||||
the typeinfo entry. Convert the offset to look like a
|
||||
function pointer, so that we can put it in the vtable. */
|
||||
init = build_nop (vfunc_ptr_type_node, offset);
|
||||
*vid->last_init = build_tree_list (NULL_TREE, init);
|
||||
vid->last_init = &TREE_CHAIN (*vid->last_init);
|
||||
CONSTRUCTOR_APPEND_ELT (vid->inits, NULL_TREE, init);
|
||||
}
|
||||
|
||||
/* Fold a OBJ_TYPE_REF expression to the address of a function.
|
||||
|
|
|
@ -4743,7 +4743,7 @@ extern tree check_elaborated_type_specifier (enum tag_types, tree, bool);
|
|||
extern void warn_extern_redeclared_static (tree, tree);
|
||||
extern tree cxx_comdat_group (tree);
|
||||
extern bool cp_missing_noreturn_ok_p (tree);
|
||||
extern void initialize_artificial_var (tree, tree);
|
||||
extern void initialize_artificial_var (tree, VEC(constructor_elt,gc) *);
|
||||
extern tree check_var_type (tree, tree);
|
||||
extern tree reshape_init (tree, tree);
|
||||
extern tree next_initializable_field (tree);
|
||||
|
|
|
@ -5542,16 +5542,15 @@ initialize_local_var (tree decl, tree init)
|
|||
|
||||
/* DECL is a VAR_DECL for a compiler-generated variable with static
|
||||
storage duration (like a virtual table) whose initializer is a
|
||||
compile-time constant. INIT must be either a TREE_LIST of values,
|
||||
or a CONSTRUCTOR. Initialize the variable and provide it to the
|
||||
compile-time constant. Initialize the variable and provide it to the
|
||||
back end. */
|
||||
|
||||
void
|
||||
initialize_artificial_var (tree decl, tree init)
|
||||
initialize_artificial_var (tree decl, VEC(constructor_elt,gc) *v)
|
||||
{
|
||||
tree init;
|
||||
gcc_assert (DECL_ARTIFICIAL (decl));
|
||||
if (TREE_CODE (init) == TREE_LIST)
|
||||
init = build_constructor_from_list (TREE_TYPE (decl), init);
|
||||
init = build_constructor (TREE_TYPE (decl), v);
|
||||
gcc_assert (TREE_CODE (init) == CONSTRUCTOR);
|
||||
DECL_INITIAL (decl) = init;
|
||||
DECL_INITIALIZED_P (decl) = 1;
|
||||
|
|
Loading…
Reference in New Issue