[PATCH,C/C++/ObjC/C++] get rid of build_function_call

Nathan Froyd froydnj@mozilla.com
Fri Jun 17 17:43:00 GMT 2011


build_function_call uses an outdated interface (a TREE_LIST containing
the arguments passed to the function) and is only used by the ObjC/C++
FEs.  The patch below deletes it and introduces a new
build_function_call_nary interface modeled after
cp_build_function_call_nary.

The C/C++ changes are minimal; the bulk of the patch is dealing with
objc-act.c.  I took the liberty of cleaning up a few
build_function_call_vec calls to use build_function_call_nary where
appropriate.

The objc_runtime_hooks.build_objc_method_call interface could use some
cleanup after this conversion so as to not build TREE_LISTs that
eventually get converted into VECs, but doing that cleanup requires some
invasive surgery (brought on by
objcp_tsubst_copy_and_build:MESSAGE_SEND_EXPR).

Tested on x86_64-unknown-linux-gnu with the appropriate testsuites.  OK
to commit?

-Nathan

gcc/c-family/
	* c-common.h (build_function_call): Delete.
	(build_function_call_nary): Declare.

gcc/
	* c-typeck.c (build_function_call): Delete.
	(build_function_call_nary): New function.
	(build_function_call_vec): Call build_function_call_nary instead.

gcc/cp/
	* cp-tree.h (cp_build_function_call): Delete.
	* decl.c (register_dtor_fn): Update comment.
	* typeck.c (build_function_call): Delete.
	(cp_build_function_call): Delete.
	(build_function_call_nary_1): New function, split out from...
	(cp_build_function_call_nary): ...here.  Call it.
	(build_function_call_nary): New function.

gcc/objc/
	* objc-act.c (objc_build_ivar_assignment): Call
	build_function_call_nary instead of build_function_call.
	(objc_build_global_assignment): Likewise.
	(objc_build_strong_cast_assignment): Likewise.
	(objc_build_synchronized): Likewise.
	(objc_synthesize_getter, objc_synthesize_setter): Likewise.
	(objc_finish_foreach_loop): Likewise.
	* objc-gnu-runtime-abi-01.c
	(gnu_runtime_abi_01_get_class_reference): Likewise.
	(build_objc_method_call): Likewise.
	(gnu_runtime_abi_01_get_category_super_ref): Likewise.
	(build_module_initializer_routine): Likewise.
	(objc_generate_static_init_call): Likewise.
	(build_throw_stmt): Likewise.
	* objc-next-runtime-abi-01.c
	(next_runtime_abi_01_get_class_reference): Likewise.
	(next_runtime_abi_01_get_category_super_ref): Likewise.
	(next_sjlj_build_try_exit): Likewise.
	(next_sjlj_build_enter_and_setjmp): Likewise.
	(next_sjlj_build_exc_extract): Likewise.
	(next_sjlj_build_catch_list): Likewise.
	(next_sjlj_build_try_catch_finally): Likewise.
	(build_throw_stmt): Likewise.
	* objc-next-runtime-abi-02.c
	(next_runtime_abi_02_get_class_reference): Likewise.
	(next_runtime_abi_02_get_category_super_ref): Likewise.
	(build_v2_build_objc_method_call): Likewise.
	(build_throw_stmt): Likewise.
	(begin_catch, finish_catch): Likewise.

diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index c63b40d..7325b64 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -867,8 +867,8 @@ extern tree c_add_case_label (location_t, splay_tree, tree, tree, tree, tree);
 
 extern void c_do_switch_warnings (splay_tree, location_t, tree, tree);
 
-extern tree build_function_call (location_t, tree, tree);
-
+extern tree build_function_call_nary (location_t, tree, ...)
+  ATTRIBUTE_SENTINEL;
 extern tree build_function_call_vec (location_t, tree,
     				     VEC(tree,gc) *, VEC(tree,gc) *);
 
diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c
index a451606..5ffbe4b 100644
--- a/gcc/c-typeck.c
+++ b/gcc/c-typeck.c
@@ -2654,24 +2654,24 @@ c_expr_sizeof_type (location_t loc, struct c_type_name *t)
   return ret;
 }
 
-/* Build a function call to function FUNCTION with parameters PARAMS.
-   The function call is at LOC.
-   PARAMS is a list--a chain of TREE_LIST nodes--in which the
-   TREE_VALUE of each node is a parameter-expression.
-   FUNCTION's data type may be a function type or a pointer-to-function.  */
+/* Build a function call to function FUNCTION with parameters passed
+   as varargs, terminated with NULL_TREE.  The function call is at LOC.  */
 
 tree
-build_function_call (location_t loc, tree function, tree params)
+build_function_call_nary (location_t loc, tree function, ...)
 {
-  VEC(tree,gc) *vec;
-  tree ret;
+  VEC(tree,gc) *v = make_tree_vector ();
+  va_list args;
+  tree t;
 
-  vec = VEC_alloc (tree, gc, list_length (params));
-  for (; params; params = TREE_CHAIN (params))
-    VEC_quick_push (tree, vec, TREE_VALUE (params));
-  ret = build_function_call_vec (loc, function, vec, NULL);
-  VEC_free (tree, gc, vec);
-  return ret;
+  va_start (args, function);
+  for (t = va_arg (args, tree) ; t != NULL_TREE; t = va_arg (args, tree))
+    VEC_safe_push (tree, gc, v, t);
+  va_end (args);
+
+  t = build_function_call_vec (loc, function, v, NULL);
+  release_tree_vector (v);
+  return t;
 }
 
 /* Build a function call to function FUNCTION with parameters PARAMS.
@@ -2758,8 +2758,9 @@ build_function_call_vec (location_t loc, tree function, VEC(tree,gc) *params,
       && !comptypes (fntype, TREE_TYPE (tem)))
     {
       tree return_type = TREE_TYPE (fntype);
-      tree trap = build_function_call (loc, built_in_decls[BUILT_IN_TRAP],
-				       NULL_TREE);
+      tree trap = build_function_call_nary (loc,
+					    built_in_decls[BUILT_IN_TRAP],
+					    NULL_TREE);
       int i;
 
       /* This situation leads to run-time undefined behavior.  We can't,
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 06b5926..d531bad 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -5598,7 +5598,6 @@ extern tree build_array_ref			(location_t, tree, tree);
 extern tree cp_build_array_ref			(location_t, tree, tree,
 						 tsubst_flags_t);
 extern tree get_member_function_from_ptrfunc	(tree *, tree);
-extern tree cp_build_function_call              (tree, tree, tsubst_flags_t);
 extern tree cp_build_function_call_nary         (tree, tsubst_flags_t, ...)
 						ATTRIBUTE_SENTINEL;
 extern tree cp_build_function_call_vec		(tree, VEC(tree,gc) **,
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 3ccefb9..d46b9bb 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -6579,8 +6579,8 @@ register_dtor_fn (tree decl)
 	  mark_used (decl);
 	  addr = build_address (decl);
 	  /* The declared type of the parameter to "__cxa_atexit" is
-	     "void *".  For plain "T*", we could just let the
-	     machinery in cp_build_function_call convert it -- but if the
+	     "void *".  For plain "T*", we could just let the machinery
+	     in cp_build_function_call_nary convert it -- but if the
 	     type is "cv-qualified T *", then we need to convert it
 	     before passing it in, to avoid spurious errors.  */
 	  addr = build_nop (ptr_type_node, addr);
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 1bed291..24903dd 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -3121,14 +3121,6 @@ get_member_function_from_ptrfunc (tree *instance_ptrptr, tree function)
 
 /* Used by the C-common bits.  */
 tree
-build_function_call (location_t loc ATTRIBUTE_UNUSED, 
-		     tree function, tree params)
-{
-  return cp_build_function_call (function, params, tf_warning_or_error);
-}
-
-/* Used by the C-common bits.  */
-tree
 build_function_call_vec (location_t loc ATTRIBUTE_UNUSED,
 			 tree function, VEC(tree,gc) *params,
 			 VEC(tree,gc) *origtypes ATTRIBUTE_UNUSED)
@@ -3145,20 +3137,33 @@ build_function_call_vec (location_t loc ATTRIBUTE_UNUSED,
   return ret;
 }
 
-/* Build a function call using a tree list of arguments.  */
-
-tree
-cp_build_function_call (tree function, tree params, tsubst_flags_t complain)
+static tree
+build_function_call_nary_1 (tree function, tsubst_flags_t complain,
+			    va_list args)
 {
   VEC(tree,gc) *vec;
-  tree ret;
+  tree t;
 
   vec = make_tree_vector ();
-  for (; params != NULL_TREE; params = TREE_CHAIN (params))
-    VEC_safe_push (tree, gc, vec, TREE_VALUE (params));
-  ret = cp_build_function_call_vec (function, &vec, complain);
+  for (t = va_arg (args, tree); t != NULL_TREE; t = va_arg (args, tree))
+    VEC_safe_push (tree, gc, vec, t);
+  t = cp_build_function_call_vec (function, &vec, complain);
   release_tree_vector (vec);
-  return ret;
+  return t;
+}
+
+/* Used by the C-common bits.  */
+tree
+build_function_call_nary (location_t loc ATTRIBUTE_UNUSED,
+			  tree function, ...)
+{
+  va_list args;
+  tree t;
+
+  va_start (args, function);
+  t = build_function_call_nary_1 (function, tf_warning_or_error, args);
+  va_end (args);
+  return t;
 }
 
 /* Build a function call using varargs.  */
@@ -3166,18 +3171,13 @@ cp_build_function_call (tree function, tree params, tsubst_flags_t complain)
 tree
 cp_build_function_call_nary (tree function, tsubst_flags_t complain, ...)
 {
-  VEC(tree,gc) *vec;
   va_list args;
-  tree ret, t;
+  tree t;
 
-  vec = make_tree_vector ();
   va_start (args, complain);
-  for (t = va_arg (args, tree); t != NULL_TREE; t = va_arg (args, tree))
-    VEC_safe_push (tree, gc, vec, t);
+  t = build_function_call_nary_1 (function, complain, args);
   va_end (args);
-  ret = cp_build_function_call_vec (function, &vec, complain);
-  release_tree_vector (vec);
-  return ret;
+  return t;
 }
 
 /* Build a function call using a vector of arguments.  PARAMS may be
diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c
index 321d52a..aaee18d 100644
--- a/gcc/objc/objc-act.c
+++ b/gcc/objc/objc-act.c
@@ -3561,7 +3561,6 @@ objc_substitute_decl (tree expr, tree oldexpr, tree newexpr)
 static tree
 objc_build_ivar_assignment (tree outervar, tree lhs, tree rhs)
 {
-  tree func_params;
   /* The LHS parameter contains the expression 'outervar->memberspec';
      we need to transform it into '&((typeof(outervar) *) 0)->memberspec',
      where memberspec may be arbitrarily complex (e.g., 'g->f.d[2].g[3]').
@@ -3577,42 +3576,39 @@ objc_build_ivar_assignment (tree outervar, tree lhs, tree rhs)
   offs = convert (integer_type_node, build_unary_op (input_location,
 						     ADDR_EXPR, offs, 0));
   offs = fold (offs);
-  func_params = tree_cons (NULL_TREE,
-	convert (objc_object_type, rhs),
-	    tree_cons (NULL_TREE, convert (objc_object_type, outervar),
-		tree_cons (NULL_TREE, offs,
-		    NULL_TREE)));
-
   assemble_external (func);
-  return build_function_call (input_location, func, func_params);
+  return build_function_call_nary (input_location, func,
+				   convert (objc_object_type, rhs),
+				   convert (objc_object_type, outervar),
+				   offs, NULL_TREE);
 }
 
 static tree
 objc_build_global_assignment (tree lhs, tree rhs)
 {
-  tree func_params = tree_cons (NULL_TREE,
-	convert (objc_object_type, rhs),
-	    tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
-		      build_unary_op (input_location, ADDR_EXPR, lhs, 0)),
-		    NULL_TREE));
-
   assemble_external (objc_assign_global_decl);
-  return build_function_call (input_location,
-			      objc_assign_global_decl, func_params);
+  return build_function_call_nary (input_location,
+				   objc_assign_global_decl,
+				   convert (objc_object_type, rhs),
+				   convert
+				   (build_pointer_type (objc_object_type),
+				    build_unary_op (input_location, ADDR_EXPR,
+						    lhs, 0)),
+				   NULL_TREE);
 }
 
 static tree
 objc_build_strong_cast_assignment (tree lhs, tree rhs)
 {
-  tree func_params = tree_cons (NULL_TREE,
-	convert (objc_object_type, rhs),
-	    tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
-		      build_unary_op (input_location, ADDR_EXPR, lhs, 0)),
-		    NULL_TREE));
-
   assemble_external (objc_assign_strong_cast_decl);
-  return build_function_call (input_location,
-			      objc_assign_strong_cast_decl, func_params);
+  return build_function_call_nary (input_location,
+				   objc_assign_strong_cast_decl,
+				   convert (objc_object_type, rhs),
+				   convert
+				   (build_pointer_type (objc_object_type),
+				    build_unary_op (input_location, ADDR_EXPR,
+						    lhs, 0)),
+				   NULL_TREE);
 }
 
 static int
@@ -4395,21 +4391,20 @@ objc_build_synchronized (location_t start_locus, tree object_expr, tree body)
   else
     {
       tree call;
-      tree args;
 
       /* objc_sync_enter (object_expr); */
       object_expr = save_expr (object_expr);
-      args = tree_cons (NULL, object_expr, NULL);
-      call = build_function_call (input_location,
-				  objc_sync_enter_decl, args);
+      call = build_function_call_nary (input_location,
+				       objc_sync_enter_decl,
+				       object_expr, NULL_TREE);
       SET_EXPR_LOCATION (call, start_locus);
       add_stmt (call);
 
       /* Build "objc_sync_exit (object_expr);" but do not add it yet;
 	 it goes inside the @finalize() clause.  */
-      args = tree_cons (NULL, object_expr, NULL);
-      call = build_function_call (input_location,
-				  objc_sync_exit_decl, args);
+      call = build_function_call_nary (input_location,
+				       objc_sync_exit_decl,
+				       object_expr, NULL_TREE);
       SET_EXPR_LOCATION (call, input_location);
 
       /* @try { body; } */
