Commit 28e42b7e by Kriang Lerdsuwanakij Committed by Kriang Lerdsuwanakij

PR c++/15664, c++/18276

	PR c++/15664, c++/18276
	* pt.c (tsubst_decl) <TEMPLATE_DECL case>: Reorganize.  Correctly
	tsubst TEMPLATE_DECL that is a TEMPLATE_TEMPLATE_PARM.

	* g++.dg/template/ttp13.C: New test.
	* g++.dg/template/ttp14.C: Likewise.

From-SVN: r91633
parent a5e51518
2004-12-02 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> 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 PR c++/18123
* parser.c (cp_parser_type_specifier): Catch template declaration * parser.c (cp_parser_type_specifier): Catch template declaration
of enum. of enum.
......
...@@ -6159,38 +6159,54 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) ...@@ -6159,38 +6159,54 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
{ {
case TEMPLATE_DECL: case TEMPLATE_DECL:
{ {
/* We can get here when processing a member template function /* We can get here when processing a member function template,
of a template class. */ member class template, and template template parameter of
a template class. */
tree decl = DECL_TEMPLATE_RESULT (t); tree decl = DECL_TEMPLATE_RESULT (t);
tree spec; 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. /* Template template parameter is treated here. */
The ARGS are for the surrounding class type, so the tree new_type = tsubst (TREE_TYPE (t), args, complain, in_decl);
full args contain the tsubst'd args for the context, if (new_type == error_mark_node)
plus the innermost args from the template decl. */ return error_mark_node;
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);
/* tsubst_template_args doesn't copy the vector if r = copy_decl (t);
nothing changed. But, *something* should have TREE_CHAIN (r) = NULL_TREE;
changed. */ TREE_TYPE (r) = new_type;
gcc_assert (full_args != tmpl_args); 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, /* We might already have an instance of this template.
/*class_specializations_p=*/true); The ARGS are for the surrounding class type, so the
if (spec != NULL_TREE) full args contain the tsubst'd args for the context,
{ plus the innermost args from the template decl. */
r = spec; tmpl_args = DECL_CLASS_TEMPLATE_P (t)
break; ? 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 /* 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) ...@@ -6202,14 +6218,6 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
gcc_assert (DECL_LANG_SPECIFIC (r) != 0); gcc_assert (DECL_LANG_SPECIFIC (r) != 0);
TREE_CHAIN (r) = NULL_TREE; 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) DECL_CONTEXT (r)
= tsubst_aggr_type (DECL_CONTEXT (t), args, = tsubst_aggr_type (DECL_CONTEXT (t), args,
complain, in_decl, complain, in_decl,
......
2004-12-02 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> 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 PR c++/18123
* g++.dg/parse/enum2.C: New test. * g++.dg/parse/enum2.C: New test.
* g++.old-deja/g++.pt/enum5.C: Adjust error location. * g++.old-deja/g++.pt/enum5.C: Adjust error location.
......
// { 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>();
}
// { 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;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment