Commit 37b6eb34 by Jason Merrill Committed by Jason Merrill

class.c (add_method): Build up OVERLOADs properly for conversion ops.

	* 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
parent 52e1eb53
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> 1998-11-23 Jason Merrill <jason@yorick.cygnus.com>
* typeck2.c (process_init_constructor): If there are elements * typeck2.c (process_init_constructor): If there are elements
......
...@@ -1217,7 +1217,13 @@ add_function_candidate (candidates, fn, arglist, flags) ...@@ -1217,7 +1217,13 @@ add_function_candidate (candidates, fn, arglist, flags)
/* Create an overload candidate for the conversion function FN which will /* Create an overload candidate for the conversion function FN which will
be invoked for expression OBJ, producing a pointer-to-function which 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 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 * static struct z_candidate *
add_conv_candidate (candidates, fn, obj, arglist) add_conv_candidate (candidates, fn, obj, arglist)
...@@ -1233,6 +1239,10 @@ add_conv_candidate (candidates, fn, obj, arglist) ...@@ -1233,6 +1239,10 @@ add_conv_candidate (candidates, fn, obj, arglist)
int viable = 1; int viable = 1;
int flags = LOOKUP_NORMAL; 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) for (i = 0; i < len; ++i)
{ {
tree arg = i == 0 ? obj : TREE_VALUE (argnode); tree arg = i == 0 ? obj : TREE_VALUE (argnode);
...@@ -1277,7 +1287,7 @@ add_conv_candidate (candidates, fn, obj, arglist) ...@@ -1277,7 +1287,7 @@ add_conv_candidate (candidates, fn, obj, arglist)
break; break;
} }
return add_candidate (candidates, fn, convs, viable); return add_candidate (candidates, totype, convs, viable);
} }
static struct z_candidate * static struct z_candidate *
...@@ -2058,6 +2068,8 @@ print_z_candidates (candidates) ...@@ -2058,6 +2068,8 @@ print_z_candidates (candidates)
cp_error ("%s %D(%T) <builtin>", str, candidates->fn, cp_error ("%s %D(%T) <builtin>", str, candidates->fn,
TREE_TYPE (TREE_VEC_ELT (candidates->convs, 0))); TREE_TYPE (TREE_VEC_ELT (candidates->convs, 0)));
} }
else if (TYPE_P (candidates->fn))
cp_error ("%s %T <conversion>", str, candidates->fn);
else else
cp_error_at ("%s %+D%s", str, candidates->fn, cp_error_at ("%s %+D%s", str, candidates->fn,
candidates->viable == -1 ? " <near match>" : ""); candidates->viable == -1 ? " <near match>" : "");
...@@ -2143,7 +2155,7 @@ build_user_type_conversion_1 (totype, expr, flags) ...@@ -2143,7 +2155,7 @@ build_user_type_conversion_1 (totype, expr, flags)
if (TREE_CODE (totype) == REFERENCE_TYPE) if (TREE_CODE (totype) == REFERENCE_TYPE)
convflags |= LOOKUP_NO_TEMP_BIND; convflags |= LOOKUP_NO_TEMP_BIND;
if (TREE_CODE (fns) != TEMPLATE_DECL) if (TREE_CODE (OVL_CURRENT (fns)) != TEMPLATE_DECL)
ics = implicit_conversion ics = implicit_conversion
(totype, TREE_TYPE (TREE_TYPE (OVL_CURRENT (fns))), 0, convflags); (totype, TREE_TYPE (TREE_TYPE (OVL_CURRENT (fns))), 0, convflags);
else else
...@@ -2369,7 +2381,6 @@ build_object_call (obj, args) ...@@ -2369,7 +2381,6 @@ build_object_call (obj, args)
struct z_candidate *candidates = 0, *cand; struct z_candidate *candidates = 0, *cand;
tree fns, convs, mem_args = NULL_TREE; tree fns, convs, mem_args = NULL_TREE;
tree type = TREE_TYPE (obj); tree type = TREE_TYPE (obj);
tree templates = NULL_TREE;
if (TYPE_PTRMEMFUNC_P (type)) if (TYPE_PTRMEMFUNC_P (type))
{ {
...@@ -2399,7 +2410,6 @@ build_object_call (obj, args) ...@@ -2399,7 +2410,6 @@ build_object_call (obj, args)
tree fn = OVL_CURRENT (fns); tree fn = OVL_CURRENT (fns);
if (TREE_CODE (fn) == TEMPLATE_DECL) if (TREE_CODE (fn) == TEMPLATE_DECL)
{ {
templates = scratch_tree_cons (NULL_TREE, fn, templates);
candidates candidates
= add_template_candidate (candidates, fn, NULL_TREE, = add_template_candidate (candidates, fn, NULL_TREE,
mem_args, NULL_TREE, mem_args, NULL_TREE,
...@@ -2429,7 +2439,6 @@ build_object_call (obj, args) ...@@ -2429,7 +2439,6 @@ build_object_call (obj, args)
tree fn = OVL_CURRENT (fns); tree fn = OVL_CURRENT (fns);
if (TREE_CODE (fn) == TEMPLATE_DECL) if (TREE_CODE (fn) == TEMPLATE_DECL)
{ {
templates = scratch_tree_cons (NULL_TREE, fn, templates);
candidates = add_template_conv_candidate (candidates, candidates = add_template_conv_candidate (candidates,
fn, fn,
obj, obj,
...@@ -4219,6 +4228,11 @@ joust (cand1, cand2, warn) ...@@ -4219,6 +4228,11 @@ joust (cand1, cand2, warn)
if (cand1->viable < cand2->viable) if (cand1->viable < cand2->viable)
return -1; 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 /* a viable function F1
is defined to be a better function than another viable function F2 if 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 for all arguments i, ICSi(F1) is not a worse conversion sequence than
......
...@@ -1235,7 +1235,9 @@ add_method (type, fields, method) ...@@ -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 /* Type conversion operators have to come before
ordinary methods; add_conversions depends on this to ordinary methods; add_conversions depends on this to
......
...@@ -3302,40 +3302,24 @@ add_conversions (binfo) ...@@ -3302,40 +3302,24 @@ add_conversions (binfo)
{ {
int i; int i;
tree method_vec = CLASSTYPE_METHOD_VEC (BINFO_TYPE (binfo)); tree method_vec = CLASSTYPE_METHOD_VEC (BINFO_TYPE (binfo));
tree name = NULL_TREE;
for (i = 2; i < TREE_VEC_LENGTH (method_vec); ++i) for (i = 2; i < TREE_VEC_LENGTH (method_vec); ++i)
{ {
tree tmp = TREE_VEC_ELT (method_vec, i); tree tmp = TREE_VEC_ELT (method_vec, i);
tree name;
if (!tmp || ! DECL_CONV_FN_P (OVL_CURRENT (tmp))) if (!tmp || ! DECL_CONV_FN_P (OVL_CURRENT (tmp)))
break; break;
if (TREE_CODE (tmp) == OVERLOAD) name = DECL_NAME (OVL_CURRENT (tmp));
{
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;
}
/* Make sure we don't already have this conversion. */ /* 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); conversions = scratch_tree_cons (binfo, tmp, conversions);
name = DECL_NAME (tmp); IDENTIFIER_MARKED (name) = 1;
} }
} }
if (name)
IDENTIFIER_MARKED (name) = 1;
return NULL_TREE; return NULL_TREE;
} }
...@@ -3351,7 +3335,7 @@ lookup_conversions (type) ...@@ -3351,7 +3335,7 @@ lookup_conversions (type)
breadth_first_search (TYPE_BINFO (type), add_conversions, 0); breadth_first_search (TYPE_BINFO (type), add_conversions, 0);
for (t = conversions; t; t = TREE_CHAIN (t)) 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; return conversions;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment