OSDN Git Service

./:
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 21 May 2009 05:58:39 +0000 (05:58 +0000)
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 21 May 2009 05:58:39 +0000 (05:58 +0000)
* tree.c (build_tree_list_vec_stat): New function.
(ctor_to_vec): New function.
(build_nt_call_vec): New function.
(build_call_array): Change args to be a const pointer.
(build_call_vec): New function.
* tree.h (build_nt_call_vec): Declare.
(build_tree_list_vec_stat): Declare.
(build_tree_list_vec): Define.
(build_call_array): Update declaration.
(build_call_vec): Declare.
(ctor_to_vec): Declare.
* c-common.c (tree_vector_cache): New static variable.
(make_tree_vector): New function.
(release_tree_vector): New function.
(make_tree_vector_single): New function.
(make_tree_vector_copy): New function.
* c-common.h (tree_vector_cache, make_tree_vector): Declare.
(make_tree_vector_single, make_tree_vector_copy): Declare.
* c-parser.c (cached_expr_list_1, cached_expr_list_2): Remove.
(c_parser_expr_list): Don't manage cache here, instead call
make_tree_vector.
(c_parser_release_expr_list): Remove static function.
(c_parser_vec_to_tree_list): Remove static function.
(c_parser_attributes): Call build_tree_list_vec instead of
c_parser_vec_to_tree_list.  Call release_tree_vector instead of
c_parser_release_expr_list.
(c_parser_postfix_expression_after_primary): Likewise.
(c_parser_objc_keywordexpr): Likewise.
cp/:
* parser.c (cp_parser_postfix_expression): Change args to a vec.
Release it when done.
(tree_vector): Define typedef.  Define VEC functions.
(cp_parser_parenthesized_expression_list): Change return type to
vec.  Change all callers.
(cp_parser_new_expression): Change placement and initializer to
vecs.  Release them when done.
(cp_parser_new_placement): Change return type to vec.  Change all
callers.
(cp_parser_new_initializer): Likewise.
* typeck.c (build_function_call_vec): Just call
cp_build_function_call_vec.
(cp_build_function_call): Just build a vec and call
cp_build_function_call_vec.
(cp_build_function_call_vec): New function based on old
cp_build_function_call.
(convert_arguments): Remove nargs and argarray parameters.  Change
values to a vec.  Change caller.
(build_x_compound_expr_from_vec): New function.
(cp_build_modify_expr): Build vec to pass to
build_special_member_call.
* call.c (struct z_candidate): Add first_arg field.  Change args
field to vec.
(convert_class_to_reference): Handle first argument separately.
(add_candidate): Add first_arg parameter.  Change args parameter
to vec.  Change all callers.
(add_function_candidate, add_conv_candidate): Likewise.
(add_template_candidate_real, add_template_candidate): Likewise.
(add_template_conv_candidate): Likewise.
(build_user_type_conversion_1): Handle first argument separately.
(resolve_args): Change return type and parameter type to vecs.
Change all callers.
(perform_overload_resolution): Change args parameter to vec.
Change all callers.
(build_new_function_call, build_operator_new_call): Likewise.
(add_candidates): Likewise.
(build_op_call): New globally visible function, built from and
replacing static function build_object_call.
(build_new_op): Don't handle CALL_EXPR.  Build vec, not tree_list,
of arguments.
(build_op_delete_call): Build vec to pass to
cp_build_function_call_vec.
(build_temp): Build vec to pass to build_special_member_call.
(convert_like_real): Likewise.
(perform_direct_initialization_if_possible): Likewise.
(build_over_call): Handle first_arg field.  Use build_call_array
rather than build_call_list.
(build_special_member_call): Change args parameter to vec.  Change
all callers.
(build_new_method_call): Likewise.
* init.c (expand_default_init): Change parms to vec.
(build_raw_new_expr): Change placement and init to vecs.  Change
all callers.
(build_new_1, build_new): Likewise.
* class.c (resolve_address_of_overloaded_function): Build array to
pass to fn_type_unification.
* pt.c (tsubst_copy_and_build): For NEW_EXPR build vecs to pass to
build_new.  For CALL_EXPR create a vec rather than a tree_list;
expand a pack if necessary.
(fn_type_unification): Change args parameter to const tree *.  Add
nargs parameter.  Change all callers.
(type_unification_real): Likewise.
(unify): Build array to pass to type_unification_real.
(get_bindings): Build array to pass to fn_type_unification.
(any_type_dependent_arguments_p): Change args parameter to a vec.
Change all callers.
(make_args_non_dependent): Renamed from build_non_dependent_args.
Change return type to void.  Change parameter type to vec.  Change
all callers.
(do_auto_deduction): Pass an array to type_unification_real.
* semantics.c (perform_koenig_lookup): Change args to vec.  Change
all callers.
(finish_call_expr): Change args to vec.  Change all callers.  Call
build_op_call instead of passing CALL_EXPR to build_new_op.
(cxx_omp_create_clause_info): Allocate vec to pass to
build_special_member_call.
* decl2.c (build_offset_ref_call_from_tree): Change args parameter
to vec.  Change all callers.
* name-lookup.c (lookup_function_nonclass): Likewise.
(struct arg_lookup): Change args to vec.
(arg_assoc_namespace): Handle args as a vec.
(arg_assoc_args_vec): New static function.
(lookup_arg_dependent): Change args parameter to vec.  Change all
callers.
* method.c (do_build_assign_ref): Allocate vec to pass to
build_special_member_call.
* except.c (build_throw): Likewise.
* typeck2.c (build_functional_cast): Likewise.
* cvt.c (ocp_convert): Likewise.
* tree.c (build_min_non_dep_call_vec): Change last parameter to
vec.  Change all callers.
* cp-tree.h: Update declarations.
* name-lookup.h: Update declarations.
objc/:
* objc-act.c (objc_generate_cxx_ctor_or_dtor): Pass NULL rather
than NULL_TREE to build_special_member_call.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@147759 138bc75d-0d04-0410-961f-82ee72b054a4

25 files changed:
gcc/ChangeLog
gcc/c-common.c
gcc/c-common.h
gcc/c-parser.c
gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/cvt.c
gcc/cp/decl2.c
gcc/cp/except.c
gcc/cp/init.c
gcc/cp/method.c
gcc/cp/name-lookup.c
gcc/cp/name-lookup.h
gcc/cp/parser.c
gcc/cp/pt.c
gcc/cp/semantics.c
gcc/cp/tree.c
gcc/cp/typeck.c
gcc/cp/typeck2.c
gcc/objc/ChangeLog
gcc/objc/objc-act.c
gcc/tree.c
gcc/tree.h

index b5afced..08543b8 100644 (file)
@@ -1,3 +1,34 @@
+2009-05-20  Ian Lance Taylor  <iant@google.com>
+
+       * tree.c (build_tree_list_vec_stat): New function.
+       (ctor_to_vec): New function.
+       (build_nt_call_vec): New function.
+       (build_call_array): Change args to be a const pointer.
+       (build_call_vec): New function.
+       * tree.h (build_nt_call_vec): Declare.
+       (build_tree_list_vec_stat): Declare.
+       (build_tree_list_vec): Define.
+       (build_call_array): Update declaration.
+       (build_call_vec): Declare.
+       (ctor_to_vec): Declare.
+       * c-common.c (tree_vector_cache): New static variable.
+       (make_tree_vector): New function.
+       (release_tree_vector): New function.
+       (make_tree_vector_single): New function.
+       (make_tree_vector_copy): New function.
+       * c-common.h (tree_vector_cache, make_tree_vector): Declare.
+       (make_tree_vector_single, make_tree_vector_copy): Declare.
+       * c-parser.c (cached_expr_list_1, cached_expr_list_2): Remove.
+       (c_parser_expr_list): Don't manage cache here, instead call
+       make_tree_vector.
+       (c_parser_release_expr_list): Remove static function.
+       (c_parser_vec_to_tree_list): Remove static function.
+       (c_parser_attributes): Call build_tree_list_vec instead of
+       c_parser_vec_to_tree_list.  Call release_tree_vector instead of
+       c_parser_release_expr_list.
+       (c_parser_postfix_expression_after_primary): Likewise.
+       (c_parser_objc_keywordexpr): Likewise.
+
 2009-05-20  Sandra Loosemore  <sandra@codesourcery.com>
 
        * doc/tm.texi (Misc): Document TARGET_INVALID_PARAMETER_TYPE,
 2009-05-20  Sandra Loosemore  <sandra@codesourcery.com>
 
        * doc/tm.texi (Misc): Document TARGET_INVALID_PARAMETER_TYPE,
index 46aacb5..45b4192 100644 (file)
@@ -9132,4 +9132,69 @@ is_typedef_decl (tree x)
           && DECL_ORIGINAL_TYPE (x) != NULL_TREE);
 }
 
           && DECL_ORIGINAL_TYPE (x) != NULL_TREE);
 }
 
+/* The C and C++ parsers both use vectors to hold function arguments.
+   For efficiency, we keep a cache of unused vectors.  This is the
+   cache.  */
+
+typedef VEC(tree,gc)* tree_gc_vec;
+DEF_VEC_P(tree_gc_vec);
+DEF_VEC_ALLOC_P(tree_gc_vec,gc);
+static GTY((deletable)) VEC(tree_gc_vec,gc) *tree_vector_cache;
+
+/* Return a new vector from the cache.  If the cache is empty,
+   allocate a new vector.  These vectors are GC'ed, so it is OK if the
+   pointer is not released..  */
+
+VEC(tree,gc) *
+make_tree_vector (void)
+{
+  if (!VEC_empty (tree_gc_vec, tree_vector_cache))
+    return VEC_pop (tree_gc_vec, tree_vector_cache);
+  else
+    {
+      /* Passing 0 to VEC_alloc returns NULL, and our callers require
+        that we always return a non-NULL value.  The vector code uses
+        4 when growing a NULL vector, so we do too.  */
+      return VEC_alloc (tree, gc, 4);
+    }
+}
+
+/* Release a vector of trees back to the cache.  */
+
+void
+release_tree_vector (VEC(tree,gc) *vec)
+{
+  if (vec != NULL)
+    {
+      VEC_truncate (tree, vec, 0);
+      VEC_safe_push (tree_gc_vec, gc, tree_vector_cache, vec);
+    }
+}
+
+/* Get a new tree vector holding a single tree.  */
+
+VEC(tree,gc) *
+make_tree_vector_single (tree t)
+{
+  VEC(tree,gc) *ret = make_tree_vector ();
+  VEC_quick_push (tree, ret, t);
+  return ret;
+}
+
+/* Get a new tree vector which is a copy of an existing one.  */
+
+VEC(tree,gc) *
+make_tree_vector_copy (const VEC(tree,gc) *orig)
+{
+  VEC(tree,gc) *ret;
+  unsigned int ix;
+  tree t;
+
+  ret = make_tree_vector ();
+  VEC_reserve (tree, gc, ret, VEC_length (tree, orig));
+  for (ix = 0; VEC_iterate (tree, orig, ix, t); ++ix)
+    VEC_quick_push (tree, ret, t);
+  return ret;
+}
+
 #include "gt-c-common.h"
 #include "gt-c-common.h"
index c4fba4d..b17020a 100644 (file)
@@ -1013,6 +1013,10 @@ extern void warn_for_sign_compare (location_t,
                                   enum tree_code resultcode);
 extern void set_underlying_type (tree x);
 extern bool is_typedef_decl (tree x);
                                   enum tree_code resultcode);
 extern void set_underlying_type (tree x);
 extern bool is_typedef_decl (tree x);
+extern VEC(tree,gc) *make_tree_vector (void);
+extern void release_tree_vector (VEC(tree,gc) *);
+extern VEC(tree,gc) *make_tree_vector_single (tree);
+extern VEC(tree,gc) *make_tree_vector_copy (const VEC(tree,gc) *);
 
 /* In c-gimplify.c  */
 extern void c_genericize (tree);
 
 /* In c-gimplify.c  */
 extern void c_genericize (tree);
index beda817..0320fee 100644 (file)
@@ -921,8 +921,6 @@ static struct c_expr c_parser_expression (c_parser *);
 static struct c_expr c_parser_expression_conv (c_parser *);
 static VEC(tree,gc) *c_parser_expr_list (c_parser *, bool, bool,
                                         VEC(tree,gc) **);
 static struct c_expr c_parser_expression_conv (c_parser *);
 static VEC(tree,gc) *c_parser_expr_list (c_parser *, bool, bool,
                                         VEC(tree,gc) **);
-static void c_parser_release_expr_list (VEC(tree,gc) *);
-static tree c_parser_vec_to_tree_list (VEC(tree,gc) *);
 static void c_parser_omp_construct (c_parser *);
 static void c_parser_omp_threadprivate (c_parser *);
 static void c_parser_omp_barrier (c_parser *);
 static void c_parser_omp_construct (c_parser *);
 static void c_parser_omp_threadprivate (c_parser *);
 static void c_parser_omp_barrier (c_parser *);
@@ -2889,9 +2887,9 @@ c_parser_attributes (c_parser *parser)
                  tree tree_list;
                  c_parser_consume_token (parser);
                  expr_list = c_parser_expr_list (parser, false, true, NULL);
                  tree tree_list;
                  c_parser_consume_token (parser);
                  expr_list = c_parser_expr_list (parser, false, true, NULL);
-                 tree_list = c_parser_vec_to_tree_list (expr_list);
+                 tree_list = build_tree_list_vec (expr_list);
                  attr_args = tree_cons (NULL_TREE, arg1, tree_list);
                  attr_args = tree_cons (NULL_TREE, arg1, tree_list);
-                 c_parser_release_expr_list (expr_list);
+                 release_tree_vector (expr_list);
                }
            }
          else
                }
            }
          else
@@ -2901,8 +2899,8 @@ c_parser_attributes (c_parser *parser)
              else
                {
                  expr_list = c_parser_expr_list (parser, false, true, NULL);
              else
                {
                  expr_list = c_parser_expr_list (parser, false, true, NULL);
-                 attr_args = c_parser_vec_to_tree_list (expr_list);
-                 c_parser_release_expr_list (expr_list);
+                 attr_args = build_tree_list_vec (expr_list);
+                 release_tree_vector (expr_list);
                }
            }
          attr = build_tree_list (attr_name, attr_args);
                }
            }
          attr = build_tree_list (attr_name, attr_args);
@@ -5719,8 +5717,8 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
          expr.original_type = NULL;
          if (exprlist != NULL)
            {
          expr.original_type = NULL;
          if (exprlist != NULL)
            {
-             c_parser_release_expr_list (exprlist);
-             c_parser_release_expr_list (origtypes);
+             release_tree_vector (exprlist);
+             release_tree_vector (origtypes);
            }
          break;
        case CPP_DOT:
            }
          break;
        case CPP_DOT:
@@ -5853,10 +5851,6 @@ c_parser_expression_conv (c_parser *parser)
      nonempty-expr-list , assignment-expression
 */
 
      nonempty-expr-list , assignment-expression
 */
 
-/* We cache two vectors, to save most allocation and deallocation.  */
-static GTY((deletable)) VEC(tree,gc) *cached_expr_list_1;
-static GTY((deletable)) VEC(tree,gc) *cached_expr_list_2;
-
 static VEC(tree,gc) *
 c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p,
                    VEC(tree,gc) **p_orig_types)
 static VEC(tree,gc) *
 c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p,
                    VEC(tree,gc) **p_orig_types)
@@ -5865,34 +5859,11 @@ c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p,
   VEC(tree,gc) *orig_types;
   struct c_expr expr;
 
   VEC(tree,gc) *orig_types;
   struct c_expr expr;
 
-  if (cached_expr_list_1 != NULL)
-    {
-      ret = cached_expr_list_1;
-      cached_expr_list_1 = NULL;
-      VEC_truncate (tree, ret, 0);
-    }
-  else if (cached_expr_list_2 != NULL)
-    {
-      ret = cached_expr_list_2;
-      cached_expr_list_2 = NULL;
-      VEC_truncate (tree, ret, 0);
-    }
-  else
-    ret = VEC_alloc (tree, gc, 16);
-
+  ret = make_tree_vector ();
   if (p_orig_types == NULL)
     orig_types = NULL;
   else
   if (p_orig_types == NULL)
     orig_types = NULL;
   else
-    {
-      if (cached_expr_list_2 != NULL)
-       {
-         orig_types = cached_expr_list_2;
-         cached_expr_list_2 = NULL;
-         VEC_truncate (tree, orig_types, 0);
-       }
-      else
-       orig_types = VEC_alloc (tree, gc, 16);
-    }
+    orig_types = make_tree_vector ();
 
   expr = c_parser_expr_no_commas (parser, NULL);
   if (convert_p)
 
   expr = c_parser_expr_no_commas (parser, NULL);
   if (convert_p)
@@ -5918,37 +5889,6 @@ c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p,
     *p_orig_types = orig_types;
   return ret;
 }
     *p_orig_types = orig_types;
   return ret;
 }
-
-/* Release a vector returned by c_parser_expr_list.  */
-
-static void
-c_parser_release_expr_list (VEC(tree,gc) *vec)
-{
-  if (cached_expr_list_1 == NULL)
-    cached_expr_list_1 = vec;
-  else if (cached_expr_list_2 == NULL)
-    cached_expr_list_2 = vec;
-  else
-    VEC_free (tree, gc, vec);
-}
-
-/* Convert a vector, as returned by c_parser_expr_list, to a
-   tree_list.  */
-
-static tree
-c_parser_vec_to_tree_list (VEC(tree,gc) *vec)
-{
-  tree ret = NULL_TREE;
-  tree *pp = &ret;
-  unsigned int i;
-  tree t;
-  for (i = 0; VEC_iterate (tree, vec, i, t); ++i)
-    {
-      *pp = build_tree_list (NULL, t);
-      pp = &TREE_CHAIN (*pp);
-    }
-  return ret;
-}
 \f
 /* Parse Objective-C-specific constructs.  */
 
 \f
 /* Parse Objective-C-specific constructs.  */
 
@@ -6830,9 +6770,9 @@ c_parser_objc_keywordexpr (c_parser *parser)
   else
     {
       /* We have a comma expression, we will collapse later.  */
   else
     {
       /* We have a comma expression, we will collapse later.  */
-      ret = c_parser_vec_to_tree_list (expr_list);
+      ret = build_tree_list_vec (expr_list);
     }
     }
-  c_parser_release_expr_list (expr_list);
+  release_tree_vector (expr_list);
   return ret;
 }
 
   return ret;
 }
 
index 626df30..57dcb54 100644 (file)
@@ -1,3 +1,99 @@
+2009-05-20  Ian Lance Taylor  <iant@google.com>
+
+       * parser.c (cp_parser_postfix_expression): Change args to a vec.
+       Release it when done.
+       (tree_vector): Define typedef.  Define VEC functions.
+       (cp_parser_parenthesized_expression_list): Change return type to
+       vec.  Change all callers.
+       (cp_parser_new_expression): Change placement and initializer to
+       vecs.  Release them when done.
+       (cp_parser_new_placement): Change return type to vec.  Change all
+       callers.
+       (cp_parser_new_initializer): Likewise.
+       * typeck.c (build_function_call_vec): Just call
+       cp_build_function_call_vec.
+       (cp_build_function_call): Just build a vec and call
+       cp_build_function_call_vec.
+       (cp_build_function_call_vec): New function based on old
+       cp_build_function_call.
+       (convert_arguments): Remove nargs and argarray parameters.  Change
+       values to a vec.  Change caller.
+       (build_x_compound_expr_from_vec): New function.
+       (cp_build_modify_expr): Build vec to pass to
+       build_special_member_call.
+       * call.c (struct z_candidate): Add first_arg field.  Change args
+       field to vec.
+       (convert_class_to_reference): Handle first argument separately.
+       (add_candidate): Add first_arg parameter.  Change args parameter
+       to vec.  Change all callers.
+       (add_function_candidate, add_conv_candidate): Likewise.
+       (add_template_candidate_real, add_template_candidate): Likewise.
+       (add_template_conv_candidate): Likewise.
+       (build_user_type_conversion_1): Handle first argument separately.
+       (resolve_args): Change return type and parameter type to vecs.
+       Change all callers.
+       (perform_overload_resolution): Change args parameter to vec.
+       Change all callers.
+       (build_new_function_call, build_operator_new_call): Likewise.
+       (add_candidates): Likewise.
+       (build_op_call): New globally visible function, built from and
+       replacing static function build_object_call.
+       (build_new_op): Don't handle CALL_EXPR.  Build vec, not tree_list,
+       of arguments.
+       (build_op_delete_call): Build vec to pass to
+       cp_build_function_call_vec.
+       (build_temp): Build vec to pass to build_special_member_call.
+       (convert_like_real): Likewise.
+       (perform_direct_initialization_if_possible): Likewise.
+       (build_over_call): Handle first_arg field.  Use build_call_array
+       rather than build_call_list.
+       (build_special_member_call): Change args parameter to vec.  Change
+       all callers.
+       (build_new_method_call): Likewise.
+       * init.c (expand_default_init): Change parms to vec.
+       (build_raw_new_expr): Change placement and init to vecs.  Change
+       all callers.
+       (build_new_1, build_new): Likewise.
+       * class.c (resolve_address_of_overloaded_function): Build array to
+       pass to fn_type_unification.
+       * pt.c (tsubst_copy_and_build): For NEW_EXPR build vecs to pass to
+       build_new.  For CALL_EXPR create a vec rather than a tree_list;
+       expand a pack if necessary.
+       (fn_type_unification): Change args parameter to const tree *.  Add
+       nargs parameter.  Change all callers.
+       (type_unification_real): Likewise.
+       (unify): Build array to pass to type_unification_real.
+       (get_bindings): Build array to pass to fn_type_unification.
+       (any_type_dependent_arguments_p): Change args parameter to a vec.
+       Change all callers.
+       (make_args_non_dependent): Renamed from build_non_dependent_args.
+       Change return type to void.  Change parameter type to vec.  Change
+       all callers.
+       (do_auto_deduction): Pass an array to type_unification_real.
+       * semantics.c (perform_koenig_lookup): Change args to vec.  Change
+       all callers.
+       (finish_call_expr): Change args to vec.  Change all callers.  Call
+       build_op_call instead of passing CALL_EXPR to build_new_op.
+       (cxx_omp_create_clause_info): Allocate vec to pass to
+       build_special_member_call.
+       * decl2.c (build_offset_ref_call_from_tree): Change args parameter
+       to vec.  Change all callers.
+       * name-lookup.c (lookup_function_nonclass): Likewise.
+       (struct arg_lookup): Change args to vec.
+       (arg_assoc_namespace): Handle args as a vec.
+       (arg_assoc_args_vec): New static function.
+       (lookup_arg_dependent): Change args parameter to vec.  Change all
+       callers.
+       * method.c (do_build_assign_ref): Allocate vec to pass to
+       build_special_member_call.
+       * except.c (build_throw): Likewise.
+       * typeck2.c (build_functional_cast): Likewise.
+       * cvt.c (ocp_convert): Likewise.
+       * tree.c (build_min_non_dep_call_vec): Change last parameter to
+       vec.  Change all callers.
+       * cp-tree.h: Update declarations.
+       * name-lookup.h: Update declarations.
+
 2009-05-20  Sandra Loosemore  <sandra@codesourcery.com>
 
        * typeck.c (default_conversion): Check targetm.promoted_type.
 2009-05-20  Sandra Loosemore  <sandra@codesourcery.com>
 
        * typeck.c (default_conversion): Check targetm.promoted_type.
index b33e903..0d5ae6a 100644 (file)
@@ -145,8 +145,7 @@ static tree convert_like_real (conversion *, tree, tree, int, int, bool,
                               bool, tsubst_flags_t);
 static void op_error (enum tree_code, enum tree_code, tree, tree,
                      tree, const char *);
                               bool, tsubst_flags_t);
 static void op_error (enum tree_code, enum tree_code, tree, tree,
                      tree, const char *);
-static tree build_object_call (tree, tree, tsubst_flags_t);
-static tree resolve_args (tree);
+static VEC(tree,gc) *resolve_args (VEC(tree,gc) *);
 static struct z_candidate *build_user_type_conversion_1 (tree, tree, int);
 static void print_z_candidate (const char *, struct z_candidate *);
 static void print_z_candidates (struct z_candidate *);
 static struct z_candidate *build_user_type_conversion_1 (tree, tree, int);
 static void print_z_candidate (const char *, struct z_candidate *);
 static void print_z_candidates (struct z_candidate *);
@@ -154,13 +153,14 @@ static tree build_this (tree);
 static struct z_candidate *splice_viable (struct z_candidate *, bool, bool *);
 static bool any_strictly_viable (struct z_candidate *);
 static struct z_candidate *add_template_candidate
 static struct z_candidate *splice_viable (struct z_candidate *, bool, bool *);
 static bool any_strictly_viable (struct z_candidate *);
 static struct z_candidate *add_template_candidate
-       (struct z_candidate **, tree, tree, tree, tree, tree,
-        tree, tree, int, unification_kind_t);
+       (struct z_candidate **, tree, tree, tree, tree, const VEC(tree,gc) *,
+        tree, tree, tree, int, unification_kind_t);
 static struct z_candidate *add_template_candidate_real
 static struct z_candidate *add_template_candidate_real
-       (struct z_candidate **, tree, tree, tree, tree, tree,
-        tree, tree, int, tree, unification_kind_t);
+       (struct z_candidate **, tree, tree, tree, tree, const VEC(tree,gc) *,
+        tree, tree, tree, int, tree, unification_kind_t);
 static struct z_candidate *add_template_conv_candidate
 static struct z_candidate *add_template_conv_candidate
-       (struct z_candidate **, tree, tree, tree, tree, tree, tree);
+       (struct z_candidate **, tree, tree, tree, const VEC(tree,gc) *, tree,
+        tree, tree);
 static void add_builtin_candidates
        (struct z_candidate **, enum tree_code, enum tree_code,
         tree, tree *, int);
 static void add_builtin_candidates
        (struct z_candidate **, enum tree_code, enum tree_code,
         tree, tree *, int);
@@ -172,9 +172,11 @@ static void build_builtin_candidate
        (struct z_candidate **, tree, tree, tree, tree *, tree *,
         int);
 static struct z_candidate *add_conv_candidate
        (struct z_candidate **, tree, tree, tree, tree *, tree *,
         int);
 static struct z_candidate *add_conv_candidate
-       (struct z_candidate **, tree, tree, tree, tree, tree);
+       (struct z_candidate **, tree, tree, tree, const VEC(tree,gc) *, tree,
+        tree);
 static struct z_candidate *add_function_candidate
 static struct z_candidate *add_function_candidate
-       (struct z_candidate **, tree, tree, tree, tree, tree, int);
+       (struct z_candidate **, tree, tree, tree, const VEC(tree,gc) *, tree,
+        tree, int);
 static conversion *implicit_conversion (tree, tree, tree, bool, int);
 static conversion *standard_conversion (tree, tree, tree, bool, int);
 static conversion *reference_binding (tree, tree, tree, bool, int);
 static conversion *implicit_conversion (tree, tree, tree, bool, int);
 static conversion *standard_conversion (tree, tree, tree, bool, int);
 static conversion *reference_binding (tree, tree, tree, bool, int);
@@ -184,7 +186,7 @@ static bool is_subseq (conversion *, conversion *);
 static conversion *maybe_handle_ref_bind (conversion **);
 static void maybe_handle_implicit_object (conversion **);
 static struct z_candidate *add_candidate
 static conversion *maybe_handle_ref_bind (conversion **);
 static void maybe_handle_implicit_object (conversion **);
 static struct z_candidate *add_candidate
-       (struct z_candidate **, tree, tree, size_t,
+       (struct z_candidate **, tree, tree, const VEC(tree,gc) *, size_t,
         conversion **, tree, tree, int);
 static tree source_type (conversion *);
 static void add_warning (struct z_candidate *, struct z_candidate *);
         conversion **, tree, tree, int);
 static tree source_type (conversion *);
 static void add_warning (struct z_candidate *, struct z_candidate *);
@@ -197,7 +199,7 @@ static conversion *conditional_conversion (tree, tree);
 static char *name_as_c_string (tree, tree, bool *);
 static tree call_builtin_trap (void);
 static tree prep_operand (tree);
 static char *name_as_c_string (tree, tree, bool *);
 static tree call_builtin_trap (void);
 static tree prep_operand (tree);
-static void add_candidates (tree, tree, tree, bool, tree, tree,
+static void add_candidates (tree, const VEC(tree,gc) *, tree, bool, tree, tree,
                            int, struct z_candidate **);
 static conversion *merge_conversion_sequences (conversion *, conversion *);
 static bool magic_varargs_p (tree);
                            int, struct z_candidate **);
 static conversion *merge_conversion_sequences (conversion *, conversion *);
 static bool magic_varargs_p (tree);
@@ -413,8 +415,13 @@ struct z_candidate {
   /* The FUNCTION_DECL that will be called if this candidate is
      selected by overload resolution.  */
   tree fn;
   /* The FUNCTION_DECL that will be called if this candidate is
      selected by overload resolution.  */
   tree fn;
-  /* The arguments to use when calling this function.  */
-  tree args;
+  /* If not NULL_TREE, the first argument to use when calling this
+     function.  */
+  tree first_arg;
+  /* The rest of the arguments to use when calling this function.  If
+     there are no further arguments this may be NULL or it may be an
+     empty vector.  */
+  const VEC(tree,gc) *args;
   /* The implicit conversion sequences for each of the arguments to
      FN.  */
   conversion **convs;
   /* The implicit conversion sequences for each of the arguments to
      FN.  */
   conversion **convs;
@@ -996,7 +1003,7 @@ static conversion *
 convert_class_to_reference (tree reference_type, tree s, tree expr, int flags)
 {
   tree conversions;
 convert_class_to_reference (tree reference_type, tree s, tree expr, int flags)
 {
   tree conversions;
-  tree arglist;
+  tree first_arg;
   conversion *conv;
   tree t;
   struct z_candidate *candidates;
   conversion *conv;
   tree t;
   struct z_candidate *candidates;
@@ -1029,8 +1036,7 @@ convert_class_to_reference (tree reference_type, tree s, tree expr, int flags)
      error messages, which we should not issue now because we are just
      trying to find a conversion operator.  Therefore, we use NULL,
      cast to the appropriate type.  */
      error messages, which we should not issue now because we are just
      trying to find a conversion operator.  Therefore, we use NULL,
      cast to the appropriate type.  */
-  arglist = build_int_cst (build_pointer_type (s), 0);
-  arglist = build_tree_list (NULL_TREE, arglist);
+  first_arg = build_int_cst (build_pointer_type (s), 0);
 
   t = TREE_TYPE (reference_type);
 
 
   t = TREE_TYPE (reference_type);
 
@@ -1056,7 +1062,8 @@ convert_class_to_reference (tree reference_type, tree s, tree expr, int flags)
              cand = add_template_candidate (&candidates,
                                             f, s,
                                             NULL_TREE,
              cand = add_template_candidate (&candidates,
                                             f, s,
                                             NULL_TREE,
-                                            arglist,
+                                            first_arg,
+                                            NULL,
                                             reference_type,
                                             TYPE_BINFO (s),
                                             TREE_PURPOSE (conversions),
                                             reference_type,
                                             TYPE_BINFO (s),
                                             TREE_PURPOSE (conversions),
@@ -1081,8 +1088,8 @@ convert_class_to_reference (tree reference_type, tree s, tree expr, int flags)
            }
          else if (TREE_CODE (t2) == REFERENCE_TYPE
                   && reference_compatible_p (t, TREE_TYPE (t2)))
            }
          else if (TREE_CODE (t2) == REFERENCE_TYPE
                   && reference_compatible_p (t, TREE_TYPE (t2)))
-           cand = add_function_candidate (&candidates, f, s, arglist,
-                                          TYPE_BINFO (s),
+           cand = add_function_candidate (&candidates, f, s, first_arg,
+                                          NULL, TYPE_BINFO (s),
                                           TREE_PURPOSE (conversions),
                                           LOOKUP_NORMAL);
 
                                           TREE_PURPOSE (conversions),
                                           LOOKUP_NORMAL);
 
@@ -1119,9 +1126,9 @@ convert_class_to_reference (tree reference_type, tree s, tree expr, int flags)
 
   /* Now that we know that this is the function we're going to use fix
      the dummy first argument.  */
 
   /* Now that we know that this is the function we're going to use fix
      the dummy first argument.  */
-  cand->args = tree_cons (NULL_TREE,
-                         build_this (expr),
-                         TREE_CHAIN (cand->args));
+  gcc_assert (cand->first_arg == NULL_TREE
+             || integer_zerop (cand->first_arg));
+  cand->first_arg = build_this (expr);
 
   /* Build a user-defined conversion sequence representing the
      conversion.  */
 
   /* Build a user-defined conversion sequence representing the
      conversion.  */
@@ -1424,11 +1431,12 @@ implicit_conversion (tree to, tree from, tree expr, bool c_cast_p,
 }
 
 /* Add a new entry to the list of candidates.  Used by the add_*_candidate
 }
 
 /* Add a new entry to the list of candidates.  Used by the add_*_candidate
-   functions.  */
+   functions.  ARGS will not be changed until a single candidate is
+   selected.  */
 
 static struct z_candidate *
 add_candidate (struct z_candidate **candidates,
 
 static struct z_candidate *
 add_candidate (struct z_candidate **candidates,
-              tree fn, tree args,
+              tree fn, tree first_arg, const VEC(tree,gc) *args,
               size_t num_convs, conversion **convs,
               tree access_path, tree conversion_path,
               int viable)
               size_t num_convs, conversion **convs,
               tree access_path, tree conversion_path,
               int viable)
@@ -1437,6 +1445,7 @@ add_candidate (struct z_candidate **candidates,
     conversion_obstack_alloc (sizeof (struct z_candidate));
 
   cand->fn = fn;
     conversion_obstack_alloc (sizeof (struct z_candidate));
 
   cand->fn = fn;
+  cand->first_arg = first_arg;
   cand->args = args;
   cand->convs = convs;
   cand->num_convs = num_convs;
   cand->args = args;
   cand->convs = convs;
   cand->num_convs = num_convs;
@@ -1449,24 +1458,27 @@ add_candidate (struct z_candidate **candidates,
   return cand;
 }
 
   return cand;
 }
 
-/* Create an overload candidate for the function or method FN called with
-   the argument list ARGLIST and add it to CANDIDATES.  FLAGS is passed on
-   to implicit_conversion.
+/* Create an overload candidate for the function or method FN called
+   with the argument list FIRST_ARG/ARGS and add it to CANDIDATES.
+   FLAGS is passed on to implicit_conversion.
+
+   This does not change ARGS.
 
    CTYPE, if non-NULL, is the type we want to pretend this function
    comes from for purposes of overload resolution.  */
 
 static struct z_candidate *
 add_function_candidate (struct z_candidate **candidates,
 
    CTYPE, if non-NULL, is the type we want to pretend this function
    comes from for purposes of overload resolution.  */
 
 static struct z_candidate *
 add_function_candidate (struct z_candidate **candidates,
-                       tree fn, tree ctype, tree arglist,
-                       tree access_path, tree conversion_path,
-                       int flags)
+                       tree fn, tree ctype, tree first_arg,
+                       const VEC(tree,gc) *args, tree access_path,
+                       tree conversion_path, int flags)
 {
   tree parmlist = TYPE_ARG_TYPES (TREE_TYPE (fn));
   int i, len;
   conversion **convs;
 {
   tree parmlist = TYPE_ARG_TYPES (TREE_TYPE (fn));
   int i, len;
   conversion **convs;
-  tree parmnode, argnode;
-  tree orig_arglist;
+  tree parmnode;
+  tree orig_first_arg = first_arg;
+  int skip;
   int viable = 1;
 
   /* At this point we should not see any functions which haven't been
   int viable = 1;
 
   /* At this point we should not see any functions which haven't been
@@ -1479,13 +1491,17 @@ add_function_candidate (struct z_candidate **candidates,
   if (DECL_CONSTRUCTOR_P (fn))
     {
       parmlist = skip_artificial_parms_for (fn, parmlist);
   if (DECL_CONSTRUCTOR_P (fn))
     {
       parmlist = skip_artificial_parms_for (fn, parmlist);
-      orig_arglist = arglist;
-      arglist = skip_artificial_parms_for (fn, arglist);
+      skip = num_artificial_parms_for (fn);
+      if (skip > 0 && first_arg != NULL_TREE)
+       {
+         --skip;
+         first_arg = NULL_TREE;
+       }
     }
   else
     }
   else
-    orig_arglist = arglist;
+    skip = 0;
 
 
-  len = list_length (arglist);
+  len = VEC_length (tree, args) - skip + (first_arg != NULL_TREE ? 1 : 0);
   convs = alloc_conversions (len);
 
   /* 13.3.2 - Viable functions [over.match.viable]
   convs = alloc_conversions (len);
 
   /* 13.3.2 - Viable functions [over.match.viable]
@@ -1518,18 +1534,23 @@ add_function_candidate (struct z_candidate **candidates,
      to the corresponding parameter of F.  */
 
   parmnode = parmlist;
      to the corresponding parameter of F.  */
 
   parmnode = parmlist;
-  argnode = arglist;
 
   for (i = 0; i < len; ++i)
     {
 
   for (i = 0; i < len; ++i)
     {
-      tree arg = TREE_VALUE (argnode);
-      tree argtype = lvalue_type (arg);
+      tree arg, argtype;
       conversion *t;
       int is_this;
 
       if (parmnode == void_list_node)
        break;
 
       conversion *t;
       int is_this;
 
       if (parmnode == void_list_node)
        break;
 
+      if (i == 0 && first_arg != NULL_TREE)
+       arg = first_arg;
+      else
+       arg = VEC_index (tree, args,
+                        i + skip - (first_arg != NULL_TREE ? 1 : 0));
+      argtype = lvalue_type (arg);
+
       is_this = (i == 0 && DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)
                 && ! DECL_CONSTRUCTOR_P (fn));
 
       is_this = (i == 0 && DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)
                 && ! DECL_CONSTRUCTOR_P (fn));
 
@@ -1591,18 +1612,18 @@ add_function_candidate (struct z_candidate **candidates,
 
       if (parmnode)
        parmnode = TREE_CHAIN (parmnode);
 
       if (parmnode)
        parmnode = TREE_CHAIN (parmnode);
-      argnode = TREE_CHAIN (argnode);
     }
 
  out:
     }
 
  out:
-  return add_candidate (candidates, fn, orig_arglist, len, convs,
+  return add_candidate (candidates, fn, orig_first_arg, args, len, convs,
                        access_path, conversion_path, viable);
 }
 
 /* Create an overload candidate for the conversion function FN which will
    be invoked for expression OBJ, producing a pointer-to-function which
                        access_path, conversion_path, viable);
 }
 
 /* Create an overload candidate for the conversion function FN which will
    be invoked for expression OBJ, producing a pointer-to-function which
-   will in turn be called with the argument list ARGLIST, and add it to
-   CANDIDATES.  FLAGS is passed on to implicit_conversion.
+   will in turn be called with the argument list FIRST_ARG/ARGLIST,
+   and add it to CANDIDATES.  This does not change ARGLIST.  FLAGS is
+   passed on to implicit_conversion.
 
    Actually, we don't really care about FN; we care about the type it
    converts to.  There may be multiple conversion functions that will
 
    Actually, we don't really care about FN; we care about the type it
    converts to.  There may be multiple conversion functions that will
@@ -1612,21 +1633,21 @@ add_function_candidate (struct z_candidate **candidates,
 
 static struct z_candidate *
 add_conv_candidate (struct z_candidate **candidates, tree fn, tree obj,
 
 static struct z_candidate *
 add_conv_candidate (struct z_candidate **candidates, tree fn, tree obj,
-                   tree arglist, tree access_path, tree conversion_path)
+                   tree first_arg, const VEC(tree,gc) *arglist,
+                   tree access_path, tree conversion_path)
 {
   tree totype = TREE_TYPE (TREE_TYPE (fn));
   int i, len, viable, flags;
 {
   tree totype = TREE_TYPE (TREE_TYPE (fn));
   int i, len, viable, flags;
-  tree parmlist, parmnode, argnode;
+  tree parmlist, parmnode;
   conversion **convs;
 
   for (parmlist = totype; TREE_CODE (parmlist) != FUNCTION_TYPE; )
     parmlist = TREE_TYPE (parmlist);
   parmlist = TYPE_ARG_TYPES (parmlist);
 
   conversion **convs;
 
   for (parmlist = totype; TREE_CODE (parmlist) != FUNCTION_TYPE; )
     parmlist = TREE_TYPE (parmlist);
   parmlist = TYPE_ARG_TYPES (parmlist);
 
-  len = list_length (arglist) + 1;
+  len = VEC_length (tree, arglist) + (first_arg != NULL_TREE ? 1 : 0) + 1;
   convs = alloc_conversions (len);
   parmnode = parmlist;
   convs = alloc_conversions (len);
   parmnode = parmlist;
-  argnode = arglist;
   viable = 1;
   flags = LOOKUP_IMPLICIT;
 
   viable = 1;
   flags = LOOKUP_IMPLICIT;
 
@@ -1636,11 +1657,19 @@ add_conv_candidate (struct z_candidate **candidates, tree fn, tree obj,
 
   for (i = 0; i < len; ++i)
     {
 
   for (i = 0; i < len; ++i)
     {
-      tree arg = i == 0 ? obj : TREE_VALUE (argnode);
-      tree argtype = lvalue_type (arg);
+      tree arg, argtype;
       conversion *t;
 
       if (i == 0)
       conversion *t;
 
       if (i == 0)
+       arg = obj;
+      else if (i == 1 && first_arg != NULL_TREE)
+       arg = first_arg;
+      else
+       arg = VEC_index (tree, arglist,
+                        i - (first_arg != NULL_TREE ? 1 : 0) - 1);
+      argtype = lvalue_type (arg);
+
+      if (i == 0)
        t = implicit_conversion (totype, argtype, arg, /*c_cast_p=*/false,
                                 flags);
       else if (parmnode == void_list_node)
        t = implicit_conversion (totype, argtype, arg, /*c_cast_p=*/false,
                                 flags);
       else if (parmnode == void_list_node)
@@ -1666,7 +1695,6 @@ add_conv_candidate (struct z_candidate **candidates, tree fn, tree obj,
 
       if (parmnode)
        parmnode = TREE_CHAIN (parmnode);
 
       if (parmnode)
        parmnode = TREE_CHAIN (parmnode);
-      argnode = TREE_CHAIN (argnode);
     }
 
   if (i < len)
     }
 
   if (i < len)
@@ -1675,7 +1703,7 @@ add_conv_candidate (struct z_candidate **candidates, tree fn, tree obj,
   if (!sufficient_parms_p (parmnode))
     viable = 0;
 
   if (!sufficient_parms_p (parmnode))
     viable = 0;
 
-  return add_candidate (candidates, totype, arglist, len, convs,
+  return add_candidate (candidates, totype, first_arg, arglist, len, convs,
                        access_path, conversion_path, viable);
 }
 
                        access_path, conversion_path, viable);
 }
 
@@ -1728,7 +1756,7 @@ build_builtin_candidate (struct z_candidate **candidates, tree fnname,
        viable = 0;
     }
 
        viable = 0;
     }
 
