static void add_pending_template (tree);
static tree reopen_tinst_level (struct tinst_level *);
static tree tsubst_initializer_list (tree, tree);
-static tree get_partial_spec_bindings (tree, tree, tree, tree);
+static tree get_partial_spec_bindings (tree, tree, tree);
static tree coerce_template_parms (tree, tree, tree, tsubst_flags_t,
bool, bool);
static tree coerce_innermost_template_parms (tree, tree, tree, tsubst_flags_t,
tree tmpl1 = TREE_VALUE (pat1);
tree tmpl2 = TREE_VALUE (pat2);
- tree parms1 = DECL_INNERMOST_TEMPLATE_PARMS (tmpl1);
- tree parms2 = DECL_INNERMOST_TEMPLATE_PARMS (tmpl2);
tree specargs1 = TI_ARGS (get_template_info (DECL_TEMPLATE_RESULT (tmpl1)));
tree specargs2 = TI_ARGS (get_template_info (DECL_TEMPLATE_RESULT (tmpl2)));
types in the arguments, and we need our dependency check functions
to behave correctly. */
++processing_template_decl;
- targs = get_partial_spec_bindings (tmpl, parms1, specargs1, specargs2);
+ targs = get_partial_spec_bindings (tmpl, tmpl1, specargs2);
if (targs)
{
--winner;
any_deductions = true;
}
- targs = get_partial_spec_bindings (tmpl, parms2, specargs2, specargs1);
+ targs = get_partial_spec_bindings (tmpl, tmpl2, specargs1);
if (targs)
{
++winner;
}
/* Return the innermost template arguments that, when applied to a partial
- specialization of TMPL whose innermost template parameters are
- TPARMS, and whose specialization arguments are SPEC_ARGS, yield the
- ARGS.
+ specialization SPEC_TMPL of TMPL, yield the ARGS.
For example, suppose we have:
template <class T, class U> struct S {};
template <class T> struct S<T*, int> {};
- Then, suppose we want to get `S<double*, int>'. The TPARMS will be
- {T}, the SPEC_ARGS will be {T*, int} and the ARGS will be {double*,
- int}. The resulting vector will be {double}, indicating that `T'
- is bound to `double'. */
+ Then, suppose we want to get `S<double*, int>'. SPEC_TMPL will be the
+ partial specialization and the ARGS will be {double*, int}. The resulting
+ vector will be {double}, indicating that `T' is bound to `double'. */
static tree
-get_partial_spec_bindings (tree tmpl, tree tparms, tree spec_args, tree args)
+get_partial_spec_bindings (tree tmpl, tree spec_tmpl, tree args)
{
+ tree tparms = DECL_INNERMOST_TEMPLATE_PARMS (spec_tmpl);
+ tree spec_args
+ = TI_ARGS (get_template_info (DECL_TEMPLATE_RESULT (spec_tmpl)));
int i, ntparms = TREE_VEC_LENGTH (tparms);
tree deduced_args;
tree innermost_deduced_args;
if (! TREE_VEC_ELT (innermost_deduced_args, i))
return NULL_TREE;
+ tree tinst = build_tree_list (spec_tmpl, deduced_args);
+ if (!push_tinst_level (tinst))
+ {
+ excessive_deduction_depth = true;
+ return NULL_TREE;
+ }
+
/* Verify that nondeduced template arguments agree with the type
obtained from argument deduction.
spec_args = coerce_template_parms (DECL_INNERMOST_TEMPLATE_PARMS (tmpl),
spec_args, tmpl,
tf_none, false, false);
+
+ pop_tinst_level ();
+
if (spec_args == error_mark_node
/* We only need to check the innermost arguments; the other
arguments will always agree. */
for (t = DECL_TEMPLATE_SPECIALIZATIONS (main_tmpl); t; t = TREE_CHAIN (t))
{
- tree partial_spec_args;
tree spec_args;
tree spec_tmpl = TREE_VALUE (t);
- partial_spec_args = TREE_PURPOSE (t);
-
- ++processing_template_decl;
-
if (outer_args)
{
- /* Discard the outer levels of args, and then substitute in the
- template args from the enclosing class. */
- partial_spec_args = INNERMOST_TEMPLATE_ARGS (partial_spec_args);
- partial_spec_args = tsubst_template_args
- (partial_spec_args, outer_args, tf_none, NULL_TREE);
-
- /* And the same for the partial specialization TEMPLATE_DECL. */
+ /* Substitute in the template args from the enclosing class. */
+ ++processing_template_decl;
spec_tmpl = tsubst (spec_tmpl, outer_args, tf_none, NULL_TREE);
+ --processing_template_decl;
}
- partial_spec_args =
- coerce_template_parms (DECL_INNERMOST_TEMPLATE_PARMS (tmpl),
- partial_spec_args,
- tmpl, tf_none,
- /*require_all_args=*/true,
- /*use_default_args=*/true);
-
- --processing_template_decl;
-
- if (partial_spec_args == error_mark_node)
- return error_mark_node;
if (spec_tmpl == error_mark_node)
return error_mark_node;
- tree parms = DECL_INNERMOST_TEMPLATE_PARMS (spec_tmpl);
- spec_args = get_partial_spec_bindings (tmpl, parms,
- partial_spec_args,
- args);
+ spec_args = get_partial_spec_bindings (tmpl, spec_tmpl, args);
if (spec_args)
{
if (outer_args)
};
template< typename T > struct has_type {
struct gcc_3_2_wknd {
- template< typename U > static yes_tag test( type_wrapper<U> const volatile*
+ template< typename U > static yes_tag test( type_wrapper<U> const volatile* // { dg-message "required" }
, type_wrapper<typename U::type>* = 0 );
};
typedef type_wrapper<T> t_;
- static const bool value = sizeof(gcc_3_2_wknd::test(static_cast<t_*>(0))) ==
+ static const bool value = sizeof(gcc_3_2_wknd::test(static_cast<t_*>(0))) == // { dg-message "required" }
sizeof(yes_tag);
};
template <class K, class T, class=void> struct Get_type {
struct FT_tag {};
struct RT_tag {};
template <class K> struct Get_type<K, RT_tag, typename if_c<
-!has_type<Get_type<K, FT_tag> >::value >::type> { };
+!has_type<Get_type<K, FT_tag> >::value >::type> { }; // { dg-message "required" }
template <class K> struct Get_type<K, FT_tag, typename if_c<
-!has_type<Get_type<K, RT_tag> >::value >::type> { }; // { dg-error "depth" }
+!has_type<Get_type<K, RT_tag> >::value >::type> { }; // { dg-message "required" }
typedef Get_type<int, FT_tag>::type P;
+// { dg-prune-output "-ftemplate-depth" }
// { dg-prune-output "compilation terminated" }