diff options
author | Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> | 2004-12-02 12:00:43 +0000 |
---|---|---|
committer | Kriang Lerdsuwanakij <lerdsuwa@gcc.gnu.org> | 2004-12-02 12:00:43 +0000 |
commit | 28e42b7eac632e5ad97801687192baa1f76a2e0d (patch) | |
tree | 107c38bb953f29351253c7b49cbde6e02dd4790c /gcc/cp/pt.c | |
parent | a5e515185ae43f376c680dc3710c0ad3c514c2e4 (diff) | |
download | gcc-28e42b7eac632e5ad97801687192baa1f76a2e0d.zip gcc-28e42b7eac632e5ad97801687192baa1f76a2e0d.tar.gz gcc-28e42b7eac632e5ad97801687192baa1f76a2e0d.tar.bz2 |
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
Diffstat (limited to 'gcc/cp/pt.c')
-rw-r--r-- | gcc/cp/pt.c | 76 |
1 files changed, 42 insertions, 34 deletions
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, |