init.c (build_new_1): Split out from build_new.
[gcc.git] / gcc / cp / call.c
index c2c0eddc71057d7835587fcb88dcafa8b0aac9da..848a821ee953511b26c24f9ab56c29ca25a0abb0 100644 (file)
@@ -1,5 +1,5 @@
 /* Functions related to invoking methods and overloaded functions.
-   Copyright (C) 1987, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+   Copyright (C) 1987, 92, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
    Contributed by Michael Tiemann (tiemann@cygnus.com) and
    hacked by Brendan Kehoe (brendan@cygnus.com).
 
@@ -31,12 +31,14 @@ Boston, MA 02111-1307, USA.  */
 #include "output.h"
 #include "flags.h"
 
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
 #include "obstack.h"
 #define obstack_chunk_alloc xmalloc
 #define obstack_chunk_free free
 
-extern void sorry ();
-
 extern int inhibit_warnings;
 extern tree ctor_label, dtor_label;
 
@@ -44,6 +46,63 @@ extern tree ctor_label, dtor_label;
    between an expected and the given type.  */
 
 static struct harshness_code convert_harshness PROTO((register tree, register tree, tree));
+static tree build_new_method_call              PROTO((tree, tree, tree, tree, int));
+
+static int rank_for_ideal PROTO((struct candidate *,
+                                struct candidate *));
+static int user_harshness PROTO((tree, tree));
+static int strictly_better PROTO((unsigned int, unsigned int));
+static struct candidate * ideal_candidate PROTO((struct candidate *,
+                                                int, int));
+static int may_be_remote PROTO((tree));
+static tree build_field_call PROTO((tree, tree, tree, tree));
+static tree find_scoped_type PROTO((tree, tree, tree));
+static void print_candidates PROTO((tree));
+static struct z_candidate * tourney PROTO((struct z_candidate *));
+static int joust PROTO((struct z_candidate *, struct z_candidate *));
+static int compare_qual PROTO((tree, tree));
+static int compare_ics PROTO((tree, tree));
+static tree build_over_call PROTO((tree, tree, tree, int));
+static tree convert_default_arg PROTO((tree, tree));
+static void enforce_access PROTO((tree, tree));
+static tree convert_like PROTO((tree, tree));
+static void op_error PROTO((enum tree_code, enum tree_code, tree, tree,
+                           tree, char *));
+static tree build_object_call PROTO((tree, tree));
+static tree resolve_args PROTO((tree));
+static struct z_candidate * build_user_type_conversion_1
+       PROTO ((tree, tree, int));
+static void print_z_candidates PROTO((struct z_candidate *));
+static tree build_this PROTO((tree));
+static struct z_candidate * splice_viable PROTO((struct z_candidate *));
+static int any_viable PROTO((struct z_candidate *));
+static struct z_candidate * add_template_candidate
+       PROTO((struct z_candidate *, tree, tree, tree, tree, int));
+static struct z_candidate * add_template_conv_candidate 
+        PROTO((struct z_candidate *, tree, tree, tree, tree));
+static struct z_candidate * add_builtin_candidates
+       PROTO((struct z_candidate *, enum tree_code, enum tree_code,
+              tree, tree *, int));
+static struct z_candidate * add_builtin_candidate
+       PROTO((struct z_candidate *, enum tree_code, enum tree_code,
+              tree, tree, tree, tree *, tree *, int));
+static int is_complete PROTO((tree));
+static struct z_candidate * build_builtin_candidate 
+       PROTO((struct z_candidate *, tree, tree, tree, tree *, tree *,
+              int));
+static struct z_candidate * add_conv_candidate 
+       PROTO((struct z_candidate *, tree, tree, tree));
+static struct z_candidate * add_function_candidate 
+       PROTO((struct z_candidate *, tree, tree, int));
+static tree implicit_conversion PROTO((tree, tree, tree, int));
+static tree standard_conversion PROTO((tree, tree, tree));
+static tree reference_binding PROTO((tree, tree, tree, int));
+static tree strip_top_quals PROTO((tree));
+static tree non_reference PROTO((tree));
+static tree build_conv PROTO((enum tree_code, tree, tree));
+static void print_n_candidates PROTO((struct candidate *, int));
+static tree default_parm_conversions PROTO((tree, tree *));
+static int is_subseq PROTO((tree, tree));
 
 #define EVIL_RETURN(ARG)       ((ARG).code = EVIL_CODE, (ARG))
 #define STD_RETURN(ARG)                ((ARG).code = STD_CODE, (ARG))
@@ -82,7 +141,7 @@ rank_for_overload (x, y)
 
 /* Compare two candidates, argument by argument.  */
 
-int
+static int
 rank_for_ideal (x, y)
      struct candidate *x, *y;
 {
@@ -627,7 +686,7 @@ convert_harshness (type, parmtype, parm)
 /* A clone of build_type_conversion for checking user-defined conversions in
    overload resolution.  */
 
-int
+static int
 user_harshness (type, parmtype)
      register tree type, parmtype;
 {
@@ -1030,7 +1089,7 @@ compute_conversion_costs (function, tta_in, cp, arglen)
 
 static int
 strictly_better (x, y)
-     unsigned short x, y;
+     unsigned int x, y;
 {
   unsigned short xor;
 
@@ -1071,7 +1130,7 @@ ideal_candidate (candidates, n_candidates, len)
      functions.  */
 
   qsort (candidates, n_candidates, sizeof (struct candidate),
-        rank_for_overload);
+        (int (*) PROTO((const void *, const void *))) rank_for_overload);
   best_code = cp[-1].h.code;
 
   /* If they're at least as good as each other, do an arg-by-arg check.  */
@@ -1085,7 +1144,7 @@ ideal_candidate (candidates, n_candidates, len)
          break;
 
       qsort (candidates+j, n_candidates-j, sizeof (struct candidate),
-            rank_for_ideal);
+            (int (*) PROTO((const void *, const void *))) rank_for_ideal);
       for (i = 0; i < len; i++)
        {
          if (cp[-1].harshness[i].code < cp[-2].harshness[i].code)
@@ -1175,6 +1234,9 @@ build_field_call (basetype_path, instance_ptr, name, parms)
 {
   tree field, instance;
 
+  if (name == ctor_identifier || name == dtor_identifier)
+    return NULL_TREE;
+
   if (instance_ptr == current_class_ptr)
     {
       /* Check to see if we really have a reference to an instance variable
@@ -1205,7 +1267,7 @@ build_field_call (basetype_path, instance_ptr, name, parms)
              if (TREE_CODE (TREE_TYPE (TREE_TYPE (instance))) == FUNCTION_TYPE)
                return build_function_call (instance, parms);
              else if (TREE_CODE (TREE_TYPE (TREE_TYPE (instance))) == METHOD_TYPE)
-               return build_function_call (instance, tree_cons (NULL_TREE, current_class_ptr, parms));
+               return build_function_call (instance, expr_tree_cons (NULL_TREE, current_class_ptr, parms));
            }
        }
       return NULL_TREE;
@@ -1266,7 +1328,7 @@ build_field_call (basetype_path, instance_ptr, name, parms)
   return NULL_TREE;
 }
 
-tree
+static tree
 find_scoped_type (type, inner_name, inner_types)
      tree type, inner_name, inner_types;
 {
@@ -1424,6 +1486,14 @@ build_scoped_method_call (exp, basetype, name, parms)
   if (TREE_CODE (type) == REFERENCE_TYPE)
     type = TREE_TYPE (type);
 
+  if (TREE_CODE (basetype) == TREE_VEC)
+    {
+      binfo = basetype;
+      basetype = BINFO_TYPE (binfo);
+    }
+  else
+    binfo = NULL_TREE;
+
   /* Destructors can be "called" for simple types; see 5.2.4 and 12.4 Note
      that explicit ~int is caught in the parser; this deals with typedefs
      and template parms.  */
@@ -1436,7 +1506,7 @@ build_scoped_method_call (exp, basetype, name, parms)
       if (basetype != name && basetype != get_type_value (name))
        cp_error ("qualified type `%T' does not match destructor name `~%T'",
                  basetype, name);
-      return convert (void_type_node, exp);
+      return cp_convert (void_type_node, exp);
     }
 
   if (! is_aggr_type (basetype, 1))
@@ -1449,13 +1519,21 @@ build_scoped_method_call (exp, basetype, name, parms)
       return error_mark_node;
     }
 
-  if ((binfo = binfo_or_else (basetype, type)))
+  if (! binfo)
     {
+      binfo = get_binfo (basetype, type, 1);
       if (binfo == error_mark_node)
        return error_mark_node;
+      if (! binfo)
+       error_not_base_type (basetype, type);
+    }
+
+  if (binfo)
+    {
       if (TREE_CODE (exp) == INDIRECT_REF)
-       decl = build_indirect_ref (convert_pointer_to (binfo,
-                                                      build_unary_op (ADDR_EXPR, exp, 0)), NULL_PTR);
+       decl = build_indirect_ref
+         (convert_pointer_to_real
+          (binfo, build_unary_op (ADDR_EXPR, exp, 0)), NULL_PTR);
       else
        decl = build_scoped_ref (exp, basetype);
 
@@ -1474,7 +1552,7 @@ build_scoped_method_call (exp, basetype, name, parms)
              return error_mark_node;
            }
          if (! TYPE_HAS_DESTRUCTOR (TREE_TYPE (decl)))
-           return convert (void_type_node, exp);
+           return cp_convert (void_type_node, exp);
          
          return build_delete (TREE_TYPE (decl), decl, integer_two_node,
                               LOOKUP_NORMAL|LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR,
@@ -1731,11 +1809,11 @@ build_method_call (instance, name, parms, basetype_path, flags)
        {
          cp_error ("destructor name `~%D' does not match type `%T' of expression",
                    name, basetype);
-         return convert (void_type_node, instance);
+         return cp_convert (void_type_node, instance);
        }
 
-      if (! TYPE_HAS_DESTRUCTOR (basetype))
-       return convert (void_type_node, instance);
+      if (! TYPE_HAS_DESTRUCTOR (complete_type (basetype)))
+       return cp_convert (void_type_node, instance);
       instance = default_conversion (instance);
       instance_ptr = build_unary_op (ADDR_EXPR, instance, 0);
       return build_delete (build_pointer_type (basetype),
@@ -1820,7 +1898,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
       if (! IS_AGGR_TYPE (basetype))
        {
        non_aggr_error:
-         if ((flags & LOOKUP_COMPLAIN) && TREE_CODE (basetype) != ERROR_MARK)
+         if ((flags & LOOKUP_COMPLAIN) && basetype != error_mark_node)
            cp_error ("request for member `%D' in `%E', which is of non-aggregate type `%T'",
                      name, instance, basetype);
 
@@ -1876,10 +1954,10 @@ build_method_call (instance, name, parms, basetype_path, flags)
       /* The MAIN_VARIANT of the type that `instance_ptr' winds up being.  */
       tree inst_ptr_basetype;
 
-      static_call_context =
-       (TREE_CODE (instance) == INDIRECT_REF
-        && TREE_CODE (TREE_OPERAND (instance, 0)) == NOP_EXPR
-        && TREE_OPERAND (TREE_OPERAND (instance, 0), 0) == error_mark_node);
+      static_call_context
+       (TREE_CODE (instance) == INDIRECT_REF
+          && TREE_CODE (TREE_OPERAND (instance, 0)) == NOP_EXPR
+          && TREE_OPERAND (TREE_OPERAND (instance, 0), 0) == error_mark_node);
 
       if (TREE_CODE (instance) == OFFSET_REF)
        instance = resolve_offset_ref (instance);
@@ -1966,7 +2044,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
            basetype = inst_ptr_basetype;
          else
            {
-             instance_ptr = convert (build_pointer_type (basetype), instance_ptr);
+             instance_ptr = cp_convert (build_pointer_type (basetype), instance_ptr);
              if (instance_ptr == error_mark_node)
                return error_mark_node;
            }
@@ -1977,8 +2055,9 @@ build_method_call (instance, name, parms, basetype_path, flags)
       if (basetype_path == NULL_TREE
          && IS_SIGNATURE (basetype))
        basetype_path = TYPE_BINFO (basetype);
-      else if (basetype_path == NULL_TREE ||
-       BINFO_TYPE (basetype_path) != TYPE_MAIN_VARIANT (inst_ptr_basetype))
+      else if (basetype_path == NULL_TREE
+              || (BINFO_TYPE (basetype_path)
+                  != TYPE_MAIN_VARIANT (inst_ptr_basetype)))
        basetype_path = TYPE_BINFO (inst_ptr_basetype);
 
       result = build_field_call (basetype_path, instance_ptr, name, parms);
@@ -2031,14 +2110,14 @@ build_method_call (instance, name, parms, basetype_path, flags)
         of the signature pointer?  */
       constp = TYPE_READONLY (basetype);
       volatilep = TYPE_VOLATILE (basetype);
-      parms = tree_cons (NULL_TREE, instance_ptr, parms);
+      parms = expr_tree_cons (NULL_TREE, instance_ptr, parms);
     }
   else if (instance)
     {
       /* TREE_READONLY (instance) fails for references.  */
       constp = TYPE_READONLY (TREE_TYPE (TREE_TYPE (instance_ptr)));
       volatilep = TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (instance_ptr)));
-      parms = tree_cons (NULL_TREE, instance_ptr, parms);
+      parms = expr_tree_cons (NULL_TREE, instance_ptr, parms);
     }
   else
     {
@@ -2047,18 +2126,18 @@ build_method_call (instance, name, parms, basetype_path, flags)
          && ! (flags & LOOKUP_HAS_IN_CHARGE))
        {
          flags |= LOOKUP_HAS_IN_CHARGE;
-         parms = tree_cons (NULL_TREE, integer_one_node, parms);
-         parmtypes = tree_cons (NULL_TREE, integer_type_node, parmtypes);
+         parms = expr_tree_cons (NULL_TREE, integer_one_node, parms);
+         parmtypes = scratch_tree_cons (NULL_TREE, integer_type_node, parmtypes);
        }
 
       constp = 0;
       volatilep = 0;
       instance_ptr = build_int_2 (0, 0);
       TREE_TYPE (instance_ptr) = build_pointer_type (basetype);
-      parms = tree_cons (NULL_TREE, instance_ptr, parms);
+      parms = expr_tree_cons (NULL_TREE, instance_ptr, parms);
     }
 
-  parmtypes = tree_cons (NULL_TREE, TREE_TYPE (instance_ptr), parmtypes);
+  parmtypes = scratch_tree_cons (NULL_TREE, TREE_TYPE (instance_ptr), parmtypes);
 
   if (last == NULL_TREE)
     last = parmtypes;
@@ -2092,10 +2171,10 @@ build_method_call (instance, name, parms, basetype_path, flags)
              tree tmplist;
              
              flags |= LOOKUP_HAS_IN_CHARGE;
-             tmplist = tree_cons (NULL_TREE, integer_zero_node,
+             tmplist = expr_tree_cons (NULL_TREE, integer_zero_node,
                                   TREE_CHAIN (parms));
              TREE_CHAIN (parms) = tmplist;
-             tmplist = tree_cons (NULL_TREE, integer_type_node, TREE_CHAIN (parmtypes));
+             tmplist = scratch_tree_cons (NULL_TREE, integer_type_node, TREE_CHAIN (parmtypes));
              TREE_CHAIN (parmtypes) = tmplist;
            }
          basetype = BINFO_TYPE (tmp);
@@ -2146,7 +2225,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
              else
                my_friendly_abort (167);
 
-             friend_parms = tree_cons (NULL_TREE, parm, TREE_CHAIN (parms));
+             friend_parms = expr_tree_cons (NULL_TREE, parm, TREE_CHAIN (parms));
 
              cp->h_len = len;
              cp->harshness = (struct harshness_code *)
@@ -2196,7 +2275,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
 #endif
              ever_seen++;
              if (pass > 0)
-               found_fns = tree_cons (NULL_TREE, function, found_fns);
+               found_fns = scratch_tree_cons (NULL_TREE, function, found_fns);
 
              /* Not looking for friends here.  */
              if (TREE_CODE (TREE_TYPE (function)) == FUNCTION_TYPE
@@ -2527,7 +2606,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
          instance_ptr = convert_pointer_to (basetype, instance_ptr);
          instance = build_indirect_ref (instance_ptr, NULL_PTR);
        }
-      parms = tree_cons (NULL_TREE, instance_ptr,
+      parms = expr_tree_cons (NULL_TREE, instance_ptr,
                         convert_arguments (NULL_TREE, TREE_CHAIN (TYPE_ARG_TYPES (fntype)), TREE_CHAIN (parms), function, sub_flags));
     }
   else
@@ -2568,14 +2647,14 @@ build_method_call (instance, name, parms, basetype_path, flags)
                   && TREE_OPERAND (TREE_OPERAND (instance_ptr, 0), 0) == instance)
            ;
          /* The call to `convert_pointer_to' may return error_mark_node.  */
