summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>1998-04-23 22:26:41 +0000
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>1998-04-23 22:26:41 +0000
commit94c2a480364d2d31dfa77e2e27c8336e63329aa5 (patch)
treeb93fa3db5f37a1e13f91c30e07db66b00d3399e4 /gcc
parent2aabe804f2edb9ff165d90e9786cba8cd5627eb1 (diff)
downloadgcc-94c2a480364d2d31dfa77e2e27c8336e63329aa5.tar.gz
* cp-tree.def: Add WRAPPER. USER_CONV now only has two ops.
* cp-tree.h: Add WRAPPER support. * call.c (add_candidate): Split out from add_*_candidate fns. (build_over_call): Take the candidate instead of function and args. Enforce access control here. Emit overload warnings here. (add_warning): New fn. (joust): Add WARN parm. If not set, call add_warning instead of printing a warning. Reenable some warnings. (tourney): Pass it. (convert_like): Adjust. (build_new_op): Adjust. (build_new_function_call): Adjust. (build_user_type_conversion_1): Adjust. (USER_CONV_FN): Adjust. * tree.c (build_expr_wrapper, build_expr_ptr_wrapper, build_int_wrapper): New fns. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@19393 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog19
-rw-r--r--gcc/cp/call.c166
-rw-r--r--gcc/cp/cp-tree.def12
-rw-r--r--gcc/cp/cp-tree.h15
-rw-r--r--gcc/cp/pt.c2
-rw-r--r--gcc/cp/tree.c35
6 files changed, 174 insertions, 75 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 5f2a5d41e9b..eb764e85be1 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,22 @@
+Thu Apr 23 21:19:06 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cp-tree.def: Add WRAPPER. USER_CONV now only has two ops.
+ * cp-tree.h: Add WRAPPER support.
+ * call.c (add_candidate): Split out from add_*_candidate fns.
+ (build_over_call): Take the candidate instead of function and args.
+ Enforce access control here. Emit overload warnings here.
+ (add_warning): New fn.
+ (joust): Add WARN parm. If not set, call add_warning instead of
+ printing a warning. Reenable some warnings.
+ (tourney): Pass it.
+ (convert_like): Adjust.
+ (build_new_op): Adjust.
+ (build_new_function_call): Adjust.
+ (build_user_type_conversion_1): Adjust.
+ (USER_CONV_FN): Adjust.
+ * tree.c (build_expr_wrapper, build_expr_ptr_wrapper,
+ build_int_wrapper): New fns.
+
Thu Apr 23 18:27:53 1998 Mark P. Mitchell <mmitchell@usa.net>
* pt.c (unify): Fix typo in previous change.
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 46a5be00ef3..5fd81f511bd 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -43,10 +43,10 @@ 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 *));
+static int joust PROTO((struct z_candidate *, struct z_candidate *, int));
static int compare_qual PROTO((tree, tree));
static int compare_ics PROTO((tree, tree));
-static tree build_over_call PROTO((tree, tree, tree, int));
+static tree build_over_call PROTO((struct z_candidate *, tree, int));
static tree convert_default_arg PROTO((tree, tree));
static tree convert_like PROTO((tree, tree));
static void op_error PROTO((enum tree_code, enum tree_code, tree, tree,
@@ -664,6 +664,7 @@ struct z_candidate {
int viable;
tree basetype_path;
tree template;
+ tree warnings;
struct z_candidate *next;
};
@@ -689,7 +690,9 @@ struct z_candidate {
#define ICS_THIS_FLAG(NODE) TREE_LANG_FLAG_2 (NODE)
#define ICS_BAD_FLAG(NODE) TREE_LANG_FLAG_3 (NODE)
-#define USER_CONV_FN(NODE) TREE_OPERAND (NODE, 1)
+#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)
@@ -1049,6 +1052,30 @@ implicit_conversion (to, from, expr, flags)
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. */
@@ -1130,17 +1157,7 @@ add_function_candidate (candidates, fn, arglist, flags)
break;
}
- 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->next = candidates;
-
- return cand;
+ return add_candidate (candidates, fn, convs, viable);
}
/* Create an overload candidate for the conversion function FN which will
@@ -1207,17 +1224,7 @@ add_conv_candidate (candidates, fn, obj, arglist)
break;
}
- 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->next = candidates;
-
- return cand;
+ return add_candidate (candidates, fn, convs, viable);
}
static struct z_candidate *
@@ -1267,17 +1274,7 @@ build_builtin_candidate (candidates, fnname, type1, type2,
viable = 0;
}
- cand = (struct z_candidate *) scratchalloc (sizeof (struct z_candidate));
-
- cand->fn = fnname;
- cand->convs = convs;
- cand->second_conv = NULL_TREE;
- cand->viable = viable;
- cand->basetype_path = NULL_TREE;
- cand->template = NULL_TREE;
- cand->next = candidates;
-
- return cand;
+ return add_candidate (candidates, fnname, convs, viable);
}
static int
@@ -2173,7 +2170,7 @@ build_user_type_conversion_1 (totype, expr, flags)
(USER_CONV,
(DECL_CONSTRUCTOR_P (cand->fn)
? totype : non_reference (TREE_TYPE (TREE_TYPE (cand->fn)))),
- expr, cand->fn, cand->convs, cand->basetype_path);
+ expr, build_expr_ptr_wrapper (cand));
ICS_USER_FLAG (cand->second_conv) = 1;
if (cand->viable == -1)
ICS_BAD_FLAG (cand->second_conv) = 1;
@@ -2287,7 +2284,7 @@ build_new_function_call (fn, args)
&& ! DECL_INITIAL (cand->fn))
add_maybe_template (cand->fn, templates);
- return build_over_call (cand->fn, cand->convs, args, LOOKUP_NORMAL);
+ return build_over_call (cand, args, LOOKUP_NORMAL);
}
return build_function_call (fn, args);
@@ -2390,7 +2387,7 @@ build_object_call (obj, args)
}
if (DECL_NAME (cand->fn) == ansi_opname [CALL_EXPR])
- return build_over_call (cand->fn, cand->convs, mem_args, LOOKUP_NORMAL);
+ return build_over_call (cand, mem_args, LOOKUP_NORMAL);
obj = convert_like (TREE_VEC_ELT (cand->convs, 0), obj);
@@ -2719,9 +2716,6 @@ build_new_op (code, flags, arg1, arg2, arg3)
: candidates->fn);
}
- if (DECL_FUNCTION_MEMBER_P (cand->fn))
- enforce_access (cand->basetype_path, cand->fn);
-
/* Pedantically, normal function declarations are never considered
to refer to template instantiations, so we only do this with
-fguiding-decls. */
@@ -2731,7 +2725,7 @@ build_new_op (code, flags, arg1, arg2, arg3)
add_maybe_template (cand->fn, templates);
return build_over_call
- (cand->fn, cand->convs,
+ (cand,
TREE_CODE (TREE_TYPE (cand->fn)) == METHOD_TYPE
? mem_arglist : arglist,
LOOKUP_NORMAL);
@@ -3045,9 +3039,10 @@ convert_like (convs, expr)
{
case USER_CONV:
{
- tree fn = TREE_OPERAND (convs, 1);
+ struct z_candidate *cand
+ = WRAPPER_PTR (TREE_OPERAND (convs, 1));
+ tree fn = cand->fn;
tree args;
- enforce_access (TREE_OPERAND (convs, 3), fn);
if (DECL_CONSTRUCTOR_P (fn))
{
@@ -3061,9 +3056,7 @@ convert_like (convs, expr)
}
else
args = build_this (expr);
- expr = build_over_call
- (TREE_OPERAND (convs, 1), TREE_OPERAND (convs, 2),
- args, LOOKUP_NORMAL);
+ 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. */
@@ -3147,16 +3140,27 @@ convert_default_arg (type, arg)
}
static tree
-build_over_call (fn, convs, args, flags)
- tree fn, convs, args;
+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;
@@ -3588,7 +3592,6 @@ build_new_method_call (instance, name, args, basetype_path, flags)
return error_mark_node;
}
- enforce_access (cand->basetype_path, cand->fn);
if (DECL_ABSTRACT_VIRTUAL_P (cand->fn)
&& instance == current_class_ref
&& DECL_CONSTRUCTOR_P (current_function_decl)
@@ -3613,7 +3616,7 @@ build_new_method_call (instance, name, args, basetype_path, flags)
add_maybe_template (cand->fn, templates);
return build_over_call
- (cand->fn, cand->convs,
+ (cand,
TREE_CODE (TREE_TYPE (cand->fn)) == METHOD_TYPE ? mem_args : args,
flags);
}
@@ -3939,7 +3942,6 @@ compare_ics (ics1, ics2)
return 0;
}
-#if 0
/* The source type for this standard conversion sequence. */
static tree
@@ -3955,7 +3957,19 @@ source_type (t)
}
my_friendly_abort (1823);
}
-#endif
+
+/* 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:
@@ -3965,8 +3979,9 @@ source_type (t)
0: cand1 and cand2 are indistinguishable */
static int
-joust (cand1, cand2)
+joust (cand1, cand2, warn)
struct z_candidate *cand1, *cand2;
+ int warn;
{
int winner = 0;
int i, off1 = 0, off2 = 0, len;
@@ -4014,7 +4029,6 @@ joust (cand1, cand2)
if (comp != 0)
{
-#if 0 /* move this warning to tourney. */
if (warn_sign_promo
&& ICS_RANK (t1) + ICS_RANK (t2) == STD_RANK + PROMO_RANK
&& TREE_CODE (t1) == STD_CONV
@@ -4029,16 +4043,23 @@ joust (cand1, cand2)
{
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);
+ type1 = TREE_TYPE (t1), type2 = TREE_TYPE (t2),
+ w = cand1, l = cand2;
else
- type1 = TREE_TYPE (t2), type2 = TREE_TYPE (t1);
+ type1 = TREE_TYPE (t2), type2 = TREE_TYPE (t1),
+ w = cand2, l = cand1;
- cp_warning ("passing `%T' chooses `%T' over `%T'",
- type, type1, type2);
- cp_warning (" in call to `%D'", DECL_NAME (cand1->fn));
+ 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);
}
-#endif
if (winner && comp != winner)
{
@@ -4049,7 +4070,6 @@ joust (cand1, cand2)
}
}
-#if 0 /* move this warning to tourney. */
/* warn about confusing overload resolution */
if (winner && cand1->second_conv
&& ! DECL_CONSTRUCTOR_P (cand1->fn)
@@ -4063,14 +4083,18 @@ joust (cand1, cand2)
w = cand1, l = cand2;
else
w = cand2, l = cand1;
- cp_warning ("choosing `%D' over `%D'", w->fn, l->fn);
- cp_warning (" for conversion from `%T' to `%T'",
- TREE_TYPE (source_type (TREE_VEC_ELT (w->convs, 0))),
- TREE_TYPE (w->second_conv));
- cp_warning (" because conversion sequence for `this' argument is better");
+ if (warn)
+ {
+ cp_warning ("choosing `%D' over `%D'", w->fn, l->fn);
+ cp_warning (" for conversion from `%T' to `%T'",
+ TREE_TYPE (source_type (TREE_VEC_ELT (w->convs, 0))),
+ TREE_TYPE (w->second_conv));
+ cp_warning (" because conversion sequence for `this' argument is better");
+ }
+ else
+ add_warning (w, l);
}
}
-#endif
if (winner)
return winner;
@@ -4171,7 +4195,7 @@ tourney (candidates)
for (challenger = champ->next; challenger; )
{
- fate = joust (champ, challenger);
+ fate = joust (champ, challenger, 0);
if (fate == 1)
challenger = challenger->next;
else
@@ -4196,7 +4220,7 @@ tourney (candidates)
for (challenger = candidates; challenger != champ;
challenger = challenger->next)
{
- fate = joust (champ, challenger);
+ fate = joust (champ, challenger, 0);
if (fate != 1)
return 0;
}
diff --git a/gcc/cp/cp-tree.def b/gcc/cp/cp-tree.def
index 5ee7500bfb5..0a42d74a67b 100644
--- a/gcc/cp/cp-tree.def
+++ b/gcc/cp/cp-tree.def
@@ -173,6 +173,10 @@ DEFTREECODE (TEMPLATE_ID_EXPR, "template_id_expr", 'e', 2)
/* XXX: could recycle some of the common fields */
DEFTREECODE (CPLUS_BINDING, "binding", 'x', 2)
+/* A generic wrapper for something not tree that we want to include in
+ tree structure. */
+DEFTREECODE (WRAPPER, "wrapper", 'x', 1)
+
/* A whole bunch of tree codes for the initial, superficial parsing of
templates. */
DEFTREECODE (LOOKUP_EXPR, "lookup_expr", 'e', 2)
@@ -208,6 +212,10 @@ DEFTREECODE (RETURN_INIT, "return_init", 'e', 2)
DEFTREECODE (TRY_BLOCK, "try_stmt", 'e', 2)
DEFTREECODE (HANDLER, "catch_stmt", 'e', 2)
+DEFTREECODE (TAG_DEFN, "tag_defn", 'e', 0)
+
+/* And some codes for expressing conversions for overload resolution. */
+
DEFTREECODE (IDENTITY_CONV, "identity_conv", 'e', 1)
DEFTREECODE (LVALUE_CONV, "lvalue_conv", 'e', 1)
DEFTREECODE (QUAL_CONV, "qual_conv", 'e', 1)
@@ -216,12 +224,10 @@ DEFTREECODE (PTR_CONV, "ptr_conv", 'e', 1)
DEFTREECODE (PMEM_CONV, "pmem_conv", 'e', 1)
DEFTREECODE (BASE_CONV, "base_conv", 'e', 1)
DEFTREECODE (REF_BIND, "ref_bind", 'e', 1)
-DEFTREECODE (USER_CONV, "user_conv", 'e', 4)
+DEFTREECODE (USER_CONV, "user_conv", 'e', 2)
DEFTREECODE (AMBIG_CONV, "ambig_conv", 'e', 1)
DEFTREECODE (RVALUE_CONV, "rvalue_conv", 'e', 1)
-DEFTREECODE (TAG_DEFN, "tag_defn", 'e', 0)
-
/*
Local variables:
mode:c
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 8b943c43a21..3247196fcc2 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -73,6 +73,18 @@ struct tree_binding
tree value;
};
+#define WRAPPER_PTR(NODE) (((struct tree_wrapper*)NODE)->u.ptr)
+#define WRAPPER_INT(NODE) (((struct tree_wrapper*)NODE)->u.i)
+
+struct tree_wrapper
+{
+ char common[sizeof (struct tree_common)];
+ union {
+ void *ptr;
+ int i;
+ } u;
+};
+
/* To identify to the debug emitters if it should pay attention to the
flag `-Wtemplate-debugging'. */
#define HAVE_TEMPLATES 1
@@ -2624,6 +2636,9 @@ extern tree hack_decl_function_context PROTO((tree));
extern tree lvalue_type PROTO((tree));
extern tree error_type PROTO((tree));
extern tree make_temp_vec PROTO((int));
+extern tree build_ptr_wrapper PROTO((void *));
+extern tree build_expr_ptr_wrapper PROTO((void *));
+extern tree build_int_wrapper PROTO((int));
extern int varargs_function_p PROTO((tree));
extern int really_overloaded_fn PROTO((tree));
extern int cp_tree_equal PROTO((tree, tree));
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index d88f9fe3a3e..5284e7654ea 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -5594,7 +5594,7 @@ template_decl_level (decl)
default:
my_friendly_abort (0);
- break;
+ return 0;
}
}
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index de3906c5802..3b4ca22efc9 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -2141,6 +2141,41 @@ make_temp_vec (len)
return node;
}
+/* Build a wrapper around some pointer PTR so we can use it as a tree. */
+
+tree
+build_ptr_wrapper (ptr)
+ void *ptr;
+{
+ tree t = make_node (WRAPPER);
+ WRAPPER_PTR (t) = ptr;
+ return t;
+}
+
+/* Same, but on the expression_obstack. */
+
+tree
+build_expr_ptr_wrapper (ptr)
+ void *ptr;
+{
+ tree t;
+ push_expression_obstack ();
+ t = build_ptr_wrapper (ptr);
+ pop_obstacks ();
+ return t;
+}
+
+/* Build a wrapper around some integer I so we can use it as a tree. */
+
+tree
+build_int_wrapper (i)
+ int i;
+{
+ tree t = make_node (WRAPPER);
+ WRAPPER_INT (t) = i;
+ return t;
+}
+
void
push_expression_obstack ()
{