86th Cygnus<->FSF quick merge
[gcc.git] / gcc / cp / call.c
index 85a2788f19214a379cd16dab4d5349b958f5c84c..c9d3f8802abbd4251177748419c5a1d18b71386e 100644 (file)
@@ -1,5 +1,5 @@
 /* Functions related to invoking methods and overloaded functions.
-   Copyright (C) 1987, 1992, 1993 Free Software Foundation, Inc.
+   Copyright (C) 1987, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
    Contributed by Michael Tiemann (tiemann@cygnus.com) and
    hacked by Brendan Kehoe (brendan@cygnus.com).
 
@@ -17,7 +17,8 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with GNU CC; see the file COPYING.  If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
 
 
 /* High-level class interface. */
@@ -27,6 +28,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include <stdio.h>
 #include "cp-tree.h"
 #include "class.h"
+#include "output.h"
 #include "flags.h"
 
 #include "obstack.h"
@@ -36,17 +38,14 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 extern void sorry ();
 
 extern int inhibit_warnings;
-extern int flag_assume_nonnull_objects;
 extern tree ctor_label, dtor_label;
 
-/* From typeck.c:  */
-extern tree unary_complex_lvalue ();
-
 /* Compute the ease with which a conversion can be performed
    between an expected and the given type.  */
-static struct harshness_code convert_harshness ();
+static struct harshness_code convert_harshness PROTO((register tree, register tree, tree));
 
 #define EVIL_RETURN(ARG)       ((ARG).code = EVIL_CODE, (ARG))
+#define STD_RETURN(ARG)                ((ARG).code = STD_CODE, (ARG))
 #define QUAL_RETURN(ARG)       ((ARG).code = QUAL_CODE, (ARG))
 #define TRIVIAL_RETURN(ARG)    ((ARG).code = TRIVIAL_CODE, (ARG))
 #define ZERO_RETURN(ARG)       ((ARG).code = 0, (ARG))
@@ -117,6 +116,7 @@ convert_harshness (type, parmtype, parm)
   struct harshness_code h;
   register enum tree_code codel;
   register enum tree_code coder;
+  int lvalue;
 
   h.code = 0;
   h.distance = 0;
@@ -126,17 +126,22 @@ convert_harshness (type, parmtype, parm)
   n_convert_harshness++;
 #endif
 
-  if (TYPE_PTRMEMFUNC_P (type))
-    type = TYPE_PTRMEMFUNC_FN_TYPE (type);
-  if (TYPE_PTRMEMFUNC_P (parmtype))
-    parmtype = TYPE_PTRMEMFUNC_FN_TYPE (parmtype);
-
   if (TREE_CODE (parmtype) == REFERENCE_TYPE)
     {
       if (parm)
        parm = convert_from_reference (parm);
       parmtype = TREE_TYPE (parmtype);
+      lvalue = 1;
     }
+  else if (parm)
+    lvalue = lvalue_p (parm);
+  else
+    lvalue = 0;
+
+  if (TYPE_PTRMEMFUNC_P (type))
+    type = TYPE_PTRMEMFUNC_FN_TYPE (type);
+  if (TYPE_PTRMEMFUNC_P (parmtype))
+    parmtype = TYPE_PTRMEMFUNC_FN_TYPE (parmtype);
 
   codel = TREE_CODE (type);
   coder = TREE_CODE (parmtype);
@@ -147,6 +152,60 @@ convert_harshness (type, parmtype, parm)
   if (coder == ERROR_MARK)
     return EVIL_RETURN (h);
 
+  if (codel == REFERENCE_TYPE)
+    {
+      tree ttl, ttr;
+      int constp = parm ? TREE_READONLY (parm) : TYPE_READONLY (parmtype);
+      int volatilep = (parm ? TREE_THIS_VOLATILE (parm)
+                      : TYPE_VOLATILE (parmtype));
+      register tree intype = TYPE_MAIN_VARIANT (parmtype);
+      register enum tree_code form = TREE_CODE (intype);
+      int penalty = 0;
+
+      ttl = TREE_TYPE (type);
+
+      /* Only allow const reference binding if we were given a parm to deal
+         with, since it isn't really a conversion.  This is a hack to
+         prevent build_type_conversion from finding this conversion, but
+         still allow overloading to find it.  */
+      if (! lvalue && ! (parm && TYPE_READONLY (ttl)))
+       return EVIL_RETURN (h);
+
+      if ((TYPE_READONLY (ttl) < constp)
+         || (TYPE_VOLATILE (ttl) < volatilep))
+       return EVIL_RETURN (h);
+
+      /* When passing a non-const argument into a const reference, dig it a
+        little, so a non-const reference is preferred over this one.  */
+      penalty = ((TYPE_READONLY (ttl) > constp)
+                + (TYPE_VOLATILE (ttl) > volatilep));
+
+      ttl = TYPE_MAIN_VARIANT (ttl);
+
+      if (form == OFFSET_TYPE)
+       {
+         intype = TREE_TYPE (intype);
+         form = TREE_CODE (intype);
+       }
+
+      ttr = intype;
+
+      if (TREE_CODE (ttl) == ARRAY_TYPE && TREE_CODE (ttr) == ARRAY_TYPE)
+       {
+         if (comptypes (ttl, ttr, 1))
+           return ZERO_RETURN (h);
+         return EVIL_RETURN (h);
+       }
+
+      h = convert_harshness (ttl, ttr, NULL_TREE);
+      if (penalty && h.code == 0)
+       {
+         h.code = QUAL_CODE;
+         h.int_penalty = penalty;
+       }
+      return h;
+    }
+
   if (codel == POINTER_TYPE && fntype_p (parmtype))
     {
       tree p1, p2;
@@ -164,10 +223,36 @@ convert_harshness (type, parmtype, parm)
       if (coder != TREE_CODE (type))
        return EVIL_RETURN (h);
 
+      if (type != parmtype && coder == METHOD_TYPE)
+       {
+         tree ttl = TYPE_METHOD_BASETYPE (type);
+         tree ttr = TYPE_METHOD_BASETYPE (parmtype);
+
+         int b_or_d = get_base_distance (ttr, ttl, 0, (tree*)0);
+         if (b_or_d < 0)
+           {
+             b_or_d = get_base_distance (ttl, ttr, 0, (tree*)0);
+             if (b_or_d < 0)
+               return EVIL_RETURN (h);
+             h.distance = -b_or_d;
+           }
+         else
+           h.distance = b_or_d;
+         h.code = STD_CODE;
+
+         type = build_function_type
+           (TREE_TYPE (type), TREE_CHAIN (TYPE_ARG_TYPES (type)));
+         parmtype = build_function_type
+           (TREE_TYPE (parmtype), TREE_CHAIN (TYPE_ARG_TYPES (parmtype)));
+       }
+
       /* We allow the default conversion between function type
         and pointer-to-function type for free.  */
-      if (type == parmtype)
-       return ZERO_RETURN (h);
+      if (comptypes (type, parmtype, 1))
+       return h;
+
+      if (pedantic)
+       return EVIL_RETURN (h);
 
       /* Compare return types.  */
       p1 = TREE_TYPE (type);
@@ -200,14 +285,16 @@ convert_harshness (type, parmtype, parm)
 
          if (! BINFO_OFFSET_ZEROP (binfo))
            {
+#if 0
              static int explained = 0;
              if (h2.distance < 0)
-               message_2_types (sorry, "cannot cast `%d' to `%d' at function call site", p2, p1);
+               message_2_types (sorry, "cannot cast `%s' to `%s' at function call site", p2, p1);
              else
-               message_2_types (sorry, "cannot cast `%d' to `%d' at function call site", p1, p2);
+               message_2_types (sorry, "cannot cast `%s' to `%s' at function call site", p1, p2);
 
              if (! explained++)
                sorry ("(because pointer values change during conversion)");
+#endif
              return EVIL_RETURN (h);
            }
        }
