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,23 +6159,40 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) ...@@ -6159,23 +6159,40 @@ 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))
{ {
/* 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;
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;
}
/* We might already have an instance of this template. /* We might already have an instance of this template.
The ARGS are for the surrounding class type, so the The ARGS are for the surrounding class type, so the
full args contain the tsubst'd args for the context, full args contain the tsubst'd args for the context,
plus the innermost args from the template decl. */ plus the innermost args from the template decl. */
tree tmpl_args = DECL_CLASS_TEMPLATE_P (t) tmpl_args = DECL_CLASS_TEMPLATE_P (t)
? CLASSTYPE_TI_ARGS (TREE_TYPE (t)) ? CLASSTYPE_TI_ARGS (TREE_TYPE (t))
: DECL_TI_ARGS (DECL_TEMPLATE_RESULT (t)); : DECL_TI_ARGS (DECL_TEMPLATE_RESULT (t));
tree full_args;
full_args = tsubst_template_args (tmpl_args, args, full_args = tsubst_template_args (tmpl_args, args,
complain, in_decl); complain, in_decl);
...@@ -6191,7 +6208,6 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) ...@@ -6191,7 +6208,6 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
r = spec; r = spec;
break; break;
} }
}
/* Make a new template decl. It will be similar to the /* Make a new template decl. It will be similar to the
original, but will record the current template arguments. original, but will record the current template arguments.
...@@ -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