-         else if (TREE_CODE (instance_ptr) == ERROR_MARK)
+         else if (instance_ptr == error_mark_node)
            return instance_ptr;
          else if (instance == NULL_TREE
                   || TREE_CODE (instance) != INDIRECT_REF
                   || TREE_OPERAND (instance, 0) != instance_ptr)
            instance = build_indirect_ref (instance_ptr, NULL_PTR);
        }
-      parms = tree_cons (NULL_TREE, instance_ptr,
+      parms = expr_tree_cons (NULL_TREE, instance_ptr,
                         convert_arguments (NULL_TREE, TREE_CHAIN (TYPE_ARG_TYPES (fntype)), TREE_CHAIN (parms), function, LOOKUP_NORMAL));
     }
 
@@ -2762,13 +2841,14 @@ build_overload_call_real (fnname, parms, flags, final_cp, require_complete)
        }
       if (TREE_CODE (function) == TEMPLATE_DECL)
        {
-         int ntparms = TREE_VEC_LENGTH (DECL_TEMPLATE_PARMS (function));
-         tree *targs = (tree *) alloca (sizeof (tree) * ntparms);
+         int ntparms = DECL_NTPARMS (function);
+         tree targs = make_scratch_vec (ntparms);
          int i;
 
-         i = type_unification (DECL_TEMPLATE_PARMS (function), targs,
+         i = type_unification (DECL_INNERMOST_TEMPLATE_PARMS (function),
+                               &TREE_VEC_ELT (targs, 0),
                                TYPE_ARG_TYPES (TREE_TYPE (function)),
-                               parms, &template_cost, 0, 0);
+                               parms, NULL_TREE, &template_cost, 0, 0);
          if (i == 0)
            {
              function = instantiate_template (function, targs);
@@ -2805,7 +2885,7 @@ build_overload_call_real (fnname, parms, flags, final_cp, require_complete)
             passed to calling function.  */
          cp->h_len = parmlength;
          cp->harshness = (struct harshness_code *)
-           oballoc ((parmlength + 1) * sizeof (struct harshness_code));
+           scratchalloc ((parmlength + 1) * sizeof (struct harshness_code));
 
          compute_conversion_costs (function, parms, cp, parmlength);
 
@@ -2864,8 +2944,7 @@ build_overload_call_real (fnname, parms, flags, final_cp, require_complete)
     return NULL_TREE;
   
   if (flags & LOOKUP_COMPLAIN)
-    report_type_mismatch (cp, parms, "function",
-                         decl_as_string (cp->function, 1));
+    report_type_mismatch (cp, parms, "function");
 
   return error_mark_node;
 }
@@ -2916,26 +2995,17 @@ struct z_candidate {
 
 #define USER_CONV_FN(NODE) TREE_OPERAND (NODE, 1)
 
-static struct z_candidate * build_user_type_conversion_1 ();
-static tree convert_like ();
-static tree build_over_call ();
-static struct z_candidate * tourney ();
-static void enforce_access ();
-
 int
 null_ptr_cst_p (t)
      tree t;
 {
   if (t == null_node
-      || integer_zerop (t) && INTEGRAL_TYPE_P (TREE_TYPE (t)))
-    return 1;
-  /* Remove this eventually.  */
-  if (! pedantic && TREE_TYPE (t) == ptr_type_node && integer_zerop (t))
+      || integer_zerop (t) && TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE)
     return 1;
   return 0;
 }
 
-tree
+static tree
 build_conv (code, type, from)
      enum tree_code code;
      tree type, from;
@@ -2952,9 +3022,7 @@ build_conv (code, type, from)
        rank = STD_RANK;
       break;
 
-    case LVALUE_CONV:
     case QUAL_CONV:
-    case RVALUE_CONV:
       if (rank < EXACT_RANK)
        rank = EXACT_RANK;
 
@@ -2967,7 +3035,7 @@ build_conv (code, type, from)
   return t;
 }
 
-tree
+static tree
 non_reference (t)
      tree t;
 {
@@ -2976,7 +3044,7 @@ non_reference (t)
   return t;
 }
 
-tree
+static tree
 strip_top_quals (t)
      tree t;
 {
@@ -2989,7 +3057,7 @@ strip_top_quals (t)
    TO, if any.  For proper handling of null pointer constants, you must
    also pass the expression EXPR to convert from.  */
 
-tree
+static tree
 standard_conversion (to, from, expr)
      tree to, from, expr;
 {
@@ -3158,7 +3226,7 @@ standard_conversion (to, from, expr)
    Currently does not distinguish in the generated trees between binding to
    an lvalue and a temporary.  Should it?  */
 
-tree
+static tree
 reference_binding (rto, rfrom, expr, flags)
      tree rto, rfrom, expr;
      int flags;
@@ -3167,13 +3235,18 @@ reference_binding (rto, rfrom, expr, flags)
   int lvalue = 1;
   tree to = TREE_TYPE (rto);
   tree from = rfrom;
+  int related;
 
   if (TREE_CODE (from) == REFERENCE_TYPE)
     from = TREE_TYPE (from);
   else if (! expr || ! real_lvalue_p (expr))
     lvalue = 0;
 
-  if (lvalue
+  related = (TYPE_MAIN_VARIANT (to) == TYPE_MAIN_VARIANT (from)
+            || (IS_AGGR_TYPE (to) && IS_AGGR_TYPE (from)
+                && DERIVED_FROM_P (to, from)));
+
+  if (lvalue && related
       && TYPE_READONLY (to) >= TYPE_READONLY (from)
       && TYPE_VOLATILE (to) >= TYPE_VOLATILE (from))
     {
@@ -3181,14 +3254,11 @@ reference_binding (rto, rfrom, expr, flags)
 
       if (TYPE_MAIN_VARIANT (to) == TYPE_MAIN_VARIANT (from))
        conv = build_conv (REF_BIND, rto, conv);
-      else if (IS_AGGR_TYPE (to) && IS_AGGR_TYPE (from)
-              && DERIVED_FROM_P (to, from))
+      else
        {
          conv = build_conv (REF_BIND, rto, conv);
          ICS_STD_RANK (conv) = STD_RANK;
        }
-      else
-       conv = NULL_TREE;
     }
   else
     conv = NULL_TREE;
@@ -3205,8 +3275,15 @@ reference_binding (rto, rfrom, expr, flags)
          if (TREE_CODE (TREE_OPERAND (conv, 0)) == BASE_CONV)
            TREE_OPERAND (conv, 0) = TREE_OPERAND (TREE_OPERAND (conv, 0), 0);
        }
-      if (conv && ! (TYPE_READONLY (to) && ! TYPE_VOLATILE (to)
-                    && (flags & LOOKUP_NO_TEMP_BIND) == 0))
+      if (conv
+         && ((! (TYPE_READONLY (to) && ! TYPE_VOLATILE (to)
+                 && (flags & LOOKUP_NO_TEMP_BIND) == 0))
+             /* If T1 is reference-related to T2, cv1 must be the same
+                cv-qualification as, or greater cv-qualification than,
+                cv2; otherwise, the program is ill-formed.  */
+             || (related
+                 && (TYPE_READONLY (to) < TYPE_READONLY (from)
+                     || TYPE_VOLATILE (to) < TYPE_VOLATILE (from)))))
        ICS_BAD_FLAG (conv) = 1;
     }
 
@@ -3218,7 +3295,7 @@ reference_binding (rto, rfrom, expr, flags)
    FLAGS are the usual overloading flags.  Only LOOKUP_NO_CONVERSION is
    significant.  */
 
-tree
+static tree
 implicit_conversion (to, from, expr, flags)
      tree to, from, expr;
      int flags;
@@ -3241,26 +3318,30 @@ implicit_conversion (to, from, expr, flags)
 
   if (conv)
     ;
-  else if ((IS_AGGR_TYPE (non_reference (from))
+  else if (expr != NULL_TREE
+          && (IS_AGGR_TYPE (non_reference (from))
            || IS_AGGR_TYPE (non_reference (to)))
           && (flags & LOOKUP_NO_CONVERSION) == 0)
     {
-      if (TREE_CODE (to) == REFERENCE_TYPE
-         && TYPE_READONLY (TREE_TYPE (to))
-         && ! TYPE_VOLATILE (TREE_TYPE (to))
+      cand = build_user_type_conversion_1
+       (to, expr, LOOKUP_ONLYCONVERTING);
+      if (cand)
+       conv = cand->second_conv;
+      if ((! conv || ICS_BAD_FLAG (conv))
+         && TREE_CODE (to) == REFERENCE_TYPE
          && (flags & LOOKUP_NO_TEMP_BIND) == 0)
        {
          cand = build_user_type_conversion_1
            (TYPE_MAIN_VARIANT (TREE_TYPE (to)), expr, LOOKUP_ONLYCONVERTING);
          if (cand)
-           conv = build_conv (REF_BIND, to, cand->second_conv);
-       }
-      else
-       {
-         cand = build_user_type_conversion_1
-           (to, expr, LOOKUP_ONLYCONVERTING);
-         if (cand)
-           conv = cand->second_conv;
+           {
+             if (! TYPE_READONLY (TREE_TYPE (to))
+                 || TYPE_VOLATILE (TREE_TYPE (to)))
+               ICS_BAD_FLAG (cand->second_conv) = 1;
+             if (!conv || (ICS_BAD_FLAG (conv)
+                           > ICS_BAD_FLAG (cand->second_conv)))
+               conv = build_conv (REF_BIND, to, cand->second_conv);
+           }
        }
     }
 
@@ -3299,7 +3380,7 @@ add_function_candidate (candidates, fn, arglist, flags)
     }
 
   len = list_length (argnode);
-  convs = make_tree_vec (len);
+  convs = make_scratch_vec (len);
 
   for (i = 0; i < len; ++i)
     {
@@ -3348,7 +3429,7 @@ add_function_candidate (candidates, fn, arglist, flags)
        break;
       }
 
-  cand = (struct z_candidate *) oballoc (sizeof (struct z_candidate));
+  cand = (struct z_candidate *) scratchalloc (sizeof (struct z_candidate));
 
   cand->fn = fn;
   cand->convs = convs;
@@ -3374,7 +3455,7 @@ add_conv_candidate (candidates, fn, obj, arglist)
   tree totype = TREE_TYPE (TREE_TYPE (fn));
   tree parmlist = TYPE_ARG_TYPES (TREE_TYPE (totype));
   int i, len = list_length (arglist) + 1;
-  tree convs = make_tree_vec (len);
+  tree convs = make_scratch_vec (len);
   tree parmnode = parmlist;
   tree argnode = arglist;
   int viable = 1;
@@ -3425,7 +3506,7 @@ add_conv_candidate (candidates, fn, obj, arglist)
        break;
       }
 
-  cand = (struct z_candidate *) oballoc (sizeof (struct z_candidate));
+  cand = (struct z_candidate *) scratchalloc (sizeof (struct z_candidate));
 
   cand->fn = fn;
   cand->convs = convs;
@@ -3454,7 +3535,7 @@ build_builtin_candidate (candidates, fnname, type1, type2,
   types[0] = type1;
   types[1] = type2;
 
-  convs = make_tree_vec (args[2] ? 3 : (args[1] ? 2 : 1));
+  convs = make_scratch_vec (args[2] ? 3 : (args[1] ? 2 : 1));
 
   for (i = 0; i < 2; ++i)
     {
@@ -3485,7 +3566,7 @@ build_builtin_candidate (candidates, fnname, type1, type2,
        viable = 0;
     }      
 
-  cand = (struct z_candidate *) oballoc (sizeof (struct z_candidate));
+  cand = (struct z_candidate *) scratchalloc (sizeof (struct z_candidate));
 
   cand->fn = fnname;
   cand->convs = convs;
@@ -3498,7 +3579,7 @@ build_builtin_candidate (candidates, fnname, type1, type2,
   return cand;
 }
 
-int
+static int
 is_complete (t)
      tree t;
 {
@@ -3524,6 +3605,9 @@ add_builtin_candidate (candidates, code, code2, fnname, type1, type2,
     case POSTDECREMENT_EXPR:
       args[1] = integer_zero_node;
       type2 = integer_type_node;
+      break;
+    default:
+      break;
     }
 
   switch (code)
@@ -3616,7 +3700,7 @@ add_builtin_candidate (candidates, code, code2, fnname, type1, type2,
        {
          tree c1 = TREE_TYPE (type1);
          tree c2 = (TYPE_PTRMEMFUNC_P (type2)
-                    ? TYPE_METHOD_BASETYPE (TYPE_PTRMEMFUNC_FN_TYPE (type2))
+                    ? TYPE_METHOD_BASETYPE (TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (type2)))
                     : TYPE_OFFSET_BASETYPE (TREE_TYPE (type2)));
 
          if (IS_AGGR_TYPE (c1) && DERIVED_FROM_P (c2, c1)
@@ -3841,15 +3925,10 @@ add_builtin_candidate (candidates, code, code2, fnname, type1, type2,
       break;
 
     case COND_EXPR:
-#if 0
       /* Kludge around broken overloading rules whereby
         bool ? const char& : enum is ambiguous
         (between int and const char&).  */
-      /* Not needed for compiles without -pedantic, since the rank compare
-        in joust will pick the int promotion.  Let's just leave this out
-        for now.  */
       flags |= LOOKUP_NO_TEMP_BIND;
-#endif
 
       /* Extension: Support ?: of enumeral type.  Hopefully this will not
          be an extension for long.  */
@@ -3999,10 +4078,10 @@ add_builtin_candidates (candidates, code, code2, fnname, args, flags)
          if (code == COND_EXPR)
            {
              if (real_lvalue_p (args[i]))
-               types[i] = tree_cons
+               types[i] = scratch_tree_cons
                  (NULL_TREE, build_reference_type (argtypes[i]), types[i]);
 
-             types[i] = tree_cons
+             types[i] = scratch_tree_cons
                (NULL_TREE, TYPE_MAIN_VARIANT (argtypes[i]), types[i]);
            }
                
@@ -4020,37 +4099,37 @@ add_builtin_candidates (candidates, code, code2, fnname, args, flags)
                continue;
 
              if (code == COND_EXPR && TREE_CODE (type) == REFERENCE_TYPE)
-               types[i] = tree_cons (NULL_TREE, type, types[i]);
+               types[i] = scratch_tree_cons (NULL_TREE, type, types[i]);
 
              type = non_reference (type);
              if (i != 0 || ! ref1)
                {
                  type = TYPE_MAIN_VARIANT (type_decays_to (type));
                  if (code == COND_EXPR && TREE_CODE (type) == ENUMERAL_TYPE)
-                   types[i] = tree_cons (NULL_TREE, type, types[i]);
+                   types[i] = scratch_tree_cons (NULL_TREE, type, types[i]);
                  if (INTEGRAL_TYPE_P (type))
                    type = type_promotes_to (type);
                }
 
              if (! value_member (type, types[i]))
-               types[i] = tree_cons (NULL_TREE, type, types[i]);
+               types[i] = scratch_tree_cons (NULL_TREE, type, types[i]);
            }
        }
       else
        {
          if (code == COND_EXPR && real_lvalue_p (args[i]))
-           types[i] = tree_cons
+           types[i] = scratch_tree_cons
              (NULL_TREE, build_reference_type (argtypes[i]), types[i]);
          type = non_reference (argtypes[i]);
          if (i != 0 || ! ref1)
            {
              type = TYPE_MAIN_VARIANT (type_decays_to (type));
              if (code == COND_EXPR && TREE_CODE (type) == ENUMERAL_TYPE)
-               types[i] = tree_cons (NULL_TREE, type, types[i]);
+               types[i] = scratch_tree_cons (NULL_TREE, type, types[i]);
              if (INTEGRAL_TYPE_P (type))
                type = type_promotes_to (type);
            }
-         types[i] = tree_cons (NULL_TREE, type, types[i]);
+         types[i] = scratch_tree_cons (NULL_TREE, type, types[i]);
        }
     }
 
@@ -4070,21 +4149,30 @@ add_builtin_candidates (candidates, code, code2, fnname, args, flags)
   return candidates;
 }
 
+/* If TMPL can be successfully instantiated as indicated by
+   EXPLICIT_TARGS and ARGLIST, adds the instantiation to CANDIDATES.
+
+   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.  FLAGS are as for
+   add_function_candidate.  */
+
 static struct z_candidate *
-add_template_candidate (candidates, tmpl, arglist, flags)
+add_template_candidate (candidates, tmpl, explicit_targs, 
+                       arglist, return_type, flags)
      struct z_candidate *candidates;
-     tree tmpl, arglist;
+     tree tmpl, explicit_targs, arglist, return_type;
      int flags;
 {
-  int ntparms = TREE_VEC_LENGTH (DECL_TEMPLATE_PARMS (tmpl));
-  tree *targs = (tree *) alloca (sizeof (tree) * ntparms);
+  int ntparms = DECL_NTPARMS (tmpl);
+  tree targs = make_scratch_vec (ntparms);
   struct z_candidate *cand;
-  int i, dummy; 
+  int i;
   tree fn;
 
-  i = type_unification (DECL_TEMPLATE_PARMS (tmpl), targs,
-                       TYPE_ARG_TYPES (TREE_TYPE (tmpl)),
-                       arglist, &dummy, 0, 0);
+  i = fn_type_unification (tmpl, explicit_targs, targs, arglist,
+                          return_type, 0); 
+
   if (i != 0)
     return candidates;
 
@@ -4097,6 +4185,33 @@ add_template_candidate (candidates, tmpl, arglist, flags)
   return cand;
 }
 
+
+static struct z_candidate *
+add_template_conv_candidate (candidates, tmpl, obj, arglist, return_type)
+     struct z_candidate *candidates;
+     tree tmpl, obj, arglist, return_type;
+{
+  int ntparms = DECL_NTPARMS (tmpl);
+  tree targs = make_scratch_vec (ntparms);
+  struct z_candidate *cand;
+  int i;
+  tree fn;
+
+  i = fn_type_unification (tmpl, NULL_TREE, targs, arglist, return_type, 0);
+
+  if (i != 0)
+    return candidates;
+
+  fn = instantiate_template (tmpl, targs);
+  if (fn == error_mark_node)
+    return candidates;
+
+  cand = add_conv_candidate (candidates, fn, obj, arglist);
+  cand->template = DECL_TEMPLATE_INFO (fn);
+  return cand;
+}
+
+
 static int
 any_viable (cands)
      struct z_candidate *cands;
@@ -4124,7 +4239,7 @@ splice_viable (cands)
   return cands;
 }
 
-tree
+static tree
 build_this (obj)
      tree obj;
 {
@@ -4166,7 +4281,10 @@ print_z_candidates (candidates)
 }
 
 /* Returns the best overload candidate to perform the requested
-   conversion.  */
+   conversion.  This function is used for three the overloading situations
+   described in [over.match.copy], [over.match.conv], and [over.match.ref].
+   If TOTYPE is a REFERENCE_TYPE, we're trying to find an lvalue binding as
+   per [dcl.init.ref], so we ignore temporary bindings.  */
 
 static struct z_candidate *
 build_user_type_conversion_1 (totype, expr, flags)
@@ -4177,6 +4295,7 @@ build_user_type_conversion_1 (totype, expr, flags)
   tree fromtype = TREE_TYPE (expr);
   tree ctors = NULL_TREE, convs = NULL_TREE, *p;
   tree args;
+  tree templates = NULL_TREE;
 
   if (IS_AGGR_TYPE (totype))
     ctors = lookup_fnfields (TYPE_BINFO (totype), ctor_identifier, 0);
@@ -4191,10 +4310,10 @@ build_user_type_conversion_1 (totype, expr, flags)
     {
       tree t = build_int_2 (0, 0);
       TREE_TYPE (t) = build_pointer_type (totype);
-      args = build_tree_list (NULL_TREE, expr);
+      args = build_scratch_list (NULL_TREE, expr);
       if (TYPE_USES_VIRTUAL_BASECLASSES (totype))
-       args = tree_cons (NULL_TREE, integer_one_node, args);
-      args = tree_cons (NULL_TREE, t, args);
+       args = scratch_tree_cons (NULL_TREE, integer_one_node, args);
+      args = scratch_tree_cons (NULL_TREE, t, args);
 
       ctors = TREE_VALUE (ctors);
     }
@@ -4203,27 +4322,66 @@ build_user_type_conversion_1 (totype, expr, flags)
       if (DECL_NONCONVERTING_P (ctors))
        continue;
 
-      candidates = add_function_candidate (candidates, ctors, args, flags);
-      candidates->second_conv = build1 (IDENTITY_CONV, totype, NULL_TREE);
-      candidates->basetype_path = TYPE_BINFO (totype);
+      if (TREE_CODE (ctors) == TEMPLATE_DECL) 
+       {
+         templates = scratch_tree_cons (NULL_TREE, ctors, templates);
+         candidates = 
+           add_template_candidate (candidates, ctors,
+                                   NULL_TREE, args, NULL_TREE, flags);
+       } 
+      else 
+       candidates = add_function_candidate (candidates, ctors,
+                                            args, flags); 
+
+      if (candidates) 
+       {
+         candidates->second_conv = build1 (IDENTITY_CONV, totype, NULL_TREE);
+         candidates->basetype_path = TYPE_BINFO (totype);
+       } 
     }
 
   if (convs)
-    args = build_tree_list (NULL_TREE, build_this (expr));
+    args = build_scratch_list (NULL_TREE, build_this (expr));
 
   for (; convs; convs = TREE_CHAIN (convs))
     {
       tree fn = TREE_VALUE (convs);
-      tree ics = implicit_conversion
-       (totype, TREE_TYPE (TREE_TYPE (fn)), 0, LOOKUP_NO_CONVERSION);
-      if (ics)
+      int convflags = LOOKUP_NO_CONVERSION;
+      tree ics;
+
+      /* If we are called to convert to a reference type, we are trying to
+        find an lvalue binding, so don't even consider temporaries.  If
+        we don't find an lvalue binding, the caller will try again to
+        look for a temporary binding.  */
+      if (TREE_CODE (totype) == REFERENCE_TYPE)
+       convflags |= LOOKUP_NO_TEMP_BIND;
+
+      ics = implicit_conversion
+       (totype, TREE_TYPE (TREE_TYPE (fn)), 0, convflags);
+
+      if (TREE_CODE (totype) == REFERENCE_TYPE && ics && ICS_BAD_FLAG (ics))
+       /* ignore the near match.  */;
+      else if (ics)
        for (; fn; fn = DECL_CHAIN (fn))
          {
-           candidates = add_function_candidate (candidates, fn, args, flags);
-           candidates->second_conv = ics;
-           candidates->basetype_path = TREE_PURPOSE (convs);
-           if (candidates->viable == 1 && ICS_BAD_FLAG (ics))
-             candidates->viable = -1;
+           if (TREE_CODE (fn) == TEMPLATE_DECL)
+             {
+               templates = scratch_tree_cons (NULL_TREE, fn, templates);
+               candidates = 
+                 add_template_candidate (candidates, fn, NULL_TREE,
+                                         args, totype, flags);
+             } 
+           else 
+             candidates = add_function_candidate (candidates, fn,
+                                                  args, flags); 
+
+           if (candidates) 
+             {
+               candidates->second_conv = ics;
+               candidates->basetype_path = TREE_PURPOSE (convs);
+               if (candidates->viable == 1 && ICS_BAD_FLAG (ics))
+                 candidates->viable = -1;
+             }
          }
     }
 
@@ -4243,7 +4401,7 @@ build_user_type_conversion_1 (totype, expr, flags)
     }
 
   candidates = splice_viable (candidates);
-  cand = tourney (candidates, totype);
+  cand = tourney (candidates);
 
   if (cand == 0)
     {
@@ -4265,11 +4423,19 @@ build_user_type_conversion_1 (totype, expr, flags)
   for (p = &(cand->second_conv); TREE_CODE (*p) != IDENTITY_CONV; )
     p = &(TREE_OPERAND (*p, 0));
 
+  /* Pedantically, normal function declarations are never considered
+     to refer to template instantiations, so we only do this with
+     -fguiding-decls.  */ 
+  if (flag_guiding_decls && templates && ! cand->template 
+      && !DECL_INITIAL (cand->fn) 
+      && TREE_CODE (TREE_TYPE (cand->fn)) != METHOD_TYPE)
+    add_maybe_template (cand->fn, templates);
+
   *p = build
     (USER_CONV,
      (DECL_CONSTRUCTOR_P (cand->fn)
       ? totype : non_reference (TREE_TYPE (TREE_TYPE (cand->fn)))),
-     NULL_TREE, cand->fn, cand->convs, cand->basetype_path);
+     expr, cand->fn, cand->convs, cand->basetype_path);
   ICS_USER_FLAG (cand->second_conv) = 1;
   if (cand->viable == -1)
     ICS_BAD_FLAG (cand->second_conv) = 1;
@@ -4294,30 +4460,63 @@ build_user_type_conversion (totype, expr, flags)
   return NULL_TREE;
 }
 
+/* Do any initial processing on the arguments to a function call.  */
+
+static tree
+resolve_args (args)
+     tree args;
+{
+  tree t;
+  for (t = args; t; t = TREE_CHAIN (t))
+    {
+      if (TREE_VALUE (t) == error_mark_node)
+       return error_mark_node;
+      else if (TREE_CODE (TREE_TYPE (TREE_VALUE (t))) == VOID_TYPE)
+       {
+         error ("invalid use of void expression");
+         return error_mark_node;
+       }
+      else if (TREE_CODE (TREE_VALUE (t)) == OFFSET_REF)
+       TREE_VALUE (t) = resolve_offset_ref (TREE_VALUE (t));
+    }
+  return args;
+}
+      
 tree
-build_new_function_call (fn, args, obj)
-     tree fn, args, obj;
+build_new_function_call (fn, args)
+     tree fn, args;
 {
   struct z_candidate *candidates = 0, *cand;
-  if (obj == NULL_TREE && TREE_CODE (fn) == TREE_LIST)
+  tree explicit_targs = NULL_TREE;
+  int template_only = 0;
+
+  if (TREE_CODE (fn) == TEMPLATE_ID_EXPR)
+    {
+      explicit_targs = TREE_OPERAND (fn, 1);
+      fn = TREE_OPERAND (fn, 0);
+      template_only = 1;
+    }
+
+  if (really_overloaded_fn (fn))
     {
       tree t;
       tree templates = NULL_TREE;
 
-      for (t = args; t; t = TREE_CHAIN (t))
-       if (TREE_VALUE (t) == error_mark_node)
-         return error_mark_node;
-       
+      args = resolve_args (args);
+
+      if (args == error_mark_node)
+       return error_mark_node;
+
       for (t = TREE_VALUE (fn); t; t = DECL_CHAIN (t))
        {
          if (TREE_CODE (t) == TEMPLATE_DECL)
            {
-             templates = decl_tree_cons (NULL_TREE, t, templates);
+             templates = scratch_tree_cons (NULL_TREE, t, templates);
              candidates = add_template_candidate
-               (candidates, t, args, LOOKUP_NORMAL);
+               (candidates, t, explicit_targs, args, NULL_TREE,
+                LOOKUP_NORMAL);  
            }
-         else
+         else if (! template_only)
            candidates = add_function_candidate
              (candidates, t, args, LOOKUP_NORMAL);
        }
@@ -4326,13 +4525,14 @@ build_new_function_call (fn, args, obj)
        {
          if (candidates && ! candidates->next)
            return build_function_call (candidates->fn, args);
-         else
-           cp_error ("no matching function for call to `%D (%A)'",
-                     TREE_PURPOSE (fn), args);
+         cp_error ("no matching function for call to `%D (%A)'",
+                   TREE_PURPOSE (fn), args);
+         if (candidates)
+           print_z_candidates (candidates);
          return error_mark_node;
        }
       candidates = splice_viable (candidates);
-      cand = tourney (candidates, NULL_TREE);
+      cand = tourney (candidates);
 
       if (cand == 0)
        {
@@ -4342,10 +4542,11 @@ build_new_function_call (fn, args, obj)
          return error_mark_node;
        }
 
-      /* Pedantically, it is ill-formed to define a function that could
-        also be a template instantiation, but we won't implement that
-        until things settle down.  */
-      if (templates && ! cand->template && ! DECL_INITIAL (cand->fn))
+      /* Pedantically, normal function declarations are never considered
+        to refer to template instantiations, so we only do this with
+        -fguiding-decls.  */
+      if (flag_guiding_decls && templates && ! cand->template 
+         && ! DECL_INITIAL (cand->fn))
        add_maybe_template (cand->fn, templates);
 
       return build_over_call (cand->fn, cand->convs, args, LOOKUP_NORMAL);
@@ -4354,26 +4555,43 @@ build_new_function_call (fn, args, obj)
   return build_function_call (fn, args);
 }
 
-tree
+static tree
 build_object_call (obj, args)
      tree obj, args;
 {
   struct z_candidate *candidates = 0, *cand;
   tree fns, convs, mem_args;
   tree type = TREE_TYPE (obj);
+  tree templates = NULL_TREE;
 
   fns = lookup_fnfields (TYPE_BINFO (type), ansi_opname [CALL_EXPR], 0);
 
+  args = resolve_args (args);
+
+  if (args == error_mark_node)
+    return error_mark_node;
+
   if (fns)
     {
       tree fn = TREE_VALUE (fns);
-      mem_args = tree_cons (NULL_TREE, build_this (obj), args);
+      mem_args = scratch_tree_cons (NULL_TREE, build_this (obj), args);
 
       for (; fn; fn = DECL_CHAIN (fn))
        {
-         candidates = add_function_candidate
-           (candidates, fn, mem_args, LOOKUP_NORMAL);
-         candidates->basetype_path = TREE_PURPOSE (fns);
+         if (TREE_CODE (fn) == TEMPLATE_DECL)
+           {
+             templates = scratch_tree_cons (NULL_TREE, fn, templates);
+             candidates 
+               = add_template_candidate (candidates, fn, NULL_TREE,
+                                         mem_args, NULL_TREE, 
+                                         LOOKUP_NORMAL);
+           }
+         else
+           candidates = add_function_candidate
+             (candidates, fn, mem_args, LOOKUP_NORMAL);
+
+         if (candidates)
+           candidates->basetype_path = TREE_PURPOSE (fns);
        }
     }
 
@@ -4388,8 +4606,20 @@ build_object_call (obj, args)
          && TREE_CODE (TREE_TYPE (totype)) == FUNCTION_TYPE)
        for (; fn; fn = DECL_CHAIN (fn))
          {
-           candidates = add_conv_candidate (candidates, fn, obj, args);
-           candidates->basetype_path = TREE_PURPOSE (convs);
+           if (TREE_CODE (fn) == TEMPLATE_DECL) 
+             {
+               templates = scratch_tree_cons (NULL_TREE, fn, templates);
+               candidates = add_template_conv_candidate (candidates,
+                                                         fn,
+                                                         obj,
+                                                         args,
+                                                         totype);
+             }
+           else
+             candidates = add_conv_candidate (candidates, fn, obj, args);
+
+           if (candidates)
+             candidates->basetype_path = TREE_PURPOSE (convs);
          }
     }
 
