Patchwork RFA: PATCH to add variadic version of build_constructor

login
register
mail settings
Submitter Jason Merrill
Date May 7, 2013, 3:20 a.m.
Message ID <518872E0.3090904@redhat.com>
Download mbox | patch
Permalink /patch/241921/
State New
Headers show

Comments

Jason Merrill - May 7, 2013, 3:20 a.m.
Most build_* functions have variadic versions, but build_constructor 
doesn't as of yet, and it would be convenient for a patch I'm working 
on.  I decided to call it build_constructor_va, but am open to other 
naming ideas.

Tested x86_64-pc-linux-gnu.  OK for trunk?
Richard Guenther - May 7, 2013, 8:41 a.m.
On Tue, May 7, 2013 at 5:20 AM, Jason Merrill <jason@redhat.com> wrote:
> Most build_* functions have variadic versions, but build_constructor doesn't
> as of yet, and it would be convenient for a patch I'm working on.  I decided
> to call it build_constructor_va, but am open to other naming ideas.
>
> Tested x86_64-pc-linux-gnu.  OK for trunk?

Eh, two NULL_TREE terminators are ugly ... callers know the number of elements,
so maybe instead pass that number as argument?

It looks like build_constructor_single can be implemented (or
completely replaced by)
build_constructor_va (build_constructor_single is nearly unused).

Can we overload build_constructor with a variadic variant?  Thus,

tree build_constructor (tree type, vec<constructor_elt, va_gc> *vals);
tree build_constructor (tree type, unsigned n, ...);

one of the nice things of using C++ is that we don't have to invent fancy
names for different interfaces of the same thing.

Richard.

Patch

commit 7cab86001c233a8cac209e905aafe796560b80ff
Author: Jason Merrill <jason@redhat.com>
Date:   Mon May 6 23:15:08 2013 -0400

    	* tree.c (build_constructor_va): New.
    	* tree.h: Declare it.

diff --git a/gcc/tree.c b/gcc/tree.c
index d8f2424..9782fba 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -1467,6 +1467,29 @@  build_constructor_from_list (tree type, tree vals)
   return build_constructor (type, v);
 }
 
+/* Return a new CONSTRUCTOR node whose type is TYPE.  If additional
+   arguments are provided, they are index/value pairs.  The list must be
+   terminated by two NULL_TREEs.  */
+
+tree
+build_constructor_va (tree type, ...)
+{
+  vec<constructor_elt, va_gc> *v = NULL;
+  va_list p;
+
+  va_start (p, type);
+  while (true)
+    {
+      tree index = va_arg (p, tree);
+      tree value = va_arg (p, tree);
+      if (index == NULL_TREE && value == NULL_TREE)
+	break;
+      CONSTRUCTOR_APPEND_ELT (v, index, value);
+    }
+  va_end (p);
+  return build_constructor (type, v);
+}
+
 /* Return a new FIXED_CST node whose type is TYPE and value is F.  */
 
 tree
diff --git a/gcc/tree.h b/gcc/tree.h
index be43440..5150237 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -4763,6 +4763,7 @@  extern tree build_vector_from_val (tree, tree);
 extern tree build_constructor (tree, vec<constructor_elt, va_gc> *);
 extern tree build_constructor_single (tree, tree, tree);
 extern tree build_constructor_from_list (tree, tree);
+extern tree build_constructor_va (tree, ...);
 extern tree build_real_from_int_cst (tree, const_tree);
 extern tree build_complex (tree, tree, tree);
 extern tree build_one_cst (tree);