aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@yorick.cygnus.com>1998-03-03 03:24:44 +0000
committerJason Merrill <jason@gcc.gnu.org>1998-03-02 22:24:44 -0500
commit277294d73bf540ec0f5bc320cebab7cfb43bacf3 (patch)
treefeddd74d6019aeb873b50f2e6071211850960347
parent494321710472a23a9a75d046f9a0fb413e33d2d2 (diff)
downloadgcc-277294d73bf540ec0f5bc320cebab7cfb43bacf3.zip
gcc-277294d73bf540ec0f5bc320cebab7cfb43bacf3.tar.gz
gcc-277294d73bf540ec0f5bc320cebab7cfb43bacf3.tar.bz2
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
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/Makefile.in6
-rw-r--r--gcc/cp/call.c2362
-rw-r--r--gcc/cp/class.c2
-rw-r--r--gcc/cp/class.h117
-rw-r--r--gcc/cp/cp-tree.h16
-rw-r--r--gcc/cp/cvt.c412
-rw-r--r--gcc/cp/decl.c4
-rw-r--r--gcc/cp/decl2.c13
-rw-r--r--gcc/cp/init.c225
-rw-r--r--gcc/cp/lex.c3
-rw-r--r--gcc/cp/method.c393
-rw-r--r--gcc/cp/pt.c34
-rw-r--r--gcc/cp/ptree.c2
-rw-r--r--gcc/cp/typeck.c141
15 files changed, 61 insertions, 3675 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 73b3b3a..54b45e1 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,11 @@
Tue Mar 3 01:38:17 1998 Jason Merrill <jason@yorick.cygnus.com>
+ * 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 9007bf2..a6f0f3c 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 276b32e..8fe87aa 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -27,7 +27,6 @@ Boston, MA 02111-1307, USA. */
#include "tree.h"
#include <stdio.h>
#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 da2f419..f13180f 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 12e45f7..0000000
--- 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 5f346b5..95bc071 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 d308805..05cd667 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 = 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;
- }
+ ctor = e;
- 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;
- }
+ 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);
}
/* 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 e5ab625..334db91 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 fa39b9e..2468342 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 ee68dfc..a420092 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 7ee6ba1..7dfcc1f 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 3a800da..e1ae250 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -34,7 +34,6 @@ Boston, MA 02111-1307, USA. */
#include <stdio.h>
#include "tree.h"
#include "cp-tree.h"
-#include "class.h"
#include "obstack.h"
#include <ctype.h>
#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 36f8aaf..dcc1373 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 13f171a..6ad4d39 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 ce695e0..7820f6e 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))
{