@@ -4401,7 +4631,7 @@ build_object_call (obj, args)
     }
 
   candidates = splice_viable (candidates);
-  cand = tourney (candidates, NULL_TREE);
+  cand = tourney (candidates);
 
   if (cand == 0)
     {
@@ -4461,12 +4691,21 @@ build_new_op (code, flags, arg1, arg2, arg3)
   tree fns, mem_arglist, arglist, fnname;
   enum tree_code code2 = NOP_EXPR;
   tree templates = NULL_TREE;
+  tree conv;
 
   if (arg1 == error_mark_node
       || arg2 == error_mark_node
       || arg3 == error_mark_node)
     return error_mark_node;
 
+  /* This can happen if a template takes all non-type parameters, e.g.
+     undeclared_template<1, 5, 72>a;  */
+  if (code == LT_EXPR && TREE_CODE (arg1) == TEMPLATE_DECL)
+    {
+      cp_error ("`%D' must be declared before use", arg1);
+      return error_mark_node;
+    }
+
   if (code == MODIFY_EXPR)
     {
       code2 = TREE_CODE (arg3);
@@ -4483,10 +4722,10 @@ build_new_op (code, flags, arg1, arg2, arg3)
       {
        tree rval;
 
-       arglist = tree_cons (NULL_TREE, arg2, arg3);
+       arglist = scratch_tree_cons (NULL_TREE, arg2, arg3);
        if (flags & LOOKUP_GLOBAL)
          return build_new_function_call
-           (lookup_name_nonclass (fnname), arglist, NULL_TREE);
+           (lookup_name_nonclass (fnname), arglist);
 
        /* FIXME */
        rval = build_method_call
@@ -4499,7 +4738,6 @@ build_new_op (code, flags, arg1, arg2, arg3)
          return rval;
 
        TREE_TYPE (rval) = arg1;
-       TREE_CALLS_NEW (rval) = 1;
        return rval;
       }
 
@@ -4511,9 +4749,9 @@ build_new_op (code, flags, arg1, arg2, arg3)
        if (flags & LOOKUP_GLOBAL)
          return build_new_function_call
            (lookup_name_nonclass (fnname),
-            build_tree_list (NULL_TREE, arg1), NULL_TREE);
+            build_scratch_list (NULL_TREE, arg1));
 
-       arglist = tree_cons (NULL_TREE, arg1, build_tree_list (NULL_TREE, arg2));
+       arglist = scratch_tree_cons (NULL_TREE, arg1, build_scratch_list (NULL_TREE, arg2));
 
        arg1 = TREE_TYPE (arg1);
 
@@ -4549,6 +4787,9 @@ build_new_op (code, flags, arg1, arg2, arg3)
 
     case CALL_EXPR:
       return build_object_call (arg1, arg2);
+
+    default:
+      break;
     }
 
   /* The comma operator can have void args.  */
@@ -4561,7 +4802,8 @@ build_new_op (code, flags, arg1, arg2, arg3)
 
   if (code == COND_EXPR)
     {
-      if (TREE_CODE (TREE_TYPE (arg2)) == VOID_TYPE
+      if (arg2 == NULL_TREE
+         || TREE_CODE (TREE_TYPE (arg2)) == VOID_TYPE
          || TREE_CODE (TREE_TYPE (arg3)) == VOID_TYPE
          || (! IS_OVERLOAD_TYPE (TREE_TYPE (arg2))
              && ! IS_OVERLOAD_TYPE (TREE_TYPE (arg3))))
@@ -4574,16 +4816,16 @@ build_new_op (code, flags, arg1, arg2, arg3)
   if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
     arg2 = integer_zero_node;
 
-  fns = lookup_name_nonclass (fnname);
-  /* + Koenig lookup */
-
   if (arg2 && arg3)
-    arglist = tree_cons (NULL_TREE, arg1, tree_cons
-                     (NULL_TREE, arg2, build_tree_list (NULL_TREE, arg3)));
+    arglist = scratch_tree_cons (NULL_TREE, arg1, scratch_tree_cons
+                     (NULL_TREE, arg2, build_scratch_list (NULL_TREE, arg3)));
   else if (arg2)
-    arglist = tree_cons (NULL_TREE, arg1, build_tree_list (NULL_TREE, arg2));
+    arglist = scratch_tree_cons (NULL_TREE, arg1, build_scratch_list (NULL_TREE, arg2));
   else
-    arglist = build_tree_list (NULL_TREE, arg1);
+    arglist = build_scratch_list (NULL_TREE, arg1);
+
+  fns = lookup_name_nonclass (fnname);
+  /* + Koenig lookup */
 
   if (fns && TREE_CODE (fns) == TREE_LIST)
     fns = TREE_VALUE (fns);
@@ -4591,9 +4833,11 @@ build_new_op (code, flags, arg1, arg2, arg3)
     {
       if (TREE_CODE (fns) == TEMPLATE_DECL)
        {
-         templates = decl_tree_cons (NULL_TREE, fns, templates);
-         candidates = add_template_candidate
-           (candidates, fns, arglist, flags);
+         templates = scratch_tree_cons (NULL_TREE, fns, templates);
+         candidates 
+           = add_template_candidate (candidates, fns, NULL_TREE,
+                                     arglist, TREE_TYPE (fnname),
+                                     flags); 
        }
       else
        candidates = add_function_candidate (candidates, fns, arglist, flags);
@@ -4607,16 +4851,31 @@ build_new_op (code, flags, arg1, arg2, arg3)
   if (fns)
     {
       tree fn = TREE_VALUE (fns);
-      mem_arglist = tree_cons (NULL_TREE, build_this (arg1), TREE_CHAIN (arglist));
+      mem_arglist = scratch_tree_cons (NULL_TREE, build_this (arg1), TREE_CHAIN (arglist));
       for (; fn; fn = DECL_CHAIN (fn))
        {
+         tree this_arglist;
+
          if (TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE)
-           candidates = add_function_candidate
-             (candidates, fn, mem_arglist, flags);
+           this_arglist = mem_arglist;
          else
-           candidates = add_function_candidate (candidates, fn, arglist, flags);
-         
-         candidates->basetype_path = TREE_PURPOSE (fns);
+           this_arglist = arglist;
+
+         if (TREE_CODE (fn) == TEMPLATE_DECL)
+           {
+             /* A member template. */
+             templates = scratch_tree_cons (NULL_TREE, fn, templates);
+             candidates 
+               = add_template_candidate (candidates, fn, NULL_TREE,
+                                         this_arglist,  TREE_TYPE (fnname),
+                                         flags); 
+           }
+         else
+           candidates = add_function_candidate
+             (candidates, fn, this_arglist, flags);
+
+         if (candidates) 
+           candidates->basetype_path = TREE_PURPOSE (fns);
        }
     }
 
@@ -4666,6 +4925,9 @@ build_new_op (code, flags, arg1, arg2, arg3)
        case COMPOUND_EXPR:
        case COMPONENT_REF:
          return NULL_TREE;
+
+       default:
+         break;
        }
       if (flags & LOOKUP_COMPLAIN)
        {
@@ -4675,7 +4937,7 @@ build_new_op (code, flags, arg1, arg2, arg3)
       return error_mark_node;
     }
   candidates = splice_viable (candidates);
-  cand = tourney (candidates, NULL_TREE);
+  cand = tourney (candidates);
 
   if (cand == 0)
     {
@@ -4707,10 +4969,11 @@ build_new_op (code, flags, arg1, arg2, arg3)
       if (DECL_FUNCTION_MEMBER_P (cand->fn))
        enforce_access (cand->basetype_path, cand->fn);
 
-      /* Pedantically, it is ill-formed to define a function that could
-        also be a template instantiation, but we won't implement that
-        until things settle down.  */
-      if (templates && ! cand->template && ! DECL_INITIAL (cand->fn)
+      /* Pedantically, normal function declarations are never considered
+        to refer to template instantiations, so we only do this with
+        -fguiding-decls.  */ 
+      if (flag_guiding_decls && templates && ! cand->template 
+         && ! DECL_INITIAL (cand->fn)
          && TREE_CODE (TREE_TYPE (cand->fn)) != METHOD_TYPE)
        add_maybe_template (cand->fn, templates);
 
@@ -4739,10 +5002,18 @@ build_new_op (code, flags, arg1, arg2, arg3)
          cp_warning ("comparison between `%#T' and `%#T'", 
                      TREE_TYPE (arg1), TREE_TYPE (arg2));
        }
+      break;
+    default:
+      break;
     }
 
-  arg1 = convert_from_reference
-    (convert_like (TREE_VEC_ELT (cand->convs, 0), arg1));
+  /* We need to strip any leading REF_BIND so that bitfields don't cause
+     errors.  This should not remove any important conversions, because
+     builtins don't apply to class objects directly.  */
+  conv = TREE_VEC_ELT (cand->convs, 0);
+  if (TREE_CODE (conv) == REF_BIND)
+    conv = TREE_OPERAND (conv, 0);
+  arg1 = convert_like (conv, arg1);
   if (arg2)
     arg2 = convert_like (TREE_VEC_ELT (cand->convs, 1), arg2);
   if (arg3)
@@ -4787,6 +5058,8 @@ builtin:
     case POSTINCREMENT_EXPR:
     case PREDECREMENT_EXPR:
     case POSTDECREMENT_EXPR:
+    case REALPART_EXPR:
+    case IMAGPART_EXPR:
       return build_unary_op (code, arg1, candidates != 0);
 
     case ARRAY_REF:
@@ -4810,6 +5083,149 @@ builtin:
     }
 }
 
