diff options
author | Jason Merrill <jason@gcc.gnu.org> | 2007-11-02 01:50:06 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2007-11-02 01:50:06 -0400 |
commit | ef3b7b176100495d541b40439b1f3b9e672d071d (patch) | |
tree | 31e836c6fc221c8334adaa2c5aa5efc804599663 /gcc/cp/pt.c | |
parent | e1a18c68eba04c396dd491a361aeef15f73e8b05 (diff) | |
download | gcc-ef3b7b176100495d541b40439b1f3b9e672d071d.zip gcc-ef3b7b176100495d541b40439b1f3b9e672d071d.tar.gz gcc-ef3b7b176100495d541b40439b1f3b9e672d071d.tar.bz2 |
re PR c++/30897 (ICE with default argument in template template parameter)
PR c++/30897
* pt.c (push_template_decl_real): Set DECL_CONTEXT on template
template parms.
(lookup_template_class): Use it to get the outer template args
for instantiating one.
PR c++/29236
* pt.c (reduce_template_parm_level): tsubst the parameters
of a template template parm.
From-SVN: r129844
Diffstat (limited to 'gcc/cp/pt.c')
-rw-r--r-- | gcc/cp/pt.c | 46 |
1 files changed, 35 insertions, 11 deletions
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 8f72ba9..e9e7789 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -132,7 +132,7 @@ static bool inline_needs_template_parms (tree); static void push_inline_template_parms_recursive (tree, int); static tree retrieve_local_specialization (tree); static void register_local_specialization (tree, tree); -static tree reduce_template_parm_level (tree, tree, int); +static tree reduce_template_parm_level (tree, tree, int, tree, tsubst_flags_t); static int mark_template_parm (tree, void *); static int template_parm_this_level_p (tree, void *); static tree tsubst_friend_function (tree, tree); @@ -2878,7 +2878,8 @@ canonical_type_parameter (tree type) new one is created. */ static tree -reduce_template_parm_level (tree index, tree type, int levels) +reduce_template_parm_level (tree index, tree type, int levels, tree args, + tsubst_flags_t complain) { if (TEMPLATE_PARM_DESCENDANTS (index) == NULL_TREE || (TEMPLATE_PARM_LEVEL (TEMPLATE_PARM_DESCENDANTS (index)) @@ -2903,9 +2904,10 @@ reduce_template_parm_level (tree index, tree type, int levels) = TEMPLATE_PARM_PARAMETER_PACK (index); /* Template template parameters need this. */ - if (TREE_CODE (decl) != CONST_DECL) - DECL_TEMPLATE_PARMS (decl) - = DECL_TEMPLATE_PARMS (TEMPLATE_PARM_DECL (index)); + if (TREE_CODE (decl) == TEMPLATE_DECL) + DECL_TEMPLATE_PARMS (decl) = tsubst_template_parms + (DECL_TEMPLATE_PARMS (TEMPLATE_PARM_DECL (index)), + args, complain); } return TEMPLATE_PARM_DESCENDANTS (index); @@ -4000,10 +4002,13 @@ template arguments to %qD do not match original template %qD", if (primary) { + tree parms = DECL_TEMPLATE_PARMS (tmpl); + int i; + DECL_PRIMARY_TEMPLATE (tmpl) = tmpl; if (DECL_CONV_FN_P (tmpl)) { - int depth = TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (tmpl)); + int depth = TMPL_PARMS_DEPTH (parms); /* It is a conversion operator. See if the type converted to depends on innermost template operands. */ @@ -4012,6 +4017,16 @@ template arguments to %qD do not match original template %qD", depth)) DECL_TEMPLATE_CONV_FN_P (tmpl) = 1; } + + /* Give template template parms a DECL_CONTEXT of the template + for which they are a parameter. */ + parms = INNERMOST_TEMPLATE_PARMS (parms); + for (i = TREE_VEC_LENGTH (parms) - 1; i >= 0; --i) + { + tree parm = TREE_VALUE (TREE_VEC_ELT (parms, i)); + if (TREE_CODE (parm) == TEMPLATE_DECL) + DECL_CONTEXT (parm) = tmpl; + } } /* The DECL_TI_ARGS of DECL contains full set of arguments referring @@ -5392,6 +5407,7 @@ lookup_template_class (tree d1, tree parm; tree arglist2; + tree outer; parmlist = DECL_INNERMOST_TEMPLATE_PARMS (template); @@ -5404,15 +5420,23 @@ lookup_template_class (tree d1, instantiation `TT<int>' is seen, we need to build the full arguments containing {int} as the innermost level. Outer levels, available when not appearing as default template argument, can be - obtained from `current_template_args ()'. + obtained from the arguments of the enclosing template. Suppose that TT is later substituted with std::vector. The above instantiation is `TT<int, std::allocator<T> >' with TT at level 1, and T at level 2, while the template arguments at level 1 becomes {std::vector} and the inner level 2 is {int}. */ - if (current_template_parms) - arglist = add_to_template_args (current_template_args (), arglist); + outer = DECL_CONTEXT (template); + if (outer) + outer = TI_ARGS (get_template_info (DECL_TEMPLATE_RESULT (outer))); + else if (current_template_parms) + /* This is an argument of the current template, so we haven't set + DECL_CONTEXT yet. */ + outer = current_template_args (); + + if (outer) + arglist = add_to_template_args (outer, arglist); arglist2 = coerce_template_parms (parmlist, arglist, template, complain, @@ -8829,7 +8853,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) r = copy_type (t); TEMPLATE_TYPE_PARM_INDEX (r) = reduce_template_parm_level (TEMPLATE_TYPE_PARM_INDEX (t), - r, levels); + r, levels, args, complain); TYPE_STUB_DECL (r) = TYPE_NAME (r) = TEMPLATE_TYPE_DECL (r); TYPE_MAIN_VARIANT (r) = r; TYPE_POINTER_TO (r) = NULL_TREE; @@ -8863,7 +8887,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) break; case TEMPLATE_PARM_INDEX: - r = reduce_template_parm_level (t, type, levels); + r = reduce_template_parm_level (t, type, levels, args, complain); break; default: |