class.c (add_method): Build up OVERLOADs properly for conversion ops.
authorJason Merrill <jason@yorick.cygnus.com>
Tue, 24 Nov 1998 02:33:48 +0000 (02:33 +0000)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 24 Nov 1998 02:33:48 +0000 (21:33 -0500)
* class.c (add_method): Build up OVERLOADs properly for conversion ops.
* search.c (lookup_conversions): Handle getting real OVERLOADs.
(add_conversions): Likewise.  Revert last change.
* call.c (add_conv_candidate): Pass totype to add_candidate instead
of fn.  Don't add a new candidate if the last one was for the same
type.
(print_z_candidates): Handle getting a type as a function.
(joust): If we got two conversion candidates to the same type,
just pick one.
(build_object_call): Lose 'templates'.
(build_user_type_conversion_1): Handle getting real OVERLOADs.
Fixes g++.jason/overload7.C.

From-SVN: r23822

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/class.c
gcc/cp/search.c

index 6e403361efe285bc0c94a61f57bab1cfd5fcfd5a..92fed9792e49ee2b7bb5aa016f71d2bbe5905bf2 100644 (file)
@@ -1,3 +1,17 @@
+1998-11-24  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * class.c (add_method): Build up OVERLOADs properly for conversion ops.
+       * search.c (lookup_conversions): Handle getting real OVERLOADs.
+       (add_conversions): Likewise.  Revert last change.
+       * call.c (add_conv_candidate): Pass totype to add_candidate instead
+       of fn.  Don't add a new candidate if the last one was for the same 
+       type.
+       (print_z_candidates): Handle getting a type as a function.
+       (joust): If we got two conversion candidates to the same type, 
+       just pick one.
+       (build_object_call): Lose 'templates'.
+       (build_user_type_conversion_1): Handle getting real OVERLOADs.
+
 1998-11-23  Jason Merrill  <jason@yorick.cygnus.com>
 
        * typeck2.c (process_init_constructor): If there are elements
index 380033054bddd3a46e779da1a17b19aaca4a2c6f..8904aa1ccc9de4988ec352350f7bf1a403fc5790 100644 (file)
@@ -1217,7 +1217,13 @@ add_function_candidate (candidates, fn, arglist, flags)
 /* Create an overload candidate for the conversion function FN which will
    be invoked for expression OBJ, producing a pointer-to-function which
    will in turn be called with the argument list ARGLIST, and add it to
-   CANDIDATES.  FLAGS is passed on to implicit_conversion.  */
+   CANDIDATES.  FLAGS is passed on to implicit_conversion.
+
+   Actually, we don't really care about FN; we care about the type it
+   converts to.  There may be multiple conversion functions that will
+   convert to that type, and we rely on build_user_type_conversion_1 to
+   choose the best one; so when we create our candidate, we record the type
+   instead of the function.  */
 
 static struct z_candidate *
 add_conv_candidate (candidates, fn, obj, arglist)
@@ -1233,6 +1239,10 @@ add_conv_candidate (candidates, fn, obj, arglist)
   int viable = 1;
   int flags = LOOKUP_NORMAL;
 
+  /* Don't bother looking up the same type twice.  */
+  if (candidates && candidates->fn == totype)
+    return candidates;
+
   for (i = 0; i < len; ++i)
     {
       tree arg = i == 0 ? obj : TREE_VALUE (argnode);
@@ -1277,7 +1287,7 @@ add_conv_candidate (candidates, fn, obj, arglist)
        break;
       }
 
-  return add_candidate (candidates, fn, convs, viable);
+  return add_candidate (candidates, totype, convs, viable);
 }
 
 static struct z_candidate *
@@ -2058,6 +2068,8 @@ print_z_candidates (candidates)
            cp_error ("%s %D(%T) <builtin>", str, candidates->fn,
                      TREE_TYPE (TREE_VEC_ELT (candidates->convs, 0)));
        }
+      else if (TYPE_P (candidates->fn))
+       cp_error ("%s %T <conversion>", str, candidates->fn);
       else
        cp_error_at ("%s %+D%s", str, candidates->fn,
                     candidates->viable == -1 ? " <near match>" : "");
@@ -2143,7 +2155,7 @@ build_user_type_conversion_1 (totype, expr, flags)
       if (TREE_CODE (totype) == REFERENCE_TYPE)
        convflags |= LOOKUP_NO_TEMP_BIND;
 
-      if (TREE_CODE (fns) != TEMPLATE_DECL)
+      if (TREE_CODE (OVL_CURRENT (fns)) != TEMPLATE_DECL)
        ics = implicit_conversion
          (totype, TREE_TYPE (TREE_TYPE (OVL_CURRENT (fns))), 0, convflags);
       else
@@ -2369,7 +2381,6 @@ build_object_call (obj, args)
   struct z_candidate *candidates = 0, *cand;
   tree fns, convs, mem_args = NULL_TREE;
   tree type = TREE_TYPE (obj);
-  tree templates = NULL_TREE;
 
   if (TYPE_PTRMEMFUNC_P (type))
     {
@@ -2399,7 +2410,6 @@ build_object_call (obj, args)
          tree fn = OVL_CURRENT (fns);
          if (TREE_CODE (fn) == TEMPLATE_DECL)
            {
-             templates = scratch_tree_cons (NULL_TREE, fn, templates);
              candidates 
                = add_template_candidate (candidates, fn, NULL_TREE,
                                          mem_args, NULL_TREE, 
@@ -2429,7 +2439,6 @@ build_object_call (obj, args)
            tree fn = OVL_CURRENT (fns);
            if (TREE_CODE (fn) == TEMPLATE_DECL) 
              {
-               templates = scratch_tree_cons (NULL_TREE, fn, templates);
                candidates = add_template_conv_candidate (candidates,
                                                          fn,
                                                          obj,
@@ -4219,6 +4228,11 @@ joust (cand1, cand2, warn)
   if (cand1->viable < cand2->viable)
     return -1;
 
+  /* If we have two pseudo-candidates for conversions to the same type,
+     arbitrarily pick one.  */
+  if (TYPE_P (cand1->fn) && cand1->fn == cand2->fn)
+    return 1;
+
   /* a viable function F1
      is defined to be a better function than another viable function F2  if
      for  all arguments i, ICSi(F1) is not a worse conversion sequence than
index 8adeac6dbb21db6b22fab5be5c0cdb14d102ea2d..de283eae2ddea8c5b6b35cbc6983e796f07a75e5 100644 (file)
@@ -1235,7 +1235,9 @@ add_method (type, fields, method)
                }
            }
 
-         if (DECL_CONV_FN_P (method))
+         if (TREE_VEC_ELT (method_vec, i))
+           /* We found a match.  */;
+         else if (DECL_CONV_FN_P (method))
            {
              /* Type conversion operators have to come before
                 ordinary methods; add_conversions depends on this to
index 8c335b0acbc32d43bf65deb436b23fcbbddb29d4..d0ae536ea7aee03be65ff0a91eb73dbd189f96bd 100644 (file)
@@ -3302,40 +3302,24 @@ add_conversions (binfo)
 {
   int i;
   tree method_vec = CLASSTYPE_METHOD_VEC (BINFO_TYPE (binfo));
-  tree name = NULL_TREE;
 
   for (i = 2; i < TREE_VEC_LENGTH (method_vec); ++i)
     {
       tree tmp = TREE_VEC_ELT (method_vec, i);
+      tree name;
 
       if (!tmp || ! DECL_CONV_FN_P (OVL_CURRENT (tmp)))
        break;
 
-      if (TREE_CODE (tmp) == OVERLOAD)
-       {
-         my_friendly_assert (TREE_CHAIN (tmp) == NULL_TREE, 981121);
-         tmp = OVL_FUNCTION (tmp);
-       }
-
-      /* We don't want to mark 'name' until we've seen all the overloads
-        in this class; we could be overloading on the quals of 'this'.  */
-      if (name && name != DECL_NAME (tmp))
-       {
-         IDENTIFIER_MARKED (name) = 1;
-         name = NULL_TREE;
-       }
+      name = DECL_NAME (OVL_CURRENT (tmp));
 
       /* Make sure we don't already have this conversion.  */
-      if (! IDENTIFIER_MARKED (DECL_NAME (tmp)))
+      if (! IDENTIFIER_MARKED (name))
        {
          conversions = scratch_tree_cons (binfo, tmp, conversions);
-         name = DECL_NAME (tmp);
+         IDENTIFIER_MARKED (name) = 1;
        }
     }
-
-  if (name)
-     IDENTIFIER_MARKED (name) = 1;
-
   return NULL_TREE;
 }
 
@@ -3351,7 +3335,7 @@ lookup_conversions (type)
     breadth_first_search (TYPE_BINFO (type), add_conversions, 0);
 
   for (t = conversions; t; t = TREE_CHAIN (t))
-    IDENTIFIER_MARKED (DECL_NAME (TREE_VALUE (t))) = 0;
+    IDENTIFIER_MARKED (DECL_NAME (OVL_CURRENT (TREE_VALUE (t)))) = 0;
 
   return conversions;
 }