-  add_candidate (candidates, fnname, /*args=*/NULL_TREE,
+  add_candidate (candidates, fnname, /*first_arg=*/NULL_TREE, /*args=*/NULL,
                 num_convs, convs,
                 /*access_path=*/NULL_TREE,
                 /*conversion_path=*/NULL_TREE,
                 num_convs, convs,
                 /*access_path=*/NULL_TREE,
                 /*conversion_path=*/NULL_TREE,
@@ -2349,37 +2377,79 @@ add_builtin_candidates (struct z_candidate **candidates, enum tree_code code,
 
    TMPL is the template.  EXPLICIT_TARGS are any explicit template
    arguments.  ARGLIST is the arguments provided at the call-site.
 
    TMPL is the template.  EXPLICIT_TARGS are any explicit template
    arguments.  ARGLIST is the arguments provided at the call-site.
-   The RETURN_TYPE is the desired type for conversion operators.  If
-   OBJ is NULL_TREE, FLAGS and CTYPE are as for add_function_candidate.
-   If an OBJ is supplied, FLAGS and CTYPE are ignored, and OBJ is as for
-   add_conv_candidate.  */
+   This does not change ARGLIST.  The RETURN_TYPE is the desired type
+   for conversion operators.  If OBJ is NULL_TREE, FLAGS and CTYPE are
+   as for add_function_candidate.  If an OBJ is supplied, FLAGS and
+   CTYPE are ignored, and OBJ is as for add_conv_candidate.  */
 
 static struct z_candidate*
 add_template_candidate_real (struct z_candidate **candidates, tree tmpl,
 
 static struct z_candidate*
 add_template_candidate_real (struct z_candidate **candidates, tree tmpl,
-                            tree ctype, tree explicit_targs, tree arglist,
-                            tree return_type, tree access_path,
-                            tree conversion_path, int flags, tree obj,
-                            unification_kind_t strict)
+                            tree ctype, tree explicit_targs, tree first_arg,
+                            const VEC(tree,gc) *arglist, tree return_type,
+                            tree access_path, tree conversion_path,
+                            int flags, tree obj, unification_kind_t strict)
 {
   int ntparms = DECL_NTPARMS (tmpl);
   tree targs = make_tree_vec (ntparms);
 {
   int ntparms = DECL_NTPARMS (tmpl);
   tree targs = make_tree_vec (ntparms);
-  tree args_without_in_chrg = arglist;
+  unsigned int nargs;
+  int skip_without_in_chrg;
+  tree first_arg_without_in_chrg;
+  tree *args_without_in_chrg;
+  unsigned int nargs_without_in_chrg;
+  unsigned int ia, ix;
+  tree arg;
   struct z_candidate *cand;
   int i;
   tree fn;
 
   struct z_candidate *cand;
   int i;
   tree fn;
 
+  nargs = (first_arg == NULL_TREE ? 0 : 1) + VEC_length (tree, arglist);
+
+  skip_without_in_chrg = 0;
+
+  first_arg_without_in_chrg = first_arg;
+
   /* We don't do deduction on the in-charge parameter, the VTT
      parameter or 'this'.  */
   if (DECL_NONSTATIC_MEMBER_FUNCTION_P (tmpl))
   /* We don't do deduction on the in-charge parameter, the VTT
      parameter or 'this'.  */
   if (DECL_NONSTATIC_MEMBER_FUNCTION_P (tmpl))
-    args_without_in_chrg = TREE_CHAIN (args_without_in_chrg);
+    {
+      if (first_arg_without_in_chrg != NULL_TREE)
+       first_arg_without_in_chrg = NULL_TREE;
+      else
+       ++skip_without_in_chrg;
+    }
 
   if ((DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (tmpl)
        || DECL_BASE_CONSTRUCTOR_P (tmpl))
       && CLASSTYPE_VBASECLASSES (DECL_CONTEXT (tmpl)))
 
   if ((DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (tmpl)
        || DECL_BASE_CONSTRUCTOR_P (tmpl))
       && CLASSTYPE_VBASECLASSES (DECL_CONTEXT (tmpl)))
-    args_without_in_chrg = TREE_CHAIN (args_without_in_chrg);
+    {
+      if (first_arg_without_in_chrg != NULL_TREE)
+       first_arg_without_in_chrg = NULL_TREE;
+      else
+       ++skip_without_in_chrg;
+    }
+
+  nargs_without_in_chrg = ((first_arg_without_in_chrg != NULL_TREE ? 1 : 0)
+                          + (VEC_length (tree, arglist)
+                             - skip_without_in_chrg));
+  args_without_in_chrg = XALLOCAVEC (tree, nargs_without_in_chrg);
+  ia = 0;
+  if (first_arg_without_in_chrg != NULL_TREE)
+    {
+      args_without_in_chrg[ia] = first_arg_without_in_chrg;
+      ++ia;
+    }
+  for (ix = skip_without_in_chrg;
+       VEC_iterate (tree, arglist, ix, arg);
+       ++ix)
+    {
+      args_without_in_chrg[ia] = arg;
+      ++ia;
+    }
+  gcc_assert (ia == nargs_without_in_chrg);
 
   i = fn_type_unification (tmpl, explicit_targs, targs,
                           args_without_in_chrg,
 
   i = fn_type_unification (tmpl, explicit_targs, targs,
                           args_without_in_chrg,
+                          nargs_without_in_chrg,
                           return_type, strict, flags);
 
   if (i != 0)
                           return_type, strict, flags);
 
   if (i != 0)
@@ -2411,7 +2481,7 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl,
      class type, and a logical interpretation is that the intent was
      to forbid the instantiation of member templates which would then
      have that form.  */
      class type, and a logical interpretation is that the intent was
      to forbid the instantiation of member templates which would then
      have that form.  */
-  if (DECL_CONSTRUCTOR_P (fn) && list_length (arglist) == 2)
+  if (DECL_CONSTRUCTOR_P (fn) && nargs == 2)
     {
       tree arg_types = FUNCTION_FIRST_USER_PARMTYPE (fn);
       if (arg_types && same_type_p (TYPE_MAIN_VARIANT (TREE_VALUE (arg_types)),
     {
       tree arg_types = FUNCTION_FIRST_USER_PARMTYPE (fn);
       if (arg_types && same_type_p (TYPE_MAIN_VARIANT (TREE_VALUE (arg_types)),
@@ -2421,11 +2491,11 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl,
 
   if (obj != NULL_TREE)
     /* Aha, this is a conversion function.  */
 
   if (obj != NULL_TREE)
     /* Aha, this is a conversion function.  */
-    cand = add_conv_candidate (candidates, fn, obj, access_path,
-                              conversion_path, arglist);
+    cand = add_conv_candidate (candidates, fn, obj, first_arg, arglist,
+                              access_path, conversion_path);
   else
     cand = add_function_candidate (candidates, fn, ctype,
   else
     cand = add_function_candidate (candidates, fn, ctype,
-                                  arglist, access_path,
+                                  first_arg, arglist, access_path,
                                   conversion_path, flags);
   if (DECL_TI_TEMPLATE (fn) != tmpl)
     /* This situation can occur if a member template of a template
                                   conversion_path, flags);
   if (DECL_TI_TEMPLATE (fn) != tmpl)
     /* This situation can occur if a member template of a template
@@ -2455,26 +2525,29 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl,
 
 static struct z_candidate *
 add_template_candidate (struct z_candidate **candidates, tree tmpl, tree ctype,
 
 static struct z_candidate *
 add_template_candidate (struct z_candidate **candidates, tree tmpl, tree ctype,
-                       tree explicit_targs, tree arglist, tree return_type,
+                       tree explicit_targs, tree first_arg,
+                       const VEC(tree,gc) *arglist, tree return_type,
                        tree access_path, tree conversion_path, int flags,
                        unification_kind_t strict)
 {
   return
     add_template_candidate_real (candidates, tmpl, ctype,
                        tree access_path, tree conversion_path, int flags,
                        unification_kind_t strict)
 {
   return
     add_template_candidate_real (candidates, tmpl, ctype,
-                                explicit_targs, arglist, return_type,
-                                access_path, conversion_path,
+                                explicit_targs, first_arg, arglist,
+                                return_type, access_path, conversion_path,
                                 flags, NULL_TREE, strict);
 }
 
 
 static struct z_candidate *
 add_template_conv_candidate (struct z_candidate **candidates, tree tmpl,
                                 flags, NULL_TREE, strict);
 }
 
 
 static struct z_candidate *
 add_template_conv_candidate (struct z_candidate **candidates, tree tmpl,
-                            tree obj, tree arglist, tree return_type,
-                            tree access_path, tree conversion_path)
+                            tree obj, tree first_arg,
+                            const VEC(tree,gc) *arglist,
+                            tree return_type, tree access_path,
+                            tree conversion_path)
 {
   return
     add_template_candidate_real (candidates, tmpl, NULL_TREE, NULL_TREE,
 {
   return
     add_template_candidate_real (candidates, tmpl, NULL_TREE, NULL_TREE,
-                                arglist, return_type, access_path,
+                                first_arg, arglist, return_type, access_path,
                                 conversion_path, 0, obj, DEDUCE_CONV);
 }
 
                                 conversion_path, 0, obj, DEDUCE_CONV);
 }
 
@@ -2681,7 +2754,8 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags)
   tree ctors = NULL_TREE;
   tree conv_fns = NULL_TREE;
   conversion *conv = NULL;
   tree ctors = NULL_TREE;
   tree conv_fns = NULL_TREE;
   conversion *conv = NULL;
-  tree args = NULL_TREE;
+  tree first_arg = NULL_TREE;
+  VEC(tree,gc) *args = NULL;
   bool any_viable_p;
   int convflags;
 
   bool any_viable_p;
   int convflags;
 
@@ -2721,15 +2795,13 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags)
 
   if (ctors)
     {
 
   if (ctors)
     {
-      tree t;
-
       ctors = BASELINK_FUNCTIONS (ctors);
 
       ctors = BASELINK_FUNCTIONS (ctors);
 
-      t = build_int_cst (build_pointer_type (totype), 0);
+      first_arg = build_int_cst (build_pointer_type (totype), 0);
       if (BRACE_ENCLOSED_INITIALIZER_P (expr)
          && !TYPE_HAS_LIST_CTOR (totype))
        {
       if (BRACE_ENCLOSED_INITIALIZER_P (expr)
          && !TYPE_HAS_LIST_CTOR (totype))
        {
-         args = ctor_to_list (expr);
+         args = ctor_to_vec (expr);
          /* We still allow more conversions within an init-list.  */
          flags = ((flags & ~LOOKUP_NO_CONVERSION)
                   /* But not for the copy ctor.  */
          /* We still allow more conversions within an init-list.  */
          flags = ((flags & ~LOOKUP_NO_CONVERSION)
                   /* But not for the copy ctor.  */
@@ -2737,12 +2809,12 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags)
                   |LOOKUP_NO_NARROWING);
        }
       else
                   |LOOKUP_NO_NARROWING);
        }
       else
-       args = build_tree_list (NULL_TREE, expr);
+       args = make_tree_vector_single (expr);
+
       /* We should never try to call the abstract or base constructor
         from here.  */
       gcc_assert (!DECL_HAS_IN_CHARGE_PARM_P (OVL_CURRENT (ctors))
                  && !DECL_HAS_VTT_PARM_P (OVL_CURRENT (ctors)));
       /* We should never try to call the abstract or base constructor
         from here.  */
       gcc_assert (!DECL_HAS_IN_CHARGE_PARM_P (OVL_CURRENT (ctors))
                  && !DECL_HAS_VTT_PARM_P (OVL_CURRENT (ctors)));
-      args = tree_cons (NULL_TREE, t, args);
     }
   for (; ctors; ctors = OVL_NEXT (ctors))
     {
     }
   for (; ctors; ctors = OVL_NEXT (ctors))
     {
@@ -2753,14 +2825,14 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags)
 
       if (TREE_CODE (ctor) == TEMPLATE_DECL)
        cand = add_template_candidate (&candidates, ctor, totype,
 
       if (TREE_CODE (ctor) == TEMPLATE_DECL)
        cand = add_template_candidate (&candidates, ctor, totype,
-                                      NULL_TREE, args, NULL_TREE,
+                                      NULL_TREE, first_arg, args, NULL_TREE,
                                       TYPE_BINFO (totype),
                                       TYPE_BINFO (totype),
                                       flags,
                                       DEDUCE_CALL);
       else
        cand = add_function_candidate (&candidates, ctor, totype,
                                       TYPE_BINFO (totype),
                                       TYPE_BINFO (totype),
                                       flags,
                                       DEDUCE_CALL);
       else
        cand = add_function_candidate (&candidates, ctor, totype,
-                                      args, TYPE_BINFO (totype),
+                                      first_arg, args, TYPE_BINFO (totype),
                                       TYPE_BINFO (totype),
                                       flags);
 
                                       TYPE_BINFO (totype),
                                       flags);
 
@@ -2784,7 +2856,7 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags)
     }
 
   if (conv_fns)
     }
 
   if (conv_fns)
-    args = build_tree_list (NULL_TREE, build_this (expr));
+    first_arg = build_this (expr);
 
   for (; conv_fns; conv_fns = TREE_CHAIN (conv_fns))
     {
 
   for (; conv_fns; conv_fns = TREE_CHAIN (conv_fns))
     {
@@ -2816,14 +2888,14 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags)
          if (TREE_CODE (fn) == TEMPLATE_DECL)
            cand = add_template_candidate (&candidates, fn, fromtype,
                                           NULL_TREE,
          if (TREE_CODE (fn) == TEMPLATE_DECL)
            cand = add_template_candidate (&candidates, fn, fromtype,
                                           NULL_TREE,
-                                          args, totype,
+                                          first_arg, NULL, totype,
                                           TYPE_BINFO (fromtype),
                                           conversion_path,
                                           flags,
                                           DEDUCE_CONV);
          else
            cand = add_function_candidate (&candidates, fn, fromtype,
                                           TYPE_BINFO (fromtype),
                                           conversion_path,
                                           flags,
                                           DEDUCE_CONV);
          else
            cand = add_function_candidate (&candidates, fn, fromtype,
-                                          args,
+                                          first_arg, NULL,
                                           TYPE_BINFO (fromtype),
                                           conversion_path,
                                           flags);
                                           TYPE_BINFO (fromtype),
                                           conversion_path,
                                           flags);
@@ -2926,23 +2998,23 @@ build_user_type_conversion (tree totype, tree expr, int flags)
 
 /* Do any initial processing on the arguments to a function call.  */
 
 
 /* Do any initial processing on the arguments to a function call.  */
 
-static tree
-resolve_args (tree args)
+static VEC(tree,gc) *
+resolve_args (VEC(tree,gc) *args)
 {
 {
-  tree t;
-  for (t = args; t; t = TREE_CHAIN (t))
-    {
-      tree arg = TREE_VALUE (t);
+  unsigned int ix;
+  tree arg;
 
 
+  for (ix = 0; VEC_iterate (tree, args, ix, arg); ++ix)
+    {
       if (error_operand_p (arg))
       if (error_operand_p (arg))
-       return error_mark_node;
+       return NULL;
       else if (VOID_TYPE_P (TREE_TYPE (arg)))
        {
          error ("invalid use of void expression");
       else if (VOID_TYPE_P (TREE_TYPE (arg)))
        {
          error ("invalid use of void expression");
-         return error_mark_node;
+         return NULL;
        }
       else if (invalid_nonstatic_memfn_p (arg, tf_warning_or_error))
        }
       else if (invalid_nonstatic_memfn_p (arg, tf_warning_or_error))
-       return error_mark_node;
+       return NULL;
     }
   return args;
 }
     }
   return args;
 }
@@ -2961,7 +3033,7 @@ resolve_args (tree args)
 
 static struct z_candidate *
 perform_overload_resolution (tree fn,
 
 static struct z_candidate *
 perform_overload_resolution (tree fn,
-                            tree args,
+                            const VEC(tree,gc) *args,
                             struct z_candidate **candidates,
                             bool *any_viable_p)
 {
                             struct z_candidate **candidates,
                             bool *any_viable_p)
 {
@@ -2972,12 +3044,11 @@ perform_overload_resolution (tree fn,
   *candidates = NULL;
   *any_viable_p = true;
 
   *candidates = NULL;
   *any_viable_p = true;
 
-  /* Check FN and ARGS.  */
+  /* Check FN.  */
   gcc_assert (TREE_CODE (fn) == FUNCTION_DECL
              || TREE_CODE (fn) == TEMPLATE_DECL
              || TREE_CODE (fn) == OVERLOAD
              || TREE_CODE (fn) == TEMPLATE_ID_EXPR);
   gcc_assert (TREE_CODE (fn) == FUNCTION_DECL
              || TREE_CODE (fn) == TEMPLATE_DECL
              || TREE_CODE (fn) == OVERLOAD
              || TREE_CODE (fn) == TEMPLATE_ID_EXPR);
-  gcc_assert (!args || TREE_CODE (args) == TREE_LIST);
 
   if (TREE_CODE (fn) == TEMPLATE_ID_EXPR)
     {
 
   if (TREE_CODE (fn) == TEMPLATE_ID_EXPR)
     {
@@ -3002,10 +3073,11 @@ perform_overload_resolution (tree fn,
 }
 
 /* Return an expression for a call to FN (a namespace-scope function,
 }
 
 /* Return an expression for a call to FN (a namespace-scope function,
-   or a static member function) with the ARGS.  */
+   or a static member function) with the ARGS.  This may change
+   ARGS.  */
 
 tree
 
 tree
-build_new_function_call (tree fn, tree args, bool koenig_p, 
+build_new_function_call (tree fn, VEC(tree,gc) **args, bool koenig_p, 
                         tsubst_flags_t complain)
 {
   struct z_candidate *candidates, *cand;
                         tsubst_flags_t complain)
 {
   struct z_candidate *candidates, *cand;
@@ -3013,9 +3085,12 @@ build_new_function_call (tree fn, tree args, bool koenig_p,
   void *p;
   tree result;
 
   void *p;
   tree result;
 
-  args = resolve_args (args);
-  if (args == error_mark_node)
-    return error_mark_node;
+  if (args != NULL && *args != NULL)
+    {
+      *args = resolve_args (*args);
+      if (*args == NULL)
+       return error_mark_node;
+    }
 
   /* If this function was found without using argument dependent
      lookup, then we want to ignore any undeclared friend
 
   /* If this function was found without using argument dependent
      lookup, then we want to ignore any undeclared friend
@@ -3029,7 +3104,8 @@ build_new_function_call (tree fn, tree args, bool koenig_p,
        {
          if (complain & tf_error)
            error ("no matching function for call to %<%D(%A)%>",
        {
          if (complain & tf_error)
            error ("no matching function for call to %<%D(%A)%>",
-                  DECL_NAME (OVL_CURRENT (orig_fn)), args);
+                  DECL_NAME (OVL_CURRENT (orig_fn)),
+                  build_tree_list_vec (*args));
          return error_mark_node;
        }
     }
          return error_mark_node;
        }
     }
@@ -3037,22 +3113,22 @@ build_new_function_call (tree fn, tree args, bool koenig_p,
   /* Get the high-water mark for the CONVERSION_OBSTACK.  */
   p = conversion_obstack_alloc (0);
 
   /* Get the high-water mark for the CONVERSION_OBSTACK.  */
   p = conversion_obstack_alloc (0);
 
-  cand = perform_overload_resolution (fn, args, &candidates, &any_viable_p);
+  cand = perform_overload_resolution (fn, *args, &candidates, &any_viable_p);
 
   if (!cand)
     {
       if (complain & tf_error)
        {
          if (!any_viable_p && candidates && ! candidates->next)
 
   if (!cand)
     {
       if (complain & tf_error)
        {
          if (!any_viable_p && candidates && ! candidates->next)
-           return cp_build_function_call (candidates->fn, args, complain);
+           return cp_build_function_call_vec (candidates->fn, args, complain);
          if (TREE_CODE (fn) == TEMPLATE_ID_EXPR)
            fn = TREE_OPERAND (fn, 0);
          if (!any_viable_p)
            error ("no matching function for call to %<%D(%A)%>",
          if (TREE_CODE (fn) == TEMPLATE_ID_EXPR)
            fn = TREE_OPERAND (fn, 0);
          if (!any_viable_p)
            error ("no matching function for call to %<%D(%A)%>",
-                  DECL_NAME (OVL_CURRENT (fn)), args);
+                  DECL_NAME (OVL_CURRENT (fn)), build_tree_list_vec (*args));
          else
            error ("call of overloaded %<%D(%A)%> is ambiguous",
          else
            error ("call of overloaded %<%D(%A)%> is ambiguous",
-                  DECL_NAME (OVL_CURRENT (fn)), args);
+                  DECL_NAME (OVL_CURRENT (fn)), build_tree_list_vec (*args));
          if (candidates)
            print_z_candidates (candidates);
        }
          if (candidates)
            print_z_candidates (candidates);
        }
@@ -3069,15 +3145,16 @@ build_new_function_call (tree fn, tree args, bool koenig_p,
 
 /* Build a call to a global operator new.  FNNAME is the name of the
    operator (either "operator new" or "operator new[]") and ARGS are
 
 /* Build a call to a global operator new.  FNNAME is the name of the
    operator (either "operator new" or "operator new[]") and ARGS are
-   the arguments provided.  *SIZE points to the total number of bytes
-   required by the allocation, and is updated if that is changed here.
-   *COOKIE_SIZE is non-NULL if a cookie should be used.  If this
-   function determines that no cookie should be used, after all,
-   *COOKIE_SIZE is set to NULL_TREE.  If FN is non-NULL, it will be
-   set, upon return, to the allocation function called.  */
+   the arguments provided.  This may change ARGS.  *SIZE points to the
+   total number of bytes required by the allocation, and is updated if
+   that is changed here.  *COOKIE_SIZE is non-NULL if a cookie should
+   be used.  If this function determines that no cookie should be
+   used, after all, *COOKIE_SIZE is set to NULL_TREE.  If FN is
+   non-NULL, it will be set, upon return, to the allocation function
+   called.  */
 
 tree
 
 tree
-build_operator_new_call (tree fnname, tree args,
+build_operator_new_call (tree fnname, VEC(tree,gc) **args,
                         tree *size, tree *cookie_size,
                         tree *fn)
 {
                         tree *size, tree *cookie_size,
                         tree *fn)
 {
@@ -3088,10 +3165,10 @@ build_operator_new_call (tree fnname, tree args,
 
   if (fn)
     *fn = NULL_TREE;
 
   if (fn)
     *fn = NULL_TREE;
-  args = tree_cons (NULL_TREE, *size, args);
-  args = resolve_args (args);
-  if (args == error_mark_node)
-    return args;
+  VEC_safe_insert (tree, gc, *args, 0, *size);
+  *args = resolve_args (*args);
+  if (*args == NULL)
+    return error_mark_node;
 
   /* Based on:
 
 
   /* Based on:
 
@@ -3102,10 +3179,10 @@ build_operator_new_call (tree fnname, tree args,
        up in the global scope.
 
      we disregard block-scope declarations of "operator new".  */
        up in the global scope.
 
      we disregard block-scope declarations of "operator new".  */
-  fns = lookup_function_nonclass (fnname, args, /*block_p=*/false);
+  fns = lookup_function_nonclass (fnname, *args, /*block_p=*/false);
 
   /* Figure out what function is being called.  */
 
   /* Figure out what function is being called.  */
-  cand = perform_overload_resolution (fns, args, &candidates, &any_viable_p);
+  cand = perform_overload_resolution (fns, *args, &candidates, &any_viable_p);
 
   /* If no suitable function could be found, issue an error message
      and give up.  */
 
   /* If no suitable function could be found, issue an error message
      and give up.  */
@@ -3113,10 +3190,10 @@ build_operator_new_call (tree fnname, tree args,
     {
       if (!any_viable_p)
        error ("no matching function for call to %<%D(%A)%>",
     {
       if (!any_viable_p)
        error ("no matching function for call to %<%D(%A)%>",
-              DECL_NAME (OVL_CURRENT (fns)), args);
+              DECL_NAME (OVL_CURRENT (fns)), build_tree_list_vec (*args));
       else
        error ("call of overloaded %<%D(%A)%> is ambiguous",
       else
        error ("call of overloaded %<%D(%A)%> is ambiguous",
-              DECL_NAME (OVL_CURRENT (fns)), args);
+              DECL_NAME (OVL_CURRENT (fns)), build_tree_list_vec (*args));
       if (candidates)
        print_z_candidates (candidates);
       return error_mark_node;
       if (candidates)
        print_z_candidates (candidates);
       return error_mark_node;
@@ -3130,12 +3207,11 @@ build_operator_new_call (tree fnname, tree args,
        bool use_cookie = true;
        if (!abi_version_at_least (2))
         {
        bool use_cookie = true;
        if (!abi_version_at_least (2))
         {
-          tree placement = TREE_CHAIN (args);
           /* In G++ 3.2, the check was implemented incorrectly; it
              looked at the placement expression, rather than the
              type of the function.  */
           /* In G++ 3.2, the check was implemented incorrectly; it
              looked at the placement expression, rather than the
              type of the function.  */
-          if (placement && !TREE_CHAIN (placement)
-              && same_type_p (TREE_TYPE (TREE_VALUE (placement)),
+          if (VEC_length (tree, *args) == 2
+              && same_type_p (TREE_TYPE (VEC_index (tree, *args, 1)),
                               ptr_type_node))
             use_cookie = false;
         }
                               ptr_type_node))
             use_cookie = false;
         }
@@ -3159,7 +3235,7 @@ build_operator_new_call (tree fnname, tree args,
           /* Update the total size.  */
           *size = size_binop (PLUS_EXPR, *size, *cookie_size);
           /* Update the argument list to reflect the adjusted size.  */
           /* Update the total size.  */
           *size = size_binop (PLUS_EXPR, *size, *cookie_size);
           /* Update the argument list to reflect the adjusted size.  */
-          TREE_VALUE (args) = *size;
+          VEC_replace (tree, *args, 0, *size);
         }
        else
         *cookie_size = NULL_TREE;
         }
        else
         *cookie_size = NULL_TREE;
@@ -3173,16 +3249,23 @@ build_operator_new_call (tree fnname, tree args,
    return build_over_call (cand, LOOKUP_NORMAL, tf_warning_or_error);
 }
 
    return build_over_call (cand, LOOKUP_NORMAL, tf_warning_or_error);
 }
 
-static tree
-build_object_call (tree obj, tree args, tsubst_flags_t complain)
+/* Build a new call to operator().  This may change ARGS.  */
+
+tree
+build_op_call (tree obj, VEC(tree,gc) **args, tsubst_flags_t complain)
 {
   struct z_candidate *candidates = 0, *cand;
 {
   struct z_candidate *candidates = 0, *cand;
-  tree fns, convs, mem_args = NULL_TREE;
+  tree fns, convs, first_mem_arg = NULL_TREE;
   tree type = TREE_TYPE (obj);
   bool any_viable_p;
   tree result = NULL_TREE;
   void *p;
 
   tree type = TREE_TYPE (obj);
   bool any_viable_p;
   tree result = NULL_TREE;
   void *p;
 
+  if (error_operand_p (obj))
+    return error_mark_node;
+
+  obj = prep_operand (obj);
+
   if (TYPE_PTRMEMFUNC_P (type))
     {
       if (complain & tf_error)
   if (TYPE_PTRMEMFUNC_P (type))
     {
       if (complain & tf_error)
@@ -3201,10 +3284,12 @@ build_object_call (tree obj, tree args, tsubst_flags_t complain)
   else
     fns = NULL_TREE;
 
   else
     fns = NULL_TREE;
 
-  args = resolve_args (args);
-
-  if (args == error_mark_node)
-    return error_mark_node;
+  if (args != NULL && *args != NULL)
+    {
+      *args = resolve_args (*args);
+      if (*args == NULL)
+       return error_mark_node;
+    }
 
   /* Get the high-water mark for the CONVERSION_OBSTACK.  */
   p = conversion_obstack_alloc (0);
 
   /* Get the high-water mark for the CONVERSION_OBSTACK.  */
   p = conversion_obstack_alloc (0);
@@ -3212,20 +3297,20 @@ build_object_call (tree obj, tree args, tsubst_flags_t complain)
   if (fns)
     {
       tree base = BINFO_TYPE (BASELINK_BINFO (fns));
   if (fns)
     {
       tree base = BINFO_TYPE (BASELINK_BINFO (fns));
-      mem_args = tree_cons (NULL_TREE, build_this (obj), args);
+      first_mem_arg = build_this (obj);
 
       for (fns = BASELINK_FUNCTIONS (fns); fns; fns = OVL_NEXT (fns))
        {
          tree fn = OVL_CURRENT (fns);
          if (TREE_CODE (fn) == TEMPLATE_DECL)
            add_template_candidate (&candidates, fn, base, NULL_TREE,
 
       for (fns = BASELINK_FUNCTIONS (fns); fns; fns = OVL_NEXT (fns))
        {
          tree fn = OVL_CURRENT (fns);
          if (TREE_CODE (fn) == TEMPLATE_DECL)
            add_template_candidate (&candidates, fn, base, NULL_TREE,
-                                   mem_args, NULL_TREE,
+                                   first_mem_arg, *args, NULL_TREE,
                                    TYPE_BINFO (type),
                                    TYPE_BINFO (type),
                                    LOOKUP_NORMAL, DEDUCE_CALL);
          else
            add_function_candidate
                                    TYPE_BINFO (type),
                                    TYPE_BINFO (type),
                                    LOOKUP_NORMAL, DEDUCE_CALL);
          else
            add_function_candidate
-             (&candidates, fn, base, mem_args, TYPE_BINFO (type),
+             (&candidates, fn, base, first_mem_arg, *args, TYPE_BINFO (type),
               TYPE_BINFO (type), LOOKUP_NORMAL);
        }
     }
               TYPE_BINFO (type), LOOKUP_NORMAL);
        }
     }
@@ -3253,12 +3338,12 @@ build_object_call (tree obj, tree args, tsubst_flags_t complain)
 
            if (TREE_CODE (fn) == TEMPLATE_DECL)
              add_template_conv_candidate
 
            if (TREE_CODE (fn) == TEMPLATE_DECL)
              add_template_conv_candidate
-               (&candidates, fn, obj, args, totype,
+               (&candidates, fn, obj, NULL_TREE, *args, totype,
                 /*access_path=*/NULL_TREE,
                 /*conversion_path=*/NULL_TREE);
            else
                 /*access_path=*/NULL_TREE,
                 /*conversion_path=*/NULL_TREE);
            else
-             add_conv_candidate (&candidates, fn, obj, args,
-                                 /*conversion_path=*/NULL_TREE,
+             add_conv_candidate (&candidates, fn, obj, NULL_TREE,
+                                 *args, /*conversion_path=*/NULL_TREE,
                                  /*access_path=*/NULL_TREE);
          }
     }
                                  /*access_path=*/NULL_TREE);
          }
     }
@@ -3268,7 +3353,8 @@ build_object_call (tree obj, tree args, tsubst_flags_t complain)
     {
       if (complain & tf_error)
         {
     {
       if (complain & tf_error)
         {
-          error ("no match for call to %<(%T) (%A)%>", TREE_TYPE (obj), args);
+          error ("no match for call to %<(%T) (%A)%>", TREE_TYPE (obj),
+                build_tree_list_vec (*args));
           print_z_candidates (candidates);
         }
       result = error_mark_node;
           print_z_candidates (candidates);
         }
       result = error_mark_node;
@@ -3281,7 +3367,7 @@ build_object_call (tree obj, tree args, tsubst_flags_t complain)
           if (complain & tf_error)
             {
               error ("call of %<(%T) (%A)%> is ambiguous", 
           if (complain & tf_error)
             {
               error ("call of %<(%T) (%A)%> is ambiguous", 
-                     TREE_TYPE (obj), args);
+                     TREE_TYPE (obj), build_tree_list_vec (*args));
               print_z_candidates (candidates);
             }
          result = error_mark_node;
               print_z_candidates (candidates);
             }
          result = error_mark_node;
@@ -3297,7 +3383,7 @@ build_object_call (tree obj, tree args, tsubst_flags_t complain)
          obj = convert_like_with_context (cand->convs[0], obj, cand->fn, -1,
                                           complain);
          obj = convert_from_reference (obj);
          obj = convert_like_with_context (cand->convs[0], obj, cand->fn, -1,
                                           complain);
          obj = convert_from_reference (obj);
-         result = cp_build_function_call (obj, args, complain);
+         result = cp_build_function_call_vec (obj, args, complain);
        }
     }
 
        }
     }
 
@@ -3849,29 +3935,33 @@ prep_operand (tree operand)
 /* Add each of the viable functions in FNS (a FUNCTION_DECL or
    OVERLOAD) to the CANDIDATES, returning an updated list of
    CANDIDATES.  The ARGS are the arguments provided to the call,
 /* Add each of the viable functions in FNS (a FUNCTION_DECL or
    OVERLOAD) to the CANDIDATES, returning an updated list of
    CANDIDATES.  The ARGS are the arguments provided to the call,
-   without any implicit object parameter.  The EXPLICIT_TARGS are
-   explicit template arguments provided.  TEMPLATE_ONLY is true if
-   only template functions should be considered.  CONVERSION_PATH,
-   ACCESS_PATH, and FLAGS are as for add_function_candidate.  */
+   without any implicit object parameter.  This may change ARGS.  The
+   EXPLICIT_TARGS are explicit template arguments provided.
+   TEMPLATE_ONLY is true if only template functions should be
+   considered.  CONVERSION_PATH, ACCESS_PATH, and FLAGS are as for
+   add_function_candidate.  */
 
 static void
 
 static void
-add_candidates (tree fns, tree args,
+add_candidates (tree fns, const VEC(tree,gc) *args,
                tree explicit_targs, bool template_only,
                tree conversion_path, tree access_path,
                int flags,
                struct z_candidate **candidates)
 {
   tree ctype;
                tree explicit_targs, bool template_only,
                tree conversion_path, tree access_path,
                int flags,
                struct z_candidate **candidates)
 {
   tree ctype;
-  tree non_static_args;
+  VEC(tree,gc) *non_static_args;
+  tree first_arg;
 
   ctype = conversion_path ? BINFO_TYPE (conversion_path) : NULL_TREE;
   /* Delay creating the implicit this parameter until it is needed.  */
 
   ctype = conversion_path ? BINFO_TYPE (conversion_path) : NULL_TREE;
   /* Delay creating the implicit this parameter until it is needed.  */
-  non_static_args = NULL_TREE;
+  non_static_args = NULL;
+  first_arg = NULL_TREE;
 
   while (fns)
     {
       tree fn;
 
   while (fns)
     {
       tree fn;
-      tree fn_args;
+      tree fn_first_arg;
+      const VEC(tree,gc) *fn_args;
 
       fn = OVL_CURRENT (fns);
       /* Figure out which set of arguments to use.  */
 
       fn = OVL_CURRENT (fns);
       /* Figure out which set of arguments to use.  */
@@ -3879,21 +3969,34 @@ add_candidates (tree fns, tree args,
        {
          /* If this function is a non-static member, prepend the implicit
             object parameter.  */
        {
          /* If this function is a non-static member, prepend the implicit
             object parameter.  */
-         if (!non_static_args)
-           non_static_args = tree_cons (NULL_TREE,
-                                        build_this (TREE_VALUE (args)),
-                                        TREE_CHAIN (args));
+         if (non_static_args == NULL)
+           {
+             unsigned int ix;
+             tree arg;
+
+             non_static_args = VEC_alloc (tree, gc,
+                                          VEC_length (tree, args) - 1);
+             for (ix = 1; VEC_iterate (tree, args, ix, arg); ++ix)
+               VEC_quick_push (tree, non_static_args, arg);
+           }
+         if (first_arg == NULL_TREE)
+           first_arg = build_this (VEC_index (tree, args, 0));
+         fn_first_arg = first_arg;
          fn_args = non_static_args;
        }
       else
          fn_args = non_static_args;
        }
       else
-       /* Otherwise, just use the list of arguments provided.  */
-       fn_args = args;
+       {
+         /* Otherwise, just use the list of arguments provided.  */
+         fn_first_arg = NULL_TREE;
+         fn_args = args;
+       }
 
       if (TREE_CODE (fn) == TEMPLATE_DECL)
        add_template_candidate (candidates,
                                fn,
                                ctype,
                                explicit_targs,
 
       if (TREE_CODE (fn) == TEMPLATE_DECL)
        add_template_candidate (candidates,
                                fn,
                                ctype,
                                explicit_targs,
+                               fn_first_arg, 
                                fn_args,
                                NULL_TREE,
                                access_path,
                                fn_args,
                                NULL_TREE,
                                access_path,
@@ -3904,6 +4007,7 @@ add_candidates (tree fns, tree args,
        add_function_candidate (candidates,
                                fn,
                                ctype,
        add_function_candidate (candidates,
                                fn,
                                ctype,
+                               fn_first_arg,
                                fn_args,
                                access_path,
                                conversion_path,
                                fn_args,
                                access_path,
                                conversion_path,
@@ -3917,7 +4021,8 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
              bool *overloaded_p, tsubst_flags_t complain)
 {
   struct z_candidate *candidates = 0, *cand;
              bool *overloaded_p, tsubst_flags_t complain)
 {
   struct z_candidate *candidates = 0, *cand;
-  tree arglist, fnname;
+  VEC(tree,gc) *arglist;
+  tree fnname;
   tree args[3];
   tree result = NULL_TREE;
   bool result_valid_p = false;
   tree args[3];
   tree result = NULL_TREE;
   bool result_valid_p = false;
@@ -3955,7 +4060,8 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
       gcc_unreachable ();
 
     case CALL_EXPR:
       gcc_unreachable ();
 
     case CALL_EXPR:
-      return build_object_call (arg1, arg2, complain);
+      /* Use build_op_call instead.  */
+      gcc_unreachable ();
 
     case TRUTH_ORIF_EXPR:
     case TRUTH_ANDIF_EXPR:
 
     case TRUTH_ORIF_EXPR:
     case TRUTH_ANDIF_EXPR:
@@ -3988,12 +4094,12 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
   if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
     arg2 = integer_zero_node;
 
   if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
     arg2 = integer_zero_node;
 
-  arglist = NULL_TREE;
-  if (arg3)
-    arglist = tree_cons (NULL_TREE, arg3, arglist);
-  if (arg2)
-    arglist = tree_cons (NULL_TREE, arg2, arglist);
-  arglist = tree_cons (NULL_TREE, arg1, arglist);
+  arglist = VEC_alloc (tree, gc, 3);
+  VEC_quick_push (tree, arglist, arg1);
+  if (arg2 != NULL_TREE)
+    VEC_quick_push (tree, arglist, arg2);
+  if (arg3 != NULL_TREE)
+    VEC_quick_push (tree, arglist, arg3);
 
   /* Get the high-water mark for the CONVERSION_OBSTACK.  */
   p = conversion_obstack_alloc (0);
 
   /* Get the high-water mark for the CONVERSION_OBSTACK.  */
   p = conversion_obstack_alloc (0);
@@ -4133,7 +4239,7 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
          if (overloaded_p)
            *overloaded_p = true;
 
          if (overloaded_p)
            *overloaded_p = true;
 
-         if (resolve_args (arglist) == error_mark_node)
+         if (resolve_args (arglist) == NULL)
            result = error_mark_node;
          else
            result = build_over_call (cand, LOOKUP_NORMAL, complain);
            result = error_mark_node;
          else
            result = build_over_call (cand, LOOKUP_NORMAL, complain);
@@ -4434,13 +4540,14 @@ build_op_delete_call (enum tree_code code, tree addr, tree size,
        }
       else
        {
        }
       else
        {
-         tree args;
-         if (pass == 0)
-           args = tree_cons (NULL_TREE, addr, NULL_TREE);
-         else
-           args = tree_cons (NULL_TREE, addr,
-                             build_tree_list (NULL_TREE, size));
-         return cp_build_function_call (fn, args, tf_warning_or_error);
+         tree ret;
+         VEC(tree,gc) *args = VEC_alloc (tree, gc, 2);
+         VEC_quick_push (tree, args, addr);
+         if (pass != 0)
+           VEC_quick_push (tree, args, size);
+         ret = cp_build_function_call_vec (fn, &args, tf_warning_or_error);
+         VEC_free (tree, gc, args);
+         return ret;
        }
     }
 
        }
     }
 
@@ -4498,12 +4605,13 @@ build_temp (tree expr, tree type, int flags,
            diagnostic_t *diagnostic_kind)
 {
   int savew, savee;
            diagnostic_t *diagnostic_kind)
 {
   int savew, savee;
+  VEC(tree,gc) *args;
 
   savew = warningcount, savee = errorcount;
 
   savew = warningcount, savee = errorcount;
-  expr = build_special_member_call (NULL_TREE,
-                                   complete_ctor_identifier,
-                                   build_tree_list (NULL_TREE, expr),
-                                   type, flags, tf_warning_or_error);
+  args = make_tree_vector_single (expr);
+  expr = build_special_member_call (NULL_TREE, complete_ctor_identifier,
+                                   &args, type, flags, tf_warning_or_error);
+  release_tree_vector (args);
   if (warningcount > savew)
     *diagnostic_kind = DK_WARNING;
   else if (errorcount > savee)
   if (warningcount > savew)
     *diagnostic_kind = DK_WARNING;
   else if (errorcount > savee)
@@ -4665,7 +4773,8 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
        tree elttype = TREE_VEC_ELT (CLASSTYPE_TI_ARGS (totype), 0);
        tree new_ctor = build_constructor (init_list_type_node, NULL);
        unsigned len = CONSTRUCTOR_NELTS (expr);
        tree elttype = TREE_VEC_ELT (CLASSTYPE_TI_ARGS (totype), 0);
        tree new_ctor = build_constructor (init_list_type_node, NULL);
        unsigned len = CONSTRUCTOR_NELTS (expr);
-       tree array, parms, val;
+       tree array, val;
+       VEC(tree,gc) *parms;
        unsigned ix;
 
        /* Convert all the elements.  */
        unsigned ix;
 
        /* Convert all the elements.  */
@@ -4684,12 +4793,14 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
        array = build_array_of_n_type (elttype, len);
        array = finish_compound_literal (array, new_ctor);
 
        array = build_array_of_n_type (elttype, len);
        array = finish_compound_literal (array, new_ctor);
 
-       parms = build_tree_list (NULL_TREE, size_int (len));
-       parms = tree_cons (NULL_TREE, decay_conversion (array), parms);
+       parms = make_tree_vector ();
+       VEC_safe_push (tree, gc, parms, decay_conversion (array));
+       VEC_safe_push (tree, gc, parms, size_int (len));
        /* Call the private constructor.  */
        push_deferring_access_checks (dk_no_check);
        new_ctor = build_special_member_call
        /* Call the private constructor.  */
        push_deferring_access_checks (dk_no_check);
        new_ctor = build_special_member_call
-         (NULL_TREE, complete_ctor_identifier, parms, totype, 0, complain);
+         (NULL_TREE, complete_ctor_identifier, &parms, totype, 0, complain);
+       release_tree_vector (parms);
        pop_deferring_access_checks ();
        return build_cplus_new (totype, new_ctor);
       }
        pop_deferring_access_checks ();
        return build_cplus_new (totype, new_ctor);
       }
@@ -5146,14 +5257,16 @@ static tree
 build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
 {
   tree fn = cand->fn;
 build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
 {
   tree fn = cand->fn;
-  tree args = cand->args;
+  const VEC(tree,gc) *args = cand->args;
+  tree first_arg = cand->first_arg;
   conversion **convs = cand->convs;
   conversion *conv;
   tree parm = TYPE_ARG_TYPES (TREE_TYPE (fn));
   int parmlen;
   conversion **convs = cand->convs;
   conversion *conv;
   tree parm = TYPE_ARG_TYPES (TREE_TYPE (fn));
   int parmlen;
-  tree arg, val;
+  tree val;
   int i = 0;
   int j = 0;
   int i = 0;
   int j = 0;
+  unsigned int arg_index = 0;
   int is_method = 0;
   int nargs;
   tree *argarray;
   int is_method = 0;
   int nargs;
   tree *argarray;
@@ -5167,8 +5280,28 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
     {
       tree expr;
       tree return_type;
     {
       tree expr;
       tree return_type;
+      const tree *argarray;
+      unsigned int nargs;
+
       return_type = TREE_TYPE (TREE_TYPE (fn));
       return_type = TREE_TYPE (TREE_TYPE (fn));
-      expr = build_call_list (return_type, build_addr_func (fn), args);
+      nargs = VEC_length (tree, args);
+      if (first_arg == NULL_TREE)
+       argarray = VEC_address (tree, CONST_CAST (VEC(tree,gc) *, args));
+      else
+       {
+         tree *alcarray;
+         unsigned int ix;
+         tree arg;
+
+         ++nargs;
+         alcarray = XALLOCAVEC (tree, nargs);
+         alcarray[0] = first_arg;
+         for (ix = 0; VEC_iterate (tree, args, ix, arg); ++ix)
+           alcarray[ix + 1] = arg;
+         argarray = alcarray;
+       }
+      expr = build_call_array (return_type, build_addr_func (fn), nargs,
+                              argarray);
       if (TREE_THIS_VOLATILE (fn) && cfun)
        current_function_returns_abnormally = 1;
       if (!VOID_TYPE_P (return_type))
       if (TREE_THIS_VOLATILE (fn) && cfun)
        current_function_returns_abnormally = 1;
       if (!VOID_TYPE_P (return_type))
@@ -5223,13 +5356,9 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
        perform_or_defer_access_check (cand->access_path, fn, fn);
     }
 
        perform_or_defer_access_check (cand->access_path, fn, fn);
     }
 
-  if (args && TREE_CODE (args) != TREE_LIST)
-    args = build_tree_list (NULL_TREE, args);
-  arg = args;
-
   /* Find maximum size of vector to hold converted arguments.  */
   parmlen = list_length (parm);
   /* Find maximum size of vector to hold converted arguments.  */
   parmlen = list_length (parm);
-  nargs = list_length (args);
+  nargs = VEC_length (tree, args) + (first_arg != NULL_TREE ? 1 : 0);
   if (parmlen > nargs)
     nargs = parmlen;
   argarray = (tree *) alloca (nargs * sizeof (tree));
   if (parmlen > nargs)
     nargs = parmlen;
   argarray = (tree *) alloca (nargs * sizeof (tree));
@@ -5238,16 +5367,24 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
      resolution, and must be of the proper type.  */
   if (DECL_CONSTRUCTOR_P (fn))
     {
      resolution, and must be of the proper type.  */
   if (DECL_CONSTRUCTOR_P (fn))
     {
-      argarray[j++] = TREE_VALUE (arg);
-      arg = TREE_CHAIN (arg);
+      if (first_arg != NULL_TREE)
+       {
+         argarray[j++] = first_arg;
+         first_arg = NULL_TREE;
+       }
+      else
+       {
+         argarray[j++] = VEC_index (tree, args, arg_index);
+         ++arg_index;
+       }
       parm = TREE_CHAIN (parm);
       /* We should never try to call the abstract constructor.  */
       gcc_assert (!DECL_HAS_IN_CHARGE_PARM_P (fn));
 
       if (DECL_HAS_VTT_PARM_P (fn))
        {
       parm = TREE_CHAIN (parm);
       /* We should never try to call the abstract constructor.  */
       gcc_assert (!DECL_HAS_IN_CHARGE_PARM_P (fn));
 
       if (DECL_HAS_VTT_PARM_P (fn))
        {
-         argarray[j++] = TREE_VALUE (arg);
-         arg = TREE_CHAIN (arg);
+         argarray[j++] = VEC_index (tree, args, arg_index);
+         ++arg_index;
          parm = TREE_CHAIN (parm);
        }
     }
          parm = TREE_CHAIN (parm);
        }
     }
@@ -5255,7 +5392,10 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
   else if (TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE)
     {
       tree parmtype = TREE_VALUE (parm);
   else if (TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE)
     {
       tree parmtype = TREE_VALUE (parm);
-      tree argtype = TREE_TYPE (TREE_VALUE (arg));
+      tree arg = (first_arg != NULL_TREE
+                 ? first_arg
+                 : VEC_index (tree, args, arg_index));
+      tree argtype = TREE_TYPE (arg);
       tree converted_arg;
       tree base_binfo;
 
       tree converted_arg;
       tree base_binfo;
 
@@ -5278,7 +5418,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
       /* Convert to the base in which the function was declared.  */
       gcc_assert (cand->conversion_path != NULL_TREE);
       converted_arg = build_base_path (PLUS_EXPR,
       /* Convert to the base in which the function was declared.  */
       gcc_assert (cand->conversion_path != NULL_TREE);
       converted_arg = build_base_path (PLUS_EXPR,
-                                      TREE_VALUE (arg),
+                                      arg,
                                       cand->conversion_path,
                                       1);
       /* Check that the base class is accessible.  */
                                       cand->conversion_path,
                                       1);
       /* Check that the base class is accessible.  */
@@ -5297,13 +5437,17 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
 
       argarray[j++] = converted_arg;
       parm = TREE_CHAIN (parm);
 
       argarray[j++] = converted_arg;
       parm = TREE_CHAIN (parm);
-      arg = TREE_CHAIN (arg);
+      if (first_arg != NULL_TREE)
+       first_arg = NULL_TREE;
+      else
+       ++arg_index;
       ++i;
       is_method = 1;
     }
 
       ++i;
       is_method = 1;
     }
 
-  for (; arg && parm;
-       parm = TREE_CHAIN (parm), arg = TREE_CHAIN (arg), ++i)
+  gcc_assert (first_arg == NULL_TREE);
+  for (; arg_index < VEC_length (tree, args) && parm;
+       parm = TREE_CHAIN (parm), ++arg_index, ++i)
     {
       tree type = TREE_VALUE (parm);
 
     {
       tree type = TREE_VALUE (parm);
 
@@ -5316,7 +5460,8 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
        conv = conv->u.next;
 
       val = convert_like_with_context
        conv = conv->u.next;
 
       val = convert_like_with_context
-       (conv, TREE_VALUE (arg), fn, i - is_method, complain);
+       (conv, VEC_index (tree, args, arg_index), fn, i - is_method,
+        complain);
 
       val = convert_for_arg_passing (type, val);
       if (val == error_mark_node)
 
       val = convert_for_arg_passing (type, val);
       if (val == error_mark_node)
@@ -5331,9 +5476,9 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
                                         TREE_PURPOSE (parm),
                                         fn, i - is_method);
   /* Ellipsis */
                                         TREE_PURPOSE (parm),
                                         fn, i - is_method);
   /* Ellipsis */
-  for (; arg; arg = TREE_CHAIN (arg))
+  for (; arg_index < VEC_length (tree, args); ++arg_index)
     {
     {
-      tree a = TREE_VALUE (arg);
+      tree a = VEC_index (tree, args, arg_index);
       if (magic_varargs_p (fn))
        /* Do no conversions for magic varargs.  */;
       else
       if (magic_varargs_p (fn))
        /* Do no conversions for magic varargs.  */;
       else
@@ -5357,7 +5502,8 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
                || DECL_MOVE_CONSTRUCTOR_P (fn)))
     {
       tree targ;
                || DECL_MOVE_CONSTRUCTOR_P (fn)))
     {
       tree targ;
-      arg = argarray[num_artificial_parms_for (fn)];
+      tree arg = argarray[num_artificial_parms_for (fn)];
+      tree fa;
 
       /* Pull out the real argument, disregarding const-correctness.  */
       targ = arg;
 
       /* Pull out the real argument, disregarding const-correctness.  */
       targ = arg;
@@ -5398,7 +5544,10 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
         INIT_EXPR to collapse the temp into our target.  Otherwise, if the
         ctor is trivial, do a bitwise copy with a simple TARGET_EXPR for a
         temp or an INIT_EXPR otherwise.  */
         INIT_EXPR to collapse the temp into our target.  Otherwise, if the
         ctor is trivial, do a bitwise copy with a simple TARGET_EXPR for a
         temp or an INIT_EXPR otherwise.  */
-      if (integer_zerop (TREE_VALUE (args)))
+      fa = (cand->first_arg != NULL_TREE
+           ? cand->first_arg
+           : VEC_index (tree, args, 0));
+      if (integer_zerop (fa))
        {
          if (TREE_CODE (arg) == TARGET_EXPR)
            return arg;
        {
          if (TREE_CODE (arg) == TARGET_EXPR)
            return arg;
@@ -5409,8 +5558,8 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
               || (TYPE_HAS_TRIVIAL_INIT_REF (DECL_CONTEXT (fn))
                   && !move_fn_p (fn)))
        {
               || (TYPE_HAS_TRIVIAL_INIT_REF (DECL_CONTEXT (fn))
                   && !move_fn_p (fn)))
        {
-         tree to = stabilize_reference
-           (cp_build_indirect_ref (TREE_VALUE (args), 0, complain));
+         tree to = stabilize_reference (cp_build_indirect_ref (fa, 0,
+                                                               complain));
 
          val = build2 (INIT_EXPR, DECL_CONTEXT (fn), to, arg);
          return val;
 
          val = build2 (INIT_EXPR, DECL_CONTEXT (fn), to, arg);
          return val;
@@ -5424,8 +5573,8 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
        (cp_build_indirect_ref (argarray[0], 0, complain));
       tree type = TREE_TYPE (to);
       tree as_base = CLASSTYPE_AS_BASE (type);
        (cp_build_indirect_ref (argarray[0], 0, complain));
       tree type = TREE_TYPE (to);
       tree as_base = CLASSTYPE_AS_BASE (type);
+      tree arg = argarray[1];
 
 
-      arg = argarray[1];
       if (tree_int_cst_equal (TYPE_SIZE (type), TYPE_SIZE (as_base)))
        {
          arg = cp_build_indirect_ref (arg, 0, complain);
       if (tree_int_cst_equal (TYPE_SIZE (type), TYPE_SIZE (as_base)))
        {
          arg = cp_build_indirect_ref (arg, 0, complain);
@@ -5631,9 +5780,10 @@ in_charge_arg_for_name (tree name)
 
 /* Build a call to a constructor, destructor, or an assignment
    operator for INSTANCE, an expression with class type.  NAME
 
 /* Build a call to a constructor, destructor, or an assignment
    operator for INSTANCE, an expression with class type.  NAME
-   indicates the special member function to call; ARGS are the
-   arguments.  BINFO indicates the base of INSTANCE that is to be
-   passed as the `this' parameter to the member function called.
+   indicates the special member function to call; *ARGS are the
+   arguments.  ARGS may be NULL.  This may change ARGS.  BINFO
+   indicates the base of INSTANCE that is to be passed as the `this'
+   parameter to the member function called.
 
    FLAGS are the LOOKUP_* flags to use when processing the call.
 
 
    FLAGS are the LOOKUP_* flags to use when processing the call.
 
@@ -5642,12 +5792,14 @@ in_charge_arg_for_name (tree name)
    store the newly constructed object into a VAR_DECL.  */
 
 tree
    store the newly constructed object into a VAR_DECL.  */
 
 tree
-build_special_member_call (tree instance, tree name, tree args,
+build_special_member_call (tree instance, tree name, VEC(tree,gc) **args,
                           tree binfo, int flags, tsubst_flags_t complain)
 {
   tree fns;
   /* The type of the subobject to be constructed or destroyed.  */
   tree class_type;
                           tree binfo, int flags, tsubst_flags_t complain)
 {
   tree fns;
   /* The type of the subobject to be constructed or destroyed.  */
   tree class_type;
+  VEC(tree,gc) *allocated = NULL;
+  tree ret;
 
   gcc_assert (name == complete_ctor_identifier
              || name == base_ctor_identifier
 
   gcc_assert (name == complete_ctor_identifier
              || name == base_ctor_identifier
@@ -5679,7 +5831,7 @@ build_special_member_call (tree instance, tree name, tree args,
       if (name == complete_dtor_identifier
          || name == base_dtor_identifier
          || name == deleting_dtor_identifier)
       if (name == complete_dtor_identifier
          || name == base_dtor_identifier
          || name == deleting_dtor_identifier)
-       gcc_assert (args == NULL_TREE);
+       gcc_assert (args == NULL || VEC_empty (tree, *args));
 
       /* Convert to the base class, if necessary.  */
       if (!same_type_ignoring_top_level_qualifiers_p
 
       /* Convert to the base class, if necessary.  */
       if (!same_type_ignoring_top_level_qualifiers_p
@@ -5728,13 +5880,24 @@ build_special_member_call (tree instance, tree name, tree args,
       sub_vtt = build2 (POINTER_PLUS_EXPR, TREE_TYPE (vtt), vtt,
                        BINFO_SUBVTT_INDEX (binfo));
 
       sub_vtt = build2 (POINTER_PLUS_EXPR, TREE_TYPE (vtt), vtt,
                        BINFO_SUBVTT_INDEX (binfo));
 
-      args = tree_cons (NULL_TREE, sub_vtt, args);
+      if (args == NULL)
+       {
+         allocated = make_tree_vector ();
+         args = &allocated;
+       }
+
+      VEC_safe_insert (tree, gc, *args, 0, sub_vtt);
     }
 
     }
 
-  return build_new_method_call (instance, fns, args,
-                               TYPE_BINFO (BINFO_TYPE (binfo)),
-                               flags, /*fn=*/NULL,
-                               complain);
+  ret = build_new_method_call (instance, fns, args,
+                              TYPE_BINFO (BINFO_TYPE (binfo)),
+                              flags, /*fn=*/NULL,
+                              complain);
+
+  if (allocated != NULL)
+    release_tree_vector (allocated);
+
+  return ret;
 }
 
 /* Return the NAME, as a C string.  The NAME indicates a function that
 }
 
 /* Return the NAME, as a C string.  The NAME indicates a function that
@@ -5783,10 +5946,11 @@ name_as_c_string (tree name, tree type, bool *free_p)
 }
 
 /* Build a call to "INSTANCE.FN (ARGS)".  If FN_P is non-NULL, it will
 }
 
 /* Build a call to "INSTANCE.FN (ARGS)".  If FN_P is non-NULL, it will
-   be set, upon return, to the function called.  */
+   be set, upon return, to the function called.  ARGS may be NULL.
+   This may change ARGS.  */
 
 tree
 
 tree
-build_new_method_call (tree instance, tree fns, tree args,
+build_new_method_call (tree instance, tree fns, VEC(tree,gc) **args,
                       tree conversion_path, int flags,
                       tree *fn_p, tsubst_flags_t complain)
 {
                       tree conversion_path, int flags,
                       tree *fn_p, tsubst_flags_t complain)
 {
@@ -5795,9 +5959,11 @@ build_new_method_call (tree instance, tree fns, tree args,
   tree basetype = NULL_TREE;
   tree access_binfo;
   tree optype;
   tree basetype = NULL_TREE;
   tree access_binfo;
   tree optype;
-  tree mem_args = NULL_TREE, instance_ptr;
+  tree first_mem_arg = NULL_TREE;
+  tree instance_ptr;
   tree name;
   tree name;
-  tree user_args;
+  bool skip_first_for_error;
+  VEC(tree,gc) *user_args;
   tree call;
   tree fn;
   tree class_type;
   tree call;
   tree fn;
   tree class_type;
@@ -5805,7 +5971,7 @@ build_new_method_call (tree instance, tree fns, tree args,
   bool any_viable_p;
   tree orig_instance;
   tree orig_fns;
   bool any_viable_p;
   tree orig_instance;
   tree orig_fns;
-  tree orig_args;
+  VEC(tree,gc) *orig_args = NULL;
   void *p;
 
   gcc_assert (instance != NULL_TREE);
   void *p;
 
   gcc_assert (instance != NULL_TREE);
@@ -5815,8 +5981,7 @@ build_new_method_call (tree instance, tree fns, tree args,
     *fn_p = NULL_TREE;
 
   if (error_operand_p (instance)
     *fn_p = NULL_TREE;
 
   if (error_operand_p (instance)
-      || error_operand_p (fns)
-      || args == error_mark_node)
+      || error_operand_p (fns))
     return error_mark_node;
 
   if (!BASELINK_P (fns))
     return error_mark_node;
 
   if (!BASELINK_P (fns))
@@ -5828,7 +5993,6 @@ build_new_method_call (tree instance, tree fns, tree args,
 
   orig_instance = instance;
   orig_fns = fns;
 
   orig_instance = instance;
   orig_fns = fns;
-  orig_args = args;
 
   /* Dismantle the baselink to collect all the information we need.  */
   if (!conversion_path)
 
   /* Dismantle the baselink to collect all the information we need.  */
   if (!conversion_path)
@@ -5853,16 +6017,20 @@ build_new_method_call (tree instance, tree fns, tree args,
 
   if (processing_template_decl)
     {
 
   if (processing_template_decl)
     {
+      orig_args = args == NULL ? NULL : make_tree_vector_copy (*args);
       instance = build_non_dependent_expr (instance);
       instance = build_non_dependent_expr (instance);
-      args = build_non_dependent_args (orig_args);
-    }
-
-  /* The USER_ARGS are the arguments we will display to users if an
-     error occurs.  The USER_ARGS should not include any
-     compiler-generated arguments.  The "this" pointer hasn't been
-     added yet.  However, we must remove the VTT pointer if this is a
-     call to a base-class constructor or destructor.  */
-  user_args = args;
+      if (args != NULL)
+       make_args_non_dependent (*args);
+    }
+
+  /* Figure out whether to skip the first argument for the error
+     message we will display to users if an error occurs.  We don't
+     want to display any compiler-generated arguments.  The "this"
+     pointer hasn't been added yet.  However, we must remove the VTT
+     pointer if this is a call to a base-class constructor or
+     destructor.  */
+  skip_first_for_error = false;
+  user_args = args == NULL ? NULL : *args;
   if (IDENTIFIER_CTOR_OR_DTOR_P (name))
     {
       /* Callers should explicitly indicate whether they want to construct
   if (IDENTIFIER_CTOR_OR_DTOR_P (name))
     {
       /* Callers should explicitly indicate whether they want to construct
@@ -5873,13 +6041,16 @@ build_new_method_call (tree instance, tree fns, tree args,
       /* Remove the VTT pointer, if present.  */
       if ((name == base_ctor_identifier || name == base_dtor_identifier)
          && CLASSTYPE_VBASECLASSES (basetype))
       /* Remove the VTT pointer, if present.  */
       if ((name == base_ctor_identifier || name == base_dtor_identifier)
          && CLASSTYPE_VBASECLASSES (basetype))
-       user_args = TREE_CHAIN (user_args);
+       skip_first_for_error = true;
     }
 
   /* Process the argument list.  */
     }
 
   /* Process the argument list.  */
-  args = resolve_args (args);
-  if (args == error_mark_node)
-    return error_mark_node;
+  if (args != NULL && *args != NULL)
+    {
+      *args = resolve_args (*args);
+      if (*args == NULL)
+       return error_mark_node;
+    }
 
   instance_ptr = build_this (instance);
 
 
   instance_ptr = build_this (instance);
 
@@ -5899,17 +6070,17 @@ build_new_method_call (tree instance, tree fns, tree args,
   /* If CONSTRUCTOR_IS_DIRECT_INIT is set, this was a T{ } form
      initializer, not T({ }).  If the type doesn't have a list ctor,
      break apart the list into separate ctor args.  */
   /* If CONSTRUCTOR_IS_DIRECT_INIT is set, this was a T{ } form
      initializer, not T({ }).  If the type doesn't have a list ctor,
      break apart the list into separate ctor args.  */
-  if (DECL_CONSTRUCTOR_P (fn) && args
-      && BRACE_ENCLOSED_INITIALIZER_P (TREE_VALUE (args))
-      && CONSTRUCTOR_IS_DIRECT_INIT (TREE_VALUE (args))
+  if (DECL_CONSTRUCTOR_P (fn) && args != NULL && !VEC_empty (tree, *args)
+      && BRACE_ENCLOSED_INITIALIZER_P (VEC_index (tree, *args, 0))
+      && CONSTRUCTOR_IS_DIRECT_INIT (VEC_index (tree, *args, 0))
       && !TYPE_HAS_LIST_CTOR (basetype))
     {
       && !TYPE_HAS_LIST_CTOR (basetype))
     {
-      gcc_assert (TREE_CHAIN (args) == NULL_TREE);
-      args = ctor_to_list (TREE_VALUE (args));
+      gcc_assert (VEC_length (tree, *args) == 1);
+      *args = ctor_to_vec (VEC_index (tree, *args, 0));
     }
 
   class_type = (conversion_path ? BINFO_TYPE (conversion_path) : NULL_TREE);
     }
 
   class_type = (conversion_path ? BINFO_TYPE (conversion_path) : NULL_TREE);
-  mem_args = tree_cons (NULL_TREE, instance_ptr, args);
+  first_mem_arg = instance_ptr;
 
   /* Get the high-water mark for the CONVERSION_OBSTACK.  */
   p = conversion_obstack_alloc (0);
 
   /* Get the high-water mark for the CONVERSION_OBSTACK.  */
   p = conversion_obstack_alloc (0);
@@ -5917,7 +6088,7 @@ build_new_method_call (tree instance, tree fns, tree args,
   for (fn = fns; fn; fn = OVL_NEXT (fn))
     {
       tree t = OVL_CURRENT (fn);
   for (fn = fns; fn; fn = OVL_NEXT (fn))
     {
       tree t = OVL_CURRENT (fn);
-      tree this_arglist;
+      tree this_first_arg;
 
       /* We can end up here for copy-init of same or base class.  */
       if ((flags & LOOKUP_ONLYCONVERTING)
 
       /* We can end up here for copy-init of same or base class.  */
       if ((flags & LOOKUP_ONLYCONVERTING)
@@ -5925,16 +6096,18 @@ build_new_method_call (tree instance, tree fns, tree args,
        continue;
 
       if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
        continue;
 
       if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
-       this_arglist = mem_args;
+       this_first_arg = first_mem_arg;
       else
       else
-       this_arglist = args;
+       this_first_arg = NULL_TREE;
 
       if (TREE_CODE (t) == TEMPLATE_DECL)
        /* A member template.  */
        add_template_candidate (&candidates, t,
                                class_type,
                                explicit_targs,
 
       if (TREE_CODE (t) == TEMPLATE_DECL)
        /* A member template.  */
        add_template_candidate (&candidates, t,
                                class_type,
                                explicit_targs,
-                               this_arglist, optype,
+                               this_first_arg,
+                               args == NULL ? NULL : *args,
+                               optype,
                                access_binfo,
                                conversion_path,
                                flags,
                                access_binfo,
                                conversion_path,
                                flags,
@@ -5942,7 +6115,8 @@ build_new_method_call (tree instance, tree fns, tree args,
       else if (! template_only)
        add_function_candidate (&candidates, t,
                                class_type,
       else if (! template_only)
        add_function_candidate (&candidates, t,
                                class_type,
-                               this_arglist,
+                               this_first_arg,
+                               args == NULL ? NULL : *args,
                                access_binfo,
                                conversion_path,
                                flags);
                                access_binfo,
                                conversion_path,
                                flags);
@@ -5959,10 +6133,14 @@ build_new_method_call (tree instance, tree fns, tree args,
            {
              char *pretty_name;
              bool free_p;
            {
              char *pretty_name;
              bool free_p;
+             tree arglist;
 
              pretty_name = name_as_c_string (name, basetype, &free_p);
 
              pretty_name = name_as_c_string (name, basetype, &free_p);
+             arglist = build_tree_list_vec (user_args);
+             if (skip_first_for_error)
+               arglist = TREE_CHAIN (arglist);
              error ("no matching function for call to %<%T::%s(%A)%#V%>",
              error ("no matching function for call to %<%T::%s(%A)%#V%>",
-                    basetype, pretty_name, user_args,
+                    basetype, pretty_name, arglist,
                     TREE_TYPE (TREE_TYPE (instance_ptr)));
              if (free_p)
                free (pretty_name);
                     TREE_TYPE (TREE_TYPE (instance_ptr)));
              if (free_p)
                free (pretty_name);
@@ -5978,12 +6156,16 @@ build_new_method_call (tree instance, tree fns, tree args,
        {
          char *pretty_name;
          bool free_p;
        {
          char *pretty_name;
          bool free_p;
+         tree arglist;
 
          if (complain & tf_error)
            {
              pretty_name = name_as_c_string (name, basetype, &free_p);
 
          if (complain & tf_error)
            {
              pretty_name = name_as_c_string (name, basetype, &free_p);
+             arglist = build_tree_list_vec (user_args);
+             if (skip_first_for_error)
+               arglist = TREE_CHAIN (arglist);
              error ("call of overloaded %<%s(%A)%> is ambiguous", pretty_name,
              error ("call of overloaded %<%s(%A)%> is ambiguous", pretty_name,
-                    user_args);
+                    arglist);
              print_z_candidates (candidates);
              if (free_p)
                free (pretty_name);
              print_z_candidates (candidates);
              if (free_p)
                free (pretty_name);
@@ -6064,7 +6246,7 @@ build_new_method_call (tree instance, tree fns, tree args,
        }
       if (TREE_CODE (call) == INDIRECT_REF)
        call = TREE_OPERAND (call, 0);
        }
       if (TREE_CODE (call) == INDIRECT_REF)
        call = TREE_OPERAND (call, 0);
-      call = (build_min_non_dep_call_list
+      call = (build_min_non_dep_call_vec
              (call,
               build_min (COMPONENT_REF, TREE_TYPE (CALL_EXPR_FN (call)),
                          orig_instance, orig_fns, NULL_TREE),
              (call,
               build_min (COMPONENT_REF, TREE_TYPE (CALL_EXPR_FN (call)),
                          orig_instance, orig_fns, NULL_TREE),
@@ -6077,6 +6259,9 @@ build_new_method_call (tree instance, tree fns, tree args,
  /* Free all the conversions we allocated.  */
   obstack_free (&conversion_obstack, p);
 
  /* Free all the conversions we allocated.  */
   obstack_free (&conversion_obstack, p);
 
+  if (orig_args != NULL)
+    release_tree_vector (orig_args);
+
   return call;
 }
 
   return call;
 }
 
@@ -7132,9 +7317,10 @@ perform_direct_initialization_if_possible (tree type,
      ill-formed.  */
   if (CLASS_TYPE_P (type))
     {
      ill-formed.  */
   if (CLASS_TYPE_P (type))
     {
+      VEC(tree,gc) *args = make_tree_vector_single (expr);
       expr = build_special_member_call (NULL_TREE, complete_ctor_identifier,
       expr = build_special_member_call (NULL_TREE, complete_ctor_identifier,
-                                       build_tree_list (NULL_TREE, expr),
-                                       type, LOOKUP_NORMAL, complain);
+                                       &args, type, LOOKUP_NORMAL, complain);
+      release_tree_vector (args);
       return build_cplus_new (type, expr);
     }
 
       return build_cplus_new (type, expr);
     }
 
index ad50a4e..049e980 100644 (file)
@@ -6072,6 +6072,9 @@ resolve_address_of_overloaded_function (tree target_type,
       tree target_arg_types;
       tree target_ret_type;
       tree fns;
       tree target_arg_types;
       tree target_ret_type;
       tree fns;
+      tree *args;
+      unsigned int nargs, ia;
+      tree arg;
 
       if (is_ptrmem)
        target_fn_type
 
       if (is_ptrmem)
        target_fn_type
@@ -6085,6 +6088,14 @@ resolve_address_of_overloaded_function (tree target_type,
       if (TREE_CODE (target_fn_type) == METHOD_TYPE)
        target_arg_types = TREE_CHAIN (target_arg_types);
 
       if (TREE_CODE (target_fn_type) == METHOD_TYPE)
        target_arg_types = TREE_CHAIN (target_arg_types);
 
+      nargs = list_length (target_arg_types);
+      args = XALLOCAVEC (tree, nargs);
+      for (arg = target_arg_types, ia = 0;
+          arg != NULL_TREE && arg != void_list_node;
+          arg = TREE_CHAIN (arg), ++ia)
+       args[ia] = TREE_VALUE (arg);
+      nargs = ia;
+
       for (fns = overload; fns; fns = OVL_NEXT (fns))
        {
          tree fn = OVL_CURRENT (fns);
       for (fns = overload; fns; fns = OVL_NEXT (fns))
        {
          tree fn = OVL_CURRENT (fns);
@@ -6104,9 +6115,9 @@ resolve_address_of_overloaded_function (tree target_type,
 
          /* Try to do argument deduction.  */
          targs = make_tree_vec (DECL_NTPARMS (fn));
 
          /* Try to do argument deduction.  */
          targs = make_tree_vec (DECL_NTPARMS (fn));
-         if (fn_type_unification (fn, explicit_targs, targs,
-                                  target_arg_types, target_ret_type,
-                                  DEDUCE_EXACT, LOOKUP_NORMAL))
+         if (fn_type_unification (fn, explicit_targs, targs, args, nargs,
+                                  target_ret_type, DEDUCE_EXACT,
+                                  LOOKUP_NORMAL))
            /* Argument deduction failed.  */
            continue;
 
            /* Argument deduction failed.  */
            continue;
 
index 3dfd482..5a32a90 100644 (file)
@@ -4176,17 +4176,20 @@ extern bool null_ptr_cst_p                      (tree);
 extern bool sufficient_parms_p                 (const_tree);
 extern tree type_decays_to                     (tree);
 extern tree build_user_type_conversion         (tree, tree, int);
 extern bool sufficient_parms_p                 (const_tree);
 extern tree type_decays_to                     (tree);
 extern tree build_user_type_conversion         (tree, tree, int);
-extern tree build_new_function_call            (tree, tree, bool, 
+extern tree build_new_function_call            (tree, VEC(tree,gc) **, bool, 
                                                 tsubst_flags_t);
                                                 tsubst_flags_t);
-extern tree build_operator_new_call            (tree, tree, tree *, tree *,
-                                                tree *);
-extern tree build_new_method_call              (tree, tree, tree, tree, int,
-                                                tree *, tsubst_flags_t);
-extern tree build_special_member_call          (tree, tree, tree, tree, int,
-                                                 tsubst_flags_t);
+extern tree build_operator_new_call            (tree, VEC(tree,gc) **, tree *,
+                                                tree *, tree *);
+extern tree build_new_method_call              (tree, tree, VEC(tree,gc) **,
+                                                tree, int, tree *,
+                                                tsubst_flags_t);
+extern tree build_special_member_call          (tree, tree, VEC(tree,gc) **,
+                                                tree, int, tsubst_flags_t);
 extern tree build_new_op                       (enum tree_code, int, tree, 
                                                 tree, tree, bool *,
                                                 tsubst_flags_t);
 extern tree build_new_op                       (enum tree_code, int, tree, 
                                                 tree, tree, bool *,
                                                 tsubst_flags_t);
+extern tree build_op_call                      (tree, VEC(tree,gc) **,
+                                                tsubst_flags_t);
 extern tree build_op_delete_call               (enum tree_code, tree, tree, bool, tree, tree);
 extern bool can_convert                                (tree, tree);
 extern bool can_convert_arg                    (tree, tree, tree, int);
 extern tree build_op_delete_call               (enum tree_code, tree, tree, bool, tree, tree);
 extern bool can_convert                                (tree, tree);
 extern bool can_convert_arg                    (tree, tree, tree, int);
@@ -4408,7 +4411,7 @@ extern void determine_visibility          (tree);
 extern void constrain_class_visibility         (tree);
 extern void import_export_decl                 (tree);
 extern tree build_cleanup                      (tree);
 extern void constrain_class_visibility         (tree);
 extern void import_export_decl                 (tree);
 extern tree build_cleanup                      (tree);
-extern tree build_offset_ref_call_from_tree    (tree, tree);
+extern tree build_offset_ref_call_from_tree    (tree, VEC(tree,gc) **);
 extern void check_default_args                 (tree);
 extern void mark_used                          (tree);
 extern void finish_static_data_member_decl     (tree, tree, bool, tree, int);
 extern void check_default_args                 (tree);
 extern void mark_used                          (tree);
 extern void finish_static_data_member_decl     (tree, tree, bool, tree, int);
@@ -4472,7 +4475,8 @@ extern tree build_zero_init                       (tree, tree, bool);
 extern tree build_value_init                   (tree);
 extern tree build_value_init_noctor            (tree);
 extern tree build_offset_ref                   (tree, tree, bool);
 extern tree build_value_init                   (tree);
 extern tree build_value_init_noctor            (tree);
 extern tree build_offset_ref                   (tree, tree, bool);
-extern tree build_new                          (tree, tree, tree, tree, int,
+extern tree build_new                          (VEC(tree,gc) **, tree, tree,
+                                                VEC(tree,gc) **, int,
                                                  tsubst_flags_t);
 extern tree build_vec_init                     (tree, tree, tree, bool, int,
                                                  tsubst_flags_t);
                                                  tsubst_flags_t);
 extern tree build_vec_init                     (tree, tree, tree, bool, int,
                                                  tsubst_flags_t);
@@ -4554,7 +4558,8 @@ extern int uses_template_parms                    (tree);
 extern int uses_template_parms_level           (tree, int);
 extern tree instantiate_class_template         (tree);
 extern tree instantiate_template               (tree, tree, tsubst_flags_t);
 extern int uses_template_parms_level           (tree, int);
 extern tree instantiate_class_template         (tree);
 extern tree instantiate_template               (tree, tree, tsubst_flags_t);
-extern int fn_type_unification                 (tree, tree, tree, tree,
+extern int fn_type_unification                 (tree, tree, tree,
+                                                const tree *, unsigned int,
                                                 tree, unification_kind_t, int);
 extern void mark_decl_instantiated             (tree, int);
 extern int more_specialized_fn                 (tree, tree, int);
                                                 tree, unification_kind_t, int);
 extern void mark_decl_instantiated             (tree, int);
 extern int more_specialized_fn                 (tree, tree, int);
@@ -4592,7 +4597,7 @@ extern bool any_dependent_template_arguments_p  (const_tree);
 extern bool dependent_template_p               (tree);
 extern bool dependent_template_id_p            (tree, tree);
 extern bool type_dependent_expression_p                (tree);
 extern bool dependent_template_p               (tree);
 extern bool dependent_template_id_p            (tree, tree);
 extern bool type_dependent_expression_p                (tree);
-extern bool any_type_dependent_arguments_p      (const_tree);
+extern bool any_type_dependent_arguments_p      (const VEC(tree,gc) *);
 extern bool type_dependent_expression_p_push   (tree);
 extern bool value_dependent_expression_p       (tree);
 extern bool any_value_dependent_elements_p      (const_tree);
 extern bool type_dependent_expression_p_push   (tree);
 extern bool value_dependent_expression_p       (tree);
 extern bool any_value_dependent_elements_p      (const_tree);
@@ -4600,7 +4605,7 @@ extern bool dependent_omp_for_p                   (tree, tree, tree, tree);
 extern tree resolve_typename_type              (tree, bool);
 extern tree template_for_substitution          (tree);
 extern tree build_non_dependent_expr           (tree);
 extern tree resolve_typename_type              (tree, bool);
 extern tree template_for_substitution          (tree);
 extern tree build_non_dependent_expr           (tree);
-extern tree build_non_dependent_args           (tree);
+extern void make_args_non_dependent            (VEC(tree,gc) *);
 extern bool reregister_specialization          (tree, tree, tree);
 extern tree fold_non_dependent_expr            (tree);
 extern bool explicit_class_specialization_p     (tree);
 extern bool reregister_specialization          (tree, tree, tree);
 extern tree fold_non_dependent_expr            (tree);
 extern bool explicit_class_specialization_p     (tree);
@@ -4748,9 +4753,9 @@ extern tree begin_stmt_expr                       (void);
 extern tree finish_stmt_expr_expr              (tree, tree);
 extern tree finish_stmt_expr                   (tree, bool);
 extern tree stmt_expr_value_expr               (tree);
 extern tree finish_stmt_expr_expr              (tree, tree);
 extern tree finish_stmt_expr                   (tree, bool);
 extern tree stmt_expr_value_expr               (tree);
-extern tree perform_koenig_lookup              (tree, tree);
-extern tree finish_call_expr                   (tree, tree, bool, bool, 
-                                                tsubst_flags_t);
+extern tree perform_koenig_lookup              (tree, VEC(tree,gc) *);
+extern tree finish_call_expr                   (tree, VEC(tree,gc) **, bool,
+                                                bool, tsubst_flags_t);
 extern tree finish_increment_expr              (tree, enum tree_code);
 extern tree finish_this_expr                   (void);
 extern tree finish_pseudo_destructor_expr       (tree, tree, tree);
 extern tree finish_increment_expr              (tree, enum tree_code);
 extern tree finish_this_expr                   (void);
 extern tree finish_pseudo_destructor_expr       (tree, tree, tree);
@@ -4832,7 +4837,7 @@ extern bool builtin_valid_in_constant_expr_p    (const_tree);
 extern tree build_min                          (enum tree_code, tree, ...);
 extern tree build_min_nt                       (enum tree_code, ...);
 extern tree build_min_non_dep                  (enum tree_code, tree, ...);
 extern tree build_min                          (enum tree_code, tree, ...);
 extern tree build_min_nt                       (enum tree_code, ...);
 extern tree build_min_non_dep                  (enum tree_code, tree, ...);
-extern tree build_min_non_dep_call_list                (tree, tree, tree);
+extern tree build_min_non_dep_call_vec         (tree, tree, VEC(tree,gc) *);
 extern tree build_cplus_new                    (tree, tree);
 extern tree build_aggr_init_expr               (tree, tree);
 extern tree get_target_expr                    (tree);
 extern tree build_cplus_new                    (tree, tree);
 extern tree build_aggr_init_expr               (tree, tree);
 extern tree get_target_expr                    (tree);
@@ -4932,6 +4937,8 @@ extern tree cp_build_indirect_ref         (tree, const char *,
 extern tree build_array_ref                    (tree, tree, location_t);
 extern tree get_member_function_from_ptrfunc   (tree *, tree);
 extern tree cp_build_function_call              (tree, tree, tsubst_flags_t);
 extern tree build_array_ref                    (tree, tree, location_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_vec         (tree, VEC(tree,gc) **,
+                                                tsubst_flags_t);
 extern tree build_x_binary_op                  (enum tree_code, tree,
                                                 enum tree_code, tree,
                                                 enum tree_code, bool *,
 extern tree build_x_binary_op                  (enum tree_code, tree,
                                                 enum tree_code, tree,
                                                 enum tree_code, bool *,
@@ -4945,6 +4952,7 @@ extern tree unary_complex_lvalue          (enum tree_code, tree);
 extern tree build_x_conditional_expr           (tree, tree, tree, 
                                                  tsubst_flags_t);
 extern tree build_x_compound_expr_from_list    (tree, const char *);
 extern tree build_x_conditional_expr           (tree, tree, tree, 
                                                  tsubst_flags_t);
 extern tree build_x_compound_expr_from_list    (tree, const char *);
+extern tree build_x_compound_expr_from_vec     (VEC(tree,gc) *, const char *);
 extern tree build_x_compound_expr              (tree, tree, tsubst_flags_t);
 extern tree build_compound_expr                 (tree, tree);
 extern tree cp_build_compound_expr             (tree, tree, tsubst_flags_t);
 extern tree build_x_compound_expr              (tree, tree, tsubst_flags_t);
 extern tree build_compound_expr                 (tree, tree);
 extern tree cp_build_compound_expr             (tree, tree, tsubst_flags_t);
index daf145f..3220fe6 100644 (file)
@@ -1,6 +1,6 @@
 /* Language-level data type conversion for GNU C++.
    Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
 /* Language-level data type conversion for GNU C++.
    Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
    Free Software Foundation, Inc.
    Hacked by Michael Tiemann (tiemann@cygnus.com)
 
    Free Software Foundation, Inc.
    Hacked by Michael Tiemann (tiemann@cygnus.com)
 
@@ -755,11 +755,15 @@ ocp_convert (tree type, tree expr, int convtype, int flags)
           the target with the temp (see [dcl.init]).  */
        ctor = build_user_type_conversion (type, ctor, flags);
       else
           the target with the temp (see [dcl.init]).  */
        ctor = build_user_type_conversion (type, ctor, flags);
       else
-       ctor = build_special_member_call (NULL_TREE,
-                                         complete_ctor_identifier,
-                                         build_tree_list (NULL_TREE, ctor),
-                                         type, flags,
-                                          tf_warning_or_error);
+       {
+         VEC(tree,gc) *ctor_vec = make_tree_vector_single (ctor);
+         ctor = build_special_member_call (NULL_TREE,
+                                           complete_ctor_identifier,
+                                           &ctor_vec,
+                                           type, flags,
+                                           tf_warning_or_error);
+         release_tree_vector (ctor_vec);
+       }
       if (ctor)
        return build_cplus_new (type, ctor);
     }
       if (ctor)
        return build_cplus_new (type, ctor);
     }
index 0e050dd..3f753d1 100644 (file)
@@ -3680,18 +3680,18 @@ cp_write_global_declarations (void)
 /* FN is an OFFSET_REF, DOTSTAR_EXPR or MEMBER_REF indicating the
    function to call in parse-tree form; it has not yet been
    semantically analyzed.  ARGS are the arguments to the function.
 /* FN is an OFFSET_REF, DOTSTAR_EXPR or MEMBER_REF indicating the
    function to call in parse-tree form; it has not yet been
    semantically analyzed.  ARGS are the arguments to the function.
-   They have already been semantically analyzed.  */
+   They have already been semantically analyzed.  This may change
+   ARGS.  */
 
 tree
 
 tree
-build_offset_ref_call_from_tree (tree fn, tree args)
+build_offset_ref_call_from_tree (tree fn, VEC(tree,gc) **args)
 {
   tree orig_fn;
 {
   tree orig_fn;
-  tree orig_args;
+  VEC(tree,gc) *orig_args = NULL;
   tree expr;
   tree object;
 
   orig_fn = fn;
   tree expr;
   tree object;
 
   orig_fn = fn;
-  orig_args = args;
   object = TREE_OPERAND (fn, 0);
 
   if (processing_template_decl)
   object = TREE_OPERAND (fn, 0);
 
   if (processing_template_decl)
@@ -3699,17 +3699,19 @@ build_offset_ref_call_from_tree (tree fn, tree args)
       gcc_assert (TREE_CODE (fn) == DOTSTAR_EXPR
                  || TREE_CODE (fn) == MEMBER_REF);
       if (type_dependent_expression_p (fn)
       gcc_assert (TREE_CODE (fn) == DOTSTAR_EXPR
                  || TREE_CODE (fn) == MEMBER_REF);
       if (type_dependent_expression_p (fn)
-         || any_type_dependent_arguments_p (args))
-       return build_nt_call_list (fn, args);
+         || any_type_dependent_arguments_p (*args))
+       return build_nt_call_vec (fn, *args);
+
+      orig_args = make_tree_vector_copy (*args);
 
       /* Transform the arguments and add the implicit "this"
         parameter.  That must be done before the FN is transformed
         because we depend on the form of FN.  */
 
       /* Transform the arguments and add the implicit "this"
         parameter.  That must be done before the FN is transformed
         because we depend on the form of FN.  */
-      args = build_non_dependent_args (args);
+      make_args_non_dependent (*args);
       object = build_non_dependent_expr (object);
       if (TREE_CODE (fn) == DOTSTAR_EXPR)
        object = cp_build_unary_op (ADDR_EXPR, object, 0, tf_warning_or_error);
       object = build_non_dependent_expr (object);
       if (TREE_CODE (fn) == DOTSTAR_EXPR)
        object = cp_build_unary_op (ADDR_EXPR, object, 0, tf_warning_or_error);
-      args = tree_cons (NULL_TREE, object, args);
+      VEC_safe_insert (tree, gc, *args, 0, object);
       /* Now that the arguments are done, transform FN.  */
       fn = build_non_dependent_expr (fn);
     }
       /* Now that the arguments are done, transform FN.  */
       fn = build_non_dependent_expr (fn);
     }
@@ -3726,12 +3728,16 @@ build_offset_ref_call_from_tree (tree fn, tree args)
                                          tf_warning_or_error);
       fn = TREE_OPERAND (fn, 1);
       fn = get_member_function_from_ptrfunc (&object_addr, fn);
                                          tf_warning_or_error);
       fn = TREE_OPERAND (fn, 1);
       fn = get_member_function_from_ptrfunc (&object_addr, fn);
-      args = tree_cons (NULL_TREE, object_addr, args);
+      VEC_safe_insert (tree, gc, *args, 0, object_addr);
     }
 
     }
 
-  expr = cp_build_function_call (fn, args, tf_warning_or_error);
+  expr = cp_build_function_call_vec (fn, args, tf_warning_or_error);
   if (processing_template_decl && expr != error_mark_node)
   if (processing_template_decl && expr != error_mark_node)
-    return build_min_non_dep_call_list (expr, orig_fn, orig_args);
+    expr = build_min_non_dep_call_vec (expr, orig_fn, orig_args);
+
+  if (orig_args != NULL)
+    release_tree_vector (orig_args);
+
   return expr;
 }
 
   return expr;
 }
 
index 2638ccc..99c7036 100644 (file)
@@ -1,6 +1,6 @@
 /* Handle exceptional things in C++.
    Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
 /* Handle exceptional things in C++.
    Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008
+   2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009
    Free Software Foundation, Inc.
    Contributed by Michael Tiemann <tiemann@cygnus.com>
    Rewritten by Mike Stump <mrs@cygnus.com>, based upon an
    Free Software Foundation, Inc.
    Contributed by Michael Tiemann <tiemann@cygnus.com>
    Rewritten by Mike Stump <mrs@cygnus.com>, based upon an
@@ -736,6 +736,7 @@ build_throw (tree exp)
       if (CLASS_TYPE_P (temp_type))
        {
          int flags = LOOKUP_NORMAL | LOOKUP_ONLYCONVERTING;
       if (CLASS_TYPE_P (temp_type))
        {
          int flags = LOOKUP_NORMAL | LOOKUP_ONLYCONVERTING;
+         VEC(tree,gc) *exp_vec;
 
          /* Under C++0x [12.8/16 class.copy], a thrown lvalue is sometimes
             treated as an rvalue for the purposes of overload resolution
 
          /* Under C++0x [12.8/16 class.copy], a thrown lvalue is sometimes
             treated as an rvalue for the purposes of overload resolution
@@ -749,11 +750,11 @@ build_throw (tree exp)
            flags = flags | LOOKUP_PREFER_RVALUE;
 
          /* Call the copy constructor.  */
            flags = flags | LOOKUP_PREFER_RVALUE;
 
          /* Call the copy constructor.  */
+         exp_vec = make_tree_vector_single (exp);
          exp = (build_special_member_call
          exp = (build_special_member_call
-                (object, complete_ctor_identifier,
-                 build_tree_list (NULL_TREE, exp),
-                 TREE_TYPE (object),
-                 flags, tf_warning_or_error));
+                (object, complete_ctor_identifier, &exp_vec,
+                 TREE_TYPE (object), flags, tf_warning_or_error));
+         release_tree_vector (exp_vec);
          if (exp == error_mark_node)
            {
              error ("  in thrown expression");
          if (exp == error_mark_node)
            {
              error ("  in thrown expression");
index 5fa5eb8..fd0d587 100644 (file)
@@ -302,7 +302,7 @@ build_value_init (tree type)
        return build_aggr_init_expr
          (type,
           build_special_member_call (NULL_TREE, complete_ctor_identifier,
        return build_aggr_init_expr
          (type,
           build_special_member_call (NULL_TREE, complete_ctor_identifier,
-                                     NULL_TREE, type, LOOKUP_NORMAL,
+                                     NULL, type, LOOKUP_NORMAL,
                                      tf_warning_or_error));
       else if (TREE_CODE (type) != UNION_TYPE && TYPE_NEEDS_CONSTRUCTING (type))
        {
                                      tf_warning_or_error));
       else if (TREE_CODE (type) != UNION_TYPE && TYPE_NEEDS_CONSTRUCTING (type))
        {
@@ -312,7 +312,7 @@ build_value_init (tree type)
             This will be handled in simplify_aggr_init_expr.  */
          tree ctor = build_special_member_call
            (NULL_TREE, complete_ctor_identifier,
             This will be handled in simplify_aggr_init_expr.  */
          tree ctor = build_special_member_call
            (NULL_TREE, complete_ctor_identifier,
-            NULL_TREE, type, LOOKUP_NORMAL, tf_warning_or_error);
+            NULL, type, LOOKUP_NORMAL, tf_warning_or_error);
 
          ctor = build_aggr_init_expr (type, ctor);
          AGGR_INIT_ZERO_FIRST (ctor) = 1;
 
          ctor = build_aggr_init_expr (type, ctor);
          AGGR_INIT_ZERO_FIRST (ctor) = 1;
@@ -951,7 +951,7 @@ expand_cleanup_for_base (tree binfo, tree flag)
   /* Call the destructor.  */
   expr = build_special_member_call (current_class_ref,
                                    base_dtor_identifier,
   /* Call the destructor.  */
   expr = build_special_member_call (current_class_ref,
                                    base_dtor_identifier,
-                                   NULL_TREE,
+                                   NULL,
                                    binfo,
                                    LOOKUP_NORMAL | LOOKUP_NONVIRTUAL,
                                     tf_warning_or_error);
                                    binfo,
                                    LOOKUP_NORMAL | LOOKUP_NONVIRTUAL,
                                     tf_warning_or_error);
@@ -1285,7 +1285,7 @@ expand_default_init (tree binfo, tree true_exp, tree exp, tree init, int flags,
      followed by initialization by X.  If neither of these work
      out, then look hard.  */
   tree rval;
      followed by initialization by X.  If neither of these work
      out, then look hard.  */
   tree rval;
-  tree parms;
+  VEC(tree,gc) *parms;
 
   if (init && TREE_CODE (init) != TREE_LIST
       && (flags & LOOKUP_ONLYCONVERTING))
 
   if (init && TREE_CODE (init) != TREE_LIST
       && (flags & LOOKUP_ONLYCONVERTING))
@@ -1325,23 +1325,28 @@ expand_default_init (tree binfo, tree true_exp, tree exp, tree init, int flags,
       return;
     }
 
       return;
     }
 
-  if (init == NULL_TREE
-      || (TREE_CODE (init) == TREE_LIST && ! TREE_TYPE (init)))
+  if (init == NULL_TREE)
+    parms = NULL;
+  else if (TREE_CODE (init) == TREE_LIST && !TREE_TYPE (init))
     {
     {
-      parms = init;
-      if (parms)
-       init = TREE_VALUE (parms);
+      parms = make_tree_vector ();
+      for (; init != NULL_TREE; init = TREE_CHAIN (init))
+       VEC_safe_push (tree, gc, parms, TREE_VALUE (init));
     }
   else
     }
   else
-    parms = build_tree_list (NULL_TREE, init);
+    parms = make_tree_vector_single (init);
 
   if (true_exp == exp)
     ctor_name = complete_ctor_identifier;
   else
     ctor_name = base_ctor_identifier;
 
 
   if (true_exp == exp)
     ctor_name = complete_ctor_identifier;
   else
     ctor_name = base_ctor_identifier;
 
-  rval = build_special_member_call (exp, ctor_name, parms, binfo, flags,
+  rval = build_special_member_call (exp, ctor_name, &parms, binfo, flags,
                                     complain);
                                     complain);
+
+  if (parms != NULL)
+    release_tree_vector (parms);
+
   if (TREE_SIDE_EFFECTS (rval))
     finish_expr_stmt (convert_to_void (rval, NULL, complain));
 }
   if (TREE_SIDE_EFFECTS (rval))
     finish_expr_stmt (convert_to_void (rval, NULL, complain));
 }
@@ -1706,18 +1711,31 @@ build_builtin_delete_call (tree addr)
    the type of the object being allocated; otherwise, it's just TYPE.
    INIT is the initializer, if any.  USE_GLOBAL_NEW is true if the
    user explicitly wrote "::operator new".  PLACEMENT, if non-NULL, is
    the type of the object being allocated; otherwise, it's just TYPE.
    INIT is the initializer, if any.  USE_GLOBAL_NEW is true if the
    user explicitly wrote "::operator new".  PLACEMENT, if non-NULL, is
-   the TREE_LIST of arguments to be provided as arguments to a
-   placement new operator.  This routine performs no semantic checks;
-   it just creates and returns a NEW_EXPR.  */
+   a vector of arguments to be provided as arguments to a placement
+   new operator.  This routine performs no semantic checks; it just
+   creates and returns a NEW_EXPR.  */
 
 static tree
 
 static tree
-build_raw_new_expr (tree placement, tree type, tree nelts, tree init,
-                   int use_global_new)
+build_raw_new_expr (VEC(tree,gc) *placement, tree type, tree nelts,
+                   VEC(tree,gc) *init, int use_global_new)
 {
 {
+  tree init_list;
   tree new_expr;
 
   tree new_expr;
 
-  new_expr = build4 (NEW_EXPR, build_pointer_type (type), placement, type,
-                    nelts, init);
+  /* If INIT is NULL, the we want to store NULL_TREE in the NEW_EXPR.
+     If INIT is not NULL, then we want to store VOID_ZERO_NODE.  This
+     permits us to distinguish the case of a missing initializer "new
+     int" from an empty initializer "new int()".  */
+  if (init == NULL)
+    init_list = NULL_TREE;
+  else if (VEC_empty (tree, init))
+    init_list = void_zero_node;
+  else
+    init_list = build_tree_list_vec (init);
+
+  new_expr = build4 (NEW_EXPR, build_pointer_type (type),
+                    build_tree_list_vec (placement), type, nelts,
+                    init_list);
   NEW_EXPR_USE_GLOBAL (new_expr) = use_global_new;
   TREE_SIDE_EFFECTS (new_expr) = 1;
 
   NEW_EXPR_USE_GLOBAL (new_expr) = use_global_new;
   TREE_SIDE_EFFECTS (new_expr) = 1;
 
@@ -1776,11 +1794,12 @@ avoid_placement_new_aliasing (tree t, tree placement)
 /* Generate code for a new-expression, including calling the "operator
    new" function, initializing the object, and, if an exception occurs
    during construction, cleaning up.  The arguments are as for
 /* Generate code for a new-expression, including calling the "operator
    new" function, initializing the object, and, if an exception occurs
    during construction, cleaning up.  The arguments are as for
-   build_raw_new_expr.  */
+   build_raw_new_expr.  This may change PLACEMENT and INIT.  */
 
 static tree
 
 static tree
-build_new_1 (tree placement, tree type, tree nelts, tree init,
-            bool globally_qualified_p, tsubst_flags_t complain)
+build_new_1 (VEC(tree,gc) **placement, tree type, tree nelts,
+            VEC(tree,gc) **init, bool globally_qualified_p,
+            tsubst_flags_t complain)
 {
   tree size, rval;
   /* True iff this is a call to "operator new[]" instead of just
 {
   tree size, rval;
   /* True iff this is a call to "operator new[]" instead of just
@@ -1807,11 +1826,12 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
      beginning of the storage allocated for an array-new expression in
      order to store the number of elements.  */
   tree cookie_size = NULL_TREE;
      beginning of the storage allocated for an array-new expression in
      order to store the number of elements.  */
   tree cookie_size = NULL_TREE;
+  bool have_placement;
+  tree placement_first;
   tree placement_expr = NULL_TREE;
   /* True if the function we are calling is a placement allocation
      function.  */
   bool placement_allocation_fn_p;
   tree placement_expr = NULL_TREE;
   /* True if the function we are calling is a placement allocation
      function.  */
   bool placement_allocation_fn_p;
-  tree args = NULL_TREE;
   /* True if the storage must be initialized, either by a constructor
      or due to an explicit new-initializer.  */
   bool is_initialized;
   /* True if the storage must be initialized, either by a constructor
      or due to an explicit new-initializer.  */
   bool is_initialized;
@@ -1855,9 +1875,9 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
   if (abstract_virtuals_error (NULL_TREE, elt_type))
     return error_mark_node;
 
   if (abstract_virtuals_error (NULL_TREE, elt_type))
     return error_mark_node;
 
-  is_initialized = (TYPE_NEEDS_CONSTRUCTING (elt_type) || init);
+  is_initialized = (TYPE_NEEDS_CONSTRUCTING (elt_type) || *init != NULL);
 
 
-  if (CP_TYPE_CONST_P (elt_type) && !init
+  if (CP_TYPE_CONST_P (elt_type) && *init == NULL
       && !type_has_user_provided_default_constructor (elt_type))
     {
       if (complain & tf_error)
       && !type_has_user_provided_default_constructor (elt_type))
     {
       if (complain & tf_error)
@@ -1871,8 +1891,18 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
 
   alloc_fn = NULL_TREE;
 
 
   alloc_fn = NULL_TREE;
 
+  /* If PLACEMENT is a single simple pointer type not passed by
+     reference, prepare to capture it in a temporary variable.  Do
+     this now, since PLACEMENT will change in the calls below.  */
+  have_placement = !VEC_empty (tree, *placement);
+  placement_first = NULL_TREE;
+  if (VEC_length (tree, *placement) == 1
+      && (TREE_CODE (TREE_TYPE (VEC_index (tree, *placement, 0)))
+         == POINTER_TYPE))
+    placement_first = VEC_index (tree, *placement, 0);
+
   /* Allocate the object.  */
   /* Allocate the object.  */
-  if (! placement && TYPE_FOR_JAVA (elt_type))
+  if (VEC_empty (tree, *placement) && TYPE_FOR_JAVA (elt_type))
     {
       tree class_addr;
       tree class_decl = build_java_class_ref (elt_type);
     {
       tree class_addr;
       tree class_decl = build_java_class_ref (elt_type);
@@ -1928,7 +1958,7 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
              size = size_binop (PLUS_EXPR, size, cookie_size);
            }
          /* Create the argument list.  */
              size = size_binop (PLUS_EXPR, size, cookie_size);
            }
          /* Create the argument list.  */
-         args = tree_cons (NULL_TREE, size, placement);
+         VEC_safe_insert (tree, gc, *placement, 0, size);
          /* Do name-lookup to find the appropriate operator.  */
          fns = lookup_fnfields (elt_type, fnname, /*protect=*/2);
          if (fns == NULL_TREE)
          /* Do name-lookup to find the appropriate operator.  */
          fns = lookup_fnfields (elt_type, fnname, /*protect=*/2);
          if (fns == NULL_TREE)
@@ -1947,7 +1977,7 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
              return error_mark_node;
            }
          alloc_call = build_new_method_call (build_dummy_object (elt_type),
              return error_mark_node;
            }
          alloc_call = build_new_method_call (build_dummy_object (elt_type),
-                                             fns, args,
+                                             fns, placement,
                                              /*conversion_path=*/NULL_TREE,
                                              LOOKUP_NORMAL,
                                              &alloc_fn,
                                              /*conversion_path=*/NULL_TREE,
                                              LOOKUP_NORMAL,
                                              &alloc_fn,
@@ -1973,12 +2003,10 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
 
   gcc_assert (alloc_fn != NULL_TREE);
 
 
   gcc_assert (alloc_fn != NULL_TREE);
 
-  /* If PLACEMENT is a simple pointer type and is not passed by reference,
-     then copy it into PLACEMENT_EXPR.  */
+  /* If we found a simple case of PLACEMENT_EXPR above, then copy it
+     into a temporary variable.  */
   if (!processing_template_decl
   if (!processing_template_decl
-      && placement != NULL_TREE
-      && TREE_CHAIN (placement) == NULL_TREE
-      && TREE_CODE (TREE_TYPE (TREE_VALUE (placement))) == POINTER_TYPE
+      && placement_first != NULL_TREE
       && TREE_CODE (alloc_call) == CALL_EXPR
       && call_expr_nargs (alloc_call) == 2
       && TREE_CODE (TREE_TYPE (CALL_EXPR_ARG (alloc_call, 0))) == INTEGER_TYPE
       && TREE_CODE (alloc_call) == CALL_EXPR
       && call_expr_nargs (alloc_call) == 2
       && TREE_CODE (TREE_TYPE (CALL_EXPR_ARG (alloc_call, 0))) == INTEGER_TYPE
@@ -1989,7 +2017,7 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
       if (INTEGRAL_TYPE_P (TREE_TYPE (TREE_TYPE (placement_arg)))
          || VOID_TYPE_P (TREE_TYPE (TREE_TYPE (placement_arg))))
        {
       if (INTEGRAL_TYPE_P (TREE_TYPE (TREE_TYPE (placement_arg)))
          || VOID_TYPE_P (TREE_TYPE (TREE_TYPE (placement_arg))))
        {
-         placement_expr = get_target_expr (TREE_VALUE (placement));
+         placement_expr = get_target_expr (placement_first);
          CALL_EXPR_ARG (alloc_call, 1)
            = convert (TREE_TYPE (placement_arg), placement_expr);
        }
          CALL_EXPR_ARG (alloc_call, 1)
            = convert (TREE_TYPE (placement_arg), placement_expr);
        }
@@ -2000,7 +2028,7 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
   if (!cookie_size && !is_initialized)
     {
       rval = build_nop (pointer_type, alloc_call);
   if (!cookie_size && !is_initialized)
     {
       rval = build_nop (pointer_type, alloc_call);
-      if (placement != NULL)
+      if (have_placement)
        rval = avoid_placement_new_aliasing (rval, placement_expr);
       return rval;
     }
        rval = avoid_placement_new_aliasing (rval, placement_expr);
       return rval;
     }
@@ -2109,15 +2137,15 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
       bool stable;
       bool explicit_value_init_p = false;
 
       bool stable;
       bool explicit_value_init_p = false;
 
-      if (init == void_zero_node)
+      if (*init != NULL && VEC_empty (tree, *init))
        {
        {
-         init = NULL_TREE;
+         *init = NULL;
          explicit_value_init_p = true;
        }
 
       if (array_p)
        {
          explicit_value_init_p = true;
        }
 
       if (array_p)
        {
-         if (init)
+         if (*init)
             {
               if (complain & tf_error)
                 permerror (input_location, "ISO C++ forbids initialization in array new");
             {
               if (complain & tf_error)
                 permerror (input_location, "ISO C++ forbids initialization in array new");
@@ -2130,7 +2158,7 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
                                                  MINUS_EXPR, outer_nelts,
                                                  integer_one_node,
                                                  complain),
                                                  MINUS_EXPR, outer_nelts,
                                                  integer_one_node,
                                                  complain),
-                             init,
+                             build_tree_list_vec (*init),
                              explicit_value_init_p,
                              /*from_array=*/0,
                               complain);
                              explicit_value_init_p,
                              /*from_array=*/0,
                               complain);
@@ -2160,17 +2188,13 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
            }
          else
            {
            }
          else
            {
+             tree ie;
+
              /* We are processing something like `new int (10)', which
                 means allocate an int, and initialize it with 10.  */
 
              /* We are processing something like `new int (10)', which
                 means allocate an int, and initialize it with 10.  */
 
-             if (TREE_CODE (init) == TREE_LIST)
-               init = build_x_compound_expr_from_list (init,
-                                                       "new initializer");
-             else
-               gcc_assert (TREE_CODE (init) != CONSTRUCTOR
-                           || TREE_TYPE (init) != NULL_TREE);
-
-             init_expr = cp_build_modify_expr (init_expr, INIT_EXPR, init,
+             ie = build_x_compound_expr_from_vec (*init, "new initializer");
+             init_expr = cp_build_modify_expr (init_expr, INIT_EXPR, ie,
                                                complain);
            }
          stable = stabilize_init (init_expr, &init_preeval_expr);
                                                complain);
            }
          stable = stabilize_init (init_expr, &init_preeval_expr);
@@ -2283,60 +2307,58 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
   /* A new-expression is never an lvalue.  */
   gcc_assert (!lvalue_p (rval));
 
   /* A new-expression is never an lvalue.  */
   gcc_assert (!lvalue_p (rval));
 
-  if (placement != NULL)
+  if (have_placement)
     rval = avoid_placement_new_aliasing (rval, placement_expr);
 
   return rval;
 }
 
     rval = avoid_placement_new_aliasing (rval, placement_expr);
 
   return rval;
 }
 
-/* Generate a representation for a C++ "new" expression.  PLACEMENT is
-   a TREE_LIST of placement-new arguments (or NULL_TREE if none).  If
-   NELTS is NULL, TYPE is the type of the storage to be allocated.  If
-   NELTS is not NULL, then this is an array-new allocation; TYPE is
-   the type of the elements in the array and NELTS is the number of
-   elements in the array.  INIT, if non-NULL, is the initializer for
-   the new object, or void_zero_node to indicate an initializer of
-   "()".  If USE_GLOBAL_NEW is true, then the user explicitly wrote
-   "::new" rather than just "new".  */
+/* Generate a representation for a C++ "new" expression.  *PLACEMENT
+   is a vector of placement-new arguments (or NULL if none).  If NELTS
+   is NULL, TYPE is the type of the storage to be allocated.  If NELTS
+   is not NULL, then this is an array-new allocation; TYPE is the type
+   of the elements in the array and NELTS is the number of elements in
+   the array.  *INIT, if non-NULL, is the initializer for the new
+   object, or an empty vector to indicate an initializer of "()".  If
+   USE_GLOBAL_NEW is true, then the user explicitly wrote "::new"
+   rather than just "new".  This may change PLACEMENT and INIT.  */
 
 tree
 
 tree
-build_new (tree placement, tree type, tree nelts, tree init,
-          int use_global_new, tsubst_flags_t complain)
+build_new (VEC(tree,gc) **placement, tree type, tree nelts,
+          VEC(tree,gc) **init, int use_global_new, tsubst_flags_t complain)
 {
   tree rval;
 {
   tree rval;
-  tree orig_placement;
-  tree orig_nelts;
-  tree orig_init;
+  VEC(tree,gc) *orig_placement = NULL;
+  tree orig_nelts = NULL_TREE;
+  VEC(tree,gc) *orig_init = NULL;
 
 
-  if (placement == error_mark_node || type == error_mark_node
-      || init == error_mark_node)
+  if (type == error_mark_node)
     return error_mark_node;
 
     return error_mark_node;
 
-  orig_placement = placement;
-  orig_nelts = nelts;
-  orig_init = init;
-
-  if (nelts == NULL_TREE && init != void_zero_node && list_length (init) == 1)
+  if (nelts == NULL_TREE && VEC_length (tree, *init) == 1)
     {
       tree auto_node = type_uses_auto (type);
     {
       tree auto_node = type_uses_auto (type);
-      if (auto_node && describable_type (TREE_VALUE (init)))
-       type = do_auto_deduction (type, TREE_VALUE (init), auto_node);
+      if (auto_node && describable_type (VEC_index (tree, *init, 0)))
+       type = do_auto_deduction (type, VEC_index (tree, *init, 0), auto_node);
     }
 
   if (processing_template_decl)
     {
       if (dependent_type_p (type)
     }
 
   if (processing_template_decl)
     {
       if (dependent_type_p (type)
-         || any_type_dependent_arguments_p (placement)
+         || any_type_dependent_arguments_p (*placement)
          || (nelts && type_dependent_expression_p (nelts))
          || (nelts && type_dependent_expression_p (nelts))
-         || (init != void_zero_node
-             && any_type_dependent_arguments_p (init)))
-       return build_raw_new_expr (placement, type, nelts, init,
+         || any_type_dependent_arguments_p (*init))
+       return build_raw_new_expr (*placement, type, nelts, *init,
                                   use_global_new);
                                   use_global_new);
-      placement = build_non_dependent_args (placement);
+
+      orig_placement = make_tree_vector_copy (*placement);
+      orig_nelts = nelts;
+      orig_init = make_tree_vector_copy (*init);
+
+      make_args_non_dependent (*placement);
       if (nelts)
        nelts = build_non_dependent_expr (nelts);
       if (nelts)
        nelts = build_non_dependent_expr (nelts);
-      if (init != void_zero_node)
-       init = build_non_dependent_args (init);
+      make_args_non_dependent (*init);
     }
 
   if (nelts)
     }
 
   if (nelts)
@@ -2381,8 +2403,13 @@ build_new (tree placement, tree type, tree nelts, tree init,
     return error_mark_node;
 
   if (processing_template_decl)
     return error_mark_node;
 
   if (processing_template_decl)
-    return build_raw_new_expr (orig_placement, type, orig_nelts, orig_init,
-                              use_global_new);
+    {
+      tree ret = build_raw_new_expr (orig_placement, type, orig_nelts,
+                                    orig_init, use_global_new);
+      release_tree_vector (orig_placement);
+      release_tree_vector (orig_init);
+      return ret;
+    }
 
   /* Wrap it in a NOP_EXPR so warn_if_unused_value doesn't complain.  */
   rval = build1 (NOP_EXPR, TREE_TYPE (rval), rval);
 
   /* Wrap it in a NOP_EXPR so warn_if_unused_value doesn't complain.  */
   rval = build1 (NOP_EXPR, TREE_TYPE (rval), rval);
@@ -2954,7 +2981,7 @@ build_dtor_call (tree exp, special_function_kind dtor_kind, int flags)
     }
   fn = lookup_fnfields (TREE_TYPE (exp), name, /*protect=*/2);
   return build_new_method_call (exp, fn,
     }
   fn = lookup_fnfields (TREE_TYPE (exp), name, /*protect=*/2);
   return build_new_method_call (exp, fn,
-                               /*args=*/NULL_TREE,
+                               /*args=*/NULL,
                                /*conversion_path=*/NULL_TREE,
                                flags,
                                /*fn_p=*/NULL,
                                /*conversion_path=*/NULL_TREE,
                                flags,
                                /*fn_p=*/NULL,
@@ -3172,7 +3199,7 @@ push_base_cleanups (void)
            {
              expr = build_special_member_call (current_class_ref,
                                                base_dtor_identifier,
            {
              expr = build_special_member_call (current_class_ref,
                                                base_dtor_identifier,
-                                               NULL_TREE,
+                                               NULL,
                                                base_binfo,
                                                (LOOKUP_NORMAL
                                                 | LOOKUP_NONVIRTUAL),
                                                base_binfo,
                                                (LOOKUP_NORMAL
                                                 | LOOKUP_NONVIRTUAL),
@@ -3194,7 +3221,7 @@ push_base_cleanups (void)
 
       expr = build_special_member_call (current_class_ref,
                                        base_dtor_identifier,
 
       expr = build_special_member_call (current_class_ref,
                                        base_dtor_identifier,
-                                       NULL_TREE, base_binfo,
+                                       NULL, base_binfo,
                                        LOOKUP_NORMAL | LOOKUP_NONVIRTUAL,
                                         tf_warning_or_error);
       finish_decl_cleanup (NULL_TREE, expr);
                                        LOOKUP_NORMAL | LOOKUP_NONVIRTUAL,
                                         tf_warning_or_error);
       finish_decl_cleanup (NULL_TREE, expr);
index e632fe0..410503d 100644 (file)
@@ -1,7 +1,7 @@
 /* Handle the hair of processing (but not expanding) inline functions.
    Also manage function and variable name overloading.
    Copyright (C) 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
 /* Handle the hair of processing (but not expanding) inline functions.
    Also manage function and variable name overloading.
    Copyright (C) 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008
+   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009
    Free Software Foundation, Inc.
    Contributed by Michael Tiemann (tiemann@cygnus.com)
 
    Free Software Foundation, Inc.
    Contributed by Michael Tiemann (tiemann@cygnus.com)
 
@@ -661,19 +661,21 @@ do_build_assign_ref (tree fndecl)
           BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
        {
          tree converted_parm;
           BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
        {
          tree converted_parm;
+         VEC(tree,gc) *parmvec;
 
          /* We must convert PARM directly to the base class
             explicitly since the base class may be ambiguous.  */
          converted_parm = build_base_path (PLUS_EXPR, parm, base_binfo, 1);
          /* Call the base class assignment operator.  */
 
          /* We must convert PARM directly to the base class
             explicitly since the base class may be ambiguous.  */
          converted_parm = build_base_path (PLUS_EXPR, parm, base_binfo, 1);
          /* Call the base class assignment operator.  */
+         parmvec = make_tree_vector_single (converted_parm);
          finish_expr_stmt
            (build_special_member_call (current_class_ref,
                                        ansi_assopname (NOP_EXPR),
          finish_expr_stmt
            (build_special_member_call (current_class_ref,
                                        ansi_assopname (NOP_EXPR),
-                                       build_tree_list (NULL_TREE,
-                                                        converted_parm),
+                                       &parmvec,
                                        base_binfo,
                                        LOOKUP_NORMAL | LOOKUP_NONVIRTUAL,
                                         tf_warning_or_error));
                                        base_binfo,
                                        LOOKUP_NORMAL | LOOKUP_NONVIRTUAL,
                                         tf_warning_or_error));
+         release_tree_vector (parmvec);
        }
 
       /* Assign to each of the non-static data members.  */
        }
 
       /* Assign to each of the non-static data members.  */
index e499ede..215750f 100644 (file)
@@ -4235,7 +4235,7 @@ lookup_name_nonclass (tree name)
 }
 
 tree
 }
 
 tree
-lookup_function_nonclass (tree name, tree args, bool block_p)
+lookup_function_nonclass (tree name, VEC(tree,gc) *args, bool block_p)
 {
   return
     lookup_arg_dependent (name,
 {
   return
     lookup_arg_dependent (name,
@@ -4427,7 +4427,7 @@ lookup_type_current_level (tree name)
 struct arg_lookup
 {
   tree name;
 struct arg_lookup
 {
   tree name;
-  tree args;
+  VEC(tree,gc) *args;
   tree namespaces;
   tree classes;
   tree functions;
   tree namespaces;
   tree classes;
   tree functions;
@@ -4435,6 +4435,7 @@ struct arg_lookup
 
 static bool arg_assoc (struct arg_lookup*, tree);
 static bool arg_assoc_args (struct arg_lookup*, tree);
 
 static bool arg_assoc (struct arg_lookup*, tree);
 static bool arg_assoc_args (struct arg_lookup*, tree);
+static bool arg_assoc_args_vec (struct arg_lookup*, VEC(tree,gc) *);
 static bool arg_assoc_type (struct arg_lookup*, tree);
 static bool add_function (struct arg_lookup *, tree);
 static bool arg_assoc_namespace (struct arg_lookup *, tree);
 static bool arg_assoc_type (struct arg_lookup*, tree);
 static bool add_function (struct arg_lookup *, tree);
 static bool arg_assoc_namespace (struct arg_lookup *, tree);
@@ -4589,13 +4590,13 @@ arg_assoc_namespace (struct arg_lookup *k, tree scope)
         classes.  */
       if (hidden_name_p (OVL_CURRENT (value)))
        {
         classes.  */
       if (hidden_name_p (OVL_CURRENT (value)))
        {
-         tree args;
+         unsigned int ix;
+         tree arg;
 
 
-         for (args = k->args; args; args = TREE_CHAIN (args))
-           if (friend_of_associated_class_p (TREE_VALUE (args),
-                                             OVL_CURRENT (value)))
+         for (ix = 0; VEC_iterate (tree, k->args, ix, arg); ++ix)
+           if (friend_of_associated_class_p (arg, OVL_CURRENT (value)))
              break;
              break;
-         if (!args)
+         if (ix >= VEC_length (tree, k->args))
            continue;
        }
 
            continue;
        }
 
@@ -4805,6 +4806,21 @@ arg_assoc_args (struct arg_lookup *k, tree args)
   return false;
 }
 
   return false;
 }
 
+/* Adds everything associated with an argument vector.  Returns true
+   on error.  */
+
+static bool
+arg_assoc_args_vec (struct arg_lookup *k, VEC(tree,gc) *args)
+{
+  unsigned int ix;
+  tree arg;
+
+  for (ix = 0; VEC_iterate (tree, args, ix, arg); ++ix)
+    if (arg_assoc (k, arg))
+      return true;
+  return false;
+}
+
 /* Adds everything associated with a given tree_node.  Returns 1 on error.  */
 
 static bool
 /* Adds everything associated with a given tree_node.  Returns 1 on error.  */
 
 static bool
@@ -4884,7 +4900,7 @@ arg_assoc (struct arg_lookup *k, tree n)
    are the functions found in normal lookup.  */
 
 tree
    are the functions found in normal lookup.  */
 
 tree
-lookup_arg_dependent (tree name, tree fns, tree args)
+lookup_arg_dependent (tree name, tree fns, VEC(tree,gc) *args)
 {
   struct arg_lookup k;
 
 {
   struct arg_lookup k;
 
@@ -4907,7 +4923,7 @@ lookup_arg_dependent (tree name, tree fns, tree args)
      picking up later definitions) in the second stage. */
   k.namespaces = NULL_TREE;
 
      picking up later definitions) in the second stage. */
   k.namespaces = NULL_TREE;
 
-  arg_assoc_args (&k, args);
+  arg_assoc_args_vec (&k, args);
 
   fns = k.functions;
   
 
   fns = k.functions;
   
index 6de4cfa..2203a84 100644 (file)
@@ -1,5 +1,6 @@
 /* Declarations for C++ name lookup routines.
 /* Declarations for C++ name lookup routines.
-   Copyright (C) 2003, 2004, 2005, 2007, 2008  Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009
+   Free Software Foundation, Inc.
    Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
 
 This file is part of GCC.
    Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
 
 This file is part of GCC.
@@ -317,7 +318,7 @@ extern tree remove_hidden_names (tree);
 extern tree lookup_qualified_name (tree, tree, bool, bool);
 extern tree lookup_name_nonclass (tree);
 extern tree lookup_name_innermost_nonclass_level (tree);
 extern tree lookup_qualified_name (tree, tree, bool, bool);
 extern tree lookup_name_nonclass (tree);
 extern tree lookup_name_innermost_nonclass_level (tree);
-extern tree lookup_function_nonclass (tree, tree, bool);
+extern tree lookup_function_nonclass (tree, VEC(tree,gc) *, bool);
 extern void push_local_binding (tree, tree, int);
 extern bool pushdecl_class_level (tree);
 extern tree pushdecl_namespace_level (tree, bool);
 extern void push_local_binding (tree, tree, int);
 extern bool pushdecl_class_level (tree);
 extern tree pushdecl_namespace_level (tree, bool);
@@ -332,7 +333,7 @@ extern void do_toplevel_using_decl (tree, tree, tree);
 extern void do_local_using_decl (tree, tree, tree);
 extern tree do_class_using_decl (tree, tree);
 extern void do_using_directive (tree);
 extern void do_local_using_decl (tree, tree, tree);
 extern tree do_class_using_decl (tree, tree);
 extern void do_using_directive (tree);
-extern tree lookup_arg_dependent (tree, tree, tree);
+extern tree lookup_arg_dependent (tree, tree, VEC(tree,gc) *);
 extern bool is_associated_namespace (tree, tree);
 extern void parse_using_directive (tree, tree);
 extern tree innermost_non_namespace_value (tree);
 extern bool is_associated_namespace (tree, tree);
 extern void parse_using_directive (tree, tree);
 extern tree innermost_non_namespace_value (tree);
index 6954ef0..e7d2e7d 100644 (file)
@@ -1584,7 +1584,7 @@ static tree cp_parser_postfix_open_square_expression
   (cp_parser *, tree, bool);
 static tree cp_parser_postfix_dot_deref_expression
   (cp_parser *, enum cpp_ttype, tree, bool, cp_id_kind *, location_t);
   (cp_parser *, tree, bool);
 static tree cp_parser_postfix_dot_deref_expression
   (cp_parser *, enum cpp_ttype, tree, bool, cp_id_kind *, location_t);
-static tree cp_parser_parenthesized_expression_list
+static VEC(tree,gc) *cp_parser_parenthesized_expression_list
   (cp_parser *, bool, bool, bool, bool *);
 static void cp_parser_pseudo_destructor_name
   (cp_parser *, tree *, tree *);
   (cp_parser *, bool, bool, bool, bool *);
 static void cp_parser_pseudo_destructor_name
   (cp_parser *, tree *, tree *);
@@ -1594,7 +1594,7 @@ static enum tree_code cp_parser_unary_operator
   (cp_token *);
 static tree cp_parser_new_expression
   (cp_parser *);
   (cp_token *);
 static tree cp_parser_new_expression
   (cp_parser *);
-static tree cp_parser_new_placement
+static VEC(tree,gc) *cp_parser_new_placement
   (cp_parser *);
 static tree cp_parser_new_type_id
   (cp_parser *, tree *);
   (cp_parser *);
 static tree cp_parser_new_type_id
   (cp_parser *, tree *);
@@ -1602,7 +1602,7 @@ static cp_declarator *cp_parser_new_declarator_opt
   (cp_parser *);
 static cp_declarator *cp_parser_direct_new_declarator
   (cp_parser *);
   (cp_parser *);
 static cp_declarator *cp_parser_direct_new_declarator
   (cp_parser *);
-static tree cp_parser_new_initializer
+static VEC(tree,gc) *cp_parser_new_initializer
   (cp_parser *);
 static tree cp_parser_delete_expression
   (cp_parser *);
   (cp_parser *);
 static tree cp_parser_delete_expression
   (cp_parser *);
@@ -4685,7 +4685,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
            bool is_builtin_constant_p;
            bool saved_integral_constant_expression_p = false;
            bool saved_non_integral_constant_expression_p = false;
            bool is_builtin_constant_p;
            bool saved_integral_constant_expression_p = false;
            bool saved_non_integral_constant_expression_p = false;
-           tree args;
+           VEC(tree,gc) *args;
 
             is_member_access = false;
 
 
             is_member_access = false;
 
@@ -4713,7 +4713,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
                  = saved_non_integral_constant_expression_p;
              }
 
                  = saved_non_integral_constant_expression_p;
              }
 
-           if (args == error_mark_node)
+           if (args == NULL)
              {
                postfix_expression = error_mark_node;
                break;
              {
                postfix_expression = error_mark_node;
                break;
@@ -4726,6 +4726,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
                                                               "a function call"))
              {
                postfix_expression = error_mark_node;
                                                               "a function call"))
              {
                postfix_expression = error_mark_node;
+               release_tree_vector (args);
                break;
              }
 
                break;
              }
 
@@ -4735,7 +4736,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
              {
                if (TREE_CODE (postfix_expression) == IDENTIFIER_NODE)
                  {
              {
                if (TREE_CODE (postfix_expression) == IDENTIFIER_NODE)
                  {
-                   if (args)
+                   if (!VEC_empty (tree, args))
                      {
                        koenig_p = true;
                        if (!any_type_dependent_arguments_p (args))
                      {
                        koenig_p = true;
                        if (!any_type_dependent_arguments_p (args))
@@ -4749,7 +4750,8 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
                /* We do not perform argument-dependent lookup if
                   normal lookup finds a non-function, in accordance
                   with the expected resolution of DR 218.  */
                /* We do not perform argument-dependent lookup if
                   normal lookup finds a non-function, in accordance
                   with the expected resolution of DR 218.  */
-               else if (args && is_overloaded_fn (postfix_expression))
+               else if (!VEC_empty (tree, args)
+                        && is_overloaded_fn (postfix_expression))
                  {
                    tree fn = get_first_fn (postfix_expression);
 
                  {
                    tree fn = get_first_fn (postfix_expression);
 
@@ -4782,7 +4784,8 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
                        || any_type_dependent_arguments_p (args)))
                  {
                    postfix_expression
                        || any_type_dependent_arguments_p (args)))
                  {
                    postfix_expression
-                     = build_nt_call_list (postfix_expression, args);
+                     = build_nt_call_vec (postfix_expression, args);
+                   release_tree_vector (args);
                    break;
                  }
 
                    break;
                  }
 
@@ -4790,7 +4793,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
                  {
                  postfix_expression
                    = (build_new_method_call
                  {
                  postfix_expression
                    = (build_new_method_call
-                      (instance, fn, args, NULL_TREE,
+                      (instance, fn, &args, NULL_TREE,
                        (idk == CP_ID_KIND_QUALIFIED
                         ? LOOKUP_NONVIRTUAL : LOOKUP_NORMAL),
                        /*fn_p=*/NULL,
                        (idk == CP_ID_KIND_QUALIFIED
                         ? LOOKUP_NONVIRTUAL : LOOKUP_NORMAL),
                        /*fn_p=*/NULL,
@@ -4798,7 +4801,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
                  }
                else
                  postfix_expression
                  }
                else
                  postfix_expression
-                   = finish_call_expr (postfix_expression, args,
+                   = finish_call_expr (postfix_expression, &args,
                                        /*disallow_virtual=*/false,
                                        /*koenig_p=*/false,
                                        tf_warning_or_error);
                                        /*disallow_virtual=*/false,
                                        /*koenig_p=*/false,
                                        tf_warning_or_error);
@@ -4807,25 +4810,27 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
                     || TREE_CODE (postfix_expression) == MEMBER_REF
                     || TREE_CODE (postfix_expression) == DOTSTAR_EXPR)
              postfix_expression = (build_offset_ref_call_from_tree
                     || TREE_CODE (postfix_expression) == MEMBER_REF
                     || TREE_CODE (postfix_expression) == DOTSTAR_EXPR)
              postfix_expression = (build_offset_ref_call_from_tree
-                                   (postfix_expression, args));
+                                   (postfix_expression, &args));
            else if (idk == CP_ID_KIND_QUALIFIED)
              /* A call to a static class member, or a namespace-scope
                 function.  */
              postfix_expression
            else if (idk == CP_ID_KIND_QUALIFIED)
              /* A call to a static class member, or a namespace-scope
                 function.  */
              postfix_expression
-               = finish_call_expr (postfix_expression, args,
+               = finish_call_expr (postfix_expression, &args,
                                    /*disallow_virtual=*/true,
                                    koenig_p,
                                    tf_warning_or_error);
            else
              /* All other function calls.  */
              postfix_expression
                                    /*disallow_virtual=*/true,
                                    koenig_p,
                                    tf_warning_or_error);
            else
              /* All other function calls.  */
              postfix_expression
-               = finish_call_expr (postfix_expression, args,
+               = finish_call_expr (postfix_expression, &args,
                                    /*disallow_virtual=*/false,
                                    koenig_p,
                                    tf_warning_or_error);
 
            /* The POSTFIX_EXPRESSION is certainly no longer an id.  */
            idk = CP_ID_KIND_NONE;
                                    /*disallow_virtual=*/false,
                                    koenig_p,
                                    tf_warning_or_error);
 
            /* The POSTFIX_EXPRESSION is certainly no longer an id.  */
            idk = CP_ID_KIND_NONE;
+
+           release_tree_vector (args);
          }
          break;
 
          }
          break;
 
@@ -5132,24 +5137,22 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser,
    ALLOW_EXPANSION_P is true if this expression allows expansion of an
    argument pack.
 
    ALLOW_EXPANSION_P is true if this expression allows expansion of an
    argument pack.
 
-   Returns a TREE_LIST.  The TREE_VALUE of each node is a
-   representation of an assignment-expression.  Note that a TREE_LIST
-   is returned even if there is only a single expression in the list.
-   error_mark_node is returned if the ( and or ) are
-   missing. NULL_TREE is returned on no expressions. The parentheses
-   are eaten. IS_ATTRIBUTE_LIST is true if this is really an attribute
-   list being parsed.  If NON_CONSTANT_P is non-NULL, *NON_CONSTANT_P
-   indicates whether or not all of the expressions in the list were
-   constant.  */
+   Returns a vector of trees.  Each element is a representation of an
+   assignment-expression.  NULL is returned if the ( and or ) are
+   missing.  An empty, but allocated, vector is returned on no
+   expressions.  The parentheses are eaten.  IS_ATTRIBUTE_LIST is true
+   if this is really an attribute list being parsed.  If
+   NON_CONSTANT_P is non-NULL, *NON_CONSTANT_P indicates whether or
+   not all of the expressions in the list were constant.  */
 
 
-static tree
+static VEC(tree,gc) *
 cp_parser_parenthesized_expression_list (cp_parser* parser,
                                         bool is_attribute_list,
                                         bool cast_p,
                                          bool allow_expansion_p,
                                         bool *non_constant_p)
 {
 cp_parser_parenthesized_expression_list (cp_parser* parser,
                                         bool is_attribute_list,
                                         bool cast_p,
                                          bool allow_expansion_p,
                                         bool *non_constant_p)
 {
-  tree expression_list = NULL_TREE;
+  VEC(tree,gc) *expression_list;
   bool fold_expr_p = is_attribute_list;
   tree identifier = NULL_TREE;
   bool saved_greater_than_is_operator_p;
   bool fold_expr_p = is_attribute_list;
   tree identifier = NULL_TREE;
   bool saved_greater_than_is_operator_p;
@@ -5159,7 +5162,9 @@ cp_parser_parenthesized_expression_list (cp_parser* parser,
     *non_constant_p = false;
 
   if (!cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>"))
     *non_constant_p = false;
 
   if (!cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>"))
-    return error_mark_node;
+    return NULL;
+
+  expression_list = make_tree_vector ();
 
   /* Within a parenthesized expression, a `>' token is always
      the greater-than operator.  */
 
   /* Within a parenthesized expression, a `>' token is always
      the greater-than operator.  */
@@ -5228,7 +5233,7 @@ cp_parser_parenthesized_expression_list (cp_parser* parser,
                expressions to the list, so that we can still tell if
                the correct form for a parenthesized expression-list
                is found. That gives better errors.  */
                expressions to the list, so that we can still tell if
                the correct form for a parenthesized expression-list
                is found. That gives better errors.  */
-           expression_list = tree_cons (NULL_TREE, expr, expression_list);
+           VEC_safe_push (tree, gc, expression_list, expr);
 
            if (expr == error_mark_node)
              goto skip_comma;
 
            if (expr == error_mark_node)
              goto skip_comma;
@@ -5264,17 +5269,15 @@ cp_parser_parenthesized_expression_list (cp_parser* parser,
        {
          parser->greater_than_is_operator_p
            = saved_greater_than_is_operator_p;
        {
          parser->greater_than_is_operator_p
            = saved_greater_than_is_operator_p;
-         return error_mark_node;
+         return NULL;
        }
     }
 
   parser->greater_than_is_operator_p
     = saved_greater_than_is_operator_p;
 
        }
     }
 
   parser->greater_than_is_operator_p
     = saved_greater_than_is_operator_p;
 
-  /* We built up the list in reverse order so we must reverse it now.  */
-  expression_list = nreverse (expression_list);
   if (identifier)
   if (identifier)
-    expression_list = tree_cons (NULL_TREE, identifier, expression_list);
+    VEC_safe_insert (tree, gc, expression_list, 0, identifier);
 
   return expression_list;
 }
 
   return expression_list;
 }
@@ -5618,10 +5621,11 @@ static tree
 cp_parser_new_expression (cp_parser* parser)
 {
   bool global_scope_p;
 cp_parser_new_expression (cp_parser* parser)
 {
   bool global_scope_p;
-  tree placement;
+  VEC(tree,gc) *placement;
   tree type;
   tree type;
-  tree initializer;
+  VEC(tree,gc) *initializer;
   tree nelts;
   tree nelts;
+  tree ret;
 
   /* Look for the optional `::' operator.  */
   global_scope_p
 
   /* Look for the optional `::' operator.  */
   global_scope_p
@@ -5637,7 +5641,11 @@ cp_parser_new_expression (cp_parser* parser)
   placement = cp_parser_new_placement (parser);
   /* If that didn't work out, there's no new-placement.  */
   if (!cp_parser_parse_definitely (parser))
   placement = cp_parser_new_placement (parser);
   /* If that didn't work out, there's no new-placement.  */
   if (!cp_parser_parse_definitely (parser))
-    placement = NULL_TREE;
+    {
+      if (placement != NULL)
+       release_tree_vector (placement);
+      placement = NULL;
+    }
 
   /* If the next token is a `(', then we have a parenthesized
      type-id.  */
 
   /* If the next token is a `(', then we have a parenthesized
      type-id.  */
@@ -5673,16 +5681,25 @@ cp_parser_new_expression (cp_parser* parser)
       || cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
     initializer = cp_parser_new_initializer (parser);
   else
       || cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
     initializer = cp_parser_new_initializer (parser);
   else
-    initializer = NULL_TREE;
+    initializer = NULL;
 
   /* A new-expression may not appear in an integral constant
      expression.  */
   if (cp_parser_non_integral_constant_expression (parser, "%<new%>"))
 
   /* A new-expression may not appear in an integral constant
      expression.  */
   if (cp_parser_non_integral_constant_expression (parser, "%<new%>"))
-    return error_mark_node;
+    ret = error_mark_node;
+  else
+    {
+      /* Create a representation of the new-expression.  */
+      ret = build_new (&placement, type, nelts, &initializer, global_scope_p,
+                      tf_warning_or_error);
+    }
 
 
-  /* Create a representation of the new-expression.  */
-  return build_new (placement, type, nelts, initializer, global_scope_p,
-                    tf_warning_or_error);
+  if (placement != NULL)
+    release_tree_vector (placement);
+  if (initializer != NULL)
+    release_tree_vector (initializer);
+
+  return ret;
 }
 
 /* Parse a new-placement.
 }
 
 /* Parse a new-placement.
@@ -5692,10 +5709,10 @@ cp_parser_new_expression (cp_parser* parser)
 
    Returns the same representation as for an expression-list.  */
 
 
    Returns the same representation as for an expression-list.  */
 
-static tree
+static VEC(tree,gc) *
 cp_parser_new_placement (cp_parser* parser)
 {
 cp_parser_new_placement (cp_parser* parser)
 {
-  tree expression_list;
+  VEC(tree,gc) *expression_list;
 
   /* Parse the expression-list.  */
   expression_list = (cp_parser_parenthesized_expression_list
 
   /* Parse the expression-list.  */
   expression_list = (cp_parser_parenthesized_expression_list
@@ -5885,28 +5902,26 @@ cp_parser_direct_new_declarator (cp_parser* parser)
      ( expression-list [opt] )
      braced-init-list
 
      ( expression-list [opt] )
      braced-init-list
 
-   Returns a representation of the expression-list.  If there is no
-   expression-list, VOID_ZERO_NODE is returned.  */
+   Returns a representation of the expression-list.  */
 
 
-static tree
+static VEC(tree,gc) *
 cp_parser_new_initializer (cp_parser* parser)
 {
 cp_parser_new_initializer (cp_parser* parser)
 {
-  tree expression_list;
+  VEC(tree,gc) *expression_list;
 
   if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
     {
 
   if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
     {
+      tree t;
       bool expr_non_constant_p;
       maybe_warn_cpp0x ("extended initializer lists");
       bool expr_non_constant_p;
       maybe_warn_cpp0x ("extended initializer lists");
-      expression_list = cp_parser_braced_list (parser, &expr_non_constant_p);
-      CONSTRUCTOR_IS_DIRECT_INIT (expression_list) = 1;
-      expression_list = build_tree_list (NULL_TREE, expression_list);
+      t = cp_parser_braced_list (parser, &expr_non_constant_p);
+      CONSTRUCTOR_IS_DIRECT_INIT (t) = 1;
+      expression_list = make_tree_vector_single (t);
     }
   else
     expression_list = (cp_parser_parenthesized_expression_list
                       (parser, false, /*cast_p=*/false, /*allow_expansion_p=*/true,
                        /*non_constant_p=*/NULL));
     }
   else
     expression_list = (cp_parser_parenthesized_expression_list
                       (parser, false, /*cast_p=*/false, /*allow_expansion_p=*/true,
                        /*non_constant_p=*/NULL));
-  if (!expression_list)
-    expression_list = void_zero_node;
 
   return expression_list;
 }
 
   return expression_list;
 }
@@ -9225,11 +9240,18 @@ cp_parser_mem_initializer (cp_parser* parser)
       expression_list = build_tree_list (NULL_TREE, expression_list);
     }
   else
       expression_list = build_tree_list (NULL_TREE, expression_list);
     }
   else
-    expression_list
-      = cp_parser_parenthesized_expression_list (parser, false,
-                                                /*cast_p=*/false,
-                                                /*allow_expansion_p=*/true,
-                                                /*non_constant_p=*/NULL);
+    {
+      VEC(tree,gc)* vec;
+      vec = cp_parser_parenthesized_expression_list (parser, false,
+                                                    /*cast_p=*/false,
+                                                    /*allow_expansion_p=*/true,
+                                                    /*non_constant_p=*/NULL);
+      if (vec == NULL)
+       return error_mark_node;
+      expression_list = build_tree_list_vec (vec);
+      release_tree_vector (vec);
+    }
+
   if (expression_list == error_mark_node)
     return error_mark_node;
   if (!expression_list)
   if (expression_list == error_mark_node)
     return error_mark_node;
   if (!expression_list)
@@ -14585,10 +14607,17 @@ cp_parser_initializer (cp_parser* parser, bool* is_direct_init,
       init = cp_parser_initializer_clause (parser, non_constant_p);
     }
   else if (token->type == CPP_OPEN_PAREN)
       init = cp_parser_initializer_clause (parser, non_constant_p);
     }
   else if (token->type == CPP_OPEN_PAREN)
-    init = cp_parser_parenthesized_expression_list (parser, false,
-                                                   /*cast_p=*/false,
-                                                    /*allow_expansion_p=*/true,
-                                                   non_constant_p);
+    {
+      VEC(tree,gc) *vec;
+      vec = cp_parser_parenthesized_expression_list (parser, false,
+                                                    /*cast_p=*/false,
+                                                    /*allow_expansion_p=*/true,
+                                                    non_constant_p);
+      if (vec == NULL)
+       return error_mark_node;
+      init = build_tree_list_vec (vec);
+      release_tree_vector (vec);
+    }
   else if (token->type == CPP_OPEN_BRACE)
     {
       maybe_warn_cpp0x ("extended initializer lists");
   else if (token->type == CPP_OPEN_BRACE)
     {
       maybe_warn_cpp0x ("extended initializer lists");
@@ -16850,10 +16879,18 @@ cp_parser_attribute_list (cp_parser* parser)
          /* If it's an `(', then parse the attribute arguments.  */
          if (token->type == CPP_OPEN_PAREN)
            {
          /* If it's an `(', then parse the attribute arguments.  */
          if (token->type == CPP_OPEN_PAREN)
            {
-             arguments = cp_parser_parenthesized_expression_list
-                         (parser, true, /*cast_p=*/false,
-                           /*allow_expansion_p=*/false,
-                          /*non_constant_p=*/NULL);
+             VEC(tree,gc) *vec;
+             vec = cp_parser_parenthesized_expression_list
+                   (parser, true, /*cast_p=*/false,
+                    /*allow_expansion_p=*/false,
+                    /*non_constant_p=*/NULL);
+             if (vec == NULL)
+               arguments = error_mark_node;
+             else
+               {
+                 arguments = build_tree_list_vec (vec);
+                 release_tree_vector (vec);
+               }
              /* Save the arguments away.  */
              TREE_VALUE (attribute) = arguments;
            }
              /* Save the arguments away.  */
              TREE_VALUE (attribute) = arguments;
            }
@@ -17981,6 +18018,7 @@ cp_parser_simple_cast_expression (cp_parser *parser)
 static tree
 cp_parser_functional_cast (cp_parser* parser, tree type)
 {
 static tree
 cp_parser_functional_cast (cp_parser* parser, tree type)
 {
+  VEC(tree,gc) *vec;
   tree expression_list;
   tree cast;
   bool nonconst_p;
   tree expression_list;
   tree cast;
   bool nonconst_p;
@@ -17995,11 +18033,18 @@ cp_parser_functional_cast (cp_parser* parser, tree type)
       return finish_compound_literal (type, expression_list);
     }
 
       return finish_compound_literal (type, expression_list);
     }
 
-  expression_list
-    = cp_parser_parenthesized_expression_list (parser, false,
-                                              /*cast_p=*/true,
-                                              /*allow_expansion_p=*/true,
-                                              /*non_constant_p=*/NULL);
+
+  vec = cp_parser_parenthesized_expression_list (parser, false,
+                                                /*cast_p=*/true,
+                                                /*allow_expansion_p=*/true,
+                                                /*non_constant_p=*/NULL);
+  if (vec == NULL)
+    expression_list = error_mark_node;
+  else
+    {
+      expression_list = build_tree_list_vec (vec);
+      release_tree_vector (vec);
+    }
 
   cast = build_functional_cast (type, expression_list,
                                 tf_warning_or_error);
 
   cast = build_functional_cast (type, expression_list,
                                 tf_warning_or_error);
index 2ca28d6..ed6b031 100644 (file)
@@ -118,8 +118,8 @@ static tree add_outermost_template_args (tree, tree);
 static bool check_instantiated_args (tree, tree, tsubst_flags_t);
 static int maybe_adjust_types_for_deduction (unification_kind_t, tree*, tree*,
                                             tree);
 static bool check_instantiated_args (tree, tree, tsubst_flags_t);
 static int maybe_adjust_types_for_deduction (unification_kind_t, tree*, tree*,
                                             tree);
-static int  type_unification_real (tree, tree, tree, tree,
-                                  int, unification_kind_t, int);
+static int type_unification_real (tree, tree, tree, const tree *,
+                                 unsigned int, int, unification_kind_t, int);
 static void note_template_header (int);
 static tree convert_nontype_argument_function (tree, tree);
 static tree convert_nontype_argument (tree, tree);
 static void note_template_header (int);
 static tree convert_nontype_argument_function (tree, tree);
 static tree convert_nontype_argument (tree, tree);
@@ -11430,24 +11430,54 @@ tsubst_copy_and_build (tree t,
 
     case NEW_EXPR:
       {
 
     case NEW_EXPR:
       {
+       tree placement = RECUR (TREE_OPERAND (t, 0));
        tree init = RECUR (TREE_OPERAND (t, 3));
        tree init = RECUR (TREE_OPERAND (t, 3));
+       VEC(tree,gc) *placement_vec;
+       VEC(tree,gc) *init_vec;
+       tree ret;
 
 
-       if (TREE_OPERAND (t, 3) && !init)
-         /* If there was an initializer in the original tree, but
-            it instantiated to an empty list, then we should pass on
-            VOID_ZERO_NODE to tell build_new that it was an empty
-            initializer () rather than no initializer.  This can only
-            happen when the initializer is a pack expansion whose
-            parameter packs are of length zero.  */
-         init = void_zero_node;
+       if (placement == NULL_TREE)
+         placement_vec = NULL;
+       else
+         {
+           placement_vec = make_tree_vector ();
+           for (; placement != NULL_TREE; placement = TREE_CHAIN (placement))
+             VEC_safe_push (tree, gc, placement_vec, TREE_VALUE (placement));
+         }
 
 
-       return build_new
-         (RECUR (TREE_OPERAND (t, 0)),
-          RECUR (TREE_OPERAND (t, 1)),
-          RECUR (TREE_OPERAND (t, 2)),
-          init,
-          NEW_EXPR_USE_GLOBAL (t),
-           complain);
+       /* If there was an initializer in the original tree, but it
+          instantiated to an empty list, then we should pass a
+          non-NULL empty vector to tell build_new that it was an
+          empty initializer() rather than no initializer.  This can
+          only happen when the initializer is a pack expansion whose
+          parameter packs are of length zero.  */
+       if (init == NULL_TREE && TREE_OPERAND (t, 3) == NULL_TREE)
+         init_vec = NULL;
+       else
+         {
+           init_vec = make_tree_vector ();
+           if (init == void_zero_node)
+             gcc_assert (init_vec != NULL);
+           else
+             {
+               for (; init != NULL_TREE; init = TREE_CHAIN (init))
+                 VEC_safe_push (tree, gc, init_vec, TREE_VALUE (init));
+             }
+         }
+
+       ret = build_new (&placement_vec,
+                        RECUR (TREE_OPERAND (t, 1)),
+                        RECUR (TREE_OPERAND (t, 2)),
+                        &init_vec,
+                        NEW_EXPR_USE_GLOBAL (t),
+                        complain);
+
+       if (placement_vec != NULL)
+         release_tree_vector (placement_vec);
+       if (init_vec != NULL)
+         release_tree_vector (init_vec);
+
+       return ret;
       }
 
     case DELETE_EXPR:
       }
 
     case DELETE_EXPR:
@@ -11465,9 +11495,11 @@ tsubst_copy_and_build (tree t,
     case CALL_EXPR:
       {
        tree function;
     case CALL_EXPR:
       {
        tree function;
-       tree call_args;
+       VEC(tree,gc) *call_args;
+       unsigned int nargs, i;
        bool qualified_p;
        bool koenig_p;
        bool qualified_p;
        bool koenig_p;
+       tree ret;
 
        function = CALL_EXPR_FN (t);
        /* When we parsed the expression,  we determined whether or
 
        function = CALL_EXPR_FN (t);
        /* When we parsed the expression,  we determined whether or
@@ -11502,8 +11534,40 @@ tsubst_copy_and_build (tree t,
              qualified_p = true;
          }
 
              qualified_p = true;
          }
 
-       /* FIXME:  Rewrite this so as not to construct an arglist.  */
-       call_args = RECUR (CALL_EXPR_ARGS (t));
+       nargs = call_expr_nargs (t);
+       call_args = make_tree_vector ();
+       for (i = 0; i < nargs; ++i)
+         {
+           tree arg = CALL_EXPR_ARG (t, i);
+
+           if (!PACK_EXPANSION_P (arg))
+             VEC_safe_push (tree, gc, call_args,
+                            RECUR (CALL_EXPR_ARG (t, i)));
+           else
+             {
+               /* Expand the pack expansion and push each entry onto
+                  CALL_ARGS.  */
+               arg = tsubst_pack_expansion (arg, args, complain, in_decl);
+               if (TREE_CODE (arg) == TREE_VEC)
+                 {
+                   unsigned int len, j;
+
+                   len = TREE_VEC_LENGTH (arg);
+                   for (j = 0; j < len; ++j)
+                     {
+                       tree value = TREE_VEC_ELT (arg, j);
+                       if (value != NULL_TREE)
+                         value = convert_from_reference (value);
+                       VEC_safe_push (tree, gc, call_args, value);
+                     }
+                 }
+               else
+                 {
+                   /* A partial substitution.  Add one entry.  */
+                   VEC_safe_push (tree, gc, call_args, arg);
+                 }
+             }
+         }
 
        /* We do not perform argument-dependent lookup if normal
           lookup finds a non-function, in accordance with the
 
        /* We do not perform argument-dependent lookup if normal
           lookup finds a non-function, in accordance with the
@@ -11524,6 +11588,7 @@ tsubst_copy_and_build (tree t,
        if (TREE_CODE (function) == IDENTIFIER_NODE)
          {
            unqualified_name_lookup_error (function);
        if (TREE_CODE (function) == IDENTIFIER_NODE)
          {
            unqualified_name_lookup_error (function);
+           release_tree_vector (call_args);
            return error_mark_node;
          }
 
            return error_mark_node;
          }
 
@@ -11532,27 +11597,32 @@ tsubst_copy_and_build (tree t,
          mark_used (function);
 
        if (TREE_CODE (function) == OFFSET_REF)
          mark_used (function);
 
        if (TREE_CODE (function) == OFFSET_REF)
-         return build_offset_ref_call_from_tree (function, call_args);
-       if (TREE_CODE (function) == COMPONENT_REF)
+         ret = build_offset_ref_call_from_tree (function, &call_args);
+       else if (TREE_CODE (function) == COMPONENT_REF)
          {
            if (!BASELINK_P (TREE_OPERAND (function, 1)))
          {
            if (!BASELINK_P (TREE_OPERAND (function, 1)))
-             return finish_call_expr (function, call_args,
+             ret = finish_call_expr (function, &call_args,
                                       /*disallow_virtual=*/false,
                                       /*koenig_p=*/false,
                                       complain);
            else
                                       /*disallow_virtual=*/false,
                                       /*koenig_p=*/false,
                                       complain);
            else
-             return (build_new_method_call
+             ret = (build_new_method_call
                      (TREE_OPERAND (function, 0),
                       TREE_OPERAND (function, 1),
                      (TREE_OPERAND (function, 0),
                       TREE_OPERAND (function, 1),
-                      call_args, NULL_TREE,
+                      &call_args, NULL_TREE,
                       qualified_p ? LOOKUP_NONVIRTUAL : LOOKUP_NORMAL,
                       /*fn_p=*/NULL,
                       complain));
          }
                       qualified_p ? LOOKUP_NONVIRTUAL : LOOKUP_NORMAL,
                       /*fn_p=*/NULL,
                       complain));
          }
-       return finish_call_expr (function, call_args,
-                                /*disallow_virtual=*/qualified_p,
-                                koenig_p,
-                                complain);
+       else
+         ret = finish_call_expr (function, &call_args,
+                                 /*disallow_virtual=*/qualified_p,
+                                 koenig_p,
+                                 complain);
+
+       release_tree_vector (call_args);
+
+       return ret;
       }
 
     case COND_EXPR:
       }
 
     case COND_EXPR:
@@ -12112,9 +12182,10 @@ instantiate_template (tree tmpl, tree targ_ptr, tsubst_flags_t complain)
   return fndecl;
 }
 
   return fndecl;
 }
 
-/* The FN is a TEMPLATE_DECL for a function.  The ARGS are the
-   arguments that are being used when calling it.  TARGS is a vector
-   into which the deduced template arguments are placed.
+/* The FN is a TEMPLATE_DECL for a function.  ARGS is an array with
+   NARGS elements of the arguments that are being used when calling
+   it.  TARGS is a vector into which the deduced template arguments
+   are placed.
 
    Return zero for success, 2 for an incomplete match that doesn't resolve
    all the types, and 1 for complete failure.  An error message will be
 
    Return zero for success, 2 for an incomplete match that doesn't resolve
    all the types, and 1 for complete failure.  An error message will be
@@ -12146,7 +12217,8 @@ int
 fn_type_unification (tree fn,
                     tree explicit_targs,
                     tree targs,
 fn_type_unification (tree fn,
                     tree explicit_targs,
                     tree targs,
-                    tree args,
+                    const tree *args,
+                    unsigned int nargs,
                     tree return_type,
                     unification_kind_t strict,
                     int flags)
                     tree return_type,
                     unification_kind_t strict,
                     int flags)
@@ -12263,8 +12335,14 @@ fn_type_unification (tree fn,
 
   if (return_type)
     {
 
   if (return_type)
     {
+      tree *new_args;
+
       parms = tree_cons (NULL_TREE, TREE_TYPE (fntype), parms);
       parms = tree_cons (NULL_TREE, TREE_TYPE (fntype), parms);
-      args = tree_cons (NULL_TREE, return_type, args);
+      new_args = XALLOCAVEC (tree, nargs + 1);
+      new_args[0] = return_type;
+      memcpy (new_args + 1, args, nargs * sizeof (tree));
+      args = new_args;
+      ++nargs;
     }
 
   /* We allow incomplete unification without an error message here
     }
 
   /* We allow incomplete unification without an error message here
@@ -12272,7 +12350,7 @@ fn_type_unification (tree fn,
      callers must be ready to deal with unification failures in any
      event.  */
   result = type_unification_real (DECL_INNERMOST_TEMPLATE_PARMS (fn),
      callers must be ready to deal with unification failures in any
      event.  */
   result = type_unification_real (DECL_INNERMOST_TEMPLATE_PARMS (fn),
-                                 targs, parms, args, /*subr=*/0,
+                                 targs, parms, args, nargs, /*subr=*/0,
                                  strict, flags);
 
   if (result == 0 && incomplete_argument_packs_p)
                                  strict, flags);
 
   if (result == 0 && incomplete_argument_packs_p)
@@ -12337,14 +12415,14 @@ fn_type_unification (tree fn,
         parameters are used in non-deduced contexts.  */
       if (strict == DEDUCE_EXACT)
        {
         parameters are used in non-deduced contexts.  */
       if (strict == DEDUCE_EXACT)
        {
+         unsigned int i;
+
          tree sarg
            = skip_artificial_parms_for (fn, TYPE_ARG_TYPES (substed));
          tree sarg
            = skip_artificial_parms_for (fn, TYPE_ARG_TYPES (substed));
-         tree arg = args;
          if (return_type)
            sarg = tree_cons (NULL_TREE, TREE_TYPE (substed), sarg);
          if (return_type)
            sarg = tree_cons (NULL_TREE, TREE_TYPE (substed), sarg);
-         for (; arg && sarg;
-              arg = TREE_CHAIN (arg), sarg = TREE_CHAIN (sarg))
-           if (!same_type_p (TREE_VALUE (arg), TREE_VALUE (sarg)))
+         for (i = 0; i < nargs && sarg; ++i, sarg = TREE_CHAIN (sarg))
+           if (!same_type_p (args[i], TREE_VALUE (sarg)))
              return 1;
        }
     }
              return 1;
        }
     }
@@ -12459,7 +12537,8 @@ static int
 type_unification_real (tree tparms,
                       tree targs,
                       tree xparms,
 type_unification_real (tree tparms,
                       tree targs,
                       tree xparms,
-                      tree xargs,
+                      const tree *xargs,
+                      unsigned int xnargs,
                       int subr,
                       unification_kind_t strict,
                       int flags)
                       int subr,
                       unification_kind_t strict,
                       int flags)
@@ -12469,11 +12548,13 @@ type_unification_real (tree tparms,
   int ntparms = TREE_VEC_LENGTH (tparms);
   int sub_strict;
   int saw_undeduced = 0;
   int ntparms = TREE_VEC_LENGTH (tparms);
   int sub_strict;
   int saw_undeduced = 0;
-  tree parms, args;
+  tree parms;
+  const tree *args;
+  unsigned int nargs;
+  unsigned int ia;
 
   gcc_assert (TREE_CODE (tparms) == TREE_VEC);
   gcc_assert (xparms == NULL_TREE || TREE_CODE (xparms) == TREE_LIST);
 
   gcc_assert (TREE_CODE (tparms) == TREE_VEC);
   gcc_assert (xparms == NULL_TREE || TREE_CODE (xparms) == TREE_LIST);
-  gcc_assert (!xargs || TREE_CODE (xargs) == TREE_LIST);
   gcc_assert (ntparms > 0);
 
   switch (strict)
   gcc_assert (ntparms > 0);
 
   switch (strict)
@@ -12498,17 +12579,19 @@ type_unification_real (tree tparms,
  again:
   parms = xparms;
   args = xargs;
  again:
   parms = xparms;
   args = xargs;
+  nargs = xnargs;
 
 
+  ia = 0;
   while (parms && parms != void_list_node
   while (parms && parms != void_list_node
-        && args && args != void_list_node)
+        && ia < nargs)
     {
       if (TREE_CODE (TREE_VALUE (parms)) == TYPE_PACK_EXPANSION)
         break;
 
       parm = TREE_VALUE (parms);
       parms = TREE_CHAIN (parms);
     {
       if (TREE_CODE (TREE_VALUE (parms)) == TYPE_PACK_EXPANSION)
         break;
 
       parm = TREE_VALUE (parms);
       parms = TREE_CHAIN (parms);
-      arg = TREE_VALUE (args);
-      args = TREE_CHAIN (args);
+      arg = args[ia];
+      ++ia;
       arg_expr = NULL;
 
       if (arg == error_mark_node)
       arg_expr = NULL;
 
       if (arg == error_mark_node)
@@ -12587,20 +12670,11 @@ type_unification_real (tree tparms,
       /* Unify the remaining arguments with the pack expansion type.  */
       tree argvec;
       tree parmvec = make_tree_vec (1);
       /* Unify the remaining arguments with the pack expansion type.  */
       tree argvec;
       tree parmvec = make_tree_vec (1);
-      int len = 0;
-      tree t;
 
 
-      /* Count the number of arguments that remain.  */
-      for (t = args; t && t != void_list_node; t = TREE_CHAIN (t))
-        len++;
-        
       /* Allocate a TREE_VEC and copy in all of the arguments */ 
       /* Allocate a TREE_VEC and copy in all of the arguments */ 
-      argvec = make_tree_vec (len);
-      for (i = 0; args && args != void_list_node; args = TREE_CHAIN (args))
-        {
-          TREE_VEC_ELT (argvec, i) = TREE_VALUE (args);
-          ++i;
-        }
+      argvec = make_tree_vec (nargs - ia);
+      for (i = 0; ia < nargs; ++ia, ++i)
+       TREE_VEC_ELT (argvec, i) = args[ia];
 
       /* Copy the parameter into parmvec.  */
       TREE_VEC_ELT (parmvec, 0) = TREE_VALUE (parms);
 
       /* Copy the parameter into parmvec.  */
       TREE_VEC_ELT (parmvec, 0) = TREE_VALUE (parms);
@@ -12614,7 +12688,7 @@ type_unification_real (tree tparms,
 
   /* Fail if we've reached the end of the parm list, and more args
      are present, and the parm list isn't variadic.  */
 
   /* Fail if we've reached the end of the parm list, and more args
      are present, and the parm list isn't variadic.  */
-  if (args && args != void_list_node && parms == void_list_node)
+  if (ia < nargs && parms == void_list_node)
     return 1;
   /* Fail if parms are left and they don't have default values.  */
   if (parms && parms != void_list_node
     return 1;
   /* Fail if parms are left and they don't have default values.  */
   if (parms && parms != void_list_node
@@ -13896,26 +13970,42 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
 
     case METHOD_TYPE:
     case FUNCTION_TYPE:
 
     case METHOD_TYPE:
     case FUNCTION_TYPE:
-      if (TREE_CODE (arg) != TREE_CODE (parm))
-       return 1;
+      {
+       unsigned int nargs;
+       tree *args;
+       tree a;
+       unsigned int i;
 
 
-      /* CV qualifications for methods can never be deduced, they must
-        match exactly.  We need to check them explicitly here,
-        because type_unification_real treats them as any other
-        cv-qualified parameter.  */
-      if (TREE_CODE (parm) == METHOD_TYPE
-         && (!check_cv_quals_for_unify
-             (UNIFY_ALLOW_NONE,
-              TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (arg))),
-              TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (parm))))))
-       return 1;
+       if (TREE_CODE (arg) != TREE_CODE (parm))
+         return 1;
 
 
-      if (unify (tparms, targs, TREE_TYPE (parm),
-                TREE_TYPE (arg), UNIFY_ALLOW_NONE))
-       return 1;
-      return type_unification_real (tparms, targs, TYPE_ARG_TYPES (parm),
-                                   TYPE_ARG_TYPES (arg), 1, DEDUCE_EXACT,
-                                   LOOKUP_NORMAL);
+       /* CV qualifications for methods can never be deduced, they must
+          match exactly.  We need to check them explicitly here,
+          because type_unification_real treats them as any other
+          cv-qualified parameter.  */
+       if (TREE_CODE (parm) == METHOD_TYPE
+           && (!check_cv_quals_for_unify
+               (UNIFY_ALLOW_NONE,
+                TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (arg))),
+                TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (parm))))))
+         return 1;
+
+       if (unify (tparms, targs, TREE_TYPE (parm),
+                  TREE_TYPE (arg), UNIFY_ALLOW_NONE))
+         return 1;
+
+       nargs = list_length (TYPE_ARG_TYPES (arg));
+       args = XALLOCAVEC (tree, nargs);
+       for (a = TYPE_ARG_TYPES (arg), i = 0;
+            a != NULL_TREE && a != void_list_node;
+            a = TREE_CHAIN (a), ++i)
+         args[i] = TREE_VALUE (a);
+       nargs = i;
+
+       return type_unification_real (tparms, targs, TYPE_ARG_TYPES (parm),
+                                     args, nargs, 1, DEDUCE_EXACT,
+                                     LOOKUP_NORMAL);
+      }
 
     case OFFSET_TYPE:
       /* Unify a pointer to member with a pointer to member function, which
 
     case OFFSET_TYPE:
       /* Unify a pointer to member with a pointer to member function, which
@@ -14469,6 +14559,9 @@ get_bindings (tree fn, tree decl, tree explicit_args, bool check_rettype)
   tree targs = make_tree_vec (ntparms);
   tree decl_type;
   tree decl_arg_types;
   tree targs = make_tree_vec (ntparms);
   tree decl_type;
   tree decl_arg_types;
+  tree *args;
+  unsigned int nargs, ix;
+  tree arg;
 
   /* Substitute the explicit template arguments into the type of DECL.
      The call to fn_type_unification will handle substitution into the
 
   /* Substitute the explicit template arguments into the type of DECL.
      The call to fn_type_unification will handle substitution into the
@@ -14503,8 +14596,15 @@ get_bindings (tree fn, tree decl, tree explicit_args, bool check_rettype)
   decl_arg_types = skip_artificial_parms_for (decl, 
                                              TYPE_ARG_TYPES (decl_type));
 
   decl_arg_types = skip_artificial_parms_for (decl, 
                                              TYPE_ARG_TYPES (decl_type));
 
+  nargs = list_length (decl_arg_types);
+  args = XALLOCAVEC (tree, nargs);
+  for (arg = decl_arg_types, ix = 0;
+       arg != NULL_TREE && arg != void_list_node;
+       arg = TREE_CHAIN (arg), ++ix)
+    args[ix] = TREE_VALUE (arg);
+
   if (fn_type_unification (fn, explicit_args, targs,
   if (fn_type_unification (fn, explicit_args, targs,
-                          decl_arg_types,
+                          args, ix,
                           (check_rettype || DECL_CONV_FN_P (fn)
                            ? TREE_TYPE (decl_type) : NULL_TREE),
                           DEDUCE_EXACT, LOOKUP_NORMAL))
                           (check_rettype || DECL_CONV_FN_P (fn)
                            ? TREE_TYPE (decl_type) : NULL_TREE),
                           DEDUCE_EXACT, LOOKUP_NORMAL))
@@ -16580,19 +16680,18 @@ type_dependent_expression_p_push (tree expr)
   return b;
 }
 
   return b;
 }
 
-/* Returns TRUE if ARGS (a TREE_LIST of arguments to a function call)
-   contains a type-dependent expression.  */
+/* Returns TRUE if ARGS contains a type-dependent expression.  */
 
 bool
 
 bool
-any_type_dependent_arguments_p (const_tree args)
+any_type_dependent_arguments_p (const VEC(tree,gc) *args)
 {
 {
-  while (args)
-    {
-      tree arg = TREE_VALUE (args);
+  unsigned int i;
+  tree arg;
 
 
+  for (i = 0; VEC_iterate (tree, args, i, arg); ++i)
+    {
       if (type_dependent_expression_p (arg))
        return true;
       if (type_dependent_expression_p (arg))
        return true;
-      args = TREE_CHAIN (args);
     }
   return false;
 }
     }
   return false;
 }
@@ -17012,22 +17111,22 @@ build_non_dependent_expr (tree expr)
   return build1 (NON_DEPENDENT_EXPR, non_reference (TREE_TYPE (expr)), expr);
 }
 
   return build1 (NON_DEPENDENT_EXPR, non_reference (TREE_TYPE (expr)), expr);
 }
 
-/* ARGS is a TREE_LIST of expressions as arguments to a function call.
-   Return a new TREE_LIST with the various arguments replaced with
-   equivalent non-dependent expressions.  */
+/* ARGS is a vector of expressions as arguments to a function call.
+   Replace the arguments with equivalent non-dependent expressions.
+   This modifies ARGS in place.  */
 
 
-tree
-build_non_dependent_args (tree args)
+void
+make_args_non_dependent (VEC(tree,gc) *args)
 {
 {
-  tree a;
-  tree new_args;
+  unsigned int ix;
+  tree arg;
 
 
-  new_args = NULL_TREE;
-  for (a = args; a; a = TREE_CHAIN (a))
-    new_args = tree_cons (NULL_TREE,
-                         build_non_dependent_expr (TREE_VALUE (a)),
-                         new_args);
-  return nreverse (new_args);
+  for (ix = 0; VEC_iterate (tree, args, ix, arg); ++ix)
+    {
+      tree newarg = build_non_dependent_expr (arg);
+      if (newarg != arg)
+       VEC_replace (tree, args, ix, newarg);
+    }
 }
 
 /* Returns a type which represents 'auto'.  We use a TEMPLATE_TYPE_PARM
 }
 
 /* Returns a type which represents 'auto'.  We use a TEMPLATE_TYPE_PARM
@@ -17084,7 +17183,8 @@ listify_autos (tree type, tree auto_node)
 tree
 do_auto_deduction (tree type, tree init, tree auto_node)
 {
 tree
 do_auto_deduction (tree type, tree init, tree auto_node)
 {
-  tree parms, args, tparms, targs;
+  tree parms, tparms, targs;
+  tree args[1];
   int val;
 
   /* [dcl.spec.auto]: Obtain P from T by replacing the occurrences of auto
   int val;
 
   /* [dcl.spec.auto]: Obtain P from T by replacing the occurrences of auto
@@ -17095,12 +17195,12 @@ do_auto_deduction (tree type, tree init, tree auto_node)
     type = listify_autos (type, auto_node);
 
   parms = build_tree_list (NULL_TREE, type);
     type = listify_autos (type, auto_node);
 
   parms = build_tree_list (NULL_TREE, type);
-  args = build_tree_list (NULL_TREE, init);
+  args[0] = init;
   tparms = make_tree_vec (1);
   targs = make_tree_vec (1);
   TREE_VEC_ELT (tparms, 0)
     = build_tree_list (NULL_TREE, TYPE_NAME (auto_node));
   tparms = make_tree_vec (1);
   targs = make_tree_vec (1);
   TREE_VEC_ELT (tparms, 0)
     = build_tree_list (NULL_TREE, TYPE_NAME (auto_node));
-  val = type_unification_real (tparms, targs, parms, args, 0,
+  val = type_unification_real (tparms, targs, parms, args, 1, 0,
                               DEDUCE_CALL, LOOKUP_NORMAL);
   if (val > 0)
     {
                               DEDUCE_CALL, LOOKUP_NORMAL);
   if (val > 0)
     {
index 18aa051..2b12448 100644 (file)
@@ -1820,7 +1820,7 @@ stmt_expr_value_expr (tree stmt_expr)
    resolution.  */
 
 tree
    resolution.  */
 
 tree
-perform_koenig_lookup (tree fn, tree args)
+perform_koenig_lookup (tree fn, VEC(tree,gc) *args)
 {
   tree identifier = NULL_TREE;
   tree functions = NULL_TREE;
 {
   tree identifier = NULL_TREE;
   tree functions = NULL_TREE;
@@ -1865,7 +1865,8 @@ perform_koenig_lookup (tree fn, tree args)
   return fn;
 }
 
   return fn;
 }
 
-/* Generate an expression for `FN (ARGS)'.
+/* Generate an expression for `FN (ARGS)'.  This may change the
+   contents of ARGS.
 
    If DISALLOW_VIRTUAL is true, the call to FN will be not generated
    as a virtual call, even if FN is virtual.  (This flag is set when
 
    If DISALLOW_VIRTUAL is true, the call to FN will be not generated
    as a virtual call, even if FN is virtual.  (This flag is set when
@@ -1876,29 +1877,26 @@ perform_koenig_lookup (tree fn, tree args)
    Returns code for the call.  */
 
 tree
    Returns code for the call.  */
 
 tree
-finish_call_expr (tree fn, tree args, bool disallow_virtual, bool koenig_p,
-                 tsubst_flags_t complain)
+finish_call_expr (tree fn, VEC(tree,gc) **args, bool disallow_virtual,
+                 bool koenig_p, tsubst_flags_t complain)
 {
   tree result;
   tree orig_fn;
 {
   tree result;
   tree orig_fn;
-  tree orig_args;
+  VEC(tree,gc) *orig_args = NULL;
 
 
-  if (fn == error_mark_node || args == error_mark_node)
+  if (fn == error_mark_node)
     return error_mark_node;
 
     return error_mark_node;
 
-  /* ARGS should be a list of arguments.  */
-  gcc_assert (!args || TREE_CODE (args) == TREE_LIST);
   gcc_assert (!TYPE_P (fn));
 
   orig_fn = fn;
   gcc_assert (!TYPE_P (fn));
 
   orig_fn = fn;
-  orig_args = args;
 
   if (processing_template_decl)
     {
       if (type_dependent_expression_p (fn)
 
   if (processing_template_decl)
     {
       if (type_dependent_expression_p (fn)
-         || any_type_dependent_arguments_p (args))
+         || any_type_dependent_arguments_p (*args))
        {
        {
-         result = build_nt_call_list (fn, args);
+         result = build_nt_call_vec (fn, *args);
          KOENIG_LOOKUP_P (result) = koenig_p;
          if (cfun)
            {
          KOENIG_LOOKUP_P (result) = koenig_p;
          if (cfun)
            {
@@ -1916,11 +1914,12 @@ finish_call_expr (tree fn, tree args, bool disallow_virtual, bool koenig_p,
            }
          return result;
        }
            }
          return result;
        }
+      orig_args = make_tree_vector_copy (*args);
       if (!BASELINK_P (fn)
          && TREE_CODE (fn) != PSEUDO_DTOR_EXPR
          && TREE_TYPE (fn) != unknown_type_node)
        fn = build_non_dependent_expr (fn);
       if (!BASELINK_P (fn)
          && TREE_CODE (fn) != PSEUDO_DTOR_EXPR
          && TREE_TYPE (fn) != unknown_type_node)
        fn = build_non_dependent_expr (fn);
-      args = build_non_dependent_args (orig_args);
+      make_args_non_dependent (*args);
     }
 
   if (is_overloaded_fn (fn))
     }
 
   if (is_overloaded_fn (fn))
@@ -1969,7 +1968,11 @@ finish_call_expr (tree fn, tree args, bool disallow_virtual, bool koenig_p,
       if (processing_template_decl)
        {
          if (type_dependent_expression_p (object))
       if (processing_template_decl)
        {
          if (type_dependent_expression_p (object))
-           return build_nt_call_list (orig_fn, orig_args);
+           {
+             tree ret = build_nt_call_vec (orig_fn, orig_args);
+             release_tree_vector (orig_args);
+             return ret;
+           }
          object = build_non_dependent_expr (object);
        }
 
          object = build_non_dependent_expr (object);
        }
 
@@ -1985,15 +1988,7 @@ finish_call_expr (tree fn, tree args, bool disallow_virtual, bool koenig_p,
       if (TREE_CODE (fn) == FUNCTION_DECL
          && (DECL_BUILT_IN_CLASS (fn) == BUILT_IN_NORMAL
              || DECL_BUILT_IN_CLASS (fn) == BUILT_IN_MD))
       if (TREE_CODE (fn) == FUNCTION_DECL
          && (DECL_BUILT_IN_CLASS (fn) == BUILT_IN_NORMAL
              || DECL_BUILT_IN_CLASS (fn) == BUILT_IN_MD))
-       {
-         VEC(tree,gc)* vec = VEC_alloc (tree, gc, list_length (args));
-         tree p;
-
-         for (p = args; p != NULL_TREE; p = TREE_CHAIN (p))
-           VEC_quick_push (tree, vec, TREE_VALUE (p));
-         result = resolve_overloaded_builtin (fn, vec);
-         VEC_free (tree, gc, vec);
-       }
+       result = resolve_overloaded_builtin (fn, *args);
 
       if (!result)
        /* A call to a namespace-scope function.  */
 
       if (!result)
        /* A call to a namespace-scope function.  */
@@ -2001,7 +1996,7 @@ finish_call_expr (tree fn, tree args, bool disallow_virtual, bool koenig_p,
     }
   else if (TREE_CODE (fn) == PSEUDO_DTOR_EXPR)
     {
     }
   else if (TREE_CODE (fn) == PSEUDO_DTOR_EXPR)
     {
-      if (args)
+      if (!VEC_empty (tree, *args))
        error ("arguments to destructor are not allowed");
       /* Mark the pseudo-destructor call as having side-effects so
         that we do not issue warnings about its use.  */
        error ("arguments to destructor are not allowed");
       /* Mark the pseudo-destructor call as having side-effects so
         that we do not issue warnings about its use.  */
@@ -2013,18 +2008,19 @@ finish_call_expr (tree fn, tree args, bool disallow_virtual, bool koenig_p,
   else if (CLASS_TYPE_P (TREE_TYPE (fn)))
     /* If the "function" is really an object of class type, it might
        have an overloaded `operator ()'.  */
   else if (CLASS_TYPE_P (TREE_TYPE (fn)))
     /* If the "function" is really an object of class type, it might
        have an overloaded `operator ()'.  */
-    result = build_new_op (CALL_EXPR, LOOKUP_NORMAL, fn, args, NULL_TREE,
-                          /*overloaded_p=*/NULL, complain);
+    result = build_op_call (fn, args, complain);
 
   if (!result)
     /* A call where the function is unknown.  */
 
   if (!result)
     /* A call where the function is unknown.  */
-    result = cp_build_function_call (fn, args, complain);
+    result = cp_build_function_call_vec (fn, args, complain);
 
   if (processing_template_decl)
     {
 
   if (processing_template_decl)
     {
-      result = build_call_list (TREE_TYPE (result), orig_fn, orig_args);
+      result = build_call_vec (TREE_TYPE (result), orig_fn, orig_args);
       KOENIG_LOOKUP_P (result) = koenig_p;
       KOENIG_LOOKUP_P (result) = koenig_p;
+      release_tree_vector (orig_args);
     }
     }
+
   return result;
 }
 
   return result;
 }
 
@@ -3423,18 +3419,23 @@ cxx_omp_create_clause_info (tree c, tree type, bool need_default_ctor,
   if (need_default_ctor
       || (need_copy_ctor && !TYPE_HAS_TRIVIAL_INIT_REF (type)))
     {
   if (need_default_ctor
       || (need_copy_ctor && !TYPE_HAS_TRIVIAL_INIT_REF (type)))
     {
+      VEC(tree,gc) *vec;
+
       if (need_default_ctor)
       if (need_default_ctor)
-       t = NULL;
+       vec = NULL;
       else
        {
          t = build_int_cst (build_pointer_type (type), 0);
          t = build1 (INDIRECT_REF, type, t);
       else
        {
          t = build_int_cst (build_pointer_type (type), 0);
          t = build1 (INDIRECT_REF, type, t);
-         t = build_tree_list (NULL, t);
+         vec = make_tree_vector_single (t);
        }
       t = build_special_member_call (NULL_TREE, complete_ctor_identifier,
        }
       t = build_special_member_call (NULL_TREE, complete_ctor_identifier,
-                                    t, type, LOOKUP_NORMAL,
+                                    &vec, type, LOOKUP_NORMAL,
                                     tf_warning_or_error);
 
                                     tf_warning_or_error);
 
+      if (vec != NULL)
+       release_tree_vector (vec);
+
       if (targetm.cxx.cdtor_returns_this () || errorcount)
        /* Because constructors and destructors return this,
           the call will have been cast to "void".  Remove the
       if (targetm.cxx.cdtor_returns_this () || errorcount)
        /* Because constructors and destructors return this,
           the call will have been cast to "void".  Remove the
@@ -3472,12 +3473,15 @@ cxx_omp_create_clause_info (tree c, tree type, bool need_default_ctor,
 
   if (need_copy_assignment && !TYPE_HAS_TRIVIAL_ASSIGN_REF (type))
     {
 
   if (need_copy_assignment && !TYPE_HAS_TRIVIAL_ASSIGN_REF (type))
     {
+      VEC(tree,gc) *vec;
+
       t = build_int_cst (build_pointer_type (type), 0);
       t = build1 (INDIRECT_REF, type, t);
       t = build_int_cst (build_pointer_type (type), 0);
       t = build1 (INDIRECT_REF, type, t);
+      vec = make_tree_vector_single (t);
       t = build_special_member_call (t, ansi_assopname (NOP_EXPR),
       t = build_special_member_call (t, ansi_assopname (NOP_EXPR),
-                                    build_tree_list (NULL, t),
-                                    type, LOOKUP_NORMAL,
+                                    &vec, type, LOOKUP_NORMAL,
                                     tf_warning_or_error);
                                     tf_warning_or_error);
+      release_tree_vector (vec);
 
       /* We'll have called convert_from_reference on the call, which
         may well have added an indirect_ref.  It's unneeded here,
 
       /* We'll have called convert_from_reference on the call, which
         may well have added an indirect_ref.  It's unneeded here,
@@ -4433,7 +4437,9 @@ void
 finish_omp_barrier (void)
 {
   tree fn = built_in_decls[BUILT_IN_GOMP_BARRIER];
 finish_omp_barrier (void)
 {
   tree fn = built_in_decls[BUILT_IN_GOMP_BARRIER];
-  tree stmt = finish_call_expr (fn, NULL, false, false, tf_warning_or_error);
+  VEC(tree,gc) *vec = make_tree_vector ();
+  tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error);
+  release_tree_vector (vec);
   finish_expr_stmt (stmt);
 }
 
   finish_expr_stmt (stmt);
 }
 
@@ -4441,7 +4447,9 @@ void
 finish_omp_flush (void)
 {
   tree fn = built_in_decls[BUILT_IN_SYNCHRONIZE];
 finish_omp_flush (void)
 {
   tree fn = built_in_decls[BUILT_IN_SYNCHRONIZE];
-  tree stmt = finish_call_expr (fn, NULL, false, false, tf_warning_or_error);
+  VEC(tree,gc) *vec = make_tree_vector ();
+  tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error);
+  release_tree_vector (vec);
   finish_expr_stmt (stmt);
 }
 
   finish_expr_stmt (stmt);
 }
 
@@ -4449,7 +4457,9 @@ void
 finish_omp_taskwait (void)
 {
   tree fn = built_in_decls[BUILT_IN_GOMP_TASKWAIT];
 finish_omp_taskwait (void)
 {
   tree fn = built_in_decls[BUILT_IN_GOMP_TASKWAIT];
-  tree stmt = finish_call_expr (fn, NULL, false, false, tf_warning_or_error);
+  VEC(tree,gc) *vec = make_tree_vector ();
+  tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error);
+  release_tree_vector (vec);
   finish_expr_stmt (stmt);
 }
 \f
   finish_expr_stmt (stmt);
 }
 \f
index f1868f5..8c51e0b 100644 (file)
@@ -1719,9 +1719,9 @@ build_min_non_dep (enum tree_code code, tree non_dep, ...)
    built.  */
 
 tree
    built.  */
 
 tree
-build_min_non_dep_call_list (tree non_dep, tree fn, tree arglist)
+build_min_non_dep_call_vec (tree non_dep, tree fn, VEC(tree,gc) *argvec)
 {
 {
-  tree t = build_nt_call_list (fn, arglist);
+  tree t = build_nt_call_vec (fn, argvec);
   TREE_TYPE (t) = TREE_TYPE (non_dep);
   TREE_SIDE_EFFECTS (t) = TREE_SIDE_EFFECTS (non_dep);
   return t;
   TREE_TYPE (t) = TREE_TYPE (non_dep);
   TREE_SIDE_EFFECTS (t) = TREE_SIDE_EFFECTS (non_dep);
   return t;
index 87138bd..074d619 100644 (file)
@@ -61,7 +61,7 @@ static void casts_away_constness_r (tree *, tree *);
 static bool casts_away_constness (tree, tree);
 static void maybe_warn_about_returning_address_of_local (tree);
 static tree lookup_destructor (tree, tree, tree);
 static bool casts_away_constness (tree, tree);
 static void maybe_warn_about_returning_address_of_local (tree);
 static tree lookup_destructor (tree, tree, tree);
-static int convert_arguments (int, tree *, tree, tree, tree, int,
+static int convert_arguments (tree, VEC(tree,gc) **, tree, int,
                               tsubst_flags_t);
 
 /* Do `exp = require_complete_type (exp);' to make sure exp
                               tsubst_flags_t);
 
 /* Do `exp = require_complete_type (exp);' to make sure exp
@@ -2866,38 +2866,57 @@ tree
 build_function_call_vec (tree function, VEC(tree,gc) *params,
                         VEC(tree,gc) *origtypes ATTRIBUTE_UNUSED)
 {
 build_function_call_vec (tree function, VEC(tree,gc) *params,
                         VEC(tree,gc) *origtypes ATTRIBUTE_UNUSED)
 {
-  tree p;
-  tree *pp;
-  unsigned int i;
-  tree t;
+  VEC(tree,gc) *orig_params = params;
+  tree ret = cp_build_function_call_vec (function, &params,
+                                        tf_warning_or_error);
 
 
-  /* FIXME: Should just change cp_build_function_call to use a
-     VEC.  */
-  p = NULL_TREE;
-  pp = &p;
-  for (i = 0; VEC_iterate (tree, params, i, t); ++i)
-    {
-      *pp = build_tree_list (NULL, t);
-      pp = &TREE_CHAIN (*pp);
-    }
-  return cp_build_function_call (function, p, tf_warning_or_error);
+  /* cp_build_function_call_vec can reallocate PARAMS by adding
+     default arguments.  That should never happen here.  Verify
+     that.  */
+  gcc_assert (params == orig_params);
+
+  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)
 {
 tree
 cp_build_function_call (tree function, tree params, tsubst_flags_t complain)
 {
+  VEC(tree,gc) *vec;
+  tree ret;
+
+  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);
+  release_tree_vector (vec);
+  return ret;
+}
+
+/* Build a function call using a vector of arguments.  PARAMS may be
+   NULL if there are no parameters.  This changes the contents of
+   PARAMS.  */
+
+tree
+cp_build_function_call_vec (tree function, VEC(tree,gc) **params,
+                           tsubst_flags_t complain)
+{
   tree fntype, fndecl;
   tree name = NULL_TREE;
   int is_method;
   tree original = function;
   tree fntype, fndecl;
   tree name = NULL_TREE;
   int is_method;
   tree original = function;
-  int nargs, parm_types_len;
+  int nargs;
   tree *argarray;
   tree parm_types;
   tree *argarray;
   tree parm_types;
+  VEC(tree,gc) *allocated = NULL;
+  tree ret;
 
   /* For Objective-C, convert any calls via a cast to OBJC_TYPE_REF
      expressions, like those used for ObjC messenger dispatches.  */
 
   /* For Objective-C, convert any calls via a cast to OBJC_TYPE_REF
      expressions, like those used for ObjC messenger dispatches.  */
-  if (params != NULL_TREE)
-    function = objc_rewrite_function_call (function, TREE_VALUE (params));
+  if (params != NULL && !VEC_empty (tree, *params))
+    function = objc_rewrite_function_call (function,
+                                          VEC_index (tree, *params, 0));
 
   /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
      Strip such NOP_EXPRs, since FUNCTION is used in non-lvalue context.  */
 
   /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
      Strip such NOP_EXPRs, since FUNCTION is used in non-lvalue context.  */
@@ -2957,57 +2976,55 @@ cp_build_function_call (tree function, tree params, tsubst_flags_t complain)
   fntype = TREE_TYPE (fntype);
   parm_types = TYPE_ARG_TYPES (fntype);
 
   fntype = TREE_TYPE (fntype);
   parm_types = TYPE_ARG_TYPES (fntype);
 
-  /* Allocate storage for converted arguments.  */
-  parm_types_len = list_length (parm_types);
-  nargs = list_length (params);
-  if (parm_types_len > nargs)
-    nargs = parm_types_len;
-  argarray = (tree *) alloca (nargs * sizeof (tree));
-
-  /* Convert the parameters to the types declared in the
-     function prototype, or apply default promotions.  */
-  nargs = convert_arguments (nargs, argarray, parm_types,
-                            params, fndecl, LOOKUP_NORMAL,
-                             complain);
+  if (params == NULL)
+    {
+      allocated = make_tree_vector ();
+      params = &allocated;
+    }
+
+  nargs = convert_arguments (parm_types, params, fndecl, LOOKUP_NORMAL,
+                            complain);
   if (nargs < 0)
     return error_mark_node;
 
   if (nargs < 0)
     return error_mark_node;
 
+  argarray = VEC_address (tree, *params);
+
   /* Check for errors in format strings and inappropriately
      null parameters.  */
   check_function_arguments (TYPE_ATTRIBUTES (fntype), nargs, argarray,
                            parm_types);
 
   /* Check for errors in format strings and inappropriately
      null parameters.  */
   check_function_arguments (TYPE_ATTRIBUTES (fntype), nargs, argarray,
                            parm_types);
 
-  return build_cxx_call (function, nargs, argarray);
+  ret = build_cxx_call (function, nargs, argarray);
+
+  if (allocated != NULL)
+    release_tree_vector (allocated);
+
+  return ret;
 }
 \f
 }
 \f
-/* Convert the actual parameter expressions in the list VALUES
-   to the types in the list TYPELIST.
+/* Convert the actual parameter expressions in the list VALUES to the
+   types in the list TYPELIST.  The converted expressions are stored
+   back in the VALUES vector.
    If parmdecls is exhausted, or when an element has NULL as its type,
    perform the default conversions.
 
    If parmdecls is exhausted, or when an element has NULL as its type,
    perform the default conversions.
 
-   Store the converted arguments in ARGARRAY.  NARGS is the size of this array.
-
    NAME is an IDENTIFIER_NODE or 0.  It is used only for error messages.
 
    This is also where warnings about wrong number of args are generated.
 
    Returns the actual number of arguments processed (which might be less
    NAME is an IDENTIFIER_NODE or 0.  It is used only for error messages.
 
    This is also where warnings about wrong number of args are generated.
 
    Returns the actual number of arguments processed (which might be less
-   than NARGS), or -1 on error.
-
-   VALUES is a chain of TREE_LIST nodes with the elements of the list
-   in the TREE_VALUE slots of those nodes.
+   than the length of the vector), or -1 on error.
 
    In C++, unspecified trailing parameters can be filled in with their
    default arguments, if such were specified.  Do so here.  */
 
 static int
 
    In C++, unspecified trailing parameters can be filled in with their
    default arguments, if such were specified.  Do so here.  */
 
 static int
-convert_arguments (int nargs, tree *argarray,
-                  tree typelist, tree values, tree fndecl, int flags,
-                   tsubst_flags_t complain)
+convert_arguments (tree typelist, VEC(tree,gc) **values, tree fndecl,
+                  int flags, tsubst_flags_t complain)
 {
 {
-  tree typetail, valtail;
+  tree typetail;
   const char *called_thing = 0;
   const char *called_thing = 0;
-  int i = 0;
+  unsigned int i;
 
   /* Argument passing is always copy-initialization.  */
   flags |= LOOKUP_ONLYCONVERTING;
 
   /* Argument passing is always copy-initialization.  */
   flags |= LOOKUP_ONLYCONVERTING;
@@ -3026,12 +3043,12 @@ convert_arguments (int nargs, tree *argarray,
        called_thing = "function";
     }
 
        called_thing = "function";
     }
 
-  for (valtail = values, typetail = typelist;
-       valtail;
-       valtail = TREE_CHAIN (valtail), i++)
+  for (i = 0, typetail = typelist;
+       i < VEC_length (tree, *values);
+       i++)
     {
       tree type = typetail ? TREE_VALUE (typetail) : 0;
     {
       tree type = typetail ? TREE_VALUE (typetail) : 0;
-      tree val = TREE_VALUE (valtail);
+      tree val = VEC_index (tree, *values, i);
 
       if (val == error_mark_node || type == error_mark_node)
        return -1;
 
       if (val == error_mark_node || type == error_mark_node)
        return -1;
@@ -3100,7 +3117,7 @@ convert_arguments (int nargs, tree *argarray,
          if (parmval == error_mark_node)
            return -1;
 
          if (parmval == error_mark_node)
            return -1;
 
-         argarray[i] = parmval;
+         VEC_replace (tree, *values, i, parmval);
        }
       else
        {
        }
       else
        {
@@ -3113,7 +3130,7 @@ convert_arguments (int nargs, tree *argarray,
          else
            val = convert_arg_to_ellipsis (val);
 
          else
            val = convert_arg_to_ellipsis (val);
 
-         argarray[i] = val;
+         VEC_replace (tree, *values, i, val);
        }
 
       if (typetail)
        }
 
       if (typetail)
@@ -3142,7 +3159,7 @@ convert_arguments (int nargs, tree *argarray,
              if (parmval == error_mark_node)
                return -1;
 
              if (parmval == error_mark_node)
                return -1;
 
-             argarray[i] = parmval;
+             VEC_safe_push (tree, gc, *values, parmval);
              typetail = TREE_CHAIN (typetail);
              /* ends with `...'.  */
              if (typetail == NULL_TREE)
              typetail = TREE_CHAIN (typetail);
              /* ends with `...'.  */
              if (typetail == NULL_TREE)
@@ -3166,8 +3183,7 @@ convert_arguments (int nargs, tree *argarray,
        }
     }
 
        }
     }
 
-  gcc_assert (i <= nargs);
-  return i;
+  return (int) i;
 }
 \f
 /* Build a binary-operation expression, after performing default
 }
 \f
 /* Build a binary-operation expression, after performing default
@@ -4994,6 +5010,34 @@ tree build_x_compound_expr_from_list (tree list, const char *msg)
   return expr;
 }
 
   return expr;
 }
 
+/* Like build_x_compound_expr_from_list, but using a VEC.  */
+
+tree
+build_x_compound_expr_from_vec (VEC(tree,gc) *vec, const char *msg)
+{
+  if (VEC_empty (tree, vec))
+    return NULL_TREE;
+  else if (VEC_length (tree, vec) == 1)
+    return VEC_index (tree, vec, 0);
+  else
+    {
+      tree expr;
+      unsigned int ix;
+      tree t;
+
+      if (msg != NULL)
+       permerror (input_location,
+                  "%s expression list treated as compound expression",
+                  msg);
+
+      expr = VEC_index (tree, vec, 0);
+      for (ix = 1; VEC_iterate (tree, vec, ix, t); ++ix)
+       expr = build_x_compound_expr (expr, t, tf_warning_or_error);
+
+      return expr;
+    }
+}
+
 /* Handle overloading of the ',' operator when needed.  */
 
 tree
 /* Handle overloading of the ',' operator when needed.  */
 
 tree
@@ -6038,10 +6082,11 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
        /* Do the default thing.  */;
       else
        {
        /* Do the default thing.  */;
       else
        {
+         VEC(tree,gc) *rhs_vec = make_tree_vector_single (rhs);
          result = build_special_member_call (lhs, complete_ctor_identifier,
          result = build_special_member_call (lhs, complete_ctor_identifier,
-                                             build_tree_list (NULL_TREE, rhs),
-                                             lhstype, LOOKUP_NORMAL,
+                                             &rhs_vec, lhstype, LOOKUP_NORMAL,
                                               complain);
                                               complain);
+         release_tree_vector (rhs_vec);
          if (result == NULL_TREE)
            return error_mark_node;
          return result;
          if (result == NULL_TREE)
            return error_mark_node;
          return result;
index 5783f67..e668427 100644 (file)
@@ -1442,6 +1442,7 @@ build_functional_cast (tree exp, tree parms, tsubst_flags_t complain)
 
   /* The type to which we are casting.  */
   tree type;
 
   /* The type to which we are casting.  */
   tree type;
+  VEC(tree,gc) *parmvec;
 
   if (exp == error_mark_node || parms == error_mark_node)
     return error_mark_node;
 
   if (exp == error_mark_node || parms == error_mark_node)
     return error_mark_node;
@@ -1512,8 +1513,12 @@ build_functional_cast (tree exp, tree parms, tsubst_flags_t complain)
     }
 
   /* Call the constructor.  */
     }
 
   /* Call the constructor.  */
-  exp = build_special_member_call (NULL_TREE, complete_ctor_identifier, parms,
-                                  type, LOOKUP_NORMAL, complain);
+  parmvec = make_tree_vector ();
+  for (; parms != NULL_TREE; parms = TREE_CHAIN (parms))
+    VEC_safe_push (tree, gc, parmvec, TREE_VALUE (parms));
+  exp = build_special_member_call (NULL_TREE, complete_ctor_identifier,
+                                  &parmvec, type, LOOKUP_NORMAL, complain);
+  release_tree_vector (parmvec);
 
   if (exp == error_mark_node)
     return error_mark_node;
 
   if (exp == error_mark_node)
     return error_mark_node;
index a1f0f24..f65fa96 100644 (file)
@@ -1,3 +1,8 @@
+2009-05-20  Ian Lance Taylor  <iant@google.com>
+
+       * objc-act.c (objc_generate_cxx_ctor_or_dtor): Pass NULL rather
+       than NULL_TREE to build_special_member_call.
+
 2009-05-10  Ian Lance Taylor  <iant@google.com>
 
        * objc-act.c (objc_building_struct): New static variable.
 2009-05-10  Ian Lance Taylor  <iant@google.com>
 
        * objc-act.c (objc_building_struct): New static variable.
index 9bf7d3f..d4624bb 100644 (file)
@@ -4538,7 +4538,7 @@ objc_generate_cxx_ctor_or_dtor (bool dtor)
             (build_special_member_call
              (build_ivar_reference (DECL_NAME (ivar)),
               dtor ? complete_dtor_identifier : complete_ctor_identifier,
             (build_special_member_call
              (build_ivar_reference (DECL_NAME (ivar)),
               dtor ? complete_dtor_identifier : complete_ctor_identifier,
-              NULL_TREE, type, LOOKUP_NORMAL, tf_warning_or_error));
+              NULL, type, LOOKUP_NORMAL, tf_warning_or_error));
        }
     }
 
        }
     }
 
index 92f16e7..b1ab5a5 100644 (file)
@@ -1827,6 +1827,23 @@ build_tree_list_stat (tree parm, tree value MEM_STAT_DECL)
   return t;
 }
 
   return t;
 }
 
+/* Build a chain of TREE_LIST nodes from a vector.  */
+
+tree
+build_tree_list_vec_stat (const VEC(tree,gc) *vec MEM_STAT_DECL)
+{
+  tree ret = NULL_TREE;
+  tree *pp = &ret;
+  unsigned int i;
+  tree t;
+  for (i = 0; VEC_iterate (tree, vec, i, t); ++i)
+    {
+      *pp = build_tree_list_stat (NULL, t PASS_MEM_STAT);
+      pp = &TREE_CHAIN (*pp);
+    }
+  return ret;
+}
+
 /* Return a newly created TREE_LIST node whose
    purpose and value fields are PURPOSE and VALUE
    and whose TREE_CHAIN is CHAIN.  */
 /* Return a newly created TREE_LIST node whose
    purpose and value fields are PURPOSE and VALUE
    and whose TREE_CHAIN is CHAIN.  */
@@ -1870,6 +1887,22 @@ ctor_to_list (tree ctor)
 
   return list;
 }
 
   return list;
 }
+
+/* Return the values of the elements of a CONSTRUCTOR as a vector of
+   trees.  */
+
+VEC(tree,gc) *
+ctor_to_vec (tree ctor)
+{
+  VEC(tree, gc) *vec = VEC_alloc (tree, gc, CONSTRUCTOR_NELTS (ctor));
+  unsigned int ix;
+  tree val;
+
+  FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (ctor), ix, val)
+    VEC_quick_push (tree, vec, val);
+
+  return vec;
+}
 \f
 /* Return the size nominally occupied by an object of type TYPE
    when it resides in memory.  The value is measured in units of bytes,
 \f
 /* Return the size nominally occupied by an object of type TYPE
    when it resides in memory.  The value is measured in units of bytes,
@@ -3483,6 +3516,23 @@ build_nt_call_list (tree fn, tree arglist)
     CALL_EXPR_ARG (t, i) = TREE_VALUE (arglist);
   return t;
 }
     CALL_EXPR_ARG (t, i) = TREE_VALUE (arglist);
   return t;
 }
+
+/* Similar to build_nt, but for creating a CALL_EXPR object with a
+   tree VEC.  */
+
+tree
+build_nt_call_vec (tree fn, VEC(tree,gc) *args)
+{
+  tree ret, t;
+  unsigned int ix;
+
+  ret = build_vl_exp (CALL_EXPR, VEC_length (tree, args) + 3);
+  CALL_EXPR_FN (ret) = fn;
+  CALL_EXPR_STATIC_CHAIN (ret) = NULL_TREE;
+  for (ix = 0; VEC_iterate (tree, args, ix, t); ++ix)
+    CALL_EXPR_ARG (ret, ix) = t;
+  return ret;
+}
 \f
 /* Create a DECL_... node of code CODE, name NAME and data type TYPE.
    We do NOT enter this node in any sort of symbol table.
 \f
 /* Create a DECL_... node of code CODE, name NAME and data type TYPE.
    We do NOT enter this node in any sort of symbol table.
@@ -8240,7 +8290,7 @@ build_call_valist (tree return_type, tree fn, int nargs, va_list args)
    which are specified as a tree array ARGS.  */
 
 tree
    which are specified as a tree array ARGS.  */
 
 tree
-build_call_array (tree return_type, tree fn, int nargs, tree *args)
+build_call_array (tree return_type, tree fn, int nargs, const tree *args)
 {
   tree t;
   int i;
 {
   tree t;
   int i;
@@ -8255,6 +8305,24 @@ build_call_array (tree return_type, tree fn, int nargs, tree *args)
   return t;
 }
 
   return t;
 }
 
+/* Like build_call_array, but takes a VEC.  */
+
+tree
+build_call_vec (tree return_type, tree fn, VEC(tree,gc) *args)
+{
+  tree ret, t;
+  unsigned int ix;
+
+  ret = build_vl_exp (CALL_EXPR, VEC_length (tree, args) + 3);
+  TREE_TYPE (ret) = return_type;
+  CALL_EXPR_FN (ret) = fn;
+  CALL_EXPR_STATIC_CHAIN (ret) = NULL_TREE;
+  for (ix = 0; VEC_iterate (tree, args, ix, t); ++ix)
+    CALL_EXPR_ARG (ret, ix) = t;
+  process_call_operands (ret);
+  return ret;
+}
+
 
 /* Returns true if it is possible to prove that the index of
    an array access REF (an ARRAY_REF expression) falls into the
 
 /* Returns true if it is possible to prove that the index of
    an array access REF (an ARRAY_REF expression) falls into the
index 66d4e25..cdabb3e 100644 (file)
@@ -3833,6 +3833,7 @@ extern tree maybe_get_identifier (const char *);
 
 extern tree build_nt (enum tree_code, ...);
 extern tree build_nt_call_list (tree, tree);
 
 extern tree build_nt (enum tree_code, ...);
 extern tree build_nt_call_list (tree, tree);
+extern tree build_nt_call_vec (tree, VEC(tree,gc) *);
 
 extern tree build0_stat (enum tree_code, tree MEM_STAT_DECL);
 #define build0(c,t) build0_stat (c,t MEM_STAT_INFO)
 
 extern tree build0_stat (enum tree_code, tree MEM_STAT_DECL);
 #define build0(c,t) build0_stat (c,t MEM_STAT_INFO)
@@ -3870,6 +3871,8 @@ extern tree build_one_cst (tree);
 extern tree build_string (int, const char *);
 extern tree build_tree_list_stat (tree, tree MEM_STAT_DECL);
 #define build_tree_list(t,q) build_tree_list_stat(t,q MEM_STAT_INFO)
 extern tree build_string (int, const char *);
 extern tree build_tree_list_stat (tree, tree MEM_STAT_DECL);
 #define build_tree_list(t,q) build_tree_list_stat(t,q MEM_STAT_INFO)
+extern tree build_tree_list_vec_stat (const VEC(tree,gc) * MEM_STAT_DECL);
+#define build_tree_list_vec(v) build_tree_list_vec_stat (v MEM_STAT_INFO)
 extern tree build_decl_stat (enum tree_code, tree, tree MEM_STAT_DECL);
 extern tree build_fn_decl (const char *, tree);
 #define build_decl(c,t,q) build_decl_stat (c,t,q MEM_STAT_INFO)
 extern tree build_decl_stat (enum tree_code, tree, tree MEM_STAT_DECL);
 extern tree build_fn_decl (const char *, tree);
 #define build_decl(c,t,q) build_decl_stat (c,t,q MEM_STAT_INFO)
@@ -3883,7 +3886,8 @@ extern tree build_vl_exp_stat (enum tree_code, int MEM_STAT_DECL);
 extern tree build_call_list (tree, tree, tree);
 extern tree build_call_nary (tree, tree, int, ...);
 extern tree build_call_valist (tree, tree, int, va_list);
 extern tree build_call_list (tree, tree, tree);
 extern tree build_call_nary (tree, tree, int, ...);
 extern tree build_call_valist (tree, tree, int, va_list);
-extern tree build_call_array (tree, tree, int, tree*);
+extern tree build_call_array (tree, tree, int, const tree *);
+extern tree build_call_vec (tree, tree, VEC(tree,gc) *);
 
 /* Construct various nodes representing data types.  */
 
 
 /* Construct various nodes representing data types.  */
 
@@ -4310,6 +4314,10 @@ extern bool initializer_zerop (const_tree);
 
 extern tree ctor_to_list (tree);
 
 
 extern tree ctor_to_list (tree);
 
+/* Given a CONSTRUCTOR CTOR, return the element values as a vector.  */
+
+extern VEC(tree,gc) *ctor_to_vec (tree);
+
 /* Examine CTOR to discover:
    * how many scalar fields are set to nonzero values,
      and place it in *P_NZ_ELTS;
 /* Examine CTOR to discover:
    * how many scalar fields are set to nonzero values,
      and place it in *P_NZ_ELTS;