/* Perform the semantic phase of lambda parsing, i.e., the process of
   building tree structure, checking semantic consistency, and
   building RTL.  These routines are used both during actual parsing
   and during the instantiation of template functions.

   Copyright (C) 1998-2025 Free Software Foundation, Inc.

   This file is part of GCC.

   GCC is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3, or (at your option)
   any later version.

   GCC is distributed in the hope that it will be useful, but
   WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   General Public License for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "cp-tree.h"
#include "stringpool.h"
#include "cgraph.h"
#include "tree-iterator.h"
#include "toplev.h"
#include "gimplify.h"
#include "target.h"
#include "decl.h"
#include "flags.h"

/* Constructor for a lambda expression.  */

tree
build_lambda_expr (void)
{
  tree lambda = make_node (LAMBDA_EXPR);
  LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda) = CPLD_NONE;
  LAMBDA_EXPR_CAPTURE_LIST         (lambda) = NULL_TREE;
  LAMBDA_EXPR_THIS_CAPTURE         (lambda) = NULL_TREE;
  LAMBDA_EXPR_REGEN_INFO           (lambda) = NULL_TREE;
  LAMBDA_EXPR_PENDING_PROXIES      (lambda) = NULL;
  return lambda;
}

/* Create the closure object for a LAMBDA_EXPR.  */

tree
build_lambda_object (tree lambda_expr)
{
  /* Build aggregate constructor call.
     - cp_parser_braced_list
     - cp_parser_functional_cast  */
  vec<constructor_elt, va_gc> *elts = NULL;
  tree node, expr, type;

  if (processing_template_decl && !in_template_context
      && current_binding_level->requires_expression)
    /* As in cp_parser_lambda_expression, don't get confused by
       cp_parser_requires_expression setting processing_template_decl.  In that
       case we want to return the result of finish_compound_literal, to avoid
       tsubst_lambda_expr.  */;
  else if (processing_template_decl || lambda_expr == error_mark_node)
    return lambda_expr;

  /* Make sure any error messages refer to the lambda-introducer.  */
  location_t loc = LAMBDA_EXPR_LOCATION (lambda_expr);
  iloc_sentinel il (loc);

  for (node = LAMBDA_EXPR_CAPTURE_LIST (lambda_expr);
       node;
       node = TREE_CHAIN (node))
    {
      tree field = TREE_PURPOSE (node);
      tree val = TREE_VALUE (node);

      if (field == error_mark_node)
	{
	  expr = error_mark_node;
	  goto out;
	}

      if (TREE_CODE (val) == TREE_LIST)
	val = build_x_compound_expr_from_list (val, ELK_INIT,
					       tf_warning_or_error);

      if (DECL_P (val))
	mark_used (val);

      /* Mere mortals can't copy arrays with aggregate initialization, so
	 do some magic to make it work here.  */
      if (TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE)
	val = build_array_copy (val);
      else if (DECL_NORMAL_CAPTURE_P (field)
	       && !DECL_VLA_CAPTURE_P (field)
	       && !TYPE_REF_P (TREE_TYPE (field)))
	{
	  /* "the entities that are captured by copy are used to
	     direct-initialize each corresponding non-static data
	     member of the resulting closure object."

	     There's normally no way to express direct-initialization
	     from an element of a CONSTRUCTOR, so we build up a special
	     TARGET_EXPR to bypass the usual copy-initialization.  */
	  val = force_rvalue (val, tf_warning_or_error);
	  if (TREE_CODE (val) == TARGET_EXPR)
	    TARGET_EXPR_DIRECT_INIT_P (val) = true;
	}

      CONSTRUCTOR_APPEND_ELT (elts, DECL_NAME (field), val);
    }

  expr = build_constructor (init_list_type_node, elts);
  CONSTRUCTOR_IS_DIRECT_INIT (expr) = 1;

  /* N2927: "[The closure] class type is not an aggregate."
     But we briefly treat it as an aggregate to make this simpler.  */
  type = LAMBDA_EXPR_CLOSURE (lambda_expr);
  CLASSTYPE_NON_AGGREGATE (type) = 0;
  expr = finish_compound_literal (type, expr, tf_warning_or_error);
  protected_set_expr_location (expr, loc);
  CLASSTYPE_NON_AGGREGATE (type) = 1;

 out:
  return expr;
}

/* Return an initialized RECORD_TYPE for LAMBDA.
   LAMBDA must have its explicit captures already.  */

tree
begin_lambda_type (tree lambda)
{
  /* Lambda names are nearly but not quite anonymous.  */
  tree name = make_anon_name ();
  IDENTIFIER_LAMBDA_P (name) = true;

  /* Create the new RECORD_TYPE for this lambda.  */
  tree type = xref_tag (/*tag_code=*/record_type, name);
  if (type == error_mark_node)
    return error_mark_node;

  /* Designate it as a struct so that we can use aggregate initialization.  */
  CLASSTYPE_DECLARED_CLASS (type) = false;

  /* Cross-reference the expression and the type.  */
  LAMBDA_EXPR_CLOSURE (lambda) = type;
  SET_CLASSTYPE_LAMBDA_EXPR (type, lambda);

  /* In C++17, assume the closure is literal; we'll clear the flag later if
     necessary.  */
  if (cxx_dialect >= cxx17)
    CLASSTYPE_LITERAL_P (type) = true;

  /* Clear base types.  */
  xref_basetypes (type, /*bases=*/NULL_TREE);

  /* Start the class.  */
  type = begin_class_definition (type);

  return type;
}

/* Given a LAMBDA_EXPR or closure type LAMBDA, return the op() of the
   closure type.  */

tree
lambda_function (tree lambda)
{
  tree type;
  if (TREE_CODE (lambda) == LAMBDA_EXPR)
    type = LAMBDA_EXPR_CLOSURE (lambda);
  else
    type = lambda;
  gcc_assert (LAMBDA_TYPE_P (type));
  /* Don't let debug_tree cause instantiation.  */
  if (CLASSTYPE_TEMPLATE_INSTANTIATION (type)
      && !COMPLETE_OR_OPEN_TYPE_P (type))
    return NULL_TREE;
  lambda = get_class_binding_direct (type, call_op_identifier);
  if (lambda)
    lambda = STRIP_TEMPLATE (get_first_fn (lambda));
  return lambda;
}

/* True if EXPR is an expression whose type can be used directly in lambda
   capture.  Not to be used for 'auto'.  */

static bool
type_deducible_expression_p (tree expr)
{
  if (!type_dependent_expression_p (expr))
    return true;
  if (BRACE_ENCLOSED_INITIALIZER_P (expr)
      || TREE_CODE (expr) == EXPR_PACK_EXPANSION)
    return false;
  tree t = non_reference (TREE_TYPE (expr));
  return (t && TREE_CODE (t) != TYPE_PACK_EXPANSION
	  && !WILDCARD_TYPE_P (t) && !LAMBDA_TYPE_P (t)
	  && !array_of_unknown_bound_p (t)
	  && !type_uses_auto (t));
}

/* Returns the type to use for the FIELD_DECL corresponding to the
   capture of EXPR.  EXPLICIT_INIT_P indicates whether this is a
   C++14 init capture, and BY_REFERENCE_P indicates whether we're
   capturing by reference.  */

tree
lambda_capture_field_type (tree expr, bool explicit_init_p,
			   bool by_reference_p)
{
  tree type;
  bool is_this = is_this_parameter (tree_strip_nop_conversions (expr));

  if (explicit_init_p)
    {
      tree auto_node = make_auto ();

      type = auto_node;
      if (by_reference_p)
	/* Add the reference now, so deduction doesn't lose
	   outermost CV qualifiers of EXPR.  */
	type = build_reference_type (type);
      if (uses_parameter_packs (expr))
	/* Stick with 'auto' even if the type could be deduced.  */
	TEMPLATE_TYPE_PARAMETER_PACK (auto_node) = true;
      else
	type = do_auto_deduction (type, expr, auto_node);
    }
  else if (!type_deducible_expression_p (expr))
    {
      type = cxx_make_type (DECLTYPE_TYPE);
      DECLTYPE_TYPE_EXPR (type) = expr;
      DECLTYPE_FOR_LAMBDA_CAPTURE (type) = true;
      DECLTYPE_FOR_REF_CAPTURE (type) = by_reference_p;
      SET_TYPE_STRUCTURAL_EQUALITY (type);
    }
  else
    {
      STRIP_ANY_LOCATION_WRAPPER (expr);

      if (!by_reference_p && is_capture_proxy (expr))
	{
	  /* When capturing by-value another capture proxy from an enclosing
	     lambda, consider the type of the corresponding field instead,
	     as the proxy may be additionally const-qualifed if the enclosing
	     lambda is non-mutable (PR94376).  */
	  gcc_assert (TREE_CODE (DECL_VALUE_EXPR (expr)) == COMPONENT_REF);
	  expr = TREE_OPERAND (DECL_VALUE_EXPR (expr), 1);
	}

      type = non_reference (unlowered_expr_type (expr));

      if ((by_reference_p && !is_this) || TREE_CODE (type) == FUNCTION_TYPE)
	type = build_reference_type (type);
    }

  return type;
}

/* Returns true iff DECL is a lambda capture proxy variable created by
   build_capture_proxy.  */

bool
is_capture_proxy (tree decl)
{
  /* Location wrappers should be stripped or otherwise handled by the
     caller before using this predicate.  */
  gcc_checking_assert (!location_wrapper_p (decl));

  return (VAR_P (decl)
	  && DECL_HAS_VALUE_EXPR_P (decl)
	  && !DECL_ANON_UNION_VAR_P (decl)
	  && !DECL_DECOMPOSITION_P (decl)
	  && !DECL_FNAME_P (decl)
	  && !(DECL_ARTIFICIAL (decl)
	       && DECL_LANG_SPECIFIC (decl)
	       && DECL_OMP_PRIVATIZED_MEMBER (decl))
	  && LAMBDA_FUNCTION_P (DECL_CONTEXT (decl)));
}

/* Returns true iff DECL is a capture proxy for a normal capture
   (i.e. without explicit initializer).  */

bool
is_normal_capture_proxy (tree decl)
{
  if (!is_capture_proxy (decl))
    /* It's not a capture proxy.  */
    return false;

  return (DECL_LANG_SPECIFIC (decl)
	  && DECL_CAPTURED_VARIABLE (decl));
}

/* If DECL is a normal capture proxy, return the variable it captures.
   Otherwise, just return DECL.  */

tree
strip_normal_capture_proxy (tree decl)
{
  while (is_normal_capture_proxy (decl))
    decl = DECL_CAPTURED_VARIABLE (decl);
  return decl;
}

/* Returns true iff DECL is a capture proxy for a normal capture
   of a constant variable.  */

bool
is_constant_capture_proxy (tree decl)
{
  if (is_normal_capture_proxy (decl))
    return decl_constant_var_p (DECL_CAPTURED_VARIABLE (decl));
  return false;
}

/* VAR is a capture proxy created by build_capture_proxy; add it to the
   current function, which is the operator() for the appropriate lambda.  */

void
insert_capture_proxy (tree var)
{
  if (is_normal_capture_proxy (var))
    {
      tree cap = DECL_CAPTURED_VARIABLE (var);
      if (CHECKING_P)
	{
	  gcc_assert (!is_normal_capture_proxy (cap));
	  tree old = retrieve_local_specialization (cap);
	  if (old)
	    gcc_assert (DECL_CONTEXT (old) != DECL_CONTEXT (var));
	}
      register_local_specialization (var, cap);
    }

  /* Put the capture proxy in the extra body block so that it won't clash
     with a later local variable.  */
  pushdecl_outermost_localscope (var);

  /* And put a DECL_EXPR in the STATEMENT_LIST for the same block.  */
  var = build_stmt (DECL_SOURCE_LOCATION (var), DECL_EXPR, var);
  /* The first stmt_list is from start_preparsed_function.  Then there's a
     possible stmt_list from begin_eh_spec_block, then the one from the
     lambda's outer {}.  */
  unsigned index = 1 + use_eh_spec_block (current_function_decl);
  tree stmt_list = (*stmt_list_stack)[index];
  gcc_assert (stmt_list);
  append_to_statement_list_force (var, &stmt_list);
}

/* We've just finished processing a lambda; if the containing scope is also
   a lambda, insert any capture proxies that were created while processing
   the nested lambda.  */

void
insert_pending_capture_proxies (void)
{
  tree lam;
  vec<tree, va_gc> *proxies;
  unsigned i;

  if (!current_function_decl || !LAMBDA_FUNCTION_P (current_function_decl))
    return;

  lam = CLASSTYPE_LAMBDA_EXPR (DECL_CONTEXT (current_function_decl));
  proxies = LAMBDA_EXPR_PENDING_PROXIES (lam);
  for (i = 0; i < vec_safe_length (proxies); ++i)
    {
      tree var = (*proxies)[i];
      insert_capture_proxy (var);
    }
  release_tree_vector (LAMBDA_EXPR_PENDING_PROXIES (lam));
  LAMBDA_EXPR_PENDING_PROXIES (lam) = NULL;
}

/* Given REF, a COMPONENT_REF designating a field in the lambda closure,
   return the type we want the proxy to have: the type of the field itself,
   with added const-qualification if the lambda isn't mutable and the
   capture is by value.  */

tree
lambda_proxy_type (tree ref)
{
  tree type;
  if (ref == error_mark_node)
    return error_mark_node;
  if (REFERENCE_REF_P (ref))
    ref = TREE_OPERAND (ref, 0);
  gcc_assert (TREE_CODE (ref) == COMPONENT_REF);
  type = TREE_TYPE (ref);
  if (!type || WILDCARD_TYPE_P (non_reference (type)))
    {
      type = cxx_make_type (DECLTYPE_TYPE);
      DECLTYPE_TYPE_EXPR (type) = ref;
      DECLTYPE_FOR_LAMBDA_PROXY (type) = true;
      SET_TYPE_STRUCTURAL_EQUALITY (type);
    }
  if (DECL_PACK_P (TREE_OPERAND (ref, 1)))
    type = make_pack_expansion (type);
  return type;
}

/* MEMBER is a capture field in a lambda closure class.  Now that we're
   inside the operator(), build a placeholder var for future lookups and
   debugging.  But if EARLY_P is true, we do not have the real operator()
   yet and we have to proceed differently.  */

tree
build_capture_proxy (tree member, tree init, bool early_p)
{
  tree var, object, fn, closure, name, lam, type;

  if (PACK_EXPANSION_P (member))
    member = PACK_EXPANSION_PATTERN (member);

  closure = DECL_CONTEXT (member);
  fn = lambda_function (closure);
  lam = CLASSTYPE_LAMBDA_EXPR (closure);

  object = DECL_ARGUMENTS (fn);
  /* The proxy variable forwards to the capture field.  */
  if (INDIRECT_TYPE_P (TREE_TYPE (object)))
    object = build_fold_indirect_ref (object);
  object = finish_non_static_data_member (member, object, NULL_TREE);
  if (REFERENCE_REF_P (object))
    object = TREE_OPERAND (object, 0);

  /* Remove the __ inserted by add_capture.  */
  if (IDENTIFIER_POINTER (DECL_NAME (member))[2] == '_'
      && IDENTIFIER_POINTER (DECL_NAME (member))[3] == '.')
    name = get_identifier ("_");
  else
    name = get_identifier (IDENTIFIER_POINTER (DECL_NAME (member)) + 2);

  if (name == this_identifier && TYPE_PTR_P (TREE_TYPE (member)))
    /* Avoid DECLTYPE_TYPE for by-ref 'this' capture in an xobj lambda; the
       constness of the closure doesn't matter just like it doesn't matter to
       other by-ref capture.  It's simpler to handle this special case here
       than in lambda_proxy_type.  */
    type = TREE_TYPE (member);
  else
    {
      type = lambda_proxy_type (object);
      if (name == this_identifier)
	{
	  type = build_pointer_type (type);
	  type = cp_build_qualified_type (type, TYPE_QUAL_CONST);
	  object = build_fold_addr_expr_with_type (object, type);
	}
    }

  if (DECL_VLA_CAPTURE_P (member))
    {
      /* Rebuild the VLA type from the pointer and maxindex.  */
      tree field = next_aggregate_field (TYPE_FIELDS (type));
      tree ptr = build_simple_component_ref (object, field);
      field = next_aggregate_field (DECL_CHAIN (field));
      tree max = build_simple_component_ref (object, field);
      type = build_cplus_array_type (TREE_TYPE (TREE_TYPE (ptr)),
				     build_index_type (max));
      type = build_reference_type (type);
      object = convert (type, ptr);
    }

  complete_type (type);

  var = build_decl (input_location, VAR_DECL, name, type);
  SET_DECL_VALUE_EXPR (var, object);
  DECL_HAS_VALUE_EXPR_P (var) = 1;
  DECL_ARTIFICIAL (var) = 1;
  TREE_USED (var) = 1;
  DECL_CONTEXT (var) = fn;

  if (DECL_NORMAL_CAPTURE_P (member))
    {
      if (DECL_VLA_CAPTURE_P (member))
	{
	  init = CONSTRUCTOR_ELT (init, 0)->value;
	  init = TREE_OPERAND (init, 0); // Strip ADDR_EXPR.
	  init = TREE_OPERAND (init, 0); // Strip ARRAY_REF.
	}
      else
	{
	  if (PACK_EXPANSION_P (init))
	    init = PACK_EXPANSION_PATTERN (init);
	}

      if (INDIRECT_REF_P (init))
	init = TREE_OPERAND (init, 0);
      STRIP_NOPS (init);

      gcc_assert (VAR_P (init) || TREE_CODE (init) == PARM_DECL);
      init = strip_normal_capture_proxy (init);
      retrofit_lang_decl (var);
      DECL_CAPTURED_VARIABLE (var) = init;
    }

  if (name == this_identifier)
    {
      if (early_p)
	return var;
      gcc_assert (LAMBDA_EXPR_THIS_CAPTURE (lam) == member);
      LAMBDA_EXPR_THIS_CAPTURE (lam) = var;
    }

  if (early_p)
    {
      gcc_checking_assert (current_binding_level->kind == sk_lambda);
      /* insert_capture_proxy below wouldn't push into the lambda scope.  */
      pushdecl (var);
    }
  else if (fn == current_function_decl)
    insert_capture_proxy (var);
  else
    vec_safe_push (LAMBDA_EXPR_PENDING_PROXIES (lam), var);

  return var;
}

