diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 1138cd203c5..b2f6cd1de99 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,30 @@ +2010-06-03 Nathan Froyd + + * 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 PR c++/44294 diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 69064a6242c..2ee779299fe 100644 --- a/gcc/cp/class.c +++ b/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. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index da8293f7b52..89a3b7c3d96 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -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); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index b9f3ea84643..390519618c1 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -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;