@@ -259,28 +346,34 @@ convert_harshness (type, parmtype, parm)
     }
   else if (codel == POINTER_TYPE && coder == OFFSET_TYPE)
     {
+      tree ttl, ttr;
+
       /* Get to the OFFSET_TYPE that this might be.  */
       type = TREE_TYPE (type);
 
       if (coder != TREE_CODE (type))
        return EVIL_RETURN (h);
 
-      if (TYPE_OFFSET_BASETYPE (type) == TYPE_OFFSET_BASETYPE (parmtype))
+      ttl = TYPE_OFFSET_BASETYPE (type);
+      ttr = TYPE_OFFSET_BASETYPE (parmtype);
+
+      if (ttl == ttr)
        h.code = 0;
-      else if (UNIQUELY_DERIVED_FROM_P (TYPE_OFFSET_BASETYPE (type),
-                              TYPE_OFFSET_BASETYPE (parmtype)))
-       {
-         h.code = STD_CODE;
-         h.distance = 1;
-       }
-      else if (UNIQUELY_DERIVED_FROM_P (TYPE_OFFSET_BASETYPE (parmtype),
-                              TYPE_OFFSET_BASETYPE (type)))
+      else
        {
+         int b_or_d = get_base_distance (ttr, ttl, 0, (tree*)0);
+         if (b_or_d < 0)
+           {
+             b_or_d = get_base_distance (ttl, ttr, 0, (tree*)0);
+             if (b_or_d < 0)
+               return EVIL_RETURN (h);
+             h.distance = -b_or_d;
+           }
+         else
+           h.distance = b_or_d;
          h.code = STD_CODE;
-         h.distance = -1;
        }
-      else
-       return EVIL_RETURN (h);
+
       /* Now test the OFFSET_TYPE's target compatibility.  */
       type = TREE_TYPE (type);
       parmtype = TREE_TYPE (parmtype);
@@ -300,6 +393,21 @@ convert_harshness (type, parmtype, parm)
   if (coder == VOID_TYPE)
     return EVIL_RETURN (h);
 
+  if (codel == BOOLEAN_TYPE)
+    {
+      if (INTEGRAL_CODE_P (coder) || coder == REAL_TYPE)
+       return STD_RETURN (h);
+      else if (coder == POINTER_TYPE || coder == OFFSET_TYPE)
+       {
+         /* Make this worse than any conversion to another pointer.
+            FIXME this is how I think the language should work, but it may not
+            end up being how the language is standardized (jason 1/30/95).  */
+         h.distance = 32767;
+         return STD_RETURN (h);
+       }
+      return EVIL_RETURN (h);
+    }
+
   if (INTEGRAL_CODE_P (codel))
     {
       /* Control equivalence of ints an enums.  */
@@ -321,13 +429,6 @@ convert_harshness (type, parmtype, parm)
              == TYPE_MAIN_VARIANT (type_promotes_to (parmtype)))
            {
              h.code = PROMO_CODE;
-#if 0 /* What purpose does this serve?  -jason */
-             /* A char, short, wchar_t, etc., should promote to an int if
-                it can handle it, otherwise to an unsigned.  So we'll make
-                an unsigned.  */
-             if (type != integer_type_node)
-               h.int_penalty = 1;
-#endif
            }
          else
            h.code = STD_CODE;
@@ -363,10 +464,17 @@ convert_harshness (type, parmtype, parm)
     }
 
   /* Convert arrays which have not previously been converted.  */
-  if (codel == ARRAY_TYPE)
-    codel = POINTER_TYPE;
   if (coder == ARRAY_TYPE)
-    coder = POINTER_TYPE;
+    {
+      coder = POINTER_TYPE;
+      if (parm)
+       {
+         parm = decay_conversion (parm);
+         parmtype = TREE_TYPE (parm);
+       }
+      else
+       parmtype = build_pointer_type (TREE_TYPE (parmtype));
+    }
 
   /* Conversions among pointers */
   if (codel == POINTER_TYPE && coder == POINTER_TYPE)
@@ -375,11 +483,10 @@ convert_harshness (type, parmtype, parm)
       register tree ttr = TYPE_MAIN_VARIANT (TREE_TYPE (parmtype));
       int penalty = 4 * (ttl != ttr);
 
-      /* Anything converts to void *.  void * converts to anything.
-        Since these may be `const void *' (etc.) use VOID_TYPE
-        instead of void_type_node.  Otherwise, the targets must be the same,
-        except that we do allow (at some cost) conversion between signed and
-        unsigned pointer types.  */
+      /* Anything converts to void *.  Since this may be `const void *'
+        (etc.) use VOID_TYPE instead of void_type_node.  Otherwise, the
+        targets must be the same, except that we do allow (at some cost)
+        conversion between signed and unsigned pointer types.  */
 
       if ((TREE_CODE (ttl) == METHOD_TYPE
           || TREE_CODE (ttl) == FUNCTION_TYPE)
@@ -396,15 +503,10 @@ convert_harshness (type, parmtype, parm)
        }
 
 #if 1
-      if (TREE_CODE (ttl) != VOID_TYPE && TREE_CODE (ttr) != VOID_TYPE)
+      if (TREE_CODE (ttl) != VOID_TYPE
+         && (TREE_CODE (ttr) != VOID_TYPE || !parm || !integer_zerop (parm)))
        {
-         if (TREE_UNSIGNED (ttl) != TREE_UNSIGNED (ttr))
-           {
-             ttl = unsigned_type (ttl);
-             ttr = unsigned_type (ttr);
-             penalty = 10;
-           }
-         if (! comp_target_types (ttl, ttr, 0))
+         if (comp_target_types (type, parmtype, 1) <= 0)
            return EVIL_RETURN (h);
        }
 #else
@@ -414,26 +516,22 @@ convert_harshness (type, parmtype, parm)
                && (ttl = unsigned_type (ttl),
                    ttr = unsigned_type (ttr),
                    penalty = 10, 0))
-           || (comp_target_types (ttl, ttr, 0))))
+           || (comp_target_types (ttl, ttr, 0) > 0)))
        return EVIL_RETURN (h);
 #endif
 
-      if (penalty == 10 || ttr == ttl)
+      if (ttr == ttl)
        {
          tree tmp1 = TREE_TYPE (type), tmp2 = TREE_TYPE (parmtype);
 
-         /* If one was unsigned but the other wasn't, then we need to
-            do a standard conversion from T to unsigned T.  */
-         if (penalty == 10)
-           h.code = PROMO_CODE; /* was STD_CODE */
-         else
-           h.code = 0;
-
+         h.code = 0;
          /* Note conversion from `T*' to `const T*',
                               or `T*' to `volatile T*'.  */
-         if (ttl == ttr
-             && ((TYPE_READONLY (tmp1) != TREE_READONLY (tmp2))
-                 || (TYPE_VOLATILE (tmp1) != TYPE_VOLATILE (tmp2))))
+         if ((TYPE_READONLY (tmp1) < TREE_READONLY (tmp2))
+             || (TYPE_VOLATILE (tmp1) < TYPE_VOLATILE (tmp2)))
+           h.code = EVIL_CODE;
+         else if ((TYPE_READONLY (tmp1) != TREE_READONLY (tmp2))
+                  || (TYPE_VOLATILE (tmp1) != TYPE_VOLATILE (tmp2)))
            h.code |= QUAL_CODE;
 
          h.distance = 0;
@@ -443,10 +541,10 @@ convert_harshness (type, parmtype, parm)
 
       if (TREE_CODE (ttl) == RECORD_TYPE && TREE_CODE (ttr) == RECORD_TYPE)
        {
-         int b_or_d = get_base_distance (ttl, ttr, 0, 0);
+         int b_or_d = get_base_distance (ttl, ttr, 0, (tree*)0);
          if (b_or_d < 0)
            {
-             b_or_d = get_base_distance (ttr, ttl, 0, 0);
+             b_or_d = get_base_distance (ttr, ttl, 0, (tree*)0);
              if (b_or_d < 0)
                return EVIL_RETURN (h);
              h.distance = -b_or_d;
@@ -465,7 +563,20 @@ convert_harshness (type, parmtype, parm)
          h.distance = CLASSTYPE_MAX_DEPTH (ttr)+1;
          return h;
        }
+
       h.code = penalty ? STD_CODE : PROMO_CODE;
+      /* Catch things like `const char *' -> `const void *'
+        vs `const char *' -> `void *'.  */
+      if (ttl != ttr)
+       {
+         tree tmp1 = TREE_TYPE (type), tmp2 = TREE_TYPE (parmtype);
+         if ((TYPE_READONLY (tmp1) < TREE_READONLY (tmp2))
+             || (TYPE_VOLATILE (tmp1) < TYPE_VOLATILE (tmp2)))
+           h.code = EVIL_CODE;
+         else if ((TYPE_READONLY (tmp1) > TREE_READONLY (tmp2))
+                  || (TYPE_VOLATILE (tmp1) > TYPE_VOLATILE (tmp2)))
+           h.code |= QUAL_CODE;
+       }
       return h;
     }
 
@@ -491,144 +602,84 @@ convert_harshness (type, parmtype, parm)
       && IS_SIGNATURE_POINTER (type) && IS_SIGNATURE (TREE_TYPE (parmtype)))
     return ZERO_RETURN (h);
 
-  if (codel == REFERENCE_TYPE)
+  if (codel == RECORD_TYPE && coder == RECORD_TYPE)
     {
-      tree ttl, ttr;
-      int constp = parm ? TREE_READONLY (parm) : TYPE_READONLY (parmtype);
-      int volatilep = (parm ? TREE_THIS_VOLATILE (parm)
-                      : TYPE_VOLATILE (parmtype));
-      register tree intype = TYPE_MAIN_VARIANT (parmtype);
-      register enum tree_code form = TREE_CODE (intype);
-      int penalty = 0;
-
-      ttl = TREE_TYPE (type);
-
-      /* When passing a non-const argument into a const reference (or vice
-        versa), dig it a little, so a non-const reference is preferred
-        over this one. (mrs) */
-      if (TYPE_READONLY (ttl) != constp
-         || TYPE_VOLATILE (ttl) != volatilep)
-       penalty = 2;
-      else
-       penalty = 0;
-
-      ttl = TYPE_MAIN_VARIANT (ttl);
-
-      if (form == OFFSET_TYPE)
+      int b_or_d = get_base_distance (type, parmtype, 0, (tree*)0);
+      if (b_or_d < 0)
        {
-         intype = TREE_TYPE (intype);
-         form = TREE_CODE (intype);
+         b_or_d = get_base_distance (parmtype, type, 0, (tree*)0);
+         if (b_or_d < 0)
+           return EVIL_RETURN (h);
+         h.distance = -b_or_d;
        }
-
-      if (ttl == intype && penalty == 0)
-       return ZERO_RETURN (h);
       else
-       penalty = 2;
+       h.distance = b_or_d;
+      h.code = STD_CODE;
+      return h;
+    }
+  return EVIL_RETURN (h);
+}
 
-      ttr = intype;
+/* A clone of build_type_conversion for checking user-defined conversions in
+   overload resolution.  */
 
-      /* If the initializer is not an lvalue, then it does not
-        matter if we make life easier for the programmer
-        by creating a temporary variable with which to
-        hold the result.  */
-      if (parm && (INTEGRAL_CODE_P (coder)
-                  || coder == REAL_TYPE)
-         && ! lvalue_p (parm))
-       {
-         h = convert_harshness (ttl, ttr, NULL_TREE);
-         if (penalty > 2 || h.code != 0)
-           h.code |= STD_CODE;
-         else
-           h.code |= TRIVIAL_CODE;
-         h.distance = 0;
-         return h;
-       }
+int
+user_harshness (type, parmtype)
+     register tree type, parmtype;
+{
+  tree conv;
+  tree winner = NULL_TREE;
+  int code;
 
-      if (TREE_UNSIGNED (ttl) ^ TREE_UNSIGNED (intype))
-       {
-         ttl = unsigned_type (ttl);
-         ttr = intype = unsigned_type (intype);
-         penalty += 2;
-       }
+  {
+    tree typename = build_typename_overload (type);
+    if (lookup_fnfields (TYPE_BINFO (parmtype), typename, 0))
+      return 0;
+  }
+                       
+  for (conv = lookup_conversions (parmtype); conv; conv = TREE_CHAIN (conv))
+    {
+      struct harshness_code tmp;
+      tree cand = TREE_VALUE (conv);
 
-      if (ttl == ttr)
+      if (winner && winner == cand)
+       continue;
+
+      tmp = convert_harshness (type, TREE_TYPE (TREE_TYPE (cand)), NULL_TREE);
+      if ((tmp.code < USER_CODE) && (tmp.distance >= 0))
        {
-         if (penalty > 2)
-           {
-             h.code = STD_CODE;
-             h.distance = 0;
-           }
+         if (winner)
+           return EVIL_CODE;
          else
            {
-             h.code = TRIVIAL_CODE;
-             /* We set this here so that build_overload_call_real will be
-                able to see the penalty we found, rather than just looking
-                at a TRIVIAL_CODE with no other information.  */
-             h.int_penalty = penalty;
+             winner = cand;
+             code = tmp.code;
            }
-         return h;
        }
+    }
 
-      /* Pointers to voids always convert for pointers.  But
-        make them less natural than more specific matches.  */
-      if (TREE_CODE (ttl) == POINTER_TYPE && TREE_CODE (ttr) == POINTER_TYPE)
-       {
-         if (TREE_TYPE (ttl) == void_type_node
-             || TREE_TYPE (ttr) == void_type_node)
-           {
-             h.code = STD_CODE;
-             h.distance = 0;
-             return h;
-           }
-       }
+  if (winner)
+    return code;
 
-      /* Here it does matter.  If this conversion is from derived to base,
-        allow it.  Otherwise, types must be compatible in the strong sense.  */
-      if (TREE_CODE (ttl) == RECORD_TYPE && TREE_CODE (ttr) == RECORD_TYPE)
-       {
-         int b_or_d = get_base_distance (ttl, ttr, 0, 0);
-         if (b_or_d < 0)
-           {
-             b_or_d = get_base_distance (ttr, ttl, 0, 0);
-             if (b_or_d < 0)
-               return EVIL_RETURN (h);
-             h.distance = -b_or_d;
-           }
-         /* Say that this conversion is relatively painless.
-            If it turns out that there is a user-defined X(X&)
-            constructor, then that will be invoked, but that's
-            preferable to dealing with other user-defined conversions
-            that may produce surprising results.  */
-         else
-           h.distance = b_or_d;
-         h.code = STD_CODE;
-         return h;
-       }
+  return -1;
+}
 
-      if (comp_target_types (ttl, intype, 1))
-       {
-         if (penalty)
-           h.code = STD_CODE;
-         h.distance = 0;
-         return h;
-       }
-    }
-  if (codel == RECORD_TYPE && coder == RECORD_TYPE)
-    {
-      int b_or_d = get_base_distance (type, parmtype, 0, 0);
-      if (b_or_d < 0)
-       {
-         b_or_d = get_base_distance (parmtype, type, 0, 0);
-         if (b_or_d < 0)
-           return EVIL_RETURN (h);
-         h.distance = -b_or_d;
-       }
-      else
-       h.distance = b_or_d;
-      h.code = STD_CODE;
-      return h;
-    }
-  return EVIL_RETURN (h);
+int
+can_convert (to, from)
+     tree to, from;
+{
+  struct harshness_code h;
+  h = convert_harshness (to, from, NULL_TREE);
+  return (h.code < USER_CODE) && (h.distance >= 0);
+}
+
+int
+can_convert_arg (to, from, arg)
+     tree to, from, arg;
+{
+  struct harshness_code h;
+  h = convert_harshness (to, from, arg);
+  return (h.code < USER_CODE) && (h.distance >= 0);
 }
 
 #ifdef DEBUG_MATCHING
@@ -912,43 +963,14 @@ compute_conversion_costs (function, tta_in, cp, arglen)
                  if (TYPE_LANG_SPECIFIC (actual_type)
                      && TYPE_HAS_CONVERSION (actual_type))
                    {
-                     tree conv;
-                     /* Don't issue warnings since we're only groping
-                        around for the right answer, we haven't yet
-                        committed to going with this solution.  */
-                     int old_inhibit_warnings = inhibit_warnings;
-
-                     inhibit_warnings = 1;
-                     conv = build_type_conversion
-                       (CALL_EXPR, TREE_VALUE (ttf), TREE_VALUE (tta), 0);
-                     inhibit_warnings = old_inhibit_warnings;
-
-                     if (conv)
-                       {
-                         if (conv == error_mark_node)
-                           win += 2;
-                         else
-                           {
-                             win++;
-                             if (TREE_CODE (conv) != CALL_EXPR)
-                               extra_conversions = 1;
-                           }
-                       }
-                     else if (TREE_CODE (TREE_VALUE (ttf)) == REFERENCE_TYPE)
+                     int extra = user_harshness (formal_type, actual_type);
+
+                     if (extra == EVIL_CODE)
+                       win += 2;
+                     else if (extra >= 0)
                        {
-                         conv = build_type_conversion (CALL_EXPR, formal_type,
-                                                       TREE_VALUE (tta), 0);
-                         if (conv)
-                           {
-                             if (conv == error_mark_node)
-                               win += 2;
-                             else
-                               {
-                                 win++;
-                                 if (TREE_CODE (conv) != CALL_EXPR)
-                                   extra_conversions = 1;
-                               }
-                           }
+                         win++;
+                         extra_conversions = extra;
                        }
                    }
                }
@@ -1047,11 +1069,9 @@ strictly_better (x, y)
    LEN is the length of the parameter list.  */
 
 static struct candidate *
-ideal_candidate (basetype, candidates, n_candidates, parms, len)
-     tree basetype;
+ideal_candidate (candidates, n_candidates, len)
      struct candidate *candidates;
      int n_candidates;
-     tree parms;
      int len;
 {
   struct candidate *cp = candidates+n_candidates;
@@ -1063,36 +1083,9 @@ ideal_candidate (basetype, candidates, n_candidates, parms, len)
      list for the last argument is the intersection of all the best-liked
      functions.  */
 
-#if 0
-  for (i = 0; i < len; i++)
-    {
-      qsort (candidates, n_candidates, sizeof (struct candidate),
-            rank_for_overload);
-      best_code = cp[-1].h.code;
-
-      /* To find out functions that are worse than that represented
-        by BEST_CODE, we can't just do a comparison like h.code>best_code.
-        The total harshness for the "best" fn may be 8|8 for two args, and
-        the harshness for the next-best may be 8|2.  If we just compared,
-        that would be checking 8>10, which would lead to the next-best
-        being disqualified.  What we actually want to do is get rid
-        of functions that are definitely worse than that represented
-        by best_code, i.e. those which have bits set higher than the
-        highest in best_code.  Sooooo, what we do is clear out everything
-        represented by best_code, and see if we still come up with something
-        higher.  If so (e.g., 8|8 vs 8|16), it'll disqualify it properly.  */
-      for (j = n_candidates-2; j >= 0; j--)
-       if ((candidates[j].h.code & ~best_code) > best_code)
-         candidates[j].h.code = EVIL_CODE;
-    }
-
-  if (cp[-1].h.code & EVIL_CODE)
-    return NULL;
-#else
   qsort (candidates, n_candidates, sizeof (struct candidate),
         rank_for_overload);
   best_code = cp[-1].h.code;
-#endif
 
   /* If they're at least as good as each other, do an arg-by-arg check.  */
   if (! strictly_better (cp[-1].h.code, cp[-2].h.code))
@@ -1179,7 +1172,7 @@ build_vfield_ref (datum, type)
     rval = build (COMPONENT_REF, TREE_TYPE (CLASSTYPE_VFIELD (type)),
                  datum, CLASSTYPE_VFIELD (type));
   else
-    rval = build_component_ref (datum, DECL_NAME (CLASSTYPE_VFIELD (type)), 0, 0);
+    rval = build_component_ref (datum, DECL_NAME (CLASSTYPE_VFIELD (type)), NULL_TREE, 0);
   flag_assume_nonnull_objects = old_assume_nonnull_objects;
 
   return rval;
@@ -1193,7 +1186,7 @@ build_field_call (basetype_path, instance_ptr, name, parms)
 {
   tree field, instance;
 
-  if (instance_ptr == current_class_decl)
+  if (instance_ptr == current_class_ptr)
     {
       /* Check to see if we really have a reference to an instance variable
         with `operator()()' overloaded.  */
@@ -1209,7 +1202,7 @@ build_field_call (basetype_path, instance_ptr, name, parms)
        {
          /* If it's a field, try overloading operator (),
             or calling if the field is a pointer-to-function.  */
-         instance = build_component_ref_1 (C_C_D, field, 0);
+         instance = build_component_ref_1 (current_class_ref, field, 0);
          if (instance == error_mark_node)
            return error_mark_node;
 
@@ -1222,7 +1215,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_decl, parms));
+               return build_function_call (instance, tree_cons (NULL_TREE, current_class_ptr, parms));
            }
        }
       return NULL_TREE;