+/* Build up a call to operator new.  This has to be handled differently
+   from other operators in the way lookup is handled; first members are
+   considered, then globals.  CODE is either NEW_EXPR or VEC_NEW_EXPR.
+   TYPE is the type to be created.  ARGS are any new-placement args.
+   FLAGS are the usual overloading flags.  */
+
+tree
+build_op_new_call (code, type, args, flags)
+     enum tree_code code;
+     tree type, args;
+     int flags;
+{
+  tree fnname = ansi_opname[code];
+
+  if (IS_AGGR_TYPE (type) && ! (flags & LOOKUP_GLOBAL)
+      && (TYPE_GETS_NEW (type) & (1 << (code == VEC_NEW_EXPR))))
+    {
+      tree dummy = build1 (NOP_EXPR, build_pointer_type (type),
+                          error_mark_node);
+      dummy = build_indirect_ref (dummy, "new");
+      return build_method_call (dummy, fnname, args, NULL_TREE, flags);
+    }
+  else
+    return build_new_function_call (lookup_name_nonclass (fnname), args);
+}
+
+/* Build a call to operator delete.  This has to be handled very specially,
+   because the restrictions on what signatures match are different from all
+   other call instances.  For a normal delete, only a delete taking (void *)
+   or (void *, size_t) is accepted.  For a placement delete, only an exact
+   match with the placement new is accepted.
+
+   CODE is either DELETE_EXPR or VEC_DELETE_EXPR.
+   ADDR is the pointer to be deleted.  For placement delete, it is also
+     used to determine what the corresponding new looked like.
+   SIZE is the size of the memory block to be deleted.
+   FLAGS are the usual overloading flags.  */
+
+tree
+build_op_delete_call (code, addr, size, flags)
+     enum tree_code code;
+     tree addr, size;
+     int flags;
+{
+  tree fn, fns, fnname, fntype, argtypes, args, type;
+  int placement;
+
+  if (addr == error_mark_node)
+    return error_mark_node;
+
+  type = TREE_TYPE (TREE_TYPE (addr));
+  fnname = ansi_opname[code];
+
+  if (IS_AGGR_TYPE (type) && ! (flags & LOOKUP_GLOBAL))
+    fns = lookup_fnfields (TYPE_BINFO (type), fnname, 0);
+  else
+    fns = NULL_TREE;
+
+  if (fns)
+    {
+      /* Build this up like build_offset_ref does.  */
+      fns = build_tree_list (error_mark_node, fns);
+      TREE_TYPE (fns) = build_offset_type (type, unknown_type_node);
+    }
+  else
+    fns = lookup_name_nonclass (fnname);
+
+  /* We can recognize a placement delete because of LOOKUP_SPECULATIVELY;
+     if we are doing placement delete we do nothing if we don't find a
+     matching op delete.  */
+  placement = !!(flags & LOOKUP_SPECULATIVELY);
+  if (placement)
+    {
+      /* If placement, we are coming from build_new, and we know that addr
+        is the allocation expression, so extract the info we need from it.
+        Obviously, if the build_new process changes this may have to
+        change as well.  */
+
+      /* The NOP_EXPR.  */
+      tree t = TREE_OPERAND (addr, 1);
+      /* The CALL_EXPR.  */
+      t = TREE_OPERAND (t, 0);
+      /* The function.  */
+      argtypes = TREE_OPERAND (TREE_OPERAND (t, 0), 0);
+      /* The second parm type.  */
+      argtypes = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (argtypes)));
+      /* The second argument.  */
+      args = TREE_CHAIN (TREE_OPERAND (t, 1));
+
+      /* Pull the dummy var out of the TARGET_EXPR for use in our call.  */
+      addr = TREE_OPERAND (addr, 0);
+    }
+  else
+    {
+      /* First try it without the size argument.  */
+      argtypes = void_list_node;
+      args = NULL_TREE;
+    }
+
+  argtypes = tree_cons (NULL_TREE, ptr_type_node, argtypes);
+  fntype = build_function_type (void_type_node, argtypes);
+
+  /* Strip const and volatile from addr.  */
+  if (type != TYPE_MAIN_VARIANT (type))
+    addr = cp_convert (build_pointer_type (TYPE_MAIN_VARIANT (type)), addr);
+
+  /* instantiate_type will always return a plain function; pretend it's
+     overloaded.  */
+  if (TREE_CODE (fns) == FUNCTION_DECL)
+    fns = scratch_tree_cons (NULL_TREE, fns, NULL_TREE);
+
+  fn = instantiate_type (fntype, fns, 0);
+
+  if (fn != error_mark_node)
+    {
+      if (TREE_CODE (TREE_VALUE (fns)) == TREE_LIST)
+       /* Member functions.  */
+       enforce_access (TREE_PURPOSE (TREE_VALUE (fns)), fn);
+      return build_function_call (fn, expr_tree_cons (NULL_TREE, addr, args));
+    }
+
+  if (placement)
+    return NULL_TREE;
+
+  /* Normal delete; now try to find a match including the size argument.  */
+  argtypes = tree_cons (NULL_TREE, ptr_type_node,
+                       tree_cons (NULL_TREE, sizetype, void_list_node));
+  fntype = build_function_type (void_type_node, argtypes);
+
+  fn = instantiate_type (fntype, fns, 0);
+
+  if (fn != error_mark_node)
+    return build_function_call
+      (fn, expr_tree_cons (NULL_TREE, addr,
+                          build_expr_list (NULL_TREE, size)));
+
+  cp_error ("no suitable operator delete for `%T'", type);
+  return error_mark_node;
+}
+
+/* If the current scope isn't allowed to access FUNCTION along
+   BASETYPE_PATH, give an error.  */
+
 static void
 enforce_access (basetype_path, function)
      tree basetype_path, function;
@@ -4873,10 +5289,10 @@ convert_like (convs, expr)
            tree t = build_int_2 (0, 0);
            TREE_TYPE (t) = build_pointer_type (DECL_CONTEXT (fn));
 
-           args = build_tree_list (NULL_TREE, expr);
+           args = build_scratch_list (NULL_TREE, expr);
            if (TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (fn)))
-             args = tree_cons (NULL_TREE, integer_one_node, args);
-           args = tree_cons (NULL_TREE, t, args);
+             args = scratch_tree_cons (NULL_TREE, integer_one_node, args);
+           args = scratch_tree_cons (NULL_TREE, t, args);
          }
        else
          args = build_this (expr);
@@ -4901,6 +5317,9 @@ convert_like (convs, expr)
       /* Call build_user_type_conversion again for the error.  */
       return build_user_type_conversion
        (TREE_TYPE (convs), TREE_OPERAND (convs, 0), LOOKUP_NORMAL);
+
+    default:
+      break;
     };
 
   expr = convert_like (TREE_OPERAND (convs, 0), expr);
@@ -4923,9 +5342,12 @@ convert_like (convs, expr)
         error_mark_node);
     case LVALUE_CONV:
       return decay_conversion (expr);
+
+    default:
+      break;
     }
-  return cp_convert (TREE_TYPE (convs), expr, CONV_IMPLICIT,
-                    LOOKUP_NORMAL|LOOKUP_NO_CONVERSION);
+  return ocp_convert (TREE_TYPE (convs), expr, CONV_IMPLICIT,
+                     LOOKUP_NORMAL|LOOKUP_NO_CONVERSION);
 }
 
 static tree
@@ -4971,19 +5393,19 @@ build_over_call (fn, convs, args, flags)
   int is_method = 0;
 
   if (args && TREE_CODE (args) != TREE_LIST)
-    args = build_tree_list (NULL_TREE, args);
+    args = build_scratch_list (NULL_TREE, args);
   arg = args;
 
   /* The implicit parameters to a constructor are not considered by overload
      resolution, and must be of the proper type.  */
   if (DECL_CONSTRUCTOR_P (fn))
     {
-      converted_args = tree_cons (NULL_TREE, TREE_VALUE (arg), converted_args);
+      converted_args = expr_tree_cons (NULL_TREE, TREE_VALUE (arg), converted_args);
       arg = TREE_CHAIN (arg);
       parm = TREE_CHAIN (parm);
       if (TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (fn)))
        {
-         converted_args = tree_cons
+         converted_args = expr_tree_cons
            (NULL_TREE, TREE_VALUE (arg), converted_args);
          arg = TREE_CHAIN (arg);
          parm = TREE_CHAIN (parm);
@@ -5000,13 +5422,13 @@ build_over_call (fn, convs, args, flags)
                    < TYPE_VOLATILE (TREE_TYPE (argtype)));
          int dc = (TYPE_READONLY (TREE_TYPE (parmtype))
                    < TYPE_READONLY (TREE_TYPE (argtype)));
-         char *p = (dv && dc ? "const and volatile" :
-                    dc ? "const" : dv ? "volatile" : "");
+         char *p = (dv && dc ? "const and volatile"
+                             : dc ? "const" : dv ? "volatile" : "");
 
          cp_pedwarn ("passing `%T' as `this' argument of `%#D' discards %s",
                      TREE_TYPE (argtype), fn, p);
        }
-      converted_args = tree_cons
+      converted_args = expr_tree_cons
        (NULL_TREE, convert_force (TREE_VALUE (parm), TREE_VALUE (arg), CONV_C_CAST),
         converted_args);
       parm = TREE_CHAIN (parm);
@@ -5015,11 +5437,12 @@ build_over_call (fn, convs, args, flags)
       is_method = 1;
     }
 
-  for (; conv = TREE_VEC_ELT (convs, i), arg && parm;
+  for (; arg && parm;
        parm = TREE_CHAIN (parm), arg = TREE_CHAIN (arg), ++i)
     {
       tree type = TREE_VALUE (parm);
 
+      conv = TREE_VEC_ELT (convs, i);
       if (ICS_BAD_FLAG (conv))
        {
          tree t = conv;
@@ -5049,7 +5472,7 @@ build_over_call (fn, convs, args, flags)
          && (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)))
        val = default_conversion (val);
 #endif
-      converted_args = tree_cons (NULL_TREE, val, converted_args);
+      converted_args = expr_tree_cons (NULL_TREE, val, converted_args);
     }
 
   /* Default arguments */
@@ -5057,12 +5480,12 @@ build_over_call (fn, convs, args, flags)
     {
       tree arg = TREE_PURPOSE (parm);
 
-      if (PARM_DEFAULT_FROM_TEMPLATE (parm))
+      if (DECL_TEMPLATE_INFO (fn))
        /* This came from a template.  Instantiate the default arg here,
           not in tsubst.  */
-       arg = tsubst_expr (arg, &TREE_VEC_ELT (DECL_TI_ARGS (fn), 0),
+       arg = tsubst_expr (arg, DECL_TI_ARGS (fn),
                           TREE_VEC_LENGTH (DECL_TI_ARGS (fn)), NULL_TREE);
-      converted_args = tree_cons
+      converted_args = expr_tree_cons
        (NULL_TREE, convert_default_arg (TREE_VALUE (parm), arg),
         converted_args);
     }
@@ -5076,7 +5499,7 @@ build_over_call (fn, convs, args, flags)
          && (TYPE_PRECISION (TREE_TYPE (val))
              < TYPE_PRECISION (double_type_node)))
        /* Convert `float' to `double'.  */
-       val = convert (double_type_node, val);
+       val = cp_convert (double_type_node, val);
       else if (TYPE_LANG_SPECIFIC (TREE_TYPE (val))
               && ! TYPE_HAS_TRIVIAL_INIT_REF (TREE_TYPE (val)))
        cp_warning ("cannot pass objects of type `%T' through `...'",
@@ -5085,7 +5508,7 @@ build_over_call (fn, convs, args, flags)
        /* Convert `short' and `char' to full-size `int'.  */
        val = default_conversion (val);
 
-      converted_args = tree_cons (NULL_TREE, val, converted_args);
+      converted_args = expr_tree_cons (NULL_TREE, val, converted_args);
     }
 
   converted_args = nreverse (converted_args);
@@ -5096,23 +5519,38 @@ build_over_call (fn, convs, args, flags)
       && TREE_VEC_LENGTH (convs) == 1
       && copy_args_p (fn))
     {
-      tree targ = NULL_TREE;
-      arg = TREE_VALUE (TREE_CHAIN (converted_args));
+      tree targ;
+      arg = TREE_CHAIN (converted_args);
+      if (TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (fn)))
+       arg = TREE_CHAIN (arg);
+      arg = TREE_VALUE (arg);
 
       /* Pull out the real argument, disregarding const-correctness.  */
-      if (TREE_CODE (arg) == ADDR_EXPR)
-       {
-         targ = TREE_OPERAND (arg, 0);
+      targ = arg;
+      while (TREE_CODE (targ) == NOP_EXPR
+            || TREE_CODE (targ) == NON_LVALUE_EXPR
+            || TREE_CODE (targ) == CONVERT_EXPR)
+       targ = TREE_OPERAND (targ, 0);
+      if (TREE_CODE (targ) == ADDR_EXPR)
+       {
+         targ = TREE_OPERAND (targ, 0);
          if (! comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (arg))),
                           TYPE_MAIN_VARIANT (TREE_TYPE (targ)), 1))
            targ = NULL_TREE;
        }
+      else
+       targ = NULL_TREE;
 
       if (targ)
        arg = targ;
       else
        arg = build_indirect_ref (arg, 0);
 
+      /* [class.copy]: the copy constructor is implicitly defined even if
+        the implementation elided its use.  */
+      if (TYPE_HAS_COMPLEX_INIT_REF (DECL_CONTEXT (fn)))
+       mark_used (fn);
+
       /* If we're creating a temp and we already have one, don't create a
          new one.  If we're not creating a temp but we get one, use
          INIT_EXPR to collapse the temp into our target.  Otherwise, if the
@@ -5177,23 +5615,43 @@ build_over_call (fn, convs, args, flags)
   fn = build_call (fn, TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))), converted_args);
   if (TREE_TYPE (fn) == void_type_node)
     return fn;
+  fn = require_complete_type (fn);
   if (IS_AGGR_TYPE (TREE_TYPE (fn)))
     fn = build_cplus_new (TREE_TYPE (fn), fn);
-  return convert_from_reference (require_complete_type (fn));
+  return convert_from_reference (fn);
 }
 
-tree
+static tree
 build_new_method_call (instance, name, args, basetype_path, flags)
      tree instance, name, args, basetype_path;
      int flags;
 {
   struct z_candidate *candidates = 0, *cand;
+  tree explicit_targs = NULL_TREE;
   tree basetype, mem_args, fns, instance_ptr;
   tree pretty_name;
+  tree user_args = args;
+  tree templates = NULL_TREE;
+  int template_only = 0;
 
-  for (fns = args; fns; fns = TREE_CHAIN (fns))
-    if (TREE_VALUE (fns) == error_mark_node)
-      return error_mark_node;
+  if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
+    {
+      explicit_targs = TREE_OPERAND (name, 1);
+      name = TREE_OPERAND (name, 0);
+      if (TREE_CODE (name) == TEMPLATE_DECL)
+       name = DECL_NAME (name);
+      template_only = 1;
+    }
+
+  /* If there is an extra argument for controlling virtual bases,
+     remove it for error reporting.  */
+  if (flags & LOOKUP_HAS_IN_CHARGE)
+    user_args = TREE_CHAIN (args);
+
+  args = resolve_args (args);
+
+  if (args == error_mark_node)
+    return error_mark_node;
 
   if (instance == NULL_TREE)
     basetype = BINFO_TYPE (basetype_path);
@@ -5234,10 +5692,13 @@ build_new_method_call (instance, name, args, basetype_path, flags)
     {
       instance_ptr = build_this (instance);
 
-      /* XXX this should be handled before we get here.  */
-      fns = build_field_call (basetype_path, instance_ptr, name, args);
-      if (fns)
-       return fns;
+      if (! template_only)
+       {
+         /* XXX this should be handled before we get here.  */
+         fns = build_field_call (basetype_path, instance_ptr, name, args);
+         if (fns)
+           return fns;
+       }
     }
   else
     {
@@ -5245,8 +5706,8 @@ build_new_method_call (instance, name, args, basetype_path, flags)
       TREE_TYPE (instance_ptr) = build_pointer_type (basetype);
     }
 
-  pretty_name =
-    (name == ctor_identifier ? constructor_name_full (basetype) : name);
+  pretty_name
+    = (name == ctor_identifier ? constructor_name (basetype) : name);
 
   fns = lookup_fnfields (basetype_path, name, 1);
 
@@ -5259,22 +5720,38 @@ build_new_method_call (instance, name, args, basetype_path, flags)
          && ! (flags & LOOKUP_HAS_IN_CHARGE))
        {
          flags |= LOOKUP_HAS_IN_CHARGE;
-         args = tree_cons (NULL_TREE, integer_one_node, args);
+         args = scratch_tree_cons (NULL_TREE, integer_one_node, args);
        }
-      mem_args = tree_cons (NULL_TREE, instance_ptr, args);
+      mem_args = scratch_tree_cons (NULL_TREE, instance_ptr, args);
       for (; t; t = DECL_CHAIN (t))
        {
+         tree this_arglist;
+
          /* We can end up here for copy-init of same or base class.  */
          if (name == ctor_identifier
              && (flags & LOOKUP_ONLYCONVERTING)
              && DECL_NONCONVERTING_P (t))
            continue;
          if (TREE_CODE (TREE_TYPE (t)) == METHOD_TYPE)
-           candidates = add_function_candidate
-             (candidates, t, mem_args, flags);
+           this_arglist = mem_args;
          else
-           candidates = add_function_candidate (candidates, t, args, flags);
-         candidates->basetype_path = TREE_PURPOSE (fns);
+           this_arglist = args;
+
+         if (TREE_CODE (t) == TEMPLATE_DECL)
+           {
+             /* A member template. */
+             templates = scratch_tree_cons (NULL_TREE, t, templates);
+             candidates = 
+               add_template_candidate (candidates, t, explicit_targs,
+                                       this_arglist,
+                                       TREE_TYPE (name), flags); 
+           }
+         else if (! template_only)
+           candidates = add_function_candidate (candidates, t,
+                                                this_arglist, flags);
+
+         if (candidates)
+           candidates->basetype_path = TREE_PURPOSE (fns);
        }
     }
 
@@ -5284,16 +5761,17 @@ build_new_method_call (instance, name, args, basetype_path, flags)
       if (flags & LOOKUP_SPECULATIVELY)
        return NULL_TREE;
       cp_error ("no matching function for call to `%T::%D (%A)%V'", basetype,
-               pretty_name, args, TREE_TYPE (TREE_TYPE (instance_ptr)));
+               pretty_name, user_args, TREE_TYPE (TREE_TYPE (instance_ptr)));
       print_z_candidates (candidates);
       return error_mark_node;
     }
   candidates = splice_viable (candidates);
