@@ -525,6 +525,7 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX];
5: CLASS_TYPE_P (in RECORD_TYPE and UNION_TYPE)
ENUM_FIXED_UNDERLYING_TYPE_P (in ENUMERAL_TYPE)
AUTO_IS_DECLTYPE (in TEMPLATE_TYPE_PARM)
+ TEMPLATE_TEMPLATE_PARM_SIMPLE_P (in TEMPLATE_TEMPLATE_PARM)
6: TYPE_DEPENDENT_P_VALID
Usage of DECL_LANG_FLAG_?:
@@ -5991,7 +5992,7 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, TYPENAME_FLAG };
((template_parm_index*)TEMPLATE_PARM_INDEX_CHECK (NODE))
#define TEMPLATE_PARM_IDX(NODE) (TEMPLATE_PARM_INDEX_CAST (NODE)->index)
#define TEMPLATE_PARM_LEVEL(NODE) (TEMPLATE_PARM_INDEX_CAST (NODE)->level)
-#define TEMPLATE_PARM_DESCENDANTS(NODE) (TREE_CHAIN (NODE))
+#define TEMPLATE_PARM_DESCENDANTS(NODE) (TREE_CHAIN (TEMPLATE_PARM_INDEX_CHECK (NODE)))
#define TEMPLATE_PARM_ORIG_LEVEL(NODE) (TEMPLATE_PARM_INDEX_CAST (NODE)->orig_level)
#define TEMPLATE_PARM_DECL(NODE) (TEMPLATE_PARM_INDEX_CAST (NODE)->decl)
#define TEMPLATE_PARM_PARAMETER_PACK(NODE) \
@@ -6009,6 +6010,8 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, TYPENAME_FLAG };
(TEMPLATE_PARM_LEVEL (TEMPLATE_TYPE_PARM_INDEX (NODE)))
#define TEMPLATE_TYPE_ORIG_LEVEL(NODE) \
(TEMPLATE_PARM_ORIG_LEVEL (TEMPLATE_TYPE_PARM_INDEX (NODE)))
+#define TEMPLATE_TYPE_DESCENDANTS(NODE) \
+ (TEMPLATE_PARM_DESCENDANTS (TEMPLATE_TYPE_PARM_INDEX (NODE)))
#define TEMPLATE_TYPE_DECL(NODE) \
(TEMPLATE_PARM_DECL (TEMPLATE_TYPE_PARM_INDEX (NODE)))
#define TEMPLATE_TYPE_PARAMETER_PACK(NODE) \
@@ -6018,6 +6021,11 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, TYPENAME_FLAG };
#define CLASS_PLACEHOLDER_TEMPLATE(NODE) \
(DECL_INITIAL (TYPE_NAME (TEMPLATE_TYPE_PARM_CHECK (NODE))))
+/* True iff the template parameters of this TEMPLATE_TEMPLATE_PARM don't
+ depend on outer template parameters. */
+#define TEMPLATE_TEMPLATE_PARM_SIMPLE_P(NODE) \
+ (TYPE_LANG_FLAG_5 (TEMPLATE_TEMPLATE_PARM_CHECK (NODE)))
+
/* Contexts in which auto deduction occurs. These flags are
used to control diagnostics in do_auto_deduction. */
@@ -219,6 +219,7 @@ static tree enclosing_instantiation_of (tree tctx);
static void instantiate_body (tree pattern, tree args, tree d, bool nested);
static tree maybe_dependent_member_ref (tree, tree, tsubst_flags_t, tree);
static void mark_template_arguments_used (tree, tree);
+static bool uses_outer_template_parms (tree);
/* Make the current scope suitable for access checking when we are
processing T. T can be FUNCTION_DECL for instantiated function
@@ -4554,12 +4555,7 @@ reduce_template_parm_level (tree index, tree type, int levels, tree args,
if (TEMPLATE_PARM_DESCENDANTS (index) == NULL_TREE
|| (TEMPLATE_PARM_LEVEL (TEMPLATE_PARM_DESCENDANTS (index))
!= TEMPLATE_PARM_LEVEL (index) - levels)
- || !(TREE_CODE (type) == TEMPLATE_TEMPLATE_PARM
- ? (comp_template_parms
- (DECL_TEMPLATE_PARMS (TYPE_NAME (type)),
- DECL_TEMPLATE_PARMS (TEMPLATE_PARM_DECL
- (TEMPLATE_PARM_DESCENDANTS (index)))))
- : same_type_p (type, TREE_TYPE (TEMPLATE_PARM_DESCENDANTS (index)))))
+ || !same_type_p (type, TREE_TYPE (TEMPLATE_PARM_DESCENDANTS (index))))
{
tree orig_decl = TEMPLATE_PARM_DECL (index);
@@ -4722,6 +4718,10 @@ process_template_parm (tree list, location_t parm_loc, tree parm,
DECL_ARTIFICIAL (decl) = 1;
SET_DECL_TEMPLATE_PARM_P (decl);
+ if (TREE_CODE (parm) == TEMPLATE_DECL
+ && !uses_outer_template_parms (parm))
+ TEMPLATE_TEMPLATE_PARM_SIMPLE_P (TREE_TYPE (parm)) = true;
+
/* Build requirements for the type/template parameter.
This must be done after SET_DECL_TEMPLATE_PARM_P or
process_template_parm could fail. */
@@ -11047,7 +11047,11 @@ uses_template_parms_level (tree t, int level)
static bool
uses_outer_template_parms (tree decl)
{
- int depth = template_class_depth (CP_DECL_CONTEXT (decl));
+ int depth;
+ if (DECL_TEMPLATE_TEMPLATE_PARM_P (decl))
+ depth = TEMPLATE_TYPE_LEVEL (TREE_TYPE (decl)) - 1;
+ else
+ depth = template_class_depth (CP_DECL_CONTEXT (decl));
if (depth == 0)
return false;
if (for_each_template_parm (TREE_TYPE (decl), template_parm_outer_level,
@@ -16293,14 +16297,15 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
t = TYPE_MAIN_VARIANT (t);
}
- if (TREE_CODE (t) == TEMPLATE_TYPE_PARM
- && (arg = TEMPLATE_TYPE_PARM_INDEX (t),
- r = TEMPLATE_PARM_DESCENDANTS (arg))
- && (TEMPLATE_PARM_LEVEL (r)
- == TEMPLATE_PARM_LEVEL (arg) - levels))
- /* Cache the simple case of lowering a type parameter. */
- r = TREE_TYPE (r);
- else
+ if (tree d = TEMPLATE_TYPE_DESCENDANTS (t))
+ if (TEMPLATE_PARM_LEVEL (d) == TEMPLATE_TYPE_LEVEL (t) - levels
+ && (code == TEMPLATE_TYPE_PARM
+ || TEMPLATE_TEMPLATE_PARM_SIMPLE_P (t)))
+ /* Cache lowering a type parameter or a simple template
+ template parameter. */
+ r = TREE_TYPE (d);
+
+ if (!r)
{
r = copy_type (t);
TEMPLATE_TYPE_PARM_INDEX (r)
@@ -16311,7 +16316,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
TYPE_POINTER_TO (r) = NULL_TREE;
TYPE_REFERENCE_TO (r) = NULL_TREE;
- if (TREE_CODE (t) == TEMPLATE_TYPE_PARM)
+ if (code == TEMPLATE_TYPE_PARM)
if (tree ci = PLACEHOLDER_TYPE_CONSTRAINTS_INFO (t))
/* Propagate constraints on placeholders since they are
only instantiated during satisfaction. */
@@ -4,8 +4,7 @@
template<typename T> struct A
{
template<T> int foo(); // { dg-error "double" "" { target c++17_down } }
- template<template<T> class> int bar(); // { dg-bogus {double.*C:7:[^\n]*double} }
- // { dg-error "double" "" { target c++17_down } .-1 }
+ template<template<T> class> int bar(); // { dg-error "double" "" { target c++17_down } }
template<T> struct X; // { dg-error "double" "" { target c++17_down } }
};