aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMark Mitchell <mmitchell@usa.net>1997-09-08 09:28:51 +0000
committerJason Merrill <jason@gcc.gnu.org>1997-09-08 05:28:51 -0400
commit786b5245966e3e9b710015ce7fd28992391d891b (patch)
tree947c04ec83511b3bab40eb322bd28e8bcd75c265 /gcc
parent267c09ab53236587a4f5c4412182885daab79fce (diff)
downloadgcc-786b5245966e3e9b710015ce7fd28992391d891b.zip
gcc-786b5245966e3e9b710015ce7fd28992391d891b.tar.gz
gcc-786b5245966e3e9b710015ce7fd28992391d891b.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog23
-rw-r--r--gcc/cp/call.c62
-rw-r--r--gcc/cp/error.c12
-rw-r--r--gcc/cp/lex.c6
-rw-r--r--gcc/cp/pt.c38
5 files changed, 117 insertions, 24 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index f446a4f..213ac39 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,26 @@
+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.
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 0631614..5bf18c9 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -78,6 +78,8 @@ 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, 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));
@@ -4170,6 +4172,33 @@ add_template_candidate (candidates, tmpl, arglist, return_type, flags)
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;
@@ -4508,6 +4537,7 @@ build_object_call (obj, args)
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);
@@ -4523,9 +4553,19 @@ build_object_call (obj, args)
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);
}
}
@@ -4540,8 +4580,20 @@ build_object_call (obj, args)
&& 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);
}
}
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index ce2bc3b..847bfa2 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -1366,13 +1366,15 @@ dump_expr (t, nop)
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));
diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c
index 471033f..8bd9c57 100644
--- a/gcc/cp/lex.c
+++ b/gcc/cp/lex.c
@@ -1191,7 +1191,7 @@ do_pending_inlines ()
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);
@@ -1254,7 +1254,7 @@ process_next_inline (t)
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;
@@ -1874,7 +1874,7 @@ do_pending_defargs ()
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)
{
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index a0154e1..0c24ec4 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -82,29 +82,40 @@ static tree add_to_template_args PROTO((tree, tree));
/* 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);
}
@@ -121,6 +132,7 @@ end_member_template_processing ()
--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
@@ -449,7 +461,11 @@ push_template_decl (decl)
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
{