86th Cygnus<->FSF quick merge
[gcc.git] / gcc / cp / call.c
index 3f293ac809b3c2d6f4117f9b68aef8a72fa57b84..c9d3f8802abbd4251177748419c5a1d18b71386e 100644 (file)
@@ -38,15 +38,11 @@ Boston, MA 02111-1307, 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))
@@ -175,8 +171,8 @@ convert_harshness (type, parmtype, parm)
       if (! lvalue && ! (parm && TYPE_READONLY (ttl)))
        return EVIL_RETURN (h);
 
-      if (TYPE_READONLY (ttl) < constp
-         || TYPE_VOLATILE (ttl) < volatilep)
+      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
@@ -232,10 +228,10 @@ convert_harshness (type, parmtype, parm)
          tree ttl = TYPE_METHOD_BASETYPE (type);
          tree ttr = TYPE_METHOD_BASETYPE (parmtype);
 
-         int b_or_d = get_base_distance (ttr, ttl, 0, 0);
+         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, 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;
@@ -365,10 +361,10 @@ convert_harshness (type, parmtype, parm)
        h.code = 0;
       else
        {
-         int b_or_d = get_base_distance (ttr, ttl, 0, 0);
+         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, 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;
@@ -433,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;
@@ -475,10 +464,6 @@ convert_harshness (type, parmtype, parm)
     }
 
   /* Convert arrays which have not previously been converted.  */
-#if 0
-  if (codel == ARRAY_TYPE)
-    codel = POINTER_TYPE;
-#endif
   if (coder == ARRAY_TYPE)
     {
       coder = POINTER_TYPE;
@@ -521,12 +506,6 @@ convert_harshness (type, parmtype, parm)
       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 (type, parmtype, 1) <= 0)
            return EVIL_RETURN (h);
        }
@@ -541,22 +520,18 @@ convert_harshness (type, parmtype, parm)
        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;
@@ -566,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;
@@ -595,8 +570,11 @@ convert_harshness (type, parmtype, parm)
       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)))
+         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;
@@ -626,10 +604,10 @@ convert_harshness (type, parmtype, parm)
 
   if (codel == RECORD_TYPE && coder == RECORD_TYPE)
     {
-      int b_or_d = get_base_distance (type, parmtype, 0, 0);
+      int b_or_d = get_base_distance (type, parmtype, 0, (tree*)0);
       if (b_or_d < 0)
        {
-         b_or_d = get_base_distance (parmtype, type, 0, 0);
+         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;
@@ -646,9 +624,8 @@ convert_harshness (type, parmtype, parm)
    overload resolution.  */
 
 int
-user_harshness (type, parmtype, parm)
+user_harshness (type, parmtype)
      register tree type, parmtype;
-     tree parm;
 {
   tree conv;
   tree winner = NULL_TREE;
@@ -663,18 +640,19 @@ user_harshness (type, parmtype, parm)
   for (conv = lookup_conversions (parmtype); conv; conv = TREE_CHAIN (conv))
     {
       struct harshness_code tmp;
+      tree cand = TREE_VALUE (conv);
 
-      if (winner && TREE_PURPOSE (winner) == TREE_PURPOSE (conv))
+      if (winner && winner == cand)
        continue;
 
-      if (tmp = convert_harshness (type, TREE_VALUE (conv), NULL_TREE),
-         tmp.code < USER_CODE && tmp.distance >= 0)
+      tmp = convert_harshness (type, TREE_TYPE (TREE_TYPE (cand)), NULL_TREE);
+      if ((tmp.code < USER_CODE) && (tmp.distance >= 0))
        {
          if (winner)
            return EVIL_CODE;
          else
            {
-             winner = conv;
+             winner = cand;
              code = tmp.code;
            }
        }
@@ -692,7 +670,7 @@ can_convert (to, from)
 {
   struct harshness_code h;
   h = convert_harshness (to, from, NULL_TREE);
-  return h.code < USER_CODE && h.distance >= 0;
+  return (h.code < USER_CODE) && (h.distance >= 0);
 }
 
 int
@@ -701,7 +679,7 @@ can_convert_arg (to, from, arg)
 {
   struct harshness_code h;
   h = convert_harshness (to, from, arg);
-  return h.code < USER_CODE && h.distance >= 0;
+  return (h.code < USER_CODE) && (h.distance >= 0);
 }
 
 #ifdef DEBUG_MATCHING
@@ -1091,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;
@@ -1107,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))
@@ -1223,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;
@@ -1237,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.  */
@@ -1253,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;
 
@@ -1266,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;
@@ -1341,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);
       }
 
@@ -1461,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',
@@ -1470,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);
@@ -1486,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))
@@ -1516,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
@@ -1572,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.
@@ -1610,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;
@@ -1639,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)
@@ -1658,6 +1715,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
     }
   /* 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;
 
@@ -1670,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",
@@ -1732,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
        {
@@ -1745,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
            {
@@ -1765,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.  */
@@ -1791,8 +1854,8 @@ build_method_call (instance, name, parms, basetype_path, flags)
        }
       else
        {
-         instance = C_C_D;
-         instance_ptr = current_class_decl;
+         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);
@@ -1886,7 +1949,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
              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);
@@ -1944,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);
@@ -1953,44 +2019,10 @@ 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 && IS_SIGNATURE (basetype))
@@ -2033,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);
@@ -2080,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;
@@ -2100,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)
@@ -2135,7 +2152,8 @@ build_method_call (instance, name, parms, basetype_path, flags)
              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.  */
@@ -2155,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
@@ -2171,30 +2189,6 @@ build_method_call (instance, name, parms, basetype_path, flags)
            basetype_path = TREE_VALUE (basetype_path);
          basetype = BINFO_TYPE (basetype_path);
 
-#if 0
-         /* 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;
-#endif
-
-         if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (function)))
-           function = DECL_CHAIN (function);
-
          for (; function; function = DECL_CHAIN (function))
            {
 #ifdef GATHER_STATISTICS
@@ -2209,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;
@@ -2251,14 +2239,8 @@ build_method_call (instance, name, parms, basetype_path, flags)
                    }
                }
            }
-         /* 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);
@@ -2282,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;
@@ -2303,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;
@@ -2333,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
@@ -2378,7 +2359,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
                  TREE_CHAIN (last) = void_list_node;
                  cp_error ("no matching function for call to `%T::%D (%A)%V'",
                            TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (instance_ptr))),
-                           name, TREE_CHAIN (parmtypes),
+                           save_name, TREE_CHAIN (parmtypes),
                            TREE_TYPE (TREE_TYPE (instance_ptr)));
                  TREE_CHAIN (last) = NULL_TREE;
                  print_candidates (found_fns);
@@ -2391,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;
@@ -2421,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)
        {
@@ -2432,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)
        {
@@ -2448,36 +2429,36 @@ 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 1
   /* Is it a synthesized method that needs to be synthesized?  */
-  if (DECL_ARTIFICIAL (function) && ! flag_no_inline
-      && ! DECL_INITIAL (function)
+  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_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);
@@ -2505,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
@@ -2535,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);
@@ -2549,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);
@@ -2608,47 +2591,6 @@ 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;
@@ -2664,29 +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);
-       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;
-    result = convert_from_reference (result);
-    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.
@@ -2710,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);
@@ -2734,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
@@ -2838,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);
@@ -2876,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)
@@ -2931,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)
@@ -2960,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)
@@ -2974,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);
 }