+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
/* 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)
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);
break;
}
- return add_candidate (candidates, fn, convs, viable);
+ return add_candidate (candidates, totype, convs, viable);
}
static struct z_candidate *
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>" : "");
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
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))
{
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,
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,
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
{
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;
}
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;
}