static GTY(()) tree ptr_id;
static GTY(()) tree max_id;

/* Return a struct containing a pointer and a length for lambda capture of
   an array of runtime length.  */

static tree
vla_capture_type (tree array_type)
{
  tree type = xref_tag (record_type, make_anon_name ());
  xref_basetypes (type, NULL_TREE);
  type = begin_class_definition (type);
  if (!ptr_id)
    {
      ptr_id = get_identifier ("ptr");
      max_id = get_identifier ("max");
    }
  tree ptrtype = build_pointer_type (TREE_TYPE (array_type));
  tree field = build_decl (input_location, FIELD_DECL, ptr_id, ptrtype);
  finish_member_declaration (field);
  field = build_decl (input_location, FIELD_DECL, max_id, sizetype);
  finish_member_declaration (field);
  return finish_struct (type, NULL_TREE);
}

/* From an ID and INITIALIZER, create a capture (by reference if
   BY_REFERENCE_P is true), add it to the capture-list for LAMBDA,
   and return it.  If ID is `this', BY_REFERENCE_P says whether
   `*this' is captured by reference.  */

tree
add_capture (tree lambda, tree id, tree orig_init, bool by_reference_p,
	     bool explicit_init_p, unsigned *name_independent_cnt)
{
  char *buf;
  tree type, member, name;
  bool vla = false;
  bool variadic = false;
  tree initializer = orig_init;

  if (PACK_EXPANSION_P (initializer))
    {
      initializer = PACK_EXPANSION_PATTERN (initializer);
      variadic = true;
    }

  if (TREE_CODE (initializer) == TREE_LIST
      /* A pack expansion might end up with multiple elements.  */
      && !PACK_EXPANSION_P (TREE_VALUE (initializer)))
    initializer = build_x_compound_expr_from_list (initializer, ELK_INIT,
						   tf_warning_or_error);
  type = TREE_TYPE (initializer);
  if (type == error_mark_node)
    return error_mark_node;

  if (!dependent_type_p (type) && array_of_runtime_bound_p (type))
    {
      vla = true;
      if (!by_reference_p)
	error ("array of runtime bound cannot be captured by copy, "
	       "only by reference");

      /* For a VLA, we capture the address of the first element and the
	 maximum index, and then reconstruct the VLA for the proxy.  */
      tree elt = cp_build_array_ref (input_location, initializer,
				     integer_zero_node, tf_warning_or_error);
      initializer = build_constructor_va (init_list_type_node, 2,
					  NULL_TREE, build_address (elt),
					  NULL_TREE,
					  array_type_nelts_minus_one (type));
      type = vla_capture_type (type);
    }
  else if (!dependent_type_p (type)
	   && variably_modified_type_p (type, NULL_TREE))
    {
      auto_diagnostic_group d;
      sorry ("capture of variably-modified type %qT that is not an N3639 array "
	     "of runtime bound", type);
      if (TREE_CODE (type) == ARRAY_TYPE
	  && variably_modified_type_p (TREE_TYPE (type), NULL_TREE))
	inform (input_location, "because the array element type %qT has "
		"variable size", TREE_TYPE (type));
      return error_mark_node;
    }
  else
    {
      type = lambda_capture_field_type (initializer, explicit_init_p,
					by_reference_p);
      if (type == error_mark_node)
	return error_mark_node;

      if (id == this_identifier && !by_reference_p)
	{
	  gcc_assert (INDIRECT_TYPE_P (type));
	  type = TREE_TYPE (type);
	  initializer = cp_build_fold_indirect_ref (initializer);
	}

      if (dependent_type_p (type))
	;
      else if (id != this_identifier && by_reference_p)
	{
	  if (!lvalue_p (initializer))
	    {
	      error ("cannot capture %qE by reference", initializer);
	      return error_mark_node;
	    }
	}
      else
	{
	  /* Capture by copy requires a complete type.  */
	  type = complete_type (type);
	  if (!COMPLETE_TYPE_P (type))
	    {
	      auto_diagnostic_group d;
	      error ("capture by copy of incomplete type %qT", type);
	      cxx_incomplete_type_inform (type);
	      return error_mark_node;
	    }
	  else if (!verify_type_context (input_location,
					 TCTX_CAPTURE_BY_COPY, type))
	    return error_mark_node;
	}

      if (cxx_dialect < cxx20 && !explicit_init_p)
	{
	  auto_diagnostic_group d;
	  tree stripped_init = tree_strip_any_location_wrapper (initializer);
	  if (DECL_DECOMPOSITION_P (stripped_init)
	      && pedwarn (input_location, OPT_Wc__20_extensions,
			  "captured structured bindings are a C++20 extension"))
	    inform (DECL_SOURCE_LOCATION (stripped_init), "declared here");
	}
    }

  /* Add __ to the beginning of the field name so that user code
     won't find the field with name lookup.  We can't just leave the name
     unset because template instantiation uses the name to find
     instantiated fields.  */
  if (id_equal (id, "_") && name_independent_cnt)
    {
      if (*name_independent_cnt == 0)
	name = get_identifier ("___");
      else
	{
	  /* For 2nd and later name-independent capture use
	     unique names.  */
	  char buf2[5 + (HOST_BITS_PER_INT + 2) / 3];
	  sprintf (buf2, "___.%u", *name_independent_cnt);
	  name = get_identifier (buf2);
	}
      name_independent_cnt[0]++;
    }
  else
    {
      buf = XALLOCAVEC (char, IDENTIFIER_LENGTH (id) + 3);
      buf[1] = buf[0] = '_';
      memcpy (buf + 2, IDENTIFIER_POINTER (id),
	      IDENTIFIER_LENGTH (id) + 1);
      name = get_identifier (buf);
    }

  if (variadic)
    {
      type = make_pack_expansion (type);
      if (explicit_init_p)
	/* With an explicit initializer 'type' is auto, which isn't really a
	   parameter pack in this context.  We will want as many fields as we
	   have elements in the expansion of the initializer, so use its packs
	   instead.  */
	{
	  PACK_EXPANSION_PARAMETER_PACKS (type)
	    = uses_parameter_packs (initializer);
	  PACK_EXPANSION_AUTO_P (type) = true;
	}
    }

  /* Make member variable.  */
  member = build_decl (input_location, FIELD_DECL, name, type);
  DECL_VLA_CAPTURE_P (member) = vla;

  if (!explicit_init_p)
    /* Normal captures are invisible to name lookup but uses are replaced
       with references to the capture field; we implement this by only
       really making them invisible in unevaluated context; see
       qualify_lookup.  For now, let's make explicitly initialized captures
       always visible.  */
    DECL_NORMAL_CAPTURE_P (member) = true;

  if (id == this_identifier)
    LAMBDA_EXPR_THIS_CAPTURE (lambda) = member;

  /* Add it to the appropriate closure class if we've started it.  */
  if (current_class_type
      && current_class_type == LAMBDA_EXPR_CLOSURE (lambda))
    {
      if (COMPLETE_TYPE_P (current_class_type))
	internal_error ("trying to capture %qD in instantiation of "
			"generic lambda", id);
      finish_member_declaration (member);
    }

  tree listmem = member;
  if (variadic)
    {
      listmem = make_pack_expansion (member);
      initializer = orig_init;
    }
  LAMBDA_EXPR_CAPTURE_LIST (lambda)
    = tree_cons (listmem, initializer, LAMBDA_EXPR_CAPTURE_LIST (lambda));

  if (LAMBDA_EXPR_CLOSURE (lambda))
    return build_capture_proxy (member, initializer, /*early_p=*/false);
  /* For explicit captures we haven't started the function yet, so we wait
     and build the proxy from cp_parser_lambda_body.  */
  LAMBDA_CAPTURE_EXPLICIT_P (LAMBDA_EXPR_CAPTURE_LIST (lambda)) = true;
  return NULL_TREE;
}

