From 277294d73bf540ec0f5bc320cebab7cfb43bacf3 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Tue, 3 Mar 1998 03:24:44 +0000 Subject: [PATCH] call.c, [...]: Remove support for -fno-ansi-overloading and overloading METHOD_CALL_EXPR. * call.c, class.c, cp-tree.h, cvt.c, decl.c, init.c, lex.c, method.c, pt.c, ptree.c, typeck.c: Remove support for -fno-ansi-overloading and overloading METHOD_CALL_EXPR. * class.h: Remove. * Makefile.in: Adjust. From-SVN: r18384 --- gcc/cp/ChangeLog | 6 + gcc/cp/Makefile.in | 6 +- gcc/cp/call.c | 2362 +------------------------------------------- gcc/cp/class.c | 2 +- gcc/cp/class.h | 117 --- gcc/cp/cp-tree.h | 16 - gcc/cp/cvt.c | 412 +------- gcc/cp/decl.c | 4 +- gcc/cp/decl2.c | 13 +- gcc/cp/init.c | 225 +---- gcc/cp/lex.c | 3 - gcc/cp/method.c | 393 +------- gcc/cp/pt.c | 34 +- gcc/cp/ptree.c | 2 - gcc/cp/typeck.c | 141 +-- 15 files changed, 61 insertions(+), 3675 deletions(-) delete mode 100644 gcc/cp/class.h diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 73b3b3ac190..54b45e1b30b 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,11 @@ Tue Mar 3 01:38:17 1998 Jason Merrill + * call.c, class.c, cp-tree.h, cvt.c, decl.c, init.c, lex.c, + method.c, pt.c, ptree.c, typeck.c: Remove support for + -fno-ansi-overloading and overloading METHOD_CALL_EXPR. + * class.h: Remove. + * Makefile.in: Adjust. + * pt.c (unify): Don't allow reduced cv-quals when strict. * call.c, class.c, pt.c, cp-tree.h: Remove nsubsts parm from diff --git a/gcc/cp/Makefile.in b/gcc/cp/Makefile.in index 9007bf28dab..a6f0f3cd1f6 100644 --- a/gcc/cp/Makefile.in +++ b/gcc/cp/Makefile.in @@ -240,12 +240,12 @@ typeck2.o : typeck2.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h typeck.o : typeck.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h $(RTL_H) \ $(srcdir)/../expr.h ../insn-codes.h class.o : class.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h -call.o : call.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h class.h +call.o : call.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h friend.o : friend.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h $(RTL_H) init.o : init.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h $(RTL_H) \ $(srcdir)/../expr.h ../insn-codes.h -method.o : method.c $(CONFIG_H) $(CXX_TREE_H) class.h -cvt.o : cvt.c $(CONFIG_H) $(CXX_TREE_H) class.h +method.o : method.c $(CONFIG_H) $(CXX_TREE_H) +cvt.o : cvt.c $(CONFIG_H) $(CXX_TREE_H) search.o : search.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../stack.h $(srcdir)/../flags.h tree.o : tree.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h ptree.o : ptree.c $(CONFIG_H) $(CXX_TREE_H) diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 276b32e7750..8fe87aa8c76 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -27,7 +27,6 @@ Boston, MA 02111-1307, USA. */ #include "tree.h" #include #include "cp-tree.h" -#include "class.h" #include "output.h" #include "flags.h" @@ -42,22 +41,10 @@ Boston, MA 02111-1307, USA. */ extern int inhibit_warnings; extern tree ctor_label, dtor_label; -/* Compute the ease with which a conversion can be performed - between an expected and the given type. */ +static tree build_new_method_call PROTO((tree, tree, tree, tree, int)); -static struct harshness_code convert_harshness PROTO((register tree, register tree, tree)); -static tree build_new_method_call PROTO((tree, tree, tree, tree, int)); - -static int rank_for_ideal PROTO((struct candidate *, - struct candidate *)); -static int user_harshness PROTO((tree, tree)); -static int strictly_better PROTO((unsigned int, unsigned int)); -static struct candidate * ideal_candidate PROTO((struct candidate *, - int, int)); -static int may_be_remote PROTO((tree)); static tree build_field_call PROTO((tree, tree, tree, tree)); static tree find_scoped_type PROTO((tree, tree, tree)); -static void print_candidates PROTO((tree)); static struct z_candidate * tourney PROTO((struct z_candidate *)); static int joust PROTO((struct z_candidate *, struct z_candidate *)); static int compare_qual PROTO((tree, tree)); @@ -100,1106 +87,9 @@ static tree reference_binding PROTO((tree, tree, tree, int)); static tree strip_top_quals PROTO((tree)); static tree non_reference PROTO((tree)); static tree build_conv PROTO((enum tree_code, tree, tree)); -static void print_n_candidates PROTO((struct candidate *, int)); static tree default_parm_conversions PROTO((tree, tree *)); static int is_subseq PROTO((tree, tree)); -#define EVIL_RETURN(ARG) ((ARG).code = EVIL_CODE, (ARG)) -#define STD_RETURN(ARG) ((ARG).code = STD_CODE, (ARG)) -#define QUAL_RETURN(ARG) ((ARG).code = QUAL_CODE, (ARG)) -#define TRIVIAL_RETURN(ARG) ((ARG).code = TRIVIAL_CODE, (ARG)) -#define ZERO_RETURN(ARG) ((ARG).code = 0, (ARG)) - -/* Ordering function for overload resolution. Compare two candidates - by gross quality. */ - -int -rank_for_overload (x, y) - struct candidate *x, *y; -{ - if (y->h.code & (EVIL_CODE|ELLIPSIS_CODE|USER_CODE)) - return y->h.code - x->h.code; - if (x->h.code & (EVIL_CODE|ELLIPSIS_CODE|USER_CODE)) - return -1; - - /* This is set by compute_conversion_costs, for calling a non-const - member function from a const member function. */ - if ((y->harshness[0].code & CONST_CODE) ^ (x->harshness[0].code & CONST_CODE)) - return y->harshness[0].code - x->harshness[0].code; - - if (y->h.code & STD_CODE) - { - if (x->h.code & STD_CODE) - return y->h.distance - x->h.distance; - return 1; - } - if (x->h.code & STD_CODE) - return -1; - - return y->h.code - x->h.code; -} - -/* Compare two candidates, argument by argument. */ - -static int -rank_for_ideal (x, y) - struct candidate *x, *y; -{ - int i; - - if (x->h_len != y->h_len) - abort (); - - for (i = 0; i < x->h_len; i++) - { - if (y->harshness[i].code - x->harshness[i].code) - return y->harshness[i].code - x->harshness[i].code; - if ((y->harshness[i].code & STD_CODE) - && (y->harshness[i].distance - x->harshness[i].distance)) - return y->harshness[i].distance - x->harshness[i].distance; - - /* They're both the same code. Now see if we're dealing with an - integral promotion that needs a finer grain of accuracy. */ - if (y->harshness[0].code & PROMO_CODE - && (y->harshness[i].int_penalty ^ x->harshness[i].int_penalty)) - return y->harshness[i].int_penalty - x->harshness[i].int_penalty; - } - return 0; -} - -/* TYPE is the type we wish to convert to. PARM is the parameter - we have to work with. We use a somewhat arbitrary cost function - to measure this conversion. */ - -static struct harshness_code -convert_harshness (type, parmtype, parm) - register tree type, parmtype; - tree parm; -{ - struct harshness_code h; - register enum tree_code codel; - register enum tree_code coder; - int lvalue; - - h.code = 0; - h.distance = 0; - h.int_penalty = 0; - -#ifdef GATHER_STATISTICS - n_convert_harshness++; -#endif - - if (TREE_CODE (parmtype) == REFERENCE_TYPE) - { - if (parm) - parm = convert_from_reference (parm); - parmtype = TREE_TYPE (parmtype); - lvalue = 1; - } - else if (parm) - lvalue = lvalue_p (parm); - else - lvalue = 0; - - if (TYPE_PTRMEMFUNC_P (type)) - type = TYPE_PTRMEMFUNC_FN_TYPE (type); - if (TYPE_PTRMEMFUNC_P (parmtype)) - parmtype = TYPE_PTRMEMFUNC_FN_TYPE (parmtype); - - codel = TREE_CODE (type); - coder = TREE_CODE (parmtype); - - if (TYPE_MAIN_VARIANT (parmtype) == TYPE_MAIN_VARIANT (type)) - return ZERO_RETURN (h); - - if (coder == ERROR_MARK) - return EVIL_RETURN (h); - - if (codel == REFERENCE_TYPE) - { - tree ttl, ttr; - int constp = parm ? TREE_READONLY (parm) : TYPE_READONLY (parmtype); - int volatilep = (parm ? TREE_THIS_VOLATILE (parm) - : TYPE_VOLATILE (parmtype)); - register tree intype = TYPE_MAIN_VARIANT (parmtype); - register enum tree_code form = TREE_CODE (intype); - int penalty = 0; - - ttl = TREE_TYPE (type); - - /* Only allow const reference binding if we were given a parm to deal - with, since it isn't really a conversion. This is a hack to - prevent build_type_conversion from finding this conversion, but - still allow overloading to find it. */ - if (! lvalue && ! (parm && TYPE_READONLY (ttl))) - return EVIL_RETURN (h); - - if ((TYPE_READONLY (ttl) < constp) - || (TYPE_VOLATILE (ttl) < volatilep)) - return EVIL_RETURN (h); - - /* When passing a non-const argument into a const reference, dig it a - little, so a non-const reference is preferred over this one. */ - penalty = ((TYPE_READONLY (ttl) > constp) - + (TYPE_VOLATILE (ttl) > volatilep)); - - ttl = TYPE_MAIN_VARIANT (ttl); - - if (form == OFFSET_TYPE) - { - intype = TREE_TYPE (intype); - form = TREE_CODE (intype); - } - - ttr = intype; - - if (TREE_CODE (ttl) == ARRAY_TYPE && TREE_CODE (ttr) == ARRAY_TYPE) - { - if (comptypes (ttl, ttr, 1)) - return ZERO_RETURN (h); - return EVIL_RETURN (h); - } - - h = convert_harshness (ttl, ttr, NULL_TREE); - if (penalty && h.code == 0) - { - h.code = QUAL_CODE; - h.int_penalty = penalty; - } - return h; - } - - if (codel == POINTER_TYPE && fntype_p (parmtype)) - { - tree p1, p2; - struct harshness_code h1, h2; - - /* Get to the METHOD_TYPE or FUNCTION_TYPE that this might be. */ - type = TREE_TYPE (type); - - if (coder == POINTER_TYPE) - { - parmtype = TREE_TYPE (parmtype); - coder = TREE_CODE (parmtype); - } - - if (coder != TREE_CODE (type)) - return EVIL_RETURN (h); - - if (type != parmtype && coder == METHOD_TYPE) - { - tree ttl = TYPE_METHOD_BASETYPE (type); - tree ttr = TYPE_METHOD_BASETYPE (parmtype); - - int b_or_d = get_base_distance (ttr, ttl, 0, (tree*)0); - if (b_or_d < 0) - { - b_or_d = get_base_distance (ttl, ttr, 0, (tree*)0); - if (b_or_d < 0) - return EVIL_RETURN (h); - h.distance = -b_or_d; - } - else - h.distance = b_or_d; - h.code = STD_CODE; - - type = build_function_type - (TREE_TYPE (type), TREE_CHAIN (TYPE_ARG_TYPES (type))); - parmtype = build_function_type - (TREE_TYPE (parmtype), TREE_CHAIN (TYPE_ARG_TYPES (parmtype))); - } - - /* We allow the default conversion between function type - and pointer-to-function type for free. */ - if (comptypes (type, parmtype, 1)) - return h; - - if (pedantic) - return EVIL_RETURN (h); - - /* Compare return types. */ - p1 = TREE_TYPE (type); - p2 = TREE_TYPE (parmtype); - h2 = convert_harshness (p1, p2, NULL_TREE); - if (h2.code & EVIL_CODE) - return h2; - - h1.code = TRIVIAL_CODE; - h1.distance = 0; - - if (h2.distance != 0) - { - tree binfo; - - /* This only works for pointers. */ - if (TREE_CODE (p1) != POINTER_TYPE - && TREE_CODE (p1) != REFERENCE_TYPE) - return EVIL_RETURN (h); - - p1 = TREE_TYPE (p1); - p2 = TREE_TYPE (p2); - /* Don't die if we happen to be dealing with void*. */ - if (!IS_AGGR_TYPE (p1) || !IS_AGGR_TYPE (p2)) - return EVIL_RETURN (h); - if (h2.distance < 0) - binfo = get_binfo (p2, p1, 0); - else - binfo = get_binfo (p1, p2, 0); - - if (! BINFO_OFFSET_ZEROP (binfo)) - { -#if 0 - static int explained = 0; - if (h2.distance < 0) - message_2_types (sorry, "cannot cast `%s' to `%s' at function call site", p2, p1); - else - message_2_types (sorry, "cannot cast `%s' to `%s' at function call site", p1, p2); - - if (! explained++) - sorry ("(because pointer values change during conversion)"); -#endif - return EVIL_RETURN (h); - } - } - - h1.code |= h2.code; - if (h2.distance > h1.distance) - h1.distance = h2.distance; - - p1 = TYPE_ARG_TYPES (type); - p2 = TYPE_ARG_TYPES (parmtype); - while (p1 && TREE_VALUE (p1) != void_type_node - && p2 && TREE_VALUE (p2) != void_type_node) - { - h2 = convert_harshness (TREE_VALUE (p1), TREE_VALUE (p2), - NULL_TREE); - if (h2.code & EVIL_CODE) - return h2; - - if (h2.distance) - { - /* This only works for pointers and references. */ - if (TREE_CODE (TREE_VALUE (p1)) != POINTER_TYPE - && TREE_CODE (TREE_VALUE (p1)) != REFERENCE_TYPE) - return EVIL_RETURN (h); - h2.distance = - h2.distance; - } - - h1.code |= h2.code; - if (h2.distance > h1.distance) - h1.distance = h2.distance; - p1 = TREE_CHAIN (p1); - p2 = TREE_CHAIN (p2); - } - if (p1 == p2) - return h1; - if (p2) - { - if (p1) - return EVIL_RETURN (h); - h1.code |= ELLIPSIS_CODE; - return h1; - } - if (p1) - { - if (TREE_PURPOSE (p1) == NULL_TREE) - h1.code |= EVIL_CODE; - return h1; - } - } - else if (codel == POINTER_TYPE && coder == OFFSET_TYPE) - { - tree ttl, ttr; - - /* Get to the OFFSET_TYPE that this might be. */ - type = TREE_TYPE (type); - - if (coder != TREE_CODE (type)) - return EVIL_RETURN (h); - - ttl = TYPE_OFFSET_BASETYPE (type); - ttr = TYPE_OFFSET_BASETYPE (parmtype); - - if (ttl == ttr) - h.code = 0; - else - { - int b_or_d = get_base_distance (ttr, ttl, 0, (tree*)0); - if (b_or_d < 0) - { - b_or_d = get_base_distance (ttl, ttr, 0, (tree*)0); - if (b_or_d < 0) - return EVIL_RETURN (h); - h.distance = -b_or_d; - } - else - h.distance = b_or_d; - h.code = STD_CODE; - } - - /* Now test the OFFSET_TYPE's target compatibility. */ - type = TREE_TYPE (type); - parmtype = TREE_TYPE (parmtype); - } - - if (coder == UNKNOWN_TYPE) - { - if (codel == FUNCTION_TYPE - || codel == METHOD_TYPE - || (codel == POINTER_TYPE - && (TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE - || TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE))) - return TRIVIAL_RETURN (h); - return EVIL_RETURN (h); - } - - if (coder == VOID_TYPE) - return EVIL_RETURN (h); - - if (codel == BOOLEAN_TYPE) - { - if (INTEGRAL_CODE_P (coder) || coder == REAL_TYPE) - return STD_RETURN (h); - else if (coder == POINTER_TYPE || coder == OFFSET_TYPE) - { - /* Make this worse than any conversion to another pointer. - FIXME this is how I think the language should work, but it may not - end up being how the language is standardized (jason 1/30/95). */ - h.distance = 32767; - return STD_RETURN (h); - } - return EVIL_RETURN (h); - } - - if (INTEGRAL_CODE_P (codel)) - { - /* Control equivalence of ints an enums. */ - - if (codel == ENUMERAL_TYPE - && flag_int_enum_equivalence == 0) - { - /* Enums can be converted to ints, but not vice-versa. */ - if (coder != ENUMERAL_TYPE - || TYPE_MAIN_VARIANT (type) != TYPE_MAIN_VARIANT (parmtype)) - return EVIL_RETURN (h); - } - - /* else enums and ints (almost) freely interconvert. */ - - if (INTEGRAL_CODE_P (coder)) - { - if (TYPE_MAIN_VARIANT (type) - == TYPE_MAIN_VARIANT (type_promotes_to (parmtype))) - { - h.code = PROMO_CODE; - } - else - h.code = STD_CODE; - - return h; - } - else if (coder == REAL_TYPE) - { - h.code = STD_CODE; - h.distance = 0; - return h; - } - } - - if (codel == REAL_TYPE) - { - if (coder == REAL_TYPE) - { - if (TYPE_MAIN_VARIANT (type) - == TYPE_MAIN_VARIANT (type_promotes_to (parmtype))) - h.code = PROMO_CODE; - else - h.code = STD_CODE; - - return h; - } - else if (INTEGRAL_CODE_P (coder)) - { - h.code = STD_CODE; - h.distance = 0; - return h; - } - } - - /* Convert arrays which have not previously been converted. */ - if (coder == ARRAY_TYPE) - { - coder = POINTER_TYPE; - if (parm) - { - parm = decay_conversion (parm); - parmtype = TREE_TYPE (parm); - } - else - parmtype = build_pointer_type (TREE_TYPE (parmtype)); - } - - /* Conversions among pointers */ - if (codel == POINTER_TYPE && coder == POINTER_TYPE) - { - register tree ttl = TYPE_MAIN_VARIANT (TREE_TYPE (type)); - register tree ttr = TYPE_MAIN_VARIANT (TREE_TYPE (parmtype)); - int penalty = 4 * (ttl != ttr); - - /* Anything converts to void *. Since this may be `const void *' - (etc.) use VOID_TYPE instead of void_type_node. Otherwise, the - targets must be the same, except that we do allow (at some cost) - conversion between signed and unsigned pointer types. */ - - if ((TREE_CODE (ttl) == METHOD_TYPE - || TREE_CODE (ttl) == FUNCTION_TYPE) - && TREE_CODE (ttl) == TREE_CODE (ttr)) - { - if (comptypes (ttl, ttr, -1)) - { - h.code = penalty ? STD_CODE : 0; - h.distance = 0; - } - else - h.code = EVIL_CODE; - return h; - } - -#if 1 - if (TREE_CODE (ttl) != VOID_TYPE - && (TREE_CODE (ttr) != VOID_TYPE || !parm || !null_ptr_cst_p (parm))) - { - if (comp_target_types (type, parmtype, 1) <= 0) - return EVIL_RETURN (h); - } -#else - if (!(TREE_CODE (ttl) == VOID_TYPE - || TREE_CODE (ttr) == VOID_TYPE - || (TREE_UNSIGNED (ttl) ^ TREE_UNSIGNED (ttr) - && (ttl = unsigned_type (ttl), - ttr = unsigned_type (ttr), - penalty = 10, 0)) - || (comp_target_types (ttl, ttr, 0) > 0))) - return EVIL_RETURN (h); -#endif - - if (ttr == ttl) - { - tree tmp1 = TREE_TYPE (type), tmp2 = TREE_TYPE (parmtype); - - h.code = 0; - /* Note conversion from `T*' to `const T*', - or `T*' to `volatile T*'. */ - if ((TYPE_READONLY (tmp1) < TREE_READONLY (tmp2)) - || (TYPE_VOLATILE (tmp1) < TYPE_VOLATILE (tmp2))) - h.code = EVIL_CODE; - else if ((TYPE_READONLY (tmp1) != TREE_READONLY (tmp2)) - || (TYPE_VOLATILE (tmp1) != TYPE_VOLATILE (tmp2))) - h.code |= QUAL_CODE; - - h.distance = 0; - return h; - } - - - if (TREE_CODE (ttl) == RECORD_TYPE && TREE_CODE (ttr) == RECORD_TYPE) - { - int b_or_d = get_base_distance (ttl, ttr, 0, (tree*)0); - if (b_or_d < 0) - { - b_or_d = get_base_distance (ttr, ttl, 0, (tree*)0); - if (b_or_d < 0) - return EVIL_RETURN (h); - h.distance = -b_or_d; - } - else - h.distance = b_or_d; - h.code = STD_CODE; - return h; - } - - /* If converting from a `class*' to a `void*', make it - less favorable than any inheritance relationship. */ - if (TREE_CODE (ttl) == VOID_TYPE && IS_AGGR_TYPE (ttr)) - { - h.code = STD_CODE; - h.distance = CLASSTYPE_MAX_DEPTH (ttr)+1; - return h; - } - - h.code = penalty ? STD_CODE : PROMO_CODE; - /* Catch things like `const char *' -> `const void *' - vs `const char *' -> `void *'. */ - if (ttl != ttr) - { - tree tmp1 = TREE_TYPE (type), tmp2 = TREE_TYPE (parmtype); - if ((TYPE_READONLY (tmp1) < TREE_READONLY (tmp2)) - || (TYPE_VOLATILE (tmp1) < TYPE_VOLATILE (tmp2))) - h.code = EVIL_CODE; - else if ((TYPE_READONLY (tmp1) > TREE_READONLY (tmp2)) - || (TYPE_VOLATILE (tmp1) > TYPE_VOLATILE (tmp2))) - h.code |= QUAL_CODE; - } - return h; - } - - if (codel == POINTER_TYPE && coder == INTEGER_TYPE) - { - /* This is not a bad match, but don't let it beat - integer-enum combinations. */ - if (parm && integer_zerop (parm)) - { - h.code = STD_CODE; - h.distance = 0; - return h; - } - } - - /* C++: Since the `this' parameter of a signature member function - is represented as a signature pointer to handle default implementations - correctly, we can have the case that `type' is a signature pointer - while `parmtype' is a pointer to a signature table. We don't really - do any conversions in this case, so just return 0. */ - - if (codel == RECORD_TYPE && coder == POINTER_TYPE - && IS_SIGNATURE_POINTER (type) && IS_SIGNATURE (TREE_TYPE (parmtype))) - return ZERO_RETURN (h); - - if (codel == RECORD_TYPE && coder == RECORD_TYPE) - { - int b_or_d = get_base_distance (type, parmtype, 0, (tree*)0); - if (b_or_d < 0) - { - b_or_d = get_base_distance (parmtype, type, 0, (tree*)0); - if (b_or_d < 0) - return EVIL_RETURN (h); - h.distance = -b_or_d; - } - else - h.distance = b_or_d; - h.code = STD_CODE; - return h; - } - return EVIL_RETURN (h); -} - -/* A clone of build_type_conversion for checking user-defined conversions in - overload resolution. */ - -static int -user_harshness (type, parmtype) - register tree type, parmtype; -{ - tree conv; - tree winner = NULL_TREE; - int code = 0; - - { - tree typename = build_typename_overload (type); - if (lookup_fnfields (TYPE_BINFO (parmtype), typename, 0)) - return 0; - } - - for (conv = lookup_conversions (parmtype); conv; conv = TREE_CHAIN (conv)) - { - struct harshness_code tmp; - tree cand = TREE_VALUE (conv); - - if (winner && winner == cand) - continue; - - tmp = convert_harshness (type, TREE_TYPE (TREE_TYPE (cand)), NULL_TREE); - if ((tmp.code < USER_CODE) && (tmp.distance >= 0)) - { - if (winner) - return EVIL_CODE; - else - { - winner = cand; - code = tmp.code; - } - } - } - - if (winner) - return code; - - return -1; -} - -#ifdef DEBUG_MATCHING -static char * -print_harshness (h) - struct harshness_code *h; -{ - static char buf[1024]; - char tmp[1024]; - - bzero (buf, 1024 * sizeof (char)); - strcat (buf, "codes=["); - if (h->code & EVIL_CODE) - strcat (buf, "EVIL"); - if (h->code & CONST_CODE) - strcat (buf, " CONST"); - if (h->code & ELLIPSIS_CODE) - strcat (buf, " ELLIPSIS"); - if (h->code & USER_CODE) - strcat (buf, " USER"); - if (h->code & STD_CODE) - strcat (buf, " STD"); - if (h->code & PROMO_CODE) - strcat (buf, " PROMO"); - if (h->code & QUAL_CODE) - strcat (buf, " QUAL"); - if (h->code & TRIVIAL_CODE) - strcat (buf, " TRIVIAL"); - if (buf[0] == '\0') - strcat (buf, "0"); - - sprintf (tmp, "] distance=%d int_penalty=%d", h->distance, h->int_penalty); - - strcat (buf, tmp); - - return buf; -} -#endif - -/* Algorithm: For each argument, calculate how difficult it is to - make FUNCTION accept that argument. If we can easily tell that - FUNCTION won't be acceptable to one of the arguments, then we - don't need to compute the ease of converting the other arguments, - since it will never show up in the intersection of all arguments' - favorite functions. - - Conversions between builtin and user-defined types are allowed, but - no function involving such a conversion is preferred to one which - does not require such a conversion. Furthermore, such conversions - must be unique. */ - -void -compute_conversion_costs (function, tta_in, cp, arglen) - tree function; - tree tta_in; - struct candidate *cp; - int arglen; -{ - tree ttf_in = TYPE_ARG_TYPES (TREE_TYPE (function)); - tree ttf = ttf_in; - tree tta = tta_in; - - /* Start out with no strikes against. */ - int evil_strikes = 0; - int ellipsis_strikes = 0; - int user_strikes = 0; - int b_or_d_strikes = 0; - int easy_strikes = 0; - - int strike_index = 0, win; - struct harshness_code lose; - extern int cp_silent; - -#ifdef GATHER_STATISTICS - n_compute_conversion_costs++; -#endif - -#ifndef DEBUG_MATCHING - /* We don't emit any warnings or errors while trying out each candidate. */ - cp_silent = 1; -#endif - - cp->function = function; - cp->arg = tta ? TREE_VALUE (tta) : NULL_TREE; - cp->u.bad_arg = 0; /* optimistic! */ - - cp->h.code = 0; - cp->h.distance = 0; - cp->h.int_penalty = 0; - bzero ((char *) cp->harshness, - (cp->h_len + 1) * sizeof (struct harshness_code)); - - while (ttf && tta) - { - struct harshness_code h; - - if (ttf == void_list_node) - break; - - if (type_unknown_p (TREE_VALUE (tta))) - { - /* Must perform some instantiation here. */ - tree rhs = TREE_VALUE (tta); - tree lhstype = TREE_VALUE (ttf); - - /* Keep quiet about possible contravariance violations. */ - int old_inhibit_warnings = inhibit_warnings; - inhibit_warnings = 1; - - /* @@ This is to undo what `grokdeclarator' does to - parameter types. It really should go through - something more general. */ - - TREE_TYPE (tta) = unknown_type_node; - rhs = instantiate_type (lhstype, rhs, 0); - inhibit_warnings = old_inhibit_warnings; - - if (TREE_CODE (rhs) == ERROR_MARK) - h.code = EVIL_CODE; - else - h = convert_harshness (lhstype, TREE_TYPE (rhs), rhs); - } - else - { -#ifdef DEBUG_MATCHING - static tree old_function = NULL_TREE; - - if (!old_function || function != old_function) - { - cp_error ("trying %D", function); - old_function = function; - } - - cp_error (" doing (%T) %E against arg %T", - TREE_TYPE (TREE_VALUE (tta)), TREE_VALUE (tta), - TREE_VALUE (ttf)); -#endif - - h = convert_harshness (TREE_VALUE (ttf), - TREE_TYPE (TREE_VALUE (tta)), - TREE_VALUE (tta)); - -#ifdef DEBUG_MATCHING - cp_error (" evaluated %s", print_harshness (&h)); -#endif - } - - cp->harshness[strike_index] = h; - if ((h.code & EVIL_CODE) - || ((h.code & STD_CODE) && h.distance < 0)) - { - cp->u.bad_arg = strike_index; - evil_strikes = 1; - } - else if (h.code & ELLIPSIS_CODE) - ellipsis_strikes += 1; -#if 0 - /* This is never set by `convert_harshness'. */ - else if (h.code & USER_CODE) - { - user_strikes += 1; - } -#endif - else - { - if ((h.code & STD_CODE) && h.distance) - { - if (h.distance > b_or_d_strikes) - b_or_d_strikes = h.distance; - } - else - easy_strikes += (h.code & (STD_CODE|PROMO_CODE|TRIVIAL_CODE)); - cp->h.code |= h.code; - /* Make sure we communicate this. */ - cp->h.int_penalty += h.int_penalty; - } - - ttf = TREE_CHAIN (ttf); - tta = TREE_CHAIN (tta); - strike_index += 1; - } - - if (tta) - { - /* ran out of formals, and parmlist is fixed size. */ - if (ttf /* == void_type_node */) - { - cp->h.code = EVIL_CODE; - cp->u.bad_arg = -1; - cp_silent = 0; - return; - } - else - { - struct harshness_code h; - int l = list_length (tta); - ellipsis_strikes += l; - h.code = ELLIPSIS_CODE; - h.distance = 0; - h.int_penalty = 0; - for (; l; --l) - cp->harshness[strike_index++] = h; - } - } - else if (ttf && ttf != void_list_node) - { - /* ran out of actuals, and no defaults. */ - if (TREE_PURPOSE (ttf) == NULL_TREE) - { - cp->h.code = EVIL_CODE; - cp->u.bad_arg = -2; - cp_silent = 0; - return; - } - /* Store index of first default. */ - cp->harshness[arglen].distance = strike_index+1; - } - else - cp->harshness[arglen].distance = 0; - - /* Argument list lengths work out, so don't need to check them again. */ - if (evil_strikes) - { - /* We do not check for derived->base conversions here, since in - no case would they give evil strike counts, unless such conversions - are somehow ambiguous. */ - - /* See if any user-defined conversions apply. - But make sure that we do not loop. */ - static int dont_convert_types = 0; - - if (dont_convert_types) - { - cp->h.code = EVIL_CODE; - cp_silent = 0; - return; - } - - win = 0; /* Only get one chance to win. */ - ttf = TYPE_ARG_TYPES (TREE_TYPE (function)); - tta = tta_in; - strike_index = 0; - evil_strikes = 0; - - while (ttf && tta) - { - if (ttf == void_list_node) - break; - - lose = cp->harshness[strike_index]; - if ((lose.code & EVIL_CODE) - || ((lose.code & STD_CODE) && lose.distance < 0)) - { - tree actual_type = TREE_TYPE (TREE_VALUE (tta)); - tree formal_type = TREE_VALUE (ttf); - int extra_conversions = 0; - - dont_convert_types = 1; - - if (TREE_CODE (formal_type) == REFERENCE_TYPE) - formal_type = TREE_TYPE (formal_type); - if (TREE_CODE (actual_type) == REFERENCE_TYPE) - actual_type = TREE_TYPE (actual_type); - - if (formal_type != error_mark_node - && actual_type != error_mark_node) - { - formal_type = complete_type (TYPE_MAIN_VARIANT (formal_type)); - actual_type = complete_type (TYPE_MAIN_VARIANT (actual_type)); - - if (TYPE_HAS_CONSTRUCTOR (formal_type)) - { - /* If it has a constructor for this type, - try to use it. */ - /* @@ There is no way to save this result yet, so - success is a NULL_TREE for now. */ - if (convert_to_aggr (formal_type, TREE_VALUE (tta), 0, 1) - != error_mark_node) - win++; - } - if (TYPE_LANG_SPECIFIC (actual_type) - && TYPE_HAS_CONVERSION (actual_type)) - { - int extra = user_harshness (formal_type, actual_type); - - if (extra == EVIL_CODE) - win += 2; - else if (extra >= 0) - { - win++; - extra_conversions = extra; - } - } - } - dont_convert_types = 0; - - if (win == 1) - { - user_strikes += 1; - cp->harshness[strike_index].code - = USER_CODE | (extra_conversions ? STD_CODE : 0); - win = 0; - } - else - { - if (cp->u.bad_arg > strike_index) - cp->u.bad_arg = strike_index; - - evil_strikes = win ? 2 : 1; - break; - } - } - - ttf = TREE_CHAIN (ttf); - tta = TREE_CHAIN (tta); - strike_index += 1; - } - } - - /* Const member functions get a small penalty because defaulting - to const is less useful than defaulting to non-const. */ - /* This is bogus, it does not correspond to anything in the ARM. - This code will be fixed when this entire section is rewritten - to conform to the ARM. (mrs) */ - if (TREE_CODE (TREE_TYPE (function)) == METHOD_TYPE) - { - tree this_parm = TREE_VALUE (ttf_in); - - if (TREE_CODE (this_parm) == RECORD_TYPE /* Is `this' a sig ptr? */ - ? TYPE_READONLY (TREE_TYPE (TREE_TYPE (TYPE_FIELDS (this_parm)))) - : TYPE_READONLY (TREE_TYPE (this_parm))) - { - cp->harshness[0].code |= TRIVIAL_CODE; - ++easy_strikes; - } - else - { - /* Calling a non-const member function from a const member function - is probably invalid, but for now we let it only draw a warning. - We indicate that such a mismatch has occurred by setting the - harshness to a maximum value. */ - if (TREE_CODE (TREE_TYPE (TREE_VALUE (tta_in))) == POINTER_TYPE - && (TYPE_READONLY (TREE_TYPE (TREE_TYPE (TREE_VALUE (tta_in)))))) - cp->harshness[0].code |= CONST_CODE; - } - } - - if (evil_strikes) - cp->h.code = EVIL_CODE; - if (ellipsis_strikes) - cp->h.code |= ELLIPSIS_CODE; - if (user_strikes) - cp->h.code |= USER_CODE; - cp_silent = 0; -#ifdef DEBUG_MATCHING - cp_error ("final eval %s", print_harshness (&cp->h)); -#endif -} - -/* Subroutine of ideal_candidate. See if X or Y is a better match - than the other. */ - -static int -strictly_better (x, y) - unsigned int x, y; -{ - unsigned short xor; - - if (x == y) - return 0; - - xor = x ^ y; - if (xor >= x || xor >= y) - return 1; - return 0; -} - -/* When one of several possible overloaded functions and/or methods - can be called, choose the best candidate for overloading. - - BASETYPE is the context from which we start method resolution - or NULL if we are comparing overloaded functions. - CANDIDATES is the array of candidates we have to choose from. - N_CANDIDATES is the length of CANDIDATES. - PARMS is a TREE_LIST of parameters to the function we'll ultimately - choose. It is modified in place when resolving methods. It is not - modified in place when resolving overloaded functions. - LEN is the length of the parameter list. */ - -static struct candidate * -ideal_candidate (candidates, n_candidates, len) - struct candidate *candidates; - int n_candidates; - int len; -{ - struct candidate *cp = candidates+n_candidates; - int i, j = -1, best_code; - - /* For each argument, sort the functions from best to worst for the arg. - For each function that's not best for this arg, set its overall - harshness to EVIL so that other args won't like it. The candidate - list for the last argument is the intersection of all the best-liked - functions. */ - - qsort (candidates, n_candidates, sizeof (struct candidate), - (int (*) PROTO((const void *, const void *))) rank_for_overload); - best_code = cp[-1].h.code; - - /* If they're at least as good as each other, do an arg-by-arg check. */ - if (! strictly_better (cp[-1].h.code, cp[-2].h.code)) - { - int better = 0; - int worse = 0; - - for (j = 0; j < n_candidates; j++) - if (! strictly_better (candidates[j].h.code, best_code)) - break; - - qsort (candidates+j, n_candidates-j, sizeof (struct candidate), - (int (*) PROTO((const void *, const void *))) rank_for_ideal); - for (i = 0; i < len; i++) - { - if (cp[-1].harshness[i].code < cp[-2].harshness[i].code) - better = 1; - else if (cp[-1].harshness[i].code > cp[-2].harshness[i].code) - worse = 1; - else if (cp[-1].harshness[i].code & STD_CODE) - { - /* If it involves a standard conversion, let the - inheritance lattice be the final arbiter. */ - if (cp[-1].harshness[i].distance > cp[-2].harshness[i].distance) - worse = 1; - else if (cp[-1].harshness[i].distance < cp[-2].harshness[i].distance) - better = 1; - } - else if (cp[-1].harshness[i].code & PROMO_CODE) - { - /* For integral promotions, take into account a finer - granularity for determining which types should be favored - over others in such promotions. */ - if (cp[-1].harshness[i].int_penalty > cp[-2].harshness[i].int_penalty) - worse = 1; - else if (cp[-1].harshness[i].int_penalty < cp[-2].harshness[i].int_penalty) - better = 1; - } - } - - if (! better || worse) - return NULL; - } - return cp-1; -} - -/* Assume that if the class referred to is not in the - current class hierarchy, that it may be remote. - PARENT is assumed to be of aggregate type here. */ - -static int -may_be_remote (parent) - tree parent; -{ - if (TYPE_OVERLOADS_METHOD_CALL_EXPR (parent) == 0) - return 0; - - if (current_class_type == NULL_TREE) - return 0; - - if (parent == current_class_type) - return 0; - - if (UNIQUELY_DERIVED_FROM_P (parent, current_class_type)) - return 0; - return 1; -} - tree build_vfield_ref (datum, type) tree datum, type; @@ -1257,9 +147,7 @@ build_field_call (basetype_path, instance_ptr, name, parms) if (instance == error_mark_node) return error_mark_node; - if (TYPE_LANG_SPECIFIC (TREE_TYPE (instance)) - && (TYPE_OVERLOADS_CALL_EXPR (TREE_TYPE (instance)) - || flag_ansi_overloading)) + if (TYPE_LANG_SPECIFIC (TREE_TYPE (instance))) return build_opfncall (CALL_EXPR, LOOKUP_NORMAL, instance, parms, NULL_TREE); if (TREE_CODE (TREE_TYPE (instance)) == POINTER_TYPE) @@ -1290,8 +178,7 @@ build_field_call (basetype_path, instance_ptr, name, parms) if (TREE_CODE (ftype) == REFERENCE_TYPE) ftype = TREE_TYPE (ftype); - if (TYPE_LANG_SPECIFIC (ftype) - && (TYPE_OVERLOADS_CALL_EXPR (ftype) || flag_ansi_overloading)) + if (TYPE_LANG_SPECIFIC (ftype)) { /* Make the next search for this field very short. */ basetype = DECL_FIELD_CONTEXT (field); @@ -1567,32 +454,6 @@ build_scoped_method_call (exp, basetype, name, parms) return error_mark_node; } -static void -print_candidates (candidates) - tree candidates; -{ - cp_error_at ("candidates are: %D", TREE_VALUE (candidates)); - candidates = TREE_CHAIN (candidates); - - while (candidates) - { - cp_error_at (" %D", TREE_VALUE (candidates)); - candidates = TREE_CHAIN (candidates); - } -} - -static void -print_n_candidates (candidates, n) - struct candidate *candidates; - int n; -{ - int i; - - cp_error_at ("candidates are: %D", candidates[0].function); - for (i = 1; i < n; i++) - cp_error_at (" %D", candidates[i].function); -} - /* We want the address of a function or method. We avoid creating a pointer-to-member function. */ @@ -1659,37 +520,6 @@ build_call (function, result_type, parms) return function; } -static tree -default_parm_conversions (parms, last) - tree parms, *last; -{ - tree parm, parmtypes = NULL_TREE; - - *last = NULL_TREE; - - for (parm = parms; parm; parm = TREE_CHAIN (parm)) - { - tree t = TREE_TYPE (TREE_VALUE (parm)); - - if (TREE_CODE (t) == OFFSET_TYPE - || TREE_CODE (t) == METHOD_TYPE - || TREE_CODE (t) == FUNCTION_TYPE) - { - TREE_VALUE (parm) = default_conversion (TREE_VALUE (parm)); - t = TREE_TYPE (TREE_VALUE (parm)); - } - - if (t == error_mark_node) - return error_mark_node; - - *last = build_tree_list (NULL_TREE, t); - parmtypes = chainon (parmtypes, *last); - } - - return parmtypes; -} - - /* Build something of the form ptr->method (args) or object.method (args). This can also build calls to constructors, and find friends. @@ -1727,28 +557,7 @@ build_method_call (instance, name, parms, basetype_path, flags) tree instance, name, parms, basetype_path; int flags; { - register tree function, fntype, value_type; - register tree basetype, save_basetype; - register tree baselink, result, parmtypes; - tree last; - int pass; - tree access = access_public_node; - tree orig_basetype = basetype_path ? BINFO_TYPE (basetype_path) : NULL_TREE; - - /* Range of cases for vtable optimization. */ - enum vtable_needs { not_needed, maybe_needed, unneeded, needed }; - enum vtable_needs need_vtbl = not_needed; - - char *name_kind; - tree save_name = name; - int ever_seen = 0; - tree instance_ptr = NULL_TREE; - int all_virtual = flag_all_virtual; - int static_call_context = 0; - tree found_fns = NULL_TREE; - - /* Keep track of `const' and `volatile' objects. */ - int constp, volatilep; + tree result, basetype, instance_ptr; #ifdef GATHER_STATISTICS n_build_method_call++; @@ -1822,1142 +631,7 @@ build_method_call (instance, name, parms, basetype_path, flags) LOOKUP_NORMAL|LOOKUP_DESTRUCTOR, 0); } - if (flag_ansi_overloading) - return build_new_method_call (instance, name, parms, basetype_path, flags); - - { - char *xref_name; - - /* Initialize name for error reporting. */ - if (IDENTIFIER_OPNAME_P (name) && ! IDENTIFIER_TYPENAME_P (name)) - { - char *p = operator_name_string (name); - xref_name = (char *)alloca (strlen (p) + 10); - sprintf (xref_name, "operator %s", p); - } - else if (TREE_CODE (name) == SCOPE_REF) - xref_name = IDENTIFIER_POINTER (TREE_OPERAND (name, 1)); - else - xref_name = IDENTIFIER_POINTER (name); - - GNU_xref_call (current_function_decl, xref_name); - } - - if (instance == NULL_TREE) - { - basetype = NULL_TREE; - /* Check cases where this is really a call to raise - an exception. */ - if (current_class_type && TREE_CODE (name) == IDENTIFIER_NODE) - { - basetype = purpose_member (name, CLASSTYPE_TAGS (current_class_type)); - if (basetype) - basetype = TREE_VALUE (basetype); - } - else if (TREE_CODE (name) == SCOPE_REF - && TREE_CODE (TREE_OPERAND (name, 0)) == IDENTIFIER_NODE) - { - if (! is_aggr_typedef (TREE_OPERAND (name, 0), 1)) - return error_mark_node; - basetype = purpose_member (TREE_OPERAND (name, 1), - CLASSTYPE_TAGS (IDENTIFIER_TYPE_VALUE (TREE_OPERAND (name, 0)))); - if (basetype) - basetype = TREE_VALUE (basetype); - } - - if (basetype != NULL_TREE) - ; - /* call to a constructor... */ - else if (basetype_path) - { - basetype = BINFO_TYPE (basetype_path); - if (name == TYPE_IDENTIFIER (basetype)) - name = ctor_identifier; - } - else if (IDENTIFIER_HAS_TYPE_VALUE (name)) - { - basetype = IDENTIFIER_TYPE_VALUE (name); - name = ctor_identifier; - } - else - { - tree typedef_name = lookup_name (name, 1); - if (typedef_name && TREE_CODE (typedef_name) == TYPE_DECL) - { - /* Canonicalize the typedef name. */ - basetype = TREE_TYPE (typedef_name); - name = ctor_identifier; - } - else - { - cp_error ("no constructor named `%T' in scope", - name); - return error_mark_node; - } - } - - if (! IS_AGGR_TYPE (basetype)) - { - non_aggr_error: - if ((flags & LOOKUP_COMPLAIN) && basetype != error_mark_node) - cp_error ("request for member `%D' in `%E', which is of non-aggregate type `%T'", - name, instance, basetype); - - return error_mark_node; - } - } - else if (instance == current_class_ref || instance == current_class_ptr) - { - /* When doing initialization, we side-effect the TREE_TYPE of - current_class_ref, hence we cannot set up BASETYPE from CURRENT_CLASS_TYPE. */ - basetype = TREE_TYPE (current_class_ref); - - /* Anything manifestly `this' in constructors and destructors - has a known type, so virtual function tables are not needed. */ - if (TYPE_VIRTUAL_P (basetype) - && !(flags & LOOKUP_NONVIRTUAL)) - need_vtbl = (dtor_label || ctor_label) - ? unneeded : maybe_needed; - - /* If `this' is a signature pointer and `name' is not a constructor, - we are calling a signature member function. In that case, set the - `basetype' to the signature type and dereference the `optr' field. */ - if (IS_SIGNATURE_POINTER (basetype) - && TYPE_IDENTIFIER (basetype) != name) - { - basetype = SIGNATURE_TYPE (basetype); - instance_ptr = instance; - basetype_path = TYPE_BINFO (basetype); - } - else - { - instance = current_class_ref; - instance_ptr = current_class_ptr; - basetype_path = TYPE_BINFO (current_class_type); - } - result = build_field_call (basetype_path, instance_ptr, name, parms); - - if (result) - return result; - } - else if (TREE_CODE (instance) == RESULT_DECL) - { - basetype = TREE_TYPE (instance); - /* Should we ever have to make a virtual function reference - from a RESULT_DECL, know that it must be of fixed type - within the scope of this function. */ - if (!(flags & LOOKUP_NONVIRTUAL) && TYPE_VIRTUAL_P (basetype)) - need_vtbl = maybe_needed; - instance_ptr = build1 (ADDR_EXPR, build_pointer_type (basetype), instance); - } - else - { - /* The MAIN_VARIANT of the type that `instance_ptr' winds up being. */ - tree inst_ptr_basetype; - - static_call_context - = (TREE_CODE (instance) == INDIRECT_REF - && TREE_CODE (TREE_OPERAND (instance, 0)) == NOP_EXPR - && TREE_OPERAND (TREE_OPERAND (instance, 0), 0) == error_mark_node); - - if (TREE_CODE (instance) == OFFSET_REF) - instance = resolve_offset_ref (instance); - - /* the base type of an instance variable is pointer to class */ - basetype = TREE_TYPE (instance); - - if (TREE_CODE (basetype) == REFERENCE_TYPE) - { - basetype = TREE_TYPE (basetype); - if (! IS_AGGR_TYPE (basetype)) - goto non_aggr_error; - /* Call to convert not needed because we are remaining - within the same type. */ - instance_ptr = build1 (NOP_EXPR, build_pointer_type (basetype), - instance); - inst_ptr_basetype = TYPE_MAIN_VARIANT (basetype); - } - else - { - if (! IS_AGGR_TYPE (basetype) - && ! (TYPE_LANG_SPECIFIC (basetype) - && (IS_SIGNATURE_POINTER (basetype) - || IS_SIGNATURE_REFERENCE (basetype)))) - goto non_aggr_error; - - /* If `instance' is a signature pointer/reference and `name' is - not a constructor, we are calling a signature member function. - In that case set the `basetype' to the signature type. */ - if ((IS_SIGNATURE_POINTER (basetype) - || IS_SIGNATURE_REFERENCE (basetype)) - && TYPE_IDENTIFIER (basetype) != name) - basetype = SIGNATURE_TYPE (basetype); - - basetype = complete_type (basetype); - - if ((IS_SIGNATURE (basetype) - && (instance_ptr = instance)) - || (lvalue_p (instance) - && (instance_ptr = build_unary_op (ADDR_EXPR, instance, 0))) - || (instance_ptr = unary_complex_lvalue (ADDR_EXPR, instance))) - { - if (instance_ptr == error_mark_node) - return error_mark_node; - } - else if (TREE_CODE (instance) == NOP_EXPR - || TREE_CODE (instance) == CONSTRUCTOR) - { - /* A cast is not an lvalue. Initialize a fresh temp - with the value we are casting from, and proceed with - that temporary. We can't cast to a reference type, - so that simplifies the initialization to something - we can manage. */ - tree temp = get_temp_name (TREE_TYPE (instance), 0); - if (IS_AGGR_TYPE (TREE_TYPE (instance))) - expand_aggr_init (temp, instance, 0, flags); - else - { - store_init_value (temp, instance); - expand_decl_init (temp); - } - instance = temp; - instance_ptr = build_unary_op (ADDR_EXPR, instance, 0); - } - else - { - if (TREE_CODE (instance) != CALL_EXPR) - my_friendly_abort (125); - if (TYPE_NEEDS_CONSTRUCTING (basetype)) - instance = build_cplus_new (basetype, instance); - else - { - instance = get_temp_name (basetype, 0); - TREE_ADDRESSABLE (instance) = 1; - } - instance_ptr = build_unary_op (ADDR_EXPR, instance, 0); - } - /* @@ Should we call comp_target_types here? */ - if (IS_SIGNATURE (basetype)) - inst_ptr_basetype = basetype; - else - inst_ptr_basetype = TREE_TYPE (TREE_TYPE (instance_ptr)); - if (TYPE_MAIN_VARIANT (basetype) == TYPE_MAIN_VARIANT (inst_ptr_basetype)) - basetype = inst_ptr_basetype; - else - { - instance_ptr = cp_convert (build_pointer_type (basetype), instance_ptr); - if (instance_ptr == error_mark_node) - return error_mark_node; - } - } - - /* After converting `instance_ptr' above, `inst_ptr_basetype' was - not updated, so we use `basetype' instead. */ - if (basetype_path == NULL_TREE - && IS_SIGNATURE (basetype)) - basetype_path = TYPE_BINFO (basetype); - else if (basetype_path == NULL_TREE - || (BINFO_TYPE (basetype_path) - != TYPE_MAIN_VARIANT (inst_ptr_basetype))) - basetype_path = TYPE_BINFO (inst_ptr_basetype); - - result = build_field_call (basetype_path, instance_ptr, name, parms); - if (result) - return result; - - if (!(flags & LOOKUP_NONVIRTUAL) && TYPE_VIRTUAL_P (basetype)) - { - if (TREE_SIDE_EFFECTS (instance_ptr)) - { - /* This action is needed because the instance is needed - for providing the base of the virtual function table. - Without using a SAVE_EXPR, the function we are building - may be called twice, or side effects on the instance - variable (such as a post-increment), may happen twice. */ - instance_ptr = save_expr (instance_ptr); - instance = build_indirect_ref (instance_ptr, NULL_PTR); - } - else if (TREE_CODE (TREE_TYPE (instance)) == POINTER_TYPE) - { - /* This happens when called for operator new (). */ - instance = build_indirect_ref (instance, NULL_PTR); - } - - need_vtbl = maybe_needed; - } - } - - if (save_name == ctor_identifier) - save_name = TYPE_IDENTIFIER (basetype); - - if (TYPE_SIZE (complete_type (basetype)) == 0) - { - /* This is worth complaining about, I think. */ - cp_error ("cannot lookup method in incomplete type `%T'", basetype); - return error_mark_node; - } - - save_basetype = TYPE_MAIN_VARIANT (basetype); - - parmtypes = default_parm_conversions (parms, &last); - if (parmtypes == error_mark_node) - { - return error_mark_node; - } - - if (instance && IS_SIGNATURE (basetype)) - { - /* @@ Should this be the constp/volatilep flags for the optr field - of the signature pointer? */ - constp = TYPE_READONLY (basetype); - volatilep = TYPE_VOLATILE (basetype); - parms = expr_tree_cons (NULL_TREE, instance_ptr, parms); - } - else if (instance) - { - /* TREE_READONLY (instance) fails for references. */ - constp = TYPE_READONLY (TREE_TYPE (TREE_TYPE (instance_ptr))); - volatilep = TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (instance_ptr))); - parms = expr_tree_cons (NULL_TREE, instance_ptr, parms); - } - else - { - /* Raw constructors are always in charge. */ - if (TYPE_USES_VIRTUAL_BASECLASSES (basetype) - && ! (flags & LOOKUP_HAS_IN_CHARGE)) - { - flags |= LOOKUP_HAS_IN_CHARGE; - parms = expr_tree_cons (NULL_TREE, integer_one_node, parms); - parmtypes = scratch_tree_cons (NULL_TREE, integer_type_node, parmtypes); - } - - constp = 0; - volatilep = 0; - instance_ptr = build_int_2 (0, 0); - TREE_TYPE (instance_ptr) = build_pointer_type (basetype); - parms = expr_tree_cons (NULL_TREE, instance_ptr, parms); - } - - parmtypes = scratch_tree_cons (NULL_TREE, TREE_TYPE (instance_ptr), parmtypes); - - if (last == NULL_TREE) - last = parmtypes; - - /* Look up function name in the structure type definition. */ - - /* FIXME Axe most of this now? */ - if ((IDENTIFIER_HAS_TYPE_VALUE (name) - && ! IDENTIFIER_OPNAME_P (name) - && IS_AGGR_TYPE (IDENTIFIER_TYPE_VALUE (name))) - || name == constructor_name (basetype) - || name == ctor_identifier) - { - tree tmp = NULL_TREE; - if (IDENTIFIER_TYPE_VALUE (name) == basetype - || name == constructor_name (basetype) - || name == ctor_identifier) - tmp = TYPE_BINFO (basetype); - else - tmp = get_binfo (IDENTIFIER_TYPE_VALUE (name), basetype, 0); - - if (tmp != NULL_TREE) - { - name_kind = "constructor"; - - if (TYPE_USES_VIRTUAL_BASECLASSES (basetype) - && ! (flags & LOOKUP_HAS_IN_CHARGE)) - { - /* Constructors called for initialization - only are never in charge. */ - tree tmplist; - - flags |= LOOKUP_HAS_IN_CHARGE; - tmplist = expr_tree_cons (NULL_TREE, integer_zero_node, - TREE_CHAIN (parms)); - TREE_CHAIN (parms) = tmplist; - tmplist = scratch_tree_cons (NULL_TREE, integer_type_node, TREE_CHAIN (parmtypes)); - TREE_CHAIN (parmtypes) = tmplist; - } - basetype = BINFO_TYPE (tmp); - } - else - name_kind = "method"; - } - else - name_kind = "method"; - - if (basetype_path == NULL_TREE - || BINFO_TYPE (basetype_path) != TYPE_MAIN_VARIANT (basetype)) - basetype_path = TYPE_BINFO (basetype); - result = lookup_fnfields (basetype_path, name, - (flags & LOOKUP_COMPLAIN)); - if (result == error_mark_node) - return error_mark_node; - - for (pass = 0; pass < 2; pass++) - { - struct candidate *candidates = 0; - struct candidate *cp = 0; - int len = 0; - unsigned best = 1; - - baselink = result; - - if (pass > 0) - { - candidates - = (struct candidate *) alloca ((ever_seen+1) - * sizeof (struct candidate)); - bzero ((char *) candidates, (ever_seen + 1) * sizeof (struct candidate)); - cp = candidates; - len = list_length (parms); - ever_seen = 0; - - /* First see if a global function has a shot at it. */ - if (flags & LOOKUP_GLOBAL) - { - tree friend_parms; - tree parm = instance_ptr; - - if (TREE_CODE (TREE_TYPE (parm)) == REFERENCE_TYPE) - parm = convert_from_reference (parm); - else if (TREE_CODE (TREE_TYPE (parm)) == POINTER_TYPE) - parm = build_indirect_ref (parm, "friendifying parms (compiler error)"); - else - my_friendly_abort (167); - - friend_parms = expr_tree_cons (NULL_TREE, parm, TREE_CHAIN (parms)); - - cp->h_len = len; - cp->harshness = (struct harshness_code *) - alloca ((len + 1) * sizeof (struct harshness_code)); - - result = build_overload_call_real (name, friend_parms, 0, cp, 1); - - /* If it turns out to be the one we were actually looking for - (it was probably a friend function), the return the - good result. */ - if (TREE_CODE (result) == CALL_EXPR) - return result; - - while ((cp->h.code & EVIL_CODE) == 0) - { - /* non-standard uses: set the field to 0 to indicate - we are using a non-member function. */ - cp->u.field = 0; - if (cp->harshness[len].distance == 0 - && cp->h.code < best) - best = cp->h.code; - cp += 1; - } - } - } - - if (baselink) - { - /* We have a hit (of sorts). If the parameter list is - "error_mark_node", or some variant thereof, it won't - match any methods. Since we have verified that the is - some method vaguely matching this one (in name at least), - silently return. - - Don't stop for friends, however. */ - basetype_path = TREE_PURPOSE (baselink); - - function = TREE_VALUE (baselink); - if (TREE_CODE (basetype_path) == TREE_LIST) - basetype_path = TREE_VALUE (basetype_path); - basetype = BINFO_TYPE (basetype_path); - - for (; function; function = DECL_CHAIN (function)) - { -#ifdef GATHER_STATISTICS - n_inner_fields_searched++; -#endif - ever_seen++; - if (pass > 0) - found_fns = scratch_tree_cons (NULL_TREE, function, found_fns); - - /* Not looking for friends here. */ - if (TREE_CODE (TREE_TYPE (function)) == FUNCTION_TYPE - && ! DECL_STATIC_FUNCTION_P (function)) - continue; - - if (pass > 0) - { - tree these_parms = parms; - -#ifdef GATHER_STATISTICS - n_inner_fields_searched++; -#endif - cp->h_len = len; - cp->harshness = (struct harshness_code *) - alloca ((len + 1) * sizeof (struct harshness_code)); - - if (DECL_STATIC_FUNCTION_P (function)) - these_parms = TREE_CHAIN (these_parms); - compute_conversion_costs (function, these_parms, cp, len); - - if ((cp->h.code & EVIL_CODE) == 0) - { - cp->u.field = function; - cp->function = function; - cp->basetypes = basetype_path; - - /* Don't allow non-converting constructors to convert. */ - if (flags & LOOKUP_ONLYCONVERTING - && DECL_LANG_SPECIFIC (function) - && DECL_NONCONVERTING_P (function)) - continue; - - /* No "two-level" conversions. */ - if (flags & LOOKUP_NO_CONVERSION - && (cp->h.code & USER_CODE)) - continue; - - cp++; - } - } - } - } - - if (pass == 0) - { - tree igv = lookup_name_nonclass (name); - - /* No exact match could be found. Now try to find match - using default conversions. */ - if ((flags & LOOKUP_GLOBAL) && igv) - { - if (TREE_CODE (igv) == FUNCTION_DECL) - ever_seen += 1; - else if (TREE_CODE (igv) == TREE_LIST) - ever_seen += count_functions (igv); - } - - if (ever_seen == 0) - { - if ((flags & (LOOKUP_SPECULATIVELY|LOOKUP_COMPLAIN)) - == LOOKUP_SPECULATIVELY) - return NULL_TREE; - - TREE_CHAIN (last) = void_list_node; - if (flags & LOOKUP_GLOBAL) - cp_error ("no global or member function `%D(%A)' defined", - save_name, parmtypes); - else - cp_error ("no member function `%T::%D(%A)' defined", - save_basetype, save_name, TREE_CHAIN (parmtypes)); - return error_mark_node; - } - continue; - } - - if (cp - candidates != 0) - { - /* Rank from worst to best. Then cp will point to best one. - Private fields have their bits flipped. For unsigned - numbers, this should make them look very large. - If the best alternate has a (signed) negative value, - then all we ever saw were private members. */ - if (cp - candidates > 1) - { - int n_candidates = cp - candidates; - extern int warn_synth; - TREE_VALUE (parms) = instance_ptr; - cp = ideal_candidate (candidates, n_candidates, len); - if (cp == (struct candidate *)0) - { - if (flags & LOOKUP_COMPLAIN) - { - TREE_CHAIN (last) = void_list_node; - cp_error ("call of overloaded %s `%D(%A)' is ambiguous", - name_kind, save_name, TREE_CHAIN (parmtypes)); - print_n_candidates (candidates, n_candidates); - } - return error_mark_node; - } - if (cp->h.code & EVIL_CODE) - return error_mark_node; - if (warn_synth - && DECL_NAME (cp->function) == ansi_opname[MODIFY_EXPR] - && DECL_ARTIFICIAL (cp->function) - && n_candidates == 2) - { - cp_warning ("using synthesized `%#D' for copy assignment", - cp->function); - cp_warning_at (" where cfront would use `%#D'", - candidates->function); - } - } - else if (cp[-1].h.code & EVIL_CODE) - { - if (flags & LOOKUP_COMPLAIN) - cp_error ("ambiguous type conversion requested for %s `%D'", - name_kind, save_name); - return error_mark_node; - } - else - cp--; - - /* The global function was the best, so use it. */ - if (cp->u.field == 0) - { - /* We must convert the instance pointer into a reference type. - Global overloaded functions can only either take - aggregate objects (which come for free from references) - or reference data types anyway. */ - TREE_VALUE (parms) = copy_node (instance_ptr); - TREE_TYPE (TREE_VALUE (parms)) = build_reference_type (TREE_TYPE (TREE_TYPE (instance_ptr))); - return build_function_call (cp->function, parms); - } - - function = cp->function; - basetype_path = cp->basetypes; - if (! DECL_STATIC_FUNCTION_P (function)) - TREE_VALUE (parms) = cp->arg; - goto found_and_maybe_warn; - } - - if (flags & (LOOKUP_COMPLAIN|LOOKUP_SPECULATIVELY)) - { - if ((flags & (LOOKUP_SPECULATIVELY|LOOKUP_COMPLAIN)) - == LOOKUP_SPECULATIVELY) - return NULL_TREE; - - if (DECL_STATIC_FUNCTION_P (cp->function)) - parms = TREE_CHAIN (parms); - if (ever_seen) - { - if (flags & LOOKUP_SPECULATIVELY) - return NULL_TREE; - if (static_call_context - && TREE_CODE (TREE_TYPE (cp->function)) == METHOD_TYPE) - cp_error ("object missing in call to `%D'", cp->function); - else if (ever_seen > 1) - { - TREE_CHAIN (last) = void_list_node; - cp_error ("no matching function for call to `%T::%D (%A)%V'", - TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (instance_ptr))), - save_name, TREE_CHAIN (parmtypes), - TREE_TYPE (TREE_TYPE (instance_ptr))); - TREE_CHAIN (last) = NULL_TREE; - print_candidates (found_fns); - } - else - report_type_mismatch (cp, parms, name_kind); - return error_mark_node; - } - - if ((flags & (LOOKUP_SPECULATIVELY|LOOKUP_COMPLAIN)) - == LOOKUP_COMPLAIN) - { - cp_error ("%T has no method named %D", save_basetype, save_name); - return error_mark_node; - } - return NULL_TREE; - } - continue; - - found_and_maybe_warn: - if ((cp->harshness[0].code & CONST_CODE) - /* 12.1p2: Constructors can be called for const objects. */ - && ! DECL_CONSTRUCTOR_P (cp->function)) - { - if (flags & LOOKUP_COMPLAIN) - { - cp_error_at ("non-const member function `%D'", cp->function); - error ("called for const object at this point in file"); - } - /* Not good enough for a match. */ - else - return error_mark_node; - } - goto found; - } - /* Silently return error_mark_node. */ - return error_mark_node; - - found: - if (flags & LOOKUP_PROTECT) - access = compute_access (basetype_path, function); - - if (access == access_private_node) - { - if (flags & LOOKUP_COMPLAIN) - { - cp_error_at ("%s `%+#D' is %s", name_kind, function, - TREE_PRIVATE (function) ? "private" - : "from private base class"); - error ("within this context"); - } - return error_mark_node; - } - else if (access == access_protected_node) - { - if (flags & LOOKUP_COMPLAIN) - { - cp_error_at ("%s `%+#D' %s", name_kind, function, - TREE_PROTECTED (function) ? "is protected" - : "has protected accessibility"); - error ("within this context"); - } - return error_mark_node; - } - - /* From here on down, BASETYPE is the type that INSTANCE_PTR's - type (if it exists) is a pointer to. */ - - if (DECL_ABSTRACT_VIRTUAL_P (function) - && instance == current_class_ref - && DECL_CONSTRUCTOR_P (current_function_decl) - && ! (flags & LOOKUP_NONVIRTUAL) - && value_member (function, get_abstract_virtuals (basetype))) - cp_error ("abstract virtual `%#D' called from constructor", function); - - if (IS_SIGNATURE (basetype)) - { - if (static_call_context) - { - cp_error ("cannot call signature member function `%T::%D' without signature pointer/reference", - basetype, save_name); - return error_mark_node; - } - return build_signature_method_call (function, parms); - } - - function = DECL_MAIN_VARIANT (function); - mark_used (function); - - fntype = TREE_TYPE (function); - if (TREE_CODE (fntype) == POINTER_TYPE) - fntype = TREE_TYPE (fntype); - basetype = DECL_CLASS_CONTEXT (function); - - /* If we are referencing a virtual function from an object - of effectively static type, then there is no need - to go through the virtual function table. */ - if (need_vtbl == maybe_needed) - { - int fixed_type = resolves_to_fixed_type_p (instance, 0); - - if (all_virtual == 1 - && DECL_VINDEX (function) - && may_be_remote (basetype)) - need_vtbl = needed; - else if (DECL_VINDEX (function)) - need_vtbl = fixed_type ? unneeded : needed; - else - need_vtbl = not_needed; - } - - if (TREE_CODE (fntype) == METHOD_TYPE && static_call_context - && !DECL_CONSTRUCTOR_P (function)) - { - /* Let's be nasty to the user now, and give reasonable - error messages. */ - instance_ptr = current_class_ptr; - if (instance_ptr) - { - if (basetype != current_class_type) - { - if (basetype == error_mark_node) - return error_mark_node; - else - { - if (orig_basetype != NULL_TREE) - error_not_base_type (orig_basetype, current_class_type); - else - error_not_base_type (function, current_class_type); - return error_mark_node; - } - } - } - /* Only allow a static member function to call another static member - function. */ - else if (DECL_LANG_SPECIFIC (function) - && !DECL_STATIC_FUNCTION_P (function)) - { - cp_error ("cannot call member function `%D' without object", - function); - return error_mark_node; - } - } - - value_type = TREE_TYPE (fntype) ? TREE_TYPE (fntype) : void_type_node; - - if (TYPE_SIZE (complete_type (value_type)) == 0) - { - if (flags & LOOKUP_COMPLAIN) - incomplete_type_error (0, value_type); - return error_mark_node; - } - - if (DECL_STATIC_FUNCTION_P (function)) - parms = convert_arguments (NULL_TREE, TYPE_ARG_TYPES (fntype), - TREE_CHAIN (parms), function, LOOKUP_NORMAL); - else if (need_vtbl == unneeded) - { - int sub_flags = DECL_CONSTRUCTOR_P (function) ? flags : LOOKUP_NORMAL; - basetype = TREE_TYPE (instance); - if (TYPE_METHOD_BASETYPE (TREE_TYPE (function)) - != TYPE_MAIN_VARIANT (basetype)) - { - basetype = DECL_CLASS_CONTEXT (function); - instance_ptr = convert_pointer_to (basetype, instance_ptr); - instance = build_indirect_ref (instance_ptr, NULL_PTR); - } - parms = expr_tree_cons (NULL_TREE, instance_ptr, - convert_arguments (NULL_TREE, TREE_CHAIN (TYPE_ARG_TYPES (fntype)), TREE_CHAIN (parms), function, sub_flags)); - } - else - { - if ((flags & LOOKUP_NONVIRTUAL) == 0) - basetype = DECL_CONTEXT (function); - - /* First parm could be integer_zerop with casts like - ((Object*)0)->Object::IsA() */ - if (!integer_zerop (TREE_VALUE (parms))) - { - /* Since we can't have inheritance with a union, doing get_binfo - on it won't work. We do all the convert_pointer_to_real - stuff to handle MI correctly...for unions, that's not - an issue, so we must short-circuit that extra work here. */ - tree tmp = TREE_TYPE (TREE_TYPE (TREE_VALUE (parms))); - if (tmp != NULL_TREE && TREE_CODE (tmp) == UNION_TYPE) - instance_ptr = TREE_VALUE (parms); - else - { - tree binfo = get_binfo (basetype, - TREE_TYPE (TREE_TYPE (TREE_VALUE (parms))), - 0); - instance_ptr = convert_pointer_to_real (binfo, TREE_VALUE (parms)); - } - instance_ptr - = convert_pointer_to (build_type_variant (basetype, - constp, volatilep), - instance_ptr); - - if (TREE_CODE (instance_ptr) == COND_EXPR) - { - instance_ptr = save_expr (instance_ptr); - instance = build_indirect_ref (instance_ptr, NULL_PTR); - } - else if (TREE_CODE (instance_ptr) == NOP_EXPR - && TREE_CODE (TREE_OPERAND (instance_ptr, 0)) == ADDR_EXPR - && TREE_OPERAND (TREE_OPERAND (instance_ptr, 0), 0) == instance) - ; - /* The call to `convert_pointer_to' may return error_mark_node. */ - else if (instance_ptr == error_mark_node) - return instance_ptr; - else if (instance == NULL_TREE - || TREE_CODE (instance) != INDIRECT_REF - || TREE_OPERAND (instance, 0) != instance_ptr) - instance = build_indirect_ref (instance_ptr, NULL_PTR); - } - parms = expr_tree_cons (NULL_TREE, instance_ptr, - convert_arguments (NULL_TREE, TREE_CHAIN (TYPE_ARG_TYPES (fntype)), TREE_CHAIN (parms), function, LOOKUP_NORMAL)); - } - - if (parms == error_mark_node - || (parms && TREE_CHAIN (parms) == error_mark_node)) - return error_mark_node; - - if (need_vtbl == needed) - { - function = build_vfn_ref (&TREE_VALUE (parms), instance, - DECL_VINDEX (function)); - TREE_TYPE (function) = build_pointer_type (fntype); - } - - if (TREE_CODE (function) == FUNCTION_DECL) - GNU_xref_call (current_function_decl, - IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (function))); - - result = build_call (function, value_type, parms); - if (IS_AGGR_TYPE (value_type)) - result = build_cplus_new (value_type, result); - result = convert_from_reference (result); - return result; -} - -/* Similar to `build_method_call', but for overloaded non-member functions. - The name of this function comes through NAME. The name depends - on PARMS. - - Note that this function must handle simple `C' promotions, - as well as variable numbers of arguments (...), and - default arguments to boot. - - If the overloading is successful, we return a tree node which - contains the call to the function. - - If overloading produces candidates which are probable, but not definite, - we hold these candidates. If FINAL_CP is non-zero, then we are free - to assume that final_cp points to enough storage for all candidates that - this function might generate. The `harshness' array is preallocated for - the first candidate, but not for subsequent ones. - - Note that the DECL_RTL of FUNCTION must be made to agree with this - function's new name. */ - -tree -build_overload_call_real (fnname, parms, flags, final_cp, require_complete) - tree fnname, parms; - int flags; - struct candidate *final_cp; - int require_complete; -{ - /* must check for overloading here */ - tree functions, function; - tree parmtypes, last; - register tree outer; - int length; - int parmlength = list_length (parms); - - struct candidate *candidates, *cp; - - if (final_cp) - { - final_cp[0].h.code = 0; - final_cp[0].h.distance = 0; - final_cp[0].function = 0; - /* end marker. */ - final_cp[1].h.code = EVIL_CODE; - } - - parmtypes = default_parm_conversions (parms, &last); - if (parmtypes == error_mark_node) - { - if (final_cp) - final_cp->h.code = EVIL_CODE; - return error_mark_node; - } - - if (last) - TREE_CHAIN (last) = void_list_node; - else - parmtypes = void_list_node; - - if (is_overloaded_fn (fnname)) - { - functions = fnname; - if (TREE_CODE (fnname) == TREE_LIST) - fnname = TREE_PURPOSE (functions); - else if (TREE_CODE (fnname) == FUNCTION_DECL) - fnname = DECL_NAME (functions); - } - else - functions = lookup_name_nonclass (fnname); - - if (functions == NULL_TREE) - { - if (flags & LOOKUP_SPECULATIVELY) - return NULL_TREE; - if (flags & LOOKUP_COMPLAIN) - error ("only member functions apply"); - if (final_cp) - final_cp->h.code = EVIL_CODE; - return error_mark_node; - } - - if (TREE_CODE (functions) == FUNCTION_DECL && ! IDENTIFIER_OPNAME_P (fnname)) - { - functions = DECL_MAIN_VARIANT (functions); - if (final_cp) - { - /* We are just curious whether this is a viable alternative or - not. */ - compute_conversion_costs (functions, parms, final_cp, parmlength); - return functions; - } - else - return build_function_call_real (functions, parms, 1, flags); - } - - if (TREE_CODE (functions) == TREE_LIST - && TREE_VALUE (functions) == NULL_TREE) - { - if (flags & LOOKUP_SPECULATIVELY) - return NULL_TREE; - - if (flags & LOOKUP_COMPLAIN) - cp_error ("function `%D' declared overloaded, but no instances of that function declared", - TREE_PURPOSE (functions)); - if (final_cp) - final_cp->h.code = EVIL_CODE; - return error_mark_node; - } - - length = count_functions (functions); - - if (final_cp) - candidates = final_cp; - else - { - candidates - = (struct candidate *)alloca ((length+1) * sizeof (struct candidate)); - bzero ((char *) candidates, (length + 1) * sizeof (struct candidate)); - } - - cp = candidates; - - my_friendly_assert (is_overloaded_fn (functions), 169); - - functions = get_first_fn (functions); - - /* OUTER is the list of FUNCTION_DECLS, in a TREE_LIST. */ - for (outer = functions; outer; outer = DECL_CHAIN (outer)) - { - int template_cost = 0; - function = outer; - if (TREE_CODE (function) != FUNCTION_DECL - && ! (TREE_CODE (function) == TEMPLATE_DECL - && TREE_CODE (DECL_TEMPLATE_RESULT (function)) == FUNCTION_DECL)) - { - enum tree_code code = TREE_CODE (function); - if (code == TEMPLATE_DECL) - code = TREE_CODE (DECL_TEMPLATE_RESULT (function)); - if (code == CONST_DECL) - cp_error_at - ("enumeral value `%D' conflicts with function of same name", - function); - else if (code == VAR_DECL) - { - if (TREE_STATIC (function)) - cp_error_at - ("variable `%D' conflicts with function of same name", - function); - else - cp_error_at - ("constant field `%D' conflicts with function of same name", - function); - } - else if (code == TYPE_DECL) - continue; - else - my_friendly_abort (2); - error ("at this point in file"); - continue; - } - if (TREE_CODE (function) == TEMPLATE_DECL) - { - int ntparms = DECL_NTPARMS (function); - tree targs = make_scratch_vec (ntparms); - int i; - - i = type_unification (DECL_INNERMOST_TEMPLATE_PARMS (function), - &TREE_VEC_ELT (targs, 0), - TYPE_ARG_TYPES (TREE_TYPE (function)), - parms, NULL_TREE, 0, 0); - if (i == 0) - { - function = instantiate_template (function, targs); - if (function == error_mark_node) - return function; - } - } - - if (TREE_CODE (function) == TEMPLATE_DECL) - { - /* Unconverted template -- failed match. */ - cp->function = function; - cp->u.bad_arg = -4; - cp->h.code = EVIL_CODE; - } - else - { - struct candidate *cp2; - - /* Check that this decl is not the same as a function that's in - the list due to some template instantiation. */ - cp2 = candidates; - while (cp2 != cp) - if (cp2->function == function) - break; - else - cp2 += 1; - if (cp2->function == function) - continue; - - function = DECL_MAIN_VARIANT (function); - - /* Can't use alloca here, since result might be - passed to calling function. */ - cp->h_len = parmlength; - cp->harshness = (struct harshness_code *) - scratchalloc ((parmlength + 1) * sizeof (struct harshness_code)); - - compute_conversion_costs (function, parms, cp, parmlength); - - /* Make sure this is clear as well. */ - cp->h.int_penalty += template_cost; - - if ((cp[0].h.code & EVIL_CODE) == 0) - { - cp[1].h.code = EVIL_CODE; - cp++; - } - } - } - - if (cp - candidates) - { - tree rval = error_mark_node; - - /* Leave marker. */ - cp[0].h.code = EVIL_CODE; - if (cp - candidates > 1) - { - struct candidate *best_cp - = ideal_candidate (candidates, cp - candidates, parmlength); - if (best_cp == (struct candidate *)0) - { - if (flags & LOOKUP_COMPLAIN) - { - cp_error ("call of overloaded `%D' is ambiguous", fnname); - print_n_candidates (candidates, cp - candidates); - } - return error_mark_node; - } - else - rval = best_cp->function; - } - else - { - cp -= 1; - if (cp->h.code & EVIL_CODE) - { - if (flags & LOOKUP_COMPLAIN) - error ("type conversion ambiguous"); - } - else - rval = cp->function; - } - - if (final_cp) - return rval; - - return build_function_call_real (rval, parms, require_complete, flags); - } - - if (flags & LOOKUP_SPECULATIVELY) - return NULL_TREE; - - if (flags & LOOKUP_COMPLAIN) - report_type_mismatch (cp, parms, "function"); - - return error_mark_node; -} - -/* This requires a complete type on the result of the call. */ - -tree -build_overload_call (fnname, parms, flags) - tree fnname, parms; - int flags; -{ - return build_overload_call_real (fnname, parms, flags, (struct candidate *)0, 1); + return build_new_method_call (instance, name, parms, basetype_path, flags); } /* New overloading code. */ @@ -6451,32 +4125,14 @@ int can_convert (to, from) tree to, from; { - if (flag_ansi_overloading) - { - tree t = implicit_conversion (to, from, NULL_TREE, LOOKUP_NORMAL); - return (t && ! ICS_BAD_FLAG (t)); - } - else - { - struct harshness_code h; - h = convert_harshness (to, from, NULL_TREE); - return (h.code < USER_CODE) && (h.distance >= 0); - } + tree t = implicit_conversion (to, from, NULL_TREE, LOOKUP_NORMAL); + return (t && ! ICS_BAD_FLAG (t)); } int can_convert_arg (to, from, arg) tree to, from, arg; { - if (flag_ansi_overloading) - { - tree t = implicit_conversion (to, from, arg, LOOKUP_NORMAL); - return (t && ! ICS_BAD_FLAG (t)); - } - else - { - struct harshness_code h; - h = convert_harshness (to, from, arg); - return (h.code < USER_CODE) && (h.distance >= 0); - } + tree t = implicit_conversion (to, from, arg, LOOKUP_NORMAL); + return (t && ! ICS_BAD_FLAG (t)); } diff --git a/gcc/cp/class.c b/gcc/cp/class.c index da2f4190526..f13180fb973 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -3229,7 +3229,7 @@ finish_struct_1 (t, warn_anon) if (IS_SIGNATURE (t)) all_virtual = 0; - else if (flag_all_virtual == 1 && TYPE_OVERLOADS_METHOD_CALL_EXPR (t)) + else if (flag_all_virtual == 1) all_virtual = 1; else all_virtual = 0; diff --git a/gcc/cp/class.h b/gcc/cp/class.h deleted file mode 100644 index 12e45f78415..00000000000 --- a/gcc/cp/class.h +++ /dev/null @@ -1,117 +0,0 @@ -/* Variables and structures for overloading rules. - Copyright (C) 1993 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* The following structure is used when comparing various alternatives - for overloading. The unsigned quantity `strikes.i' is used - for fast comparison of two possibilities. This number is an - aggregate of four constituents: - - EVIL: if this is non-zero, then the candidate should not be considered - ELLIPSIS: if this is non-zero, then some actual argument has been matched - against an ellipsis - USER: if this is non-zero, then a user-defined type conversion is needed - B_OR_D: if this is non-zero, then use a base pointer instead of the - type of the pointer we started with. - EASY: if this is non-zero, then we have a builtin conversion - (such as int to long, int to float, etc) to do. - - If two candidates require user-defined type conversions, and the - type conversions are not identical, then an ambiguity error - is reported. - - If two candidates agree on user-defined type conversions, - and one uses pointers of strictly higher type (derived where - another uses base), then that alternative is silently chosen. - - Note that this technique really only works for 255 arguments. Perhaps - this is not enough. */ - -/* These macros and harshness_code are used by the NEW METHOD. */ -#define EVIL_CODE (1<<7) -#define CONST_CODE (1<<6) -#define ELLIPSIS_CODE (1<<5) -#define USER_CODE (1<<4) -#define STD_CODE (1<<3) -#define PROMO_CODE (1<<2) -#define QUAL_CODE (1<<1) -#define TRIVIAL_CODE (1<<0) - -struct harshness_code -{ - /* What kind of conversion is involved. */ - unsigned short code; - - /* The inheritance distance. */ - short distance; - - /* For a PROMO_CODE, Any special penalties involved in integral conversions. - This exists because $4.1 of the ARM states that something like - `short unsigned int' should promote to `int', not `unsigned int'. - If, for example, it tries to match two fns, f(int) and f(unsigned), - f(int) should be a better match than f(unsigned) by this rule. Without - this extra metric, they both only appear as "integral promotions", which - will lead to an ambiguity. - For a TRIVIAL_CODE, This is also used by build_overload_call_real and - convert_harshness to keep track of other information we need. */ - unsigned short int_penalty; -}; - -struct candidate -{ - struct harshness_code h; /* Used for single-argument conversions. */ - - int h_len; /* The length of the harshness vector. */ - - tree function; /* A FUNCTION_DECL */ - tree basetypes; /* The path to function. */ - tree arg; /* first parm to function. */ - - /* Indexed by argument number, encodes evil, user, d_to_b, and easy - strikes for that argument. At end of array, we store the index+1 - of where we started using default parameters, or 0 if there are - none. */ - struct harshness_code *harshness; - - union - { - tree field; /* If no evil strikes, the FUNCTION_DECL of - the function (if a member function). */ - int bad_arg; /* the index of the first bad argument: - 0 if no bad arguments - > 0 is first bad argument - -1 if extra actual arguments - -2 if too few actual arguments. - -3 if const/non const method mismatch. - -4 if type unification failed. - -5 if contravariance violation. */ - } u; -}; -int rank_for_overload PROTO ((struct candidate *, struct candidate *)); - -/* Variables shared between class.c and call.c. */ - -extern int n_vtables; -extern int n_vtable_entries; -extern int n_vtable_searches; -extern int n_vtable_elems; -extern int n_convert_harshness; -extern int n_compute_conversion_costs; -extern int n_build_method_call; -extern int n_inner_fields_searched; diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 5f346b51488..95bc071aee0 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -327,11 +327,6 @@ extern int flag_elide_constructors; extern int flag_ansi; -/* Nonzero means do argument matching for overloading according to the - ANSI rules, rather than what g++ used to believe to be correct. */ - -extern int flag_ansi_overloading; - /* Nonzero means recognize and handle signature language constructs. */ extern int flag_handle_signatures; @@ -620,10 +615,6 @@ struct lang_type convenient, don't reprocess any methods that appear in its redefinition. */ #define TYPE_REDEFINED(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.redefined) -/* Nonzero means that this _CLASSTYPE node overloads the method call - operator. In this case, all method calls go through `operator->()(...). */ -#define TYPE_OVERLOADS_METHOD_CALL_EXPR(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_method_call_overloaded) - /* Nonzero means that this type is a signature. */ # define IS_SIGNATURE(NODE) (TYPE_LANG_SPECIFIC(NODE)?TYPE_LANG_SPECIFIC(NODE)->type_flags.is_signature:0) # define SET_SIGNATURE(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.is_signature=1) @@ -2039,19 +2030,14 @@ extern tree current_class_type; /* _TYPE: the type of the current class */ extern char **opname_tab, **assignop_tab; /* in call.c */ -extern struct candidate *ansi_c_filler; extern int get_arglist_len_in_bytes PROTO((tree)); -extern int rank_for_overload PROTO((struct candidate *, struct candidate *)); -extern void compute_conversion_costs PROTO((tree, tree, struct candidate *, int)); extern tree build_vfield_ref PROTO((tree, tree)); extern tree resolve_scope_to_name PROTO((tree, tree)); extern tree build_scoped_method_call PROTO((tree, tree, tree, tree)); extern tree build_addr_func PROTO((tree)); extern tree build_call PROTO((tree, tree, tree)); extern tree build_method_call PROTO((tree, tree, tree, tree, int)); -extern tree build_overload_call_real PROTO((tree, tree, int, struct candidate *, int)); -extern tree build_overload_call PROTO((tree, tree, int)); extern int null_ptr_cst_p PROTO((tree)); extern tree type_decays_to PROTO((tree)); extern tree build_user_type_conversion PROTO((tree, tree, int)); @@ -2090,7 +2076,6 @@ extern void warn_hidden PROTO((tree)); /* in cvt.c */ extern tree convert_to_reference PROTO((tree, tree, int, int, tree)); extern tree convert_from_reference PROTO((tree)); -extern tree convert_to_aggr PROTO((tree, tree, char **, int)); extern tree convert_pointer_to_real PROTO((tree, tree)); extern tree convert_pointer_to PROTO((tree, tree)); extern tree ocp_convert PROTO((tree, tree, int, int)); @@ -2399,7 +2384,6 @@ extern void yyhook PROTO((int)); /* in method.c */ extern void init_method PROTO((void)); extern void do_inline_function_hair PROTO((tree, tree)); -extern void report_type_mismatch PROTO((struct candidate *, tree, char *)); extern char *build_overload_name PROTO((tree, int, int)); extern tree build_static_name PROTO((tree, tree)); extern tree build_decl_overload PROTO((tree, tree, int)); diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index d308805aa62..05cd6677770 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -30,7 +30,6 @@ Boston, MA 02111-1307, USA. */ #include "tree.h" #include "flags.h" #include "cp-tree.h" -#include "class.h" #include "convert.h" #ifdef HAVE_STDLIB_H @@ -482,11 +481,8 @@ convert_to_reference (reftype, expr, convtype, flags, decl) { /* Look for a user-defined conversion to lvalue that we can use. */ - if (flag_ansi_overloading) - rval_as_conversion - = build_type_conversion (CONVERT_EXPR, reftype, expr, 1); - else - rval_as_conversion = build_type_conversion (CONVERT_EXPR, type, expr, 1); + rval_as_conversion + = build_type_conversion (CONVERT_EXPR, reftype, expr, 1); if (rval_as_conversion && rval_as_conversion != error_mark_node && real_lvalue_p (rval_as_conversion)) @@ -556,7 +552,7 @@ convert_to_reference (reftype, expr, convtype, flags, decl) if (rval != error_mark_node) rval = build1 (NOP_EXPR, reftype, rval); } - else if (flag_ansi_overloading) + else { rval = convert_for_initialization (NULL_TREE, type, expr, flags, "converting", 0, 0); @@ -568,89 +564,6 @@ convert_to_reference (reftype, expr, convtype, flags, decl) cp_pedwarn ("initializing non-const `%T' with `%T' will use a temporary", reftype, intype); } - else - { - tree rval_as_ctor = NULL_TREE; - - if (rval_as_conversion) - { - if (rval_as_conversion == error_mark_node) - { - cp_error ("conversion from `%T' to `%T' is ambiguous", - intype, reftype); - return error_mark_node; - } - rval_as_conversion = build_up_reference (reftype, rval_as_conversion, - flags, 1); - } - - /* Definitely need to go through a constructor here. */ - if (TYPE_HAS_CONSTRUCTOR (type) - && ! CLASSTYPE_ABSTRACT_VIRTUALS (type) - && (rval = build_method_call - (NULL_TREE, ctor_identifier, - build_expr_list (NULL_TREE, expr), TYPE_BINFO (type), - LOOKUP_NO_CONVERSION|LOOKUP_SPECULATIVELY - | LOOKUP_ONLYCONVERTING))) - { - tree init; - - if (toplevel_bindings_p ()) - { - tree t = get_temp_name (type, toplevel_bindings_p ()); - init = build_method_call (t, ctor_identifier, - build_expr_list (NULL_TREE, expr), - TYPE_BINFO (type), - LOOKUP_NORMAL|LOOKUP_NO_CONVERSION - | LOOKUP_ONLYCONVERTING); - - if (init == error_mark_node) - return error_mark_node; - - make_decl_rtl (t, NULL_PTR, 1); - static_aggregates = perm_tree_cons (expr, t, static_aggregates); - rval = build_unary_op (ADDR_EXPR, t, 0); - } - else - { - init = build_method_call (NULL_TREE, ctor_identifier, - build_expr_list (NULL_TREE, expr), - TYPE_BINFO (type), - LOOKUP_NORMAL|LOOKUP_NO_CONVERSION - |LOOKUP_ONLYCONVERTING); - - if (init == error_mark_node) - return error_mark_node; - - rval = build_cplus_new (type, init); - rval = build_up_reference (reftype, rval, flags, 1); - } - rval_as_ctor = rval; - } - - if (rval_as_ctor && rval_as_conversion) - { - cp_error ("ambiguous conversion from `%T' to `%T'; both user-defined conversion and constructor apply", - intype, reftype); - return error_mark_node; - } - else if (rval_as_ctor) - rval = rval_as_ctor; - else if (rval_as_conversion) - rval = rval_as_conversion; - else if (! IS_AGGR_TYPE (type) && ! IS_AGGR_TYPE (intype)) - { - rval = cp_convert (type, expr); - if (rval == error_mark_node) - return error_mark_node; - - rval = build_up_reference (reftype, rval, flags, 1); - } - - if (rval && ! TYPE_READONLY (TREE_TYPE (reftype))) - cp_pedwarn ("initializing non-const `%T' with `%T' will use a temporary", - reftype, intype); - } if (rval) { @@ -685,190 +598,6 @@ convert_from_reference (val) return val; } -/* See if there is a constructor of type TYPE which will convert - EXPR. The reference manual seems to suggest (8.5.6) that we need - not worry about finding constructors for base classes, then converting - to the derived class. - - MSGP is a pointer to a message that would be an appropriate error - string. If MSGP is NULL, then we are not interested in reporting - errors. */ - -tree -convert_to_aggr (type, expr, msgp, protect) - tree type, expr; - char **msgp; - int protect; -{ - tree basetype = type; - tree name = TYPE_IDENTIFIER (basetype); - tree function, fndecl, fntype, parmtypes, parmlist, result; -#if 0 - /* See code below that used this. */ - tree method_name; -#endif - tree access; - int can_be_private, can_be_protected; - - if (! TYPE_HAS_CONSTRUCTOR (basetype)) - { - if (msgp) - *msgp = "type `%s' does not have a constructor"; - return error_mark_node; - } - - access = access_public_node; - can_be_private = 0; - can_be_protected = IDENTIFIER_CLASS_VALUE (name) || name == current_class_name; - - parmlist = build_expr_list (NULL_TREE, expr); - parmtypes = scratch_tree_cons (NULL_TREE, TREE_TYPE (expr), void_list_node); - - if (TYPE_USES_VIRTUAL_BASECLASSES (basetype)) - { - parmtypes = expr_tree_cons (NULL_TREE, integer_type_node, parmtypes); - parmlist = scratch_tree_cons (NULL_TREE, integer_one_node, parmlist); - } - - /* The type of the first argument will be filled in inside the loop. */ - parmlist = expr_tree_cons (NULL_TREE, integer_zero_node, parmlist); - parmtypes = scratch_tree_cons (NULL_TREE, build_pointer_type (basetype), parmtypes); - - /* No exact conversion was found. See if an approximate - one will do. */ - fndecl = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 0); - - { - int saw_private = 0; - int saw_protected = 0; - struct candidate *candidates - = (struct candidate *) alloca ((decl_list_length (fndecl)+1) * sizeof (struct candidate)); - struct candidate *cp = candidates; - - while (fndecl) - { - function = fndecl; - cp->h_len = 2; - cp->harshness = (struct harshness_code *) - alloca (3 * sizeof (struct harshness_code)); - - compute_conversion_costs (fndecl, parmlist, cp, 2); - if ((cp->h.code & EVIL_CODE) == 0) - { - cp->u.field = fndecl; - if (protect) - { - if (TREE_PRIVATE (fndecl)) - access = access_private_node; - else if (TREE_PROTECTED (fndecl)) - access = access_protected_node; - else - access = access_public_node; - } - else - access = access_public_node; - - if (access == access_private_node - ? (basetype == current_class_type - || is_friend (basetype, cp->function) - || purpose_member (basetype, DECL_ACCESS (fndecl))) - : access == access_protected_node - ? (can_be_protected - || purpose_member (basetype, DECL_ACCESS (fndecl))) - : 1) - { - if (cp->h.code <= TRIVIAL_CODE) - goto found_and_ok; - cp++; - } - else - { - if (access == access_private_node) - saw_private = 1; - else - saw_protected = 1; - } - } - fndecl = DECL_CHAIN (fndecl); - } - if (cp - candidates) - { - /* Rank from worst to best. Then cp will point to best one. - Private fields have their bits flipped. For unsigned - numbers, this should make them look very large. - If the best alternate has a (signed) negative value, - then all we ever saw were private members. */ - if (cp - candidates > 1) - qsort (candidates, /* char *base */ - cp - candidates, /* int nel */ - sizeof (struct candidate), /* int width */ - (int (*) PROTO((const void *, const void *))) rank_for_overload); /* int (*compar)() */ - - --cp; - if (cp->h.code & EVIL_CODE) - { - if (msgp) - *msgp = "ambiguous type conversion possible for `%s'"; - return error_mark_node; - } - - function = cp->function; - fndecl = cp->u.field; - goto found_and_ok; - } - else if (msgp) - { - if (saw_private) - { - if (saw_protected) - *msgp = "only private and protected conversions apply"; - else - *msgp = "only private conversions apply"; - } - else if (saw_protected) - *msgp = "only protected conversions apply"; - else - *msgp = "no appropriate conversion to type `%s'"; - } - return error_mark_node; - } - /* NOTREACHED */ - - found: - if (access == access_private_node) - if (! can_be_private) - { - if (msgp) - *msgp = TREE_PRIVATE (fndecl) - ? "conversion to type `%s' is private" - : "conversion to type `%s' is from private base class"; - return error_mark_node; - } - if (access == access_protected_node) - if (! can_be_protected) - { - if (msgp) - *msgp = TREE_PRIVATE (fndecl) - ? "conversion to type `%s' is protected" - : "conversion to type `%s' is from protected base class"; - return error_mark_node; - } - function = fndecl; - found_and_ok: - - /* It will convert, but we don't do anything about it yet. */ - if (msgp == 0) - return NULL_TREE; - - fntype = TREE_TYPE (function); - - parmlist = convert_arguments (NULL_TREE, TYPE_ARG_TYPES (fntype), - parmlist, NULL_TREE, LOOKUP_NORMAL); - - result = build_call (function, TREE_TYPE (fntype), parmlist); - return result; -} - /* Call this when we know (for any reason) that expr is not, in fact, zero. This routine is like convert_pointer_to, but it pays attention to which specific instance of what type we want to @@ -1119,71 +848,20 @@ ocp_convert (type, expr, convtype, flags) There may be some ambiguity between using a constructor vs. using a type conversion operator when both apply. */ - if (flag_ansi_overloading) + ctor = e; + + if ((flags & LOOKUP_ONLYCONVERTING) + && ! (IS_AGGR_TYPE (dtype) && DERIVED_FROM_P (type, dtype))) { - ctor = e; - - if ((flags & LOOKUP_ONLYCONVERTING) - && ! (IS_AGGR_TYPE (dtype) && DERIVED_FROM_P (type, dtype))) - { - ctor = build_user_type_conversion (type, ctor, flags); - flags |= LOOKUP_NO_CONVERSION; - } - if (ctor) - ctor = build_method_call (NULL_TREE, ctor_identifier, - build_expr_list (NULL_TREE, ctor), - TYPE_BINFO (type), flags); - if (ctor) - return build_cplus_new (type, ctor); - } - else - { - if (IS_AGGR_TYPE (dtype) && ! DERIVED_FROM_P (type, dtype) - && TYPE_HAS_CONVERSION (dtype)) - conversion = build_type_conversion (CONVERT_EXPR, type, e, 1); - - if (conversion == error_mark_node) - { - if (flags & LOOKUP_COMPLAIN) - error ("ambiguous pointer conversion"); - return conversion; - } - - if (TYPE_HAS_CONSTRUCTOR (complete_type (type))) - ctor = build_method_call (NULL_TREE, ctor_identifier, - build_expr_list (NULL_TREE, e), - TYPE_BINFO (type), - (flags & LOOKUP_NORMAL) - | LOOKUP_SPECULATIVELY - | (flags & LOOKUP_ONLYCONVERTING) - | (flags & LOOKUP_NO_CONVERSION) - | (conversion ? LOOKUP_NO_CONVERSION : 0)); - - if (ctor == error_mark_node) - { - if (flags & LOOKUP_COMPLAIN) - cp_error ("in conversion to type `%T'", type); - if (flags & LOOKUP_SPECULATIVELY) - return NULL_TREE; - return error_mark_node; - } - - if (conversion && ctor) - { - if (flags & LOOKUP_COMPLAIN) - error ("both constructor and type conversion operator apply"); - if (flags & LOOKUP_SPECULATIVELY) - return NULL_TREE; - return error_mark_node; - } - else if (conversion) - return conversion; - else if (ctor) - { - ctor = build_cplus_new (type, ctor); - return ctor; - } + ctor = build_user_type_conversion (type, ctor, flags); + flags |= LOOKUP_NO_CONVERSION; } + if (ctor) + ctor = build_method_call (NULL_TREE, ctor_identifier, + build_expr_list (NULL_TREE, ctor), + TYPE_BINFO (type), flags); + if (ctor) + return build_cplus_new (type, ctor); } /* If TYPE or TREE_TYPE (E) is not on the permanent_obstack, @@ -1339,64 +1017,8 @@ build_type_conversion (code, xtype, expr, for_sure) { /* C++: check to see if we can convert this aggregate type into the required type. */ - tree basetype; - tree conv; - tree winner = NULL_TREE; - - if (flag_ansi_overloading) - return build_user_type_conversion - (xtype, expr, for_sure ? LOOKUP_NORMAL : 0); - - if (expr == error_mark_node) - return error_mark_node; - - basetype = TREE_TYPE (expr); - if (TREE_CODE (basetype) == REFERENCE_TYPE) - basetype = TREE_TYPE (basetype); - - basetype = TYPE_MAIN_VARIANT (basetype); - if (! TYPE_LANG_SPECIFIC (basetype) || ! TYPE_HAS_CONVERSION (basetype)) - return NULL_TREE; - - /* Do we have an exact match? */ - { - tree typename = build_typename_overload (xtype); - if (lookup_fnfields (TYPE_BINFO (basetype), typename, 0)) - return build_type_conversion_1 (xtype, basetype, expr, typename, - for_sure); - } - - /* Nope; try looking for others. */ - for (conv = lookup_conversions (basetype); conv; conv = TREE_CHAIN (conv)) - { - tree cand = TREE_VALUE (conv); - - if (winner && winner == cand) - continue; - - if (can_convert (xtype, TREE_TYPE (TREE_TYPE (cand)))) - { - if (winner) - { - if (for_sure) - { - cp_error ("ambiguous conversion from `%T' to `%T'", basetype, - xtype); - cp_error (" candidate conversions include `%D' and `%D'", - winner, cand); - } - return NULL_TREE; - } - else - winner = cand; - } - } - - if (winner) - return build_type_conversion_1 (xtype, basetype, expr, - DECL_NAME (winner), for_sure); - - return NULL_TREE; + return build_user_type_conversion + (xtype, expr, for_sure ? LOOKUP_NORMAL : 0); } /* Convert the given EXPR to one of a group of types suitable for use in an diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index e5ab625e723..334db914a14 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -10760,8 +10760,7 @@ grok_op_properties (decl, virtualp, friendp) } } - if (name == ansi_opname[(int) CALL_EXPR] - || name == ansi_opname[(int) METHOD_CALL_EXPR]) + if (name == ansi_opname[(int) CALL_EXPR]) return; /* no restrictions on args */ if (IDENTIFIER_TYPENAME_P (name) && ! DECL_TEMPLATE_INFO (decl)) @@ -11245,7 +11244,6 @@ xref_basetypes (code_type_node, name, ref, binfo) TYPE_USES_COMPLEX_INHERITANCE (ref) = 1; } - TYPE_OVERLOADS_METHOD_CALL_EXPR (ref) |= TYPE_OVERLOADS_METHOD_CALL_EXPR (basetype); TYPE_GETS_NEW (ref) |= TYPE_GETS_NEW (basetype); TYPE_GETS_DELETE (ref) |= TYPE_GETS_DELETE (basetype); CLASSTYPE_LOCAL_TYPEDECLS (ref) |= CLASSTYPE_LOCAL_TYPEDECLS (basetype); diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index fa39b9e4b8d..24683421908 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -143,11 +143,6 @@ int flag_no_ident; int flag_ansi; -/* Nonzero means do argument matching for overloading according to the - ANSI rules, rather than what g++ used to believe to be correct. */ - -int flag_ansi_overloading = 1; - /* Nonzero means do emit exported implementations of functions even if they can be inlined. */ @@ -470,7 +465,6 @@ static struct { char *string; int *variable; int on_value;} lang_f_options[] = {"implement-inlines", &flag_implement_inlines, 1}, {"external-templates", &flag_external_templates, 1}, {"implicit-templates", &flag_implicit_templates, 1}, - {"ansi-overloading", &flag_ansi_overloading, 1}, {"huge-objects", &flag_huge_objects, 1}, {"conserve-space", &flag_conserve_space, 1}, {"vtable-thunks", &flag_vtable_thunks, 1}, @@ -565,6 +559,13 @@ lang_decode_option (p) flag_guiding_decls = 0; found = 1; } + else if (!strcmp (p, "ansi-overloading")) + found = 1; + else if (!strcmp (p, "no-ansi-overloading")) + { + error ("-fno-ansi-overloading is no longer supported"); + found = 1; + } else if (!strncmp (p, "template-depth-", 15)) { char *endp = p + 15; diff --git a/gcc/cp/init.c b/gcc/cp/init.c index ee68dfc1b48..a420092984f 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -1249,7 +1249,7 @@ expand_default_init (binfo, true_exp, exp, init, alias_this, flags) tree rval; tree parms; - if (flag_ansi_overloading && init && TREE_CODE (init) != TREE_LIST + if (init && TREE_CODE (init) != TREE_LIST && (flags & LOOKUP_ONLYCONVERTING)) { /* Base subobjects should only get direct-initialization. */ @@ -1287,15 +1287,6 @@ expand_default_init (binfo, true_exp, exp, init, alias_this, flags) if (parms) init = TREE_VALUE (parms); } - else if (! flag_ansi_overloading - && TREE_CODE (init) == INDIRECT_REF && TREE_HAS_CONSTRUCTOR (init) - && TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (init))) - { - rval = convert_for_initialization (exp, type, init, 0, 0, 0, 0); - TREE_USED (rval) = 1; - expand_expr_stmt (rval); - return; - } else parms = build_expr_list (NULL_TREE, init); @@ -1308,52 +1299,9 @@ expand_default_init (binfo, true_exp, exp, init, alias_this, flags) flags |= LOOKUP_HAS_IN_CHARGE; } - if (flag_ansi_overloading) - { - rval = build_method_call (exp, ctor_identifier, - parms, binfo, flags); - expand_expr_stmt (rval); - return; - } - - if (init && TREE_CHAIN (parms) == NULL_TREE - && TYPE_HAS_TRIVIAL_INIT_REF (type) - && TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (init))) - { - rval = build (INIT_EXPR, type, exp, init); - TREE_SIDE_EFFECTS (rval) = 1; - expand_expr_stmt (rval); - } - else - { - if (flags & LOOKUP_ONLYCONVERTING) - flags |= LOOKUP_NO_CONVERSION; - rval = build_method_call (exp, ctor_identifier, - parms, binfo, flags); - - /* Private, protected, or otherwise unavailable. */ - if (rval == error_mark_node) - { - if (flags & LOOKUP_COMPLAIN) - cp_error ("in base initialization for %sclass `%T'", - TREE_VIA_VIRTUAL (binfo) ? "virtual base " : "", - binfo); - } - else if (rval == NULL_TREE) - my_friendly_abort (361); - else - { - /* p. 222: if the base class assigns to `this', then that - value is used in the derived class. */ - if ((flag_this_is_variable & 1) && alias_this) - { - TREE_TYPE (rval) = TREE_TYPE (current_class_ptr); - expand_assignment (current_class_ptr, rval, 0, 0); - } - else - expand_expr_stmt (rval); - } - } + rval = build_method_call (exp, ctor_identifier, + parms, binfo, flags); + expand_expr_stmt (rval); } /* This function is responsible for initializing EXP with INIT @@ -1413,171 +1361,6 @@ expand_aggr_init_1 (binfo, true_exp, exp, init, alias_this, flags) return; } - if (init && ! flag_ansi_overloading) - { - tree init_list = NULL_TREE; - - if (TREE_CODE (init) == TREE_LIST) - { - init_list = init; - if (TREE_CHAIN (init) == NULL_TREE) - init = TREE_VALUE (init); - } - - init_type = TREE_TYPE (init); - - if (TREE_CODE (init) != TREE_LIST) - { - if (init_type == error_mark_node) - return; - - /* This happens when we use C++'s functional cast notation. - If the types match, then just use the TARGET_EXPR - directly. Otherwise, we need to create the initializer - separately from the object being initialized. */ - if (TREE_CODE (init) == TARGET_EXPR) - { - if (TYPE_MAIN_VARIANT (init_type) == TYPE_MAIN_VARIANT (type)) - { - if (TREE_CODE (exp) == VAR_DECL - || TREE_CODE (exp) == RESULT_DECL) - /* Unify the initialization targets. */ - DECL_RTL (TREE_OPERAND (init, 0)) = DECL_RTL (exp); - else - DECL_RTL (TREE_OPERAND (init, 0)) = expand_expr (exp, NULL_RTX, VOIDmode, EXPAND_NORMAL); - - expand_expr_stmt (init); - return; - } - } - - if (init_type == type && TREE_CODE (init) == CALL_EXPR) - { - /* A CALL_EXPR is a legitimate form of initialization, so - we should not print this warning message. */ - - expand_assignment (exp, init, 0, 0); - if (exp == DECL_RESULT (current_function_decl)) - { - /* Failing this assertion means that the return value - from receives multiple initializations. */ - my_friendly_assert (DECL_INITIAL (exp) == NULL_TREE - || DECL_INITIAL (exp) == error_mark_node, - 212); - DECL_INITIAL (exp) = init; - } - return; - } - else if (init_type == type - && TREE_CODE (init) == COND_EXPR) - { - /* Push value to be initialized into the cond, where possible. - Avoid spurious warning messages when initializing the - result of this function. */ - TREE_OPERAND (init, 1) - = build_modify_expr (exp, INIT_EXPR, TREE_OPERAND (init, 1)); - if (exp == DECL_RESULT (current_function_decl)) - DECL_INITIAL (exp) = NULL_TREE; - TREE_OPERAND (init, 2) - = build_modify_expr (exp, INIT_EXPR, TREE_OPERAND (init, 2)); - if (exp == DECL_RESULT (current_function_decl)) - DECL_INITIAL (exp) = init; - TREE_SIDE_EFFECTS (init) = 1; - expand_expr (init, const0_rtx, VOIDmode, EXPAND_NORMAL); - free_temp_slots (); - return; - } - } - - /* We did not know what we were initializing before. Now we do. */ - if (TREE_CODE (init) == TARGET_EXPR) - { - tree tmp = TREE_OPERAND (TREE_OPERAND (init, 1), 1); - - if (tmp && TREE_CODE (TREE_VALUE (tmp)) == NOP_EXPR - && TREE_OPERAND (TREE_VALUE (tmp), 0) == integer_zero_node) - { - /* In order for this to work for RESULT_DECLs, if their - type has a constructor, then they must be BLKmode - so that they will be meaningfully addressable. */ - tree arg = build_unary_op (ADDR_EXPR, exp, 0); - init = TREE_OPERAND (init, 1); - init = build (CALL_EXPR, build_pointer_type (TREE_TYPE (init)), - TREE_OPERAND (init, 0), TREE_OPERAND (init, 1), NULL_TREE); - TREE_SIDE_EFFECTS (init) = 1; - TREE_VALUE (TREE_OPERAND (init, 1)) - = convert_pointer_to (TREE_TYPE (TREE_TYPE (TREE_VALUE (tmp))), arg); - - if (alias_this) - { - expand_assignment (current_function_decl, init, 0, 0); - return; - } - if (exp == DECL_RESULT (current_function_decl)) - { - if (DECL_INITIAL (DECL_RESULT (current_function_decl))) - fatal ("return value from function receives multiple initializations"); - DECL_INITIAL (exp) = init; - } - expand_expr_stmt (init); - return; - } - } - - /* Handle this case: when calling a constructor: xyzzy foo(bar); - which really means: xyzzy foo = bar; Ugh! - - More useful for this case: xyzzy *foo = new xyzzy (bar); */ - - if (! TYPE_NEEDS_CONSTRUCTING (type) && ! IS_AGGR_TYPE (type)) - { - if (init_list && TREE_CHAIN (init_list)) - { - warning ("initializer list being treated as compound expression"); - init = cp_convert (type, build_compound_expr (init_list)); - if (init == error_mark_node) - return; - } - - expand_assignment (exp, init, 0, 0); - - return; - } - - /* If this is copy-initialization, see whether we can go through a - type conversion operator. */ - if (TREE_CODE (init) != TREE_LIST && (flags & LOOKUP_ONLYCONVERTING)) - { - tree ttype = TREE_CODE (init_type) == REFERENCE_TYPE - ? TREE_TYPE (init_type) : init_type; - - if (ttype != type && IS_AGGR_TYPE (ttype)) - { - tree rval = build_type_conversion (CONVERT_EXPR, type, init, 1); - - if (rval) - { - /* See if there is a constructor for``type'' that takes a - ``ttype''-typed object. */ - tree parms = build_expr_list (NULL_TREE, init); - tree as_cons = NULL_TREE; - if (TYPE_HAS_CONSTRUCTOR (type)) - as_cons = build_method_call (exp, ctor_identifier, - parms, binfo, - LOOKUP_SPECULATIVELY|LOOKUP_NO_CONVERSION); - if (as_cons != NULL_TREE && as_cons != error_mark_node) - /* ANSI C++ June 5 1992 WP 12.3.2.6.1 */ - cp_error ("ambiguity between conversion to `%T' and constructor", - type); - else - if (rval != error_mark_node) - expand_aggr_init_1 (binfo, true_exp, exp, rval, alias_this, flags); - return; - } - } - } - } - /* We know that expand_default_init can handle everything we want at this point. */ expand_default_init (binfo, true_exp, exp, init, alias_this, flags); diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c index 7ee6ba1b011..7dfcc1f4c21 100644 --- a/gcc/cp/lex.c +++ b/gcc/cp/lex.c @@ -615,8 +615,6 @@ init_lex () IDENTIFIER_OPNAME_P (ansi_opname[(int) MAX_EXPR]) = 1; ansi_opname[(int) COND_EXPR] = get_identifier ("__cn"); IDENTIFIER_OPNAME_P (ansi_opname[(int) COND_EXPR]) = 1; - ansi_opname[(int) METHOD_CALL_EXPR] = get_identifier ("__wr"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) METHOD_CALL_EXPR]) = 1; init_method (); init_error (); @@ -747,7 +745,6 @@ init_lex () opname_tab[(int) COMPONENT_REF] = "->"; opname_tab[(int) MEMBER_REF] = "->*"; - opname_tab[(int) METHOD_CALL_EXPR] = "->()"; opname_tab[(int) INDIRECT_REF] = "*"; opname_tab[(int) ARRAY_REF] = "[]"; opname_tab[(int) MODIFY_EXPR] = "="; diff --git a/gcc/cp/method.c b/gcc/cp/method.c index 3a800dafc71..e1ae25072ac 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -34,7 +34,6 @@ Boston, MA 02111-1307, USA. */ #include #include "tree.h" #include "cp-tree.h" -#include "class.h" #include "obstack.h" #include #include "rtl.h" @@ -175,92 +174,6 @@ do_inline_function_hair (type, friend_list) } } -/* Report an argument type mismatch between the best declared function - we could find and the current argument list that we have. */ - -void -report_type_mismatch (cp, parmtypes, name_kind) - struct candidate *cp; - tree parmtypes; - char *name_kind; -{ - int i = cp->u.bad_arg; - tree ttf, tta; - char *tmp_firstobj; - - switch (i) - { - case -4: - my_friendly_assert (TREE_CODE (cp->function) == TEMPLATE_DECL, 240); - cp_error ("type unification failed for function template `%#D'", - cp->function); - return; - - case -2: - cp_error ("too few arguments for %s `%#D'", name_kind, cp->function); - return; - case -1: - cp_error ("too many arguments for %s `%#D'", name_kind, cp->function); - return; - case 0: - if (TREE_CODE (TREE_TYPE (cp->function)) != METHOD_TYPE) - break; - case -3: - /* Happens when the implicit object parameter is rejected. */ - my_friendly_assert (! TYPE_READONLY (TREE_TYPE (TREE_VALUE (parmtypes))), - 241); - if (TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (TREE_VALUE (parmtypes)))) - && ! TYPE_VOLATILE (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (cp->function)))))) - cp_error ("call to non-volatile %s `%#D' with volatile object", - name_kind, cp->function); - else - cp_error ("call to non-const %s `%#D' with const object", - name_kind, cp->function); - return; - } - - ttf = TYPE_ARG_TYPES (TREE_TYPE (cp->function)); - tta = parmtypes; - - while (i-- > 0) - { - ttf = TREE_CHAIN (ttf); - tta = TREE_CHAIN (tta); - } - - OB_INIT (); - OB_PUTS ("bad argument "); - sprintf (digit_buffer, "%d", cp->u.bad_arg - - (TREE_CODE (TREE_TYPE (cp->function)) == METHOD_TYPE) - + 1); - OB_PUTCP (digit_buffer); - - OB_PUTS (" for function `"); - OB_PUTCP (decl_as_string (cp->function, 1)); - OB_PUTS ("' (type was "); - - /* Reset `i' so that type printing routines do the right thing. */ - if (tta) - { - enum tree_code code = TREE_CODE (TREE_TYPE (TREE_VALUE (tta))); - if (code == ERROR_MARK) - OB_PUTS ("(failed type instantiation)"); - else - { - i = (code == FUNCTION_TYPE || code == METHOD_TYPE); - OB_PUTCP (type_as_string (TREE_TYPE (TREE_VALUE (tta)), 1)); - } - } - else OB_PUTS ("void"); - OB_PUTC (')'); - OB_FINISH (); - - tmp_firstobj = (char *)alloca (obstack_object_size (&scratch_obstack)); - bcopy (obstack_base (&scratch_obstack), tmp_firstobj, - obstack_object_size (&scratch_obstack)); - error (tmp_firstobj); -} - /* Here is where overload code starts. */ /* type tables for K and B type compression */ @@ -1733,311 +1646,7 @@ build_opfncall (code, flags, xarg1, xarg2, arg3) int flags; tree xarg1, xarg2, arg3; { - tree rval = 0; - tree arg1, arg2; - tree type1, type2, fnname; - tree fields1 = 0, parms = 0; - tree global_fn; - int try_second; - int binary_is_unary; - - if (flag_ansi_overloading) - return build_new_op (code, flags, xarg1, xarg2, arg3); - - if (xarg1 == error_mark_node) - return error_mark_node; - - if (code == COND_EXPR) - { - if (xarg2 == error_mark_node - || arg3 == error_mark_node) - return error_mark_node; - } - if (code == COMPONENT_REF) - if (TREE_CODE (TREE_TYPE (xarg1)) == POINTER_TYPE) - return rval; - - /* First, see if we can work with the first argument */ - type1 = TREE_TYPE (xarg1); - - /* Some tree codes have length > 1, but we really only want to - overload them if their first argument has a user defined type. */ - switch (code) - { - case PREINCREMENT_EXPR: - case PREDECREMENT_EXPR: - case POSTINCREMENT_EXPR: - case POSTDECREMENT_EXPR: - case COMPONENT_REF: - binary_is_unary = 1; - try_second = 0; - break; - - /* ARRAY_REFs and CALL_EXPRs must overload successfully. - If they do not, return error_mark_node instead of NULL_TREE. */ - case ARRAY_REF: - if (xarg2 == error_mark_node) - return error_mark_node; - case CALL_EXPR: - rval = error_mark_node; - binary_is_unary = 0; - try_second = 0; - break; - - case VEC_NEW_EXPR: - case NEW_EXPR: - { - tree args = expr_tree_cons (NULL_TREE, xarg2, arg3); - fnname = ansi_opname[(int) code]; - if (flags & LOOKUP_GLOBAL) - return build_overload_call (fnname, args, flags & LOOKUP_COMPLAIN); - - rval = build_method_call - (build_indirect_ref (build1 (NOP_EXPR, xarg1, error_mark_node), - "new"), - fnname, args, NULL_TREE, flags); - if (rval == error_mark_node) - /* User might declare fancy operator new, but invoke it - like standard one. */ - return rval; - - TREE_TYPE (rval) = xarg1; - return rval; - } - break; - - case VEC_DELETE_EXPR: - case DELETE_EXPR: - { - fnname = ansi_opname[(int) code]; - if (flags & LOOKUP_GLOBAL) - return build_overload_call (fnname, - build_expr_list (NULL_TREE, xarg1), - flags & LOOKUP_COMPLAIN); - arg1 = TREE_TYPE (xarg1); - - /* This handles the case where we're trying to delete - X (*a)[10]; - a=new X[5][10]; - delete[] a; */ - - if (TREE_CODE (TREE_TYPE (arg1)) == ARRAY_TYPE) - { - /* Strip off the pointer and the array. */ - arg1 = TREE_TYPE (TREE_TYPE (arg1)); - - while (TREE_CODE (arg1) == ARRAY_TYPE) - arg1 = (TREE_TYPE (arg1)); - - arg1 = build_pointer_type (arg1); - } - - rval = build_method_call - (build_indirect_ref (build1 (NOP_EXPR, arg1, - error_mark_node), - NULL_PTR), - fnname, expr_tree_cons (NULL_TREE, xarg1, - build_expr_list (NULL_TREE, xarg2)), - NULL_TREE, flags); -#if 0 - /* This can happen when operator delete is protected. */ - my_friendly_assert (rval != error_mark_node, 250); - TREE_TYPE (rval) = void_type_node; -#endif - return rval; - } - break; - - default: - binary_is_unary = 0; - try_second = tree_code_length [(int) code] == 2; - if (try_second && xarg2 == error_mark_node) - return error_mark_node; - break; - } - - if (try_second && xarg2 == error_mark_node) - return error_mark_node; - - /* What ever it was, we do not know how to deal with it. */ - if (type1 == NULL_TREE) - return rval; - - if (TREE_CODE (type1) == OFFSET_TYPE) - type1 = TREE_TYPE (type1); - - if (TREE_CODE (type1) == REFERENCE_TYPE) - { - arg1 = convert_from_reference (xarg1); - type1 = TREE_TYPE (arg1); - } - else - { - arg1 = xarg1; - } - - if (!IS_AGGR_TYPE (type1) || TYPE_PTRMEMFUNC_P (type1)) - { - /* Try to fail. First, fail if unary */ - if (! try_second) - return rval; - /* Second, see if second argument is non-aggregate. */ - type2 = TREE_TYPE (xarg2); - if (TREE_CODE (type2) == OFFSET_TYPE) - type2 = TREE_TYPE (type2); - if (TREE_CODE (type2) == REFERENCE_TYPE) - { - arg2 = convert_from_reference (xarg2); - type2 = TREE_TYPE (arg2); - } - else - { - arg2 = xarg2; - } - - if (!IS_AGGR_TYPE (type2)) - return rval; - try_second = 0; - } - - if (try_second) - { - /* First arg may succeed; see whether second should. */ - type2 = TREE_TYPE (xarg2); - if (TREE_CODE (type2) == OFFSET_TYPE) - type2 = TREE_TYPE (type2); - if (TREE_CODE (type2) == REFERENCE_TYPE) - { - arg2 = convert_from_reference (xarg2); - type2 = TREE_TYPE (arg2); - } - else - { - arg2 = xarg2; - } - - if (! IS_AGGR_TYPE (type2)) - try_second = 0; - } - - if (type1 == unknown_type_node - || (try_second && TREE_TYPE (xarg2) == unknown_type_node)) - { - /* This will not be implemented in the foreseeable future. */ - return rval; - } - - if (code == MODIFY_EXPR) - fnname = ansi_assopname[(int) TREE_CODE (arg3)]; - else - fnname = ansi_opname[(int) code]; - - global_fn = lookup_name_nonclass (fnname); - - /* This is the last point where we will accept failure. This - may be too eager if we wish an overloaded operator not to match, - but would rather a normal operator be called on a type-converted - argument. */ - - if (IS_AGGR_TYPE (type1)) - { - fields1 = lookup_fnfields (TYPE_BINFO (type1), fnname, 0); - /* ARM $13.4.7, prefix/postfix ++/--. */ - if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR) - { - xarg2 = integer_zero_node; - binary_is_unary = 0; - - if (fields1) - { - tree t, t2; - int have_postfix = 0; - - /* Look for an `operator++ (int)'. If they didn't have - one, then we fall back to the old way of doing things. */ - for (t = TREE_VALUE (fields1); t ; t = DECL_CHAIN (t)) - { - t2 = TYPE_ARG_TYPES (TREE_TYPE (t)); - if (TREE_CHAIN (t2) != NULL_TREE - && TREE_VALUE (TREE_CHAIN (t2)) == integer_type_node) - { - have_postfix = 1; - break; - } - } - - if (! have_postfix) - { - char *op = POSTINCREMENT_EXPR ? "++" : "--"; - - /* There's probably a LOT of code in the world that - relies upon this old behavior. */ - pedwarn ("no `operator%s (int)' declared for postfix `%s', using prefix operator instead", - op, op); - xarg2 = NULL_TREE; - binary_is_unary = 1; - } - } - } - } - - if (fields1 == NULL_TREE && global_fn == NULL_TREE) - return rval; - - /* If RVAL winds up being `error_mark_node', we will return - that... There is no way that normal semantics of these - operators will succeed. */ - - /* This argument may be an uncommitted OFFSET_REF. This is - the case for example when dealing with static class members - which are referenced from their class name rather than - from a class instance. */ - if (TREE_CODE (xarg1) == OFFSET_REF - && TREE_CODE (TREE_OPERAND (xarg1, 1)) == VAR_DECL) - xarg1 = TREE_OPERAND (xarg1, 1); - if (try_second && xarg2 && TREE_CODE (xarg2) == OFFSET_REF - && TREE_CODE (TREE_OPERAND (xarg2, 1)) == VAR_DECL) - xarg2 = TREE_OPERAND (xarg2, 1); - - if (global_fn) - flags |= LOOKUP_GLOBAL; - - if (code == CALL_EXPR) - { - /* This can only be a member function. */ - return build_method_call (xarg1, fnname, xarg2, - NULL_TREE, LOOKUP_NORMAL); - } - else if (tree_code_length[(int) code] == 1 || binary_is_unary) - { - parms = NULL_TREE; - rval = build_method_call (xarg1, fnname, NULL_TREE, NULL_TREE, flags); - } - else if (code == COND_EXPR) - { - parms = expr_tree_cons (NULL_TREE, xarg2, build_expr_list (NULL_TREE, arg3)); - rval = build_method_call (xarg1, fnname, parms, NULL_TREE, flags); - } - else if (code == METHOD_CALL_EXPR) - { - /* must be a member function. */ - parms = expr_tree_cons (NULL_TREE, xarg2, arg3); - return build_method_call (xarg1, fnname, parms, NULL_TREE, - LOOKUP_NORMAL); - } - else if (fields1) - { - parms = build_expr_list (NULL_TREE, xarg2); - rval = build_method_call (xarg1, fnname, parms, NULL_TREE, flags); - } - else - { - parms = expr_tree_cons (NULL_TREE, xarg1, - build_expr_list (NULL_TREE, xarg2)); - rval = build_overload_call (fnname, parms, flags); - } - - return rval; + return build_new_op (code, flags, xarg1, xarg2, arg3); } /* This function takes an identifier, ID, and attempts to figure out what diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 36f8aafa554..dcc137396dc 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -3890,38 +3890,6 @@ tsubst (t, args, in_decl) if (IDENTIFIER_OPNAME_P (DECL_NAME (r))) grok_op_properties (r, DECL_VIRTUAL_P (r), DECL_FRIEND_P (r)); - /* Look for matching decls for the moment. */ - if (! member && ! flag_ansi_overloading) - { - tree decls = lookup_name_nonclass (DECL_NAME (t)); - tree d = NULL_TREE; - - if (decls == NULL_TREE) - /* no match */; - else if (is_overloaded_fn (decls)) - for (decls = get_first_fn (decls); decls; - decls = DECL_CHAIN (decls)) - { - if (TREE_CODE (decls) == FUNCTION_DECL - && TREE_TYPE (decls) == type) - { - d = decls; - break; - } - } - - if (d) - { - int dcl_only = ! DECL_INITIAL (d); - if (dcl_only) - DECL_INITIAL (r) = error_mark_node; - duplicate_decls (r, d); - r = d; - if (dcl_only) - DECL_INITIAL (r) = 0; - } - } - if (DECL_TEMPLATE_INFO (t) != NULL_TREE) { DECL_TEMPLATE_INFO (r) = perm_tree_cons (tmpl, argvec, NULL_TREE); @@ -5539,7 +5507,7 @@ unify (tparms, targs, ntparms, parm, arg, strict) if (CLASSTYPE_TEMPLATE_INFO (parm) && uses_template_parms (parm)) { tree t = NULL_TREE; - if (flag_ansi_overloading && ! strict) + if (! strict) t = get_template_base (CLASSTYPE_TI_TEMPLATE (parm), arg); else if (CLASSTYPE_TEMPLATE_INFO (arg) diff --git a/gcc/cp/ptree.c b/gcc/cp/ptree.c index 13f171aa0a1..6ad4d39de93 100644 --- a/gcc/cp/ptree.c +++ b/gcc/cp/ptree.c @@ -118,8 +118,6 @@ print_lang_type (file, node, indent) fputs (" has=", file); if (TYPE_HAS_ASSIGN_REF (node)) fputs (" this=(X&)", file); - if (TYPE_OVERLOADS_METHOD_CALL_EXPR (node)) - fputs (" op->()", file); if (TYPE_GETS_INIT_AGGR (node)) fputs (" gets X(X, ...)", file); if (TYPE_OVERLOADS_CALL_EXPR (node)) diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index ce695e0b44d..7820f6ea3cf 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -2470,24 +2470,10 @@ build_x_function_call (function, params, decl) } else { - tree val = TREE_VALUE (function); - - if (flag_ansi_overloading) - { - /* Put back explicit template arguments, if any. */ - if (template_id) - function = template_id; - return build_new_function_call (function, params); - } - - if (TREE_CODE (val) == TEMPLATE_DECL) - return build_overload_call_real - (function, params, LOOKUP_COMPLAIN, (struct candidate *)0, 0); - else if (DECL_CHAIN (val) != NULL_TREE) - return build_overload_call - (function, params, LOOKUP_COMPLAIN); - else - my_friendly_abort (360); + /* Put back explicit template arguments, if any. */ + if (template_id) + function = template_id; + return build_new_function_call (function, params); } } @@ -3062,17 +3048,7 @@ build_x_binary_op (code, arg1, arg2) if (processing_template_decl) return build_min_nt (code, arg1, arg2); - if (flag_ansi_overloading) - return build_new_op (code, LOOKUP_NORMAL, arg1, arg2, NULL_TREE); - - rval = build_opfncall (code, LOOKUP_SPECULATIVELY, - arg1, arg2, NULL_TREE); - if (rval) - return build_opfncall (code, LOOKUP_NORMAL, arg1, arg2, NULL_TREE); - if (code == MEMBER_REF) - return build_m_component_ref (build_indirect_ref (arg1, NULL_PTR), - arg2); - return build_binary_op (code, arg1, arg2, 1); + return build_new_op (code, LOOKUP_NORMAL, arg1, arg2, NULL_TREE); } tree @@ -4131,21 +4107,10 @@ build_x_unary_op (code, xarg) { tree rval; - if (flag_ansi_overloading) - { - rval = build_new_op (code, LOOKUP_NORMAL, xarg, - NULL_TREE, NULL_TREE); - if (rval || code != ADDR_EXPR) - return rval; - } - else - { - rval = build_opfncall (code, LOOKUP_SPECULATIVELY, xarg, - NULL_TREE, NULL_TREE); - if (rval) - return build_opfncall (code, LOOKUP_NORMAL, xarg, - NULL_TREE, NULL_TREE); - } + rval = build_new_op (code, LOOKUP_NORMAL, xarg, + NULL_TREE, NULL_TREE); + if (rval || code != ADDR_EXPR) + return rval; } if (code == ADDR_EXPR) @@ -4907,16 +4872,7 @@ build_x_conditional_expr (ifexp, op1, op2) if (processing_template_decl) return build_min_nt (COND_EXPR, ifexp, op1, op2); - if (flag_ansi_overloading) - return build_new_op (COND_EXPR, LOOKUP_NORMAL, ifexp, op1, op2); - - /* See comments in `build_x_binary_op'. */ - if (op1 != 0) - rval = build_opfncall (COND_EXPR, LOOKUP_SPECULATIVELY, ifexp, op1, op2); - if (rval) - return build_opfncall (COND_EXPR, LOOKUP_NORMAL, ifexp, op1, op2); - - return build_conditional_expr (ifexp, op1, op2); + return build_new_op (COND_EXPR, LOOKUP_NORMAL, ifexp, op1, op2); } tree @@ -7092,82 +7048,7 @@ convert_for_initialization (exp, type, rhs, flags, errtype, fndecl, parmnum) if (IS_AGGR_TYPE (type) && (TYPE_NEEDS_CONSTRUCTING (type) || TREE_HAS_CONSTRUCTOR (rhs))) - { - if (flag_ansi_overloading) - return ocp_convert (type, rhs, CONV_IMPLICIT|CONV_FORCE_TEMP, flags); - - if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (rhstype)) - { - /* This is sufficient to perform initialization. No need, - apparently, to go through X(X&) to do first-cut - initialization. Return through a TARGET_EXPR so that we get - cleanups if it is used. */ - if (TREE_CODE (rhs) == CALL_EXPR) - { - rhs = build_cplus_new (type, rhs); - return rhs; - } - /* Handle the case of default parameter initialization and - initialization of static variables. */ - else if (TREE_CODE (rhs) == TARGET_EXPR) - return rhs; - else if (TREE_CODE (rhs) == INDIRECT_REF && TREE_HAS_CONSTRUCTOR (rhs)) - { - my_friendly_assert (TREE_CODE (TREE_OPERAND (rhs, 0)) == CALL_EXPR, 318); - if (exp) - { - my_friendly_assert (TREE_VALUE (TREE_OPERAND (TREE_OPERAND (rhs, 0), 1)) == NULL_TREE, 316); - TREE_VALUE (TREE_OPERAND (TREE_OPERAND (rhs, 0), 1)) - = build_unary_op (ADDR_EXPR, exp, 0); - } - else - rhs = build_cplus_new (type, TREE_OPERAND (rhs, 0)); - return rhs; - } - else if (TYPE_HAS_TRIVIAL_INIT_REF (type)) - return rhs; - } - if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (rhstype) - || (IS_AGGR_TYPE (rhstype) && UNIQUELY_DERIVED_FROM_P (type, rhstype))) - { - if (TYPE_HAS_INIT_REF (type)) - { - tree init = build_method_call (exp, ctor_identifier, - build_expr_list (NULL_TREE, rhs), - TYPE_BINFO (type), LOOKUP_NORMAL); - - if (init == error_mark_node) - return error_mark_node; - - if (exp == 0) - { - exp = build_cplus_new (type, init); - return exp; - } - - return build (COMPOUND_EXPR, type, init, exp); - } - - /* ??? The following warnings are turned off because - this is another place where the default X(X&) constructor - is implemented. */ - if (TYPE_HAS_ASSIGNMENT (type)) - cp_warning ("bitwise copy: `%T' defines operator=", type); - - if (TREE_CODE (TREE_TYPE (rhs)) == REFERENCE_TYPE) - rhs = convert_from_reference (rhs); - if (type != rhstype) - { - tree nrhs = build1 (NOP_EXPR, type, rhs); - TREE_CONSTANT (nrhs) = TREE_CONSTANT (rhs); - rhs = nrhs; - } - return rhs; - } - - return ocp_convert (type, rhs, CONV_OLD_CONVERT, - flags | LOOKUP_NO_CONVERSION); - } + return ocp_convert (type, rhs, CONV_IMPLICIT|CONV_FORCE_TEMP, flags); if (type == TREE_TYPE (rhs)) {