@@ -7458,19 +7453,13 @@ objc_synthesize_getter (tree klass, tree class_methods ATTRIBUTE_UNUSED, tree pr
 	else
 	  is_atomic = boolean_true_node;
 
-	ret_val = build_function_call
-	  (location,
-	   /* Function prototype.  */
-	   objc_getProperty_decl,
-	   /* Parameters.  */
-	   tree_cons    /* self */
-	   (NULL_TREE, self_decl,
-	    tree_cons   /* _cmd */
-	    (NULL_TREE, cmd,
-	     tree_cons  /* offset */
-	     (NULL_TREE, offset,
-	      tree_cons /* is_atomic */
-	      (NULL_TREE, is_atomic, NULL_TREE)))));
+	ret_val = build_function_call_nary (location,
+					    objc_getProperty_decl,
+					    self_decl, /* self */
+					    cmd,       /* _cmd */
+					    offset,    /* offset */
+					    is_atomic, /* is_atomic */
+					    NULL_TREE);
       }
       break;
     case OBJC_PROPERTY_ASSIGN:
@@ -7495,6 +7484,7 @@ objc_synthesize_getter (tree klass, tree class_methods ATTRIBUTE_UNUSED, tree pr
 	     instead of objc_getPropertyStruct.  */
 	  tree objc_property_temp_decl, function_decl, function_call;
 	  tree size_of, is_atomic;
+	  tree property_ivar_name;
 
 	  objc_property_temp_decl = objc_create_temporary_var (TREE_TYPE (property), "__objc_property_temp");
 	  DECL_SOURCE_LOCATION (objc_property_temp_decl) = location;
@@ -7516,27 +7506,30 @@ objc_synthesize_getter (tree klass, tree class_methods ATTRIBUTE_UNUSED, tree pr
 	  else
 	    function_decl = objc_getPropertyStruct_decl;
 
-	  function_call = build_function_call
-	    (location,
-	     /* Function prototype.  */
-	     function_decl,
-	     /* Parameters.  */
-	     tree_cons /* &__objc_property_temp_decl */
-	     /* Warning: note that using build_fold_addr_expr_loc()
-		here causes invalid code to be generated.  */
-	     (NULL_TREE, build_unary_op (location, ADDR_EXPR, objc_property_temp_decl, 0),
-	      tree_cons /* &(self->PROPERTY_IVAR_NAME); */
-	      (NULL_TREE, build_fold_addr_expr_loc (location,
-						    objc_lookup_ivar
-						    (NULL_TREE, PROPERTY_IVAR_NAME (property))),
-	       tree_cons /* sizeof (PROPERTY_IVAR) */
-	       (NULL_TREE, size_of,
-		tree_cons /* is_atomic */
-		(NULL_TREE, is_atomic,
-		 /* TODO: This is currently ignored by the GNU
-		    runtime, but what about the next one ? */
-		 tree_cons /* has_strong */
-		 (NULL_TREE, boolean_true_node, NULL_TREE))))));
+	  property_ivar_name = PROPERTY_IVAR_NAME (property);
+	  property_ivar_name =
+	    build_fold_addr_expr_loc
+	    (location, objc_lookup_ivar (NULL_TREE, property_ivar_name));
+	  function_call = (build_function_call_nary
+			   (location, function_decl,
+			    /* Warning: note that using
+			       build_fold_addr_expr_loc here causes
+			       invalid code to be generated.  */
+			    /* &__objc_property_temp_decl */
+			    build_unary_op (location, ADDR_EXPR,
+					    objc_property_temp_decl, 0),
+			    /* &(self->PROPERTY_IVAR_NAME) */
+			    property_ivar_name,
+			    /* sizeof (PROPERTY_IVAR) */
+			    size_of,
+			    /* is_atomic */
+			    is_atomic,
+			    /* TODO: This is currently ignored by the
+			       GNU runtime, but what about the next
+			       one?  */
+			    /* has strong */
+			    boolean_true_node,
+			    NULL_TREE));
 
 	  add_stmt (function_call);
 
@@ -7658,23 +7651,15 @@ objc_synthesize_setter (tree klass, tree class_methods ATTRIBUTE_UNUSED, tree pr
 	else
 	  should_copy = boolean_false_node;
 
-	statement = build_function_call
-	  (location,
-	   /* Function prototype.  */
-	   objc_setProperty_decl,
-	   /* Parameters.  */
-	   tree_cons    /* self */
-	   (NULL_TREE, self_decl,
-	    tree_cons   /* _cmd */
-	    (NULL_TREE, cmd,
-	     tree_cons  /* offset */
-	     (NULL_TREE, offset,
-	      tree_cons /* new_value */
-	      (NULL_TREE, new_value,
-	       tree_cons /* is_atomic */
-	       (NULL_TREE, is_atomic,
-		tree_cons /* should_copy */
-		(NULL_TREE, should_copy, NULL_TREE)))))));
+	statement = build_function_call_nary (location,
+					      objc_setProperty_decl,
+					      self_decl, /* self */
+					      cmd,       /* _cmd */
+					      offset,    /* offset */
+					      new_value, /* new_value */
+					      is_atomic, /* is_atomic */
+					      should_copy, /* should_copy */
+					      NULL_TREE);
       }
       break;
     case OBJC_PROPERTY_ASSIGN:
@@ -7700,6 +7685,7 @@ objc_synthesize_setter (tree klass, tree class_methods ATTRIBUTE_UNUSED, tree pr
 	     For the NeXT runtime, we need to use objc_copyStruct
 	     instead of objc_getPropertyStruct.  */
 	  tree function_decl, size_of, is_atomic;
+	  tree property_ivar_name;
 
 	  /* sizeof (ivar type).  Since the ivar and the property have
 	     the same type, there is no need to lookup the ivar.  */
@@ -7717,25 +7703,26 @@ objc_synthesize_setter (tree klass, tree class_methods ATTRIBUTE_UNUSED, tree pr
 	  else
 	    function_decl = objc_setPropertyStruct_decl;
 
-	  statement = build_function_call
-	    (location,
-	     /* Function prototype.  */
-	     function_decl,
-	     /* Parameters.  */
-	     tree_cons /* &(self->PROPERTY_IVAR_NAME); */
-	     (NULL_TREE, build_fold_addr_expr_loc (location,
-						   objc_lookup_ivar
-						   (NULL_TREE, PROPERTY_IVAR_NAME (property))),
-	      tree_cons /* &new_value */
-	      (NULL_TREE, build_fold_addr_expr_loc (location, new_value),
-	       tree_cons /* sizeof (PROPERTY_IVAR) */
-	       (NULL_TREE, size_of,
-		tree_cons /* is_atomic */
-		(NULL_TREE, is_atomic,
-		 /* TODO: This is currently ignored by the GNU
-		    runtime, but what about the next one ? */
-		 tree_cons /* has_strong */
-		 (NULL_TREE, boolean_true_node, NULL_TREE))))));
+	  property_ivar_name = PROPERTY_IVAR_NAME (property);
+	  property_ivar_name =
+	    build_fold_addr_expr_loc
+	    (location, objc_lookup_ivar (NULL_TREE, property_ivar_name));
+	  statement = (build_function_call_nary
+		       (location, function_decl,
+			/* &(self->PROPERTY_IVAR_NAME) */
+			property_ivar_name,
+			/* &new_value */
+			build_fold_addr_expr_loc (location, new_value),
+			/* sizeof (PROPERTY_IVAR) */
+			size_of,
+			/* is_atomic */
+			is_atomic,
+			/* TODO: This is currently ignored by the
+			   GNU runtime, but what about the next
+			   one?  */
+			/* has strong */
+			boolean_true_node,
+			NULL_TREE));
 	}
       break;
     default:
@@ -10146,9 +10133,9 @@ objc_finish_foreach_loop (location_t location, tree object_expression, tree coll
 				     RO_UNARY_STAR), 1)),
 	       false, NULL),
 	      /* Then block.  */
-	      build_function_call (input_location,
-				   objc_enumeration_mutation_decl,
-				   tree_cons (NULL, collection_expression, NULL)),
+	      build_function_call_nary (input_location,
+					objc_enumeration_mutation_decl,
+					collection_expression, NULL_TREE),
 	      /* Else block.  */
 	      NULL_TREE);
   SET_EXPR_LOCATION (t, location);
diff --git a/gcc/objc/objc-gnu-runtime-abi-01.c b/gcc/objc/objc-gnu-runtime-abi-01.c
index d21f2e9..65f585a 100644
--- a/gcc/objc/objc-gnu-runtime-abi-01.c
+++ b/gcc/objc/objc-gnu-runtime-abi-01.c
@@ -565,17 +565,17 @@ gnu_runtime_abi_01_string_decl (tree type, const char *name,
 static tree
 gnu_runtime_abi_01_get_class_reference (tree ident)
 {
-  tree params;
+  tree t;
 
   add_class_reference (ident);
 
-  params = build_tree_list (NULL_TREE, my_build_string_pointer
-						(IDENTIFIER_LENGTH (ident) + 1,
-						 IDENTIFIER_POINTER (ident)));
+  t = my_build_string_pointer (IDENTIFIER_LENGTH (ident) + 1,
+			       IDENTIFIER_POINTER (ident));
 
   /* FIXME: Do we need this assemble_external() ? */
   /* assemble_external (objc_get_class_decl);*/
-  return build_function_call (input_location, objc_get_class_decl, params);
+  return build_function_call_nary (input_location,
+				   objc_get_class_decl, t, NULL_TREE);
 }
 
 /* Used by build_function_type_for_method.  Append the types for
@@ -664,7 +664,6 @@ build_objc_method_call (location_t loc, int super_flag, tree method_prototype,
 							 : umsg_decl));
   tree rcv_p = (super_flag ? objc_super_type : objc_object_type);
   VEC(tree, gc) *parms;
-  VEC(tree, gc) *tv;
   unsigned nparm = (method_params ? list_length (method_params) : 0);
 
   /* If a prototype for the method to be called exists, then cast
@@ -694,14 +693,11 @@ build_objc_method_call (location_t loc, int super_flag, tree method_prototype,
 
   /* Param list + 2 slots for object and selector.  */
   parms = VEC_alloc (tree, gc, nparm + 2);
-  tv = VEC_alloc (tree, gc, 2);
 
   /* First, call the lookup function to get a pointer to the method,
      then cast the pointer, then call it with the method arguments.  */
-  VEC_quick_push (tree, tv, lookup_object);
-  VEC_quick_push (tree, tv, selector);
-  method = build_function_call_vec (loc, sender, tv, NULL);
-  VEC_free (tree, gc, tv);
+  method = build_function_call_nary (loc, sender,
+				     lookup_object, selector, NULL_TREE);
 
   /* Pass the appropriate object to the method.  */
   VEC_quick_push (tree, parms, (super_flag ? self_decl : lookup_object));
@@ -843,9 +839,9 @@ gnu_runtime_abi_01_get_category_super_ref (location_t loc ATTRIBUTE_UNUSED,
   super_name = my_build_string_pointer (IDENTIFIER_LENGTH (super_name) + 1,
 					IDENTIFIER_POINTER (super_name));
   /* super_class = get_{meta_}class("CLASS_SUPER_NAME");  */
-  return build_function_call (input_location,
-			      super_class,
-			      build_tree_list (NULL_TREE, super_name));
+  return build_function_call_nary (input_location,
+				   super_class,
+				   super_name, NULL_TREE);
 }
 
 static bool
@@ -952,13 +948,12 @@ build_module_initializer_routine (void)
 		       NULL_TREE, objc_get_parm_info (0, NULL_TREE));
 #endif
   body = c_begin_compound_stmt (true);
-  add_stmt (build_function_call
+  add_stmt (build_function_call_nary
 	    (input_location,
 	     execclass_decl,
-	     build_tree_list
-	     (NULL_TREE,
-	      build_unary_op (input_location, ADDR_EXPR,
-			      UOBJC_MODULES_decl, 0))));
+	     build_unary_op (input_location, ADDR_EXPR,
+			     UOBJC_MODULES_decl, 0),
+	     NULL_TREE));
   add_stmt (c_end_compound_stmt (input_location, body, true));
 
   TREE_PUBLIC (current_function_decl) = 0;
@@ -993,8 +988,8 @@ tree
 objc_generate_static_init_call (tree ctors ATTRIBUTE_UNUSED)
 {
   add_stmt (build_stmt (input_location, EXPR_STMT,
-			build_function_call (input_location,
-					     GNU_INIT_decl, NULL_TREE)));
+			build_function_call_nary (input_location,
+						  GNU_INIT_decl, NULL_TREE)));
 
   return ctors;
 }
@@ -2209,13 +2204,8 @@ objc_eh_personality (void)
 static tree
 build_throw_stmt (location_t loc, tree throw_expr, bool rethrown ATTRIBUTE_UNUSED)
 {
-  tree t;
-  VEC(tree, gc) *parms = VEC_alloc (tree, gc, 1);
-  /* A throw is just a call to the runtime throw function with the
-     object as a parameter.  */
-  VEC_quick_push (tree, parms, throw_expr);
-  t = build_function_call_vec (loc, objc_exception_throw_decl, parms, NULL);
-  VEC_free (tree, gc, parms);
+  tree t = build_function_call_nary (loc, objc_exception_throw_decl,
+				     throw_expr, NULL_TREE);
   return add_stmt (t);
 }
 
diff --git a/gcc/objc/objc-next-runtime-abi-01.c b/gcc/objc/objc-next-runtime-abi-01.c
index d5b795f..eb3accf 100644
--- a/gcc/objc/objc-next-runtime-abi-01.c
+++ b/gcc/objc/objc-next-runtime-abi-01.c
@@ -709,16 +709,15 @@ next_runtime_abi_01_get_class_reference (tree ident)
     }
   else
     {
-      tree params;
+      tree t;
 
       add_class_reference (ident);
 
-      params = build_tree_list (NULL_TREE,
-				my_build_string_pointer
-				(IDENTIFIER_LENGTH (ident) + 1,
-				 IDENTIFIER_POINTER (ident)));
+      t = my_build_string_pointer (IDENTIFIER_LENGTH (ident) + 1,
+				   IDENTIFIER_POINTER (ident));
 
-      return build_function_call (input_location, objc_get_class_decl, params);
+      return build_function_call_nary (input_location, objc_get_class_decl,
+				       t, NULL_TREE);
     }
 }
 
@@ -980,9 +979,9 @@ next_runtime_abi_01_get_category_super_ref (location_t loc ATTRIBUTE_UNUSED,
   super_name = my_build_string_pointer (IDENTIFIER_LENGTH (super_name) + 1,
 					IDENTIFIER_POINTER (super_name));
   /* super_class = objc_get{Meta}Class("CLASS_SUPER_NAME"); */
-  return build_function_call (input_location,
-			      super_class,
-			      build_tree_list (NULL_TREE, super_name));
+  return build_function_call_nary (input_location,
+				   super_class,
+				   super_name, NULL_TREE);
 }
 
 static bool
