summaryrefslogtreecommitdiffstats
path: root/contrib/gcc/cp/call.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/gcc/cp/call.c')
-rw-r--r--contrib/gcc/cp/call.c1810
1 files changed, 1164 insertions, 646 deletions
diff --git a/contrib/gcc/cp/call.c b/contrib/gcc/cp/call.c
index c8dcaf0..ac7aeb8 100644
--- a/contrib/gcc/cp/call.c
+++ b/contrib/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).
@@ -38,20 +38,20 @@ Boston, MA 02111-1307, USA. */
extern int inhibit_warnings;
-static tree build_new_method_call PARAMS ((tree, tree, tree, tree, int));
-
-static tree build_field_call PARAMS ((tree, tree, tree, tree));
+static tree build_field_call PARAMS ((tree, tree, tree));
static struct z_candidate * tourney PARAMS ((struct z_candidate *));
static int equal_functions PARAMS ((tree, tree));
static int joust PARAMS ((struct z_candidate *, struct z_candidate *, int));
static int compare_ics PARAMS ((tree, tree));
static tree build_over_call PARAMS ((struct z_candidate *, tree, int));
static tree build_java_interface_fn_ref PARAMS ((tree, tree));
-#define convert_like(CONV, EXPR) \
- convert_like_real ((CONV), (EXPR), NULL_TREE, 0, 0)
-#define convert_like_with_context(CONV, EXPR, FN, ARGNO) \
- convert_like_real ((CONV), (EXPR), (FN), (ARGNO), 0)
-static tree convert_like_real PARAMS ((tree, tree, tree, int, int));
+#define convert_like(CONV, EXPR) \
+ convert_like_real ((CONV), (EXPR), NULL_TREE, 0, 0, \
+ /*issue_conversion_warnings=*/true)
+#define convert_like_with_context(CONV, EXPR, FN, ARGNO) \
+ convert_like_real ((CONV), (EXPR), (FN), (ARGNO), 0, \
+ /*issue_conversion_warnings=*/true)
+static tree convert_like_real (tree, tree, tree, int, int, bool);
static void op_error PARAMS ((enum tree_code, enum tree_code, tree, tree,
tree, const char *));
static tree build_object_call PARAMS ((tree, tree));
@@ -62,38 +62,39 @@ static void print_z_candidates PARAMS ((struct z_candidate *));
static tree build_this PARAMS ((tree));
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, int,
- unification_kind_t));
+ 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, int,
- tree, unification_kind_t));
+ 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));
-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));
+ PARAMS ((struct z_candidate **, tree, tree, tree, tree, tree));
static struct z_candidate * add_function_candidate
- PARAMS ((struct z_candidate *, 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 PARAMS ((struct z_candidate *,
- tree, tree, int));
+static struct z_candidate *add_candidate
+ (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,56 +103,46 @@ static tree convert_class_to_reference PARAMS ((tree, tree, tree));
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)
tree datum, type;
{
- tree rval;
-
if (datum == error_mark_node)
return error_mark_node;
if (TREE_CODE (TREE_TYPE (datum)) == REFERENCE_TYPE)
datum = convert_from_reference (datum);
- if (! TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (type))
- rval = build (COMPONENT_REF, TREE_TYPE (TYPE_VFIELD (type)),
- datum, TYPE_VFIELD (type));
- else
- rval = build_component_ref (datum, DECL_NAME (TYPE_VFIELD (type)), NULL_TREE, 0);
+ if (TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (type)
+ && !same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (datum), type))
+ datum = convert_to_base (datum, type, /*check_access=*/false);
- return rval;
+ return build (COMPONENT_REF, TREE_TYPE (TYPE_VFIELD (type)),
+ datum, TYPE_VFIELD (type));
}
/* Build a call to a member of an object. I.e., one that overloads
operator ()(), or is a pointer-to-function or pointer-to-method. */
static tree
-build_field_call (basetype_path, instance_ptr, name, parms)
- tree basetype_path, instance_ptr, name, parms;
+build_field_call (tree instance_ptr, tree decl, tree parms)
{
- tree field, instance;
-
- if (IDENTIFIER_CTOR_OR_DTOR_P (name))
- return NULL_TREE;
-
- /* Speed up the common case. */
- if (instance_ptr == current_class_ptr
- && IDENTIFIER_CLASS_VALUE (name) == NULL_TREE)
- return NULL_TREE;
-
- field = lookup_field (basetype_path, name, 1, 0);
+ tree instance;
- if (field == error_mark_node || field == NULL_TREE)
- return field;
+ if (decl == error_mark_node || decl == NULL_TREE)
+ return decl;
- if (TREE_CODE (field) == FIELD_DECL || TREE_CODE (field) == VAR_DECL)
+ if (TREE_CODE (decl) == FIELD_DECL || TREE_CODE (decl) == VAR_DECL)
{
/* If it's a field, try overloading operator (),
or calling if the field is a pointer-to-function. */
instance = build_indirect_ref (instance_ptr, NULL);
- instance = build_component_ref_1 (instance, field, 0);
+ instance = build_class_member_access_expr (instance, decl,
+ /*access_path=*/NULL_TREE,
+ /*preserve_reference=*/false);
if (instance == error_mark_node)
return error_mark_node;
@@ -298,27 +289,10 @@ build_scoped_method_call (exp, basetype, name, parms)
return error_mark_node;
}
- if (! binfo)
- {
- binfo = lookup_base (type, basetype, ba_check, NULL);
- if (binfo == error_mark_node)
- return error_mark_node;
- if (! binfo)
- error_not_base_type (basetype, type);
- }
+ decl = build_scoped_ref (exp, basetype, &binfo);
if (binfo)
{
- if (TREE_CODE (exp) == INDIRECT_REF)
- {
- decl = build_base_path (PLUS_EXPR,
- build_unary_op (ADDR_EXPR, exp, 0),
- binfo, 1);
- decl = build_indirect_ref (decl, NULL);
- }
- else
- decl = build_scoped_ref (exp, basetype);
-
/* Call to a destructor. */
if (TREE_CODE (name) == BIT_NOT_EXPR)
{
@@ -355,7 +329,7 @@ build_addr_func (function)
type = build_pointer_type (type);
- if (mark_addressable (function) == 0)
+ if (!cxx_mark_addressable (function))
return error_mark_node;
addr = build1 (ADDR_EXPR, type, function);
@@ -386,6 +360,7 @@ build_call (function, parms)
tree tmp;
tree decl;
tree result_type;
+ tree fntype;
function = build_addr_func (function);
@@ -395,7 +370,8 @@ build_call (function, parms)
return error_mark_node;
}
- result_type = TREE_TYPE (TREE_TYPE (TREE_TYPE (function)));
+ fntype = TREE_TYPE (TREE_TYPE (function));
+ result_type = TREE_TYPE (fntype);
if (TREE_CODE (function) == ADDR_EXPR
&& TREE_CODE (TREE_OPERAND (function, 0)) == FUNCTION_DECL)
@@ -408,11 +384,12 @@ build_call (function, parms)
nothrow = ((decl && TREE_NOTHROW (decl))
|| TYPE_NOTHROW_P (TREE_TYPE (TREE_TYPE (function))));
- if (decl && TREE_THIS_VOLATILE (decl))
+ if (decl && TREE_THIS_VOLATILE (decl) && cfun)
current_function_returns_abnormally = 1;
if (decl && TREE_DEPRECATED (decl))
warn_deprecated_use (decl);
+ require_complete_eh_spec_types (fntype, decl);
if (decl && DECL_CONSTRUCTOR_P (decl))
is_constructor = 1;
@@ -492,7 +469,10 @@ build_method_call (instance, name, parms, basetype_path, flags)
tree instance, name, parms, basetype_path;
int flags;
{
- tree basetype, instance_ptr;
+ tree fn;
+ tree object_type;
+ tree template_args = NULL_TREE;
+ bool has_template_args = false;
#ifdef GATHER_STATISTICS
n_build_method_call++;
@@ -501,7 +481,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
if (instance == error_mark_node
|| name == error_mark_node
|| parms == error_mark_node
- || (instance != NULL_TREE && TREE_TYPE (instance) == error_mark_node))
+ || (instance && TREE_TYPE (instance) == error_mark_node))
return error_mark_node;
if (processing_template_decl)
@@ -524,39 +504,111 @@ build_method_call (instance, name, parms, basetype_path, flags)
return build_min_nt (METHOD_CALL_EXPR, name, instance, parms, NULL_TREE);
}
+ if (TREE_CODE (instance) == OFFSET_REF)
+ instance = resolve_offset_ref (instance);
+ if (TREE_CODE (TREE_TYPE (instance)) == REFERENCE_TYPE)
+ instance = convert_from_reference (instance);
+ object_type = TREE_TYPE (instance);
+
if (TREE_CODE (name) == BIT_NOT_EXPR)
{
+ tree instance_ptr;
+
if (parms)
error ("destructors take no parameters");
- basetype = TREE_TYPE (instance);
- if (TREE_CODE (basetype) == REFERENCE_TYPE)
- basetype = TREE_TYPE (basetype);
- if (! check_dtor_name (basetype, name))
+ if (! check_dtor_name (object_type, name))
error
("destructor name `~%T' does not match type `%T' of expression",
- TREE_OPERAND (name, 0), basetype);
+ TREE_OPERAND (name, 0), object_type);
- if (! TYPE_HAS_DESTRUCTOR (complete_type (basetype)))
+ /* 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);
- return build_delete (build_pointer_type (basetype),
+ return build_delete (build_pointer_type (object_type),
instance_ptr, sfk_complete_destructor,
LOOKUP_NORMAL|LOOKUP_DESTRUCTOR, 0);
}
- return build_new_method_call (instance, name, parms, basetype_path, flags);
+ if (!CLASS_TYPE_P (object_type))
+ {
+ if ((flags & LOOKUP_COMPLAIN)
+ && TREE_TYPE (instance) != error_mark_node)
+ error ("request for member `%D' in `%E', which is of non-aggregate type `%T'",
+ name, instance, object_type);
+ return error_mark_node;
+ }
+
+ if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
+ {
+ template_args = TREE_OPERAND (name, 1);
+ has_template_args = true;
+ 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);
+ else if (DECL_P (name))
+ name = DECL_NAME (name);
+ if (has_template_args)
+ fn = lookup_fnfields (object_type, name, /*protect=*/2);
+ else
+ fn = lookup_member (object_type, name, /*protect=*/2, /*want_type=*/0);
+
+ if (fn && TREE_CODE (fn) == TREE_LIST && !BASELINK_P (fn))
+ {
+ error ("request for member `%D' is ambiguous", name);
+ print_candidates (fn);
+ return error_mark_node;
+ }
+
+ /* If the name could not be found, issue an error. */
+ if (!fn)
+ {
+ unqualified_name_lookup_error (name);
+ return error_mark_node;
+ }
+
+ if (BASELINK_P (fn) && has_template_args)
+ BASELINK_FUNCTIONS (fn)
+ = build_nt (TEMPLATE_ID_EXPR,
+ BASELINK_FUNCTIONS (fn),
+ template_args);
+ if (BASELINK_P (fn) && basetype_path)
+ BASELINK_ACCESS_BINFO (fn) = basetype_path;
+
+ return build_new_method_call (instance, fn, parms,
+ /*conversion_path=*/NULL_TREE, flags);
}
/* New overloading code. */
-struct z_candidate {
+struct z_candidate GTY(()) {
+ /* The FUNCTION_DECL that will be called if this candidate is
+ selected by overload resolution. */
tree fn;
tree convs;
tree second_conv;
int viable;
- tree basetype_path;
+ /* If FN is a member function, the binfo indicating the path used to
+ qualify the name of FN at the call site. This path is used to
+ determine whether or not FN is accessible if it is selected by
+ overload resolution. The DECL_CONTEXT of FN will always be a
+ (possibly improper) base of this binfo. */
+ tree access_path;
+ /* If FN is a non-static member function, the binfo indicating the
+ subobject to which the `this' pointer should be converted if FN
+ is selected by overload resolution. The type pointed to the by
+ the `this' pointer must correspond to the most derived class
+ indicated by the CONVERSION_PATH. */
+ tree conversion_path;
tree template;
tree warnings;
struct z_candidate *next;
@@ -588,8 +640,7 @@ struct z_candidate {
should be created to hold the result of the conversion. */
#define NEED_TEMPORARY_P(NODE) TREE_LANG_FLAG_4 (NODE)
-#define USER_CONV_CAND(NODE) \
- ((struct z_candidate *)WRAPPER_PTR (TREE_OPERAND (NODE, 1)))
+#define USER_CONV_CAND(NODE) WRAPPER_ZC (TREE_OPERAND (NODE, 1))
#define USER_CONV_FN(NODE) (USER_CONV_CAND (NODE)->fn)
int
@@ -607,8 +658,8 @@ null_ptr_cst_p (t)
}
-/* Returns non-zero if PARMLIST consists of only default parms and/or
- ellipsis. */
+/* Returns nonzero if PARMLIST consists of only default parms and/or
+ ellipsis. */
int
sufficient_parms_p (parmlist)
@@ -654,7 +705,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;
}
@@ -801,8 +852,7 @@ standard_conversion (to, from, expr)
(TREE_TYPE (TREE_TYPE (from)),
TREE_TYPE (TREE_TYPE (to)))))
{
- from = build_offset_type (tbase, TREE_TYPE (TREE_TYPE (from)));
- from = build_pointer_type (from);
+ from = build_ptrmem_type (tbase, TREE_TYPE (TREE_TYPE (from)));
conv = build_conv (PMEM_CONV, from, conv);
}
}
@@ -899,7 +949,7 @@ standard_conversion (to, from, expr)
return conv;
}
-/* Returns non-zero if T1 is reference-related to T2. */
+/* Returns nonzero if T1 is reference-related to T2. */
static int
reference_related_p (t1, t2)
@@ -919,7 +969,7 @@ reference_related_p (t1, t2)
&& DERIVED_FROM_P (t1, t2)));
}
-/* Returns non-zero if T1 is reference-compatible with T2. */
+/* Returns nonzero if T1 is reference-compatible with T2. */
static int
reference_compatible_p (t1, t2)
@@ -947,9 +997,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
@@ -975,10 +1030,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);
@@ -986,43 +1041,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),
- 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,
- LOOKUP_NORMAL);
-
- if (candidates != old_candidates)
- candidates->basetype_path = TYPE_BINFO (s);
+ 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
@@ -1035,16 +1105,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);
- TREE_OPERAND (conv, 1) = build_ptr_wrapper (cand);
- ICS_USER_FLAG (conv) = 1;
+ /* 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);
+
+ /* 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
@@ -1056,7 +1131,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]
@@ -1093,9 +1174,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);
@@ -1173,7 +1252,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
@@ -1207,11 +1286,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);
@@ -1251,7 +1332,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. */
@@ -1265,11 +1345,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
@@ -1282,6 +1357,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)
@@ -1299,18 +1376,20 @@ implicit_conversion (to, from, expr, flags)
functions. */
static struct z_candidate *
-add_candidate (candidates, fn, convs, viable)
- struct z_candidate *candidates;
- tree fn, convs;
- int viable;
+add_candidate (struct z_candidate **candidates,
+ tree fn, tree convs, tree access_path, tree
+ conversion_path, int viable)
{
struct z_candidate *cand
= (struct z_candidate *) ggc_alloc_cleared (sizeof (struct z_candidate));
cand->fn = fn;
cand->convs = convs;
+ cand->access_path = access_path;
+ cand->conversion_path = conversion_path;
cand->viable = viable;
- cand->next = candidates;
+ cand->next = *candidates;
+ *candidates = cand;
return cand;
}
@@ -1323,10 +1402,10 @@ add_candidate (candidates, fn, convs, viable)
comes from for purposes of overload resolution. */
static struct z_candidate *
-add_function_candidate (candidates, fn, ctype, arglist, flags)
- struct z_candidate *candidates;
- tree fn, ctype, arglist;
- int flags;
+add_function_candidate (struct z_candidate **candidates,
+ tree fn, tree ctype, tree arglist,
+ tree access_path, tree conversion_path,
+ int flags)
{
tree parmlist = TYPE_ARG_TYPES (TREE_TYPE (fn));
int i, len;
@@ -1334,6 +1413,11 @@ add_function_candidate (candidates, fn, ctype, arglist, flags)
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))
@@ -1438,7 +1522,8 @@ add_function_candidate (candidates, fn, ctype, arglist, flags)
}
out:
- return add_candidate (candidates, fn, convs, viable);
+ return add_candidate (candidates, fn, convs, access_path,
+ conversion_path, viable);
}
/* Create an overload candidate for the conversion function FN which will
@@ -1453,9 +1538,12 @@ add_function_candidate (candidates, fn, ctype, arglist, flags)
instead of the function. */
static struct z_candidate *
-add_conv_candidate (candidates, fn, obj, arglist)
- struct z_candidate *candidates;
+add_conv_candidate (candidates, fn, obj, arglist, access_path,
+ conversion_path)
+ struct z_candidate **candidates;
tree fn, obj, arglist;
+ tree access_path;
+ tree conversion_path;
{
tree totype = TREE_TYPE (TREE_TYPE (fn));
int i, len, viable, flags;
@@ -1473,8 +1561,8 @@ add_conv_candidate (candidates, fn, obj, arglist)
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)
{
@@ -1515,13 +1603,14 @@ add_conv_candidate (candidates, fn, obj, arglist)
if (!sufficient_parms_p (parmnode))
viable = 0;
- return add_candidate (candidates, totype, convs, viable);
+ return add_candidate (candidates, totype, convs, 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;
@@ -1564,7 +1653,10 @@ build_builtin_candidate (candidates, fnname, type1, type2,
viable = 0;
}
- return add_candidate (candidates, fnname, convs, viable);
+ add_candidate (candidates, fnname, convs,
+ /*access_path=*/NULL_TREE,
+ /*conversion_path=*/NULL_TREE,
+ viable);
}
static int
@@ -1574,7 +1666,7 @@ is_complete (t)
return COMPLETE_TYPE_P (complete_type (t));
}
-/* Returns non-zero if TYPE is a promoted arithmetic type. */
+/* Returns nonzero if TYPE is a promoted arithmetic type. */
static int
promoted_arithmetic_type_p (type)
@@ -1602,10 +1694,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;
@@ -1645,7 +1737,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))
@@ -1653,7 +1745,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
@@ -1669,7 +1761,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*);
@@ -1686,7 +1778,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
@@ -1695,7 +1787,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
@@ -1718,7 +1810,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
@@ -1774,7 +1866,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:
@@ -1816,7 +1908,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))
@@ -1832,7 +1924,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
@@ -1853,7 +1945,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
@@ -1905,7 +1997,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:
@@ -1915,7 +2007,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))
@@ -1930,7 +2022,7 @@ add_builtin_candidate (candidates, code, code2, fnname, type1, type2,
type2 = type1;
break;
}
- return candidates;
+ return;
default:
abort ();
@@ -1965,16 +2057,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 legal overloaded operator. */
- return candidates;
+ break;
default:
abort ();
@@ -1991,13 +2080,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);
}
@@ -2023,11 +2113,11 @@ type_decays_to (type)
Here we generate a superset of the possible candidates for this particular
case. That is a subset of the full set the standard defines, plus some
other cases which the standard disallows. add_builtin_candidate will
- filter out the illegal set. */
+ 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;
@@ -2070,20 +2160,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:
@@ -2110,7 +2202,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]);
@@ -2125,7 +2217,7 @@ add_builtin_candidates (candidates, code, code2, fnname, args, flags)
}
else if (! convs)
- return candidates;
+ return;
for (; convs; convs = TREE_CHAIN (convs))
{
@@ -2177,16 +2269,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;
}
@@ -2202,10 +2294,12 @@ add_builtin_candidates (candidates, code, code2, fnname, args, flags)
static struct z_candidate*
add_template_candidate_real (candidates, tmpl, ctype, explicit_targs,
- arglist, return_type, flags,
- obj, strict)
- struct z_candidate *candidates;
+ arglist, return_type, access_path,
+ conversion_path, flags, obj, strict)
+ struct z_candidate **candidates;
tree tmpl, ctype, explicit_targs, arglist, return_type;
+ tree access_path;
+ tree conversion_path;
int flags;
tree obj;
unification_kind_t strict;
@@ -2232,11 +2326,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]:
@@ -2265,15 +2359,17 @@ 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)
/* Aha, this is a conversion function. */
- cand = add_conv_candidate (candidates, fn, obj, arglist);
+ cand = add_conv_candidate (candidates, fn, obj, access_path,
+ conversion_path, arglist);
else
cand = add_function_candidate (candidates, fn, ctype,
- arglist, flags);
+ arglist, access_path,
+ conversion_path, flags);
if (DECL_TI_TEMPLATE (fn) != tmpl)
/* This situation can occur if a member template of a template
class is specialized. Then, instantiate_template might return
@@ -2302,27 +2398,35 @@ add_template_candidate_real (candidates, tmpl, ctype, explicit_targs,
static struct z_candidate *
add_template_candidate (candidates, tmpl, ctype, explicit_targs,
- arglist, return_type, flags, strict)
- struct z_candidate *candidates;
+ arglist, return_type, access_path,
+ conversion_path, flags, strict)
+ struct z_candidate **candidates;
tree tmpl, ctype, explicit_targs, arglist, return_type;
+ tree access_path;
+ tree conversion_path;
int flags;
unification_kind_t strict;
{
return
add_template_candidate_real (candidates, tmpl, ctype,
- explicit_targs, arglist, return_type, flags,
- NULL_TREE, strict);
+ explicit_targs, arglist, return_type,
+ access_path, conversion_path,
+ flags, NULL_TREE, strict);
}
static struct z_candidate *
-add_template_conv_candidate (candidates, tmpl, obj, arglist, return_type)
- struct z_candidate *candidates;
+add_template_conv_candidate (candidates, tmpl, obj, arglist, return_type,
+ access_path, conversion_path)
+ struct z_candidate **candidates;
tree tmpl, obj, arglist, return_type;
+ tree access_path;
+ tree conversion_path;
{
return
add_template_candidate_real (candidates, tmpl, NULL_TREE, NULL_TREE,
- arglist, return_type, 0, obj, DEDUCE_CONV);
+ arglist, return_type, access_path,
+ conversion_path, 0, obj, DEDUCE_CONV);
}
@@ -2336,6 +2440,16 @@ any_viable (cands)
return 0;
}
+static int
+any_strictly_viable (cands)
+ struct z_candidate *cands;
+{
+ for (; cands; cands = cands->next)
+ if (cands->viable == 1)
+ return 1;
+ return 0;
+}
+
static struct z_candidate *
splice_viable (cands)
struct z_candidate *cands;
@@ -2361,11 +2475,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)
@@ -2392,6 +2546,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].
@@ -2405,9 +2588,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
@@ -2430,7 +2612,7 @@ build_user_type_conversion_1 (totype, expr, flags)
{
tree t;
- ctors = TREE_VALUE (ctors);
+ ctors = BASELINK_FUNCTIONS (ctors);
t = build_int_2 (0, 0);
TREE_TYPE (t) = build_pointer_type (totype);
@@ -2449,22 +2631,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, 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, 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);
- candidates->basetype_path = TYPE_BINFO (totype);
- }
+ if (cand)
+ cand->second_conv = build1 (IDENTITY_CONV, totype, NULL_TREE);
}
if (convs)
@@ -2472,9 +2652,9 @@ build_user_type_conversion_1 (totype, expr, flags)
for (; convs; convs = TREE_CHAIN (convs))
{
- tree fns = TREE_VALUE (convs);
+ tree fns;
+ tree conversion_path = TREE_PURPOSE (convs);
int convflags = LOOKUP_NO_CONVERSION;
- tree ics;
/* If we are called to convert to a reference type, we are trying to
find an lvalue binding, so don't even consider temporaries. If
@@ -2482,73 +2662,50 @@ build_user_type_conversion_1 (totype, expr, flags)
look for a temporary binding. */
if (TREE_CODE (totype) == REFERENCE_TYPE)
convflags |= LOOKUP_NO_TEMP_BIND;
+
+ for (fns = TREE_VALUE (convs); fns; fns = OVL_NEXT (fns))
+ {
+ tree fn = OVL_CURRENT (fns);
+
+ /* [over.match.funcs] For conversion functions, the function
+ is considered to be a member of the class of the implicit
+ object argument for the purpose of defining the type of
+ the implicit object parameter.
- if (TREE_CODE (OVL_CURRENT (fns)) != TEMPLATE_DECL)
- ics = implicit_conversion
- (totype, TREE_TYPE (TREE_TYPE (OVL_CURRENT (fns))), 0, convflags);
- else
- /* We can't compute this yet. */
- ics = error_mark_node;
+ So we pass fromtype as CTYPE to add_*_candidate. */
- if (TREE_CODE (totype) == REFERENCE_TYPE && ics && ICS_BAD_FLAG (ics))
- /* ignore the near match. */;
- else if (ics)
- for (; 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 object
- argument for the purpose of defining the type of the implicit
- object parameter.
+ if (TREE_CODE (fn) == TEMPLATE_DECL)
+ cand = add_template_candidate (&candidates, fn, fromtype, NULL_TREE,
+ args, totype,
+ TYPE_BINFO (fromtype),
+ conversion_path,
+ flags,
+ DEDUCE_CONV);
+ else
+ cand = add_function_candidate (&candidates, fn, fromtype,
+ args,
+ TYPE_BINFO (fromtype),
+ conversion_path,
+ flags);
- So we pass fromtype as CTYPE to add_*_candidate. */
+ if (cand)
+ {
+ tree ics = implicit_conversion
+ (totype, TREE_TYPE (TREE_TYPE (cand->fn)),
+ 0, convflags);
- if (TREE_CODE (fn) == TEMPLATE_DECL)
- {
- templates = tree_cons (NULL_TREE, fn, templates);
- candidates =
- add_template_candidate (candidates, fn, fromtype, NULL_TREE,
- args, totype, flags,
- DEDUCE_CONV);
- }
- else
- candidates = add_function_candidate (candidates, fn, fromtype,
- args, flags);
-
- if (candidates != old_candidates)
- {
- if (TREE_CODE (fn) == TEMPLATE_DECL)
- ics = implicit_conversion
- (totype, TREE_TYPE (TREE_TYPE (candidates->fn)),
- 0, convflags);
-
- candidates->second_conv = ics;
- candidates->basetype_path = TYPE_BINFO (fromtype);
-
- if (ics == NULL_TREE)
- candidates->viable = 0;
- else if (candidates->viable == 1 && ICS_BAD_FLAG (ics))
- candidates->viable = -1;
- }
- }
+ cand->second_conv = ics;
+
+ if (ics == NULL_TREE)
+ cand->viable = 0;
+ else if (cand->viable == 1 && ICS_BAD_FLAG (ics))
+ cand->viable = -1;
+ }
+ }
}
if (! any_viable (candidates))
- {
-#if 0
- if (flags & LOOKUP_COMPLAIN)
- {
- if (candidates && ! candidates->next)
- /* say why this one won't work or try to be loose */;
- else
- error ("no viable candidates");
- }
-#endif
-
- return 0;
- }
+ return 0;
candidates = splice_viable (candidates);
cand = tourney (candidates);
@@ -2565,23 +2722,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;
- ICS_BAD_FLAG (cand->second_conv) = 1;
+ 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_ptr_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;
}
@@ -2603,6 +2766,78 @@ 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 (!CLASS_TYPE_P (scope))
+ {
+ error ("`%T' is not a class type", scope);
+ return error_mark_node;
+ }
+ 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
@@ -2628,6 +2863,9 @@ resolve_args (args)
}
return args;
}
+
+/* Return an expression for a call to FN (a namespace-scope function)
+ with the ARGS. */
tree
build_new_function_call (fn, args)
@@ -2637,6 +2875,15 @@ build_new_function_call (fn, args)
tree explicit_targs = NULL_TREE;
int template_only = 0;
+ /* Check FN and ARGS. */
+ my_friendly_assert (TREE_CODE (fn) == FUNCTION_DECL
+ || TREE_CODE (fn) == TEMPLATE_DECL
+ || TREE_CODE (fn) == OVERLOAD
+ || TREE_CODE (fn) == TEMPLATE_ID_EXPR,
+ 20020712);
+ my_friendly_assert (!args || TREE_CODE (args) == TREE_LIST,
+ 20020712);
+
if (TREE_CODE (fn) == TEMPLATE_ID_EXPR)
{
explicit_targs = TREE_OPERAND (fn, 1);
@@ -2644,30 +2891,30 @@ build_new_function_call (fn, args)
template_only = 1;
}
- if (really_overloaded_fn (fn))
+ if (really_overloaded_fn (fn)
+ || TREE_CODE (fn) == TEMPLATE_DECL)
{
tree t1;
- tree templates = NULL_TREE;
args = resolve_args (args);
if (args == error_mark_node)
return error_mark_node;
- for (t1 = fn; t1; t1 = OVL_CHAIN (t1))
+ for (t1 = fn; t1; t1 = OVL_NEXT (t1))
{
- tree t = OVL_FUNCTION (t1);
+ 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,
- 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, LOOKUP_NORMAL);
+ add_function_candidate
+ (&candidates, t, NULL_TREE, args, /*access_path=*/NULL_TREE,
+ /*conversion_path=*/NULL_TREE, LOOKUP_NORMAL);
}
if (! any_viable (candidates))
@@ -2675,7 +2922,7 @@ build_new_function_call (fn, args)
if (candidates && ! candidates->next)
return build_function_call (candidates->fn, args);
error ("no matching function for call to `%D(%A)'",
- DECL_NAME (OVL_FUNCTION (fn)), args);
+ DECL_NAME (OVL_CURRENT (fn)), args);
if (candidates)
print_z_candidates (candidates);
return error_mark_node;
@@ -2694,7 +2941,7 @@ build_new_function_call (fn, args)
return build_over_call (cand, args, LOOKUP_NORMAL);
}
- /* This is not really overloaded. */
+ /* This is not really overloaded. */
fn = OVL_CURRENT (fn);
return build_function_call (fn, args);
@@ -2727,25 +2974,22 @@ build_object_call (obj, args)
if (fns)
{
- tree base = BINFO_TYPE (TREE_PURPOSE (fns));
+ tree base = BINFO_TYPE (BASELINK_BINFO (fns));
mem_args = tree_cons (NULL_TREE, build_this (obj), args);
- for (fns = TREE_VALUE (fns); fns; fns = OVL_NEXT (fns))
+ for (fns = BASELINK_FUNCTIONS (fns); fns; fns = OVL_NEXT (fns))
{
tree fn = OVL_CURRENT (fns);
if (TREE_CODE (fn) == TEMPLATE_DECL)
- {
- candidates
- = add_template_candidate (candidates, fn, base, NULL_TREE,
- mem_args, NULL_TREE,
- 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, LOOKUP_NORMAL);
-
- if (candidates)
- candidates->basetype_path = TYPE_BINFO (type);
+ add_function_candidate
+ (&candidates, fn, base, mem_args, TYPE_BINFO (type),
+ TYPE_BINFO (type), LOOKUP_NORMAL);
}
}
@@ -2767,15 +3011,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);
- }
+ 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);
+ add_conv_candidate (&candidates, fn, obj, args,
+ /*conversion_path=*/NULL_TREE,
+ /*access_path=*/NULL_TREE);
}
}
@@ -2826,23 +3069,27 @@ op_error (code, code2, arg1, arg2, arg3, problem)
switch (code)
{
case COND_EXPR:
- error ("%s for `%T ? %T : %T' operator", problem,
- error_type (arg1), error_type (arg2), error_type (arg3));
+ error ("%s for ternary 'operator?:' in '%E ? %E : %E'",
+ problem, arg1, arg2, arg3);
break;
+
case POSTINCREMENT_EXPR:
case POSTDECREMENT_EXPR:
- error ("%s for `%T %s' operator", problem, error_type (arg1), opname);
+ error ("%s for 'operator%s' in '%E%s'", problem, opname, arg1, opname);
break;
+
case ARRAY_REF:
- error ("%s for `%T [%T]' operator", problem,
- error_type (arg1), error_type (arg2));
+ error ("%s for 'operator[]' in '%E[%E]'", problem, arg1, arg2);
break;
+
default:
if (arg2)
- error ("%s for `%T %s %T' operator", problem,
- error_type (arg1), opname, error_type (arg2));
+ error ("%s for 'operator%s' in '%E %s %E'",
+ problem, opname, arg1, opname, arg2);
else
- error ("%s for `%s %T' operator", problem, opname, error_type (arg1));
+ error ("%s for 'operator%s' in '%s%E'",
+ problem, opname, opname, arg1);
+ break;
}
}
@@ -2857,6 +3104,7 @@ conditional_conversion (e1, e2)
tree t1 = non_reference (TREE_TYPE (e1));
tree t2 = non_reference (TREE_TYPE (e2));
tree conv;
+ bool good_base;
/* [expr.cond]
@@ -2885,10 +3133,9 @@ conditional_conversion (e1, e2)
changed to an rvalue of type T2 that still refers to the original
source class object (or the appropriate subobject thereof). */
if (CLASS_TYPE_P (t1) && CLASS_TYPE_P (t2)
- && same_or_base_type_p (TYPE_MAIN_VARIANT (t2),
- TYPE_MAIN_VARIANT (t1)))
+ && ((good_base = DERIVED_FROM_P (t2, t1)) || DERIVED_FROM_P (t1, t2)))
{
- if (at_least_as_qualified_p (t2, t1))
+ if (good_base && at_least_as_qualified_p (t2, t1))
{
conv = build1 (IDENTITY_CONV, t1, e1);
if (!same_type_p (TYPE_MAIN_VARIANT (t1),
@@ -2899,19 +3146,17 @@ conditional_conversion (e1, e2)
else
return NULL_TREE;
}
+ else
+ /* [expr.cond]
- /* [expr.cond]
-
- E1 can be converted to match E2 if E1 can be implicitly converted
- to the type that expression E2 would have if E2 were converted to
- an rvalue (or the type it has, if E2 is an rvalue). */
- return implicit_conversion (t2, t1, e1, LOOKUP_NORMAL);
+ Otherwise: E1 can be converted to match E2 if E1 can be implicitly
+ converted to the type that expression E2 would have if E2 were
+ converted to an rvalue (or the type it has, if E2 is an rvalue). */
+ return implicit_conversion (t2, t1, e1, LOOKUP_NORMAL);
}
/* Implement [expr.cond]. ARG1, ARG2, and ARG3 are the three
- arguments to the conditional expression. By the time this function
- is called, any suitable candidate functions are included in
- CANDIDATES. */
+ arguments to the conditional expression. */
tree
build_conditional_expr (arg1, arg2, arg3)
@@ -2984,7 +3229,7 @@ build_conditional_expr (arg1, arg2, arg3)
type of the other and is an rvalue.
--Both the second and the third operands have type void; the
- result is of type void and is an rvalue. */
+ result is of type void and is an rvalue. */
if ((TREE_CODE (arg2) == THROW_EXPR)
^ (TREE_CODE (arg3) == THROW_EXPR))
result_type = ((TREE_CODE (arg2) == THROW_EXPR)
@@ -3085,12 +3330,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]
@@ -3138,18 +3383,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)
@@ -3206,7 +3443,7 @@ build_conditional_expr (arg1, arg2, arg3)
qualification conversions (_conv.qual_) are performed to bring
them to a common type, whose cv-qualification shall match the
cv-qualification of either the second or the third operand.
- The result is of the common type. */
+ The result is of the common type. */
else if ((null_ptr_cst_p (arg2)
&& (TYPE_PTR_P (arg3_type) || TYPE_PTRMEM_P (arg3_type)
|| TYPE_PTRMEMFUNC_P (arg3_type)))
@@ -3255,8 +3492,8 @@ 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;
if (arg1 == error_mark_node
|| arg2 == error_mark_node
@@ -3283,6 +3520,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)
{
@@ -3290,7 +3531,7 @@ build_new_op (code, flags, arg1, arg2, arg3)
case VEC_NEW_EXPR:
case VEC_DELETE_EXPR:
case DELETE_EXPR:
- /* Use build_op_new_call and build_op_delete_call instead. */
+ /* Use build_op_new_call and build_op_delete_call instead. */
abort ();
case CALL_EXPR:
@@ -3305,12 +3546,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)
@@ -3344,16 +3591,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),
- 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, 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)))
@@ -3367,12 +3615,14 @@ build_new_op (code, flags, arg1, arg2, arg3)
if (fns)
{
- tree basetype = BINFO_TYPE (TREE_PURPOSE (fns));
+ tree conversion_path = BASELINK_BINFO (fns);
+
mem_arglist = tree_cons (NULL_TREE, build_this (arg1), TREE_CHAIN (arglist));
- for (fns = TREE_VALUE (fns); fns; fns = OVL_NEXT (fns))
+ for (fns = BASELINK_FUNCTIONS (fns); fns; fns = OVL_NEXT (fns))
{
tree fn = OVL_CURRENT (fns);
tree this_arglist;
+ tree access_path = TYPE_BINFO (TREE_TYPE (arg1));
if (TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE)
this_arglist = mem_arglist;
@@ -3380,20 +3630,17 @@ 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, basetype, NULL_TREE,
- this_arglist, TREE_TYPE (fnname),
- 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, basetype, this_arglist, flags);
-
- if (candidates)
- candidates->basetype_path = TYPE_BINFO (TREE_TYPE (arg1));
+ add_function_candidate
+ (&candidates, fn, BINFO_TYPE (conversion_path), this_arglist,
+ access_path, conversion_path, flags);
}
}
@@ -3417,11 +3664,28 @@ 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);
}
- if (! any_viable (candidates))
+ switch (code)
+ {
+ case COMPOUND_EXPR:
+ case ADDR_EXPR:
+ /* For these, the built-in candidates set is empty
+ [over.match.oper]/3. We don't want non-strict matches
+ because exact matches are always possible with built-in
+ operators. The built-in candidate set for COMPONENT_REF
+ would be empty too, but since there are no such built-in
+ operators, we accept non-strict matches for them. */
+ viable_candidates = any_strictly_viable (candidates);
+ break;
+
+ default:
+ viable_candidates = any_viable (candidates);
+ break;
+ }
+
+ if (! viable_candidates)
{
switch (code)
{
@@ -3656,10 +3920,10 @@ build_op_delete_call (code, addr, size, flags, placement)
tree alloc_fn;
tree call_expr;
- /* Find the allocation function that is being called. */
+ /* Find the allocation function that is being called. */
call_expr = placement;
/* Sometimes we have a COMPOUND_EXPR, rather than a simple
- CALL_EXPR. */
+ CALL_EXPR. */
while (TREE_CODE (call_expr) == COMPOUND_EXPR)
call_expr = TREE_OPERAND (call_expr, 1);
/* Extract the function. */
@@ -3698,7 +3962,7 @@ build_op_delete_call (code, addr, size, flags, placement)
/* Go through the `operator delete' functions looking for one
with a matching type. */
- for (fn = BASELINK_P (fns) ? TREE_VALUE (fns) : fns;
+ for (fn = BASELINK_P (fns) ? BASELINK_FUNCTIONS (fns) : fns;
fn;
fn = OVL_NEXT (fn))
{
@@ -3776,18 +4040,17 @@ enforce_access (basetype_path, decl)
return 1;
}
-/* Perform the conversions in CONVS on the expression EXPR.
- FN and ARGNUM are used for diagnostics. ARGNUM is zero based, -1
- indicates the `this' argument of a method. INNER is non-zero when
+/* Perform the conversions in CONVS on the expression EXPR. FN and
+ ARGNUM are used for diagnostics. ARGNUM is zero based, -1
+ indicates the `this' argument of a method. INNER is nonzero when
being called to continue a conversion chain. It is negative when a
- reference binding will be applied, positive otherwise. */
+ reference binding will be applied, positive otherwise. If
+ ISSUE_CONVERSION_WARNINGS is true, warnings about suspicious
+ conversions will be emitted if appropriate. */
static tree
-convert_like_real (convs, expr, fn, argnum, inner)
- tree convs, expr;
- tree fn;
- int argnum;
- int inner;
+convert_like_real (tree convs, tree expr, tree fn, int argnum, int inner,
+ bool issue_conversion_warnings)
{
int savew, savee;
@@ -3803,11 +4066,13 @@ convert_like_real (convs, expr, fn, argnum, inner)
{
if (TREE_CODE (t) == USER_CONV || !ICS_BAD_FLAG (t))
{
- expr = convert_like_real (t, expr, fn, argnum, 1);
+ expr = convert_like_real (t, expr, fn, argnum, 1,
+ /*issue_conversion_warnings=*/false);
break;
}
else if (TREE_CODE (t) == AMBIG_CONV)
- return convert_like_real (t, expr, fn, argnum, 1);
+ return convert_like_real (t, expr, fn, argnum, 1,
+ /*issue_conversion_warnings=*/false);
else if (TREE_CODE (t) == IDENTITY_CONV)
break;
}
@@ -3817,15 +4082,14 @@ convert_like_real (convs, expr, fn, argnum, inner)
return cp_convert (totype, expr);
}
- if (!inner)
+ if (issue_conversion_warnings)
expr = dubious_conversion_warnings
(totype, expr, "argument", fn, argnum);
switch (TREE_CODE (convs))
{
case USER_CONV:
{
- struct z_candidate *cand
- = WRAPPER_PTR (TREE_OPERAND (convs, 1));
+ struct z_candidate *cand = USER_CONV_CAND (convs);
tree convfn = cand->fn;
tree args;
@@ -3863,7 +4127,7 @@ convert_like_real (convs, expr, fn, argnum, inner)
&& (inner >= 0 || !lvalue_p (expr)))
{
savew = warningcount, savee = errorcount;
- expr = build_new_method_call
+ expr = build_special_member_call
(NULL_TREE, complete_ctor_identifier,
build_tree_list (NULL_TREE, expr), TYPE_BINFO (totype),
/* Core issue 84, now a DR, says that we don't allow UDCs
@@ -3910,7 +4174,8 @@ convert_like_real (convs, expr, fn, argnum, inner)
};
expr = convert_like_real (TREE_OPERAND (convs, 0), expr, fn, argnum,
- TREE_CODE (convs) == REF_BIND ? -1 : 1);
+ TREE_CODE (convs) == REF_BIND ? -1 : 1,
+ /*issue_conversion_warnings=*/false);
if (expr == error_mark_node)
return error_mark_node;
@@ -3945,10 +4210,10 @@ convert_like_real (convs, expr, fn, argnum, inner)
type is the same class as, or a derived class of, the class of the
destination [is treated as direct-initialization]. [dcl.init] */
savew = warningcount, savee = errorcount;
- expr = build_new_method_call (NULL_TREE, complete_ctor_identifier,
- build_tree_list (NULL_TREE, expr),
- TYPE_BINFO (totype),
- LOOKUP_NORMAL|LOOKUP_ONLYCONVERTING);
+ expr = build_special_member_call (NULL_TREE, complete_ctor_identifier,
+ build_tree_list (NULL_TREE, expr),
+ TYPE_BINFO (totype),
+ LOOKUP_NORMAL|LOOKUP_ONLYCONVERTING);
if (fn)
{
if (warningcount > savew)
@@ -3963,7 +4228,7 @@ convert_like_real (convs, expr, fn, argnum, inner)
tree ref_type = totype;
/* If necessary, create a temporary. */
- if (NEED_TEMPORARY_P (convs) || !lvalue_p (expr))
+ if (NEED_TEMPORARY_P (convs) || !non_cast_lvalue_p (expr))
{
tree type = TREE_TYPE (TREE_OPERAND (convs, 0));
expr = build_target_expr_with_type (expr, type);
@@ -3981,9 +4246,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:
@@ -4001,6 +4264,22 @@ convert_like_real (convs, expr, fn, argnum, inner)
LOOKUP_NORMAL|LOOKUP_NO_CONVERSION);
}
+/* Build a call to __builtin_trap which can be used in an expression. */
+
+static tree
+call_builtin_trap ()
+{
+ tree fn = get_identifier ("__builtin_trap");
+ if (IDENTIFIER_GLOBAL_VALUE (fn))
+ fn = IDENTIFIER_GLOBAL_VALUE (fn);
+ else
+ abort ();
+
+ fn = build_call (fn, NULL_TREE);
+ fn = build (COMPOUND_EXPR, integer_type_node, fn, integer_zero_node);
+ return fn;
+}
+
/* ARG is being passed to a varargs function. Perform any conversions
required. Array/function to pointer decay must have already happened.
Return the converted value. */
@@ -4022,12 +4301,13 @@ convert_arg_to_ellipsis (arg)
if (arg != error_mark_node && ! pod_type_p (TREE_TYPE (arg)))
{
- /* Undefined behaviour [expr.call] 5.2.2/7. We used to just warn
+ /* Undefined behavior [expr.call] 5.2.2/7. We used to just warn
here and do a bitwise copy, but now cp_expr_size will abort if we
try to do that. */
- error ("cannot pass objects of non-POD type `%#T' through `...'",
- TREE_TYPE (arg));
- arg = error_mark_node;
+ warning ("cannot pass objects of non-POD type `%#T' through `...'; \
+call will abort at runtime",
+ TREE_TYPE (arg));
+ arg = call_builtin_trap ();
}
return arg;
@@ -4050,7 +4330,7 @@ build_x_va_arg (expr, type)
if (! pod_type_p (type))
{
- /* Undefined behaviour [expr.call] 5.2.2/7. */
+ /* Undefined behavior [expr.call] 5.2.2/7. */
warning ("cannot receive objects of non-POD type `%#T' through `...'",
type);
}
@@ -4058,24 +4338,27 @@ build_x_va_arg (expr, type)
return build_va_arg (expr, type);
}
-/* TYPE has been given to va_arg. Apply the default conversions which would
- have happened when passed via ellipsis. Return the promoted type, or
- NULL_TREE, if there is no change. */
+/* TYPE has been given to va_arg. Apply the default conversions which
+ would have happened when passed via ellipsis. Return the promoted
+ type, or the passed type if there is no change. */
tree
-convert_type_from_ellipsis (type)
+cxx_type_promotes_to (type)
tree type;
{
tree promote;
-
+
if (TREE_CODE (type) == ARRAY_TYPE)
- promote = build_pointer_type (TREE_TYPE (type));
- else if (TREE_CODE (type) == FUNCTION_TYPE)
- promote = build_pointer_type (type);
- else
- promote = type_promotes_to (type);
+ return build_pointer_type (TREE_TYPE (type));
+
+ if (TREE_CODE (type) == FUNCTION_TYPE)
+ return build_pointer_type (type);
+
+ promote = type_promotes_to (type);
+ if (same_type_p (type, promote))
+ promote = type;
- return same_type_p (type, promote) ? NULL_TREE : promote;
+ return promote;
}
/* ARG is a default argument expression being passed to a parameter of
@@ -4128,15 +4411,48 @@ convert_default_arg (type, arg, fn, parmnum)
arg = convert_for_initialization (0, type, arg, LOOKUP_NORMAL,
"default argument", fn, parmnum);
- if (PROMOTE_PROTOTYPES
- && INTEGRAL_TYPE_P (type)
- && (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)))
- arg = default_conversion (arg);
+ arg = convert_for_arg_passing (type, arg);
}
return arg;
}
+/* Returns the type which will really be used for passing an argument of
+ type TYPE. */
+
+tree
+type_passed_as (type)
+ tree type;
+{
+ /* Pass classes with copy ctors by invisible reference. */
+ if (TREE_ADDRESSABLE (type))
+ type = build_reference_type (type);
+ else if (PROMOTE_PROTOTYPES
+ && INTEGRAL_TYPE_P (type)
+ && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))
+ type = integer_type_node;
+
+ return type;
+}
+
+/* Actually perform the appropriate conversion. */
+
+tree
+convert_for_arg_passing (type, val)
+ tree type, val;
+{
+ if (val == error_mark_node)
+ ;
+ /* Pass classes with copy ctors by invisible reference. */
+ else if (TREE_ADDRESSABLE (type))
+ val = build1 (ADDR_EXPR, build_reference_type (type), val);
+ else if (PROMOTE_PROTOTYPES
+ && INTEGRAL_TYPE_P (type)
+ && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))
+ val = default_conversion (val);
+ return val;
+}
+
/* Subroutine of the various build_*_call functions. Overload resolution
has chosen a winning candidate CAND; build up a CALL_EXPR accordingly.
ARGS is a TREE_LIST of the unconverted arguments to the call. FLAGS is a
@@ -4159,10 +4475,10 @@ build_over_call (cand, args, flags)
/* Give any warnings we noticed during overload resolution. */
if (cand->warnings)
for (val = cand->warnings; val; val = TREE_CHAIN (val))
- joust (cand, WRAPPER_PTR (TREE_VALUE (val)), 1);
+ joust (cand, WRAPPER_ZC (TREE_VALUE (val)), 1);
if (DECL_FUNCTION_MEMBER_P (fn))
- enforce_access (cand->basetype_path, fn);
+ enforce_access (cand->access_path, fn);
if (args && TREE_CODE (args) != TREE_LIST)
args = build_tree_list (NULL_TREE, args);
@@ -4191,7 +4507,9 @@ build_over_call (cand, args, flags)
{
tree parmtype = TREE_VALUE (parm);
tree argtype = TREE_TYPE (TREE_VALUE (arg));
- tree t;
+ tree converted_arg;
+ tree base_binfo;
+
if (ICS_BAD_FLAG (TREE_VEC_ELT (convs, i)))
pedwarn ("passing `%T' as `this' argument of `%#D' discards qualifiers",
TREE_TYPE (argtype), fn);
@@ -4203,10 +4521,22 @@ build_over_call (cand, args, flags)
So we can assume that anything passed as 'this' is non-null, and
optimize accordingly. */
my_friendly_assert (TREE_CODE (parmtype) == POINTER_TYPE, 19990811);
- t = lookup_base (TREE_TYPE (TREE_TYPE (TREE_VALUE (arg))),
- TREE_TYPE (parmtype), ba_ignore, NULL);
- t = build_base_path (PLUS_EXPR, TREE_VALUE (arg), t, 1);
- converted_args = tree_cons (NULL_TREE, t, converted_args);
+ /* Convert to the base in which the function was declared. */
+ my_friendly_assert (cand->conversion_path != NULL_TREE, 20020730);
+ converted_arg = build_base_path (PLUS_EXPR,
+ TREE_VALUE (arg),
+ cand->conversion_path,
+ 1);
+ /* If fn was found by a using declaration, the conversion path
+ will be to the derived class, not the base declaring fn. We
+ must convert from derived to base. */
+ base_binfo = lookup_base (TREE_TYPE (TREE_TYPE (converted_arg)),
+ TREE_TYPE (parmtype), ba_ignore, NULL);
+
+ converted_arg = build_base_path (PLUS_EXPR, converted_arg,
+ base_binfo, 1);
+
+ converted_args = tree_cons (NULL_TREE, converted_arg, converted_args);
parm = TREE_CHAIN (parm);
arg = TREE_CHAIN (arg);
++i;
@@ -4222,10 +4552,7 @@ build_over_call (cand, args, flags)
val = convert_like_with_context
(conv, TREE_VALUE (arg), fn, i - is_method);
- if (PROMOTE_PROTOTYPES
- && INTEGRAL_TYPE_P (type)
- && (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)))
- val = default_conversion (val);
+ val = convert_for_arg_passing (type, val);
converted_args = tree_cons (NULL_TREE, val, converted_args);
}
@@ -4296,20 +4623,13 @@ build_over_call (cand, args, flags)
temp or an INIT_EXPR otherwise. */
if (integer_zerop (TREE_VALUE (args)))
{
- if (! real_lvalue_p (arg))
+ if (TREE_CODE (arg) == TARGET_EXPR)
return arg;
else if (TYPE_HAS_TRIVIAL_INIT_REF (DECL_CONTEXT (fn)))
return build_target_expr_with_type (arg, DECL_CONTEXT (fn));
}
- else if ((!real_lvalue_p (arg)
- || TYPE_HAS_TRIVIAL_INIT_REF (DECL_CONTEXT (fn)))
- /* Empty classes have padding which can be hidden
- inside an (empty) base of the class. This must not
- be touched as it might overlay things. When the
- gcc core learns about empty classes, we can treat it
- like other classes. */
- && !(is_empty_class (DECL_CONTEXT (fn))
- && TYPE_HAS_TRIVIAL_INIT_REF (DECL_CONTEXT (fn))))
+ else if (TREE_CODE (arg) == TARGET_EXPR
+ || TYPE_HAS_TRIVIAL_INIT_REF (DECL_CONTEXT (fn)))
{
tree address;
tree to = stabilize_reference
@@ -4331,24 +4651,7 @@ build_over_call (cand, args, flags)
(build_indirect_ref (TREE_VALUE (converted_args), 0));
arg = build_indirect_ref (TREE_VALUE (TREE_CHAIN (converted_args)), 0);
- if (is_empty_class (TREE_TYPE (to)))
- {
- TREE_USED (arg) = 1;
-
- val = build (COMPOUND_EXPR, DECL_CONTEXT (fn), arg, to);
- /* Even though the assignment may not actually result in any
- code being generated, we do not want to warn about the
- assignment having no effect. That would be confusing to
- users who may be performing the assignment as part of a
- generic algorithm, for example.
-
- Ideally, the notions of having side-effects and of being
- useless would be orthogonal. */
- TREE_SIDE_EFFECTS (val) = 1;
- TREE_NO_UNUSED_WARNING (val) = 1;
- }
- else
- val = build (MODIFY_EXPR, TREE_TYPE (to), to, arg);
+ val = build (MODIFY_EXPR, TREE_TYPE (to), to, arg);
return val;
}
@@ -4358,7 +4661,7 @@ build_over_call (cand, args, flags)
{
tree t, *p = &TREE_VALUE (converted_args);
tree binfo = lookup_base (TREE_TYPE (TREE_TYPE (*p)),
- DECL_VIRTUAL_CONTEXT (fn),
+ DECL_CONTEXT (fn),
ba_any, NULL);
my_friendly_assert (binfo && binfo != error_mark_node, 20010730);
@@ -4377,10 +4680,22 @@ build_over_call (cand, args, flags)
else
fn = build_addr_func (fn);
+ return build_cxx_call (fn, args, converted_args);
+}
+
+/* Build and return a call to FN, using the the CONVERTED_ARGS. ARGS
+ gives the original form of the arguments. This function performs
+ no overload resolution, conversion, or other high-level
+ operations. */
+
+tree
+build_cxx_call(tree fn, tree args, tree converted_args)
+{
+ tree fndecl;
+
/* Recognize certain built-in functions so we can make tree-codes
other than CALL_EXPR. We do this when it enables fold-const.c
to do something useful. */
-
if (TREE_CODE (fn) == ADDR_EXPR
&& TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL
&& DECL_BUILT_IN (TREE_OPERAND (fn, 0)))
@@ -4391,20 +4706,32 @@ build_over_call (cand, args, flags)
return exp;
}
- /* Some built-in function calls will be evaluated at
- compile-time in fold (). */
- fn = fold (build_call (fn, converted_args));
+ fn = build_call (fn, converted_args);
+
+ /* If this call might throw an exception, note that fact. */
+ fndecl = get_callee_fndecl (fn);
+ if ((!fndecl || !TREE_NOTHROW (fndecl))
+ && at_function_scope_p ()
+ && cfun)
+ cp_function_chain->can_throw = 1;
+
+ /* Some built-in function calls will be evaluated at compile-time in
+ fold (). */
+ fn = fold (fn);
+
if (VOID_TYPE_P (TREE_TYPE (fn)))
return fn;
+
fn = require_complete_type (fn);
if (fn == error_mark_node)
return error_mark_node;
+
if (IS_AGGR_TYPE (TREE_TYPE (fn)))
fn = build_cplus_new (TREE_TYPE (fn), fn);
return convert_from_reference (fn);
}
-static tree java_iface_lookup_fn;
+static GTY(()) tree java_iface_lookup_fn;
/* Make an expression which yields the address of the Java interface
method FN. This is achieved by generating a call to libjava's
@@ -4428,16 +4755,15 @@ build_java_interface_fn_ref (fn, instance)
java_iface_lookup_fn
= builtin_function ("_Jv_LookupInterfaceMethodIdx",
build_function_type (ptr_type_node, t),
- 0, NOT_BUILT_IN, NULL);
- ggc_add_tree_root (&java_iface_lookup_fn, 1);
+ 0, NOT_BUILT_IN, NULL, NULL_TREE);
}
/* Look up the pointer to the runtime java.lang.Class object for `instance'.
- This is the first entry in the vtable. */
+ This is the first entry in the vtable. */
klass_ref = build_vtbl_ref (build_indirect_ref (instance, 0),
integer_zero_node);
- /* Get the java.lang.Class pointer for the interface being called. */
+ /* Get the java.lang.Class pointer for the interface being called. */
iface = DECL_CONTEXT (fn);
iface_ref = lookup_field (iface, get_identifier ("class$"), 0, 0);
if (!iface_ref || TREE_CODE (iface_ref) != VAR_DECL
@@ -4449,7 +4775,7 @@ build_java_interface_fn_ref (fn, instance)
}
iface_ref = build1 (ADDR_EXPR, build_pointer_type (iface), iface_ref);
- /* Determine the itable index of FN. */
+ /* Determine the itable index of FN. */
i = 1;
for (method = TYPE_METHODS (iface); method; method = TREE_CHAIN (method))
{
@@ -4493,143 +4819,190 @@ in_charge_arg_for_name (name)
return NULL_TREE;
}
-static tree
-build_new_method_call (instance, name, args, basetype_path, flags)
- tree instance, name, args, basetype_path;
- int flags;
+/* Build a call to a constructor, destructor, or an assignment
+ operator for INSTANCE, an expression with class type. NAME
+ indicates the special member function to call; ARGS are the
+ arguments. BINFO indicates the base of INSTANCE that is to be
+ passed as the `this' parameter to the member function called.
+
+ FLAGS are the LOOKUP_* flags to use when processing the call.
+
+ If NAME indicates a complete object constructor, INSTANCE may be
+ NULL_TREE. In this case, the caller will call build_cplus_new to
+ store the newly constructed object into a VAR_DECL. */
+
+tree
+build_special_member_call (tree instance, tree name, tree args,
+ tree binfo, int flags)
+{
+ tree fns;
+ /* The type of the subobject to be constructed or destroyed. */
+ tree class_type;
+
+ my_friendly_assert (name == complete_ctor_identifier
+ || name == base_ctor_identifier
+ || name == complete_dtor_identifier
+ || name == base_dtor_identifier
+ || name == deleting_dtor_identifier
+ || name == ansi_assopname (NOP_EXPR),
+ 20020712);
+ my_friendly_assert (binfo != NULL_TREE, 20020712);
+
+ class_type = BINFO_TYPE (binfo);
+
+ /* Handle the special case where INSTANCE is NULL_TREE. */
+ if (name == complete_ctor_identifier && !instance)
+ {
+ instance = build_int_2 (0, 0);
+ TREE_TYPE (instance) = build_pointer_type (class_type);
+ instance = build1 (INDIRECT_REF, class_type, instance);
+ }
+ else if (name == complete_dtor_identifier
+ || name == base_dtor_identifier
+ || name == deleting_dtor_identifier)
+ my_friendly_assert (args == NULL_TREE, 20020712);
+
+ my_friendly_assert (instance != NULL_TREE, 20020712);
+
+ /* Resolve the name. */
+ if (!complete_type_or_else (BINFO_TYPE (binfo), NULL_TREE))
+ return error_mark_node;
+
+ fns = lookup_fnfields (binfo, name, 1);
+
+ /* When making a call to a constructor or destructor for a subobject
+ that uses virtual base classes, pass down a pointer to a VTT for
+ the subobject. */
+ if ((name == base_ctor_identifier
+ || name == base_dtor_identifier)
+ && TYPE_USES_VIRTUAL_BASECLASSES (class_type))
+ {
+ tree vtt;
+ tree sub_vtt;
+
+ /* If the current function is a complete object constructor
+ or destructor, then we fetch the VTT directly.
+ Otherwise, we look it up using the VTT we were given. */
+ vtt = TREE_CHAIN (CLASSTYPE_VTABLES (current_class_type));
+ vtt = decay_conversion (vtt);
+ vtt = build (COND_EXPR, TREE_TYPE (vtt),
+ build (EQ_EXPR, boolean_type_node,
+ current_in_charge_parm, integer_zero_node),
+ current_vtt_parm,
+ vtt);
+ if (TREE_VIA_VIRTUAL (binfo))
+ binfo = binfo_for_vbase (class_type, current_class_type);
+ my_friendly_assert (BINFO_SUBVTT_INDEX (binfo), 20010110);
+ sub_vtt = build (PLUS_EXPR, TREE_TYPE (vtt), vtt,
+ BINFO_SUBVTT_INDEX (binfo));
+
+ args = tree_cons (NULL_TREE, sub_vtt, args);
+ }
+
+ return build_new_method_call (instance, fns, args, binfo, flags);
+}
+
+/* Build a call to "INSTANCE.FN (ARGS)". */
+
+tree
+build_new_method_call (tree instance, tree fns, tree args,
+ tree conversion_path, int flags)
{
struct z_candidate *candidates = 0, *cand;
tree explicit_targs = NULL_TREE;
- tree basetype, mem_args = NULL_TREE, fns, instance_ptr;
- tree pretty_name;
+ tree basetype = NULL_TREE;
+ tree access_binfo;
+ tree optype;
+ tree mem_args = NULL_TREE, instance_ptr;
+ tree name, pretty_name;
tree user_args;
- tree templates = NULL_TREE;
tree call;
int template_only = 0;
- if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
- {
- explicit_targs = TREE_OPERAND (name, 1);
- name = TREE_OPERAND (name, 0);
- if (DECL_P (name))
- name = DECL_NAME (name);
- else
- {
- if (TREE_CODE (name) == COMPONENT_REF)
- name = TREE_OPERAND (name, 1);
- if (TREE_CODE (name) == OVERLOAD)
- name = DECL_NAME (OVL_CURRENT (name));
- }
+ my_friendly_assert (instance != NULL_TREE, 20020729);
- template_only = 1;
- }
+ if (instance == error_mark_node || fns == error_mark_node
+ || args == error_mark_node)
+ return error_mark_node;
+ /* Process the argument list. */
user_args = args;
args = resolve_args (args);
-
if (args == error_mark_node)
return error_mark_node;
- if (instance == NULL_TREE)
- basetype = BINFO_TYPE (basetype_path);
- else
+ if (TREE_CODE (instance) == OFFSET_REF)
+ instance = resolve_offset_ref (instance);
+ if (TREE_CODE (TREE_TYPE (instance)) == REFERENCE_TYPE)
+ instance = convert_from_reference (instance);
+ basetype = TYPE_MAIN_VARIANT (TREE_TYPE (instance));
+ instance_ptr = build_this (instance);
+
+ if (!BASELINK_P (fns))
{
- if (TREE_CODE (instance) == OFFSET_REF)
- instance = resolve_offset_ref (instance);
- if (TREE_CODE (TREE_TYPE (instance)) == REFERENCE_TYPE)
- instance = convert_from_reference (instance);
- basetype = TYPE_MAIN_VARIANT (TREE_TYPE (instance));
+ call = build_field_call (instance_ptr, fns, args);
+ if (call)
+ return call;
+ error ("call to non-function `%D'", fns);
+ return error_mark_node;
+ }
- /* XXX this should be handled before we get here. */
- if (! IS_AGGR_TYPE (basetype))
- {
- if ((flags & LOOKUP_COMPLAIN) && basetype != error_mark_node)
- error ("request for member `%D' in `%E', which is of non-aggregate type `%T'",
- name, instance, basetype);
+ if (!conversion_path)
+ conversion_path = BASELINK_BINFO (fns);
+ access_binfo = BASELINK_ACCESS_BINFO (fns);
+ optype = BASELINK_OPTYPE (fns);
+ fns = BASELINK_FUNCTIONS (fns);
- return error_mark_node;
- }
+ if (TREE_CODE (fns) == TEMPLATE_ID_EXPR)
+ {
+ explicit_targs = TREE_OPERAND (fns, 1);
+ fns = TREE_OPERAND (fns, 0);
+ template_only = 1;
}
- if (basetype_path == NULL_TREE)
- basetype_path = TYPE_BINFO (basetype);
+ my_friendly_assert (TREE_CODE (fns) == FUNCTION_DECL
+ || TREE_CODE (fns) == TEMPLATE_DECL
+ || TREE_CODE (fns) == OVERLOAD,
+ 20020712);
- if (instance)
+ /* XXX this should be handled before we get here. */
+ if (! IS_AGGR_TYPE (basetype))
{
- instance_ptr = build_this (instance);
+ if ((flags & LOOKUP_COMPLAIN) && basetype != error_mark_node)
+ error ("request for member `%D' in `%E', which is of non-aggregate type `%T'",
+ fns, instance, basetype);
- if (! template_only)
- {
- /* XXX this should be handled before we get here. */
- fns = build_field_call (basetype_path, instance_ptr, name, args);
- if (fns)
- return fns;
- }
- }
- else
- {
- instance_ptr = build_int_2 (0, 0);
- TREE_TYPE (instance_ptr) = build_pointer_type (basetype);
+ return error_mark_node;
}
- /* Callers should explicitly indicate whether they want to construct
- the complete object or just the part without virtual bases. */
- my_friendly_assert (name != ctor_identifier, 20000408);
- /* Similarly for destructors. */
- my_friendly_assert (name != dtor_identifier, 20000408);
+ name = DECL_NAME (get_first_fn (fns));
if (IDENTIFIER_CTOR_OR_DTOR_P (name))
{
- int constructor_p;
-
- constructor_p = (name == complete_ctor_identifier
- || name == base_ctor_identifier);
- pretty_name = (constructor_p
- ? constructor_name (basetype) : dtor_identifier);
-
- /* If we're a call to a constructor or destructor for a
- subobject that uses virtual base classes, then we need to
- pass down a pointer to a VTT for the subobject. */
- if ((name == base_ctor_identifier
- || name == base_dtor_identifier)
- && TYPE_USES_VIRTUAL_BASECLASSES (basetype))
- {
- tree vtt;
- tree sub_vtt;
- tree basebinfo = basetype_path;
-
- /* If the current function is a complete object constructor
- or destructor, then we fetch the VTT directly.
- Otherwise, we look it up using the VTT we were given. */
- vtt = IDENTIFIER_GLOBAL_VALUE (get_vtt_name (current_class_type));
- vtt = decay_conversion (vtt);
- vtt = build (COND_EXPR, TREE_TYPE (vtt),
- build (EQ_EXPR, boolean_type_node,
- current_in_charge_parm, integer_zero_node),
- current_vtt_parm,
- vtt);
- if (TREE_VIA_VIRTUAL (basebinfo))
- basebinfo = binfo_for_vbase (basetype, current_class_type);
- my_friendly_assert (BINFO_SUBVTT_INDEX (basebinfo), 20010110);
- sub_vtt = build (PLUS_EXPR, TREE_TYPE (vtt), vtt,
- BINFO_SUBVTT_INDEX (basebinfo));
-
- args = tree_cons (NULL_TREE, sub_vtt, args);
- }
+ /* Callers should explicitly indicate whether they want to construct
+ the complete object or just the part without virtual bases. */
+ my_friendly_assert (name != ctor_identifier, 20000408);
+ /* Similarly for destructors. */
+ my_friendly_assert (name != dtor_identifier, 20000408);
+
+ if (name == complete_ctor_identifier
+ || name == base_ctor_identifier)
+ pretty_name = constructor_name (basetype);
+ else
+ pretty_name = dtor_identifier;
}
else
pretty_name = name;
- fns = lookup_fnfields (basetype_path, name, 1);
-
- if (fns == error_mark_node)
- return error_mark_node;
if (fns)
{
- tree base = BINFO_TYPE (TREE_PURPOSE (fns));
- tree fn = TREE_VALUE (fns);
+ tree fn;
+ tree class_type = (conversion_path
+ ? BINFO_TYPE (conversion_path)
+ : NULL_TREE);
+
mem_args = tree_cons (NULL_TREE, instance_ptr, args);
- for (; fn; fn = OVL_NEXT (fn))
+ for (fn = fns; fn; fn = OVL_NEXT (fn))
{
tree t = OVL_CURRENT (fn);
tree this_arglist;
@@ -4645,20 +5018,22 @@ build_new_method_call (instance, name, args, basetype_path, flags)
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, base, explicit_targs,
- this_arglist,
- TREE_TYPE (name), 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, base,
- this_arglist, flags);
-
- if (candidates)
- candidates->basetype_path = basetype_path;
+ add_function_candidate (&candidates, t,
+ class_type,
+ this_arglist,
+ access_binfo,
+ conversion_path,
+ flags);
}
}
@@ -4668,7 +5043,7 @@ build_new_method_call (instance, name, args, basetype_path, flags)
if (flags & LOOKUP_SPECULATIVELY)
return NULL_TREE;
if (!COMPLETE_TYPE_P (basetype))
- incomplete_type_error (instance_ptr, basetype);
+ cxx_incomplete_type_error (instance_ptr, basetype);
else
error ("no matching function for call to `%T::%D(%A)%#V'",
basetype, pretty_name, user_args,
@@ -4713,16 +5088,16 @@ build_new_method_call (instance, name, args, basetype_path, flags)
else
{
call = build_over_call (cand, args, flags);
- /* Do evaluate the object parameter in a call to a static member
- function. */
- if (TREE_SIDE_EFFECTS (instance))
+ /* In an expression of the form `a->f()' where `f' turns out to
+ be a static member function, `a' is none-the-less evaluated. */
+ if (instance && TREE_SIDE_EFFECTS (instance))
call = build (COMPOUND_EXPR, TREE_TYPE (call), instance, call);
}
return call;
}
-/* Returns non-zero iff standard conversion sequence ICS1 is a proper
+/* Returns nonzero iff standard conversion sequence ICS1 is a proper
subsequence of ICS2. */
static int
@@ -4762,7 +5137,7 @@ is_subseq (ics1, ics2)
}
}
-/* Returns non-zero iff DERIVED is derived from BASE. The inputs may
+/* Returns nonzero iff DERIVED is derived from BASE. The inputs may
be any _TYPE nodes. */
int
@@ -4860,7 +5235,7 @@ compare_ics (ics1, ics2)
tree deref_to_type2 = NULL_TREE;
int rank1, rank2;
- /* REF_BINDING is non-zero if the result of the conversion sequence
+ /* REF_BINDING is nonzero if the result of the conversion sequence
is a reference type. In that case TARGET_TYPE is the
type referred to by the reference. */
tree target_type1;
@@ -5206,25 +5581,10 @@ add_warning (winner, loser)
struct z_candidate *winner, *loser;
{
winner->warnings = tree_cons (NULL_TREE,
- build_ptr_wrapper (loser),
+ build_zc_wrapper (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:
@@ -5359,7 +5719,7 @@ joust (cand1, cand2, warn)
&& TREE_CODE (convn) == QUAL_CONV)
/* Don't complain about `operator char *()' beating
`operator const char *() const'. */;
- else if (warn)
+ else if (warn && warn_conversion)
{
tree source = source_type (TREE_VEC_ELT (w->convs, 0));
if (! DECL_CONSTRUCTOR_P (w->fn))
@@ -5488,11 +5848,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;
@@ -5559,7 +5917,7 @@ tourney (candidates)
return champ;
}
-/* Returns non-zero if things of type FROM can be converted to TO. */
+/* Returns nonzero if things of type FROM can be converted to TO. */
int
can_convert (to, from)
@@ -5568,7 +5926,7 @@ can_convert (to, from)
return can_convert_arg (to, from, NULL_TREE);
}
-/* Returns non-zero if ARG (of type FROM) can be converted to TO. */
+/* Returns nonzero if ARG (of type FROM) can be converted to TO. */
int
can_convert_arg (to, from, arg)
@@ -5614,17 +5972,81 @@ perform_implicit_conversion (type, expr)
return convert_like (conv, expr);
}
+/* Convert EXPR to TYPE (as a direct-initialization) if that is
+ permitted. If the conversion is valid, the converted expression is
+ returned. Otherwise, NULL_TREE is returned. */
+
+tree
+perform_direct_initialization_if_possible (tree type, tree expr)
+{
+ tree conv;
+
+ if (type == error_mark_node || error_operand_p (expr))
+ return error_mark_node;
+ conv = implicit_conversion (type, TREE_TYPE (expr), expr,
+ LOOKUP_NORMAL);
+ if (!conv || ICS_BAD_FLAG (conv))
+ return NULL_TREE;
+ return convert_like_real (conv, expr, NULL_TREE, 0, 0,
+ /*issue_conversion_warnings=*/false);
+}
+
+/* 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))
{
@@ -5632,5 +6054,101 @@ 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 return 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))
+ {
+ tree init;
+ tree type;
+
+ /* Create the temporary variable. */
+ type = TREE_TYPE (expr);
+ var = make_temporary_var_for_ref_to_temp (decl, type);
+ layout_decl (var, 0);
+ if (at_function_scope_p ())
+ {
+ tree cleanup;
+
+ add_decl_stmt (var);
+ cleanup = cxx_maybe_build_cleanup (var);
+ if (cleanup)
+ finish_decl_cleanup (var, cleanup);
+ }
+ else
+ {
+ rest_of_decl_compilation (var, NULL, /*toplev=*/1, at_eof);
+ if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
+ static_aggregates = tree_cons (NULL_TREE, var,
+ static_aggregates);
+ }
+ init = build (INIT_EXPR, type, var, expr);
+ /* Use its address to initialize the reference variable. */
+ expr = build_address (var);
+ expr = build (COMPOUND_EXPR, TREE_TYPE (expr), init, expr);
+ }
+ 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);
}
+
+#include "gt-cp-call.h"
OpenPOWER on IntegriCloud