This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
(C++) patch to push_template_decl
- To: egcs-patches at cygnus dot com
- Subject: (C++) patch to push_template_decl
- From: Jason Merrill <jason at cygnus dot com>
- Date: Thu, 29 Oct 1998 02:27:29 -0800
Fixes spec23.C. Applied.
1998-10-29 Jason Merrill <jason@yorick.cygnus.com>
* pt.c (push_template_decl_real): Generalize check for incorrect
number of template parms.
Index: pt.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/pt.c,v
retrieving revision 1.225
diff -c -p -r1.225 pt.c
*** pt.c 1998/10/28 20:29:09 1.225
--- pt.c 1998/10/29 10:25:41
*************** push_template_decl_real (decl, is_friend
*** 2166,2173 ****
}
else
{
! tree t;
! tree a;
if (CLASSTYPE_TEMPLATE_INSTANTIATION (ctx))
cp_error ("must specialize `%#T' before defining member `%#D'",
--- 2166,2173 ----
}
else
{
! tree a, t, current, parms;
! int mem, i;
if (CLASSTYPE_TEMPLATE_INSTANTIATION (ctx))
cp_error ("must specialize `%#T' before defining member `%#D'",
*************** push_template_decl_real (decl, is_friend
*** 2193,2267 ****
else
tmpl = DECL_TI_TEMPLATE (decl);
! if (is_member_template (tmpl) || is_member_template_class (tmpl))
{
! if (DECL_FUNCTION_TEMPLATE_P (tmpl)
! && DECL_TEMPLATE_INFO (decl) && DECL_TI_ARGS (decl)
! && DECL_TEMPLATE_SPECIALIZATION (decl))
! {
! tree new_tmpl;
!
! /* The declaration is a specialization of a member
! template, declared outside the class. Therefore, the
! innermost template arguments will be NULL, so we
! replace them with the arguments determined by the
! earlier call to check_explicit_specialization. */
! args = DECL_TI_ARGS (decl);
!
! new_tmpl
! = build_template_decl (decl, current_template_parms);
! DECL_TEMPLATE_RESULT (new_tmpl) = decl;
! TREE_TYPE (new_tmpl) = TREE_TYPE (decl);
! DECL_TI_TEMPLATE (decl) = new_tmpl;
! SET_DECL_TEMPLATE_SPECIALIZATION (new_tmpl);
! DECL_TEMPLATE_INFO (new_tmpl) =
! perm_tree_cons (tmpl, args, NULL_TREE);
!
! register_specialization (new_tmpl, tmpl, args);
! return decl;
! }
!
! a = innermost_args (args);
! t = DECL_INNERMOST_TEMPLATE_PARMS (tmpl);
! if (TREE_VEC_LENGTH (t) != TREE_VEC_LENGTH (a))
! {
! cp_error ("got %d template parameters for `%#D'",
! TREE_VEC_LENGTH (a), decl);
! cp_error (" but %d required", TREE_VEC_LENGTH (t));
! }
! if (TMPL_ARGS_DEPTH (args) > 1)
! /* Get the template parameters for the enclosing template
! class. */
! a = TMPL_ARGS_LEVEL (args, TMPL_ARGS_DEPTH (args) - 1);
! else
! a = NULL_TREE;
! }
! else
! a = innermost_args (args);
! t = NULL_TREE;
! if (CLASSTYPE_TEMPLATE_SPECIALIZATION (ctx))
! {
! /* When processing an inline member template of a
! specialized class, there is no CLASSTYPE_TI_SPEC_INFO. */
! if (CLASSTYPE_TI_SPEC_INFO (ctx))
! t = TREE_VALUE (CLASSTYPE_TI_SPEC_INFO (ctx));
}
- else if (CLASSTYPE_TEMPLATE_INFO (ctx))
- t = DECL_INNERMOST_TEMPLATE_PARMS (CLASSTYPE_TI_TEMPLATE (ctx));
! /* There should be template arguments if and only if there is a
! template class. */
! my_friendly_assert((a != NULL_TREE) == (t != NULL_TREE), 0);
! if (t != NULL_TREE
! && TREE_VEC_LENGTH (t) != TREE_VEC_LENGTH (a))
{
! cp_error ("got %d template parameters for `%#D'",
! TREE_VEC_LENGTH (a), decl);
! cp_error (" but `%#T' has %d", ctx, TREE_VEC_LENGTH (t));
}
}
DECL_TEMPLATE_RESULT (tmpl) = decl;
--- 2193,2260 ----
else
tmpl = DECL_TI_TEMPLATE (decl);
! if (is_member_template (tmpl)
! && DECL_FUNCTION_TEMPLATE_P (tmpl)
! && DECL_TEMPLATE_INFO (decl) && DECL_TI_ARGS (decl)
! && DECL_TEMPLATE_SPECIALIZATION (decl))
{
! tree new_tmpl;
! /* The declaration is a specialization of a member
! template, declared outside the class. Therefore, the
! innermost template arguments will be NULL, so we
! replace them with the arguments determined by the
! earlier call to check_explicit_specialization. */
! args = DECL_TI_ARGS (decl);
!
! new_tmpl
! = build_template_decl (decl, current_template_parms);
! DECL_TEMPLATE_RESULT (new_tmpl) = decl;
! TREE_TYPE (new_tmpl) = TREE_TYPE (decl);
! DECL_TI_TEMPLATE (decl) = new_tmpl;
! SET_DECL_TEMPLATE_SPECIALIZATION (new_tmpl);
! DECL_TEMPLATE_INFO (new_tmpl) =
! perm_tree_cons (tmpl, args, NULL_TREE);
! register_specialization (new_tmpl, tmpl, args);
! return decl;
}
! /* Make sure the template headers we got make sense. */
! mem = (is_member_template (tmpl) || is_member_template_class (tmpl));
! parms = DECL_TEMPLATE_PARMS (tmpl);
! i = TMPL_PARMS_DEPTH (parms);
! if (TMPL_ARGS_DEPTH (args) != i)
{
! cp_error ("expected %d levels of template parms for `%#D', got %d",
! i, decl, TMPL_ARGS_DEPTH (args));
}
+ else
+ for (current = decl; i > 0; --i, parms = TREE_CHAIN (parms))
+ {
+ a = TMPL_ARGS_LEVEL (args, i);
+ t = INNERMOST_TEMPLATE_PARMS (parms);
+
+ if (TREE_VEC_LENGTH (t) != TREE_VEC_LENGTH (a))
+ {
+ if (current == decl)
+ cp_error ("got %d template parameters for `%#D'",
+ TREE_VEC_LENGTH (a), decl);
+ else
+ cp_error ("got %d template parameters for `%#T'",
+ TREE_VEC_LENGTH (a), current);
+ cp_error (" but %d required", TREE_VEC_LENGTH (t));
+ }
+
+ /* Perhaps we should also check that the parms are used in the
+ appropriate qualifying scopes in the declarator? */
+
+ if (current == decl)
+ current = ctx;
+ else
+ current = TYPE_CONTEXT (current);
+ }
}
DECL_TEMPLATE_RESULT (tmpl) = decl;