@@ -2553,10 +2552,9 @@ next_sjlj_build_try_exit (struct objc_try_context **ctcp)
 {
   tree t;
   t = build_fold_addr_expr_loc (input_location, (*ctcp)->stack_decl);
-  t = tree_cons (NULL, t, NULL);
-  t = build_function_call (input_location,
-			   objc_exception_try_exit_decl, t);
-  return t;
+  return build_function_call_nary (input_location,
+				   objc_exception_try_exit_decl,
+				   t, NULL_TREE);
 }
 
 /* Build
@@ -2574,9 +2572,9 @@ next_sjlj_build_enter_and_setjmp (struct objc_try_context **ctcp)
   tree t, enter, sj, cond;
 
   t = build_fold_addr_expr_loc (input_location, (*ctcp)->stack_decl);
-  t = tree_cons (NULL, t, NULL);
-  enter = build_function_call (input_location,
-			       objc_exception_try_enter_decl, t);
+  enter = build_function_call_nary (input_location,
+				    objc_exception_try_enter_decl,
+				    t, NULL_TREE);
 
   t = objc_build_component_ref ((*ctcp)->stack_decl,
 				get_identifier ("buf"));
@@ -2590,9 +2588,8 @@ next_sjlj_build_enter_and_setjmp (struct objc_try_context **ctcp)
 #else
   t = convert (ptr_type_node, t);
 #endif
-  t = tree_cons (NULL, t, NULL);
-  sj = build_function_call (input_location,
-			    objc_setjmp_decl, t);
+  sj = build_function_call_nary (input_location,
+				 objc_setjmp_decl, t, NULL_TREE);
 
   cond = build2 (COMPOUND_EXPR, TREE_TYPE (sj), enter, sj);
   cond = c_common_truthvalue_conversion (input_location, cond);
@@ -2610,9 +2607,8 @@ next_sjlj_build_exc_extract (struct objc_try_context **ctcp, tree decl)
   tree t;
 
   t = build_fold_addr_expr_loc (input_location, (*ctcp)->stack_decl);
-  t = tree_cons (NULL, t, NULL);
-  t = build_function_call (input_location,
-			   objc_exception_extract_decl, t);
+  t = build_function_call_nary (input_location,
+				objc_exception_extract_decl, t, NULL_TREE);
   t = convert (TREE_TYPE (decl), t);
   t = build2 (MODIFY_EXPR, void_type_node, decl, t);
 
@@ -2654,17 +2650,17 @@ next_sjlj_build_catch_list (struct objc_try_context **ctcp)
 	}
       else
 	{
-	  tree args, cond;
+	  tree cond;
 
 	  if (type == error_mark_node)
 	    cond = error_mark_node;
 	  else
 	    {
-	      args = tree_cons (NULL, (*ctcp)->caught_decl, NULL);
 	      t = objc_get_class_reference (OBJC_TYPE_NAME (TREE_TYPE (type)));
-	      args = tree_cons (NULL, t, args);
-	      t = build_function_call (input_location,
-				       objc_exception_match_decl, args);
+	      t = build_function_call_nary (input_location,
+					    objc_exception_match_decl,
+					    t, (*ctcp)->caught_decl,
+					    NULL_TREE);
 	      cond = c_common_truthvalue_conversion (input_location, t);
 	    }
 	  t = build3 (COND_EXPR, void_type_node, cond, body, NULL);
@@ -2797,9 +2793,9 @@ next_sjlj_build_try_catch_finally (struct objc_try_context **ctcp)
   append_to_statement_list (cur_try_context->finally_body,
 			    &TREE_OPERAND (try_fin, 1));
 
-  t = tree_cons (NULL, rethrow_decl, NULL);
-  t = build_function_call (input_location,
-			   objc_exception_throw_decl, t);
+  t = build_function_call_nary (input_location,
+				objc_exception_throw_decl,
+				rethrow_decl, NULL_TREE);
   t = build_stmt (input_location, COND_EXPR,
 		  c_common_truthvalue_conversion (input_location,
 						  rethrow_decl),
@@ -2889,12 +2885,10 @@ static tree
 build_throw_stmt (location_t loc, tree throw_expr, bool rethrown ATTRIBUTE_UNUSED)
 {
   tree t;
-  VEC(tree, gc) *parms = VEC_alloc (tree, gc, 1);
   /* A throw is just a call to the runtime throw function with the
      object as a parameter.  */
-  VEC_quick_push (tree, parms, throw_expr);
-  t = build_function_call_vec (loc, objc_exception_throw_decl, parms, NULL);
-  VEC_free (tree, gc, parms);
+  t = build_function_call_nary (loc, objc_exception_throw_decl,
+				throw_expr, NULL_TREE);
   return add_stmt (t);
 }
 
diff --git a/gcc/objc/objc-next-runtime-abi-02.c b/gcc/objc/objc-next-runtime-abi-02.c
index fd9bb99..ed17812 100644
--- a/gcc/objc/objc-next-runtime-abi-02.c
+++ b/gcc/objc/objc-next-runtime-abi-02.c
@@ -1084,18 +1084,14 @@ next_runtime_abi_02_get_class_reference (tree ident)
   else
     {
       /* We fall back to using objc_getClass ().  */
-      VEC(tree,gc) *vec =  VEC_alloc (tree, gc, 1);
       tree t;
       /* ??? add_class_reference (ident); - is pointless, since the
          system lib does not export the equivalent symbols.  Maybe we
          need to build a class ref anyway.  */
       t = my_build_string_pointer (IDENTIFIER_LENGTH (ident) + 1,
 				   IDENTIFIER_POINTER (ident));
-      VEC_quick_push (tree, vec, t);
-      t = build_function_call_vec (input_location, objc_get_class_decl,
-				   vec, NULL);
-      VEC_free (tree, gc, vec);
-      return t;
+      return build_function_call_nary (input_location, objc_get_class_decl,
+				       t, NULL_TREE);
     }
 }
 
@@ -1518,9 +1514,9 @@ next_runtime_abi_02_get_category_super_ref (location_t loc ATTRIBUTE_UNUSED,
   super_name = my_build_string_pointer (IDENTIFIER_LENGTH (super_name) + 1,
 					IDENTIFIER_POINTER (super_name));
   /* super_class = objc_get{Meta}Class("CLASS_SUPER_NAME"); */
-  return build_function_call (input_location,
-			      super_class,
-			      build_tree_list (NULL_TREE, super_name));
+  return build_function_call_nary (input_location,
+				   super_class,
+				   super_name, NULL_TREE);
 }
 
 static tree
@@ -1584,6 +1580,8 @@ build_v2_build_objc_method_call (int super_flag, tree method_prototype,
 {
   tree ret_val;
   tree sender, rcv_p, t;
+  VEC(tree, gc) *parms;
+  unsigned nparm = (method_params ? list_length (method_params) : 0);
   tree ret_type
     = (method_prototype
        ? TREE_VALUE (TREE_TYPE (method_prototype))
@@ -1615,14 +1613,21 @@ build_v2_build_objc_method_call (int super_flag, tree method_prototype,
 
   lookup_object = build_c_cast (input_location, rcv_p, lookup_object);
 
+  parms = make_tree_vector ();
+
   /* Use SAVE_EXPR to avoid evaluating the receiver twice.  */
   lookup_object = save_expr (lookup_object);
 
-  method_params = tree_cons (NULL_TREE, lookup_object,
-                             tree_cons (NULL_TREE, selector,
-                                        method_params));
+  VEC_safe_push (tree, gc, parms, lookup_object);
+  VEC_safe_push (tree, gc, parms, selector);
+  /* Now append the remainder of the parms.  */
+  if (nparm)
+    for (; method_params; method_params = TREE_CHAIN (method_params))
+      VEC_quick_push (tree, parms, TREE_VALUE (method_params));
+
   t = build3 (OBJ_TYPE_REF, sender_cast, sender, lookup_object, size_zero_node);
-  ret_val =  build_function_call (input_location, t, method_params);
+  ret_val =  build_function_call_vec (input_location, t, parms, NULL);
+  release_tree_vector (parms);
   if (check_for_nil)
     {
       /* receiver != nil ? ret_val : 0 */
@@ -3670,15 +3675,12 @@ build_throw_stmt (location_t loc, tree throw_expr, bool rethrown)
   tree t;
   if (rethrown)
     /* We have a separate re-throw entry.  */
-    t = build_function_call_vec (loc, objc_rethrow_exception_decl, NULL, NULL);
+    t = build_function_call_nary (loc, objc_rethrow_exception_decl,
+				  NULL_TREE);
   else
-    {
-      /* Throw like the others...  */
-      VEC(tree, gc) *parms = VEC_alloc (tree, gc, 1);
-      VEC_quick_push (tree, parms, throw_expr);
-      t = build_function_call_vec (loc, objc_exception_throw_decl, parms, NULL);
-      VEC_free (tree, gc, parms);
-    }
+    /* Throw like the others...  */
+    t = build_function_call_nary (loc, objc_exception_throw_decl,
+				  throw_expr, NULL_TREE);
   return add_stmt (t);
 }
 
@@ -3713,8 +3715,8 @@ static tree begin_catch (struct objc_try_context **cur_try_context, tree type,
   if (type && type != error_mark_node)
     {
       t = build1(NOP_EXPR, ptr_type_node, t);
-      t = build_function_call (input_location, objc2_begin_catch_decl,
-			      tree_cons (NULL_TREE, t, NULL_TREE));
+      t = build_function_call_nary (input_location, objc2_begin_catch_decl,
+				    t, NULL_TREE);
 
       /* We might want to build a catch object for this (if it's not
 	 id).  */
@@ -3755,7 +3757,7 @@ finish_catch (struct objc_try_context **cur_try_context, tree curr_catch)
 
   /* Pick up the new context we made in begin_try above...  */
   ct = *cur_try_context;
-  func = build_function_call_vec (loc, objc2_end_catch_decl, NULL, NULL);
+  func = build_function_call_nary (loc, objc2_end_catch_decl, NULL_TREE);
   append_to_statement_list (func, &ct->finally_body);
   try_exp = build_stmt (loc, TRY_FINALLY_EXPR, ct->try_body, ct->finally_body);
   *cur_try_context = ct->outer;



More information about the Gcc-patches mailing list