xref: /dragonfly/contrib/gcc-8.0/gcc/cp/lambda.c (revision 58e805e6)
138fd1498Szrj /* Perform the semantic phase of lambda parsing, i.e., the process of
238fd1498Szrj    building tree structure, checking semantic consistency, and
338fd1498Szrj    building RTL.  These routines are used both during actual parsing
438fd1498Szrj    and during the instantiation of template functions.
538fd1498Szrj 
638fd1498Szrj    Copyright (C) 1998-2018 Free Software Foundation, Inc.
738fd1498Szrj 
838fd1498Szrj    This file is part of GCC.
938fd1498Szrj 
1038fd1498Szrj    GCC is free software; you can redistribute it and/or modify it
1138fd1498Szrj    under the terms of the GNU General Public License as published by
1238fd1498Szrj    the Free Software Foundation; either version 3, or (at your option)
1338fd1498Szrj    any later version.
1438fd1498Szrj 
1538fd1498Szrj    GCC is distributed in the hope that it will be useful, but
1638fd1498Szrj    WITHOUT ANY WARRANTY; without even the implied warranty of
1738fd1498Szrj    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
1838fd1498Szrj    General Public License for more details.
1938fd1498Szrj 
2038fd1498Szrj You should have received a copy of the GNU General Public License
2138fd1498Szrj along with GCC; see the file COPYING3.  If not see
2238fd1498Szrj <http://www.gnu.org/licenses/>.  */
2338fd1498Szrj 
2438fd1498Szrj #include "config.h"
2538fd1498Szrj #include "system.h"
2638fd1498Szrj #include "coretypes.h"
2738fd1498Szrj #include "cp-tree.h"
2838fd1498Szrj #include "stringpool.h"
2938fd1498Szrj #include "cgraph.h"
3038fd1498Szrj #include "tree-iterator.h"
3138fd1498Szrj #include "toplev.h"
3238fd1498Szrj #include "gimplify.h"
3338fd1498Szrj 
3438fd1498Szrj /* Constructor for a lambda expression.  */
3538fd1498Szrj 
3638fd1498Szrj tree
build_lambda_expr(void)3738fd1498Szrj build_lambda_expr (void)
3838fd1498Szrj {
3938fd1498Szrj   tree lambda = make_node (LAMBDA_EXPR);
4038fd1498Szrj   LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda) = CPLD_NONE;
4138fd1498Szrj   LAMBDA_EXPR_CAPTURE_LIST         (lambda) = NULL_TREE;
4238fd1498Szrj   LAMBDA_EXPR_THIS_CAPTURE         (lambda) = NULL_TREE;
4338fd1498Szrj   LAMBDA_EXPR_PENDING_PROXIES      (lambda) = NULL;
4438fd1498Szrj   LAMBDA_EXPR_MUTABLE_P            (lambda) = false;
4538fd1498Szrj   return lambda;
4638fd1498Szrj }
4738fd1498Szrj 
4838fd1498Szrj /* Create the closure object for a LAMBDA_EXPR.  */
4938fd1498Szrj 
5038fd1498Szrj tree
build_lambda_object(tree lambda_expr)5138fd1498Szrj build_lambda_object (tree lambda_expr)
5238fd1498Szrj {
5338fd1498Szrj   /* Build aggregate constructor call.
5438fd1498Szrj      - cp_parser_braced_list
5538fd1498Szrj      - cp_parser_functional_cast  */
5638fd1498Szrj   vec<constructor_elt, va_gc> *elts = NULL;
5738fd1498Szrj   tree node, expr, type;
5838fd1498Szrj   location_t saved_loc;
5938fd1498Szrj 
6038fd1498Szrj   if (processing_template_decl || lambda_expr == error_mark_node)
6138fd1498Szrj     return lambda_expr;
6238fd1498Szrj 
6338fd1498Szrj   /* Make sure any error messages refer to the lambda-introducer.  */
6438fd1498Szrj   saved_loc = input_location;
6538fd1498Szrj   input_location = LAMBDA_EXPR_LOCATION (lambda_expr);
6638fd1498Szrj 
6738fd1498Szrj   for (node = LAMBDA_EXPR_CAPTURE_LIST (lambda_expr);
6838fd1498Szrj        node;
6938fd1498Szrj        node = TREE_CHAIN (node))
7038fd1498Szrj     {
7138fd1498Szrj       tree field = TREE_PURPOSE (node);
7238fd1498Szrj       tree val = TREE_VALUE (node);
7338fd1498Szrj 
7438fd1498Szrj       if (field == error_mark_node)
7538fd1498Szrj 	{
7638fd1498Szrj 	  expr = error_mark_node;
7738fd1498Szrj 	  goto out;
7838fd1498Szrj 	}
7938fd1498Szrj 
8038fd1498Szrj       if (TREE_CODE (val) == TREE_LIST)
8138fd1498Szrj 	val = build_x_compound_expr_from_list (val, ELK_INIT,
8238fd1498Szrj 					       tf_warning_or_error);
8338fd1498Szrj 
8438fd1498Szrj       if (DECL_P (val))
8538fd1498Szrj 	mark_used (val);
8638fd1498Szrj 
8738fd1498Szrj       /* Mere mortals can't copy arrays with aggregate initialization, so
8838fd1498Szrj 	 do some magic to make it work here.  */
8938fd1498Szrj       if (TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE)
9038fd1498Szrj 	val = build_array_copy (val);
9138fd1498Szrj       else if (DECL_NORMAL_CAPTURE_P (field)
9238fd1498Szrj 	       && !DECL_VLA_CAPTURE_P (field)
9338fd1498Szrj 	       && TREE_CODE (TREE_TYPE (field)) != REFERENCE_TYPE)
9438fd1498Szrj 	{
9538fd1498Szrj 	  /* "the entities that are captured by copy are used to
9638fd1498Szrj 	     direct-initialize each corresponding non-static data
9738fd1498Szrj 	     member of the resulting closure object."
9838fd1498Szrj 
9938fd1498Szrj 	     There's normally no way to express direct-initialization
10038fd1498Szrj 	     from an element of a CONSTRUCTOR, so we build up a special
10138fd1498Szrj 	     TARGET_EXPR to bypass the usual copy-initialization.  */
10238fd1498Szrj 	  val = force_rvalue (val, tf_warning_or_error);
10338fd1498Szrj 	  if (TREE_CODE (val) == TARGET_EXPR)
10438fd1498Szrj 	    TARGET_EXPR_DIRECT_INIT_P (val) = true;
10538fd1498Szrj 	}
10638fd1498Szrj 
10738fd1498Szrj       CONSTRUCTOR_APPEND_ELT (elts, DECL_NAME (field), val);
10838fd1498Szrj     }
10938fd1498Szrj 
11038fd1498Szrj   expr = build_constructor (init_list_type_node, elts);
11138fd1498Szrj   CONSTRUCTOR_IS_DIRECT_INIT (expr) = 1;
11238fd1498Szrj 
11338fd1498Szrj   /* N2927: "[The closure] class type is not an aggregate."
11438fd1498Szrj      But we briefly treat it as an aggregate to make this simpler.  */
11538fd1498Szrj   type = LAMBDA_EXPR_CLOSURE (lambda_expr);
11638fd1498Szrj   CLASSTYPE_NON_AGGREGATE (type) = 0;
11738fd1498Szrj   expr = finish_compound_literal (type, expr, tf_warning_or_error);
11838fd1498Szrj   CLASSTYPE_NON_AGGREGATE (type) = 1;
11938fd1498Szrj 
12038fd1498Szrj  out:
12138fd1498Szrj   input_location = saved_loc;
12238fd1498Szrj   return expr;
12338fd1498Szrj }
12438fd1498Szrj 
12538fd1498Szrj /* Return an initialized RECORD_TYPE for LAMBDA.
12638fd1498Szrj    LAMBDA must have its explicit captures already.  */
12738fd1498Szrj 
12838fd1498Szrj tree
begin_lambda_type(tree lambda)12938fd1498Szrj begin_lambda_type (tree lambda)
13038fd1498Szrj {
13138fd1498Szrj   tree type;
13238fd1498Szrj 
13338fd1498Szrj   {
13438fd1498Szrj     /* Unique name.  This is just like an unnamed class, but we cannot use
13538fd1498Szrj        make_anon_name because of certain checks against TYPE_UNNAMED_P.  */
13638fd1498Szrj     tree name;
13738fd1498Szrj     name = make_lambda_name ();
13838fd1498Szrj 
13938fd1498Szrj     /* Create the new RECORD_TYPE for this lambda.  */
14038fd1498Szrj     type = xref_tag (/*tag_code=*/record_type,
14138fd1498Szrj                      name,
14238fd1498Szrj                      /*scope=*/ts_lambda,
14338fd1498Szrj                      /*template_header_p=*/false);
14438fd1498Szrj     if (type == error_mark_node)
14538fd1498Szrj       return error_mark_node;
14638fd1498Szrj   }
14738fd1498Szrj 
14838fd1498Szrj   /* Designate it as a struct so that we can use aggregate initialization.  */
14938fd1498Szrj   CLASSTYPE_DECLARED_CLASS (type) = false;
15038fd1498Szrj 
15138fd1498Szrj   /* Cross-reference the expression and the type.  */
15238fd1498Szrj   LAMBDA_EXPR_CLOSURE (lambda) = type;
15338fd1498Szrj   CLASSTYPE_LAMBDA_EXPR (type) = lambda;
15438fd1498Szrj 
15538fd1498Szrj   /* In C++17, assume the closure is literal; we'll clear the flag later if
15638fd1498Szrj      necessary.  */
15738fd1498Szrj   if (cxx_dialect >= cxx17)
15838fd1498Szrj     CLASSTYPE_LITERAL_P (type) = true;
15938fd1498Szrj 
16038fd1498Szrj   /* Clear base types.  */
16138fd1498Szrj   xref_basetypes (type, /*bases=*/NULL_TREE);
16238fd1498Szrj 
16338fd1498Szrj   /* Start the class.  */
16438fd1498Szrj   type = begin_class_definition (type);
16538fd1498Szrj 
16638fd1498Szrj   return type;
16738fd1498Szrj }
16838fd1498Szrj 
16938fd1498Szrj /* Returns the type to use for the return type of the operator() of a
17038fd1498Szrj    closure class.  */
17138fd1498Szrj 
17238fd1498Szrj tree
lambda_return_type(tree expr)17338fd1498Szrj lambda_return_type (tree expr)
17438fd1498Szrj {
17538fd1498Szrj   if (expr == NULL_TREE)
17638fd1498Szrj     return void_type_node;
17738fd1498Szrj   if (type_unknown_p (expr)
17838fd1498Szrj       || BRACE_ENCLOSED_INITIALIZER_P (expr))
17938fd1498Szrj     {
18038fd1498Szrj       cxx_incomplete_type_error (expr, TREE_TYPE (expr));
18138fd1498Szrj       return error_mark_node;
18238fd1498Szrj     }
18338fd1498Szrj   gcc_checking_assert (!type_dependent_expression_p (expr));
18438fd1498Szrj   return cv_unqualified (type_decays_to (unlowered_expr_type (expr)));
18538fd1498Szrj }
18638fd1498Szrj 
18738fd1498Szrj /* Given a LAMBDA_EXPR or closure type LAMBDA, return the op() of the
18838fd1498Szrj    closure type.  */
18938fd1498Szrj 
19038fd1498Szrj tree
lambda_function(tree lambda)19138fd1498Szrj lambda_function (tree lambda)
19238fd1498Szrj {
19338fd1498Szrj   tree type;
19438fd1498Szrj   if (TREE_CODE (lambda) == LAMBDA_EXPR)
19538fd1498Szrj     type = LAMBDA_EXPR_CLOSURE (lambda);
19638fd1498Szrj   else
19738fd1498Szrj     type = lambda;
19838fd1498Szrj   gcc_assert (LAMBDA_TYPE_P (type));
19938fd1498Szrj   /* Don't let debug_tree cause instantiation.  */
20038fd1498Szrj   if (CLASSTYPE_TEMPLATE_INSTANTIATION (type)
20138fd1498Szrj       && !COMPLETE_OR_OPEN_TYPE_P (type))
20238fd1498Szrj     return NULL_TREE;
20338fd1498Szrj   lambda = lookup_member (type, call_op_identifier,
20438fd1498Szrj 			  /*protect=*/0, /*want_type=*/false,
20538fd1498Szrj 			  tf_warning_or_error);
20638fd1498Szrj   if (lambda)
20738fd1498Szrj     lambda = STRIP_TEMPLATE (get_first_fn (lambda));
20838fd1498Szrj   return lambda;
20938fd1498Szrj }
21038fd1498Szrj 
21138fd1498Szrj /* Returns the type to use for the FIELD_DECL corresponding to the
21238fd1498Szrj    capture of EXPR.  EXPLICIT_INIT_P indicates whether this is a
21338fd1498Szrj    C++14 init capture, and BY_REFERENCE_P indicates whether we're
21438fd1498Szrj    capturing by reference.  */
21538fd1498Szrj 
21638fd1498Szrj tree
lambda_capture_field_type(tree expr,bool explicit_init_p,bool by_reference_p)21738fd1498Szrj lambda_capture_field_type (tree expr, bool explicit_init_p,
21838fd1498Szrj 			   bool by_reference_p)
21938fd1498Szrj {
22038fd1498Szrj   tree type;
22138fd1498Szrj   bool is_this = is_this_parameter (tree_strip_nop_conversions (expr));
22238fd1498Szrj 
22338fd1498Szrj   if (!is_this && type_dependent_expression_p (expr))
22438fd1498Szrj     {
22538fd1498Szrj       type = cxx_make_type (DECLTYPE_TYPE);
22638fd1498Szrj       DECLTYPE_TYPE_EXPR (type) = expr;
22738fd1498Szrj       DECLTYPE_FOR_LAMBDA_CAPTURE (type) = true;
22838fd1498Szrj       DECLTYPE_FOR_INIT_CAPTURE (type) = explicit_init_p;
22938fd1498Szrj       DECLTYPE_FOR_REF_CAPTURE (type) = by_reference_p;
23038fd1498Szrj       SET_TYPE_STRUCTURAL_EQUALITY (type);
23138fd1498Szrj     }
23238fd1498Szrj   else if (!is_this && explicit_init_p)
23338fd1498Szrj     {
23438fd1498Szrj       tree auto_node = make_auto ();
23538fd1498Szrj 
23638fd1498Szrj       type = auto_node;
23738fd1498Szrj       if (by_reference_p)
23838fd1498Szrj 	/* Add the reference now, so deduction doesn't lose
23938fd1498Szrj 	   outermost CV qualifiers of EXPR.  */
24038fd1498Szrj 	type = build_reference_type (type);
24138fd1498Szrj       type = do_auto_deduction (type, expr, auto_node);
24238fd1498Szrj     }
24338fd1498Szrj   else
24438fd1498Szrj     {
24538fd1498Szrj       type = non_reference (unlowered_expr_type (expr));
24638fd1498Szrj 
24738fd1498Szrj       if (!is_this
24838fd1498Szrj 	  && (by_reference_p || TREE_CODE (type) == FUNCTION_TYPE))
24938fd1498Szrj 	type = build_reference_type (type);
25038fd1498Szrj     }
25138fd1498Szrj 
25238fd1498Szrj   return type;
25338fd1498Szrj }
25438fd1498Szrj 
25538fd1498Szrj /* Returns true iff DECL is a lambda capture proxy variable created by
25638fd1498Szrj    build_capture_proxy.  */
25738fd1498Szrj 
25838fd1498Szrj bool
is_capture_proxy(tree decl)25938fd1498Szrj is_capture_proxy (tree decl)
26038fd1498Szrj {
26138fd1498Szrj   return (VAR_P (decl)
26238fd1498Szrj 	  && DECL_HAS_VALUE_EXPR_P (decl)
26338fd1498Szrj 	  && !DECL_ANON_UNION_VAR_P (decl)
26438fd1498Szrj 	  && !DECL_DECOMPOSITION_P (decl)
265*58e805e6Szrj 	  && !(DECL_ARTIFICIAL (decl)
266*58e805e6Szrj 	       && DECL_LANG_SPECIFIC (decl)
267*58e805e6Szrj 	       && DECL_OMP_PRIVATIZED_MEMBER (decl))
26838fd1498Szrj 	  && LAMBDA_FUNCTION_P (DECL_CONTEXT (decl)));
26938fd1498Szrj }
27038fd1498Szrj 
27138fd1498Szrj /* Returns true iff DECL is a capture proxy for a normal capture
27238fd1498Szrj    (i.e. without explicit initializer).  */
27338fd1498Szrj 
27438fd1498Szrj bool
is_normal_capture_proxy(tree decl)27538fd1498Szrj is_normal_capture_proxy (tree decl)
27638fd1498Szrj {
27738fd1498Szrj   if (!is_capture_proxy (decl))
27838fd1498Szrj     /* It's not a capture proxy.  */
27938fd1498Szrj     return false;
28038fd1498Szrj 
28138fd1498Szrj   if (variably_modified_type_p (TREE_TYPE (decl), NULL_TREE))
28238fd1498Szrj     /* VLA capture.  */
28338fd1498Szrj     return true;
28438fd1498Szrj 
28538fd1498Szrj   /* It is a capture proxy, is it a normal capture?  */
28638fd1498Szrj   tree val = DECL_VALUE_EXPR (decl);
28738fd1498Szrj   if (val == error_mark_node)
28838fd1498Szrj     return true;
28938fd1498Szrj 
29038fd1498Szrj   if (TREE_CODE (val) == ADDR_EXPR)
29138fd1498Szrj     val = TREE_OPERAND (val, 0);
29238fd1498Szrj   gcc_assert (TREE_CODE (val) == COMPONENT_REF);
29338fd1498Szrj   val = TREE_OPERAND (val, 1);
29438fd1498Szrj   return DECL_NORMAL_CAPTURE_P (val);
29538fd1498Szrj }
29638fd1498Szrj 
29738fd1498Szrj /* Returns true iff DECL is a capture proxy for a normal capture
29838fd1498Szrj    of a constant variable.  */
29938fd1498Szrj 
30038fd1498Szrj bool
is_constant_capture_proxy(tree decl)30138fd1498Szrj is_constant_capture_proxy (tree decl)
30238fd1498Szrj {
30338fd1498Szrj   if (is_normal_capture_proxy (decl))
30438fd1498Szrj     return decl_constant_var_p (DECL_CAPTURED_VARIABLE (decl));
30538fd1498Szrj   return false;
30638fd1498Szrj }
30738fd1498Szrj 
30838fd1498Szrj /* VAR is a capture proxy created by build_capture_proxy; add it to the
30938fd1498Szrj    current function, which is the operator() for the appropriate lambda.  */
31038fd1498Szrj 
31138fd1498Szrj void
insert_capture_proxy(tree var)31238fd1498Szrj insert_capture_proxy (tree var)
31338fd1498Szrj {
31438fd1498Szrj   if (is_normal_capture_proxy (var))
31538fd1498Szrj     {
31638fd1498Szrj       tree cap = DECL_CAPTURED_VARIABLE (var);
31738fd1498Szrj       if (CHECKING_P)
31838fd1498Szrj 	{
31938fd1498Szrj 	  gcc_assert (!is_normal_capture_proxy (cap));
32038fd1498Szrj 	  tree old = retrieve_local_specialization (cap);
32138fd1498Szrj 	  if (old)
32238fd1498Szrj 	    gcc_assert (DECL_CONTEXT (old) != DECL_CONTEXT (var));
32338fd1498Szrj 	}
32438fd1498Szrj       register_local_specialization (var, cap);
32538fd1498Szrj     }
32638fd1498Szrj 
32738fd1498Szrj   /* Put the capture proxy in the extra body block so that it won't clash
32838fd1498Szrj      with a later local variable.  */
32938fd1498Szrj   pushdecl_outermost_localscope (var);
33038fd1498Szrj 
33138fd1498Szrj   /* And put a DECL_EXPR in the STATEMENT_LIST for the same block.  */
33238fd1498Szrj   var = build_stmt (DECL_SOURCE_LOCATION (var), DECL_EXPR, var);
33338fd1498Szrj   tree stmt_list = (*stmt_list_stack)[1];
33438fd1498Szrj   gcc_assert (stmt_list);
33538fd1498Szrj   append_to_statement_list_force (var, &stmt_list);
33638fd1498Szrj }
33738fd1498Szrj 
33838fd1498Szrj /* We've just finished processing a lambda; if the containing scope is also
33938fd1498Szrj    a lambda, insert any capture proxies that were created while processing
34038fd1498Szrj    the nested lambda.  */
34138fd1498Szrj 
34238fd1498Szrj void
insert_pending_capture_proxies(void)34338fd1498Szrj insert_pending_capture_proxies (void)
34438fd1498Szrj {
34538fd1498Szrj   tree lam;
34638fd1498Szrj   vec<tree, va_gc> *proxies;
34738fd1498Szrj   unsigned i;
34838fd1498Szrj 
34938fd1498Szrj   if (!current_function_decl || !LAMBDA_FUNCTION_P (current_function_decl))
35038fd1498Szrj     return;
35138fd1498Szrj 
35238fd1498Szrj   lam = CLASSTYPE_LAMBDA_EXPR (DECL_CONTEXT (current_function_decl));
35338fd1498Szrj   proxies = LAMBDA_EXPR_PENDING_PROXIES (lam);
35438fd1498Szrj   for (i = 0; i < vec_safe_length (proxies); ++i)
35538fd1498Szrj     {
35638fd1498Szrj       tree var = (*proxies)[i];
35738fd1498Szrj       insert_capture_proxy (var);
35838fd1498Szrj     }
35938fd1498Szrj   release_tree_vector (LAMBDA_EXPR_PENDING_PROXIES (lam));
36038fd1498Szrj   LAMBDA_EXPR_PENDING_PROXIES (lam) = NULL;
36138fd1498Szrj }
36238fd1498Szrj 
36338fd1498Szrj /* Given REF, a COMPONENT_REF designating a field in the lambda closure,
36438fd1498Szrj    return the type we want the proxy to have: the type of the field itself,
36538fd1498Szrj    with added const-qualification if the lambda isn't mutable and the
36638fd1498Szrj    capture is by value.  */
36738fd1498Szrj 
36838fd1498Szrj tree
lambda_proxy_type(tree ref)36938fd1498Szrj lambda_proxy_type (tree ref)
37038fd1498Szrj {
37138fd1498Szrj   tree type;
37238fd1498Szrj   if (ref == error_mark_node)
37338fd1498Szrj     return error_mark_node;
37438fd1498Szrj   if (REFERENCE_REF_P (ref))
37538fd1498Szrj     ref = TREE_OPERAND (ref, 0);
37638fd1498Szrj   gcc_assert (TREE_CODE (ref) == COMPONENT_REF);
37738fd1498Szrj   type = TREE_TYPE (ref);
37838fd1498Szrj   if (!type || WILDCARD_TYPE_P (non_reference (type)))
37938fd1498Szrj     {
38038fd1498Szrj       type = cxx_make_type (DECLTYPE_TYPE);
38138fd1498Szrj       DECLTYPE_TYPE_EXPR (type) = ref;
38238fd1498Szrj       DECLTYPE_FOR_LAMBDA_PROXY (type) = true;
38338fd1498Szrj       SET_TYPE_STRUCTURAL_EQUALITY (type);
38438fd1498Szrj     }
38538fd1498Szrj   if (DECL_PACK_P (TREE_OPERAND (ref, 1)))
38638fd1498Szrj     type = make_pack_expansion (type);
38738fd1498Szrj   return type;
38838fd1498Szrj }
38938fd1498Szrj 
39038fd1498Szrj /* MEMBER is a capture field in a lambda closure class.  Now that we're
39138fd1498Szrj    inside the operator(), build a placeholder var for future lookups and
39238fd1498Szrj    debugging.  */
39338fd1498Szrj 
39438fd1498Szrj static tree
build_capture_proxy(tree member,tree init)39538fd1498Szrj build_capture_proxy (tree member, tree init)
39638fd1498Szrj {
39738fd1498Szrj   tree var, object, fn, closure, name, lam, type;
39838fd1498Szrj 
39938fd1498Szrj   if (PACK_EXPANSION_P (member))
40038fd1498Szrj     member = PACK_EXPANSION_PATTERN (member);
40138fd1498Szrj 
40238fd1498Szrj   closure = DECL_CONTEXT (member);
40338fd1498Szrj   fn = lambda_function (closure);
40438fd1498Szrj   lam = CLASSTYPE_LAMBDA_EXPR (closure);
40538fd1498Szrj 
40638fd1498Szrj   /* The proxy variable forwards to the capture field.  */
40738fd1498Szrj   object = build_fold_indirect_ref (DECL_ARGUMENTS (fn));
40838fd1498Szrj   object = finish_non_static_data_member (member, object, NULL_TREE);
40938fd1498Szrj   if (REFERENCE_REF_P (object))
41038fd1498Szrj     object = TREE_OPERAND (object, 0);
41138fd1498Szrj 
41238fd1498Szrj   /* Remove the __ inserted by add_capture.  */
41338fd1498Szrj   name = get_identifier (IDENTIFIER_POINTER (DECL_NAME (member)) + 2);
41438fd1498Szrj 
41538fd1498Szrj   type = lambda_proxy_type (object);
41638fd1498Szrj 
41738fd1498Szrj   if (name == this_identifier && !POINTER_TYPE_P (type))
41838fd1498Szrj     {
41938fd1498Szrj       type = build_pointer_type (type);
42038fd1498Szrj       type = cp_build_qualified_type (type, TYPE_QUAL_CONST);
42138fd1498Szrj       object = build_fold_addr_expr_with_type (object, type);
42238fd1498Szrj     }
42338fd1498Szrj 
42438fd1498Szrj   if (DECL_VLA_CAPTURE_P (member))
42538fd1498Szrj     {
42638fd1498Szrj       /* Rebuild the VLA type from the pointer and maxindex.  */
42738fd1498Szrj       tree field = next_initializable_field (TYPE_FIELDS (type));
42838fd1498Szrj       tree ptr = build_simple_component_ref (object, field);
42938fd1498Szrj       field = next_initializable_field (DECL_CHAIN (field));
43038fd1498Szrj       tree max = build_simple_component_ref (object, field);
43138fd1498Szrj       type = build_cplus_array_type (TREE_TYPE (TREE_TYPE (ptr)),
43238fd1498Szrj 				     build_index_type (max));
43338fd1498Szrj       type = build_reference_type (type);
43438fd1498Szrj       REFERENCE_VLA_OK (type) = true;
43538fd1498Szrj       object = convert (type, ptr);
43638fd1498Szrj     }
43738fd1498Szrj 
43838fd1498Szrj   complete_type (type);
43938fd1498Szrj 
44038fd1498Szrj   var = build_decl (input_location, VAR_DECL, name, type);
44138fd1498Szrj   SET_DECL_VALUE_EXPR (var, object);
44238fd1498Szrj   DECL_HAS_VALUE_EXPR_P (var) = 1;
44338fd1498Szrj   DECL_ARTIFICIAL (var) = 1;
44438fd1498Szrj   TREE_USED (var) = 1;
44538fd1498Szrj   DECL_CONTEXT (var) = fn;
44638fd1498Szrj 
44738fd1498Szrj   if (DECL_NORMAL_CAPTURE_P (member))
44838fd1498Szrj     {
44938fd1498Szrj       if (DECL_VLA_CAPTURE_P (member))
45038fd1498Szrj 	{
45138fd1498Szrj 	  init = CONSTRUCTOR_ELT (init, 0)->value;
45238fd1498Szrj 	  init = TREE_OPERAND (init, 0); // Strip ADDR_EXPR.
45338fd1498Szrj 	  init = TREE_OPERAND (init, 0); // Strip ARRAY_REF.
45438fd1498Szrj 	}
45538fd1498Szrj       else
45638fd1498Szrj 	{
45738fd1498Szrj 	  if (PACK_EXPANSION_P (init))
45838fd1498Szrj 	    init = PACK_EXPANSION_PATTERN (init);
45938fd1498Szrj 	}
46038fd1498Szrj 
46138fd1498Szrj       if (INDIRECT_REF_P (init))
46238fd1498Szrj 	init = TREE_OPERAND (init, 0);
46338fd1498Szrj       STRIP_NOPS (init);
46438fd1498Szrj 
46538fd1498Szrj       gcc_assert (VAR_P (init) || TREE_CODE (init) == PARM_DECL);
46638fd1498Szrj       while (is_normal_capture_proxy (init))
46738fd1498Szrj 	init = DECL_CAPTURED_VARIABLE (init);
46838fd1498Szrj       retrofit_lang_decl (var);
46938fd1498Szrj       DECL_CAPTURED_VARIABLE (var) = init;
47038fd1498Szrj     }
47138fd1498Szrj 
47238fd1498Szrj   if (name == this_identifier)
47338fd1498Szrj     {
47438fd1498Szrj       gcc_assert (LAMBDA_EXPR_THIS_CAPTURE (lam) == member);
47538fd1498Szrj       LAMBDA_EXPR_THIS_CAPTURE (lam) = var;
47638fd1498Szrj     }
47738fd1498Szrj 
47838fd1498Szrj   if (fn == current_function_decl)
47938fd1498Szrj     insert_capture_proxy (var);
48038fd1498Szrj   else
48138fd1498Szrj     vec_safe_push (LAMBDA_EXPR_PENDING_PROXIES (lam), var);
48238fd1498Szrj 
48338fd1498Szrj   return var;
48438fd1498Szrj }
48538fd1498Szrj 
48638fd1498Szrj static GTY(()) tree ptr_id;
48738fd1498Szrj static GTY(()) tree max_id;
48838fd1498Szrj 
48938fd1498Szrj /* Return a struct containing a pointer and a length for lambda capture of
49038fd1498Szrj    an array of runtime length.  */
49138fd1498Szrj 
49238fd1498Szrj static tree
vla_capture_type(tree array_type)49338fd1498Szrj vla_capture_type (tree array_type)
49438fd1498Szrj {
49538fd1498Szrj   tree type = xref_tag (record_type, make_anon_name (), ts_current, false);
49638fd1498Szrj   xref_basetypes (type, NULL_TREE);
49738fd1498Szrj   type = begin_class_definition (type);
49838fd1498Szrj   if (!ptr_id)
49938fd1498Szrj     {
50038fd1498Szrj       ptr_id = get_identifier ("ptr");
50138fd1498Szrj       max_id = get_identifier ("max");
50238fd1498Szrj     }
50338fd1498Szrj   tree ptrtype = build_pointer_type (TREE_TYPE (array_type));
50438fd1498Szrj   tree field = build_decl (input_location, FIELD_DECL, ptr_id, ptrtype);
50538fd1498Szrj   finish_member_declaration (field);
50638fd1498Szrj   field = build_decl (input_location, FIELD_DECL, max_id, sizetype);
50738fd1498Szrj   finish_member_declaration (field);
50838fd1498Szrj   return finish_struct (type, NULL_TREE);
50938fd1498Szrj }
51038fd1498Szrj 
51138fd1498Szrj /* From an ID and INITIALIZER, create a capture (by reference if
51238fd1498Szrj    BY_REFERENCE_P is true), add it to the capture-list for LAMBDA,
51338fd1498Szrj    and return it.  If ID is `this', BY_REFERENCE_P says whether
51438fd1498Szrj    `*this' is captured by reference.  */
51538fd1498Szrj 
51638fd1498Szrj tree
add_capture(tree lambda,tree id,tree orig_init,bool by_reference_p,bool explicit_init_p)51738fd1498Szrj add_capture (tree lambda, tree id, tree orig_init, bool by_reference_p,
51838fd1498Szrj 	     bool explicit_init_p)
51938fd1498Szrj {
52038fd1498Szrj   char *buf;
52138fd1498Szrj   tree type, member, name;
52238fd1498Szrj   bool vla = false;
52338fd1498Szrj   bool variadic = false;
52438fd1498Szrj   tree initializer = orig_init;
52538fd1498Szrj 
52638fd1498Szrj   if (PACK_EXPANSION_P (initializer))
52738fd1498Szrj     {
52838fd1498Szrj       initializer = PACK_EXPANSION_PATTERN (initializer);
52938fd1498Szrj       variadic = true;
53038fd1498Szrj     }
53138fd1498Szrj 
53238fd1498Szrj   if (TREE_CODE (initializer) == TREE_LIST
53338fd1498Szrj       /* A pack expansion might end up with multiple elements.  */
53438fd1498Szrj       && !PACK_EXPANSION_P (TREE_VALUE (initializer)))
53538fd1498Szrj     initializer = build_x_compound_expr_from_list (initializer, ELK_INIT,
53638fd1498Szrj 						   tf_warning_or_error);
53738fd1498Szrj   type = TREE_TYPE (initializer);
53838fd1498Szrj   if (type == error_mark_node)
53938fd1498Szrj     return error_mark_node;
54038fd1498Szrj 
54138fd1498Szrj   if (array_of_runtime_bound_p (type))
54238fd1498Szrj     {
54338fd1498Szrj       vla = true;
54438fd1498Szrj       if (!by_reference_p)
54538fd1498Szrj 	error ("array of runtime bound cannot be captured by copy, "
54638fd1498Szrj 	       "only by reference");
54738fd1498Szrj 
54838fd1498Szrj       /* For a VLA, we capture the address of the first element and the
54938fd1498Szrj 	 maximum index, and then reconstruct the VLA for the proxy.  */
55038fd1498Szrj       tree elt = cp_build_array_ref (input_location, initializer,
55138fd1498Szrj 				     integer_zero_node, tf_warning_or_error);
55238fd1498Szrj       initializer = build_constructor_va (init_list_type_node, 2,
55338fd1498Szrj 					  NULL_TREE, build_address (elt),
55438fd1498Szrj 					  NULL_TREE, array_type_nelts (type));
55538fd1498Szrj       type = vla_capture_type (type);
55638fd1498Szrj     }
55738fd1498Szrj   else if (!dependent_type_p (type)
55838fd1498Szrj 	   && variably_modified_type_p (type, NULL_TREE))
55938fd1498Szrj     {
56038fd1498Szrj       sorry ("capture of variably-modified type %qT that is not an N3639 array "
56138fd1498Szrj 	     "of runtime bound", type);
56238fd1498Szrj       if (TREE_CODE (type) == ARRAY_TYPE
56338fd1498Szrj 	  && variably_modified_type_p (TREE_TYPE (type), NULL_TREE))
56438fd1498Szrj 	inform (input_location, "because the array element type %qT has "
56538fd1498Szrj 		"variable size", TREE_TYPE (type));
56638fd1498Szrj       return error_mark_node;
56738fd1498Szrj     }
56838fd1498Szrj   else
56938fd1498Szrj     {
57038fd1498Szrj       type = lambda_capture_field_type (initializer, explicit_init_p,
57138fd1498Szrj 					by_reference_p);
57238fd1498Szrj       if (type == error_mark_node)
57338fd1498Szrj 	return error_mark_node;
57438fd1498Szrj 
57538fd1498Szrj       if (id == this_identifier && !by_reference_p)
57638fd1498Szrj 	{
57738fd1498Szrj 	  gcc_assert (POINTER_TYPE_P (type));
57838fd1498Szrj 	  type = TREE_TYPE (type);
57938fd1498Szrj 	  initializer = cp_build_fold_indirect_ref (initializer);
58038fd1498Szrj 	}
58138fd1498Szrj 
58238fd1498Szrj       if (dependent_type_p (type))
58338fd1498Szrj 	;
58438fd1498Szrj       else if (id != this_identifier && by_reference_p)
58538fd1498Szrj 	{
58638fd1498Szrj 	  if (!lvalue_p (initializer))
58738fd1498Szrj 	    {
58838fd1498Szrj 	      error ("cannot capture %qE by reference", initializer);
58938fd1498Szrj 	      return error_mark_node;
59038fd1498Szrj 	    }
59138fd1498Szrj 	}
59238fd1498Szrj       else
59338fd1498Szrj 	{
59438fd1498Szrj 	  /* Capture by copy requires a complete type.  */
59538fd1498Szrj 	  type = complete_type (type);
59638fd1498Szrj 	  if (!COMPLETE_TYPE_P (type))
59738fd1498Szrj 	    {
59838fd1498Szrj 	      error ("capture by copy of incomplete type %qT", type);
59938fd1498Szrj 	      cxx_incomplete_type_inform (type);
60038fd1498Szrj 	      return error_mark_node;
60138fd1498Szrj 	    }
60238fd1498Szrj 	}
60338fd1498Szrj     }
60438fd1498Szrj 
60538fd1498Szrj   /* Add __ to the beginning of the field name so that user code
60638fd1498Szrj      won't find the field with name lookup.  We can't just leave the name
60738fd1498Szrj      unset because template instantiation uses the name to find
60838fd1498Szrj      instantiated fields.  */
60938fd1498Szrj   buf = (char *) alloca (IDENTIFIER_LENGTH (id) + 3);
61038fd1498Szrj   buf[1] = buf[0] = '_';
61138fd1498Szrj   memcpy (buf + 2, IDENTIFIER_POINTER (id),
61238fd1498Szrj 	  IDENTIFIER_LENGTH (id) + 1);
61338fd1498Szrj   name = get_identifier (buf);
61438fd1498Szrj 
61538fd1498Szrj   /* If TREE_TYPE isn't set, we're still in the introducer, so check
61638fd1498Szrj      for duplicates.  */
61738fd1498Szrj   if (!LAMBDA_EXPR_CLOSURE (lambda))
61838fd1498Szrj     {
61938fd1498Szrj       if (IDENTIFIER_MARKED (name))
62038fd1498Szrj 	{
62138fd1498Szrj 	  pedwarn (input_location, 0,
62238fd1498Szrj 		   "already captured %qD in lambda expression", id);
62338fd1498Szrj 	  return NULL_TREE;
62438fd1498Szrj 	}
62538fd1498Szrj       IDENTIFIER_MARKED (name) = true;
62638fd1498Szrj     }
62738fd1498Szrj 
62838fd1498Szrj   if (variadic)
62938fd1498Szrj     type = make_pack_expansion (type);
63038fd1498Szrj 
63138fd1498Szrj   /* Make member variable.  */
63238fd1498Szrj   member = build_decl (input_location, FIELD_DECL, name, type);
63338fd1498Szrj   DECL_VLA_CAPTURE_P (member) = vla;
63438fd1498Szrj 
63538fd1498Szrj   if (!explicit_init_p)
63638fd1498Szrj     /* Normal captures are invisible to name lookup but uses are replaced
63738fd1498Szrj        with references to the capture field; we implement this by only
63838fd1498Szrj        really making them invisible in unevaluated context; see
63938fd1498Szrj        qualify_lookup.  For now, let's make explicitly initialized captures
64038fd1498Szrj        always visible.  */
64138fd1498Szrj     DECL_NORMAL_CAPTURE_P (member) = true;
64238fd1498Szrj 
64338fd1498Szrj   if (id == this_identifier)
64438fd1498Szrj     LAMBDA_EXPR_THIS_CAPTURE (lambda) = member;
64538fd1498Szrj 
64638fd1498Szrj   /* Add it to the appropriate closure class if we've started it.  */
64738fd1498Szrj   if (current_class_type
64838fd1498Szrj       && current_class_type == LAMBDA_EXPR_CLOSURE (lambda))
64938fd1498Szrj     {
65038fd1498Szrj       if (COMPLETE_TYPE_P (current_class_type))
65138fd1498Szrj 	internal_error ("trying to capture %qD in instantiation of "
65238fd1498Szrj 			"generic lambda", id);
65338fd1498Szrj       finish_member_declaration (member);
65438fd1498Szrj     }
65538fd1498Szrj 
65638fd1498Szrj   tree listmem = member;
65738fd1498Szrj   if (variadic)
65838fd1498Szrj     {
65938fd1498Szrj       listmem = make_pack_expansion (member);
66038fd1498Szrj       initializer = orig_init;
66138fd1498Szrj     }
66238fd1498Szrj   LAMBDA_EXPR_CAPTURE_LIST (lambda)
66338fd1498Szrj     = tree_cons (listmem, initializer, LAMBDA_EXPR_CAPTURE_LIST (lambda));
66438fd1498Szrj 
66538fd1498Szrj   if (LAMBDA_EXPR_CLOSURE (lambda))
66638fd1498Szrj     return build_capture_proxy (member, initializer);
66738fd1498Szrj   /* For explicit captures we haven't started the function yet, so we wait
66838fd1498Szrj      and build the proxy from cp_parser_lambda_body.  */
66938fd1498Szrj   LAMBDA_CAPTURE_EXPLICIT_P (LAMBDA_EXPR_CAPTURE_LIST (lambda)) = true;
67038fd1498Szrj   return NULL_TREE;
67138fd1498Szrj }
67238fd1498Szrj 
67338fd1498Szrj /* Register all the capture members on the list CAPTURES, which is the
67438fd1498Szrj    LAMBDA_EXPR_CAPTURE_LIST for the lambda after the introducer.  */
67538fd1498Szrj 
67638fd1498Szrj void
register_capture_members(tree captures)67738fd1498Szrj register_capture_members (tree captures)
67838fd1498Szrj {
67938fd1498Szrj   if (captures == NULL_TREE)
68038fd1498Szrj     return;
68138fd1498Szrj 
68238fd1498Szrj   register_capture_members (TREE_CHAIN (captures));
68338fd1498Szrj 
68438fd1498Szrj   tree field = TREE_PURPOSE (captures);
68538fd1498Szrj   if (PACK_EXPANSION_P (field))
68638fd1498Szrj     field = PACK_EXPANSION_PATTERN (field);
68738fd1498Szrj 
68838fd1498Szrj   /* We set this in add_capture to avoid duplicates.  */
68938fd1498Szrj   IDENTIFIER_MARKED (DECL_NAME (field)) = false;
69038fd1498Szrj   finish_member_declaration (field);
69138fd1498Szrj }
69238fd1498Szrj 
69338fd1498Szrj /* Similar to add_capture, except this works on a stack of nested lambdas.
69438fd1498Szrj    BY_REFERENCE_P in this case is derived from the default capture mode.
69538fd1498Szrj    Returns the capture for the lambda at the bottom of the stack.  */
69638fd1498Szrj 
69738fd1498Szrj tree
add_default_capture(tree lambda_stack,tree id,tree initializer)69838fd1498Szrj add_default_capture (tree lambda_stack, tree id, tree initializer)
69938fd1498Szrj {
70038fd1498Szrj   bool this_capture_p = (id == this_identifier);
70138fd1498Szrj 
70238fd1498Szrj   tree var = NULL_TREE;
70338fd1498Szrj 
70438fd1498Szrj   tree saved_class_type = current_class_type;
70538fd1498Szrj 
70638fd1498Szrj   tree node;
70738fd1498Szrj 
70838fd1498Szrj   for (node = lambda_stack;
70938fd1498Szrj        node;
71038fd1498Szrj        node = TREE_CHAIN (node))
71138fd1498Szrj     {
71238fd1498Szrj       tree lambda = TREE_VALUE (node);
71338fd1498Szrj 
71438fd1498Szrj       current_class_type = LAMBDA_EXPR_CLOSURE (lambda);
71538fd1498Szrj       if (DECL_PACK_P (initializer))
71638fd1498Szrj 	initializer = make_pack_expansion (initializer);
71738fd1498Szrj       var = add_capture (lambda,
71838fd1498Szrj                             id,
71938fd1498Szrj                             initializer,
72038fd1498Szrj                             /*by_reference_p=*/
72138fd1498Szrj 			    (this_capture_p
72238fd1498Szrj 			     || (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda)
72338fd1498Szrj 				 == CPLD_REFERENCE)),
72438fd1498Szrj 			    /*explicit_init_p=*/false);
72538fd1498Szrj       initializer = convert_from_reference (var);
72638fd1498Szrj     }
72738fd1498Szrj 
72838fd1498Szrj   current_class_type = saved_class_type;
72938fd1498Szrj 
73038fd1498Szrj   return var;
73138fd1498Szrj }
73238fd1498Szrj 
73338fd1498Szrj /* Return the capture pertaining to a use of 'this' in LAMBDA, in the
73438fd1498Szrj    form of an INDIRECT_REF, possibly adding it through default
73538fd1498Szrj    capturing, if ADD_CAPTURE_P is true.  */
73638fd1498Szrj 
73738fd1498Szrj tree
lambda_expr_this_capture(tree lambda,bool add_capture_p)73838fd1498Szrj lambda_expr_this_capture (tree lambda, bool add_capture_p)
73938fd1498Szrj {
74038fd1498Szrj   tree result;
74138fd1498Szrj 
74238fd1498Szrj   tree this_capture = LAMBDA_EXPR_THIS_CAPTURE (lambda);
74338fd1498Szrj 
74438fd1498Szrj   /* In unevaluated context this isn't an odr-use, so don't capture.  */
74538fd1498Szrj   if (cp_unevaluated_operand)
74638fd1498Szrj     add_capture_p = false;
74738fd1498Szrj 
74838fd1498Szrj   /* Try to default capture 'this' if we can.  */
74938fd1498Szrj   if (!this_capture
75038fd1498Szrj       && (!add_capture_p
75138fd1498Szrj           || LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda) != CPLD_NONE))
75238fd1498Szrj     {
75338fd1498Szrj       tree lambda_stack = NULL_TREE;
75438fd1498Szrj       tree init = NULL_TREE;
75538fd1498Szrj 
75638fd1498Szrj       /* If we are in a lambda function, we can move out until we hit:
75738fd1498Szrj            1. a non-lambda function or NSDMI,
75838fd1498Szrj            2. a lambda function capturing 'this', or
75938fd1498Szrj            3. a non-default capturing lambda function.  */
76038fd1498Szrj       for (tree tlambda = lambda; ;)
76138fd1498Szrj 	{
76238fd1498Szrj           lambda_stack = tree_cons (NULL_TREE,
76338fd1498Szrj                                     tlambda,
76438fd1498Szrj                                     lambda_stack);
76538fd1498Szrj 
76638fd1498Szrj 	  tree closure = LAMBDA_EXPR_CLOSURE (tlambda);
76738fd1498Szrj 	  tree containing_function
76838fd1498Szrj 	    = decl_function_context (TYPE_NAME (closure));
76938fd1498Szrj 
77038fd1498Szrj 	  tree ex = LAMBDA_EXPR_EXTRA_SCOPE (tlambda);
77138fd1498Szrj 	  if (ex && TREE_CODE (ex) == FIELD_DECL)
77238fd1498Szrj 	    {
77338fd1498Szrj 	      /* Lambda in an NSDMI.  We don't have a function to look up
77438fd1498Szrj 		 'this' in, but we can find (or rebuild) the fake one from
77538fd1498Szrj 		 inject_this_parameter.  */
77638fd1498Szrj 	      if (!containing_function && !COMPLETE_TYPE_P (closure))
77738fd1498Szrj 		/* If we're parsing a lambda in a non-local class,
77838fd1498Szrj 		   we can find the fake 'this' in scope_chain.  */
77938fd1498Szrj 		init = scope_chain->x_current_class_ptr;
78038fd1498Szrj 	      else
78138fd1498Szrj 		/* Otherwise it's either gone or buried in
78238fd1498Szrj 		   function_context_stack, so make another.  */
78338fd1498Szrj 		init = build_this_parm (NULL_TREE, DECL_CONTEXT (ex),
78438fd1498Szrj 					TYPE_UNQUALIFIED);
78538fd1498Szrj 	      gcc_checking_assert
78638fd1498Szrj 		(init && (TREE_TYPE (TREE_TYPE (init))
78738fd1498Szrj 			  == current_nonlambda_class_type ()));
78838fd1498Szrj 	      break;
78938fd1498Szrj 	    }
79038fd1498Szrj 
79138fd1498Szrj 	  if (containing_function == NULL_TREE)
79238fd1498Szrj 	    /* We ran out of scopes; there's no 'this' to capture.  */
79338fd1498Szrj 	    break;
79438fd1498Szrj 
79538fd1498Szrj 	  if (!LAMBDA_FUNCTION_P (containing_function))
79638fd1498Szrj 	    {
79738fd1498Szrj 	      /* We found a non-lambda function.  */
79838fd1498Szrj 	      if (DECL_NONSTATIC_MEMBER_FUNCTION_P (containing_function))
79938fd1498Szrj 		/* First parameter is 'this'.  */
80038fd1498Szrj 		init = DECL_ARGUMENTS (containing_function);
80138fd1498Szrj 	      break;
80238fd1498Szrj 	    }
80338fd1498Szrj 
80438fd1498Szrj 	  tlambda
80538fd1498Szrj             = CLASSTYPE_LAMBDA_EXPR (DECL_CONTEXT (containing_function));
80638fd1498Szrj 
80738fd1498Szrj           if (LAMBDA_EXPR_THIS_CAPTURE (tlambda))
80838fd1498Szrj 	    {
80938fd1498Szrj 	      /* An outer lambda has already captured 'this'.  */
81038fd1498Szrj 	      init = LAMBDA_EXPR_THIS_CAPTURE (tlambda);
81138fd1498Szrj 	      break;
81238fd1498Szrj 	    }
81338fd1498Szrj 
81438fd1498Szrj 	  if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (tlambda) == CPLD_NONE)
81538fd1498Szrj 	    /* An outer lambda won't let us capture 'this'.  */
81638fd1498Szrj 	    break;
81738fd1498Szrj 	}
81838fd1498Szrj 
81938fd1498Szrj       if (init)
82038fd1498Szrj         {
82138fd1498Szrj           if (add_capture_p)
82238fd1498Szrj 	    this_capture = add_default_capture (lambda_stack,
82338fd1498Szrj 					        /*id=*/this_identifier,
82438fd1498Szrj 					        init);
82538fd1498Szrj           else
82638fd1498Szrj 	    this_capture = init;
82738fd1498Szrj         }
82838fd1498Szrj     }
82938fd1498Szrj 
83038fd1498Szrj   if (cp_unevaluated_operand)
83138fd1498Szrj     result = this_capture;
83238fd1498Szrj   else if (!this_capture)
83338fd1498Szrj     {
83438fd1498Szrj       if (add_capture_p)
83538fd1498Szrj 	{
83638fd1498Szrj 	  error ("%<this%> was not captured for this lambda function");
83738fd1498Szrj 	  result = error_mark_node;
83838fd1498Szrj 	}
83938fd1498Szrj       else
84038fd1498Szrj 	result = NULL_TREE;
84138fd1498Szrj     }
84238fd1498Szrj   else
84338fd1498Szrj     {
84438fd1498Szrj       /* To make sure that current_class_ref is for the lambda.  */
84538fd1498Szrj       gcc_assert (TYPE_MAIN_VARIANT (TREE_TYPE (current_class_ref))
84638fd1498Szrj 		  == LAMBDA_EXPR_CLOSURE (lambda));
84738fd1498Szrj 
84838fd1498Szrj       result = this_capture;
84938fd1498Szrj 
85038fd1498Szrj       /* If 'this' is captured, each use of 'this' is transformed into an
85138fd1498Szrj 	 access to the corresponding unnamed data member of the closure
85238fd1498Szrj 	 type cast (_expr.cast_ 5.4) to the type of 'this'. [ The cast
85338fd1498Szrj 	 ensures that the transformed expression is an rvalue. ] */
85438fd1498Szrj       result = rvalue (result);
85538fd1498Szrj     }
85638fd1498Szrj 
85738fd1498Szrj   return result;
85838fd1498Szrj }
85938fd1498Szrj 
86038fd1498Szrj /* Return the innermost LAMBDA_EXPR we're currently in, if any.  */
86138fd1498Szrj 
86238fd1498Szrj tree
current_lambda_expr(void)86338fd1498Szrj current_lambda_expr (void)
86438fd1498Szrj {
86538fd1498Szrj   tree type = current_class_type;
86638fd1498Szrj   while (type && !LAMBDA_TYPE_P (type))
86738fd1498Szrj     type = decl_type_context (TYPE_NAME (type));
86838fd1498Szrj   if (type)
86938fd1498Szrj     return CLASSTYPE_LAMBDA_EXPR (type);
87038fd1498Szrj   else
87138fd1498Szrj     return NULL_TREE;
87238fd1498Szrj }
87338fd1498Szrj 
87438fd1498Szrj /* Return the current LAMBDA_EXPR, if this is a resolvable dummy
87538fd1498Szrj    object.  NULL otherwise..  */
87638fd1498Szrj 
87738fd1498Szrj static tree
resolvable_dummy_lambda(tree object)87838fd1498Szrj resolvable_dummy_lambda (tree object)
87938fd1498Szrj {
88038fd1498Szrj   if (!is_dummy_object (object))
88138fd1498Szrj     return NULL_TREE;
88238fd1498Szrj 
88338fd1498Szrj   tree type = TYPE_MAIN_VARIANT (TREE_TYPE (object));
88438fd1498Szrj   gcc_assert (!TYPE_PTR_P (type));
88538fd1498Szrj 
88638fd1498Szrj   if (type != current_class_type
88738fd1498Szrj       && current_class_type
88838fd1498Szrj       && LAMBDA_TYPE_P (current_class_type)
88938fd1498Szrj       && lambda_function (current_class_type)
890*58e805e6Szrj       && DERIVED_FROM_P (type, nonlambda_method_basetype()))
89138fd1498Szrj     return CLASSTYPE_LAMBDA_EXPR (current_class_type);
89238fd1498Szrj 
89338fd1498Szrj   return NULL_TREE;
89438fd1498Szrj }
89538fd1498Szrj 
89638fd1498Szrj /* We don't want to capture 'this' until we know we need it, i.e. after
89738fd1498Szrj    overload resolution has chosen a non-static member function.  At that
89838fd1498Szrj    point we call this function to turn a dummy object into a use of the
89938fd1498Szrj    'this' capture.  */
90038fd1498Szrj 
90138fd1498Szrj tree
maybe_resolve_dummy(tree object,bool add_capture_p)90238fd1498Szrj maybe_resolve_dummy (tree object, bool add_capture_p)
90338fd1498Szrj {
90438fd1498Szrj   if (tree lam = resolvable_dummy_lambda (object))
90538fd1498Szrj     if (tree cap = lambda_expr_this_capture (lam, add_capture_p))
90638fd1498Szrj       if (cap != error_mark_node)
90738fd1498Szrj 	object = build_fold_indirect_ref (cap);
90838fd1498Szrj 
90938fd1498Szrj   return object;
91038fd1498Szrj }
91138fd1498Szrj 
91238fd1498Szrj /* When parsing a generic lambda containing an argument-dependent
91338fd1498Szrj    member function call we defer overload resolution to instantiation
91438fd1498Szrj    time.  But we have to know now whether to capture this or not.
91538fd1498Szrj    Do that if FNS contains any non-static fns.
91638fd1498Szrj    The std doesn't anticipate this case, but I expect this to be the
91738fd1498Szrj    outcome of discussion.  */
91838fd1498Szrj 
91938fd1498Szrj void
maybe_generic_this_capture(tree object,tree fns)92038fd1498Szrj maybe_generic_this_capture (tree object, tree fns)
92138fd1498Szrj {
92238fd1498Szrj   if (tree lam = resolvable_dummy_lambda (object))
92338fd1498Szrj     if (!LAMBDA_EXPR_THIS_CAPTURE (lam))
92438fd1498Szrj       {
92538fd1498Szrj 	/* We've not yet captured, so look at the function set of
92638fd1498Szrj 	   interest.  */
92738fd1498Szrj 	if (BASELINK_P (fns))
92838fd1498Szrj 	  fns = BASELINK_FUNCTIONS (fns);
92938fd1498Szrj 	bool id_expr = TREE_CODE (fns) == TEMPLATE_ID_EXPR;
93038fd1498Szrj 	if (id_expr)
93138fd1498Szrj 	  fns = TREE_OPERAND (fns, 0);
93238fd1498Szrj 
93338fd1498Szrj 	for (lkp_iterator iter (fns); iter; ++iter)
93438fd1498Szrj 	  if ((!id_expr || TREE_CODE (*iter) == TEMPLATE_DECL)
93538fd1498Szrj 	      && DECL_NONSTATIC_MEMBER_FUNCTION_P (*iter))
93638fd1498Szrj 	    {
93738fd1498Szrj 	      /* Found a non-static member.  Capture this.  */
93838fd1498Szrj 	      lambda_expr_this_capture (lam, true);
93938fd1498Szrj 	      break;
94038fd1498Szrj 	    }
94138fd1498Szrj       }
94238fd1498Szrj }
94338fd1498Szrj 
94438fd1498Szrj /* Returns the innermost non-lambda function.  */
94538fd1498Szrj 
94638fd1498Szrj tree
current_nonlambda_function(void)94738fd1498Szrj current_nonlambda_function (void)
94838fd1498Szrj {
94938fd1498Szrj   tree fn = current_function_decl;
95038fd1498Szrj   while (fn && LAMBDA_FUNCTION_P (fn))
95138fd1498Szrj     fn = decl_function_context (fn);
95238fd1498Szrj   return fn;
95338fd1498Szrj }
95438fd1498Szrj 
955*58e805e6Szrj /* Returns the method basetype of the innermost non-lambda function, including
956*58e805e6Szrj    a hypothetical constructor if inside an NSDMI, or NULL_TREE if none.  */
95738fd1498Szrj 
95838fd1498Szrj tree
nonlambda_method_basetype(void)95938fd1498Szrj nonlambda_method_basetype (void)
96038fd1498Szrj {
96138fd1498Szrj   if (!current_class_ref)
96238fd1498Szrj     return NULL_TREE;
96338fd1498Szrj 
964*58e805e6Szrj   tree type = current_class_type;
96538fd1498Szrj   if (!type || !LAMBDA_TYPE_P (type))
96638fd1498Szrj     return type;
96738fd1498Szrj 
968*58e805e6Szrj   while (true)
969*58e805e6Szrj     {
970*58e805e6Szrj       tree lam = CLASSTYPE_LAMBDA_EXPR (type);
971*58e805e6Szrj       tree ex = LAMBDA_EXPR_EXTRA_SCOPE (lam);
972*58e805e6Szrj       if (ex && TREE_CODE (ex) == FIELD_DECL)
973*58e805e6Szrj 	/* Lambda in an NSDMI.  */
974*58e805e6Szrj 	return DECL_CONTEXT (ex);
97538fd1498Szrj 
976*58e805e6Szrj       tree fn = TYPE_CONTEXT (type);
977*58e805e6Szrj       if (!fn || TREE_CODE (fn) != FUNCTION_DECL
978*58e805e6Szrj 	  || !DECL_NONSTATIC_MEMBER_FUNCTION_P (fn))
979*58e805e6Szrj 	/* No enclosing non-lambda method.  */
98038fd1498Szrj 	return NULL_TREE;
981*58e805e6Szrj       if (!LAMBDA_FUNCTION_P (fn))
982*58e805e6Szrj 	/* Found an enclosing non-lambda method.  */
98338fd1498Szrj 	return TYPE_METHOD_BASETYPE (TREE_TYPE (fn));
984*58e805e6Szrj       type = DECL_CONTEXT (fn);
985*58e805e6Szrj     }
98638fd1498Szrj }
98738fd1498Szrj 
98838fd1498Szrj /* Like current_scope, but looking through lambdas.  */
98938fd1498Szrj 
99038fd1498Szrj tree
current_nonlambda_scope(void)99138fd1498Szrj current_nonlambda_scope (void)
99238fd1498Szrj {
99338fd1498Szrj   tree scope = current_scope ();
99438fd1498Szrj   for (;;)
99538fd1498Szrj     {
99638fd1498Szrj       if (TREE_CODE (scope) == FUNCTION_DECL
99738fd1498Szrj 	  && LAMBDA_FUNCTION_P (scope))
99838fd1498Szrj 	{
99938fd1498Szrj 	  scope = CP_TYPE_CONTEXT (DECL_CONTEXT (scope));
100038fd1498Szrj 	  continue;
100138fd1498Szrj 	}
100238fd1498Szrj       else if (LAMBDA_TYPE_P (scope))
100338fd1498Szrj 	{
100438fd1498Szrj 	  scope = CP_TYPE_CONTEXT (scope);
100538fd1498Szrj 	  continue;
100638fd1498Szrj 	}
100738fd1498Szrj       break;
100838fd1498Szrj     }
100938fd1498Szrj   return scope;
101038fd1498Szrj }
101138fd1498Szrj 
101238fd1498Szrj /* Helper function for maybe_add_lambda_conv_op; build a CALL_EXPR with
101338fd1498Szrj    indicated FN and NARGS, but do not initialize the return type or any of the
101438fd1498Szrj    argument slots.  */
101538fd1498Szrj 
101638fd1498Szrj static tree
prepare_op_call(tree fn,int nargs)101738fd1498Szrj prepare_op_call (tree fn, int nargs)
101838fd1498Szrj {
101938fd1498Szrj   tree t;
102038fd1498Szrj 
102138fd1498Szrj   t = build_vl_exp (CALL_EXPR, nargs + 3);
102238fd1498Szrj   CALL_EXPR_FN (t) = fn;
102338fd1498Szrj   CALL_EXPR_STATIC_CHAIN (t) = NULL;
102438fd1498Szrj 
102538fd1498Szrj   return t;
102638fd1498Szrj }
102738fd1498Szrj 
102838fd1498Szrj /* Return true iff CALLOP is the op() for a generic lambda.  */
102938fd1498Szrj 
103038fd1498Szrj bool
generic_lambda_fn_p(tree callop)103138fd1498Szrj generic_lambda_fn_p (tree callop)
103238fd1498Szrj {
103338fd1498Szrj   return (LAMBDA_FUNCTION_P (callop)
103438fd1498Szrj 	  && DECL_TEMPLATE_INFO (callop)
103538fd1498Szrj 	  && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (callop)));
103638fd1498Szrj }
103738fd1498Szrj 
103838fd1498Szrj /* If the closure TYPE has a static op(), also add a conversion to function
103938fd1498Szrj    pointer.  */
104038fd1498Szrj 
104138fd1498Szrj void
maybe_add_lambda_conv_op(tree type)104238fd1498Szrj maybe_add_lambda_conv_op (tree type)
104338fd1498Szrj {
104438fd1498Szrj   bool nested = (cfun != NULL);
104538fd1498Szrj   bool nested_def = decl_function_context (TYPE_MAIN_DECL (type));
104638fd1498Szrj   tree callop = lambda_function (type);
104738fd1498Szrj   tree lam = CLASSTYPE_LAMBDA_EXPR (type);
104838fd1498Szrj 
104938fd1498Szrj   if (LAMBDA_EXPR_CAPTURE_LIST (lam) != NULL_TREE
105038fd1498Szrj       || LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lam) != CPLD_NONE)
105138fd1498Szrj     return;
105238fd1498Szrj 
105338fd1498Szrj   if (processing_template_decl)
105438fd1498Szrj     return;
105538fd1498Szrj 
105638fd1498Szrj   bool const generic_lambda_p = generic_lambda_fn_p (callop);
105738fd1498Szrj 
105838fd1498Szrj   if (!generic_lambda_p && DECL_INITIAL (callop) == NULL_TREE)
105938fd1498Szrj     {
106038fd1498Szrj       /* If the op() wasn't instantiated due to errors, give up.  */
106138fd1498Szrj       gcc_assert (errorcount || sorrycount);
106238fd1498Szrj       return;
106338fd1498Szrj     }
106438fd1498Szrj 
106538fd1498Szrj   /* Non-template conversion operators are defined directly with build_call_a
106638fd1498Szrj      and using DIRECT_ARGVEC for arguments (including 'this').  Templates are
106738fd1498Szrj      deferred and the CALL is built in-place.  In the case of a deduced return
106838fd1498Szrj      call op, the decltype expression, DECLTYPE_CALL, used as a substitute for
106938fd1498Szrj      the return type is also built in-place.  The arguments of DECLTYPE_CALL in
107038fd1498Szrj      the return expression may differ in flags from those in the body CALL.  In
107138fd1498Szrj      particular, parameter pack expansions are marked PACK_EXPANSION_LOCAL_P in
107238fd1498Szrj      the body CALL, but not in DECLTYPE_CALL.  */
107338fd1498Szrj 
107438fd1498Szrj   vec<tree, va_gc> *direct_argvec = 0;
107538fd1498Szrj   tree decltype_call = 0, call = 0;
107638fd1498Szrj   tree optype = TREE_TYPE (callop);
107738fd1498Szrj   tree fn_result = TREE_TYPE (optype);
107838fd1498Szrj 
107938fd1498Szrj   tree thisarg = build_nop (TREE_TYPE (DECL_ARGUMENTS (callop)),
108038fd1498Szrj 			    null_pointer_node);
108138fd1498Szrj   if (generic_lambda_p)
108238fd1498Szrj     {
108338fd1498Szrj       ++processing_template_decl;
108438fd1498Szrj 
108538fd1498Szrj       /* Prepare the dependent member call for the static member function
108638fd1498Szrj 	 '_FUN' and, potentially, prepare another call to be used in a decltype
108738fd1498Szrj 	 return expression for a deduced return call op to allow for simple
108838fd1498Szrj 	 implementation of the conversion operator.  */
108938fd1498Szrj 
109038fd1498Szrj       tree instance = cp_build_fold_indirect_ref (thisarg);
109138fd1498Szrj       tree objfn = build_min (COMPONENT_REF, NULL_TREE,
109238fd1498Szrj 			      instance, DECL_NAME (callop), NULL_TREE);
109338fd1498Szrj       int nargs = list_length (DECL_ARGUMENTS (callop)) - 1;
109438fd1498Szrj 
109538fd1498Szrj       call = prepare_op_call (objfn, nargs);
109638fd1498Szrj       if (type_uses_auto (fn_result))
109738fd1498Szrj 	decltype_call = prepare_op_call (objfn, nargs);
109838fd1498Szrj     }
109938fd1498Szrj   else
110038fd1498Szrj     {
110138fd1498Szrj       direct_argvec = make_tree_vector ();
110238fd1498Szrj       direct_argvec->quick_push (thisarg);
110338fd1498Szrj     }
110438fd1498Szrj 
110538fd1498Szrj   /* Copy CALLOP's argument list (as per 'copy_list') as FN_ARGS in order to
110638fd1498Szrj      declare the static member function "_FUN" below.  For each arg append to
110738fd1498Szrj      DIRECT_ARGVEC (for the non-template case) or populate the pre-allocated
110838fd1498Szrj      call args (for the template case).  If a parameter pack is found, expand
110938fd1498Szrj      it, flagging it as PACK_EXPANSION_LOCAL_P for the body call.  */
111038fd1498Szrj 
111138fd1498Szrj   tree fn_args = NULL_TREE;
111238fd1498Szrj   {
111338fd1498Szrj     int ix = 0;
111438fd1498Szrj     tree src = DECL_CHAIN (DECL_ARGUMENTS (callop));
111538fd1498Szrj     tree tgt = NULL;
111638fd1498Szrj 
111738fd1498Szrj     while (src)
111838fd1498Szrj       {
111938fd1498Szrj 	tree new_node = copy_node (src);
112038fd1498Szrj 
1121*58e805e6Szrj 	/* Clear TREE_ADDRESSABLE on thunk arguments.  */
1122*58e805e6Szrj 	TREE_ADDRESSABLE (new_node) = 0;
1123*58e805e6Szrj 
112438fd1498Szrj 	if (!fn_args)
112538fd1498Szrj 	  fn_args = tgt = new_node;
112638fd1498Szrj 	else
112738fd1498Szrj 	  {
112838fd1498Szrj 	    TREE_CHAIN (tgt) = new_node;
112938fd1498Szrj 	    tgt = new_node;
113038fd1498Szrj 	  }
113138fd1498Szrj 
113238fd1498Szrj 	mark_exp_read (tgt);
113338fd1498Szrj 
113438fd1498Szrj 	if (generic_lambda_p)
113538fd1498Szrj 	  {
113638fd1498Szrj 	    /* Avoid capturing variables in this context.  */
113738fd1498Szrj 	    ++cp_unevaluated_operand;
113838fd1498Szrj 	    tree a = forward_parm (tgt);
113938fd1498Szrj 	    --cp_unevaluated_operand;
114038fd1498Szrj 
114138fd1498Szrj 	    CALL_EXPR_ARG (call, ix) = a;
114238fd1498Szrj 	    if (decltype_call)
114338fd1498Szrj 	      CALL_EXPR_ARG (decltype_call, ix) = unshare_expr (a);
114438fd1498Szrj 
114538fd1498Szrj 	    if (PACK_EXPANSION_P (a))
114638fd1498Szrj 	      /* Set this after unsharing so it's not in decltype_call.  */
114738fd1498Szrj 	      PACK_EXPANSION_LOCAL_P (a) = true;
114838fd1498Szrj 
114938fd1498Szrj 	    ++ix;
115038fd1498Szrj 	  }
115138fd1498Szrj 	else
115238fd1498Szrj 	  vec_safe_push (direct_argvec, tgt);
115338fd1498Szrj 
115438fd1498Szrj 	src = TREE_CHAIN (src);
115538fd1498Szrj       }
115638fd1498Szrj   }
115738fd1498Szrj 
115838fd1498Szrj   if (generic_lambda_p)
115938fd1498Szrj     {
116038fd1498Szrj       if (decltype_call)
116138fd1498Szrj 	{
116238fd1498Szrj 	  fn_result = finish_decltype_type
116338fd1498Szrj 	    (decltype_call, /*id_expression_or_member_access_p=*/false,
116438fd1498Szrj 	     tf_warning_or_error);
116538fd1498Szrj 	}
116638fd1498Szrj     }
116738fd1498Szrj   else
116838fd1498Szrj     call = build_call_a (callop,
116938fd1498Szrj 			 direct_argvec->length (),
117038fd1498Szrj 			 direct_argvec->address ());
117138fd1498Szrj 
117238fd1498Szrj   CALL_FROM_THUNK_P (call) = 1;
117338fd1498Szrj   SET_EXPR_LOCATION (call, UNKNOWN_LOCATION);
117438fd1498Szrj 
117538fd1498Szrj   tree stattype = build_function_type (fn_result, FUNCTION_ARG_CHAIN (callop));
117638fd1498Szrj   stattype = (cp_build_type_attribute_variant
117738fd1498Szrj 	      (stattype, TYPE_ATTRIBUTES (optype)));
117838fd1498Szrj   if (flag_noexcept_type
117938fd1498Szrj       && TYPE_NOTHROW_P (TREE_TYPE (callop)))
118038fd1498Szrj     stattype = build_exception_variant (stattype, noexcept_true_spec);
118138fd1498Szrj 
118238fd1498Szrj   if (generic_lambda_p)
118338fd1498Szrj     --processing_template_decl;
118438fd1498Szrj 
118538fd1498Szrj   /* First build up the conversion op.  */
118638fd1498Szrj 
118738fd1498Szrj   tree rettype = build_pointer_type (stattype);
118838fd1498Szrj   tree name = make_conv_op_name (rettype);
118938fd1498Szrj   tree thistype = cp_build_qualified_type (type, TYPE_QUAL_CONST);
119038fd1498Szrj   tree fntype = build_method_type_directly (thistype, rettype, void_list_node);
119138fd1498Szrj   tree convfn = build_lang_decl (FUNCTION_DECL, name, fntype);
119238fd1498Szrj   SET_DECL_LANGUAGE (convfn, lang_cplusplus);
119338fd1498Szrj   tree fn = convfn;
119438fd1498Szrj   DECL_SOURCE_LOCATION (fn) = DECL_SOURCE_LOCATION (callop);
119538fd1498Szrj   SET_DECL_ALIGN (fn, MINIMUM_METHOD_BOUNDARY);
119638fd1498Szrj   grokclassfn (type, fn, NO_SPECIAL);
119738fd1498Szrj   set_linkage_according_to_type (type, fn);
119838fd1498Szrj   rest_of_decl_compilation (fn, namespace_bindings_p (), at_eof);
119938fd1498Szrj   DECL_IN_AGGR_P (fn) = 1;
120038fd1498Szrj   DECL_ARTIFICIAL (fn) = 1;
120138fd1498Szrj   DECL_NOT_REALLY_EXTERN (fn) = 1;
120238fd1498Szrj   DECL_DECLARED_INLINE_P (fn) = 1;
120338fd1498Szrj   DECL_ARGUMENTS (fn) = build_this_parm (fn, fntype, TYPE_QUAL_CONST);
120438fd1498Szrj 
120538fd1498Szrj   if (nested_def)
120638fd1498Szrj     DECL_INTERFACE_KNOWN (fn) = 1;
120738fd1498Szrj 
120838fd1498Szrj   if (generic_lambda_p)
120938fd1498Szrj     fn = add_inherited_template_parms (fn, DECL_TI_TEMPLATE (callop));
121038fd1498Szrj 
121138fd1498Szrj   add_method (type, fn, false);
121238fd1498Szrj 
121338fd1498Szrj   /* Generic thunk code fails for varargs; we'll complain in mark_used if
121438fd1498Szrj      the conversion op is used.  */
121538fd1498Szrj   if (varargs_function_p (callop))
121638fd1498Szrj     {
121738fd1498Szrj       DECL_DELETED_FN (fn) = 1;
121838fd1498Szrj       return;
121938fd1498Szrj     }
122038fd1498Szrj 
122138fd1498Szrj   /* Now build up the thunk to be returned.  */
122238fd1498Szrj 
122338fd1498Szrj   name = get_identifier ("_FUN");
122438fd1498Szrj   tree statfn = build_lang_decl (FUNCTION_DECL, name, stattype);
122538fd1498Szrj   SET_DECL_LANGUAGE (statfn, lang_cplusplus);
122638fd1498Szrj   fn = statfn;
122738fd1498Szrj   DECL_SOURCE_LOCATION (fn) = DECL_SOURCE_LOCATION (callop);
122838fd1498Szrj   grokclassfn (type, fn, NO_SPECIAL);
122938fd1498Szrj   set_linkage_according_to_type (type, fn);
123038fd1498Szrj   rest_of_decl_compilation (fn, namespace_bindings_p (), at_eof);
123138fd1498Szrj   DECL_IN_AGGR_P (fn) = 1;
123238fd1498Szrj   DECL_ARTIFICIAL (fn) = 1;
123338fd1498Szrj   DECL_NOT_REALLY_EXTERN (fn) = 1;
123438fd1498Szrj   DECL_DECLARED_INLINE_P (fn) = 1;
123538fd1498Szrj   DECL_STATIC_FUNCTION_P (fn) = 1;
123638fd1498Szrj   DECL_ARGUMENTS (fn) = fn_args;
123738fd1498Szrj   for (tree arg = fn_args; arg; arg = DECL_CHAIN (arg))
123838fd1498Szrj     {
123938fd1498Szrj       /* Avoid duplicate -Wshadow warnings.  */
124038fd1498Szrj       DECL_NAME (arg) = NULL_TREE;
124138fd1498Szrj       DECL_CONTEXT (arg) = fn;
124238fd1498Szrj     }
124338fd1498Szrj   if (nested_def)
124438fd1498Szrj     DECL_INTERFACE_KNOWN (fn) = 1;
124538fd1498Szrj 
124638fd1498Szrj   if (generic_lambda_p)
124738fd1498Szrj     fn = add_inherited_template_parms (fn, DECL_TI_TEMPLATE (callop));
124838fd1498Szrj 
124938fd1498Szrj   if (flag_sanitize & SANITIZE_NULL)
125038fd1498Szrj     /* Don't UBsan this function; we're deliberately calling op() with a null
125138fd1498Szrj        object argument.  */
125238fd1498Szrj     add_no_sanitize_value (fn, SANITIZE_UNDEFINED);
125338fd1498Szrj 
125438fd1498Szrj   add_method (type, fn, false);
125538fd1498Szrj 
125638fd1498Szrj   if (nested)
125738fd1498Szrj     push_function_context ();
125838fd1498Szrj   else
125938fd1498Szrj     /* Still increment function_depth so that we don't GC in the
126038fd1498Szrj        middle of an expression.  */
126138fd1498Szrj     ++function_depth;
126238fd1498Szrj 
126338fd1498Szrj   /* Generate the body of the thunk.  */
126438fd1498Szrj 
126538fd1498Szrj   start_preparsed_function (statfn, NULL_TREE,
126638fd1498Szrj 			    SF_PRE_PARSED | SF_INCLASS_INLINE);
126738fd1498Szrj   if (DECL_ONE_ONLY (statfn))
126838fd1498Szrj     {
126938fd1498Szrj       /* Put the thunk in the same comdat group as the call op.  */
127038fd1498Szrj       cgraph_node::get_create (statfn)->add_to_same_comdat_group
127138fd1498Szrj 	(cgraph_node::get_create (callop));
127238fd1498Szrj     }
127338fd1498Szrj   tree body = begin_function_body ();
127438fd1498Szrj   tree compound_stmt = begin_compound_stmt (0);
127538fd1498Szrj   if (!generic_lambda_p)
127638fd1498Szrj     {
127738fd1498Szrj       set_flags_from_callee (call);
127838fd1498Szrj       if (MAYBE_CLASS_TYPE_P (TREE_TYPE (call)))
127938fd1498Szrj 	call = build_cplus_new (TREE_TYPE (call), call, tf_warning_or_error);
128038fd1498Szrj     }
128138fd1498Szrj   call = convert_from_reference (call);
128238fd1498Szrj   finish_return_stmt (call);
128338fd1498Szrj 
128438fd1498Szrj   finish_compound_stmt (compound_stmt);
128538fd1498Szrj   finish_function_body (body);
128638fd1498Szrj 
128738fd1498Szrj   fn = finish_function (/*inline_p=*/true);
128838fd1498Szrj   if (!generic_lambda_p)
128938fd1498Szrj     expand_or_defer_fn (fn);
129038fd1498Szrj 
129138fd1498Szrj   /* Generate the body of the conversion op.  */
129238fd1498Szrj 
129338fd1498Szrj   start_preparsed_function (convfn, NULL_TREE,
129438fd1498Szrj 			    SF_PRE_PARSED | SF_INCLASS_INLINE);
129538fd1498Szrj   body = begin_function_body ();
129638fd1498Szrj   compound_stmt = begin_compound_stmt (0);
129738fd1498Szrj 
129838fd1498Szrj   /* decl_needed_p needs to see that it's used.  */
129938fd1498Szrj   TREE_USED (statfn) = 1;
130038fd1498Szrj   finish_return_stmt (decay_conversion (statfn, tf_warning_or_error));
130138fd1498Szrj 
130238fd1498Szrj   finish_compound_stmt (compound_stmt);
130338fd1498Szrj   finish_function_body (body);
130438fd1498Szrj 
130538fd1498Szrj   fn = finish_function (/*inline_p=*/true);
130638fd1498Szrj   if (!generic_lambda_p)
130738fd1498Szrj     expand_or_defer_fn (fn);
130838fd1498Szrj 
130938fd1498Szrj   if (nested)
131038fd1498Szrj     pop_function_context ();
131138fd1498Szrj   else
131238fd1498Szrj     --function_depth;
131338fd1498Szrj }
131438fd1498Szrj 
131538fd1498Szrj /* True if FN is the static function "_FUN" that gets returned from the lambda
131638fd1498Szrj    conversion operator.  */
131738fd1498Szrj 
131838fd1498Szrj bool
lambda_static_thunk_p(tree fn)131938fd1498Szrj lambda_static_thunk_p (tree fn)
132038fd1498Szrj {
132138fd1498Szrj   return (fn && TREE_CODE (fn) == FUNCTION_DECL
132238fd1498Szrj 	  && DECL_ARTIFICIAL (fn)
132338fd1498Szrj 	  && DECL_STATIC_FUNCTION_P (fn)
132438fd1498Szrj 	  && LAMBDA_TYPE_P (CP_DECL_CONTEXT (fn)));
132538fd1498Szrj }
132638fd1498Szrj 
132738fd1498Szrj /* Returns true iff VAL is a lambda-related declaration which should
132838fd1498Szrj    be ignored by unqualified lookup.  */
132938fd1498Szrj 
133038fd1498Szrj bool
is_lambda_ignored_entity(tree val)133138fd1498Szrj is_lambda_ignored_entity (tree val)
133238fd1498Szrj {
133338fd1498Szrj   /* Look past normal capture proxies.  */
133438fd1498Szrj   if (is_normal_capture_proxy (val))
133538fd1498Szrj     return true;
133638fd1498Szrj 
133738fd1498Szrj   /* Always ignore lambda fields, their names are only for debugging.  */
133838fd1498Szrj   if (TREE_CODE (val) == FIELD_DECL
133938fd1498Szrj       && CLASSTYPE_LAMBDA_EXPR (DECL_CONTEXT (val)))
134038fd1498Szrj     return true;
134138fd1498Szrj 
134238fd1498Szrj   /* None of the lookups that use qualify_lookup want the op() from the
134338fd1498Szrj      lambda; they want the one from the enclosing class.  */
134438fd1498Szrj   if (TREE_CODE (val) == FUNCTION_DECL && LAMBDA_FUNCTION_P (val))
134538fd1498Szrj     return true;
134638fd1498Szrj 
134738fd1498Szrj   return false;
134838fd1498Szrj }
134938fd1498Szrj 
135038fd1498Szrj /* Lambdas that appear in variable initializer or default argument scope
135138fd1498Szrj    get that in their mangling, so we need to record it.  We might as well
135238fd1498Szrj    use the count for function and namespace scopes as well.  */
135338fd1498Szrj static GTY(()) tree lambda_scope;
135438fd1498Szrj static GTY(()) int lambda_count;
135538fd1498Szrj struct GTY(()) tree_int
135638fd1498Szrj {
135738fd1498Szrj   tree t;
135838fd1498Szrj   int i;
135938fd1498Szrj };
136038fd1498Szrj static GTY(()) vec<tree_int, va_gc> *lambda_scope_stack;
136138fd1498Szrj 
136238fd1498Szrj void
start_lambda_scope(tree decl)136338fd1498Szrj start_lambda_scope (tree decl)
136438fd1498Szrj {
136538fd1498Szrj   tree_int ti;
136638fd1498Szrj   gcc_assert (decl);
136738fd1498Szrj   /* Once we're inside a function, we ignore variable scope and just push
136838fd1498Szrj      the function again so that popping works properly.  */
136938fd1498Szrj   if (current_function_decl && TREE_CODE (decl) == VAR_DECL)
137038fd1498Szrj     decl = current_function_decl;
137138fd1498Szrj   ti.t = lambda_scope;
137238fd1498Szrj   ti.i = lambda_count;
137338fd1498Szrj   vec_safe_push (lambda_scope_stack, ti);
137438fd1498Szrj   if (lambda_scope != decl)
137538fd1498Szrj     {
137638fd1498Szrj       /* Don't reset the count if we're still in the same function.  */
137738fd1498Szrj       lambda_scope = decl;
137838fd1498Szrj       lambda_count = 0;
137938fd1498Szrj     }
138038fd1498Szrj }
138138fd1498Szrj 
138238fd1498Szrj void
record_lambda_scope(tree lambda)138338fd1498Szrj record_lambda_scope (tree lambda)
138438fd1498Szrj {
138538fd1498Szrj   LAMBDA_EXPR_EXTRA_SCOPE (lambda) = lambda_scope;
138638fd1498Szrj   LAMBDA_EXPR_DISCRIMINATOR (lambda) = lambda_count++;
138738fd1498Szrj }
138838fd1498Szrj 
1389*58e805e6Szrj /* This lambda is an instantiation of a lambda in a template default argument
1390*58e805e6Szrj    that got no LAMBDA_EXPR_EXTRA_SCOPE, so this shouldn't either.  But we do
1391*58e805e6Szrj    need to use and increment the global count to avoid collisions.  */
1392*58e805e6Szrj 
1393*58e805e6Szrj void
record_null_lambda_scope(tree lambda)1394*58e805e6Szrj record_null_lambda_scope (tree lambda)
1395*58e805e6Szrj {
1396*58e805e6Szrj   if (vec_safe_is_empty (lambda_scope_stack))
1397*58e805e6Szrj     record_lambda_scope (lambda);
1398*58e805e6Szrj   else
1399*58e805e6Szrj     {
1400*58e805e6Szrj       tree_int *p = lambda_scope_stack->begin();
1401*58e805e6Szrj       LAMBDA_EXPR_EXTRA_SCOPE (lambda) = p->t;
1402*58e805e6Szrj       LAMBDA_EXPR_DISCRIMINATOR (lambda) = p->i++;
1403*58e805e6Szrj     }
1404*58e805e6Szrj   gcc_assert (LAMBDA_EXPR_EXTRA_SCOPE (lambda) == NULL_TREE);
1405*58e805e6Szrj }
1406*58e805e6Szrj 
140738fd1498Szrj void
finish_lambda_scope(void)140838fd1498Szrj finish_lambda_scope (void)
140938fd1498Szrj {
141038fd1498Szrj   tree_int *p = &lambda_scope_stack->last ();
141138fd1498Szrj   if (lambda_scope != p->t)
141238fd1498Szrj     {
141338fd1498Szrj       lambda_scope = p->t;
141438fd1498Szrj       lambda_count = p->i;
141538fd1498Szrj     }
141638fd1498Szrj   lambda_scope_stack->pop ();
141738fd1498Szrj }
141838fd1498Szrj 
141938fd1498Szrj tree
start_lambda_function(tree fco,tree lambda_expr)142038fd1498Szrj start_lambda_function (tree fco, tree lambda_expr)
142138fd1498Szrj {
142238fd1498Szrj   /* Let the front end know that we are going to be defining this
142338fd1498Szrj      function.  */
142438fd1498Szrj   start_preparsed_function (fco,
142538fd1498Szrj 			    NULL_TREE,
142638fd1498Szrj 			    SF_PRE_PARSED | SF_INCLASS_INLINE);
142738fd1498Szrj 
142838fd1498Szrj   tree body = begin_function_body ();
142938fd1498Szrj 
143038fd1498Szrj   /* Push the proxies for any explicit captures.  */
143138fd1498Szrj   for (tree cap = LAMBDA_EXPR_CAPTURE_LIST (lambda_expr); cap;
143238fd1498Szrj        cap = TREE_CHAIN (cap))
143338fd1498Szrj     build_capture_proxy (TREE_PURPOSE (cap), TREE_VALUE (cap));
143438fd1498Szrj 
143538fd1498Szrj   return body;
143638fd1498Szrj }
143738fd1498Szrj 
143838fd1498Szrj /* Subroutine of prune_lambda_captures: CAP is a node in
143938fd1498Szrj    LAMBDA_EXPR_CAPTURE_LIST.  Return the variable it captures for which we
144038fd1498Szrj    might optimize away the capture, or NULL_TREE if there is no such
144138fd1498Szrj    variable.  */
144238fd1498Szrj 
144338fd1498Szrj static tree
var_to_maybe_prune(tree cap)144438fd1498Szrj var_to_maybe_prune (tree cap)
144538fd1498Szrj {
144638fd1498Szrj   if (LAMBDA_CAPTURE_EXPLICIT_P (cap))
144738fd1498Szrj     /* Don't prune explicit captures.  */
144838fd1498Szrj     return NULL_TREE;
144938fd1498Szrj 
145038fd1498Szrj   tree mem = TREE_PURPOSE (cap);
145138fd1498Szrj   if (!DECL_P (mem) || !DECL_NORMAL_CAPTURE_P (mem))
145238fd1498Szrj     /* Packs and init-captures aren't captures of constant vars.  */
145338fd1498Szrj     return NULL_TREE;
145438fd1498Szrj 
145538fd1498Szrj   tree init = TREE_VALUE (cap);
145638fd1498Szrj   if (is_normal_capture_proxy (init))
145738fd1498Szrj     init = DECL_CAPTURED_VARIABLE (init);
145838fd1498Szrj   if (decl_constant_var_p (init))
145938fd1498Szrj     return init;
146038fd1498Szrj 
146138fd1498Szrj   return NULL_TREE;
146238fd1498Szrj }
146338fd1498Szrj 
146438fd1498Szrj /* walk_tree helper for prune_lambda_captures: Remember which capture proxies
146538fd1498Szrj    for constant variables are actually used in the lambda body.
146638fd1498Szrj 
146738fd1498Szrj    There will always be a DECL_EXPR for the capture proxy; remember it when we
146838fd1498Szrj    see it, but replace it with any other use.  */
146938fd1498Szrj 
147038fd1498Szrj static tree
mark_const_cap_r(tree * t,int * walk_subtrees,void * data)147138fd1498Szrj mark_const_cap_r (tree *t, int *walk_subtrees, void *data)
147238fd1498Szrj {
147338fd1498Szrj   hash_map<tree,tree*> &const_vars = *(hash_map<tree,tree*>*)data;
147438fd1498Szrj 
147538fd1498Szrj   tree var = NULL_TREE;
147638fd1498Szrj   if (TREE_CODE (*t) == DECL_EXPR)
147738fd1498Szrj     {
147838fd1498Szrj       tree decl = DECL_EXPR_DECL (*t);
147938fd1498Szrj       if (is_constant_capture_proxy (decl))
1480*58e805e6Szrj 	{
148138fd1498Szrj 	  var = DECL_CAPTURED_VARIABLE (decl);
148238fd1498Szrj 	  *walk_subtrees = 0;
148338fd1498Szrj 	}
1484*58e805e6Szrj     }
148538fd1498Szrj   else if (is_constant_capture_proxy (*t))
148638fd1498Szrj     var = DECL_CAPTURED_VARIABLE (*t);
148738fd1498Szrj 
148838fd1498Szrj   if (var)
148938fd1498Szrj     {
149038fd1498Szrj       tree *&slot = const_vars.get_or_insert (var);
149138fd1498Szrj       if (!slot || VAR_P (*t))
149238fd1498Szrj 	slot = t;
149338fd1498Szrj     }
149438fd1498Szrj 
149538fd1498Szrj   return NULL_TREE;
149638fd1498Szrj }
149738fd1498Szrj 
149838fd1498Szrj /* We're at the end of processing a lambda; go back and remove any captures of
149938fd1498Szrj    constant variables for which we've folded away all uses.  */
150038fd1498Szrj 
150138fd1498Szrj static void
prune_lambda_captures(tree body)150238fd1498Szrj prune_lambda_captures (tree body)
150338fd1498Szrj {
150438fd1498Szrj   tree lam = current_lambda_expr ();
150538fd1498Szrj   if (!LAMBDA_EXPR_CAPTURE_OPTIMIZED (lam))
150638fd1498Szrj     /* No uses were optimized away.  */
150738fd1498Szrj     return;
150838fd1498Szrj   if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lam) == CPLD_NONE)
150938fd1498Szrj     /* No default captures, and we don't prune explicit captures.  */
151038fd1498Szrj     return;
151138fd1498Szrj 
151238fd1498Szrj   hash_map<tree,tree*> const_vars;
151338fd1498Szrj 
151438fd1498Szrj   cp_walk_tree_without_duplicates (&body, mark_const_cap_r, &const_vars);
151538fd1498Szrj 
151638fd1498Szrj   tree *fieldp = &TYPE_FIELDS (LAMBDA_EXPR_CLOSURE (lam));
151738fd1498Szrj   for (tree *capp = &LAMBDA_EXPR_CAPTURE_LIST (lam); *capp; )
151838fd1498Szrj     {
151938fd1498Szrj       tree cap = *capp;
152038fd1498Szrj       if (tree var = var_to_maybe_prune (cap))
152138fd1498Szrj 	{
1522*58e805e6Szrj 	  tree **use = const_vars.get (var);
1523*58e805e6Szrj 	  if (use && TREE_CODE (**use) == DECL_EXPR)
152438fd1498Szrj 	    {
152538fd1498Szrj 	      /* All uses of this capture were folded away, leaving only the
152638fd1498Szrj 		 proxy declaration.  */
152738fd1498Szrj 
152838fd1498Szrj 	      /* Splice the capture out of LAMBDA_EXPR_CAPTURE_LIST.  */
152938fd1498Szrj 	      *capp = TREE_CHAIN (cap);
153038fd1498Szrj 
153138fd1498Szrj 	      /* And out of TYPE_FIELDS.  */
153238fd1498Szrj 	      tree field = TREE_PURPOSE (cap);
153338fd1498Szrj 	      while (*fieldp != field)
153438fd1498Szrj 		fieldp = &DECL_CHAIN (*fieldp);
153538fd1498Szrj 	      *fieldp = DECL_CHAIN (*fieldp);
153638fd1498Szrj 
153738fd1498Szrj 	      /* And remove the capture proxy declaration.  */
1538*58e805e6Szrj 	      **use = void_node;
153938fd1498Szrj 	      continue;
154038fd1498Szrj 	    }
154138fd1498Szrj 	}
154238fd1498Szrj 
154338fd1498Szrj       capp = &TREE_CHAIN (cap);
154438fd1498Szrj     }
154538fd1498Szrj }
154638fd1498Szrj 
154738fd1498Szrj void
finish_lambda_function(tree body)154838fd1498Szrj finish_lambda_function (tree body)
154938fd1498Szrj {
155038fd1498Szrj   finish_function_body (body);
155138fd1498Szrj 
155238fd1498Szrj   prune_lambda_captures (body);
155338fd1498Szrj 
155438fd1498Szrj   /* Finish the function and generate code for it if necessary.  */
155538fd1498Szrj   tree fn = finish_function (/*inline_p=*/true);
155638fd1498Szrj 
155738fd1498Szrj   /* Only expand if the call op is not a template.  */
155838fd1498Szrj   if (!DECL_TEMPLATE_INFO (fn))
155938fd1498Szrj     expand_or_defer_fn (fn);
156038fd1498Szrj }
156138fd1498Szrj 
156238fd1498Szrj #include "gt-cp-lambda.h"
1563