From 786b5245966e3e9b710015ce7fd28992391d891b Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Mon, 8 Sep 1997 09:28:51 +0000 Subject: [PATCH] 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 * 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 --- gcc/cp/ChangeLog | 23 ++++++++++++++++++ gcc/cp/call.c | 62 ++++++++++++++++++++++++++++++++++++++++++++---- gcc/cp/error.c | 12 ++++++---- gcc/cp/lex.c | 6 ++--- gcc/cp/pt.c | 38 ++++++++++++++++++++--------- 5 files changed, 117 insertions(+), 24 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index f446a4f5947..213ac3980d3 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,26 @@ +Mon Sep 8 01:21:43 1997 Mark Mitchell + + * 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 * decl.c (replace_defag): Undo previous change. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 06316143a2b..5bf18c9b69c 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 ce2bc3b88dc..847bfa22495 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 471033faf9e..8bd9c57624a 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 a0154e173ef..0c24ec4eeb9 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 { -- 2.30.2