aboutsummaryrefslogtreecommitdiff
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.c4513
1 files changed, 0 insertions, 4513 deletions
diff --git a/contrib/gcc/cp/call.c b/contrib/gcc/cp/call.c
deleted file mode 100644
index 094a345c6e98..000000000000
--- a/contrib/gcc/cp/call.c
+++ /dev/null
@@ -1,4513 +0,0 @@
-/* Functions related to invoking methods and overloaded functions.
- Copyright (C) 1987, 92-97, 1998, 1999 Free Software Foundation, Inc.
- Contributed by Michael Tiemann (tiemann@cygnus.com) and
- modified by Brendan Kehoe (brendan@cygnus.com).
-
-This file is part of GNU CC.
-
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
-
-
-/* High-level class interface. */
-
-#include "config.h"
-#include "system.h"
-#include "tree.h"
-#include "cp-tree.h"
-#include "output.h"
-#include "flags.h"
-#include "rtl.h"
-#include "toplev.h"
-
-#include "obstack.h"
-#define obstack_chunk_alloc xmalloc
-#define obstack_chunk_free free
-
-extern int inhibit_warnings;
-extern tree ctor_label, dtor_label;
-
-static tree build_new_method_call PROTO((tree, tree, tree, tree, int));
-
-static tree build_field_call PROTO((tree, tree, tree, tree));
-static tree find_scoped_type PROTO((tree, tree, tree));
-static struct z_candidate * tourney PROTO((struct z_candidate *));
-static int joust PROTO((struct z_candidate *, struct z_candidate *, int));
-static int compare_ics PROTO((tree, tree));
-static tree build_over_call PROTO((struct z_candidate *, tree, int));
-static tree convert_like PROTO((tree, tree));
-static void op_error PROTO((enum tree_code, enum tree_code, tree, tree,
- tree, const char *));
-static tree build_object_call PROTO((tree, tree));
-static tree resolve_args PROTO((tree));
-static struct z_candidate * build_user_type_conversion_1
- PROTO ((tree, tree, int));
-static void print_z_candidates PROTO((struct z_candidate *));
-static tree build_this PROTO((tree));
-static struct z_candidate * splice_viable PROTO((struct z_candidate *));
-static int any_viable PROTO((struct z_candidate *));
-static struct z_candidate * add_template_candidate
- PROTO((struct z_candidate *, tree, tree, tree, tree, int,
- unification_kind_t));
-static struct z_candidate * add_template_candidate_real
- PROTO((struct z_candidate *, tree, tree, tree, tree, int,
- tree, unification_kind_t));
-static struct z_candidate * add_template_conv_candidate
- PROTO((struct z_candidate *, tree, tree, tree, tree));
-static struct z_candidate * add_builtin_candidates
- PROTO((struct z_candidate *, enum tree_code, enum tree_code,
- tree, tree *, int));
-static struct z_candidate * add_builtin_candidate
- PROTO((struct z_candidate *, enum tree_code, enum tree_code,
- tree, tree, tree, tree *, tree *, int));
-static int is_complete PROTO((tree));
-static struct z_candidate * build_builtin_candidate
- PROTO((struct z_candidate *, tree, tree, tree, tree *, tree *,
- int));
-static struct z_candidate * add_conv_candidate
- PROTO((struct z_candidate *, tree, tree, tree));
-static struct z_candidate * add_function_candidate
- PROTO((struct z_candidate *, tree, tree, int));
-static tree implicit_conversion PROTO((tree, tree, tree, int));
-static tree standard_conversion PROTO((tree, tree, tree));
-static tree reference_binding PROTO((tree, tree, tree, int));
-static tree strip_top_quals PROTO((tree));
-static tree non_reference PROTO((tree));
-static tree build_conv PROTO((enum tree_code, tree, tree));
-static int is_subseq PROTO((tree, tree));
-static int maybe_handle_ref_bind PROTO((tree*, tree*));
-static void maybe_handle_implicit_object PROTO((tree*));
-static struct z_candidate * add_candidate PROTO((struct z_candidate *,
- tree, tree, int));
-static tree source_type PROTO((tree));
-static void add_warning PROTO((struct z_candidate *, struct z_candidate *));
-
-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_USES_COMPLEX_INHERITANCE (type))
- rval = build (COMPONENT_REF, TREE_TYPE (CLASSTYPE_VFIELD (type)),
- datum, CLASSTYPE_VFIELD (type));
- else
- rval = build_component_ref (datum, DECL_NAME (CLASSTYPE_VFIELD (type)), NULL_TREE, 0);
-
- return rval;
-}
-
-/* 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;
-{
- tree field, instance;
-
- if (name == ctor_identifier || name == dtor_identifier)
- 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);
-
- if (field == error_mark_node || field == NULL_TREE)
- return field;
-
- if (TREE_CODE (field) == FIELD_DECL || TREE_CODE (field) == 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_PTR);
- instance = build_component_ref_1 (instance, field, 0);
-
- if (instance == error_mark_node)
- return error_mark_node;
-
- if (IS_AGGR_TYPE (TREE_TYPE (instance)))
- return build_opfncall (CALL_EXPR, LOOKUP_NORMAL,
- instance, parms, NULL_TREE);
- else if (TREE_CODE (TREE_TYPE (instance)) == POINTER_TYPE)
- {
- if (TREE_CODE (TREE_TYPE (TREE_TYPE (instance))) == FUNCTION_TYPE)
- return build_function_call (instance, parms);
- else if (TREE_CODE (TREE_TYPE (TREE_TYPE (instance)))
- == METHOD_TYPE)
- return build_function_call
- (instance, expr_tree_cons (NULL_TREE, instance_ptr, parms));
- }
- }
-
- return NULL_TREE;
-}
-
-static tree
-find_scoped_type (type, inner_name, inner_types)
- tree type, inner_name, inner_types;
-{
- tree tags = CLASSTYPE_TAGS (type);
-
- while (tags)
- {
- /* The TREE_PURPOSE of an enum tag (which becomes a member of the
- enclosing class) is set to the name for the enum type. So, if
- inner_name is `bar', and we strike `baz' for `enum bar { baz }',
- then this test will be true. */
- if (TREE_PURPOSE (tags) == inner_name)
- {
- if (inner_types == NULL_TREE)
- return TYPE_MAIN_DECL (TREE_VALUE (tags));
- return resolve_scope_to_name (TREE_VALUE (tags), inner_types);
- }
- tags = TREE_CHAIN (tags);
- }
-
- /* Look for a TYPE_DECL. */
- for (tags = TYPE_FIELDS (type); tags; tags = TREE_CHAIN (tags))
- if (TREE_CODE (tags) == TYPE_DECL && DECL_NAME (tags) == inner_name)
- {
- /* Code by raeburn. */
- if (inner_types == NULL_TREE)
- return tags;
- return resolve_scope_to_name (TREE_TYPE (tags), inner_types);
- }
-
- return NULL_TREE;
-}
-
-/* Resolve an expression NAME1::NAME2::...::NAMEn to
- the name that names the above nested type. INNER_TYPES
- is a chain of nested type names (held together by SCOPE_REFs);
- OUTER_TYPE is the type we know to enclose INNER_TYPES.
- Returns NULL_TREE if there is an error. */
-
-tree
-resolve_scope_to_name (outer_type, inner_stuff)
- tree outer_type, inner_stuff;
-{
- register tree tmp;
- tree inner_name, inner_type;
-
- if (outer_type == NULL_TREE && current_class_type != NULL_TREE)
- {
- /* We first try to look for a nesting in our current class context,
- then try any enclosing classes. */
- tree type = current_class_type;
-
- while (type && (TREE_CODE (type) == RECORD_TYPE
- || TREE_CODE (type) == UNION_TYPE))
- {
- tree rval = resolve_scope_to_name (type, inner_stuff);
-
- if (rval != NULL_TREE)
- return rval;
- type = DECL_CONTEXT (TYPE_MAIN_DECL (type));
- }
- }
-
- if (TREE_CODE (inner_stuff) == SCOPE_REF)
- {
- inner_name = TREE_OPERAND (inner_stuff, 0);
- inner_type = TREE_OPERAND (inner_stuff, 1);
- }
- else
- {
- inner_name = inner_stuff;
- inner_type = NULL_TREE;
- }
-
- if (outer_type == NULL_TREE)
- {
- tree x;
- /* If we have something that's already a type by itself,
- use that. */
- if (IDENTIFIER_HAS_TYPE_VALUE (inner_name))
- {
- if (inner_type)
- return resolve_scope_to_name (IDENTIFIER_TYPE_VALUE (inner_name),
- inner_type);
- return inner_name;
- }
-
- x = lookup_name (inner_name, 0);
-
- if (x && TREE_CODE (x) == NAMESPACE_DECL)
- {
- x = lookup_namespace_name (x, inner_type);
- return x;
- }
- return NULL_TREE;
- }
-
- if (! IS_AGGR_TYPE (outer_type))
- return NULL_TREE;
-
- /* Look for member classes or enums. */
- tmp = find_scoped_type (outer_type, inner_name, inner_type);
-
- /* If it's not a type in this class, then go down into the
- base classes and search there. */
- if (! tmp && TYPE_BINFO (outer_type))
- {
- tree binfos = TYPE_BINFO_BASETYPES (outer_type);
- int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
-
- for (i = 0; i < n_baselinks; i++)
- {
- tree base_binfo = TREE_VEC_ELT (binfos, i);
- tmp = resolve_scope_to_name (BINFO_TYPE (base_binfo), inner_stuff);
- if (tmp)
- return tmp;
- }
- tmp = NULL_TREE;
- }
-
- return tmp;
-}
-
-/* Returns nonzero iff the destructor name specified in NAME
- (a BIT_NOT_EXPR) matches BASETYPE. The operand of NAME can take many
- forms... */
-
-int
-check_dtor_name (basetype, name)
- tree basetype, name;
-{
- name = TREE_OPERAND (name, 0);
-
- /* Just accept something we've already complained about. */
- if (name == error_mark_node)
- return 1;
-
- if (TREE_CODE (name) == TYPE_DECL)
- name = TREE_TYPE (name);
- else if (TREE_CODE_CLASS (TREE_CODE (name)) == 't')
- /* OK */;
- else if (TREE_CODE (name) == IDENTIFIER_NODE)
- {
- if ((IS_AGGR_TYPE (basetype) && name == constructor_name (basetype))
- || (TREE_CODE (basetype) == ENUMERAL_TYPE
- && name == TYPE_IDENTIFIER (basetype)))
- name = basetype;
- else
- name = get_type_value (name);
- }
- else
- my_friendly_abort (980605);
-
- if (name && TYPE_MAIN_VARIANT (basetype) == TYPE_MAIN_VARIANT (name))
- return 1;
- return 0;
-}
-
-/* Build a method call of the form `EXP->SCOPES::NAME (PARMS)'.
- This is how virtual function calls are avoided. */
-
-tree
-build_scoped_method_call (exp, basetype, name, parms)
- tree exp, basetype, name, parms;
-{
- /* Because this syntactic form does not allow
- a pointer to a base class to be `stolen',
- we need not protect the derived->base conversion
- that happens here.
-
- @@ But we do have to check access privileges later. */
- tree binfo, decl;
- tree type = TREE_TYPE (exp);
-
- if (type == error_mark_node
- || basetype == error_mark_node)
- return error_mark_node;
-
- if (processing_template_decl)
- {
- if (TREE_CODE (name) == BIT_NOT_EXPR
- && TREE_CODE (TREE_OPERAND (name, 0)) == IDENTIFIER_NODE)
- {
- tree type = get_aggr_from_typedef (TREE_OPERAND (name, 0), 0);
- if (type)
- name = build_min_nt (BIT_NOT_EXPR, type);
- }
- name = build_min_nt (SCOPE_REF, basetype, name);
- return build_min_nt (METHOD_CALL_EXPR, name, exp, parms, NULL_TREE);
- }
-
- if (TREE_CODE (type) == REFERENCE_TYPE)
- type = TREE_TYPE (type);
-
- if (TREE_CODE (basetype) == TREE_VEC)
- {
- binfo = basetype;
- basetype = BINFO_TYPE (binfo);
- }
- else
- binfo = NULL_TREE;
-
- /* Check the destructor call syntax. */
- if (TREE_CODE (name) == BIT_NOT_EXPR)
- {
- /* We can get here if someone writes their destructor call like
- `obj.NS::~T()'; this isn't really a scoped method call, so hand
- it off. */
- if (TREE_CODE (basetype) == NAMESPACE_DECL)
- return build_method_call (exp, name, parms, NULL_TREE, LOOKUP_NORMAL);
-
- if (! check_dtor_name (basetype, name))
- cp_error ("qualified type `%T' does not match destructor name `~%T'",
- basetype, TREE_OPERAND (name, 0));
-
- /* Destructors can be "called" for simple types; see 5.2.4 and 12.4 Note
- that explicit ~int is caught in the parser; this deals with typedefs
- and template parms. */
- if (! IS_AGGR_TYPE (basetype))
- {
- if (TYPE_MAIN_VARIANT (type) != TYPE_MAIN_VARIANT (basetype))
- cp_error ("type of `%E' does not match destructor type `%T' (type was `%T')",
- exp, basetype, type);
-
- return cp_convert (void_type_node, exp);
- }
- }
-
- if (! is_aggr_type (basetype, 1))
- return error_mark_node;
-
- if (! IS_AGGR_TYPE (type))
- {
- cp_error ("base object `%E' of scoped method call is of non-aggregate type `%T'",
- exp, type);
- return error_mark_node;
- }
-
- if (! binfo)
- {
- binfo = get_binfo (basetype, type, 1);
- if (binfo == error_mark_node)
- return error_mark_node;
- if (! binfo)
- error_not_base_type (basetype, type);
- }
-
- if (binfo)
- {
- if (TREE_CODE (exp) == INDIRECT_REF)
- decl = build_indirect_ref
- (convert_pointer_to_real
- (binfo, build_unary_op (ADDR_EXPR, exp, 0)), NULL_PTR);
- else
- decl = build_scoped_ref (exp, basetype);
-
- /* Call to a destructor. */
- if (TREE_CODE (name) == BIT_NOT_EXPR)
- {
- if (! TYPE_HAS_DESTRUCTOR (TREE_TYPE (decl)))
- return cp_convert (void_type_node, exp);
-
- return build_delete (TREE_TYPE (decl), decl, integer_two_node,
- LOOKUP_NORMAL|LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR,
- 0);
- }
-
- /* Call to a method. */
- return build_method_call (decl, name, parms, binfo,
- LOOKUP_NORMAL|LOOKUP_NONVIRTUAL);
- }
- return error_mark_node;
-}
-
-/* We want the address of a function or method. We avoid creating a
- pointer-to-member function. */
-
-tree
-build_addr_func (function)
- tree function;
-{
- tree type = TREE_TYPE (function);
-
- /* We have to do these by hand to avoid real pointer to member
- functions. */
- if (TREE_CODE (type) == METHOD_TYPE)
- {
- tree addr;
-
- type = build_pointer_type (type);
-
- if (mark_addressable (function) == 0)
- return error_mark_node;
-
- addr = build1 (ADDR_EXPR, type, function);
-
- /* Address of a static or external variable or function counts
- as a constant */
- if (staticp (function))
- TREE_CONSTANT (addr) = 1;
-
- function = addr;
- }
- else
- function = default_conversion (function);
-
- return function;
-}
-
-/* Build a CALL_EXPR, we can handle FUNCTION_TYPEs, METHOD_TYPEs, or
- POINTER_TYPE to those. Note, pointer to member function types
- (TYPE_PTRMEMFUNC_P) must be handled by our callers. */
-
-tree
-build_call (function, result_type, parms)
- tree function, result_type, parms;
-{
- int is_constructor = 0;
- tree tmp;
- tree decl;
-
- function = build_addr_func (function);
-
- if (TYPE_PTRMEMFUNC_P (TREE_TYPE (function)))
- {
- sorry ("unable to call pointer to member function here");
- return error_mark_node;
- }
-
- if (TREE_CODE (function) == ADDR_EXPR
- && TREE_CODE (TREE_OPERAND (function, 0)) == FUNCTION_DECL)
- decl = TREE_OPERAND (function, 0);
- else
- decl = NULL_TREE;
-
- if (decl && DECL_CONSTRUCTOR_P (decl))
- is_constructor = 1;
-
- if (decl)
- my_friendly_assert (TREE_USED (decl), 990125);
-
- /* Don't pass empty class objects by value. This is useful
- for tags in STL, which are used to control overload resolution.
- We don't need to handle other cases of copying empty classes. */
- if (! decl || ! DECL_BUILT_IN (decl))
- for (tmp = parms; tmp; tmp = TREE_CHAIN (tmp))
- if (is_empty_class (TREE_TYPE (TREE_VALUE (tmp)))
- && ! TREE_ADDRESSABLE (TREE_TYPE (TREE_VALUE (tmp))))
- {
- tree t = make_node (RTL_EXPR);
- TREE_TYPE (t) = TREE_TYPE (TREE_VALUE (tmp));
- RTL_EXPR_RTL (t) = const0_rtx;
- RTL_EXPR_SEQUENCE (t) = NULL_RTX;
- TREE_VALUE (tmp) = build (COMPOUND_EXPR, TREE_TYPE (t),
- TREE_VALUE (tmp), t);
- }
-
- function = build_nt (CALL_EXPR, function, parms, NULL_TREE);
- TREE_HAS_CONSTRUCTOR (function) = is_constructor;
- TREE_TYPE (function) = result_type;
- TREE_SIDE_EFFECTS (function) = 1;
-
- return function;
-}
-
-/* Build something of the form ptr->method (args)
- or object.method (args). This can also build
- calls to constructors, and find friends.
-
- Member functions always take their class variable
- as a pointer.
-
- INSTANCE is a class instance.
-
- NAME is the name of the method desired, usually an IDENTIFIER_NODE.
-
- PARMS help to figure out what that NAME really refers to.
-
- BASETYPE_PATH, if non-NULL, contains a chain from the type of INSTANCE
- down to the real instance type to use for access checking. We need this
- information to get protected accesses correct. This parameter is used
- by build_member_call.
-
- FLAGS is the logical disjunction of zero or more LOOKUP_
- flags. See cp-tree.h for more info.
-
- If this is all OK, calls build_function_call with the resolved
- member function.
-
- This function must also handle being called to perform
- initialization, promotion/coercion of arguments, and
- instantiation of default parameters.
-
- Note that NAME may refer to an instance variable name. If
- `operator()()' is defined for the type of that field, then we return
- that result. */
-
-tree
-build_method_call (instance, name, parms, basetype_path, flags)
- tree instance, name, parms, basetype_path;
- int flags;
-{
- tree basetype, instance_ptr;
-
-#ifdef GATHER_STATISTICS
- n_build_method_call++;
-#endif
-
- if (instance == error_mark_node
- || name == error_mark_node
- || parms == error_mark_node
- || (instance != NULL_TREE && TREE_TYPE (instance) == error_mark_node))
- return error_mark_node;
-
- if (processing_template_decl)
- {
- /* We need to process template parm names here so that tsubst catches
- them properly. Other type names can wait. */
- if (TREE_CODE (name) == BIT_NOT_EXPR)
- {
- tree type = NULL_TREE;
-
- if (TREE_CODE (TREE_OPERAND (name, 0)) == IDENTIFIER_NODE)
- type = get_aggr_from_typedef (TREE_OPERAND (name, 0), 0);
- else if (TREE_CODE (TREE_OPERAND (name, 0)) == TYPE_DECL)
- type = TREE_TYPE (TREE_OPERAND (name, 0));
-
- if (type && TREE_CODE (type) == TEMPLATE_TYPE_PARM)
- name = build_min_nt (BIT_NOT_EXPR, type);
- }
-
- return build_min_nt (METHOD_CALL_EXPR, name, instance, parms, NULL_TREE);
- }
-
- if (TREE_CODE (name) == BIT_NOT_EXPR)
- {
- 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))
- cp_error
- ("destructor name `~%T' does not match type `%T' of expression",
- TREE_OPERAND (name, 0), basetype);
-
- if (! TYPE_HAS_DESTRUCTOR (complete_type (basetype)))
- 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),
- instance_ptr, integer_two_node,
- LOOKUP_NORMAL|LOOKUP_DESTRUCTOR, 0);
- }
-
- return build_new_method_call (instance, name, parms, basetype_path, flags);
-}
-
-/* New overloading code. */
-
-struct z_candidate {
- tree fn;
- tree convs;
- tree second_conv;
- int viable;
- tree basetype_path;
- tree template;
- tree warnings;
- struct z_candidate *next;
-};
-
-#define IDENTITY_RANK 0
-#define EXACT_RANK 1
-#define PROMO_RANK 2
-#define STD_RANK 3
-#define PBOOL_RANK 4
-#define USER_RANK 5
-#define ELLIPSIS_RANK 6
-#define BAD_RANK 7
-
-#define ICS_RANK(NODE) \
- (ICS_BAD_FLAG (NODE) ? BAD_RANK \
- : ICS_ELLIPSIS_FLAG (NODE) ? ELLIPSIS_RANK \
- : ICS_USER_FLAG (NODE) ? USER_RANK \
- : ICS_STD_RANK (NODE))
-
-#define ICS_STD_RANK(NODE) TREE_COMPLEXITY (NODE)
-
-#define ICS_USER_FLAG(NODE) TREE_LANG_FLAG_0 (NODE)
-#define ICS_ELLIPSIS_FLAG(NODE) TREE_LANG_FLAG_1 (NODE)
-#define ICS_THIS_FLAG(NODE) TREE_LANG_FLAG_2 (NODE)
-#define ICS_BAD_FLAG(NODE) TREE_LANG_FLAG_3 (NODE)
-
-#define USER_CONV_CAND(NODE) \
- ((struct z_candidate *)WRAPPER_PTR (TREE_OPERAND (NODE, 1)))
-#define USER_CONV_FN(NODE) (USER_CONV_CAND (NODE)->fn)
-
-int
-null_ptr_cst_p (t)
- tree t;
-{
- if (t == null_node
- || (integer_zerop (t) && TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE))
- return 1;
- return 0;
-}
-
-static tree
-build_conv (code, type, from)
- enum tree_code code;
- tree type, from;
-{
- tree t = build1 (code, type, from);
- int rank = ICS_STD_RANK (from);
- switch (code)
- {
- case PTR_CONV:
- case PMEM_CONV:
- case BASE_CONV:
- case STD_CONV:
- if (rank < STD_RANK)
- rank = STD_RANK;
- break;
-
- case QUAL_CONV:
- if (rank < EXACT_RANK)
- rank = EXACT_RANK;
-
- default:
- break;
- }
- ICS_STD_RANK (t) = rank;
- ICS_USER_FLAG (t) = ICS_USER_FLAG (from);
- ICS_BAD_FLAG (t) = ICS_BAD_FLAG (from);
- return t;
-}
-
-static tree
-non_reference (t)
- tree t;
-{
- if (TREE_CODE (t) == REFERENCE_TYPE)
- t = TREE_TYPE (t);
- return t;
-}
-
-static tree
-strip_top_quals (t)
- tree t;
-{
- if (TREE_CODE (t) == ARRAY_TYPE)
- return t;
- return TYPE_MAIN_VARIANT (t);
-}
-
-/* Returns the standard conversion path (see [conv]) from type FROM to type
- TO, if any. For proper handling of null pointer constants, you must
- also pass the expression EXPR to convert from. */
-
-static tree
-standard_conversion (to, from, expr)
- tree to, from, expr;
-{
- enum tree_code fcode, tcode;
- tree conv;
- int fromref = 0;
-
- if (TREE_CODE (to) == REFERENCE_TYPE)
- to = TREE_TYPE (to);
- if (TREE_CODE (from) == REFERENCE_TYPE)
- {
- fromref = 1;
- from = TREE_TYPE (from);
- }
- to = strip_top_quals (to);
- from = strip_top_quals (from);
-
- if ((TYPE_PTRFN_P (to) || TYPE_PTRMEMFUNC_P (to))
- && expr && type_unknown_p (expr))
- {
- expr = instantiate_type (to, expr, 0);
- if (expr == error_mark_node)
- return NULL_TREE;
- from = TREE_TYPE (expr);
- }
-
- fcode = TREE_CODE (from);
- tcode = TREE_CODE (to);
-
- conv = build1 (IDENTITY_CONV, from, expr);
-
- if (fcode == FUNCTION_TYPE)
- {
- from = build_pointer_type (from);
- fcode = TREE_CODE (from);
- conv = build_conv (LVALUE_CONV, from, conv);
- }
- else if (fcode == ARRAY_TYPE)
- {
- from = build_pointer_type (TREE_TYPE (from));
- fcode = TREE_CODE (from);
- conv = build_conv (LVALUE_CONV, from, conv);
- }
- else if (fromref || (expr && real_lvalue_p (expr)))
- conv = build_conv (RVALUE_CONV, from, conv);
-
- if (from == to)
- return conv;
-
- if ((tcode == POINTER_TYPE || TYPE_PTRMEMFUNC_P (to))
- && expr && null_ptr_cst_p (expr))
- {
- conv = build_conv (STD_CONV, to, conv);
- }
- else if (tcode == POINTER_TYPE && fcode == POINTER_TYPE)
- {
- enum tree_code ufcode = TREE_CODE (TREE_TYPE (from));
- enum tree_code utcode = TREE_CODE (TREE_TYPE (to));
-
- if (same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (from)),
- TYPE_MAIN_VARIANT (TREE_TYPE (to))))
- ;
- else if (utcode == VOID_TYPE && ufcode != OFFSET_TYPE
- && ufcode != FUNCTION_TYPE)
- {
- from = build_pointer_type
- (cp_build_qualified_type (void_type_node,
- CP_TYPE_QUALS (TREE_TYPE (from))));
- conv = build_conv (PTR_CONV, from, conv);
- }
- else if (ufcode == OFFSET_TYPE && utcode == OFFSET_TYPE)
- {
- tree fbase = TYPE_OFFSET_BASETYPE (TREE_TYPE (from));
- tree tbase = TYPE_OFFSET_BASETYPE (TREE_TYPE (to));
-
- if (DERIVED_FROM_P (fbase, tbase)
- && (same_type_p
- (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (from))),
- TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (to))))))
- {
- from = build_offset_type (tbase, TREE_TYPE (TREE_TYPE (from)));
- from = build_pointer_type (from);
- conv = build_conv (PMEM_CONV, from, conv);
- }
- }
- else if (IS_AGGR_TYPE (TREE_TYPE (from))
- && IS_AGGR_TYPE (TREE_TYPE (to)))
- {
- if (DERIVED_FROM_P (TREE_TYPE (to), TREE_TYPE (from)))
- {
- from =
- cp_build_qualified_type (TREE_TYPE (to),
- CP_TYPE_QUALS (TREE_TYPE (from)));
- from = build_pointer_type (from);
- conv = build_conv (PTR_CONV, from, conv);
- }
- }
-
- if (same_type_p (from, to))
- /* OK */;
- else if (comp_ptr_ttypes (TREE_TYPE (to), TREE_TYPE (from)))
- conv = build_conv (QUAL_CONV, to, conv);
- else if (expr && string_conv_p (to, expr, 0))
- /* converting from string constant to char *. */
- conv = build_conv (QUAL_CONV, to, conv);
- else if (ptr_reasonably_similar (TREE_TYPE (to), TREE_TYPE (from)))
- {
- conv = build_conv (PTR_CONV, to, conv);
- ICS_BAD_FLAG (conv) = 1;
- }
- else
- return 0;
-
- from = to;
- }
- else if (TYPE_PTRMEMFUNC_P (to) && TYPE_PTRMEMFUNC_P (from))
- {
- tree fromfn = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (from));
- tree tofn = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (to));
- tree fbase = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (fromfn)));
- tree tbase = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (tofn)));
-
- if (! DERIVED_FROM_P (fbase, tbase)
- || ! same_type_p (TREE_TYPE (fromfn), TREE_TYPE (tofn))
- || ! compparms (TREE_CHAIN (TYPE_ARG_TYPES (fromfn)),
- TREE_CHAIN (TYPE_ARG_TYPES (tofn)))
- || CP_TYPE_QUALS (fbase) != CP_TYPE_QUALS (tbase))
- return 0;
-
- from = cp_build_qualified_type (tbase, CP_TYPE_QUALS (fbase));
- from = build_cplus_method_type (from, TREE_TYPE (fromfn),
- TREE_CHAIN (TYPE_ARG_TYPES (fromfn)));
- from = build_ptrmemfunc_type (build_pointer_type (from));
- conv = build_conv (PMEM_CONV, from, conv);
- }
- else if (tcode == BOOLEAN_TYPE)
- {
- if (! (INTEGRAL_CODE_P (fcode) || fcode == REAL_TYPE
- || fcode == POINTER_TYPE || TYPE_PTRMEMFUNC_P (from)))
- return 0;
-
- conv = build_conv (STD_CONV, to, conv);
- if (fcode == POINTER_TYPE
- || (TYPE_PTRMEMFUNC_P (from) && ICS_STD_RANK (conv) < PBOOL_RANK))
- ICS_STD_RANK (conv) = PBOOL_RANK;
- }
- /* We don't check for ENUMERAL_TYPE here because there are no standard
- conversions to enum type. */
- else if (tcode == INTEGER_TYPE || tcode == BOOLEAN_TYPE
- || tcode == REAL_TYPE)
- {
- if (! (INTEGRAL_CODE_P (fcode) || fcode == REAL_TYPE))
- return 0;
- conv = build_conv (STD_CONV, to, conv);
-
- /* Give this a better rank if it's a promotion. */
- if (to == type_promotes_to (from)
- && ICS_STD_RANK (TREE_OPERAND (conv, 0)) <= PROMO_RANK)
- ICS_STD_RANK (conv) = PROMO_RANK;
- }
- else if (IS_AGGR_TYPE (to) && IS_AGGR_TYPE (from)
- && DERIVED_FROM_P (to, from))
- {
- if (TREE_CODE (conv) == RVALUE_CONV)
- conv = TREE_OPERAND (conv, 0);
- conv = build_conv (BASE_CONV, to, conv);
- }
- else
- return 0;
-
- return conv;
-}
-
-/* Returns the conversion path from type FROM to reference type TO for
- purposes of reference binding. For lvalue binding, either pass a
- reference type to FROM or an lvalue expression to EXPR.
-
- Currently does not distinguish in the generated trees between binding to
- an lvalue and a temporary. Should it? */
-
-static tree
-reference_binding (rto, rfrom, expr, flags)
- tree rto, rfrom, expr;
- int flags;
-{
- tree conv;
- int lvalue = 1;
- tree to = TREE_TYPE (rto);
- tree from = rfrom;
- int related;
-
- if (TREE_CODE (to) == FUNCTION_TYPE && expr && type_unknown_p (expr))
- {
- expr = instantiate_type (to, expr, 0);
- if (expr == error_mark_node)
- return NULL_TREE;
- from = TREE_TYPE (expr);
- }
-
- if (TREE_CODE (from) == REFERENCE_TYPE)
- from = TREE_TYPE (from);
- else if (! expr || ! real_lvalue_p (expr))
- lvalue = 0;
-
- related = (same_type_p (TYPE_MAIN_VARIANT (to),
- TYPE_MAIN_VARIANT (from))
- || (IS_AGGR_TYPE (to) && IS_AGGR_TYPE (from)
- && DERIVED_FROM_P (to, from)));
-
- if (lvalue && related && at_least_as_qualified_p (to, from))
- {
- conv = build1 (IDENTITY_CONV, from, expr);
-
- if (same_type_p (TYPE_MAIN_VARIANT (to),
- TYPE_MAIN_VARIANT (from)))
- conv = build_conv (REF_BIND, rto, conv);
- else
- {
- conv = build_conv (REF_BIND, rto, conv);
- ICS_STD_RANK (conv) = STD_RANK;
- }
- }
- else
- conv = NULL_TREE;
-
- if (! conv)
- {
- conv = standard_conversion (to, rfrom, expr);
- if (conv)
- {
- conv = build_conv (REF_BIND, rto, conv);
-
- /* Bind directly to a base subobject of a class rvalue. Do it
- after building the conversion for proper handling of ICS_RANK. */
- if (TREE_CODE (TREE_OPERAND (conv, 0)) == BASE_CONV)
- TREE_OPERAND (conv, 0) = TREE_OPERAND (TREE_OPERAND (conv, 0), 0);
- }
- if (conv
- && ((! (CP_TYPE_CONST_NON_VOLATILE_P (to)
- && (flags & LOOKUP_NO_TEMP_BIND) == 0))
- /* If T1 is reference-related to T2, cv1 must be the same
- cv-qualification as, or greater cv-qualification than,
- cv2; otherwise, the program is ill-formed. */
- || (related && !at_least_as_qualified_p (to, from))))
- ICS_BAD_FLAG (conv) = 1;
- }
-
- return conv;
-}
-
-/* Returns the implicit conversion sequence (see [over.ics]) from type FROM
- to type TO. The optional expression EXPR may affect the conversion.
- FLAGS are the usual overloading flags. Only LOOKUP_NO_CONVERSION is
- significant. */
-
-static tree
-implicit_conversion (to, from, expr, flags)
- tree to, from, expr;
- int flags;
-{
- tree conv;
- struct z_candidate *cand;
-
- if (TREE_CODE (to) == REFERENCE_TYPE)
- conv = reference_binding (to, from, expr, flags);
- else
- conv = standard_conversion (to, from, expr);
-
- if (conv)
- ;
- else if (expr != NULL_TREE
- && (IS_AGGR_TYPE (non_reference (from))
- || IS_AGGR_TYPE (non_reference (to)))
- && (flags & LOOKUP_NO_CONVERSION) == 0)
- {
- cand = build_user_type_conversion_1
- (to, expr, LOOKUP_ONLYCONVERTING);
- if (cand)
- conv = cand->second_conv;
- if ((! conv || ICS_BAD_FLAG (conv))
- && TREE_CODE (to) == REFERENCE_TYPE
- && (flags & LOOKUP_NO_TEMP_BIND) == 0)
- {
- cand = build_user_type_conversion_1
- (TYPE_MAIN_VARIANT (TREE_TYPE (to)), expr, LOOKUP_ONLYCONVERTING);
- if (cand)
- {
- if (!CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (to)))
- ICS_BAD_FLAG (cand->second_conv) = 1;
- if (!conv || (ICS_BAD_FLAG (conv)
- > ICS_BAD_FLAG (cand->second_conv)))
- conv = build_conv (REF_BIND, to, cand->second_conv);
- }
- }
- }
-
- return conv;
-}
-
-/* Add a new entry to the list of candidates. Used by the add_*_candidate
- functions. */
-
-static struct z_candidate *
-add_candidate (candidates, fn, convs, viable)
- struct z_candidate *candidates;
- tree fn, convs;
- int viable;
-{
- struct z_candidate *cand
- = (struct z_candidate *) scratchalloc (sizeof (struct z_candidate));
-
- cand->fn = fn;
- cand->convs = convs;
- cand->second_conv = NULL_TREE;
- cand->viable = viable;
- cand->basetype_path = NULL_TREE;
- cand->template = NULL_TREE;
- cand->warnings = NULL_TREE;
- cand->next = candidates;
-
- return cand;
-}
-
-/* Create an overload candidate for the function or method FN called with
- the argument list ARGLIST and add it to CANDIDATES. FLAGS is passed on
- to implicit_conversion. */
-
-static struct z_candidate *
-add_function_candidate (candidates, fn, arglist, flags)
- struct z_candidate *candidates;
- tree fn, arglist;
- int flags;
-{
- tree parmlist = TYPE_ARG_TYPES (TREE_TYPE (fn));
- int i, len;
- tree convs;
- tree parmnode, argnode;
- int viable = 1;
-
- /* The `this' and `in_chrg' arguments to constructors are not considered
- in overload resolution. */
- if (DECL_CONSTRUCTOR_P (fn))
- {
- parmlist = TREE_CHAIN (parmlist);
- arglist = TREE_CHAIN (arglist);
- if (TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (fn)))
- {
- parmlist = TREE_CHAIN (parmlist);
- arglist = TREE_CHAIN (arglist);
- }
- }
-
- len = list_length (arglist);
- convs = make_scratch_vec (len);
-
- /* 13.3.2 - Viable functions [over.match.viable]
- First, to be a viable function, a candidate function shall have enough
- parameters to agree in number with the arguments in the list.
-
- We need to check this first; otherwise, checking the ICSes might cause
- us to produce an ill-formed template instantiation. */
-
- parmnode = parmlist;
- for (i = 0; i < len; ++i)
- {
- if (parmnode == NULL_TREE || parmnode == void_list_node)
- break;
- parmnode = TREE_CHAIN (parmnode);
- }
-
- if (i < len && parmnode)
- viable = 0;
-
- /* Make sure there are default args for the rest of the parms. */
- else for (; parmnode && parmnode != void_list_node;
- parmnode = TREE_CHAIN (parmnode))
- if (! TREE_PURPOSE (parmnode))
- {
- viable = 0;
- break;
- }
-
- if (! viable)
- goto out;
-
- /* Second, for F to be a viable function, there shall exist for each
- argument an implicit conversion sequence that converts that argument
- to the corresponding parameter of F. */
-
- parmnode = parmlist;
- argnode = arglist;
-
- for (i = 0; i < len; ++i)
- {
- tree arg = TREE_VALUE (argnode);
- tree argtype = lvalue_type (arg);
- tree t;
-
- if (parmnode == void_list_node)
- break;
-
- if (parmnode)
- {
- tree parmtype = TREE_VALUE (parmnode);
-
- /* [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.
-
- Since build_over_call ignores the ICS for the `this' parameter,
- we can just change the parm type. */
- if (DECL_CONV_FN_P (fn) && i == 0)
- {
- parmtype
- = build_qualified_type (TREE_TYPE (argtype),
- TYPE_QUALS (TREE_TYPE (parmtype)));
- parmtype = build_pointer_type (parmtype);
- }
-
- t = implicit_conversion (parmtype, argtype, arg, flags);
- }
- else
- {
- t = build1 (IDENTITY_CONV, argtype, arg);
- ICS_ELLIPSIS_FLAG (t) = 1;
- }
-
- if (i == 0 && t && TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE
- && ! DECL_CONSTRUCTOR_P (fn))
- ICS_THIS_FLAG (t) = 1;
-
- TREE_VEC_ELT (convs, i) = t;
- if (! t)
- {
- viable = 0;
- break;
- }
-
- if (ICS_BAD_FLAG (t))
- viable = -1;
-
- if (parmnode)
- parmnode = TREE_CHAIN (parmnode);
- argnode = TREE_CHAIN (argnode);
- }
-
- out:
- return add_candidate (candidates, fn, convs, viable);
-}
-
-/* Create an overload candidate for the conversion function FN which will
- be invoked for expression OBJ, producing a pointer-to-function which
- will in turn be called with the argument list ARGLIST, and add it to
- CANDIDATES. FLAGS is passed on to implicit_conversion.
-
- Actually, we don't really care about FN; we care about the type it
- converts to. There may be multiple conversion functions that will
- convert to that type, and we rely on build_user_type_conversion_1 to
- choose the best one; so when we create our candidate, we record the type
- instead of the function. */
-
-static struct z_candidate *
-add_conv_candidate (candidates, fn, obj, arglist)
- struct z_candidate *candidates;
- tree fn, obj, arglist;
-{
- tree totype = TREE_TYPE (TREE_TYPE (fn));
- tree parmlist = TYPE_ARG_TYPES (TREE_TYPE (totype));
- int i, len = list_length (arglist) + 1;
- tree convs = make_scratch_vec (len);
- tree parmnode = parmlist;
- tree argnode = arglist;
- int viable = 1;
- int flags = LOOKUP_NORMAL;
-
- /* Don't bother looking up the same type twice. */
- if (candidates && candidates->fn == totype)
- return candidates;
-
- for (i = 0; i < len; ++i)
- {
- tree arg = i == 0 ? obj : TREE_VALUE (argnode);
- tree argtype = lvalue_type (arg);
- tree t;
-
- if (i == 0)
- t = implicit_conversion (totype, argtype, arg, flags);
- else if (parmnode == void_list_node)
- break;
- else if (parmnode)
- t = implicit_conversion (TREE_VALUE (parmnode), argtype, arg, flags);
- else
- {
- t = build1 (IDENTITY_CONV, argtype, arg);
- ICS_ELLIPSIS_FLAG (t) = 1;
- }
-
- TREE_VEC_ELT (convs, i) = t;
- if (! t)
- break;
-
- if (ICS_BAD_FLAG (t))
- viable = -1;
-
- if (i == 0)
- continue;
-
- if (parmnode)
- parmnode = TREE_CHAIN (parmnode);
- argnode = TREE_CHAIN (argnode);
- }
-
- if (i < len)
- viable = 0;
-
- for (; parmnode && parmnode != void_list_node;
- parmnode = TREE_CHAIN (parmnode))
- if (! TREE_PURPOSE (parmnode))
- {
- viable = 0;
- break;
- }
-
- return add_candidate (candidates, totype, convs, viable);
-}
-
-static struct z_candidate *
-build_builtin_candidate (candidates, fnname, type1, type2,
- args, argtypes, flags)
- struct z_candidate *candidates;
- tree fnname, type1, type2, *args, *argtypes;
- int flags;
-
-{
- tree t, convs;
- int viable = 1, i;
- tree types[2];
-
- types[0] = type1;
- types[1] = type2;
-
- convs = make_scratch_vec (args[2] ? 3 : (args[1] ? 2 : 1));
-
- for (i = 0; i < 2; ++i)
- {
- if (! args[i])
- break;
-
- t = implicit_conversion (types[i], argtypes[i], args[i], flags);
- if (! t)
- {
- viable = 0;
- /* We need something for printing the candidate. */
- t = build1 (IDENTITY_CONV, types[i], NULL_TREE);
- }
- else if (ICS_BAD_FLAG (t))
- viable = 0;
- TREE_VEC_ELT (convs, i) = t;
- }
-
- /* For COND_EXPR we rearranged the arguments; undo that now. */
- if (args[2])
- {
- TREE_VEC_ELT (convs, 2) = TREE_VEC_ELT (convs, 1);
- TREE_VEC_ELT (convs, 1) = TREE_VEC_ELT (convs, 0);
- t = implicit_conversion (boolean_type_node, argtypes[2], args[2], flags);
- if (t)
- TREE_VEC_ELT (convs, 0) = t;
- else
- viable = 0;
- }
-
- return add_candidate (candidates, fnname, convs, viable);
-}
-
-static int
-is_complete (t)
- tree t;
-{
- return TYPE_SIZE (complete_type (t)) != NULL_TREE;
-}
-
-/* Create any builtin operator overload candidates for the operator in
- question given the converted operand types TYPE1 and TYPE2. The other
- args are passed through from add_builtin_candidates to
- build_builtin_candidate. */
-
-static struct z_candidate *
-add_builtin_candidate (candidates, code, code2, fnname, type1, type2,
- args, argtypes, flags)
- struct z_candidate *candidates;
- enum tree_code code, code2;
- tree fnname, type1, type2, *args, *argtypes;
- int flags;
-{
- switch (code)
- {
- case POSTINCREMENT_EXPR:
- case POSTDECREMENT_EXPR:
- args[1] = integer_zero_node;
- type2 = integer_type_node;
- break;
- default:
- break;
- }
-
- switch (code)
- {
-
-/* 4 For every pair T, VQ), where T is an arithmetic or enumeration type,
- and VQ is either volatile or empty, there exist candidate operator
- functions of the form
- VQ T& operator++(VQ T&);
- T operator++(VQ T&, int);
- 5 For every pair T, VQ), where T is an enumeration type or an arithmetic
- type other than bool, and VQ is either volatile or empty, there exist
- candidate operator functions of the form
- VQ T& operator--(VQ T&);
- T operator--(VQ T&, int);
- 6 For every pair T, VQ), where T is a cv-qualified or cv-unqualified
- complete object type, and VQ is either volatile or empty, there exist
- candidate operator functions of the form
- T*VQ& operator++(T*VQ&);
- T*VQ& operator--(T*VQ&);
- T* operator++(T*VQ&, int);
- T* operator--(T*VQ&, int); */
-
- case POSTDECREMENT_EXPR:
- case PREDECREMENT_EXPR:
- if (TREE_CODE (type1) == BOOLEAN_TYPE)
- return candidates;
- case POSTINCREMENT_EXPR:
- case PREINCREMENT_EXPR:
- if ((ARITHMETIC_TYPE_P (type1) && TREE_CODE (type1) != ENUMERAL_TYPE)
- || TYPE_PTROB_P (type1))
- {
- type1 = build_reference_type (type1);
- break;
- }
- return candidates;
-
-/* 7 For every cv-qualified or cv-unqualified complete object type T, there
- exist candidate operator functions of the form
-
- T& operator*(T*);
-
- 8 For every function type T, there exist candidate operator functions of
- the form
- T& operator*(T*); */
-
- case INDIRECT_REF:
- if (TREE_CODE (type1) == POINTER_TYPE
- && (TYPE_PTROB_P (type1)
- || TREE_CODE (TREE_TYPE (type1)) == FUNCTION_TYPE))
- break;
- return candidates;
-
-/* 9 For every type T, there exist candidate operator functions of the form
- T* operator+(T*);
-
- 10For every promoted arithmetic type T, there exist candidate operator
- functions of the form
- T operator+(T);
- T operator-(T); */
-
- case CONVERT_EXPR: /* unary + */
- if (TREE_CODE (type1) == POINTER_TYPE
- && TREE_CODE (TREE_TYPE (type1)) != OFFSET_TYPE)
- break;
- case NEGATE_EXPR:
- if (ARITHMETIC_TYPE_P (type1))
- break;
- return candidates;
-
-/* 11For every promoted integral type T, there exist candidate operator
- functions of the form
- T operator~(T); */
-
- case BIT_NOT_EXPR:
- if (INTEGRAL_TYPE_P (type1))
- break;
- return candidates;
-
-/* 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
- object type or a function type, and CV1 and CV2 are cv-qualifier-seqs,
- there exist candidate operator functions of the form
- CV12 T& operator->*(CV1 C1*, CV2 T C2::*);
- where CV12 is the union of CV1 and CV2. */
-
- case MEMBER_REF:
- if (TREE_CODE (type1) == POINTER_TYPE
- && (TYPE_PTRMEMFUNC_P (type2) || TYPE_PTRMEM_P (type2)))
- {
- tree c1 = TREE_TYPE (type1);
- tree c2 = (TYPE_PTRMEMFUNC_P (type2)
- ? TYPE_METHOD_BASETYPE (TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (type2)))
- : TYPE_OFFSET_BASETYPE (TREE_TYPE (type2)));
-
- if (IS_AGGR_TYPE (c1) && DERIVED_FROM_P (c2, c1)
- && (TYPE_PTRMEMFUNC_P (type2)
- || is_complete (TREE_TYPE (TREE_TYPE (type2)))))
- break;
- }
- return candidates;
-
-/* 13For every pair of promoted arithmetic types L and R, there exist can-
- didate operator functions of the form
- LR operator*(L, R);
- LR operator/(L, R);
- LR operator+(L, R);
- LR operator-(L, R);
- bool operator<(L, R);
- bool operator>(L, R);
- bool operator<=(L, R);
- bool operator>=(L, R);
- bool operator==(L, R);
- bool operator!=(L, R);
- where LR is the result of the usual arithmetic conversions between
- types L and R.
-
- 14For every pair of types T and I, where T is a cv-qualified or cv-
- unqualified complete object type and I is a promoted integral type,
- there exist candidate operator functions of the form
- T* operator+(T*, I);
- T& operator[](T*, I);
- T* operator-(T*, I);
- T* operator+(I, T*);
- T& operator[](I, T*);
-
- 15For every T, where T is a pointer to complete object type, there exist
- candidate operator functions of the form112)
- ptrdiff_t operator-(T, T);
-
- 16For every pointer type T, there exist candidate operator functions of
- the form
- bool operator<(T, T);
- bool operator>(T, T);
- bool operator<=(T, T);
- bool operator>=(T, T);
- bool operator==(T, T);
- bool operator!=(T, T);
-
- 17For every pointer to member type T, there exist candidate operator
- functions of the form
- bool operator==(T, T);
- bool operator!=(T, T); */
-
- case MINUS_EXPR:
- if (TYPE_PTROB_P (type1) && TYPE_PTROB_P (type2))
- break;
- if (TYPE_PTROB_P (type1) && INTEGRAL_TYPE_P (type2))
- {
- type2 = ptrdiff_type_node;
- break;
- }
- case MULT_EXPR:
- case TRUNC_DIV_EXPR:
- if (ARITHMETIC_TYPE_P (type1) && ARITHMETIC_TYPE_P (type2))
- break;
- return candidates;
-
- case EQ_EXPR:
- case NE_EXPR:
- if ((TYPE_PTRMEMFUNC_P (type1) && TYPE_PTRMEMFUNC_P (type2))
- || (TYPE_PTRMEM_P (type1) && TYPE_PTRMEM_P (type2)))
- break;
- if ((TYPE_PTRMEMFUNC_P (type1) || TYPE_PTRMEM_P (type1))
- && null_ptr_cst_p (args[1]))
- {
- type2 = type1;
- break;
- }
- if ((TYPE_PTRMEMFUNC_P (type2) || TYPE_PTRMEM_P (type2))
- && null_ptr_cst_p (args[0]))
- {
- type1 = type2;
- break;
- }
- case LT_EXPR:
- case GT_EXPR:
- case LE_EXPR:
- case GE_EXPR:
- case MAX_EXPR:
- case MIN_EXPR:
- if ((ARITHMETIC_TYPE_P (type1) && ARITHMETIC_TYPE_P (type2))
- || (TYPE_PTR_P (type1) && TYPE_PTR_P (type2)))
- break;
- if (TYPE_PTR_P (type1) && null_ptr_cst_p (args[1]))
- {
- type2 = type1;
- break;
- }
- if (null_ptr_cst_p (args[0]) && TYPE_PTR_P (type2))
- {
- type1 = type2;
- break;
- }
- return candidates;
-
- case PLUS_EXPR:
- if (ARITHMETIC_TYPE_P (type1) && ARITHMETIC_TYPE_P (type2))
- break;
- case ARRAY_REF:
- if (INTEGRAL_TYPE_P (type1) && TYPE_PTROB_P (type2))
- {
- type1 = ptrdiff_type_node;
- break;
- }
- if (TYPE_PTROB_P (type1) && INTEGRAL_TYPE_P (type2))
- {
- type2 = ptrdiff_type_node;
- break;
- }
- return candidates;
-
-/* 18For every pair of promoted integral types L and R, there exist candi-
- date operator functions of the form
- LR operator%(L, R);
- LR operator&(L, R);
- LR operator^(L, R);
- LR operator|(L, R);
- L operator<<(L, R);
- L operator>>(L, R);
- where LR is the result of the usual arithmetic conversions between
- types L and R. */
-
- case TRUNC_MOD_EXPR:
- case BIT_AND_EXPR:
- case BIT_IOR_EXPR:
- case BIT_XOR_EXPR:
- case LSHIFT_EXPR:
- case RSHIFT_EXPR:
- if (INTEGRAL_TYPE_P (type1) && INTEGRAL_TYPE_P (type2))
- break;
- return candidates;
-
-/* 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
- type, there exist candidate operator functions of the form
- VQ L& operator=(VQ L&, R);
- VQ L& operator*=(VQ L&, R);
- VQ L& operator/=(VQ L&, R);
- VQ L& operator+=(VQ L&, R);
- VQ L& operator-=(VQ L&, R);
-
- 20For every pair T, VQ), where T is any type and VQ is either volatile
- or empty, there exist candidate operator functions of the form
- T*VQ& operator=(T*VQ&, T*);
-
- 21For every pair T, VQ), where T is a pointer to member type and VQ is
- either volatile or empty, there exist candidate operator functions of
- the form
- VQ T& operator=(VQ T&, T);
-
- 22For every triple T, VQ, I), where T is a cv-qualified or cv-
- unqualified complete object type, VQ is either volatile or empty, and
- I is a promoted integral type, there exist candidate operator func-
- tions of the form
- T*VQ& operator+=(T*VQ&, I);
- T*VQ& operator-=(T*VQ&, I);
-
- 23For every triple L, VQ, R), where L is an integral or enumeration
- type, VQ is either volatile or empty, and R is a promoted integral
- type, there exist candidate operator functions of the form
-
- VQ L& operator%=(VQ L&, R);
- VQ L& operator<<=(VQ L&, R);
- VQ L& operator>>=(VQ L&, R);
- VQ L& operator&=(VQ L&, R);
- VQ L& operator^=(VQ L&, R);
- VQ L& operator|=(VQ L&, R); */
-
- case MODIFY_EXPR:
- switch (code2)
- {
- case PLUS_EXPR:
- case MINUS_EXPR:
- if (TYPE_PTROB_P (type1) && INTEGRAL_TYPE_P (type2))
- {
- type2 = ptrdiff_type_node;
- break;
- }
- case MULT_EXPR:
- case TRUNC_DIV_EXPR:
- if (ARITHMETIC_TYPE_P (type1) && ARITHMETIC_TYPE_P (type2))
- break;
- return candidates;
-
- case TRUNC_MOD_EXPR:
- case BIT_AND_EXPR:
- case BIT_IOR_EXPR:
- case BIT_XOR_EXPR:
- case LSHIFT_EXPR:
- case RSHIFT_EXPR:
- if (INTEGRAL_TYPE_P (type1) && INTEGRAL_TYPE_P (type2))
- break;
- return candidates;
-
- case NOP_EXPR:
- if (ARITHMETIC_TYPE_P (type1) && ARITHMETIC_TYPE_P (type2))
- break;
- if ((TYPE_PTRMEMFUNC_P (type1) && TYPE_PTRMEMFUNC_P (type2))
- || (TYPE_PTR_P (type1) && TYPE_PTR_P (type2))
- || (TYPE_PTRMEM_P (type1) && TYPE_PTRMEM_P (type2))
- || ((TYPE_PTRMEMFUNC_P (type1)
- || TREE_CODE (type1) == POINTER_TYPE)
- && null_ptr_cst_p (args[1])))
- {
- type2 = type1;
- break;
- }
- return candidates;
-
- default:
- my_friendly_abort (367);
- }
- type1 = build_reference_type (type1);
- break;
-
- case COND_EXPR:
- /* Kludge around broken overloading rules whereby
- bool ? const char& : enum is ambiguous
- (between int and const char&). */
- flags |= LOOKUP_NO_TEMP_BIND;
-
- /* Extension: Support ?: of enumeral type. Hopefully this will not
- be an extension for long. */
- if (TREE_CODE (type1) == ENUMERAL_TYPE && type1 == type2)
- break;
- else if (TREE_CODE (type1) == ENUMERAL_TYPE
- || TREE_CODE (type2) == ENUMERAL_TYPE)
- return candidates;
- if (ARITHMETIC_TYPE_P (type1) && ARITHMETIC_TYPE_P (type2))
- break;
- if (TREE_CODE (type1) == TREE_CODE (type2)
- && (TREE_CODE (type1) == REFERENCE_TYPE
- || TREE_CODE (type1) == POINTER_TYPE
- || TYPE_PTRMEMFUNC_P (type1)
- || IS_AGGR_TYPE (type1)))
- break;
- if (TREE_CODE (type1) == REFERENCE_TYPE
- || TREE_CODE (type2) == REFERENCE_TYPE)
- return candidates;
- if (((TYPE_PTRMEMFUNC_P (type1) || TREE_CODE (type1) == POINTER_TYPE)
- && null_ptr_cst_p (args[1]))
- || IS_AGGR_TYPE (type1))
- {
- type2 = type1;
- break;
- }
- if (((TYPE_PTRMEMFUNC_P (type2) || TREE_CODE (type2) == POINTER_TYPE)
- && null_ptr_cst_p (args[0]))
- || IS_AGGR_TYPE (type2))
- {
- type1 = type2;
- break;
- }
- return candidates;
-
- default:
- my_friendly_abort (367);
- }
-
- /* If we're dealing with two pointer types, we need candidates
- for both of them. */
- if (type2 && type1 != type2
- && TREE_CODE (type1) == TREE_CODE (type2)
- && (TREE_CODE (type1) == REFERENCE_TYPE
- || (TREE_CODE (type1) == POINTER_TYPE
- && TYPE_PTRMEM_P (type1) == TYPE_PTRMEM_P (type2))
- || TYPE_PTRMEMFUNC_P (type1)
- || IS_AGGR_TYPE (type1)))
- {
- candidates = build_builtin_candidate
- (candidates, fnname, type1, type1, args, argtypes, flags);
- return build_builtin_candidate
- (candidates, fnname, type2, type2, args, argtypes, flags);
- }
-
- return build_builtin_candidate
- (candidates, fnname, type1, type2, args, argtypes, flags);
-}
-
-tree
-type_decays_to (type)
- tree type;
-{
- if (TREE_CODE (type) == ARRAY_TYPE)
- return build_pointer_type (TREE_TYPE (type));
- if (TREE_CODE (type) == FUNCTION_TYPE)
- return build_pointer_type (type);
- return type;
-}
-
-/* There are three conditions of builtin candidates:
-
- 1) bool-taking candidates. These are the same regardless of the input.
- 2) pointer-pair taking candidates. These are generated for each type
- one of the input types converts to.
- 3) arithmetic candidates. According to the WP, we should generate
- all of these, but I'm trying not to... */
-
-static struct z_candidate *
-add_builtin_candidates (candidates, code, code2, fnname, args, flags)
- struct z_candidate *candidates;
- enum tree_code code, code2;
- tree fnname, *args;
- int flags;
-{
- int ref1, i;
- tree type, argtypes[3], types[2];
-
- for (i = 0; i < 3; ++i)
- {
- if (args[i])
- argtypes[i] = lvalue_type (args[i]);
- else
- argtypes[i] = NULL_TREE;
- }
-
- switch (code)
- {
-/* 4 For every pair T, VQ), where T is an arithmetic or enumeration type,
- and VQ is either volatile or empty, there exist candidate operator
- functions of the form
- VQ T& operator++(VQ T&); */
-
- case POSTINCREMENT_EXPR:
- case PREINCREMENT_EXPR:
- case POSTDECREMENT_EXPR:
- case PREDECREMENT_EXPR:
- case MODIFY_EXPR:
- ref1 = 1;
- break;
-
-/* 24There also exist candidate operator functions of the form
- bool operator!(bool);
- bool operator&&(bool, bool);
- bool operator||(bool, bool); */
-
- case TRUTH_NOT_EXPR:
- return build_builtin_candidate
- (candidates, fnname, boolean_type_node,
- NULL_TREE, args, argtypes, flags);
-
- case TRUTH_ORIF_EXPR:
- case TRUTH_ANDIF_EXPR:
- return build_builtin_candidate
- (candidates, fnname, boolean_type_node,
- boolean_type_node, args, argtypes, flags);
-
- case ADDR_EXPR:
- case COMPOUND_EXPR:
- case COMPONENT_REF:
- return candidates;
-
- default:
- ref1 = 0;
- }
-
- types[0] = types[1] = NULL_TREE;
-
- for (i = 0; i < 2; ++i)
- {
- if (! args[i])
- ;
- else if (IS_AGGR_TYPE (argtypes[i]))
- {
- tree convs;
-
- if (i == 0 && code == MODIFY_EXPR && code2 == NOP_EXPR)
- return candidates;
-
- convs = lookup_conversions (argtypes[i]);
-
- if (code == COND_EXPR)
- {
- if (real_lvalue_p (args[i]))
- types[i] = scratch_tree_cons
- (NULL_TREE, build_reference_type (argtypes[i]), types[i]);
-
- types[i] = scratch_tree_cons
- (NULL_TREE, TYPE_MAIN_VARIANT (argtypes[i]), types[i]);
- }
-
- else if (! convs)
- return candidates;
-
- for (; convs; convs = TREE_CHAIN (convs))
- {
- type = TREE_TYPE (TREE_TYPE (OVL_CURRENT (TREE_VALUE (convs))));
-
- if (i == 0 && ref1
- && (TREE_CODE (type) != REFERENCE_TYPE
- || CP_TYPE_CONST_P (TREE_TYPE (type))))
- continue;
-
- if (code == COND_EXPR && TREE_CODE (type) == REFERENCE_TYPE)
- types[i] = scratch_tree_cons (NULL_TREE, type, types[i]);
-
- type = non_reference (type);
- if (i != 0 || ! ref1)
- {
- type = TYPE_MAIN_VARIANT (type_decays_to (type));
- if (code == COND_EXPR && TREE_CODE (type) == ENUMERAL_TYPE)
- types[i] = scratch_tree_cons (NULL_TREE, type, types[i]);
- if (INTEGRAL_TYPE_P (type))
- type = type_promotes_to (type);
- }
-
- if (! value_member (type, types[i]))
- types[i] = scratch_tree_cons (NULL_TREE, type, types[i]);
- }
- }
- else
- {
- if (code == COND_EXPR && real_lvalue_p (args[i]))
- types[i] = scratch_tree_cons
- (NULL_TREE, build_reference_type (argtypes[i]), types[i]);
- type = non_reference (argtypes[i]);
- if (i != 0 || ! ref1)
- {
- type = TYPE_MAIN_VARIANT (type_decays_to (type));
- if (code == COND_EXPR && TREE_CODE (type) == ENUMERAL_TYPE)
- types[i] = scratch_tree_cons (NULL_TREE, type, types[i]);
- if (INTEGRAL_TYPE_P (type))
- type = type_promotes_to (type);
- }
- types[i] = scratch_tree_cons (NULL_TREE, type, types[i]);
- }
- }
-
- for (; types[0]; types[0] = TREE_CHAIN (types[0]))
- {
- if (types[1])
- for (type = types[1]; type; type = TREE_CHAIN (type))
- candidates = add_builtin_candidate
- (candidates, code, code2, fnname, TREE_VALUE (types[0]),
- TREE_VALUE (type), args, argtypes, flags);
- else
- candidates = add_builtin_candidate
- (candidates, code, code2, fnname, TREE_VALUE (types[0]),
- NULL_TREE, args, argtypes, flags);
- }
-
- return candidates;
-}
-
-
-/* If TMPL can be successfully instantiated as indicated by
- EXPLICIT_TARGS and ARGLIST, adds the instantiation to CANDIDATES.
-
- TMPL is the template. EXPLICIT_TARGS are any explicit template
- arguments. ARGLIST is the arguments provided at the call-site.
- The RETURN_TYPE is the desired type for conversion operators. If
- OBJ is NULL_TREE, FLAGS are as for add_function_candidate. If an
- OBJ is supplied, FLAGS are ignored, and OBJ is as for
- add_conv_candidate. */
-
-static struct z_candidate*
-add_template_candidate_real (candidates, tmpl, explicit_targs,
- arglist, return_type, flags,
- obj, strict)
- struct z_candidate *candidates;
- tree tmpl, explicit_targs, arglist, return_type;
- int flags;
- tree obj;
- unification_kind_t strict;
-{
- int ntparms = DECL_NTPARMS (tmpl);
- tree targs = make_scratch_vec (ntparms);
- struct z_candidate *cand;
- int i;
- tree fn;
-
- i = fn_type_unification (tmpl, explicit_targs, targs, arglist,
- return_type, strict);
-
- if (i != 0)
- return candidates;
-
- fn = instantiate_template (tmpl, targs);
- if (fn == error_mark_node)
- return candidates;
-
- if (obj != NULL_TREE)
- /* Aha, this is a conversion function. */
- cand = add_conv_candidate (candidates, fn, obj, arglist);
- else
- cand = add_function_candidate (candidates, fn, arglist, 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
- an instantiation of the specialization, in which case the
- DECL_TI_TEMPLATE field will point at the original
- specialization. For example:
-
- template <class T> struct S { template <class U> void f(U);
- template <> void f(int) {}; };
- S<double> sd;
- sd.f(3);
-
- Here, TMPL will be template <class U> S<double>::f(U).
- And, instantiate template will give us the specialization
- template <> S<double>::f(int). But, the DECL_TI_TEMPLATE field
- for this will point at template <class T> template <> S<T>::f(int),
- so that we can find the definition. For the purposes of
- overload resolution, however, we want the original TMPL. */
- cand->template = tree_cons (tmpl, targs, NULL_TREE);
- else
- cand->template = DECL_TEMPLATE_INFO (fn);
-
- return cand;
-}
-
-
-static struct z_candidate *
-add_template_candidate (candidates, tmpl, explicit_targs,
- arglist, return_type, flags, strict)
- struct z_candidate *candidates;
- tree tmpl, explicit_targs, arglist, return_type;
- int flags;
- unification_kind_t strict;
-{
- return
- add_template_candidate_real (candidates, tmpl, explicit_targs,
- arglist, return_type, flags,
- NULL_TREE, strict);
-}
-
-
-static struct z_candidate *
-add_template_conv_candidate (candidates, tmpl, obj, arglist, return_type)
- struct z_candidate *candidates;
- tree tmpl, obj, arglist, return_type;
-{
- return
- add_template_candidate_real (candidates, tmpl, NULL_TREE, arglist,
- return_type, 0, obj, DEDUCE_CONV);
-}
-
-
-static int
-any_viable (cands)
- struct z_candidate *cands;
-{
- for (; cands; cands = cands->next)
- if (pedantic ? cands->viable == 1 : cands->viable)
- return 1;
- return 0;
-}
-
-static struct z_candidate *
-splice_viable (cands)
- struct z_candidate *cands;
-{
- struct z_candidate **p = &cands;
-
- for (; *p; )
- {
- if (pedantic ? (*p)->viable == 1 : (*p)->viable)
- p = &((*p)->next);
- else
- *p = (*p)->next;
- }
-
- return cands;
-}
-
-static tree
-build_this (obj)
- tree obj;
-{
- /* Fix this to work on non-lvalues. */
- if (IS_SIGNATURE_POINTER (TREE_TYPE (obj))
- || IS_SIGNATURE_REFERENCE (TREE_TYPE (obj)))
- return obj;
- else
- return build_unary_op (ADDR_EXPR, obj, 0);
-}
-
-static void
-print_z_candidates (candidates)
- struct z_candidate *candidates;
-{
- const char *str = "candidates are:";
- for (; candidates; candidates = candidates->next)
- {
- if (TREE_CODE (candidates->fn) == IDENTIFIER_NODE)
- {
- if (candidates->fn == ansi_opname [COND_EXPR])
- cp_error ("%s %D(%T, %T, %T) <builtin>", str, candidates->fn,
- TREE_TYPE (TREE_VEC_ELT (candidates->convs, 0)),
- TREE_TYPE (TREE_VEC_ELT (candidates->convs, 1)),
- TREE_TYPE (TREE_VEC_ELT (candidates->convs, 2)));
- else if (TREE_VEC_LENGTH (candidates->convs) == 2)
- cp_error ("%s %D(%T, %T) <builtin>", str, candidates->fn,
- TREE_TYPE (TREE_VEC_ELT (candidates->convs, 0)),
- TREE_TYPE (TREE_VEC_ELT (candidates->convs, 1)));
- else
- cp_error ("%s %D(%T) <builtin>", str, candidates->fn,
- TREE_TYPE (TREE_VEC_ELT (candidates->convs, 0)));
- }
- else if (TYPE_P (candidates->fn))
- cp_error ("%s %T <conversion>", str, candidates->fn);
- else
- cp_error_at ("%s %+#D%s", str, candidates->fn,
- candidates->viable == -1 ? " <near match>" : "");
- str = " ";
- }
-}
-
-/* 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].
- If TOTYPE is a REFERENCE_TYPE, we're trying to find an lvalue binding as
- per [dcl.init.ref], so we ignore temporary bindings. */
-
-static struct z_candidate *
-build_user_type_conversion_1 (totype, expr, flags)
- tree totype, expr;
- int flags;
-{
- struct z_candidate *candidates, *cand;
- tree fromtype = TREE_TYPE (expr);
- tree ctors = NULL_TREE, convs = NULL_TREE, *p;
- tree args = NULL_TREE;
- tree templates = NULL_TREE;
-
- if (IS_AGGR_TYPE (totype))
- ctors = lookup_fnfields (TYPE_BINFO (totype), ctor_identifier, 0);
- if (IS_AGGR_TYPE (fromtype)
- && (! IS_AGGR_TYPE (totype) || ! DERIVED_FROM_P (totype, fromtype)))
- convs = lookup_conversions (fromtype);
-
- candidates = 0;
- flags |= LOOKUP_NO_CONVERSION;
-
- if (ctors)
- {
- tree t = build_int_2 (0, 0);
- TREE_TYPE (t) = build_pointer_type (totype);
- args = build_scratch_list (NULL_TREE, expr);
- if (TYPE_USES_VIRTUAL_BASECLASSES (totype))
- args = scratch_tree_cons (NULL_TREE, integer_one_node, args);
- args = scratch_tree_cons (NULL_TREE, t, args);
-
- ctors = TREE_VALUE (ctors);
- }
- for (; ctors; ctors = OVL_NEXT (ctors))
- {
- tree ctor = OVL_CURRENT (ctors);
- if (DECL_NONCONVERTING_P (ctor))
- continue;
-
- if (TREE_CODE (ctor) == TEMPLATE_DECL)
- {
- templates = scratch_tree_cons (NULL_TREE, ctor, templates);
- candidates =
- add_template_candidate (candidates, ctor,
- NULL_TREE, args, NULL_TREE, flags,
- DEDUCE_CALL);
- }
- else
- candidates = add_function_candidate (candidates, ctor,
- args, flags);
-
- if (candidates)
- {
- candidates->second_conv = build1 (IDENTITY_CONV, totype, NULL_TREE);
- candidates->basetype_path = TYPE_BINFO (totype);
- }
- }
-
- if (convs)
- args = build_scratch_list (NULL_TREE, build_this (expr));
-
- for (; convs; convs = TREE_CHAIN (convs))
- {
- tree fns = TREE_VALUE (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
- we don't find an lvalue binding, the caller will try again to
- look for a temporary binding. */
- if (TREE_CODE (totype) == REFERENCE_TYPE)
- convflags |= LOOKUP_NO_TEMP_BIND;
-
- 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;
-
- 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;
-
- if (TREE_CODE (fn) == TEMPLATE_DECL)
- {
- templates = scratch_tree_cons (NULL_TREE, fn, templates);
- candidates =
- add_template_candidate (candidates, fn, NULL_TREE,
- args, totype, flags,
- DEDUCE_CONV);
- }
- else
- candidates = add_function_candidate (candidates, fn,
- 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 = TREE_PURPOSE (convs);
-
- if (ics == NULL_TREE)
- candidates->viable = 0;
- else if (candidates->viable == 1 && ICS_BAD_FLAG (ics))
- candidates->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
- cp_error ("no viable candidates");
- }
-#endif
-
- return 0;
- }
-
- candidates = splice_viable (candidates);
- cand = tourney (candidates);
-
- if (cand == 0)
- {
- if (flags & LOOKUP_COMPLAIN)
- {
- cp_error ("conversion from `%T' to `%T' is ambiguous",
- fromtype, totype);
- print_z_candidates (candidates);
- }
-
- 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;
-
- return cand;
- }
-
- for (p = &(cand->second_conv); TREE_CODE (*p) != IDENTITY_CONV; )
- p = &(TREE_OPERAND (*p, 0));
-
- /* Pedantically, normal function declarations are never considered
- to refer to template instantiations, so we only do this with
- -fguiding-decls. */
- if (flag_guiding_decls && templates && ! cand->template
- && !DECL_INITIAL (cand->fn)
- && TREE_CODE (TREE_TYPE (cand->fn)) != METHOD_TYPE)
- add_maybe_template (cand->fn, templates);
-
- *p = build
- (USER_CONV,
- (DECL_CONSTRUCTOR_P (cand->fn)
- ? totype : non_reference (TREE_TYPE (TREE_TYPE (cand->fn)))),
- expr, build_expr_ptr_wrapper (cand));
- ICS_USER_FLAG (cand->second_conv) = 1;
- if (cand->viable == -1)
- ICS_BAD_FLAG (cand->second_conv) = 1;
-
- return cand;
-}
-
-tree
-build_user_type_conversion (totype, expr, flags)
- tree totype, expr;
- int flags;
-{
- struct z_candidate *cand
- = build_user_type_conversion_1 (totype, expr, flags);
-
- if (cand)
- {
- if (TREE_CODE (cand->second_conv) == AMBIG_CONV)
- return error_mark_node;
- return convert_from_reference (convert_like (cand->second_conv, expr));
- }
- return NULL_TREE;
-}
-
-/* Do any initial processing on the arguments to a function call. */
-
-static tree
-resolve_args (args)
- tree args;
-{
- tree t;
- for (t = args; t; t = TREE_CHAIN (t))
- {
- if (TREE_VALUE (t) == error_mark_node)
- return error_mark_node;
- else if (TREE_CODE (TREE_TYPE (TREE_VALUE (t))) == VOID_TYPE)
- {
- error ("invalid use of void expression");
- return error_mark_node;
- }
- else if (TREE_CODE (TREE_VALUE (t)) == OFFSET_REF)
- TREE_VALUE (t) = resolve_offset_ref (TREE_VALUE (t));
- }
- return args;
-}
-
-tree
-build_new_function_call (fn, args)
- tree fn, args;
-{
- struct z_candidate *candidates = 0, *cand;
- tree explicit_targs = NULL_TREE;
- int template_only = 0;
-
- if (TREE_CODE (fn) == TEMPLATE_ID_EXPR)
- {
- explicit_targs = TREE_OPERAND (fn, 1);
- fn = TREE_OPERAND (fn, 0);
- template_only = 1;
- }
-
- if (really_overloaded_fn (fn))
- {
- 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))
- {
- tree t = OVL_FUNCTION (t1);
- struct z_candidate *old_candidates = candidates;
-
- if (TREE_CODE (t) == TEMPLATE_DECL)
- {
- templates = scratch_tree_cons (NULL_TREE, t, templates);
- candidates = add_template_candidate
- (candidates, t, explicit_targs, args, NULL_TREE,
- LOOKUP_NORMAL, DEDUCE_CALL);
- }
- else if (! template_only)
- candidates = add_function_candidate
- (candidates, t, args, LOOKUP_NORMAL);
-
- if (candidates != old_candidates)
- candidates->basetype_path = DECL_REAL_CONTEXT (t);
- }
-
- if (! any_viable (candidates))
- {
- if (candidates && ! candidates->next)
- return build_function_call (candidates->fn, args);
- cp_error ("no matching function for call to `%D (%A)'",
- DECL_NAME (OVL_FUNCTION (fn)), args);
- if (candidates)
- print_z_candidates (candidates);
- return error_mark_node;
- }
- candidates = splice_viable (candidates);
- cand = tourney (candidates);
-
- if (cand == 0)
- {
- cp_error ("call of overloaded `%D (%A)' is ambiguous",
- DECL_NAME (OVL_FUNCTION (fn)), args);
- print_z_candidates (candidates);
- return error_mark_node;
- }
-
- /* Pedantically, normal function declarations are never considered
- to refer to template instantiations, so we only do this with
- -fguiding-decls. */
- if (flag_guiding_decls && templates && ! cand->template
- && ! DECL_INITIAL (cand->fn))
- add_maybe_template (cand->fn, templates);
-
- return build_over_call (cand, args, LOOKUP_NORMAL);
- }
-
- /* This is not really overloaded. */
- fn = OVL_CURRENT (fn);
-
- return build_function_call (fn, args);
-}
-
-static tree
-build_object_call (obj, args)
- tree obj, args;
-{
- struct z_candidate *candidates = 0, *cand;
- tree fns, convs, mem_args = NULL_TREE;
- tree type = TREE_TYPE (obj);
-
- if (TYPE_PTRMEMFUNC_P (type))
- {
- /* It's no good looking for an overloaded operator() on a
- pointer-to-member-function. */
- cp_error ("pointer-to-member function %E cannot be called", obj);
- cp_error ("without an object; consider using .* or ->*");
- return error_mark_node;
- }
-
- fns = lookup_fnfields (TYPE_BINFO (type), ansi_opname [CALL_EXPR], 1);
- if (fns == error_mark_node)
- return error_mark_node;
-
- args = resolve_args (args);
-
- if (args == error_mark_node)
- return error_mark_node;
-
- if (fns)
- {
- tree base = TREE_PURPOSE (fns);
- mem_args = scratch_tree_cons (NULL_TREE, build_this (obj), args);
-
- for (fns = TREE_VALUE (fns); fns; fns = OVL_NEXT (fns))
- {
- tree fn = OVL_CURRENT (fns);
- if (TREE_CODE (fn) == TEMPLATE_DECL)
- {
- candidates
- = add_template_candidate (candidates, fn, NULL_TREE,
- mem_args, NULL_TREE,
- LOOKUP_NORMAL, DEDUCE_CALL);
- }
- else
- candidates = add_function_candidate
- (candidates, fn, mem_args, LOOKUP_NORMAL);
-
- if (candidates)
- candidates->basetype_path = base;
- }
- }
-
- convs = lookup_conversions (type);
-
- for (; convs; convs = TREE_CHAIN (convs))
- {
- tree fns = TREE_VALUE (convs);
- tree totype = TREE_TYPE (TREE_TYPE (OVL_CURRENT (fns)));
-
- if ((TREE_CODE (totype) == POINTER_TYPE
- || TREE_CODE (totype) == REFERENCE_TYPE)
- && TREE_CODE (TREE_TYPE (totype)) == FUNCTION_TYPE)
- for (; fns; fns = OVL_NEXT (fns))
- {
- tree fn = OVL_CURRENT (fns);
- if (TREE_CODE (fn) == TEMPLATE_DECL)
- {
- candidates = add_template_conv_candidate (candidates,
- fn,
- obj,
- args,
- totype);
- }
- else
- candidates = add_conv_candidate (candidates, fn, obj, args);
-
- if (candidates)
- candidates->basetype_path = TREE_PURPOSE (convs);
- }
- }
-
- if (! any_viable (candidates))
- {
- cp_error ("no match for call to `(%T) (%A)'", TREE_TYPE (obj), args);
- print_z_candidates (candidates);
- return error_mark_node;
- }
-
- candidates = splice_viable (candidates);
- cand = tourney (candidates);
-
- if (cand == 0)
- {
- cp_error ("call of `(%T) (%A)' is ambiguous", TREE_TYPE (obj), args);
- print_z_candidates (candidates);
- return error_mark_node;
- }
-
- /* Since cand->fn will be a type, not a function, for a conversion
- function, we must be careful not to unconditionally look at
- DECL_NAME here. */
- if (TREE_CODE (cand->fn) == FUNCTION_DECL
- && DECL_NAME (cand->fn) == ansi_opname [CALL_EXPR])
- return build_over_call (cand, mem_args, LOOKUP_NORMAL);
-
- obj = convert_like (TREE_VEC_ELT (cand->convs, 0), obj);
-
- /* FIXME */
- return build_function_call (obj, args);
-}
-
-static void
-op_error (code, code2, arg1, arg2, arg3, problem)
- enum tree_code code, code2;
- tree arg1, arg2, arg3;
- const char *problem;
-{
- const char * opname
- = (code == MODIFY_EXPR ? assignop_tab [code2] : opname_tab [code]);
-
- switch (code)
- {
- case COND_EXPR:
- cp_error ("%s for `%T ? %T : %T'", problem,
- error_type (arg1), error_type (arg2), error_type (arg3));
- break;
- case POSTINCREMENT_EXPR:
- case POSTDECREMENT_EXPR:
- cp_error ("%s for `%T%s'", problem, error_type (arg1), opname);
- break;
- case ARRAY_REF:
- cp_error ("%s for `%T[%T]'", problem,
- error_type (arg1), error_type (arg2));
- break;
- default:
- if (arg2)
- cp_error ("%s for `%T %s %T'", problem,
- error_type (arg1), opname, error_type (arg2));
- else
- cp_error ("%s for `%s%T'", problem, opname, error_type (arg1));
- }
-}
-
-tree
-build_new_op (code, flags, arg1, arg2, arg3)
- enum tree_code code;
- int flags;
- tree 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;
-
- if (arg1 == error_mark_node
- || arg2 == error_mark_node
- || arg3 == error_mark_node)
- return error_mark_node;
-
- /* This can happen if a template takes all non-type parameters, e.g.
- undeclared_template<1, 5, 72>a; */
- if (code == LT_EXPR && TREE_CODE (arg1) == TEMPLATE_DECL)
- {
- cp_error ("`%D' must be declared before use", arg1);
- return error_mark_node;
- }
-
- if (code == MODIFY_EXPR)
- {
- code2 = TREE_CODE (arg3);
- arg3 = NULL_TREE;
- fnname = ansi_assopname[code2];
- }
- else
- fnname = ansi_opname[code];
-
- switch (code)
- {
- case NEW_EXPR:
- case VEC_NEW_EXPR:
- case VEC_DELETE_EXPR:
- case DELETE_EXPR:
- /* Use build_op_new_call and build_op_delete_call instead. */
- my_friendly_abort (981018);
-
- case CALL_EXPR:
- return build_object_call (arg1, arg2);
-
- default:
- break;
- }
-
- /* The comma operator can have void args. */
- if (TREE_CODE (arg1) == OFFSET_REF)
- arg1 = resolve_offset_ref (arg1);
- if (arg2 && TREE_CODE (arg2) == OFFSET_REF)
- arg2 = resolve_offset_ref (arg2);
- if (arg3 && TREE_CODE (arg3) == OFFSET_REF)
- arg3 = resolve_offset_ref (arg3);
-
- if (code == COND_EXPR)
- {
- if (arg2 == NULL_TREE
- || TREE_CODE (TREE_TYPE (arg2)) == VOID_TYPE
- || TREE_CODE (TREE_TYPE (arg3)) == VOID_TYPE
- || (! IS_OVERLOAD_TYPE (TREE_TYPE (arg2))
- && ! IS_OVERLOAD_TYPE (TREE_TYPE (arg3))))
- goto builtin;
- }
- else if (! IS_OVERLOAD_TYPE (TREE_TYPE (arg1))
- && (! arg2 || ! IS_OVERLOAD_TYPE (TREE_TYPE (arg2))))
- goto builtin;
-
- if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
- arg2 = integer_zero_node;
-
- if (arg2 && arg3)
- arglist = scratch_tree_cons (NULL_TREE, arg1, scratch_tree_cons
- (NULL_TREE, arg2, build_scratch_list (NULL_TREE, arg3)));
- else if (arg2)
- arglist = scratch_tree_cons (NULL_TREE, arg1, build_scratch_list (NULL_TREE, arg2));
- else
- arglist = build_scratch_list (NULL_TREE, arg1);
-
- fns = lookup_function_nonclass (fnname, arglist);
-
- if (fns && TREE_CODE (fns) == TREE_LIST)
- fns = TREE_VALUE (fns);
- for (; fns; fns = OVL_NEXT (fns))
- {
- tree fn = OVL_CURRENT (fns);
- if (TREE_CODE (fn) == TEMPLATE_DECL)
- {
- templates = scratch_tree_cons (NULL_TREE, fn, templates);
- candidates
- = add_template_candidate (candidates, fn, NULL_TREE,
- arglist, TREE_TYPE (fnname),
- flags, DEDUCE_CALL);
- }
- else
- candidates = add_function_candidate (candidates, fn, arglist, flags);
- }
-
- if (IS_AGGR_TYPE (TREE_TYPE (arg1)))
- {
- fns = lookup_fnfields (TYPE_BINFO (TREE_TYPE (arg1)), fnname, 1);
- if (fns == error_mark_node)
- return fns;
- }
- else
- fns = NULL_TREE;
-
- if (fns)
- {
- tree basetype = TREE_PURPOSE (fns);
- mem_arglist = scratch_tree_cons (NULL_TREE, build_this (arg1), TREE_CHAIN (arglist));
- for (fns = TREE_VALUE (fns); fns; fns = OVL_NEXT (fns))
- {
- tree fn = OVL_CURRENT (fns);
- tree this_arglist;
-
- if (TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE)
- this_arglist = mem_arglist;
- else
- this_arglist = arglist;
-
- if (TREE_CODE (fn) == TEMPLATE_DECL)
- {
- /* A member template. */
- templates = scratch_tree_cons (NULL_TREE, fn, templates);
- candidates
- = add_template_candidate (candidates, fn, NULL_TREE,
- this_arglist, TREE_TYPE (fnname),
- flags, DEDUCE_CALL);
- }
- else
- candidates = add_function_candidate
- (candidates, fn, this_arglist, flags);
-
- if (candidates)
- candidates->basetype_path = basetype;
- }
- }
-
- {
- tree args[3];
-
- /* Rearrange the arguments for ?: so that add_builtin_candidate only has
- to know about two args; a builtin candidate will always have a first
- parameter of type bool. We'll handle that in
- build_builtin_candidate. */
- if (code == COND_EXPR)
- {
- args[0] = arg2;
- args[1] = arg3;
- args[2] = arg1;
- }
- else
- {
- args[0] = arg1;
- args[1] = arg2;
- args[2] = NULL_TREE;
- }
-
- candidates = add_builtin_candidates
- (candidates, code, code2, fnname, args, flags);
- }
-
- if (! any_viable (candidates))
- {
- switch (code)
- {
- case POSTINCREMENT_EXPR:
- case POSTDECREMENT_EXPR:
- /* Look for an `operator++ (int)'. If they didn't have
- one, then we fall back to the old way of doing things. */
- if (flags & LOOKUP_COMPLAIN)
- cp_pedwarn ("no `%D (int)' declared for postfix `%s', trying prefix operator instead",
- fnname, opname_tab [code]);
- if (code == POSTINCREMENT_EXPR)
- code = PREINCREMENT_EXPR;
- else
- code = PREDECREMENT_EXPR;
- return build_new_op (code, flags, arg1, NULL_TREE, NULL_TREE);
-
- /* The caller will deal with these. */
- case ADDR_EXPR:
- case COMPOUND_EXPR:
- case COMPONENT_REF:
- return NULL_TREE;
-
- default:
- break;
- }
- if (flags & LOOKUP_COMPLAIN)
- {
- op_error (code, code2, arg1, arg2, arg3, "no match");
- print_z_candidates (candidates);
- }
- return error_mark_node;
- }
- candidates = splice_viable (candidates);
- cand = tourney (candidates);
-
- if (cand == 0)
- {
- if (flags & LOOKUP_COMPLAIN)
- {
- op_error (code, code2, arg1, arg2, arg3, "ambiguous overload");
- print_z_candidates (candidates);
- }
- return error_mark_node;
- }
-
- if (TREE_CODE (cand->fn) == FUNCTION_DECL)
- {
- extern int warn_synth;
- if (warn_synth
- && fnname == ansi_opname[MODIFY_EXPR]
- && DECL_ARTIFICIAL (cand->fn)
- && candidates->next
- && ! candidates->next->next)
- {
- cp_warning ("using synthesized `%#D' for copy assignment",
- cand->fn);
- cp_warning_at (" where cfront would use `%#D'",
- cand == candidates
- ? candidates->next->fn
- : candidates->fn);
- }
-
- /* Pedantically, normal function declarations are never considered
- to refer to template instantiations, so we only do this with
- -fguiding-decls. */
- if (flag_guiding_decls && templates && ! cand->template
- && ! DECL_INITIAL (cand->fn)
- && TREE_CODE (TREE_TYPE (cand->fn)) != METHOD_TYPE)
- add_maybe_template (cand->fn, templates);
-
- return build_over_call
- (cand,
- TREE_CODE (TREE_TYPE (cand->fn)) == METHOD_TYPE
- ? mem_arglist : arglist,
- LOOKUP_NORMAL);
- }
-
- /* Check for comparison of different enum types. */
- switch (code)
- {
- case GT_EXPR:
- case LT_EXPR:
- case GE_EXPR:
- case LE_EXPR:
- case EQ_EXPR:
- case NE_EXPR:
- if (TREE_CODE (TREE_TYPE (arg1)) == ENUMERAL_TYPE
- && TREE_CODE (TREE_TYPE (arg2)) == ENUMERAL_TYPE
- && (TYPE_MAIN_VARIANT (TREE_TYPE (arg1))
- != TYPE_MAIN_VARIANT (TREE_TYPE (arg2))))
- {
- cp_warning ("comparison between `%#T' and `%#T'",
- TREE_TYPE (arg1), TREE_TYPE (arg2));
- }
- break;
- default:
- break;
- }
-
- /* We need to strip any leading REF_BIND so that bitfields don't cause
- errors. This should not remove any important conversions, because
- builtins don't apply to class objects directly. */
- conv = TREE_VEC_ELT (cand->convs, 0);
- if (TREE_CODE (conv) == REF_BIND)
- conv = TREE_OPERAND (conv, 0);
- arg1 = convert_like (conv, arg1);
- if (arg2)
- {
- conv = TREE_VEC_ELT (cand->convs, 1);
- if (TREE_CODE (conv) == REF_BIND)
- conv = TREE_OPERAND (conv, 0);
- arg2 = convert_like (conv, arg2);
- }
- if (arg3)
- {
- conv = TREE_VEC_ELT (cand->convs, 2);
- if (TREE_CODE (conv) == REF_BIND)
- conv = TREE_OPERAND (conv, 0);
- arg3 = convert_like (conv, arg3);
- }
-
-builtin:
- switch (code)
- {
- case MODIFY_EXPR:
- return build_modify_expr (arg1, code2, arg2);
-
- case INDIRECT_REF:
- return build_indirect_ref (arg1, "unary *");
-
- case PLUS_EXPR:
- case MINUS_EXPR:
- case MULT_EXPR:
- case TRUNC_DIV_EXPR:
- case GT_EXPR:
- case LT_EXPR:
- case GE_EXPR:
- case LE_EXPR:
- case EQ_EXPR:
- case NE_EXPR:
- case MAX_EXPR:
- case MIN_EXPR:
- case LSHIFT_EXPR:
- case RSHIFT_EXPR:
- case TRUNC_MOD_EXPR:
- case BIT_AND_EXPR:
- case BIT_IOR_EXPR:
- case BIT_XOR_EXPR:
- case TRUTH_ANDIF_EXPR:
- case TRUTH_ORIF_EXPR:
- return build_binary_op_nodefault (code, arg1, arg2, code);
-
- case CONVERT_EXPR:
- case NEGATE_EXPR:
- case BIT_NOT_EXPR:
- case TRUTH_NOT_EXPR:
- case PREINCREMENT_EXPR:
- case POSTINCREMENT_EXPR:
- case PREDECREMENT_EXPR:
- case POSTDECREMENT_EXPR:
- case REALPART_EXPR:
- case IMAGPART_EXPR:
- return build_unary_op (code, arg1, candidates != 0);
-
- case ARRAY_REF:
- return build_array_ref (arg1, arg2);
-
- case COND_EXPR:
- return build_conditional_expr (arg1, arg2, arg3);
-
- case MEMBER_REF:
- return build_m_component_ref
- (build_indirect_ref (arg1, NULL_PTR), arg2);
-
- /* The caller will deal with these. */
- case ADDR_EXPR:
- case COMPONENT_REF:
- case COMPOUND_EXPR:
- return NULL_TREE;
-
- default:
- my_friendly_abort (367);
- return NULL_TREE;
- }
-}
-
-/* Build up a call to operator new. This has to be handled differently
- from other operators in the way lookup is handled; first members are
- considered, then globals. CODE is either NEW_EXPR or VEC_NEW_EXPR.
- TYPE is the type to be created. ARGS are any new-placement args.
- FLAGS are the usual overloading flags. */
-
-tree
-build_op_new_call (code, type, args, flags)
- enum tree_code code;
- tree type, args;
- int flags;
-{
- tree fnname = ansi_opname[code];
-
- if (IS_AGGR_TYPE (type) && ! (flags & LOOKUP_GLOBAL)
- && (TYPE_GETS_NEW (type) & (1 << (code == VEC_NEW_EXPR))))
- {
- return build_method_call (build_dummy_object (type),
- fnname, args, NULL_TREE, flags);
- }
- else
- return build_new_function_call
- (lookup_function_nonclass (fnname, args), args);
-}
-
-/* Build a call to operator delete. This has to be handled very specially,
- because the restrictions on what signatures match are different from all
- other call instances. For a normal delete, only a delete taking (void *)
- or (void *, size_t) is accepted. For a placement delete, only an exact
- match with the placement new is accepted.
-
- CODE is either DELETE_EXPR or VEC_DELETE_EXPR.
- ADDR is the pointer to be deleted. For placement delete, it is also
- used to determine what the corresponding new looked like.
- SIZE is the size of the memory block to be deleted.
- FLAGS are the usual overloading flags.
- PLACEMENT is the corresponding placement new call, or 0. */
-
-tree
-build_op_delete_call (code, addr, size, flags, placement)
- enum tree_code code;
- tree addr, size, placement;
- int flags;
-{
- tree fn, fns, fnname, fntype, argtypes, args, type;
-
- if (addr == error_mark_node)
- return error_mark_node;
-
- type = TREE_TYPE (TREE_TYPE (addr));
- fnname = ansi_opname[code];
-
- if (IS_AGGR_TYPE (type) && ! (flags & LOOKUP_GLOBAL))
- /* In [class.free]
-
- If the result of the lookup is ambiguous or inaccessible, or if
- the lookup selects a placement deallocation function, the
- program is ill-formed.
-
- Therefore, we ask lookup_fnfields to complain ambout ambiguity. */
- {
- fns = lookup_fnfields (TYPE_BINFO (type), fnname, 1);
- if (fns == error_mark_node)
- return error_mark_node;
- }
- else
- fns = NULL_TREE;
-
- if (fns == NULL_TREE)
- fns = lookup_name_nonclass (fnname);
-
- if (placement)
- {
- /* placement is a CALL_EXPR around an ADDR_EXPR around a function. */
-
- /* Extract the function. */
- argtypes = TREE_OPERAND (TREE_OPERAND (placement, 0), 0);
- /* Then the second parm type. */
- argtypes = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (argtypes)));
-
- /* Also the second argument. */
- args = TREE_CHAIN (TREE_OPERAND (placement, 1));
- }
- else
- {
- /* First try it without the size argument. */
- argtypes = void_list_node;
- args = NULL_TREE;
- }
-
- argtypes = tree_cons (NULL_TREE, ptr_type_node, argtypes);
- fntype = build_function_type (void_type_node, argtypes);
-
- /* Strip const and volatile from addr. */
- if (type != TYPE_MAIN_VARIANT (type))
- addr = cp_convert (build_pointer_type (TYPE_MAIN_VARIANT (type)), addr);
-
- fn = instantiate_type (fntype, fns, 2);
-
- if (fn != error_mark_node)
- {
- if (TREE_CODE (fns) == TREE_LIST)
- /* Member functions. */
- enforce_access (TREE_PURPOSE (fns), fn);
- return build_function_call (fn, expr_tree_cons (NULL_TREE, addr, args));
- }
-
- /* If we are doing placement delete we do nothing if we don't find a
- matching op delete. */
- if (placement)
- return NULL_TREE;
-
- /* Normal delete; now try to find a match including the size argument. */
- argtypes = tree_cons (NULL_TREE, ptr_type_node,
- tree_cons (NULL_TREE, sizetype, void_list_node));
- fntype = build_function_type (void_type_node, argtypes);
-
- fn = instantiate_type (fntype, fns, 2);
-
- if (fn != error_mark_node)
- {
- if (BASELINK_P (fns))
- /* Member functions. */
- enforce_access (TREE_PURPOSE (fns), fn);
- return build_function_call
- (fn, expr_tree_cons (NULL_TREE, addr,
- build_expr_list (NULL_TREE, size)));
- }
-
- /* finish_function passes LOOKUP_SPECULATIVELY if we're in a
- destructor, in which case the error should be deferred
- until someone actually tries to delete one of these. */
- if (flags & LOOKUP_SPECULATIVELY)
- return NULL_TREE;
-
- cp_error ("no suitable operator delete for `%T'", type);
- return error_mark_node;
-}
-
-/* If the current scope isn't allowed to access DECL along
- BASETYPE_PATH, give an error. The most derived class in
- BASETYPE_PATH is the one used to qualify DECL. */
-
-int
-enforce_access (basetype_path, decl)
- tree basetype_path;
- tree decl;
-{
- int accessible;
-
- accessible = accessible_p (basetype_path, decl);
- if (!accessible)
- {
- if (TREE_PRIVATE (decl))
- cp_error_at ("`%+#D' is private", decl);
- else if (TREE_PROTECTED (decl))
- cp_error_at ("`%+#D' is protected", decl);
- else
- cp_error_at ("`%+#D' is inaccessible", decl);
- cp_error ("within this context");
- return 0;
- }
-
- return 1;
-}
-
-/* Perform the conversions in CONVS on the expression EXPR. */
-
-static tree
-convert_like (convs, expr)
- tree convs, expr;
-{
- if (ICS_BAD_FLAG (convs)
- && TREE_CODE (convs) != USER_CONV
- && TREE_CODE (convs) != AMBIG_CONV)
- {
- tree t = convs;
- for (; t; t = TREE_OPERAND (t, 0))
- {
- if (TREE_CODE (t) == USER_CONV)
- {
- expr = convert_like (t, expr);
- break;
- }
- else if (TREE_CODE (t) == AMBIG_CONV)
- return convert_like (t, expr);
- else if (TREE_CODE (t) == IDENTITY_CONV)
- break;
- }
- return convert_for_initialization
- (NULL_TREE, TREE_TYPE (convs), expr, LOOKUP_NORMAL,
- "conversion", NULL_TREE, 0);
- }
-
- switch (TREE_CODE (convs))
- {
- case USER_CONV:
- {
- struct z_candidate *cand
- = WRAPPER_PTR (TREE_OPERAND (convs, 1));
- tree fn = cand->fn;
- tree args;
-
- if (DECL_CONSTRUCTOR_P (fn))
- {
- tree t = build_int_2 (0, 0);
- TREE_TYPE (t) = build_pointer_type (DECL_CONTEXT (fn));
-
- args = build_scratch_list (NULL_TREE, expr);
- if (TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (fn)))
- args = scratch_tree_cons (NULL_TREE, integer_one_node, args);
- args = scratch_tree_cons (NULL_TREE, t, args);
- }
- else
- args = build_this (expr);
- expr = build_over_call (cand, args, LOOKUP_NORMAL);
-
- /* If this is a constructor or a function returning an aggr type,
- we need to build up a TARGET_EXPR. */
- if (DECL_CONSTRUCTOR_P (fn))
- expr = build_cplus_new (TREE_TYPE (convs), expr);
-
- return expr;
- }
- case IDENTITY_CONV:
- if (type_unknown_p (expr))
- expr = instantiate_type (TREE_TYPE (convs), expr, 1);
- if (TREE_READONLY_DECL_P (expr))
- expr = decl_constant_value (expr);
- return expr;
- case AMBIG_CONV:
- /* Call build_user_type_conversion again for the error. */
- return build_user_type_conversion
- (TREE_TYPE (convs), TREE_OPERAND (convs, 0), LOOKUP_NORMAL);
-
- default:
- break;
- };
-
- expr = convert_like (TREE_OPERAND (convs, 0), expr);
- if (expr == error_mark_node)
- return error_mark_node;
-
- switch (TREE_CODE (convs))
- {
- case RVALUE_CONV:
- if (! IS_AGGR_TYPE (TREE_TYPE (convs)))
- return expr;
- /* else fall through */
- case BASE_CONV:
- {
- tree cvt_expr = build_user_type_conversion
- (TREE_TYPE (convs), expr, LOOKUP_NORMAL);
- if (!cvt_expr)
- {
- /* This can occur if, for example, the EXPR has incomplete
- type. We can't check for that before attempting the
- conversion because the type might be an incomplete
- array type, which is OK if some constructor for the
- destination type takes a pointer argument. */
- if (TYPE_SIZE (TREE_TYPE (expr)) == 0)
- {
- if (same_type_p (TREE_TYPE (expr), TREE_TYPE (convs)))
- incomplete_type_error (expr, TREE_TYPE (expr));
- else
- cp_error ("could not convert `%E' (with incomplete type `%T') to `%T'",
- expr, TREE_TYPE (expr), TREE_TYPE (convs));
- }
- else
- cp_error ("could not convert `%E' to `%T'",
- expr, TREE_TYPE (convs));
- return error_mark_node;
- }
- return cvt_expr;
- }
-
- case REF_BIND:
- return convert_to_reference
- (TREE_TYPE (convs), expr,
- CONV_IMPLICIT, LOOKUP_NORMAL|LOOKUP_NO_CONVERSION,
- error_mark_node);
- case LVALUE_CONV:
- return decay_conversion (expr);
-
- case QUAL_CONV:
- /* Warn about deprecated conversion if appropriate. */
- string_conv_p (TREE_TYPE (convs), expr, 1);
- break;
-
- default:
- break;
- }
- return ocp_convert (TREE_TYPE (convs), expr, CONV_IMPLICIT,
- LOOKUP_NORMAL|LOOKUP_NO_CONVERSION);
-}
-
-/* ARG is being passed to a varargs function. Perform any conversions
- required. Return the converted value. */
-
-tree
-convert_arg_to_ellipsis (arg)
- tree arg;
-{
- if (TREE_CODE (TREE_TYPE (arg)) == REAL_TYPE
- && (TYPE_PRECISION (TREE_TYPE (arg))
- < TYPE_PRECISION (double_type_node)))
- /* Convert `float' to `double'. */
- arg = cp_convert (double_type_node, arg);
- else if (IS_AGGR_TYPE (TREE_TYPE (arg))
- && ! TYPE_HAS_TRIVIAL_INIT_REF (TREE_TYPE (arg)))
- cp_warning ("cannot pass objects of type `%T' through `...'",
- TREE_TYPE (arg));
- else
- /* Convert `short' and `char' to full-size `int'. */
- arg = default_conversion (arg);
-
- arg = require_complete_type (arg);
-
- return arg;
-}
-
-/* ARG is a default argument expression being passed to a parameter of
- the indicated TYPE, which is a parameter to FN. Do any required
- conversions. Return the converted value. */
-
-tree
-convert_default_arg (type, arg, fn)
- tree type;
- tree arg;
- tree fn;
-{
- if (fn && DECL_TEMPLATE_INFO (fn))
- {
- /* This default argument came from a template. Instantiate the
- default argument here, not in tsubst. In the case of
- something like:
-
- template <class T>
- struct S {
- static T t();
- void f(T = t());
- };
-
- we must be careful to do name lookup in the scope of S<T>,
- rather than in the current class. */
- if (DECL_CLASS_SCOPE_P (fn))
- pushclass (DECL_REAL_CONTEXT (fn), 2);
-
- arg = tsubst_expr (arg, DECL_TI_ARGS (fn), /*complain=*/1, NULL_TREE);
-
- if (DECL_CLASS_SCOPE_P (fn))
- popclass ();
-
- /* Make sure the default argument is reasonable. */
- arg = check_default_argument (type, arg);
- }
-
- arg = break_out_target_exprs (arg);
-
- if (TREE_CODE (arg) == CONSTRUCTOR)
- {
- arg = digest_init (type, arg, 0);
- arg = convert_for_initialization (0, type, arg, LOOKUP_NORMAL,
- "default argument", 0, 0);
- }
- else
- {
- /* This could get clobbered by the following call. */
- if (TREE_HAS_CONSTRUCTOR (arg))
- arg = copy_node (arg);
-
- arg = convert_for_initialization (0, type, arg, LOOKUP_NORMAL,
- "default argument", 0, 0);
-#ifdef PROMOTE_PROTOTYPES
- if ((TREE_CODE (type) == INTEGER_TYPE
- || TREE_CODE (type) == ENUMERAL_TYPE)
- && (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)))
- arg = default_conversion (arg);
-#endif
- }
-
- return arg;
-}
-
-static tree
-build_over_call (cand, args, flags)
- struct z_candidate *cand;
- tree args;
- int flags;
-{
- tree fn = cand->fn;
- tree convs = cand->convs;
- tree converted_args = NULL_TREE;
- tree parm = TYPE_ARG_TYPES (TREE_TYPE (fn));
- tree conv, arg, val;
- int i = 0;
- int is_method = 0;
-
- /* 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);
-
- if (DECL_FUNCTION_MEMBER_P (fn))
- enforce_access (cand->basetype_path, fn);
-
- if (args && TREE_CODE (args) != TREE_LIST)
- args = build_scratch_list (NULL_TREE, args);
- arg = args;
-
- /* The implicit parameters to a constructor are not considered by overload
- resolution, and must be of the proper type. */
- if (DECL_CONSTRUCTOR_P (fn))
- {
- converted_args = expr_tree_cons (NULL_TREE, TREE_VALUE (arg), converted_args);
- arg = TREE_CHAIN (arg);
- parm = TREE_CHAIN (parm);
- if (TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (fn)))
- {
- converted_args = expr_tree_cons
- (NULL_TREE, TREE_VALUE (arg), converted_args);
- arg = TREE_CHAIN (arg);
- parm = TREE_CHAIN (parm);
- }
- }
- /* Bypass access control for 'this' parameter. */
- else if (TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE)
- {
- tree parmtype = TREE_VALUE (parm);
- tree argtype = TREE_TYPE (TREE_VALUE (arg));
- tree t;
- if (ICS_BAD_FLAG (TREE_VEC_ELT (convs, i)))
- cp_pedwarn ("passing `%T' as `this' argument of `%#D' discards qualifiers",
- TREE_TYPE (argtype), fn);
-
- /* [class.mfct.nonstatic]: If a nonstatic member function of a class
- X is called for an object that is not of type X, or of a type
- derived from X, the behavior is undefined.
-
- So we can assume that anything passed as 'this' is non-null, and
- optimize accordingly. */
- if (TREE_CODE (parmtype) == POINTER_TYPE)
- t = convert_pointer_to_real (TREE_TYPE (parmtype), TREE_VALUE (arg));
- else
- /* This happens with signatures. */
- t = convert_force (parmtype, TREE_VALUE (arg), CONV_C_CAST);
- converted_args = expr_tree_cons (NULL_TREE, t, converted_args);
- parm = TREE_CHAIN (parm);
- arg = TREE_CHAIN (arg);
- ++i;
- is_method = 1;
- }
-
- for (; arg && parm;
- parm = TREE_CHAIN (parm), arg = TREE_CHAIN (arg), ++i)
- {
- tree type = TREE_VALUE (parm);
-
- conv = TREE_VEC_ELT (convs, i);
- if (ICS_BAD_FLAG (conv))
- {
- tree t = conv;
- val = TREE_VALUE (arg);
-
- for (; t; t = TREE_OPERAND (t, 0))
- {
- if (TREE_CODE (t) == USER_CONV
- || TREE_CODE (t) == AMBIG_CONV)
- {
- val = convert_like (t, val);
- break;
- }
- else if (TREE_CODE (t) == IDENTITY_CONV)
- break;
- }
- val = convert_for_initialization
- (NULL_TREE, type, val, LOOKUP_NORMAL,
- "argument passing", fn, i - is_method);
- }
- else
- {
- /* Issue warnings about peculiar, but legal, uses of NULL. */
- if (ARITHMETIC_TYPE_P (TREE_VALUE (parm))
- && TREE_VALUE (arg) == null_node)
- cp_warning ("converting NULL to non-pointer type");
-
- val = convert_like (conv, TREE_VALUE (arg));
- }
-
-#ifdef PROMOTE_PROTOTYPES
- if ((TREE_CODE (type) == INTEGER_TYPE
- || TREE_CODE (type) == ENUMERAL_TYPE)
- && (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)))
- val = default_conversion (val);
-#endif
- converted_args = expr_tree_cons (NULL_TREE, val, converted_args);
- }
-
- /* Default arguments */
- for (; parm && parm != void_list_node; parm = TREE_CHAIN (parm))
- converted_args
- = expr_tree_cons (NULL_TREE,
- convert_default_arg (TREE_VALUE (parm),
- TREE_PURPOSE (parm),
- fn),
- converted_args);
-
- /* Ellipsis */
- for (; arg; arg = TREE_CHAIN (arg))
- converted_args
- = expr_tree_cons (NULL_TREE,
- convert_arg_to_ellipsis (TREE_VALUE (arg)),
- converted_args);
-
- converted_args = nreverse (converted_args);
-
- if (warn_format && (DECL_NAME (fn) || DECL_ASSEMBLER_NAME (fn)))
- check_function_format (DECL_NAME (fn), DECL_ASSEMBLER_NAME (fn),
- converted_args);
-
- /* Avoid actually calling copy constructors and copy assignment operators,
- if possible. */
-
- if (! flag_elide_constructors)
- /* Do things the hard way. */;
- else if (DECL_CONSTRUCTOR_P (fn)
- && TREE_VEC_LENGTH (convs) == 1
- && copy_args_p (fn))
- {
- tree targ;
- arg = TREE_CHAIN (converted_args);
- if (TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (fn)))
- arg = TREE_CHAIN (arg);
- arg = TREE_VALUE (arg);
-
- /* Pull out the real argument, disregarding const-correctness. */
- targ = arg;
- while (TREE_CODE (targ) == NOP_EXPR
- || TREE_CODE (targ) == NON_LVALUE_EXPR
- || TREE_CODE (targ) == CONVERT_EXPR)
- targ = TREE_OPERAND (targ, 0);
- if (TREE_CODE (targ) == ADDR_EXPR)
- {
- targ = TREE_OPERAND (targ, 0);
- if (!same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (arg))),
- TYPE_MAIN_VARIANT (TREE_TYPE (targ))))
- targ = NULL_TREE;
- }
- else
- targ = NULL_TREE;
-
- if (targ)
- arg = targ;
- else
- arg = build_indirect_ref (arg, 0);
-
- /* [class.copy]: the copy constructor is implicitly defined even if
- the implementation elided its use. */
- if (TYPE_HAS_COMPLEX_INIT_REF (DECL_CONTEXT (fn)))
- mark_used (fn);
-
- /* If we're creating a temp and we already have one, don't create a
- new one. If we're not creating a temp but we get one, use
- INIT_EXPR to collapse the temp into our target. Otherwise, if the
- ctor is trivial, do a bitwise copy with a simple TARGET_EXPR for a
- temp or an INIT_EXPR otherwise. */
- if (integer_zerop (TREE_VALUE (args)))
- {
- if (! real_lvalue_p (arg))
- return arg;
- else if (TYPE_HAS_TRIVIAL_INIT_REF (DECL_CONTEXT (fn)))
- {
- val = build_decl (VAR_DECL, NULL_TREE, DECL_CONTEXT (fn));
- val = build (TARGET_EXPR, DECL_CONTEXT (fn), val, arg, 0, 0);
- TREE_SIDE_EFFECTS (val) = 1;
- return val;
- }
- }
- else if (! real_lvalue_p (arg)
- || TYPE_HAS_TRIVIAL_INIT_REF (DECL_CONTEXT (fn)))
- {
- tree address;
- tree to = stabilize_reference
- (build_indirect_ref (TREE_VALUE (args), 0));
-
- /* If we're initializing an empty class, then we actually
- have to use a MODIFY_EXPR rather than an INIT_EXPR. The
- reason is that the dummy padding member in the target may
- not actually be allocated if TO is a base class
- subobject. Since we've set TYPE_NONCOPIED_PARTS on the
- padding, a MODIFY_EXPR will preserve its value, which is
- the right thing to do if it's not really padding at all.
-
- It's not safe to just throw away the ARG if we're looking
- at an empty class because the ARG might contain a
- TARGET_EXPR which wants to be bound to TO. If it is not,
- expand_expr will assign a dummy slot for the TARGET_EXPR,
- and we will call a destructor for it, which is wrong,
- because we will also destroy TO, but will never have
- constructed it. */
- val = build (is_empty_class (DECL_CLASS_CONTEXT (fn))
- ? MODIFY_EXPR : INIT_EXPR,
- DECL_CONTEXT (fn), to, arg);
- TREE_SIDE_EFFECTS (val) = 1;
- address = build_unary_op (ADDR_EXPR, val, 0);
- /* Avoid a warning about this expression, if the address is
- never used. */
- TREE_USED (address) = 1;
- return address;
- }
- }
- else if (DECL_NAME (fn) == ansi_opname[MODIFY_EXPR]
- && copy_args_p (fn)
- && TYPE_HAS_TRIVIAL_ASSIGN_REF (DECL_CLASS_CONTEXT (fn)))
- {
- tree to = stabilize_reference
- (build_indirect_ref (TREE_VALUE (converted_args), 0));
-
- arg = build_indirect_ref (TREE_VALUE (TREE_CHAIN (converted_args)), 0);
-
- val = build (MODIFY_EXPR, TREE_TYPE (to), to, arg);
- TREE_SIDE_EFFECTS (val) = 1;
- return val;
- }
-
- mark_used (fn);
-
- if (DECL_CLASS_SCOPE_P (fn) && IS_SIGNATURE (DECL_CONTEXT (fn)))
- return build_signature_method_call (fn, converted_args);
- else if (DECL_VINDEX (fn) && (flags & LOOKUP_NONVIRTUAL) == 0)
- {
- tree t, *p = &TREE_VALUE (converted_args);
- tree binfo = get_binfo
- (DECL_CONTEXT (fn), TREE_TYPE (TREE_TYPE (*p)), 0);
- *p = convert_pointer_to_real (binfo, *p);
- if (TREE_SIDE_EFFECTS (*p))
- *p = save_expr (*p);
- t = build_pointer_type (TREE_TYPE (fn));
- fn = build_vfn_ref (p, build_indirect_ref (*p, 0), DECL_VINDEX (fn));
- TREE_TYPE (fn) = t;
- }
- else if (DECL_INLINE (fn))
- fn = inline_conversion (fn);
- else
- fn = build_addr_func (fn);
-
- /* 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)))
- switch (DECL_FUNCTION_CODE (TREE_OPERAND (fn, 0)))
- {
- case BUILT_IN_ABS:
- case BUILT_IN_LABS:
- case BUILT_IN_FABS:
- if (converted_args == 0)
- return integer_zero_node;
- return build_unary_op (ABS_EXPR, TREE_VALUE (converted_args), 0);
- default:
- break;
- }
-
- fn = build_call (fn, TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))), converted_args);
- if (TREE_CODE (TREE_TYPE (fn)) == VOID_TYPE)
- return fn;
- fn = require_complete_type (fn);
- if (IS_AGGR_TYPE (TREE_TYPE (fn)))
- fn = build_cplus_new (TREE_TYPE (fn), fn);
- return convert_from_reference (fn);
-}
-
-static tree
-build_new_method_call (instance, name, args, basetype_path, flags)
- tree instance, name, args, basetype_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 user_args = args;
- tree templates = NULL_TREE;
- int template_only = 0;
-
- if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
- {
- explicit_targs = TREE_OPERAND (name, 1);
- name = TREE_OPERAND (name, 0);
- if (TREE_CODE_CLASS (TREE_CODE (name)) == 'd')
- 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));
- }
-
- template_only = 1;
- }
-
- /* If there is an extra argument for controlling virtual bases,
- remove it for error reporting. */
- if (flags & LOOKUP_HAS_IN_CHARGE)
- user_args = TREE_CHAIN (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));
-
- /* XXX this should be handled before we get here. */
- if (! IS_AGGR_TYPE (basetype)
- && ! (TYPE_LANG_SPECIFIC (basetype)
- && (IS_SIGNATURE_POINTER (basetype)
- || IS_SIGNATURE_REFERENCE (basetype))))
- {
- if ((flags & LOOKUP_COMPLAIN) && basetype != error_mark_node)
- cp_error ("request for member `%D' in `%E', which is of non-aggregate type `%T'",
- name, instance, basetype);
-
- return error_mark_node;
- }
-
- /* If `instance' is a signature pointer/reference and `name' is
- not a constructor, we are calling a signature member function.
- In that case set the `basetype' to the signature type. */
- if ((IS_SIGNATURE_POINTER (basetype)
- || IS_SIGNATURE_REFERENCE (basetype))
- && TYPE_IDENTIFIER (basetype) != name)
- basetype = SIGNATURE_TYPE (basetype);
- }
-
- if (basetype_path == NULL_TREE)
- basetype_path = TYPE_BINFO (basetype);
-
- if (instance)
- {
- instance_ptr = build_this (instance);
-
- 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);
- }
-
- pretty_name
- = (name == ctor_identifier ? constructor_name (basetype) : name);
-
- fns = lookup_fnfields (basetype_path, name, 1);
-
- if (fns == error_mark_node)
- return error_mark_node;
- if (fns)
- {
- tree fn = TREE_VALUE (fns);
- if (name == ctor_identifier && TYPE_USES_VIRTUAL_BASECLASSES (basetype)
- && ! (flags & LOOKUP_HAS_IN_CHARGE))
- {
- flags |= LOOKUP_HAS_IN_CHARGE;
- args = scratch_tree_cons (NULL_TREE, integer_one_node, args);
- }
- mem_args = scratch_tree_cons (NULL_TREE, instance_ptr, args);
- for (; fn; fn = OVL_NEXT (fn))
- {
- tree t = OVL_CURRENT (fn);
- tree this_arglist;
-
- /* We can end up here for copy-init of same or base class. */
- if (name == ctor_identifier
- && (flags & LOOKUP_ONLYCONVERTING)
- && DECL_NONCONVERTING_P (t))
- continue;
- if (TREE_CODE (TREE_TYPE (t)) == METHOD_TYPE)
- this_arglist = mem_args;
- else
- this_arglist = args;
-
- if (TREE_CODE (t) == TEMPLATE_DECL)
- {
- /* A member template. */
- templates = scratch_tree_cons (NULL_TREE, t, templates);
- candidates =
- add_template_candidate (candidates, t, explicit_targs,
- this_arglist,
- TREE_TYPE (name), flags, DEDUCE_CALL);
- }
- else if (! template_only)
- candidates = add_function_candidate (candidates, t,
- this_arglist, flags);
-
- if (candidates)
- candidates->basetype_path = TREE_PURPOSE (fns);
- }
- }
-
- if (! any_viable (candidates))
- {
- /* XXX will LOOKUP_SPECULATIVELY be needed when this is done? */
- if (flags & LOOKUP_SPECULATIVELY)
- return NULL_TREE;
- if (TYPE_SIZE (basetype) == 0)
- incomplete_type_error (instance_ptr, basetype);
- else
- cp_error ("no matching function for call to `%T::%D (%A)%V'",
- basetype, pretty_name, user_args,
- TREE_TYPE (TREE_TYPE (instance_ptr)));
- print_z_candidates (candidates);
- return error_mark_node;
- }
- candidates = splice_viable (candidates);
- cand = tourney (candidates);
-
- if (cand == 0)
- {
- cp_error ("call of overloaded `%D(%A)' is ambiguous", pretty_name,
- user_args);
- print_z_candidates (candidates);
- return error_mark_node;
- }
-
- if (DECL_ABSTRACT_VIRTUAL_P (cand->fn)
- && instance == current_class_ref
- && DECL_CONSTRUCTOR_P (current_function_decl)
- && ! (flags & LOOKUP_NONVIRTUAL)
- && value_member (cand->fn, CLASSTYPE_ABSTRACT_VIRTUALS (basetype)))
- cp_error ("abstract virtual `%#D' called from constructor", cand->fn);
- if (TREE_CODE (TREE_TYPE (cand->fn)) == METHOD_TYPE
- && is_dummy_object (instance_ptr))
- {
- cp_error ("cannot call member function `%D' without object", cand->fn);
- return error_mark_node;
- }
-
- if (DECL_VINDEX (cand->fn) && ! (flags & LOOKUP_NONVIRTUAL)
- && ((instance == current_class_ref && (dtor_label || ctor_label))
- || resolves_to_fixed_type_p (instance, 0)))
- flags |= LOOKUP_NONVIRTUAL;
-
- /* Pedantically, normal function declarations are never considered
- to refer to template instantiations, so we only do this with
- -fguiding-decls. */
- if (flag_guiding_decls && templates && ! cand->template
- && ! DECL_INITIAL (cand->fn))
- add_maybe_template (cand->fn, templates);
-
- return build_over_call
- (cand,
- TREE_CODE (TREE_TYPE (cand->fn)) == METHOD_TYPE ? mem_args : args,
- flags);
-}
-
-/* Returns non-zero iff standard conversion sequence ICS1 is a proper
- subsequence of ICS2. */
-
-static int
-is_subseq (ics1, ics2)
- tree ics1, ics2;
-{
- /* We can assume that a conversion of the same code
- between the same types indicates a subsequence since we only get
- here if the types we are converting from are the same. */
-
- while (TREE_CODE (ics1) == RVALUE_CONV
- || TREE_CODE (ics1) == LVALUE_CONV)
- ics1 = TREE_OPERAND (ics1, 0);
-
- while (1)
- {
- while (TREE_CODE (ics2) == RVALUE_CONV
- || TREE_CODE (ics2) == LVALUE_CONV)
- ics2 = TREE_OPERAND (ics2, 0);
-
- if (TREE_CODE (ics2) == USER_CONV
- || TREE_CODE (ics2) == AMBIG_CONV
- || TREE_CODE (ics2) == IDENTITY_CONV)
- /* At this point, ICS1 cannot be a proper subsequence of
- ICS2. We can get a USER_CONV when we are comparing the
- second standard conversion sequence of two user conversion
- sequences. */
- return 0;
-
- ics2 = TREE_OPERAND (ics2, 0);
-
- if (TREE_CODE (ics2) == TREE_CODE (ics1)
- && same_type_p (TREE_TYPE (ics2), TREE_TYPE (ics1))
- && same_type_p (TREE_TYPE (TREE_OPERAND (ics2, 0)),
- TREE_TYPE (TREE_OPERAND (ics1, 0))))
- return 1;
- }
-}
-
-/* Returns non-zero iff DERIVED is derived from BASE. The inputs may
- be any _TYPE nodes. */
-
-int
-is_properly_derived_from (derived, base)
- tree derived;
- tree base;
-{
- if (!IS_AGGR_TYPE_CODE (TREE_CODE (derived))
- || !IS_AGGR_TYPE_CODE (TREE_CODE (base)))
- return 0;
-
- /* We only allow proper derivation here. The DERIVED_FROM_P macro
- considers every class derived from itself. */
- return (!same_type_p (TYPE_MAIN_VARIANT (derived),
- TYPE_MAIN_VARIANT (base))
- && DERIVED_FROM_P (base, derived));
-}
-
-/* We build the ICS for an implicit object parameter as a pointer
- conversion sequence. However, such a sequence should be compared
- as if it were a reference conversion sequence. If ICS is the
- implicit conversion sequence for an implicit object parameter,
- modify it accordingly. */
-
-static void
-maybe_handle_implicit_object (ics)
- tree* ics;
-{
- if (ICS_THIS_FLAG (*ics))
- {
- /* [over.match.funcs]
-
- For non-static member functions, the type of the
- implicit object parameter is "reference to cv X"
- where X is the class of which the function is a
- member and cv is the cv-qualification on the member
- function declaration. */
- tree t = *ics;
- if (TREE_CODE (t) == QUAL_CONV)
- t = TREE_OPERAND (t, 0);
- if (TREE_CODE (t) == PTR_CONV)
- t = TREE_OPERAND (t, 0);
- t = build1 (IDENTITY_CONV, TREE_TYPE (TREE_TYPE (t)), NULL_TREE);
- t = build_conv (REF_BIND,
- build_reference_type (TREE_TYPE (TREE_TYPE (*ics))),
- t);
- ICS_STD_RANK (t) = ICS_STD_RANK (*ics);
- *ics = t;
- }
-}
-
-/* If ICS is a REF_BIND, modify it appropriately, set TARGET_TYPE
- to the type the reference originally referred to, and return 1.
- Otherwise, return 0. */
-
-static int
-maybe_handle_ref_bind (ics, target_type)
- tree* ics;
- tree* target_type;
-{
- if (TREE_CODE (*ics) == REF_BIND)
- {
- /* [over.ics.rank]
-
- When a parameter of reference type binds directly
- (_dcl.init.ref_) to an argument expression, the implicit
- conversion sequence is the identity conversion, unless the
- argument expression has a type that is a derived class of the
- parameter type, in which case the implicit conversion
- sequence is a derived-to-base Conversion.
-
- If the parameter binds directly to the result of applying a
- conversion function to the argument expression, the implicit
- conversion sequence is a user-defined conversion sequence
- (_over.ics.user_), with the second standard conversion
- sequence either an identity conversion or, if the conversion
- function returns an entity of a type that is a derived class
- of the parameter type, a derived-to-base Conversion.
-
- When a parameter of reference type is not bound directly to
- an argument expression, the conversion sequence is the one
- required to convert the argument expression to the underlying
- type of the reference according to _over.best.ics_.
- Conceptually, this conversion sequence corresponds to
- copy-initializing a temporary of the underlying type with the
- argument expression. Any difference in top-level
- cv-qualification is subsumed by the initialization itself and
- does not constitute a conversion. */
-
- tree old_ics = *ics;
-
- *target_type = TREE_TYPE (TREE_TYPE (*ics));
- *ics = TREE_OPERAND (*ics, 0);
- if (TREE_CODE (*ics) == IDENTITY_CONV
- && is_properly_derived_from (TREE_TYPE (*ics), *target_type))
- *ics = build_conv (BASE_CONV, *target_type, *ics);
- ICS_USER_FLAG (*ics) = ICS_USER_FLAG (old_ics);
- ICS_BAD_FLAG (*ics) = ICS_BAD_FLAG (old_ics);
-
- return 1;
- }
-
- return 0;
-}
-
-/* Compare two implicit conversion sequences according to the rules set out in
- [over.ics.rank]. Return values:
-
- 1: ics1 is better than ics2
- -1: ics2 is better than ics1
- 0: ics1 and ics2 are indistinguishable */
-
-static int
-compare_ics (ics1, ics2)
- tree ics1, ics2;
-{
- tree from_type1;
- tree from_type2;
- tree to_type1;
- tree to_type2;
- tree deref_from_type1 = NULL_TREE;
- tree deref_from_type2 = NULL_TREE;
- tree deref_to_type1 = NULL_TREE;
- tree deref_to_type2 = NULL_TREE;
-
- /* REF_BINDING is non-zero if the result of the conversion sequence
- is a reference type. In that case TARGET_TYPE is the
- type referred to by the reference. */
- int ref_binding1;
- int ref_binding2;
- tree target_type1;
- tree target_type2;
-
- /* Handle implicit object parameters. */
- maybe_handle_implicit_object (&ics1);
- maybe_handle_implicit_object (&ics2);
-
- /* Handle reference parameters. */
- ref_binding1 = maybe_handle_ref_bind (&ics1, &target_type1);
- ref_binding2 = maybe_handle_ref_bind (&ics2, &target_type2);
-
- /* [over.ics.rank]
-
- When comparing the basic forms of implicit conversion sequences (as
- defined in _over.best.ics_)
-
- --a standard conversion sequence (_over.ics.scs_) is a better
- conversion sequence than a user-defined conversion sequence
- or an ellipsis conversion sequence, and
-
- --a user-defined conversion sequence (_over.ics.user_) is a
- better conversion sequence than an ellipsis conversion sequence
- (_over.ics.ellipsis_). */
- if (ICS_RANK (ics1) > ICS_RANK (ics2))
- return -1;
- else if (ICS_RANK (ics1) < ICS_RANK (ics2))
- return 1;
-
- if (ICS_RANK (ics1) == BAD_RANK)
- {
- /* Both ICS are bad. We try to make a decision based on what
- would have happenned if they'd been good. */
- if (ICS_USER_FLAG (ics1) > ICS_USER_FLAG (ics2)
- || ICS_STD_RANK (ics1) > ICS_STD_RANK (ics2))
- return -1;
- else if (ICS_USER_FLAG (ics1) < ICS_USER_FLAG (ics2)
- || ICS_STD_RANK (ics1) < ICS_STD_RANK (ics2))
- return 1;
-
- /* We couldn't make up our minds; try to figure it out below. */
- }
-
- if (ICS_ELLIPSIS_FLAG (ics1))
- /* Both conversions are ellipsis conversions. */
- return 0;
-
- /* User-defined conversion sequence U1 is a better conversion sequence
- than another user-defined conversion sequence U2 if they contain the
- same user-defined conversion operator or constructor and if the sec-
- ond standard conversion sequence of U1 is better than the second
- standard conversion sequence of U2. */
-
- if (ICS_USER_FLAG (ics1))
- {
- tree t1, t2;
-
- for (t1 = ics1; TREE_CODE (t1) != USER_CONV; t1 = TREE_OPERAND (t1, 0))
- if (TREE_CODE (t1) == AMBIG_CONV)
- return 0;
- for (t2 = ics2; TREE_CODE (t2) != USER_CONV; t2 = TREE_OPERAND (t2, 0))
- if (TREE_CODE (t2) == AMBIG_CONV)
- return 0;
-
- if (USER_CONV_FN (t1) != USER_CONV_FN (t2))
- return 0;
-
- /* We can just fall through here, after setting up
- FROM_TYPE1 and FROM_TYPE2. */
- from_type1 = TREE_TYPE (t1);
- from_type2 = TREE_TYPE (t2);
- }
- else
- {
- /* We're dealing with two standard conversion sequences.
-
- [over.ics.rank]
-
- Standard conversion sequence S1 is a better conversion
- sequence than standard conversion sequence S2 if
-
- --S1 is a proper subsequence of S2 (comparing the conversion
- sequences in the canonical form defined by _over.ics.scs_,
- excluding any Lvalue Transformation; the identity
- conversion sequence is considered to be a subsequence of
- any non-identity conversion sequence */
-
- from_type1 = ics1;
- while (TREE_CODE (from_type1) != IDENTITY_CONV)
- from_type1 = TREE_OPERAND (from_type1, 0);
- from_type1 = TREE_TYPE (from_type1);
-
- from_type2 = ics2;
- while (TREE_CODE (from_type2) != IDENTITY_CONV)
- from_type2 = TREE_OPERAND (from_type2, 0);
- from_type2 = TREE_TYPE (from_type2);
- }
-
- if (same_type_p (from_type1, from_type2))
- {
- if (is_subseq (ics1, ics2))
- return 1;
- if (is_subseq (ics2, ics1))
- return -1;
- }
- /* Otherwise, one sequence cannot be a subsequence of the other; they
- don't start with the same type. This can happen when comparing the
- second standard conversion sequence in two user-defined conversion
- sequences. */
-
- /* [over.ics.rank]
-
- Or, if not that,
-
- --the rank of S1 is better than the rank of S2 (by the rules
- defined below):
-
- Standard conversion sequences are ordered by their ranks: an Exact
- Match is a better conversion than a Promotion, which is a better
- conversion than a Conversion.
-
- Two conversion sequences with the same rank are indistinguishable
- unless one of the following rules applies:
-
- --A conversion that is not a conversion of a pointer, or pointer
- to member, to bool is better than another conversion that is such
- a conversion.
-
- The ICS_STD_RANK automatically handles the pointer-to-bool rule,
- so that we do not have to check it explicitly. */
- if (ICS_STD_RANK (ics1) < ICS_STD_RANK (ics2))
- return 1;
- else if (ICS_STD_RANK (ics2) < ICS_STD_RANK (ics1))
- return -1;
-
- to_type1 = TREE_TYPE (ics1);
- to_type2 = TREE_TYPE (ics2);
-
- if (TYPE_PTR_P (from_type1)
- && TYPE_PTR_P (from_type2)
- && TYPE_PTR_P (to_type1)
- && TYPE_PTR_P (to_type2))
- {
- deref_from_type1 = TREE_TYPE (from_type1);
- deref_from_type2 = TREE_TYPE (from_type2);
- deref_to_type1 = TREE_TYPE (to_type1);
- deref_to_type2 = TREE_TYPE (to_type2);
- }
- /* The rules for pointers to members A::* are just like the rules
- for pointers A*, except opposite: if B is derived from A then
- A::* converts to B::*, not vice versa. For that reason, we
- switch the from_ and to_ variables here. */
- else if (TYPE_PTRMEM_P (from_type1)
- && TYPE_PTRMEM_P (from_type2)
- && TYPE_PTRMEM_P (to_type1)
- && TYPE_PTRMEM_P (to_type2))
- {
- deref_to_type1 = TYPE_OFFSET_BASETYPE (TREE_TYPE (from_type1));
- deref_to_type2 = TYPE_OFFSET_BASETYPE (TREE_TYPE (from_type2));
- deref_from_type1 = TYPE_OFFSET_BASETYPE (TREE_TYPE (to_type1));
- deref_from_type2 = TYPE_OFFSET_BASETYPE (TREE_TYPE (to_type2));
- }
- else if (TYPE_PTRMEMFUNC_P (from_type1)
- && TYPE_PTRMEMFUNC_P (from_type2)
- && TYPE_PTRMEMFUNC_P (to_type1)
- && TYPE_PTRMEMFUNC_P (to_type2))
- {
- deref_to_type1 = TYPE_PTRMEMFUNC_OBJECT_TYPE (from_type1);
- deref_to_type2 = TYPE_PTRMEMFUNC_OBJECT_TYPE (from_type2);
- deref_from_type1 = TYPE_PTRMEMFUNC_OBJECT_TYPE (to_type1);
- deref_from_type2 = TYPE_PTRMEMFUNC_OBJECT_TYPE (to_type2);
- }
-
- if (deref_from_type1 != NULL_TREE
- && IS_AGGR_TYPE_CODE (TREE_CODE (deref_from_type1))
- && IS_AGGR_TYPE_CODE (TREE_CODE (deref_from_type2)))
- {
- /* This was one of the pointer or pointer-like conversions.
-
- [over.ics.rank]
-
- --If class B is derived directly or indirectly from class A,
- conversion of B* to A* is better than conversion of B* to
- void*, and conversion of A* to void* is better than
- conversion of B* to void*. */
- if (TREE_CODE (deref_to_type1) == VOID_TYPE
- && TREE_CODE (deref_to_type2) == VOID_TYPE)
- {
- if (is_properly_derived_from (deref_from_type1,
- deref_from_type2))
- return -1;
- else if (is_properly_derived_from (deref_from_type2,
- deref_from_type1))
- return 1;
- }
- else if (TREE_CODE (deref_to_type1) == VOID_TYPE
- || TREE_CODE (deref_to_type2) == VOID_TYPE)
- {
- if (same_type_p (deref_from_type1, deref_from_type2))
- {
- if (TREE_CODE (deref_to_type2) == VOID_TYPE)
- {
- if (is_properly_derived_from (deref_from_type1,
- deref_to_type1))
- return 1;
- }
- /* We know that DEREF_TO_TYPE1 is `void' here. */
- else if (is_properly_derived_from (deref_from_type1,
- deref_to_type2))
- return -1;
- }
- }
- else if (IS_AGGR_TYPE_CODE (TREE_CODE (deref_to_type1))
- && IS_AGGR_TYPE_CODE (TREE_CODE (deref_to_type2)))
- {
- /* [over.ics.rank]
-
- --If class B is derived directly or indirectly from class A
- and class C is derived directly or indirectly from B,
-
- --conversion of C* to B* is better than conversion of C* to
- A*,
-
- --conversion of B* to A* is better than conversion of C* to
- A* */
- if (same_type_p (deref_from_type1, deref_from_type2))
- {
- if (is_properly_derived_from (deref_to_type1,
- deref_to_type2))
- return 1;
- else if (is_properly_derived_from (deref_to_type2,
- deref_to_type1))
- return -1;
- }
- else if (same_type_p (deref_to_type1, deref_to_type2))
- {
- if (is_properly_derived_from (deref_from_type2,
- deref_from_type1))
- return 1;
- else if (is_properly_derived_from (deref_from_type1,
- deref_from_type2))
- return -1;
- }
- }
- }
- else if (IS_AGGR_TYPE_CODE (TREE_CODE (from_type1))
- && same_type_p (from_type1, from_type2))
- {
- /* [over.ics.rank]
-
- --binding of an expression of type C to a reference of type
- B& is better than binding an expression of type C to a
- reference of type A&
-
- --conversion of C to B is better than conversion of C to A, */
- if (is_properly_derived_from (from_type1, to_type1)
- && is_properly_derived_from (from_type1, to_type2))
- {
- if (is_properly_derived_from (to_type1, to_type2))
- return 1;
- else if (is_properly_derived_from (to_type2, to_type1))
- return -1;
- }
- }
- else if (IS_AGGR_TYPE_CODE (TREE_CODE (to_type1))
- && same_type_p (to_type1, to_type2))
- {
- /* [over.ics.rank]
-
- --binding of an expression of type B to a reference of type
- A& is better than binding an expression of type C to a
- reference of type A&,
-
- --onversion of B to A is better than conversion of C to A */
- if (is_properly_derived_from (from_type1, to_type1)
- && is_properly_derived_from (from_type2, to_type1))
- {
- if (is_properly_derived_from (from_type2, from_type1))
- return 1;
- else if (is_properly_derived_from (from_type1, from_type2))
- return -1;
- }
- }
-
- /* [over.ics.rank]
-
- --S1 and S2 differ only in their qualification conversion and yield
- similar types T1 and T2 (_conv.qual_), respectively, and the cv-
- qualification signature of type T1 is a proper subset of the cv-
- qualification signature of type T2 */
- if (TREE_CODE (ics1) == QUAL_CONV
- && TREE_CODE (ics2) == QUAL_CONV
- && same_type_p (from_type1, from_type2))
- return comp_cv_qual_signature (to_type1, to_type2);
-
- /* [over.ics.rank]
-
- --S1 and S2 are reference bindings (_dcl.init.ref_), and the
- types to which the references refer are the same type except for
- top-level cv-qualifiers, and the type to which the reference
- initialized by S2 refers is more cv-qualified than the type to
- which the reference initialized by S1 refers */
-
- if (ref_binding1 && ref_binding2
- && same_type_p (TYPE_MAIN_VARIANT (to_type1),
- TYPE_MAIN_VARIANT (to_type2)))
- return comp_cv_qualification (target_type2, target_type1);
-
- /* Neither conversion sequence is better than the other. */
- return 0;
-}
-
-/* The source type for this standard conversion sequence. */
-
-static tree
-source_type (t)
- tree t;
-{
- for (;; t = TREE_OPERAND (t, 0))
- {
- if (TREE_CODE (t) == USER_CONV
- || TREE_CODE (t) == AMBIG_CONV
- || TREE_CODE (t) == IDENTITY_CONV)
- return TREE_TYPE (t);
- }
- my_friendly_abort (1823);
-}
-
-/* Note a warning about preferring WINNER to LOSER. We do this by storing
- a pointer to LOSER and re-running joust to produce the warning if WINNER
- is actually used. */
-
-static void
-add_warning (winner, loser)
- struct z_candidate *winner, *loser;
-{
- winner->warnings = expr_tree_cons (NULL_PTR,
- build_expr_ptr_wrapper (loser),
- winner->warnings);
-}
-
-/* Compare two candidates for overloading as described in
- [over.match.best]. Return values:
-
- 1: cand1 is better than cand2
- -1: cand2 is better than cand1
- 0: cand1 and cand2 are indistinguishable */
-
-static int
-joust (cand1, cand2, warn)
- struct z_candidate *cand1, *cand2;
- int warn;
-{
- int winner = 0;
- int i, off1 = 0, off2 = 0, len;
-
- /* Candidates that involve bad conversions are always worse than those
- that don't. */
- if (cand1->viable > cand2->viable)
- return 1;
- if (cand1->viable < cand2->viable)
- return -1;
-
- /* If we have two pseudo-candidates for conversions to the same type,
- arbitrarily pick one. */
- if (TYPE_P (cand1->fn) && cand1->fn == cand2->fn)
- return 1;
-
- /* a viable function F1
- is defined to be a better function than another viable function F2 if
- for all arguments i, ICSi(F1) is not a worse conversion sequence than
- ICSi(F2), and then */
-
- /* for some argument j, ICSj(F1) is a better conversion sequence than
- ICSj(F2) */
-
- /* For comparing static and non-static member functions, we ignore the
- implicit object parameter of the non-static function. The WP says to
- pretend that the static function has an object parm, but that won't
- work with operator overloading. */
- len = TREE_VEC_LENGTH (cand1->convs);
- if (len != TREE_VEC_LENGTH (cand2->convs))
- {
- if (DECL_STATIC_FUNCTION_P (cand1->fn)
- && ! DECL_STATIC_FUNCTION_P (cand2->fn))
- off2 = 1;
- else if (! DECL_STATIC_FUNCTION_P (cand1->fn)
- && DECL_STATIC_FUNCTION_P (cand2->fn))
- {
- off1 = 1;
- --len;
- }
- else
- my_friendly_abort (42);
- }
-
- for (i = 0; i < len; ++i)
- {
- tree t1 = TREE_VEC_ELT (cand1->convs, i+off1);
- tree t2 = TREE_VEC_ELT (cand2->convs, i+off2);
- int comp = compare_ics (t1, t2);
-
- if (comp != 0)
- {
- if (warn_sign_promo
- && ICS_RANK (t1) + ICS_RANK (t2) == STD_RANK + PROMO_RANK
- && TREE_CODE (t1) == STD_CONV
- && TREE_CODE (t2) == STD_CONV
- && TREE_CODE (TREE_TYPE (t1)) == INTEGER_TYPE
- && TREE_CODE (TREE_TYPE (t2)) == INTEGER_TYPE
- && (TYPE_PRECISION (TREE_TYPE (t1))
- == TYPE_PRECISION (TREE_TYPE (t2)))
- && (TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (t1, 0)))
- || (TREE_CODE (TREE_TYPE (TREE_OPERAND (t1, 0)))
- == ENUMERAL_TYPE)))
- {
- tree type = TREE_TYPE (TREE_OPERAND (t1, 0));
- tree type1, type2;
- struct z_candidate *w, *l;
- if (comp > 0)
- type1 = TREE_TYPE (t1), type2 = TREE_TYPE (t2),
- w = cand1, l = cand2;
- else
- type1 = TREE_TYPE (t2), type2 = TREE_TYPE (t1),
- w = cand2, l = cand1;
-
- if (warn)
- {
- cp_warning ("passing `%T' chooses `%T' over `%T'",
- type, type1, type2);
- cp_warning (" in call to `%D'", w->fn);
- }
- else
- add_warning (w, l);
- }
-
- if (winner && comp != winner)
- {
- winner = 0;
- goto tweak;
- }
- winner = comp;
- }
- }
-
- /* warn about confusing overload resolution for user-defined conversions,
- either between a constructor and a conversion op, or between two
- conversion ops. */
- if (winner && cand1->second_conv
- && ((DECL_CONSTRUCTOR_P (cand1->fn)
- != DECL_CONSTRUCTOR_P (cand2->fn))
- /* Don't warn if the two conv ops convert to the same type... */
- || (! DECL_CONSTRUCTOR_P (cand1->fn)
- && ! same_type_p (TREE_TYPE (TREE_TYPE (cand1->fn)),
- TREE_TYPE (TREE_TYPE (cand2->fn))))))
- {
- int comp = compare_ics (cand1->second_conv, cand2->second_conv);
- if (comp != winner)
- {
- struct z_candidate *w, *l;
- if (winner == 1)
- w = cand1, l = cand2;
- else
- w = cand2, l = cand1;
- if (warn)
- {
- tree source = source_type (TREE_VEC_ELT (w->convs, 0));
- if (! DECL_CONSTRUCTOR_P (w->fn))
- source = TREE_TYPE (source);
- cp_warning ("choosing `%D' over `%D'", w->fn, l->fn);
- cp_warning (" for conversion from `%T' to `%T'",
- source, TREE_TYPE (w->second_conv));
- cp_warning (" because conversion sequence for the argument is better");
- }
- else
- add_warning (w, l);
- }
- }
-
- if (winner)
- return winner;
-
- /* or, if not that,
- F1 is a non-template function and F2 is a template function */
-
- if (! cand1->template && cand2->template)
- return 1;
- else if (cand1->template && ! cand2->template)
- return -1;
- else if (cand1->template && cand2->template)
- winner = more_specialized
- (TI_TEMPLATE (cand1->template), TI_TEMPLATE (cand2->template),
- NULL_TREE);
-
- /* or, if not that,
- the context is an initialization by user-defined conversion (see
- _dcl.init_ and _over.match.user_) and the standard conversion
- sequence from the return type of F1 to the destination type (i.e.,
- the type of the entity being initialized) is a better conversion
- sequence than the standard conversion sequence from the return type
- of F2 to the destination type. */
-
- if (! winner && cand1->second_conv)
- winner = compare_ics (cand1->second_conv, cand2->second_conv);
-
- /* If the built-in candidates are the same, arbitrarily pick one. */
- if (! winner && cand1->fn == cand2->fn
- && TREE_CODE (cand1->fn) == IDENTIFIER_NODE)
- {
- for (i = 0; i < len; ++i)
- if (!same_type_p (TREE_TYPE (TREE_VEC_ELT (cand1->convs, i)),
- TREE_TYPE (TREE_VEC_ELT (cand2->convs, i))))
- break;
- if (i == TREE_VEC_LENGTH (cand1->convs))
- return 1;
-
- /* Kludge around broken overloading rules whereby
- Integer a, b; test ? a : b; is ambiguous, since there's a builtin
- that takes references and another that takes values. */
- if (cand1->fn == ansi_opname[COND_EXPR])
- {
- tree c1 = TREE_VEC_ELT (cand1->convs, 1);
- tree c2 = TREE_VEC_ELT (cand2->convs, 1);
- tree t1 = strip_top_quals (non_reference (TREE_TYPE (c1)));
- tree t2 = strip_top_quals (non_reference (TREE_TYPE (c2)));
-
- if (same_type_p (t1, t2))
- {
- if (TREE_CODE (c1) == REF_BIND && TREE_CODE (c2) != REF_BIND)
- return 1;
- if (TREE_CODE (c1) != REF_BIND && TREE_CODE (c2) == REF_BIND)
- return -1;
- }
- }
- }
-
-tweak:
-
- /* Extension: If the worst conversion for one candidate is worse than the
- worst conversion for the other, take the first. */
- if (! winner && ! pedantic)
- {
- int rank1 = IDENTITY_RANK, rank2 = IDENTITY_RANK;
-
- for (i = 0; i < len; ++i)
- {
- if (ICS_RANK (TREE_VEC_ELT (cand1->convs, i+off1)) > rank1)
- rank1 = ICS_RANK (TREE_VEC_ELT (cand1->convs, i+off1));
- if (ICS_RANK (TREE_VEC_ELT (cand2->convs, i+off2)) > rank2)
- rank2 = ICS_RANK (TREE_VEC_ELT (cand2->convs, i+off2));
- }
-
- if (rank1 < rank2)
- return 1;
- if (rank1 > rank2)
- return -1;
- }
-
- return winner;
-}
-
-/* Given a list of candidates for overloading, find the best one, if any.
- This algorithm has a worst case of O(2n) (winner is last), and a best
- case of O(n/2) (totally ambiguous); much better than a sorting
- algorithm. */
-
-static struct z_candidate *
-tourney (candidates)
- struct z_candidate *candidates;
-{
- struct z_candidate *champ = candidates, *challenger;
- int fate;
- int champ_compared_to_predecessor = 0;
-
- /* Walk through the list once, comparing each current champ to the next
- candidate, knocking out a candidate or two with each comparison. */
-
- for (challenger = champ->next; challenger; )
- {
- fate = joust (champ, challenger, 0);
- if (fate == 1)
- challenger = challenger->next;
- else
- {
- if (fate == 0)
- {
- champ = challenger->next;
- if (champ == 0)
- return 0;
- champ_compared_to_predecessor = 0;
- }
- else
- {
- champ = challenger;
- champ_compared_to_predecessor = 1;
- }
-
- challenger = champ->next;
- }
- }
-
- /* Make sure the champ is better than all the candidates it hasn't yet
- been compared to. */
-
- for (challenger = candidates;
- challenger != champ
- && !(champ_compared_to_predecessor && challenger->next == champ);
- challenger = challenger->next)
- {
- fate = joust (champ, challenger, 0);
- if (fate != 1)
- return 0;
- }
-
- return champ;
-}
-
-int
-can_convert (to, from)
- tree to, from;
-{
- tree t = implicit_conversion (to, from, NULL_TREE, LOOKUP_NORMAL);
- return (t && ! ICS_BAD_FLAG (t));
-}
-
-int
-can_convert_arg (to, from, arg)
- tree to, from, arg;
-{
- tree t = implicit_conversion (to, from, arg, LOOKUP_NORMAL);
- return (t && ! ICS_BAD_FLAG (t));
-}