Commit 9d6a019c by Nathan Froyd Committed by Nathan Froyd

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