-  cand = tourney (candidates, NULL_TREE);
+  cand = tourney (candidates);
 
   if (cand == 0)
     {
-      cp_error ("call of overloaded `%D(%A)' is ambiguous", pretty_name, args);
+      cp_error ("call of overloaded `%D(%A)' is ambiguous", pretty_name,
+               user_args);
       print_z_candidates (candidates);
       return error_mark_node;
     }
@@ -5315,6 +5793,13 @@ build_new_method_call (instance, name, args, basetype_path, flags)
          || resolves_to_fixed_type_p (instance, 0)))
     flags |= LOOKUP_NONVIRTUAL;
 
+  /* Pedantically, normal function declarations are never considered
+     to refer to template instantiations, so we only do this with
+     -fguiding-decls.  */ 
+  if (flag_guiding_decls && templates && ! cand->template 
+      && ! DECL_INITIAL (cand->fn))
+    add_maybe_template (cand->fn, templates);
+
   return build_over_call
     (cand->fn, cand->convs,
      TREE_CODE (TREE_TYPE (cand->fn)) == METHOD_TYPE ? mem_args : args,
@@ -5331,6 +5816,11 @@ compare_qual (ics1, ics2)
   tree to1 = TREE_TYPE (ics1);
   tree to2 = TREE_TYPE (ics2);
 
+  if (TYPE_PTRMEMFUNC_P (to1))
+    to1 = TYPE_PTRMEMFUNC_FN_TYPE (to1);
+  if (TYPE_PTRMEMFUNC_P (to2))
+    to2 = TYPE_PTRMEMFUNC_FN_TYPE (to2);
+
   to1 = TREE_TYPE (to1);
   to2 = TREE_TYPE (to2);
 
@@ -5355,6 +5845,34 @@ compare_qual (ics1, ics2)
   return 0;
 }
 
+/* Determine whether standard conversion sequence ICS1 is a proper
+   subsequence of ICS2.  We assume that a conversion of the same code
+   between the same types indicates a subsequence.  */
+
+static int
+is_subseq (ics1, ics2)
+     tree ics1, ics2;
+{
+  /* Do not consider lvalue transformations here.  */
+  if (TREE_CODE (ics2) == RVALUE_CONV
+      || TREE_CODE (ics2) == LVALUE_CONV)
+    return 0;
+
+  for (;; ics2 = TREE_OPERAND (ics2, 0))
+    {
+      if (TREE_CODE (ics2) == TREE_CODE (ics1)
+         && comptypes (TREE_TYPE (ics2), TREE_TYPE (ics1), 1)
+         && comptypes (TREE_TYPE (TREE_OPERAND (ics2, 0)),
+                       TREE_TYPE (TREE_OPERAND (ics1, 0)), 1))
+       return 1;
+
+      if (TREE_CODE (ics2) == USER_CONV
+         || TREE_CODE (ics2) == AMBIG_CONV
+         || TREE_CODE (ics2) == IDENTITY_CONV)
+       return 0;
+    }
+}
+
 /* Compare two implicit conversion sequences according to the rules set out in
    [over.ics.rank].  Return values:
 
@@ -5382,15 +5900,23 @@ compare_ics (ics1, ics2)
      they were REF_BINDs.  */
   if (ICS_THIS_FLAG (ics1))
     {
-      ics1 = build_conv (REF_BIND, TREE_TYPE (ics1), main1);
-      TREE_OPERAND (ics1, 0) = TREE_OPERAND (main1, 0);
-      main1 = ics1;
+      tree t = main1;
+      if (TREE_CODE (t) == PTR_CONV)
+       t = TREE_OPERAND (t, 0);
+      t = build1 (IDENTITY_CONV, TREE_TYPE (TREE_TYPE (t)), NULL_TREE);
+      t = build_conv (REF_BIND, TREE_TYPE (ics1), t);
+      ICS_STD_RANK (t) = ICS_STD_RANK (main1);
+      main1 = ics1 = t;
     }
   if (ICS_THIS_FLAG (ics2))
     {
-      ics2 = build_conv (REF_BIND, TREE_TYPE (ics2), main2);
-      TREE_OPERAND (ics2, 0) = TREE_OPERAND (main2, 0);
-      main2 = ics2;
+      tree t = main2;
+      if (TREE_CODE (t) == PTR_CONV)
+       t = TREE_OPERAND (t, 0);
+      t = build1 (IDENTITY_CONV, TREE_TYPE (TREE_TYPE (t)), NULL_TREE);
+      t = build_conv (REF_BIND, TREE_TYPE (ics2), t);
+      ICS_STD_RANK (t) = ICS_STD_RANK (main2);
+      main2 = ics2 = t;
     }
 
   if (ICS_RANK (ics1) > ICS_RANK (ics2))
@@ -5444,7 +5970,14 @@ compare_ics (ics1, ics2)
 #endif
 
   if (TREE_CODE (main1) != TREE_CODE (main2))
-    return 0;
+    {
+      /* ...if S1  is  a  proper  subsequence  of  S2  */
+      if (is_subseq (main1, main2))
+       return 1;
+      if (is_subseq (main2, main1))
+       return -1;
+      return 0;
+    }
 
   if (TREE_CODE (main1) == PTR_CONV || TREE_CODE (main1) == PMEM_CONV
       || TREE_CODE (main1) == REF_BIND || TREE_CODE (main1) == BASE_CONV)
@@ -5474,8 +6007,8 @@ compare_ics (ics1, ics2)
        
       if (TYPE_PTRMEMFUNC_P (to1))
        {
-         to1 = TYPE_METHOD_BASETYPE (TYPE_PTRMEMFUNC_FN_TYPE (to1));
-         from1 = TYPE_METHOD_BASETYPE (TYPE_PTRMEMFUNC_FN_TYPE (from1));
+         to1 = TYPE_METHOD_BASETYPE (TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (to1)));
+         from1 = TYPE_METHOD_BASETYPE (TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (from1)));
        }
       else if (TREE_CODE (main1) != BASE_CONV)
        {
@@ -5492,8 +6025,8 @@ compare_ics (ics1, ics2)
 
       if (TYPE_PTRMEMFUNC_P (to2))
        {
-         to2 = TYPE_METHOD_BASETYPE (TYPE_PTRMEMFUNC_FN_TYPE (to2));
-         from2 = TYPE_METHOD_BASETYPE (TYPE_PTRMEMFUNC_FN_TYPE (from2));
+         to2 = TYPE_METHOD_BASETYPE (TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (to2)));
+         from2 = TYPE_METHOD_BASETYPE (TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (from2)));
        }
       else if (TREE_CODE (main1) != BASE_CONV)
        {
@@ -5594,6 +6127,22 @@ compare_ics (ics1, ics2)
   return 0;
 }
 
+/* The source type for this standard conversion sequence.  */
+
+static tree
+source_type (t)
+     tree t;
+{
+  for (;; t = TREE_OPERAND (t, 0))
+    {
+      if (TREE_CODE (t) == USER_CONV
+         || TREE_CODE (t) == AMBIG_CONV
+         || TREE_CODE (t) == IDENTITY_CONV)
+       return TREE_TYPE (t);
+    }
+  my_friendly_abort (1823);
+}
+
 /* Compare two candidates for overloading as described in
    [over.match.best].  Return values:
 
@@ -5645,11 +6194,38 @@ joust (cand1, cand2)
 
   for (i = 0; i < len; ++i)
     {
-      int comp = compare_ics (TREE_VEC_ELT (cand1->convs, i+off1),
-                             TREE_VEC_ELT (cand2->convs, i+off2));
+      tree t1 = TREE_VEC_ELT (cand1->convs, i+off1);
+      tree t2 = TREE_VEC_ELT (cand2->convs, i+off2);
+      int comp = compare_ics (t1, t2);
 
       if (comp != 0)
        {
+#if 0 /* move this warning to tourney.  */
+         if (warn_sign_promo
+             && ICS_RANK (t1) + ICS_RANK (t2) == STD_RANK + PROMO_RANK
+             && TREE_CODE (t1) == STD_CONV
+             && TREE_CODE (t2) == STD_CONV
+             && TREE_CODE (TREE_TYPE (t1)) == INTEGER_TYPE
+             && TREE_CODE (TREE_TYPE (t2)) == INTEGER_TYPE
+             && (TYPE_PRECISION (TREE_TYPE (t1))
+                 == TYPE_PRECISION (TREE_TYPE (t2)))
+             && (TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (t1, 0)))
+                 || (TREE_CODE (TREE_TYPE (TREE_OPERAND (t1, 0)))
+                     == ENUMERAL_TYPE)))
+           {
+             tree type = TREE_TYPE (TREE_OPERAND (t1, 0));
+             tree type1, type2;
+             if (comp > 0)
+               type1 = TREE_TYPE (t1), type2 = TREE_TYPE (t2);
+             else
+               type1 = TREE_TYPE (t2), type2 = TREE_TYPE (t1);
+
+             cp_warning ("passing `%T' chooses `%T' over `%T'",
+                         type, type1, type2);
+             cp_warning ("  in call to `%D'", DECL_NAME (cand1->fn));
+           }
+#endif
+
          if (winner && comp != winner)
            {
              winner = 0;
@@ -5659,6 +6235,29 @@ joust (cand1, cand2)
        }
     }
 
+#if 0 /* move this warning to tourney.  */
+  /* warn about confusing overload resolution */
+  if (winner && cand1->second_conv
+      && ! DECL_CONSTRUCTOR_P (cand1->fn)
+      && ! DECL_CONSTRUCTOR_P (cand2->fn))
+    {
+      int comp = compare_ics (cand1->second_conv, cand2->second_conv);
+      if (comp && comp != winner)
+       {
+         struct z_candidate *w, *l;
+         if (winner == 1)
+           w = cand1, l = cand2;
+         else
+           w = cand2, l = cand1;
+         cp_warning ("choosing `%D' over `%D'", w->fn, l->fn);
+         cp_warning ("  for conversion from `%T' to `%T'",
+                     TREE_TYPE (source_type (TREE_VEC_ELT (w->convs, 0))),
+                     TREE_TYPE (w->second_conv));
+         cp_warning ("  because conversion sequence for `this' argument is better");
+       }
+    }
+#endif
+
   if (winner)
     return winner;
 
@@ -5694,10 +6293,10 @@ joust (cand1, cand2)
          break;
       if (i == TREE_VEC_LENGTH (cand1->convs))
        return 1;
-#if 0
+
       /* Kludge around broken overloading rules whereby
-        bool ? void *const & : void *const & is ambiguous.  */
-      /* Huh?  Explain the problem better.  */
+        Integer a, b; test ? a : b; is ambiguous, since there's a builtin
+        that takes references and another that takes values.  */
       if (cand1->fn == ansi_opname[COND_EXPR])
        {
          tree c1 = TREE_VEC_ELT (cand1->convs, 1);
@@ -5713,7 +6312,6 @@ joust (cand1, cand2)
                return -1;
            }
        }
-#endif
     }
 
 tweak: