OSDN Git Service

* g++.old-deja/g++.benjamin/16077.C: Adjust warnings.
[pf3gnuchains/gcc-fork.git] / gcc / cp / call.c
index 1b79ac4..ed9227f 100644 (file)
@@ -1,23 +1,23 @@
 /* Functions related to invoking methods and overloaded functions.
-   Copyright (C) 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+   Copyright (C) 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 
+   1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
    Contributed by Michael Tiemann (tiemann@cygnus.com) and
    modified by Brendan Kehoe (brendan@cygnus.com).
 
-This file is part of GNU CC.
+This file is part of GCC.
 
-GNU CC is free software; you can redistribute it and/or modify
+GCC is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2, or (at your option)
 any later version.
 
-GNU CC is distributed in the hope that it will be useful,
+GCC is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 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
+along with GCC; see the file COPYING.  If not, write to
 the Free Software Foundation, 59 Temple Place - Suite 330,
 Boston, MA 02111-1307, USA.  */
 
@@ -26,6 +26,8 @@ Boston, MA 02111-1307, USA.  */
 
 #include "config.h"
 #include "system.h"
+#include "coretypes.h"
+#include "tm.h"
 #include "tree.h"
 #include "cp-tree.h"
 #include "output.h"
@@ -33,79 +35,81 @@ Boston, MA 02111-1307, USA.  */
 #include "rtl.h"
 #include "toplev.h"
 #include "expr.h"
-#include "ggc.h"
 #include "diagnostic.h"
 
 extern int inhibit_warnings;
 
-static tree build_field_call PARAMS ((tree, tree, tree));
-static struct z_candidate * tourney PARAMS ((struct z_candidate *));
-static int equal_functions PARAMS ((tree, tree));
-static int joust PARAMS ((struct z_candidate *, struct z_candidate *, int));
-static int compare_ics PARAMS ((tree, tree));
-static tree build_over_call PARAMS ((struct z_candidate *, tree, int));
-static tree build_java_interface_fn_ref PARAMS ((tree, tree));
+static tree build_field_call (tree, tree, tree);
+static struct z_candidate * tourney (struct z_candidate *);
+static int equal_functions (tree, tree);
+static int joust (struct z_candidate *, struct z_candidate *, bool);
+static int compare_ics (tree, tree);
+static tree build_over_call (struct z_candidate *, int);
+static tree build_java_interface_fn_ref (tree, tree);
 #define convert_like(CONV, EXPR) \
   convert_like_real ((CONV), (EXPR), NULL_TREE, 0, 0)
 #define convert_like_with_context(CONV, EXPR, FN, ARGNO) \
   convert_like_real ((CONV), (EXPR), (FN), (ARGNO), 0)
-static tree convert_like_real PARAMS ((tree, tree, tree, int, int));
-static void op_error PARAMS ((enum tree_code, enum tree_code, tree, tree,
-                           tree, const char *));
-static tree build_object_call PARAMS ((tree, tree));
-static tree resolve_args PARAMS ((tree));
-static struct z_candidate * build_user_type_conversion_1
-       PARAMS ((tree, tree, int));
-static void print_z_candidates PARAMS ((struct z_candidate *));
-static tree build_this PARAMS ((tree));
-static struct z_candidate * splice_viable PARAMS ((struct z_candidate *));
-static int any_viable PARAMS ((struct z_candidate *));
-static int any_strictly_viable PARAMS ((struct z_candidate *));
-static struct z_candidate * add_template_candidate
-       PARAMS ((struct z_candidate *, tree, tree, tree, tree, tree, 
-                tree, tree, int, unification_kind_t));
-static struct z_candidate * add_template_candidate_real
-       PARAMS ((struct z_candidate *, tree, tree, tree, tree, tree, 
-                tree, tree, int, tree, unification_kind_t));
-static struct z_candidate * add_template_conv_candidate 
-        PARAMS ((struct z_candidate *, tree, tree, tree, tree, tree, tree));
-static struct z_candidate * add_builtin_candidates
-       PARAMS ((struct z_candidate *, enum tree_code, enum tree_code,
-              tree, tree *, int));
-static struct z_candidate * add_builtin_candidate
-       PARAMS ((struct z_candidate *, enum tree_code, enum tree_code,
-              tree, tree, tree, tree *, tree *, int));
-static int is_complete PARAMS ((tree));
-static struct z_candidate * build_builtin_candidate 
-       PARAMS ((struct z_candidate *, tree, tree, tree, tree *, tree *,
-              int));
-static struct z_candidate * add_conv_candidate 
-       PARAMS ((struct z_candidate *, tree, tree, tree, tree, tree));
-static struct z_candidate * add_function_candidate 
-       (struct z_candidate *, tree, tree, tree, tree, tree, int);
-static tree implicit_conversion PARAMS ((tree, tree, tree, int));
-static tree standard_conversion PARAMS ((tree, tree, tree));
-static tree reference_binding PARAMS ((tree, tree, tree, int));
-static tree non_reference PARAMS ((tree));
-static tree build_conv PARAMS ((enum tree_code, tree, tree));
-static int is_subseq PARAMS ((tree, tree));
-static tree maybe_handle_ref_bind PARAMS ((tree*));
-static void maybe_handle_implicit_object PARAMS ((tree*));
+static tree convert_like_real (tree, tree, tree, int, int);
+static void op_error (enum tree_code, enum tree_code, tree, tree,
+                           tree, const char *);
+static tree build_object_call (tree, tree);
+static tree resolve_args (tree);
+static struct z_candidate *build_user_type_conversion_1 (tree, tree, int);
+static void print_z_candidates (struct z_candidate *);
+static tree build_this (tree);
+static struct z_candidate *splice_viable (struct z_candidate *);
+static bool any_viable (struct z_candidate *);
+static bool any_strictly_viable (struct z_candidate *);
+static struct z_candidate *add_template_candidate
+        (struct z_candidate **, tree, tree, tree, tree, tree, 
+         tree, tree, int, unification_kind_t);
+static struct z_candidate *add_template_candidate_real
+       (struct z_candidate **, tree, tree, tree, tree, tree, 
+           tree, tree, int, tree, unification_kind_t);
+static struct z_candidate *add_template_conv_candidate 
+        (struct z_candidate **, tree, tree, tree, tree, tree, tree);
+static void add_builtin_candidates
+       (struct z_candidate **, enum tree_code, enum tree_code,
+              tree, tree *, int);
+static void add_builtin_candidate
+       (struct z_candidate **, enum tree_code, enum tree_code,
+              tree, tree, tree, tree *, tree *, int);
+static bool is_complete (tree);
+static void build_builtin_candidate 
+       (struct z_candidate **, tree, tree, tree, tree *, tree *,
+              int);
+static struct z_candidate *add_conv_candidate 
+       (struct z_candidate **, tree, tree, tree, tree, tree);
+static struct z_candidate *add_function_candidate 
+       (struct z_candidate **, tree, tree, tree, tree, tree, int);
+static tree implicit_conversion (tree, tree, tree, int);
+static tree standard_conversion (tree, tree, tree);
+static tree reference_binding (tree, tree, tree, int);
+static tree non_reference (tree);
+static tree build_conv (enum tree_code, tree, tree);
+static bool is_subseq (tree, tree);
+static tree maybe_handle_ref_bind (tree *);
+static void maybe_handle_implicit_object (tree *);
 static struct z_candidate *add_candidate 
-        (struct z_candidate *, tree, tree, tree, tree, int);
-static tree source_type PARAMS ((tree));
-static void add_warning PARAMS ((struct z_candidate *, struct z_candidate *));
-static int reference_related_p PARAMS ((tree, tree));
-static int reference_compatible_p PARAMS ((tree, tree));
-static tree convert_class_to_reference PARAMS ((tree, tree, tree));
-static tree direct_reference_binding PARAMS ((tree, tree));
-static int promoted_arithmetic_type_p PARAMS ((tree));
-static tree conditional_conversion PARAMS ((tree, tree));
-static tree call_builtin_trap PARAMS ((void));
+        (struct z_candidate **, tree, tree, tree, tree, tree, int);
+static tree source_type (tree);
+static void add_warning (struct z_candidate *, struct z_candidate *);
+static bool reference_related_p (tree, tree);
+static bool reference_compatible_p (tree, tree);
+static tree convert_class_to_reference (tree, tree, tree);
+static tree direct_reference_binding (tree, tree);
+static bool promoted_arithmetic_type_p (tree);
+static tree conditional_conversion (tree, tree);
+static char *name_as_c_string (tree, tree, bool *);
+static tree call_builtin_trap (void);
+static tree prep_operand (tree);
+static void add_candidates (tree, tree, tree, bool, tree, tree,
+                           int, struct z_candidate **);
+static tree merge_conversion_sequences (tree, tree);
 
 tree
-build_vfield_ref (datum, type)
-     tree datum, type;
+build_vfield_ref (tree datum, tree type)
 {
   if (datum == error_mark_node)
     return error_mark_node;
@@ -145,8 +149,8 @@ build_field_call (tree instance_ptr, tree decl, tree parms)
        return error_mark_node;
 
       if (IS_AGGR_TYPE (TREE_TYPE (instance)))
-       return build_opfncall (CALL_EXPR, LOOKUP_NORMAL,
-                              instance, parms, NULL_TREE);
+       return build_new_op (CALL_EXPR, LOOKUP_NORMAL,
+                            instance, parms, NULL_TREE);
       else if (TREE_CODE (TREE_TYPE (instance)) == FUNCTION_TYPE
               || (TREE_CODE (TREE_TYPE (instance)) == POINTER_TYPE
                   && (TREE_CODE (TREE_TYPE (TREE_TYPE (instance)))
@@ -161,15 +165,14 @@ build_field_call (tree instance_ptr, tree decl, tree parms)
    (a BIT_NOT_EXPR) matches BASETYPE.  The operand of NAME can take many
    forms...  */
 
-int
-check_dtor_name (basetype, name)
-     tree basetype, name;
+bool
+check_dtor_name (tree basetype, tree name)
 {
   name = TREE_OPERAND (name, 0);
 
   /* Just accept something we've already complained about.  */
   if (name == error_mark_node)
-    return 1;
+    return true;
 
   if (TREE_CODE (name) == TYPE_DECL)
     name = TREE_TYPE (name);
@@ -192,21 +195,20 @@ check_dtor_name (basetype, name)
 
      NAME will be a class template.  */
   else if (DECL_CLASS_TEMPLATE_P (name))
-    return 0;
+    return false;
   else
     abort ();
 
   if (name && TYPE_MAIN_VARIANT (basetype) == TYPE_MAIN_VARIANT (name))
-    return 1;
-  return 0;
+    return true;
+  return false;
 }
 
 /* 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, basetype, name, parms)
-     tree exp, basetype, name, parms;
+build_scoped_method_call (tree exp, tree basetype, tree name, tree parms)
 {
   /* Because this syntactic form does not allow
      a pointer to a base class to be `stolen',
@@ -223,13 +225,6 @@ build_scoped_method_call (exp, basetype, name, parms)
 
   if (processing_template_decl)
     {
-      if (TREE_CODE (name) == BIT_NOT_EXPR
-         && TREE_CODE (TREE_OPERAND (name, 0)) == IDENTIFIER_NODE)
-       {
-         tree type = get_aggr_from_typedef (TREE_OPERAND (name, 0), 0);
-         if (type)
-           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);
     }
@@ -313,8 +308,7 @@ build_scoped_method_call (exp, basetype, name, parms)
    pointer-to-member function.  */
 
 tree
-build_addr_func (function)
-     tree function;
+build_addr_func (tree function)
 {
   tree type = TREE_TYPE (function);
 
@@ -349,8 +343,7 @@ build_addr_func (function)
    (TYPE_PTRMEMFUNC_P) must be handled by our callers.  */
 
 tree
-build_call (function, parms)
-     tree function, parms;
+build_call (tree function, tree parms)
 {
   int is_constructor = 0;
   int nothrow;
@@ -462,9 +455,8 @@ extern int n_build_method_call;
 #endif
 
 tree
-build_method_call (instance, name, parms, basetype_path, flags)
-     tree instance, name, parms, basetype_path;
-     int flags;
+build_method_call (tree instance, tree name, tree parms,
+                   tree basetype_path, int flags)
 {
   tree fn;
   tree object_type;
@@ -482,24 +474,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
     return error_mark_node;
 
   if (processing_template_decl)
-    {
-      /* We need to process template parm names here so that tsubst catches
-        them properly.  Other type names can wait.  */
-      if (TREE_CODE (name) == BIT_NOT_EXPR)
-       {
-         tree type = NULL_TREE;
-
-         if (TREE_CODE (TREE_OPERAND (name, 0)) == IDENTIFIER_NODE)
-           type = get_aggr_from_typedef (TREE_OPERAND (name, 0), 0);
-         else if (TREE_CODE (TREE_OPERAND (name, 0)) == TYPE_DECL)
-           type = TREE_TYPE (TREE_OPERAND (name, 0));
-
-         if (type && TREE_CODE (type) == TEMPLATE_TYPE_PARM)
-           name = build_min_nt (BIT_NOT_EXPR, type);
-       }
-
-      return build_min_nt (METHOD_CALL_EXPR, name, instance, parms, NULL_TREE);
-    }
+    return build_min_nt (METHOD_CALL_EXPR, name, instance, parms, NULL_TREE);
 
   if (TREE_CODE (instance) == OFFSET_REF)
     instance = resolve_offset_ref (instance);
@@ -550,7 +525,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
   if (has_template_args)
     fn = lookup_fnfields (object_type, name, /*protect=*/2);
   else
-    fn = lookup_member (object_type, name, /*protect=*/2, /*want_type=*/0);
+    fn = lookup_member (object_type, name, /*protect=*/2, /*want_type=*/false);
   
   if (fn && TREE_CODE (fn) == TREE_LIST && !BASELINK_P (fn))
     {
@@ -584,7 +559,14 @@ struct z_candidate GTY(()) {
   /* The FUNCTION_DECL that will be called if this candidate is
      selected by overload resolution.  */
   tree fn;
+  /* The arguments to use when calling this function.  */
+  tree args;
+  /* The implicit conversion sequences for each of the arguments to
+     FN.  */
   tree convs;
+  /* If FN is a user-defined conversion, the standard conversion
+     sequence from the type returned by FN to the desired destination
+     type.  */
   tree second_conv;
   int viable;
   /* If FN is a member function, the binfo indicating the path used to
@@ -633,9 +615,8 @@ struct z_candidate GTY(()) {
 #define USER_CONV_CAND(NODE) WRAPPER_ZC (TREE_OPERAND (NODE, 1))
 #define USER_CONV_FN(NODE) (USER_CONV_CAND (NODE)->fn)
 
-int
-null_ptr_cst_p (t)
-     tree t;
+bool
+null_ptr_cst_p (tree t)
 {
   /* [conv.ptr]
 
@@ -643,29 +624,26 @@ null_ptr_cst_p (t)
      (_expr.const_) rvalue of integer type that evaluates to zero.  */
   if (t == null_node
       || (CP_INTEGRAL_TYPE_P (TREE_TYPE (t)) && integer_zerop (t)))
-    return 1;
-  return 0;
+    return true;
+  return false;
 }
 
 
 /* Returns nonzero if PARMLIST consists of only default parms and/or
    ellipsis.  */
 
-int
-sufficient_parms_p (parmlist)
-     tree parmlist;
+bool
+sufficient_parms_p (tree parmlist)
 {
   for (; parmlist && parmlist != void_list_node;
        parmlist = TREE_CHAIN (parmlist))
     if (!TREE_PURPOSE (parmlist))
-      return 0;
-  return 1;
+      return false;
+  return true;
 }
 
 static tree
-build_conv (code, type, from)
-     enum tree_code code;
-     tree type, from;
+build_conv (enum tree_code code, tree type, tree from)
 {
   tree t;
   int rank = ICS_STD_RANK (from);
@@ -695,7 +673,7 @@ build_conv (code, type, from)
       break;
     }
   ICS_STD_RANK (t) = rank;
-  ICS_USER_FLAG (t) = ICS_USER_FLAG (from);
+  ICS_USER_FLAG (t) = (code == USER_CONV || ICS_USER_FLAG (from));
   ICS_BAD_FLAG (t) = ICS_BAD_FLAG (from);
   return t;
 }
@@ -704,8 +682,7 @@ build_conv (code, type, from)
    Otherwise, return T itself.  */
 
 static tree
-non_reference (t)
-     tree t;
+non_reference (tree t)
 {
   if (TREE_CODE (t) == REFERENCE_TYPE)
     t = TREE_TYPE (t);
@@ -713,8 +690,7 @@ non_reference (t)
 }
 
 tree
-strip_top_quals (t)
-     tree t;
+strip_top_quals (tree t)
 {
   if (TREE_CODE (t) == ARRAY_TYPE)
     return t;
@@ -726,18 +702,17 @@ strip_top_quals (t)
    also pass the expression EXPR to convert from.  */
 
 static tree
-standard_conversion (to, from, expr)
-     tree to, from, expr;
+standard_conversion (tree to, tree from, tree expr)
 {
   enum tree_code fcode, tcode;
   tree conv;
-  int fromref = 0;
+  bool fromref = false;
 
   if (TREE_CODE (to) == REFERENCE_TYPE)
     to = TREE_TYPE (to);
   if (TREE_CODE (from) == REFERENCE_TYPE)
     {
-      fromref = 1;
+      fromref = true;
       from = TREE_TYPE (from);
     }
   to = strip_top_quals (to);
@@ -941,10 +916,8 @@ standard_conversion (to, from, expr)
 
 /* Returns nonzero if T1 is reference-related to T2.  */
 
-static int
-reference_related_p (t1, t2)
-     tree t1;
-     tree t2;
+static bool
+reference_related_p (tree t1, tree t2)
 {
   t1 = TYPE_MAIN_VARIANT (t1);
   t2 = TYPE_MAIN_VARIANT (t2);
@@ -961,10 +934,8 @@ reference_related_p (t1, t2)
 
 /* Returns nonzero if T1 is reference-compatible with T2.  */
 
-static int
-reference_compatible_p (t1, t2)
-     tree t1;
-     tree t2;
+static bool
+reference_compatible_p (tree t1, tree t2)
 {
   /* [dcl.init.ref]
 
@@ -979,17 +950,19 @@ reference_compatible_p (t1, t2)
    converted to T as in [over.match.ref].  */
 
 static tree
-convert_class_to_reference (t, s, expr)
-     tree t;
-     tree s;
-     tree expr;
+convert_class_to_reference (tree t, tree s, tree expr)
 {
   tree conversions;
   tree arglist;
   tree conv;
+  tree reference_type;
   struct z_candidate *candidates;
   struct z_candidate *cand;
 
+  conversions = lookup_conversions (s);
+  if (!conversions)
+    return NULL_TREE;
+
   /* [over.match.ref]
 
      Assuming that "cv1 T" is the underlying type of the reference
@@ -1015,10 +988,10 @@ convert_class_to_reference (t, s, expr)
   arglist = build_int_2 (0, 0);
   TREE_TYPE (arglist) = build_pointer_type (s);
   arglist = build_tree_list (NULL_TREE, arglist);
-  
-  for (conversions = lookup_conversions (s);
-       conversions;
-       conversions = TREE_CHAIN (conversions))
+
+  reference_type = build_reference_type (t);
+
+  while (conversions)
     {
       tree fns = TREE_VALUE (conversions);
 
@@ -1026,44 +999,58 @@ convert_class_to_reference (t, s, expr)
        {
          tree f = OVL_CURRENT (fns);
          tree t2 = TREE_TYPE (TREE_TYPE (f));
-         struct z_candidate *old_candidates = candidates;
+         
+         cand = NULL;
 
          /* If this is a template function, try to get an exact
              match.  */
          if (TREE_CODE (f) == TEMPLATE_DECL)
            {
-             candidates 
-               = add_template_candidate (candidates,
-                                         f, s,
-                                         NULL_TREE,
-                                         arglist,
-                                         build_reference_type (t),
-                                         TYPE_BINFO (s),
-                                         TREE_PURPOSE (conversions),
-                                         LOOKUP_NORMAL,
-                                         DEDUCE_CONV);
+             cand = add_template_candidate (&candidates,
+                                            f, s,
+                                            NULL_TREE,
+                                            arglist,
+                                            reference_type,
+                                            TYPE_BINFO (s),
+                                            TREE_PURPOSE (conversions),
+                                            LOOKUP_NORMAL,
+                                            DEDUCE_CONV);
              
-             if (candidates != old_candidates)
+             if (cand)
                {
                  /* Now, see if the conversion function really returns
                     an lvalue of the appropriate type.  From the
                     point of view of unification, simply returning an
                     rvalue of the right type is good enough.  */
-                 f = candidates->fn;
+                 f = cand->fn;
                  t2 = TREE_TYPE (TREE_TYPE (f));
                  if (TREE_CODE (t2) != REFERENCE_TYPE
                      || !reference_compatible_p (t, TREE_TYPE (t2)))
-                   candidates = candidates->next;
+                   {
+                     candidates = candidates->next;
+                     cand = NULL;
+                   }
                }
            }
          else if (TREE_CODE (t2) == REFERENCE_TYPE
                   && reference_compatible_p (t, TREE_TYPE (t2)))
-           candidates 
-             = add_function_candidate (candidates, f, s, arglist, 
-                                       TYPE_BINFO (s),         
-                                       TREE_PURPOSE (conversions),
-                                       LOOKUP_NORMAL);
+           cand = add_function_candidate (&candidates, f, s, arglist, 
+                                          TYPE_BINFO (s),      
+                                          TREE_PURPOSE (conversions),
+                                          LOOKUP_NORMAL);
+         
+         if (cand)
+           /* Build a standard conversion sequence indicating the
+              binding from the reference type returned by the
+              function to the desired REFERENCE_TYPE.  */
+           cand->second_conv
+             = (direct_reference_binding 
+                (reference_type, 
+                 build1 (IDENTITY_CONV, 
+                         TREE_TYPE (TREE_TYPE (TREE_TYPE (cand->fn))),
+                         NULL_TREE)));
        }
+      conversions = TREE_CHAIN (conversions);
     }
 
   /* If none of the conversion functions worked out, let our caller
@@ -1076,16 +1063,27 @@ convert_class_to_reference (t, s, expr)
   if (!cand)
     return NULL_TREE;
 
-  conv = build1 (IDENTITY_CONV, s, expr);
-  conv = build_conv (USER_CONV, TREE_TYPE (TREE_TYPE (cand->fn)),
-                    conv);
+  /* Now that we know that this is the function we're going to use fix
+     the dummy first argument.  */
+  cand->args = tree_cons (NULL_TREE,
+                         build_this (expr),
+                         TREE_CHAIN (cand->args));
+
+  /* Build a user-defined conversion sequence representing the
+     conversion.  */
+  conv = build_conv (USER_CONV,
+                    TREE_TYPE (TREE_TYPE (cand->fn)),
+                    build1 (IDENTITY_CONV, TREE_TYPE (expr), expr));
   TREE_OPERAND (conv, 1) = build_zc_wrapper (cand);
-  ICS_USER_FLAG (conv) = 1;
+
+  /* Merge it with the standard conversion sequence from the
+     conversion function's return type to the desired type.  */
+  cand->second_conv = merge_conversion_sequences (conv, cand->second_conv);
+
   if (cand->viable == -1)
     ICS_BAD_FLAG (conv) = 1;
-  cand->second_conv = conv;
-
-  return conv;
+  
+  return cand->second_conv;
 }
 
 /* A reference of the indicated TYPE is being bound directly to the
@@ -1093,11 +1091,15 @@ convert_class_to_reference (t, s, expr)
    Return a conversion sequence for this binding.  */
 
 static tree
-direct_reference_binding (type, conv)
-     tree type;
-     tree conv;
+direct_reference_binding (tree type, tree conv)
 {
-  tree t = TREE_TYPE (type);
+  tree t;
+
+  my_friendly_assert (TREE_CODE (type) == REFERENCE_TYPE, 20030306);
+  my_friendly_assert (TREE_CODE (TREE_TYPE (conv)) != REFERENCE_TYPE,
+                     20030306);
+
+  t = TREE_TYPE (type);
 
   /* [over.ics.rank] 
      
@@ -1134,15 +1136,13 @@ direct_reference_binding (type, conv)
    the conversion returned.  */
 
 static tree
-reference_binding (rto, rfrom, expr, flags)
-     tree rto, rfrom, expr;
-     int flags;
+reference_binding (tree rto, tree rfrom, tree expr, int flags)
 {
   tree conv = NULL_TREE;
   tree to = TREE_TYPE (rto);
   tree from = rfrom;
-  int related_p;
-  int compatible_p;
+  bool related_p;
+  bool compatible_p;
   cp_lvalue_kind lvalue_p = clk_none;
 
   if (TREE_CODE (to) == FUNCTION_TYPE && expr && type_unknown_p (expr))
@@ -1214,7 +1214,7 @@ reference_binding (rto, rfrom, expr, flags)
        in the second case.  */
       conv = convert_class_to_reference (to, from, expr);
       if (conv)
-       return direct_reference_binding (rto, conv);
+       return conv;
     }
 
   /* From this point on, we conceptually need temporaries, even if we
@@ -1248,11 +1248,13 @@ reference_binding (rto, rfrom, expr, flags)
      -- The reference is bound to the object represented by the rvalue
         or to a sub-object within that object.  
 
-     In this case, the implicit conversion sequence is supposed to be
-     same as we would obtain by generating a temporary.  Fortunately,
-     if the types are reference compatible, then this is either an
-     identity conversion or the derived-to-base conversion, just as
-     for direct binding.  */
+     -- ...
+       
+     We use the first alternative.  The implicit conversion sequence
+     is supposed to be same as we would obtain by generating a
+     temporary.  Fortunately, if the types are reference compatible,
+     then this is either an identity conversion or the derived-to-base
+     conversion, just as for direct binding.  */
   if (CLASS_TYPE_P (from) && compatible_p)
     {
       conv = build1 (IDENTITY_CONV, from, expr);
@@ -1287,12 +1289,9 @@ reference_binding (rto, rfrom, expr, flags)
    significant.  */
 
 static tree
-implicit_conversion (to, from, expr, flags)
-     tree to, from, expr;
-     int flags;
+implicit_conversion (tree to, tree from, tree expr, int flags)
 {
   tree conv;
-  struct z_candidate *cand;
 
   /* Resolve expressions like `A::p' that we thought might become
      pointers-to-members.  */
@@ -1317,12 +1316,15 @@ implicit_conversion (to, from, expr, flags)
     conv = standard_conversion (to, from, expr);
 
   if (conv)
-    ;
-  else if (expr != NULL_TREE
-          && (IS_AGGR_TYPE (from)
-              || IS_AGGR_TYPE (to))
-          && (flags & LOOKUP_NO_CONVERSION) == 0)
+    return conv;
+
+  if (expr != NULL_TREE
+      && (IS_AGGR_TYPE (from)
+         || IS_AGGR_TYPE (to))
+      && (flags & LOOKUP_NO_CONVERSION) == 0)
     {
+      struct z_candidate *cand;
+
       cand = build_user_type_conversion_1
        (to, expr, LOOKUP_ONLYCONVERTING);
       if (cand)
@@ -1331,28 +1333,31 @@ implicit_conversion (to, from, expr, flags)
       /* We used to try to bind a reference to a temporary here, but that
         is now handled by the recursive call to this function at the end
         of reference_binding.  */
+      return conv;
     }
 
-  return conv;
+  return NULL_TREE;
 }
 
 /* Add a new entry to the list of candidates.  Used by the add_*_candidate
    functions.  */
 
 static struct z_candidate *
-add_candidate (struct z_candidate *candidates, 
-              tree fn, tree convs, tree access_path, tree
-              conversion_path, int viable)
+add_candidate (struct z_candidate **candidates, 
+              tree fn, tree args, tree convs, tree access_path, 
+              tree conversion_path, int viable)
 {
   struct z_candidate *cand
     = (struct z_candidate *) ggc_alloc_cleared (sizeof (struct z_candidate));
 
   cand->fn = fn;
+  cand->args = args;
   cand->convs = convs;
   cand->access_path = access_path;
   cand->conversion_path = conversion_path;
   cand->viable = viable;
-  cand->next = candidates;
+  cand->next = *candidates;
+  *candidates = cand;
 
   return cand;
 }
@@ -1365,7 +1370,7 @@ add_candidate (struct z_candidate *candidates,
    comes from for purposes of overload resolution.  */
 
 static struct z_candidate *
-add_function_candidate (struct z_candidate *candidates, 
+add_function_candidate (struct z_candidate **candidates, 
                        tree fn, tree ctype, tree arglist, 
                        tree access_path, tree conversion_path,
                        int flags)
@@ -1374,15 +1379,24 @@ add_function_candidate (struct z_candidate *candidates,
   int i, len;
   tree convs;
   tree parmnode, argnode;
+  tree orig_arglist;
   int viable = 1;
 
+  /* Built-in functions that haven't been declared don't really
+     exist.  */
+  if (DECL_ANTICIPATED (fn))
+    return NULL;
+
   /* The `this', `in_chrg' and VTT arguments to constructors are not
      considered in overload resolution.  */
   if (DECL_CONSTRUCTOR_P (fn))
     {
       parmlist = skip_artificial_parms_for (fn, parmlist);
+      orig_arglist = arglist;
       arglist = skip_artificial_parms_for (fn, arglist);
     }
+  else 
+    orig_arglist = arglist;
 
   len = list_length (arglist);
   convs = make_tree_vec (len);
@@ -1480,7 +1494,7 @@ add_function_candidate (struct z_candidate *candidates,
     }
 
  out:
-  return add_candidate (candidates, fn, convs, access_path,
+  return add_candidate (candidates, fn, orig_arglist, convs, access_path,
                        conversion_path, viable);
 }
 
@@ -1496,12 +1510,8 @@ add_function_candidate (struct z_candidate *candidates,
    instead of the function.  */
 
 static struct z_candidate *
-add_conv_candidate (candidates, fn, obj, arglist, access_path,
-                   conversion_path)
-     struct z_candidate *candidates;
-     tree fn, obj, arglist;
-     tree access_path;
-     tree conversion_path;
+add_conv_candidate (struct z_candidate **candidates, tree fn, tree obj,
+                    tree arglist, tree access_path, tree conversion_path)
 {
   tree totype = TREE_TYPE (TREE_TYPE (fn));
   int i, len, viable, flags;
@@ -1519,8 +1529,8 @@ add_conv_candidate (candidates, fn, obj, arglist, access_path,
   flags = LOOKUP_NORMAL;
 
   /* Don't bother looking up the same type twice.  */
-  if (candidates && candidates->fn == totype)
-    return candidates;
+  if (*candidates && (*candidates)->fn == totype)
+    return NULL;
 
   for (i = 0; i < len; ++i)
     {
@@ -1561,17 +1571,14 @@ add_conv_candidate (candidates, fn, obj, arglist, access_path,
   if (!sufficient_parms_p (parmnode))
     viable = 0;
 
-  return add_candidate (candidates, totype, convs, access_path,
+  return add_candidate (candidates, totype, arglist, convs, access_path,
                        conversion_path, viable);
 }
 
-static struct z_candidate *
-build_builtin_candidate (candidates, fnname, type1, type2,
-                        args, argtypes, flags)
-     struct z_candidate *candidates;
-     tree fnname, type1, type2, *args, *argtypes;
-     int flags;
-
+static void
+build_builtin_candidate (struct z_candidate **candidates, tree fnname,
+                         tree type1, tree type2, tree *args, tree *argtypes,
+                         int flags)
 {
   tree t, convs;
   int viable = 1, i;
@@ -1611,24 +1618,22 @@ build_builtin_candidate (candidates, fnname, type1, type2,
        viable = 0;
     }      
 
-  return add_candidate (candidates, fnname, convs, 
-                       /*access_path=*/NULL_TREE,
-                       /*conversion_path=*/NULL_TREE,
-                       viable);
+  add_candidate (candidates, fnname, /*args=*/NULL_TREE, convs, 
+                /*access_path=*/NULL_TREE,
+                /*conversion_path=*/NULL_TREE,
+                viable);
 }
 
-static int
-is_complete (t)
-     tree t;
+static bool
+is_complete (tree t)
 {
   return COMPLETE_TYPE_P (complete_type (t));
 }
 
 /* Returns nonzero if TYPE is a promoted arithmetic type.  */
 
-static int
-promoted_arithmetic_type_p (type)
-     tree type;
+static bool
+promoted_arithmetic_type_p (tree type)
 {
   /* [over.built]
 
@@ -1652,13 +1657,10 @@ promoted_arithmetic_type_p (type)
    of which TYPE1 and TYPE2 are, we add both candidates
    CODE (TYPE1, TYPE1) and CODE (TYPE2, TYPE2).  */
 
-static struct z_candidate *
-add_builtin_candidate (candidates, code, code2, fnname, type1, type2,
-                      args, argtypes, flags)
-     struct z_candidate *candidates;
-     enum tree_code code, code2;
-     tree fnname, type1, type2, *args, *argtypes;
-     int flags;
+static void
+add_builtin_candidate (struct z_candidate **candidates, enum tree_code code,
+                       enum tree_code code2, tree fnname, tree type1,
+                       tree type2, tree *args, tree *argtypes, int flags)
 {
   switch (code)
     {
@@ -1695,7 +1697,7 @@ add_builtin_candidate (candidates, code, code2, fnname, type1, type2,
     case POSTDECREMENT_EXPR:
     case PREDECREMENT_EXPR:
       if (TREE_CODE (type1) == BOOLEAN_TYPE)
-       return candidates;
+       return;
     case POSTINCREMENT_EXPR:
     case PREINCREMENT_EXPR:
       if (ARITHMETIC_TYPE_P (type1) || TYPE_PTROB_P (type1))
@@ -1703,7 +1705,7 @@ add_builtin_candidate (candidates, code, code2, fnname, type1, type2,
          type1 = build_reference_type (type1);
          break;
        }
-      return candidates;
+      return;
 
 /* 7 For every cv-qualified or cv-unqualified complete object type T, there
      exist candidate operator functions of the form
@@ -1719,7 +1721,7 @@ add_builtin_candidate (candidates, code, code2, fnname, type1, type2,
          && (TYPE_PTROB_P (type1)
              || TREE_CODE (TREE_TYPE (type1)) == FUNCTION_TYPE))
        break;
-      return candidates;
+      return
 
 /* 9 For every type T, there exist candidate operator functions of the form
             T*      operator+(T*);
@@ -1736,7 +1738,7 @@ add_builtin_candidate (candidates, code, code2, fnname, type1, type2,
     case NEGATE_EXPR:
       if (ARITHMETIC_TYPE_P (type1))
        break;
-      return candidates;
+      return;
 
 /* 11For every promoted integral type T,  there  exist  candidate  operator
      functions of the form
@@ -1745,7 +1747,7 @@ add_builtin_candidate (candidates, code, code2, fnname, type1, type2,
     case BIT_NOT_EXPR:
       if (INTEGRAL_TYPE_P (type1))
        break;
-      return candidates;
+      return;
 
 /* 12For every quintuple C1, C2, T, CV1, CV2), where C2 is a class type, C1
      is the same type as C2 or is a derived class of C2, T  is  a  complete
@@ -1768,7 +1770,7 @@ add_builtin_candidate (candidates, code, code2, fnname, type1, type2,
                  || is_complete (TREE_TYPE (TREE_TYPE (type2)))))
            break;
        }
-      return candidates;
+      return;
 
 /* 13For every pair of promoted arithmetic types L and R, there exist  can-
      didate operator functions of the form
@@ -1824,7 +1826,7 @@ add_builtin_candidate (candidates, code, code2, fnname, type1, type2,
     case TRUNC_DIV_EXPR:
       if (ARITHMETIC_TYPE_P (type1) && ARITHMETIC_TYPE_P (type2))
        break;
-      return candidates;
+      return;
 
     case EQ_EXPR:
     case NE_EXPR:
@@ -1866,7 +1868,7 @@ add_builtin_candidate (candidates, code, code2, fnname, type1, type2,
          type1 = type2;
          break;
        }
-      return candidates;
+      return;
 
     case PLUS_EXPR:
       if (ARITHMETIC_TYPE_P (type1) && ARITHMETIC_TYPE_P (type2))
@@ -1882,7 +1884,7 @@ add_builtin_candidate (candidates, code, code2, fnname, type1, type2,
          type2 = ptrdiff_type_node;
          break;
        }
-      return candidates;
+      return;
 
 /* 18For  every pair of promoted integral types L and R, there exist candi-
      date operator functions of the form
@@ -1903,7 +1905,7 @@ add_builtin_candidate (candidates, code, code2, fnname, type1, type2,
     case RSHIFT_EXPR:
       if (INTEGRAL_TYPE_P (type1) && INTEGRAL_TYPE_P (type2))
        break;
-      return candidates;
+      return;
 
 /* 19For  every  triple  L, VQ, R), where L is an arithmetic or enumeration
      type, VQ is either volatile or empty, and R is a  promoted  arithmetic
@@ -1955,7 +1957,7 @@ add_builtin_candidate (candidates, code, code2, fnname, type1, type2,
        case TRUNC_DIV_EXPR:
          if (ARITHMETIC_TYPE_P (type1) && ARITHMETIC_TYPE_P (type2))
            break;
-         return candidates;
+         return;
 
        case TRUNC_MOD_EXPR:
        case BIT_AND_EXPR:
@@ -1965,7 +1967,7 @@ add_builtin_candidate (candidates, code, code2, fnname, type1, type2,
        case RSHIFT_EXPR:
          if (INTEGRAL_TYPE_P (type1) && INTEGRAL_TYPE_P (type2))
            break;
-         return candidates;
+         return;
 
        case NOP_EXPR:
          if (ARITHMETIC_TYPE_P (type1) && ARITHMETIC_TYPE_P (type2))
@@ -1980,7 +1982,7 @@ add_builtin_candidate (candidates, code, code2, fnname, type1, type2,
              type2 = type1;
              break;
            }
-         return candidates;
+         return;
 
        default:
          abort ();
@@ -2015,16 +2017,13 @@ add_builtin_candidate (candidates, code, code2, fnname, type1, type2,
          || !(TREE_CODE (type2) == POINTER_TYPE
               || TYPE_PTRMEM_P (type2)
               || TYPE_PTRMEMFUNC_P (type2)))
-       return candidates;
+       return;
       
       /* We don't check that the two types are the same; the logic
         below will actually create two candidates; one in which both
         parameter types are TYPE1, and one in which both parameter
         types are TYPE2.  */
-       break;
-
-      /* These arguments do not make for a valid overloaded operator.  */
-      return candidates;
+      break;
 
     default:
       abort ();
@@ -2041,19 +2040,19 @@ add_builtin_candidate (candidates, code, code2, fnname, type1, type2,
          || IS_AGGR_TYPE (type1)
          || TREE_CODE (type1) == ENUMERAL_TYPE))
     {
-      candidates = build_builtin_candidate
+      build_builtin_candidate
        (candidates, fnname, type1, type1, args, argtypes, flags);
-      return build_builtin_candidate
+      build_builtin_candidate
        (candidates, fnname, type2, type2, args, argtypes, flags);
+      return;
     }
 
-  return build_builtin_candidate
+  build_builtin_candidate
     (candidates, fnname, type1, type2, args, argtypes, flags);
 }
 
 tree
-type_decays_to (type)
-     tree type;
+type_decays_to (tree type)
 {
   if (TREE_CODE (type) == ARRAY_TYPE)
     return build_pointer_type (TREE_TYPE (type));
@@ -2075,12 +2074,10 @@ type_decays_to (type)
    other cases which the standard disallows. add_builtin_candidate will
    filter out the invalid set.  */
 
-static struct z_candidate *
-add_builtin_candidates (candidates, code, code2, fnname, args, flags)
-     struct z_candidate *candidates;
-     enum tree_code code, code2;
-     tree fnname, *args;
-     int flags;
+static void
+add_builtin_candidates (struct z_candidate **candidates, enum tree_code code,
+                        enum tree_code code2, tree fnname, tree *args,
+                        int flags)
 {
   int ref1, i;
   int enum_p = 0;
@@ -2120,20 +2117,22 @@ add_builtin_candidates (candidates, code, code2, fnname, args, flags)
             bool    operator||(bool, bool);  */
 
     case TRUTH_NOT_EXPR:
-      return build_builtin_candidate
+      build_builtin_candidate
        (candidates, fnname, boolean_type_node,
         NULL_TREE, args, argtypes, flags);
+      return;
 
     case TRUTH_ORIF_EXPR:
     case TRUTH_ANDIF_EXPR:
-      return build_builtin_candidate
+      build_builtin_candidate
        (candidates, fnname, boolean_type_node,
         boolean_type_node, args, argtypes, flags);
+      return;
 
     case ADDR_EXPR:
     case COMPOUND_EXPR:
     case COMPONENT_REF:
-      return candidates;
+      return;
 
     case COND_EXPR:
     case EQ_EXPR:
@@ -2160,7 +2159,7 @@ add_builtin_candidates (candidates, code, code2, fnname, args, flags)
          tree convs;
 
          if (i == 0 && code == MODIFY_EXPR && code2 == NOP_EXPR)
-           return candidates;
+           return;
 
          convs = lookup_conversions (argtypes[i]);
 
@@ -2175,7 +2174,7 @@ add_builtin_candidates (candidates, code, code2, fnname, args, flags)
            }
 
          else if (! convs)
-           return candidates;
+           return;
 
          for (; convs; convs = TREE_CHAIN (convs))
            {
@@ -2227,16 +2226,16 @@ add_builtin_candidates (candidates, code, code2, fnname, args, flags)
     {
       if (types[1])
        for (type = types[1]; type; type = TREE_CHAIN (type))
-         candidates = add_builtin_candidate
+         add_builtin_candidate
            (candidates, code, code2, fnname, TREE_VALUE (types[0]),
             TREE_VALUE (type), args, argtypes, flags);
       else
-       candidates = add_builtin_candidate
+       add_builtin_candidate
          (candidates, code, code2, fnname, TREE_VALUE (types[0]),
           NULL_TREE, args, argtypes, flags);
     }
 
-  return candidates;
+  return;
 }
 
 
@@ -2251,16 +2250,11 @@ add_builtin_candidates (candidates, code, code2, fnname, args, flags)
    add_conv_candidate.  */
 
 static struct z_candidate*
-add_template_candidate_real (candidates, tmpl, ctype, explicit_targs,
-                            arglist, return_type, access_path,
-                            conversion_path, flags, obj, strict)
-     struct z_candidate *candidates;
-     tree tmpl, ctype, explicit_targs, arglist, return_type;
-     tree access_path;
-     tree conversion_path;
-     int flags;
-     tree obj;
-     unification_kind_t strict;
+add_template_candidate_real (struct z_candidate **candidates, tree tmpl,
+                             tree ctype, tree explicit_targs, tree arglist,
+                             tree return_type, tree access_path,
+                            tree conversion_path, int flags, tree obj,
+                             unification_kind_t strict)
 {
   int ntparms = DECL_NTPARMS (tmpl);
   tree targs = make_tree_vec (ntparms);
@@ -2284,11 +2278,11 @@ add_template_candidate_real (candidates, tmpl, ctype, explicit_targs,
                           return_type, strict, -1);
 
   if (i != 0)
-    return candidates;
+    return NULL;
 
   fn = instantiate_template (tmpl, targs);
   if (fn == error_mark_node)
-    return candidates;
+    return NULL;
 
   /* In [class.copy]:
 
@@ -2317,7 +2311,7 @@ add_template_candidate_real (candidates, tmpl, ctype, explicit_targs,
       tree arg_types = FUNCTION_FIRST_USER_PARMTYPE (fn);
       if (arg_types && same_type_p (TYPE_MAIN_VARIANT (TREE_VALUE (arg_types)),
                                    ctype))
-       return candidates;
+       return NULL;
     }
 
   if (obj != NULL_TREE)
@@ -2355,15 +2349,10 @@ add_template_candidate_real (candidates, tmpl, ctype, explicit_targs,
 
 
 static struct z_candidate *
-add_template_candidate (candidates, tmpl, ctype, explicit_targs, 
-                       arglist, return_type, access_path, 
-                       conversion_path, flags, strict)
-     struct z_candidate *candidates;
-     tree tmpl, ctype, explicit_targs, arglist, return_type;
-     tree access_path;
-     tree conversion_path;
-     int flags;
-     unification_kind_t strict;
+add_template_candidate (struct z_candidate **candidates, tree tmpl, tree ctype,
+                        tree explicit_targs, tree arglist, tree return_type,
+                        tree access_path, tree conversion_path, int flags,
+                        unification_kind_t strict)
 {
   return 
     add_template_candidate_real (candidates, tmpl, ctype,
@@ -2374,12 +2363,9 @@ add_template_candidate (candidates, tmpl, ctype, explicit_targs,
 
 
 static struct z_candidate *
-add_template_conv_candidate (candidates, tmpl, obj, arglist, return_type,
-                            access_path, conversion_path)
-     struct z_candidate *candidates;
-     tree tmpl, obj, arglist, return_type;
-     tree access_path;
-     tree conversion_path;
+add_template_conv_candidate (struct z_candidate **candidates, tree tmpl,
+                             tree obj, tree arglist, tree return_type,
+                            tree access_path, tree conversion_path)
 {
   return 
     add_template_candidate_real (candidates, tmpl, NULL_TREE, NULL_TREE,
@@ -2388,29 +2374,26 @@ add_template_conv_candidate (candidates, tmpl, obj, arglist, return_type,
 }
 
 
-static int
-any_viable (cands)
-     struct z_candidate *cands;
+static bool
+any_viable (struct z_candidate *cands)
 {
   for (; cands; cands = cands->next)
     if (pedantic ? cands->viable == 1 : cands->viable)
-      return 1;
-  return 0;
+      return true;
+  return false;
 }
 
-static int
-any_strictly_viable (cands)
-     struct z_candidate *cands;
+static bool
+any_strictly_viable (struct z_candidate *cands)
 {
   for (; cands; cands = cands->next)
     if (cands->viable == 1)
-      return 1;
-  return 0;
+      return true;
+  return false;
 }
 
 static struct z_candidate *
-splice_viable (cands)
-     struct z_candidate *cands;
+splice_viable (struct z_candidate *cands)
 {
   struct z_candidate **p = &cands;
 
@@ -2426,16 +2409,14 @@ splice_viable (cands)
 }
 
 static tree
-build_this (obj)
-     tree obj;
+build_this (tree obj)
 {
   /* Fix this to work on non-lvalues.  */
   return build_unary_op (ADDR_EXPR, obj, 0);
 }
 
 static void
-print_z_candidates (candidates)
-     struct z_candidate *candidates;
+print_z_candidates (struct z_candidate *candidates)
 {
   const char *str = "candidates are:";
   for (; candidates; candidates = candidates->next)
@@ -2464,6 +2445,35 @@ print_z_candidates (candidates)
     }
 }
 
+/* USER_SEQ is a user-defined conversion sequence, beginning with a
+   USER_CONV.  STD_SEQ is the standard conversion sequence applied to
+   the result of the conversion function to convert it to the final
+   desired type.  Merge the the two sequences into a single sequence,
+   and return the merged sequence.  */
+
+static tree
+merge_conversion_sequences (tree user_seq, tree std_seq)
+{
+  tree *t;
+
+  my_friendly_assert (TREE_CODE (user_seq) == USER_CONV,
+                     20030306);
+
+  /* Find the end of the second conversion sequence.  */
+  t = &(std_seq); 
+  while (TREE_CODE (*t) != IDENTITY_CONV)
+    t = &TREE_OPERAND (*t, 0);
+
+  /* Replace the identity conversion with the user conversion
+     sequence.  */
+  *t = user_seq;
+
+  /* The entire sequence is a user-conversion sequence.  */
+  ICS_USER_FLAG (std_seq) = 1;
+
+  return std_seq;
+}
+
 /* Returns the best overload candidate to perform the requested
    conversion.  This function is used for three the overloading situations
    described in [over.match.copy], [over.match.conv], and [over.match.ref].
@@ -2471,15 +2481,12 @@ print_z_candidates (candidates)
    per [dcl.init.ref], so we ignore temporary bindings.  */
 
 static struct z_candidate *
-build_user_type_conversion_1 (totype, expr, flags)
-     tree totype, expr;
-     int flags;
+build_user_type_conversion_1 (tree totype, tree expr, int flags)
 {
   struct z_candidate *candidates, *cand;
   tree fromtype = TREE_TYPE (expr);
-  tree ctors = NULL_TREE, convs = NULL_TREE, *p;
+  tree ctors = NULL_TREE, convs = NULL_TREE;
   tree args = NULL_TREE;
-  tree templates = NULL_TREE;
 
   /* We represent conversion within a hierarchy using RVALUE_CONV and
      BASE_CONV, as specified by [over.best.ics]; these become plain
@@ -2521,24 +2528,20 @@ build_user_type_conversion_1 (totype, expr, flags)
        continue;
 
       if (TREE_CODE (ctor) == TEMPLATE_DECL) 
-       {
-         templates = tree_cons (NULL_TREE, ctor, templates);
-         candidates = 
-           add_template_candidate (candidates, ctor, totype,
-                                   NULL_TREE, args, NULL_TREE, 
-                                   TYPE_BINFO (totype),
-                                   TYPE_BINFO (totype),
-                                   flags,
-                                   DEDUCE_CALL);
-       }
+       cand = add_template_candidate (&candidates, ctor, totype,
+                                      NULL_TREE, args, NULL_TREE, 
+                                      TYPE_BINFO (totype),
+                                      TYPE_BINFO (totype),
+                                      flags,
+                                      DEDUCE_CALL);
       else 
-       candidates = add_function_candidate (candidates, ctor, totype,
-                                            args, TYPE_BINFO (totype), 
-                                            TYPE_BINFO (totype),
-                                            flags); 
+       cand = add_function_candidate (&candidates, ctor, totype,
+                                      args, TYPE_BINFO (totype), 
+                                      TYPE_BINFO (totype),
+                                      flags); 
 
-      if (candidates) 
-       candidates->second_conv = build1 (IDENTITY_CONV, totype, NULL_TREE);
+      if (cand)
+       cand->second_conv = build1 (IDENTITY_CONV, totype, NULL_TREE);
     }
 
   if (convs)
@@ -2560,7 +2563,6 @@ build_user_type_conversion_1 (totype, expr, flags)
       for (fns = TREE_VALUE (convs); fns; fns = OVL_NEXT (fns))
        {
          tree fn = OVL_CURRENT (fns);
-         struct z_candidate *old_candidates = candidates;
          
          /* [over.match.funcs] For conversion functions, the function
             is considered to be a member of the class of the implicit
@@ -2570,34 +2572,32 @@ build_user_type_conversion_1 (totype, expr, flags)
             So we pass fromtype as CTYPE to add_*_candidate.  */
 
          if (TREE_CODE (fn) == TEMPLATE_DECL)
-           {
-             templates = tree_cons (NULL_TREE, fn, templates);
-             candidates = 
-               add_template_candidate (candidates, fn, fromtype, NULL_TREE,
-                                       args, totype, TYPE_BINFO (fromtype), 
-                                       conversion_path,
-                                       flags,
-                                       DEDUCE_CONV);
-           } 
+           cand = add_template_candidate (&candidates, fn, fromtype, 
+                                          NULL_TREE,
+                                          args, totype, 
+                                          TYPE_BINFO (fromtype), 
+                                          conversion_path,
+                                          flags,
+                                          DEDUCE_CONV);
          else 
-           candidates = add_function_candidate (candidates, fn, fromtype,
-                                                args,
-                                                TYPE_BINFO (fromtype),
-                                                conversion_path,
-                                                flags); 
+           cand = add_function_candidate (&candidates, fn, fromtype,
+                                          args,
+                                          TYPE_BINFO (fromtype),
+                                          conversion_path,
+                                          flags); 
 
-         if (candidates != old_candidates)
+         if (cand)
            {
-             tree ics = implicit_conversion
-               (totype, TREE_TYPE (TREE_TYPE (candidates->fn)),
-                0, convflags);
+             tree ics = implicit_conversion (totype, 
+                                             TREE_TYPE (TREE_TYPE (cand->fn)),
+                                             0, convflags);
 
-             candidates->second_conv = ics;
+             cand->second_conv = ics;
              
              if (ics == NULL_TREE)
-               candidates->viable = 0;
+               cand->viable = 0;
              else if (candidates->viable == 1 && ICS_BAD_FLAG (ics))
-               candidates->viable = -1;
+               cand->viable = -1;
            }
        }
     }
@@ -2620,31 +2620,35 @@ build_user_type_conversion_1 (totype, expr, flags)
       cand = candidates;       /* any one will do */
       cand->second_conv = build1 (AMBIG_CONV, totype, expr);
       ICS_USER_FLAG (cand->second_conv) = 1;
-      ICS_BAD_FLAG (cand->second_conv) = 1;
+      if (!any_strictly_viable (candidates))
+       ICS_BAD_FLAG (cand->second_conv) = 1;
+      /* If there are viable candidates, don't set ICS_BAD_FLAG; an
+        ambiguous conversion is no worse than another user-defined
+        conversion.  */
 
       return cand;
     }
 
-  for (p = &(cand->second_conv); TREE_CODE (*p) != IDENTITY_CONV; )
-    p = &(TREE_OPERAND (*p, 0));
-
-  *p = build
+  /* Build the user conversion sequence.  */
+  convs = build_conv
     (USER_CONV,
      (DECL_CONSTRUCTOR_P (cand->fn)
       ? totype : non_reference (TREE_TYPE (TREE_TYPE (cand->fn)))),
-     expr, build_zc_wrapper (cand));
-  
-  ICS_USER_FLAG (cand->second_conv) = ICS_USER_FLAG (*p) = 1;
+     build1 (IDENTITY_CONV, TREE_TYPE (expr), expr));
+  TREE_OPERAND (convs, 1) = build_zc_wrapper (cand);
+
+  /* Combine it with the second conversion sequence.  */
+  cand->second_conv = merge_conversion_sequences (convs,
+                                                 cand->second_conv);
+
   if (cand->viable == -1)
-    ICS_BAD_FLAG (cand->second_conv) = ICS_BAD_FLAG (*p) = 1;
+    ICS_BAD_FLAG (cand->second_conv) = 1;
 
   return cand;
 }
 
 tree
-build_user_type_conversion (totype, expr, flags)
-     tree totype, expr;
-     int flags;
+build_user_type_conversion (tree totype, tree expr, int flags)
 {
   struct z_candidate *cand
     = build_user_type_conversion_1 (totype, expr, flags);
@@ -2658,11 +2662,77 @@ build_user_type_conversion (totype, expr, flags)
   return NULL_TREE;
 }
 
+/* Find the possibly overloaded set of functions corresponding to a
+   call of the form SCOPE::NAME (...). NAME might be a
+   TEMPLATE_ID_EXPR, OVERLOAD, _DECL, IDENTIFIER_NODE or LOOKUP_EXPR. */
+
+tree
+resolve_scoped_fn_name (tree scope, tree name)
+{
+  tree fn;
+  tree template_args = NULL_TREE;
+  bool is_template_id = TREE_CODE (name) == TEMPLATE_ID_EXPR;
+  
+  if (is_template_id)
+    {
+      template_args = TREE_OPERAND (name, 1);
+      name = TREE_OPERAND (name, 0);
+    }
+  if (TREE_CODE (name) == OVERLOAD)
+    name = DECL_NAME (get_first_fn (name));
+  else if (TREE_CODE (name) == LOOKUP_EXPR)
+    name = TREE_OPERAND (name, 0);
+  
+  if (TREE_CODE (scope) == NAMESPACE_DECL)
+    fn = lookup_namespace_name (scope, name);
+  else
+    {
+      if (!TYPE_BEING_DEFINED (scope)
+         && !COMPLETE_TYPE_P (complete_type (scope)))
+       {
+         error ("incomplete type '%T' cannot be used to name a scope",
+                scope);
+         return error_mark_node;
+       }
+      
+      if (BASELINK_P (name))
+       fn = name;
+      else
+       fn = lookup_member (scope, name, /*protect=*/1, /*want_type=*/false);
+      if (fn && current_class_type)
+       fn = (adjust_result_of_qualified_name_lookup 
+             (fn, scope, current_class_type));
+
+      /* It might be the name of a function pointer member.  */
+      if (fn && TREE_CODE (fn) == FIELD_DECL)
+       fn = resolve_offset_ref (build_offset_ref (scope, fn));
+    }
+  
+  if (!fn)
+    {
+      error ("'%D' has no member named '%E'", scope, name);
+      return error_mark_node;
+    }
+  if (is_template_id)
+    {
+      tree fns = fn;
+
+      if (BASELINK_P (fn))
+       fns = BASELINK_FUNCTIONS (fns);
+      fns = build_nt (TEMPLATE_ID_EXPR, fns, template_args);
+      if (BASELINK_P (fn))
+       BASELINK_FUNCTIONS (fn) = fns;
+      else
+       fn = fns;
+    }
+  
+  return fn;
+}
+
 /* Do any initial processing on the arguments to a function call.  */
 
 static tree
-resolve_args (args)
-     tree args;
+resolve_args (tree args)
 {
   tree t;
   for (t = args; t; t = TREE_CHAIN (t))
@@ -2684,17 +2754,31 @@ resolve_args (args)
   return args;
 }
 
-/* Return an expression for a call to FN (a namespace-scope function)
-   with the ARGS.  */
-      
-tree
-build_new_function_call (fn, args)
-     tree fn, args;
+/* Perform overload resolution on FN, which is called with the ARGS.
+
+   Return the candidate function selected by overload resolution, or
+   NULL if the event that overload resolution failed.  In the case
+   that overload resolution fails, *CANDIDATES will be the set of
+   candidates considered, and ANY_VIABLE_P will be set to true or
+   false to indicate whether or not any of the candidates were
+   viable.  
+
+   The ARGS should already have gone through RESOLVE_ARGS before this
+   function is called.  */
+
+static struct z_candidate *
+perform_overload_resolution (tree fn, 
+                            tree args, 
+                            struct z_candidate **candidates,
+                            bool *any_viable_p)
 {
-  struct z_candidate *candidates = 0, *cand;
+  struct z_candidate *cand;
   tree explicit_targs = NULL_TREE;
   int template_only = 0;
 
+  *candidates = NULL;
+  *any_viable_p = true;
+
   /* Check FN and ARGS.  */
   my_friendly_assert (TREE_CODE (fn) == FUNCTION_DECL 
                      || TREE_CODE (fn) == TEMPLATE_DECL
@@ -2711,69 +2795,150 @@ build_new_function_call (fn, args)
       template_only = 1;
     }
 
-  if (really_overloaded_fn (fn) 
-      || TREE_CODE (fn) == TEMPLATE_DECL)
-    {
-      tree t1;
-      tree templates = NULL_TREE;
+  /* Add the various candidate functions.  */
+  add_candidates (fn, args, explicit_targs, template_only,
+                 /*conversion_path=*/NULL_TREE,
+                 /*access_path=*/NULL_TREE,
+                 LOOKUP_NORMAL,
+                 candidates);
 
-      args = resolve_args (args);
+  if (! any_viable (*candidates))
+    {
+      *any_viable_p = false;
+      return NULL;
+    }
 
-      if (args == error_mark_node)
-       return error_mark_node;
+  *candidates = splice_viable (*candidates);
+  cand = tourney (*candidates);
 
-      for (t1 = fn; t1; t1 = OVL_NEXT (t1))
-       {
-         tree t = OVL_CURRENT (t1);
+  return cand;
+}
 
-         if (TREE_CODE (t) == TEMPLATE_DECL)
-           {
-             templates = tree_cons (NULL_TREE, t, templates);
-             candidates = add_template_candidate
-               (candidates, t, NULL_TREE, explicit_targs, args, 
-                NULL_TREE,
-                /*access_path=*/NULL_TREE, /*conversion_path=*/NULL_TREE,
-                LOOKUP_NORMAL, DEDUCE_CALL);  
-           }
-         else if (! template_only)
-           candidates = add_function_candidate
-             (candidates, t, NULL_TREE, args, /*access_path=*/NULL_TREE, 
-              /*conversion_path=*/NULL_TREE, LOOKUP_NORMAL);
-       }
+/* Return an expression for a call to FN (a namespace-scope function,
+   or a static member function) with the ARGS.  */
+      
+tree
+build_new_function_call (tree fn, tree args)
+{
+  struct z_candidate *candidates, *cand;
+  bool any_viable_p;
 
-      if (! any_viable (candidates))
-       {
-         if (candidates && ! candidates->next)
-           return build_function_call (candidates->fn, args);
-         error ("no matching function for call to `%D(%A)'",
-                   DECL_NAME (OVL_CURRENT (fn)), args);
-         if (candidates)
-           print_z_candidates (candidates);
-         return error_mark_node;
-       }
-      candidates = splice_viable (candidates);
-      cand = tourney (candidates);
+  args = resolve_args (args);
+  if (args == error_mark_node)
+    return error_mark_node;
 
-      if (cand == 0)
-       {
-         error ("call of overloaded `%D(%A)' is ambiguous",
-                   DECL_NAME (OVL_FUNCTION (fn)), args);
-         print_z_candidates (candidates);
-         return error_mark_node;
-       }
+  cand = perform_overload_resolution (fn, args, &candidates, &any_viable_p);
 
-      return build_over_call (cand, args, LOOKUP_NORMAL);
+  if (!cand)
+    {
+      if (!any_viable_p && candidates && ! candidates->next)
+       return build_function_call (candidates->fn, args);
+      if (TREE_CODE (fn) == TEMPLATE_ID_EXPR)
+       fn = TREE_OPERAND (fn, 0);
+      if (!any_viable_p)
+       error ("no matching function for call to `%D(%A)'",
+              DECL_NAME (OVL_CURRENT (fn)), args);
+      else
+       error ("call of overloaded `%D(%A)' is ambiguous",
+              DECL_NAME (OVL_FUNCTION (fn)), args);
+      if (candidates)
+       print_z_candidates (candidates);
+      return error_mark_node;
     }
 
-  /* This is not really overloaded.  */
-  fn = OVL_CURRENT (fn);
+  return build_over_call (cand, LOOKUP_NORMAL);
+}
+
+/* Build a call to a global operator new.  FNNAME is the name of the
+   operator (either "operator new" or "operator new[]") and ARGS are
+   the arguments provided.  *SIZE points to the total number of bytes
+   required by the allocation, and is updated if that is changed here.
+   *COOKIE_SIZE is non-NULL if a cookie should be used.  If this
+   function determins that no cookie should be used, after all,
+   *COOKIE_SIZE is set to NULL_TREE. */
 
-  return build_function_call (fn, args);
+tree
+build_operator_new_call (tree fnname, tree args, tree *size, tree *cookie_size)
+{
+  tree fns;
+  struct z_candidate *candidates;
+  struct z_candidate *cand;
+  bool any_viable_p;
+
+  args = tree_cons (NULL_TREE, *size, args);
+  args = resolve_args (args);
+  if (args == error_mark_node)
+    return args;
+
+  fns = lookup_function_nonclass (fnname, args);
+
+  /* Figure out what function is being called.  */
+  cand = perform_overload_resolution (fns, args, &candidates, &any_viable_p);
+  
+  /* If no suitable function could be found, issue an error message
+     and give up.  */
+  if (!cand)
+    {
+      if (!any_viable_p)
+       error ("no matching function for call to `%D(%A)'",
+              DECL_NAME (OVL_CURRENT (fns)), args);
+      else
+       error ("call of overlopaded `%D(%A)' is ambiguous",
+              DECL_NAME (OVL_FUNCTION (fns)), args);
+      if (candidates)
+       print_z_candidates (candidates);
+      return error_mark_node;
+    }
+
+   /* If a cookie is required, add some extra space.  Whether
+      or not a cookie is required cannot be determined until
+      after we know which function was called.  */
+   if (*cookie_size)
+     {
+       bool use_cookie = true;
+       if (!abi_version_at_least (2))
+        {
+          tree placement = TREE_CHAIN (args);
+          /* In G++ 3.2, the check was implemented incorrectly; it
+             looked at the placement expression, rather than the
+             type of the function.  */
+          if (placement && !TREE_CHAIN (placement)
+              && same_type_p (TREE_TYPE (TREE_VALUE (placement)),
+                              ptr_type_node))
+            use_cookie = false;
+        }
+       else
+        {
+          tree arg_types;
+
+          arg_types = TYPE_ARG_TYPES (TREE_TYPE (cand->fn));
+          /* Skip the size_t parameter.  */
+          arg_types = TREE_CHAIN (arg_types);
+          /* Check the remaining parameters (if any).  */
+          if (arg_types 
+              && TREE_CHAIN (arg_types) == void_list_node
+              && same_type_p (TREE_VALUE (arg_types),
+                              ptr_type_node))
+            use_cookie = false;
+        }
+       /* If we need a cookie, adjust the number of bytes allocated.  */
+       if (use_cookie)
+        {
+          /* Update the total size.  */
+          *size = size_binop (PLUS_EXPR, *size, *cookie_size);
+          /* Update the argument list to reflect the adjusted size.  */
+          TREE_VALUE (args) = *size;
+        }
+       else
+        *cookie_size = NULL_TREE;
+     }
+
+   /* Build the CALL_EXPR.  */
+   return build_over_call (cand, LOOKUP_NORMAL);
 }
 
 static tree
-build_object_call (obj, args)
-     tree obj, args;
+build_object_call (tree obj, tree args)
 {
   struct z_candidate *candidates = 0, *cand;
   tree fns, convs, mem_args = NULL_TREE;
@@ -2805,17 +2970,14 @@ build_object_call (obj, args)
        {
          tree fn = OVL_CURRENT (fns);
          if (TREE_CODE (fn) == TEMPLATE_DECL)
-           {
-             candidates 
-               = add_template_candidate (candidates, fn, base, NULL_TREE,
-                                         mem_args, NULL_TREE, 
-                                         TYPE_BINFO (type),
-                                         TYPE_BINFO (type),
-                                         LOOKUP_NORMAL, DEDUCE_CALL);
-           }
+           add_template_candidate (&candidates, fn, base, NULL_TREE,
+                                   mem_args, NULL_TREE, 
+                                   TYPE_BINFO (type),
+                                   TYPE_BINFO (type),
+                                   LOOKUP_NORMAL, DEDUCE_CALL);
          else
-           candidates = add_function_candidate
-             (candidates, fn, base, mem_args, TYPE_BINFO (type),
+           add_function_candidate
+             (&candidates, fn, base, mem_args, TYPE_BINFO (type),
               TYPE_BINFO (type), LOOKUP_NORMAL);
        }
     }
@@ -2838,16 +3000,14 @@ build_object_call (obj, args)
          {
            tree fn = OVL_CURRENT (fns);
            if (TREE_CODE (fn) == TEMPLATE_DECL) 
-             {
-               candidates = (add_template_conv_candidate 
-                             (candidates, fn, obj, args, totype,
-                              /*access_path=*/NULL_TREE,
-                              /*conversion_path=*/NULL_TREE));
-             }
+             add_template_conv_candidate 
+               (&candidates, fn, obj, args, totype,
+                /*access_path=*/NULL_TREE,
+                /*conversion_path=*/NULL_TREE);
            else
-             candidates = add_conv_candidate (candidates, fn, obj, args,
-                                              /*conversion_path=*/NULL_TREE,
-                                              /*access_path=*/NULL_TREE);
+             add_conv_candidate (&candidates, fn, obj, args,
+                                 /*conversion_path=*/NULL_TREE,
+                                 /*access_path=*/NULL_TREE);
          }
     }
 
@@ -2873,7 +3033,7 @@ build_object_call (obj, args)
      DECL_NAME here.  */
   if (TREE_CODE (cand->fn) == FUNCTION_DECL
       && DECL_OVERLOADED_OPERATOR_P (cand->fn) == CALL_EXPR)
-    return build_over_call (cand, mem_args, LOOKUP_NORMAL);
+    return build_over_call (cand, LOOKUP_NORMAL);
 
   obj = convert_like_with_context
           (TREE_VEC_ELT (cand->convs, 0), obj, cand->fn, -1);
@@ -2883,10 +3043,8 @@ build_object_call (obj, args)
 }
 
 static void
-op_error (code, code2, arg1, arg2, arg3, problem)
-     enum tree_code code, code2;
-     tree arg1, arg2, arg3;
-     const char *problem;
+op_error (enum tree_code code, enum tree_code code2,
+          tree arg1, tree arg2, tree arg3, const char *problem)
 {
   const char *opname;
 
@@ -2922,9 +3080,7 @@ op_error (code, code2, arg1, arg2, arg3, problem)
    convert E1 to E2 in [expr.cond].  */
 
 static tree
-conditional_conversion (e1, e2)
-     tree e1;
-     tree e2;
+conditional_conversion (tree e1, tree e2)
 {
   tree t1 = non_reference (TREE_TYPE (e1));
   tree t2 = non_reference (TREE_TYPE (e2));
@@ -2984,16 +3140,13 @@ conditional_conversion (e1, e2)
    arguments to the conditional expression.  */
 
 tree
-build_conditional_expr (arg1, arg2, arg3)
-     tree arg1;
-     tree arg2;
-     tree arg3;
+build_conditional_expr (tree arg1, tree arg2, tree arg3)
 {
   tree arg2_type;
   tree arg3_type;
   tree result;
   tree result_type = NULL_TREE;
-  int lvalue_p = 1;
+  bool lvalue_p = true;
   struct z_candidate *candidates = 0;
   struct z_candidate *cand;
 
@@ -3005,7 +3158,12 @@ build_conditional_expr (arg1, arg2, arg3)
     {
       if (pedantic)
        pedwarn ("ISO C++ forbids omitting the middle term of a ?: expression");
-      arg1 = arg2 = save_expr (arg1);
+
+      /* Make sure that lvalues remain lvalues.  See g++.oliva/ext1.C.  */
+      if (real_lvalue_p (arg1))
+       arg2 = arg1 = stabilize_reference (arg1);
+      else
+       arg2 = arg1 = save_expr (arg1);
     }
 
   /* [expr.cond]
@@ -3068,7 +3226,7 @@ build_conditional_expr (arg1, arg2, arg3)
          return error_mark_node;
        }
 
-      lvalue_p = 0;
+      lvalue_p = false;
       goto valid_operands;
     }
   /* [expr.cond]
@@ -3105,13 +3263,9 @@ build_conditional_expr (arg1, arg2, arg3)
          arg2 = convert_from_reference (arg2);
          /* That may not quite have done the trick.  If the two types
             are cv-qualified variants of one another, we will have
-            just used an IDENTITY_CONV.  (There's no conversion from
-            an lvalue of one class type to an lvalue of another type,
-            even a cv-qualified variant, and we don't want to lose
-            lvalue-ness here.)  So, we manually add a NOP_EXPR here
-            if necessary.  */
+            just used an IDENTITY_CONV.  */
          if (!same_type_p (TREE_TYPE (arg2), arg3_type))
-           arg2 = build1 (NOP_EXPR, arg3_type, arg2);
+           arg2 = convert (arg3_type, arg2);
          arg2_type = TREE_TYPE (arg2);
        }
       else if (conv3 && !ICS_BAD_FLAG (conv3))
@@ -3119,7 +3273,7 @@ build_conditional_expr (arg1, arg2, arg3)
          arg3 = convert_like (conv3, arg3);
          arg3 = convert_from_reference (arg3);
          if (!same_type_p (TREE_TYPE (arg3), arg2_type))
-           arg3 = build1 (NOP_EXPR, arg2_type, arg3);
+           arg3 = convert (arg2_type, arg3);
          arg3_type = TREE_TYPE (arg3);
        }
     }
@@ -3142,7 +3296,7 @@ build_conditional_expr (arg1, arg2, arg3)
      cv-qualified) class type, overload resolution is used to
      determine the conversions (if any) to be applied to the operands
      (_over.match.oper_, _over.built_).  */
-  lvalue_p = 0;
+  lvalue_p = false;
   if (!same_type_p (arg2_type, arg3_type)
       && (CLASS_TYPE_P (arg2_type) || CLASS_TYPE_P (arg3_type)))
     {
@@ -3155,12 +3309,12 @@ build_conditional_expr (arg1, arg2, arg3)
       args[0] = arg2;
       args[1] = arg3;
       args[2] = arg1;
-      candidates = add_builtin_candidates (candidates, 
-                                          COND_EXPR, 
-                                          NOP_EXPR,
-                                          ansi_opname (COND_EXPR),
-                                          args,
-                                          LOOKUP_NORMAL);
+      add_builtin_candidates (&candidates, 
+                             COND_EXPR, 
+                             NOP_EXPR,
+                             ansi_opname (COND_EXPR),
+                             args,
+                             LOOKUP_NORMAL);
 
       /* [expr.cond]
 
@@ -3208,14 +3362,14 @@ build_conditional_expr (arg1, arg2, arg3)
      We use ocp_convert rather than build_user_type_conversion because the
      latter returns NULL_TREE on failure, while the former gives an error.  */
 
-  if (IS_AGGR_TYPE (TREE_TYPE (arg2)) && real_lvalue_p (arg2))
+  if (IS_AGGR_TYPE (TREE_TYPE (arg2)))
     arg2 = ocp_convert (TREE_TYPE (arg2), arg2,
                        CONV_IMPLICIT|CONV_FORCE_TEMP, LOOKUP_NORMAL);
   else
     arg2 = decay_conversion (arg2);
   arg2_type = TREE_TYPE (arg2);
 
-  if (IS_AGGR_TYPE (TREE_TYPE (arg3)) && real_lvalue_p (arg3))
+  if (IS_AGGR_TYPE (TREE_TYPE (arg3)))
     arg3 = ocp_convert (TREE_TYPE (arg3), arg3,
                        CONV_IMPLICIT|CONV_FORCE_TEMP, LOOKUP_NORMAL);
   else
@@ -3316,32 +3470,108 @@ build_conditional_expr (arg1, arg2, arg3)
   return result;
 }
 
+/* OPERAND is an operand to an expression.  Perform necessary steps
+   required before using it.  If OPERAND is NULL_TREE, NULL_TREE is
+   returned.  */
+
+static tree
+prep_operand (tree operand)
+{
+  if (operand)
+    {
+      if (TREE_CODE (operand) == OFFSET_REF)
+       operand = resolve_offset_ref (operand);
+      operand = convert_from_reference (operand);
+      if (CLASS_TYPE_P (TREE_TYPE (operand))
+         && CLASSTYPE_TEMPLATE_INSTANTIATION (TREE_TYPE (operand)))
+       /* Make sure the template type is instantiated now.  */
+       instantiate_class_template (TYPE_MAIN_VARIANT (TREE_TYPE (operand)));
+    }
+
+  return operand;
+}
+
+/* Add each of the viable functions in FNS (a FUNCTION_DECL or
+   OVERLOAD) to the CANDIDATES, returning an updated list of
+   CANDIDATES.  The ARGS are the arguments provided to the call,
+   without any implicit object parameter.  The EXPLICIT_TARGS are
+   explicit template arguments provided.  TEMPLATE_ONLY is true if
+   only template fucntions should be considered.  CONVERSION_PATH,
+   ACCESS_PATH, and FLAGS are as for add_function_candidate.  */
+
+static void
+add_candidates (tree fns, tree args, 
+               tree explicit_targs, bool template_only,
+               tree conversion_path, tree access_path,
+               int flags,
+               struct z_candidate **candidates)
+{
+  tree ctype;
+  tree non_static_args;
+
+  ctype = conversion_path ? BINFO_TYPE (conversion_path) : NULL_TREE;
+  /* Delay creating the implicit this parameter until it is needed.  */
+  non_static_args = NULL_TREE;
+
+  while (fns) 
+    {
+      tree fn;
+      tree fn_args;
+
+      fn = OVL_CURRENT (fns);
+      /* Figure out which set of arguments to use.  */
+      if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn))
+       {
+         /* If this function is a non-static member, prepend the implicit
+            object parameter.  */
+         if (!non_static_args)
+           non_static_args = tree_cons (NULL_TREE,
+                                        build_this (TREE_VALUE (args)),
+                                        TREE_CHAIN (args));
+         fn_args = non_static_args;
+       }
+      else
+       /* Otherwise, just use the list of arguments provided.  */
+       fn_args = args;
+
+      if (TREE_CODE (fn) == TEMPLATE_DECL)
+       add_template_candidate (candidates, 
+                               fn, 
+                               ctype,
+                               explicit_targs,
+                               fn_args,
+                               NULL_TREE,
+                               access_path,
+                               conversion_path,
+                               flags,
+                               DEDUCE_CALL);
+      else if (!template_only)
+       add_function_candidate (candidates,
+                               fn,
+                               ctype,
+                               fn_args,
+                               access_path,
+                               conversion_path,
+                               flags);
+      fns = OVL_NEXT (fns);
+    }
+}
+
 tree
-build_new_op (code, flags, arg1, arg2, arg3)
-     enum tree_code code;
-     int flags;
-     tree arg1, arg2, arg3;
+build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3)
 {
   struct z_candidate *candidates = 0, *cand;
-  tree fns, mem_arglist = NULL_TREE, arglist, fnname;
+  tree arglist, fnname;
+  tree args[3];
   enum tree_code code2 = NOP_EXPR;
-  tree templates = NULL_TREE;
   tree conv;
   bool viable_candidates;
 
-  if (arg1 == error_mark_node
-      || arg2 == error_mark_node
-      || arg3 == error_mark_node)
+  if (error_operand_p (arg1) 
+      || error_operand_p (arg2) 
+      || error_operand_p (arg3))
     return error_mark_node;
 
-  /* This can happen if a template takes all non-type parameters, e.g.
-     undeclared_template<1, 5, 72>a;  */
-  if (code == LT_EXPR && TREE_CODE (arg1) == TEMPLATE_DECL)
-    {
-      error ("`%D' must be declared before use", arg1);
-      return error_mark_node;
-    }
-
   if (code == MODIFY_EXPR)
     {
       code2 = TREE_CODE (arg3);
@@ -3351,9 +3581,7 @@ build_new_op (code, flags, arg1, arg2, arg3)
   else
     fnname = ansi_opname (code);
 
-  if (TREE_CODE (arg1) == OFFSET_REF)
-    arg1 = resolve_offset_ref (arg1);
-  arg1 = convert_from_reference (arg1);
+  arg1 = prep_operand (arg1);
   
   switch (code)
     {
@@ -3371,18 +3599,8 @@ build_new_op (code, flags, arg1, arg2, arg3)
       break;
     }
 
-  if (arg2)
-    {
-      if (TREE_CODE (arg2) == OFFSET_REF)
-       arg2 = resolve_offset_ref (arg2);
-      arg2 = convert_from_reference (arg2);
-    }
-  if (arg3)
-    {
-      if (TREE_CODE (arg3) == OFFSET_REF)
-       arg3 = resolve_offset_ref (arg3);
-      arg3 = convert_from_reference (arg3);
-    }
+  arg2 = prep_operand (arg2);
+  arg3 = prep_operand (arg3);
   
   if (code == COND_EXPR)
     {
@@ -3407,98 +3625,45 @@ build_new_op (code, flags, arg1, arg2, arg3)
     arglist = tree_cons (NULL_TREE, arg2, arglist);
   arglist = tree_cons (NULL_TREE, arg1, arglist);
 
-  fns = lookup_function_nonclass (fnname, arglist);
-
-  if (fns && TREE_CODE (fns) == TREE_LIST)
-    fns = TREE_VALUE (fns);
-  for (; fns; fns = OVL_NEXT (fns))
+  /* Add namespace-scope operators to the list of functions to
+     consider.  */
+  add_candidates (lookup_function_nonclass (fnname, arglist),
+                 arglist, NULL_TREE, false, NULL_TREE, NULL_TREE,
+                 flags, &candidates);
+  /* Add class-member operators to the candidate set.  */
+  if (CLASS_TYPE_P (TREE_TYPE (arg1)))
     {
-      tree fn = OVL_CURRENT (fns);
-      if (TREE_CODE (fn) == TEMPLATE_DECL)
-       {
-         templates = tree_cons (NULL_TREE, fn, templates);
-         candidates 
-           = add_template_candidate (candidates, fn, NULL_TREE, NULL_TREE,
-                                     arglist, TREE_TYPE (fnname),
-                                     /*access_path=*/NULL_TREE,
-                                     /*conversion_path=*/NULL_TREE,
-                                     flags, DEDUCE_CALL); 
-       }
-      else
-       candidates = add_function_candidate (candidates, fn, NULL_TREE,
-                                            arglist,
-                                            /*access_path=*/NULL_TREE,
-                                            /*conversion_path=*/NULL_TREE,
-                                            flags);
-    }
+      tree fns;
 
-  if (IS_AGGR_TYPE (TREE_TYPE (arg1)))
-    {
       fns = lookup_fnfields (TYPE_BINFO (TREE_TYPE (arg1)), fnname, 1);
       if (fns == error_mark_node)
        return fns;
+      if (fns)
+       add_candidates (BASELINK_FUNCTIONS (fns), arglist, 
+                       NULL_TREE, false,
+                       BASELINK_BINFO (fns),
+                       TYPE_BINFO (TREE_TYPE (arg1)),
+                       flags, &candidates);
+    }
+
+  /* Rearrange the arguments for ?: so that add_builtin_candidate only has
+     to know about two args; a builtin candidate will always have a first
+     parameter of type bool.  We'll handle that in
+     build_builtin_candidate.  */
+  if (code == COND_EXPR)
+    {
+      args[0] = arg2;
+      args[1] = arg3;
+      args[2] = arg1;
     }
   else
-    fns = NULL_TREE;
-
-  if (fns)
     {
-      tree conversion_path = BASELINK_BINFO (fns);
-
-      mem_arglist = tree_cons (NULL_TREE, build_this (arg1), TREE_CHAIN (arglist));
-      for (fns = BASELINK_FUNCTIONS (fns); fns; fns = OVL_NEXT (fns))
-       {
-         tree fn = OVL_CURRENT (fns);
-         tree this_arglist;
-         tree access_path = TYPE_BINFO (TREE_TYPE (arg1));
-
-         if (TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE)
-           this_arglist = mem_arglist;
-         else
-           this_arglist = arglist;
-
-         if (TREE_CODE (fn) == TEMPLATE_DECL)
-           {
-             /* A member template.  */
-             templates = tree_cons (NULL_TREE, fn, templates);
-             candidates 
-               = add_template_candidate (candidates, fn, 
-                                         BINFO_TYPE (conversion_path),
-                                         NULL_TREE,
-                                         this_arglist,  TREE_TYPE (fnname),
-                                         access_path, conversion_path,
-                                         flags, DEDUCE_CALL); 
-           }
-         else
-           candidates = add_function_candidate
-             (candidates, fn, BINFO_TYPE (conversion_path), this_arglist, 
-              access_path, conversion_path, flags);
-       }
+      args[0] = arg1;
+      args[1] = arg2;
+      args[2] = NULL_TREE;
     }
 
-  {
-    tree args[3];
-
-    /* Rearrange the arguments for ?: so that add_builtin_candidate only has
-       to know about two args; a builtin candidate will always have a first
-       parameter of type bool.  We'll handle that in
-       build_builtin_candidate.  */
-    if (code == COND_EXPR)
-      {
-       args[0] = arg2;
-       args[1] = arg3;
-       args[2] = arg1;
-      }
-    else
-      {
-       args[0] = arg1;
-       args[1] = arg2;
-       args[2] = NULL_TREE;
-      }
-
-    candidates = add_builtin_candidates
-      (candidates, code, code2, fnname, args, flags);
-  }
+  add_builtin_candidates (&candidates, code, code2, fnname, args, flags);
 
   switch (code)
     {
@@ -3567,7 +3732,6 @@ build_new_op (code, flags, arg1, arg2, arg3)
 
   if (TREE_CODE (cand->fn) == FUNCTION_DECL)
     {
-      extern int warn_synth;
       if (warn_synth
          && fnname == ansi_assopname (NOP_EXPR)
          && DECL_ARTIFICIAL (cand->fn)
@@ -3582,11 +3746,7 @@ build_new_op (code, flags, arg1, arg2, arg3)
                         : candidates->fn);
        }
 
-      return build_over_call
-       (cand,
-        TREE_CODE (TREE_TYPE (cand->fn)) == METHOD_TYPE
-        ? mem_arglist : arglist,
-        LOOKUP_NORMAL);
+      return build_over_call (cand, LOOKUP_NORMAL);
     }
 
   /* Check for comparison of different enum types.  */
@@ -3711,10 +3871,8 @@ builtin:
    PLACEMENT is the corresponding placement new call, or NULL_TREE.  */
 
 tree
-build_op_delete_call (code, addr, size, flags, placement)
-     enum tree_code code;
-     tree addr, size, placement;
-     int flags;
+build_op_delete_call (enum tree_code code, tree addr, tree size,
+                      int flags, tree placement)
 {
   tree fn = NULL_TREE;
   tree fns, fnname, fntype, argtypes, args, type;
@@ -3850,15 +4008,10 @@ build_op_delete_call (code, addr, size, flags, placement)
    BASETYPE_PATH, give an error.  The most derived class in
    BASETYPE_PATH is the one used to qualify DECL.  */
 
-int
-enforce_access (basetype_path, decl)
-     tree basetype_path;
-     tree decl;
+bool
+enforce_access (tree basetype_path, tree decl)
 {
-  int accessible;
-
-  accessible = accessible_p (basetype_path, decl);
-  if (!accessible)
+  if (!accessible_p (basetype_path, decl))
     {
       if (TREE_PRIVATE (decl))
        cp_error_at ("`%+#D' is private", decl);
@@ -3867,10 +4020,10 @@ enforce_access (basetype_path, decl)
       else
        cp_error_at ("`%+#D' is inaccessible", decl);
       error ("within this context");
-      return 0;
+      return false;
     }
 
-  return 1;
+  return true;
 }
 
 /* Perform the conversions in CONVS on the expression EXPR. 
@@ -3880,11 +4033,7 @@ enforce_access (basetype_path, decl)
    reference binding will be applied, positive otherwise.  */
 
 static tree
-convert_like_real (convs, expr, fn, argnum, inner)
-     tree convs, expr;
-     tree fn;
-     int argnum;
-     int inner;
+convert_like_real (tree convs, tree expr, tree fn, int argnum, int inner)
 {
   int savew, savee;
 
@@ -3921,8 +4070,7 @@ convert_like_real (convs, expr, fn, argnum, inner)
     {
     case USER_CONV:
       {
-       struct z_candidate *cand
-         = WRAPPER_ZC (TREE_OPERAND (convs, 1));
+       struct z_candidate *cand = USER_CONV_CAND (convs);
        tree convfn = cand->fn;
        tree args;
 
@@ -3941,7 +4089,7 @@ convert_like_real (convs, expr, fn, argnum, inner)
          }
        else
          args = build_this (expr);
-       expr = build_over_call (cand, args, LOOKUP_NORMAL);
+       expr = build_over_call (cand, LOOKUP_NORMAL);
 
        /* If this is a constructor or a function returning an aggr type,
           we need to build up a TARGET_EXPR.  */
@@ -3996,6 +4144,12 @@ convert_like_real (convs, expr, fn, argnum, inner)
     case IDENTITY_CONV:
       if (type_unknown_p (expr))
        expr = instantiate_type (totype, expr, tf_error | tf_warning);
+      /* Convert a non-array constant variable to its underlying value, unless we
+        are about to bind it to a reference, in which case we need to
+        leave it as an lvalue.  */
+      if (inner >= 0
+         && TREE_CODE (TREE_TYPE (expr)) != ARRAY_TYPE)
+       expr = decl_constant_value (expr);
       return expr;
     case AMBIG_CONV:
       /* Call build_user_type_conversion again for the error.  */
@@ -4011,13 +4165,6 @@ convert_like_real (convs, expr, fn, argnum, inner)
   if (expr == error_mark_node)
     return error_mark_node;
 
-  /* Convert a non-array constant variable to its underlying value, unless we
-     are about to bind it to a reference, in which case we need to
-     leave it as an lvalue.  */
-  if (TREE_CODE (convs) != REF_BIND
-      && TREE_CODE (TREE_TYPE (expr)) != ARRAY_TYPE)
-    expr = decl_constant_value (expr);
-
   switch (TREE_CODE (convs))
     {
     case RVALUE_CONV:
@@ -4078,9 +4225,7 @@ convert_like_real (convs, expr, fn, argnum, inner)
        expr = cp_convert (build_pointer_type (TREE_TYPE (ref_type)), 
                           expr);
        /* Convert the pointer to the desired reference type.  */
-       expr = build1 (NOP_EXPR, ref_type, expr);
-
-       return expr;
+       return build_nop (ref_type, expr);
       }
 
     case LVALUE_CONV:
@@ -4101,7 +4246,7 @@ convert_like_real (convs, expr, fn, argnum, inner)
 /* Build a call to __builtin_trap which can be used in an expression.  */
 
 static tree
-call_builtin_trap ()
+call_builtin_trap (void)
 {
   tree fn = get_identifier ("__builtin_trap");
   if (IDENTIFIER_GLOBAL_VALUE (fn))
@@ -4119,8 +4264,7 @@ call_builtin_trap ()
    Return the converted value.  */
 
 tree
-convert_arg_to_ellipsis (arg)
-     tree arg;
+convert_arg_to_ellipsis (tree arg)
 {
   if (TREE_CODE (TREE_TYPE (arg)) == REAL_TYPE
       && (TYPE_PRECISION (TREE_TYPE (arg))
@@ -4150,9 +4294,7 @@ call will abort at runtime",
 /* va_arg (EXPR, TYPE) is a builtin. Make sure it is not abused.  */
 
 tree
-build_x_va_arg (expr, type)
-     tree expr;
-     tree type;
+build_x_va_arg (tree expr, tree type)
 {
   if (processing_template_decl)
     return build_min (VA_ARG_EXPR, type, expr);
@@ -4177,8 +4319,7 @@ build_x_va_arg (expr, type)
    type, or the passed type if there is no change.  */
 
 tree
-cxx_type_promotes_to (type)
-     tree type;
+cxx_type_promotes_to (tree type)
 {
   tree promote;
 
@@ -4200,30 +4341,16 @@ cxx_type_promotes_to (type)
    conversions.  Return the converted value.  */
 
 tree
-convert_default_arg (type, arg, fn, parmnum)
-     tree type;
-     tree arg;
-     tree fn;
-     int parmnum;
+convert_default_arg (tree type, tree arg, tree fn, int parmnum)
 {
+  /* If the ARG is an unparsed default argument expression, the
+     conversion cannot be performed.  */
   if (TREE_CODE (arg) == DEFAULT_ARG)
     {
-      /* When processing the default args for a class, we can find that
-         there is an ordering constraint, and we call a function who's
-         default args have not yet been converted. For instance,
-          class A {
-              A (int = 0);
-              void Foo (A const & = A ());
-          };
-         We must process A::A before A::Foo's default arg can be converted.
-         Remember the dependent function, so do_pending_defargs can retry,
-         and check loops.  */
-      unprocessed_defarg_fn (fn);
-      
-      /* Don't return error_mark node, as we won't be able to distinguish
-         genuine errors from this case, and that would lead to repeated
-         diagnostics.  Just make something of the right type.  */
-      return build1 (NOP_EXPR, type, integer_zero_node);
+      error ("the default argument for parameter %d of `%D' has "
+            "not yet been parsed",
+            parmnum, fn);
+      return error_mark_node;
     }
 
   if (fn && DECL_TEMPLATE_INFO (fn))
@@ -4255,8 +4382,7 @@ convert_default_arg (type, arg, fn, parmnum)
    type TYPE.  */
 
 tree
-type_passed_as (type)
-     tree type;
+type_passed_as (tree type)
 {
   /* Pass classes with copy ctors by invisible reference.  */
   if (TREE_ADDRESSABLE (type))
@@ -4272,11 +4398,12 @@ type_passed_as (type)
 /* Actually perform the appropriate conversion.  */
 
 tree
-convert_for_arg_passing (type, val)
-     tree type, val;
+convert_for_arg_passing (tree type, tree val)
 {
+  if (val == error_mark_node)
+    ;
   /* Pass classes with copy ctors by invisible reference.  */
-  if (TREE_ADDRESSABLE (type))
+  else if (TREE_ADDRESSABLE (type))
     val = build1 (ADDR_EXPR, build_reference_type (type), val);
   else if (PROMOTE_PROTOTYPES
           && INTEGRAL_TYPE_P (type)
@@ -4285,32 +4412,16 @@ convert_for_arg_passing (type, val)
   return val;
 }
 
-/* Convert VALUE for assignment into inlined parameter PARM.  */
-
-tree
-cp_convert_parm_for_inlining (parm, value, fn)
-     tree parm, value;
-     tree fn ATTRIBUTE_UNUSED;
-{
-  /* When inlining, we don't need to mess with invisible references, so
-     undo the ADDR_EXPR.  */
-  if (TREE_ADDRESSABLE (TREE_TYPE (parm)))
-    value = build_indirect_ref (value, NULL);
-  return value;
-}
-
 /* Subroutine of the various build_*_call functions.  Overload resolution
    has chosen a winning candidate CAND; build up a CALL_EXPR accordingly.
    ARGS is a TREE_LIST of the unconverted arguments to the call.  FLAGS is a
    bitmask of various LOOKUP_* flags which apply to the call itself.  */
 
 static tree
-build_over_call (cand, args, flags)
-     struct z_candidate *cand;
-     tree args;
-     int flags;
+build_over_call (struct z_candidate *cand, int flags)
 {
   tree fn = cand->fn;
+  tree args = cand->args;
   tree convs = cand->convs;
   tree converted_args = NULL_TREE;
   tree parm = TYPE_ARG_TYPES (TREE_TYPE (fn));
@@ -4469,12 +4580,12 @@ build_over_call (cand, args, flags)
          temp or an INIT_EXPR otherwise.  */
       if (integer_zerop (TREE_VALUE (args)))
        {
-         if (! real_lvalue_p (arg))
+         if (TREE_CODE (arg) == TARGET_EXPR)
            return arg;
          else if (TYPE_HAS_TRIVIAL_INIT_REF (DECL_CONTEXT (fn)))
            return build_target_expr_with_type (arg, DECL_CONTEXT (fn));
        }
-      else if (!real_lvalue_p (arg)
+      else if (TREE_CODE (arg) == TARGET_EXPR
               || TYPE_HAS_TRIVIAL_INIT_REF (DECL_CONTEXT (fn)))
        {
          tree address;
@@ -4507,7 +4618,7 @@ build_over_call (cand, args, flags)
     {
       tree t, *p = &TREE_VALUE (converted_args);
       tree binfo = lookup_base (TREE_TYPE (TREE_TYPE (*p)),
-                               DECL_VIRTUAL_CONTEXT (fn),
+                               DECL_CONTEXT (fn),
                                ba_any, NULL);
       my_friendly_assert (binfo && binfo != error_mark_node, 20010730);
       
@@ -4560,8 +4671,7 @@ static GTY(()) tree java_iface_lookup_fn;
    _Jv_LookupInterfaceMethodIdx().  */
 
 static tree
-build_java_interface_fn_ref (fn, instance)
-    tree fn, instance;
+build_java_interface_fn_ref (tree fn, tree instance)
 {
   tree lookup_args, lookup_fn, method, idx;
   tree klass_ref, iface, iface_ref;
@@ -4587,7 +4697,7 @@ build_java_interface_fn_ref (fn, instance)
 
   /* Get the java.lang.Class pointer for the interface being called.  */
   iface = DECL_CONTEXT (fn);
-  iface_ref = lookup_field (iface, get_identifier ("class$"), 0, 0);
+  iface_ref = lookup_field (iface, get_identifier ("class$"), 0, false);
   if (!iface_ref || TREE_CODE (iface_ref) != VAR_DECL
       || DECL_CONTEXT (iface_ref) != iface)
     {
@@ -4622,8 +4732,7 @@ build_java_interface_fn_ref (fn, instance)
    call to a function with the indicated NAME.  */
 
 tree
-in_charge_arg_for_name (name)
-     tree name;
+in_charge_arg_for_name (tree name)
 {
   if (name == base_ctor_identifier
       || name == base_dtor_identifier)
@@ -4705,15 +4814,13 @@ build_special_member_call (tree instance, tree name, tree args,
       /* If the current function is a complete object constructor
         or destructor, then we fetch the VTT directly.
         Otherwise, we look it up using the VTT we were given.  */
-      vtt = IDENTIFIER_GLOBAL_VALUE (get_vtt_name (current_class_type));
+      vtt = TREE_CHAIN (CLASSTYPE_VTABLES (current_class_type));
       vtt = decay_conversion (vtt);
       vtt = build (COND_EXPR, TREE_TYPE (vtt),
                   build (EQ_EXPR, boolean_type_node,
                          current_in_charge_parm, integer_zero_node),
                   current_vtt_parm,
                   vtt);
-      if (TREE_VIA_VIRTUAL (binfo))
-       binfo = binfo_for_vbase (class_type, current_class_type);
       my_friendly_assert (BINFO_SUBVTT_INDEX (binfo), 20010110);
       sub_vtt = build (PLUS_EXPR, TREE_TYPE (vtt), vtt,
                       BINFO_SUBVTT_INDEX (binfo));
@@ -4724,6 +4831,42 @@ build_special_member_call (tree instance, tree name, tree args,
   return build_new_method_call (instance, fns, args, binfo, flags);
 }
 
+/* Return the NAME, as a C string.  The NAME indicates a function that
+   is a member of TYPE.  *FREE_P is set to true if the caller must
+   free the memory returned.  
+
+   Rather than go through all of this, we should simply set the names
+   of constructors and destructors appropriately, and dispense with
+   ctor_identifier, dtor_identifier, etc.  */
+
+static char *
+name_as_c_string (tree name, tree type, bool *free_p)
+{
+  char *pretty_name;
+
+  /* Assume that we will not allocate memory.  */
+  *free_p = false;
+  /* Constructors and destructors are special.  */
+  if (IDENTIFIER_CTOR_OR_DTOR_P (name))
+    {
+      pretty_name 
+       = (char *) IDENTIFIER_POINTER (constructor_name (type));
+      /* For a destructor, add the '~'.  */
+      if (name == complete_dtor_identifier
+         || name == base_dtor_identifier
+         || name == deleting_dtor_identifier)
+       {
+         pretty_name = concat ("~", pretty_name, NULL);
+         /* Remember that we need to free the memory allocated.  */
+         *free_p = true;
+       }
+    }
+  else
+    pretty_name = (char *) IDENTIFIER_POINTER (name);
+
+  return pretty_name;
+}
+
 /* Build a call to "INSTANCE.FN (ARGS)".  */
 
 tree
@@ -4736,15 +4879,17 @@ build_new_method_call (tree instance, tree fns, tree args,
   tree access_binfo;
   tree optype;
   tree mem_args = NULL_TREE, instance_ptr;
-  tree name, pretty_name;
+  tree name;
   tree user_args;
-  tree templates = NULL_TREE;
   tree call;
+  tree fn;
+  tree class_type;
   int template_only = 0;
 
   my_friendly_assert (instance != NULL_TREE, 20020729);
 
-  if (instance == error_mark_node || fns == error_mark_node 
+  if (error_operand_p (instance) 
+      || error_operand_p (fns)
       || args == error_mark_node)
     return error_mark_node;
 
@@ -4798,7 +4943,8 @@ build_new_method_call (tree instance, tree fns, tree args,
       return error_mark_node;
     }
 
-  name = DECL_NAME (get_first_fn (fns));
+  fn = get_first_fn (fns);
+  name = DECL_NAME (fn);
 
   if (IDENTIFIER_CTOR_OR_DTOR_P (name))
     {
@@ -4807,61 +4953,52 @@ build_new_method_call (tree instance, tree fns, tree args,
       my_friendly_assert (name != ctor_identifier, 20000408);
       /* Similarly for destructors.  */
       my_friendly_assert (name != dtor_identifier, 20000408);
-      
-      if (name == complete_ctor_identifier
-         || name == base_ctor_identifier)
-       pretty_name = constructor_name (basetype);
-      else
-       pretty_name = dtor_identifier;
     }
-  else
-    pretty_name = name;
 
-  if (fns)
+  /* It's OK to call destructors on cv-qualified objects.  Therefore,
+     convert the INSTANCE_PTR to the unqualified type, if necessary.  */
+  if (DECL_DESTRUCTOR_P (fn))
     {
-      tree fn;
-      tree class_type = (conversion_path 
-                        ? BINFO_TYPE (conversion_path)
-                        : NULL_TREE);
+      tree type = build_pointer_type (basetype);
+      if (!same_type_p (type, TREE_TYPE (instance_ptr)))
+       instance_ptr = build_nop (type, instance_ptr);
+    }
 
-      mem_args = tree_cons (NULL_TREE, instance_ptr, args);
-      for (fn = fns; fn; fn = OVL_NEXT (fn))
-       {
-         tree t = OVL_CURRENT (fn);
-         tree this_arglist;
+  class_type = (conversion_path ? BINFO_TYPE (conversion_path) : NULL_TREE);
+  mem_args = tree_cons (NULL_TREE, instance_ptr, args);
 
-         /* We can end up here for copy-init of same or base class.  */
-         if ((flags & LOOKUP_ONLYCONVERTING)
-             && DECL_NONCONVERTING_P (t))
-           continue;
+  for (fn = fns; fn; fn = OVL_NEXT (fn))
+    {
+      tree t = OVL_CURRENT (fn);
+      tree this_arglist;
 
-         if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
-           this_arglist = mem_args;
-         else
-           this_arglist = args;
+      /* We can end up here for copy-init of same or base class.  */
+      if ((flags & LOOKUP_ONLYCONVERTING)
+         && DECL_NONCONVERTING_P (t))
+       continue;
 
-         if (TREE_CODE (t) == TEMPLATE_DECL)
-           {
-             /* A member template.  */
-             templates = tree_cons (NULL_TREE, t, templates);
-             candidates = 
-               add_template_candidate (candidates, t, 
-                                       class_type,
-                                       explicit_targs,
-                                       this_arglist, optype,
-                                       access_binfo, 
-                                       conversion_path,
-                                       flags,
-                                       DEDUCE_CALL);
-           }
-         else if (! template_only)
-           candidates = add_function_candidate (candidates, t, 
-                                                class_type,
-                                                this_arglist,
-                                                access_binfo,
-                                                conversion_path,
-                                                flags);
-       }
+      if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
+       this_arglist = mem_args;
+      else
+       this_arglist = args;
+
+      if (TREE_CODE (t) == TEMPLATE_DECL)
+       /* A member template.  */
+       add_template_candidate (&candidates, t, 
+                               class_type,
+                               explicit_targs,
+                               this_arglist, optype,
+                               access_binfo, 
+                               conversion_path,
+                               flags,
+                               DEDUCE_CALL);
+      else if (! template_only)
+       add_function_candidate (&candidates, t, 
+                               class_type,
+                               this_arglist,
+                               access_binfo,
+                               conversion_path,
+                               flags);
     }
 
   if (! any_viable (candidates))
@@ -4872,9 +5009,17 @@ build_new_method_call (tree instance, tree fns, tree args,
       if (!COMPLETE_TYPE_P (basetype))
        cxx_incomplete_type_error (instance_ptr, basetype);
       else
-       error ("no matching function for call to `%T::%D(%A)%#V'",
-              basetype, pretty_name, user_args,
-              TREE_TYPE (TREE_TYPE (instance_ptr)));
+       {
+         char *pretty_name;
+         bool free_p;
+
+         pretty_name = name_as_c_string (name, basetype, &free_p);
+         error ("no matching function for call to `%T::%s(%A)%#V'",
+                basetype, pretty_name, user_args,
+                TREE_TYPE (TREE_TYPE (instance_ptr)));
+         if (free_p)
+           free (pretty_name);
+       }
       print_z_candidates (candidates);
       return error_mark_node;
     }
@@ -4883,9 +5028,15 @@ build_new_method_call (tree instance, tree fns, tree args,
 
   if (cand == 0)
     {
-      error ("call of overloaded `%D(%A)' is ambiguous", pretty_name,
-               user_args);
+      char *pretty_name;
+      bool free_p;
+
+      pretty_name = name_as_c_string (name, basetype, &free_p);
+      error ("call of overloaded `%s(%A)' is ambiguous", pretty_name,
+            user_args);
       print_z_candidates (candidates);
+      if (free_p)
+       free (pretty_name);
       return error_mark_node;
     }
 
@@ -4911,25 +5062,24 @@ build_new_method_call (tree instance, tree fns, tree args,
     flags |= LOOKUP_NONVIRTUAL;
 
   if (TREE_CODE (TREE_TYPE (cand->fn)) == METHOD_TYPE)
-    call = build_over_call (cand, mem_args, flags);
+    call = build_over_call (cand, flags);
   else
     {
-      call = build_over_call (cand, args, flags);
+      call = build_over_call (cand, flags);
       /* In an expression of the form `a->f()' where `f' turns out to
         be a static member function, `a' is none-the-less evaluated.  */
-      if (instance && TREE_SIDE_EFFECTS (instance))
+      if (!is_dummy_object (instance_ptr) && TREE_SIDE_EFFECTS (instance))
        call = build (COMPOUND_EXPR, TREE_TYPE (call), instance, call);
     }
 
   return call;
 }
 
-/* Returns nonzero iff standard conversion sequence ICS1 is a proper
+/* Returns true iff standard conversion sequence ICS1 is a proper
    subsequence of ICS2.  */
 
-static int
-is_subseq (ics1, ics2)
-     tree ics1, ics2;
+static bool
+is_subseq (tree ics1, tree ics2)
 {
   /* We can assume that a conversion of the same code
      between the same types indicates a subsequence since we only get
@@ -4952,7 +5102,7 @@ is_subseq (ics1, ics2)
           ICS2.  We can get a USER_CONV when we are comparing the
           second standard conversion sequence of two user conversion
           sequences.  */
-       return 0;
+       return false;
 
       ics2 = TREE_OPERAND (ics2, 0);
 
@@ -4960,21 +5110,19 @@ is_subseq (ics1, ics2)
          && same_type_p (TREE_TYPE (ics2), TREE_TYPE (ics1))
          && same_type_p (TREE_TYPE (TREE_OPERAND (ics2, 0)),
                             TREE_TYPE (TREE_OPERAND (ics1, 0))))
-       return 1;
+       return true;
     }
 }
 
 /* Returns nonzero iff DERIVED is derived from BASE.  The inputs may
    be any _TYPE nodes.  */
 
-int
-is_properly_derived_from (derived, base)
-     tree derived;
-     tree base;
+bool
+is_properly_derived_from (tree derived, tree base)
 {
   if (!IS_AGGR_TYPE_CODE (TREE_CODE (derived))
       || !IS_AGGR_TYPE_CODE (TREE_CODE (base)))
-    return 0;
+    return false;
 
   /* We only allow proper derivation here.  The DERIVED_FROM_P macro
      considers every class derived from itself.  */
@@ -4989,8 +5137,7 @@ is_properly_derived_from (derived, base)
    modify it accordingly.  */
 
 static void
-maybe_handle_implicit_object (ics)
-     tree* ics;
+maybe_handle_implicit_object (tree *ics)
 {
   if (ICS_THIS_FLAG (*ics))
     {
@@ -5025,8 +5172,7 @@ maybe_handle_implicit_object (ics)
    leave *ICS unchanged and return NULL_TREE.  */
 
 static tree
-maybe_handle_ref_bind (ics)
-     tree* ics;
+maybe_handle_ref_bind (tree *ics)
 {
   if (TREE_CODE (*ics) == REF_BIND)
     {
@@ -5049,8 +5195,7 @@ maybe_handle_ref_bind (ics)
       0: ics1 and ics2 are indistinguishable */
 
 static int
-compare_ics (ics1, ics2)
-     tree ics1, ics2;
+compare_ics (tree ics1, tree ics2)
 {
   tree from_type1;
   tree from_type2;
@@ -5386,8 +5531,7 @@ compare_ics (ics1, ics2)
 /* The source type for this standard conversion sequence.  */
 
 static tree
-source_type (t)
-     tree t;
+source_type (tree t)
 {
   for (;; t = TREE_OPERAND (t, 0))
     {
@@ -5404,8 +5548,7 @@ source_type (t)
    is actually used.  */
 
 static void
-add_warning (winner, loser)
-     struct z_candidate *winner, *loser;
+add_warning (struct z_candidate *winner, struct z_candidate *loser)
 {
   winner->warnings = tree_cons (NULL_TREE,
                                build_zc_wrapper (loser),
@@ -5417,9 +5560,7 @@ add_warning (winner, loser)
    both are extern "C".  */
 
 static inline int
-equal_functions (fn1, fn2)
-     tree fn1;
-     tree fn2;
+equal_functions (tree fn1, tree fn2)
 {
   if (DECL_LOCAL_FUNCTION_P (fn1) || DECL_LOCAL_FUNCTION_P (fn2)
       || DECL_EXTERN_C_FUNCTION_P (fn1))
@@ -5435,9 +5576,7 @@ equal_functions (fn1, fn2)
       0: cand1 and cand2 are indistinguishable */
 
 static int
-joust (cand1, cand2, warn)
-     struct z_candidate *cand1, *cand2;
-     int warn;
+joust (struct z_candidate *cand1, struct z_candidate *cand2, bool warn)
 {
   int winner = 0;
   int i, off1 = 0, off2 = 0, len;
@@ -5711,8 +5850,7 @@ tweak:
    algorithm.  */
 
 static struct z_candidate *
-tourney (candidates)
-     struct z_candidate *candidates;
+tourney (struct z_candidate *candidates)
 {
   struct z_candidate *champ = candidates, *challenger;
   int fate;
@@ -5763,18 +5901,16 @@ tourney (candidates)
 
 /* Returns nonzero if things of type FROM can be converted to TO.  */
 
-int
-can_convert (to, from)
-     tree to, from;
+bool
+can_convert (tree to, tree from)
 {
   return can_convert_arg (to, from, NULL_TREE);
 }
 
 /* Returns nonzero if ARG (of type FROM) can be converted to TO.  */
 
-int
-can_convert_arg (to, from, arg)
-     tree to, from, arg;
+bool
+can_convert_arg (tree to, tree from, tree arg)
 {
   tree t = implicit_conversion (to, from, arg, LOOKUP_NORMAL);
   return (t && ! ICS_BAD_FLAG (t));
@@ -5782,12 +5918,10 @@ can_convert_arg (to, from, arg)
 
 /* Like can_convert_arg, but allows dubious conversions as well.  */
 
-int
-can_convert_arg_bad (to, from, arg)
-     tree to, from, arg;
+bool
+can_convert_arg_bad (tree to, tree from, tree arg)
 {
-  tree t = implicit_conversion (to, from, arg, LOOKUP_NORMAL);
-  return !!t;
+  return implicit_conversion (to, from, arg, LOOKUP_NORMAL) != 0;
 }
 
 /* Convert EXPR to TYPE.  Return the converted expression.
@@ -5797,13 +5931,11 @@ can_convert_arg_bad (to, from, arg)
    doing a bad conversion, convert_like will complain.  */
 
 tree
-perform_implicit_conversion (type, expr)
-     tree type;
-     tree expr;
+perform_implicit_conversion (tree type, tree expr)
 {
   tree conv;
   
-  if (expr == error_mark_node)
+  if (error_operand_p (expr))
     return error_mark_node;
   conv = implicit_conversion (type, TREE_TYPE (expr), expr,
                              LOOKUP_NORMAL);
@@ -5816,17 +5948,59 @@ perform_implicit_conversion (type, expr)
   return convert_like (conv, expr);
 }
 
+/* DECL is a VAR_DECL whose type is a REFERENCE_TYPE.  The reference
+   is being bound to a temporary.  Create and return a new VAR_DECL
+   with the indicated TYPE; this variable will store the value to
+   which the reference is bound.  */
+
+tree 
+make_temporary_var_for_ref_to_temp (tree decl, tree type)
+{
+  tree var;
+
+  /* Create the variable.  */
+  var = build_decl (VAR_DECL, NULL_TREE, type);
+  DECL_ARTIFICIAL (var) = 1;
+  TREE_USED (var) = 1;
+
+  /* Register the variable.  */
+  if (TREE_STATIC (decl))
+    {
+      /* Namespace-scope or local static; give it a mangled name.  */
+      tree name;
+
+      TREE_STATIC (var) = 1;
+      name = mangle_ref_init_variable (decl);
+      DECL_NAME (var) = name;
+      SET_DECL_ASSEMBLER_NAME (var, name);
+      var = pushdecl_top_level (var);
+    }
+  else
+    {
+      /* Create a new cleanup level if necessary.  */
+      maybe_push_cleanup_level (type);
+      /* Don't push unnamed temps.  Do set DECL_CONTEXT, though.  */
+      DECL_CONTEXT (var) = current_function_decl;
+    }
+
+  return var;
+}
+
 /* Convert EXPR to the indicated reference TYPE, in a way suitable for
-   initializing a variable of that TYPE.  Return the converted
-   expression.  */
+   initializing a variable of that TYPE.   If DECL is non-NULL, it is
+   the VAR_DECL being initialized with the EXPR.  (In that case, the
+   type of DECL will be TYPE.)
+
+   Return the converted expression.  */
 
 tree
-initialize_reference (type, expr)
-     tree type;
-     tree expr;
+initialize_reference (tree type, tree expr, tree decl)
 {
   tree conv;
 
+  if (type == error_mark_node || error_operand_p (expr))
+    return error_mark_node;
+
   conv = reference_binding (type, TREE_TYPE (expr), expr, LOOKUP_NORMAL);
   if (!conv || ICS_BAD_FLAG (conv))
     {
@@ -5834,6 +6008,81 @@ initialize_reference (type, expr)
       return error_mark_node;
     }
 
+  /* If DECL is non-NULL, then this special rule applies:
+
+       [class.temporary]
+
+       The temporary to which the reference is bound or the temporary
+       that is the complete object to which the reference is bound
+       persists for the lifetime of the reference.
+
+       The temporaries created during the evaluation of the expression
+       initializing the reference, except the temporary to which the
+       reference is bound, are destroyed at the end of the
+       full-expression in which they are created.
+
+     In that case, we store the converted expression into a new
+     VAR_DECL in a new scope.  
+
+     However, we want to be careful not to create temporaries when
+     they are not required.  For example, given:
+
+       struct B {}; 
+       struct D : public B {};
+       D f();
+       const B& b = f();
+
+     there is no need to copy the return value from "f"; we can just
+     extend its lifetime.  Similarly, given:
+
+       struct S {};
+       struct T { operator S(); };
+       T t;
+       const S& s = t;
+
+    we can extend the lifetime of the returnn value of the conversion
+    operator.  */
+  my_friendly_assert (TREE_CODE (conv) == REF_BIND, 20030302);
+  if (decl)
+    {
+      tree var;
+      tree base_conv_type;
+
+      /* Skip over the REF_BIND.  */
+      conv = TREE_OPERAND (conv, 0);
+      /* If the next conversion is a BASE_CONV, skip that too -- but
+        remember that the conversion was required.  */
+      if (TREE_CODE (conv) == BASE_CONV)
+       {
+         my_friendly_assert (!NEED_TEMPORARY_P (conv), 20030307);
+         base_conv_type = TREE_TYPE (conv);
+         conv = TREE_OPERAND (conv, 0);
+       }
+      else
+       base_conv_type = NULL_TREE;
+      /* Perform the remainder of the conversion.  */
+      expr = convert_like (conv, expr);
+      if (!real_non_cast_lvalue_p (expr))
+       {
+         /* Create the temporary variable.  */
+         var = make_temporary_var_for_ref_to_temp (decl, TREE_TYPE (expr));
+         DECL_INITIAL (var) = expr;
+         cp_finish_decl (var, expr, NULL_TREE, 
+                     LOOKUP_ONLYCONVERTING|DIRECT_BIND);
+         /* Use its address to initialize the reference variable.  */
+         expr = build_address (var);
+       }
+      else
+       /* Take the address of EXPR.  */
+       expr = build_unary_op (ADDR_EXPR, expr, 0);
+      /* If a BASE_CONV was required, perform it now.  */
+      if (base_conv_type)
+       expr = (perform_implicit_conversion 
+               (build_pointer_type (base_conv_type), expr));
+      return build_nop (type, expr);
+    }
+
+  /* Perform the conversion.  */
   return convert_like (conv, expr);
 }