@@ -1297,28 +1290,19 @@ find_scoped_type (type, inner_name, inner_types)
       if (TREE_PURPOSE (tags) == inner_name)
        {
          if (inner_types == NULL_TREE)
-           return DECL_NESTED_TYPENAME (TYPE_NAME (TREE_VALUE (tags)));
+           return TYPE_NAME (TREE_VALUE (tags));
          return resolve_scope_to_name (TREE_VALUE (tags), inner_types);
        }
       tags = TREE_CHAIN (tags);
     }
 
-#if 0
-  /* XXX This needs to be fixed better.  */
-  if (TREE_CODE (type) == UNINSTANTIATED_P_TYPE)
-    {
-      sorry ("nested class lookup in template type");
-      return NULL_TREE;
-    }
-#endif
-
   /* Look for a TYPE_DECL.  */
   for (tags = TYPE_FIELDS (type); tags; tags = TREE_CHAIN (tags))
     if (TREE_CODE (tags) == TYPE_DECL && DECL_NAME (tags) == inner_name)
       {
        /* Code by raeburn.  */
        if (inner_types == NULL_TREE)
-         return DECL_NESTED_TYPENAME (tags);
+         return tags;
        return resolve_scope_to_name (TREE_TYPE (tags), inner_types);
       }
 
@@ -1367,6 +1351,7 @@ resolve_scope_to_name (outer_type, inner_stuff)
 
   if (outer_type == NULL_TREE)
     {
+      tree x;
       /* If we have something that's already a type by itself,
         use that.  */
       if (IDENTIFIER_HAS_TYPE_VALUE (inner_name))
@@ -1376,6 +1361,14 @@ resolve_scope_to_name (outer_type, inner_stuff)
                                          inner_type);
          return inner_name;
        }
+      
+      x = lookup_name (inner_name, 0);
+
+      if (x && TREE_CODE (x) == NAMESPACE_DECL)
+       {
+         x = lookup_namespace_name (x, inner_type);
+         return x;
+       }
       return NULL_TREE;
     }
 
@@ -1408,8 +1401,8 @@ resolve_scope_to_name (outer_type, inner_stuff)
 /* Build a method call of the form `EXP->SCOPES::NAME (PARMS)'.
    This is how virtual function calls are avoided.  */
 tree
-build_scoped_method_call (exp, scopes, name, parms)
-     tree exp, scopes, name, parms;
+build_scoped_method_call (exp, basetype, name, parms)
+     tree exp, basetype, name, parms;
 {
   /* Because this syntactic form does not allow
      a pointer to a base class to be `stolen',
@@ -1417,15 +1410,23 @@ build_scoped_method_call (exp, scopes, name, parms)
      that happens here.
      
      @@ But we do have to check access privileges later.  */
-  tree basename = resolve_scope_to_name (NULL_TREE, scopes);
-  tree basetype, binfo, decl;
+  tree binfo, decl;
   tree type = TREE_TYPE (exp);
 
   if (type == error_mark_node
-      || basename == NULL_TREE)
+      || basetype == error_mark_node)
     return error_mark_node;
 
-  basetype = IDENTIFIER_TYPE_VALUE (basename);
+  if (current_template_parms)
+    {
+      if (TREE_CODE (name) == BIT_NOT_EXPR)
+       {
+         tree type = get_aggr_from_typedef (TREE_OPERAND (name, 0), 1);
+         name = build_min_nt (BIT_NOT_EXPR, type);
+       }
+      name = build_min_nt (SCOPE_REF, basetype, name);
+      return build_min_nt (METHOD_CALL_EXPR, name, exp, parms, NULL_TREE);
+    }
 
   if (TREE_CODE (type) == REFERENCE_TYPE)
     type = TREE_TYPE (type);
@@ -1433,19 +1434,19 @@ build_scoped_method_call (exp, scopes, name, parms)
   /* 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.  */
-  if (TREE_CODE (name) == BIT_NOT_EXPR && ! is_aggr_typedef (basename, 0))
+  if (TREE_CODE (name) == BIT_NOT_EXPR && ! IS_AGGR_TYPE (basetype))
     {
       if (type != basetype)
        cp_error ("type of `%E' does not match destructor type `%T' (type was `%T')",
                  exp, basetype, type);
       name = TREE_OPERAND (name, 0);
-      if (basetype != get_type_value (name))
+      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);
     }
 
-  if (! is_aggr_typedef (basename, 1))
+  if (! is_aggr_type (basetype, 1))
     return error_mark_node;
 
   if (! IS_AGGR_TYPE (type))
@@ -1463,14 +1464,15 @@ build_scoped_method_call (exp, scopes, name, parms)
        decl = build_indirect_ref (convert_pointer_to (binfo,
                                                       build_unary_op (ADDR_EXPR, exp, 0)), NULL_PTR);
       else
-       decl = build_scoped_ref (exp, scopes);
+       decl = build_scoped_ref (exp, basetype);
 
       /* Call to a destructor.  */
       if (TREE_CODE (name) == BIT_NOT_EXPR)
        {
          /* Explicit call to destructor.  */
          name = TREE_OPERAND (name, 0);
-         if (! (name == constructor_name (TREE_TYPE (decl))
+         if (! (name == TYPE_MAIN_VARIANT (TREE_TYPE (decl))
+                || name == constructor_name (TREE_TYPE (decl))
                 || TREE_TYPE (decl) == get_type_value (name)))
            {
              cp_error
@@ -1519,6 +1521,101 @@ print_n_candidates (candidates, n)
     cp_error_at ("                %D", candidates[i].function);
 }
 
+/* We want the address of a function or method.  We avoid creating a
+   pointer-to-member function.  */
+tree
+build_addr_func (function)
+     tree function;
+{
+  tree type = TREE_TYPE (function);
+
+  /* We have to do these by hand to avoid real pointer to member
+     functions.  */
+  if (TREE_CODE (type) == METHOD_TYPE)
+    {
+      tree addr;
+
+      type = build_pointer_type (type);
+
+      if (mark_addressable (function) == 0)
+       return error_mark_node;
+
+      addr = build1 (ADDR_EXPR, type, function);
+
+      /* Address of a static or external variable or function counts
+        as a constant */
+      if (staticp (function))
+       TREE_CONSTANT (addr) = 1;
+
+      function = addr;
+    }
+  else
+    function = default_conversion (function);
+
+  return function;
+}
+
+/* Build a CALL_EXPR, we can handle FUNCTION_TYPEs, METHOD_TYPEs, or
+   POINTER_TYPE to those.  Note, pointer to member function types
+   (TYPE_PTRMEMFUNC_P) must be handled by our callers.  */
+tree
+build_call (function, result_type, parms)
+     tree function, result_type, parms;
+{
+  int is_constructor = 0;
+
+  function = build_addr_func (function);
+
+  if (TYPE_PTRMEMFUNC_P (TREE_TYPE (function)))
+    {
+      sorry ("unable to call pointer to member function here");
+      return error_mark_node;
+    }
+
+  if (TREE_CODE (function) == ADDR_EXPR
+      && TREE_CODE (TREE_OPERAND (function, 0)) == FUNCTION_DECL
+      && DECL_CONSTRUCTOR_P (TREE_OPERAND (function, 0)))
+    is_constructor = 1;
+
+  function = build_nt (CALL_EXPR, function, parms, NULL_TREE);
+  TREE_HAS_CONSTRUCTOR (function) = is_constructor;
+  TREE_TYPE (function) = result_type;
+  TREE_SIDE_EFFECTS (function) = 1;
+  
+  return function;
+}
+
+static tree
+default_parm_conversions (parms, last)
+     tree parms, *last;
+{
+  tree parm, parmtypes = NULL_TREE;
+
+  *last = NULL_TREE;
+
+  for (parm = parms; parm; parm = TREE_CHAIN (parm))
+    {
+      tree t = TREE_TYPE (TREE_VALUE (parm));
+
+      if (TREE_CODE (t) == OFFSET_TYPE
+         || TREE_CODE (t) == METHOD_TYPE
+         || TREE_CODE (t) == FUNCTION_TYPE)
+       {
+         TREE_VALUE (parm) = default_conversion (TREE_VALUE (parm));
+         t = TREE_TYPE (TREE_VALUE (parm));
+       }
+
+      if (t == error_mark_node)
+         return error_mark_node;
+
+      *last = build_tree_list (NULL_TREE, t);
+      parmtypes = chainon (parmtypes, *last);
+    }
+
+  return parmtypes;
+}
+
+
 /* Build something of the form ptr->method (args)
    or object.method (args).  This can also build
    calls to constructors, and find friends.
@@ -1557,16 +1654,18 @@ build_method_call (instance, name, parms, basetype_path, flags)
 {
   register tree function, fntype, value_type;
   register tree basetype, save_basetype;
-  register tree baselink, result, method_name, parmtypes, parm;
+  register tree baselink, result, parmtypes, parm;
   tree last;
   int pass;
-  enum access_type access = access_public;
+  tree access = access_public_node;
+  tree orig_basetype = basetype_path ? BINFO_TYPE (basetype_path) : NULL_TREE;
 
   /* Range of cases for vtable optimization.  */
   enum vtable_needs { not_needed, maybe_needed, unneeded, needed };
   enum vtable_needs need_vtbl = not_needed;
 
   char *name_kind;
+  tree save_name = name;
   int ever_seen = 0;
   tree instance_ptr = NULL_TREE;
   int all_virtual = flag_all_virtual;
@@ -1586,6 +1685,17 @@ build_method_call (instance, name, parms, basetype_path, flags)
       || (instance != NULL_TREE && TREE_TYPE (instance) == error_mark_node))
     return error_mark_node;
 
+  if (current_template_parms)
+    {
+      if (TREE_CODE (name) == BIT_NOT_EXPR)
+       {
+         tree type = get_aggr_from_typedef (TREE_OPERAND (name, 0), 1);
+         name = build_min_nt (BIT_NOT_EXPR, type);
+       }
+
+      return build_min_nt (METHOD_CALL_EXPR, name, instance, parms, NULL_TREE);
+    }
+
   /* This is the logic that magically deletes the second argument to
      operator delete, if it is not needed. */
   if (name == ansi_opname[(int) DELETE_EXPR] && list_length (parms)==2)
@@ -1597,14 +1707,15 @@ build_method_call (instance, name, parms, basetype_path, flags)
       result = build_method_call (instance, name, parms, basetype_path,
                                  (LOOKUP_SPECULATIVELY|flags)
                                  &~LOOKUP_COMPLAIN);
-      /* If it works, return it. */
-      if (result && result != error_mark_node)
+      /* If it finds a match, return it. */
+      if (result)
        return build_method_call (instance, name, parms, basetype_path, flags);
       /* If it doesn't work, two argument delete must work */
       TREE_CHAIN (parms) = save_last;
     }
   /* We already know whether it's needed or not for vec delete.  */
   else if (name == ansi_opname[(int) VEC_DELETE_EXPR]
+          && TYPE_LANG_SPECIFIC (TREE_TYPE (instance))
           && ! TYPE_VEC_DELETE_TAKES_SIZE (TREE_TYPE (instance)))
     TREE_CHAIN (parms) = NULL_TREE;
 
@@ -1617,8 +1728,9 @@ build_method_call (instance, name, parms, basetype_path, flags)
       basetype = TREE_TYPE (instance);
       if (TREE_CODE (basetype) == REFERENCE_TYPE)
        basetype = TREE_TYPE (basetype);
-      if (! ((IS_AGGR_TYPE (basetype)
-             && name == constructor_name (basetype))
+      if (! (name == basetype
+            || (IS_AGGR_TYPE (basetype)
+                && name == constructor_name (basetype))
             || basetype == get_type_value (name)))
        {
          cp_error ("destructor name `~%D' does not match type `%T' of expression",
@@ -1679,11 +1791,15 @@ build_method_call (instance, name, parms, basetype_path, flags)
        ;
       /* call to a constructor... */
       else if (basetype_path)
-       basetype = BINFO_TYPE (basetype_path);
+       {
+         basetype = BINFO_TYPE (basetype_path);
+         if (name == TYPE_IDENTIFIER (basetype))
+           name = ctor_identifier;
+       }
       else if (IDENTIFIER_HAS_TYPE_VALUE (name))
        {
          basetype = IDENTIFIER_TYPE_VALUE (name);
-         name = constructor_name_full (basetype);
+         name = ctor_identifier;
        }
       else
        {
@@ -1692,7 +1808,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
            {
              /* Canonicalize the typedef name.  */
              basetype = TREE_TYPE (typedef_name);
-             name = TYPE_IDENTIFIER (basetype);
+             name = ctor_identifier;
            }
          else
            {
@@ -1712,11 +1828,11 @@ build_method_call (instance, name, parms, basetype_path, flags)
          return error_mark_node;
        }
     }
-  else if (instance == C_C_D || instance == current_class_decl)
+  else if (instance == current_class_ref || instance == current_class_ptr)
     {
       /* When doing initialization, we side-effect the TREE_TYPE of
-        C_C_D, hence we cannot set up BASETYPE from CURRENT_CLASS_TYPE.  */
-      basetype = TREE_TYPE (C_C_D);
+        current_class_ref, hence we cannot set up BASETYPE from CURRENT_CLASS_TYPE.  */
+      basetype = TREE_TYPE (current_class_ref);
 
       /* Anything manifestly `this' in constructors and destructors
         has a known type, so virtual function tables are not needed.  */
@@ -1725,10 +1841,24 @@ build_method_call (instance, name, parms, basetype_path, flags)
        need_vtbl = (dtor_label || ctor_label)
          ? unneeded : maybe_needed;
 
-      instance = C_C_D;
-      instance_ptr = current_class_decl;
-      result = build_field_call (TYPE_BINFO (current_class_type),
-                                instance_ptr, name, parms);
+      /* If `this' is a signature pointer and `name' is not a constructor,
+        we are calling a signature member function.  In that case, set the
+        `basetype' to the signature type and dereference the `optr' field.  */
+      if (IS_SIGNATURE_POINTER (basetype)
+         && TYPE_IDENTIFIER (basetype) != name)
+       {
+         basetype = SIGNATURE_TYPE (basetype);
+         instance_ptr = build_optr_ref (instance);
+         instance_ptr = convert (build_pointer_type (basetype), instance_ptr);
+         basetype_path = TYPE_BINFO (basetype);
+       }
+      else
+       {
+         instance = current_class_ref;
+         instance_ptr = current_class_ptr;
+         basetype_path = TYPE_BINFO (current_class_type);
+       }
+      result = build_field_call (basetype_path, instance_ptr, name, parms);
 
       if (result)
        return result;
@@ -1741,7 +1871,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
         within the scope of this function.  */
       if (!(flags & LOOKUP_NONVIRTUAL) && TYPE_VIRTUAL_P (basetype))
        need_vtbl = maybe_needed;
-      instance_ptr = build1 (ADDR_EXPR, TYPE_POINTER_TO (basetype), instance);
+      instance_ptr = build1 (ADDR_EXPR, build_pointer_type (basetype), instance);
     }
   else
     {
@@ -1772,7 +1902,10 @@ build_method_call (instance, name, parms, basetype_path, flags)
        }
       else
        {
-         if (! IS_AGGR_TYPE (basetype))
+         if (! IS_AGGR_TYPE (basetype)
+             && ! (TYPE_LANG_SPECIFIC (basetype)
+                   && (IS_SIGNATURE_POINTER (basetype)
+                       || IS_SIGNATURE_REFERENCE (basetype))))
            goto non_aggr_error;
 
          /* If `instance' is a signature pointer/reference and `name' is
@@ -1784,7 +1917,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
            basetype = SIGNATURE_TYPE (basetype);
 
          if ((IS_SIGNATURE (basetype)
-              && (instance_ptr = build_optr_ref (instance)))
+              && (instance_ptr = instance))
              || (lvalue_p (instance)
                  && (instance_ptr = build_unary_op (ADDR_EXPR, instance, 0)))
              || (instance_ptr = unary_complex_lvalue (ADDR_EXPR, instance)))
@@ -1813,14 +1946,10 @@ build_method_call (instance, name, parms, basetype_path, flags)
            }
          else
            {
-             if (TREE_CODE (instance) != CALL_EXPR
-#ifdef PCC_STATIC_STRUCT_RETURN
-                 && TREE_CODE (instance) != RTL_EXPR
-#endif
-                 )
+             if (TREE_CODE (instance) != CALL_EXPR)
                my_friendly_abort (125);
              if (TYPE_NEEDS_CONSTRUCTING (basetype))
-               instance = build_cplus_new (basetype, instance, 0);
+               instance = build_cplus_new (basetype, instance);
              else
                {
                  instance = get_temp_name (basetype, 0);
@@ -1829,12 +1958,15 @@ build_method_call (instance, name, parms, basetype_path, flags)
              instance_ptr = build_unary_op (ADDR_EXPR, instance, 0);
            }
          /* @@ Should we call comp_target_types here?  */
-         inst_ptr_basetype = TREE_TYPE (TREE_TYPE (instance_ptr));
+         if (IS_SIGNATURE (basetype))
+           inst_ptr_basetype = basetype;
+         else
+           inst_ptr_basetype = TREE_TYPE (TREE_TYPE (instance_ptr));
          if (TYPE_MAIN_VARIANT (basetype) == TYPE_MAIN_VARIANT (inst_ptr_basetype))
            basetype = inst_ptr_basetype;
          else
            {
-             instance_ptr = convert (TYPE_POINTER_TO (basetype), instance_ptr);
+             instance_ptr = convert (build_pointer_type (basetype), instance_ptr);
              if (instance_ptr == error_mark_node)
                return error_mark_node;
            }
@@ -1875,7 +2007,10 @@ build_method_call (instance, name, parms, basetype_path, flags)
        }
     }
 
-  if (TYPE_SIZE (basetype) == 0)
+  if (save_name == ctor_identifier)
+    save_name = TYPE_IDENTIFIER (basetype);
+
+  if (TYPE_SIZE (complete_type (basetype)) == 0)
     {
       /* This is worth complaining about, I think.  */
       cp_error ("cannot lookup method in incomplete type `%T'", basetype);
@@ -1884,47 +2019,21 @@ build_method_call (instance, name, parms, basetype_path, flags)
 
   save_basetype = TYPE_MAIN_VARIANT (basetype);
 
-#if 0
-  if (all_virtual == 1
-      && (! strncmp (IDENTIFIER_POINTER (name), OPERATOR_METHOD_FORMAT,
-                    OPERATOR_METHOD_LENGTH)
-         || instance_ptr == NULL_TREE
-         || (TYPE_OVERLOADS_METHOD_CALL_EXPR (basetype) == 0)))
-    all_virtual = 0;
-#endif
-
-  last = NULL_TREE;
-  for (parmtypes = NULL_TREE, parm = parms; parm; parm = TREE_CHAIN (parm))
+  parmtypes = default_parm_conversions (parms, &last);
+  if (parmtypes == error_mark_node)
     {
-      tree t = TREE_TYPE (TREE_VALUE (parm));
-      if (TREE_CODE (t) == OFFSET_TYPE)
-       {
-         /* Convert OFFSET_TYPE entities to their normal selves.  */
-         TREE_VALUE (parm) = resolve_offset_ref (TREE_VALUE (parm));
-         t = TREE_TYPE (TREE_VALUE (parm));
-       }
-      if (TREE_CODE (TREE_VALUE (parm)) == OFFSET_REF
-         && TREE_CODE (t) == METHOD_TYPE)
-       {
-         TREE_VALUE (parm) = build_unary_op (ADDR_EXPR, TREE_VALUE (parm), 0);
-       }
-#if 0
-      /* This breaks reference-to-array parameters.  */
-      if (TREE_CODE (t) == ARRAY_TYPE)
-       {
-         /* Perform the conversion from ARRAY_TYPE to POINTER_TYPE in place.
-            This eliminates needless calls to `compute_conversion_costs'.  */
-         TREE_VALUE (parm) = default_conversion (TREE_VALUE (parm));
-         t = TREE_TYPE (TREE_VALUE (parm));
-       }
-#endif
-      if (t == error_mark_node)
-       return error_mark_node;
-      last = build_tree_list (NULL_TREE, t);
-      parmtypes = chainon (parmtypes, last);
+      return error_mark_node;
     }
 
-  if (instance)
+  if (instance && IS_SIGNATURE (basetype))
+    {
+      /* @@ Should this be the constp/volatilep flags for the optr field
+        of the signature pointer?  */
+      constp = TYPE_READONLY (basetype);
+      volatilep = TYPE_VOLATILE (basetype);
+      parms = 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)));
@@ -1942,40 +2051,11 @@ build_method_call (instance, name, parms, basetype_path, flags)
          parmtypes = tree_cons (NULL_TREE, integer_type_node, parmtypes);
        }
 
-      if (flag_this_is_variable > 0)
-       {
-         constp = 0;
-         volatilep = 0;
-         parms = tree_cons (NULL_TREE,
-                            build1 (NOP_EXPR, TYPE_POINTER_TO (basetype),
-                                    integer_zero_node), parms);
-       }
-      else
-       {
-         constp = 0;
-         volatilep = 0;
-         instance_ptr = build_new (NULL_TREE, basetype, void_type_node, 0);
-         if (instance_ptr == error_mark_node)
-           return error_mark_node;
-         instance_ptr = save_expr (instance_ptr);
-         TREE_CALLS_NEW (instance_ptr) = 1;
-         instance = build_indirect_ref (instance_ptr, NULL_PTR);
-
-#if 0
-         /* This breaks initialization of a reference from a new
-             expression of a different type.  And it doesn't appear to
-             serve its original purpose any more, either.  jason 10/12/94 */
-         /* If it's a default argument initialized from a ctor, what we get
-            from instance_ptr will match the arglist for the FUNCTION_DECL
-            of the constructor.  */
-         if (parms && TREE_CODE (TREE_VALUE (parms)) == CALL_EXPR
-             && TREE_OPERAND (TREE_VALUE (parms), 1)
-             && TREE_CALLS_NEW (TREE_VALUE (TREE_OPERAND (TREE_VALUE (parms), 1))))
-           parms = build_tree_list (NULL_TREE, instance_ptr);
-         else
-#endif
-           parms = tree_cons (NULL_TREE, instance_ptr, parms);
-       }
+      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);
     }
 
   parmtypes = tree_cons (NULL_TREE, TREE_TYPE (instance_ptr), parmtypes);
