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
This commit is contained in:
Jason Merrill 1998-03-03 03:24:44 +00:00 committed by Jason Merrill
parent 4943217104
commit 277294d73b
15 changed files with 61 additions and 3675 deletions

View file

@ -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

View file

@ -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)

File diff suppressed because it is too large Load diff

View file

@ -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;

View file

@ -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;

View file

@ -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));

View file

@ -30,7 +30,6 @@ Boston, MA 02111-1307, USA. */
#include "tree.h"
#include "flags.h"
#include "cp-tree.h"
#include "class.h"
#include "convert.h"
#ifdef HAVE_STDLIB_H
@ -482,11 +481,8 @@ convert_to_reference (reftype, expr, convtype, flags, decl)
{
/* Look for a user-defined conversion to lvalue that we can use. */
if (flag_ansi_overloading)
rval_as_conversion
= build_type_conversion (CONVERT_EXPR, reftype, expr, 1);
else
rval_as_conversion = build_type_conversion (CONVERT_EXPR, type, expr, 1);
rval_as_conversion
= build_type_conversion (CONVERT_EXPR, reftype, expr, 1);
if (rval_as_conversion && rval_as_conversion != error_mark_node
&& real_lvalue_p (rval_as_conversion))
@ -556,7 +552,7 @@ convert_to_reference (reftype, expr, convtype, flags, decl)
if (rval != error_mark_node)
rval = build1 (NOP_EXPR, reftype, rval);
}
else if (flag_ansi_overloading)
else
{
rval = convert_for_initialization (NULL_TREE, type, expr, flags,
"converting", 0, 0);
@ -568,89 +564,6 @@ convert_to_reference (reftype, expr, convtype, flags, decl)
cp_pedwarn ("initializing non-const `%T' with `%T' will use a temporary",
reftype, intype);
}
else
{
tree rval_as_ctor = NULL_TREE;
if (rval_as_conversion)
{
if (rval_as_conversion == error_mark_node)
{
cp_error ("conversion from `%T' to `%T' is ambiguous",
intype, reftype);
return error_mark_node;
}
rval_as_conversion = build_up_reference (reftype, rval_as_conversion,
flags, 1);
}
/* Definitely need to go through a constructor here. */
if (TYPE_HAS_CONSTRUCTOR (type)
&& ! CLASSTYPE_ABSTRACT_VIRTUALS (type)
&& (rval = build_method_call
(NULL_TREE, ctor_identifier,
build_expr_list (NULL_TREE, expr), TYPE_BINFO (type),
LOOKUP_NO_CONVERSION|LOOKUP_SPECULATIVELY
| LOOKUP_ONLYCONVERTING)))
{
tree init;
if (toplevel_bindings_p ())
{
tree t = get_temp_name (type, toplevel_bindings_p ());
init = build_method_call (t, ctor_identifier,
build_expr_list (NULL_TREE, expr),
TYPE_BINFO (type),
LOOKUP_NORMAL|LOOKUP_NO_CONVERSION
| LOOKUP_ONLYCONVERTING);
if (init == error_mark_node)
return error_mark_node;
make_decl_rtl (t, NULL_PTR, 1);
static_aggregates = perm_tree_cons (expr, t, static_aggregates);
rval = build_unary_op (ADDR_EXPR, t, 0);
}
else
{
init = build_method_call (NULL_TREE, ctor_identifier,
build_expr_list (NULL_TREE, expr),
TYPE_BINFO (type),
LOOKUP_NORMAL|LOOKUP_NO_CONVERSION
|LOOKUP_ONLYCONVERTING);
if (init == error_mark_node)
return error_mark_node;
rval = build_cplus_new (type, init);
rval = build_up_reference (reftype, rval, flags, 1);
}
rval_as_ctor = rval;
}
if (rval_as_ctor && rval_as_conversion)
{
cp_error ("ambiguous conversion from `%T' to `%T'; both user-defined conversion and constructor apply",
intype, reftype);
return error_mark_node;
}
else if (rval_as_ctor)
rval = rval_as_ctor;
else if (rval_as_conversion)
rval = rval_as_conversion;
else if (! IS_AGGR_TYPE (type) && ! IS_AGGR_TYPE (intype))
{
rval = cp_convert (type, expr);
if (rval == error_mark_node)
return error_mark_node;
rval = build_up_reference (reftype, rval, flags, 1);
}
if (rval && ! TYPE_READONLY (TREE_TYPE (reftype)))
cp_pedwarn ("initializing non-const `%T' with `%T' will use a temporary",
reftype, intype);
}
if (rval)
{
@ -685,190 +598,6 @@ convert_from_reference (val)
return val;
}
/* See if there is a constructor of type TYPE which will convert
EXPR. The reference manual seems to suggest (8.5.6) that we need
not worry about finding constructors for base classes, then converting
to the derived class.
MSGP is a pointer to a message that would be an appropriate error
string. If MSGP is NULL, then we are not interested in reporting
errors. */
tree
convert_to_aggr (type, expr, msgp, protect)
tree type, expr;
char **msgp;
int protect;
{
tree basetype = type;
tree name = TYPE_IDENTIFIER (basetype);
tree function, fndecl, fntype, parmtypes, parmlist, result;
#if 0
/* See code below that used this. */
tree method_name;
#endif
tree access;
int can_be_private, can_be_protected;
if (! TYPE_HAS_CONSTRUCTOR (basetype))
{
if (msgp)
*msgp = "type `%s' does not have a constructor";
return error_mark_node;
}
access = access_public_node;
can_be_private = 0;
can_be_protected = IDENTIFIER_CLASS_VALUE (name) || name == current_class_name;
parmlist = build_expr_list (NULL_TREE, expr);
parmtypes = scratch_tree_cons (NULL_TREE, TREE_TYPE (expr), void_list_node);
if (TYPE_USES_VIRTUAL_BASECLASSES (basetype))
{
parmtypes = expr_tree_cons (NULL_TREE, integer_type_node, parmtypes);
parmlist = scratch_tree_cons (NULL_TREE, integer_one_node, parmlist);
}
/* The type of the first argument will be filled in inside the loop. */
parmlist = expr_tree_cons (NULL_TREE, integer_zero_node, parmlist);
parmtypes = scratch_tree_cons (NULL_TREE, build_pointer_type (basetype), parmtypes);
/* No exact conversion was found. See if an approximate
one will do. */
fndecl = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 0);
{
int saw_private = 0;
int saw_protected = 0;
struct candidate *candidates
= (struct candidate *) alloca ((decl_list_length (fndecl)+1) * sizeof (struct candidate));
struct candidate *cp = candidates;
while (fndecl)
{
function = fndecl;
cp->h_len = 2;
cp->harshness = (struct harshness_code *)
alloca (3 * sizeof (struct harshness_code));
compute_conversion_costs (fndecl, parmlist, cp, 2);
if ((cp->h.code & EVIL_CODE) == 0)
{
cp->u.field = fndecl;
if (protect)
{
if (TREE_PRIVATE (fndecl))
access = access_private_node;
else if (TREE_PROTECTED (fndecl))
access = access_protected_node;
else
access = access_public_node;
}
else
access = access_public_node;
if (access == access_private_node
? (basetype == current_class_type
|| is_friend (basetype, cp->function)
|| purpose_member (basetype, DECL_ACCESS (fndecl)))
: access == access_protected_node
? (can_be_protected
|| purpose_member (basetype, DECL_ACCESS (fndecl)))
: 1)
{
if (cp->h.code <= TRIVIAL_CODE)
goto found_and_ok;
cp++;
}
else
{
if (access == access_private_node)
saw_private = 1;
else
saw_protected = 1;
}
}
fndecl = DECL_CHAIN (fndecl);
}
if (cp - candidates)
{
/* Rank from worst to best. Then cp will point to best one.
Private fields have their bits flipped. For unsigned
numbers, this should make them look very large.
If the best alternate has a (signed) negative value,
then all we ever saw were private members. */
if (cp - candidates > 1)
qsort (candidates, /* char *base */
cp - candidates, /* int nel */
sizeof (struct candidate), /* int width */
(int (*) PROTO((const void *, const void *))) rank_for_overload); /* int (*compar)() */
--cp;
if (cp->h.code & EVIL_CODE)
{
if (msgp)
*msgp = "ambiguous type conversion possible for `%s'";
return error_mark_node;
}
function = cp->function;
fndecl = cp->u.field;
goto found_and_ok;
}
else if (msgp)
{
if (saw_private)
{
if (saw_protected)
*msgp = "only private and protected conversions apply";
else
*msgp = "only private conversions apply";
}
else if (saw_protected)
*msgp = "only protected conversions apply";
else
*msgp = "no appropriate conversion to type `%s'";
}
return error_mark_node;
}
/* NOTREACHED */
found:
if (access == access_private_node)
if (! can_be_private)
{
if (msgp)
*msgp = TREE_PRIVATE (fndecl)
? "conversion to type `%s' is private"
: "conversion to type `%s' is from private base class";
return error_mark_node;
}
if (access == access_protected_node)
if (! can_be_protected)
{
if (msgp)
*msgp = TREE_PRIVATE (fndecl)
? "conversion to type `%s' is protected"
: "conversion to type `%s' is from protected base class";
return error_mark_node;
}
function = fndecl;
found_and_ok:
/* It will convert, but we don't do anything about it yet. */
if (msgp == 0)
return NULL_TREE;
fntype = TREE_TYPE (function);
parmlist = convert_arguments (NULL_TREE, TYPE_ARG_TYPES (fntype),
parmlist, NULL_TREE, LOOKUP_NORMAL);
result = build_call (function, TREE_TYPE (fntype), parmlist);
return result;
}
/* Call this when we know (for any reason) that expr is not, in fact,
zero. This routine is like convert_pointer_to, but it pays
attention to which specific instance of what type we want to
@ -1119,71 +848,20 @@ ocp_convert (type, expr, convtype, flags)
There may be some ambiguity between using a constructor
vs. using a type conversion operator when both apply. */
if (flag_ansi_overloading)
ctor = e;
if ((flags & LOOKUP_ONLYCONVERTING)
&& ! (IS_AGGR_TYPE (dtype) && DERIVED_FROM_P (type, dtype)))
{
ctor = e;
if ((flags & LOOKUP_ONLYCONVERTING)
&& ! (IS_AGGR_TYPE (dtype) && DERIVED_FROM_P (type, dtype)))
{
ctor = build_user_type_conversion (type, ctor, flags);
flags |= LOOKUP_NO_CONVERSION;
}
if (ctor)
ctor = build_method_call (NULL_TREE, ctor_identifier,
build_expr_list (NULL_TREE, ctor),
TYPE_BINFO (type), flags);
if (ctor)
return build_cplus_new (type, ctor);
}
else
{
if (IS_AGGR_TYPE (dtype) && ! DERIVED_FROM_P (type, dtype)
&& TYPE_HAS_CONVERSION (dtype))
conversion = build_type_conversion (CONVERT_EXPR, type, e, 1);
if (conversion == error_mark_node)
{
if (flags & LOOKUP_COMPLAIN)
error ("ambiguous pointer conversion");
return conversion;
}
if (TYPE_HAS_CONSTRUCTOR (complete_type (type)))
ctor = build_method_call (NULL_TREE, ctor_identifier,
build_expr_list (NULL_TREE, e),
TYPE_BINFO (type),
(flags & LOOKUP_NORMAL)
| LOOKUP_SPECULATIVELY
| (flags & LOOKUP_ONLYCONVERTING)
| (flags & LOOKUP_NO_CONVERSION)
| (conversion ? LOOKUP_NO_CONVERSION : 0));
if (ctor == error_mark_node)
{
if (flags & LOOKUP_COMPLAIN)
cp_error ("in conversion to type `%T'", type);
if (flags & LOOKUP_SPECULATIVELY)
return NULL_TREE;
return error_mark_node;
}
if (conversion && ctor)
{
if (flags & LOOKUP_COMPLAIN)
error ("both constructor and type conversion operator apply");
if (flags & LOOKUP_SPECULATIVELY)
return NULL_TREE;
return error_mark_node;
}
else if (conversion)
return conversion;
else if (ctor)
{
ctor = build_cplus_new (type, ctor);
return ctor;
}
ctor = build_user_type_conversion (type, ctor, flags);
flags |= LOOKUP_NO_CONVERSION;
}
if (ctor)
ctor = build_method_call (NULL_TREE, ctor_identifier,
build_expr_list (NULL_TREE, ctor),
TYPE_BINFO (type), flags);
if (ctor)
return build_cplus_new (type, ctor);
}
/* If TYPE or TREE_TYPE (E) is not on the permanent_obstack,
@ -1339,64 +1017,8 @@ build_type_conversion (code, xtype, expr, for_sure)
{
/* C++: check to see if we can convert this aggregate type
into the required type. */
tree basetype;
tree conv;
tree winner = NULL_TREE;
if (flag_ansi_overloading)
return build_user_type_conversion
(xtype, expr, for_sure ? LOOKUP_NORMAL : 0);
if (expr == error_mark_node)
return error_mark_node;
basetype = TREE_TYPE (expr);
if (TREE_CODE (basetype) == REFERENCE_TYPE)
basetype = TREE_TYPE (basetype);
basetype = TYPE_MAIN_VARIANT (basetype);
if (! TYPE_LANG_SPECIFIC (basetype) || ! TYPE_HAS_CONVERSION (basetype))
return NULL_TREE;
/* Do we have an exact match? */
{
tree typename = build_typename_overload (xtype);
if (lookup_fnfields (TYPE_BINFO (basetype), typename, 0))
return build_type_conversion_1 (xtype, basetype, expr, typename,
for_sure);
}
/* Nope; try looking for others. */
for (conv = lookup_conversions (basetype); conv; conv = TREE_CHAIN (conv))
{
tree cand = TREE_VALUE (conv);
if (winner && winner == cand)
continue;
if (can_convert (xtype, TREE_TYPE (TREE_TYPE (cand))))
{
if (winner)
{
if (for_sure)
{
cp_error ("ambiguous conversion from `%T' to `%T'", basetype,
xtype);
cp_error (" candidate conversions include `%D' and `%D'",
winner, cand);
}
return NULL_TREE;
}
else
winner = cand;
}
}
if (winner)
return build_type_conversion_1 (xtype, basetype, expr,
DECL_NAME (winner), for_sure);
return NULL_TREE;
return build_user_type_conversion
(xtype, expr, for_sure ? LOOKUP_NORMAL : 0);
}
/* Convert the given EXPR to one of a group of types suitable for use in an

View file

@ -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);

View file

@ -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;

View file

@ -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);

View file

@ -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] = "=";

View file

@ -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

View file

@ -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)

View file

@ -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))

View file

@ -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))
{