From: Jason Merrill Date: Tue, 24 Nov 1998 02:33:48 +0000 (+0000) Subject: class.c (add_method): Build up OVERLOADs properly for conversion ops. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=37b6eb345f9504a6b4543a9b1ecceb965556173d;p=gcc.git 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 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 6e403361efe..92fed9792e4 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,17 @@ +1998-11-24 Jason Merrill + + * 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 * typeck2.c (process_init_constructor): If there are elements diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 380033054bd..8904aa1ccc9 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -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) ", str, candidates->fn, TREE_TYPE (TREE_VEC_ELT (candidates->convs, 0))); } + else if (TYPE_P (candidates->fn)) + cp_error ("%s %T ", str, candidates->fn); else cp_error_at ("%s %+D%s", str, candidates->fn, candidates->viable == -1 ? " " : ""); @@ -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 diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 8adeac6dbb2..de283eae2dd 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -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 diff --git a/gcc/cp/search.c b/gcc/cp/search.c index 8c335b0acbc..d0ae536ea7a 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -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; }