Commit 786b5245 by Mark Mitchell Committed by Jason Merrill

pt.c (begin_member_template_processing): Take a function as argument, not a set…

pt.c (begin_member_template_processing): Take a function as argument, not a set of template arguments.

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.

From-SVN: r15155
parent 267c09ab
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> Sat Sep 6 10:20:27 1997 Mark Mitchell <mmitchell@usa.net>
* decl.c (replace_defag): Undo previous change. * decl.c (replace_defag): Undo previous change.
......
...@@ -78,6 +78,8 @@ static struct z_candidate * splice_viable PROTO((struct z_candidate *)); ...@@ -78,6 +78,8 @@ static struct z_candidate * splice_viable PROTO((struct z_candidate *));
static int any_viable PROTO((struct z_candidate *)); static int any_viable PROTO((struct z_candidate *));
static struct z_candidate * add_template_candidate static struct z_candidate * add_template_candidate
PROTO((struct z_candidate *, tree, tree, tree, int)); 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 static struct z_candidate * add_builtin_candidates
PROTO((struct z_candidate *, enum tree_code, enum tree_code, PROTO((struct z_candidate *, enum tree_code, enum tree_code,
tree, tree *, int)); tree, tree *, int));
...@@ -4170,6 +4172,33 @@ add_template_candidate (candidates, tmpl, arglist, return_type, flags) ...@@ -4170,6 +4172,33 @@ add_template_candidate (candidates, tmpl, arglist, return_type, flags)
return cand; 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 static int
any_viable (cands) any_viable (cands)
struct z_candidate *cands; struct z_candidate *cands;
...@@ -4508,6 +4537,7 @@ build_object_call (obj, args) ...@@ -4508,6 +4537,7 @@ build_object_call (obj, args)
struct z_candidate *candidates = 0, *cand; struct z_candidate *candidates = 0, *cand;
tree fns, convs, mem_args; tree fns, convs, mem_args;
tree type = TREE_TYPE (obj); tree type = TREE_TYPE (obj);
tree templates = NULL_TREE;
fns = lookup_fnfields (TYPE_BINFO (type), ansi_opname [CALL_EXPR], 0); fns = lookup_fnfields (TYPE_BINFO (type), ansi_opname [CALL_EXPR], 0);
...@@ -4523,9 +4553,19 @@ build_object_call (obj, args) ...@@ -4523,9 +4553,19 @@ build_object_call (obj, args)
for (; fn; fn = DECL_CHAIN (fn)) for (; fn; fn = DECL_CHAIN (fn))
{ {
candidates = add_function_candidate if (TREE_CODE (fn) == TEMPLATE_DECL)
(candidates, fn, mem_args, LOOKUP_NORMAL); {
candidates->basetype_path = TREE_PURPOSE (fns); 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);
} }
} }
...@@ -4540,8 +4580,20 @@ build_object_call (obj, args) ...@@ -4540,8 +4580,20 @@ build_object_call (obj, args)
&& TREE_CODE (TREE_TYPE (totype)) == FUNCTION_TYPE) && TREE_CODE (TREE_TYPE (totype)) == FUNCTION_TYPE)
for (; fn; fn = DECL_CHAIN (fn)) for (; fn; fn = DECL_CHAIN (fn))
{ {
candidates = add_conv_candidate (candidates, fn, obj, args); if (TREE_CODE (fn) == TEMPLATE_DECL)
candidates->basetype_path = TREE_PURPOSE (convs); {
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);
} }
} }
......
...@@ -1366,13 +1366,15 @@ dump_expr (t, nop) ...@@ -1366,13 +1366,15 @@ dump_expr (t, nop)
if (current_template_parms) if (current_template_parms)
{ {
int i; int i;
tree parms; int l = list_length (current_template_parms);
tree parms = current_template_parms;
tree r; tree r;
for (parms = current_template_parms; for (i = 0; i < l - TEMPLATE_CONST_LEVEL (t); ++i)
TREE_CHAIN (parms); {
parms = TREE_CHAIN (parms)) parms = TREE_CHAIN (parms);
; my_friendly_assert (parms != NULL_TREE, 0);
}
r = TREE_VEC_ELT (TREE_VALUE (parms), r = TREE_VEC_ELT (TREE_VALUE (parms),
TEMPLATE_CONST_IDX (t)); TEMPLATE_CONST_IDX (t));
......
...@@ -1191,7 +1191,7 @@ do_pending_inlines () ...@@ -1191,7 +1191,7 @@ do_pending_inlines ()
if (context) if (context)
push_cp_function_context (context); push_cp_function_context (context);
if (is_member_template (t->fndecl)) 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) if (t->len > 0)
{ {
feed_input (t->buf, t->len); feed_input (t->buf, t->len);
...@@ -1254,7 +1254,7 @@ process_next_inline (t) ...@@ -1254,7 +1254,7 @@ process_next_inline (t)
if (context) if (context)
push_cp_function_context (context); push_cp_function_context (context);
if (is_member_template (i->fndecl)) 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); feed_input (i->buf, i->len);
lineno = i->lineno; lineno = i->lineno;
input_filename = i->filename; input_filename = i->filename;
...@@ -1874,7 +1874,7 @@ do_pending_defargs () ...@@ -1874,7 +1874,7 @@ do_pending_defargs ()
push_nested_class (TREE_PURPOSE (defarg_fns), 1); push_nested_class (TREE_PURPOSE (defarg_fns), 1);
pushlevel (0); pushlevel (0);
if (is_member_template (defarg_fn)) 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) if (TREE_CODE (defarg_fn) == FUNCTION_DECL)
{ {
......
...@@ -82,29 +82,40 @@ static tree add_to_template_args PROTO((tree, tree)); ...@@ -82,29 +82,40 @@ static tree add_to_template_args PROTO((tree, tree));
/* Restore the template parameter context. */ /* Restore the template parameter context. */
void void
begin_member_template_processing (parms) begin_member_template_processing (decl)
tree parms; tree decl;
{ {
tree parms;
int i; int i;
parms = DECL_INNERMOST_TEMPLATE_PARMS (DECL_TI_TEMPLATE (decl));
++processing_template_decl; ++processing_template_decl;
current_template_parms current_template_parms
= tree_cons (build_int_2 (0, processing_template_decl), = tree_cons (build_int_2 (0, processing_template_decl),
parms, current_template_parms); parms, current_template_parms);
pushlevel (0);
for (i = 0; i < TREE_VEC_LENGTH (parms); ++i) 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)) switch (TREE_CODE (parm))
{ {
case TEMPLATE_TYPE_PARM: case TYPE_DECL:
pushdecl (TYPE_NAME (parm));
break;
case TEMPLATE_CONST_PARM:
pushdecl (parm); pushdecl (parm);
break; 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: default:
my_friendly_abort (0); my_friendly_abort (0);
} }
...@@ -121,6 +132,7 @@ end_member_template_processing () ...@@ -121,6 +132,7 @@ end_member_template_processing ()
--processing_template_decl; --processing_template_decl;
current_template_parms = TREE_CHAIN (current_template_parms); 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 /* Returns non-zero iff T is a member template function. Works if T
...@@ -449,7 +461,11 @@ push_template_decl (decl) ...@@ -449,7 +461,11 @@ push_template_decl (decl)
DECL_TEMPLATE_PARMS (tmpl) = current_template_parms; DECL_TEMPLATE_PARMS (tmpl) = current_template_parms;
DECL_CONTEXT (tmpl) = DECL_CONTEXT (decl); DECL_CONTEXT (tmpl) = DECL_CONTEXT (decl);
if (DECL_LANG_SPECIFIC (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 else
{ {
......
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