@@ -1985,15 +2065,17 @@ build_method_call (instance, name, parms, basetype_path, flags)
 
   /* Look up function name in the structure type definition.  */
 
+  /* FIXME Axe most of this now?  */
   if ((IDENTIFIER_HAS_TYPE_VALUE (name)
        && ! IDENTIFIER_OPNAME_P (name)
-       && IS_AGGR_TYPE (IDENTIFIER_TYPE_VALUE (name))
-       && TREE_CODE (IDENTIFIER_TYPE_VALUE (name)) != UNINSTANTIATED_P_TYPE)
-      || name == constructor_name (basetype))
+       && IS_AGGR_TYPE (IDENTIFIER_TYPE_VALUE (name)))
+      || name == constructor_name (basetype)
+      || name == ctor_identifier)
     {
       tree tmp = NULL_TREE;
       if (IDENTIFIER_TYPE_VALUE (name) == basetype
-         || name == constructor_name (basetype))
+         || name == constructor_name (basetype)
+         || name == ctor_identifier)
        tmp = TYPE_BINFO (basetype);
       else
        tmp = get_binfo (IDENTIFIER_TYPE_VALUE (name), basetype, 0);
@@ -2032,19 +2114,6 @@ build_method_call (instance, name, parms, basetype_path, flags)
   if (result == error_mark_node)
     return error_mark_node;
 
-
-#if 0
-  /* Now, go look for this method name.  We do not find destructors here.
-
-     Putting `void_list_node' on the end of the parmtypes
-     fakes out `build_decl_overload' into doing the right thing.  */
-  TREE_CHAIN (last) = void_list_node;
-  method_name = build_decl_overload (name, parmtypes,
-                                    1 + (name == constructor_name (save_basetype)
-                                         || name == constructor_name_full (save_basetype)));
-  TREE_CHAIN (last) = NULL_TREE;
-#endif
-
   for (pass = 0; pass < 2; pass++)
     {
       struct candidate *candidates;
@@ -2052,10 +2121,6 @@ build_method_call (instance, name, parms, basetype_path, flags)
       int len;
       unsigned best = 1;
 
-      /* This increments every time we go up the type hierarchy.
-        The idea is to prefer a function of the derived class if possible. */
-      int b_or_d = 0;
-
       baselink = result;
 
       if (pass > 0)
@@ -2075,30 +2140,20 @@ build_method_call (instance, name, parms, basetype_path, flags)
              tree parm = instance_ptr;
 
              if (TREE_CODE (TREE_TYPE (parm)) == REFERENCE_TYPE)
-               {
-                 /* TREE_VALUE (parms) may have been modified by now;
-                     restore it to its original value. */
-                 TREE_VALUE (parms) = parm;
-                 friend_parms = parms;
-               }
+               parm = convert_from_reference (parm);
              else if (TREE_CODE (TREE_TYPE (parm)) == POINTER_TYPE)
-               {
-                 tree new_type;
-                 parm = build_indirect_ref (parm, "friendifying parms (compiler error)");
-                 new_type = cp_build_type_variant (TREE_TYPE (parm), constp,
-                                                  volatilep);
-                 new_type = build_reference_type (new_type);
-                 parm = convert (new_type, parm);
-                 friend_parms = tree_cons (NULL_TREE, parm, TREE_CHAIN (parms));
-               }
+               parm = build_indirect_ref (parm, "friendifying parms (compiler error)");
              else
                my_friendly_abort (167);
 
+             friend_parms = tree_cons (NULL_TREE, parm, TREE_CHAIN (parms));
+
              cp->h_len = len;
              cp->harshness = (struct harshness_code *)
                alloca ((len + 1) * sizeof (struct harshness_code));
 
-             result = build_overload_call (name, friend_parms, 0, cp);
+             result = build_overload_call_real (name, friend_parms, 0, cp, 1);
+
              /* If it turns out to be the one we were actually looking for
                 (it was probably a friend function), the return the
                 good result.  */
@@ -2118,7 +2173,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
            }
        }
 
