aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/call.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/call.c')
-rw-r--r--gcc/cp/call.c827
1 files changed, 538 insertions, 289 deletions
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 072fbe64515..b950eb05feb 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -1,6 +1,6 @@
/* Functions related to invoking methods and overloaded functions.
- Copyright (C) 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2003,
+ 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com) and
modified by Brendan Kehoe (brendan@cygnus.com).
@@ -62,37 +62,37 @@ static struct z_candidate * splice_viable PARAMS ((struct z_candidate *));
static int any_viable PARAMS ((struct z_candidate *));
static int any_strictly_viable PARAMS ((struct z_candidate *));
static struct z_candidate * add_template_candidate
- PARAMS ((struct z_candidate *, tree, tree, tree, tree, tree,
+ PARAMS ((struct z_candidate **, tree, tree, tree, tree, tree,
tree, tree, int, unification_kind_t));
static struct z_candidate * add_template_candidate_real
- PARAMS ((struct z_candidate *, tree, tree, tree, tree, tree,
+ PARAMS ((struct z_candidate **, tree, tree, tree, tree, tree,
tree, tree, int, tree, unification_kind_t));
static struct z_candidate * add_template_conv_candidate
- PARAMS ((struct z_candidate *, tree, tree, tree, tree, tree, tree));
-static struct z_candidate * add_builtin_candidates
- PARAMS ((struct z_candidate *, enum tree_code, enum tree_code,
+ PARAMS ((struct z_candidate **, tree, tree, tree, tree, tree, tree));
+static void add_builtin_candidates
+ PARAMS ((struct z_candidate **, enum tree_code, enum tree_code,
tree, tree *, int));
-static struct z_candidate * add_builtin_candidate
- PARAMS ((struct z_candidate *, enum tree_code, enum tree_code,
+static void add_builtin_candidate
+ PARAMS ((struct z_candidate **, enum tree_code, enum tree_code,
tree, tree, tree, tree *, tree *, int));
static int is_complete PARAMS ((tree));
-static struct z_candidate * build_builtin_candidate
- PARAMS ((struct z_candidate *, tree, tree, tree, tree *, tree *,
+static void build_builtin_candidate
+ PARAMS ((struct z_candidate **, tree, tree, tree, tree *, tree *,
int));
static struct z_candidate * add_conv_candidate
- PARAMS ((struct z_candidate *, tree, tree, tree, tree, tree));
+ PARAMS ((struct z_candidate **, tree, tree, tree, tree, tree));
static struct z_candidate * add_function_candidate
- (struct z_candidate *, tree, tree, tree, tree, tree, int);
+ (struct z_candidate **, tree, tree, tree, tree, tree, int);
static tree implicit_conversion PARAMS ((tree, tree, tree, int));
static tree standard_conversion PARAMS ((tree, tree, tree));
-static tree reference_binding PARAMS ((tree, tree, tree, int));
+static tree reference_binding (tree, tree, tree, int);
static tree non_reference PARAMS ((tree));
static tree build_conv PARAMS ((enum tree_code, tree, tree));
static int is_subseq PARAMS ((tree, tree));
static tree maybe_handle_ref_bind PARAMS ((tree*));
static void maybe_handle_implicit_object PARAMS ((tree*));
static struct z_candidate *add_candidate
- (struct z_candidate *, tree, tree, tree, tree, int);
+ (struct z_candidate **, tree, tree, tree, tree, int);
static tree source_type PARAMS ((tree));
static void add_warning PARAMS ((struct z_candidate *, struct z_candidate *));
static int reference_related_p PARAMS ((tree, tree));
@@ -102,6 +102,7 @@ static tree direct_reference_binding PARAMS ((tree, tree));
static int promoted_arithmetic_type_p PARAMS ((tree));
static tree conditional_conversion PARAMS ((tree, tree));
static tree call_builtin_trap PARAMS ((void));
+static tree merge_conversion_sequences (tree, tree);
tree
build_vfield_ref (datum, type)
@@ -519,7 +520,12 @@ build_method_call (instance, name, parms, basetype_path, flags)
("destructor name `~%T' does not match type `%T' of expression",
TREE_OPERAND (name, 0), object_type);
- if (! TYPE_HAS_DESTRUCTOR (complete_type (object_type)))
+ /* The destructor type must be complete. */
+ object_type = complete_type_or_else (object_type, NULL_TREE);
+ if (!object_type || object_type == error_mark_node)
+ return error_mark_node;
+
+ if (! TYPE_HAS_DESTRUCTOR (object_type))
return cp_convert (void_type_node, instance);
instance = default_conversion (instance);
instance_ptr = build_unary_op (ADDR_EXPR, instance, 0);
@@ -545,6 +551,8 @@ build_method_call (instance, name, parms, basetype_path, flags)
}
if (TREE_CODE (name) == OVERLOAD)
name = DECL_NAME (get_first_fn (name));
+ else if (TREE_CODE (name) == LOOKUP_EXPR)
+ name = TREE_OPERAND (name, 0);
else if (DECL_P (name))
name = DECL_NAME (name);
if (has_template_args)
@@ -695,7 +703,7 @@ build_conv (code, type, from)
break;
}
ICS_STD_RANK (t) = rank;
- ICS_USER_FLAG (t) = ICS_USER_FLAG (from);
+ ICS_USER_FLAG (t) = (code == USER_CONV || ICS_USER_FLAG (from));
ICS_BAD_FLAG (t) = ICS_BAD_FLAG (from);
return t;
}
@@ -987,9 +995,14 @@ convert_class_to_reference (t, s, expr)
tree conversions;
tree arglist;
tree conv;
+ tree reference_type;
struct z_candidate *candidates;
struct z_candidate *cand;
+ conversions = lookup_conversions (s);
+ if (!conversions)
+ return NULL_TREE;
+
/* [over.match.ref]
Assuming that "cv1 T" is the underlying type of the reference
@@ -1015,10 +1028,10 @@ convert_class_to_reference (t, s, expr)
arglist = build_int_2 (0, 0);
TREE_TYPE (arglist) = build_pointer_type (s);
arglist = build_tree_list (NULL_TREE, arglist);
-
- for (conversions = lookup_conversions (s);
- conversions;
- conversions = TREE_CHAIN (conversions))
+
+ reference_type = build_reference_type (t);
+
+ while (conversions)
{
tree fns = TREE_VALUE (conversions);
@@ -1026,44 +1039,58 @@ convert_class_to_reference (t, s, expr)
{
tree f = OVL_CURRENT (fns);
tree t2 = TREE_TYPE (TREE_TYPE (f));
- struct z_candidate *old_candidates = candidates;
+
+ cand = NULL;
/* If this is a template function, try to get an exact
match. */
if (TREE_CODE (f) == TEMPLATE_DECL)
{
- candidates
- = add_template_candidate (candidates,
- f, s,
- NULL_TREE,
- arglist,
- build_reference_type (t),
- TYPE_BINFO (s),
- TREE_PURPOSE (conversions),
- LOOKUP_NORMAL,
- DEDUCE_CONV);
+ cand = add_template_candidate (&candidates,
+ f, s,
+ NULL_TREE,
+ arglist,
+ reference_type,
+ TYPE_BINFO (s),
+ TREE_PURPOSE (conversions),
+ LOOKUP_NORMAL,
+ DEDUCE_CONV);
- if (candidates != old_candidates)
+ if (cand)
{
/* Now, see if the conversion function really returns
an lvalue of the appropriate type. From the
point of view of unification, simply returning an
rvalue of the right type is good enough. */
- f = candidates->fn;
+ f = cand->fn;
t2 = TREE_TYPE (TREE_TYPE (f));
if (TREE_CODE (t2) != REFERENCE_TYPE
|| !reference_compatible_p (t, TREE_TYPE (t2)))
- candidates = candidates->next;
+ {
+ candidates = candidates->next;
+ cand = NULL;
+ }
}
}
else if (TREE_CODE (t2) == REFERENCE_TYPE
&& reference_compatible_p (t, TREE_TYPE (t2)))
- candidates
- = add_function_candidate (candidates, f, s, arglist,
- TYPE_BINFO (s),
- TREE_PURPOSE (conversions),
- LOOKUP_NORMAL);
+ cand = add_function_candidate (&candidates, f, s, arglist,
+ TYPE_BINFO (s),
+ TREE_PURPOSE (conversions),
+ LOOKUP_NORMAL);
+
+ if (cand)
+ /* Build a standard conversion sequence indicating the
+ binding from the reference type returned by the
+ function to the desired REFERENCE_TYPE. */
+ cand->second_conv
+ = (direct_reference_binding
+ (reference_type,
+ build1 (IDENTITY_CONV,
+ TREE_TYPE (TREE_TYPE (TREE_TYPE (cand->fn))),
+ NULL_TREE)));
}
+ conversions = TREE_CHAIN (conversions);
}
/* If none of the conversion functions worked out, let our caller
@@ -1076,16 +1103,21 @@ convert_class_to_reference (t, s, expr)
if (!cand)
return NULL_TREE;
- conv = build1 (IDENTITY_CONV, s, expr);
- conv = build_conv (USER_CONV, TREE_TYPE (TREE_TYPE (cand->fn)),
- conv);
+ /* Build a user-defined conversion sequence representing the
+ conversion. */
+ conv = build_conv (USER_CONV,
+ TREE_TYPE (TREE_TYPE (cand->fn)),
+ build1 (IDENTITY_CONV, TREE_TYPE (expr), expr));
TREE_OPERAND (conv, 1) = build_zc_wrapper (cand);
- ICS_USER_FLAG (conv) = 1;
+
+ /* Merge it with the standard conversion sequence from the
+ conversion function's return type to the desired type. */
+ cand->second_conv = merge_conversion_sequences (conv, cand->second_conv);
+
if (cand->viable == -1)
ICS_BAD_FLAG (conv) = 1;
- cand->second_conv = conv;
- return conv;
+ return cand->second_conv;
}
/* A reference of the indicated TYPE is being bound directly to the
@@ -1097,7 +1129,13 @@ direct_reference_binding (type, conv)
tree type;
tree conv;
{
- tree t = TREE_TYPE (type);
+ tree t;
+
+ my_friendly_assert (TREE_CODE (type) == REFERENCE_TYPE, 20030306);
+ my_friendly_assert (TREE_CODE (TREE_TYPE (conv)) != REFERENCE_TYPE,
+ 20030306);
+
+ t = TREE_TYPE (type);
/* [over.ics.rank]
@@ -1134,9 +1172,7 @@ direct_reference_binding (type, conv)
the conversion returned. */
static tree
-reference_binding (rto, rfrom, expr, flags)
- tree rto, rfrom, expr;
- int flags;
+reference_binding (tree rto, tree rfrom, tree expr, int flags)
{
tree conv = NULL_TREE;
tree to = TREE_TYPE (rto);
@@ -1214,7 +1250,7 @@ reference_binding (rto, rfrom, expr, flags)
in the second case. */
conv = convert_class_to_reference (to, from, expr);
if (conv)
- return direct_reference_binding (rto, conv);
+ return conv;
}
/* From this point on, we conceptually need temporaries, even if we
@@ -1248,11 +1284,13 @@ reference_binding (rto, rfrom, expr, flags)
-- The reference is bound to the object represented by the rvalue
or to a sub-object within that object.
- In this case, the implicit conversion sequence is supposed to be
- same as we would obtain by generating a temporary. Fortunately,
- if the types are reference compatible, then this is either an
- identity conversion or the derived-to-base conversion, just as
- for direct binding. */
+ -- ...
+
+ We use the first alternative. The implicit conversion sequence
+ is supposed to be same as we would obtain by generating a
+ temporary. Fortunately, if the types are reference compatible,
+ then this is either an identity conversion or the derived-to-base
+ conversion, just as for direct binding. */
if (CLASS_TYPE_P (from) && compatible_p)
{
conv = build1 (IDENTITY_CONV, from, expr);
@@ -1292,7 +1330,6 @@ implicit_conversion (to, from, expr, flags)
int flags;
{
tree conv;
- struct z_candidate *cand;
/* Resolve expressions like `A::p' that we thought might become
pointers-to-members. */
@@ -1306,11 +1343,6 @@ implicit_conversion (to, from, expr, flags)
|| expr == error_mark_node)
return NULL_TREE;
- /* Make sure both the FROM and TO types are complete so that
- user-defined conversions are available. */
- complete_type (from);
- complete_type (to);
-
if (TREE_CODE (to) == REFERENCE_TYPE)
conv = reference_binding (to, from, expr, flags);
else
@@ -1323,6 +1355,8 @@ implicit_conversion (to, from, expr, flags)
|| IS_AGGR_TYPE (to))
&& (flags & LOOKUP_NO_CONVERSION) == 0)
{
+ struct z_candidate *cand;
+
cand = build_user_type_conversion_1
(to, expr, LOOKUP_ONLYCONVERTING);
if (cand)
@@ -1340,7 +1374,7 @@ implicit_conversion (to, from, expr, flags)
functions. */
static struct z_candidate *
-add_candidate (struct z_candidate *candidates,
+add_candidate (struct z_candidate **candidates,
tree fn, tree convs, tree access_path, tree
conversion_path, int viable)
{
@@ -1352,7 +1386,8 @@ add_candidate (struct z_candidate *candidates,
cand->access_path = access_path;
cand->conversion_path = conversion_path;
cand->viable = viable;
- cand->next = candidates;
+ cand->next = *candidates;
+ *candidates = cand;
return cand;
}
@@ -1365,7 +1400,7 @@ add_candidate (struct z_candidate *candidates,
comes from for purposes of overload resolution. */
static struct z_candidate *
-add_function_candidate (struct z_candidate *candidates,
+add_function_candidate (struct z_candidate **candidates,
tree fn, tree ctype, tree arglist,
tree access_path, tree conversion_path,
int flags)
@@ -1376,6 +1411,11 @@ add_function_candidate (struct z_candidate *candidates,
tree parmnode, argnode;
int viable = 1;
+ /* Built-in functions that haven't been declared don't really
+ exist. */
+ if (DECL_ANTICIPATED (fn))
+ return NULL;
+
/* The `this', `in_chrg' and VTT arguments to constructors are not
considered in overload resolution. */
if (DECL_CONSTRUCTOR_P (fn))
@@ -1498,7 +1538,7 @@ add_function_candidate (struct z_candidate *candidates,
static struct z_candidate *
add_conv_candidate (candidates, fn, obj, arglist, access_path,
conversion_path)
- struct z_candidate *candidates;
+ struct z_candidate **candidates;
tree fn, obj, arglist;
tree access_path;
tree conversion_path;
@@ -1519,8 +1559,8 @@ add_conv_candidate (candidates, fn, obj, arglist, access_path,
flags = LOOKUP_NORMAL;
/* Don't bother looking up the same type twice. */
- if (candidates && candidates->fn == totype)
- return candidates;
+ if (*candidates && (*candidates)->fn == totype)
+ return NULL;
for (i = 0; i < len; ++i)
{
@@ -1565,10 +1605,10 @@ add_conv_candidate (candidates, fn, obj, arglist, access_path,
conversion_path, viable);
}
-static struct z_candidate *
+static void
build_builtin_candidate (candidates, fnname, type1, type2,
args, argtypes, flags)
- struct z_candidate *candidates;
+ struct z_candidate **candidates;
tree fnname, type1, type2, *args, *argtypes;
int flags;
@@ -1611,10 +1651,10 @@ build_builtin_candidate (candidates, fnname, type1, type2,
viable = 0;
}
- return add_candidate (candidates, fnname, convs,
- /*access_path=*/NULL_TREE,
- /*conversion_path=*/NULL_TREE,
- viable);
+ add_candidate (candidates, fnname, convs,
+ /*access_path=*/NULL_TREE,
+ /*conversion_path=*/NULL_TREE,
+ viable);
}
static int
@@ -1652,10 +1692,10 @@ promoted_arithmetic_type_p (type)
of which TYPE1 and TYPE2 are, we add both candidates
CODE (TYPE1, TYPE1) and CODE (TYPE2, TYPE2). */
-static struct z_candidate *
+static void
add_builtin_candidate (candidates, code, code2, fnname, type1, type2,
args, argtypes, flags)
- struct z_candidate *candidates;
+ struct z_candidate **candidates;
enum tree_code code, code2;
tree fnname, type1, type2, *args, *argtypes;
int flags;
@@ -1695,7 +1735,7 @@ add_builtin_candidate (candidates, code, code2, fnname, type1, type2,
case POSTDECREMENT_EXPR:
case PREDECREMENT_EXPR:
if (TREE_CODE (type1) == BOOLEAN_TYPE)
- return candidates;
+ return;
case POSTINCREMENT_EXPR:
case PREINCREMENT_EXPR:
if (ARITHMETIC_TYPE_P (type1) || TYPE_PTROB_P (type1))
@@ -1703,7 +1743,7 @@ add_builtin_candidate (candidates, code, code2, fnname, type1, type2,
type1 = build_reference_type (type1);
break;
}
- return candidates;
+ return;
/* 7 For every cv-qualified or cv-unqualified complete object type T, there
exist candidate operator functions of the form
@@ -1719,7 +1759,7 @@ add_builtin_candidate (candidates, code, code2, fnname, type1, type2,
&& (TYPE_PTROB_P (type1)
|| TREE_CODE (TREE_TYPE (type1)) == FUNCTION_TYPE))
break;
- return candidates;
+ return;
/* 9 For every type T, there exist candidate operator functions of the form
T* operator+(T*);
@@ -1736,7 +1776,7 @@ add_builtin_candidate (candidates, code, code2, fnname, type1, type2,
case NEGATE_EXPR:
if (ARITHMETIC_TYPE_P (type1))
break;
- return candidates;
+ return;
/* 11For every promoted integral type T, there exist candidate operator
functions of the form
@@ -1745,7 +1785,7 @@ add_builtin_candidate (candidates, code, code2, fnname, type1, type2,
case BIT_NOT_EXPR:
if (INTEGRAL_TYPE_P (type1))
break;
- return candidates;
+ return;
/* 12For every quintuple C1, C2, T, CV1, CV2), where C2 is a class type, C1
is the same type as C2 or is a derived class of C2, T is a complete
@@ -1768,7 +1808,7 @@ add_builtin_candidate (candidates, code, code2, fnname, type1, type2,
|| is_complete (TREE_TYPE (TREE_TYPE (type2)))))
break;
}
- return candidates;
+ return;
/* 13For every pair of promoted arithmetic types L and R, there exist can-
didate operator functions of the form
@@ -1824,7 +1864,7 @@ add_builtin_candidate (candidates, code, code2, fnname, type1, type2,
case TRUNC_DIV_EXPR:
if (ARITHMETIC_TYPE_P (type1) && ARITHMETIC_TYPE_P (type2))
break;
- return candidates;
+ return;
case EQ_EXPR:
case NE_EXPR:
@@ -1866,7 +1906,7 @@ add_builtin_candidate (candidates, code, code2, fnname, type1, type2,
type1 = type2;
break;
}
- return candidates;
+ return;
case PLUS_EXPR:
if (ARITHMETIC_TYPE_P (type1) && ARITHMETIC_TYPE_P (type2))
@@ -1882,7 +1922,7 @@ add_builtin_candidate (candidates, code, code2, fnname, type1, type2,
type2 = ptrdiff_type_node;
break;
}
- return candidates;
+ return;
/* 18For every pair of promoted integral types L and R, there exist candi-
date operator functions of the form
@@ -1903,7 +1943,7 @@ add_builtin_candidate (candidates, code, code2, fnname, type1, type2,
case RSHIFT_EXPR:
if (INTEGRAL_TYPE_P (type1) && INTEGRAL_TYPE_P (type2))
break;
- return candidates;
+ return;
/* 19For every triple L, VQ, R), where L is an arithmetic or enumeration
type, VQ is either volatile or empty, and R is a promoted arithmetic
@@ -1955,7 +1995,7 @@ add_builtin_candidate (candidates, code, code2, fnname, type1, type2,
case TRUNC_DIV_EXPR:
if (ARITHMETIC_TYPE_P (type1) && ARITHMETIC_TYPE_P (type2))
break;
- return candidates;
+ return;
case TRUNC_MOD_EXPR:
case BIT_AND_EXPR:
@@ -1965,7 +2005,7 @@ add_builtin_candidate (candidates, code, code2, fnname, type1, type2,
case RSHIFT_EXPR:
if (INTEGRAL_TYPE_P (type1) && INTEGRAL_TYPE_P (type2))
break;
- return candidates;
+ return;
case NOP_EXPR:
if (ARITHMETIC_TYPE_P (type1) && ARITHMETIC_TYPE_P (type2))
@@ -1980,7 +2020,7 @@ add_builtin_candidate (candidates, code, code2, fnname, type1, type2,
type2 = type1;
break;
}
- return candidates;
+ return;
default:
abort ();
@@ -2015,16 +2055,13 @@ add_builtin_candidate (candidates, code, code2, fnname, type1, type2,
|| !(TREE_CODE (type2) == POINTER_TYPE
|| TYPE_PTRMEM_P (type2)
|| TYPE_PTRMEMFUNC_P (type2)))
- return candidates;
+ return;
/* We don't check that the two types are the same; the logic
below will actually create two candidates; one in which both
parameter types are TYPE1, and one in which both parameter
types are TYPE2. */
- break;
-
- /* These arguments do not make for a valid overloaded operator. */
- return candidates;
+ break;
default:
abort ();
@@ -2041,13 +2078,14 @@ add_builtin_candidate (candidates, code, code2, fnname, type1, type2,
|| IS_AGGR_TYPE (type1)
|| TREE_CODE (type1) == ENUMERAL_TYPE))
{
- candidates = build_builtin_candidate
+ build_builtin_candidate
(candidates, fnname, type1, type1, args, argtypes, flags);
- return build_builtin_candidate
+ build_builtin_candidate
(candidates, fnname, type2, type2, args, argtypes, flags);
+ return;
}
- return build_builtin_candidate
+ build_builtin_candidate
(candidates, fnname, type1, type2, args, argtypes, flags);
}
@@ -2075,9 +2113,9 @@ type_decays_to (type)
other cases which the standard disallows. add_builtin_candidate will
filter out the invalid set. */
-static struct z_candidate *
+static void
add_builtin_candidates (candidates, code, code2, fnname, args, flags)
- struct z_candidate *candidates;
+ struct z_candidate **candidates;
enum tree_code code, code2;
tree fnname, *args;
int flags;
@@ -2120,20 +2158,22 @@ add_builtin_candidates (candidates, code, code2, fnname, args, flags)
bool operator||(bool, bool); */
case TRUTH_NOT_EXPR:
- return build_builtin_candidate
+ build_builtin_candidate
(candidates, fnname, boolean_type_node,
NULL_TREE, args, argtypes, flags);
+ return;
case TRUTH_ORIF_EXPR:
case TRUTH_ANDIF_EXPR:
- return build_builtin_candidate
+ build_builtin_candidate
(candidates, fnname, boolean_type_node,
boolean_type_node, args, argtypes, flags);
+ return;
case ADDR_EXPR:
case COMPOUND_EXPR:
case COMPONENT_REF:
- return candidates;
+ return;
case COND_EXPR:
case EQ_EXPR:
@@ -2160,7 +2200,7 @@ add_builtin_candidates (candidates, code, code2, fnname, args, flags)
tree convs;
if (i == 0 && code == MODIFY_EXPR && code2 == NOP_EXPR)
- return candidates;
+ return;
convs = lookup_conversions (argtypes[i]);
@@ -2175,7 +2215,7 @@ add_builtin_candidates (candidates, code, code2, fnname, args, flags)
}
else if (! convs)
- return candidates;
+ return;
for (; convs; convs = TREE_CHAIN (convs))
{
@@ -2227,16 +2267,16 @@ add_builtin_candidates (candidates, code, code2, fnname, args, flags)
{
if (types[1])
for (type = types[1]; type; type = TREE_CHAIN (type))
- candidates = add_builtin_candidate
+ add_builtin_candidate
(candidates, code, code2, fnname, TREE_VALUE (types[0]),
TREE_VALUE (type), args, argtypes, flags);
else
- candidates = add_builtin_candidate
+ add_builtin_candidate
(candidates, code, code2, fnname, TREE_VALUE (types[0]),
NULL_TREE, args, argtypes, flags);
}
- return candidates;
+ return;
}
@@ -2254,7 +2294,7 @@ static struct z_candidate*
add_template_candidate_real (candidates, tmpl, ctype, explicit_targs,
arglist, return_type, access_path,
conversion_path, flags, obj, strict)
- struct z_candidate *candidates;
+ struct z_candidate **candidates;
tree tmpl, ctype, explicit_targs, arglist, return_type;
tree access_path;
tree conversion_path;
@@ -2284,11 +2324,11 @@ add_template_candidate_real (candidates, tmpl, ctype, explicit_targs,
return_type, strict, -1);
if (i != 0)
- return candidates;
+ return NULL;
fn = instantiate_template (tmpl, targs);
if (fn == error_mark_node)
- return candidates;
+ return NULL;
/* In [class.copy]:
@@ -2317,7 +2357,7 @@ add_template_candidate_real (candidates, tmpl, ctype, explicit_targs,
tree arg_types = FUNCTION_FIRST_USER_PARMTYPE (fn);
if (arg_types && same_type_p (TYPE_MAIN_VARIANT (TREE_VALUE (arg_types)),
ctype))
- return candidates;
+ return NULL;
}
if (obj != NULL_TREE)
@@ -2358,7 +2398,7 @@ static struct z_candidate *
add_template_candidate (candidates, tmpl, ctype, explicit_targs,
arglist, return_type, access_path,
conversion_path, flags, strict)
- struct z_candidate *candidates;
+ struct z_candidate **candidates;
tree tmpl, ctype, explicit_targs, arglist, return_type;
tree access_path;
tree conversion_path;
@@ -2376,7 +2416,7 @@ add_template_candidate (candidates, tmpl, ctype, explicit_targs,
static struct z_candidate *
add_template_conv_candidate (candidates, tmpl, obj, arglist, return_type,
access_path, conversion_path)
- struct z_candidate *candidates;
+ struct z_candidate **candidates;
tree tmpl, obj, arglist, return_type;
tree access_path;
tree conversion_path;
@@ -2433,11 +2473,51 @@ build_this (obj)
return build_unary_op (ADDR_EXPR, obj, 0);
}
+/* Returns true iff functions are equivalent. Equivalent functions are
+ not '==' only if one is a function-local extern function or if
+ both are extern "C". */
+
+static inline int
+equal_functions (fn1, fn2)
+ tree fn1;
+ tree fn2;
+{
+ if (DECL_LOCAL_FUNCTION_P (fn1) || DECL_LOCAL_FUNCTION_P (fn2)
+ || DECL_EXTERN_C_FUNCTION_P (fn1))
+ return decls_match (fn1, fn2);
+ return fn1 == fn2;
+}
+
static void
-print_z_candidates (candidates)
- struct z_candidate *candidates;
+print_z_candidates (struct z_candidate *candidates)
{
- const char *str = "candidates are:";
+ const char *str;
+ struct z_candidate *cand1;
+ struct z_candidate **cand2;
+
+ /* There may be duplicates in the set of candidates. We put off
+ checking this condition as long as possible, since we have no way
+ to eliminate duplicates from a set of functions in less than n^2
+ time. Now we are about to emit an error message, so it is more
+ permissible to go slowly. */
+ for (cand1 = candidates; cand1; cand1 = cand1->next)
+ {
+ tree fn = cand1->fn;
+ /* Skip builtin candidates and conversion functions. */
+ if (TREE_CODE (fn) != FUNCTION_DECL)
+ continue;
+ cand2 = &cand1->next;
+ while (*cand2)
+ {
+ if (TREE_CODE ((*cand2)->fn) == FUNCTION_DECL
+ && equal_functions (fn, (*cand2)->fn))
+ *cand2 = (*cand2)->next;
+ else
+ cand2 = &(*cand2)->next;
+ }
+ }
+
+ str = "candidates are:";
for (; candidates; candidates = candidates->next)
{
if (TREE_CODE (candidates->fn) == IDENTIFIER_NODE)
@@ -2464,6 +2544,35 @@ print_z_candidates (candidates)
}
}
+/* USER_SEQ is a user-defined conversion sequence, beginning with a
+ USER_CONV. STD_SEQ is the standard conversion sequence applied to
+ the result of the conversion function to convert it to the final
+ desired type. Merge the the two sequences into a single sequence,
+ and return the merged sequence. */
+
+static tree
+merge_conversion_sequences (tree user_seq, tree std_seq)
+{
+ tree *t;
+
+ my_friendly_assert (TREE_CODE (user_seq) == USER_CONV,
+ 20030306);
+
+ /* Find the end of the second conversion sequence. */
+ t = &(std_seq);
+ while (TREE_CODE (*t) != IDENTITY_CONV)
+ t = &TREE_OPERAND (*t, 0);
+
+ /* Replace the identity conversion with the user conversion
+ sequence. */
+ *t = user_seq;
+
+ /* The entire sequence is a user-conversion sequence. */
+ ICS_USER_FLAG (std_seq) = 1;
+
+ return std_seq;
+}
+
/* Returns the best overload candidate to perform the requested
conversion. This function is used for three the overloading situations
described in [over.match.copy], [over.match.conv], and [over.match.ref].
@@ -2477,9 +2586,8 @@ build_user_type_conversion_1 (totype, expr, flags)
{
struct z_candidate *candidates, *cand;
tree fromtype = TREE_TYPE (expr);
- tree ctors = NULL_TREE, convs = NULL_TREE, *p;
+ tree ctors = NULL_TREE, convs = NULL_TREE;
tree args = NULL_TREE;
- tree templates = NULL_TREE;
/* We represent conversion within a hierarchy using RVALUE_CONV and
BASE_CONV, as specified by [over.best.ics]; these become plain
@@ -2521,24 +2629,20 @@ build_user_type_conversion_1 (totype, expr, flags)
continue;
if (TREE_CODE (ctor) == TEMPLATE_DECL)
- {
- templates = tree_cons (NULL_TREE, ctor, templates);
- candidates =
- add_template_candidate (candidates, ctor, totype,
- NULL_TREE, args, NULL_TREE,
- TYPE_BINFO (totype),
- TYPE_BINFO (totype),
- flags,
- DEDUCE_CALL);
- }
+ cand = add_template_candidate (&candidates, ctor, totype,
+ NULL_TREE, args, NULL_TREE,
+ TYPE_BINFO (totype),
+ TYPE_BINFO (totype),
+ flags,
+ DEDUCE_CALL);
else
- candidates = add_function_candidate (candidates, ctor, totype,
- args, TYPE_BINFO (totype),
- TYPE_BINFO (totype),
- flags);
+ cand = add_function_candidate (&candidates, ctor, totype,
+ args, TYPE_BINFO (totype),
+ TYPE_BINFO (totype),
+ flags);
- if (candidates)
- candidates->second_conv = build1 (IDENTITY_CONV, totype, NULL_TREE);
+ if (cand)
+ cand->second_conv = build1 (IDENTITY_CONV, totype, NULL_TREE);
}
if (convs)
@@ -2560,7 +2664,6 @@ build_user_type_conversion_1 (totype, expr, flags)
for (fns = TREE_VALUE (convs); fns; fns = OVL_NEXT (fns))
{
tree fn = OVL_CURRENT (fns);
- struct z_candidate *old_candidates = candidates;
/* [over.match.funcs] For conversion functions, the function
is considered to be a member of the class of the implicit
@@ -2570,34 +2673,31 @@ build_user_type_conversion_1 (totype, expr, flags)
So we pass fromtype as CTYPE to add_*_candidate. */
if (TREE_CODE (fn) == TEMPLATE_DECL)
- {
- templates = tree_cons (NULL_TREE, fn, templates);
- candidates =
- add_template_candidate (candidates, fn, fromtype, NULL_TREE,
- args, totype, TYPE_BINFO (fromtype),
- conversion_path,
- flags,
- DEDUCE_CONV);
- }
+ cand = add_template_candidate (&candidates, fn, fromtype, NULL_TREE,
+ args, totype,
+ TYPE_BINFO (fromtype),
+ conversion_path,
+ flags,
+ DEDUCE_CONV);
else
- candidates = add_function_candidate (candidates, fn, fromtype,
- args,
- TYPE_BINFO (fromtype),
- conversion_path,
- flags);
+ cand = add_function_candidate (&candidates, fn, fromtype,
+ args,
+ TYPE_BINFO (fromtype),
+ conversion_path,
+ flags);
- if (candidates != old_candidates)
+ if (cand)
{
tree ics = implicit_conversion
- (totype, TREE_TYPE (TREE_TYPE (candidates->fn)),
+ (totype, TREE_TYPE (TREE_TYPE (cand->fn)),
0, convflags);
- candidates->second_conv = ics;
+ cand->second_conv = ics;
if (ics == NULL_TREE)
- candidates->viable = 0;
- else if (candidates->viable == 1 && ICS_BAD_FLAG (ics))
- candidates->viable = -1;
+ cand->viable = 0;
+ else if (cand->viable == 1 && ICS_BAD_FLAG (ics))
+ cand->viable = -1;
}
}
}
@@ -2620,24 +2720,29 @@ build_user_type_conversion_1 (totype, expr, flags)
cand = candidates; /* any one will do */
cand->second_conv = build1 (AMBIG_CONV, totype, expr);
ICS_USER_FLAG (cand->second_conv) = 1;
- /* Don't set ICS_BAD_FLAG; an ambiguous conversion is no worse than
- another user-defined conversion. */
+ if (!any_strictly_viable (candidates))
+ ICS_BAD_FLAG (cand->second_conv) = 1;
+ /* If there are viable candidates, don't set ICS_BAD_FLAG; an
+ ambiguous conversion is no worse than another user-defined
+ conversion. */
return cand;
}
- for (p = &(cand->second_conv); TREE_CODE (*p) != IDENTITY_CONV; )
- p = &(TREE_OPERAND (*p, 0));
-
- *p = build
+ /* Build the user conversion sequence. */
+ convs = build_conv
(USER_CONV,
(DECL_CONSTRUCTOR_P (cand->fn)
? totype : non_reference (TREE_TYPE (TREE_TYPE (cand->fn)))),
- expr, build_zc_wrapper (cand));
-
- ICS_USER_FLAG (cand->second_conv) = ICS_USER_FLAG (*p) = 1;
+ build1 (IDENTITY_CONV, TREE_TYPE (expr), expr));
+ TREE_OPERAND (convs, 1) = build_zc_wrapper (cand);
+
+ /* Combine it with the second conversion sequence. */
+ cand->second_conv = merge_conversion_sequences (convs,
+ cand->second_conv);
+
if (cand->viable == -1)
- ICS_BAD_FLAG (cand->second_conv) = ICS_BAD_FLAG (*p) = 1;
+ ICS_BAD_FLAG (cand->second_conv) = 1;
return cand;
}
@@ -2659,6 +2764,73 @@ build_user_type_conversion (totype, expr, flags)
return NULL_TREE;
}
+/* Find the possibly overloaded set of functions corresponding to a
+ call of the form SCOPE::NAME (...). NAME might be a
+ TEMPLATE_ID_EXPR, OVERLOAD, _DECL, IDENTIFIER_NODE or LOOKUP_EXPR. */
+
+tree
+resolve_scoped_fn_name (tree scope, tree name)
+{
+ tree fn;
+ tree template_args = NULL_TREE;
+ bool is_template_id = TREE_CODE (name) == TEMPLATE_ID_EXPR;
+
+ if (is_template_id)
+ {
+ template_args = TREE_OPERAND (name, 1);
+ name = TREE_OPERAND (name, 0);
+ }
+ if (TREE_CODE (name) == OVERLOAD)
+ name = DECL_NAME (get_first_fn (name));
+ else if (TREE_CODE (name) == LOOKUP_EXPR)
+ name = TREE_OPERAND (name, 0);
+
+ if (TREE_CODE (scope) == NAMESPACE_DECL)
+ fn = lookup_namespace_name (scope, name);
+ else
+ {
+ if (!TYPE_BEING_DEFINED (scope)
+ && !COMPLETE_TYPE_P (complete_type (scope)))
+ {
+ error ("incomplete type '%T' cannot be used to name a scope",
+ scope);
+ return error_mark_node;
+ }
+
+ if (BASELINK_P (name))
+ fn = name;
+ else
+ fn = lookup_member (scope, name, /*protect=*/1, /*prefer_type=*/0);
+ if (fn && current_class_type)
+ fn = (adjust_result_of_qualified_name_lookup
+ (fn, scope, current_class_type));
+
+ /* It might be the name of a function pointer member. */
+ if (fn && TREE_CODE (fn) == FIELD_DECL)
+ fn = resolve_offset_ref (build_offset_ref (scope, fn));
+ }
+
+ if (!fn)
+ {
+ error ("'%D' has no member named '%E'", scope, name);
+ return error_mark_node;
+ }
+ if (is_template_id)
+ {
+ tree fns = fn;
+
+ if (BASELINK_P (fn))
+ fns = BASELINK_FUNCTIONS (fns);
+ fns = build_nt (TEMPLATE_ID_EXPR, fns, template_args);
+ if (BASELINK_P (fn))
+ BASELINK_FUNCTIONS (fn) = fns;
+ else
+ fn = fns;
+ }
+
+ return fn;
+}
+
/* Do any initial processing on the arguments to a function call. */
static tree
@@ -2716,7 +2888,6 @@ build_new_function_call (fn, args)
|| TREE_CODE (fn) == TEMPLATE_DECL)
{
tree t1;
- tree templates = NULL_TREE;
args = resolve_args (args);
@@ -2728,17 +2899,14 @@ build_new_function_call (fn, args)
tree t = OVL_CURRENT (t1);
if (TREE_CODE (t) == TEMPLATE_DECL)
- {
- templates = tree_cons (NULL_TREE, t, templates);
- candidates = add_template_candidate
- (candidates, t, NULL_TREE, explicit_targs, args,
- NULL_TREE,
- /*access_path=*/NULL_TREE, /*conversion_path=*/NULL_TREE,
- LOOKUP_NORMAL, DEDUCE_CALL);
- }
+ add_template_candidate
+ (&candidates, t, NULL_TREE, explicit_targs, args,
+ NULL_TREE,
+ /*access_path=*/NULL_TREE, /*conversion_path=*/NULL_TREE,
+ LOOKUP_NORMAL, DEDUCE_CALL);
else if (! template_only)
- candidates = add_function_candidate
- (candidates, t, NULL_TREE, args, /*access_path=*/NULL_TREE,
+ add_function_candidate
+ (&candidates, t, NULL_TREE, args, /*access_path=*/NULL_TREE,
/*conversion_path=*/NULL_TREE, LOOKUP_NORMAL);
}
@@ -2806,17 +2974,14 @@ build_object_call (obj, args)
{
tree fn = OVL_CURRENT (fns);
if (TREE_CODE (fn) == TEMPLATE_DECL)
- {
- candidates
- = add_template_candidate (candidates, fn, base, NULL_TREE,
- mem_args, NULL_TREE,
- TYPE_BINFO (type),
- TYPE_BINFO (type),
- LOOKUP_NORMAL, DEDUCE_CALL);
- }
+ add_template_candidate (&candidates, fn, base, NULL_TREE,
+ mem_args, NULL_TREE,
+ TYPE_BINFO (type),
+ TYPE_BINFO (type),
+ LOOKUP_NORMAL, DEDUCE_CALL);
else
- candidates = add_function_candidate
- (candidates, fn, base, mem_args, TYPE_BINFO (type),
+ add_function_candidate
+ (&candidates, fn, base, mem_args, TYPE_BINFO (type),
TYPE_BINFO (type), LOOKUP_NORMAL);
}
}
@@ -2839,16 +3004,14 @@ build_object_call (obj, args)
{
tree fn = OVL_CURRENT (fns);
if (TREE_CODE (fn) == TEMPLATE_DECL)
- {
- candidates = (add_template_conv_candidate
- (candidates, fn, obj, args, totype,
- /*access_path=*/NULL_TREE,
- /*conversion_path=*/NULL_TREE));
- }
+ add_template_conv_candidate
+ (&candidates, fn, obj, args, totype,
+ /*access_path=*/NULL_TREE,
+ /*conversion_path=*/NULL_TREE);
else
- candidates = add_conv_candidate (candidates, fn, obj, args,
- /*conversion_path=*/NULL_TREE,
- /*access_path=*/NULL_TREE);
+ add_conv_candidate (&candidates, fn, obj, args,
+ /*conversion_path=*/NULL_TREE,
+ /*access_path=*/NULL_TREE);
}
}
@@ -3156,12 +3319,12 @@ build_conditional_expr (arg1, arg2, arg3)
args[0] = arg2;
args[1] = arg3;
args[2] = arg1;
- candidates = add_builtin_candidates (candidates,
- COND_EXPR,
- NOP_EXPR,
- ansi_opname (COND_EXPR),
- args,
- LOOKUP_NORMAL);
+ add_builtin_candidates (&candidates,
+ COND_EXPR,
+ NOP_EXPR,
+ ansi_opname (COND_EXPR),
+ args,
+ LOOKUP_NORMAL);
/* [expr.cond]
@@ -3209,18 +3372,10 @@ build_conditional_expr (arg1, arg2, arg3)
We use ocp_convert rather than build_user_type_conversion because the
latter returns NULL_TREE on failure, while the former gives an error. */
- if (IS_AGGR_TYPE (TREE_TYPE (arg2)) && real_lvalue_p (arg2))
- arg2 = ocp_convert (TREE_TYPE (arg2), arg2,
- CONV_IMPLICIT|CONV_FORCE_TEMP, LOOKUP_NORMAL);
- else
- arg2 = decay_conversion (arg2);
+ arg2 = force_rvalue (arg2);
arg2_type = TREE_TYPE (arg2);
- if (IS_AGGR_TYPE (TREE_TYPE (arg3)) && real_lvalue_p (arg3))
- arg3 = ocp_convert (TREE_TYPE (arg3), arg3,
- CONV_IMPLICIT|CONV_FORCE_TEMP, LOOKUP_NORMAL);
- else
- arg3 = decay_conversion (arg3);
+ arg3 = force_rvalue (arg3);
arg3_type = TREE_TYPE (arg3);
if (arg2 == error_mark_node || arg3 == error_mark_node)
@@ -3326,7 +3481,6 @@ build_new_op (code, flags, arg1, arg2, arg3)
struct z_candidate *candidates = 0, *cand;
tree fns, mem_arglist = NULL_TREE, arglist, fnname;
enum tree_code code2 = NOP_EXPR;
- tree templates = NULL_TREE;
tree conv;
bool viable_candidates;
@@ -3355,6 +3509,10 @@ build_new_op (code, flags, arg1, arg2, arg3)
if (TREE_CODE (arg1) == OFFSET_REF)
arg1 = resolve_offset_ref (arg1);
arg1 = convert_from_reference (arg1);
+ if (CLASS_TYPE_P (TREE_TYPE (arg1))
+ && CLASSTYPE_TEMPLATE_INSTANTIATION (TREE_TYPE (arg1)))
+ /* Make sure the template type is instantiated now. */
+ instantiate_class_template (TYPE_MAIN_VARIANT (TREE_TYPE (arg1)));
switch (code)
{
@@ -3377,12 +3535,18 @@ build_new_op (code, flags, arg1, arg2, arg3)
if (TREE_CODE (arg2) == OFFSET_REF)
arg2 = resolve_offset_ref (arg2);
arg2 = convert_from_reference (arg2);
+ if (CLASS_TYPE_P (TREE_TYPE (arg2))
+ && CLASSTYPE_TEMPLATE_INSTANTIATION (TREE_TYPE (arg2)))
+ instantiate_class_template (TYPE_MAIN_VARIANT (TREE_TYPE (arg2)));
}
if (arg3)
{
if (TREE_CODE (arg3) == OFFSET_REF)
arg3 = resolve_offset_ref (arg3);
arg3 = convert_from_reference (arg3);
+ if (CLASS_TYPE_P (TREE_TYPE (arg3))
+ && CLASSTYPE_TEMPLATE_INSTANTIATION (TREE_TYPE (arg3)))
+ instantiate_class_template (TYPE_MAIN_VARIANT (TREE_TYPE (arg3)));
}
if (code == COND_EXPR)
@@ -3416,21 +3580,17 @@ build_new_op (code, flags, arg1, arg2, arg3)
{
tree fn = OVL_CURRENT (fns);
if (TREE_CODE (fn) == TEMPLATE_DECL)
- {
- templates = tree_cons (NULL_TREE, fn, templates);
- candidates
- = add_template_candidate (candidates, fn, NULL_TREE, NULL_TREE,
- arglist, TREE_TYPE (fnname),
- /*access_path=*/NULL_TREE,
- /*conversion_path=*/NULL_TREE,
- flags, DEDUCE_CALL);
- }
+ add_template_candidate (&candidates, fn, NULL_TREE, NULL_TREE,
+ arglist, TREE_TYPE (fnname),
+ /*access_path=*/NULL_TREE,
+ /*conversion_path=*/NULL_TREE,
+ flags, DEDUCE_CALL);
else
- candidates = add_function_candidate (candidates, fn, NULL_TREE,
- arglist,
- /*access_path=*/NULL_TREE,
- /*conversion_path=*/NULL_TREE,
- flags);
+ add_function_candidate (&candidates, fn, NULL_TREE,
+ arglist,
+ /*access_path=*/NULL_TREE,
+ /*conversion_path=*/NULL_TREE,
+ flags);
}
if (IS_AGGR_TYPE (TREE_TYPE (arg1)))
@@ -3459,20 +3619,16 @@ build_new_op (code, flags, arg1, arg2, arg3)
this_arglist = arglist;
if (TREE_CODE (fn) == TEMPLATE_DECL)
- {
- /* A member template. */
- templates = tree_cons (NULL_TREE, fn, templates);
- candidates
- = add_template_candidate (candidates, fn,
- BINFO_TYPE (conversion_path),
- NULL_TREE,
- this_arglist, TREE_TYPE (fnname),
- access_path, conversion_path,
- flags, DEDUCE_CALL);
- }
+ /* A member template. */
+ add_template_candidate (&candidates, fn,
+ BINFO_TYPE (conversion_path),
+ NULL_TREE,
+ this_arglist, TREE_TYPE (fnname),
+ access_path, conversion_path,
+ flags, DEDUCE_CALL);
else
- candidates = add_function_candidate
- (candidates, fn, BINFO_TYPE (conversion_path), this_arglist,
+ add_function_candidate
+ (&candidates, fn, BINFO_TYPE (conversion_path), this_arglist,
access_path, conversion_path, flags);
}
}
@@ -3497,8 +3653,7 @@ build_new_op (code, flags, arg1, arg2, arg3)
args[2] = NULL_TREE;
}
- candidates = add_builtin_candidates
- (candidates, code, code2, fnname, args, flags);
+ add_builtin_candidates (&candidates, code, code2, fnname, args, flags);
}
switch (code)
@@ -3922,8 +4077,7 @@ convert_like_real (convs, expr, fn, argnum, inner)
{
case USER_CONV:
{
- struct z_candidate *cand
- = WRAPPER_ZC (TREE_OPERAND (convs, 1));
+ struct z_candidate *cand = USER_CONV_CAND (convs);
tree convfn = cand->fn;
tree args;
@@ -4079,9 +4233,7 @@ convert_like_real (convs, expr, fn, argnum, inner)
expr = cp_convert (build_pointer_type (TREE_TYPE (ref_type)),
expr);
/* Convert the pointer to the desired reference type. */
- expr = build1 (NOP_EXPR, ref_type, expr);
-
- return expr;
+ return build_nop (ref_type, expr);
}
case LVALUE_CONV:
@@ -4727,7 +4879,6 @@ build_new_method_call (tree instance, tree fns, tree args,
tree mem_args = NULL_TREE, instance_ptr;
tree name, pretty_name;
tree user_args;
- tree templates = NULL_TREE;
tree call;
int template_only = 0;
@@ -4830,26 +4981,22 @@ build_new_method_call (tree instance, tree fns, tree args,
this_arglist = args;
if (TREE_CODE (t) == TEMPLATE_DECL)
- {
- /* A member template. */
- templates = tree_cons (NULL_TREE, t, templates);
- candidates =
- add_template_candidate (candidates, t,
- class_type,
- explicit_targs,
- this_arglist, optype,
- access_binfo,
- conversion_path,
- flags,
- DEDUCE_CALL);
- }
+ /* A member template. */
+ add_template_candidate (&candidates, t,
+ class_type,
+ explicit_targs,
+ this_arglist, optype,
+ access_binfo,
+ conversion_path,
+ flags,
+ DEDUCE_CALL);
else if (! template_only)
- candidates = add_function_candidate (candidates, t,
- class_type,
- this_arglist,
- access_binfo,
- conversion_path,
- flags);
+ add_function_candidate (&candidates, t,
+ class_type,
+ this_arglist,
+ access_binfo,
+ conversion_path,
+ flags);
}
}
@@ -5401,21 +5548,6 @@ add_warning (winner, loser)
winner->warnings);
}
-/* Returns true iff functions are equivalent. Equivalent functions are
- not '==' only if one is a function-local extern function or if
- both are extern "C". */
-
-static inline int
-equal_functions (fn1, fn2)
- tree fn1;
- tree fn2;
-{
- if (DECL_LOCAL_FUNCTION_P (fn1) || DECL_LOCAL_FUNCTION_P (fn2)
- || DECL_EXTERN_C_FUNCTION_P (fn1))
- return decls_match (fn1, fn2);
- return fn1 == fn2;
-}
-
/* Compare two candidates for overloading as described in
[over.match.best]. Return values:
@@ -5679,11 +5811,9 @@ tweak:
if (winner)
{
if (warn)
- {
- pedwarn ("choosing `%D' over `%D'", w->fn, l->fn);
- pedwarn (
-" because worst conversion for the former is better than worst conversion for the latter");
- }
+ pedwarn ("ISO C++ says that `%D' and `%D' are ambiguous \
+even though the worst conversion for the former is better than the worst \
+conversion for the latter", w->fn, l->fn);
else
add_warning (w, l);
return winner;
@@ -5805,17 +5935,62 @@ perform_implicit_conversion (type, expr)
return convert_like (conv, expr);
}
+/* DECL is a VAR_DECL whose type is a REFERENCE_TYPE. The reference
+ is being bound to a temporary. Create and return a new VAR_DECL
+ with the indicated TYPE; this variable will store the value to
+ which the reference is bound. */
+
+tree
+make_temporary_var_for_ref_to_temp (tree decl, tree type)
+{
+ tree var;
+
+ /* Create the variable. */
+ var = build_decl (VAR_DECL, NULL_TREE, type);
+ DECL_ARTIFICIAL (var) = 1;
+ TREE_USED (var) = 1;
+
+ /* Register the variable. */
+ if (TREE_STATIC (decl))
+ {
+ /* Namespace-scope or local static; give it a mangled name. */
+ tree name;
+
+ TREE_STATIC (var) = 1;
+ name = mangle_ref_init_variable (decl);
+ DECL_NAME (var) = name;
+ SET_DECL_ASSEMBLER_NAME (var, name);
+ var = pushdecl_top_level (var);
+ }
+ else
+ {
+ /* Create a new cleanup level if necessary. */
+ maybe_push_cleanup_level (type);
+ /* Don't push unnamed temps. Do set DECL_CONTEXT, though. */
+ DECL_CONTEXT (var) = current_function_decl;
+ }
+
+ return var;
+}
+
/* Convert EXPR to the indicated reference TYPE, in a way suitable for
- initializing a variable of that TYPE. Return the converted
- expression. */
+ initializing a variable of that TYPE. If DECL is non-NULL, it is
+ the VAR_DECL being initialized with the EXPR. (In that case, the
+ type of DECL will be TYPE.)
+
+ Return the converted expression. */
tree
-initialize_reference (type, expr)
+initialize_reference (type, expr, decl)
tree type;
tree expr;
+ tree decl;
{
tree conv;
+ if (type == error_mark_node || error_operand_p (expr))
+ return error_mark_node;
+
conv = reference_binding (type, TREE_TYPE (expr), expr, LOOKUP_NORMAL);
if (!conv || ICS_BAD_FLAG (conv))
{
@@ -5823,6 +5998,80 @@ initialize_reference (type, expr)
return error_mark_node;
}
+ /* If DECL is non-NULL, then this special rule applies:
+
+ [class.temporary]
+
+ The temporary to which the reference is bound or the temporary
+ that is the complete object to which the reference is bound
+ persists for the lifetime of the reference.
+
+ The temporaries created during the evaluation of the expression
+ initializing the reference, except the temporary to which the
+ reference is bound, are destroyed at the end of the
+ full-expression in which they are created.
+
+ In that case, we store the converted expression into a new
+ VAR_DECL in a new scope.
+
+ However, we want to be careful not to create temporaries when
+ they are not required. For example, given:
+
+ struct B {};
+ struct D : public B {};
+ D f();
+ const B& b = f();
+
+ there is no need to copy the return value from "f"; we can just
+ extend its lifetime. Similarly, given:
+
+ struct S {};
+ struct T { operator S(); };
+ T t;
+ const S& s = t;
+
+ we can extend the lifetime of the returnn value of the conversion
+ operator. */
+ my_friendly_assert (TREE_CODE (conv) == REF_BIND, 20030302);
+ if (decl)
+ {
+ tree var;
+ tree base_conv_type;
+
+ /* Skip over the REF_BIND. */
+ conv = TREE_OPERAND (conv, 0);
+ /* If the next conversion is a BASE_CONV, skip that too -- but
+ remember that the conversion was required. */
+ if (TREE_CODE (conv) == BASE_CONV && !NEED_TEMPORARY_P (conv))
+ {
+ base_conv_type = TREE_TYPE (conv);
+ conv = TREE_OPERAND (conv, 0);
+ }
+ else
+ base_conv_type = NULL_TREE;
+ /* Perform the remainder of the conversion. */
+ expr = convert_like (conv, expr);
+ if (!real_non_cast_lvalue_p (expr))
+ {
+ /* Create the temporary variable. */
+ var = make_temporary_var_for_ref_to_temp (decl, TREE_TYPE (expr));
+ DECL_INITIAL (var) = expr;
+ cp_finish_decl (var, expr, NULL_TREE,
+ LOOKUP_ONLYCONVERTING|DIRECT_BIND);
+ /* Use its address to initialize the reference variable. */
+ expr = build_address (var);
+ }
+ else
+ /* Take the address of EXPR. */
+ expr = build_unary_op (ADDR_EXPR, expr, 0);
+ /* If a BASE_CONV was required, perform it now. */
+ if (base_conv_type)
+ expr = (perform_implicit_conversion
+ (build_pointer_type (base_conv_type), expr));
+ return build_nop (type, expr);
+ }
+
+ /* Perform the conversion. */
return convert_like (conv, expr);
}