+Mon Sep 8 01:21:43 1997 Mark Mitchell <mmitchell@usa.net>
+
+ * pt.c (begin_member_template_processing): Take a function as
+ argument, not a set of template arguments. Use the template
+ parameters, rather than the arguments. Handle non-type parameters
+ correctly. Push a binding level for the parameters so that multiple
+ member templates using the same parameter names can be declared.
+ (end_member_template_processing): Pop the binding level.
+ (push_template_decl): Mark member templates as static when
+ appropriate.
+
+ * lex.c (do_pending_inlines): Pass the function, not its template
+ arguments, to begin_member_template_processing.
+ (process_next_inline): Likewise.
+ (do_pending_defargs): Likewise.
+
+ * error.c (dump_expr): Obtain the correct declaration for a
+ TEMPLATE_CONST_PARM.
+
+ * call.c (add_template_conv_candidate): New function.
+ (build_object_call): Handle member templates, as done in the other
+ build_ functions.
+
Sat Sep 6 10:20:27 1997 Mark Mitchell <mmitchell@usa.net>
* decl.c (replace_defag): Undo previous change.
static int any_viable PROTO((struct z_candidate *));
static struct z_candidate * add_template_candidate
PROTO((struct z_candidate *, tree, tree, tree, int));
+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));
return cand;
}
+
+static struct z_candidate *
+add_template_conv_candidate (candidates, tmpl, obj, arglist, return_type)
+ struct z_candidate *candidates;
+ tree tmpl, obj, arglist, return_type;
+{
+ int ntparms = DECL_NTPARMS (tmpl);
+ tree targs = make_tree_vec (ntparms);
+ struct z_candidate *cand;
+ int i;
+ tree fn;
+
+ i = fn_type_unification (tmpl, targs, arglist, return_type, 0);
+
+ if (i != 0)
+ return candidates;
+
+ fn = instantiate_template (tmpl, targs);
+ if (fn == error_mark_node)
+ return candidates;
+
+ cand = add_conv_candidate (candidates, fn, obj, arglist);
+ cand->template = DECL_TEMPLATE_INFO (fn);
+ return cand;
+}
+
+
static int
any_viable (cands)
struct z_candidate *cands;
struct z_candidate *candidates = 0, *cand;
tree fns, convs, mem_args;
tree type = TREE_TYPE (obj);
+ tree templates = NULL_TREE;
fns = lookup_fnfields (TYPE_BINFO (type), ansi_opname [CALL_EXPR], 0);
for (; fn; fn = DECL_CHAIN (fn))
{
- candidates = add_function_candidate
- (candidates, fn, mem_args, LOOKUP_NORMAL);
- candidates->basetype_path = TREE_PURPOSE (fns);
+ if (TREE_CODE (fn) == TEMPLATE_DECL)
+ {
+ templates = decl_tree_cons (NULL_TREE, fn, templates);
+ candidates = add_template_candidate (candidates, fn,
+ mem_args, NULL_TREE,
+ LOOKUP_NORMAL);
+ }
+ else
+ candidates = add_function_candidate
+ (candidates, fn, mem_args, LOOKUP_NORMAL);
+
+ if (candidates)
+ candidates->basetype_path = TREE_PURPOSE (fns);
}
}
&& TREE_CODE (TREE_TYPE (totype)) == FUNCTION_TYPE)
for (; fn; fn = DECL_CHAIN (fn))
{
- candidates = add_conv_candidate (candidates, fn, obj, args);
- candidates->basetype_path = TREE_PURPOSE (convs);
+ if (TREE_CODE (fn) == TEMPLATE_DECL)
+ {
+ templates = decl_tree_cons (NULL_TREE, fn, templates);
+ 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 (current_template_parms)
{
int i;
- tree parms;
+ int l = list_length (current_template_parms);
+ tree parms = current_template_parms;
tree r;
- for (parms = current_template_parms;
- TREE_CHAIN (parms);
- parms = TREE_CHAIN (parms))
- ;
+ for (i = 0; i < l - TEMPLATE_CONST_LEVEL (t); ++i)
+ {
+ parms = TREE_CHAIN (parms);
+ my_friendly_assert (parms != NULL_TREE, 0);
+ }
r = TREE_VEC_ELT (TREE_VALUE (parms),
TEMPLATE_CONST_IDX (t));
if (context)
push_cp_function_context (context);
if (is_member_template (t->fndecl))
- begin_member_template_processing (DECL_TI_ARGS (t->fndecl));
+ begin_member_template_processing (t->fndecl);
if (t->len > 0)
{
feed_input (t->buf, t->len);
if (context)
push_cp_function_context (context);
if (is_member_template (i->fndecl))
- begin_member_template_processing (DECL_TI_ARGS (i->fndecl));
+ begin_member_template_processing (i->fndecl);
feed_input (i->buf, i->len);
lineno = i->lineno;
input_filename = i->filename;
push_nested_class (TREE_PURPOSE (defarg_fns), 1);
pushlevel (0);
if (is_member_template (defarg_fn))
- begin_member_template_processing (DECL_TI_ARGS (defarg_fn));
+ begin_member_template_processing (defarg_fn);
if (TREE_CODE (defarg_fn) == FUNCTION_DECL)
{
/* Restore the template parameter context. */
void
-begin_member_template_processing (parms)
- tree parms;
+begin_member_template_processing (decl)
+ tree decl;
{
+ tree parms;
int i;
+ parms = DECL_INNERMOST_TEMPLATE_PARMS (DECL_TI_TEMPLATE (decl));
+
++processing_template_decl;
current_template_parms
= tree_cons (build_int_2 (0, processing_template_decl),
parms, current_template_parms);
+ pushlevel (0);
for (i = 0; i < TREE_VEC_LENGTH (parms); ++i)
{
- tree parm = TREE_VEC_ELT (parms, i);
-
+ tree parm = TREE_VALUE (TREE_VEC_ELT (parms, i));
+ my_friendly_assert (TREE_CODE_CLASS (TREE_CODE (parm)) == 'd', 0);
+
switch (TREE_CODE (parm))
{
- case TEMPLATE_TYPE_PARM:
- pushdecl (TYPE_NAME (parm));
- break;
-
- case TEMPLATE_CONST_PARM:
+ case TYPE_DECL:
pushdecl (parm);
break;
-
+
+ case PARM_DECL:
+ {
+ /* Make a CONST_DECL as is done in process_template_parm. */
+ tree decl = build_decl (CONST_DECL, DECL_NAME (parm),
+ TREE_TYPE (parm));
+ DECL_INITIAL (decl) = DECL_INITIAL (parm);
+ pushdecl (decl);
+ }
+ break;
+
default:
my_friendly_abort (0);
}
--processing_template_decl;
current_template_parms = TREE_CHAIN (current_template_parms);
+ poplevel (0, 0, 0);
}
/* Returns non-zero iff T is a member template function. Works if T
DECL_TEMPLATE_PARMS (tmpl) = current_template_parms;
DECL_CONTEXT (tmpl) = DECL_CONTEXT (decl);
if (DECL_LANG_SPECIFIC (decl))
- DECL_CLASS_CONTEXT (tmpl) = DECL_CLASS_CONTEXT (decl);
+ {
+ DECL_CLASS_CONTEXT (tmpl) = DECL_CLASS_CONTEXT (decl);
+ DECL_STATIC_FUNCTION_P (tmpl) =
+ DECL_STATIC_FUNCTION_P (decl);
+ }
}
else
{