From e6f1275f861e69c54e4812870d5c05c8c72df757 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Fri, 20 Mar 1998 05:44:06 -0500 Subject: [PATCH] pt.c (complete_template_args): Rewrite. * pt.c (complete_template_args): Rewrite. (tsubst, FUNCTION_DECL): Use it. * semantics.c (finish_asm_stmt): Fix combine strings. Call c_expand_asm_operands () if output_operands, input_operands or clobbers is not NULL_TREE. * pt.c (complete_template_args): New function. (get_bindings): Deal with specializations of function templates with return type containing parameters from outer class templates. (tsubst, TEMPLATE_TEMPLATE_PARM): When reducing parameter level, substitute arguments and compose a new type. From-SVN: r18724 --- gcc/cp/ChangeLog | 20 +++++++ gcc/cp/pt.c | 134 +++++++++++++++++++++++++++++++++++++++------ gcc/cp/semantics.c | 5 +- 3 files changed, 140 insertions(+), 19 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 5c41abc7b24..6c7d567addd 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,23 @@ +Fri Mar 20 10:42:07 1998 Jason Merrill + + * pt.c (complete_template_args): Rewrite. + (tsubst, FUNCTION_DECL): Use it. + +Fri Mar 20 08:12:43 1998 H.J. Lu (hjl@gnu.org) + + * semantics.c (finish_asm_stmt): Fix combine strings. Call + c_expand_asm_operands () if output_operands, input_operands or + clobbers is not NULL_TREE. + +Fri Mar 20 00:10:19 1998 Kriang Lerdsuwanakij + + * pt.c (complete_template_args): New function. + (get_bindings): Deal with specializations of function templates + with return type containing parameters from outer class + templates. + (tsubst, TEMPLATE_TEMPLATE_PARM): When reducing parameter level, + substitute arguments and compose a new type. + Thu Mar 19 19:01:48 1998 Mark Mitchell * pt.c (tsubst): Clear DECL_PENDING_INLINE_INFO for new diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 6102bead6ca..d372e11e3a1 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -81,6 +81,7 @@ static tree get_class_bindings PROTO((tree, tree, tree, tree)); static tree coerce_template_parms PROTO((tree, tree, tree, int, int, int)); static tree tsubst_enum PROTO((tree, tree, tree *)); static tree add_to_template_args PROTO((tree, tree)); +static tree complete_template_args PROTO((tree, tree, int)); static int type_unification_real PROTO((tree, tree *, tree, tree, int, int, int)); static void note_template_header PROTO((int)); @@ -340,6 +341,103 @@ is_member_template (t) return 0; } +/* Return a new template argument vector which contains all of ARGS + for all outer templates TYPE is contained in, but has as its + innermost set of arguments the EXTRA_ARGS. If UNBOUND_ONLY, we + are only interested in unbound template arguments, not arguments from + enclosing templates that have been instantiated already. */ + +static tree +complete_template_args (tmpl, extra_args, unbound_only) + tree tmpl, extra_args; + int unbound_only; +{ + /* depth is the number of levels of enclosing args we're adding. */ + int depth, i; + tree args, new_args, spec_args = NULL_TREE; + + my_friendly_assert (TREE_CODE (tmpl) == TEMPLATE_DECL, 0); + my_friendly_assert (TREE_CODE (extra_args) == TREE_VEC, 0); + + if (DECL_TEMPLATE_INFO (tmpl) && !unbound_only) + { + /* A specialization of a member template of a template class shows up + as a TEMPLATE_DECL with DECL_TEMPLATE_SPECIALIZATION set. + DECL_TI_ARGS is the specialization args, and DECL_TI_TEMPLATE + is the template being specialized. */ + if (DECL_TEMPLATE_SPECIALIZATION (tmpl)) + { + spec_args = DECL_TI_ARGS (tmpl); + tmpl = DECL_TI_TEMPLATE (tmpl); + } + + if (DECL_TEMPLATE_INFO (tmpl)) + { + /* A partial instantiation of a member template shows up as a + TEMPLATE_DECL with DECL_TEMPLATE_INFO. DECL_TI_ARGS is + all the bound template arguments. */ + args = DECL_TI_ARGS (tmpl); + if (TREE_CODE (TREE_VEC_ELT (args, 0)) != TREE_VEC) + depth = 1; + else + depth = TREE_VEC_LENGTH (args); + } + else + /* If we are a specialization, we might have no previously bound + template args. */ + depth = 0; + + new_args = make_tree_vec (depth + 1 + (!!spec_args)); + + if (depth == 1) + TREE_VEC_ELT (new_args, 0) = args; + else + for (i = 0; i < depth; ++i) + TREE_VEC_ELT (new_args, i) = TREE_VEC_ELT (args, i); + } + else + { + tree type; + int skip; + + /* For unbound args, we have to do more work. We are getting bindings + for the innermost args from extra_args, so we start from our + context and work out until we've seen all the args. We need to + do it this way to handle partial specialization. */ + + depth = list_length (DECL_TEMPLATE_PARMS (tmpl)) - 1; + if (depth == 0) + return extra_args; + + new_args = make_tree_vec (depth + 1); + + if (! is_member_template (tmpl)) + /* If this isn't a member template, extra_args is for the innermost + template class, so skip over it. */ + skip = 1; + + type = DECL_REAL_CONTEXT (tmpl); + for (i = depth; i; type = TYPE_CONTEXT (type)) + if (PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (type))) + { + if (skip) + skip = 0; + else + { + --i; + TREE_VEC_ELT (new_args, i) = CLASSTYPE_TI_ARGS (type); + } + } + } + + TREE_VEC_ELT (new_args, depth) = extra_args; + + if (spec_args) + TREE_VEC_ELT (new_args, depth + 1) = spec_args; + + return new_args; +} + /* Return a new template argument vector which contains all of ARGS, but has as its innermost set of arguments the EXTRA_ARGS. */ @@ -3591,7 +3689,20 @@ tsubst (t, args, in_decl) { case TEMPLATE_TYPE_PARM: case TEMPLATE_TEMPLATE_PARM: - r = copy_node (t); + + if (TREE_CODE (t) == TEMPLATE_TEMPLATE_PARM + && CLASSTYPE_TEMPLATE_INFO (t)) + { + tree argvec = tsubst (CLASSTYPE_TI_ARGS (t), + args, in_decl); + r = lookup_template_class (TYPE_NAME (t), argvec, in_decl, + DECL_CONTEXT (TYPE_NAME (t))); + r = cp_build_type_variant (r, TYPE_READONLY (t), + TYPE_VOLATILE (t)); + } + else + r = copy_node (t); + TEMPLATE_TYPE_PARM_INDEX (r) = reduce_template_parm_level (TEMPLATE_TYPE_PARM_INDEX (t), r, levels); @@ -3804,21 +3915,8 @@ tsubst (t, args, in_decl) /* Start by getting the innermost args. */ argvec = tsubst (DECL_TI_ARGS (t), args, in_decl); - /* If tmpl is an instantiation of a member template, tack on - the args for the enclosing class. NOTE: this will change - for member class templates. The generalized procedure - is to grab the outer args, then tack on the current args, - then any specialized args. */ - if (DECL_TEMPLATE_INFO (tmpl) && DECL_TI_ARGS (tmpl)) - { - if (!DECL_TEMPLATE_SPECIALIZATION (tmpl)) - argvec = add_to_template_args (DECL_TI_ARGS (tmpl), argvec); - else - /* In this case, we are instantiating a - specialization. The innermost template args are - already given by the specialization. */ - argvec = add_to_template_args (argvec, DECL_TI_ARGS (tmpl)); - } + if (DECL_TEMPLATE_INFO (tmpl)) + argvec = complete_template_args (tmpl, argvec, 0); /* Do we already have this instantiation? */ spec = retrieve_specialization (tmpl, argvec); @@ -5701,7 +5799,9 @@ get_bindings_real (fn, decl, explicit_args, check_rettype) if (check_rettype) { /* Check to see that the resulting return type is also OK. */ - tree t = tsubst (TREE_TYPE (TREE_TYPE (fn)), targs, NULL_TREE); + tree t = tsubst (TREE_TYPE (TREE_TYPE (fn)), + complete_template_args (fn, targs, 1), + NULL_TREE); if (!comptypes (t, TREE_TYPE (TREE_TYPE (decl)), 1)) return NULL_TREE; diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index f3022466955..79f50386314 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -709,7 +709,7 @@ finish_asm_stmt (cv_qualifier, string, output_operands, tree clobbers; { if (TREE_CHAIN (string)) - combine_strings (string); + string = combine_strings (string); if (processing_template_decl) { @@ -721,7 +721,8 @@ finish_asm_stmt (cv_qualifier, string, output_operands, else { emit_line_note (input_filename, lineno); - if (output_operands != NULL_TREE) + if (output_operands != NULL_TREE || input_operands != NULL_TREE + || clobbers != NULL_TREE) { if (cv_qualifier != NULL_TREE && cv_qualifier != ridpointers[(int) RID_VOLATILE]) -- 2.30.2