-      while (baselink)
+      if (baselink)
        {
          /* We have a hit (of sorts). If the parameter list is
             "error_mark_node", or some variant thereof, it won't
@@ -2134,28 +2189,6 @@ build_method_call (instance, name, parms, basetype_path, flags)
            basetype_path = TREE_VALUE (basetype_path);
          basetype = BINFO_TYPE (basetype_path);
 
-         /* Cast the instance variable if necessary.  */
-         if (basetype != TYPE_MAIN_VARIANT
-             (TREE_TYPE (TREE_TYPE (TREE_VALUE (parms)))))
-           {
-             if (basetype == save_basetype)
-               TREE_VALUE (parms) = instance_ptr;
-             else
-               {
-                 tree type = build_pointer_type
-                   (build_type_variant (basetype, constp, volatilep));
-                 TREE_VALUE (parms) = convert_force (type, instance_ptr, 0);
-               }
-           }
-
-         /* FIXME: this is the wrong place to get an error.  Hopefully
-            the access-control rewrite will make this change more cleanly.  */
-         if (TREE_VALUE (parms) == error_mark_node)
-           return error_mark_node;
-
-         if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (function)))
-           function = DECL_CHAIN (function);
-
          for (; function; function = DECL_CHAIN (function))
            {
 #ifdef GATHER_STATISTICS
@@ -2170,12 +2203,6 @@ build_method_call (instance, name, parms, basetype_path, flags)
                  && ! DECL_STATIC_FUNCTION_P (function))
                continue;
 
-#if 0
-             if (pass == 0
-                 && DECL_ASSEMBLER_NAME (function) == method_name)
-               goto found;
-#endif
-
              if (pass > 0)
                {
                  tree these_parms = parms;
@@ -2208,31 +2235,12 @@ build_method_call (instance, name, parms, basetype_path, flags)
                          && (cp->h.code & USER_CODE))
                        continue;
 
-                     /* If we used default parameters, we must
-                        check to see whether anyone else might
-                        use them also, and report a possible
-                        ambiguity.  */
-                     if (! TYPE_USES_MULTIPLE_INHERITANCE (save_basetype)
-                         && cp->harshness[len].distance == 0
-                         && cp->h.code < best)
-                       {
-                         if (! DECL_STATIC_FUNCTION_P (function))
-                           TREE_VALUE (parms) = cp->arg;
-                         if (best == 1)
-                           goto found_and_maybe_warn;
-                       }
                      cp++;
                    }
                }
            }
-         /* Now we have run through one link's member functions.
-            arrange to head-insert this link's links.  */
-         baselink = next_baselink (baselink);
-         b_or_d += 1;
-         /* Don't grab functions from base classes.  lookup_fnfield will
-            do the work to get us down into the right place.  */
-         baselink = NULL_TREE;
        }
+
       if (pass == 0)
        {
          tree igv = lookup_name_nonclass (name);
@@ -2256,10 +2264,10 @@ build_method_call (instance, name, parms, basetype_path, flags)
              TREE_CHAIN (last) = void_list_node;
              if (flags & LOOKUP_GLOBAL)
                cp_error ("no global or member function `%D(%A)' defined",
-                         name, parmtypes);
+                         save_name, parmtypes);
              else
                cp_error ("no member function `%T::%D(%A)' defined",
-                         save_basetype, name, TREE_CHAIN (parmtypes));
+                         save_basetype, save_name, TREE_CHAIN (parmtypes));
              return error_mark_node;
            }
          continue;
@@ -2277,15 +2285,14 @@ build_method_call (instance, name, parms, basetype_path, flags)
              int n_candidates = cp - candidates;
              extern int warn_synth;
              TREE_VALUE (parms) = instance_ptr;
-             cp = ideal_candidate (save_basetype, candidates,
-                                   n_candidates, parms, len);
+             cp = ideal_candidate (candidates, n_candidates, len);
              if (cp == (struct candidate *)0)
                {
                  if (flags & LOOKUP_COMPLAIN)
                    {
                      TREE_CHAIN (last) = void_list_node;
                      cp_error ("call of overloaded %s `%D(%A)' is ambiguous",
-                               name_kind, name, TREE_CHAIN (parmtypes));
+                               name_kind, save_name, TREE_CHAIN (parmtypes));
                      print_n_candidates (candidates, n_candidates);
                    }
                  return error_mark_node;
@@ -2307,7 +2314,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
            {
              if (flags & LOOKUP_COMPLAIN)
                cp_error ("ambiguous type conversion requested for %s `%D'",
-                         name_kind, name);
+                         name_kind, save_name);
              return error_mark_node;
            }
          else
@@ -2350,9 +2357,10 @@ build_method_call (instance, name, parms, basetype_path, flags)
              else if (ever_seen > 1)
                {
                  TREE_CHAIN (last) = void_list_node;
-                 cp_error ("no matching function for call to `%T::%D (%A)'",
-                           TREE_TYPE (TREE_TYPE (instance_ptr)),
-                           name, TREE_CHAIN (parmtypes));
+                 cp_error ("no matching function for call to `%T::%D (%A)%V'",
+                           TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (instance_ptr))),
+                           save_name, TREE_CHAIN (parmtypes),
+                           TREE_TYPE (TREE_TYPE (instance_ptr)));
                  TREE_CHAIN (last) = NULL_TREE;
                  print_candidates (found_fns);
                }
@@ -2364,7 +2372,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
          if ((flags & (LOOKUP_SPECULATIVELY|LOOKUP_COMPLAIN))
              == LOOKUP_COMPLAIN)
            {
-             cp_error ("%T has no method named %D", save_basetype, name);
+             cp_error ("%T has no method named %D", save_basetype, save_name);
              return error_mark_node;
            }
          return NULL_TREE;
@@ -2394,7 +2402,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
   if (flags & LOOKUP_PROTECT)
     access = compute_access (basetype_path, function);
 
-  if (access == access_private)
+  if (access == access_private_node)
     {
       if (flags & LOOKUP_COMPLAIN)
        {
@@ -2405,7 +2413,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
        }
       return error_mark_node;
     }
-  else if (access == access_protected)
+  else if (access == access_protected_node)
     {
       if (flags & LOOKUP_COMPLAIN)
        {
@@ -2421,31 +2429,37 @@ build_method_call (instance, name, parms, basetype_path, flags)
      type (if it exists) is a pointer to.  */
 
   if (DECL_ABSTRACT_VIRTUAL_P (function)
-      && instance == C_C_D
+      && instance == current_class_ref
       && DECL_CONSTRUCTOR_P (current_function_decl)
       && ! (flags & LOOKUP_NONVIRTUAL)
       && value_member (function, get_abstract_virtuals (basetype)))
     cp_error ("abstract virtual `%#D' called from constructor", function);
 
-  if (IS_SIGNATURE (basetype) && static_call_context)
+  if (IS_SIGNATURE (basetype))
     {
-      cp_error ("cannot call signature member function `%T::%D' without signature pointer/reference",
-               basetype, name);
-      return error_mark_node;
+      if (static_call_context)
+       {
+         cp_error ("cannot call signature member function `%T::%D' without signature pointer/reference",
+                   basetype, save_name);
+         return error_mark_node;
        }
-  else if (IS_SIGNATURE (basetype))
-    return build_signature_method_call (basetype, instance, function, parms);
+      return build_signature_method_call (basetype, instance, function, parms);
+    }
 
   function = DECL_MAIN_VARIANT (function);
-  /* Declare external function if necessary. */
-  assemble_external (function);
+  mark_used (function);
 
-#if 0
-  if (DECL_ARTIFICIAL (function) && ! flag_no_inline
-      && DECL_SAVED_INSNS (function) == 0
-      && ! TREE_ASM_WRITTEN (function))
+  /* Is it a synthesized method that needs to be synthesized?  */
+  if (DECL_ARTIFICIAL (function) && ! DECL_INITIAL (function)
+      /* Kludge: don't synthesize for default args.  */
+      && current_function_decl)
     synthesize_method (function);
-#endif
+
+  if (pedantic && DECL_THIS_INLINE (function) && ! DECL_ARTIFICIAL (function)
+      && ! DECL_INITIAL (function) && ! DECL_PENDING_INLINE_INFO (function)
+      && ! (DECL_TEMPLATE_INFO (function)
+           && TREE_LANG_FLAG_0 (DECL_TEMPLATE_INFO (function))))
+    cp_warning ("inline function `%#D' called before definition", function);
 
   fntype = TREE_TYPE (function);
   if (TREE_CODE (fntype) == POINTER_TYPE)
@@ -2472,21 +2486,23 @@ build_method_call (instance, name, parms, basetype_path, flags)
   if (TREE_CODE (fntype) == METHOD_TYPE && static_call_context
       && !DECL_CONSTRUCTOR_P (function))
     {
-      /* Let's be nice to the user for now, and give reasonable
-        default behavior.  */
-      instance_ptr = current_class_decl;
+      /* Let's be nasty to the user now, and give reasonable
+        error messages.  */
+      instance_ptr = current_class_ptr;
       if (instance_ptr)
        {
          if (basetype != current_class_type)
            {
-             tree binfo = get_binfo (basetype, current_class_type, 1);
-             if (binfo == NULL_TREE)
-               {
-                 error_not_base_type (function, current_class_type);
-                 return error_mark_node;
-               }
-             else if (basetype == error_mark_node)
+             if (basetype == error_mark_node)
                return error_mark_node;
+             else 
+                {
+                 if (orig_basetype != NULL_TREE)
+                   error_not_base_type (orig_basetype, current_class_type);
+                 else
+                   error_not_base_type (function, current_class_type);
+                  return error_mark_node;
+                }
            }
        }
       /* Only allow a static member function to call another static member
@@ -2502,7 +2518,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
 
   value_type = TREE_TYPE (fntype) ? TREE_TYPE (fntype) : void_type_node;
 
-  if (TYPE_SIZE (value_type) == 0)
+  if (TYPE_SIZE (complete_type (value_type)) == 0)
     {
       if (flags & LOOKUP_COMPLAIN)
        incomplete_type_error (0, value_type);
@@ -2516,8 +2532,8 @@ build_method_call (instance, name, parms, basetype_path, flags)
     {
       int sub_flags = DECL_CONSTRUCTOR_P (function) ? flags : LOOKUP_NORMAL;
       basetype = TREE_TYPE (instance);
-      if (TYPE_METHOD_BASETYPE (TREE_TYPE (function)) != TYPE_MAIN_VARIANT (basetype)
-         && TYPE_USES_COMPLEX_INHERITANCE (basetype))
+      if (TYPE_METHOD_BASETYPE (TREE_TYPE (function))
+         != TYPE_MAIN_VARIANT (basetype))
        {
          basetype = DECL_CLASS_CONTEXT (function);
          instance_ptr = convert_pointer_to (basetype, instance_ptr);
@@ -2575,46 +2591,9 @@ build_method_call (instance, name, parms, basetype_path, flags)
                         convert_arguments (NULL_TREE, TREE_CHAIN (TYPE_ARG_TYPES (fntype)), TREE_CHAIN (parms), function, LOOKUP_NORMAL));
     }
 
-#if 0
-  /* Constructors do not overload method calls.  */
-  else if (TYPE_OVERLOADS_METHOD_CALL_EXPR (basetype)
-          && name != TYPE_IDENTIFIER (basetype)
-          && (TREE_CODE (function) != FUNCTION_DECL
-              || strncmp (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (function)),
-                          OPERATOR_METHOD_FORMAT,
-                          OPERATOR_METHOD_LENGTH))
-          && (may_be_remote (basetype) || instance != C_C_D))
-    {
-      tree fn_as_int;
-
-      parms = TREE_CHAIN (parms);
-
-      if (!all_virtual && TREE_CODE (function) == FUNCTION_DECL)
-       fn_as_int = build_unary_op (ADDR_EXPR, function, 0);
-      else
-       fn_as_int = convert (TREE_TYPE (default_conversion (function)), DECL_VINDEX (function));
-      if (all_virtual == 1)
-       fn_as_int = convert (integer_type_node, fn_as_int);
-
-      result = build_opfncall (METHOD_CALL_EXPR, LOOKUP_NORMAL, instance, fn_as_int, parms);
-
-      if (result == NULL_TREE)
-       {
-         compiler_error ("could not overload `operator->()(...)'");
-         return error_mark_node;
-       }
-      else if (result == error_mark_node)
-       return error_mark_node;
-
-#if 0
-      /* Do this if we want the result of operator->() to inherit
-        the type of the function it is subbing for.  */
-      TREE_TYPE (result) = value_type;
-#endif
-
-      return result;
-    }
-#endif
+  if (parms == error_mark_node
+      || (parms && TREE_CHAIN (parms) == error_mark_node))
+    return error_mark_node;
 
   if (need_vtbl == needed)
     {
@@ -2627,34 +2606,9 @@ build_method_call (instance, name, parms, basetype_path, flags)
     GNU_xref_call (current_function_decl,
                   IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (function)));
 
-  {
-    int is_constructor;
-    
-    if (TREE_CODE (function) == FUNCTION_DECL)
-      {
-       is_constructor = DECL_CONSTRUCTOR_P (function);
-       if (DECL_INLINE (function))
-         function = build1 (ADDR_EXPR, build_pointer_type (fntype), function);
-       else
-         {
-           assemble_external (function);
-           TREE_USED (function) = 1;
-           function = default_conversion (function);
-         }
-      }
-    else
-      {
-       is_constructor = 0;
-       function = default_conversion (function);
-      }
-
-    result = build_nt (CALL_EXPR, function, parms, NULL_TREE);
-
-    TREE_TYPE (result) = value_type;
-    TREE_SIDE_EFFECTS (result) = 1;
-    TREE_HAS_CONSTRUCTOR (result) = is_constructor;
-    return result;
-  }
+  result = build_call (function, value_type, parms);
+  result = convert_from_reference (result);
+  return result;
 }
 
 /* Similar to `build_method_call', but for overloaded non-member functions.
@@ -2678,15 +2632,15 @@ build_method_call (instance, name, parms, basetype_path, flags)
    function's new name.  */
 
 tree
-build_overload_call_real (fnname, parms, flags, final_cp, buildxxx)
+build_overload_call_real (fnname, parms, flags, final_cp, require_complete)
      tree fnname, parms;
      int flags;
      struct candidate *final_cp;
-     int buildxxx;
+     int require_complete;
 {
   /* must check for overloading here */
-  tree overload_name, functions, function, parm;
-  tree parmtypes = NULL_TREE, last = NULL_TREE;
+  tree functions, function, parm;
+  tree parmtypes, last;
   register tree outer;
   int length;
   int parmlength = list_length (parms);
@@ -2702,31 +2656,14 @@ build_overload_call_real (fnname, parms, flags, final_cp, buildxxx)
       final_cp[1].h.code = EVIL_CODE;
     }
 
-  for (parm = parms; parm; parm = TREE_CHAIN (parm))
+  parmtypes = default_parm_conversions (parms, &last);
+  if (parmtypes == error_mark_node)
     {
-      register tree t = TREE_TYPE (TREE_VALUE (parm));
-
-      if (t == error_mark_node)
-       {
-         if (final_cp)
-           final_cp->h.code = EVIL_CODE;
-         return error_mark_node;
-       }
-      if (TREE_CODE (t) == OFFSET_TYPE)
-#if 0
-      /* This breaks reference-to-array parameters.  */
-         || TREE_CODE (t) == ARRAY_TYPE
-#endif
-       {
-         /* Perform the conversion from ARRAY_TYPE to POINTER_TYPE in place.
-            Also convert OFFSET_TYPE entities to their normal selves.
-            This eliminates needless calls to `compute_conversion_costs'.  */
-         TREE_VALUE (parm) = default_conversion (TREE_VALUE (parm));
-         t = TREE_TYPE (TREE_VALUE (parm));
-       }
-      last = build_tree_list (NULL_TREE, t);
-      parmtypes = chainon (parmtypes, last);
+      if (final_cp)
+       final_cp->h.code = EVIL_CODE;
+      return error_mark_node;
     }
+
   if (last)
     TREE_CHAIN (last) = void_list_node;
   else
@@ -2806,7 +2743,6 @@ build_overload_call_real (fnname, parms, flags, final_cp, buildxxx)
       function = outer;
       if (TREE_CODE (function) != FUNCTION_DECL
          && ! (TREE_CODE (function) == TEMPLATE_DECL
-               && ! DECL_TEMPLATE_IS_CLASS (function)
                && TREE_CODE (DECL_TEMPLATE_RESULT (function)) == FUNCTION_DECL))
        {
          enum tree_code code = TREE_CODE (function);
@@ -2844,7 +2780,11 @@ build_overload_call_real (fnname, parms, flags, final_cp, buildxxx)
                                TYPE_ARG_TYPES (TREE_TYPE (function)),
                                parms, &template_cost, 0);
          if (i == 0)
-           function = instantiate_template (function, targs);
+           {
+             function = instantiate_template (function, targs);
+             if (function == error_mark_node)
+               return function;
+           }
        }
 
       if (TREE_CODE (function) == TEMPLATE_DECL)
@@ -2899,8 +2839,7 @@ build_overload_call_real (fnname, parms, flags, final_cp, buildxxx)
       if (cp - candidates > 1)
        {
          struct candidate *best_cp
-           = ideal_candidate (NULL_TREE, candidates,
-                              cp - candidates, parms, parmlength);
+           = ideal_candidate (candidates, cp - candidates, parmlength);
          if (best_cp == (struct candidate *)0)
            {
              if (flags & LOOKUP_COMPLAIN)
@@ -2928,8 +2867,7 @@ build_overload_call_real (fnname, parms, flags, final_cp, buildxxx)
       if (final_cp)
        return rval;
 
-      return buildxxx ? build_function_call_real (rval, parms, 0, flags)
-        : build_function_call_real (rval, parms, 1, flags);
+      return build_function_call_real (rval, parms, require_complete, flags);
     }
 
   if (flags & LOOKUP_SPECULATIVELY)
@@ -2942,20 +2880,11 @@ build_overload_call_real (fnname, parms, flags, final_cp, buildxxx)
   return error_mark_node;
 }
 
+/* This requires a complete type on the result of the call.  */
 tree
-build_overload_call (fnname, parms, flags, final_cp)
+build_overload_call (fnname, parms, flags)
      tree fnname, parms;
      int flags;
-     struct candidate *final_cp;
-{
-  return build_overload_call_real (fnname, parms, flags, final_cp, 0);
-}
-
-tree
-build_overload_call_maybe (fnname, parms, flags, final_cp)
-     tree fnname, parms;
-     int flags;
-     struct candidate *final_cp;
 {
-  return build_overload_call_real (fnname, parms, flags, final_cp, 1);
+  return build_overload_call_real (fnname, parms, flags, (struct candidate *)0, 1);
 }