static tree canonicalize_expr_argument (tree, tsubst_flags_t);
static tree make_argument_pack (tree);
static void register_parameter_specializations (tree, tree);
+static tree enclosing_instantiation_of (tree tctx);
/* Make the current scope suitable for access checking when we are
processing T. T can be FUNCTION_DECL for instantiated function
}
else if (CLASS_TYPE_P (template_type))
{
+ /* Lambda closures are regenerated in tsubst_lambda_expr, not
+ instantiated here. */
+ gcc_assert (!LAMBDA_TYPE_P (template_type));
+
t = make_class_type (TREE_CODE (template_type));
CLASSTYPE_DECLARED_CLASS (t)
= CLASSTYPE_DECLARED_CLASS (template_type);
return t;
/* Calculate the most general template of which R is a
- specialization, and the complete set of arguments used to
- specialize R. */
+ specialization. */
gen_tmpl = most_general_template (DECL_TI_TEMPLATE (t));
+
+ /* We're substituting a lambda function under tsubst_lambda_expr but not
+ directly from it; find the matching function we're already inside.
+ But don't do this if T is a generic lambda with a single level of
+ template parms, as in that case we're doing a normal instantiation. */
+ if (LAMBDA_FUNCTION_P (t) && !lambda_fntype
+ && (!generic_lambda_fn_p (t)
+ || TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (gen_tmpl)) > 1))
+ return enclosing_instantiation_of (t);
+
+ /* Calculate the complete set of arguments used to
+ specialize R. */
argvec = tsubst_template_args (DECL_TI_ARGS
(DECL_TEMPLATE_RESULT
(DECL_TI_TEMPLATE (t))),
return CLASSTYPE_TEMPLATE_INFO (closure) != NULL_TREE;
}
-/* True if FN is the op() for a lambda regenerated from a lambda in an
- uninstantiated template. */
-
-bool
-regenerated_lambda_fn_p (tree fn)
-{
- return (LAMBDA_FUNCTION_P (fn)
- && !DECL_TEMPLATE_INSTANTIATION (fn));
-}
-
/* We're instantiating a variable from template function TCTX. Return the
corresponding current enclosing scope. This gets complicated because lambda
functions in templates are regenerated rather than instantiated, but generic
lambda functions are subsequently instantiated. */
static tree
-enclosing_instantiation_of (tree tctx)
+enclosing_instantiation_of (tree otctx)
{
+ tree tctx = otctx;
tree fn = current_function_decl;
int lambda_count = 0;
++lambda_count;
for (; fn; fn = decl_function_context (fn))
{
- tree lambda = fn;
+ tree ofn = fn;
int flambda_count = 0;
- for (; fn && regenerated_lambda_fn_p (fn);
+ for (; flambda_count < lambda_count && fn && LAMBDA_FUNCTION_P (fn);
fn = decl_function_context (fn))
++flambda_count;
if (DECL_TEMPLATE_INFO (fn)
? most_general_template (fn) != most_general_template (tctx)
: fn != tctx)
continue;
- if (lambda_count)
- {
- fn = lambda;
- while (flambda_count-- > lambda_count)
- fn = decl_function_context (fn);
- }
- return fn;
+ gcc_assert (DECL_NAME (ofn) == DECL_NAME (otctx)
+ || DECL_CONV_FN_P (ofn));
+ return ofn;
}
gcc_unreachable ();
}