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
This commit is contained in:
Kriang Lerdsuwanakij 2004-12-02 12:00:43 +00:00 committed by Kriang Lerdsuwanakij
parent a5e515185a
commit 28e42b7eac
5 changed files with 89 additions and 34 deletions

View File

@ -1,3 +1,9 @@
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

View File

@ -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,

View File

@ -1,3 +1,9 @@
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

View File

@ -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>();
}

View File

@ -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;