/* Register all the capture members on the list CAPTURES, which is the
   LAMBDA_EXPR_CAPTURE_LIST for the lambda after the introducer.  */

void
register_capture_members (tree captures)
{
  if (captures == NULL_TREE)
    return;

  register_capture_members (TREE_CHAIN (captures));

  tree field = TREE_PURPOSE (captures);
  if (PACK_EXPANSION_P (field))
    field = PACK_EXPANSION_PATTERN (field);

  finish_member_declaration (field);
}

/* Similar to add_capture, except this works on a stack of nested lambdas.
   BY_REFERENCE_P in this case is derived from the default capture mode.
   Returns the capture for the lambda at the bottom of the stack.  */

tree
add_default_capture (tree lambda_stack, tree id, tree initializer)
{
  bool this_capture_p = (id == this_identifier);
  tree var = NULL_TREE;
  tree saved_class_type = current_class_type;

  for (tree node = lambda_stack;
       node;
       node = TREE_CHAIN (node))
    {
      tree lambda = TREE_VALUE (node);

      current_class_type = LAMBDA_EXPR_CLOSURE (lambda);
      if (DECL_PACK_P (initializer))
	initializer = make_pack_expansion (initializer);
      var = add_capture (lambda,
                            id,
                            initializer,
                            /*by_reference_p=*/
			    (this_capture_p
			     || (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda)
				 == CPLD_REFERENCE)),
			    /*explicit_init_p=*/false, NULL);
      initializer = convert_from_reference (var);

      /* Warn about deprecated implicit capture of this via [=].  */
      if (cxx_dialect >= cxx20
	  && this_capture_p
	  && LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda) == CPLD_COPY)
	{
	  auto_diagnostic_group d;
	  if (warning_at (LAMBDA_EXPR_LOCATION (lambda), OPT_Wdeprecated,
			  "implicit capture of %qE via %<[=]%> is deprecated "
			  "in C++20", this_identifier))
	    inform (LAMBDA_EXPR_LOCATION (lambda), "add explicit %<this%> or "
		    "%<*this%> capture");
	}
    }

  current_class_type = saved_class_type;

  return var;
}

/* Return the capture pertaining to a use of 'this' in LAMBDA, in the
   form of an INDIRECT_REF, possibly adding it through default
   capturing, if ADD_CAPTURE_P is nonzero.  If ADD_CAPTURE_P is negative,
   try to capture but don't complain if we can't.  */

tree
lambda_expr_this_capture (tree lambda, int add_capture_p)
{
  tree result;

  tree this_capture = LAMBDA_EXPR_THIS_CAPTURE (lambda);
  if (this_capture)
    if (tree spec = retrieve_local_specialization (this_capture))
      {
	gcc_checking_assert (generic_lambda_fn_p (lambda_function (lambda)));
	this_capture = spec;
      }

  /* In unevaluated context this isn't an odr-use, so don't capture.  */
  if (cp_unevaluated_operand)
    add_capture_p = false;

  /* If we captured 'this' but don't have a capture proxy yet, look up the
     captured 'this' again.  */
  if (this_capture && TREE_CODE (this_capture) == FIELD_DECL)
    {
      gcc_assert (!add_capture_p);
      this_capture = NULL_TREE;
    }

  /* Try to default capture 'this' if we can.  */
  if (!this_capture)
    {
      tree lambda_stack = NULL_TREE;
      tree init = NULL_TREE;
      bool saw_complete = false;

      /* If we are in a lambda function, we can move out until we hit:
           1. a non-lambda function or NSDMI,
           2. a lambda function capturing 'this', or
           3. a non-default capturing lambda function.  */
      for (tree tlambda = lambda; ;)
	{
	  if (add_capture_p
	      && LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (tlambda) == CPLD_NONE)
	    /* tlambda won't let us capture 'this'.  */
	    break;

	  if (add_capture_p)
	    lambda_stack = tree_cons (NULL_TREE,
				      tlambda,
				      lambda_stack);

	  tree closure = LAMBDA_EXPR_CLOSURE (tlambda);
	  if (COMPLETE_TYPE_P (closure))
	    /* We're instantiating a generic lambda op(), the containing
	       scope may be gone.  */
	    saw_complete = true;

	  tree containing_function
	    = decl_function_context (TYPE_NAME (closure));

	  tree ex = LAMBDA_EXPR_EXTRA_SCOPE (tlambda);
	  if (ex && TREE_CODE (ex) == FIELD_DECL)
	    {
	      /* Lambda in an NSDMI.  We don't have a function to look up
		 'this' in, but we can find (or rebuild) the fake one from
		 inject_this_parameter.  */
	      if (!containing_function && !saw_complete)
		/* If we're parsing a lambda in a non-local class,
		   we can find the fake 'this' in scope_chain.  */
		init = scope_chain->x_current_class_ptr;
	      else
		/* Otherwise it's either gone or buried in
		   function_context_stack, so make another.  */
		init = build_this_parm (NULL_TREE, DECL_CONTEXT (ex),
					TYPE_UNQUALIFIED);
	      gcc_checking_assert
		(init && (TREE_TYPE (TREE_TYPE (init))
			  == current_nonlambda_class_type ()));
	      break;
	    }

	  if (containing_function == NULL_TREE)
	    /* We ran out of scopes; there's no 'this' to capture.  */
	    break;

	  if (!LAMBDA_FUNCTION_P (containing_function))
	    {
	      /* We found a non-lambda function.
		 There is no this pointer in xobj member functions.  */
	      if (DECL_IOBJ_MEMBER_FUNCTION_P (containing_function))
		/* First parameter is 'this'.  */
		init = DECL_ARGUMENTS (containing_function);
	      break;
	    }

	  tlambda
            = CLASSTYPE_LAMBDA_EXPR (DECL_CONTEXT (containing_function));

          if (LAMBDA_EXPR_THIS_CAPTURE (tlambda))
	    {
	      /* An outer lambda has already captured 'this'.  */
	      init = LAMBDA_EXPR_THIS_CAPTURE (tlambda);
	      break;
	    }
	}

      if (init)
        {
          if (add_capture_p)
	    this_capture = add_default_capture (lambda_stack,
					        /*id=*/this_identifier,
					        init);
          else
	    this_capture = init;
        }
    }

  if (cp_unevaluated_operand)
    result = this_capture;
  else if (!this_capture)
    {
      if (add_capture_p == 1)
	{
	  error ("%<this%> was not captured for this lambda function");
	  result = error_mark_node;
	}
      else
	result = NULL_TREE;
    }
  else
    {
      /* To make sure that current_class_ref is for the lambda.  */
      gcc_assert (!current_class_ref
		  || (TYPE_MAIN_VARIANT (TREE_TYPE (current_class_ref))
		      == LAMBDA_EXPR_CLOSURE (lambda)));

      result = this_capture;

      /* If 'this' is captured, each use of 'this' is transformed into an
	 access to the corresponding unnamed data member of the closure
	 type cast (_expr.cast_ 5.4) to the type of 'this'. [ The cast
	 ensures that the transformed expression is an rvalue. ] */
      result = rvalue (result);
    }

  gcc_checking_assert (!result || result == error_mark_node
		       || TYPE_PTR_P (TREE_TYPE (result)));

  return result;
}

/* Return the innermost LAMBDA_EXPR we're currently in, if any.  */

tree
current_lambda_expr (void)
{
  tree type = current_class_type;
  while (type && !LAMBDA_TYPE_P (type))
    type = decl_type_context (TYPE_NAME (type));
  if (type)
    return CLASSTYPE_LAMBDA_EXPR (type);
  else
    return NULL_TREE;
}

/* Return the current LAMBDA_EXPR, if this is a resolvable dummy
   object.  NULL otherwise..  */

static tree
resolvable_dummy_lambda (tree object)
{
  if (!is_dummy_object (object))
    return NULL_TREE;

  tree type = TYPE_MAIN_VARIANT (TREE_TYPE (object));
  gcc_assert (!TYPE_PTR_P (type));

  tree fn;
  if (type != current_class_type
      && current_class_type
      && LAMBDA_TYPE_P (current_class_type)
      && (fn = lambda_function (current_class_type))
      /* Even dummy lambdas have an operator() since P2036, but the
	 dummy operator() doesn't have this set.  */
      && DECL_LAMBDA_FUNCTION_P (fn)
      && DERIVED_FROM_P (type, nonlambda_method_basetype()))
    return CLASSTYPE_LAMBDA_EXPR (current_class_type);

  return NULL_TREE;
}

