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:
parent
a5e515185a
commit
28e42b7eac
5 changed files with 89 additions and 34 deletions
|
@ -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
|
||||
|
|
76
gcc/cp/pt.c
76
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,
|
||||
|
|
|
@ -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
|
||||
|
|
20
gcc/testsuite/g++.dg/template/ttp13.C
Normal file
20
gcc/testsuite/g++.dg/template/ttp13.C
Normal 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>();
|
||||
}
|
15
gcc/testsuite/g++.dg/template/ttp14.C
Normal file
15
gcc/testsuite/g++.dg/template/ttp14.C
Normal 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;
|
Loading…
Add table
Reference in a new issue