diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/pt.c | 76 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/ttp13.C | 20 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/ttp14.C | 15 |
5 files changed, 89 insertions, 34 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 4ad1c6e..4a48637 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,11 @@ 2004-12-02 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> + PR c++/15664, c++/18276 + * pt.c (tsubst_decl) <TEMPLATE_DECL case>: Reorganize. Correctly + tsubst TEMPLATE_DECL that is a TEMPLATE_TEMPLATE_PARM. + +2004-12-02 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> + PR c++/18123 * parser.c (cp_parser_type_specifier): Catch template declaration of enum. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 34e86c8..a0cc45c 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -6159,38 +6159,54 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) { case TEMPLATE_DECL: { - /* We can get here when processing a member template function - of a template class. */ + /* We can get here when processing a member function template, + member class template, and template template parameter of + a template class. */ tree decl = DECL_TEMPLATE_RESULT (t); tree spec; - int is_template_template_parm = DECL_TEMPLATE_TEMPLATE_PARM_P (t); + tree tmpl_args; + tree full_args; - if (!is_template_template_parm) + if (DECL_TEMPLATE_TEMPLATE_PARM_P (t)) { - /* We might already have an instance of this template. - The ARGS are for the surrounding class type, so the - full args contain the tsubst'd args for the context, - plus the innermost args from the template decl. */ - tree tmpl_args = DECL_CLASS_TEMPLATE_P (t) - ? CLASSTYPE_TI_ARGS (TREE_TYPE (t)) - : DECL_TI_ARGS (DECL_TEMPLATE_RESULT (t)); - tree full_args; - - full_args = tsubst_template_args (tmpl_args, args, - complain, in_decl); + /* Template template parameter is treated here. */ + tree new_type = tsubst (TREE_TYPE (t), args, complain, in_decl); + if (new_type == error_mark_node) + return error_mark_node; - /* tsubst_template_args doesn't copy the vector if - nothing changed. But, *something* should have - changed. */ - gcc_assert (full_args != tmpl_args); + r = copy_decl (t); + TREE_CHAIN (r) = NULL_TREE; + TREE_TYPE (r) = new_type; + DECL_TEMPLATE_RESULT (r) + = build_decl (TYPE_DECL, DECL_NAME (decl), new_type); + DECL_TEMPLATE_PARMS (r) + = tsubst_template_parms (DECL_TEMPLATE_PARMS (t), args, + complain); + TYPE_NAME (new_type) = r; + break; + } - spec = retrieve_specialization (t, full_args, - /*class_specializations_p=*/true); - if (spec != NULL_TREE) - { - r = spec; - break; - } + /* We might already have an instance of this template. + The ARGS are for the surrounding class type, so the + full args contain the tsubst'd args for the context, + plus the innermost args from the template decl. */ + tmpl_args = DECL_CLASS_TEMPLATE_P (t) + ? CLASSTYPE_TI_ARGS (TREE_TYPE (t)) + : DECL_TI_ARGS (DECL_TEMPLATE_RESULT (t)); + full_args = tsubst_template_args (tmpl_args, args, + complain, in_decl); + + /* tsubst_template_args doesn't copy the vector if + nothing changed. But, *something* should have + changed. */ + gcc_assert (full_args != tmpl_args); + + spec = retrieve_specialization (t, full_args, + /*class_specializations_p=*/true); + if (spec != NULL_TREE) + { + r = spec; + break; } /* Make a new template decl. It will be similar to the @@ -6202,14 +6218,6 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) gcc_assert (DECL_LANG_SPECIFIC (r) != 0); TREE_CHAIN (r) = NULL_TREE; - if (is_template_template_parm) - { - tree new_decl = tsubst (decl, args, complain, in_decl); - DECL_TEMPLATE_RESULT (r) = new_decl; - TREE_TYPE (r) = TREE_TYPE (new_decl); - break; - } - DECL_CONTEXT (r) = tsubst_aggr_type (DECL_CONTEXT (t), args, complain, in_decl, diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 84eae74..c55808a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,11 @@ 2004-12-02 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> + PR c++/15664, c++/18276 + * g++.dg/template/ttp13.C: New test. + * g++.dg/template/ttp14.C: Likewise. + +2004-12-02 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> + PR c++/18123 * g++.dg/parse/enum2.C: New test. * g++.old-deja/g++.pt/enum5.C: Adjust error location. diff --git a/gcc/testsuite/g++.dg/template/ttp13.C b/gcc/testsuite/g++.dg/template/ttp13.C new file mode 100644 index 0000000..2c35b3a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ttp13.C @@ -0,0 +1,20 @@ +// { dg-do compile } + +// Origin: Wolfgang Bangerth <bangerth@dealii.org> + +// PR c++/15664: Template substitution of template template parameter + +template <int N> struct S { + template<template<typename> class A> + friend void foo(); +}; + +template<template<typename> class A> +void foo(); + +template <typename> struct X {}; + +int main () { + S<1> s; + foo<X>(); +} diff --git a/gcc/testsuite/g++.dg/template/ttp14.C b/gcc/testsuite/g++.dg/template/ttp14.C new file mode 100644 index 0000000..2b21609 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ttp14.C @@ -0,0 +1,15 @@ +// { dg-do compile } + +// Origin: akim@epita.fr +// Volker Reichelt <reichelt@gcc.gnu.org> + +// PR c++/18276: Template substitution of template template parameter + +template<template<int> class> struct A; + +template<int> struct B +{ + template<template<int> class> friend class A; +}; + +B<0> b; |