/* We don't want to capture 'this' until we know we need it, i.e. after
   overload resolution has chosen a non-static member function.  At that
   point we call this function to turn a dummy object into a use of the
   'this' capture.  */

tree
maybe_resolve_dummy (tree object, bool add_capture_p)
{
  if (tree lam = resolvable_dummy_lambda (object))
    if (tree cap = lambda_expr_this_capture (lam, add_capture_p))
      if (cap != error_mark_node)
	object = build_fold_indirect_ref (cap);

  return object;
}

/* When parsing a generic lambda containing an argument-dependent
   member function call we defer overload resolution to instantiation
   time.  But we have to know now whether to capture this or not.
   Do that if FNS contains any non-static fns as per
   [expr.prim.lambda.capture]/7.1.  */

void
maybe_generic_this_capture (tree object, tree fns)
{
  if (tree lam = resolvable_dummy_lambda (object))
    if (!LAMBDA_EXPR_THIS_CAPTURE (lam))
      {
	/* We've not yet captured, so look at the function set of
	   interest.  */
	if (BASELINK_P (fns))
	  fns = BASELINK_FUNCTIONS (fns);
	bool id_expr = TREE_CODE (fns) == TEMPLATE_ID_EXPR;
	if (id_expr)
	  fns = TREE_OPERAND (fns, 0);

	for (lkp_iterator iter (fns); iter; ++iter)
	  if (((!id_expr && TREE_CODE (*iter) != USING_DECL)
	       || TREE_CODE (*iter) == TEMPLATE_DECL)
	      && DECL_OBJECT_MEMBER_FUNCTION_P (*iter))
	    {
	      /* Found a non-static member.  Capture this.  */
	      lambda_expr_this_capture (lam, /*maybe*/-1);
	      break;
	    }
      }
}

/* Returns the innermost non-lambda function.  If ONLY_SKIP_CONSTEVAL_BLOCK_P,
   we only skip lambda functions that represent consteval blocks.  */

tree
current_nonlambda_function (bool only_skip_consteval_block_p/*=false*/)
{
  tree fn = current_function_decl;
  tree lam;
  while (fn && LAMBDA_FUNCTION_P (fn)
	 && (!only_skip_consteval_block_p
	     /* Only keep going if FN represents a consteval block.  */
	     || ((lam = CLASSTYPE_LAMBDA_EXPR (CP_DECL_CONTEXT (fn)))
		 && LAMBDA_EXPR_CONSTEVAL_BLOCK_P (lam))))
    fn = decl_function_context (fn);
  return fn;
}

/* Returns the method basetype of the innermost non-lambda function, including
   a hypothetical constructor if inside an NSDMI, or NULL_TREE if none.  */

tree
nonlambda_method_basetype (void)
{
  tree type = current_class_type;
  if (!type || !LAMBDA_TYPE_P (type))
    return current_class_ref ? type : NULL_TREE;

  while (true)
    {
      tree lam = CLASSTYPE_LAMBDA_EXPR (type);
      tree ex = LAMBDA_EXPR_EXTRA_SCOPE (lam);
      if (ex && TREE_CODE (ex) == FIELD_DECL)
	/* Lambda in an NSDMI.  */
	return DECL_CONTEXT (ex);

      tree fn = TYPE_CONTEXT (type);
      if (!fn || TREE_CODE (fn) != FUNCTION_DECL
	  || !DECL_OBJECT_MEMBER_FUNCTION_P (fn))
	/* No enclosing non-lambda method.  */
	return NULL_TREE;
      if (!LAMBDA_FUNCTION_P (fn))
	/* Found an enclosing non-lambda method.  */
	return TYPE_METHOD_BASETYPE (TREE_TYPE (fn));
      type = DECL_CONTEXT (fn);
    }
}

/* Like current_scope, but looking through lambdas.  If ONLY_SKIP_CLOSURES_P,
   only look through closure types.  */

tree
current_nonlambda_scope (bool only_skip_closures_p/*=false*/)
{
  tree scope = current_scope ();
  for (;;)
    {
      if (!only_skip_closures_p
	  && TREE_CODE (scope) == FUNCTION_DECL
	  && LAMBDA_FUNCTION_P (scope))
	{
	  scope = CP_TYPE_CONTEXT (DECL_CONTEXT (scope));
	  continue;
	}
      else if (LAMBDA_TYPE_P (scope))
	{
	  scope = CP_TYPE_CONTEXT (scope);
	  continue;
	}
      break;
    }
  return scope;
}

/* Helper function for maybe_add_lambda_conv_op; build a CALL_EXPR with
   indicated FN and NARGS, but do not initialize the return type or any of the
   argument slots.  */

static tree
prepare_op_call (tree fn, int nargs)
{
  tree t;

  t = build_vl_exp (CALL_EXPR, nargs + 3);
  CALL_EXPR_FN (t) = fn;
  CALL_EXPR_STATIC_CHAIN (t) = NULL;

  return t;
}

/* Return true iff CALLOP is the op() for a generic lambda.  */

bool
generic_lambda_fn_p (tree callop)
{
  return (LAMBDA_FUNCTION_P (callop)
	  && DECL_TEMPLATE_INFO (callop)
	  && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (callop)));
}

/* If the closure TYPE has a static op(), also add a conversion to function
   pointer.  */

void
maybe_add_lambda_conv_op (tree type)
{
  bool nested = (cfun != NULL);
  bool nested_def = decl_function_context (TYPE_MAIN_DECL (type));
  tree callop = lambda_function (type);
  tree lam = CLASSTYPE_LAMBDA_EXPR (type);

  if (LAMBDA_EXPR_CAPTURE_LIST (lam) != NULL_TREE
      || LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lam) != CPLD_NONE
      /* CWG2561 ...and no explicit object parameter.  */
      || DECL_XOBJ_MEMBER_FUNCTION_P (callop))
    return;

  if (processing_template_decl)
    return;

  bool const generic_lambda_p = generic_lambda_fn_p (callop);

  if (!generic_lambda_p && undeduced_auto_decl (callop))
    {
      /* If the op() wasn't deduced due to errors, give up.  */
      gcc_assert (errorcount || sorrycount);
      return;
    }

  /* Non-generic non-capturing lambdas only have a conversion function to
     pointer to function when the trailing requires-clause's constraints are
     satisfied.  */
  if (!generic_lambda_p && !constraints_satisfied_p (callop))
    return;

  /* Non-template conversion operators are defined directly with build_call_a
     and using DIRECT_ARGVEC for arguments (including 'this').  Templates are
     deferred and the CALL is built in-place.  In the case of a deduced return
     call op, the decltype expression, DECLTYPE_CALL, used as a substitute for
     the return type is also built in-place.  The arguments of DECLTYPE_CALL in
     the return expression may differ in flags from those in the body CALL.  In
     particular, parameter pack expansions are marked PACK_EXPANSION_LOCAL_P in
     the body CALL, but not in DECLTYPE_CALL.  */

  vec<tree, va_gc> *direct_argvec = 0;
  tree decltype_call = 0, call = 0;
  tree optype = TREE_TYPE (callop);
  tree fn_result = TREE_TYPE (optype);

  tree thisarg = NULL_TREE;
  if (TREE_CODE (optype) == METHOD_TYPE)
    thisarg = build_int_cst (TREE_TYPE (DECL_ARGUMENTS (callop)), 0);
  if (generic_lambda_p)
    {
      ++processing_template_decl;

      /* Prepare the dependent member call for the static member function
	 '_FUN' and, potentially, prepare another call to be used in a decltype
	 return expression for a deduced return call op to allow for simple
	 implementation of the conversion operator.  */

      tree objfn;
      int nargs = list_length (DECL_ARGUMENTS (callop));
      if (thisarg)
	{
	  tree instance = cp_build_fold_indirect_ref (thisarg);
	  objfn = lookup_template_function (DECL_NAME (callop),
					    DECL_TI_ARGS (callop));
	  objfn = build_min (COMPONENT_REF, NULL_TREE,
			     instance, objfn, NULL_TREE);
	  --nargs;
	  call = prepare_op_call (objfn, nargs);
	}
      else
	objfn = callop;

      if (type_uses_auto (fn_result))
	decltype_call = prepare_op_call (objfn, nargs);
    }
  else if (thisarg)
    {
      direct_argvec = make_tree_vector ();
      direct_argvec->quick_push (thisarg);
    }

  /* Copy CALLOP's argument list (as per 'copy_list') as FN_ARGS in order to
     declare the static member function "_FUN" below.  For each arg append to
     DIRECT_ARGVEC (for the non-template case) or populate the pre-allocated
     call args (for the template case).  If a parameter pack is found, expand
     it, flagging it as PACK_EXPANSION_LOCAL_P for the body call.  */

  tree fn_args = NULL_TREE;
  {
    int ix = 0;
    tree src = FUNCTION_FIRST_USER_PARM (callop);
    tree tgt = NULL;

    if (!thisarg && !decltype_call)
      src = NULL_TREE;
    while (src)
      {
	tree new_node = copy_node (src);
	/* We set DECL_CONTEXT of NEW_NODE to the statfn below.
	   Notice this is creating a recursive type!  */

	/* Clear TREE_ADDRESSABLE on thunk arguments.  */
	TREE_ADDRESSABLE (new_node) = 0;

	if (!fn_args)
	  fn_args = tgt = new_node;
	else
	  {
	    TREE_CHAIN (tgt) = new_node;
	    tgt = new_node;
	  }

	mark_exp_read (tgt);

	if (generic_lambda_p)
	  {
	    tree a = tgt;
	    if (thisarg)
	      {
		if (DECL_PACK_P (tgt))
		  {
		    a = make_pack_expansion (a);
		    PACK_EXPANSION_LOCAL_P (a) = true;
		  }
		CALL_EXPR_ARG (call, ix) = a;
	      }

	    if (decltype_call)
	      {
		/* Avoid capturing variables in this context.  */
		++cp_unevaluated_operand;
		CALL_EXPR_ARG (decltype_call, ix) = forward_parm (tgt);
		--cp_unevaluated_operand;
	      }

	    ++ix;
	  }
	else
	  vec_safe_push (direct_argvec, tgt);

	src = TREE_CHAIN (src);
      }
  }

  if (generic_lambda_p)
    {
      if (decltype_call)
	{
	  fn_result = finish_decltype_type
	    (decltype_call, /*id_expression_or_member_access_p=*/false,
	     tf_warning_or_error);
	}
    }
  else if (thisarg)
    {
      /* Don't warn on deprecated or unavailable lambda declarations, unless
	 the lambda is actually called.  */
      auto du = make_temp_override (deprecated_state,
				    UNAVAILABLE_DEPRECATED_SUPPRESS);
      call = build_call_a (callop, direct_argvec->length (),
			   direct_argvec->address ());
    }

  if (thisarg)
    {
      CALL_FROM_THUNK_P (call) = 1;
      SET_EXPR_LOCATION (call, UNKNOWN_LOCATION);
    }

  tree stattype
    = build_function_type (fn_result, FUNCTION_FIRST_USER_PARMTYPE (callop));
  stattype = (cp_build_type_attribute_variant
	      (stattype, TYPE_ATTRIBUTES (optype)));
  if (flag_noexcept_type
      && TYPE_NOTHROW_P (TREE_TYPE (callop)))
    stattype = build_exception_variant (stattype, noexcept_true_spec);

  if (generic_lambda_p)
    --processing_template_decl;

  /* First build up the conversion op.  */

  tree rettype = build_pointer_type (stattype);
  tree name = make_conv_op_name (rettype);
  tree thistype = cp_build_qualified_type (type, TYPE_QUAL_CONST);
  tree fntype = build_method_type_directly (thistype, rettype, void_list_node);
  /* DR 1722: The conversion function should be noexcept.  */
  fntype = build_exception_variant (fntype, noexcept_true_spec);
  tree convfn = build_lang_decl (FUNCTION_DECL, name, fntype);
  SET_DECL_LANGUAGE (convfn, lang_cplusplus);
  tree fn = convfn;
  DECL_SOURCE_LOCATION (fn) = DECL_SOURCE_LOCATION (callop);
  SET_DECL_ALIGN (fn, MINIMUM_METHOD_BOUNDARY);
  grokclassfn (type, fn, NO_SPECIAL);
  set_linkage_according_to_type (type, fn);
  rest_of_decl_compilation (fn, namespace_bindings_p (), at_eof);
  DECL_IN_AGGR_P (fn) = 1;
  DECL_ARTIFICIAL (fn) = 1;
  DECL_NOT_REALLY_EXTERN (fn) = 1;
  DECL_DECLARED_INLINE_P (fn) = 1;
  DECL_DECLARED_CONSTEXPR_P (fn) = DECL_DECLARED_CONSTEXPR_P (callop);
  if (DECL_IMMEDIATE_FUNCTION_P (callop))
    SET_DECL_IMMEDIATE_FUNCTION_P (fn);
  DECL_ARGUMENTS (fn) = build_this_parm (fn, fntype, TYPE_QUAL_CONST);

  if (nested_def)
    DECL_INTERFACE_KNOWN (fn) = 1;

  if (generic_lambda_p)
    fn = add_inherited_template_parms (fn, DECL_TI_TEMPLATE (callop));

  add_method (type, fn, false);

  if (thisarg == NULL_TREE)
    {
      /* For static lambda, just return operator().  */
      if (nested)
	push_function_context ();
      else
	/* Still increment function_depth so that we don't GC in the
	   middle of an expression.  */
	++function_depth;

      /* Generate the body of the conversion op.  */

      start_preparsed_function (convfn, NULL_TREE,
				SF_PRE_PARSED | SF_INCLASS_INLINE);
      tree body = begin_function_body ();
      tree compound_stmt = begin_compound_stmt (0);

      /* decl_needed_p needs to see that it's used.  */
      TREE_USED (callop) = 1;
      finish_return_stmt (decay_conversion (callop, tf_warning_or_error));

      finish_compound_stmt (compound_stmt);
      finish_function_body (body);

      fn = finish_function (/*inline_p=*/true);
      if (!generic_lambda_p)
	expand_or_defer_fn (fn);

      if (nested)
	pop_function_context ();
      else
	--function_depth;
      return;
    }

  /* Generic thunk code fails for varargs; we'll complain in mark_used if
     the conversion op is used.  */
  if (varargs_function_p (callop))
    {
      DECL_DELETED_FN (fn) = 1;
      return;
    }

  /* Now build up the thunk to be returned.  */

  tree statfn = build_lang_decl (FUNCTION_DECL, fun_identifier, stattype);
  SET_DECL_LANGUAGE (statfn, lang_cplusplus);
  fn = statfn;
  DECL_SOURCE_LOCATION (fn) = DECL_SOURCE_LOCATION (callop);
  grokclassfn (type, fn, NO_SPECIAL);
  set_linkage_according_to_type (type, fn);
  rest_of_decl_compilation (fn, namespace_bindings_p (), at_eof);
  DECL_IN_AGGR_P (fn) = 1;
  DECL_ARTIFICIAL (fn) = 1;
  DECL_NOT_REALLY_EXTERN (fn) = 1;
  DECL_DECLARED_INLINE_P (fn) = 1;
  DECL_STATIC_FUNCTION_P (fn) = 1;
  DECL_DECLARED_CONSTEXPR_P (fn) = DECL_DECLARED_CONSTEXPR_P (callop);
  if (DECL_IMMEDIATE_FUNCTION_P (callop))
    SET_DECL_IMMEDIATE_FUNCTION_P (fn);
  DECL_ARGUMENTS (fn) = fn_args;
  for (tree arg = fn_args; arg; arg = DECL_CHAIN (arg))
    {
      /* Avoid duplicate -Wshadow warnings.  */
      DECL_NAME (arg) = NULL_TREE;
      DECL_CONTEXT (arg) = fn;
    }
  if (nested_def)
    DECL_INTERFACE_KNOWN (fn) = 1;

  if (generic_lambda_p)
    fn = add_inherited_template_parms (fn, DECL_TI_TEMPLATE (callop));

  if (flag_sanitize & SANITIZE_NULL)
    /* Don't UBsan this function; we're deliberately calling op() with a null
       object argument.  */
    add_no_sanitize_value (fn, SANITIZE_UNDEFINED);

  add_method (type, fn, false);

  if (nested)
    push_function_context ();
  else
    /* Still increment function_depth so that we don't GC in the
       middle of an expression.  */
    ++function_depth;

  /* Generate the body of the thunk.  */

  start_preparsed_function (statfn, NULL_TREE,
			    SF_PRE_PARSED | SF_INCLASS_INLINE);
  tree body = begin_function_body ();
  tree compound_stmt = begin_compound_stmt (0);
  if (!generic_lambda_p)
    {
      set_flags_from_callee (call);
      if (MAYBE_CLASS_TYPE_P (TREE_TYPE (call)))
	call = build_cplus_new (TREE_TYPE (call), call, tf_warning_or_error);
    }
  call = convert_from_reference (call);
  finish_return_stmt (call);

  finish_compound_stmt (compound_stmt);
  finish_function_body (body);

  fn = finish_function (/*inline_p=*/true);
  if (!generic_lambda_p)
    expand_or_defer_fn (fn);

  /* Generate the body of the conversion op.  */

  start_preparsed_function (convfn, NULL_TREE,
			    SF_PRE_PARSED | SF_INCLASS_INLINE);
  body = begin_function_body ();
  compound_stmt = begin_compound_stmt (0);

  /* decl_needed_p needs to see that it's used.  */
  TREE_USED (statfn) = 1;
  finish_return_stmt (decay_conversion (statfn, tf_warning_or_error));

  finish_compound_stmt (compound_stmt);
  finish_function_body (body);

  fn = finish_function (/*inline_p=*/true);
  if (!generic_lambda_p)
    expand_or_defer_fn (fn);

  if (nested)
    pop_function_context ();
  else
    --function_depth;
}

/* True if FN is the static function "_FUN" that gets returned from the lambda
   conversion operator.  */

bool
lambda_static_thunk_p (tree fn)
{
  return (fn && TREE_CODE (fn) == FUNCTION_DECL
	  && DECL_ARTIFICIAL (fn)
	  && DECL_STATIC_FUNCTION_P (fn)
	  && LAMBDA_TYPE_P (CP_DECL_CONTEXT (fn)));
}

bool
call_from_lambda_thunk_p (tree call)
{
  return (CALL_FROM_THUNK_P (call)
	  && lambda_static_thunk_p (current_function_decl));
}

/* Returns true iff VAL is a lambda-related declaration which should
   be ignored by unqualified lookup.  */

bool
is_lambda_ignored_entity (tree val)
{
  /* Look past normal, non-VLA capture proxies.  */
  if (is_normal_capture_proxy (val)
      && !variably_modified_type_p (TREE_TYPE (val), NULL_TREE))
    return true;

  /* Always ignore lambda fields, their names are only for debugging.  */
  if (TREE_CODE (val) == FIELD_DECL
      && CLASSTYPE_LAMBDA_EXPR (DECL_CONTEXT (val)))
    return true;

  /* None of the lookups that use qualify_lookup want the op() from the
     lambda; they want the one from the enclosing class.  */
  if (tree fns = maybe_get_fns (val))
    if (LAMBDA_FUNCTION_P (OVL_FIRST (fns)))
      return true;

  return false;
}

/* Lambdas that appear in variable initializer or default argument
   scope get that in their mangling, so we need to record it.  Also,
   multiple lambdas in the same scope may need a mangling
   discriminator.  In ABI <= 17, there is a single per-scope sequence
   number.  In ABI >= 18, there are per-scope per-signature sequence
   numbers.  */
struct GTY(()) lambda_sig_count
{
  tree fn; // The lambda fn whose sig this is.
  unsigned count;
};
struct GTY(()) lambda_discriminator
{
  tree scope;
  unsigned nesting; // Inside a function, VAR_DECLs get the function
  		    // as scope. This counts that nesting.
  unsigned count;   // The per-scope counter.
  vec<lambda_sig_count, va_gc> *discriminators; // Per-signature counters
};
// The current scope.
static GTY(()) lambda_discriminator lambda_scope;
// Stack of previous scopes.
static GTY(()) vec<lambda_discriminator, va_gc> *lambda_scope_stack;

// Push DECL as lambda extra scope, also new discriminator counters.

void
start_lambda_scope (tree decl)
{
  gcc_checking_assert (decl);
  if (current_function_decl && VAR_P (decl))
    // If we're inside a function, we ignore variable scope.  Don't push.
    lambda_scope.nesting++;
  else
    {
      vec_safe_push (lambda_scope_stack, lambda_scope);
      lambda_scope.scope = decl;
      lambda_scope.nesting = 0;
      lambda_scope.count = 0;
      lambda_scope.discriminators = nullptr;
    }
}

// Pop from the current lambda extra scope.

void
finish_lambda_scope (void)
{
  if (!lambda_scope.nesting--)
    {
      lambda_scope = lambda_scope_stack->last ();
      lambda_scope_stack->pop ();
    }
}

// Record the current lambda scope into LAMBDA

void
record_lambda_scope (tree lambda)
{
  tree closure = LAMBDA_EXPR_CLOSURE (lambda);
  gcc_checking_assert (closure);

  /* Before ABI v20, lambdas in static data member initializers did not
     get a dedicated lambda scope.  */
  tree scope = lambda_scope.scope;
  if (is_static_data_member_initialized_in_class (scope))
    {
      if (!abi_version_at_least (20))
	scope = NULL_TREE;
      if (warn_abi && abi_version_crosses (20) && !processing_template_decl)
	{
	  if (abi_version_at_least (20))
	    warning_at (location_of (closure), OPT_Wabi,
			"the mangled name of %qT changed in "
			"%<-fabi-version=20%> (GCC 15.1)", closure);
	  else
	    warning_at (location_of (closure), OPT_Wabi,
			"the mangled name of %qT changes in "
			"%<-fabi-version=20%> (GCC 15.1)", closure);
	}
    }

  /* An otherwise unattached class-scope lambda in a member template
     should not have a mangling scope, as the mangling scope will not
     correctly inherit on instantiation.  */
  tree ctx = TYPE_CONTEXT (closure);
  if (scope
      && ctx
      && CLASS_TYPE_P (ctx)
      && ctx == TREE_TYPE (scope)
      && current_template_depth > template_class_depth (ctx))
    scope = NULL_TREE;

  LAMBDA_EXPR_EXTRA_SCOPE (lambda) = scope;
  if (scope)
    maybe_key_decl (scope, TYPE_NAME (closure));
}

// Compare lambda template heads TMPL_A and TMPL_B, used for both
// templated lambdas, and template template parameters of said lambda.

static bool
compare_lambda_template_head (tree tmpl_a, tree tmpl_b)
{
  // We only need one level of template parms
  tree inner_a = INNERMOST_TEMPLATE_PARMS (DECL_TEMPLATE_PARMS (tmpl_a));
  tree inner_b = INNERMOST_TEMPLATE_PARMS (DECL_TEMPLATE_PARMS (tmpl_b));

  // We only compare explicit template parms, ignoring trailing
  // synthetic ones.
  int len_a = TREE_VEC_LENGTH (inner_a);
  int len_b = TREE_VEC_LENGTH (inner_b);

  for (int ix = 0, len = MAX (len_a, len_b); ix != len; ix++)
    {
      tree parm_a = NULL_TREE;
      if (ix < len_a)
	{
	  parm_a = TREE_VEC_ELT (inner_a, ix);
	  if (parm_a == error_mark_node)
	    return false;
	  parm_a = TREE_VALUE (parm_a);
	  if (parm_a == error_mark_node)
	    return false;
	  if (DECL_VIRTUAL_P (parm_a))
	    parm_a = NULL_TREE;
	}

      tree parm_b = NULL_TREE;
      if (ix < len_b)
	{
	  parm_b = TREE_VEC_ELT (inner_b, ix);
	  if (parm_b == error_mark_node)
	    return false;
	  parm_b = TREE_VALUE (parm_b);
	  if (parm_b == error_mark_node)
	    return false;
	  if (DECL_VIRTUAL_P (parm_b))
	    parm_b = NULL_TREE;
	}

      if (!parm_a && !parm_b)
	// we're done
	break;

      if (!(parm_a && parm_b))
	return false;

      if (TREE_CODE (parm_a) != TREE_CODE (parm_b))
	return false;

      if (TREE_CODE (parm_a) == PARM_DECL)
	{
	  if (TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (parm_a))
	      != TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (parm_b)))
	    return false;

	  if (!same_type_p (TREE_TYPE (parm_a), TREE_TYPE (parm_b)))
	    return false;
	}
      else
	{
	  if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (parm_a))
	      != TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (parm_b)))
	    return false;

	  if (TREE_CODE (parm_a) != TEMPLATE_DECL)
	    gcc_checking_assert (TREE_CODE (parm_a) == TYPE_DECL);
	  else if (!compare_lambda_template_head (parm_a, parm_b))
	    return false;
	}
    }

  return true;
}

// Compare lambda signatures FN_A and FN_B, they may be TEMPLATE_DECLs too.

static bool
compare_lambda_sig (tree fn_a, tree fn_b)
{
  if (TREE_CODE (fn_a) == TEMPLATE_DECL
      && TREE_CODE (fn_b) == TEMPLATE_DECL)
    {
      if (!compare_lambda_template_head (fn_a, fn_b))
	return false;
      fn_a = DECL_TEMPLATE_RESULT (fn_a);
      fn_b = DECL_TEMPLATE_RESULT (fn_b);
    }
  else if (TREE_CODE (fn_a) == TEMPLATE_DECL
	   || TREE_CODE (fn_b) == TEMPLATE_DECL)
    return false;

  if (fn_a == error_mark_node
      || fn_b == error_mark_node)
    return false;

  for (tree args_a = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn_a))),
	 args_b = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn_b)));
       args_a || args_b;
       args_a = TREE_CHAIN (args_a), args_b = TREE_CHAIN (args_b))
    {
      if (!args_a || !args_b)
	return false;
      // This check also deals with differing variadicness
      if (!same_type_p (TREE_VALUE (args_a), TREE_VALUE (args_b)))
	return false;
    }

  return true;
}

// Record the per-scope discriminator of LAMBDA.  If the extra scope
// is empty, we must use the empty scope counter, which might not be
// the live one.

void
record_lambda_scope_discriminator (tree lambda)
{
  auto *slot = (vec_safe_is_empty (lambda_scope_stack)
		|| LAMBDA_EXPR_EXTRA_SCOPE (lambda)
		? &lambda_scope : lambda_scope_stack->begin ());
  LAMBDA_EXPR_SCOPE_ONLY_DISCRIMINATOR (lambda) = slot->count++;
}

// Record the per-scope per-signature discriminator of LAMBDA.  If the
// extra scope is empty, we must use the empty scope counter, which
// might not be the live one.

void
record_lambda_scope_sig_discriminator (tree lambda, tree fn)
{
  auto *slot = (vec_safe_is_empty (lambda_scope_stack)
		|| LAMBDA_EXPR_EXTRA_SCOPE (lambda)
		? &lambda_scope : lambda_scope_stack->begin ());
  gcc_checking_assert (LAMBDA_EXPR_EXTRA_SCOPE (lambda) == slot->scope);

  // A linear search, we're not expecting this to be a big list, and
  // this avoids needing a signature hash function.
  lambda_sig_count *sig;
  if (unsigned ix = vec_safe_length (slot->discriminators))
    for (sig = slot->discriminators->begin (); ix--; sig++)
      if (compare_lambda_sig (fn, sig->fn))
	goto found;
  {
    lambda_sig_count init = {fn, 0};
    sig = vec_safe_push (slot->discriminators, init);
  }
 found:
  LAMBDA_EXPR_SCOPE_SIG_DISCRIMINATOR (lambda) = sig->count++;
}

/* Push the proxies for any explicit captures in LAMBDA_EXPR.
   If EARLY_P, we do not have the real operator() yet.  */

void
push_capture_proxies (tree lambda_expr, bool early_p)
{
  for (tree cap = LAMBDA_EXPR_CAPTURE_LIST (lambda_expr); cap;
       cap = TREE_CHAIN (cap))
    build_capture_proxy (TREE_PURPOSE (cap), TREE_VALUE (cap), early_p);
}

tree
start_lambda_function (tree fco, tree lambda_expr)
{
  /* Let the front end know that we are going to be defining this
     function.  */
  start_preparsed_function (fco,
			    NULL_TREE,
			    SF_PRE_PARSED | SF_INCLASS_INLINE);

  tree body = begin_function_body ();

  /* Push the proxies for any explicit captures.  */
  push_capture_proxies (lambda_expr);

  return body;
}

/* Subroutine of prune_lambda_captures: CAP is a node in
   LAMBDA_EXPR_CAPTURE_LIST.  Return the variable it captures for which we
   might optimize away the capture, or NULL_TREE if there is no such
   variable.  */

static tree
var_to_maybe_prune (tree cap)
{
  if (LAMBDA_CAPTURE_EXPLICIT_P (cap))
    /* Don't prune explicit captures.  */
    return NULL_TREE;

  tree mem = TREE_PURPOSE (cap);
  if (!DECL_P (mem) || !DECL_NORMAL_CAPTURE_P (mem))
    /* Packs and init-captures aren't captures of constant vars.  */
    return NULL_TREE;

  tree init = TREE_VALUE (cap);
  if (is_normal_capture_proxy (init))
    init = DECL_CAPTURED_VARIABLE (init);
  if (decl_constant_var_p (init))
    return init;

  return NULL_TREE;
}

/* walk_tree helper for prune_lambda_captures: Remember which capture proxies
   for constant variables are actually used in the lambda body.

   There will always be a DECL_EXPR for the capture proxy; remember it when we
   see it, but replace it with any other use.  */

static tree
mark_const_cap_r (tree *t, int *walk_subtrees, void *data)
{
  hash_map<tree,tree*> &const_vars = *(hash_map<tree,tree*>*)data;

  tree var = NULL_TREE;
  if (TREE_CODE (*t) == DECL_EXPR)
    {
      tree decl = DECL_EXPR_DECL (*t);
      if (is_constant_capture_proxy (decl))
	{
	  var = DECL_CAPTURED_VARIABLE (decl);
	  *walk_subtrees = 0;
	}
    }
  else if (!location_wrapper_p (*t) /* is_capture_proxy dislikes them.  */
	   && is_constant_capture_proxy (*t))
    var = DECL_CAPTURED_VARIABLE (*t);

  if (var)
    {
      tree *&slot = const_vars.get_or_insert (var);
      if (!slot || VAR_P (*t))
	slot = t;
    }

  return NULL_TREE;
}

/* We're at the end of processing a lambda; go back and remove any captures of
   constant variables for which we've folded away all uses.  */

static void
prune_lambda_captures (tree body)
{
  tree lam = current_lambda_expr ();
  if (!LAMBDA_EXPR_CAPTURE_OPTIMIZED (lam))
    /* No uses were optimized away.  */
    return;
  if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lam) == CPLD_NONE)
    /* No default captures, and we don't prune explicit captures.  */
    return;
  /* Don't bother pruning in a template, we'll prune at instantiation time.  */
  if (dependent_type_p (TREE_TYPE (lam)))
    return;

  hash_map<tree,tree*> const_vars;

  cp_walk_tree_without_duplicates (&body, mark_const_cap_r, &const_vars);

  tree bind_expr = expr_single (DECL_SAVED_TREE (lambda_function (lam)));
  bool noexcept_p = (bind_expr
		     && TREE_CODE (bind_expr) == MUST_NOT_THROW_EXPR);
  if (noexcept_p)
    bind_expr = expr_single (TREE_OPERAND (bind_expr, 0));

  tree *fieldp = &TYPE_FIELDS (LAMBDA_EXPR_CLOSURE (lam));
  for (tree *capp = &LAMBDA_EXPR_CAPTURE_LIST (lam); *capp; )
    {
      tree cap = *capp;
      if (tree var = var_to_maybe_prune (cap))
	{
	  tree **use = const_vars.get (var);
	  if (TREE_CODE (**use) == DECL_EXPR)
	    {
	      /* All uses of this capture were folded away, leaving only the
		 proxy declaration.  */

	      if (noexcept_p)
		{
		  /* We didn't handle noexcept lambda captures correctly before
		     the fix for PR c++/119764.  */
		  if (abi_version_crosses (21))
		    warning_at (location_of (lam), OPT_Wabi, "%qD is no longer"
				" captured in noexcept lambda in ABI v21 "
				"(GCC 16)", var);
		  if (!abi_version_at_least (21))
		    goto next;
		}

	      /* Splice the capture out of LAMBDA_EXPR_CAPTURE_LIST.  */
	      *capp = TREE_CHAIN (cap);

	      /* And out of TYPE_FIELDS.  */
	      tree field = TREE_PURPOSE (cap);
	      while (*fieldp != field)
		fieldp = &DECL_CHAIN (*fieldp);
	      *fieldp = DECL_CHAIN (*fieldp);

	      /* And out of the bindings for the function.  */
	      tree *blockp = &BLOCK_VARS (current_binding_level->blocks);
	      while (*blockp != DECL_EXPR_DECL (**use))
		blockp = &DECL_CHAIN (*blockp);
	      *blockp = DECL_CHAIN (*blockp);

	      /* And maybe out of the vars declared in the containing
		 BIND_EXPR, if it's listed there.  */
	      tree *bindp = &BIND_EXPR_VARS (bind_expr);
	      while (*bindp && *bindp != DECL_EXPR_DECL (**use))
		bindp = &DECL_CHAIN (*bindp);
	      if (*bindp)
		*bindp = DECL_CHAIN (*bindp);

	      /* And remove the capture proxy declaration.  */
	      **use = void_node;
	      continue;
	    }
	}

    next:
      capp = &TREE_CHAIN (cap);
    }
}

// Record the per-scope per-signature discriminator of LAMBDA.  If the
// extra scope is empty, we must use the empty scope counter, which
// might not be the live one.

void
finish_lambda_function (tree body)
{
  finish_function_body (body);

  prune_lambda_captures (cur_stmt_list);

  /* Finish the function and generate code for it if necessary.  */
  tree fn = finish_function (/*inline_p=*/true);

  /* Only expand if the call op is not a template.  */
  if (!DECL_TEMPLATE_INFO (fn))
    expand_or_defer_fn (fn);
}

#include "gt-cp-lambda.h"
