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
This commit is contained in:
parent
52e1eb536c
commit
37b6eb345f
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue