Commit 5ffe581d by Jason Merrill Committed by Jason Merrill

cp-tree.def: Add WRAPPER.

	* 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.

From-SVN: r19393
parent 62441128
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> Thu Apr 23 18:27:53 1998 Mark P. Mitchell <mmitchell@usa.net>
* pt.c (unify): Fix typo in previous change. * pt.c (unify): Fix typo in previous change.
......
...@@ -43,10 +43,10 @@ static tree build_new_method_call PROTO((tree, tree, tree, tree, int)); ...@@ -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 build_field_call PROTO((tree, tree, tree, tree));
static tree find_scoped_type PROTO((tree, tree, tree)); static tree find_scoped_type PROTO((tree, tree, tree));
static struct z_candidate * tourney PROTO((struct z_candidate *)); 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_qual PROTO((tree, tree));
static int compare_ics 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_default_arg PROTO((tree, tree));
static tree convert_like PROTO((tree, tree)); static tree convert_like PROTO((tree, tree));
static void op_error PROTO((enum tree_code, enum tree_code, tree, tree, static void op_error PROTO((enum tree_code, enum tree_code, tree, tree,
...@@ -664,6 +664,7 @@ struct z_candidate { ...@@ -664,6 +664,7 @@ struct z_candidate {
int viable; int viable;
tree basetype_path; tree basetype_path;
tree template; tree template;
tree warnings;
struct z_candidate *next; struct z_candidate *next;
}; };
...@@ -689,7 +690,9 @@ struct z_candidate { ...@@ -689,7 +690,9 @@ struct z_candidate {
#define ICS_THIS_FLAG(NODE) TREE_LANG_FLAG_2 (NODE) #define ICS_THIS_FLAG(NODE) TREE_LANG_FLAG_2 (NODE)
#define ICS_BAD_FLAG(NODE) TREE_LANG_FLAG_3 (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 int
null_ptr_cst_p (t) null_ptr_cst_p (t)
...@@ -1049,6 +1052,30 @@ implicit_conversion (to, from, expr, flags) ...@@ -1049,6 +1052,30 @@ implicit_conversion (to, from, expr, flags)
return 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 /* 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 the argument list ARGLIST and add it to CANDIDATES. FLAGS is passed on
to implicit_conversion. */ to implicit_conversion. */
...@@ -1130,17 +1157,7 @@ add_function_candidate (candidates, fn, arglist, flags) ...@@ -1130,17 +1157,7 @@ add_function_candidate (candidates, fn, arglist, flags)
break; break;
} }
cand = (struct z_candidate *) scratchalloc (sizeof (struct z_candidate)); return add_candidate (candidates, fn, convs, viable);
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;
} }
/* Create an overload candidate for the conversion function FN which will /* Create an overload candidate for the conversion function FN which will
...@@ -1207,17 +1224,7 @@ add_conv_candidate (candidates, fn, obj, arglist) ...@@ -1207,17 +1224,7 @@ add_conv_candidate (candidates, fn, obj, arglist)
break; break;
} }
cand = (struct z_candidate *) scratchalloc (sizeof (struct z_candidate)); return add_candidate (candidates, fn, convs, viable);
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;
} }
static struct z_candidate * static struct z_candidate *
...@@ -1267,17 +1274,7 @@ build_builtin_candidate (candidates, fnname, type1, type2, ...@@ -1267,17 +1274,7 @@ build_builtin_candidate (candidates, fnname, type1, type2,
viable = 0; viable = 0;
} }
cand = (struct z_candidate *) scratchalloc (sizeof (struct z_candidate)); return add_candidate (candidates, fnname, convs, viable);
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;
} }
static int static int
...@@ -2173,7 +2170,7 @@ build_user_type_conversion_1 (totype, expr, flags) ...@@ -2173,7 +2170,7 @@ build_user_type_conversion_1 (totype, expr, flags)
(USER_CONV, (USER_CONV,
(DECL_CONSTRUCTOR_P (cand->fn) (DECL_CONSTRUCTOR_P (cand->fn)
? totype : non_reference (TREE_TYPE (TREE_TYPE (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; ICS_USER_FLAG (cand->second_conv) = 1;
if (cand->viable == -1) if (cand->viable == -1)
ICS_BAD_FLAG (cand->second_conv) = 1; ICS_BAD_FLAG (cand->second_conv) = 1;
...@@ -2287,7 +2284,7 @@ build_new_function_call (fn, args) ...@@ -2287,7 +2284,7 @@ build_new_function_call (fn, args)
&& ! DECL_INITIAL (cand->fn)) && ! DECL_INITIAL (cand->fn))
add_maybe_template (cand->fn, templates); 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); return build_function_call (fn, args);
...@@ -2390,7 +2387,7 @@ build_object_call (obj, args) ...@@ -2390,7 +2387,7 @@ build_object_call (obj, args)
} }
if (DECL_NAME (cand->fn) == ansi_opname [CALL_EXPR]) 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); obj = convert_like (TREE_VEC_ELT (cand->convs, 0), obj);
...@@ -2719,9 +2716,6 @@ build_new_op (code, flags, arg1, arg2, arg3) ...@@ -2719,9 +2716,6 @@ build_new_op (code, flags, arg1, arg2, arg3)
: candidates->fn); : candidates->fn);
} }
if (DECL_FUNCTION_MEMBER_P (cand->fn))
enforce_access (cand->basetype_path, cand->fn);
/* Pedantically, normal function declarations are never considered /* Pedantically, normal function declarations are never considered
to refer to template instantiations, so we only do this with to refer to template instantiations, so we only do this with
-fguiding-decls. */ -fguiding-decls. */
...@@ -2731,7 +2725,7 @@ build_new_op (code, flags, arg1, arg2, arg3) ...@@ -2731,7 +2725,7 @@ build_new_op (code, flags, arg1, arg2, arg3)
add_maybe_template (cand->fn, templates); add_maybe_template (cand->fn, templates);
return build_over_call return build_over_call
(cand->fn, cand->convs, (cand,
TREE_CODE (TREE_TYPE (cand->fn)) == METHOD_TYPE TREE_CODE (TREE_TYPE (cand->fn)) == METHOD_TYPE
? mem_arglist : arglist, ? mem_arglist : arglist,
LOOKUP_NORMAL); LOOKUP_NORMAL);
...@@ -3045,9 +3039,10 @@ convert_like (convs, expr) ...@@ -3045,9 +3039,10 @@ convert_like (convs, expr)
{ {
case USER_CONV: 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; tree args;
enforce_access (TREE_OPERAND (convs, 3), fn);
if (DECL_CONSTRUCTOR_P (fn)) if (DECL_CONSTRUCTOR_P (fn))
{ {
...@@ -3061,9 +3056,7 @@ convert_like (convs, expr) ...@@ -3061,9 +3056,7 @@ convert_like (convs, expr)
} }
else else
args = build_this (expr); args = build_this (expr);
expr = build_over_call expr = build_over_call (cand, args, LOOKUP_NORMAL);
(TREE_OPERAND (convs, 1), TREE_OPERAND (convs, 2),
args, LOOKUP_NORMAL);
/* If this is a constructor or a function returning an aggr type, /* If this is a constructor or a function returning an aggr type,
we need to build up a TARGET_EXPR. */ we need to build up a TARGET_EXPR. */
...@@ -3147,16 +3140,27 @@ convert_default_arg (type, arg) ...@@ -3147,16 +3140,27 @@ convert_default_arg (type, arg)
} }
static tree static tree
build_over_call (fn, convs, args, flags) build_over_call (cand, args, flags)
tree fn, convs, args; struct z_candidate *cand;
tree args;
int flags; int flags;
{ {
tree fn = cand->fn;
tree convs = cand->convs;
tree converted_args = NULL_TREE; tree converted_args = NULL_TREE;
tree parm = TYPE_ARG_TYPES (TREE_TYPE (fn)); tree parm = TYPE_ARG_TYPES (TREE_TYPE (fn));
tree conv, arg, val; tree conv, arg, val;
int i = 0; int i = 0;
int is_method = 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) if (args && TREE_CODE (args) != TREE_LIST)
args = build_scratch_list (NULL_TREE, args); args = build_scratch_list (NULL_TREE, args);
arg = args; arg = args;
...@@ -3588,7 +3592,6 @@ build_new_method_call (instance, name, args, basetype_path, flags) ...@@ -3588,7 +3592,6 @@ build_new_method_call (instance, name, args, basetype_path, flags)
return error_mark_node; return error_mark_node;
} }
enforce_access (cand->basetype_path, cand->fn);
if (DECL_ABSTRACT_VIRTUAL_P (cand->fn) if (DECL_ABSTRACT_VIRTUAL_P (cand->fn)
&& instance == current_class_ref && instance == current_class_ref
&& DECL_CONSTRUCTOR_P (current_function_decl) && DECL_CONSTRUCTOR_P (current_function_decl)
...@@ -3613,7 +3616,7 @@ build_new_method_call (instance, name, args, basetype_path, flags) ...@@ -3613,7 +3616,7 @@ build_new_method_call (instance, name, args, basetype_path, flags)
add_maybe_template (cand->fn, templates); add_maybe_template (cand->fn, templates);
return build_over_call return build_over_call
(cand->fn, cand->convs, (cand,
TREE_CODE (TREE_TYPE (cand->fn)) == METHOD_TYPE ? mem_args : args, TREE_CODE (TREE_TYPE (cand->fn)) == METHOD_TYPE ? mem_args : args,
flags); flags);
} }
...@@ -3939,7 +3942,6 @@ compare_ics (ics1, ics2) ...@@ -3939,7 +3942,6 @@ compare_ics (ics1, ics2)
return 0; return 0;
} }
#if 0
/* The source type for this standard conversion sequence. */ /* The source type for this standard conversion sequence. */
static tree static tree
...@@ -3955,7 +3957,19 @@ source_type (t) ...@@ -3955,7 +3957,19 @@ source_type (t)
} }
my_friendly_abort (1823); 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 /* Compare two candidates for overloading as described in
[over.match.best]. Return values: [over.match.best]. Return values:
...@@ -3965,8 +3979,9 @@ source_type (t) ...@@ -3965,8 +3979,9 @@ source_type (t)
0: cand1 and cand2 are indistinguishable */ 0: cand1 and cand2 are indistinguishable */
static int static int
joust (cand1, cand2) joust (cand1, cand2, warn)
struct z_candidate *cand1, *cand2; struct z_candidate *cand1, *cand2;
int warn;
{ {
int winner = 0; int winner = 0;
int i, off1 = 0, off2 = 0, len; int i, off1 = 0, off2 = 0, len;
...@@ -4014,7 +4029,6 @@ joust (cand1, cand2) ...@@ -4014,7 +4029,6 @@ joust (cand1, cand2)
if (comp != 0) if (comp != 0)
{ {
#if 0 /* move this warning to tourney. */
if (warn_sign_promo if (warn_sign_promo
&& ICS_RANK (t1) + ICS_RANK (t2) == STD_RANK + PROMO_RANK && ICS_RANK (t1) + ICS_RANK (t2) == STD_RANK + PROMO_RANK
&& TREE_CODE (t1) == STD_CONV && TREE_CODE (t1) == STD_CONV
...@@ -4029,16 +4043,23 @@ joust (cand1, cand2) ...@@ -4029,16 +4043,23 @@ joust (cand1, cand2)
{ {
tree type = TREE_TYPE (TREE_OPERAND (t1, 0)); tree type = TREE_TYPE (TREE_OPERAND (t1, 0));
tree type1, type2; tree type1, type2;
struct z_candidate *w, *l;
if (comp > 0) if (comp > 0)
type1 = TREE_TYPE (t1), type2 = TREE_TYPE (t2); type1 = TREE_TYPE (t1), type2 = TREE_TYPE (t2),
w = cand1, l = cand2;
else 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'", if (warn)
type, type1, type2); {
cp_warning (" in call to `%D'", DECL_NAME (cand1->fn)); 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) if (winner && comp != winner)
{ {
...@@ -4049,7 +4070,6 @@ joust (cand1, cand2) ...@@ -4049,7 +4070,6 @@ joust (cand1, cand2)
} }
} }
#if 0 /* move this warning to tourney. */
/* warn about confusing overload resolution */ /* warn about confusing overload resolution */
if (winner && cand1->second_conv if (winner && cand1->second_conv
&& ! DECL_CONSTRUCTOR_P (cand1->fn) && ! DECL_CONSTRUCTOR_P (cand1->fn)
...@@ -4063,14 +4083,18 @@ joust (cand1, cand2) ...@@ -4063,14 +4083,18 @@ joust (cand1, cand2)
w = cand1, l = cand2; w = cand1, l = cand2;
else else
w = cand2, l = cand1; w = cand2, l = cand1;
cp_warning ("choosing `%D' over `%D'", w->fn, l->fn); if (warn)
cp_warning (" for conversion from `%T' to `%T'", {
TREE_TYPE (source_type (TREE_VEC_ELT (w->convs, 0))), cp_warning ("choosing `%D' over `%D'", w->fn, l->fn);
TREE_TYPE (w->second_conv)); cp_warning (" for conversion from `%T' to `%T'",
cp_warning (" because conversion sequence for `this' argument is better"); 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) if (winner)
return winner; return winner;
...@@ -4171,7 +4195,7 @@ tourney (candidates) ...@@ -4171,7 +4195,7 @@ tourney (candidates)
for (challenger = champ->next; challenger; ) for (challenger = champ->next; challenger; )
{ {
fate = joust (champ, challenger); fate = joust (champ, challenger, 0);
if (fate == 1) if (fate == 1)
challenger = challenger->next; challenger = challenger->next;
else else
...@@ -4196,7 +4220,7 @@ tourney (candidates) ...@@ -4196,7 +4220,7 @@ tourney (candidates)
for (challenger = candidates; challenger != champ; for (challenger = candidates; challenger != champ;
challenger = challenger->next) challenger = challenger->next)
{ {
fate = joust (champ, challenger); fate = joust (champ, challenger, 0);
if (fate != 1) if (fate != 1)
return 0; return 0;
} }
......
...@@ -173,6 +173,10 @@ DEFTREECODE (TEMPLATE_ID_EXPR, "template_id_expr", 'e', 2) ...@@ -173,6 +173,10 @@ DEFTREECODE (TEMPLATE_ID_EXPR, "template_id_expr", 'e', 2)
/* XXX: could recycle some of the common fields */ /* XXX: could recycle some of the common fields */
DEFTREECODE (CPLUS_BINDING, "binding", 'x', 2) 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 /* A whole bunch of tree codes for the initial, superficial parsing of
templates. */ templates. */
DEFTREECODE (LOOKUP_EXPR, "lookup_expr", 'e', 2) DEFTREECODE (LOOKUP_EXPR, "lookup_expr", 'e', 2)
...@@ -208,6 +212,10 @@ DEFTREECODE (RETURN_INIT, "return_init", 'e', 2) ...@@ -208,6 +212,10 @@ DEFTREECODE (RETURN_INIT, "return_init", 'e', 2)
DEFTREECODE (TRY_BLOCK, "try_stmt", 'e', 2) DEFTREECODE (TRY_BLOCK, "try_stmt", 'e', 2)
DEFTREECODE (HANDLER, "catch_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 (IDENTITY_CONV, "identity_conv", 'e', 1)
DEFTREECODE (LVALUE_CONV, "lvalue_conv", 'e', 1) DEFTREECODE (LVALUE_CONV, "lvalue_conv", 'e', 1)
DEFTREECODE (QUAL_CONV, "qual_conv", 'e', 1) DEFTREECODE (QUAL_CONV, "qual_conv", 'e', 1)
...@@ -216,12 +224,10 @@ DEFTREECODE (PTR_CONV, "ptr_conv", 'e', 1) ...@@ -216,12 +224,10 @@ DEFTREECODE (PTR_CONV, "ptr_conv", 'e', 1)
DEFTREECODE (PMEM_CONV, "pmem_conv", 'e', 1) DEFTREECODE (PMEM_CONV, "pmem_conv", 'e', 1)
DEFTREECODE (BASE_CONV, "base_conv", 'e', 1) DEFTREECODE (BASE_CONV, "base_conv", 'e', 1)
DEFTREECODE (REF_BIND, "ref_bind", '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 (AMBIG_CONV, "ambig_conv", 'e', 1)
DEFTREECODE (RVALUE_CONV, "rvalue_conv", 'e', 1) DEFTREECODE (RVALUE_CONV, "rvalue_conv", 'e', 1)
DEFTREECODE (TAG_DEFN, "tag_defn", 'e', 0)
/* /*
Local variables: Local variables:
mode:c mode:c
......
...@@ -73,6 +73,18 @@ struct tree_binding ...@@ -73,6 +73,18 @@ struct tree_binding
tree value; 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 /* To identify to the debug emitters if it should pay attention to the
flag `-Wtemplate-debugging'. */ flag `-Wtemplate-debugging'. */
#define HAVE_TEMPLATES 1 #define HAVE_TEMPLATES 1
...@@ -2624,6 +2636,9 @@ extern tree hack_decl_function_context PROTO((tree)); ...@@ -2624,6 +2636,9 @@ extern tree hack_decl_function_context PROTO((tree));
extern tree lvalue_type PROTO((tree)); extern tree lvalue_type PROTO((tree));
extern tree error_type PROTO((tree)); extern tree error_type PROTO((tree));
extern tree make_temp_vec PROTO((int)); 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 varargs_function_p PROTO((tree));
extern int really_overloaded_fn PROTO((tree)); extern int really_overloaded_fn PROTO((tree));
extern int cp_tree_equal PROTO((tree, tree)); extern int cp_tree_equal PROTO((tree, tree));
......
...@@ -5594,7 +5594,7 @@ template_decl_level (decl) ...@@ -5594,7 +5594,7 @@ template_decl_level (decl)
default: default:
my_friendly_abort (0); my_friendly_abort (0);
break; return 0;
} }
} }
......
...@@ -2141,6 +2141,41 @@ make_temp_vec (len) ...@@ -2141,6 +2141,41 @@ make_temp_vec (len)
return node; 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 void
push_expression_obstack () push_expression_obstack ()
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment