public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH,c++] rewrite vtable initialization construction to use VECs
@ 2010-05-23 17:54 Nathan Froyd
  2010-05-24 16:20 ` Mark Mitchell
  0 siblings, 1 reply; 12+ messages in thread
From: Nathan Froyd @ 2010-05-23 17:54 UTC (permalink / raw)
  To: gcc-patches

The patch below started out as an attempt to remove one more instance of
build_constructor_from_list from the C++ front-end, but doing so
required extensive surgery on the way vtable initializers are built.
The effort has the (pleasant?) side-effect of removing TREE_LIST bits
from vtable initialization code.

I realize the TARGET_VTABLE_DATA_ENTRY_DISTANCE bits in here require
testing on ia64-<mumble>; if these changes look good, I will attempt to
do that on the compile farm.  If somebody was already set up to do
bootstrapping on ia64-<mumble> and was willing to test these changes for
me, that'd be great too.

Tested on x86_64-unknown-linux-gnu.  OK to commit?

-Nathan

	* 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.

diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 748e1b3..ca16ce5 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);
@@ -7035,36 +7035,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);
@@ -7086,13 +7086,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);
 
@@ -7101,7 +7101,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.  */
@@ -7147,8 +7147,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;
@@ -7162,19 +7162,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.  */
@@ -7188,8 +7187,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));
@@ -7200,30 +7198,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
@@ -7233,13 +7224,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
@@ -7287,7 +7276,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,
@@ -7330,12 +7319,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);
@@ -7348,9 +7336,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.  */
@@ -7364,12 +7353,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;
@@ -7378,7 +7366,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);
 }
 
@@ -7396,8 +7384,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;
@@ -7417,10 +7406,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
@@ -7434,24 +7420,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))
@@ -7505,23 +7492,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);
@@ -7534,12 +7522,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;
@@ -7567,26 +7554,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;
@@ -7612,28 +7599,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);
+
+      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 i;
+	  int j;
+	  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)
-	    add = tree_cons (NULL_TREE,
-			     build1 (NOP_EXPR, vtable_entry_type,
-				     null_pointer_node),
-			     add);
-	  *prev = add;
+	  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;
@@ -7719,7 +7729,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)
 	      {
@@ -7728,22 +7738,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
@@ -7853,12 +7853,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));
     }
 }
 
@@ -8093,8 +8090,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);
     }
 }
 
@@ -8138,15 +8134,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 3e1b310..cdb12cb 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -4748,7 +4748,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 95ae8eb..a6dedeb 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -5544,16 +5544,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;
-- 
1.6.3.3

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2010-06-16 18:07 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-05-23 17:54 [PATCH,c++] rewrite vtable initialization construction to use VECs Nathan Froyd
2010-05-24 16:20 ` Mark Mitchell
2010-06-03 20:47   ` Nathan Froyd
2010-06-10 17:12     ` Steve Ellcey
2010-06-15 13:50       ` Nathan Froyd
2010-06-15 17:44         ` Steve Ellcey
2010-06-15 18:41           ` Nathan Froyd
2010-06-15 21:01             ` Steve Ellcey
2010-06-15 21:03               ` Nathan Froyd
2010-06-16  6:14                 ` Steve Ellcey
2010-06-16 18:07                 ` Steve Ellcey
2010-06-16 20:17                   ` Nathan Froyd

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).